pai-zero 0.11.2 → 0.11.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/logger.ts","../../src/core/config.ts","../../src/cli/commands/welcome.cmd.ts","../../src/ui/banner.ts","../../src/ui/progress.ts","../../src/ui/index.ts","../../src/stages/environment/analyzer.ts","../../src/stages/environment/interviewer.ts","../../src/stages/environment/generator.ts","../../src/stages/environment/installer.ts","../../src/utils/platform.ts","../../src/stages/environment/provisioners/mcp.ts","../../src/stages/environment/provisioners/registry.ts","../../src/stages/environment/provisioners/claude-commands.ts","../../src/stages/environment/doctor.ts","../../src/stages/environment/index.ts","../../src/core/detector.ts","../../src/stages/evaluation/prompts/analyze.ts","../../src/stages/evaluation/analyzer.ts","../../src/core/types/stage.ts","../../src/core/types/scoring.ts","../../src/core/types/index.ts","../../src/stages/evaluation/scorer.ts","../../src/stages/evaluation/reporter.ts","../../src/utils/shell-cd.ts","../../src/utils/claude-settings.ts","../../src/stages/evaluation/cache.ts","../../src/cli/commands/evaluate.cmd.ts","../../src/cli/commands/env.cmd.ts","../../src/cli/commands/init.cmd.ts","../../src/cli/commands/add.cmd.ts","../../src/cli/commands/check.cmd.ts","../../src/cli/commands/status.cmd.ts","../../src/cli/commands/help.cmd.ts","../../src/stages/design/openspec.ts","../../src/stages/design/omc.ts","../../src/cli/commands/design.cmd.ts","../../src/stages/validation/runner.ts","../../src/stages/validation/harness.ts","../../src/cli/commands/validate.cmd.ts","../../src/cli/commands/test.cmd.ts","../../src/cli/commands/grade.cmd.ts","../../src/pipeline/context.ts","../../src/stages/design/index.ts","../../src/stages/execution/index.ts","../../src/stages/validation/index.ts","../../src/stages/evaluation/index.ts","../../src/pipeline/index.ts","../../src/cli/commands/pipeline.cmd.ts","../../src/cli/commands/run.cmd.ts","../../src/cli/commands/remove.cmd.ts","../../src/core/errors.ts","../../src/cli/commands/upgrade.cmd.ts","../../src/cli/commands/savetoken.cmd.ts","../../src/cli/commands/wakeup.cmd.ts","../../src/cli/index.ts","../../src/cli/deprecation.ts","../../bin/pai.ts"],"sourcesContent":["import chalk from 'chalk';\n\n/**\n * Professional color palette — low fatigue, high clarity\n */\nexport const colors = {\n accent: chalk.hex('#7B93DB'),\n success: chalk.hex('#6BCB77'),\n warn: chalk.hex('#E2B340'),\n err: chalk.hex('#E06C75'),\n dim: chalk.gray,\n bold: chalk.bold.white,\n muted: chalk.dim,\n};\n\nconst c = colors;\n\nexport function info(msg: string): void {\n console.log(c.dim(` · ${msg}`));\n}\n\nexport function success(msg: string): void {\n console.log(c.success(` ✓ ${msg}`));\n}\n\nexport function warn(msg: string): void {\n console.log(c.warn(` ! ${msg}`));\n}\n\nexport function error(msg: string): void {\n console.log(c.err(` ✗ ${msg}`));\n}\n\nexport function section(title: string): void {\n console.log('');\n console.log(c.accent(` ${title}`));\n console.log(c.dim(' ' + '─'.repeat(38)));\n}\n\nexport function plain(msg: string): void {\n console.log(msg);\n}\n\nexport function step(num: number, total: number, title: string): void {\n console.log('');\n console.log(c.accent(` Step ${num}/${total}`) + ` ${c.bold(title)}`);\n console.log('');\n}\n\nexport function hint(msg: string): void {\n console.log(c.dim(` ${msg}`));\n}\n","import path from 'node:path';\nimport { createRequire } from 'node:module';\nimport fs from 'fs-extra';\nimport type { PaiConfig, Mode, LegacyMode } from './types/index.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nconst CONFIG_DIR = '.pai';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * 레거시 모드값(`mockup`)을 현재 Mode 타입으로 정규화.\n * - `mockup` → `prototype` (자동 매핑)\n * - 이미 Mode인 경우 그대로 반환\n * - 알 수 없는 값은 `prototype`으로 fallback (안전 기본값)\n */\nexport function normalizeMode(value: unknown): Mode {\n if (value === 'prototype' || value === 'poc' || value === 'production') return value;\n if (value === 'mockup') return 'prototype';\n return 'prototype';\n}\n\nexport async function loadConfig(cwd: string): Promise<PaiConfig | null> {\n const configPath = path.join(cwd, CONFIG_DIR, CONFIG_FILE);\n if (!(await fs.pathExists(configPath))) return null;\n\n const raw = (await fs.readJson(configPath)) as PaiConfig & { mode: Mode | LegacyMode };\n return {\n ...raw,\n mode: normalizeMode(raw.mode),\n };\n}\n\nexport async function saveConfig(cwd: string, config: PaiConfig): Promise<void> {\n const configDir = path.join(cwd, CONFIG_DIR);\n await fs.ensureDir(configDir);\n await fs.writeJson(path.join(configDir, CONFIG_FILE), config, { spaces: 2 });\n}\n\nexport function createDefaultConfig(projectName: string, mode: Mode | LegacyMode): PaiConfig {\n return {\n version: pkg.version,\n mode: normalizeMode(mode),\n projectName,\n installedAt: new Date().toISOString(),\n plugins: [],\n };\n}\n","/**\n * `pai` 인자 없이 실행 시 표시되는 환영 화면.\n *\n * 설치 직후 사용자가 \"다음에 뭘 해야 하나?\"에 즉시 답을 찾도록\n * 핵심 3가지 시작 경로(처음/기존/도움)를 제시한다.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { colors as c } from '../../ui/logger.js';\nimport { loadConfig } from '../../core/config.js';\n\nconst require = createRequire(import.meta.url);\n// Path relative to bundled dist/cli/index.js or dist/bin/pai.js\nconst pkg = require('../../package.json') as { version: string };\n\nexport async function welcomeCommand(cwd: string): Promise<void> {\n // 현재 디렉토리가 이미 PAI 프로젝트인지 감지\n const paiConfig = await loadConfig(cwd);\n const inPaiProject = paiConfig !== null;\n const hasGit = fs.existsSync(path.join(cwd, '.git'));\n const hasPackageJson = fs.existsSync(path.join(cwd, 'package.json'));\n\n console.log('');\n console.log(c.accent(' ╭────────────────────────────────────╮'));\n console.log(c.accent(` │ 🔧 PAI Zero v${pkg.version.padEnd(22)}│`));\n console.log(c.accent(' │ Plugin AI for ProjectZero │'));\n console.log(c.accent(' ╰────────────────────────────────────╯'));\n console.log('');\n\n if (inPaiProject) {\n // ── 이미 PAI 프로젝트 안 ─────────────────────────\n console.log(c.dim(' 현재 PAI 프로젝트가 감지되었습니다'));\n console.log(c.dim(` ─ 모드: ${paiConfig!.mode}`));\n console.log(c.dim(` ─ 플러그인: ${paiConfig!.plugins.length}개 설치됨`));\n console.log('');\n console.log(c.accent(' 바로 쓸 수 있는 명령어'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai status'.padEnd(18)} ${c.dim('설치된 플러그인 확인')}`);\n console.log(` ${c.success('●')} ${'pai grade'.padEnd(18)} ${c.dim('AI 개발 준비도 평가 (6카테고리)')}`);\n console.log(` ${c.success('●')} ${'pai add'.padEnd(18)} ${c.dim('플러그인 추가 · 모드 승격 (prototype→poc→production)')}`);\n console.log(` ${c.success('●')} ${'pai design'.padEnd(18)} ${c.dim('PRD/OMC 설계 관리')}`);\n console.log(` ${c.success('●')} ${'pai test'.padEnd(18)} ${c.dim('테스트 + 하네스 검증')}`);\n console.log(` ${c.success('●')} ${'pai check'.padEnd(18)} ${c.dim('환경 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 목록: ') + c.accent('pai help'));\n } else if (hasGit || hasPackageJson) {\n // ── 기존 코드베이스 ──────────────────────────────\n console.log(c.dim(' 기존 프로젝트가 감지되었습니다 (PAI 미설치)'));\n console.log('');\n console.log(c.accent(' 시작하기'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('▸')} ${'pai init'.padEnd(18)} ${c.dim('이 프로젝트에 PAI 적용 (자동 진단 포함)')}`);\n console.log(` ${c.success('▸')} ${'pai check'.padEnd(18)}${c.dim('환경부터 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 목록: ') + c.accent('pai help'));\n } else {\n // ── 빈 디렉토리 / 신규 설치 직후 ─────────────────\n console.log(c.accent(' 처음이신가요?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('▸')} ${'pai init <프로젝트명>'.padEnd(24)}${c.dim('새 프로젝트 시작')}`);\n console.log('');\n console.log(c.accent(' 이미 PAI 프로젝트에 있다면?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai status'.padEnd(18)} ${c.dim('설치된 플러그인 확인')}`);\n console.log(` ${c.success('●')} ${'pai grade'.padEnd(18)} ${c.dim('AI 개발 준비도 평가')}`);\n console.log(` ${c.success('●')} ${'pai add'.padEnd(18)} ${c.dim('플러그인 추가 (모드 승격)')}`);\n console.log('');\n console.log(c.accent(' 문제가 있나요?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai check'.padEnd(18)} ${c.dim('Node / Git / Claude Code / OMC 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 명령어: ') + c.accent('pai help'));\n }\n\n console.log('');\n console.log(c.dim(' 문서: https://github.com/SoInKyu/pai'));\n console.log('');\n}\n","import { colors } from './logger.js';\n\nexport function printBanner(): void {\n const c = colors;\n console.log('');\n console.log(c.accent(' PAI Zero'));\n console.log(c.dim(' Plugin AI for ProjectZero'));\n console.log(c.dim(' ─────────────────────────'));\n console.log('');\n}\n\n/**\n * `pai init` 실행 시 출력되는 대형 글자 아트.\n * \"Welcome PAI!\" ASCII banner.\n */\nexport function printWelcomeBanner(): void {\n const c = colors;\n // ANSI Shadow style — 'Welcome PAI!'\n const art = [\n \" __ __ _ ____ _ ___ _ \",\n \" \\\\ \\\\ / /__| | ___ ___ _ __ ___ ___ | _ \\\\ / \\\\ |_ _|| |\",\n \" \\\\ \\\\ /\\\\ / / _ \\\\ |/ __/ _ \\\\| '_ ` _ \\\\ / _ \\\\ | |_) |/ _ \\\\ | | | |\",\n \" \\\\ V V / __/ | (_| (_) | | | | | | __/ | __// ___ \\\\ | | |_|\",\n \" \\\\_/\\\\_/ \\\\___|_|\\\\___\\\\___/|_| |_| |_|\\\\___| |_| /_/ \\\\_|___|(_)\",\n ];\n console.log('');\n for (const line of art) {\n console.log(c.accent(line));\n }\n console.log('');\n console.log(c.dim(' Plugin AI for ProjectZero'));\n console.log(c.dim(' ─────────────────────────────────────────────────────────────────'));\n console.log('');\n}\n","/**\n * Progress — ora 기반 스피너 + 파일명 스크롤 애니메이션\n */\nimport ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n spinner: 'dots12',\n color: 'white',\n }).start();\n}\n\nexport async function withSpinner<T>(text: string, fn: () => Promise<T>): Promise<T> {\n const spinner = createSpinner(text);\n try {\n const result = await fn();\n spinner.succeed(text.replace(/중\\.\\.\\.$/u, '완료'));\n return result;\n } catch (err) {\n spinner.fail(text.replace(/중\\.\\.\\.$/u, '실패'));\n throw err;\n }\n}\n\n/**\n * 파일명이 슈슉 스크롤되는 스피너\n * 스피너 텍스트 옆에 현재 파일명이 갱신됨\n */\nexport async function withFileSpinner<T>(\n label: string,\n files: string[],\n fn: () => Promise<T>,\n): Promise<T> {\n const spinner = ora({\n spinner: 'dots12',\n color: 'white',\n }).start();\n\n // Start file name scrolling\n let fileIdx = 0;\n const interval = setInterval(() => {\n if (fileIdx < files.length) {\n const file = files[fileIdx]!;\n spinner.text = `${label} ${chalk.gray(file)}`;\n fileIdx++;\n } else {\n fileIdx = 0; // loop\n }\n }, 500);\n\n try {\n const result = await fn();\n clearInterval(interval);\n spinner.succeed(label.replace(/중\\.\\.\\.$/u, '완료'));\n return result;\n } catch (err) {\n clearInterval(interval);\n spinner.fail(label.replace(/중\\.\\.\\.$/u, '실패'));\n throw err;\n }\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function progressBar(current: number, total: number, width = 30): string {\n const ratio = Math.min(current / total, 1);\n const filled = Math.round(width * ratio);\n const empty = width - filled;\n const bar = chalk.hex('#7B93DB')('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n const pct = Math.round(ratio * 100);\n return `${bar} ${pct}%`;\n}\n","export { info, success, warn, error, section, plain, step, hint, colors } from './logger.js';\nexport { printBanner, printWelcomeBanner } from './banner.js';\nexport { createSpinner, withSpinner, withFileSpinner, sleep, progressBar } from './progress.js';\n","/**\n * Environment Analyzer — roboco-cli에서 내재화\n * 프로젝트 스택, 구조, 기존 설정, Git 정보를 병렬 분석\n */\nimport { readdir, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { AnalysisResult, StackInfo, RepoStructure, ExistingConfig, GitInfo } from '../../core/types/index.js';\n\nexport async function analyzeProject(targetPath: string): Promise<AnalysisResult> {\n try {\n await access(targetPath);\n } catch {\n throw new Error(`Directory not found: ${targetPath}`);\n }\n\n const [stack, structure, existingConfig, git] = await Promise.all([\n detectStack(targetPath),\n scanStructure(targetPath),\n checkExistingConfig(targetPath),\n getGitInfo(targetPath),\n ]);\n\n return { stack, structure, existingConfig, git };\n}\n\nasync function detectStack(cwd: string): Promise<StackInfo> {\n const info: StackInfo = {\n languages: [],\n frameworks: [],\n packageManager: null,\n hasTypeScript: false,\n };\n\n if (await fs.pathExists(join(cwd, 'package.json'))) {\n info.languages.push('JavaScript');\n info.packageManager = 'npm';\n\n try {\n const pkg = await fs.readJson(join(cwd, 'package.json'));\n const allDeps: Record<string, string> = {\n ...(pkg.dependencies ?? {}),\n ...(pkg.devDependencies ?? {}),\n };\n\n if (allDeps['typescript'] || (await fs.pathExists(join(cwd, 'tsconfig.json')))) {\n info.hasTypeScript = true;\n info.languages.push('TypeScript');\n }\n\n const frameworkMap: Record<string, string> = {\n react: 'React',\n vue: 'Vue',\n next: 'Next.js',\n nuxt: 'Nuxt',\n express: 'Express',\n fastify: 'Fastify',\n nestjs: 'NestJS',\n svelte: 'Svelte',\n angular: 'Angular',\n };\n\n for (const [dep, name] of Object.entries(frameworkMap)) {\n if (allDeps[dep] || allDeps[`@${dep}/core`]) {\n info.frameworks.push(name);\n }\n }\n } catch {\n // ignore parse errors\n }\n\n if (await fs.pathExists(join(cwd, 'pnpm-lock.yaml'))) info.packageManager = 'pnpm';\n else if (await fs.pathExists(join(cwd, 'yarn.lock'))) info.packageManager = 'yarn';\n else if (await fs.pathExists(join(cwd, 'bun.lockb'))) info.packageManager = 'bun';\n }\n\n if (\n (await fs.pathExists(join(cwd, 'pyproject.toml'))) ||\n (await fs.pathExists(join(cwd, 'requirements.txt')))\n ) {\n info.languages.push('Python');\n }\n if (await fs.pathExists(join(cwd, 'go.mod'))) info.languages.push('Go');\n if (await fs.pathExists(join(cwd, 'Cargo.toml'))) info.languages.push('Rust');\n if (\n (await fs.pathExists(join(cwd, 'pom.xml'))) ||\n (await fs.pathExists(join(cwd, 'build.gradle')))\n ) {\n info.languages.push('Java');\n }\n\n return info;\n}\n\nasync function scanStructure(cwd: string): Promise<RepoStructure> {\n const entries = await readdir(cwd, { withFileTypes: true });\n const rootFiles = entries.filter((e) => e.isFile()).map((e) => e.name);\n const rootDirs = entries\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => e.name);\n\n const sourceCandidates = ['src', 'lib', 'app', 'source'];\n const sourceDir = sourceCandidates.find((d) => rootDirs.includes(d)) ?? null;\n\n const testCandidates = ['test', 'tests', '__tests__', 'spec'];\n const testDir = testCandidates.find((d) => rootDirs.includes(d)) ?? null;\n\n const isMonorepo = rootDirs.includes('packages') || rootDirs.includes('apps');\n\n return { rootFiles, rootDirs, sourceDir, testDir, isMonorepo };\n}\n\nasync function checkExistingConfig(cwd: string): Promise<ExistingConfig> {\n const [hasClaudeMd, hasClaudeDir, hasPaiDir, hasOpenSpec, hasOmc] = await Promise.all([\n fs.pathExists(join(cwd, 'CLAUDE.md')),\n fs.pathExists(join(cwd, '.claude')),\n fs.pathExists(join(cwd, '.pai')),\n fs.pathExists(join(cwd, 'docs', 'openspec.md')).then((r) =>\n r ? r : fs.pathExists(join(cwd, 'openspec.md')),\n ),\n fs.pathExists(join(cwd, '.pai', 'omc.md')),\n ]);\n\n let claudeSettings: Record<string, unknown> | null = null;\n try {\n if (await fs.pathExists(join(cwd, '.claude', 'settings.json'))) {\n claudeSettings = await fs.readJson(join(cwd, '.claude', 'settings.json'));\n }\n } catch {\n // ignore\n }\n\n const claudeSkills = await listDirNames(join(cwd, '.claude', 'skills'));\n const claudeCommands = await listDirNames(join(cwd, '.claude', 'commands'));\n\n return {\n hasClaudeMd,\n hasClaudeDir,\n hasPaiDir,\n hasOpenSpec,\n hasOmc,\n claudeSettings,\n claudeSkills,\n claudeCommands,\n };\n}\n\nasync function listDirNames(dirPath: string): Promise<string[]> {\n try {\n const entries = await readdir(dirPath, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nasync function getGitInfo(cwd: string): Promise<GitInfo> {\n const isGitRepo = await fs.pathExists(join(cwd, '.git'));\n if (!isGitRepo) {\n return { isGitRepo: false, remoteUrl: null, repoName: null, currentBranch: null };\n }\n\n const { execa } = await import('execa');\n\n async function gitCmd(args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execa('git', args, { cwd, timeout: 5000 });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n const [remoteUrl, currentBranch] = await Promise.all([\n gitCmd(['remote', 'get-url', 'origin']),\n gitCmd(['branch', '--show-current']),\n ]);\n\n let repoName: string | null = null;\n if (remoteUrl) {\n const match = remoteUrl.match(/\\/([^/]+?)(?:\\.git)?$/);\n repoName = match?.[1] ?? null;\n }\n\n return { isGitRepo, remoteUrl, repoName, currentBranch };\n}\n","/**\n * Interviewer — AI → Interactive → Auto 폴백 체인\n * SDK 미설치 시 Interactive/Auto로 자연스럽게 동작\n *\n * v0.6.0: 비개발자 친화적 UX — 단계적 안내, 심플한 선택지\n */\nimport type { AnalysisResult, Mode } from '../../core/types/index.js';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\nimport { normalizeMode } from '../../core/config.js';\n\nexport interface InterviewResult {\n mode: Mode;\n projectName: string;\n authMethods: string[];\n customAuth?: { clientId: string; clientSecret: string };\n extraTools: string[]; // vercel, supabase, gstack, harness, mcp\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n setupDomains: {\n claudeEnv: boolean;\n processDocs: boolean;\n cicd: boolean;\n };\n tools: {\n omc: boolean;\n openspec: boolean;\n githubMcp: boolean;\n harness: boolean;\n };\n autoGenerated: boolean;\n}\n\nexport async function runInterview(\n analysis: AnalysisResult,\n cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n // Try AI interview first (if SDK available)\n try {\n return await aiInterview(analysis, cwd, projectName);\n } catch {\n // Fall through to interactive\n }\n\n return interactiveInterview(analysis, cwd, projectName);\n}\n\nasync function aiInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n // Dynamic import — fails if SDK not installed\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n\n ui.info('AI 인터뷰 모드로 시작합니다...');\n\n const prompt = buildAiPrompt(analysis);\n let resultJson = '';\n\n for await (const message of query({\n prompt,\n options: {\n maxTurns: 10,\n systemPrompt: `You are PAI, an AI assistant that helps set up vibe coding environments.\nAnalyze the repository and ask the user targeted questions about project level (prototype/poc/production), authentication, and domain.\n- prototype: quick idea validation, UI mockup, concept demo\n- poc: PoC web development, working demo with basic features\n- production: operational service with tests, QA, deployment, monitoring\nOutput your final recommendation as a JSON code block with this schema:\n\\`\\`\\`json\n{\n \"mode\": \"prototype\" | \"poc\" | \"production\",\n \"projectName\": string,\n \"authMethods\": string[],\n \"setupDomains\": { \"claudeEnv\": true, \"processDocs\": boolean, \"cicd\": boolean },\n \"tools\": { \"omc\": true, \"openspec\": boolean, \"githubMcp\": boolean, \"harness\": boolean }\n}\n\\`\\`\\``,\n allowedTools: [],\n permissionMode: 'plan',\n },\n })) {\n if ('result' in message) {\n resultJson = message.result as string;\n }\n }\n\n return parseAiResult(resultJson, analysis, projectName);\n}\n\nfunction buildAiPrompt(analysis: AnalysisResult): string {\n return [\n 'I want to set up a PAI vibe coding environment.',\n '',\n 'Repository analysis:',\n `- Languages: ${analysis.stack.languages.join(', ') || 'None detected'}`,\n `- Frameworks: ${analysis.stack.frameworks.join(', ') || 'None'}`,\n `- Package manager: ${analysis.stack.packageManager ?? 'None'}`,\n `- TypeScript: ${analysis.stack.hasTypeScript ? 'Yes' : 'No'}`,\n `- Git: ${analysis.git.isGitRepo ? 'Yes' : 'No'}`,\n `- Remote: ${analysis.git.remoteUrl ?? 'None'}`,\n `- Monorepo: ${analysis.structure.isMonorepo ? 'Yes' : 'No'}`,\n `- CLAUDE.md: ${analysis.existingConfig.hasClaudeMd ? 'Yes' : 'No'}`,\n '',\n 'Please ask me about the project purpose and provide your recommendation.',\n ].join('\\n');\n}\n\nfunction parseAiResult(\n result: string,\n analysis: AnalysisResult,\n projectName: string,\n): InterviewResult {\n const jsonMatch = result.match(/```json\\s*([\\s\\S]*?)```/);\n if (jsonMatch?.[1]) {\n try {\n const parsed = JSON.parse(jsonMatch[1]) as Partial<InterviewResult>;\n return {\n mode: normalizeMode(parsed.mode),\n projectName,\n authMethods: parsed.authMethods ?? [],\n extraTools: parsed.extraTools ?? [],\n setupDomains: {\n claudeEnv: true,\n processDocs: parsed.setupDomains?.processDocs ?? true,\n cicd: parsed.setupDomains?.cicd ?? analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: parsed.tools?.openspec ?? true,\n githubMcp: parsed.tools?.githubMcp ?? false,\n harness: parsed.tools?.harness ?? false,\n },\n autoGenerated: false,\n };\n } catch {\n // Fall through\n }\n }\n\n ui.warn('AI 응답을 파싱할 수 없습니다. Interactive 모드로 전환합니다.');\n throw new Error('AI parse failed');\n}\n\nasync function interactiveInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n\n // ── Step 1/3: 프로젝트 수준 ─────────────────────\n ui.step(1, 3, '프로젝트 수준을 선택해주세요');\n ui.hint('선택에 따라 설치되는 플러그인 세트가 달라집니다.');\n console.log('');\n\n const { mode } = await inquirer.prompt([{\n type: 'list',\n name: 'mode',\n message: '어떤 수준의 프로젝트인가요?',\n choices: [\n {\n name: `🧪 prototype ${c.dim('─ 빠른 검증 (아이디어·UI 목업·컨셉 시연)')}`,\n value: 'prototype',\n },\n {\n name: `🔬 poc ${c.dim('─ PoC 웹개발 (동작 데모·기본 기능 구현)')}`,\n value: 'poc',\n },\n {\n name: `🏭 production ${c.dim('─ 운영 서비스 (테스트·QA·배포·모니터링)')}`,\n value: 'production',\n },\n ],\n }]);\n\n // 선택된 모드에 설치될 플러그인 미리보기\n console.log('');\n console.log(c.dim(' 이 수준에 설치될 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n const matrix: Record<string, string[]> = {\n prototype: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)'],\n poc: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)', 'OMC (객체모델)', 'Vercel 배포 (선택)'],\n production: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)', 'OMC (객체모델)', 'gstack (테스트)', 'Harness (검증)', 'Vercel 배포 (선택)', 'Supabase DB (선택)'],\n };\n for (const item of matrix[mode as string] ?? []) {\n console.log(` ${c.success('✓')} ${item}`);\n }\n\n // ── Step 2/3: 로그인 ────────────────────────────\n ui.step(2, 3, '로그인 기능');\n ui.hint('나중에 추가할 수도 있습니다.');\n console.log('');\n\n const { needAuth } = await inquirer.prompt([{\n type: 'list',\n name: 'needAuth',\n message: '로그인 기능이 필요한가요?',\n choices: [\n { name: '지금은 필요 없어요', value: false },\n { name: '네, 설정할게요', value: true },\n ],\n }]);\n\n let authMethods: string[] = [];\n let customAuth: InterviewResult['customAuth'];\n\n if (needAuth) {\n console.log('');\n ui.hint('Space로 선택 · 선택 후 Enter로 완료');\n const Separator = (inquirer as unknown as { Separator: new (s?: string) => unknown }).Separator;\n const { auths } = await inquirer.prompt([{\n type: 'checkbox',\n name: 'auths',\n message: '사용할 로그인 방식:',\n choices: [\n { name: 'Google 로그인', value: 'google' },\n { name: 'Kakao 로그인', value: 'kakao' },\n { name: 'Naver 로그인', value: 'naver' },\n { name: `사내 인증 ${c.dim('(OAuth2)')}`, value: 'custom' },\n new Separator('─────────────────────────'),\n { name: chalk.green('↵ 선택 완료'), value: '__done__' },\n ],\n validate: (answer: string[]) => {\n const items = answer.filter(a => a !== '__done__');\n if (items.length === 0) return 'Space로 최소 1개를 선택해주세요.';\n return true;\n },\n }]);\n authMethods = (auths as string[]).filter(a => a !== '__done__');\n\n if (authMethods.includes('custom')) {\n console.log('');\n const { registerNow } = await inquirer.prompt([{\n type: 'list',\n name: 'registerNow',\n message: 'OAuth2 인증 키를 지금 등록하시겠습니까?',\n choices: [\n { name: '지금 등록하기', value: true },\n { name: `나중에 등록하기 ${c.dim('─ .env.local에 빈 값으로 생성')}`, value: false },\n ],\n }]);\n\n if (registerNow) {\n ui.hint('사내 OAuth2 인증 정보를 입력해주세요.');\n customAuth = await inquirer.prompt([\n { type: 'input', name: 'clientId', message: 'Client ID:' },\n { type: 'password', name: 'clientSecret', message: 'Client Secret:', mask: '*' },\n ]);\n }\n }\n }\n\n // ── 모드별 추가 도구 ─────────────────────────────\n let extraTools: string[] = [];\n\n // PoC 이상: OMC 객체모델 자동 포함\n if (mode === 'poc' || mode === 'production') {\n extraTools.push('omc');\n }\n\n // PoC 이상: Vercel 배포 옵션\n if (mode === 'poc' || mode === 'production') {\n console.log('');\n const { hosting } = await inquirer.prompt([{\n type: 'list',\n name: 'hosting',\n message: '배포 환경:',\n choices: [\n { name: `Vercel ${c.dim('─ 자동 배포 (Preview + Production)')}`, value: 'vercel' },\n { name: `다른 서비스 사용 ${c.dim('─ AWS, GCP, Netlify 등)')}`, value: 'other' },\n { name: `나중에 정하기 ${c.dim('─ 배포 설정 없이 시작')}`, value: 'skip' },\n ],\n }]);\n if (hosting === 'vercel') extraTools.push('vercel');\n }\n\n // Production: DB + 테스트/검증 도구 자동 포함\n if (mode === 'production') {\n console.log('');\n const { database } = await inquirer.prompt([{\n type: 'list',\n name: 'database',\n message: '데이터베이스:',\n choices: [\n { name: `Supabase ${c.dim('─ PostgreSQL + Auth + Storage')}`, value: 'supabase' },\n { name: `다른 서비스 사용 ${c.dim('─ PlanetScale, Neon, Firebase 등')}`, value: 'other' },\n { name: `나중에 정하기 ${c.dim('─ DB 설정 없이 시작')}`, value: 'skip' },\n ],\n }]);\n if (database === 'supabase') extraTools.push('supabase');\n extraTools.push('gstack', 'harness');\n }\n\n // ── MCP 서버 기능 필요 여부 ──────────────────────\n let mcp: InterviewResult['mcp'];\n console.log('');\n const { mcpNeed } = await inquirer.prompt([{\n type: 'list',\n name: 'mcpNeed',\n message: 'MCP(Model Context Protocol) 서버 기능이 필요하신가요?',\n choices: [\n { name: `필요하다 ${c.dim('─ AI가 호출할 커스텀 도구/리소스/프롬프트 제공')}`, value: 'yes' },\n { name: '필요하지 않다', value: 'no' },\n ],\n default: 'yes',\n }]);\n const mcpDev = mcpNeed === 'yes';\n\n if (mcpDev) {\n console.log('');\n const hasSupabase = extraTools.includes('supabase');\n const typeChoices: Array<{ name: string; value: string }> = [\n { name: `Tools 서버 (개인용) ${c.dim('─ AI가 호출할 기능 제공')}`, value: 'tools' },\n ];\n if (hasSupabase) {\n typeChoices.push({\n name: `Tools 서버 (공개 배포) ${c.dim('─ API 키 + 관리화면 + 사용량 추적')}`,\n value: 'tools-public',\n });\n }\n typeChoices.push(\n { name: `Resources 서버 ${c.dim('─ AI가 읽을 컨텍스트 제공')}`, value: 'resources' },\n { name: `Prompts 서버 ${c.dim('─ 재사용 프롬프트 템플릿')}`, value: 'prompts' },\n { name: `All-in-one ${c.dim('─ 모두 포함')}`, value: 'all' },\n );\n\n const { mcpType } = await inquirer.prompt([{\n type: 'list',\n name: 'mcpType',\n message: 'MCP 서버 유형:',\n choices: typeChoices,\n }]);\n\n const { mcpName } = await inquirer.prompt([{\n type: 'input',\n name: 'mcpName',\n message: 'MCP 서버 이름:',\n default: `${projectName}-mcp`,\n validate: (v: string) => /^[a-z0-9][a-z0-9-]*$/.test(v.trim())\n ? true\n : '영문 소문자, 숫자, 하이픈(-)만 사용할 수 있습니다.',\n }]);\n\n mcp = {\n enabled: true,\n type: mcpType as 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all',\n name: mcpName.trim(),\n };\n extraTools.push('mcp');\n }\n\n // ── Step 3/3: 설치 확인 ─────────────────────────\n ui.step(3, 3, '설치 확인');\n console.log('');\n console.log(c.dim(' 설치될 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} GitHub 프로젝트 구조`);\n console.log(` ${c.success('✓')} PRD 설계 템플릿`);\n console.log(` ${c.success('✓')} AI 도메인 모델`);\n console.log(` ${c.success('✓')} AI 컨텍스트 (CLAUDE.md)`);\n console.log(` ${c.success('✓')} /pai 슬래시 커맨드`);\n\n if (extraTools.length > 0) {\n console.log('');\n if (extraTools.includes('vercel')) console.log(` ${c.accent('+')} Vercel 자동 배포`);\n if (extraTools.includes('supabase')) console.log(` ${c.accent('+')} Supabase 데이터베이스`);\n if (extraTools.includes('gstack')) console.log(` ${c.accent('+')} gstack 테스트 자동화`);\n if (extraTools.includes('harness')) console.log(` ${c.accent('+')} Harness 품질 검증`);\n if (extraTools.includes('mcp') && mcp) {\n console.log(` ${c.accent('+')} MCP 서버 (${mcp.name}, ${mcp.type})`);\n }\n }\n\n if (authMethods.length > 0) {\n console.log('');\n console.log(` ${c.accent('+')} 로그인: ${authMethods.join(', ')}`);\n }\n\n console.log('');\n const { proceed } = await inquirer.prompt([{\n type: 'confirm',\n name: 'proceed',\n message: '이대로 설치를 시작할까요?',\n default: true,\n }]);\n\n if (!proceed) {\n ui.info('취소되었습니다. 다시 시작하려면: npx pai-zero init');\n process.exit(0);\n }\n\n const hasWebFramework = analysis.stack.frameworks.some((f) =>\n ['React', 'Vue', 'Next.js', 'Nuxt', 'Svelte', 'Angular'].includes(f),\n );\n\n return {\n mode,\n projectName,\n authMethods,\n customAuth,\n extraTools,\n mcp,\n setupDomains: {\n claudeEnv: true,\n processDocs: true,\n cicd: analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: true,\n githubMcp: analysis.git.remoteUrl?.includes('github.com') ?? false,\n harness: extraTools.includes('harness') || hasWebFramework,\n },\n autoGenerated: false,\n };\n}\n\nexport function autoInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): InterviewResult {\n const hasWebFramework = analysis.stack.frameworks.some((f) =>\n ['React', 'Vue', 'Next.js', 'Nuxt', 'Svelte', 'Angular'].includes(f),\n );\n\n return {\n mode: hasWebFramework ? 'production' : 'prototype',\n projectName,\n authMethods: [],\n extraTools: hasWebFramework ? ['omc', 'vercel', 'supabase', 'gstack', 'harness'] : [],\n setupDomains: {\n claudeEnv: true,\n processDocs: true,\n cicd: analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: true,\n githubMcp: analysis.git.remoteUrl?.includes('github.com') ?? false,\n harness: hasWebFramework || analysis.structure.isMonorepo,\n },\n autoGenerated: true,\n };\n}\n","/**\n * Generator — CLAUDE.md, settings.json, 프로세스 문서 생성\n * roboco-cli의 generator 패턴을 PAI에 맞게 재구성\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { AnalysisResult } from '../../core/types/index.js';\nimport type { InterviewResult } from './interviewer.js';\nimport * as ui from '../../ui/index.js';\n\ninterface FileOperation {\n path: string;\n content: string;\n description: string;\n overwrite?: boolean;\n}\n\nexport async function generateFiles(\n cwd: string,\n analysis: AnalysisResult,\n interview: InterviewResult,\n): Promise<string[]> {\n const files: FileOperation[] = [];\n\n // CLAUDE.md\n files.push(generateClaudeMd(cwd, analysis, interview));\n\n // .claude/settings.json\n files.push(generateClaudeSettings(cwd, analysis));\n\n // Process docs (optional)\n if (interview.setupDomains.processDocs) {\n files.push(...generateProcessDocs(cwd));\n }\n\n // CI/CD (optional)\n if (interview.setupDomains.cicd) {\n files.push(...generateCicd(cwd, analysis));\n }\n\n const created: string[] = [];\n for (const file of files) {\n if ((await fs.pathExists(file.path)) && !file.overwrite) {\n continue;\n }\n await fs.ensureDir(join(file.path, '..'));\n await fs.writeFile(file.path, file.content, 'utf8');\n created.push(file.path);\n }\n\n return created;\n}\n\nfunction relativePath(base: string, full: string): string {\n return full.startsWith(base) ? full.slice(base.length + 1) : full;\n}\n\nfunction generateClaudeMd(\n cwd: string,\n analysis: AnalysisResult,\n interview: InterviewResult,\n): FileOperation {\n const stack = [...analysis.stack.languages, ...analysis.stack.frameworks].join(', ') || 'Not detected';\n const tools = Object.entries(interview.tools)\n .filter(([, v]) => v)\n .map(([k]) => k)\n .join(', ');\n\n const content = `# ${interview.projectName}\n\n## Project Overview\n\nDescribe your project here.\n\n<pai>\n## PAI Configuration\n\nThis project uses PAI (Plugin-based AI) for structured AI development.\n\n### Pipeline: 설계-실행-검증-평가-환경\n\n1. **Environment** — 프로젝트 환경 구성 (이 단계)\n2. **Design** — OpenSpec/OMC 기반 설계\n3. **Execution** — AI 코드 생성\n4. **Validation** — gstack 테스트 / harness 검증\n5. **Evaluation** — 품질 평가 (6카테고리)\n\n### Stack\n- **Languages**: ${stack}\n- **Tools**: ${tools}\n- **Mode**: ${interview.mode}\n- **Config**: \\`.pai/config.json\\`\n\nRun \\`pai env status\\` to check setup, \\`pai evaluate\\` for quality scoring.\n\n### Global Rules\n\n- **심층 인터뷰 자동 수행**: 컨텍스트가 부족하거나 모호한 경우, AskUserQuestion 도구를 사용하여 심층 인터뷰를 자동으로 진행합니다. 추측하지 말고 반드시 질문하세요.\n- **Ideation → PRD 파이프라인**: \\`/pai design\\` 실행 시 ideation.md → openspec.md 순서로 심층 인터뷰를 통해 작성합니다.\n- **기술 제약 파악**: 코드 생성 전 기술적 제약 사항을 심층 인터뷰로 확인합니다.\n- **하네스 엔지니어링**: AI 에이전트가 안전하게 작업할 수 있도록 테스트/검증 환경을 구성합니다.\n- **Git 커밋 규칙**: 작업 단위별로 의미 있는 커밋 메시지를 작성합니다.\n\n### Contribution Guide\n\n기여자는 \\`CONTRIBUTING.md\\`를 참고하세요. 이 가이드는 \\`.claude/skills/\\`에 스킬로 등록되어 자동 적용됩니다.\n</pai>\n`;\n\n return {\n path: join(cwd, 'CLAUDE.md'),\n content,\n description: 'CLAUDE.md',\n overwrite: false,\n };\n}\n\nfunction generateClaudeSettings(cwd: string, analysis: AnalysisResult): FileOperation {\n const hooks = generateHooksForStack(analysis.stack.languages);\n\n const settings: Record<string, unknown> = {\n permissions: {\n allow: [\n 'Read',\n 'Write',\n 'Edit',\n 'Glob',\n 'Grep',\n 'Bash(npm run *)',\n 'Bash(git status*)',\n 'Bash(git diff*)',\n 'Bash(git log*)',\n ],\n deny: [\n 'Bash(rm -rf *)',\n 'Bash(git push --force*)',\n 'Bash(git reset --hard*)',\n ],\n },\n ...(Object.keys(hooks).length > 0 ? { hooks } : {}),\n };\n\n // Merge with existing settings\n if (analysis.existingConfig.claudeSettings) {\n const existing = analysis.existingConfig.claudeSettings;\n return {\n path: join(cwd, '.claude', 'settings.json'),\n content: JSON.stringify(deepMergeSettings(existing, settings), null, 2) + '\\n',\n description: '.claude/settings.json (merged)',\n overwrite: true,\n };\n }\n\n return {\n path: join(cwd, '.claude', 'settings.json'),\n content: JSON.stringify(settings, null, 2) + '\\n',\n description: '.claude/settings.json',\n overwrite: false,\n };\n}\n\nfunction deepMergeSettings(\n existing: Record<string, unknown>,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...existing };\n\n for (const [key, value] of Object.entries(defaults)) {\n if (key === 'permissions' && result[key] && typeof result[key] === 'object') {\n const ep = result[key] as Record<string, unknown>;\n const dp = value as Record<string, unknown>;\n result[key] = {\n allow: [...new Set([\n ...((ep['allow'] as string[]) ?? []),\n ...((dp['allow'] as string[]) ?? []),\n ])],\n deny: [...new Set([\n ...((ep['deny'] as string[]) ?? []),\n ...((dp['deny'] as string[]) ?? []),\n ])],\n };\n } else if (!(key in result)) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction generateHooksForStack(languages: string[]): Record<string, unknown> {\n const hooks: Record<string, unknown> = {};\n\n if (languages.includes('TypeScript') || languages.includes('JavaScript')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'npx prettier --write $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n } else if (languages.includes('Python')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'black $CLAUDE_FILE_PATH 2>/dev/null || ruff format $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n } else if (languages.includes('Go')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'gofmt -w $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n }\n\n return hooks;\n}\n\nfunction generateProcessDocs(cwd: string): FileOperation[] {\n const stages = [\n { file: '01-intent.md', title: 'Intent', desc: '구현하고자 하는 것을 명확히 정의합니다.' },\n { file: '02-requirements.md', title: 'Requirements', desc: '상세 요구사항을 정의합니다.' },\n { file: '03-research.md', title: 'Research', desc: '접근 방법과 도구를 조사합니다.' },\n { file: '04-plan.md', title: 'Plan', desc: '단계별 구현 계획을 수립합니다.' },\n { file: '05-implement.md', title: 'Implement', desc: 'AI와 함께 솔루션을 구축합니다.' },\n ];\n\n return stages.map(({ file, title, desc }) => ({\n path: join(cwd, 'docs', 'vibe-coding', file),\n content: `# Stage: ${title}\\n\\n${desc}\\n\\n## Checklist\\n\\n- [ ] \\n`,\n description: `Process: ${title}`,\n }));\n}\n\nfunction generateCicd(cwd: string, analysis: AnalysisResult): FileOperation[] {\n const files: FileOperation[] = [];\n\n files.push({\n path: join(cwd, '.github', 'workflows', 'vibe-coding-check.yml'),\n content: `name: Vibe Coding Check\n\non:\n pull_request:\n branches: [main, dev]\n\njobs:\n check:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Check CLAUDE.md exists\n run: test -f CLAUDE.md\n - name: Check .claude directory\n run: test -d .claude\n`,\n description: 'GitHub Actions workflow',\n });\n\n const lintCmd = getLintCommand(analysis.stack.languages);\n files.push({\n path: join(cwd, '.husky', 'pre-commit'),\n content: `${lintCmd}\\n`,\n description: 'Pre-commit hook',\n });\n\n return files;\n}\n\nfunction getLintCommand(languages: string[]): string {\n if (languages.includes('TypeScript') || languages.includes('JavaScript')) return 'npx lint-staged';\n if (languages.includes('Python')) return 'ruff check --fix . && ruff format .';\n if (languages.includes('Go')) return 'gofmt -l . && go vet ./...';\n if (languages.includes('Rust')) return 'cargo fmt --check && cargo clippy';\n return 'echo \"No lint configured\"';\n}\n","/**\n * Installer — OMC는 npx로 직접 설치 (3회 재시도), 나머지는 안내\n */\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { createSpinner } from '../../ui/progress.js';\n\nexport interface InstallResult {\n tool: string;\n success: boolean;\n message: string;\n}\n\nexport interface ToolSelection {\n omc: boolean;\n openspec: boolean;\n githubMcp: boolean;\n harness: boolean;\n}\n\nexport async function installTools(tools: ToolSelection, _cwd: string): Promise<InstallResult[]> {\n // OMC는 Claude Code 시작 시 옵션으로 통합됨 — init 중 설치하지 않음\n return [];\n}\n\nasync function installOMCWithRetry(cwd: string): Promise<InstallResult> {\n const fsLib = (await import('fs-extra')).default;\n const { join } = await import('node:path');\n const { homedir } = await import('node:os');\n\n // Check if already installed\n const indicators = [\n join(cwd, '.omc'),\n join(homedir(), '.claude', 'plugins', 'oh-my-claudecode'),\n ];\n for (const path of indicators) {\n if (await fsLib.pathExists(path)) {\n ui.success('OMC 이미 설치됨');\n return { tool: 'oh-my-claudecode', success: true, message: 'OMC 이미 설치됨' };\n }\n }\n\n const spinner = createSpinner('OMC (oh-my-claudecode) 설치 중...');\n\n try {\n const { execa } = await import('execa');\n await execa('npx', ['-y', 'github:Yeachan-Heo/oh-my-claudecode', 'install'], { timeout: 120000, cwd });\n spinner.succeed('OMC 설치 완료');\n return { tool: 'oh-my-claudecode', success: true, message: 'oh-my-claudecode install 완료' };\n } catch {\n spinner.warn('OMC 자동 설치를 건너뜁니다');\n ui.hint('Claude Code 터미널에서 설치: npx oh-my-claudecode install');\n return { tool: 'oh-my-claudecode', success: false, message: '수동 설치: npx oh-my-claudecode install' };\n }\n}\n\nexport function printInstallReport(results: InstallResult[], tools: ToolSelection): void {\n const manualSteps: Array<{ label: string; command: string }> = [];\n\n if (tools.githubMcp) {\n manualSteps.push({\n label: 'GitHub MCP 서버 (선택사항)',\n command: 'claude mcp add github -- npx -y @modelcontextprotocol/server-github',\n });\n }\n\n if (manualSteps.length === 0) return;\n\n console.log('');\n ui.info('아래 항목은 Claude Code 터미널에서 직접 설치하세요:');\n console.log('');\n\n for (const step of manualSteps) {\n console.log(` ${chalk.gray(step.label)}`);\n console.log(` $ ${chalk.white(step.command)}`);\n console.log('');\n }\n}\n","import os from 'node:os';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { execFileSync } from 'node:child_process';\n\nexport const isWindows = process.platform === 'win32';\nexport const isMac = process.platform === 'darwin';\n\nexport interface WindowsDiagnostic {\n issues: Array<{ title: string; fix: string }>;\n warnings: Array<{ title: string; hint?: string }>;\n}\n\nexport function diagnoseWindowsEnv(): WindowsDiagnostic {\n const issues: WindowsDiagnostic['issues'] = [];\n const warnings: WindowsDiagnostic['warnings'] = [];\n\n if (!isWindows) return { issues, warnings };\n\n warnings.push({\n title: 'PowerShell 실행 정책',\n hint: '문제 발생 시: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser',\n });\n\n const pathEnv = process.env['PATH'] || process.env['Path'] || '';\n if (!pathEnv.toLowerCase().includes('node')) {\n issues.push({\n title: 'Node.js PATH 미등록',\n fix: 'Node.js를 재설치하거나 환경변수 PATH에 Node.js 경로를 추가하세요.',\n });\n }\n\n const home = process.env['HOME'] || process.env['USERPROFILE'];\n if (!home) {\n issues.push({\n title: 'HOME 환경변수 없음',\n fix: 'PowerShell에서: $env:HOME = $env:USERPROFILE 실행 후 재시도',\n });\n }\n\n return { issues, warnings };\n}\n\nexport function writeEnvFile(filePath: string, entries: Record<string, string>): void {\n const content = Object.entries(entries)\n .map(([k, v]) => `${k}=${v}`)\n .join('\\n');\n fs.writeFileSync(filePath, content + '\\n', { encoding: 'utf8' });\n}\n\nexport function getPlatformInfo() {\n return {\n isWindows,\n isMac,\n isLinux: !isWindows && !isMac,\n shell: isWindows ? 'PowerShell' : (process.env['SHELL'] || 'bash'),\n home: process.env['HOME'] || process.env['USERPROFILE'] || os.homedir(),\n nodeVersion: process.version,\n };\n}\n\n/**\n * 플랫폼별 쉘 RC 파일 경로\n * macOS/Linux: ~/.zshrc 또는 ~/.bashrc\n * Windows: PowerShell $PROFILE (Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1)\n */\nexport function getShellRcPath(): string {\n const home = os.homedir();\n if (isWindows) {\n // PowerShell 7+ profile path\n const ps7 = path.join(home, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1');\n // Windows PowerShell 5.x profile path\n const ps5 = path.join(home, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');\n // Prefer PS7, fallback to PS5\n if (fs.existsSync(path.dirname(ps7))) return ps7;\n return ps5;\n }\n const shell = process.env['SHELL'] || '';\n return shell.includes('zsh')\n ? path.join(home, '.zshrc')\n : path.join(home, '.bashrc');\n}\n\n/**\n * 플랫폼별 서브쉘 스폰 — cwd에서 새 쉘을 시작\n * macOS/Linux: zsh/bash -l\n * Windows: powershell.exe -NoExit\n */\nexport function spawnSubshell(cwd: string): void {\n try {\n if (isWindows) {\n execFileSync('powershell.exe', ['-NoExit', '-Command', `Set-Location '${cwd}'`], {\n stdio: 'inherit',\n cwd,\n });\n } else {\n const shell = process.env['SHELL'] || '/bin/zsh';\n execFileSync(shell, ['-l'], { stdio: 'inherit', cwd });\n }\n } catch {\n // user exited shell\n }\n}\n\n/**\n * 플랫폼별 YOLO alias 텍스트\n */\nexport function getYoloAliasLine(): string {\n if (isWindows) {\n return \"function claude-yolo { claude --dangerously-skip-permissions @args }\";\n }\n return \"alias claude-yolo='claude --dangerously-skip-permissions'\";\n}\n\n/**\n * 플랫폼별 YOLO alias 감지\n */\nexport function hasYoloAlias(rcContent: string): boolean {\n return rcContent.includes('claude-yolo') || rcContent.includes('dangerously-skip-permissions');\n}\n\n/**\n * Windows 파일시스템 금지 문자를 `-`로 치환.\n * 백업 파일명(ISO8601 `:` 포함) 등 크로스플랫폼 파일명 생성에 사용.\n *\n * 금지 문자: \\ / : * ? \" < > |\n */\nexport function sanitizeFilenameForWindows(name: string): string {\n return name.replace(/[\\\\/:*?\"<>|]/g, '-');\n}\n","/**\n * MCP Server Provisioner\n * MCP(Model Context Protocol) 서버 스캐폴딩 생성\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { ProvisionerContext } from './registry.js';\n\ntype McpType = 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n\nexport async function provisionMcp(ctx: ProvisionerContext): Promise<void> {\n const mcp = (ctx as ProvisionerContext & {\n mcp?: { enabled: boolean; type: McpType; name: string };\n }).mcp;\n\n if (!mcp?.enabled) return;\n\n const mcpDir = join(ctx.cwd, 'mcp-server');\n await fs.ensureDir(mcpDir);\n await fs.ensureDir(join(mcpDir, 'src'));\n await fs.ensureDir(join(mcpDir, 'tests'));\n\n // package.json\n const isPublicDeps = mcp.type === 'tools-public';\n const pkgJson = {\n name: mcp.name,\n version: '0.1.0',\n description: `MCP server for ${ctx.projectName}`,\n type: 'module',\n main: 'dist/index.js',\n bin: { [mcp.name]: './dist/index.js' },\n scripts: {\n build: 'tsc',\n dev: 'tsc --watch',\n test: 'vitest run',\n start: 'node dist/index.js',\n },\n dependencies: {\n '@modelcontextprotocol/sdk': '^1.0.0',\n ...(isPublicDeps ? { '@supabase/supabase-js': '^2.48.0' } : {}),\n },\n devDependencies: {\n typescript: '^5.7.0',\n '@types/node': '^20.17.0',\n vitest: '^3.0.0',\n },\n };\n const pkgPath = join(mcpDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n await fs.writeJson(pkgPath, pkgJson, { spaces: 2 });\n }\n\n // tsconfig.json\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n outDir: './dist',\n rootDir: './src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n declaration: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist', 'tests'],\n };\n const tsPath = join(mcpDir, 'tsconfig.json');\n if (!(await fs.pathExists(tsPath))) {\n await fs.writeJson(tsPath, tsconfig, { spaces: 2 });\n }\n\n // src/index.ts\n const indexPath = join(mcpDir, 'src', 'index.ts');\n if (!(await fs.pathExists(indexPath))) {\n await fs.writeFile(indexPath, buildIndexTs(mcp), 'utf8');\n }\n\n // Type-specific files\n const isTools = mcp.type === 'tools' || mcp.type === 'tools-public' || mcp.type === 'all';\n const isPublic = mcp.type === 'tools-public';\n\n if (isTools) {\n const toolsPath = join(mcpDir, 'src', 'tools.ts');\n if (!(await fs.pathExists(toolsPath))) {\n await fs.writeFile(toolsPath, isPublic ? TOOLS_PUBLIC_TEMPLATE : TOOLS_TEMPLATE, 'utf8');\n }\n }\n\n // Public 배포 — auth 미들웨어, Supabase 마이그레이션, 대시보드\n if (isPublic) {\n const authPath = join(mcpDir, 'src', 'auth.ts');\n if (!(await fs.pathExists(authPath))) {\n await fs.writeFile(authPath, AUTH_MIDDLEWARE_TEMPLATE, 'utf8');\n }\n\n const rateLimitPath = join(mcpDir, 'src', 'rate-limit.ts');\n if (!(await fs.pathExists(rateLimitPath))) {\n await fs.writeFile(rateLimitPath, RATE_LIMIT_TEMPLATE, 'utf8');\n }\n\n // Supabase 마이그레이션\n const migDir = join(ctx.cwd, 'supabase', 'migrations');\n await fs.ensureDir(migDir);\n const migPath = join(migDir, '20260101_mcp_keys_and_usage.sql');\n if (!(await fs.pathExists(migPath))) {\n await fs.writeFile(migPath, SUPABASE_MIGRATION, 'utf8');\n }\n\n // 관리 대시보드 (Next.js App Router)\n const dashDir = join(ctx.cwd, 'src', 'app', 'dashboard');\n await fs.ensureDir(join(dashDir, 'keys'));\n await fs.ensureDir(join(dashDir, 'usage'));\n\n const dashLayoutPath = join(dashDir, 'layout.tsx');\n if (!(await fs.pathExists(dashLayoutPath))) {\n await fs.writeFile(dashLayoutPath, DASHBOARD_LAYOUT, 'utf8');\n }\n const dashPagePath = join(dashDir, 'page.tsx');\n if (!(await fs.pathExists(dashPagePath))) {\n await fs.writeFile(dashPagePath, DASHBOARD_PAGE, 'utf8');\n }\n const keysPagePath = join(dashDir, 'keys', 'page.tsx');\n if (!(await fs.pathExists(keysPagePath))) {\n await fs.writeFile(keysPagePath, KEYS_PAGE, 'utf8');\n }\n const usagePagePath = join(dashDir, 'usage', 'page.tsx');\n if (!(await fs.pathExists(usagePagePath))) {\n await fs.writeFile(usagePagePath, USAGE_PAGE, 'utf8');\n }\n\n // API 라우트\n const apiKeysDir = join(ctx.cwd, 'src', 'app', 'api', 'keys');\n await fs.ensureDir(apiKeysDir);\n const keysRoutePath = join(apiKeysDir, 'route.ts');\n if (!(await fs.pathExists(keysRoutePath))) {\n await fs.writeFile(keysRoutePath, KEYS_API_ROUTE, 'utf8');\n }\n }\n if (mcp.type === 'resources' || mcp.type === 'all') {\n const resPath = join(mcpDir, 'src', 'resources.ts');\n if (!(await fs.pathExists(resPath))) {\n await fs.writeFile(resPath, RESOURCES_TEMPLATE, 'utf8');\n }\n }\n if (mcp.type === 'prompts' || mcp.type === 'all') {\n const promptsPath = join(mcpDir, 'src', 'prompts.ts');\n if (!(await fs.pathExists(promptsPath))) {\n await fs.writeFile(promptsPath, PROMPTS_TEMPLATE, 'utf8');\n }\n }\n\n // tests/server.test.ts\n const testPath = join(mcpDir, 'tests', 'server.test.ts');\n if (!(await fs.pathExists(testPath))) {\n await fs.writeFile(testPath, TEST_TEMPLATE, 'utf8');\n }\n\n // README.md\n const readmePath = join(mcpDir, 'README.md');\n if (!(await fs.pathExists(readmePath))) {\n await fs.writeFile(readmePath, buildReadme(mcp), 'utf8');\n }\n\n // docs/openspec.md에 MCP 섹션 추가 (있으면 append)\n const openspecPath = join(ctx.cwd, 'docs', 'openspec.md');\n if (await fs.pathExists(openspecPath)) {\n const existing = await fs.readFile(openspecPath, 'utf8');\n if (!existing.includes('## MCP 서버')) {\n const section = buildOpenSpecMcpSection(mcp);\n await fs.appendFile(openspecPath, `\\n\\n${section}\\n`);\n }\n }\n\n // .mcp.json (프로젝트 루트)\n const mcpJsonPath = join(ctx.cwd, '.mcp.json');\n const mcpJson = (await fs.pathExists(mcpJsonPath))\n ? await fs.readJson(mcpJsonPath)\n : { mcpServers: {} };\n mcpJson.mcpServers[mcp.name] = {\n command: 'node',\n args: ['./mcp-server/dist/index.js'],\n };\n await fs.writeJson(mcpJsonPath, mcpJson, { spaces: 2 });\n\n // .gitignore (MCP 서버 디렉토리)\n const gitignorePath = join(mcpDir, '.gitignore');\n if (!(await fs.pathExists(gitignorePath))) {\n await fs.writeFile(gitignorePath, 'node_modules/\\ndist/\\n*.log\\n', 'utf8');\n }\n}\n\nfunction buildIndexTs(mcp: { type: McpType; name: string }): string {\n const imports: string[] = [];\n const registrations: string[] = [];\n\n if (mcp.type === 'tools' || mcp.type === 'all') {\n imports.push(\"import { registerTools } from './tools.js';\");\n registrations.push(' registerTools(server);');\n }\n if (mcp.type === 'resources' || mcp.type === 'all') {\n imports.push(\"import { registerResources } from './resources.js';\");\n registrations.push(' registerResources(server);');\n }\n if (mcp.type === 'prompts' || mcp.type === 'all') {\n imports.push(\"import { registerPrompts } from './prompts.js';\");\n registrations.push(' registerPrompts(server);');\n }\n\n return `#!/usr/bin/env node\n/**\n * ${mcp.name} — MCP Server\n * Generated by PAI\n */\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n${imports.join('\\n')}\n\nasync function main() {\n const server = new Server(\n {\n name: '${mcp.name}',\n version: '0.1.0',\n },\n {\n capabilities: {\n${mcp.type === 'tools' || mcp.type === 'all' ? ' tools: {},' : ''}\n${mcp.type === 'resources' || mcp.type === 'all' ? ' resources: {},' : ''}\n${mcp.type === 'prompts' || mcp.type === 'all' ? ' prompts: {},' : ''}\n },\n },\n );\n\n${registrations.join('\\n')}\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('${mcp.name} MCP server running on stdio');\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n`;\n}\n\nconst TOOLS_PUBLIC_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { verifyApiKey } from './auth.js';\nimport { checkRateLimit, logUsage } from './rate-limit.js';\n\nexport function registerTools(server: Server): void {\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'hello',\n description: '인증된 도구 호출 — API 키 필요',\n inputSchema: {\n type: 'object',\n properties: {\n apiKey: { type: 'string', description: 'API 키' },\n name: { type: 'string', description: '인사할 대상' },\n },\n required: ['apiKey', 'name'],\n },\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const { apiKey, ...params } = (args as { apiKey?: string; [k: string]: unknown }) ?? {};\n\n if (!apiKey) throw new Error('API key required');\n const user = await verifyApiKey(apiKey);\n if (!user) throw new Error('Invalid API key');\n\n const allowed = await checkRateLimit(user.id);\n if (!allowed) throw new Error('Rate limit exceeded');\n\n if (name === 'hello') {\n const target = (params as { name?: string })?.name ?? 'world';\n const result = { content: [{ type: 'text' as const, text: \\`Hello, \\${target}!\\` }] };\n await logUsage(user.id, name);\n return result;\n }\n\n throw new Error(\\`Unknown tool: \\${name}\\`);\n });\n}\n`;\n\nconst AUTH_MIDDLEWARE_TEMPLATE = `import { createClient } from '@supabase/supabase-js';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nexport interface AuthUser {\n id: string;\n email: string;\n}\n\n/**\n * API 키 검증 — Supabase api_keys 테이블에서 조회\n */\nexport async function verifyApiKey(apiKey: string): Promise<AuthUser | null> {\n const { data, error } = await supabase\n .from('api_keys')\n .select('user_id, revoked_at, users(id, email)')\n .eq('key_hash', await hashKey(apiKey))\n .single();\n\n if (error || !data || data.revoked_at) return null;\n\n // 마지막 사용 시간 업데이트\n await supabase\n .from('api_keys')\n .update({ last_used_at: new Date().toISOString() })\n .eq('key_hash', await hashKey(apiKey));\n\n const users = (data as unknown as { users: { id: string; email: string } }).users;\n return { id: users.id, email: users.email };\n}\n\nasync function hashKey(key: string): Promise<string> {\n const crypto = await import('node:crypto');\n return crypto.createHash('sha256').update(key).digest('hex');\n}\n\nexport async function generateApiKey(): Promise<{ key: string; hash: string }> {\n const crypto = await import('node:crypto');\n const key = \\`mcp_\\${crypto.randomBytes(32).toString('hex')}\\`;\n const hash = crypto.createHash('sha256').update(key).digest('hex');\n return { key, hash };\n}\n`;\n\nconst RATE_LIMIT_TEMPLATE = `import { createClient } from '@supabase/supabase-js';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nconst RATE_LIMIT_PER_HOUR = 100;\n\n/**\n * Rate limit 체크 — 최근 1시간 내 호출 수 확인\n */\nexport async function checkRateLimit(userId: string): Promise<boolean> {\n const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();\n const { count } = await supabase\n .from('usage_logs')\n .select('*', { count: 'exact', head: true })\n .eq('user_id', userId)\n .gte('created_at', oneHourAgo);\n\n return (count ?? 0) < RATE_LIMIT_PER_HOUR;\n}\n\n/**\n * 사용량 기록 — usage_logs 테이블에 저장\n */\nexport async function logUsage(userId: string, toolName: string): Promise<void> {\n await supabase.from('usage_logs').insert({\n user_id: userId,\n tool_name: toolName,\n created_at: new Date().toISOString(),\n });\n}\n`;\n\nconst SUPABASE_MIGRATION = `-- MCP Tools 공개 배포 — API 키 관리 + 사용량 추적\n-- Generated by PAI\n\n-- 사용자 테이블 (Supabase Auth와 연동)\ncreate table if not exists public.users (\n id uuid primary key references auth.users(id) on delete cascade,\n email text not null unique,\n created_at timestamptz default now()\n);\n\n-- API 키 테이블\ncreate table if not exists public.api_keys (\n id uuid primary key default gen_random_uuid(),\n user_id uuid not null references public.users(id) on delete cascade,\n key_hash text not null unique,\n name text not null,\n created_at timestamptz default now(),\n last_used_at timestamptz,\n revoked_at timestamptz\n);\n\ncreate index if not exists api_keys_user_id_idx on public.api_keys(user_id);\ncreate index if not exists api_keys_key_hash_idx on public.api_keys(key_hash);\n\n-- 사용량 로그 테이블\ncreate table if not exists public.usage_logs (\n id bigserial primary key,\n user_id uuid not null references public.users(id) on delete cascade,\n tool_name text not null,\n created_at timestamptz default now()\n);\n\ncreate index if not exists usage_logs_user_id_idx on public.usage_logs(user_id);\ncreate index if not exists usage_logs_created_at_idx on public.usage_logs(created_at);\n\n-- RLS (Row Level Security)\nalter table public.users enable row level security;\nalter table public.api_keys enable row level security;\nalter table public.usage_logs enable row level security;\n\ncreate policy \"Users can view own data\" on public.users\n for select using (auth.uid() = id);\n\ncreate policy \"Users can manage own api keys\" on public.api_keys\n for all using (auth.uid() = user_id);\n\ncreate policy \"Users can view own usage\" on public.usage_logs\n for select using (auth.uid() = user_id);\n`;\n\nconst DASHBOARD_LAYOUT = `import Link from 'next/link';\nimport type { ReactNode } from 'react';\n\nexport default function DashboardLayout({ children }: { children: ReactNode }) {\n return (\n <div style={{ display: 'flex', minHeight: '100vh' }}>\n <aside style={{ width: 240, borderRight: '1px solid #eee', padding: 24 }}>\n <h2 style={{ fontSize: 18, marginBottom: 16 }}>MCP 대시보드</h2>\n <nav>\n <Link href=\"/dashboard\" style={{ display: 'block', padding: '8px 0' }}>개요</Link>\n <Link href=\"/dashboard/keys\" style={{ display: 'block', padding: '8px 0' }}>API 키</Link>\n <Link href=\"/dashboard/usage\" style={{ display: 'block', padding: '8px 0' }}>사용량</Link>\n </nav>\n </aside>\n <main style={{ flex: 1, padding: 24 }}>{children}</main>\n </div>\n );\n}\n`;\n\nconst DASHBOARD_PAGE = `export default function DashboardPage() {\n return (\n <div>\n <h1>MCP 대시보드</h1>\n <p>API 키를 발급하고 사용량을 관리하세요.</p>\n <ul>\n <li><a href=\"/dashboard/keys\">API 키 발급</a></li>\n <li><a href=\"/dashboard/usage\">사용량 확인</a></li>\n </ul>\n </div>\n );\n}\n`;\n\nconst KEYS_PAGE = `'use client';\nimport { useEffect, useState } from 'react';\n\ninterface ApiKey {\n id: string;\n name: string;\n created_at: string;\n last_used_at?: string;\n}\n\nexport default function KeysPage() {\n const [keys, setKeys] = useState<ApiKey[]>([]);\n const [newKeyName, setNewKeyName] = useState('');\n const [newKey, setNewKey] = useState<string | null>(null);\n\n useEffect(() => {\n fetch('/api/keys').then(r => r.json()).then(setKeys);\n }, []);\n\n async function create() {\n const res = await fetch('/api/keys', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: newKeyName }),\n });\n const data = await res.json();\n setNewKey(data.key);\n setKeys([...keys, data.apiKey]);\n setNewKeyName('');\n }\n\n async function revoke(id: string) {\n await fetch(\\`/api/keys/\\${id}\\`, { method: 'DELETE' });\n setKeys(keys.filter(k => k.id !== id));\n }\n\n return (\n <div>\n <h1>API 키 관리</h1>\n <div style={{ marginBottom: 24 }}>\n <input\n placeholder=\"키 이름\"\n value={newKeyName}\n onChange={e => setNewKeyName(e.target.value)}\n />\n <button onClick={create}>새 키 발급</button>\n </div>\n {newKey && (\n <div style={{ padding: 16, background: '#fffbe6', marginBottom: 24 }}>\n <strong>새 API 키 (한 번만 표시):</strong>\n <pre>{newKey}</pre>\n </div>\n )}\n <table style={{ width: '100%' }}>\n <thead>\n <tr><th>이름</th><th>생성일</th><th>마지막 사용</th><th></th></tr>\n </thead>\n <tbody>\n {keys.map(k => (\n <tr key={k.id}>\n <td>{k.name}</td>\n <td>{new Date(k.created_at).toLocaleDateString()}</td>\n <td>{k.last_used_at ? new Date(k.last_used_at).toLocaleString() : '—'}</td>\n <td><button onClick={() => revoke(k.id)}>삭제</button></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n`;\n\nconst USAGE_PAGE = `'use client';\nimport { useEffect, useState } from 'react';\n\ninterface UsageLog {\n tool_name: string;\n count: number;\n}\n\nexport default function UsagePage() {\n const [usage, setUsage] = useState<UsageLog[]>([]);\n const [total, setTotal] = useState(0);\n\n useEffect(() => {\n fetch('/api/usage').then(r => r.json()).then(data => {\n setUsage(data.byTool ?? []);\n setTotal(data.total ?? 0);\n });\n }, []);\n\n return (\n <div>\n <h1>사용량</h1>\n <p>최근 30일 총 호출: <strong>{total}</strong></p>\n <table style={{ width: '100%' }}>\n <thead>\n <tr><th>도구</th><th>호출 수</th></tr>\n </thead>\n <tbody>\n {usage.map(u => (\n <tr key={u.tool_name}>\n <td>{u.tool_name}</td>\n <td>{u.count}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n`;\n\nconst KEYS_API_ROUTE = `import { NextResponse } from 'next/server';\nimport { createClient } from '@supabase/supabase-js';\nimport crypto from 'node:crypto';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nexport async function GET() {\n // TODO: 현재 로그인 사용자의 키만 조회 (auth 미들웨어 연동 필요)\n const { data, error } = await supabase\n .from('api_keys')\n .select('id, name, created_at, last_used_at')\n .is('revoked_at', null);\n if (error) return NextResponse.json({ error: error.message }, { status: 500 });\n return NextResponse.json(data);\n}\n\nexport async function POST(request: Request) {\n const { name } = await request.json();\n const key = \\`mcp_\\${crypto.randomBytes(32).toString('hex')}\\`;\n const key_hash = crypto.createHash('sha256').update(key).digest('hex');\n\n // TODO: 현재 로그인 사용자 ID 연동\n const user_id = 'TODO-REPLACE-WITH-AUTH-USER-ID';\n\n const { data, error } = await supabase\n .from('api_keys')\n .insert({ user_id, name, key_hash })\n .select('id, name, created_at')\n .single();\n if (error) return NextResponse.json({ error: error.message }, { status: 500 });\n\n return NextResponse.json({ apiKey: data, key });\n}\n`;\n\nconst TOOLS_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerTools(server: Server): void {\n // Tool 목록 정의\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'hello',\n description: '테스트용 인사 도구 — 이 템플릿을 수정해서 실제 도구를 구현하세요',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: '인사할 대상' },\n },\n required: ['name'],\n },\n },\n ],\n }));\n\n // Tool 호출 처리\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n if (name === 'hello') {\n const target = (args as { name?: string })?.name ?? 'world';\n return {\n content: [{ type: 'text', text: \\`Hello, \\${target}!\\` }],\n };\n }\n\n throw new Error(\\`Unknown tool: \\${name}\\`);\n });\n}\n`;\n\nconst RESOURCES_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerResources(server: Server): void {\n // Resource 목록 정의\n server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: [\n {\n uri: 'example://sample',\n name: 'Sample Resource',\n description: '예제 리소스 — AI가 읽을 컨텍스트',\n mimeType: 'text/plain',\n },\n ],\n }));\n\n // Resource 읽기\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n\n if (uri === 'example://sample') {\n return {\n contents: [{\n uri,\n mimeType: 'text/plain',\n text: 'This is a sample resource content.',\n }],\n };\n }\n\n throw new Error(\\`Unknown resource: \\${uri}\\`);\n });\n}\n`;\n\nconst PROMPTS_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerPrompts(server: Server): void {\n // Prompt 목록 정의\n server.setRequestHandler(ListPromptsRequestSchema, async () => ({\n prompts: [\n {\n name: 'review-code',\n description: '코드 리뷰 요청 프롬프트',\n arguments: [\n { name: 'code', description: '리뷰할 코드', required: true },\n ],\n },\n ],\n }));\n\n // Prompt 가져오기\n server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n if (name === 'review-code') {\n const code = (args as { code?: string })?.code ?? '';\n return {\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: \\`다음 코드를 리뷰해주세요:\\\\n\\\\n\\${code}\\`,\n },\n }],\n };\n }\n\n throw new Error(\\`Unknown prompt: \\${name}\\`);\n });\n}\n`;\n\nconst TEST_TEMPLATE = `import { describe, it, expect } from 'vitest';\n\ndescribe('MCP Server', () => {\n it('should be tested', () => {\n // TODO: MCP 서버 테스트 작성\n expect(true).toBe(true);\n });\n});\n`;\n\nfunction buildOpenSpecMcpSection(mcp: { name: string; type: McpType }): string {\n const isPublic = mcp.type === 'tools-public';\n const hasTools = mcp.type === 'tools' || mcp.type === 'tools-public' || mcp.type === 'all';\n const hasResources = mcp.type === 'resources' || mcp.type === 'all';\n const hasPrompts = mcp.type === 'prompts' || mcp.type === 'all';\n\n const lines: string[] = [\n '## MCP 서버 (자동 생성됨)',\n '',\n '이 프로젝트는 MCP(Model Context Protocol) 서버를 포함합니다.',\n '`/pai design` 실행 시 아래 표를 심층 인터뷰로 채우세요.',\n '',\n `- **이름**: ${mcp.name}`,\n `- **타입**: ${mcp.type}`,\n ];\n\n if (isPublic) {\n lines.push(\n '- **인프라**: Supabase (api_keys, usage_logs)',\n '- **레이트 리밋**: 100회/시간 (기본값)',\n '- **관리 화면**: `/dashboard/keys`, `/dashboard/usage`',\n );\n }\n\n lines.push('', '### MCP 도구 / 리소스 / 프롬프트 설계');\n\n if (hasTools) {\n lines.push(\n '',\n '#### Tools (AI가 호출할 기능)',\n '',\n '| 도구 이름 | 설명 | 입력 파라미터 | 출력 형식 | 내부 로직 |',\n '|----------|------|-------------|----------|----------|',\n '| TODO | TODO | TODO | TODO | TODO |',\n );\n }\n\n if (hasResources) {\n lines.push(\n '',\n '#### Resources (AI가 읽을 컨텍스트)',\n '',\n '| URI | 이름 | 설명 | MIME 타입 |',\n '|-----|------|------|----------|',\n '| TODO | TODO | TODO | TODO |',\n );\n }\n\n if (hasPrompts) {\n lines.push(\n '',\n '#### Prompts (재사용 프롬프트 템플릿)',\n '',\n '| 이름 | 설명 | 인자 |',\n '|------|------|------|',\n '| TODO | TODO | TODO |',\n );\n }\n\n if (isPublic) {\n lines.push(\n '',\n '### 공개 배포 설정',\n '',\n '- **레이트 리밋**: TODO (기본 100회/시간)',\n '- **요금제**: 무료 (Stripe 제외)',\n '- **API 키 정책**: 사용자당 복수 키 허용',\n );\n }\n\n return lines.join('\\n');\n}\n\nfunction buildReadme(mcp: { name: string; type: McpType }): string {\n const isPublic = mcp.type === 'tools-public';\n return `# ${mcp.name} — MCP Server\n\nPAI가 생성한 MCP(Model Context Protocol) 서버입니다.\n\n## 타입: ${mcp.type}\n\n${mcp.type === 'tools' || mcp.type === 'all' ? '- **Tools**: AI가 호출할 기능 제공 (src/tools.ts)' : ''}\n${isPublic ? '- **Tools (공개 배포)**: API 키 검증 + 레이트 리밋 + 사용량 추적 (src/tools.ts, auth.ts, rate-limit.ts)' : ''}\n${mcp.type === 'resources' || mcp.type === 'all' ? '- **Resources**: AI가 읽을 컨텍스트 제공 (src/resources.ts)' : ''}\n${mcp.type === 'prompts' || mcp.type === 'all' ? '- **Prompts**: 재사용 프롬프트 템플릿 (src/prompts.ts)' : ''}\n\n${isPublic ? `\n## 공개 배포 설정\n\n1. **Supabase 마이그레이션 실행**\n \\\\\\`\\\\\\`\\\\\\`bash\n supabase db push\n \\\\\\`\\\\\\`\\\\\\`\n (\\\\\\`supabase/migrations/\\\\\\` 참고)\n\n2. **환경 변수 설정 (.env.local)**\n \\\\\\`\\\\\\`\\\\\\`\n NEXT_PUBLIC_SUPABASE_URL=...\n NEXT_PUBLIC_SUPABASE_ANON_KEY=...\n SUPABASE_SERVICE_ROLE_KEY=...\n \\\\\\`\\\\\\`\\\\\\`\n\n3. **대시보드 접속**\n \\\\\\`\\\\\\`\\\\\\`bash\n npm run dev\n # → http://localhost:3000/dashboard\n \\\\\\`\\\\\\`\\\\\\`\n - API 키 발급 및 관리\n - 사용량 확인\n` : ''}\n\n## 개발\n\n\\`\\`\\`bash\ncd mcp-server\nnpm install\nnpm run build\nnpm test\n\\`\\`\\`\n\n## Claude Code 연결\n\n프로젝트 루트의 \\`.mcp.json\\` 파일에 이미 등록되어 있습니다.\nClaude Code를 재시작하면 자동으로 MCP 서버가 로드됩니다.\n\n수동 등록:\n\\`\\`\\`bash\nclaude mcp add ${mcp.name} -- node ./mcp-server/dist/index.js\n\\`\\`\\`\n\n## 다음 단계\n\n1. \\`npm install\\` — 의존성 설치\n2. \\`npm run build\\` — TypeScript 컴파일\n3. \\`src/\\` 디렉토리의 템플릿을 실제 로직으로 수정\n4. Claude Code 재시작 → MCP 서버 사용\n\n## 참고 문서\n\n- [MCP 공식 문서](https://modelcontextprotocol.io/)\n- [SDK 문서](https://github.com/modelcontextprotocol/sdk)\n`;\n}\n","/**\n * Provisioner Registry — 조용한 파일 생성 (로그 없음, 스피너가 대신 표시)\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport { writeEnvFile } from '../../../utils/platform.js';\nimport type { Mode } from '../../../core/types/index.js';\n\nexport interface ProvisionerContext {\n cwd: string;\n projectName: string;\n mode: Mode;\n envEntries: Record<string, string>;\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n}\n\nexport type Provisioner = (ctx: ProvisionerContext) => Promise<void>;\n\nasync function provisionGitHub(ctx: ProvisionerContext): Promise<void> {\n const gitDir = join(ctx.cwd, '.git');\n if (!(await fs.pathExists(gitDir))) {\n await fs.ensureDir(join(ctx.cwd, '.github', 'workflows'));\n try {\n const { execa } = await import('execa');\n await execa('git', ['init'], { cwd: ctx.cwd });\n await execa('git', ['checkout', '-b', 'main'], { cwd: ctx.cwd });\n } catch {\n // silent — git not available\n }\n }\n\n const dirs = ['src', 'docs', 'tests', 'public', '.pai'];\n await Promise.all(dirs.map((d) => fs.ensureDir(join(ctx.cwd, d))));\n\n // handoff.md 생성\n const handoffPath = join(ctx.cwd, 'handoff.md');\n if (!(await fs.pathExists(handoffPath))) {\n const now = new Date().toLocaleString('ko-KR');\n await fs.writeFile(handoffPath, [\n `# Handoff — ${ctx.projectName}`,\n '',\n `> 마지막 업데이트: ${now}`,\n '',\n '## 진행 중',\n '- [ ] Ideation 문서 작성 — 심층 인터뷰를 통해 아이디어를 구체화 (담당: PAI > Design)',\n '',\n '## 다음 단계',\n '- [ ] Ideation 기반 PRD 작성 — 심층 인터뷰로 맥락/기술 제약 보강',\n '- [ ] 하네스 엔지니어링 구성 확인 — 에이전트 작업 환경 검증',\n '- [ ] AI 코드 생성 시작',\n '',\n '## 완료',\n `- [x] 프로젝트 초기화 (${now}) (담당: PAI > Environment)`,\n '',\n '## 작업 파이프라인',\n '```',\n '1. /pai design → Ideation 심층 인터뷰 → docs/ideation.md 생성',\n '2. /pai design → PRD 심층 인터뷰 → docs/openspec.md 작성',\n '3. /pai design → 기술 제약 심층 인터뷰 → 하네스 엔지니어링 확인',\n '4. AI 코드 생성 → 검증 → 평가',\n '```',\n '',\n '## 메모',\n `- 모드: ${ctx.mode}`,\n '- 컨텍스트가 부족하면 AI가 자동으로 심층 인터뷰를 진행합니다',\n ].join('\\n') + '\\n');\n }\n\n // CONTRIBUTING.md 생성\n const contribPath = join(ctx.cwd, 'CONTRIBUTING.md');\n if (!(await fs.pathExists(contribPath))) {\n await fs.writeFile(contribPath, [\n `# Contributing to ${ctx.projectName}`,\n '',\n '이 프로젝트에 기여해 주셔서 감사합니다.',\n '',\n '## 개발 환경 설정',\n '',\n '```bash',\n 'git clone <repo-url>',\n 'cd ' + ctx.projectName,\n 'npm install',\n '```',\n '',\n '## 브랜치 규칙',\n '',\n '- `main` — 안정 버전',\n '- `feat/<기능명>` — 새 기능 개발',\n '- `fix/<이슈번호>` — 버그 수정',\n '',\n '## 커밋 메시지',\n '',\n '```',\n 'feat: 새 기능 추가',\n 'fix: 버그 수정',\n 'docs: 문서 수정',\n 'refactor: 리팩토링',\n 'test: 테스트 추가/수정',\n '```',\n '',\n '## PR 프로세스',\n '',\n '1. 브랜치 생성 → 작업 → 커밋',\n '2. `npm test` 로 테스트 통과 확인',\n '3. PR 생성 — 변경 사항 요약 작성',\n '4. 리뷰 후 머지',\n '',\n '## AI 협업 규칙',\n '',\n '- `CLAUDE.md` 를 읽고 프로젝트 컨텍스트를 파악하세요',\n '- `/pai evaluate` 로 AI 준비도를 확인하세요',\n '- 컨텍스트가 부족하면 추측하지 말고 질문하세요',\n '',\n ].join('\\n') + '\\n');\n }\n\n // CONTRIBUTING 스킬 등록\n const contribSkillDir = join(ctx.cwd, '.claude', 'skills');\n await fs.ensureDir(contribSkillDir);\n const contribSkillPath = join(contribSkillDir, 'contributing.md');\n if (!(await fs.pathExists(contribSkillPath))) {\n await fs.writeFile(contribSkillPath, [\n '---',\n 'name: contributing',\n 'description: \"기여자 가이드 — 브랜치 규칙, 커밋 메시지, PR 프로세스 자동 적용\"',\n '---',\n '',\n '# Contributing Guide',\n '',\n '프로젝트 기여 시 `CONTRIBUTING.md`의 규칙을 자동으로 적용합니다.',\n '',\n '## 자동 적용 규칙',\n '',\n '1. **브랜치**: `feat/`, `fix/`, `docs/`, `refactor/`, `test/` 접두사 사용',\n '2. **커밋**: `feat:`, `fix:`, `docs:`, `refactor:`, `test:` 형식',\n '3. **PR**: 변경 사항 요약 필수',\n '4. **테스트**: PR 전 `npm test` 통과 필수',\n '',\n '## 작업 시 확인',\n '',\n '- `CONTRIBUTING.md` 를 읽고 규칙을 따르세요',\n '- 커밋 메시지가 규칙에 맞는지 확인하세요',\n '- PR 생성 시 변경 사항을 요약하세요',\n '',\n ].join('\\n') + '\\n');\n }\n\n const gitignorePath = join(ctx.cwd, '.gitignore');\n if (!(await fs.pathExists(gitignorePath))) {\n await fs.writeFile(gitignorePath, [\n '# Dependencies',\n 'node_modules/',\n '',\n '# Environment',\n '.env',\n '.env.local',\n '.env*.local',\n '',\n '# Build',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '',\n '# Services',\n '.vercel',\n '.supabase',\n '',\n '# OS',\n '.DS_Store',\n 'Thumbs.db',\n '',\n '# IDE',\n '.idea/',\n '.vscode/settings.json',\n '*.swp',\n '*.swo',\n '',\n '# PAI / OMC state',\n '.omc/state/',\n '.omc/sessions/',\n '.omc/logs/',\n '',\n '# Logs',\n '*.log',\n 'npm-debug.log*',\n '',\n '# Windows',\n 'desktop.ini',\n '$RECYCLE.BIN/',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionVercel(ctx: ProvisionerContext): Promise<void> {\n const vercelJson = join(ctx.cwd, 'vercel.json');\n if (!(await fs.pathExists(vercelJson))) {\n await fs.writeJson(vercelJson, {\n version: 2, name: ctx.projectName,\n builds: [{ src: 'src/**', use: '@vercel/static' }],\n }, { spaces: 2 });\n }\n}\n\nasync function provisionSupabase(ctx: ProvisionerContext): Promise<void> {\n const supabaseDir = join(ctx.cwd, 'supabase');\n await fs.ensureDir(supabaseDir);\n const configToml = join(supabaseDir, 'config.toml');\n if (!(await fs.pathExists(configToml))) {\n await fs.writeFile(configToml, '[api]\\nschemas = [\"public\"]\\n[auth]\\nsite_url = \"http://localhost:3000\"\\n');\n }\n ctx.envEntries['NEXT_PUBLIC_SUPABASE_URL'] = 'YOUR_SUPABASE_URL';\n ctx.envEntries['NEXT_PUBLIC_SUPABASE_ANON_KEY'] = 'YOUR_SUPABASE_ANON_KEY';\n}\n\nasync function provisionOpenSpec(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, 'docs'));\n const openspecPath = join(ctx.cwd, 'docs', 'openspec.md');\n if (!(await fs.pathExists(openspecPath))) {\n await fs.writeFile(openspecPath, [\n `# OpenSpec — ${ctx.projectName}`,\n '', '## 1. 목적 (Purpose)', '> 이 서비스는 무엇을 해결하는가?',\n '', '## 2. 사용자 (Users)', '| 역할 | 설명 |', '|------|------|', '| - | - |',\n '', '## 3. 핵심 기능 (Features)', '- [ ] Feature 1',\n '', '## 4. 기술 스택 (Stack)', '- Frontend:', '- Backend:', '- DB:',\n '', '## 5. API 엔드포인트 (Endpoints)',\n '| Method | Path | 설명 |', '|--------|------|------|', '| GET | /api/health | 헬스체크 |',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionOMC(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n const omcPath = join(ctx.cwd, '.pai', 'omc.md');\n if (!(await fs.pathExists(omcPath))) {\n await fs.writeFile(omcPath, [\n `# OMC — Object Model Context (${ctx.projectName})`,\n '', '> AI가 이 프로젝트의 도메인을 이해하기 위한 핵심 객체 모델',\n '', '## 도메인 객체', '', '### User', '```', 'id: string',\n 'email: string', 'role: \"admin\" | \"member\"', '```',\n '', '## 비즈니스 규칙', '- (여기에 핵심 비즈니스 로직을 기술)',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionGstack(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n await fs.writeJson(join(ctx.cwd, '.pai', 'gstack.json'), {\n version: '1.0', testRunner: 'jest',\n coverageThreshold: { global: { lines: 80 } },\n qualityGates: ['lint', 'typecheck', 'test'],\n }, { spaces: 2 });\n}\n\nasync function provisionRoboco(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n const robocoPath = join(ctx.cwd, '.pai', 'roboco.json');\n if (await fs.pathExists(robocoPath)) return;\n await fs.writeJson(robocoPath, {\n version: '1.0',\n checks: ['github', 'vercel', 'supabase', 'openspec', 'omc'],\n reportOutput: 'AI_READINESS_REPORT.md',\n note: 'PAI Zero에 내재화됨. `pai evaluate`로 진단 가능.',\n }, { spaces: 2 });\n}\n\nasync function provisionHarness(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n await fs.writeJson(join(ctx.cwd, '.pai', 'harness.json'), {\n version: '1.0', specFile: 'docs/openspec.md',\n checkOn: ['pre-commit', 'ci'],\n rules: ['spec-implementation-match', 'api-contract-test'],\n }, { spaces: 2 });\n}\n\nasync function provisionMcpWrapper(ctx: ProvisionerContext): Promise<void> {\n const { provisionMcp } = await import('./mcp.js');\n await provisionMcp(ctx);\n}\n\nexport const PROVISIONERS: Record<string, Provisioner> = {\n github: provisionGitHub,\n vercel: provisionVercel,\n supabase: provisionSupabase,\n openspec: provisionOpenSpec,\n omc: provisionOMC,\n gstack: provisionGstack,\n roboco: provisionRoboco,\n harness: provisionHarness,\n mcp: provisionMcpWrapper,\n};\n\nexport async function runProvisioners(\n keys: string[],\n ctx: ProvisionerContext,\n): Promise<Array<{ key: string; success: boolean; error?: string }>> {\n const results: Array<{ key: string; success: boolean; error?: string }> = [];\n\n for (const key of keys) {\n const provisioner = PROVISIONERS[key];\n if (!provisioner) {\n results.push({ key, success: false, error: 'unknown' });\n continue;\n }\n try {\n await provisioner(ctx);\n results.push({ key, success: true });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n results.push({ key, success: false, error: msg });\n }\n }\n\n if (Object.keys(ctx.envEntries).length > 0) {\n writeEnvFile(join(ctx.cwd, '.env.local'), ctx.envEntries);\n }\n\n return results;\n}\n","/**\n * Claude Code 스킬/커맨드 프로비저너\n * 프로젝트의 .claude/ 디렉토리에 PAI 슬래시 커맨드를 설치\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../../ui/index.js';\n\nconst SKILL_CONTENT = `---\nname: pai\ndescription: \"PAI(Plugin-based AI) 빌드 오케스트레이터 — AI 개발을 5단계 파이프라인으로 구조화\"\nargument-hint: \"[init|help|status|check|design|test|grade|add|handoff|savetoken|wakeup]\"\n---\n\n# PAI — Plugin-based AI 빌드 오케스트레이터\n\n사용자가 \\`/pai\\` 또는 \\`/pai <명령>\\`을 입력하면 아래 프로세스를 수행하세요.\n\n## 명령어 라우팅 (v0.11+)\n\n사용자의 입력에 따라 적절한 작업을 수행하세요:\n\n- \\`/pai\\` 또는 \\`/pai help\\` → **안내 모드**: 명령어 목록, 파이프라인 설명, 시작 가이드 표시\n- \\`/pai init\\` → **초기화 모드**: 프로젝트 분석 → 사용자 인터뷰 → 파일 생성\n- \\`/pai status\\` → **상태 확인**: 플러그인 설치 상태 스캔 및 보고\n- \\`/pai check\\` → **환경 점검**: Node.js, Git, Claude Code 환경 점검\n- \\`/pai design\\` → **설계 관리**: OpenSpec/OMC 템플릿 생성 + PRD 완성도 검증\n- \\`/pai test\\` → **테스트·검증**: 테스트 실행 + 하네스(설계↔구현) 검증\n- \\`/pai grade\\` → **품질 평가**: 6카테고리 가중 점수 평가\n- \\`/pai add\\` → **플러그인 추가**: Mockup → Production 확장\n- \\`/pai savetoken\\` → **토큰 절감**: AI API 호출 분석 + 스크립트 대체 + 절감 리포트\n- \\`/pai wakeup\\` → **웨이크업**: Claude Code 세션 자동 시작 + 토큰 윈도우 리셋\n\n### 구 명령어 호환 (v0.13 까지 유지)\n\n\\`/pai info\\` → help, \\`/pai doctor\\` → check, \\`/pai validate\\` → test, \\`/pai evaluate\\` → grade, \\`/pai install\\` → add\n\n각 명령의 상세 지침은 \\`.claude/commands/pai/\\` 디렉토리에 있습니다.\n해당 파일을 읽고 지시에 따라 수행하세요.\n\n## 파이프라인 5단계\n\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n## 핵심 원칙\n\n1. **이미 존재하는 파일은 덮어쓰지 않음** — 건너뛰고 안내\n2. **컨텍스트 격리** — 각 파이프라인 단계는 독립적으로 수행\n3. **사용자 친화적** — 결과를 명확히 보고하고 다음 단계를 안내\n4. **PRD 시작 가능 상태가 목표** — 설치 후 \\`docs/openspec.md\\`로 안내\n\n## 품질 평가 기준 (evaluate)\n\n| 카테고리 | 분류 | 가중치 |\n|---------|------|--------|\n| 테스트 커버리지 | 필수 | 20% |\n| CI/CD | 필수 | 20% |\n| 훅 기반 검증 | 필수 | 20% |\n| 리포지토리 구조 | 선택 | 13.3% |\n| 문서화 수준 | 선택 | 13.3% |\n| 하네스 엔지니어링 | 선택 | 13.4% |\n\n등급: A(90+), B(80+), C(70+), D(50+), F(<50)\n페널티: 필수 카테고리 F등급 시 전체 등급 최대 C로 제한\n`;\n\nconst COMMANDS: Record<string, string> = {\n 'info.md': `---\nname: \"PAI: Info\"\ndescription: \"PAI 안내 — 명령어, 파이프라인, 핵심 파일 설명\"\n---\n\n# PAI 안내\n\n사용자에게 PAI(Plugin-based AI) 시스템을 안내합니다.\n\n## 수행할 작업\n\n아래 내용을 읽기 쉽게 사용자에게 설명하세요:\n\n### PAI란?\nPAI는 AI 개발을 5단계 파이프라인으로 구조화하는 빌드 오케스트레이터입니다.\n\n### 파이프라인 5단계\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n### 사용 가능한 명령어\n| 명령어 | 설명 | 사용 시점 |\n|--------|------|----------|\n| \\`/pai info\\` | PAI 안내 | PAI가 뭔지 알고 싶을 때 |\n| \\`/pai init\\` | 프로젝트 초기화 | 새 프로젝트 시작 시 |\n| \\`/pai status\\` | 상태 확인 | 설치 상태 점검 시 |\n| \\`/pai doctor\\` | 환경 진단 | 환경 문제 점검 시 |\n| \\`/pai design\\` | PRD/OMC 생성 | 설계 문서 관리 시 |\n| \\`/pai validate\\` | 테스트/검증 | 코드 작성 후 |\n| \\`/pai evaluate\\` | 품질 평가 | 준비도 평가 시 |\n| \\`/pai install\\` | 플러그인 추가 | Production 확장 시 |\n\n### 추천 시작 순서\n1. **처음이라면** → \\`/pai init\\`\n2. **PRD 작성** → \\`/pai design\\`\n3. **코드 작성 후** → \\`/pai validate\\`\n4. **품질 점검** → \\`/pai evaluate\\`\n`,\n\n 'init.md': `---\nname: \"PAI: Init\"\ndescription: \"프로젝트 초기화 — 분석, 인터뷰, 환경 파일 생성\"\n---\n\n# PAI 프로젝트 초기화\n\n이 프로젝트에 PAI(Plugin-based AI) 환경을 구축합니다.\n\n## 수행할 작업\n\n### 1단계: 프로젝트 분석\n현재 작업 디렉토리를 분석하세요:\n- \\`package.json\\` 존재 여부 → 언어/프레임워크 감지\n- \\`tsconfig.json\\` → TypeScript 여부\n- \\`.git\\` → Git 초기화 여부\n- \\`.pai/config.json\\` → 이미 PAI 초기화된 프로젝트인지 (있으면 \\`/pai status\\` 안내)\n\n분석 결과를 사용자에게 요약해 주세요.\n\n### 2단계: 사용자 인터뷰\n사용자에게 다음을 질문하세요:\n1. **프로젝트명** (현재 폴더명을 기본값으로 제안)\n2. **프로젝트 목적**: Mockup(프로토타입) vs Production(실서비스)\n3. **인증 방식** (필요 시): Google/Naver/Kakao OAuth2, 사내 인증, 없음\n\n### 3단계: 파일 생성\n사용자 답변에 따라 다음 파일을 생성하세요:\n\n**필수 (Mockup + Production):**\n- \\`docs/openspec.md\\` — PRD 템플릿 (목적/사용자/기능/스택/API)\n- \\`.pai/omc.md\\` — 도메인 객체 모델 템플릿\n- \\`.pai/config.json\\` — PAI 설정\n- \\`CLAUDE.md\\` — AI 컨텍스트\n- \\`.gitignore\\`, \\`src/\\`, \\`docs/\\`, \\`tests/\\` 디렉토리\n\n**Production 추가:**\n- \\`.pai/gstack.json\\` — QA 설정 (커버리지 80%)\n- \\`.pai/harness.json\\` — 검증 설정\n\n### 4단계: 완료 안내\n> 다음 단계: \\`docs/openspec.md\\`를 열어 PRD를 작성하세요.\n> PRD 작성 후: \\`/pai design validate\\`로 완성도를 검증할 수 있습니다.\n\n### 주의사항\n- **이미 존재하는 파일은 덮어쓰지 마세요**\n- **CLAUDE.md가 이미 있으면** \\`<pai>\\` 블록만 추가\n`,\n\n 'status.md': `---\nname: \"PAI: Status\"\ndescription: \"현재 프로젝트의 PAI 플러그인 설치 상태 확인\"\n---\n\n# PAI 프로젝트 상태 확인\n\n## 수행할 작업\n\n다음 파일/디렉토리 존재 여부를 확인하고 상태를 보고하세요:\n\n| 확인 경로 | 플러그인 |\n|-----------|---------|\n| \\`.git\\` 또는 \\`.github\\` | GitHub |\n| \\`vercel.json\\` | Vercel |\n| \\`supabase/\\` | Supabase |\n| \\`docs/openspec.md\\` | OpenSpec |\n| \\`.pai/omc.md\\` | OMC |\n| \\`.pai/gstack.json\\` | gstack |\n| \\`.pai/harness.json\\` | Harness |\n| \\`CLAUDE.md\\` | AI 컨텍스트 |\n| \\`.claude/settings.json\\` | AI 설정 |\n| \\`.pai/config.json\\` | PAI Core |\n\n\\`package.json\\`에서 스택도 감지하세요.\n\n보고 형식:\n\\`\\`\\`\n프로젝트 상태\n─────────────\n스택: TypeScript, React\n모드: production\n\n ✅ GitHub — 설치됨\n ✅ OpenSpec — 설치됨\n ⚠️ gstack — 미설치\n\\`\\`\\`\n`,\n\n 'doctor.md': `---\nname: \"PAI: Doctor\"\ndescription: \"개발 환경 진단 — Node.js, Git, Claude Code 점검\"\n---\n\n# PAI 환경 진단\n\n## 수행할 작업\n\n다음 항목을 점검하세요:\n\n1. **Node.js 버전**: \\`node --version\\` (v20 이상 필요)\n2. **패키지 매니저**: \\`npm --version\\`\n3. **Git 상태**: \\`git --version\\`, \\`git remote -v\\`\n4. **Claude Code 파일**: CLAUDE.md, .claude/settings.json, .claude/skills/ 존재 여부\n5. **PAI 설정**: .pai/config.json 내용 확인\n\n보고 형식:\n\\`\\`\\`\nPAI Doctor — 환경 진단\n══════════════════════\n ✅ Node.js v20.11.0 (>=20 OK)\n ✅ Git 2.43.0\n ⚠️ .claude/settings.json 없음\n → /pai init 으로 생성하세요\n\\`\\`\\`\n`,\n\n 'design.md': `---\nname: \"PAI: Design\"\ndescription: \"Ideation → PRD → 하네스 구성까지 심층 인터뷰 기반 설계\"\n---\n\n# PAI 설계 — 심층 인터뷰 기반 파이프라인\n\n## 인자: $ARGUMENTS\n- 인자 없음 → 전체 파이프라인 (Ideation → PRD → 하네스)\n- \\`ideation\\` → Ideation만 수행\n- \\`prd\\` → PRD만 수행\n- \\`validate\\` → 검증만 수행\n\n## Phase 1: Ideation (아이디어 구체화)\n\n**목표**: 사용자의 머릿속 아이디어를 \\`docs/ideation.md\\`로 구체화\n\nAskUserQuestion 도구로 심층 인터뷰를 진행하세요:\n1. \"어떤 문제를 해결하고 싶으세요?\" — 핵심 과제 파악\n2. \"이 서비스를 주로 사용할 사람은 누구인가요?\" — 대상 사용자\n3. \"비슷한 서비스가 있다면 뭐가 다른가요?\" — 차별점\n4. \"반드시 있어야 할 기능 3가지는?\" — 핵심 기능\n5. \"언제까지 만들고 싶으세요?\" — 일정 제약\n\n답변을 종합하여 \\`docs/ideation.md\\`를 생성하세요.\n\n## Phase 2: PRD 작성 (제품 요구사항)\n\n**목표**: Ideation을 기반으로 \\`docs/openspec.md\\` PRD 작성\n\n\\`docs/ideation.md\\`를 읽고, 부족한 맥락은 AskUserQuestion으로 보강:\n1. \"기술 스택 선호가 있으세요?\" — 프레임워크/언어 제약\n2. \"외부 API 연동이 필요한가요?\" — 의존성 파악\n3. \"데이터는 어떤 것을 저장해야 하나요?\" — DB 스키마 힌트\n4. \"로그인/회원가입이 필요한가요?\" — 인증 범위\n\n답변을 종합하여 \\`docs/openspec.md\\` 5개 섹션을 작성:\n- 목적 (Purpose)\n- 사용자 (Users)\n- 핵심 기능 (Features)\n- 기술 스택 (Stack)\n- API 엔드포인트\n\n## Phase 2.5: MCP 서버 설계 (MCP 프로젝트만)\n\n\\\\\\`.pai/config.json\\\\\\`의 \\\\\\`mcp.enabled\\\\\\`가 true이면 이 Phase를 수행하세요:\n\n1. \\\\\\`docs/openspec.md\\\\\\`의 \"## MCP 서버\" 섹션을 찾아 현재 정의된 도구/리소스/프롬프트 목록 확인\n2. TODO로 채워진 항목이 있으면 AskUserQuestion으로 심층 인터뷰:\n\n **Tools 서버 (tools / tools-public / all)**:\n - \"이 MCP 서버에서 제공할 도구 이름과 기능은?\"\n - \"각 도구의 입력 파라미터(JSON Schema)는?\"\n - \"출력 형식(text/json/image)은?\"\n - \"내부 로직은 어디에 구현? (src/lib/ 또는 외부 API 호출?)\"\n\n **Resources 서버 (resources / all)**:\n - \"AI에게 제공할 컨텍스트는 무엇인가요?\"\n - \"각 리소스의 URI 스키마(예: \\\\\\`wiki://pages/\\\\\\`)는?\"\n - \"MIME 타입(text/plain, application/json)은?\"\n\n **Prompts 서버 (prompts / all)**:\n - \"재사용 프롬프트 이름과 용도는?\"\n - \"각 프롬프트에 필요한 인자는?\"\n\n3. 답변을 종합하여 \\\\\\`openspec.md\\\\\\`의 MCP 섹션 테이블을 채웁니다.\n\n4. **공개 배포(tools-public)**인 경우 추가 질문:\n - \"시간당 레이트 리밋을 변경할까요? (기본 100회/시간)\"\n - \"각 도구별 비용이 다르게 설계되나요?\"\n - \"대시보드에서 사용자에게 표시할 무료 한도는?\"\n\n5. MCP 서버의 \\\\\\`src/tools.ts\\\\\\`, \\\\\\`src/resources.ts\\\\\\` 등에 설계된 도구를 구현하도록 사용자에게 안내하세요.\n\n## Phase 3: 기술 제약 + 하네스 엔지니어링\n\n**목표**: AI 에이전트가 안전하게 작업할 수 있는 환경 확인\n\nAskUserQuestion으로 기술적 제약 파악:\n1. \"기존에 사용 중인 DB나 서버가 있나요?\" — 기존 인프라\n2. \"배포 환경은 어디인가요?\" — 배포 제약\n3. \"팀에서 사용하는 코딩 규칙이 있나요?\" — 스타일 제약\n\n하네스 엔지니어링 확인:\n- \\`CLAUDE.md\\` — AI 컨텍스트 충분한지 검증\n- \\`.claude/settings.json\\` — 권한 설정 적절한지 확인\n- 테스트 환경 — \\`tests/\\` 디렉토리 + 테스트 프레임워크 존재 확인\n- 부족한 항목은 자동 생성 제안\n\n## Phase 4: 검증\n\n모든 Phase 완료 후:\n1. \\`docs/ideation.md\\` 존재 + 내용 확인\n2. \\`docs/openspec.md\\` 5개 섹션 완성도 검증\n3. \\`handoff.md\\` 업데이트 — 완료된 항목 체크, 다음 단계 갱신\n\n## 중요 원칙\n\n- **추측 금지**: 컨텍스트가 부족하면 반드시 AskUserQuestion으로 질문\n- **이미 존재하는 파일 덮어쓰지 않음** — 보강만 제안\n- **각 Phase 완료 시 사용자에게 결과 요약** 보고\n`,\n\n 'validate.md': `---\nname: \"PAI: Validate\"\ndescription: \"테스트 실행 + 하네스(설계↔구현 일치) 검증\"\n---\n\n# PAI 검증\n\n## 수행할 작업\n\n### 1. 테스트 실행\n\\`\\`\\`bash\nnpm test\n\\`\\`\\`\n결과를 보고하고, 실패 시 원인 설명 + 수정 제안.\n\n### 2. 하네스 검증\n\\`.pai/harness.json\\`이 있으면:\n- \\`docs/openspec.md\\`의 API 엔드포인트가 \\`src/\\`에 구현되어 있는지 검증\n- 테스트 디렉토리 존재 여부 확인\n\n없으면: \"Harness 미설정 — \\`/pai install\\`에서 추가 가능\" 안내\n`,\n\n 'evaluate.md': `---\nname: \"PAI: Evaluate\"\ndescription: \"6카테고리 가중 점수 기반 AI 개발 준비도 평가\"\n---\n\n# PAI 품질 평가\n\n## 수행할 작업\n\n6카테고리별로 파일 존재 여부와 설정 품질을 확인하고 0~100점으로 채점하세요.\n\n### [필수] 1. 테스트 커버리지 (20%)\n테스트 프레임워크 설정, 테스트 디렉토리, 커버리지 설정 확인\n\n### [필수] 2. CI/CD (20%)\n.github/workflows, .gitlab-ci.yml 등 파이프라인 설정 확인\n\n### [필수] 3. 훅 기반 검증 (20%)\n.husky, lint-staged, .claude/settings.json 훅 확인\n\n### [선택] 4. 리포지토리 구조 (13.3%)\nsrc/ 조직, 의존성 관리, .gitignore 확인\n\n### [선택] 5. 문서화 수준 (13.3%)\nREADME.md, CONTRIBUTING.md, docs/ 확인\n\n### [선택] 6. 하네스 엔지니어링 (13.4%)\nCLAUDE.md, AGENTS.md, .claude/ 설정 확인\n\n### 점수 계산\n종합 점수 = 가중 평균, 등급: A(90+) B(80+) C(70+) D(50+) F(<50)\n**페널티**: 필수 카테고리 F시 전체 최대 C\n\n각 카테고리별 개선 권고사항을 구체적으로 제시하세요.\n`,\n\n 'install.md': `---\nname: \"PAI: Install\"\ndescription: \"플러그인 추가 설치 — Mockup에서 Production 확장\"\n---\n\n# PAI 플러그인 추가 설치\n\n## 수행할 작업\n\n### 1. 현재 설치 상태 확인\n파일 존재 여부로 이미 설치된 플러그인을 파악하세요.\n\n### 2. 미설치 항목 안내\n이미 설치된 항목은 \\`(이미 설치됨)\\`으로, 미설치 항목만 선택 가능하게 안내하세요.\n\n### 3. 사용자 선택에 따라 파일 생성\n- **Vercel**: vercel.json\n- **Supabase**: supabase/config.toml + .env.local 키\n- **gstack**: .pai/gstack.json\n- **Harness**: .pai/harness.json\n\n### 4. .pai/config.json 업데이트\nplugins 배열에 새 플러그인 추가\n\n### 주의: 이미 존재하는 파일은 덮어쓰지 않음\n`,\n\n 'handoff.md': `---\nname: \"PAI: Handoff\"\ndescription: \"Task 현황 확인 및 handoff.md 관리\"\n---\n\n# PAI Handoff — Task 관리\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Handoff Manager\n 담당: handoff.md Task 기록/관리\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n### handoff.md 확인\n\\\\\\`handoff.md\\\\\\`를 읽고 현황을 보고하세요. 없으면 템플릿으로 생성하세요.\n\n### 현황 보기\n진행 중, 다음 단계, 완료 항목을 정리해서 보여주세요.\n\n### Task 추가\n사용자 요청 시 적절한 PAI Stage를 담당자로 지정하여 추가하세요.\n- PRD/설계 → PAI > Design\n- 코드 → PAI > Execution\n- 테스트 → PAI > Validation\n- 품질 → PAI > Evaluation\n- 환경 → PAI > Environment\n\n### Task 완료\n완료 섹션으로 이동하고 날짜를 기록하세요.\n`,\n\n 'vibe-ready.md': `---\nname: \"PAI: Vibe Ready\"\ndescription: \"바이브 코딩 준비도 측정 — 6카테고리 평가 + docs/p-reports/ 자동 저장\"\n---\n\n# PAI 바이브 코딩 준비도\n\n프로젝트의 바이브 코딩 준비 상태를 6카테고리로 분석하고, 상세 리포트를 자동 생성합니다.\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Evaluation Stage\n 담당: scorer (6카테고리 가중 평가)\n 출력: docs/p-reports/YYYY-MM-DD.md\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n\\\\\\`/pai evaluate\\\\\\` 와 동일하게 6카테고리를 평가하세요.\n평가가 끝나면 \\\\\\`docs/p-reports/\\\\\\` 폴더에 오늘 날짜(YYYY-MM-DD.md)로 상세 리포트를 저장하세요.\n`,\n\n 'upgrade.md': `---\nname: \"PAI: Upgrade\"\ndescription: \"PAI 슬래시 커맨드 & 스킬을 최신 버전으로 업그레이드\"\n---\n\n# PAI 업그레이드\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Environment Stage\n 담당: upgrade (시스템 파일 갱신)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n터미널에서 다음 명령을 실행하세요:\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero upgrade\n\\\\\\`\\\\\\`\\\\\\`\n\n강제 업그레이드 (이미 최신이어도):\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero upgrade --force\n\\\\\\`\\\\\\`\\\\\\`\n\n### 주의사항\n- 슬래시 커맨드와 SKILL.md는 최신으로 덮어씁니다.\n- 프로젝트 파일(openspec.md, omc.md, CLAUDE.md)은 건드리지 않습니다.\n`,\n\n 'savetoken.md': `---\nname: \"PAI: SaveToken\"\ndescription: \"AI 토큰 절감 분석 — API 호출 스캔, 대체 코드 생성, 절감 리포트\"\n---\n\n# PAI SaveToken — AI 토큰 절감 분석\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n💰 PAI > SaveToken\n 담당: savetoken (토큰 절감 분석)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n### Phase 1: 스캔\n\n1. 먼저 CLI 스캔 리포트가 있는지 확인하세요:\n \\\\\\`\\\\\\`\\\\\\`bash\n cat .pai/savetoken-report.md 2>/dev/null\n \\\\\\`\\\\\\`\\\\\\`\n 없으면 먼저 실행: \\\\\\`npx pai-zero savetoken\\\\\\`\n\n2. 프로젝트 전체에서 아래 패턴을 검색하세요:\n - AI SDK 임포트: \\\\\\`@anthropic-ai/sdk\\\\\\`, \\\\\\`openai\\\\\\`, \\\\\\`@google/generative-ai\\\\\\`, \\\\\\`langchain\\\\\\`\n - API 호출: \\\\\\`messages.create\\\\\\`, \\\\\\`chat.completions.create\\\\\\`, \\\\\\`generateContent\\\\\\`\n - Fetch: \\\\\\`api.anthropic.com\\\\\\`, \\\\\\`api.openai.com\\\\\\`\n\n### Phase 2: 각 호출 심층 분석\n\n발견된 각 API 호출에 대해:\n\n1. **목적 파악**: 이 호출이 무엇을 하는지 분석\n2. **프롬프트 분석**: 시스템 프롬프트와 사용자 프롬프트 내용 확인\n3. **입출력 패턴**: 입력 데이터 형태와 기대 출력 형태 파악\n4. **대체 가능성 판단**: 아래 기준으로 분류\n\n### Phase 3: 영향도 분류 및 대체 전략\n\n#### 🟢 영향도 낮음 — 즉시 대체 가능 (예상 절감: 해당 호출 100%)\n- 텍스트 포맷팅/변환 → \\\\\\`regex\\\\\\`, \\\\\\`string.replace()\\\\\\`\n- 데이터 유효성 검증 → \\\\\\`zod\\\\\\`, \\\\\\`joi\\\\\\`, JSON schema\n- 템플릿 기반 생성 → \\\\\\`handlebars\\\\\\`, 문자열 템플릿\n- 고정 카테고리 분류 → \\\\\\`switch-case\\\\\\`, lookup table\n- 설정 파일 생성 → 템플릿 + 변수 치환\n\n**대체 코드를 직접 작성**하여 \\\\\\`.pai/savetoken/\\\\\\` 디렉토리에 저장하세요.\n\n#### 🟡 영향도 중간 — 검토 후 대체 (예상 절감: 해당 호출 50-80%)\n- 텍스트 요약 → extractive 방식 (키워드 빈도 기반)\n- 간단한 분류 → TF-IDF, 키워드 매칭, 규칙 기반\n- 구조화된 데이터 추출 → regex, AST parser\n- 반복적 번역 → i18n 파일 + 사전\n\n**대체 로직의 의사코드**를 작성하고 구현 난이도를 평가하세요.\n\n#### 🔴 영향도 높음 — AI 필수 (프롬프트 최적화로 절감)\n- 코드 생성/리팩토링 → 프롬프트 캐싱, few-shot 최적화\n- 복잡한 추론/분석 → 프롬프트 압축, 컨텍스트 정리\n- 창의적 콘텐츠 생성 → 프롬프트 재설계\n- 멀티턴 대화 → 턴 수 최소화\n\n**프롬프트 최적화 방안**을 제시하세요.\n\n### Phase 4: 리포트 생성\n\n\\\\\\`.pai/savetoken/\\\\\\` 디렉토리에 다음을 저장:\n\n1. \\\\\\`analysis.md\\\\\\` — 전체 분석 리포트\n - 호출별 목적, 영향도, 대체 전략\n - 총 예상 절감률 (%)\n - 단계별 추진 로드맵\n2. \\\\\\`replacements/\\\\\\` — 대체 코드 파일들 (영향도 낮음)\n3. \\\\\\`optimizations.md\\\\\\` — 프롬프트 최적화 제안 (영향도 높음)\n\n## 리포트 형식\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# SaveToken 분석 결과\n\n## 요약\n- 총 API 호출: N건\n- 대체 가능: M건 (영향도 낮음 X건, 중간 Y건)\n- AI 필수: Z건\n- **예상 토큰 절감: ~XX%**\n\n## 단계별 추진 전략\n\n### 1단계: 즉시 적용 (영향도 낮음)\n영향도, 파일, 현재 방식, 대체 방식, 예상 절감\n\n### 2단계: 검토 후 적용 (영향도 중간)\n...\n\n### 3단계: 프롬프트 최적화 (영향도 높음)\n...\n\\\\\\`\\\\\\`\\\\\\`\n\n## 주의사항\n- 대체 코드는 기존 입출력 인터페이스를 유지해야 합니다\n- 영향도 중간 이상은 반드시 테스트와 함께 적용하세요\n- AI 호출이 필수인 경우, 프롬프트 캐싱(prompt caching)이 가장 효과적입니다\n`,\n\n 'wakeup.md': `---\nname: \"PAI: Wakeup\"\ndescription: \"매일 아침 영감 메시지 스케줄 설정\"\n---\n\n# PAI Wakeup\n\n매일 아침 영감을 주는 메시지를 스케줄링합니다.\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n☀️ PAI > Wakeup\n 담당: wakeup (영감 메시지)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 사용법\n\n터미널에서 실행:\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero wakeup 06:00 # 평일 오전 6시 (기본)\nnpx pai-zero wakeup 07:30 매일 # 매일 오전 7시 30분\nnpx pai-zero wakeup 08:00 주말 # 주말 오전 8시\nnpx pai-zero wakeup status # 현재 설정 확인\nnpx pai-zero wakeup off # 해제\nnpx pai-zero wakeup # 지금 랜덤 메시지 보기\n\\\\\\`\\\\\\`\\\\\\`\n\n## 스케줄 옵션\n\n| 옵션 | 설명 | cron |\n|------|------|------|\n| 평일 | 월~금 (기본값) | \\\\\\`* * * * 1-5\\\\\\` |\n| 매일 | 매일 | \\\\\\`* * * * *\\\\\\` |\n| 주말 | 토~일 | \\\\\\`* * * * 0,6\\\\\\` |\n\n## 동작 방식\n\n- 시스템 crontab에 스케줄 등록\n- 지정 시간에 macOS 알림 또는 Linux notify-send 전송\n- \\\\\\`~/.pai/wakeup-today.txt\\\\\\` 에 오늘의 메시지 저장\n`,\n\n // ─────────────────────────────────────────────────────────────\n // v0.11+ 신규 명령어 (구 명령어는 deprecation 경고와 함께 유지)\n // ─────────────────────────────────────────────────────────────\n\n 'help.md': `---\nname: \"PAI: Help\"\ndescription: \"PAI 안내 — 명령어, 파이프라인, 핵심 파일 설명\"\n---\n\n# PAI 안내\n\n사용자에게 PAI(Plugin-based AI) 시스템을 안내합니다.\n\n### PAI란?\nPAI는 AI 개발을 5단계 파이프라인으로 구조화하는 빌드 오케스트레이터입니다.\n\n### 파이프라인 5단계\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n### 사용 가능한 명령어 (v0.11+)\n| 명령어 | 설명 | 사용 시점 |\n|--------|------|----------|\n| \\`/pai help\\` | 이 안내 | PAI가 뭔지 알고 싶을 때 |\n| \\`/pai init\\` | 프로젝트 초기화 | 새 프로젝트 시작 시 |\n| \\`/pai status\\` | 상태 확인 | 설치 플러그인 점검 |\n| \\`/pai check\\` | 환경 점검 | Node/Git/Claude Code 검증 |\n| \\`/pai design\\` | PRD/OMC 생성 | 설계 문서 관리 |\n| \\`/pai test\\` | 테스트·검증 | 코드 작성 후 |\n| \\`/pai grade\\` | 품질 평가 | 준비도 평가 |\n| \\`/pai add\\` | 플러그인 추가 | Production 확장 |\n\n### 구 명령어 (v0.13 까지 유지)\n\\`/pai info → help\\`, \\`/pai doctor → check\\`, \\`/pai validate → test\\`, \\`/pai evaluate → grade\\`, \\`/pai install → add\\`\n\n### 핵심 파일\n- \\`docs/openspec.md\\` — PRD, \\`.pai/omc.md\\` — 도메인 모델, \\`.pai/config.json\\` — PAI 설정, \\`CLAUDE.md\\` — AI 컨텍스트\n`,\n\n 'check.md': `---\nname: \"PAI: Check\"\ndescription: \"개발 환경 점검 — Node.js, Git, Claude Code\"\n---\n\n# PAI 환경 점검\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Environment Stage\n 담당: check (환경 점검)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 점검 항목\n1. **Node.js** — \\`node --version\\` (v20+)\n2. **npm** — \\`npm --version\\`\n3. **Git** — \\`git --version\\` + \\`git remote -v\\`\n4. **Claude Code** — \\`CLAUDE.md\\`, \\`.claude/settings.json\\`, \\`~/.claude/settings.json\\`의 \\`enabledPlugins[\"oh-my-claudecode@omc\"]\\`\n5. **PAI 설정** — \\`.pai/config.json\\`, \\`.pai/omc.md\\`, \\`docs/openspec.md\\`\n\n### Windows 추가 점검\n- \\`Get-ExecutionPolicy\\` → RemoteSigned 이상\n- \\`$env:HOME\\` 또는 \\`$env:USERPROFILE\\` 설정\n- PowerShell 7 권장\n\n### 결과 보고\n각 항목 ✅/⚠️/❌ 표시 + 권장 조치 안내.\n`,\n\n 'test.md': `---\nname: \"PAI: Test\"\ndescription: \"테스트 실행 + 하네스(설계↔구현 일치) 검증\"\n---\n\n# PAI 테스트·검증\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Validation Stage\n 담당: gstack runner + harness checker\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 1단계: 테스트 실행\n- \\`.pai/gstack.json\\`의 \\`testRunner\\` 또는 \\`package.json\\`의 \\`scripts.test\\` 사용\n- \\`npm test\\` 실행 후 결과 보고\n\n### 2단계: 하네스 검증 (\\`.pai/harness.json\\` 존재 시)\n- \\`spec-implementation-match\\`: OpenSpec 엔드포인트 ↔ 구현 매칭\n- \\`api-contract-test\\`: 각 엔드포인트에 대한 테스트 존재 여부\n\n### 3단계: 결과 보고 + 개선 제안\n하네스 설정이 없으면 \\`/pai add\\`에서 Harness Engineering 선택 안내.\n`,\n\n 'grade.md': `---\nname: \"PAI: Grade\"\ndescription: \"6카테고리 가중 점수 기반 AI 개발 준비도 평가\"\n---\n\n# PAI 품질 평가\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Evaluation Stage\n 담당: scorer (6카테고리 가중 평가)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 6카테고리 (0~100점 채점)\n| # | 카테고리 | 분류 | 가중치 |\n|---|---------|------|--------|\n| 1 | 테스트 커버리지 | 필수 | 20% |\n| 2 | CI/CD | 필수 | 20% |\n| 3 | 훅 기반 검증 | 필수 | 20% |\n| 4 | 리포지토리 구조 | 선택 | 13.3% |\n| 5 | 문서화 수준 | 선택 | 13.3% |\n| 6 | 하네스 엔지니어링 | 선택 | 13.4% |\n\n### 점수 계산\n\\`\\`\\`\n종합 점수 = Σ(카테고리 점수 × 가중치) / Σ(가중치)\n등급: A(90+), B(80+), C(70+), D(50+), F(<50)\n페널티: 필수 카테고리 중 F면 전체 등급 최대 C로 제한\n\\`\\`\\`\n\n### 결과 보고\n막대 그래프 + 점수/등급 + 카테고리별 개선 권고사항 제시.\n`,\n\n 'add.md': `---\nname: \"PAI: Add\"\ndescription: \"플러그인 추가 설치 — Mockup에서 Production 확장\"\n---\n\n# PAI 플러그인 추가 설치\n\n기존 프로젝트에 추가 플러그인을 설치합니다. (Mockup → Production 확장)\n\n### 1단계: 현재 설치 상태 스캔\n| 플러그인 | 감지 경로 |\n|---------|----------|\n| GitHub | \\`.git\\` / \\`.github\\` |\n| Vercel | \\`vercel.json\\` |\n| Supabase | \\`supabase/\\` |\n| OpenSpec | \\`docs/openspec.md\\` |\n| OMC | \\`.pai/omc.md\\` |\n| gstack | \\`.pai/gstack.json\\` |\n| Harness | \\`.pai/harness.json\\` |\n\n### 2단계: 미설치 항목 체크박스로 사용자에게 제시\n\n### 3단계: 선택된 플러그인 파일 생성\n- **Vercel**: \\`vercel.json\\`\n- **Supabase**: \\`supabase/config.toml\\` + \\`.env.local\\` (URL/KEY)\n- **gstack**: \\`.pai/gstack.json\\` (testRunner, coverageThreshold 80%)\n- **Harness**: \\`.pai/harness.json\\` (specFile, rules)\n\n### 4단계: \\`.pai/config.json\\`의 \\`plugins\\` 배열에 추가\n\n### 주의\n이미 존재하는 파일은 절대 덮어쓰지 않음. \\`.env.local\\`은 append only.\n`,\n};\n\n// ── Shared helper ─────────────────────────────────────\n\ninterface WriteResult {\n written: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nasync function writeCommandFiles(\n cmdDir: string,\n entries: Record<string, string>,\n options: { skipIfExists: boolean },\n): Promise<WriteResult> {\n await fs.ensureDir(cmdDir);\n const written: string[] = [];\n const skipped: string[] = [];\n const errors: Array<{ file: string; error: string }> = [];\n\n for (const [filename, content] of Object.entries(entries)) {\n const filePath = join(cmdDir, filename);\n try {\n if (options.skipIfExists && await fs.pathExists(filePath)) {\n skipped.push(filename);\n continue;\n }\n await fs.writeFile(filePath, content);\n written.push(filename);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ file: filename, error: msg });\n }\n }\n\n return { written, skipped, errors };\n}\n\n// ── Init (skip if exists) ─────────────────────────────\n\nexport async function provisionClaudeCommands(cwd: string): Promise<void> {\n const skillDir = join(cwd, '.claude', 'skills', 'pai');\n await fs.ensureDir(skillDir);\n const skillPath = join(skillDir, 'SKILL.md');\n if (!(await fs.pathExists(skillPath))) {\n await fs.writeFile(skillPath, SKILL_CONTENT);\n }\n\n const cmdDir = join(cwd, '.claude', 'commands', 'pai');\n await writeCommandFiles(cmdDir, COMMANDS, { skipIfExists: true });\n}\n\n// ── Upgrade (always overwrite) ────────────────────────\n\nexport interface UpgradeResult {\n skillUpdated: boolean;\n commandsWritten: string[];\n commandErrors: Array<{ file: string; error: string }>;\n}\n\nexport async function upgradeClaudeCommands(cwd: string): Promise<UpgradeResult> {\n const result: UpgradeResult = {\n skillUpdated: false,\n commandsWritten: [],\n commandErrors: [],\n };\n\n // Always overwrite SKILL.md\n const skillDir = join(cwd, '.claude', 'skills', 'pai');\n await fs.ensureDir(skillDir);\n try {\n await fs.writeFile(join(skillDir, 'SKILL.md'), SKILL_CONTENT);\n result.skillUpdated = true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n result.commandErrors.push({ file: 'SKILL.md', error: msg });\n }\n\n // Always overwrite all command files\n const cmdDir = join(cwd, '.claude', 'commands', 'pai');\n const { written, errors } = await writeCommandFiles(cmdDir, COMMANDS, { skipIfExists: false });\n result.commandsWritten = written;\n result.commandErrors.push(...errors);\n\n return result;\n}\n","/**\n * Doctor — 환경 헬스 체크\n */\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\ninterface Check {\n label: string;\n ok: boolean;\n detail: string;\n fix?: string;\n}\n\nexport async function runDoctor(): Promise<void> {\n ui.section('PAI Doctor — 환경 진단');\n\n const checks: Check[] = [];\n\n // Node.js version\n const nodeVersion = process.version;\n const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0]!, 10);\n checks.push({\n label: 'Node.js 버전',\n ok: nodeMajor >= 20,\n detail: `${nodeVersion} ${nodeMajor >= 20 ? '(>=20 OK)' : '(업그레이드 필요)'}`,\n fix: nodeMajor < 20 ? 'Node.js 20 이상으로 업그레이드하세요' : undefined,\n });\n\n // Claude Code CLI\n const claudeCheck = await checkCommand('claude', ['--version']);\n checks.push({\n label: 'Claude Code CLI',\n ok: claudeCheck.ok,\n detail: claudeCheck.detail,\n fix: claudeCheck.ok ? undefined : 'npm install -g @anthropic-ai/claude-code',\n });\n\n // Global config\n const globalConfigPath = join(homedir(), '.pai', 'config.json');\n const hasGlobalConfig = await fs.pathExists(globalConfigPath);\n checks.push({\n label: '글로벌 설정',\n ok: true,\n detail: hasGlobalConfig ? globalConfigPath : '미설정 (기본값 사용)',\n });\n\n // Claude Agent SDK (optional)\n let hasSdk = false;\n try {\n await import('@anthropic-ai/claude-agent-sdk');\n hasSdk = true;\n } catch {\n // not installed\n }\n checks.push({\n label: 'Agent SDK',\n ok: true, // optional이므로 항상 OK\n detail: hasSdk ? '설치됨 (AI 기능 활성화)' : '미설치 (정적 분석 모드)',\n });\n\n // Print results\n console.log('');\n let passed = 0;\n for (const check of checks) {\n const icon = check.ok ? '✓' : '✗';\n const pad = ' '.repeat(Math.max(1, 20 - check.label.length));\n if (check.ok) {\n ui.success(`${icon} ${check.label}${pad}${check.detail}`);\n passed++;\n } else {\n ui.error(`${icon} ${check.label}${pad}${check.detail}`);\n if (check.fix) {\n ui.info(` → ${check.fix}`);\n }\n }\n }\n\n console.log('');\n ui.info(`${passed}/${checks.length} 항목 통과`);\n\n if (passed < checks.length) {\n process.exitCode = 1;\n }\n}\n\nasync function checkCommand(cmd: string, args: string[]): Promise<{ ok: boolean; detail: string }> {\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa(cmd, args, { timeout: 10000 });\n return { ok: true, detail: stdout.trim().split('\\n')[0] ?? 'ok' };\n } catch {\n return { ok: false, detail: 'not found' };\n }\n}\n","/**\n * Environment Stage — 파이프라인 1단계\n * roboco-cli의 핵심 기능을 PAI Stage 인터페이스로 래핑\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { analyzeProject } from './analyzer.js';\nimport { runInterview } from './interviewer.js';\nimport { generateFiles } from './generator.js';\nimport { installTools, printInstallReport } from './installer.js';\nimport { runProvisioners, type ProvisionerContext } from './provisioners/registry.js';\nimport { provisionClaudeCommands } from './provisioners/claude-commands.js';\nimport { getPluginsForMode } from '../../core/detector.js';\nimport { saveConfig, createDefaultConfig } from '../../core/config.js';\nimport { withSpinner, withFileSpinner, sleep } from '../../ui/progress.js';\nimport * as ui from '../../ui/index.js';\n\nexport const environmentStage: Stage = {\n name: 'environment',\n\n canSkip(input: StageInput): boolean {\n return input.config.plugins.length > 0;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const artifacts: string[] = [];\n const errors: StageResult['errors'] = [];\n\n try {\n // 1. Analyze\n console.log('');\n const analysis = await withSpinner('프로젝트 분석 중...', async () => {\n const result = await analyzeProject(input.cwd);\n await sleep(500);\n return result;\n });\n\n console.log('');\n if (analysis.stack.languages.length > 0) {\n ui.success(`스택: ${analysis.stack.languages.join(', ')}`);\n }\n if (analysis.stack.frameworks.length > 0) {\n ui.success(`프레임워크: ${analysis.stack.frameworks.join(', ')}`);\n }\n ui.success(`Git: ${analysis.git.isGitRepo ? `${analysis.git.repoName ?? 'local'}` : '미초기화'}`);\n\n // 2. Interview (interactive — no spinner)\n const interview = await runInterview(analysis, input.cwd, input.config.projectName);\n\n // 3. Generate config files\n console.log('');\n const configFiles = ['CLAUDE.md', '.claude/settings.json', 'docs/vibe-coding/01-intent.md',\n 'docs/vibe-coding/02-requirements.md', 'docs/vibe-coding/03-research.md',\n 'docs/vibe-coding/04-plan.md', 'docs/vibe-coding/05-implement.md'];\n const generated = await withFileSpinner('설정 파일 생성 중...', configFiles, async () => {\n const files = await generateFiles(input.cwd, analysis, interview);\n await sleep(400);\n return files;\n });\n artifacts.push(...generated);\n\n // 4. Run provisioners — 모드별 basePlugins + extraTools\n // basePlugins: 모든 수준에서 설치되는 최소 세트\n // extraTools: 인터뷰어가 모드에 따라 omc/gstack/harness/vercel/supabase 추가\n const basePlugins = ['github', 'openspec', 'roboco'];\n const pluginKeys = [...new Set([...basePlugins, ...interview.extraTools])];\n\n const provCtx: ProvisionerContext = {\n cwd: input.cwd,\n projectName: interview.projectName,\n mode: interview.mode,\n envEntries: {\n PAI_PROJECT_NAME: interview.projectName,\n PAI_MODE: interview.mode,\n },\n mcp: interview.mcp,\n };\n\n if (interview.authMethods.includes('custom')) {\n provCtx.envEntries['OAUTH_CLIENT_ID'] = interview.customAuth?.clientId || 'YOUR_CLIENT_ID_HERE';\n provCtx.envEntries['OAUTH_CLIENT_SECRET'] = interview.customAuth?.clientSecret || 'YOUR_CLIENT_SECRET_HERE';\n provCtx.envEntries['OAUTH_REDIRECT_URI'] = 'http://localhost:3000/auth/callback';\n }\n\n const pluginFileNames = ['.gitignore', 'src/', 'docs/', 'tests/', 'public/',\n 'docs/openspec.md', '.pai/omc.md', '.pai/roboco.json',\n ...(interview.extraTools.includes('vercel') ? ['vercel.json'] : []),\n ...(interview.extraTools.includes('supabase') ? ['supabase/config.toml'] : []),\n ...(interview.extraTools.includes('gstack') ? ['.pai/gstack.json'] : []),\n ...(interview.extraTools.includes('harness') ? ['.pai/harness.json'] : []),\n ...(interview.extraTools.includes('mcp') ? ['mcp-server/', '.mcp.json'] : []),\n '.env.local'];\n\n console.log('');\n await withFileSpinner('프로젝트 구조 설치 중...', pluginFileNames, async () => {\n await runProvisioners(pluginKeys, provCtx);\n await sleep(500);\n });\n\n const cmdFiles = ['SKILL.md', 'info.md', 'init.md', 'status.md',\n 'doctor.md', 'design.md', 'validate.md', 'evaluate.md', 'install.md'];\n\n console.log('');\n await withFileSpinner('슬래시 커맨드 설치 중...', cmdFiles, async () => {\n await provisionClaudeCommands(input.cwd);\n await sleep(400);\n });\n\n // 5. OMC install (npx omc init)\n console.log('');\n const installResults = await installTools(interview.tools, input.cwd);\n printInstallReport(installResults, interview.tools);\n\n // 6. Save PAI config\n console.log('');\n await withSpinner('설정 저장 중...', async () => {\n const config = createDefaultConfig(interview.projectName, interview.mode);\n config.plugins = pluginKeys;\n if (interview.mcp) config.mcp = interview.mcp;\n await saveConfig(input.cwd, config);\n await sleep(300);\n });\n\n return {\n stage: 'environment',\n status: 'success',\n data: { analysis, interview, installResults },\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'ENV_SETUP_FAILED', message: msg, recoverable: true });\n return {\n stage: 'environment',\n status: 'failed',\n data: {},\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nexport { analyzeProject } from './analyzer.js';\nexport { runInterview } from './interviewer.js';\nexport { runDoctor } from './doctor.js';\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport type { Mode } from './types/index.js';\nimport { normalizeMode } from './config.js';\n\nexport interface PluginMeta {\n label: string;\n description: string;\n modes: Mode[];\n required: boolean;\n}\n\nexport const PLUGIN_SIGNATURES: Record<string, string[]> = {\n github: ['.git', '.github'],\n vercel: ['.vercel', 'vercel.json'],\n supabase: ['supabase', '.supabase'],\n openspec: ['openspec.md', 'docs/openspec.md', '.pai/openspec.md'],\n omc: ['.pai/omc.md', 'omc.config.js', 'omc.config.json'],\n gstack: ['.pai/gstack.json', 'gstack.config.js'],\n roboco: ['.pai/roboco.json', 'roboco.config.js', '.roboco'],\n harness: ['.pai/harness.json', 'harness.config.js', '.harness'],\n};\n\n/**\n * PLUGIN_META — 플러그인별 메타데이터 + 모드 매트릭스.\n *\n * v0.11.1 3단계 모드 매트릭스:\n * - prototype: github, openspec, roboco (최소)\n * - poc: + omc + (vercel 선택)\n * - production: + gstack, harness + (vercel, supabase 선택)\n */\nexport const PLUGIN_META: Record<string, PluginMeta> = {\n github: {\n label: 'GitHub 레포 & 폴더 구조',\n description: '레포 초기화, .gitignore, 기본 브랜치 설정',\n modes: ['prototype', 'poc', 'production'],\n required: true,\n },\n openspec: {\n label: 'OpenSpec (PRD 설계)',\n description: 'AI 기반 PRD 생성 및 스펙 문서화',\n modes: ['prototype', 'poc', 'production'],\n required: true,\n },\n roboco: {\n label: 'roboco (AI 진단)',\n description: '설치 상태 평가 및 AI 준비도 리포트 생성',\n modes: ['prototype', 'poc', 'production'],\n required: false,\n },\n omc: {\n label: 'OMC (Object Model Context)',\n description: '객체 모델 컨텍스트 — AI가 도메인을 이해하는 구조',\n modes: ['poc', 'production'],\n required: false,\n },\n vercel: {\n label: 'Vercel 배포 연동',\n description: '자동 배포 파이프라인 및 Preview URL 설정',\n modes: ['poc', 'production'],\n required: false,\n },\n gstack: {\n label: 'gstack (QA / 품질관리)',\n description: '테스트 자동화 및 품질 기준 설정',\n modes: ['production'],\n required: false,\n },\n harness: {\n label: 'Harness Engineering (검증 자동화)',\n description: '설계(OpenSpec)와 구현 일치 여부 자동 체크',\n modes: ['production'],\n required: false,\n },\n supabase: {\n label: 'Supabase (DB & Auth)',\n description: '데이터베이스, 인증, API 키 자동 연동',\n modes: ['production'],\n required: false,\n },\n};\n\nexport interface ProjectState {\n isNewProject: boolean;\n hasPaiConfig: boolean;\n projectMode: Mode | null;\n installedPlugins: string[];\n missingPlugins: string[];\n details: Record<string, { installed: boolean; signatures: string[] }>;\n}\n\nexport async function scanProjectState(cwd: string): Promise<ProjectState> {\n const result: ProjectState = {\n isNewProject: true,\n hasPaiConfig: false,\n projectMode: null,\n installedPlugins: [],\n missingPlugins: [],\n details: {},\n };\n\n const paiConfigPath = path.join(cwd, '.pai', 'config.json');\n if (await fs.pathExists(paiConfigPath)) {\n result.hasPaiConfig = true;\n try {\n const config = await fs.readJson(paiConfigPath);\n // 레거시 'mockup' 자동 정규화\n result.projectMode = config.mode != null ? normalizeMode(config.mode) : null;\n } catch {\n // ignore parse errors\n }\n }\n\n for (const [key, signatures] of Object.entries(PLUGIN_SIGNATURES)) {\n const installed = await Promise.any(\n signatures.map(async (sig) => {\n if (await fs.pathExists(path.join(cwd, sig))) return true;\n throw new Error('not found');\n }),\n ).catch(() => false);\n\n result.details[key] = { installed: installed as boolean, signatures };\n if (installed) {\n result.installedPlugins.push(key);\n } else {\n result.missingPlugins.push(key);\n }\n }\n\n const hasAnyContent =\n result.installedPlugins.length > 0 ||\n (await fs.pathExists(path.join(cwd, 'package.json'))) ||\n (await fs.pathExists(path.join(cwd, 'src'))) ||\n (await fs.pathExists(path.join(cwd, 'README.md')));\n\n result.isNewProject = !hasAnyContent;\n\n return result;\n}\n\nexport function getPluginsForMode(mode: Mode): Array<{ key: string } & PluginMeta> {\n return Object.entries(PLUGIN_META)\n .filter(([, meta]) => meta.modes.includes(mode))\n .map(([key, meta]) => ({ key, ...meta }));\n}\n\n/**\n * 모드별 기본(required=true) + 선택(required=false) 플러그인 키만 반환.\n * environment stage가 basePlugins 산출 시 사용.\n */\nexport function getBasePluginsForMode(mode: Mode): string[] {\n return Object.entries(PLUGIN_META)\n .filter(([, meta]) => meta.modes.includes(mode) && meta.required)\n .map(([key]) => key);\n}\n\n/**\n * 모드 승격 경로. prototype → poc → production.\n * 현재 모드의 다음 단계를 반환 (없으면 null).\n */\nexport function nextMode(current: Mode): Mode | null {\n if (current === 'prototype') return 'poc';\n if (current === 'poc') return 'production';\n return null;\n}\n\n/**\n * 모드 승격 시 새로 추가되는 플러그인 키 (required + optional 전체).\n */\nexport function pluginsAddedByPromotion(from: Mode, to: Mode): string[] {\n const fromSet = new Set(getPluginsForMode(from).map((p) => p.key));\n return getPluginsForMode(to)\n .map((p) => p.key)\n .filter((k) => !fromSet.has(k));\n}\n","/**\n * LLM Analysis Prompt — vibe-ready-cli에서 내재화\n */\nexport function buildAnalysisPrompt(repoPath: string): string {\n return `Analyze the repository at \"${repoPath}\" for vibe coding readiness.\n\nUse only Read, Glob, and Grep tools. Complete in ~20 tool calls.\nFocus on config files, not source code.\n\nEvaluate these 6 categories:\n\n### Must-Have (60% weight)\n1. **테스트 커버리지**: test framework config, test dirs, coverage thresholds\n - 0=none, 20=config only, 40=minimal files, 60=moderate, 80=good, 100=comprehensive\n2. **CI/CD**: pipeline configs, quality gates, multi-stage\n - 0=none, 20=exists but minimal, 40=basic, 60=tests+lint, 80=tests+lint+build, 100=comprehensive\n3. **훅 기반 검증**: git hooks, lint-staged, AI agent hooks (.claude/settings.json)\n - 0=none, 20=framework only, 40=single hook, 60=lint+format, 80=lint+test+format, 100=comprehensive+AI\n\n### Nice-to-Have (40% weight)\n4. **리포지토리 구조**: dir organization, deps management, env config\n - 0=flat/chaotic, 20=minimal, 40=basic, 60=reasonable, 80=well-organized, 100=exemplary\n5. **문서화 수준**: README, CONTRIBUTING, API docs, architecture docs\n - 0=none, 20=minimal, 40=basic, 60=good README, 80=README+API, 100=comprehensive\n6. **하네스 엔지니어링**: CLAUDE.md, AGENTS.md, .claude/ config, skills, commands\n - 0=none, 20=basic, 40=one AI config, 60=context+config, 80=context+safety+skills, 100=comprehensive\n\nOutput ONLY a JSON block:\n\\`\\`\\`json\n{\n \"categories\": [\n {\n \"name\": \"카테고리명 (Korean)\",\n \"tier\": \"must\" | \"nice\",\n \"score\": 0-100,\n \"recommendations\": [{ \"severity\": \"critical\"|\"warning\"|\"info\", \"message\": \"...\", \"action\": \"...\" }],\n \"rawFindings\": [{ \"item\": \"filename or concept\", \"found\": true|false, \"details\": \"...\" }]\n }\n ],\n \"summary\": \"2-3 sentence Korean summary\"\n}\n\\`\\`\\``;\n}\n","/**\n * Evaluation Analyzer\n * SDK 있을 때: LLM 기반 분석 / SDK 없을 때: 정적 파일 분석\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { LLMAnalysisOutput, LLMCategoryOutput } from '../../core/types/index.js';\n\nexport async function analyzeRepository(repoPath: string): Promise<LLMAnalysisOutput> {\n // Try AI analysis first\n try {\n return await aiAnalysis(repoPath);\n } catch {\n // Fall back to static analysis\n return staticAnalysis(repoPath);\n }\n}\n\nasync function aiAnalysis(repoPath: string): Promise<LLMAnalysisOutput> {\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n const { buildAnalysisPrompt } = await import('./prompts/analyze.js');\n\n const prompt = buildAnalysisPrompt(repoPath);\n let resultText = '';\n\n for await (const message of query({\n prompt,\n options: {\n maxTurns: 200,\n systemPrompt: 'You are a vibe coding readiness analyzer. Analyze the repository and output JSON.',\n allowedTools: ['Read', 'Glob', 'Grep'],\n permissionMode: 'plan',\n },\n })) {\n if ('result' in message) {\n resultText = message.result as string;\n }\n }\n\n return parseJsonFromText(resultText);\n}\n\nfunction parseJsonFromText(text: string): LLMAnalysisOutput {\n const jsonMatch = text.match(/```json\\s*([\\s\\S]*?)```/);\n if (jsonMatch?.[1]) {\n return JSON.parse(jsonMatch[1]) as LLMAnalysisOutput;\n }\n // Try parsing the whole text\n return JSON.parse(text) as LLMAnalysisOutput;\n}\n\nasync function staticAnalysis(repoPath: string): Promise<LLMAnalysisOutput> {\n const categories: LLMCategoryOutput[] = [];\n\n // 1. 테스트 커버리지\n categories.push(await checkTestCoverage(repoPath));\n // 2. CI/CD\n categories.push(await checkCiCd(repoPath));\n // 3. 훅 기반 검증\n categories.push(await checkHooks(repoPath));\n // 4. 리포지토리 구조\n categories.push(await checkRepoStructure(repoPath));\n // 5. 문서화 수준\n categories.push(await checkDocumentation(repoPath));\n // 6. 하네스 엔지니어링\n categories.push(await checkHarnessEngineering(repoPath));\n\n return {\n categories,\n summary: `정적 분석 완료. ${categories.filter((c) => c.score >= 60).length}/6 카테고리 통과.`,\n };\n}\n\nasync function checkTestCoverage(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const testConfigs = ['jest.config.ts', 'jest.config.js', 'vitest.config.ts', 'vitest.config.js',\n 'pytest.ini', 'phpunit.xml', '.nycrc'];\n for (const f of testConfigs) {\n const found = await fs.pathExists(join(repoPath, f));\n findings.push({ item: f, found, details: found ? '존재' : '없음' });\n if (found) score += 20;\n }\n\n const testDirs = ['tests', 'test', '__tests__', 'spec'];\n let hasTestDir = false;\n for (const d of testDirs) {\n if (await fs.pathExists(join(repoPath, d))) {\n findings.push({ item: d, found: true, details: '테스트 디렉토리 존재' });\n hasTestDir = true;\n score += 30;\n break;\n }\n }\n if (!hasTestDir) {\n findings.push({ item: 'test directory', found: false, details: '테스트 디렉토리 없음' });\n }\n\n score = Math.min(100, score);\n const recommendations = score < 60\n ? [{ severity: 'critical' as const, message: '테스트 환경 미구성', action: '테스트 프레임워크와 테스트 디렉토리를 추가하세요' }]\n : [];\n\n return { name: '테스트 커버리지', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkCiCd(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const ciConfigs = [\n { path: '.github/workflows', label: 'GitHub Actions' },\n { path: '.gitlab-ci.yml', label: 'GitLab CI' },\n { path: 'Jenkinsfile', label: 'Jenkins' },\n { path: '.circleci', label: 'CircleCI' },\n ];\n\n for (const { path, label } of ciConfigs) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 40;\n }\n\n score = Math.min(100, score);\n const recommendations = score === 0\n ? [{ severity: 'critical' as const, message: 'CI/CD 미구성', action: 'GitHub Actions 또는 다른 CI 파이프라인을 설정하세요' }]\n : [];\n\n return { name: 'CI/CD', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkHooks(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const hookConfigs = [\n { path: '.husky', label: 'Husky' },\n { path: '.lintstagedrc', label: 'lint-staged' },\n { path: '.lintstagedrc.json', label: 'lint-staged (json)' },\n { path: 'commitlint.config.js', label: 'commitlint' },\n { path: '.claude/settings.json', label: 'Claude Code settings' },\n ];\n\n for (const { path, label } of hookConfigs) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 20;\n }\n\n score = Math.min(100, score);\n const recommendations = score < 40\n ? [{ severity: 'warning' as const, message: '훅 기반 검증 부족', action: 'Husky + lint-staged를 설정하여 커밋 전 검증을 추가하세요' }]\n : [];\n\n return { name: '훅 기반 검증', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkRepoStructure(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const structureChecks = [\n { path: 'src', label: 'src/ 디렉토리' },\n { path: 'package.json', label: '의존성 관리' },\n { path: '.env.example', label: '환경변수 예시' },\n { path: '.gitignore', label: '.gitignore' },\n ];\n\n for (const { path, label } of structureChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 25;\n }\n\n score = Math.min(100, score);\n return { name: '리포지토리 구조', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n\nasync function checkDocumentation(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const docChecks = [\n { path: 'README.md', label: 'README.md', points: 30 },\n { path: 'CONTRIBUTING.md', label: 'CONTRIBUTING.md', points: 20 },\n { path: 'docs', label: 'docs/ 디렉토리', points: 25 },\n { path: 'docs/openspec.md', label: 'OpenSpec PRD', points: 25 },\n ];\n\n for (const { path, label, points } of docChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += points;\n }\n\n score = Math.min(100, score);\n return { name: '문서화 수준', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n\nasync function checkHarnessEngineering(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const harnessChecks = [\n { path: 'CLAUDE.md', label: 'CLAUDE.md', points: 25 },\n { path: 'AGENTS.md', label: 'AGENTS.md', points: 15 },\n { path: '.claude/settings.json', label: '.claude/settings.json', points: 20 },\n { path: '.claude/skills', label: '.claude/skills/', points: 20 },\n { path: '.claude/commands', label: '.claude/commands/', points: 10 },\n { path: '.pai/config.json', label: 'PAI config', points: 10 },\n ];\n\n for (const { path, label, points } of harnessChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += points;\n }\n\n score = Math.min(100, score);\n return { name: '하네스 엔지니어링', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n","/**\n * Stage — 파이프라인 단계의 계약\n *\n * 모든 파이프라인 단계는 이 인터페이스를 구현합니다.\n * Stage 간 직접 import는 금지 — previousResults를 통해서만 이전 결과 접근.\n */\n\nexport type StageName =\n | 'environment'\n | 'design'\n | 'execution'\n | 'validation'\n | 'evaluation';\n\nexport interface StageError {\n code: string;\n message: string;\n recoverable: boolean;\n}\n\nexport interface StageResult {\n stage: StageName;\n status: 'success' | 'partial' | 'failed' | 'skipped';\n data: Record<string, unknown>;\n artifacts: string[];\n duration: number;\n errors: StageError[];\n}\n\nexport interface StageInput {\n cwd: string;\n config: PaiConfig;\n previousResults: ReadonlyMap<StageName, StageResult>;\n}\n\nexport interface Stage {\n name: StageName;\n run(input: StageInput): Promise<StageResult>;\n canSkip(input: StageInput): boolean;\n}\n\n/**\n * PAI 프로젝트 개발 수준.\n * - `prototype` — 빠른 검증용 (아이디어 정리, UI 목업, 컨셉 시연)\n * - `poc` — PoC 웹개발 (동작 데모, 기본 기능 구현)\n * - `production`— 운영 서비스 (테스트/QA/배포/모니터링)\n *\n * v0.11.1 이전 버전은 `mockup | production` 이분법을 사용했다.\n * 레거시 `mockup`은 `loadConfig()`에서 `prototype`으로 자동 매핑된다.\n */\nexport type Mode = 'prototype' | 'poc' | 'production';\n\n/** 레거시 모드 — 로드 시 Mode로 정규화됨. 저장/코드 분기에는 사용 금지. */\nexport type LegacyMode = 'mockup';\n\nexport interface PaiConfig {\n version: string;\n mode: Mode;\n projectName: string;\n installedAt: string;\n plugins: string[];\n evaluation?: {\n categories?: Record<string, { weight?: number; tier?: 'must' | 'nice' }>;\n };\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n}\n\nexport const STAGE_ORDER: readonly StageName[] = [\n 'environment',\n 'design',\n 'execution',\n 'validation',\n 'evaluation',\n] as const;\n","/**\n * Scoring types — vibe-ready-cli에서 내재화\n * 품질 평가 점수 시스템 타입들\n */\n\nexport type Grade = 'A' | 'B' | 'C' | 'D' | 'F';\nexport type CategoryTier = 'must' | 'nice';\n\nexport interface RawFinding {\n item: string;\n found: boolean;\n details: string;\n}\n\nexport interface Recommendation {\n severity: 'critical' | 'warning' | 'info';\n message: string;\n action: string;\n}\n\nexport interface CategoryResult {\n name: string;\n tier: CategoryTier;\n score: number;\n grade: Grade;\n recommendations: Recommendation[];\n rawFindings: RawFinding[];\n}\n\nexport interface EvaluationResult {\n categories: CategoryResult[];\n totalScore: number;\n totalGrade: Grade;\n summary: string;\n penaltyApplied: boolean;\n penaltyReason?: string;\n}\n\nexport interface LLMCategoryOutput {\n name: string;\n tier: CategoryTier;\n score: number;\n recommendations: Recommendation[];\n rawFindings: RawFinding[];\n}\n\nexport interface LLMAnalysisOutput {\n categories: LLMCategoryOutput[];\n summary: string;\n}\n\nexport interface CategoryWeight {\n name: string;\n tier: CategoryTier;\n weight: number;\n}\n\nexport const DEFAULT_CATEGORY_WEIGHTS: CategoryWeight[] = [\n { name: '테스트 커버리지', tier: 'must', weight: 0.20 },\n { name: 'CI/CD', tier: 'must', weight: 0.20 },\n { name: '훅 기반 검증', tier: 'must', weight: 0.20 },\n { name: '리포지토리 구조', tier: 'nice', weight: 0.133 },\n { name: '문서화 수준', tier: 'nice', weight: 0.133 },\n { name: '하네스 엔지니어링', tier: 'nice', weight: 0.134 },\n];\n\nexport function gradeFromScore(score: number): Grade {\n if (score >= 90) return 'A';\n if (score >= 80) return 'B';\n if (score >= 70) return 'C';\n if (score >= 50) return 'D';\n return 'F';\n}\n","export type {\n StageName,\n StageError,\n StageResult,\n StageInput,\n Stage,\n PaiConfig,\n Mode,\n LegacyMode,\n} from './stage.js';\nexport { STAGE_ORDER } from './stage.js';\n\nexport type {\n StackInfo,\n RepoStructure,\n ExistingConfig,\n GitInfo,\n AnalysisResult,\n} from './analysis.js';\n\nexport type {\n Grade,\n CategoryTier,\n RawFinding,\n Recommendation,\n CategoryResult,\n EvaluationResult,\n LLMCategoryOutput,\n LLMAnalysisOutput,\n CategoryWeight,\n} from './scoring.js';\nexport { gradeFromScore, DEFAULT_CATEGORY_WEIGHTS } from './scoring.js';\n","/**\n * Scorer — vibe-ready-cli에서 내재화\n * 가중 평균 + 페널티 로직\n */\nimport type {\n CategoryResult,\n CategoryTier,\n EvaluationResult,\n Grade,\n LLMAnalysisOutput,\n CategoryWeight,\n} from '../../core/types/index.js';\nimport { gradeFromScore, DEFAULT_CATEGORY_WEIGHTS } from '../../core/types/index.js';\n\nexport function computeResult(\n llmOutput: LLMAnalysisOutput,\n customWeights?: CategoryWeight[],\n): EvaluationResult {\n const weights = customWeights ?? DEFAULT_CATEGORY_WEIGHTS;\n\n const categories: CategoryResult[] = llmOutput.categories.map((cat) => ({\n name: cat.name,\n tier: cat.tier,\n score: Math.round(Math.max(0, Math.min(100, cat.score))),\n grade: gradeFromScore(Math.max(0, Math.min(100, cat.score))),\n recommendations: cat.recommendations,\n rawFindings: cat.rawFindings,\n }));\n\n const totalScore = computeWeightedAverage(categories, weights);\n let totalGrade = gradeFromScore(totalScore);\n\n const { penaltyApplied, penaltyReason } = checkPenalty(categories);\n if (penaltyApplied && gradeRank(totalGrade) > gradeRank('C')) {\n totalGrade = 'C';\n }\n\n return {\n categories,\n totalScore,\n totalGrade,\n summary: llmOutput.summary,\n penaltyApplied,\n penaltyReason,\n };\n}\n\nfunction computeWeightedAverage(\n categories: CategoryResult[],\n weights: CategoryWeight[],\n): number {\n let weightedSum = 0;\n let totalWeight = 0;\n\n for (const cat of categories) {\n const config = weights.find((w) => w.name === cat.name);\n const weight = config?.weight ?? (cat.tier === 'must' ? 0.20 : 0.133);\n weightedSum += cat.score * weight;\n totalWeight += weight;\n }\n\n if (totalWeight === 0) return 0;\n return Math.round((weightedSum / totalWeight) * 100) / 100;\n}\n\nfunction checkPenalty(categories: CategoryResult[]): {\n penaltyApplied: boolean;\n penaltyReason?: string;\n} {\n const failedMust = categories.filter(\n (c) => c.tier === 'must' && c.grade === 'F',\n );\n\n if (failedMust.length > 0) {\n const names = failedMust.map((c) => c.name).join(', ');\n return {\n penaltyApplied: true,\n penaltyReason: `필수 카테고리 F 등급: ${names} → 전체 등급 최대 C로 제한`,\n };\n }\n\n return { penaltyApplied: false };\n}\n\nfunction gradeRank(grade: Grade): number {\n const ranks: Record<Grade, number> = { A: 4, B: 3, C: 2, D: 1, F: 0 };\n return ranks[grade];\n}\n","/**\n * Reporter — 터미널/Markdown 출력\n */\nimport chalk from 'chalk';\nimport type { EvaluationResult, CategoryResult, Grade } from '../../core/types/index.js';\n\nconst GRADE_COLORS: Record<Grade, (s: string) => string> = {\n A: chalk.hex('#6BCB77'),\n B: chalk.hex('#7B93DB'),\n C: chalk.hex('#E2B340'),\n D: chalk.hex('#E06C75'),\n F: chalk.hex('#CC4444'),\n};\n\nexport function printReport(result: EvaluationResult): void {\n console.log('');\n console.log(chalk.hex('#7B93DB')(' PAI Evaluation Report'));\n console.log(chalk.gray(' ─────────────────────────────────'));\n console.log('');\n\n // Overall score\n const gradeColor = GRADE_COLORS[result.totalGrade];\n console.log(` 종합 점수: ${gradeColor(String(result.totalScore))} / 100 등급: ${gradeColor(result.totalGrade)}`);\n\n if (result.penaltyApplied) {\n console.log(chalk.red(` ⚠ ${result.penaltyReason}`));\n }\n\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n\n // Category breakdown\n for (const cat of result.categories) {\n const color = GRADE_COLORS[cat.grade];\n const tierLabel = cat.tier === 'must' ? chalk.hex('#E06C75')('[필수]') : chalk.gray('[선택]');\n const bar = renderBar(cat.score);\n console.log(` ${tierLabel} ${cat.name.padEnd(16)} ${bar} ${color(`${cat.score}`).padStart(12)} ${color(cat.grade)}`);\n }\n\n console.log('');\n console.log(chalk.gray(` ${result.summary}`));\n console.log('');\n}\n\nexport function printVerboseFindings(result: EvaluationResult): void {\n for (const cat of result.categories) {\n console.log('');\n console.log(chalk.bold(` ${cat.name} (${cat.grade}, ${cat.score}점)`));\n\n for (const f of cat.rawFindings) {\n const icon = f.found ? chalk.green('✓') : chalk.red('✗');\n console.log(` ${icon} ${f.item} — ${f.details}`);\n }\n\n for (const r of cat.recommendations) {\n const severity = r.severity === 'critical' ? chalk.red('!') : r.severity === 'warning' ? chalk.yellow('!') : chalk.gray('i');\n console.log(` ${severity} ${r.message}`);\n console.log(chalk.gray(` → ${r.action}`));\n }\n }\n}\n\nfunction renderBar(score: number): string {\n const width = 20;\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 80 ? chalk.hex('#6BCB77') : score >= 60 ? chalk.hex('#E2B340') : chalk.hex('#E06C75');\n return color('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n}\n\nexport function buildMarkdownReport(result: EvaluationResult): string {\n const lines: string[] = [\n '# PAI Evaluation Report',\n '',\n `> 생성일시: ${new Date().toLocaleString('ko-KR')}`,\n '',\n `## 종합 점수: ${result.totalScore}/100 — 등급 ${result.totalGrade}`,\n '',\n ];\n\n if (result.penaltyApplied) {\n lines.push(`> ⚠ ${result.penaltyReason}`);\n lines.push('');\n }\n\n lines.push('## 카테고리별 상세');\n lines.push('');\n lines.push('| 카테고리 | 분류 | 점수 | 등급 |');\n lines.push('|---------|------|------|------|');\n\n for (const cat of result.categories) {\n const tier = cat.tier === 'must' ? '필수' : '선택';\n lines.push(`| ${cat.name} | ${tier} | ${cat.score} | ${cat.grade} |`);\n }\n\n lines.push('');\n lines.push('## 권고사항');\n lines.push('');\n\n const allRecs = result.categories.flatMap((c) =>\n c.recommendations.map((r) => ({ ...r, category: c.name })),\n );\n\n if (allRecs.length === 0) {\n lines.push('모든 항목이 양호합니다!');\n } else {\n for (const r of allRecs) {\n const icon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : 'ℹ️';\n lines.push(`- ${icon} **${r.category}**: ${r.message}`);\n lines.push(` - ${r.action}`);\n }\n }\n\n lines.push('');\n lines.push(`## 요약`);\n lines.push('');\n lines.push(result.summary);\n lines.push('');\n lines.push('---');\n lines.push('*Generated by PAI (Plugin-based AI)*');\n\n return lines.join('\\n') + '\\n';\n}\n\nexport function buildDetailedReport(result: EvaluationResult, projectName: string): string {\n const now = new Date().toLocaleString('ko-KR');\n const mustCats = result.categories.filter((c) => c.tier === 'must');\n const niceCats = result.categories.filter((c) => c.tier === 'nice');\n\n const lines: string[] = [\n `# ${projectName} 바이브 코딩 준비도 분석 리포트`,\n '',\n `> 스캔 일시: ${now}`,\n `> 분석 대상: ${projectName}`,\n '',\n '---',\n '',\n '## 요약',\n '',\n `${projectName}의 바이브 코딩 준비도 종합 점수는 **${result.totalScore}/100 (${result.totalGrade}등급)**입니다.`,\n '',\n ];\n\n if (result.penaltyApplied) {\n lines.push(`> ⚠ ${result.penaltyReason}`);\n lines.push('');\n }\n\n // Grade description\n if (result.totalGrade === 'A') {\n lines.push('AI 지원 코딩 워크플로우를 활용할 준비가 잘 되어 있습니다.');\n } else if (result.totalGrade === 'B') {\n lines.push('대부분 준비되어 있으며, 일부 개선으로 최적의 바이브 코딩 환경을 구축할 수 있습니다.');\n } else if (result.totalGrade === 'C') {\n lines.push('기본적인 구조는 갖추고 있으나, 바이브 코딩의 잠재력을 충분히 활용하려면 개선이 필요합니다.');\n } else if (result.totalGrade === 'D') {\n lines.push('AI 지원 코딩 워크플로우를 본격적으로 활용하기에는 상당한 개선이 필요한 상태입니다.');\n } else {\n lines.push('바이브 코딩 환경이 거의 구성되지 않은 상태로, 기본 설정부터 시작해야 합니다.');\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // Category overview table\n lines.push('## 항목별 현황');\n lines.push('');\n lines.push('| 항목 | 분류 | 점수 | 등급 | 가중치 |');\n lines.push('|------|------|------|------|--------|');\n\n for (const cat of result.categories) {\n const tier = cat.tier === 'must' ? '**필수**' : '선택';\n lines.push(`| ${cat.name} | ${tier} | ${cat.score}/100 | ${cat.grade} | ${cat.tier === 'must' ? '20%' : '13.3%'} |`);\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // Detailed analysis per category\n lines.push('## 항목별 상세 분석');\n lines.push('');\n\n for (const cat of result.categories) {\n const tierLabel = cat.tier === 'must' ? '필수' : '선택';\n lines.push(`### ${cat.name} (${tierLabel}, 가중치 ${cat.tier === 'must' ? '20%' : '13.3%'}) — ${cat.grade}등급`);\n lines.push('');\n\n // Raw findings\n if (cat.rawFindings.length > 0) {\n lines.push('**점검 결과:**');\n lines.push('');\n for (const f of cat.rawFindings) {\n const icon = f.found ? '✅' : '❌';\n lines.push(`- ${icon} ${f.item} — ${f.details}`);\n }\n lines.push('');\n }\n\n // Grade assessment\n if (cat.grade === 'A' || cat.grade === 'B') {\n lines.push(`**평가:** 양호한 상태입니다.`);\n } else if (cat.grade === 'C') {\n lines.push(`**평가:** 기본은 갖추고 있으나 추가 개선이 권장됩니다.`);\n } else if (cat.grade === 'D') {\n lines.push(`**평가:** 개선이 필요합니다.`);\n } else {\n lines.push(`**평가:** 시급한 개선이 필요합니다.`);\n }\n lines.push('');\n\n // Recommendations\n if (cat.recommendations.length > 0) {\n lines.push('**권고사항:**');\n lines.push('');\n for (const r of cat.recommendations) {\n const icon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : 'ℹ️';\n lines.push(`- ${icon} ${r.message}`);\n lines.push(` - → ${r.action}`);\n }\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n }\n\n // Improvement roadmap\n lines.push('## 개선 로드맵');\n lines.push('');\n\n const critical = result.categories.filter((c) => c.grade === 'F');\n const warning = result.categories.filter((c) => c.grade === 'D');\n const ok = result.categories.filter((c) => c.grade === 'C' || c.grade === 'B' || c.grade === 'A');\n\n if (critical.length > 0) {\n lines.push('### 즉시 개선 필요 (F등급)');\n lines.push('');\n lines.push('| 항목 | 현재 점수 | 목표 | 조치 |');\n lines.push('|------|----------|------|------|');\n for (const c of critical) {\n const action = c.recommendations[0]?.action ?? '설정 추가 필요';\n lines.push(`| ${c.name} | ${c.score}점 (F) | 50점+ (D) | ${action} |`);\n }\n lines.push('');\n }\n\n if (warning.length > 0) {\n lines.push('### 단기 개선 권장 (D등급)');\n lines.push('');\n lines.push('| 항목 | 현재 점수 | 목표 | 조치 |');\n lines.push('|------|----------|------|------|');\n for (const c of warning) {\n const action = c.recommendations[0]?.action ?? '추가 설정 권장';\n lines.push(`| ${c.name} | ${c.score}점 (D) | 70점+ (C) | ${action} |`);\n }\n lines.push('');\n }\n\n if (ok.length > 0) {\n lines.push('### 양호 (C등급 이상)');\n lines.push('');\n for (const c of ok) {\n lines.push(`- ✅ ${c.name}: ${c.score}점 (${c.grade})`);\n }\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n\n // Conclusion\n lines.push('## 결론');\n lines.push('');\n lines.push(result.summary);\n lines.push('');\n\n if (result.totalGrade === 'F' || result.totalGrade === 'D') {\n const immediateActions = critical.length + warning.length;\n lines.push(`즉시 개선 가능한 ${immediateActions}개 항목을 완료하면 점수를 크게 끌어올릴 수 있습니다.`);\n } else if (result.totalGrade === 'C') {\n lines.push('기본 구조가 잘 갖추어져 있으며, 단기 개선 항목을 마무리하면 B등급 달성이 가능합니다.');\n } else {\n lines.push('바이브 코딩 환경이 잘 구성되어 있습니다. 지속적인 품질 관리를 권장합니다.');\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('*PAI Zero (Plugin AI for ProjectZero) + Claude Code로 생성됨*');\n\n return lines.join('\\n') + '\\n';\n}\n","/**\n * Shell CD Helper — 부모 쉘 디렉토리 자동 이동 지원\n * macOS/Linux: bash/zsh 함수 → .zshrc/.bashrc\n * Windows: PowerShell 함수 → $PROFILE\n */\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport fs from 'fs-extra';\nimport { isWindows, getShellRcPath } from './platform.js';\n\nconst PAI_DIR = join(homedir(), '.pai');\nconst CD_FILE = join(PAI_DIR, '.cd-after');\nconst HELPER_FILE_SH = join(PAI_DIR, 'shell-helper.sh');\nconst HELPER_FILE_PS1 = join(PAI_DIR, 'shell-helper.ps1');\n\nconst BASH_HELPER = `# PAI shell helper — 자동 디렉토리 이동 지원\npai() {\n local cd_target=\"$HOME/.pai/.cd-after\"\n rm -f \"$cd_target\"\n PAI_CD_AFTER=\"$cd_target\" command npx pai-zero \"$@\"\n local exit_code=$?\n if [ -f \"$cd_target\" ]; then\n local dir\n dir=\"$(cat \"$cd_target\")\"\n rm -f \"$cd_target\"\n if [ -n \"$dir\" ] && [ -d \"$dir\" ]; then\n cd \"$dir\" || true\n echo \" → cd $dir\"\n fi\n fi\n return $exit_code\n}\n`;\n\nconst POWERSHELL_HELPER = `# PAI shell helper — 자동 디렉토리 이동 지원\nfunction pai {\n $cdTarget = Join-Path $env:USERPROFILE '.pai\\\\.cd-after'\n Remove-Item $cdTarget -ErrorAction SilentlyContinue\n $env:PAI_CD_AFTER = $cdTarget\n & npx pai-zero @args\n $exitCode = $LASTEXITCODE\n if (Test-Path $cdTarget) {\n $dir = Get-Content $cdTarget -Raw\n Remove-Item $cdTarget -ErrorAction SilentlyContinue\n if ($dir -and (Test-Path $dir)) {\n Set-Location $dir\n Write-Host \" -> cd $dir\"\n }\n }\n return $exitCode\n}\n`;\n\n/**\n * .cd-after 파일에 이동할 디렉토리를 기록\n */\nexport async function requestCdAfter(targetDir: string): Promise<void> {\n await fs.ensureDir(PAI_DIR);\n await fs.writeFile(CD_FILE, targetDir);\n}\n\n/**\n * 쉘 헬퍼 파일 생성 + RC 파일에 등록\n * @returns true if already installed\n */\nexport async function installShellHelper(): Promise<boolean> {\n await fs.ensureDir(PAI_DIR);\n\n if (isWindows) {\n return installPowerShellHelper();\n }\n return installBashHelper();\n}\n\nasync function installBashHelper(): Promise<boolean> {\n await fs.writeFile(HELPER_FILE_SH, BASH_HELPER);\n\n const rcFile = getShellRcPath();\n const sourceLine = 'source \"$HOME/.pai/shell-helper.sh\"';\n\n if (await fs.pathExists(rcFile)) {\n const content = await fs.readFile(rcFile, 'utf8');\n if (content.includes('shell-helper.sh')) {\n return true;\n }\n await fs.appendFile(rcFile, `\\n# PAI — 자동 디렉토리 이동\\n${sourceLine}\\n`);\n return false;\n }\n\n await fs.writeFile(rcFile, `${sourceLine}\\n`);\n return false;\n}\n\nasync function installPowerShellHelper(): Promise<boolean> {\n await fs.writeFile(HELPER_FILE_PS1, POWERSHELL_HELPER);\n\n const rcFile = getShellRcPath();\n const sourceLine = '. \"$env:USERPROFILE\\\\.pai\\\\shell-helper.ps1\"';\n\n await fs.ensureDir(join(rcFile, '..'));\n\n if (await fs.pathExists(rcFile)) {\n const content = await fs.readFile(rcFile, 'utf8');\n if (content.includes('shell-helper.ps1')) {\n return true;\n }\n await fs.appendFile(rcFile, `\\n# PAI — 자동 디렉토리 이동\\n${sourceLine}\\n`);\n return false;\n }\n\n await fs.writeFile(rcFile, `${sourceLine}\\n`);\n return false;\n}\n","/**\n * Claude Code ~/.claude/settings.json 안전 병합 유틸\n *\n * - 크로스플랫폼 (macOS / Windows / Linux) — 경로/파일명 차이 흡수\n * - 기존 필드 보존 (deep merge)\n * - BOM 포함 JSON 파싱 지원 (한국어 Windows 환경)\n * - 쓰기 전 타임스탬프 백업 생성\n */\nimport os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { sanitizeFilenameForWindows } from './platform.js';\n\nconst DEFAULT_MARKETPLACE_ID = 'omc';\nconst DEFAULT_MARKETPLACE_URL = 'https://github.com/Yeachan-Heo/oh-my-claudecode.git';\nconst DEFAULT_PLUGIN_ID = 'oh-my-claudecode@omc';\n\nexport interface EnableOmcOptions {\n marketplaceId?: string; // 기본: omc\n marketplaceUrl?: string; // 기본: OMC GitHub repo\n pluginId?: string; // 기본: oh-my-claudecode@omc\n backup?: boolean; // 기본: true\n}\n\nexport type EnableOmcAction =\n | 'added' // 신규 등록\n | 'already-enabled' // 이미 등록됨 — 파일 수정 없음\n | 'created'; // settings.json 자체를 신규 생성\n\nexport interface EnableOmcResult {\n action: EnableOmcAction;\n settingsPath: string;\n backupPath?: string;\n}\n\nexport class ClaudeSettingsError extends Error {\n constructor(message: string, public readonly backupPath?: string) {\n super(message);\n this.name = 'ClaudeSettingsError';\n }\n}\n\n/**\n * ~/.claude/settings.json 경로. 플랫폼 독립.\n */\nexport function getClaudeSettingsPath(homeDir: string = os.homedir()): string {\n return path.join(homeDir, '.claude', 'settings.json');\n}\n\n/**\n * BOM(0xFEFF) 포함 JSON 안전 파싱. 한국어 Windows에서 일부 에디터가 UTF-8 BOM 삽입.\n */\nfunction parseJsonWithBom(raw: string): unknown {\n const stripped = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;\n return JSON.parse(stripped);\n}\n\nfunction timestampSuffix(): string {\n // ISO8601에서 Windows 금지 문자(:) 제거\n return sanitizeFilenameForWindows(new Date().toISOString());\n}\n\n/**\n * OMC 마켓플레이스 + 플러그인 활성화 정보를 ~/.claude/settings.json 에 병합.\n *\n * - 파일 없음 → 최소 스켈레톤 생성\n * - 이미 등록됨 → no-op, 'already-enabled' 반환\n * - 기존 필드 → 모두 보존 (deep merge)\n * - 손상된 JSON → 백업 후 ClaudeSettingsError throw (덮어쓰지 않음)\n */\nexport async function enableOmcPlugin(\n options: EnableOmcOptions = {},\n): Promise<EnableOmcResult> {\n const marketplaceId = options.marketplaceId ?? DEFAULT_MARKETPLACE_ID;\n const marketplaceUrl = options.marketplaceUrl ?? DEFAULT_MARKETPLACE_URL;\n const pluginId = options.pluginId ?? DEFAULT_PLUGIN_ID;\n const wantBackup = options.backup ?? true;\n\n const settingsPath = getClaudeSettingsPath();\n await fs.ensureDir(path.dirname(settingsPath));\n\n // ── 1. 파일 없음 → 신규 생성 ────────────────\n if (!(await fs.pathExists(settingsPath))) {\n const skeleton = buildSkeleton(marketplaceId, marketplaceUrl, pluginId);\n await fs.writeFile(settingsPath, JSON.stringify(skeleton, null, 2) + '\\n', 'utf8');\n return { action: 'created', settingsPath };\n }\n\n // ── 2. 읽기 + BOM 처리 + 파싱 ────────────────\n const raw = await fs.readFile(settingsPath, 'utf8');\n let parsed: Record<string, unknown>;\n try {\n const value = parseJsonWithBom(raw);\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('settings.json is not a JSON object');\n }\n parsed = value as Record<string, unknown>;\n } catch (err) {\n // 손상된 JSON — 백업 후 중단 (절대 덮어쓰지 않음)\n const backupPath = `${settingsPath}.backup-${timestampSuffix()}`;\n await fs.copy(settingsPath, backupPath);\n throw new ClaudeSettingsError(\n `settings.json 파싱 실패: ${(err as Error).message}. 백업: ${backupPath}`,\n backupPath,\n );\n }\n\n // ── 3. 이미 등록됨? ────────────────\n if (isAlreadyEnabled(parsed, marketplaceId, pluginId)) {\n return { action: 'already-enabled', settingsPath };\n }\n\n // ── 4. 백업 ────────────────\n let backupPath: string | undefined;\n if (wantBackup) {\n backupPath = `${settingsPath}.backup-${timestampSuffix()}`;\n await fs.copy(settingsPath, backupPath);\n }\n\n // ── 5. deep merge 후 저장 ────────────────\n const merged = mergeOmcIntoSettings(parsed, marketplaceId, marketplaceUrl, pluginId);\n await fs.writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf8');\n\n return { action: 'added', settingsPath, backupPath };\n}\n\n/* ─────────────────────────────────────────────────────────────\n * 내부 헬퍼 (export는 테스트용)\n * ─────────────────────────────────────────────────────────── */\n\nexport function buildSkeleton(\n marketplaceId: string,\n marketplaceUrl: string,\n pluginId: string,\n): Record<string, unknown> {\n return {\n extraKnownMarketplaces: {\n [marketplaceId]: {\n source: { source: 'git', url: marketplaceUrl },\n },\n },\n enabledPlugins: {\n [pluginId]: true,\n },\n };\n}\n\nexport function isAlreadyEnabled(\n settings: Record<string, unknown>,\n marketplaceId: string,\n pluginId: string,\n): boolean {\n const markets = settings['extraKnownMarketplaces'];\n const enabled = settings['enabledPlugins'];\n const hasMarket =\n typeof markets === 'object' &&\n markets !== null &&\n marketplaceId in (markets as Record<string, unknown>);\n const hasPlugin =\n typeof enabled === 'object' &&\n enabled !== null &&\n (enabled as Record<string, unknown>)[pluginId] === true;\n return hasMarket && hasPlugin;\n}\n\nexport function mergeOmcIntoSettings(\n settings: Record<string, unknown>,\n marketplaceId: string,\n marketplaceUrl: string,\n pluginId: string,\n): Record<string, unknown> {\n const next: Record<string, unknown> = { ...settings };\n\n const existingMarkets =\n typeof next['extraKnownMarketplaces'] === 'object' && next['extraKnownMarketplaces'] !== null\n ? { ...(next['extraKnownMarketplaces'] as Record<string, unknown>) }\n : {};\n existingMarkets[marketplaceId] = {\n source: { source: 'git', url: marketplaceUrl },\n };\n next['extraKnownMarketplaces'] = existingMarkets;\n\n const existingPlugins =\n typeof next['enabledPlugins'] === 'object' && next['enabledPlugins'] !== null\n ? { ...(next['enabledPlugins'] as Record<string, unknown>) }\n : {};\n existingPlugins[pluginId] = true;\n next['enabledPlugins'] = existingPlugins;\n\n return next;\n}\n","/**\n * Cache — SHA256 기반 레포 해시, TTL 24시간\n */\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { LLMAnalysisOutput } from '../../core/types/index.js';\n\nconst CACHE_DIR = '.pai';\nconst CACHE_FILE = 'cache/evaluation.json';\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\ninterface CacheEntry {\n repoPath: string;\n repoHash: string;\n timestamp: number;\n llmOutput: LLMAnalysisOutput;\n}\n\ninterface CacheStore {\n version: 1;\n entries: Record<string, CacheEntry>;\n}\n\nconst FILES_TO_HASH = [\n 'package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml',\n 'tsconfig.json', 'jest.config.ts', 'vitest.config.ts',\n '.github/workflows', '.gitlab-ci.yml',\n '.husky', '.lintstagedrc',\n 'CLAUDE.md', 'AGENTS.md', '.cursorrules',\n 'README.md', 'CONTRIBUTING.md',\n];\n\nexport function computeRepoHash(repoPath: string): string {\n const hash = createHash('sha256');\n for (const file of FILES_TO_HASH) {\n const fullPath = join(repoPath, file);\n try {\n const content = readFileSync(fullPath);\n hash.update(`${file}:${content.length}`);\n } catch {\n hash.update(`${file}:missing`);\n }\n }\n return hash.digest('hex').slice(0, 16);\n}\n\nfunction getCachePath(repoPath: string): string {\n return join(repoPath, CACHE_DIR, CACHE_FILE);\n}\n\nfunction loadCache(repoPath: string): CacheStore {\n try {\n const data = readFileSync(getCachePath(repoPath), 'utf-8');\n return JSON.parse(data) as CacheStore;\n } catch {\n return { version: 1, entries: {} };\n }\n}\n\nfunction saveCache(repoPath: string, store: CacheStore): void {\n const cacheDir = join(repoPath, CACHE_DIR, 'cache');\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n writeFileSync(getCachePath(repoPath), JSON.stringify(store, null, 2));\n}\n\nexport function getCachedResult(repoPath: string): LLMAnalysisOutput | null {\n const store = loadCache(repoPath);\n const repoHash = computeRepoHash(repoPath);\n const entry = store.entries[repoHash];\n\n if (!entry) return null;\n if (Date.now() - entry.timestamp > CACHE_TTL_MS) return null;\n\n return entry.llmOutput;\n}\n\nexport function setCachedResult(repoPath: string, llmOutput: LLMAnalysisOutput): void {\n const store = loadCache(repoPath);\n const repoHash = computeRepoHash(repoPath);\n\n // Cleanup expired entries\n const now = Date.now();\n for (const [key, entry] of Object.entries(store.entries)) {\n if (now - entry.timestamp > CACHE_TTL_MS) {\n delete store.entries[key];\n }\n }\n\n store.entries[repoHash] = { repoPath, repoHash, timestamp: now, llmOutput };\n saveCache(repoPath, store);\n}\n","import { join, basename } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\nimport { analyzeRepository } from '../../stages/evaluation/analyzer.js';\nimport { computeResult } from '../../stages/evaluation/scorer.js';\nimport { getCachedResult, setCachedResult } from '../../stages/evaluation/cache.js';\nimport { printReport, printVerboseFindings, buildDetailedReport } from '../../stages/evaluation/reporter.js';\nimport { loadConfig } from '../../core/config.js';\n\nexport interface EvaluateOptions {\n failUnder?: number;\n verbose?: boolean;\n output?: string;\n cache?: boolean;\n}\n\nexport async function evaluateCommand(cwd: string, options: EvaluateOptions): Promise<void> {\n const useCache = options.cache !== false;\n\n // Analyze\n let llmOutput = useCache ? getCachedResult(cwd) : null;\n if (llmOutput) {\n ui.info('캐시된 결과 사용 (24시간 이내)');\n } else {\n llmOutput = await analyzeRepository(cwd);\n if (useCache) {\n setCachedResult(cwd, llmOutput);\n }\n }\n\n const result = computeResult(llmOutput);\n\n // Print to terminal\n printReport(result);\n\n if (options.verbose) {\n printVerboseFindings(result);\n }\n\n // Auto-save detailed report to docs/p-reports/YYYY-MM-DD.md\n const config = await loadConfig(cwd);\n const projectName = config?.projectName ?? basename(cwd);\n const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD\n const reportDir = join(cwd, 'docs', 'p-reports');\n const reportPath = join(reportDir, `${today}.md`);\n\n await fs.ensureDir(reportDir);\n const detailedReport = buildDetailedReport(result, projectName);\n await fs.writeFile(reportPath, detailedReport, 'utf8');\n\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n console.log('');\n\n // Cat the report\n console.log(detailedReport);\n\n // Custom output path (optional)\n if (options.output) {\n await fs.writeFile(options.output, detailedReport, 'utf8');\n ui.success(`추가 저장: ${options.output}`);\n }\n\n // Fail-under check\n if (options.failUnder && result.totalScore < options.failUnder) {\n ui.error(`점수 ${result.totalScore}이 최소 기준 ${options.failUnder}에 미달합니다.`);\n process.exitCode = 1;\n }\n}\n","import * as ui from '../../ui/index.js';\nimport {\n scanProjectState,\n PLUGIN_META,\n getPluginsForMode,\n nextMode,\n pluginsAddedByPromotion,\n} from '../../core/detector.js';\nimport { loadConfig, createDefaultConfig, saveConfig } from '../../core/config.js';\nimport { runProvisioners, type ProvisionerContext } from '../../stages/environment/provisioners/registry.js';\nimport { runDoctor } from '../../stages/environment/doctor.js';\nimport { analyzeProject } from '../../stages/environment/analyzer.js';\nimport { colors as c } from '../../ui/logger.js';\nimport type { Mode } from '../../core/types/index.js';\n\nexport async function envSetupCommand(cwd: string): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const { basename } = await import('node:path');\n\n ui.section('플러그인 추가 · 모드 승격');\n const state = await scanProjectState(cwd);\n const existingConfig = await loadConfig(cwd);\n const currentMode: Mode = state.projectMode ?? existingConfig?.mode ?? 'prototype';\n\n // ── 1. 모드 승격 제안 ────────────────────────────\n const upgradeTarget = nextMode(currentMode);\n let promotedMode: Mode | null = null;\n const autoPluginsFromPromotion: string[] = [];\n\n if (upgradeTarget) {\n const addedPlugins = pluginsAddedByPromotion(currentMode, upgradeTarget);\n const notYetInstalled = addedPlugins.filter((k) => !(state.details[k]?.installed ?? false));\n\n console.log('');\n console.log(c.dim(` 현재 모드: ${c.accent(currentMode)}`));\n console.log(c.dim(` 다음 단계: ${c.accent(upgradeTarget)}`));\n if (notYetInstalled.length > 0) {\n console.log(c.dim(` 승격 시 추가되는 플러그인: ${notYetInstalled.join(', ')}`));\n }\n console.log('');\n\n const { promote } = await inquirer.prompt([{\n type: 'confirm',\n name: 'promote',\n message: `${upgradeTarget} 수준으로 승격하시겠어요?`,\n default: true,\n }]);\n\n if (promote) {\n promotedMode = upgradeTarget;\n autoPluginsFromPromotion.push(...notYetInstalled);\n }\n } else {\n ui.info(`이미 최상위 모드(${currentMode})입니다.`);\n }\n\n // ── 2. 개별 플러그인 추가 선택 ───────────────────\n // 승격 후에도 현재 모드에서 선택 가능한 미설치 플러그인을 추가로 고를 수 있음\n const targetMode = promotedMode ?? currentMode;\n const availableForMode = getPluginsForMode(targetMode).map((p) => p.key);\n const remaining = availableForMode.filter(\n (k) => !(state.details[k]?.installed ?? false) && !autoPluginsFromPromotion.includes(k),\n );\n\n let selectedKeys: string[] = [];\n if (remaining.length > 0) {\n console.log('');\n const choices = remaining.map((k) => {\n const meta = PLUGIN_META[k];\n const tag = meta?.required ? '[필수]' : '[선택]';\n return {\n name: `${meta?.label ?? k} ${c.dim(tag)}`,\n value: k,\n checked: meta?.required ?? false,\n };\n });\n const answer = await inquirer.prompt([{\n type: 'checkbox',\n name: 'selectedKeys',\n message: autoPluginsFromPromotion.length > 0\n ? '추가로 설치할 플러그인 (선택):'\n : '설치할 플러그인을 선택하세요:',\n choices,\n }]);\n selectedKeys = answer.selectedKeys as string[];\n }\n\n const allToInstall = [...new Set([...autoPluginsFromPromotion, ...selectedKeys])];\n if (allToInstall.length === 0) {\n ui.info('선택된 플러그인이 없습니다.');\n if (promotedMode) {\n // 승격만 저장\n const config = existingConfig ?? createDefaultConfig(basename(cwd), promotedMode);\n config.mode = promotedMode;\n await saveConfig(cwd, config);\n ui.success(`모드: ${currentMode} → ${promotedMode}`);\n }\n return;\n }\n\n // ── 3. 프로젝트명 (없으면) ───────────────────────\n const projectName = existingConfig?.projectName ?? basename(cwd);\n\n const ctx: ProvisionerContext = {\n cwd,\n projectName,\n mode: targetMode,\n envEntries: {},\n };\n\n // ── 4. 설치 ─────────────────────────────────────\n ui.section('플러그인 설치 중...');\n await runProvisioners(allToInstall, ctx);\n\n // ── 5. config 갱신 ──────────────────────────────\n const config = existingConfig ?? createDefaultConfig(projectName, targetMode);\n config.mode = targetMode;\n config.plugins = [...new Set([...config.plugins, ...allToInstall])];\n await saveConfig(cwd, config);\n\n ui.success('설치 완료');\n if (promotedMode) {\n ui.success(`모드: ${currentMode} → ${promotedMode}`);\n }\n console.log('');\n ui.hint('다음 단계: /pai status 또는 /pai grade');\n}\n\nexport async function envDoctorCommand(): Promise<void> {\n await runDoctor();\n}\n\nexport async function envStatusCommand(cwd: string): Promise<void> {\n ui.section('프로젝트 상태');\n\n const state = await scanProjectState(cwd);\n const analysis = await analyzeProject(cwd);\n\n if (state.isNewProject) {\n ui.info('신규 프로젝트 — `pai init` 으로 초기화하세요.');\n return;\n }\n\n // Stack info\n if (analysis.stack.languages.length > 0) {\n ui.success(`스택: ${analysis.stack.languages.join(', ')}`);\n }\n if (analysis.stack.frameworks.length > 0) {\n ui.success(`프레임워크: ${analysis.stack.frameworks.join(', ')}`);\n }\n if (analysis.git.isGitRepo) {\n ui.success(`Git: ${analysis.git.repoName ?? 'local'} (${analysis.git.currentBranch ?? 'unknown'})`);\n }\n\n // Plugin state\n console.log('');\n for (const [key, meta] of Object.entries(PLUGIN_META)) {\n const installed = state.details[key]?.installed ?? false;\n if (installed) {\n ui.success(`${meta.label}`);\n } else {\n ui.warn(`${meta.label} — 미설치`);\n }\n }\n\n if (state.projectMode) {\n console.log('');\n ui.info(`모드: ${state.projectMode}`);\n const next = nextMode(state.projectMode);\n if (next) {\n ui.hint(`승격 경로: ${state.projectMode} → ${next} (pai add 에서 승격 가능)`);\n }\n }\n}\n","import { join, basename } from 'node:path';\nimport fs from 'fs-extra';\nimport { printWelcomeBanner } from '../../ui/index.js';\nimport { environmentStage } from '../../stages/environment/index.js';\nimport { loadConfig, createDefaultConfig, saveConfig } from '../../core/config.js';\nimport { scanProjectState } from '../../core/detector.js';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport async function initCommand(cwd: string, nameArg?: string): Promise<void> {\n printWelcomeBanner();\n\n // Windows 환경 체크\n const { isWindows, diagnoseWindowsEnv } = await import('../../utils/platform.js');\n if (isWindows) {\n const { issues, warnings } = diagnoseWindowsEnv();\n if (issues.length > 0) {\n ui.section('Windows 환경 문제');\n for (const i of issues) {\n ui.error(i.title);\n ui.hint(` 해결: ${i.fix}`);\n }\n const { default: inquirer } = await import('inquirer');\n const { proceed } = await inquirer.prompt([{\n type: 'confirm',\n name: 'proceed',\n message: '문제가 있지만 계속 진행하시겠습니까?',\n default: true,\n }]);\n if (!proceed) return;\n }\n if (warnings.length > 0) {\n for (const w of warnings) {\n ui.warn(w.title);\n if (w.hint) ui.hint(w.hint);\n }\n }\n }\n\n // 이미 PAI 프로젝트 내부에서 실행한 경우\n const currentConfig = await loadConfig(cwd);\n if (currentConfig && !nameArg) {\n const state = await scanProjectState(cwd);\n await handleExistingProject(cwd, state);\n return;\n }\n\n // 레거시 프로젝트 감지 (PAI 미설치, 코드 존재)\n if (!nameArg) {\n const isLegacy = await detectLegacyProject(cwd);\n if (isLegacy) {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n console.log('');\n ui.info('기존 프로젝트가 감지되었습니다.');\n\n // 1. AI 바이브코딩 환경 리포트 제안\n console.log('');\n const { runReport } = await inquirer.prompt([{\n type: 'confirm',\n name: 'runReport',\n message: '현재 폴더의 AI 바이브코딩 환경을 먼저 진단할까요?',\n default: true,\n }]);\n\n if (runReport) {\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n console.log('');\n const llmOutput = await analyzeRepository(cwd);\n const evalResult = computeResult(llmOutput);\n printReport(evalResult);\n\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(cwd, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n const legacyName = basename(cwd);\n const detailedReport = buildDetailedReport(evalResult, legacyName);\n await fs.writeFile(join(reportDir, `${today}.md`), detailedReport, 'utf8');\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n } catch {\n ui.warn('진단을 건너뜁니다.');\n }\n }\n\n // 2. PAI 오케스트레이터 설치\n console.log('');\n const { installNow } = await inquirer.prompt([{\n type: 'confirm',\n name: 'installNow',\n message: 'PAI 빌드 오케스트레이터를 설치할까요?',\n default: true,\n }]);\n\n if (installNow) {\n return await installOrchestratorOnly(cwd, basename(cwd));\n }\n return;\n }\n }\n\n // Step 1: 프로젝트 이름\n ui.step(1, 3, '프로젝트 이름');\n ui.hint('이 이름으로 프로젝트 폴더가 생성됩니다.');\n ui.hint('영문 소문자, 숫자, 하이픈(-)을 사용해주세요.');\n console.log('');\n\n const { default: inquirer } = await import('inquirer');\n\n let projectName: string;\n if (nameArg) {\n projectName = nameArg;\n ui.success(`프로젝트: ${projectName}`);\n } else {\n const answer = await inquirer.prompt([{\n type: 'input',\n name: 'name',\n message: '프로젝트 이름:',\n default: 'my-project',\n validate: (v: string) => {\n if (!v.trim()) return '이름을 입력해주세요.';\n if (!/^[a-z0-9][a-z0-9-]*$/.test(v.trim())) {\n return '영문 소문자, 숫자, 하이픈(-)만 사용할 수 있습니다.';\n }\n return true;\n },\n }]);\n projectName = answer.name.trim();\n }\n\n // Step 2: 폴더 생성 또는 확인\n const projectDir = join(cwd, projectName);\n\n if (await fs.pathExists(projectDir)) {\n const existingConfig = await loadConfig(projectDir);\n if (existingConfig) {\n console.log('');\n ui.info(`${projectName}/ 에 이미 PAI 프로젝트가 있습니다.`);\n const state = await scanProjectState(projectDir);\n await handleExistingProject(projectDir, state);\n return;\n }\n\n console.log('');\n ui.warn(`${projectName}/ 폴더가 이미 존재합니다.`);\n ui.hint('이 폴더에 PAI를 설치합니다.');\n } else {\n await fs.ensureDir(projectDir);\n ui.success(`${projectName}/ 폴더 생성`);\n }\n\n // Step 3: 환경 설정 실행\n await setupInDirectory(projectDir, projectName);\n}\n\nasync function setupInDirectory(projectDir: string, projectName: string): Promise<void> {\n // 쉘 헬퍼 설치 (자동 cd 지원)\n const { installShellHelper } = await import('../../utils/shell-cd.js');\n const alreadyInstalled = await installShellHelper();\n if (!alreadyInstalled) {\n ui.success('쉘 헬퍼 설치 (~/.pai/shell-helper.sh)');\n ui.hint('새 터미널에서 pai 명령으로 자동 디렉토리 이동이 활성화됩니다.');\n console.log('');\n }\n\n ui.step(2, 3, '프로젝트 설정');\n\n const config = createDefaultConfig(projectName, 'prototype');\n const input = {\n cwd: projectDir,\n config,\n previousResults: new Map(),\n };\n\n const result = await environmentStage.run(input);\n\n if (result.status === 'success') {\n // 쉘 헬퍼를 통해 프로젝트 디렉토리로 자동 이동\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(projectDir);\n } catch { /* shell-cd not available */ }\n\n const interview = result.data.interview as { extraTools: string[] };\n const isCurrentDir = projectDir === process.cwd();\n await showCompletion(projectName, projectDir, interview.extraTools, isCurrentDir);\n } else {\n for (const err of result.errors) {\n ui.error(err.message);\n }\n }\n}\n\nasync function showCompletion(projectName: string, projectDir: string, extraTools: string[], isCurrentDir: boolean): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n const { sleep } = await import('../../ui/progress.js');\n\n ui.step(3, 3, '완료');\n\n console.log(c.success(' 프로젝트가 준비되었습니다!'));\n console.log('');\n console.log(c.dim(' 생성된 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} PRD 템플릿 ${c.dim('docs/openspec.md')}`);\n console.log(` ${c.success('✓')} 도메인 모델 ${c.dim('.pai/omc.md')}`);\n console.log(` ${c.success('✓')} AI 컨텍스트 ${c.dim('CLAUDE.md')}`);\n console.log(` ${c.success('✓')} 슬래시 커맨드 ${c.dim('/pai init, /pai evaluate 등')}`);\n\n // ── 설치된 플러그인 & 기능 (비유 기반) ──────────\n console.log('');\n console.log(c.accent(' 설치된 플러그인 & 기능'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${chalk.cyan('OpenSpec+OMC')} 설계도 & 지형도 — 무엇을, 어디에 만들지 정의`);\n console.log(` ${chalk.cyan('RoboCo CLI')} 현장 소장 — 전체 공정 관리, AI에게 작업 지시`);\n console.log(` ${chalk.cyan('Vibe-Ready')} 품질 검수 — AI 개발 준비도 6카테고리 평가`);\n\n if (extraTools.includes('gstack')) {\n console.log(` ${chalk.cyan('gstack')} 표준 자재 & 공법 — 기술 스택 표준 구조 제공`);\n }\n if (extraTools.includes('harness')) {\n console.log(` ${chalk.cyan('Harness')} 안전장치 & 검사대 — AI 코드 작동 테스트`);\n }\n if (extraTools.includes('vercel')) {\n console.log(` ${chalk.cyan('Vercel')} 자동 배포 — Preview + Production`);\n }\n if (extraTools.includes('supabase')) {\n console.log(` ${chalk.cyan('Supabase')} DB + 인증 + 스토리지 (PostgreSQL 기반)`);\n }\n if (extraTools.includes('mcp')) {\n console.log(` ${chalk.cyan('MCP 서버')} AI 도구 — Claude가 호출할 커스텀 기능/데이터`);\n }\n\n // ── 설치 확인 ──────────────────────────────────\n console.log('');\n console.log(c.accent(' 설치 확인'));\n console.log(c.dim(' ─────────────────────────────'));\n\n const checks = [\n { label: 'AI 컨텍스트', path: 'CLAUDE.md' },\n { label: 'PRD 템플릿', path: 'docs/openspec.md' },\n { label: '프로젝트 설정', path: '.pai/config.json' },\n { label: 'Claude 설정', path: '.claude/settings.json' },\n { label: '슬래시 커맨드', path: '.claude/skills/pai/SKILL.md' },\n ];\n\n for (const check of checks) {\n const exists = await fs.pathExists(join(projectDir, check.path));\n console.log(` ${exists ? c.success('✓') : c.err('✗')} ${check.label.padEnd(16)} ${c.dim(check.path)}`);\n }\n\n // ── Vibe-Ready 평가 제안 ────────────────────────\n console.log('');\n const { runEval } = await inquirer.prompt([{\n type: 'confirm',\n name: 'runEval',\n message: 'AI를 통한 바이브코딩 상태 체크(Vibe-Ready) 평가를 진행할까요?',\n default: true,\n }]);\n\n if (runEval) {\n const { createSpinner } = await import('../../ui/progress.js');\n\n await sleep(2000);\n const spinner = createSpinner('바이브코딩 상태 체크 중...');\n\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n const llmOutput = await analyzeRepository(projectDir);\n const evalResult = computeResult(llmOutput);\n spinner.succeed('체크 완료');\n\n await sleep(500);\n printReport(evalResult);\n\n await sleep(500);\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(projectDir, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n const detailedReport = buildDetailedReport(evalResult, projectName);\n await fs.writeFile(join(reportDir, `${today}.md`), detailedReport, 'utf8');\n\n await sleep(500);\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n } catch {\n spinner.fail('평가 실패');\n await sleep(500);\n ui.hint('나중에 실행: pai evaluate');\n }\n } else {\n await sleep(500);\n ui.hint('나중에 실행: pai evaluate');\n }\n\n // 프로젝트 디렉토리로 이동\n if (!isCurrentDir) {\n process.chdir(projectDir);\n }\n\n // ── 안내 메시지 ────────────────────────────────\n console.log('');\n if (!isCurrentDir) {\n console.log(` ${chalk.green('→')} cd ${projectName} ${c.dim('이동 완료')}`);\n }\n console.log('');\n ui.success('이제 Claude Code와 함께 PRD 문서를 작성하세요.');\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n\n // ── Claude 모드 설정 (alias 있으면 bypass) ─────\n const { getShellRcPath, hasYoloAlias: checkYolo } = await import('../../utils/platform.js');\n const shellRc = getShellRcPath();\n let hasYoloAliasSet = false;\n\n try {\n const rcContent = await fs.readFile(shellRc, 'utf8');\n hasYoloAliasSet = checkYolo(rcContent);\n } catch { /* file not found */ }\n\n let useYolo = false;\n if (!hasYoloAliasSet) {\n console.log('');\n const { mode } = await inquirer.prompt([{\n type: 'list',\n name: 'mode',\n message: 'Claude Code 실행 모드를 설정합니다:',\n choices: [\n { name: `일반 모드 ${c.dim('─ 권한 확인 후 실행')}`, value: 'normal' },\n { name: `claude-YOLO mode ${c.dim('─ 권한 확인 없이 자동 실행 (alias 설정)')}`, value: 'yolo' },\n ],\n }]);\n\n if (mode === 'yolo') {\n useYolo = true;\n const { getYoloAliasLine } = await import('../../utils/platform.js');\n const aliasLine = getYoloAliasLine();\n try {\n const rcContent = await fs.readFile(shellRc, 'utf8').catch(() => '');\n if (!rcContent.includes('claude-yolo')) {\n await fs.ensureDir(join(shellRc, '..'));\n await fs.appendFile(shellRc, `\\n# PAI — claude-YOLO mode\\n${aliasLine}\\n`);\n await sleep(500);\n ui.success('claude-yolo alias 설정 완료');\n ui.hint('새 터미널에서 claude-yolo 로 실행 가능');\n }\n } catch { /* rc file write failed */ }\n }\n } else {\n useYolo = true;\n }\n\n // ── Claude Code 시작 ───────────────────────────\n console.log('');\n const claudeCmd = useYolo ? 'claude --dangerously-skip-permissions' : 'claude';\n\n const { launch } = await inquirer.prompt([{\n type: 'list',\n name: 'launch',\n message: 'Claude Code를 시작할까요?',\n choices: [\n { name: `OMC + Claude 시작 ${c.dim('─ oh-my-claudecode 설정 후 시작')}`, value: 'omc' },\n { name: `Claude 바로 시작 ${c.dim(`─ ${claudeCmd}`)}`, value: 'claude' },\n { name: chalk.gray('나중에 직접 실행'), value: 'none' },\n ],\n }]);\n\n if (launch === 'none') {\n console.log('');\n ui.hint('claude 를 입력하면 시작됩니다.');\n console.log('');\n\n if (!isCurrentDir) {\n const { spawnSubshell } = await import('../../utils/platform.js');\n spawnSubshell(projectDir);\n }\n return;\n }\n\n // OMC 선택 시 Claude Code 마켓플레이스에 OMC 플러그인을 등록.\n // 실제 설치는 Claude Code 기동 시 내부 메커니즘이 수행 (npx 호출 안 함).\n if (launch === 'omc') {\n console.log('');\n const { createSpinner } = await import('../../ui/progress.js');\n const spinner = createSpinner('OMC 플러그인 등록 중...');\n try {\n const { enableOmcPlugin, ClaudeSettingsError } = await import('../../utils/claude-settings.js');\n const result = await enableOmcPlugin();\n if (result.action === 'already-enabled') {\n spinner.succeed('OMC 플러그인 이미 등록됨');\n } else if (result.action === 'created') {\n spinner.succeed('Claude 설정 신규 생성 + OMC 플러그인 등록 완료');\n } else {\n spinner.succeed('OMC 플러그인 등록 완료');\n }\n ui.hint('Claude Code 기동 시 플러그인이 자동 설치됩니다.');\n if (result.backupPath) {\n ui.hint(`설정 백업: ${result.backupPath}`);\n }\n // ClaudeSettingsError는 상위에서 catch\n void ClaudeSettingsError;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n spinner.warn(`OMC 플러그인 등록 실패 — ${msg}`);\n ui.hint('Claude Code 기동 후 직접 등록하세요:');\n ui.hint(' /plugin install Yeachan-Heo/oh-my-claudecode');\n }\n }\n\n const cmd = claudeCmd;\n\n console.log('');\n if (!isCurrentDir) {\n console.log(c.dim(` → cd ${projectName}`));\n }\n console.log(c.dim(` → ${cmd}`));\n console.log('');\n\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(projectDir);\n\n const { execa } = await import('execa');\n process.chdir(projectDir);\n const parts = cmd.split(' ');\n await execa(parts[0]!, parts.slice(1), {\n stdio: 'inherit',\n cwd: projectDir,\n });\n\n // Claude Code 종료 후 프로젝트 디렉토리에서 서브쉘 시작\n if (!isCurrentDir) {\n const { spawnSubshell } = await import('../../utils/platform.js');\n spawnSubshell(projectDir);\n }\n } catch {\n ui.warn(`실행 실패. 직접 입력하세요: ${cmd}`);\n }\n}\n\nasync function handleExistingProject(\n cwd: string,\n state: Awaited<ReturnType<typeof scanProjectState>>,\n): Promise<void> {\n const { PLUGIN_META } = await import('../../core/detector.js');\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n\n ui.section('기존 프로젝트');\n\n const allPlugins = Object.entries(PLUGIN_META).map(([key, meta]) => ({\n key,\n label: meta.label,\n installed: state.details[key]?.installed ?? false,\n }));\n\n for (const p of allPlugins) {\n if (p.installed) {\n ui.success(p.label);\n } else {\n console.log(c.dim(` · ${p.label} ${chalk.gray('미설치')}`));\n }\n }\n\n // 현재 모드 표시 (승격 경로 안내용)\n const currentConfig = await loadConfig(cwd);\n if (currentConfig) {\n console.log('');\n console.log(c.dim(` 현재 모드: ${c.accent(currentConfig.mode)}`));\n }\n\n console.log('');\n const { action } = await inquirer.prompt([{\n type: 'list',\n name: 'action',\n message: '어떤 작업을 할까요?',\n choices: [\n {\n name: `📊 AI 개발 준비도 평가 ${c.dim('(pai grade — 6카테고리 점수)')}`,\n value: 'evaluate',\n },\n {\n name: `➕ 플러그인 추가·모드 승격 ${c.dim('(pai add — prototype → poc → production)')}`,\n value: 'install',\n },\n {\n name: `🩺 환경 점검 ${c.dim('(pai check — Node/Git/Claude/OMC)')}`,\n value: 'doctor',\n },\n { name: chalk.gray('🚪 종료'), value: 'exit' },\n ],\n }]);\n\n switch (action) {\n case 'evaluate': {\n const { evaluateCommand } = await import('./evaluate.cmd.js');\n await evaluateCommand(cwd, {});\n break;\n }\n case 'install': {\n const { envSetupCommand } = await import('./env.cmd.js');\n await envSetupCommand(cwd);\n break;\n }\n case 'doctor': {\n const { runDoctor } = await import('../../stages/environment/doctor.js');\n await runDoctor();\n break;\n }\n default:\n console.log('');\n }\n}\n\nasync function installOrchestratorOnly(projectDir: string, projectName: string): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n const { generateFiles } = await import('../../stages/environment/generator.js');\n const { analyzeProject } = await import('../../stages/environment/analyzer.js');\n const { provisionClaudeCommands } = await import('../../stages/environment/provisioners/claude-commands.js');\n const { runProvisioners } = await import('../../stages/environment/provisioners/registry.js');\n const { withSpinner, withFileSpinner, sleep } = await import('../../ui/progress.js');\n\n // 쉘 헬퍼 설치\n const { installShellHelper } = await import('../../utils/shell-cd.js');\n await installShellHelper();\n\n // 1. 플러그인 선택\n console.log('');\n ui.hint('Space로 선택 · 선택 후 Enter로 완료');\n const Separator = (inquirer as unknown as { Separator: new (s?: string) => unknown }).Separator;\n const { plugins } = await inquirer.prompt([{\n type: 'checkbox',\n name: 'plugins',\n message: '설치할 플러그인을 선택하세요:',\n choices: [\n { name: `OpenSpec+OMC ${c.dim('─ 설계도 & 지형도')}`, value: 'openspec', checked: true },\n { name: `RoboCo CLI ${c.dim('─ 현장 소장 (공정 관리)')}`, value: 'roboco', checked: true },\n { name: `Vibe-Ready ${c.dim('─ 품질 검수 (6카테고리 평가)')}`, value: 'vibe-ready', checked: true },\n { name: `gstack ${c.dim('─ 표준 자재 & 공법 (기술 스택)')}`, value: 'gstack' },\n { name: `Harness ${c.dim('─ 안전장치 & 검사대 (테스트)')}`, value: 'harness' },\n new Separator('─────────────────────────'),\n { name: chalk.green('↵ 선택 완료'), value: '__done__' },\n ],\n }]);\n const selectedPlugins = (plugins as string[]).filter(p => p !== '__done__');\n\n // 2. 프로젝트 분석\n console.log('');\n const analysis = await withSpinner('프로젝트 분석 중...', async () => {\n const result = await analyzeProject(projectDir);\n await sleep(500);\n return result;\n });\n\n // 3. 설정 파일 생성 (인터뷰 없이 자동)\n const extraTools: string[] = [];\n if (selectedPlugins.includes('gstack')) extraTools.push('gstack');\n if (selectedPlugins.includes('harness')) extraTools.push('harness');\n\n const autoInterview = {\n mode: 'prototype' as const,\n projectName,\n authMethods: [],\n extraTools,\n setupDomains: { claudeEnv: true, processDocs: true, cicd: analysis.git.isGitRepo },\n tools: {\n omc: selectedPlugins.includes('openspec'),\n openspec: selectedPlugins.includes('openspec'),\n githubMcp: false,\n harness: selectedPlugins.includes('harness'),\n },\n autoGenerated: true,\n };\n\n console.log('');\n await withFileSpinner('AI 컨텍스트 생성 중...', ['CLAUDE.md', '.claude/settings.json'], async () => {\n await generateFiles(projectDir, analysis, autoInterview);\n await sleep(400);\n });\n\n // 4. 프로비저너 실행 (선택된 플러그인만)\n const basePlugins = ['github'];\n if (selectedPlugins.includes('openspec')) basePlugins.push('openspec', 'omc');\n if (selectedPlugins.includes('roboco')) basePlugins.push('roboco');\n const allPluginKeys = [...basePlugins, ...extraTools];\n\n const provCtx = {\n cwd: projectDir,\n projectName,\n mode: 'prototype' as const,\n envEntries: { PAI_PROJECT_NAME: projectName, PAI_MODE: 'prototype' },\n };\n\n console.log('');\n await withSpinner('플러그인 설치 중...', async () => {\n await runProvisioners(allPluginKeys, provCtx);\n await sleep(400);\n });\n\n // 5. 슬래시 커맨드 설치\n console.log('');\n await withFileSpinner('슬래시 커맨드 설치 중...', ['SKILL.md', 'evaluate.md', 'doctor.md'], async () => {\n await provisionClaudeCommands(projectDir);\n await sleep(400);\n });\n\n // 6. 설정 저장\n console.log('');\n await withSpinner('설정 저장 중...', async () => {\n const config = createDefaultConfig(projectName, 'prototype');\n config.plugins = allPluginKeys;\n await saveConfig(projectDir, config);\n await sleep(300);\n });\n\n console.log('');\n ui.success('PAI 빌드 오케스트레이터 설치 완료');\n\n // 7. AI 바이브코딩 수준 — 간략 그래프\n console.log('');\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n const llmOutput = await analyzeRepository(projectDir);\n const evalResult = computeResult(llmOutput);\n printReport(evalResult);\n\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(projectDir, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n await fs.writeFile(join(reportDir, `${today}.md`), buildDetailedReport(evalResult, projectName), 'utf8');\n\n console.log('');\n ui.hint(`상세 리포트: docs/p-reports/${today}.md`);\n } catch {\n ui.hint('AI 준비도 평가: /pai evaluate');\n }\n\n // 8. Claude Code 시작\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n\n const { launch } = await inquirer.prompt([{\n type: 'list',\n name: 'launch',\n message: 'Claude Code를 시작할까요?',\n choices: [\n { name: `Claude 바로 시작 ${c.dim('─ claude')}`, value: 'claude' },\n { name: chalk.gray('나중에 직접 실행'), value: 'none' },\n ],\n }]);\n\n if (launch === 'none') {\n console.log('');\n ui.hint('claude 를 입력하면 시작됩니다.');\n return;\n }\n\n console.log('');\n console.log(c.dim(' → claude'));\n console.log('');\n\n try {\n const { execa } = await import('execa');\n process.chdir(projectDir);\n await execa('claude', [], { stdio: 'inherit', cwd: projectDir });\n } catch {\n ui.warn('실행 실패. 직접 입력하세요: claude');\n }\n}\n\nasync function installDiagnosticOnly(projectDir: string, projectName: string): Promise<void> {\n const { provisionClaudeCommands } = await import('../../stages/environment/provisioners/claude-commands.js');\n const { withSpinner } = await import('../../ui/progress.js');\n\n console.log('');\n await withSpinner('진단 도구 설치 중...', async () => {\n await provisionClaudeCommands(projectDir);\n });\n\n const config = createDefaultConfig(projectName, 'prototype');\n config.plugins = ['roboco'];\n await saveConfig(projectDir, config);\n\n console.log('');\n ui.success('진단 도구 설치 완료');\n console.log('');\n console.log(c.dim(' 사용 가능한 슬래시 커맨드'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} /pai evaluate ${c.dim('AI 준비도 평가 (6카테고리 리포트)')}`);\n console.log(` ${c.success('✓')} /pai doctor ${c.dim('개발 환경 진단 (Node, Git, Claude)')}`);\n console.log(` ${c.success('✓')} /pai status ${c.dim('플러그인 설치 현황')}`);\n console.log(` ${c.success('✓')} /pai install ${c.dim('추가 플러그인 설치')}`);\n console.log('');\n ui.hint('전체 파이프라인이 필요하면: npx pai-zero init');\n}\n\nasync function detectLegacyProject(cwd: string): Promise<boolean> {\n const signals = [\n 'package.json', '.git', 'pom.xml', 'build.gradle',\n 'go.mod', 'Cargo.toml', 'requirements.txt', 'pyproject.toml',\n 'Gemfile', 'composer.json', 'Makefile', '.gitignore',\n ];\n\n for (const signal of signals) {\n if (await fs.pathExists(join(cwd, signal))) return true;\n }\n return false;\n}\n","/**\n * `pai add` — 플러그인 추가 (구 `pai env setup`).\n */\nexport { envSetupCommand as addCommand } from './env.cmd.js';\n","/**\n * `pai check` — 환경 점검 (구 `pai env doctor`).\n */\nexport { envDoctorCommand as checkCommand } from './env.cmd.js';\n","/**\n * `pai status` — 프로젝트 상태 (구 `pai env status`).\n */\nexport { envStatusCommand as statusCommand } from './env.cmd.js';\n","/**\n * `pai help` — 명령어 안내. 구 슬래시 `/pai info` 내용 통합.\n */\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport async function helpCommand(): Promise<void> {\n ui.section('PAI 명령어');\n const lines: Array<[string, string]> = [\n ['pai init', '프로젝트 초기화 (새/기존 자동 감지)'],\n ['pai add', '플러그인 추가 (Mockup → Production 확장)'],\n ['pai check', '환경 점검 (Node / Git / Claude Code)'],\n ['pai status', '현재 프로젝트 상태 확인'],\n ['pai design', 'PRD / OMC 템플릿 & 검증'],\n ['pai test', '테스트 실행 + 하네스 검증'],\n ['pai grade', 'AI 개발 준비도 평가 (6카테고리)'],\n ['pai run', '전체 5단계 파이프라인 실행'],\n ['pai remove', 'PAI 생성 파일 삭제'],\n ['pai upgrade', '슬래시 커맨드 최신화'],\n ['pai savetoken', 'AI 토큰 절감 분석'],\n ['pai wakeup', 'Claude 세션 자동 시작'],\n ['pai help', '이 안내'],\n ];\n for (const [cmd, desc] of lines) {\n console.log(` ${c.accent(cmd.padEnd(16))} ${c.dim(desc)}`);\n }\n console.log('');\n console.log(c.dim(' 파이프라인: Environment → Design → Execution → Validation → Evaluation'));\n console.log('');\n console.log(c.dim(' 구 명령어(env setup, evaluate, validate, pipeline, install) 는 v0.13 까지 유지됩니다.'));\n}\n","/**\n * OpenSpec — PRD 템플릿 생성 및 완성도 검증\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nconst REQUIRED_SECTIONS = [\n { marker: '## 1.', label: '목적 (Purpose)' },\n { marker: '## 2.', label: '사용자 (Users)' },\n { marker: '## 3.', label: '핵심 기능 (Features)' },\n { marker: '## 4.', label: '기술 스택 (Stack)' },\n { marker: '## 5.', label: 'API 엔드포인트 (Endpoints)' },\n];\n\nexport async function initOpenSpec(cwd: string, projectName: string): Promise<void> {\n const docsDir = join(cwd, 'docs');\n await fs.ensureDir(docsDir);\n\n const openspecPath = join(docsDir, 'openspec.md');\n if (await fs.pathExists(openspecPath)) {\n ui.info('docs/openspec.md 이미 존재 — 건너뜀');\n return;\n }\n\n await fs.writeFile(openspecPath, [\n `# OpenSpec — ${projectName}`,\n '', '## 1. 목적 (Purpose)', '> 이 서비스는 무엇을 해결하는가?',\n '', '## 2. 사용자 (Users)', '| 역할 | 설명 |', '|------|------|', '| - | - |',\n '', '## 3. 핵심 기능 (Features)', '- [ ] Feature 1',\n '', '## 4. 기술 스택 (Stack)', '- Frontend:', '- Backend:', '- DB:',\n '', '## 5. API 엔드포인트 (Endpoints)',\n '| Method | Path | 설명 |', '|--------|------|------|', '| GET | /api/health | 헬스체크 |',\n ].join('\\n') + '\\n');\n\n ui.success('OpenSpec 템플릿 생성 → docs/openspec.md');\n}\n\nexport interface ValidationResult {\n complete: boolean;\n totalSections: number;\n filledSections: number;\n missing: string[];\n warnings: string[];\n}\n\nexport async function validateOpenSpec(cwd: string): Promise<ValidationResult> {\n const candidates = [\n join(cwd, 'docs', 'openspec.md'),\n join(cwd, 'openspec.md'),\n join(cwd, '.pai', 'openspec.md'),\n ];\n\n let specPath: string | null = null;\n for (const p of candidates) {\n if (await fs.pathExists(p)) {\n specPath = p;\n break;\n }\n }\n\n if (!specPath) {\n return {\n complete: false,\n totalSections: REQUIRED_SECTIONS.length,\n filledSections: 0,\n missing: REQUIRED_SECTIONS.map((s) => s.label),\n warnings: ['openspec.md 파일이 없습니다. `pai design init` 을 실행하세요.'],\n };\n }\n\n const content = await fs.readFile(specPath, 'utf8');\n const missing: string[] = [];\n let filled = 0;\n\n for (const section of REQUIRED_SECTIONS) {\n const idx = content.indexOf(section.marker);\n if (idx === -1) {\n missing.push(section.label);\n continue;\n }\n\n // Check if section has content beyond template placeholders\n const nextSection = content.indexOf('\\n## ', idx + 1);\n const sectionContent = nextSection > 0\n ? content.slice(idx, nextSection)\n : content.slice(idx);\n\n const lines = sectionContent.split('\\n').filter((l) =>\n l.trim() && !l.startsWith('#') && !l.startsWith('|--') && l.trim() !== '| - | - |'\n && !l.startsWith('>'),\n );\n\n if (lines.length > 1) {\n filled++;\n } else {\n missing.push(`${section.label} (내용 미작성)`);\n }\n }\n\n const warnings: string[] = [];\n if (content.length < 200) {\n warnings.push('PRD가 너무 짧습니다. 최소 각 섹션별 2-3줄 이상 작성을 권장합니다.');\n }\n\n return {\n complete: missing.length === 0,\n totalSections: REQUIRED_SECTIONS.length,\n filledSections: filled,\n missing,\n warnings,\n };\n}\n","/**\n * OMC — Object Model Context 관리\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport async function initOMC(cwd: string, projectName: string): Promise<void> {\n const paiDir = join(cwd, '.pai');\n await fs.ensureDir(paiDir);\n\n const omcPath = join(paiDir, 'omc.md');\n if (await fs.pathExists(omcPath)) {\n ui.info('.pai/omc.md 이미 존재 — 건너뜀');\n return;\n }\n\n await fs.writeFile(omcPath, [\n `# OMC — Object Model Context (${projectName})`,\n '', '> AI가 이 프로젝트의 도메인을 이해하기 위한 핵심 객체 모델',\n '', '## 도메인 객체',\n '', '### User', '```', 'id: string', 'email: string', 'role: \"admin\" | \"member\"', '```',\n '', '## 관계 (Relations)', '- User → (owns) → Project',\n '', '## 비즈니스 규칙', '- (여기에 핵심 비즈니스 로직을 기술)',\n '', '## 용어 사전 (Glossary)', '| 용어 | 정의 |', '|------|------|',\n ].join('\\n') + '\\n');\n\n ui.success('OMC 템플릿 생성 → .pai/omc.md');\n}\n","import * as ui from '../../ui/index.js';\nimport { initOpenSpec, validateOpenSpec } from '../../stages/design/openspec.js';\nimport { initOMC } from '../../stages/design/omc.js';\nimport { loadConfig } from '../../core/config.js';\nimport { basename } from 'node:path';\n\nexport async function designInitCommand(cwd: string): Promise<void> {\n ui.section('설계 템플릿 생성');\n const config = await loadConfig(cwd);\n const projectName = config?.projectName ?? basename(cwd);\n\n await initOpenSpec(cwd, projectName);\n await initOMC(cwd, projectName);\n\n ui.info('');\n ui.info('다음 단계: docs/openspec.md를 열어 PRD를 작성하세요.');\n}\n\nexport async function designValidateCommand(cwd: string): Promise<void> {\n ui.section('PRD 완성도 검증');\n\n const result = await validateOpenSpec(cwd);\n\n ui.info(`섹션 완성도: ${result.filledSections}/${result.totalSections}`);\n\n if (result.missing.length > 0) {\n console.log('');\n ui.warn('미작성 섹션:');\n for (const m of result.missing) {\n ui.warn(` - ${m}`);\n }\n }\n\n for (const w of result.warnings) {\n ui.warn(w);\n }\n\n if (result.complete) {\n console.log('');\n ui.success('PRD 완성도 검증 통과!');\n } else {\n console.log('');\n ui.info('docs/openspec.md를 열어 미작성 섹션을 채워주세요.');\n }\n}\n","/**\n * Validation Runner — gstack 설정 기반 테스트 실행\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport interface TestRunResult {\n runner: string;\n passed: boolean;\n output: string;\n duration: number;\n}\n\nexport async function runTests(cwd: string): Promise<TestRunResult> {\n const start = Date.now();\n\n // Read gstack config\n const gstackPath = join(cwd, '.pai', 'gstack.json');\n let runner = 'npm test';\n\n if (await fs.pathExists(gstackPath)) {\n try {\n const config = await fs.readJson(gstackPath);\n if (config.testRunner === 'vitest') runner = 'npx vitest run';\n else if (config.testRunner === 'jest') runner = 'npx jest';\n else if (config.testRunner === 'mocha') runner = 'npx mocha';\n } catch {\n // use default\n }\n }\n\n // Check if test script exists\n const pkgPath = join(cwd, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n try {\n const pkg = await fs.readJson(pkgPath);\n if (!pkg.scripts?.test || pkg.scripts.test.includes('no test specified')) {\n return {\n runner,\n passed: false,\n output: '테스트 스크립트가 정의되지 않았습니다. package.json의 scripts.test를 설정하세요.',\n duration: Date.now() - start,\n };\n }\n } catch {\n // continue\n }\n }\n\n try {\n const { execa } = await import('execa');\n const { stdout, stderr } = await execa('npm', ['test'], {\n cwd,\n timeout: 120000,\n env: { ...process.env, CI: 'true' },\n });\n return {\n runner,\n passed: true,\n output: stdout || stderr,\n duration: Date.now() - start,\n };\n } catch (err) {\n const output = err instanceof Error ? err.message : String(err);\n return {\n runner,\n passed: false,\n output,\n duration: Date.now() - start,\n };\n }\n}\n","/**\n * Harness — OpenSpec ↔ 구현 일치 검증\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport interface HarnessResult {\n enabled: boolean;\n specFile: string | null;\n rules: string[];\n checks: Array<{ rule: string; passed: boolean; detail: string }>;\n}\n\nexport async function runHarnessCheck(cwd: string): Promise<HarnessResult> {\n const harnessPath = join(cwd, '.pai', 'harness.json');\n\n if (!(await fs.pathExists(harnessPath))) {\n return { enabled: false, specFile: null, rules: [], checks: [] };\n }\n\n let config: { specFile?: string; rules?: string[] };\n try {\n config = await fs.readJson(harnessPath);\n } catch {\n return { enabled: false, specFile: null, rules: [], checks: [] };\n }\n\n const specFile = config.specFile ?? 'docs/openspec.md';\n const rules = config.rules ?? [];\n const checks: HarnessResult['checks'] = [];\n\n // Rule: spec-implementation-match\n if (rules.includes('spec-implementation-match')) {\n const specExists = await fs.pathExists(join(cwd, specFile));\n const srcExists = await fs.pathExists(join(cwd, 'src'));\n checks.push({\n rule: 'spec-implementation-match',\n passed: specExists && srcExists,\n detail: specExists && srcExists\n ? '설계 문서와 소스 디렉토리 존재'\n : `${!specExists ? specFile + ' 없음' : ''} ${!srcExists ? 'src/ 없음' : ''}`.trim(),\n });\n }\n\n // Rule: api-contract-test\n if (rules.includes('api-contract-test')) {\n const testDir = await fs.pathExists(join(cwd, 'tests'));\n const testDir2 = await fs.pathExists(join(cwd, 'test'));\n checks.push({\n rule: 'api-contract-test',\n passed: testDir || testDir2,\n detail: testDir || testDir2\n ? '테스트 디렉토리 존재'\n : '테스트 디렉토리(tests/ 또는 test/) 없음',\n });\n }\n\n return { enabled: true, specFile, rules, checks };\n}\n","import * as ui from '../../ui/index.js';\nimport { runTests } from '../../stages/validation/runner.js';\nimport { runHarnessCheck } from '../../stages/validation/harness.js';\n\nexport async function validateCommand(cwd: string): Promise<void> {\n // 1. Tests\n ui.section('테스트 실행');\n const testResult = await runTests(cwd);\n\n if (testResult.passed) {\n ui.success(`테스트 통과 (${testResult.runner}, ${testResult.duration}ms)`);\n } else {\n ui.error('테스트 실패');\n ui.info(testResult.output.slice(0, 300));\n }\n\n // 2. Harness\n ui.section('하네스 검증');\n const harness = await runHarnessCheck(cwd);\n\n if (!harness.enabled) {\n ui.info('Harness 설정 없음 — 건너뜀');\n ui.info('설정 추가: `pai env setup` 에서 Harness Engineering 선택');\n } else {\n for (const check of harness.checks) {\n if (check.passed) {\n ui.success(`${check.rule}: ${check.detail}`);\n } else {\n ui.warn(`${check.rule}: ${check.detail}`);\n }\n }\n }\n\n // Summary\n const allPassed = testResult.passed && harness.checks.every((c) => c.passed);\n console.log('');\n if (allPassed) {\n ui.success('검증 통과!');\n } else if (!testResult.passed) {\n ui.error('검증 실패 — 테스트를 수정하세요.');\n process.exitCode = 1;\n } else {\n ui.warn('부분 통과 — 하네스 검증 항목을 확인하세요.');\n }\n}\n","/**\n * `pai test` — 테스트/검증 (구 `pai validate`).\n */\nexport { validateCommand as testCommand } from './validate.cmd.js';\n","/**\n * `pai grade` — 품질 평가 (구 `pai evaluate`).\n */\nexport { evaluateCommand as gradeCommand } from './evaluate.cmd.js';\n","/**\n * Pipeline Context — 불변 실행 컨텍스트\n */\nimport type { StageName, StageResult, PaiConfig } from '../core/types/index.js';\n\nexport class PipelineContext {\n private readonly results = new Map<StageName, StageResult>();\n\n constructor(\n public readonly cwd: string,\n public readonly config: PaiConfig,\n ) {}\n\n setResult(name: StageName, result: StageResult): void {\n this.results.set(name, result);\n }\n\n getResults(): ReadonlyMap<StageName, StageResult> {\n return this.results;\n }\n\n getResult(name: StageName): StageResult | undefined {\n return this.results.get(name);\n }\n}\n","/**\n * Design Stage — 파이프라인 2단계\n * OpenSpec/OMC 기반 설계 관리\n * Production 모드에서 PRD 생성 시 Harness 자동 설치\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { initOpenSpec, validateOpenSpec } from './openspec.js';\nimport { initOMC } from './omc.js';\nimport { withSpinner, sleep } from '../../ui/progress.js';\nimport * as ui from '../../ui/index.js';\n\nexport const designStage: Stage = {\n name: 'design',\n\n canSkip(input: StageInput): boolean {\n return input.config.plugins.includes('openspec') && input.config.plugins.includes('omc');\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const artifacts: string[] = [];\n const errors: StageResult['errors'] = [];\n\n try {\n const projectName = input.config.projectName;\n\n // Generate templates with spinner\n await withSpinner('설계 템플릿 생성 중...', async () => {\n await initOpenSpec(input.cwd, projectName);\n await initOMC(input.cwd, projectName);\n await sleep(300);\n });\n\n // Auto-install harness for production mode\n if (input.config.mode === 'production') {\n await autoInstallHarness(input.cwd);\n }\n\n // Validate\n console.log('');\n ui.section('PRD 완성도 검증');\n const validation = await validateOpenSpec(input.cwd);\n\n ui.info(`섹션 완성도: ${validation.filledSections}/${validation.totalSections}`);\n\n if (validation.missing.length > 0) {\n ui.warn('미작성 섹션:');\n for (const m of validation.missing) {\n ui.warn(` - ${m}`);\n }\n }\n\n for (const w of validation.warnings) {\n ui.warn(w);\n }\n\n if (validation.complete) {\n ui.success('PRD 완성도 검증 통과!');\n }\n\n return {\n stage: 'design',\n status: validation.complete ? 'success' : 'partial',\n data: { validation },\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'DESIGN_FAILED', message: msg, recoverable: true });\n return {\n stage: 'design',\n status: 'failed',\n data: {},\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nasync function autoInstallHarness(cwd: string): Promise<void> {\n const harnessPath = join(cwd, '.pai', 'harness.json');\n if (await fs.pathExists(harnessPath)) return;\n\n await withSpinner('Harness Engineering 자동 설정 중...', async () => {\n await fs.ensureDir(join(cwd, '.pai'));\n await fs.writeJson(harnessPath, {\n version: '1.0',\n specFile: 'docs/openspec.md',\n checkOn: ['pre-commit', 'ci'],\n rules: ['spec-implementation-match', 'api-contract-test'],\n }, { spaces: 2 });\n await sleep(400);\n });\n\n ui.success('Production 모드 감지 → Harness 자동 설치 완료');\n}\n\nexport { initOpenSpec, validateOpenSpec } from './openspec.js';\nexport { initOMC } from './omc.js';\n","/**\n * Execution Stage — 파이프라인 3단계\n * OMC 기반 AI 코드 생성 (Claude Code에 위임)\n * 이 단계는 얇은 래퍼 — 실제 코드 생성은 사용자가 Claude Code로 수행\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport * as ui from '../../ui/index.js';\n\nexport const executionStage: Stage = {\n name: 'execution',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n\n ui.section('실행 단계');\n ui.info('이 단계는 Claude Code를 통해 수행합니다.');\n ui.info('OMC(.pai/omc.md)와 OpenSpec(docs/openspec.md)을 기반으로');\n ui.info('Claude Code에서 코드를 생성하세요.');\n ui.info('');\n ui.info('팁: Claude Code에서 다음 명령어를 사용하세요:');\n ui.info(' /pai design validate — PRD 기반 구현 검증');\n\n return {\n stage: 'execution',\n status: 'skipped',\n data: { message: 'Delegated to Claude Code' },\n artifacts: [],\n duration: Date.now() - start,\n errors: [],\n };\n },\n};\n","/**\n * Validation Stage — 파이프라인 4단계\n * gstack 테스트 + harness 검증\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { runTests } from './runner.js';\nimport { runHarnessCheck } from './harness.js';\nimport * as ui from '../../ui/index.js';\n\nexport const validationStage: Stage = {\n name: 'validation',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const errors: StageResult['errors'] = [];\n\n // 1. Run tests\n ui.section('테스트 실행');\n const testResult = await runTests(input.cwd);\n\n if (testResult.passed) {\n ui.success(`테스트 통과 (${testResult.runner}, ${testResult.duration}ms)`);\n } else {\n ui.error(`테스트 실패: ${testResult.output.slice(0, 200)}`);\n errors.push({ code: 'TEST_FAILED', message: testResult.output.slice(0, 500), recoverable: true });\n }\n\n // 2. Harness check\n ui.section('하네스 검증');\n const harness = await runHarnessCheck(input.cwd);\n\n if (!harness.enabled) {\n ui.info('Harness 설정 없음 (.pai/harness.json) — 건너뜀');\n } else {\n for (const check of harness.checks) {\n if (check.passed) {\n ui.success(`${check.rule}: ${check.detail}`);\n } else {\n ui.warn(`${check.rule}: ${check.detail}`);\n }\n }\n }\n\n const allPassed = testResult.passed && harness.checks.every((c) => c.passed);\n\n return {\n stage: 'validation',\n status: allPassed ? 'success' : testResult.passed ? 'partial' : 'failed',\n data: { testResult, harness },\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n },\n};\n\nexport { runTests } from './runner.js';\nexport { runHarnessCheck } from './harness.js';\n","/**\n * Evaluation Stage — 파이프라인 5단계\n * vibe-ready-cli 6카테고리 가중 점수 시스템\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { analyzeRepository } from './analyzer.js';\nimport { computeResult } from './scorer.js';\nimport { getCachedResult, setCachedResult } from './cache.js';\nimport { printReport, printVerboseFindings, buildMarkdownReport, buildDetailedReport } from './reporter.js';\nimport * as ui from '../../ui/index.js';\n\nexport interface EvaluateOptions {\n failUnder?: number;\n verbose?: boolean;\n output?: string;\n cache?: boolean;\n}\n\nexport const evaluationStage: Stage = {\n name: 'evaluation',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const errors: StageResult['errors'] = [];\n\n try {\n ui.section('AI 품질 평가');\n\n const llmOutput = await analyzeRepository(input.cwd);\n const result = computeResult(llmOutput);\n\n printReport(result);\n\n return {\n stage: 'evaluation',\n status: result.totalGrade === 'F' ? 'failed' : 'success',\n data: { result },\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'EVAL_FAILED', message: msg, recoverable: true });\n return {\n stage: 'evaluation',\n status: 'failed',\n data: {},\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nexport async function runEvaluation(cwd: string, options: EvaluateOptions = {}): Promise<void> {\n const useCache = options.cache !== false;\n\n // Try cache first\n let llmOutput = useCache ? getCachedResult(cwd) : null;\n if (llmOutput) {\n ui.info('캐시된 결과 사용 (24시간 이내)');\n } else {\n llmOutput = await analyzeRepository(cwd);\n if (useCache) {\n setCachedResult(cwd, llmOutput);\n }\n }\n\n const result = computeResult(llmOutput);\n\n // Print report\n printReport(result);\n\n if (options.verbose) {\n printVerboseFindings(result);\n }\n\n // Save to file\n if (options.output) {\n const fs = await import('fs-extra');\n const markdown = buildMarkdownReport(result);\n await fs.writeFile(options.output, markdown, 'utf8');\n ui.success(`리포트 저장: ${options.output}`);\n }\n\n // Fail-under check\n if (options.failUnder && result.totalScore < options.failUnder) {\n ui.error(`점수 ${result.totalScore}이 최소 기준 ${options.failUnder}에 미달합니다.`);\n process.exitCode = 1;\n }\n}\n\nexport { computeResult } from './scorer.js';\nexport { analyzeRepository } from './analyzer.js';\n","/**\n * Pipeline Runner — 5단계 순차 실행\n */\nimport type { Stage, StageName, StageInput, StageResult, PaiConfig } from '../core/types/index.js';\nimport { STAGE_ORDER } from '../core/types/index.js';\nimport { PipelineContext } from './context.js';\nimport { environmentStage } from '../stages/environment/index.js';\nimport { designStage } from '../stages/design/index.js';\nimport { executionStage } from '../stages/execution/index.js';\nimport { validationStage } from '../stages/validation/index.js';\nimport { evaluationStage } from '../stages/evaluation/index.js';\nimport * as ui from '../ui/index.js';\n\nconst STAGES: Record<StageName, Stage> = {\n environment: environmentStage,\n design: designStage,\n execution: executionStage,\n validation: validationStage,\n evaluation: evaluationStage,\n};\n\nexport interface PipelineOptions {\n from?: StageName;\n only?: StageName[];\n}\n\nexport async function runPipeline(\n cwd: string,\n config: PaiConfig,\n options: PipelineOptions = {},\n): Promise<Map<StageName, StageResult>> {\n const ctx = new PipelineContext(cwd, config);\n\n // Determine which stages to run\n let stagesToRun: StageName[];\n\n if (options.only) {\n stagesToRun = STAGE_ORDER.filter((s) => options.only!.includes(s));\n } else if (options.from) {\n const fromIdx = STAGE_ORDER.indexOf(options.from);\n stagesToRun = STAGE_ORDER.slice(fromIdx >= 0 ? fromIdx : 0);\n } else {\n stagesToRun = [...STAGE_ORDER];\n }\n\n ui.section(`파이프라인 실행 (${stagesToRun.length}단계)`);\n ui.info(`단계: ${stagesToRun.join(' → ')}`);\n\n const startTime = Date.now();\n\n let shouldStop = false;\n\n for (const stageName of stagesToRun) {\n const stage = STAGES[stageName];\n\n console.log('');\n ui.section(`[${STAGE_ORDER.indexOf(stageName) + 1}/${STAGE_ORDER.length}] ${stageName.toUpperCase()}`);\n\n const input: StageInput = {\n cwd,\n config,\n previousResults: ctx.getResults(),\n };\n\n // Check if stage can be skipped\n if (stage.canSkip(input)) {\n ui.info(`${stageName} — 건너뜀 (이미 완료)`);\n ctx.setResult(stageName, {\n stage: stageName,\n status: 'skipped',\n data: {},\n artifacts: [],\n duration: 0,\n errors: [],\n });\n continue;\n }\n\n const result = await stage.run(input);\n ctx.setResult(stageName, result);\n\n // Report stage result\n switch (result.status) {\n case 'success':\n ui.success(`${stageName} 완료 (${result.duration}ms)`);\n break;\n case 'partial':\n ui.warn(`${stageName} 부분 완료 (${result.duration}ms)`);\n break;\n case 'failed':\n ui.error(`${stageName} 실패 (${result.duration}ms)`);\n for (const err of result.errors) {\n ui.error(` ${err.message}`);\n }\n if (!result.errors.some((e) => e.recoverable)) {\n ui.error('복구 불가능한 오류 — 파이프라인 중단');\n shouldStop = true;\n }\n break;\n case 'skipped':\n ui.info(`${stageName} 건너뜀`);\n break;\n }\n\n if (shouldStop) break;\n }\n\n // Summary\n const totalDuration = Date.now() - startTime;\n console.log('');\n ui.section('파이프라인 요약');\n\n for (const stageName of stagesToRun) {\n const result = ctx.getResult(stageName);\n if (!result) continue;\n\n const icon =\n result.status === 'success' ? '✓' :\n result.status === 'partial' ? '△' :\n result.status === 'skipped' ? '○' : '✗';\n\n ui.info(`${icon} ${stageName.padEnd(14)} ${result.status} (${result.duration}ms)`);\n }\n\n console.log('');\n ui.info(`총 소요 시간: ${totalDuration}ms`);\n\n return ctx.getResults() as Map<StageName, StageResult>;\n}\n","import * as ui from '../../ui/index.js';\nimport { runPipeline, type PipelineOptions } from '../../pipeline/index.js';\nimport { loadConfig, createDefaultConfig } from '../../core/config.js';\nimport type { StageName } from '../../core/types/index.js';\nimport { printBanner } from '../../ui/index.js';\n\nexport interface PipelineCLIOptions {\n from?: string;\n only?: string;\n}\n\nexport async function pipelineCommand(cwd: string, options: PipelineCLIOptions): Promise<void> {\n printBanner();\n\n const config = (await loadConfig(cwd)) ?? createDefaultConfig('my-project', 'mockup');\n\n const pipelineOpts: PipelineOptions = {};\n\n if (options.from) {\n pipelineOpts.from = options.from as StageName;\n }\n\n if (options.only) {\n pipelineOpts.only = options.only.split(',').map((s) => s.trim()) as StageName[];\n }\n\n await runPipeline(cwd, config, pipelineOpts);\n}\n","/**\n * `pai run` — 전체 파이프라인 (구 `pai pipeline`).\n */\nexport { pipelineCommand as runCommand } from './pipeline.cmd.js';\n","import { basename, dirname } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\nimport { loadConfig } from '../../core/config.js';\n\nexport async function removeCommand(cwd: string, options: { force?: boolean }): Promise<void> {\n ui.section('프로젝트 삭제');\n\n // PAI 프로젝트인지 확인\n const config = await loadConfig(cwd);\n if (!config) {\n ui.error('PAI 프로젝트가 아닙니다.');\n ui.hint('.pai/config.json 을 찾을 수 없습니다.');\n return;\n }\n\n const folderName = basename(cwd);\n const parentDir = dirname(cwd);\n\n console.log('');\n if (config.version) {\n ui.info(`PAI v${config.version} 으로 설치된 프로젝트`);\n }\n console.log(c.err(` ${folderName}/ 폴더 전체가 삭제됩니다.`));\n ui.hint('이 작업은 되돌릴 수 없습니다.');\n console.log('');\n\n // 삭제할 내용 미리보기\n const items = await fs.readdir(cwd);\n const fileCount = items.filter((i) => !i.startsWith('.')).length;\n const hiddenCount = items.filter((i) => i.startsWith('.')).length;\n ui.info(`파일/폴더 ${fileCount}개, 숨김 항목 ${hiddenCount}개`);\n console.log('');\n\n if (!options.force) {\n const { default: inquirer } = await import('inquirer');\n const { confirmName } = await inquirer.prompt([{\n type: 'input',\n name: 'confirmName',\n message: `삭제하려면 프로젝트 이름을 입력하세요 (${folderName}):`,\n }]);\n\n if (confirmName.trim() !== folderName) {\n ui.info('이름이 일치하지 않습니다. 삭제를 취소합니다.');\n return;\n }\n }\n\n // 부모 디렉토리로 이동 후 폴더 삭제\n process.chdir(parentDir);\n\n try {\n await fs.remove(cwd);\n console.log('');\n ui.success(`${folderName}/ 프로젝트가 삭제되었습니다.`);\n\n // 쉘 헬퍼를 통해 부모 디렉토리로 자동 이동\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(parentDir);\n } catch {\n // shell-cd not available\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n ui.error(`삭제 실패: ${msg}`);\n return;\n }\n\n // 새 프로젝트 생성 제안\n console.log('');\n const { default: inquirer } = await import('inquirer');\n const { createNew } = await inquirer.prompt([{\n type: 'confirm',\n name: 'createNew',\n message: '새로운 프로젝트를 만드시겠습니까?',\n default: true,\n }]);\n\n if (createNew) {\n const { initCommand } = await import('./init.cmd.js');\n await initCommand(process.cwd());\n } else {\n // 상위 폴더에서 서브쉘 시작 — 사용자 터미널이 실제로 이동\n console.log('');\n ui.success(`→ cd .. ${c.dim('상위 폴더로 이동')}`);\n const { spawnSubshell } = await import('../../utils/platform.js');\n spawnSubshell(parentDir);\n }\n}\n","export class PaiError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly recoverable: boolean = false,\n ) {\n super(message);\n this.name = 'PaiError';\n }\n}\n\nexport class StageExecutionError extends PaiError {\n constructor(\n public readonly stageName: string,\n message: string,\n recoverable = false,\n ) {\n super(message, `STAGE_${stageName.toUpperCase()}_ERROR`, recoverable);\n this.name = 'StageExecutionError';\n }\n}\n\nexport class ConfigNotFoundError extends PaiError {\n constructor(path: string) {\n super(\n `.pai/config.json not found at ${path}. Run 'pai init' first.`,\n 'CONFIG_NOT_FOUND',\n true,\n );\n this.name = 'ConfigNotFoundError';\n }\n}\n","import { createRequire } from 'node:module';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { loadConfig, saveConfig } from '../../core/config.js';\nimport { upgradeClaudeCommands } from '../../stages/environment/provisioners/claude-commands.js';\nimport { ConfigNotFoundError } from '../../core/errors.js';\nimport { withSpinner, sleep } from '../../ui/progress.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nfunction compareSemver(a: string, b: string): -1 | 0 | 1 {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const na = pa[i] ?? 0;\n const nb = pb[i] ?? 0;\n if (na < nb) return -1;\n if (na > nb) return 1;\n }\n return 0;\n}\n\nexport async function upgradeCommand(\n cwd: string,\n options: { force?: boolean },\n): Promise<void> {\n ui.section('PAI 업그레이드');\n\n // 1. Load config\n const config = await loadConfig(cwd);\n if (!config) {\n throw new ConfigNotFoundError(cwd);\n }\n\n const currentVersion = pkg.version;\n const configVersion = config.version;\n\n console.log('');\n console.log(` 현재 버전: ${chalk.gray(`v${configVersion}`)}`);\n console.log(` 최신 버전: ${chalk.cyan(`v${currentVersion}`)}`);\n\n // 2. Version check\n if (!options.force && compareSemver(configVersion, currentVersion) >= 0) {\n console.log('');\n ui.success('이미 최신 버전입니다.');\n ui.info('강제 업그레이드: npx pai-zero upgrade --force');\n return;\n }\n\n // 3. Upgrade files\n console.log('');\n const result = await withSpinner('슬래시 커맨드 & 스킬 업그레이드 중...', async () => {\n const r = await upgradeClaudeCommands(cwd);\n await sleep(400);\n return r;\n });\n\n // 4. Report\n console.log('');\n if (result.skillUpdated) {\n ui.success('SKILL.md 업데이트');\n }\n if (result.commandsWritten.length > 0) {\n ui.success(`슬래시 커맨드 ${result.commandsWritten.length}개 업데이트`);\n for (const f of result.commandsWritten) {\n console.log(chalk.gray(` ${f}`));\n }\n }\n\n // 5. Error check\n if (result.commandErrors.length > 0) {\n console.log('');\n for (const e of result.commandErrors) {\n ui.error(`${e.file}: ${e.error}`);\n }\n ui.error('일부 파일 업데이트 실패. config.version을 변경하지 않습니다.');\n ui.info('문제 해결 후 다시 실행: npx pai-zero upgrade --force');\n return;\n }\n\n // 6. Update config version only after all writes succeed\n config.version = currentVersion;\n await saveConfig(cwd, config);\n\n console.log('');\n ui.success(`v${configVersion} → v${currentVersion} 업그레이드 완료!`);\n console.log('');\n}\n","/**\n * SaveToken — AI 토큰 절감 분석기\n * 프로젝트의 AI API 호출을 스캔하고 스크립트 대체 가능성을 분석\n */\nimport { join, relative } from 'node:path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\ninterface CallSite {\n file: string;\n line: number;\n content: string;\n sdk: string;\n category: 'import' | 'api-call' | 'fetch';\n}\n\nconst SCAN_PATTERNS: Array<{ pattern: string; sdk: string; category: CallSite['category'] }> = [\n // SDK imports\n { pattern: '@anthropic-ai/sdk', sdk: 'Anthropic', category: 'import' },\n { pattern: '@anthropic-ai/claude-agent-sdk', sdk: 'Claude Agent SDK', category: 'import' },\n { pattern: \"from 'openai'\", sdk: 'OpenAI', category: 'import' },\n { pattern: 'from \"openai\"', sdk: 'OpenAI', category: 'import' },\n { pattern: '@google/generative-ai', sdk: 'Google AI', category: 'import' },\n { pattern: 'cohere-ai', sdk: 'Cohere', category: 'import' },\n { pattern: 'langchain', sdk: 'LangChain', category: 'import' },\n // API calls\n { pattern: 'messages.create', sdk: 'Anthropic', category: 'api-call' },\n { pattern: 'chat.completions.create', sdk: 'OpenAI', category: 'api-call' },\n { pattern: 'generateContent', sdk: 'Google AI', category: 'api-call' },\n { pattern: 'completions.create', sdk: 'OpenAI', category: 'api-call' },\n // Fetch to AI APIs\n { pattern: 'api.anthropic.com', sdk: 'Anthropic', category: 'fetch' },\n { pattern: 'api.openai.com', sdk: 'OpenAI', category: 'fetch' },\n { pattern: 'generativelanguage.googleapis.com', sdk: 'Google AI', category: 'fetch' },\n];\n\nexport async function savetokenCommand(cwd: string): Promise<void> {\n const { createSpinner } = await import('../../ui/progress.js');\n\n console.log('');\n ui.section('SaveToken — AI 토큰 절감 분석');\n console.log('');\n\n const spinner = createSpinner('프로젝트 스캔 중...');\n const callSites = await scanProject(cwd);\n spinner.succeed(`스캔 완료 — ${callSites.length}건 발견`);\n\n if (callSites.length === 0) {\n console.log('');\n ui.info('AI API 호출이 발견되지 않았습니다.');\n ui.hint('이 프로젝트에는 AI SDK 사용이 없거나, 지원하지 않는 패턴입니다.');\n return;\n }\n\n // Group by category\n const imports = callSites.filter(s => s.category === 'import');\n const apiCalls = callSites.filter(s => s.category === 'api-call');\n const fetchCalls = callSites.filter(s => s.category === 'fetch');\n\n // Group by SDK\n const sdks = [...new Set(callSites.map(s => s.sdk))];\n\n // Print summary\n console.log('');\n console.log(c.dim(' 사용 중인 AI SDK'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const sdk of sdks) {\n const count = callSites.filter(s => s.sdk === sdk).length;\n console.log(` ${chalk.cyan(sdk.padEnd(20))} ${chalk.white(String(count))}건`);\n }\n\n if (imports.length > 0) {\n console.log('');\n console.log(c.dim(' SDK 임포트'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of imports) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n if (apiCalls.length > 0) {\n console.log('');\n console.log(c.dim(' AI API 호출 지점'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of apiCalls) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))} ${chalk.cyan(site.sdk)}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n if (fetchCalls.length > 0) {\n console.log('');\n console.log(c.dim(' Fetch 기반 AI 호출'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of fetchCalls) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))} ${chalk.cyan(site.sdk)}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n // Estimate & impact summary\n const totalApiPoints = apiCalls.length + fetchCalls.length;\n console.log('');\n console.log(c.accent(' 절감 가능성 추정'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` 총 API 호출 지점 ${chalk.white(String(totalApiPoints))}건`);\n console.log(` 분석 필요 ${chalk.yellow('Claude Code에서 심층 분석 필요')}`);\n console.log('');\n console.log(c.dim(' 영향도별 대체 전략'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${chalk.green('●')} 낮음 텍스트 포맷팅, 유효성 검증, 템플릿 생성`);\n console.log(` → ${c.dim('regex, JSON schema, 템플릿 엔진으로 즉시 대체')}`);\n console.log(` ${chalk.yellow('●')} 중간 데이터 분류, 요약, 간단한 추출`);\n console.log(` → ${c.dim('룰 기반 로직, 키워드 매칭으로 검토 후 대체')}`);\n console.log(` ${chalk.red('●')} 높음 코드 생성, 복잡한 추론, 창의적 생성`);\n console.log(` → ${c.dim('AI 필수 — 프롬프트 최적화로 토큰 절감')}`);\n\n // Save report\n const reportDir = join(cwd, '.pai');\n await fs.ensureDir(reportDir);\n const report = buildReport(callSites, cwd);\n const reportPath = join(reportDir, 'savetoken-report.md');\n await fs.writeFile(reportPath, report, 'utf8');\n\n console.log('');\n ui.success('스캔 리포트 저장: .pai/savetoken-report.md');\n console.log('');\n ui.hint('심층 분석 + 대체 코드 생성은 Claude Code에서:');\n ui.info(' /pai savetoken');\n}\n\nasync function scanProject(cwd: string): Promise<CallSite[]> {\n const { execa } = await import('execa');\n const results: CallSite[] = [];\n const seen = new Set<string>();\n\n for (const { pattern, sdk, category } of SCAN_PATTERNS) {\n try {\n const { stdout } = await execa('grep', [\n '-rn',\n '--include=*.ts', '--include=*.tsx', '--include=*.js', '--include=*.jsx',\n '--include=*.py', '--include=*.java', '--include=*.go', '--include=*.rs',\n '--exclude-dir=node_modules', '--exclude-dir=dist', '--exclude-dir=.git',\n '--exclude-dir=build', '--exclude-dir=__pycache__', '--exclude-dir=.next',\n '--exclude-dir=.claude', '--exclude=savetoken.cmd.*',\n '--exclude=claude-commands.*',\n pattern, cwd,\n ]);\n\n for (const line of stdout.split('\\n').filter(Boolean)) {\n const match = line.match(/^(.+?):(\\d+):(.+)$/);\n if (!match) continue;\n\n const file = relative(cwd, match[1]!);\n const lineNum = parseInt(match[2]!);\n const content = match[3]!;\n const key = `${file}:${lineNum}`;\n\n if (seen.has(key)) continue;\n seen.add(key);\n\n results.push({ file, line: lineNum, content, sdk, category });\n }\n } catch {\n // grep exit 1 = no matches, expected\n }\n }\n\n return results.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n}\n\nfunction buildReport(callSites: CallSite[], cwd: string): string {\n const imports = callSites.filter(s => s.category === 'import');\n const apiCalls = callSites.filter(s => s.category === 'api-call');\n const fetchCalls = callSites.filter(s => s.category === 'fetch');\n const sdks = [...new Set(callSites.map(s => s.sdk))];\n const totalApiPoints = apiCalls.length + fetchCalls.length;\n\n const lines: string[] = [\n '# PAI SaveToken — AI 토큰 절감 분석 리포트',\n '',\n `> 생성일: ${new Date().toISOString().slice(0, 10)}`,\n `> 프로젝트: ${cwd}`,\n '',\n '## 요약',\n '',\n `| 항목 | 건수 |`,\n `|------|------|`,\n `| SDK 임포트 | ${imports.length} |`,\n `| API 호출 지점 | ${apiCalls.length} |`,\n `| Fetch 기반 호출 | ${fetchCalls.length} |`,\n `| **합계** | **${callSites.length}** |`,\n '',\n '## 사용 중인 AI SDK',\n '',\n ];\n\n for (const sdk of sdks) {\n const count = callSites.filter(s => s.sdk === sdk).length;\n lines.push(`- **${sdk}**: ${count}건`);\n }\n\n if (apiCalls.length > 0 || fetchCalls.length > 0) {\n lines.push('', '## API 호출 지점 (대체 대상)', '');\n lines.push('| 파일 | 라인 | SDK | 코드 |');\n lines.push('|------|------|-----|------|');\n for (const site of [...apiCalls, ...fetchCalls]) {\n const code = site.content.trim().substring(0, 60).replace(/\\|/g, '\\\\|');\n lines.push(`| ${site.file} | ${site.line} | ${site.sdk} | \\`${code}\\` |`);\n }\n }\n\n lines.push(\n '',\n '## 영향도별 대체 전략',\n '',\n '### 영향도 낮음 (즉시 대체 가능)',\n '- 텍스트 포맷팅/변환 → regex, string template',\n '- 데이터 유효성 검증 → JSON schema, zod/joi',\n '- 템플릿 기반 생성 → handlebars, ejs',\n '- 고정 분류 → lookup table, switch-case',\n '',\n '### 영향도 중간 (검토 후 대체)',\n '- 텍스트 요약 → extractive 방식 (키워드 추출)',\n '- 간단한 분류 → TF-IDF, 키워드 매칭',\n '- 데이터 추출 → regex, DOM parser',\n '- 번역 (고정 문구) → i18n 파일',\n '',\n '### 영향도 높음 (AI 필수 — 프롬프트 최적화)',\n '- 코드 생성/리팩토링',\n '- 복잡한 추론/분석',\n '- 창의적 콘텐츠 생성',\n '- 멀티턴 대화',\n '',\n '## 다음 단계',\n '',\n `총 ${totalApiPoints}건의 API 호출 지점이 발견되었습니다.`,\n '',\n 'Claude Code에서 `/pai savetoken`을 실행하면:',\n '1. 각 호출의 목적을 AI가 분석합니다',\n '2. 대체 가능한 항목의 스크립트를 자동 생성합니다',\n '3. 영향도별 마이그레이션 계획을 제시합니다',\n '4. 예상 토큰 절감률을 산출합니다',\n '',\n );\n\n return lines.join('\\n');\n}\n","/**\n * Wakeup — Claude Code 세션 자동 시작 + 토큰 윈도우 리셋\n * macOS: launchd + pmset (wake-from-sleep) + osascript (Terminal)\n * Linux: crontab + terminal fallback\n */\nimport { join } from 'node:path';\nimport { homedir, platform as osPlatform } from 'node:os';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport type Schedule = '평일' | '매일' | '주말';\n\nconst PAI_DIR = join(homedir(), '.pai');\nconst CONFIG_FILE = join(PAI_DIR, 'wakeup-config.json');\nconst MESSAGES_FILE = join(PAI_DIR, 'wakeup-messages.json');\nconst SCRIPT_FILE = join(PAI_DIR, 'wakeup.sh');\nconst PLIST_NAME = 'com.pai.wakeup';\nconst PLIST_PATH = join(homedir(), 'Library', 'LaunchAgents', `${PLIST_NAME}.plist`);\nconst CRON_MARKER = '# PAI-WAKEUP';\n\ninterface WakeupConfig {\n time: string;\n schedule: Schedule;\n projectDir: string;\n launchMode: 'normal' | 'yolo';\n}\n\nconst MESSAGES: string[] = [\n `Here's to the crazy ones. The misfits. The rebels. The troublemakers.\nThe round pegs in the square holes. The ones who see things differently.\n\nThey're not fond of rules. And they have no respect for the status quo.\n\nYou can praise them, disagree with them, quote them, disbelieve them,\nglorify or vilify them. About the only thing you can't do is ignore them.\nBecause they change things.\n\nThey invent. They imagine. They heal. They explore. They create.\nThey inspire. They push the human race forward.\n\nMaybe they have to be crazy. How else can you stare at an empty canvas\nand see a work of art? Or sit in silence and hear a song that's never\nbeen written? Or gaze at a red planet and see a laboratory on wheels?\n\nBecause the people who are crazy enough to think they can change\nthe world, are the ones who do.\n\n— Think Different`,\n\n `\"Your work is going to fill a large part of your life,\nand the only way to be truly satisfied is to do what you\nbelieve is great work. And the only way to do great work\nis to love what you do.\"\n\n— Steve Jobs`,\n\n `\"The best way to predict the future is to invent it.\"\n\n— Alan Kay`,\n\n `\"Talk is cheap. Show me the code.\"\n\n— Linus Torvalds`,\n\n `\"The most dangerous phrase in the language is,\n'We've always done it this way.'\"\n\n— Grace Hopper`,\n\n `\"Premature optimization is the root of all evil.\"\n\n— Donald Knuth`,\n\n `\"Make it work, make it right, make it fast.\"\n\n— Kent Beck`,\n\n `\"Any fool can write code that a computer can understand.\nGood programmers write code that humans can understand.\"\n\n— Martin Fowler`,\n\n `\"Simplicity is prerequisite for reliability.\"\n\n— Edsger W. Dijkstra`,\n\n `\"First, solve the problem. Then, write the code.\"\n\n— John Johnson`,\n];\n\n// ── Main ────────────────────────────────────────\n\nexport async function wakeupCommand(timeOrAction?: string, schedule: Schedule = '평일'): Promise<void> {\n if (timeOrAction === 'off') {\n await disableWakeup();\n return;\n }\n\n if (timeOrAction === 'status') {\n await showStatus();\n return;\n }\n\n if (!timeOrAction) {\n showMessage();\n return;\n }\n\n // Validate time\n if (!/^\\d{1,2}:\\d{2}$/.test(timeOrAction)) {\n ui.error('시간 형식이 올바르지 않습니다. 예: 06:00, 22:30');\n return;\n }\n\n const [h, m] = timeOrAction.split(':').map(Number);\n if (h! < 0 || h! > 23 || m! < 0 || m! > 59) {\n ui.error('시간 범위를 확인해주세요. (00:00 ~ 23:59)');\n return;\n }\n\n // Interactive setup\n const { default: inquirer } = await import('inquirer');\n\n console.log('');\n const { projectDir } = await inquirer.prompt([{\n type: 'input',\n name: 'projectDir',\n message: 'Claude Code를 시작할 프로젝트 경로:',\n default: process.cwd(),\n }]);\n\n const { launchMode } = await inquirer.prompt([{\n type: 'list',\n name: 'launchMode',\n message: '실행 모드:',\n choices: [\n { name: `claude ${chalk.gray('일반 모드')}`, value: 'normal' },\n { name: `claude --dangerously-skip-permissions ${chalk.gray('claude-YOLO mode')}`, value: 'yolo' },\n ],\n }]);\n\n // Save config & files\n const config: WakeupConfig = {\n time: timeOrAction,\n schedule,\n projectDir,\n launchMode,\n };\n\n await fs.ensureDir(PAI_DIR);\n await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });\n await fs.writeJson(MESSAGES_FILE, MESSAGES);\n await createWakeupScript(config);\n\n // Platform-specific scheduling\n if (osPlatform() === 'darwin') {\n await setupMacOS(config);\n } else if (osPlatform() === 'win32') {\n await setupWindows(config);\n } else {\n await setupLinux(config);\n }\n\n console.log('');\n ui.success('☀️ 웨이크업 설정 완료');\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` 시간 ${chalk.white(config.time)}`);\n console.log(` 스케줄 ${chalk.white(scheduleToLabel(config.schedule))}`);\n console.log(` 프로젝트 ${chalk.white(config.projectDir)}`);\n console.log(` 모드 ${chalk.white(config.launchMode === 'yolo' ? 'claude-YOLO mode' : '일반 모드')}`);\n if (osPlatform() === 'darwin') {\n console.log(` 스케줄러 ${chalk.white('launchd + pmset (wake-from-sleep)')}`);\n }\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n ui.hint('해제: pai wakeup off');\n ui.hint('확인: pai wakeup status');\n\n console.log('');\n showMessage();\n}\n\n// ── macOS: launchd + pmset ──────────────────────\n\nasync function setupMacOS(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const [hour, minute] = config.time.split(':').map(Number);\n\n // 1. Create LaunchAgent plist\n const plistDir = join(homedir(), 'Library', 'LaunchAgents');\n await fs.ensureDir(plistDir);\n\n const weekdays = scheduleToWeekdays(config.schedule);\n let calendarEntries: string;\n\n if (weekdays.length === 7) {\n calendarEntries = ` <dict>\n <key>Hour</key><integer>${hour}</integer>\n <key>Minute</key><integer>${minute}</integer>\n </dict>`;\n } else {\n calendarEntries = ` <array>\n${weekdays.map(d => ` <dict>\n <key>Hour</key><integer>${hour}</integer>\n <key>Minute</key><integer>${minute}</integer>\n <key>Weekday</key><integer>${d}</integer>\n </dict>`).join('\\n')}\n </array>`;\n }\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_NAME}</string>\n <key>ProgramArguments</key>\n <array>\n <string>/bin/bash</string>\n <string>${SCRIPT_FILE}</string>\n </array>\n <key>StartCalendarInterval</key>\n${calendarEntries}\n <key>StandardOutPath</key>\n <string>${PAI_DIR}/wakeup.log</string>\n <key>StandardErrorPath</key>\n <string>${PAI_DIR}/wakeup.log</string>\n</dict>\n</plist>`;\n\n await fs.writeFile(PLIST_PATH, plist);\n\n // Load LaunchAgent\n await execa('launchctl', ['unload', PLIST_PATH]).catch(() => {});\n await execa('launchctl', ['load', PLIST_PATH]);\n ui.success('launchd 스케줄 등록 완료');\n\n // 2. pmset — wake from sleep\n const pmsetDays = scheduleToPmsetDays(config.schedule);\n console.log('');\n ui.info('Sleep 상태에서도 깨어나려면 관리자 권한이 필요합니다.');\n console.log('');\n\n try {\n await execa('sudo', ['pmset', 'repeat', 'wakeorpoweron', pmsetDays, `${config.time}:00`], {\n stdio: 'inherit',\n });\n ui.success('pmset wake-from-sleep 설정 완료');\n } catch {\n ui.warn('pmset 설정 실패 — sleep 상태에서는 깨어나지 않습니다.');\n ui.hint(`수동 설정: sudo pmset repeat wakeorpoweron ${pmsetDays} ${config.time}:00`);\n }\n}\n\n// ── Windows: Task Scheduler ─────────────────────\n\nasync function setupWindows(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const [hour, minute] = config.time.split(':').map(Number);\n\n // PowerShell wakeup script\n const psScriptDir = join(homedir(), '.pai');\n await fs.ensureDir(psScriptDir);\n const psScriptPath = join(psScriptDir, 'wakeup.ps1');\n\n const claudeCmd = config.launchMode === 'yolo'\n ? 'claude --dangerously-skip-permissions'\n : 'claude';\n\n const psScript = `# PAI Wakeup — Claude Code 세션 자동 시작\n$paiDir = \"$env:USERPROFILE\\\\.pai\"\n$msgFile = Join-Path $paiDir \"wakeup-messages.json\"\n$todayFile = Join-Path $paiDir \"wakeup-today.txt\"\n\n# Pick random message\ntry {\n $msgs = Get-Content $msgFile -Raw | ConvertFrom-Json\n $msg = $msgs[(Get-Random -Maximum $msgs.Count)]\n} catch {\n $msg = \"Make it work, make it right, make it fast. — Kent Beck\"\n}\nSet-Content -Path $todayFile -Value $msg\n\n# Windows notification\n[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null\n$template = [Windows.UI.Notifications.ToastTemplateType]::ToastText02\n$xml = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($template)\n$text = $xml.GetElementsByTagName(\"text\")\n$text[0].AppendChild($xml.CreateTextNode(\"PAI Wakeup\")) | Out-Null\n$text[1].AppendChild($xml.CreateTextNode($msg.Substring(0, [Math]::Min(100, $msg.Length)))) | Out-Null\n$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(\"PAI\")\n$notifier.Show([Windows.UI.Notifications.ToastNotification]::new($xml))\n\n# Open PowerShell with Claude Code\nStart-Process powershell -ArgumentList \"-NoExit\", \"-Command\", \"Get-Content '$todayFile'; Write-Host ''; Set-Location '${config.projectDir}'; ${claudeCmd}\"\n`;\n\n await fs.writeFile(psScriptPath, psScript, 'utf8');\n\n // schtasks — schedule\n const daysMap: Record<string, string> = {\n '평일': 'MON,TUE,WED,THU,FRI',\n '매일': 'MON,TUE,WED,THU,FRI,SAT,SUN',\n '주말': 'SAT,SUN',\n };\n const days = daysMap[config.schedule] || daysMap['평일'];\n\n // Remove existing task\n await execa('schtasks', ['/delete', '/tn', 'PAI-WAKEUP', '/f']).catch(() => {});\n\n try {\n await execa('schtasks', [\n '/create', '/tn', 'PAI-WAKEUP',\n '/tr', `powershell.exe -ExecutionPolicy Bypass -File \"${psScriptPath}\"`,\n '/sc', 'WEEKLY', '/d', days!,\n '/st', `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`,\n '/f',\n ]);\n ui.success('Windows Task Scheduler 등록 완료');\n } catch {\n ui.warn('Task Scheduler 등록 실패');\n ui.hint('관리자 권한으로 재시도하거나, 작업 스케줄러에서 직접 등록하세요');\n }\n}\n\n// ── Linux: crontab fallback ─────────────────────\n\nasync function setupLinux(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const cronExpr = scheduleToCron(config.time, config.schedule);\n const cronLine = `${cronExpr} ${SCRIPT_FILE} ${CRON_MARKER}`;\n\n await removeCronEntry();\n const existing = await execa('crontab', ['-l']).then(r => r.stdout).catch(() => '');\n const newCrontab = existing.trim() ? `${existing.trim()}\\n${cronLine}\\n` : `${cronLine}\\n`;\n await execa('crontab', ['-'], { input: newCrontab });\n\n ui.success('crontab 스케줄 등록 완료');\n}\n\n// ── Disable ─────────────────────────────────────\n\nasync function disableWakeup(): Promise<void> {\n const { execa } = await import('execa');\n\n if (osPlatform() === 'darwin') {\n await execa('launchctl', ['unload', PLIST_PATH]).catch(() => {});\n await fs.remove(PLIST_PATH).catch(() => {});\n ui.success('launchd 스케줄 제거');\n\n console.log('');\n ui.info('pmset wake-from-sleep 해제에 관리자 권한이 필요합니다.');\n try {\n await execa('sudo', ['pmset', 'repeat', 'cancel'], { stdio: 'inherit' });\n ui.success('pmset wake-from-sleep 해제 완료');\n } catch {\n ui.hint('수동 해제: sudo pmset repeat cancel');\n }\n } else if (osPlatform() === 'win32') {\n try {\n await execa('schtasks', ['/delete', '/tn', 'PAI-WAKEUP', '/f']);\n ui.success('Windows Task Scheduler 제거 완료');\n } catch {\n ui.hint('수동 해제: schtasks /delete /tn PAI-WAKEUP /f');\n }\n } else {\n await removeCronEntry();\n }\n\n await fs.remove(CONFIG_FILE).catch(() => {});\n console.log('');\n ui.success('☀️ 웨이크업 해제 완료');\n}\n\n// ── Status ──────────────────────────────────────\n\nasync function showStatus(): Promise<void> {\n if (await fs.pathExists(CONFIG_FILE)) {\n const config: WakeupConfig = await fs.readJson(CONFIG_FILE);\n\n console.log('');\n ui.success('☀️ 웨이크업 활성화');\n console.log(` 시간 ${chalk.white(config.time)}`);\n console.log(` 스케줄 ${chalk.white(scheduleToLabel(config.schedule))}`);\n console.log(` 프로젝트 ${chalk.white(config.projectDir)}`);\n console.log(` 모드 ${chalk.white(config.launchMode === 'yolo' ? 'claude-YOLO mode' : '일반 모드')}`);\n\n if (osPlatform() === 'darwin') {\n const plistExists = await fs.pathExists(PLIST_PATH);\n console.log(` launchd ${plistExists ? chalk.green('활성') : chalk.red('비활성')}`);\n }\n console.log('');\n } else {\n ui.info('웨이크업이 설정되지 않았습니다.');\n ui.hint('설정: pai wakeup 06:00');\n }\n}\n\n// ── Show Message ────────────────────────────────\n\nfunction showMessage(): void {\n const idx = Math.floor(Math.random() * MESSAGES.length);\n const msg = MESSAGES[idx]!;\n\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n for (const line of msg.split('\\n')) {\n console.log(` ${line}`);\n }\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n}\n\n// ── Helpers ─────────────────────────────────────\n\nfunction scheduleToLabel(schedule: Schedule): string {\n switch (schedule) {\n case '평일': return '평일 (월-금)';\n case '매일': return '매일';\n case '주말': return '주말 (토-일)';\n }\n}\n\nfunction scheduleToWeekdays(schedule: Schedule): number[] {\n switch (schedule) {\n case '평일': return [1, 2, 3, 4, 5];\n case '매일': return [0, 1, 2, 3, 4, 5, 6];\n case '주말': return [0, 6];\n }\n}\n\nfunction scheduleToPmsetDays(schedule: Schedule): string {\n switch (schedule) {\n case '평일': return 'MTWRF';\n case '매일': return 'MTWRFSU';\n case '주말': return 'SU';\n }\n}\n\nfunction scheduleToCron(time: string, schedule: Schedule): string {\n const [hour, minute] = time.split(':').map(Number);\n switch (schedule) {\n case '평일': return `${minute} ${hour} * * 1-5`;\n case '매일': return `${minute} ${hour} * * *`;\n case '주말': return `${minute} ${hour} * * 0,6`;\n }\n}\n\nasync function removeCronEntry(): Promise<void> {\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa('crontab', ['-l']);\n const filtered = stdout.split('\\n').filter(l => !l.includes(CRON_MARKER)).join('\\n');\n if (filtered.trim()) {\n await execa('crontab', ['-'], { input: `${filtered.trim()}\\n` });\n } else {\n await execa('crontab', ['-r']).catch(() => {});\n }\n } catch {\n // No crontab exists\n }\n}\n\nasync function createWakeupScript(config: WakeupConfig): Promise<void> {\n const claudeCmd = config.launchMode === 'yolo'\n ? 'claude --dangerously-skip-permissions'\n : 'claude';\n\n const script = `#!/bin/bash\n# PAI Wakeup — Claude Code 세션 자동 시작\n# 설정 시간에 맥을 깨우고 터미널에서 Claude Code를 시작합니다\nPAI_DIR=\"$HOME/.pai\"\nMSG_FILE=\"$PAI_DIR/wakeup-messages.json\"\nTODAY_FILE=\"$PAI_DIR/wakeup-today.txt\"\nLOG_FILE=\"$PAI_DIR/wakeup.log\"\n\necho \"[$(date)] PAI Wakeup triggered\" >> \"$LOG_FILE\"\n\n# Pick random message via Node.js\nMSG=$(node -e \"\nconst fs = require('fs');\ntry {\n const msgs = JSON.parse(fs.readFileSync('$MSG_FILE', 'utf8'));\n const msg = msgs[Math.floor(Math.random() * msgs.length)];\n process.stdout.write(msg);\n} catch(e) {\n process.stdout.write('Make it work, make it right, make it fast. — Kent Beck');\n}\n\" 2>/dev/null)\n\necho \"$MSG\" > \"$TODAY_FILE\"\n\n# macOS: GUI 세션 대기 후 Terminal 실행\nif [[ \"$(uname)\" == \"Darwin\" ]]; then\n # Sleep에서 깨어난 직후 GUI가 아직 준비 안 됨 — 로그인 화면 잠금 해제 대기\n MAX_WAIT=300 # 최대 5분 대기\n WAITED=0\n while [ $WAITED -lt $MAX_WAIT ]; do\n # WindowServer 프로세스가 있고 콘솔 사용자가 있으면 GUI 준비 완료\n if pgrep -q \"WindowServer\" && [ \"$(stat -f%Su /dev/console 2>/dev/null)\" = \"$(whoami)\" ]; then\n echo \"[$(date)] GUI session ready (waited \\${WAITED}s)\" >> \"$LOG_FILE\"\n break\n fi\n sleep 5\n WAITED=$((WAITED + 5))\n done\n\n if [ $WAITED -ge $MAX_WAIT ]; then\n echo \"[$(date)] GUI session timeout — skipping Terminal launch\" >> \"$LOG_FILE\"\n exit 0\n fi\n\n # 추가 안정화 대기\n sleep 10\n\n # Notification\n FIRST_LINE=$(echo \"$MSG\" | head -1 | cut -c1-80)\n osascript -e \"display notification \\\\\"$FIRST_LINE\\\\\" with title \\\\\"☀️ PAI Wakeup\\\\\" subtitle \\\\\"Claude Code 세션을 시작합니다\\\\\"\" 2>/dev/null\n\n # Open Terminal.app with Claude Code (재시도 3회)\n for attempt in 1 2 3; do\n osascript <<'APPLESCRIPT' 2>>\"$LOG_FILE\" && break\ntell application \"Terminal\"\n activate\n do script \"clear; echo ''; cat '$TODAY_FILE'; echo ''; echo '─────────────────────────────'; echo ''; cd '${config.projectDir}' && ${claudeCmd}\"\nend tell\nAPPLESCRIPT\n echo \"[$(date)] Terminal launch attempt $attempt failed, retrying...\" >> \"$LOG_FILE\"\n sleep 10\n done\nfi\n\n# Linux: Open terminal + Claude Code\nif [[ \"$(uname)\" == \"Linux\" ]]; then\n if command -v gnome-terminal &>/dev/null; then\n gnome-terminal -- bash -c \"cat '$TODAY_FILE'; echo ''; cd '${config.projectDir}' && ${claudeCmd}; exec bash\"\n elif command -v xterm &>/dev/null; then\n xterm -e \"cat '$TODAY_FILE'; echo ''; cd '${config.projectDir}' && ${claudeCmd}\"\n fi\nfi\n\necho \"[$(date)] PAI Wakeup completed\" >> \"$LOG_FILE\"\n`;\n\n await fs.writeFile(SCRIPT_FILE, script, { mode: 0o755 });\n}\n","import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { warnDeprecated } from './deprecation.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('pai')\n .description('PAI Zero (Plugin AI for ProjectZero) — AI 개발 빌드 오케스트레이터')\n .version(pkg.version, '-v, --version')\n .action(async () => {\n // 인자 없이 `pai` 실행 시 welcome 화면 출력\n const { welcomeCommand } = await import('./commands/welcome.cmd.js');\n await welcomeCommand(process.cwd());\n });\n\n /* ───────────────────────── 신규 동사 (v0.11+) ───────────────────────── */\n\n // pai init [project-name]\n program\n .command('init [project-name]')\n .description('프로젝트 초기화 (새 프로젝트 / 기존 프로젝트 자동 감지)')\n .action(async (projectName?: string) => {\n const { initCommand } = await import('./commands/init.cmd.js');\n await initCommand(process.cwd(), projectName);\n });\n\n // pai add\n program\n .command('add')\n .description('플러그인 추가 (Mockup → Production 확장)')\n .action(async () => {\n const { addCommand } = await import('./commands/add.cmd.js');\n await addCommand(process.cwd());\n });\n\n // pai check\n program\n .command('check')\n .description('환경 점검 (Node / Git / Claude Code)')\n .action(async () => {\n const { checkCommand } = await import('./commands/check.cmd.js');\n await checkCommand();\n });\n\n // pai status\n program\n .command('status')\n .description('현재 프로젝트 상태 확인 (설치된 플러그인)')\n .action(async () => {\n const { statusCommand } = await import('./commands/status.cmd.js');\n await statusCommand(process.cwd());\n });\n\n // pai help\n program\n .command('help')\n .description('명령어 안내')\n .action(async () => {\n const { helpCommand } = await import('./commands/help.cmd.js');\n await helpCommand();\n });\n\n // pai design <subcommand>\n const design = program\n .command('design')\n .description('설계 관리 (OpenSpec / OMC)');\n\n design\n .command('init')\n .description('PRD/OMC 템플릿 생성')\n .action(async () => {\n const { designInitCommand } = await import('./commands/design.cmd.js');\n await designInitCommand(process.cwd());\n });\n\n design\n .command('validate')\n .description('PRD 완성도 검증')\n .action(async () => {\n const { designValidateCommand } = await import('./commands/design.cmd.js');\n await designValidateCommand(process.cwd());\n });\n\n // pai test\n program\n .command('test')\n .description('테스트 / 하네스 검증 실행')\n .action(async () => {\n const { testCommand } = await import('./commands/test.cmd.js');\n await testCommand(process.cwd());\n });\n\n // pai grade\n program\n .command('grade')\n .description('AI 개발 준비도 평가 (6카테고리 점수)')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n const { gradeCommand } = await import('./commands/grade.cmd.js');\n await gradeCommand(process.cwd(), options);\n });\n\n // pai run\n program\n .command('run')\n .description('전체 5단계 파이프라인 실행')\n .option('--from <stage>', '특정 단계부터 실행')\n .option('--only <stages>', '선택적 단계 실행 (쉼표 구분)')\n .action(async (options) => {\n const { runCommand } = await import('./commands/run.cmd.js');\n await runCommand(process.cwd(), options);\n });\n\n // pai remove\n program\n .command('remove')\n .description('PAI 생성 파일 전체 삭제 (초기화)')\n .option('--force', '확인 없이 강제 삭제')\n .action(async (options) => {\n const { removeCommand } = await import('./commands/remove.cmd.js');\n await removeCommand(process.cwd(), options);\n });\n\n // pai upgrade\n program\n .command('upgrade')\n .description('PAI 슬래시 커맨드 & 스킬을 최신 버전으로 업그레이드')\n .option('--force', '버전 체크 무시하고 강제 업그레이드')\n .action(async (options) => {\n const { upgradeCommand } = await import('./commands/upgrade.cmd.js');\n await upgradeCommand(process.cwd(), options);\n });\n\n // pai savetoken\n program\n .command('savetoken')\n .description('AI 토큰 절감 분석')\n .action(async () => {\n const { savetokenCommand } = await import('./commands/savetoken.cmd.js');\n await savetokenCommand(process.cwd());\n });\n\n // pai wakeup [time] [schedule]\n program\n .command('wakeup [time] [schedule]')\n .description('Claude Code 세션 자동 시작 + 토큰 윈도우 리셋')\n .action(async (time?: string, schedule?: string) => {\n const { wakeupCommand } = await import('./commands/wakeup.cmd.js');\n type Schedule = '평일' | '매일' | '주말';\n const validSchedules: Schedule[] = ['평일', '매일', '주말'];\n const sched: Schedule = validSchedules.includes(schedule as Schedule) ? schedule as Schedule : '평일';\n await wakeupCommand(time, sched);\n });\n\n /* ───────────────────────── 구 명령어 (deprecation alias) ─────────────\n * v0.11 경고 → v0.13 제거 예정\n * 기존 사용자 스크립트/블로그 호환 위해 유지\n * ──────────────────────────────────────────────────────────────────── */\n\n // env 그룹 (구): setup / doctor / status\n const env = program\n .command('env')\n .description('[구] 환경 관리 — pai add / check / status 권장');\n\n env\n .command('setup')\n .description('[구] → pai add')\n .action(async () => {\n warnDeprecated('pai env setup', 'pai add');\n const { envSetupCommand } = await import('./commands/env.cmd.js');\n await envSetupCommand(process.cwd());\n });\n\n env\n .command('doctor')\n .description('[구] → pai check')\n .action(async () => {\n warnDeprecated('pai env doctor', 'pai check');\n const { envDoctorCommand } = await import('./commands/env.cmd.js');\n await envDoctorCommand();\n });\n\n env\n .command('status')\n .description('[구] → pai status')\n .action(async () => {\n warnDeprecated('pai env status', 'pai status');\n const { envStatusCommand } = await import('./commands/env.cmd.js');\n await envStatusCommand(process.cwd());\n });\n\n // pai validate → pai test\n program\n .command('validate')\n .description('[구] → pai test')\n .action(async () => {\n warnDeprecated('pai validate', 'pai test');\n const { validateCommand } = await import('./commands/validate.cmd.js');\n await validateCommand(process.cwd());\n });\n\n // pai evaluate → pai grade\n program\n .command('evaluate')\n .description('[구] → pai grade')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n warnDeprecated('pai evaluate', 'pai grade');\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), options);\n });\n\n // pai pipeline → pai run\n program\n .command('pipeline')\n .description('[구] → pai run')\n .option('--from <stage>', '특정 단계부터 실행')\n .option('--only <stages>', '선택적 단계 실행 (쉼표 구분)')\n .action(async (options) => {\n warnDeprecated('pai pipeline', 'pai run');\n const { pipelineCommand } = await import('./commands/pipeline.cmd.js');\n await pipelineCommand(process.cwd(), options);\n });\n\n // pai install → pai add (가장 오독되던 이름)\n program\n .command('install')\n .description('[구] → pai add')\n .action(async () => {\n warnDeprecated('pai install', 'pai add');\n const { envSetupCommand } = await import('./commands/env.cmd.js');\n await envSetupCommand(process.cwd());\n });\n\n // 이전 레거시 유지\n program\n .command('diagnose')\n .description('[구] → pai grade')\n .action(async () => {\n warnDeprecated('pai diagnose', 'pai grade');\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), {});\n });\n\n program\n .command('vibe-ready')\n .description('바이브 코딩 준비도 측정 (= pai grade)')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), options);\n });\n\n return program;\n}\n","/**\n * 구 명령어 deprecation 경고 — 세션 내 1회만 출력.\n * v0.11 alias 도입, v0.13 제거 스케줄.\n */\nconst warned = new Set<string>();\n\nexport function warnDeprecated(oldCmd: string, newCmd: string): void {\n if (warned.has(oldCmd)) return;\n warned.add(oldCmd);\n process.stderr.write(\n `\\x1b[33m⚠ '${oldCmd}' is deprecated. Use '${newCmd}' (see 'pai help'). Removed in v0.13.\\x1b[0m\\n`,\n );\n}\n","#!/usr/bin/env node\n\nimport { createProgram } from '../src/cli/index.js';\n\nconst program = createProgram();\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n console.error('\\n[PAI Error]', err.message || err);\n if (process.env['PAI_DEBUG']) {\n console.error(err.stack);\n }\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;AAAA,OAAO,WAAW;AAiBX,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,EAAE,IAAI,UAAO,GAAG,EAAE,CAAC;AACjC;AAEO,SAAS,QAAQ,KAAmB;AACzC,UAAQ,IAAI,EAAE,QAAQ,YAAO,GAAG,EAAE,CAAC;AACrC;AAEO,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,EAAE,KAAK,OAAO,GAAG,EAAE,CAAC;AAClC;AAEO,SAAS,MAAM,KAAmB;AACvC,UAAQ,IAAI,EAAE,IAAI,YAAO,GAAG,EAAE,CAAC;AACjC;AAEO,SAAS,QAAQ,OAAqB;AAC3C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,EAAE,OAAO,KAAK,KAAK,EAAE,CAAC;AAClC,UAAQ,IAAI,EAAE,IAAI,OAAO,SAAI,OAAO,EAAE,CAAC,CAAC;AAC1C;AAMO,SAAS,KAAK,KAAa,OAAe,OAAqB;AACpE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,EAAE,OAAO,UAAU,GAAG,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,KAAK,KAAK,CAAC,EAAE;AACrE,UAAQ,IAAI,EAAE;AAChB;AAEO,SAAS,KAAK,KAAmB;AACtC,UAAQ,IAAI,EAAE,IAAI,KAAK,GAAG,EAAE,CAAC;AAC/B;AAnDA,IAKa,QAUP;AAfN;AAAA;AAAA;AAKO,IAAM,SAAS;AAAA,MACpB,QAAQ,MAAM,IAAI,SAAS;AAAA,MAC3B,SAAS,MAAM,IAAI,SAAS;AAAA,MAC5B,MAAM,MAAM,IAAI,SAAS;AAAA,MACzB,KAAK,MAAM,IAAI,SAAS;AAAA,MACxB,KAAK,MAAM;AAAA,MACX,MAAM,MAAM,KAAK;AAAA,MACjB,OAAO,MAAM;AAAA,IACf;AAEA,IAAM,IAAI;AAAA;AAAA;;;ACfV,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAC9B,OAAO,QAAQ;AAeR,SAAS,cAAc,OAAsB;AAClD,MAAI,UAAU,eAAe,UAAU,SAAS,UAAU,aAAc,QAAO;AAC/E,MAAI,UAAU,SAAU,QAAO;AAC/B,SAAO;AACT;AAEA,eAAsB,WAAW,KAAwC;AACvE,QAAM,aAAa,KAAK,KAAK,KAAK,YAAY,WAAW;AACzD,MAAI,CAAE,MAAM,GAAG,WAAW,UAAU,EAAI,QAAO;AAE/C,QAAM,MAAO,MAAM,GAAG,SAAS,UAAU;AACzC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,MAAM,cAAc,IAAI,IAAI;AAAA,EAC9B;AACF;AAEA,eAAsB,WAAW,KAAa,QAAkC;AAC9E,QAAM,YAAY,KAAK,KAAK,KAAK,UAAU;AAC3C,QAAM,GAAG,UAAU,SAAS;AAC5B,QAAM,GAAG,UAAU,KAAK,KAAK,WAAW,WAAW,GAAG,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC7E;AAEO,SAAS,oBAAoB,aAAqB,MAAoC;AAC3F,SAAO;AAAA,IACL,SAAS,IAAI;AAAA,IACb,MAAM,cAAc,IAAI;AAAA,IACxB;AAAA,IACA,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,IACpC,SAAS,CAAC;AAAA,EACZ;AACF;AAhDA,IAKMA,UACA,KAEA,YACA;AATN;AAAA;AAAA;AAKA,IAAMA,WAAU,cAAc,YAAY,GAAG;AAC7C,IAAM,MAAMA,SAAQ,oBAAoB;AAExC,IAAM,aAAa;AACnB,IAAM,cAAc;AAAA;AAAA;;;ACTpB;AAAA;AAAA;AAAA;AAMA,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,SAAQ;AACf,OAAOC,WAAU;AAQjB,eAAsB,eAAe,KAA4B;AAE/D,QAAM,YAAY,MAAM,WAAW,GAAG;AACtC,QAAM,eAAe,cAAc;AACnC,QAAM,SAASD,IAAG,WAAWC,MAAK,KAAK,KAAK,MAAM,CAAC;AACnD,QAAM,iBAAiBD,IAAG,WAAWC,MAAK,KAAK,KAAK,cAAc,CAAC;AAEnE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,OAAO,wOAA0C,CAAC;AAChE,UAAQ,IAAI,OAAE,OAAO,kCAAsBC,KAAI,QAAQ,OAAO,EAAE,CAAC,QAAG,CAAC;AACrE,UAAQ,IAAI,OAAE,OAAO,oDAA0C,CAAC;AAChE,UAAQ,IAAI,OAAE,OAAO,wOAA0C,CAAC;AAChE,UAAQ,IAAI,EAAE;AAEd,MAAI,cAAc;AAEhB,YAAQ,IAAI,OAAE,IAAI,8FAAwB,CAAC;AAC3C,YAAQ,IAAI,OAAE,IAAI,0BAAW,UAAW,IAAI,EAAE,CAAC;AAC/C,YAAQ,IAAI,OAAE,IAAI,sCAAa,UAAW,QAAQ,MAAM,2BAAO,CAAC;AAChE,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,OAAO,8DAAiB,CAAC;AACvC,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,IAAI,OAAE,IAAI,0DAAa,CAAC,EAAE;AACpF,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,KAAK,OAAE,IAAI,6EAAsB,CAAC,EAAE;AAC7F,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,UAAU,OAAO,EAAE,CAAC,OAAO,OAAE,IAAI,2GAA4C,CAAC,EAAE;AACnH,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,IAAI,OAAE,IAAI,mCAAe,CAAC,EAAE;AACtF,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,WAAW,OAAO,EAAE,CAAC,MAAM,OAAE,IAAI,sDAAc,CAAC,EAAE;AACrF,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,KAAK,OAAE,IAAI,2BAAO,CAAC,EAAE;AAC9E,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,+BAAW,IAAI,OAAE,OAAO,UAAU,CAAC;AAAA,EACvD,WAAW,UAAU,gBAAgB;AAEnC,YAAQ,IAAI,OAAE,IAAI,mHAA8B,CAAC;AACjD,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,OAAO,4BAAQ,CAAC;AAC9B,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,WAAW,OAAO,EAAE,CAAC,IAAI,OAAE,IAAI,iGAA2B,CAAC,EAAE;AAChG,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,GAAG,OAAE,IAAI,uCAAS,CAAC,EAAE;AAC9E,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,+BAAW,IAAI,OAAE,OAAO,UAAU,CAAC;AAAA,EACvD,OAAO;AAEL,YAAQ,IAAI,OAAE,OAAO,yCAAW,CAAC;AACjC,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,4CAAmB,OAAO,EAAE,CAAC,GAAG,OAAE,IAAI,8CAAW,CAAC,EAAE;AACvF,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,OAAO,uEAAqB,CAAC;AAC3C,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,aAAa,OAAO,EAAE,CAAC,IAAI,OAAE,IAAI,0DAAa,CAAC,EAAE;AACpF,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,KAAK,OAAE,IAAI,iDAAc,CAAC,EAAE;AACrF,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,UAAU,OAAO,EAAE,CAAC,OAAO,OAAE,IAAI,mEAAiB,CAAC,EAAE;AACxF,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,OAAO,0CAAY,CAAC;AAClC,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,YAAY,OAAO,EAAE,CAAC,KAAK,OAAE,IAAI,6CAAmC,CAAC,EAAE;AAC1G,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,qCAAY,IAAI,OAAE,OAAO,UAAU,CAAC;AAAA,EACxD;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,gDAAsC,CAAC;AACzD,UAAQ,IAAI,EAAE;AAChB;AA9EA,IAYMC,UAEAD;AAdN;AAAA;AAAA;AASA;AACA;AAEA,IAAMC,WAAUJ,eAAc,YAAY,GAAG;AAE7C,IAAMG,OAAMC,SAAQ,oBAAoB;AAAA;AAAA;;;ACZjC,SAAS,cAAoB;AAClC,QAAMC,KAAI;AACV,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,GAAE,OAAO,YAAY,CAAC;AAClC,UAAQ,IAAIA,GAAE,IAAI,6BAA6B,CAAC;AAChD,UAAQ,IAAIA,GAAE,IAAI,0JAA6B,CAAC;AAChD,UAAQ,IAAI,EAAE;AAChB;AAMO,SAAS,qBAA2B;AACzC,QAAMA,KAAI;AAEV,QAAM,MAAM;AAAA,IACV;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,UAAQ,IAAI,EAAE;AACd,aAAW,QAAQ,KAAK;AACtB,YAAQ,IAAIA,GAAE,OAAO,IAAI,CAAC;AAAA,EAC5B;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,GAAE,IAAI,6BAA6B,CAAC;AAChD,UAAQ,IAAIA,GAAE,IAAI,0YAAqE,CAAC;AACxF,UAAQ,IAAI,EAAE;AAChB;AAjCA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,OAAO,SAAuB;AAC9B,OAAOC,YAAW;AAEX,SAAS,cAAc,MAAmB;AAC/C,SAAO,IAAI;AAAA,IACT;AAAA,IACA,SAAS;AAAA,IACT,OAAO;AAAA,EACT,CAAC,EAAE,MAAM;AACX;AAEA,eAAsB,YAAe,MAAc,IAAkC;AACnF,QAAM,UAAU,cAAc,IAAI;AAClC,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,YAAQ,QAAQ,KAAK,QAAQ,aAAa,cAAI,CAAC;AAC/C,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,YAAQ,KAAK,KAAK,QAAQ,aAAa,cAAI,CAAC;AAC5C,UAAM;AAAA,EACR;AACF;AAMA,eAAsB,gBACpB,OACA,OACA,IACY;AACZ,QAAM,UAAU,IAAI;AAAA,IAClB,SAAS;AAAA,IACT,OAAO;AAAA,EACT,CAAC,EAAE,MAAM;AAGT,MAAI,UAAU;AACd,QAAM,WAAW,YAAY,MAAM;AACjC,QAAI,UAAU,MAAM,QAAQ;AAC1B,YAAM,OAAO,MAAM,OAAO;AAC1B,cAAQ,OAAO,GAAG,KAAK,IAAIA,OAAM,KAAK,IAAI,CAAC;AAC3C;AAAA,IACF,OAAO;AACL,gBAAU;AAAA,IACZ;AAAA,EACF,GAAG,GAAG;AAEN,MAAI;AACF,UAAM,SAAS,MAAM,GAAG;AACxB,kBAAc,QAAQ;AACtB,YAAQ,QAAQ,MAAM,QAAQ,aAAa,cAAI,CAAC;AAChD,WAAO;AAAA,EACT,SAAS,KAAK;AACZ,kBAAc,QAAQ;AACtB,YAAQ,KAAK,MAAM,QAAQ,aAAa,cAAI,CAAC;AAC7C,UAAM;AAAA,EACR;AACF;AAEO,SAAS,MAAM,IAA2B;AAC/C,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEO,SAAS,YAAY,SAAiB,OAAe,QAAQ,IAAY;AAC9E,QAAM,QAAQ,KAAK,IAAI,UAAU,OAAO,CAAC;AACzC,QAAM,SAAS,KAAK,MAAM,QAAQ,KAAK;AACvC,QAAM,QAAQ,QAAQ;AACtB,QAAM,MAAMA,OAAM,IAAI,SAAS,EAAE,SAAI,OAAO,MAAM,CAAC,IAAIA,OAAM,KAAK,SAAI,OAAO,KAAK,CAAC;AACnF,QAAM,MAAM,KAAK,MAAM,QAAQ,GAAG;AAClC,SAAO,GAAG,GAAG,IAAI,GAAG;AACtB;AA3EA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;ACFA;AAAA;AAAA;AAAA;AAIA,SAAS,SAAS,cAAc;AAChC,SAAS,YAAY;AACrB,OAAOC,SAAQ;AAGf,eAAsB,eAAe,YAA6C;AAChF,MAAI;AACF,UAAM,OAAO,UAAU;AAAA,EACzB,QAAQ;AACN,UAAM,IAAI,MAAM,wBAAwB,UAAU,EAAE;AAAA,EACtD;AAEA,QAAM,CAAC,OAAO,WAAW,gBAAgB,GAAG,IAAI,MAAM,QAAQ,IAAI;AAAA,IAChE,YAAY,UAAU;AAAA,IACtB,cAAc,UAAU;AAAA,IACxB,oBAAoB,UAAU;AAAA,IAC9B,WAAW,UAAU;AAAA,EACvB,CAAC;AAED,SAAO,EAAE,OAAO,WAAW,gBAAgB,IAAI;AACjD;AAEA,eAAe,YAAY,KAAiC;AAC1D,QAAMC,QAAkB;AAAA,IACtB,WAAW,CAAC;AAAA,IACZ,YAAY,CAAC;AAAA,IACb,gBAAgB;AAAA,IAChB,eAAe;AAAA,EACjB;AAEA,MAAI,MAAMD,IAAG,WAAW,KAAK,KAAK,cAAc,CAAC,GAAG;AAClD,IAAAC,MAAK,UAAU,KAAK,YAAY;AAChC,IAAAA,MAAK,iBAAiB;AAEtB,QAAI;AACF,YAAMC,OAAM,MAAMF,IAAG,SAAS,KAAK,KAAK,cAAc,CAAC;AACvD,YAAM,UAAkC;AAAA,QACtC,GAAIE,KAAI,gBAAgB,CAAC;AAAA,QACzB,GAAIA,KAAI,mBAAmB,CAAC;AAAA,MAC9B;AAEA,UAAI,QAAQ,YAAY,KAAM,MAAMF,IAAG,WAAW,KAAK,KAAK,eAAe,CAAC,GAAI;AAC9E,QAAAC,MAAK,gBAAgB;AACrB,QAAAA,MAAK,UAAU,KAAK,YAAY;AAAA,MAClC;AAEA,YAAM,eAAuC;AAAA,QAC3C,OAAO;AAAA,QACP,KAAK;AAAA,QACL,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,QACT,QAAQ;AAAA,QACR,QAAQ;AAAA,QACR,SAAS;AAAA,MACX;AAEA,iBAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,YAAY,GAAG;AACtD,YAAI,QAAQ,GAAG,KAAK,QAAQ,IAAI,GAAG,OAAO,GAAG;AAC3C,UAAAA,MAAK,WAAW,KAAK,IAAI;AAAA,QAC3B;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAEA,QAAI,MAAMD,IAAG,WAAW,KAAK,KAAK,gBAAgB,CAAC,EAAG,CAAAC,MAAK,iBAAiB;AAAA,aACnE,MAAMD,IAAG,WAAW,KAAK,KAAK,WAAW,CAAC,EAAG,CAAAC,MAAK,iBAAiB;AAAA,aACnE,MAAMD,IAAG,WAAW,KAAK,KAAK,WAAW,CAAC,EAAG,CAAAC,MAAK,iBAAiB;AAAA,EAC9E;AAEA,MACG,MAAMD,IAAG,WAAW,KAAK,KAAK,gBAAgB,CAAC,KAC/C,MAAMA,IAAG,WAAW,KAAK,KAAK,kBAAkB,CAAC,GAClD;AACA,IAAAC,MAAK,UAAU,KAAK,QAAQ;AAAA,EAC9B;AACA,MAAI,MAAMD,IAAG,WAAW,KAAK,KAAK,QAAQ,CAAC,EAAG,CAAAC,MAAK,UAAU,KAAK,IAAI;AACtE,MAAI,MAAMD,IAAG,WAAW,KAAK,KAAK,YAAY,CAAC,EAAG,CAAAC,MAAK,UAAU,KAAK,MAAM;AAC5E,MACG,MAAMD,IAAG,WAAW,KAAK,KAAK,SAAS,CAAC,KACxC,MAAMA,IAAG,WAAW,KAAK,KAAK,cAAc,CAAC,GAC9C;AACA,IAAAC,MAAK,UAAU,KAAK,MAAM;AAAA,EAC5B;AAEA,SAAOA;AACT;AAEA,eAAe,cAAc,KAAqC;AAChE,QAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;AAC1D,QAAM,YAAY,QAAQ,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AACrE,QAAM,WAAW,QACd,OAAO,CAAC,MAAM,EAAE,YAAY,KAAK,CAAC,EAAE,KAAK,WAAW,GAAG,CAAC,EACxD,IAAI,CAAC,MAAM,EAAE,IAAI;AAEpB,QAAM,mBAAmB,CAAC,OAAO,OAAO,OAAO,QAAQ;AACvD,QAAM,YAAY,iBAAiB,KAAK,CAAC,MAAM,SAAS,SAAS,CAAC,CAAC,KAAK;AAExE,QAAM,iBAAiB,CAAC,QAAQ,SAAS,aAAa,MAAM;AAC5D,QAAM,UAAU,eAAe,KAAK,CAAC,MAAM,SAAS,SAAS,CAAC,CAAC,KAAK;AAEpE,QAAM,aAAa,SAAS,SAAS,UAAU,KAAK,SAAS,SAAS,MAAM;AAE5E,SAAO,EAAE,WAAW,UAAU,WAAW,SAAS,WAAW;AAC/D;AAEA,eAAe,oBAAoB,KAAsC;AACvE,QAAM,CAAC,aAAa,cAAc,WAAW,aAAa,MAAM,IAAI,MAAM,QAAQ,IAAI;AAAA,IACpFD,IAAG,WAAW,KAAK,KAAK,WAAW,CAAC;AAAA,IACpCA,IAAG,WAAW,KAAK,KAAK,SAAS,CAAC;AAAA,IAClCA,IAAG,WAAW,KAAK,KAAK,MAAM,CAAC;AAAA,IAC/BA,IAAG,WAAW,KAAK,KAAK,QAAQ,aAAa,CAAC,EAAE;AAAA,MAAK,CAAC,MACpD,IAAI,IAAIA,IAAG,WAAW,KAAK,KAAK,aAAa,CAAC;AAAA,IAChD;AAAA,IACAA,IAAG,WAAW,KAAK,KAAK,QAAQ,QAAQ,CAAC;AAAA,EAC3C,CAAC;AAED,MAAI,iBAAiD;AACrD,MAAI;AACF,QAAI,MAAMA,IAAG,WAAW,KAAK,KAAK,WAAW,eAAe,CAAC,GAAG;AAC9D,uBAAiB,MAAMA,IAAG,SAAS,KAAK,KAAK,WAAW,eAAe,CAAC;AAAA,IAC1E;AAAA,EACF,QAAQ;AAAA,EAER;AAEA,QAAM,eAAe,MAAM,aAAa,KAAK,KAAK,WAAW,QAAQ,CAAC;AACtE,QAAM,iBAAiB,MAAM,aAAa,KAAK,KAAK,WAAW,UAAU,CAAC;AAE1E,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,aAAa,SAAoC;AAC9D,MAAI;AACF,UAAM,UAAU,MAAM,QAAQ,SAAS,EAAE,eAAe,KAAK,CAAC;AAC9D,WAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI;AAAA,EACjE,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAEA,eAAe,WAAW,KAA+B;AACvD,QAAM,YAAY,MAAMA,IAAG,WAAW,KAAK,KAAK,MAAM,CAAC;AACvD,MAAI,CAAC,WAAW;AACd,WAAO,EAAE,WAAW,OAAO,WAAW,MAAM,UAAU,MAAM,eAAe,KAAK;AAAA,EAClF;AAEA,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AAEtC,iBAAe,OAAO,MAAwC;AAC5D,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,MAAM,OAAO,MAAM,EAAE,KAAK,SAAS,IAAK,CAAC;AAClE,aAAO,OAAO,KAAK,KAAK;AAAA,IAC1B,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,CAAC,WAAW,aAAa,IAAI,MAAM,QAAQ,IAAI;AAAA,IACnD,OAAO,CAAC,UAAU,WAAW,QAAQ,CAAC;AAAA,IACtC,OAAO,CAAC,UAAU,gBAAgB,CAAC;AAAA,EACrC,CAAC;AAED,MAAI,WAA0B;AAC9B,MAAI,WAAW;AACb,UAAM,QAAQ,UAAU,MAAM,uBAAuB;AACrD,eAAW,QAAQ,CAAC,KAAK;AAAA,EAC3B;AAEA,SAAO,EAAE,WAAW,WAAW,UAAU,cAAc;AACzD;AAzLA;AAAA;AAAA;AAAA;AAAA;;;ACoCA,eAAsB,aACpB,UACA,KACA,aAC0B;AAE1B,MAAI;AACF,WAAO,MAAM,YAAY,UAAU,KAAK,WAAW;AAAA,EACrD,QAAQ;AAAA,EAER;AAEA,SAAO,qBAAqB,UAAU,KAAK,WAAW;AACxD;AAEA,eAAe,YACb,UACA,MACA,aAC0B;AAE1B,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,gCAAgC;AAE/D,EAAG,KAAK,4EAAqB;AAE7B,QAAM,SAAS,cAAc,QAAQ;AACrC,MAAI,aAAa;AAEjB,mBAAiB,WAAW,MAAM;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,MACP,UAAU;AAAA,MACV,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAed,cAAc,CAAC;AAAA,MACf,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC,GAAG;AACF,QAAI,YAAY,SAAS;AACvB,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,SAAO,cAAc,YAAY,UAAU,WAAW;AACxD;AAEA,SAAS,cAAc,UAAkC;AACvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,SAAS,MAAM,UAAU,KAAK,IAAI,KAAK,eAAe;AAAA,IACtE,iBAAiB,SAAS,MAAM,WAAW,KAAK,IAAI,KAAK,MAAM;AAAA,IAC/D,sBAAsB,SAAS,MAAM,kBAAkB,MAAM;AAAA,IAC7D,iBAAiB,SAAS,MAAM,gBAAgB,QAAQ,IAAI;AAAA,IAC5D,UAAU,SAAS,IAAI,YAAY,QAAQ,IAAI;AAAA,IAC/C,aAAa,SAAS,IAAI,aAAa,MAAM;AAAA,IAC7C,eAAe,SAAS,UAAU,aAAa,QAAQ,IAAI;AAAA,IAC3D,gBAAgB,SAAS,eAAe,cAAc,QAAQ,IAAI;AAAA,IAClE;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAEA,SAAS,cACP,QACA,UACA,aACiB;AACjB,QAAM,YAAY,OAAO,MAAM,yBAAyB;AACxD,MAAI,YAAY,CAAC,GAAG;AAClB,QAAI;AACF,YAAM,SAAS,KAAK,MAAM,UAAU,CAAC,CAAC;AACtC,aAAO;AAAA,QACL,MAAM,cAAc,OAAO,IAAI;AAAA,QAC/B;AAAA,QACA,aAAa,OAAO,eAAe,CAAC;AAAA,QACpC,YAAY,OAAO,cAAc,CAAC;AAAA,QAClC,cAAc;AAAA,UACZ,WAAW;AAAA,UACX,aAAa,OAAO,cAAc,eAAe;AAAA,UACjD,MAAM,OAAO,cAAc,QAAQ,SAAS,IAAI;AAAA,QAClD;AAAA,QACA,OAAO;AAAA,UACL,KAAK;AAAA,UACL,UAAU,OAAO,OAAO,YAAY;AAAA,UACpC,WAAW,OAAO,OAAO,aAAa;AAAA,UACtC,SAAS,OAAO,OAAO,WAAW;AAAA,QACpC;AAAA,QACA,eAAe;AAAA,MACjB;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,EAAG,KAAK,0IAA2C;AACnD,QAAM,IAAI,MAAM,iBAAiB;AACnC;AAEA,eAAe,qBACb,UACA,MACA,aAC0B;AAC1B,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAMG,UAAS,MAAM,OAAO,OAAO,GAAG;AAGtC,EAAG,KAAK,GAAG,GAAG,kFAAiB;AAC/B,EAAG,KAAK,sIAA6B;AACrC,UAAQ,IAAI,EAAE;AAEd,QAAM,EAAE,KAAK,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACtC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,MAAM,0BAAmB,OAAE,IAAI,8GAA6B,CAAC;AAAA,QAC7D,OAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM,0BAAmB,OAAE,IAAI,sGAA6B,CAAC;AAAA,QAC7D,OAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM,0BAAmB,OAAE,IAAI,gHAA4B,CAAC;AAAA,QAC5D,OAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF,CAAC,CAAC;AAGF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,6DAAgB,CAAC;AACnC,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,QAAM,SAAmC;AAAA,IACvC,WAAY,CAAC,uBAAa,kBAAkB,uBAAa;AAAA,IACzD,KAAY,CAAC,uBAAa,kBAAkB,yBAAe,kCAAc,oCAAgB;AAAA,IACzF,YAAY,CAAC,uBAAa,kBAAkB,yBAAe,kCAAc,+BAAgB,0BAAgB,sCAAkB,4BAAkB;AAAA,EAC/I;AACA,aAAW,QAAQ,OAAO,IAAc,KAAK,CAAC,GAAG;AAC/C,YAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,IAAI,IAAI,EAAE;AAAA,EAC3C;AAGA,EAAG,KAAK,GAAG,GAAG,iCAAQ;AACtB,EAAG,KAAK,8EAAkB;AAC1B,UAAQ,IAAI,EAAE;AAEd,QAAM,EAAE,SAAS,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IAC1C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,sDAAc,OAAO,MAAM;AAAA,MACnC,EAAE,MAAM,0CAAY,OAAO,KAAK;AAAA,IAClC;AAAA,EACF,CAAC,CAAC;AAEF,MAAI,cAAwB,CAAC;AAC7B,MAAI;AAEJ,MAAI,UAAU;AACZ,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,4EAA4B;AACpC,UAAM,YAAa,SAAmE;AACtF,UAAM,EAAE,MAAM,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACvC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,6BAAc,OAAO,SAAS;AAAA,QACtC,EAAE,MAAM,4BAAa,OAAO,QAAQ;AAAA,QACpC,EAAE,MAAM,4BAAa,OAAO,QAAQ;AAAA,QACpC,EAAE,MAAM,6BAAS,OAAE,IAAI,UAAU,CAAC,IAAI,OAAO,SAAS;AAAA,QACtD,IAAI,UAAU,wJAA2B;AAAA,QACzC,EAAE,MAAMA,OAAM,MAAM,kCAAS,GAAG,OAAO,WAAW;AAAA,MACpD;AAAA,MACA,UAAU,CAAC,WAAqB;AAC9B,cAAM,QAAQ,OAAO,OAAO,OAAK,MAAM,UAAU;AACjD,YAAI,MAAM,WAAW,EAAG,QAAO;AAC/B,eAAO;AAAA,MACT;AAAA,IACF,CAAC,CAAC;AACF,kBAAe,MAAmB,OAAO,OAAK,MAAM,UAAU;AAE9D,QAAI,YAAY,SAAS,QAAQ,GAAG;AAClC,cAAQ,IAAI,EAAE;AACd,YAAM,EAAE,YAAY,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,QAC7C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACP,EAAE,MAAM,yCAAW,OAAO,KAAK;AAAA,UAC/B,EAAE,MAAM,gDAAa,OAAE,IAAI,iEAAyB,CAAC,IAAI,OAAO,MAAM;AAAA,QACxE;AAAA,MACF,CAAC,CAAC;AAEF,UAAI,aAAa;AACf,QAAG,KAAK,2FAA0B;AAClC,qBAAa,MAAM,SAAS,OAAO;AAAA,UACjC,EAAE,MAAM,SAAS,MAAM,YAAY,SAAS,aAAa;AAAA,UACzD,EAAE,MAAM,YAAY,MAAM,gBAAgB,SAAS,kBAAkB,MAAM,IAAI;AAAA,QACjF,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AAGA,MAAI,aAAuB,CAAC;AAG5B,MAAI,SAAS,SAAS,SAAS,cAAc;AAC3C,eAAW,KAAK,KAAK;AAAA,EACvB;AAGA,MAAI,SAAS,SAAS,SAAS,cAAc;AAC3C,YAAQ,IAAI,EAAE;AACd,UAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACzC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,mBAAmB,OAAE,IAAI,0DAAiC,CAAC,IAAI,OAAO,SAAS;AAAA,QACvF,EAAE,MAAM,iDAAc,OAAE,IAAI,mCAAyB,CAAC,IAAI,OAAO,QAAQ;AAAA,QACzE,EAAE,MAAM,6CAAe,OAAE,IAAI,6DAAgB,CAAC,IAAI,OAAO,OAAO;AAAA,MAClE;AAAA,IACF,CAAC,CAAC;AACF,QAAI,YAAY,SAAU,YAAW,KAAK,QAAQ;AAAA,EACpD;AAGA,MAAI,SAAS,cAAc;AACzB,YAAQ,IAAI,EAAE;AACd,UAAM,EAAE,SAAS,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MAC1C,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,mBAAmB,OAAE,IAAI,qCAAgC,CAAC,IAAI,OAAO,WAAW;AAAA,QACxF,EAAE,MAAM,iDAAc,OAAE,IAAI,4CAAkC,CAAC,IAAI,OAAO,QAAQ;AAAA,QAClF,EAAE,MAAM,6CAAe,OAAE,IAAI,mDAAgB,CAAC,IAAI,OAAO,OAAO;AAAA,MAClE;AAAA,IACF,CAAC,CAAC;AACF,QAAI,aAAa,WAAY,YAAW,KAAK,UAAU;AACvD,eAAW,KAAK,UAAU,SAAS;AAAA,EACrC;AAGA,MAAI;AACJ,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACzC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,kCAAc,OAAE,IAAI,8HAA+B,CAAC,IAAI,OAAO,MAAM;AAAA,MAC7E,EAAE,MAAM,yCAAW,OAAO,KAAK;AAAA,IACjC;AAAA,IACA,SAAS;AAAA,EACX,CAAC,CAAC;AACF,QAAM,SAAS,YAAY;AAE3B,MAAI,QAAQ;AACV,YAAQ,IAAI,EAAE;AACd,UAAM,cAAc,WAAW,SAAS,UAAU;AAClD,UAAM,cAAsD;AAAA,MAC1D,EAAE,MAAM,8CAAqB,OAAE,IAAI,+DAAkB,CAAC,IAAI,OAAO,QAAQ;AAAA,IAC3E;AACA,QAAI,aAAa;AACf,kBAAY,KAAK;AAAA,QACf,MAAM,kDAAoB,OAAE,IAAI,iFAA0B,CAAC;AAAA,QAC3D,OAAO;AAAA,MACT,CAAC;AAAA,IACH;AACA,gBAAY;AAAA,MACV,EAAE,MAAM,kCAAwB,OAAE,IAAI,qEAAmB,CAAC,IAAI,OAAO,YAAY;AAAA,MACjF,EAAE,MAAM,kCAAwB,OAAE,IAAI,wEAAiB,CAAC,IAAI,OAAO,UAAU;AAAA,MAC7E,EAAE,MAAM,0BAA0B,OAAE,IAAI,mCAAU,CAAC,IAAI,OAAO,MAAM;AAAA,IACtE;AAEA,UAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACzC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX,CAAC,CAAC;AAEF,UAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACzC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,GAAG,WAAW;AAAA,MACvB,UAAU,CAAC,MAAc,uBAAuB,KAAK,EAAE,KAAK,CAAC,IACzD,OACA;AAAA,IACN,CAAC,CAAC;AAEF,UAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM;AAAA,MACN,MAAM,QAAQ,KAAK;AAAA,IACrB;AACA,eAAW,KAAK,KAAK;AAAA,EACvB;AAGA,EAAG,KAAK,GAAG,GAAG,2BAAO;AACrB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,mCAAU,CAAC;AAC7B,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,+CAAiB;AAChD,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,sCAAa;AAC5C,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,qCAAY;AAC3C,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,0CAAsB;AACrD,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,6CAAe;AAE9C,MAAI,WAAW,SAAS,GAAG;AACzB,YAAQ,IAAI,EAAE;AACd,QAAI,WAAW,SAAS,QAAQ,EAAG,SAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,mCAAe;AAChF,QAAI,WAAW,SAAS,UAAU,EAAG,SAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,gDAAkB;AACrF,QAAI,WAAW,SAAS,QAAQ,EAAG,SAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,+CAAiB;AAClF,QAAI,WAAW,SAAS,SAAS,EAAG,SAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,oCAAgB;AAClF,QAAI,WAAW,SAAS,KAAK,KAAK,KAAK;AACrC,cAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,sBAAY,IAAI,IAAI,KAAK,IAAI,IAAI,GAAG;AAAA,IACpE;AAAA,EACF;AAEA,MAAI,YAAY,SAAS,GAAG;AAC1B,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,KAAK,OAAE,OAAO,GAAG,CAAC,wBAAS,YAAY,KAAK,IAAI,CAAC,EAAE;AAAA,EACjE;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACzC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC,CAAC;AAEF,MAAI,CAAC,SAAS;AACZ,IAAG,KAAK,4GAAsC;AAC9C,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,kBAAkB,SAAS,MAAM,WAAW;AAAA,IAAK,CAAC,MACtD,CAAC,SAAS,OAAO,WAAW,QAAQ,UAAU,SAAS,EAAE,SAAS,CAAC;AAAA,EACrE;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,MACZ,WAAW;AAAA,MACX,aAAa;AAAA,MACb,MAAM,SAAS,IAAI;AAAA,IACrB;AAAA,IACA,OAAO;AAAA,MACL,KAAK;AAAA,MACL,UAAU;AAAA,MACV,WAAW,SAAS,IAAI,WAAW,SAAS,YAAY,KAAK;AAAA,MAC7D,SAAS,WAAW,SAAS,SAAS,KAAK;AAAA,IAC7C;AAAA,IACA,eAAe;AAAA,EACjB;AACF;AAtaA;AAAA;AAAA;AAOA;AACA;AACA;AAAA;AAAA;;;ACTA;AAAA;AAAA;AAAA;AAIA,SAAS,QAAAC,aAAY;AACrB,OAAOC,SAAQ;AAYf,eAAsB,cACpB,KACA,UACA,WACmB;AACnB,QAAM,QAAyB,CAAC;AAGhC,QAAM,KAAK,iBAAiB,KAAK,UAAU,SAAS,CAAC;AAGrD,QAAM,KAAK,uBAAuB,KAAK,QAAQ,CAAC;AAGhD,MAAI,UAAU,aAAa,aAAa;AACtC,UAAM,KAAK,GAAG,oBAAoB,GAAG,CAAC;AAAA,EACxC;AAGA,MAAI,UAAU,aAAa,MAAM;AAC/B,UAAM,KAAK,GAAG,aAAa,KAAK,QAAQ,CAAC;AAAA,EAC3C;AAEA,QAAM,UAAoB,CAAC;AAC3B,aAAW,QAAQ,OAAO;AACxB,QAAK,MAAMA,IAAG,WAAW,KAAK,IAAI,KAAM,CAAC,KAAK,WAAW;AACvD;AAAA,IACF;AACA,UAAMA,IAAG,UAAUD,MAAK,KAAK,MAAM,IAAI,CAAC;AACxC,UAAMC,IAAG,UAAU,KAAK,MAAM,KAAK,SAAS,MAAM;AAClD,YAAQ,KAAK,KAAK,IAAI;AAAA,EACxB;AAEA,SAAO;AACT;AAMA,SAAS,iBACP,KACA,UACA,WACe;AACf,QAAM,QAAQ,CAAC,GAAG,SAAS,MAAM,WAAW,GAAG,SAAS,MAAM,UAAU,EAAE,KAAK,IAAI,KAAK;AACxF,QAAM,QAAQ,OAAO,QAAQ,UAAU,KAAK,EACzC,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,EACnB,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,EACd,KAAK,IAAI;AAEZ,QAAM,UAAU,KAAK,UAAU,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAoBzB,KAAK;AAAA,eACT,KAAK;AAAA,cACN,UAAU,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmB1B,SAAO;AAAA,IACL,MAAMD,MAAK,KAAK,WAAW;AAAA,IAC3B;AAAA,IACA,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEA,SAAS,uBAAuB,KAAa,UAAyC;AACpF,QAAM,QAAQ,sBAAsB,SAAS,MAAM,SAAS;AAE5D,QAAM,WAAoC;AAAA,IACxC,aAAa;AAAA,MACX,OAAO;AAAA,QACL;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,MAAM;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,IACA,GAAI,OAAO,KAAK,KAAK,EAAE,SAAS,IAAI,EAAE,MAAM,IAAI,CAAC;AAAA,EACnD;AAGA,MAAI,SAAS,eAAe,gBAAgB;AAC1C,UAAM,WAAW,SAAS,eAAe;AACzC,WAAO;AAAA,MACL,MAAMA,MAAK,KAAK,WAAW,eAAe;AAAA,MAC1C,SAAS,KAAK,UAAU,kBAAkB,UAAU,QAAQ,GAAG,MAAM,CAAC,IAAI;AAAA,MAC1E,aAAa;AAAA,MACb,WAAW;AAAA,IACb;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAMA,MAAK,KAAK,WAAW,eAAe;AAAA,IAC1C,SAAS,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI;AAAA,IAC7C,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF;AAEA,SAAS,kBACP,UACA,UACyB;AACzB,QAAM,SAAS,EAAE,GAAG,SAAS;AAE7B,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,QAAQ,GAAG;AACnD,QAAI,QAAQ,iBAAiB,OAAO,GAAG,KAAK,OAAO,OAAO,GAAG,MAAM,UAAU;AAC3E,YAAM,KAAK,OAAO,GAAG;AACrB,YAAM,KAAK;AACX,aAAO,GAAG,IAAI;AAAA,QACZ,OAAO,CAAC,GAAG,oBAAI,IAAI;AAAA,UACjB,GAAK,GAAG,OAAO,KAAkB,CAAC;AAAA,UAClC,GAAK,GAAG,OAAO,KAAkB,CAAC;AAAA,QACpC,CAAC,CAAC;AAAA,QACF,MAAM,CAAC,GAAG,oBAAI,IAAI;AAAA,UAChB,GAAK,GAAG,MAAM,KAAkB,CAAC;AAAA,UACjC,GAAK,GAAG,MAAM,KAAkB,CAAC;AAAA,QACnC,CAAC,CAAC;AAAA,MACJ;AAAA,IACF,WAAW,EAAE,OAAO,SAAS;AAC3B,aAAO,GAAG,IAAI;AAAA,IAChB;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,sBAAsB,WAA8C;AAC3E,QAAM,QAAiC,CAAC;AAExC,MAAI,UAAU,SAAS,YAAY,KAAK,UAAU,SAAS,YAAY,GAAG;AACxE,UAAM,aAAa,IAAI,CAAC;AAAA,MACtB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,6DAA6D,CAAC;AAAA,IACpG,CAAC;AAAA,EACH,WAAW,UAAU,SAAS,QAAQ,GAAG;AACvC,UAAM,aAAa,IAAI,CAAC;AAAA,MACtB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,2FAA2F,CAAC;AAAA,IAClI,CAAC;AAAA,EACH,WAAW,UAAU,SAAS,IAAI,GAAG;AACnC,UAAM,aAAa,IAAI,CAAC;AAAA,MACtB,SAAS;AAAA,MACT,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,iDAAiD,CAAC;AAAA,IACxF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,SAAS,oBAAoB,KAA8B;AACzD,QAAM,SAAS;AAAA,IACb,EAAE,MAAM,gBAAgB,OAAO,UAAU,MAAM,8GAAyB;AAAA,IACxE,EAAE,MAAM,sBAAsB,OAAO,gBAAgB,MAAM,8EAAkB;AAAA,IAC7E,EAAE,MAAM,kBAAkB,OAAO,YAAY,MAAM,qFAAoB;AAAA,IACvE,EAAE,MAAM,cAAc,OAAO,QAAQ,MAAM,qFAAoB;AAAA,IAC/D,EAAE,MAAM,mBAAmB,OAAO,aAAa,MAAM,iFAAqB;AAAA,EAC5E;AAEA,SAAO,OAAO,IAAI,CAAC,EAAE,MAAM,OAAO,KAAK,OAAO;AAAA,IAC5C,MAAMA,MAAK,KAAK,QAAQ,eAAe,IAAI;AAAA,IAC3C,SAAS,YAAY,KAAK;AAAA;AAAA,EAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IACrC,aAAa,YAAY,KAAK;AAAA,EAChC,EAAE;AACJ;AAEA,SAAS,aAAa,KAAa,UAA2C;AAC5E,QAAM,QAAyB,CAAC;AAEhC,QAAM,KAAK;AAAA,IACT,MAAMA,MAAK,KAAK,WAAW,aAAa,uBAAuB;AAAA,IAC/D,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAgBT,aAAa;AAAA,EACf,CAAC;AAED,QAAM,UAAU,eAAe,SAAS,MAAM,SAAS;AACvD,QAAM,KAAK;AAAA,IACT,MAAMA,MAAK,KAAK,UAAU,YAAY;AAAA,IACtC,SAAS,GAAG,OAAO;AAAA;AAAA,IACnB,aAAa;AAAA,EACf,CAAC;AAED,SAAO;AACT;AAEA,SAAS,eAAe,WAA6B;AACnD,MAAI,UAAU,SAAS,YAAY,KAAK,UAAU,SAAS,YAAY,EAAG,QAAO;AACjF,MAAI,UAAU,SAAS,QAAQ,EAAG,QAAO;AACzC,MAAI,UAAU,SAAS,IAAI,EAAG,QAAO;AACrC,MAAI,UAAU,SAAS,MAAM,EAAG,QAAO;AACvC,SAAO;AACT;AA5QA;AAAA;AAAA;AAAA;AAAA;;;ACGA,OAAOE,YAAW;AAiBlB,eAAsB,aAAa,OAAsB,MAAwC;AAE/F,SAAO,CAAC;AACV;AAiCO,SAAS,mBAAmB,SAA0B,OAA4B;AACvF,QAAM,cAAyD,CAAC;AAEhE,MAAI,MAAM,WAAW;AACnB,gBAAY,KAAK;AAAA,MACf,OAAO;AAAA,MACP,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AAEA,MAAI,YAAY,WAAW,EAAG;AAE9B,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,yHAAoC;AAC5C,UAAQ,IAAI,EAAE;AAEd,aAAWC,SAAQ,aAAa;AAC9B,YAAQ,IAAI,KAAKD,OAAM,KAAKC,MAAK,KAAK,CAAC,EAAE;AACzC,YAAQ,IAAI,OAAOD,OAAM,MAAMC,MAAK,OAAO,CAAC,EAAE;AAC9C,YAAQ,IAAI,EAAE;AAAA,EAChB;AACF;AA7EA;AAAA;AAAA;AAIA;AACA;AAAA;AAAA;;;ACLA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAO,QAAQ;AACf,OAAOC,SAAQ;AACf,OAAOC,WAAU;AACjB,SAAS,oBAAoB;AAUtB,SAAS,qBAAwC;AACtD,QAAM,SAAsC,CAAC;AAC7C,QAAM,WAA0C,CAAC;AAEjD,MAAI,CAAC,UAAW,QAAO,EAAE,QAAQ,SAAS;AAE1C,WAAS,KAAK;AAAA,IACZ,OAAO;AAAA,IACP,MAAM;AAAA,EACR,CAAC;AAED,QAAM,UAAU,QAAQ,IAAI,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK;AAC9D,MAAI,CAAC,QAAQ,YAAY,EAAE,SAAS,MAAM,GAAG;AAC3C,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,QAAM,OAAO,QAAQ,IAAI,MAAM,KAAK,QAAQ,IAAI,aAAa;AAC7D,MAAI,CAAC,MAAM;AACT,WAAO,KAAK;AAAA,MACV,OAAO;AAAA,MACP,KAAK;AAAA,IACP,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,QAAQ,SAAS;AAC5B;AAEO,SAAS,aAAa,UAAkB,SAAuC;AACpF,QAAM,UAAU,OAAO,QAAQ,OAAO,EACnC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,EAC3B,KAAK,IAAI;AACZ,EAAAD,IAAG,cAAc,UAAU,UAAU,MAAM,EAAE,UAAU,OAAO,CAAC;AACjE;AAEO,SAAS,kBAAkB;AAChC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,CAAC,aAAa,CAAC;AAAA,IACxB,OAAO,YAAY,eAAgB,QAAQ,IAAI,OAAO,KAAK;AAAA,IAC3D,MAAM,QAAQ,IAAI,MAAM,KAAK,QAAQ,IAAI,aAAa,KAAK,GAAG,QAAQ;AAAA,IACtE,aAAa,QAAQ;AAAA,EACvB;AACF;AAOO,SAAS,iBAAyB;AACvC,QAAM,OAAO,GAAG,QAAQ;AACxB,MAAI,WAAW;AAEb,UAAM,MAAMC,MAAK,KAAK,MAAM,aAAa,cAAc,kCAAkC;AAEzF,UAAM,MAAMA,MAAK,KAAK,MAAM,aAAa,qBAAqB,kCAAkC;AAEhG,QAAID,IAAG,WAAWC,MAAK,QAAQ,GAAG,CAAC,EAAG,QAAO;AAC7C,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,QAAQ,IAAI,OAAO,KAAK;AACtC,SAAO,MAAM,SAAS,KAAK,IACvBA,MAAK,KAAK,MAAM,QAAQ,IACxBA,MAAK,KAAK,MAAM,SAAS;AAC/B;AAOO,SAAS,cAAc,KAAmB;AAC/C,MAAI;AACF,QAAI,WAAW;AACb,mBAAa,kBAAkB,CAAC,WAAW,YAAY,iBAAiB,GAAG,GAAG,GAAG;AAAA,QAC/E,OAAO;AAAA,QACP;AAAA,MACF,CAAC;AAAA,IACH,OAAO;AACL,YAAM,QAAQ,QAAQ,IAAI,OAAO,KAAK;AACtC,mBAAa,OAAO,CAAC,IAAI,GAAG,EAAE,OAAO,WAAW,IAAI,CAAC;AAAA,IACvD;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAKO,SAAS,mBAA2B;AACzC,MAAI,WAAW;AACb,WAAO;AAAA,EACT;AACA,SAAO;AACT;AAKO,SAAS,aAAa,WAA4B;AACvD,SAAO,UAAU,SAAS,aAAa,KAAK,UAAU,SAAS,8BAA8B;AAC/F;AAQO,SAAS,2BAA2B,MAAsB;AAC/D,SAAO,KAAK,QAAQ,iBAAiB,GAAG;AAC1C;AAjIA,IAKa,WACA;AANb;AAAA;AAAA;AAKO,IAAM,YAAY,QAAQ,aAAa;AACvC,IAAM,QAAQ,QAAQ,aAAa;AAAA;AAAA;;;ACN1C;AAAA;AAAA;AAAA;AAIA,SAAS,QAAAC,aAAY;AACrB,OAAOC,SAAQ;AAKf,eAAsB,aAAa,KAAwC;AACzE,QAAM,MAAO,IAEV;AAEH,MAAI,CAAC,KAAK,QAAS;AAEnB,QAAM,SAASD,MAAK,IAAI,KAAK,YAAY;AACzC,QAAMC,IAAG,UAAU,MAAM;AACzB,QAAMA,IAAG,UAAUD,MAAK,QAAQ,KAAK,CAAC;AACtC,QAAMC,IAAG,UAAUD,MAAK,QAAQ,OAAO,CAAC;AAGxC,QAAM,eAAe,IAAI,SAAS;AAClC,QAAM,UAAU;AAAA,IACd,MAAM,IAAI;AAAA,IACV,SAAS;AAAA,IACT,aAAa,kBAAkB,IAAI,WAAW;AAAA,IAC9C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,KAAK,EAAE,CAAC,IAAI,IAAI,GAAG,kBAAkB;AAAA,IACrC,SAAS;AAAA,MACP,OAAO;AAAA,MACP,KAAK;AAAA,MACL,MAAM;AAAA,MACN,OAAO;AAAA,IACT;AAAA,IACA,cAAc;AAAA,MACZ,6BAA6B;AAAA,MAC7B,GAAI,eAAe,EAAE,yBAAyB,UAAU,IAAI,CAAC;AAAA,IAC/D;AAAA,IACA,iBAAiB;AAAA,MACf,YAAY;AAAA,MACZ,eAAe;AAAA,MACf,QAAQ;AAAA,IACV;AAAA,EACF;AACA,QAAM,UAAUA,MAAK,QAAQ,cAAc;AAC3C,MAAI,CAAE,MAAMC,IAAG,WAAW,OAAO,GAAI;AACnC,UAAMA,IAAG,UAAU,SAAS,SAAS,EAAE,QAAQ,EAAE,CAAC;AAAA,EACpD;AAGA,QAAM,WAAW;AAAA,IACf,iBAAiB;AAAA,MACf,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,kBAAkB;AAAA,MAClB,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,iBAAiB;AAAA,MACjB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,aAAa;AAAA,IACf;AAAA,IACA,SAAS,CAAC,UAAU;AAAA,IACpB,SAAS,CAAC,gBAAgB,QAAQ,OAAO;AAAA,EAC3C;AACA,QAAM,SAASD,MAAK,QAAQ,eAAe;AAC3C,MAAI,CAAE,MAAMC,IAAG,WAAW,MAAM,GAAI;AAClC,UAAMA,IAAG,UAAU,QAAQ,UAAU,EAAE,QAAQ,EAAE,CAAC;AAAA,EACpD;AAGA,QAAM,YAAYD,MAAK,QAAQ,OAAO,UAAU;AAChD,MAAI,CAAE,MAAMC,IAAG,WAAW,SAAS,GAAI;AACrC,UAAMA,IAAG,UAAU,WAAW,aAAa,GAAG,GAAG,MAAM;AAAA,EACzD;AAGA,QAAM,UAAU,IAAI,SAAS,WAAW,IAAI,SAAS,kBAAkB,IAAI,SAAS;AACpF,QAAM,WAAW,IAAI,SAAS;AAE9B,MAAI,SAAS;AACX,UAAM,YAAYD,MAAK,QAAQ,OAAO,UAAU;AAChD,QAAI,CAAE,MAAMC,IAAG,WAAW,SAAS,GAAI;AACrC,YAAMA,IAAG,UAAU,WAAW,WAAW,wBAAwB,gBAAgB,MAAM;AAAA,IACzF;AAAA,EACF;AAGA,MAAI,UAAU;AACZ,UAAM,WAAWD,MAAK,QAAQ,OAAO,SAAS;AAC9C,QAAI,CAAE,MAAMC,IAAG,WAAW,QAAQ,GAAI;AACpC,YAAMA,IAAG,UAAU,UAAU,0BAA0B,MAAM;AAAA,IAC/D;AAEA,UAAM,gBAAgBD,MAAK,QAAQ,OAAO,eAAe;AACzD,QAAI,CAAE,MAAMC,IAAG,WAAW,aAAa,GAAI;AACzC,YAAMA,IAAG,UAAU,eAAe,qBAAqB,MAAM;AAAA,IAC/D;AAGA,UAAM,SAASD,MAAK,IAAI,KAAK,YAAY,YAAY;AACrD,UAAMC,IAAG,UAAU,MAAM;AACzB,UAAM,UAAUD,MAAK,QAAQ,iCAAiC;AAC9D,QAAI,CAAE,MAAMC,IAAG,WAAW,OAAO,GAAI;AACnC,YAAMA,IAAG,UAAU,SAAS,oBAAoB,MAAM;AAAA,IACxD;AAGA,UAAM,UAAUD,MAAK,IAAI,KAAK,OAAO,OAAO,WAAW;AACvD,UAAMC,IAAG,UAAUD,MAAK,SAAS,MAAM,CAAC;AACxC,UAAMC,IAAG,UAAUD,MAAK,SAAS,OAAO,CAAC;AAEzC,UAAM,iBAAiBA,MAAK,SAAS,YAAY;AACjD,QAAI,CAAE,MAAMC,IAAG,WAAW,cAAc,GAAI;AAC1C,YAAMA,IAAG,UAAU,gBAAgB,kBAAkB,MAAM;AAAA,IAC7D;AACA,UAAM,eAAeD,MAAK,SAAS,UAAU;AAC7C,QAAI,CAAE,MAAMC,IAAG,WAAW,YAAY,GAAI;AACxC,YAAMA,IAAG,UAAU,cAAc,gBAAgB,MAAM;AAAA,IACzD;AACA,UAAM,eAAeD,MAAK,SAAS,QAAQ,UAAU;AACrD,QAAI,CAAE,MAAMC,IAAG,WAAW,YAAY,GAAI;AACxC,YAAMA,IAAG,UAAU,cAAc,WAAW,MAAM;AAAA,IACpD;AACA,UAAM,gBAAgBD,MAAK,SAAS,SAAS,UAAU;AACvD,QAAI,CAAE,MAAMC,IAAG,WAAW,aAAa,GAAI;AACzC,YAAMA,IAAG,UAAU,eAAe,YAAY,MAAM;AAAA,IACtD;AAGA,UAAM,aAAaD,MAAK,IAAI,KAAK,OAAO,OAAO,OAAO,MAAM;AAC5D,UAAMC,IAAG,UAAU,UAAU;AAC7B,UAAM,gBAAgBD,MAAK,YAAY,UAAU;AACjD,QAAI,CAAE,MAAMC,IAAG,WAAW,aAAa,GAAI;AACzC,YAAMA,IAAG,UAAU,eAAe,gBAAgB,MAAM;AAAA,IAC1D;AAAA,EACF;AACA,MAAI,IAAI,SAAS,eAAe,IAAI,SAAS,OAAO;AAClD,UAAM,UAAUD,MAAK,QAAQ,OAAO,cAAc;AAClD,QAAI,CAAE,MAAMC,IAAG,WAAW,OAAO,GAAI;AACnC,YAAMA,IAAG,UAAU,SAAS,oBAAoB,MAAM;AAAA,IACxD;AAAA,EACF;AACA,MAAI,IAAI,SAAS,aAAa,IAAI,SAAS,OAAO;AAChD,UAAM,cAAcD,MAAK,QAAQ,OAAO,YAAY;AACpD,QAAI,CAAE,MAAMC,IAAG,WAAW,WAAW,GAAI;AACvC,YAAMA,IAAG,UAAU,aAAa,kBAAkB,MAAM;AAAA,IAC1D;AAAA,EACF;AAGA,QAAM,WAAWD,MAAK,QAAQ,SAAS,gBAAgB;AACvD,MAAI,CAAE,MAAMC,IAAG,WAAW,QAAQ,GAAI;AACpC,UAAMA,IAAG,UAAU,UAAU,eAAe,MAAM;AAAA,EACpD;AAGA,QAAM,aAAaD,MAAK,QAAQ,WAAW;AAC3C,MAAI,CAAE,MAAMC,IAAG,WAAW,UAAU,GAAI;AACtC,UAAMA,IAAG,UAAU,YAAY,YAAY,GAAG,GAAG,MAAM;AAAA,EACzD;AAGA,QAAM,eAAeD,MAAK,IAAI,KAAK,QAAQ,aAAa;AACxD,MAAI,MAAMC,IAAG,WAAW,YAAY,GAAG;AACrC,UAAM,WAAW,MAAMA,IAAG,SAAS,cAAc,MAAM;AACvD,QAAI,CAAC,SAAS,SAAS,qBAAW,GAAG;AACnC,YAAMC,WAAU,wBAAwB,GAAG;AAC3C,YAAMD,IAAG,WAAW,cAAc;AAAA;AAAA,EAAOC,QAAO;AAAA,CAAI;AAAA,IACtD;AAAA,EACF;AAGA,QAAM,cAAcF,MAAK,IAAI,KAAK,WAAW;AAC7C,QAAM,UAAW,MAAMC,IAAG,WAAW,WAAW,IAC5C,MAAMA,IAAG,SAAS,WAAW,IAC7B,EAAE,YAAY,CAAC,EAAE;AACrB,UAAQ,WAAW,IAAI,IAAI,IAAI;AAAA,IAC7B,SAAS;AAAA,IACT,MAAM,CAAC,4BAA4B;AAAA,EACrC;AACA,QAAMA,IAAG,UAAU,aAAa,SAAS,EAAE,QAAQ,EAAE,CAAC;AAGtD,QAAM,gBAAgBD,MAAK,QAAQ,YAAY;AAC/C,MAAI,CAAE,MAAMC,IAAG,WAAW,aAAa,GAAI;AACzC,UAAMA,IAAG,UAAU,eAAe,iCAAiC,MAAM;AAAA,EAC3E;AACF;AAEA,SAAS,aAAa,KAA8C;AAClE,QAAM,UAAoB,CAAC;AAC3B,QAAM,gBAA0B,CAAC;AAEjC,MAAI,IAAI,SAAS,WAAW,IAAI,SAAS,OAAO;AAC9C,YAAQ,KAAK,6CAA6C;AAC1D,kBAAc,KAAK,0BAA0B;AAAA,EAC/C;AACA,MAAI,IAAI,SAAS,eAAe,IAAI,SAAS,OAAO;AAClD,YAAQ,KAAK,qDAAqD;AAClE,kBAAc,KAAK,8BAA8B;AAAA,EACnD;AACA,MAAI,IAAI,SAAS,aAAa,IAAI,SAAS,OAAO;AAChD,YAAQ,KAAK,iDAAiD;AAC9D,kBAAc,KAAK,4BAA4B;AAAA,EACjD;AAEA,SAAO;AAAA;AAAA,KAEJ,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKX,QAAQ,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA,eAKL,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAKrB,IAAI,SAAS,WAAW,IAAI,SAAS,QAAQ,uBAAuB,EAAE;AAAA,EACtE,IAAI,SAAS,eAAe,IAAI,SAAS,QAAQ,2BAA2B,EAAE;AAAA,EAC9E,IAAI,SAAS,aAAa,IAAI,SAAS,QAAQ,yBAAyB,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA,EAK1E,cAAc,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA;AAAA,mBAIP,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQ3B;AAmfA,SAAS,wBAAwB,KAA8C;AAC7E,QAAM,WAAW,IAAI,SAAS;AAC9B,QAAM,WAAW,IAAI,SAAS,WAAW,IAAI,SAAS,kBAAkB,IAAI,SAAS;AACrF,QAAM,eAAe,IAAI,SAAS,eAAe,IAAI,SAAS;AAC9D,QAAM,aAAa,IAAI,SAAS,aAAa,IAAI,SAAS;AAE1D,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,uBAAa,IAAI,IAAI;AAAA,IACrB,uBAAa,IAAI,IAAI;AAAA,EACvB;AAEA,MAAI,UAAU;AACZ,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,KAAK,IAAI,mFAA4B;AAE3C,MAAI,UAAU;AACZ,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,cAAc;AAChB,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,YAAY;AACd,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,MAAI,UAAU;AACZ,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AAEA,SAAS,YAAY,KAA8C;AACjE,QAAM,WAAW,IAAI,SAAS;AAC9B,SAAO,KAAK,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA,mBAIb,IAAI,IAAI;AAAA;AAAA,EAEf,IAAI,SAAS,WAAW,IAAI,SAAS,QAAQ,sFAA8C,EAAE;AAAA,EAC7F,WAAW,gLAA2F,EAAE;AAAA,EACxG,IAAI,SAAS,eAAe,IAAI,SAAS,QAAQ,oGAAuD,EAAE;AAAA,EAC1G,IAAI,SAAS,aAAa,IAAI,SAAS,QAAQ,mGAAiD,EAAE;AAAA;AAAA,EAElG,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAuBT,EAAE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iBAkBW,IAAI,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAezB;AAx3BA,IAyPM,uBAiDA,0BA+CA,qBAmCA,oBAkDA,kBAoBA,gBAcA,WAyEA,YAyCA,gBAsCA,gBAwCA,oBAsCA,kBA0CA;AAhuBN;AAAA;AAAA;AAyPA,IAAM,wBAAwB;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAiD9B,IAAM,2BAA2B;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA+CjC,IAAM,sBAAsB;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;AAmC5B,IAAM,qBAAqB;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkD3B,IAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBzB,IAAM,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcvB,IAAM,YAAY;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;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;AAyElB,IAAM,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;AAAA;AAAA;AAAA;AAAA;AAyCnB,IAAM,iBAAiB;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;AAsCvB,IAAM,iBAAiB;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;AAAA;AAAA;AAwCvB,IAAM,qBAAqB;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;AAsC3B,IAAM,mBAAmB;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;AAAA;AAAA;AAAA;AAAA;AA0CzB,IAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AChuBtB;AAAA;AAAA;AAAA;AAAA;AAGA,SAAS,QAAAE,aAAY;AACrB,OAAOC,SAAQ;AAkBf,eAAe,gBAAgB,KAAwC;AACrE,QAAM,SAASD,MAAK,IAAI,KAAK,MAAM;AACnC,MAAI,CAAE,MAAMC,IAAG,WAAW,MAAM,GAAI;AAClC,UAAMA,IAAG,UAAUD,MAAK,IAAI,KAAK,WAAW,WAAW,CAAC;AACxD,QAAI;AACF,YAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,YAAM,MAAM,OAAO,CAAC,MAAM,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;AAC7C,YAAM,MAAM,OAAO,CAAC,YAAY,MAAM,MAAM,GAAG,EAAE,KAAK,IAAI,IAAI,CAAC;AAAA,IACjE,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,QAAM,OAAO,CAAC,OAAO,QAAQ,SAAS,UAAU,MAAM;AACtD,QAAM,QAAQ,IAAI,KAAK,IAAI,CAAC,MAAMC,IAAG,UAAUD,MAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC;AAGjE,QAAM,cAAcA,MAAK,IAAI,KAAK,YAAY;AAC9C,MAAI,CAAE,MAAMC,IAAG,WAAW,WAAW,GAAI;AACvC,UAAM,OAAM,oBAAI,KAAK,GAAE,eAAe,OAAO;AAC7C,UAAMA,IAAG,UAAU,aAAa;AAAA,MAC9B,oBAAe,IAAI,WAAW;AAAA,MAC9B;AAAA,MACA,kDAAe,GAAG;AAAA,MAClB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,sDAAmB,GAAG;AAAA,MACtB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,mBAAS,IAAI,IAAI;AAAA,MACjB;AAAA,IACF,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AAGA,QAAM,cAAcD,MAAK,IAAI,KAAK,iBAAiB;AACnD,MAAI,CAAE,MAAMC,IAAG,WAAW,WAAW,GAAI;AACvC,UAAMA,IAAG,UAAU,aAAa;AAAA,MAC9B,qBAAqB,IAAI,WAAW;AAAA,MACpC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,IAAI;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AAGA,QAAM,kBAAkBD,MAAK,IAAI,KAAK,WAAW,QAAQ;AACzD,QAAMC,IAAG,UAAU,eAAe;AAClC,QAAM,mBAAmBD,MAAK,iBAAiB,iBAAiB;AAChE,MAAI,CAAE,MAAMC,IAAG,WAAW,gBAAgB,GAAI;AAC5C,UAAMA,IAAG,UAAU,kBAAkB;AAAA,MACnC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AAEA,QAAM,gBAAgBD,MAAK,IAAI,KAAK,YAAY;AAChD,MAAI,CAAE,MAAMC,IAAG,WAAW,aAAa,GAAI;AACzC,UAAMA,IAAG,UAAU,eAAe;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AACF;AAEA,eAAe,gBAAgB,KAAwC;AACrE,QAAM,aAAaD,MAAK,IAAI,KAAK,aAAa;AAC9C,MAAI,CAAE,MAAMC,IAAG,WAAW,UAAU,GAAI;AACtC,UAAMA,IAAG,UAAU,YAAY;AAAA,MAC7B,SAAS;AAAA,MAAG,MAAM,IAAI;AAAA,MACtB,QAAQ,CAAC,EAAE,KAAK,UAAU,KAAK,iBAAiB,CAAC;AAAA,IACnD,GAAG,EAAE,QAAQ,EAAE,CAAC;AAAA,EAClB;AACF;AAEA,eAAe,kBAAkB,KAAwC;AACvE,QAAM,cAAcD,MAAK,IAAI,KAAK,UAAU;AAC5C,QAAMC,IAAG,UAAU,WAAW;AAC9B,QAAM,aAAaD,MAAK,aAAa,aAAa;AAClD,MAAI,CAAE,MAAMC,IAAG,WAAW,UAAU,GAAI;AACtC,UAAMA,IAAG,UAAU,YAAY,2EAA2E;AAAA,EAC5G;AACA,MAAI,WAAW,0BAA0B,IAAI;AAC7C,MAAI,WAAW,+BAA+B,IAAI;AACpD;AAEA,eAAe,kBAAkB,KAAwC;AACvE,QAAMA,IAAG,UAAUD,MAAK,IAAI,KAAK,MAAM,CAAC;AACxC,QAAM,eAAeA,MAAK,IAAI,KAAK,QAAQ,aAAa;AACxD,MAAI,CAAE,MAAMC,IAAG,WAAW,YAAY,GAAI;AACxC,UAAMA,IAAG,UAAU,cAAc;AAAA,MAC/B,qBAAgB,IAAI,WAAW;AAAA,MAC/B;AAAA,MAAI;AAAA,MAAsB;AAAA,MAC1B;AAAA,MAAI;AAAA,MAAqB;AAAA,MAAe;AAAA,MAAmB;AAAA,MAC3D;AAAA,MAAI;AAAA,MAA0B;AAAA,MAC9B;AAAA,MAAI;AAAA,MAAuB;AAAA,MAAe;AAAA,MAAc;AAAA,MACxD;AAAA,MAAI;AAAA,MACJ;AAAA,MAA0B;AAAA,MAA4B;AAAA,IACxD,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AACF;AAEA,eAAe,aAAa,KAAwC;AAClE,QAAMA,IAAG,UAAUD,MAAK,IAAI,KAAK,MAAM,CAAC;AACxC,QAAM,UAAUA,MAAK,IAAI,KAAK,QAAQ,QAAQ;AAC9C,MAAI,CAAE,MAAMC,IAAG,WAAW,OAAO,GAAI;AACnC,UAAMA,IAAG,UAAU,SAAS;AAAA,MAC1B,sCAAiC,IAAI,WAAW;AAAA,MAChD;AAAA,MAAI;AAAA,MACJ;AAAA,MAAI;AAAA,MAAa;AAAA,MAAI;AAAA,MAAY;AAAA,MAAO;AAAA,MACxC;AAAA,MAAiB;AAAA,MAA4B;AAAA,MAC7C;AAAA,MAAI;AAAA,MAAc;AAAA,IACpB,EAAE,KAAK,IAAI,IAAI,IAAI;AAAA,EACrB;AACF;AAEA,eAAe,gBAAgB,KAAwC;AACrE,QAAMA,IAAG,UAAUD,MAAK,IAAI,KAAK,MAAM,CAAC;AACxC,QAAMC,IAAG,UAAUD,MAAK,IAAI,KAAK,QAAQ,aAAa,GAAG;AAAA,IACvD,SAAS;AAAA,IAAO,YAAY;AAAA,IAC5B,mBAAmB,EAAE,QAAQ,EAAE,OAAO,GAAG,EAAE;AAAA,IAC3C,cAAc,CAAC,QAAQ,aAAa,MAAM;AAAA,EAC5C,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClB;AAEA,eAAe,gBAAgB,KAAwC;AACrE,QAAMC,IAAG,UAAUD,MAAK,IAAI,KAAK,MAAM,CAAC;AACxC,QAAM,aAAaA,MAAK,IAAI,KAAK,QAAQ,aAAa;AACtD,MAAI,MAAMC,IAAG,WAAW,UAAU,EAAG;AACrC,QAAMA,IAAG,UAAU,YAAY;AAAA,IAC7B,SAAS;AAAA,IACT,QAAQ,CAAC,UAAU,UAAU,YAAY,YAAY,KAAK;AAAA,IAC1D,cAAc;AAAA,IACd,MAAM;AAAA,EACR,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClB;AAEA,eAAe,iBAAiB,KAAwC;AACtE,QAAMA,IAAG,UAAUD,MAAK,IAAI,KAAK,MAAM,CAAC;AACxC,QAAMC,IAAG,UAAUD,MAAK,IAAI,KAAK,QAAQ,cAAc,GAAG;AAAA,IACxD,SAAS;AAAA,IAAO,UAAU;AAAA,IAC1B,SAAS,CAAC,cAAc,IAAI;AAAA,IAC5B,OAAO,CAAC,6BAA6B,mBAAmB;AAAA,EAC1D,GAAG,EAAE,QAAQ,EAAE,CAAC;AAClB;AAEA,eAAe,oBAAoB,KAAwC;AACzE,QAAM,EAAE,cAAAE,cAAa,IAAI,MAAM;AAC/B,QAAMA,cAAa,GAAG;AACxB;AAcA,eAAsB,gBACpB,MACA,KACmE;AACnE,QAAM,UAAoE,CAAC;AAE3E,aAAW,OAAO,MAAM;AACtB,UAAM,cAAc,aAAa,GAAG;AACpC,QAAI,CAAC,aAAa;AAChB,cAAQ,KAAK,EAAE,KAAK,SAAS,OAAO,OAAO,UAAU,CAAC;AACtD;AAAA,IACF;AACA,QAAI;AACF,YAAM,YAAY,GAAG;AACrB,cAAQ,KAAK,EAAE,KAAK,SAAS,KAAK,CAAC;AAAA,IACrC,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,cAAQ,KAAK,EAAE,KAAK,SAAS,OAAO,OAAO,IAAI,CAAC;AAAA,IAClD;AAAA,EACF;AAEA,MAAI,OAAO,KAAK,IAAI,UAAU,EAAE,SAAS,GAAG;AAC1C,iBAAaF,MAAK,IAAI,KAAK,YAAY,GAAG,IAAI,UAAU;AAAA,EAC1D;AAEA,SAAO;AACT;AAlUA,IA4Ra;AA5Rb;AAAA;AAAA;AAKA;AAuRO,IAAM,eAA4C;AAAA,MACvD,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,KAAK;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,KAAK;AAAA,IACP;AAAA;AAAA;;;ACtSA;AAAA;AAAA;AAAA;AAAA;AAIA,SAAS,QAAAG,aAAY;AACrB,OAAOC,SAAQ;AAg0Bf,eAAe,kBACb,QACA,SACA,SACsB;AACtB,QAAMA,IAAG,UAAU,MAAM;AACzB,QAAM,UAAoB,CAAC;AAC3B,QAAM,UAAoB,CAAC;AAC3B,QAAM,SAAiD,CAAC;AAExD,aAAW,CAAC,UAAU,OAAO,KAAK,OAAO,QAAQ,OAAO,GAAG;AACzD,UAAM,WAAWD,MAAK,QAAQ,QAAQ;AACtC,QAAI;AACF,UAAI,QAAQ,gBAAgB,MAAMC,IAAG,WAAW,QAAQ,GAAG;AACzD,gBAAQ,KAAK,QAAQ;AACrB;AAAA,MACF;AACA,YAAMA,IAAG,UAAU,UAAU,OAAO;AACpC,cAAQ,KAAK,QAAQ;AAAA,IACvB,SAAS,KAAK;AACZ,YAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,aAAO,KAAK,EAAE,MAAM,UAAU,OAAO,IAAI,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,SAAS,OAAO;AACpC;AAIA,eAAsB,wBAAwB,KAA4B;AACxE,QAAM,WAAWD,MAAK,KAAK,WAAW,UAAU,KAAK;AACrD,QAAMC,IAAG,UAAU,QAAQ;AAC3B,QAAM,YAAYD,MAAK,UAAU,UAAU;AAC3C,MAAI,CAAE,MAAMC,IAAG,WAAW,SAAS,GAAI;AACrC,UAAMA,IAAG,UAAU,WAAW,aAAa;AAAA,EAC7C;AAEA,QAAM,SAASD,MAAK,KAAK,WAAW,YAAY,KAAK;AACrD,QAAM,kBAAkB,QAAQ,UAAU,EAAE,cAAc,KAAK,CAAC;AAClE;AAUA,eAAsB,sBAAsB,KAAqC;AAC/E,QAAM,SAAwB;AAAA,IAC5B,cAAc;AAAA,IACd,iBAAiB,CAAC;AAAA,IAClB,eAAe,CAAC;AAAA,EAClB;AAGA,QAAM,WAAWA,MAAK,KAAK,WAAW,UAAU,KAAK;AACrD,QAAMC,IAAG,UAAU,QAAQ;AAC3B,MAAI;AACF,UAAMA,IAAG,UAAUD,MAAK,UAAU,UAAU,GAAG,aAAa;AAC5D,WAAO,eAAe;AAAA,EACxB,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,WAAO,cAAc,KAAK,EAAE,MAAM,YAAY,OAAO,IAAI,CAAC;AAAA,EAC5D;AAGA,QAAM,SAASA,MAAK,KAAK,WAAW,YAAY,KAAK;AACrD,QAAM,EAAE,SAAS,OAAO,IAAI,MAAM,kBAAkB,QAAQ,UAAU,EAAE,cAAc,MAAM,CAAC;AAC7F,SAAO,kBAAkB;AACzB,SAAO,cAAc,KAAK,GAAG,MAAM;AAEnC,SAAO;AACT;AAh5BA,IAQM,eA6DA;AArEN;AAAA;AAAA;AAQA,IAAM,gBAAgB;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6DtB,IAAM,WAAmC;AAAA,MACvC,WAAW;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;AAAA;AAAA;AAAA;AAAA,MAyCX,WAAW;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiDX,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;AAAA;AAAA;AAAA,MAuCb,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,MA4Bb,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;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;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,MAuGb,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuBf,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,MAoCf,cAAc;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,MA2Bd,cAAc;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,MAoCd,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAyBjB,cAAc;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,MAiCd,gBAAgB;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;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;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,MA2GhB,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiDb,WAAW;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,MAqCX,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["require","createRequire","fs","path","pkg","require","c","chalk","fs","info","pkg","chalk","join","fs","chalk","step","fs","path","join","fs","section","join","fs","provisionMcp","join","fs","join","fs","path","fs","analyzer_exports","join","fs","buildAnalysisPrompt","c","path","init_analyzer","c","chalk","c","join","homedir","fs","os","path","fs","backupPath","join","join","fs","init_analyzer","basename","config","join","basename","fs","isWindows","diagnoseWindowsEnv","inquirer","chalk","analyzeRepository","computeResult","printReport","buildDetailedReport","installShellHelper","requestCdAfter","sleep","createSpinner","getShellRcPath","getYoloAliasLine","spawnSubshell","enableOmcPlugin","ClaudeSettingsError","PLUGIN_META","evaluateCommand","envSetupCommand","runDoctor","generateFiles","analyzeProject","provisionClaudeCommands","runProvisioners","withSpinner","withFileSpinner","join","fs","section","join","fs","basename","join","fs","pkg","join","fs","c","join","fs","c","init_analyzer","basename","fs","inquirer","requestCdAfter","initCommand","spawnSubshell","path","createRequire","chalk","pkg","require","join","fs","chalk","createSpinner","join","homedir","fs","chalk","PAI_DIR","CONFIG_FILE","createRequire","require","createRequire","pkg","program","welcomeCommand","initCommand","checkCommand","helpCommand","designInitCommand","designValidateCommand","removeCommand","upgradeCommand","savetokenCommand","wakeupCommand","envSetupCommand","envDoctorCommand","envStatusCommand","validateCommand","evaluateCommand","pipelineCommand"]}
1
+ {"version":3,"sources":["../../src/ui/logger.ts","../../src/core/config.ts","../../src/cli/commands/welcome.cmd.ts","../../src/ui/banner.ts","../../src/ui/progress.ts","../../src/ui/index.ts","../../src/stages/environment/analyzer.ts","../../src/stages/environment/interviewer.ts","../../src/stages/environment/generator.ts","../../src/stages/environment/installer.ts","../../src/utils/platform.ts","../../src/stages/environment/provisioners/mcp.ts","../../src/stages/environment/provisioners/registry.ts","../../src/stages/environment/provisioners/claude-commands.ts","../../src/stages/environment/doctor.ts","../../src/stages/environment/index.ts","../../src/core/detector.ts","../../src/stages/evaluation/prompts/analyze.ts","../../src/stages/evaluation/analyzer.ts","../../src/core/types/stage.ts","../../src/core/types/scoring.ts","../../src/core/types/index.ts","../../src/stages/evaluation/scorer.ts","../../src/stages/evaluation/reporter.ts","../../src/utils/shell-cd.ts","../../src/utils/claude-settings.ts","../../src/stages/evaluation/cache.ts","../../src/cli/commands/evaluate.cmd.ts","../../src/cli/commands/env.cmd.ts","../../src/cli/commands/init.cmd.ts","../../src/cli/commands/add.cmd.ts","../../src/cli/commands/check.cmd.ts","../../src/cli/commands/status.cmd.ts","../../src/cli/commands/help.cmd.ts","../../src/stages/design/openspec.ts","../../src/stages/design/omc.ts","../../src/cli/commands/design.cmd.ts","../../src/stages/validation/runner.ts","../../src/stages/validation/harness.ts","../../src/cli/commands/validate.cmd.ts","../../src/cli/commands/test.cmd.ts","../../src/cli/commands/grade.cmd.ts","../../src/pipeline/context.ts","../../src/stages/design/index.ts","../../src/stages/execution/index.ts","../../src/stages/validation/index.ts","../../src/stages/evaluation/index.ts","../../src/pipeline/index.ts","../../src/cli/commands/pipeline.cmd.ts","../../src/cli/commands/run.cmd.ts","../../src/cli/commands/remove.cmd.ts","../../src/core/errors.ts","../../src/cli/commands/upgrade.cmd.ts","../../src/cli/commands/savetoken.cmd.ts","../../src/cli/commands/wakeup.cmd.ts","../../src/cli/index.ts","../../src/cli/deprecation.ts","../../bin/pai.ts"],"sourcesContent":["import chalk from 'chalk';\n\n/**\n * Professional color palette — low fatigue, high clarity\n */\nexport const colors = {\n accent: chalk.hex('#7B93DB'),\n success: chalk.hex('#6BCB77'),\n warn: chalk.hex('#E2B340'),\n err: chalk.hex('#E06C75'),\n dim: chalk.gray,\n bold: chalk.bold.white,\n muted: chalk.dim,\n};\n\nconst c = colors;\n\nexport function info(msg: string): void {\n console.log(c.dim(` · ${msg}`));\n}\n\nexport function success(msg: string): void {\n console.log(c.success(` ✓ ${msg}`));\n}\n\nexport function warn(msg: string): void {\n console.log(c.warn(` ! ${msg}`));\n}\n\nexport function error(msg: string): void {\n console.log(c.err(` ✗ ${msg}`));\n}\n\nexport function section(title: string): void {\n console.log('');\n console.log(c.accent(` ${title}`));\n console.log(c.dim(' ' + '─'.repeat(38)));\n}\n\nexport function plain(msg: string): void {\n console.log(msg);\n}\n\nexport function step(num: number, total: number, title: string): void {\n console.log('');\n console.log(c.accent(` Step ${num}/${total}`) + ` ${c.bold(title)}`);\n console.log('');\n}\n\nexport function hint(msg: string): void {\n console.log(c.dim(` ${msg}`));\n}\n","import path from 'node:path';\nimport { createRequire } from 'node:module';\nimport fs from 'fs-extra';\nimport type { PaiConfig, Mode, LegacyMode } from './types/index.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nconst CONFIG_DIR = '.pai';\nconst CONFIG_FILE = 'config.json';\n\n/**\n * 레거시 모드값(`mockup`)을 현재 Mode 타입으로 정규화.\n * - `mockup` → `prototype` (자동 매핑)\n * - 이미 Mode인 경우 그대로 반환\n * - 알 수 없는 값은 `prototype`으로 fallback (안전 기본값)\n */\nexport function normalizeMode(value: unknown): Mode {\n if (value === 'prototype' || value === 'poc' || value === 'production') return value;\n if (value === 'mockup') return 'prototype';\n return 'prototype';\n}\n\nexport async function loadConfig(cwd: string): Promise<PaiConfig | null> {\n const configPath = path.join(cwd, CONFIG_DIR, CONFIG_FILE);\n if (!(await fs.pathExists(configPath))) return null;\n\n const raw = (await fs.readJson(configPath)) as PaiConfig & { mode: Mode | LegacyMode };\n return {\n ...raw,\n mode: normalizeMode(raw.mode),\n };\n}\n\nexport async function saveConfig(cwd: string, config: PaiConfig): Promise<void> {\n const configDir = path.join(cwd, CONFIG_DIR);\n await fs.ensureDir(configDir);\n await fs.writeJson(path.join(configDir, CONFIG_FILE), config, { spaces: 2 });\n}\n\nexport function createDefaultConfig(projectName: string, mode: Mode | LegacyMode): PaiConfig {\n return {\n version: pkg.version,\n mode: normalizeMode(mode),\n projectName,\n installedAt: new Date().toISOString(),\n plugins: [],\n };\n}\n","/**\n * `pai` 인자 없이 실행 시 표시되는 환영 화면.\n *\n * 설치 직후 사용자가 \"다음에 뭘 해야 하나?\"에 즉시 답을 찾도록\n * 핵심 3가지 시작 경로(처음/기존/도움)를 제시한다.\n */\nimport { createRequire } from 'node:module';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { colors as c } from '../../ui/logger.js';\nimport { loadConfig } from '../../core/config.js';\n\nconst require = createRequire(import.meta.url);\n// Path relative to bundled dist/cli/index.js or dist/bin/pai.js\nconst pkg = require('../../package.json') as { version: string };\n\nexport async function welcomeCommand(cwd: string): Promise<void> {\n // 현재 디렉토리가 이미 PAI 프로젝트인지 감지\n const paiConfig = await loadConfig(cwd);\n const inPaiProject = paiConfig !== null;\n const hasGit = fs.existsSync(path.join(cwd, '.git'));\n const hasPackageJson = fs.existsSync(path.join(cwd, 'package.json'));\n\n console.log('');\n console.log(c.accent(' ╭────────────────────────────────────╮'));\n console.log(c.accent(` │ 🔧 PAI Zero v${pkg.version.padEnd(22)}│`));\n console.log(c.accent(' │ Plugin AI for ProjectZero │'));\n console.log(c.accent(' ╰────────────────────────────────────╯'));\n console.log('');\n\n if (inPaiProject) {\n // ── 이미 PAI 프로젝트 안 ─────────────────────────\n console.log(c.dim(' 현재 PAI 프로젝트가 감지되었습니다'));\n console.log(c.dim(` ─ 모드: ${paiConfig!.mode}`));\n console.log(c.dim(` ─ 플러그인: ${paiConfig!.plugins.length}개 설치됨`));\n console.log('');\n console.log(c.accent(' 바로 쓸 수 있는 명령어'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai status'.padEnd(18)} ${c.dim('설치된 플러그인 확인')}`);\n console.log(` ${c.success('●')} ${'pai grade'.padEnd(18)} ${c.dim('AI 개발 준비도 평가 (6카테고리)')}`);\n console.log(` ${c.success('●')} ${'pai add'.padEnd(18)} ${c.dim('플러그인 추가 · 모드 승격 (prototype→poc→production)')}`);\n console.log(` ${c.success('●')} ${'pai design'.padEnd(18)} ${c.dim('PRD/OMC 설계 관리')}`);\n console.log(` ${c.success('●')} ${'pai test'.padEnd(18)} ${c.dim('테스트 + 하네스 검증')}`);\n console.log(` ${c.success('●')} ${'pai check'.padEnd(18)} ${c.dim('환경 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 목록: ') + c.accent('pai help'));\n } else if (hasGit || hasPackageJson) {\n // ── 기존 코드베이스 ──────────────────────────────\n console.log(c.dim(' 기존 프로젝트가 감지되었습니다 (PAI 미설치)'));\n console.log('');\n console.log(c.accent(' 시작하기'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('▸')} ${'pai init'.padEnd(18)} ${c.dim('이 프로젝트에 PAI 적용 (자동 진단 포함)')}`);\n console.log(` ${c.success('▸')} ${'pai check'.padEnd(18)}${c.dim('환경부터 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 목록: ') + c.accent('pai help'));\n } else {\n // ── 빈 디렉토리 / 신규 설치 직후 ─────────────────\n console.log(c.accent(' 처음이신가요?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('▸')} ${'pai init <프로젝트명>'.padEnd(24)}${c.dim('새 프로젝트 시작')}`);\n console.log('');\n console.log(c.accent(' 이미 PAI 프로젝트에 있다면?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai status'.padEnd(18)} ${c.dim('설치된 플러그인 확인')}`);\n console.log(` ${c.success('●')} ${'pai grade'.padEnd(18)} ${c.dim('AI 개발 준비도 평가')}`);\n console.log(` ${c.success('●')} ${'pai add'.padEnd(18)} ${c.dim('플러그인 추가 (모드 승격)')}`);\n console.log('');\n console.log(c.accent(' 문제가 있나요?'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('●')} ${'pai check'.padEnd(18)} ${c.dim('Node / Git / Claude Code / OMC 점검')}`);\n console.log('');\n console.log(c.dim(' 전체 명령어: ') + c.accent('pai help'));\n }\n\n console.log('');\n console.log(c.dim(' 문서: https://github.com/SoInKyu/pai'));\n console.log('');\n}\n","import { colors } from './logger.js';\n\nexport function printBanner(): void {\n const c = colors;\n console.log('');\n console.log(c.accent(' PAI Zero'));\n console.log(c.dim(' Plugin AI for ProjectZero'));\n console.log(c.dim(' ─────────────────────────'));\n console.log('');\n}\n\n/**\n * `pai init` 실행 시 출력되는 대형 글자 아트.\n * \"Welcome PAI!\" ASCII banner.\n */\nexport function printWelcomeBanner(): void {\n const c = colors;\n // ANSI Shadow style — 'Welcome PAI!'\n const art = [\n \" __ __ _ ____ _ ___ _ \",\n \" \\\\ \\\\ / /__| | ___ ___ _ __ ___ ___ | _ \\\\ / \\\\ |_ _|| |\",\n \" \\\\ \\\\ /\\\\ / / _ \\\\ |/ __/ _ \\\\| '_ ` _ \\\\ / _ \\\\ | |_) |/ _ \\\\ | | | |\",\n \" \\\\ V V / __/ | (_| (_) | | | | | | __/ | __// ___ \\\\ | | |_|\",\n \" \\\\_/\\\\_/ \\\\___|_|\\\\___\\\\___/|_| |_| |_|\\\\___| |_| /_/ \\\\_|___|(_)\",\n ];\n console.log('');\n for (const line of art) {\n console.log(c.accent(line));\n }\n console.log('');\n console.log(c.dim(' Plugin AI for ProjectZero'));\n console.log(c.dim(' ─────────────────────────────────────────────────────────────────'));\n console.log('');\n}\n","/**\n * Progress — ora 기반 스피너 + 파일명 스크롤 애니메이션\n */\nimport ora, { type Ora } from 'ora';\nimport chalk from 'chalk';\n\nexport function createSpinner(text: string): Ora {\n return ora({\n text,\n spinner: 'dots12',\n color: 'white',\n }).start();\n}\n\nexport async function withSpinner<T>(text: string, fn: () => Promise<T>): Promise<T> {\n const spinner = createSpinner(text);\n try {\n const result = await fn();\n spinner.succeed(text.replace(/중\\.\\.\\.$/u, '완료'));\n return result;\n } catch (err) {\n spinner.fail(text.replace(/중\\.\\.\\.$/u, '실패'));\n throw err;\n }\n}\n\n/**\n * 파일명이 슈슉 스크롤되는 스피너\n * 스피너 텍스트 옆에 현재 파일명이 갱신됨\n */\nexport async function withFileSpinner<T>(\n label: string,\n files: string[],\n fn: () => Promise<T>,\n): Promise<T> {\n const spinner = ora({\n spinner: 'dots12',\n color: 'white',\n }).start();\n\n // Start file name scrolling\n let fileIdx = 0;\n const interval = setInterval(() => {\n if (fileIdx < files.length) {\n const file = files[fileIdx]!;\n spinner.text = `${label} ${chalk.gray(file)}`;\n fileIdx++;\n } else {\n fileIdx = 0; // loop\n }\n }, 500);\n\n try {\n const result = await fn();\n clearInterval(interval);\n spinner.succeed(label.replace(/중\\.\\.\\.$/u, '완료'));\n return result;\n } catch (err) {\n clearInterval(interval);\n spinner.fail(label.replace(/중\\.\\.\\.$/u, '실패'));\n throw err;\n }\n}\n\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport function progressBar(current: number, total: number, width = 30): string {\n const ratio = Math.min(current / total, 1);\n const filled = Math.round(width * ratio);\n const empty = width - filled;\n const bar = chalk.hex('#7B93DB')('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n const pct = Math.round(ratio * 100);\n return `${bar} ${pct}%`;\n}\n","export { info, success, warn, error, section, plain, step, hint, colors } from './logger.js';\nexport { printBanner, printWelcomeBanner } from './banner.js';\nexport { createSpinner, withSpinner, withFileSpinner, sleep, progressBar } from './progress.js';\n","/**\n * Environment Analyzer — roboco-cli에서 내재화\n * 프로젝트 스택, 구조, 기존 설정, Git 정보를 병렬 분석\n */\nimport { readdir, access } from 'node:fs/promises';\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { AnalysisResult, StackInfo, RepoStructure, ExistingConfig, GitInfo } from '../../core/types/index.js';\n\nexport async function analyzeProject(targetPath: string): Promise<AnalysisResult> {\n try {\n await access(targetPath);\n } catch {\n throw new Error(`Directory not found: ${targetPath}`);\n }\n\n const [stack, structure, existingConfig, git] = await Promise.all([\n detectStack(targetPath),\n scanStructure(targetPath),\n checkExistingConfig(targetPath),\n getGitInfo(targetPath),\n ]);\n\n return { stack, structure, existingConfig, git };\n}\n\nasync function detectStack(cwd: string): Promise<StackInfo> {\n const info: StackInfo = {\n languages: [],\n frameworks: [],\n packageManager: null,\n hasTypeScript: false,\n };\n\n if (await fs.pathExists(join(cwd, 'package.json'))) {\n info.languages.push('JavaScript');\n info.packageManager = 'npm';\n\n try {\n const pkg = await fs.readJson(join(cwd, 'package.json'));\n const allDeps: Record<string, string> = {\n ...(pkg.dependencies ?? {}),\n ...(pkg.devDependencies ?? {}),\n };\n\n if (allDeps['typescript'] || (await fs.pathExists(join(cwd, 'tsconfig.json')))) {\n info.hasTypeScript = true;\n info.languages.push('TypeScript');\n }\n\n const frameworkMap: Record<string, string> = {\n react: 'React',\n vue: 'Vue',\n next: 'Next.js',\n nuxt: 'Nuxt',\n express: 'Express',\n fastify: 'Fastify',\n nestjs: 'NestJS',\n svelte: 'Svelte',\n angular: 'Angular',\n };\n\n for (const [dep, name] of Object.entries(frameworkMap)) {\n if (allDeps[dep] || allDeps[`@${dep}/core`]) {\n info.frameworks.push(name);\n }\n }\n } catch {\n // ignore parse errors\n }\n\n if (await fs.pathExists(join(cwd, 'pnpm-lock.yaml'))) info.packageManager = 'pnpm';\n else if (await fs.pathExists(join(cwd, 'yarn.lock'))) info.packageManager = 'yarn';\n else if (await fs.pathExists(join(cwd, 'bun.lockb'))) info.packageManager = 'bun';\n }\n\n if (\n (await fs.pathExists(join(cwd, 'pyproject.toml'))) ||\n (await fs.pathExists(join(cwd, 'requirements.txt')))\n ) {\n info.languages.push('Python');\n }\n if (await fs.pathExists(join(cwd, 'go.mod'))) info.languages.push('Go');\n if (await fs.pathExists(join(cwd, 'Cargo.toml'))) info.languages.push('Rust');\n if (\n (await fs.pathExists(join(cwd, 'pom.xml'))) ||\n (await fs.pathExists(join(cwd, 'build.gradle')))\n ) {\n info.languages.push('Java');\n }\n\n return info;\n}\n\nasync function scanStructure(cwd: string): Promise<RepoStructure> {\n const entries = await readdir(cwd, { withFileTypes: true });\n const rootFiles = entries.filter((e) => e.isFile()).map((e) => e.name);\n const rootDirs = entries\n .filter((e) => e.isDirectory() && !e.name.startsWith('.'))\n .map((e) => e.name);\n\n const sourceCandidates = ['src', 'lib', 'app', 'source'];\n const sourceDir = sourceCandidates.find((d) => rootDirs.includes(d)) ?? null;\n\n const testCandidates = ['test', 'tests', '__tests__', 'spec'];\n const testDir = testCandidates.find((d) => rootDirs.includes(d)) ?? null;\n\n const isMonorepo = rootDirs.includes('packages') || rootDirs.includes('apps');\n\n return { rootFiles, rootDirs, sourceDir, testDir, isMonorepo };\n}\n\nasync function checkExistingConfig(cwd: string): Promise<ExistingConfig> {\n const [hasClaudeMd, hasClaudeDir, hasPaiDir, hasOpenSpec, hasOmc] = await Promise.all([\n fs.pathExists(join(cwd, 'CLAUDE.md')),\n fs.pathExists(join(cwd, '.claude')),\n fs.pathExists(join(cwd, '.pai')),\n fs.pathExists(join(cwd, 'docs', 'openspec.md')).then((r) =>\n r ? r : fs.pathExists(join(cwd, 'openspec.md')),\n ),\n fs.pathExists(join(cwd, '.pai', 'omc.md')),\n ]);\n\n let claudeSettings: Record<string, unknown> | null = null;\n try {\n if (await fs.pathExists(join(cwd, '.claude', 'settings.json'))) {\n claudeSettings = await fs.readJson(join(cwd, '.claude', 'settings.json'));\n }\n } catch {\n // ignore\n }\n\n const claudeSkills = await listDirNames(join(cwd, '.claude', 'skills'));\n const claudeCommands = await listDirNames(join(cwd, '.claude', 'commands'));\n\n return {\n hasClaudeMd,\n hasClaudeDir,\n hasPaiDir,\n hasOpenSpec,\n hasOmc,\n claudeSettings,\n claudeSkills,\n claudeCommands,\n };\n}\n\nasync function listDirNames(dirPath: string): Promise<string[]> {\n try {\n const entries = await readdir(dirPath, { withFileTypes: true });\n return entries.filter((e) => e.isDirectory()).map((e) => e.name);\n } catch {\n return [];\n }\n}\n\nasync function getGitInfo(cwd: string): Promise<GitInfo> {\n const isGitRepo = await fs.pathExists(join(cwd, '.git'));\n if (!isGitRepo) {\n return { isGitRepo: false, remoteUrl: null, repoName: null, currentBranch: null };\n }\n\n const { execa } = await import('execa');\n\n async function gitCmd(args: string[]): Promise<string | null> {\n try {\n const { stdout } = await execa('git', args, { cwd, timeout: 5000 });\n return stdout.trim() || null;\n } catch {\n return null;\n }\n }\n\n const [remoteUrl, currentBranch] = await Promise.all([\n gitCmd(['remote', 'get-url', 'origin']),\n gitCmd(['branch', '--show-current']),\n ]);\n\n let repoName: string | null = null;\n if (remoteUrl) {\n const match = remoteUrl.match(/\\/([^/]+?)(?:\\.git)?$/);\n repoName = match?.[1] ?? null;\n }\n\n return { isGitRepo, remoteUrl, repoName, currentBranch };\n}\n","/**\n * Interviewer — AI → Interactive → Auto 폴백 체인\n * SDK 미설치 시 Interactive/Auto로 자연스럽게 동작\n *\n * v0.6.0: 비개발자 친화적 UX — 단계적 안내, 심플한 선택지\n */\nimport type { AnalysisResult, Mode } from '../../core/types/index.js';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\nimport { normalizeMode } from '../../core/config.js';\n\nexport interface InterviewResult {\n mode: Mode;\n projectName: string;\n authMethods: string[];\n customAuth?: { clientId: string; clientSecret: string };\n extraTools: string[]; // vercel, supabase, gstack, harness, mcp\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n setupDomains: {\n claudeEnv: boolean;\n processDocs: boolean;\n cicd: boolean;\n };\n tools: {\n omc: boolean;\n openspec: boolean;\n githubMcp: boolean;\n harness: boolean;\n };\n autoGenerated: boolean;\n}\n\nexport async function runInterview(\n analysis: AnalysisResult,\n cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n // Try AI interview first (if SDK available)\n try {\n return await aiInterview(analysis, cwd, projectName);\n } catch {\n // Fall through to interactive\n }\n\n return interactiveInterview(analysis, cwd, projectName);\n}\n\nasync function aiInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n // Dynamic import — fails if SDK not installed\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n\n ui.info('AI 인터뷰 모드로 시작합니다...');\n\n const prompt = buildAiPrompt(analysis);\n let resultJson = '';\n\n for await (const message of query({\n prompt,\n options: {\n maxTurns: 10,\n systemPrompt: `You are PAI, an AI assistant that helps set up vibe coding environments.\nAnalyze the repository and ask the user targeted questions about project level (prototype/poc/production), authentication, and domain.\n- prototype: quick idea validation, UI mockup, concept demo\n- poc: PoC web development, working demo with basic features\n- production: operational service with tests, QA, deployment, monitoring\nOutput your final recommendation as a JSON code block with this schema:\n\\`\\`\\`json\n{\n \"mode\": \"prototype\" | \"poc\" | \"production\",\n \"projectName\": string,\n \"authMethods\": string[],\n \"setupDomains\": { \"claudeEnv\": true, \"processDocs\": boolean, \"cicd\": boolean },\n \"tools\": { \"omc\": true, \"openspec\": boolean, \"githubMcp\": boolean, \"harness\": boolean }\n}\n\\`\\`\\``,\n allowedTools: [],\n permissionMode: 'plan',\n },\n })) {\n if ('result' in message) {\n resultJson = message.result as string;\n }\n }\n\n return parseAiResult(resultJson, analysis, projectName);\n}\n\nfunction buildAiPrompt(analysis: AnalysisResult): string {\n return [\n 'I want to set up a PAI vibe coding environment.',\n '',\n 'Repository analysis:',\n `- Languages: ${analysis.stack.languages.join(', ') || 'None detected'}`,\n `- Frameworks: ${analysis.stack.frameworks.join(', ') || 'None'}`,\n `- Package manager: ${analysis.stack.packageManager ?? 'None'}`,\n `- TypeScript: ${analysis.stack.hasTypeScript ? 'Yes' : 'No'}`,\n `- Git: ${analysis.git.isGitRepo ? 'Yes' : 'No'}`,\n `- Remote: ${analysis.git.remoteUrl ?? 'None'}`,\n `- Monorepo: ${analysis.structure.isMonorepo ? 'Yes' : 'No'}`,\n `- CLAUDE.md: ${analysis.existingConfig.hasClaudeMd ? 'Yes' : 'No'}`,\n '',\n 'Please ask me about the project purpose and provide your recommendation.',\n ].join('\\n');\n}\n\nfunction parseAiResult(\n result: string,\n analysis: AnalysisResult,\n projectName: string,\n): InterviewResult {\n const jsonMatch = result.match(/```json\\s*([\\s\\S]*?)```/);\n if (jsonMatch?.[1]) {\n try {\n const parsed = JSON.parse(jsonMatch[1]) as Partial<InterviewResult>;\n return {\n mode: normalizeMode(parsed.mode),\n projectName,\n authMethods: parsed.authMethods ?? [],\n extraTools: parsed.extraTools ?? [],\n setupDomains: {\n claudeEnv: true,\n processDocs: parsed.setupDomains?.processDocs ?? true,\n cicd: parsed.setupDomains?.cicd ?? analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: parsed.tools?.openspec ?? true,\n githubMcp: parsed.tools?.githubMcp ?? false,\n harness: parsed.tools?.harness ?? false,\n },\n autoGenerated: false,\n };\n } catch {\n // Fall through\n }\n }\n\n ui.warn('AI 응답을 파싱할 수 없습니다. Interactive 모드로 전환합니다.');\n throw new Error('AI parse failed');\n}\n\nasync function interactiveInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): Promise<InterviewResult> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n\n // ── Step 1/3: 프로젝트 수준 ─────────────────────\n ui.step(1, 3, '프로젝트 수준을 선택해주세요');\n ui.hint('선택에 따라 설치되는 플러그인 세트가 달라집니다.');\n console.log('');\n\n const { mode } = await inquirer.prompt([{\n type: 'list',\n name: 'mode',\n message: '어떤 수준의 프로젝트인가요?',\n choices: [\n {\n name: `🧪 prototype ${c.dim('─ 빠른 검증 (아이디어·UI 목업·컨셉 시연)')}`,\n value: 'prototype',\n },\n {\n name: `🔬 poc ${c.dim('─ PoC 웹개발 (동작 데모·기본 기능 구현)')}`,\n value: 'poc',\n },\n {\n name: `🏭 production ${c.dim('─ 운영 서비스 (테스트·QA·배포·모니터링)')}`,\n value: 'production',\n },\n ],\n }]);\n\n // 선택된 모드에 설치될 플러그인 미리보기\n console.log('');\n console.log(c.dim(' 이 수준에 설치될 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n const matrix: Record<string, string[]> = {\n prototype: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)'],\n poc: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)', 'OMC (객체모델)', 'Vercel 배포 (선택)'],\n production: ['GitHub 구조', 'OpenSpec (PRD)', 'roboco (진단)', 'OMC (객체모델)', 'gstack (테스트)', 'Harness (검증)', 'Vercel 배포 (선택)', 'Supabase DB (선택)'],\n };\n for (const item of matrix[mode as string] ?? []) {\n console.log(` ${c.success('✓')} ${item}`);\n }\n\n // ── Step 2/3: 로그인 ────────────────────────────\n ui.step(2, 3, '로그인 기능');\n ui.hint('나중에 추가할 수도 있습니다.');\n console.log('');\n\n const { needAuth } = await inquirer.prompt([{\n type: 'list',\n name: 'needAuth',\n message: '로그인 기능이 필요한가요?',\n choices: [\n { name: '지금은 필요 없어요', value: false },\n { name: '네, 설정할게요', value: true },\n ],\n }]);\n\n let authMethods: string[] = [];\n let customAuth: InterviewResult['customAuth'];\n\n if (needAuth) {\n console.log('');\n ui.hint('Space로 선택 · 선택 후 Enter로 완료');\n const Separator = (inquirer as unknown as { Separator: new (s?: string) => unknown }).Separator;\n const { auths } = await inquirer.prompt([{\n type: 'checkbox',\n name: 'auths',\n message: '사용할 로그인 방식:',\n choices: [\n { name: 'Google 로그인', value: 'google' },\n { name: 'Kakao 로그인', value: 'kakao' },\n { name: 'Naver 로그인', value: 'naver' },\n { name: `사내 인증 ${c.dim('(OAuth2)')}`, value: 'custom' },\n new Separator('─────────────────────────'),\n { name: chalk.green('↵ 선택 완료'), value: '__done__' },\n ],\n validate: (answer: string[]) => {\n const items = answer.filter(a => a !== '__done__');\n if (items.length === 0) return 'Space로 최소 1개를 선택해주세요.';\n return true;\n },\n }]);\n authMethods = (auths as string[]).filter(a => a !== '__done__');\n\n if (authMethods.includes('custom')) {\n console.log('');\n const { registerNow } = await inquirer.prompt([{\n type: 'list',\n name: 'registerNow',\n message: 'OAuth2 인증 키를 지금 등록하시겠습니까?',\n choices: [\n { name: '지금 등록하기', value: true },\n { name: `나중에 등록하기 ${c.dim('─ .env.local에 빈 값으로 생성')}`, value: false },\n ],\n }]);\n\n if (registerNow) {\n ui.hint('사내 OAuth2 인증 정보를 입력해주세요.');\n customAuth = await inquirer.prompt([\n { type: 'input', name: 'clientId', message: 'Client ID:' },\n { type: 'password', name: 'clientSecret', message: 'Client Secret:', mask: '*' },\n ]);\n }\n }\n }\n\n // ── 모드별 추가 도구 ─────────────────────────────\n let extraTools: string[] = [];\n\n // PoC 이상: OMC 객체모델 자동 포함\n if (mode === 'poc' || mode === 'production') {\n extraTools.push('omc');\n }\n\n // PoC 이상: Vercel 배포 옵션\n if (mode === 'poc' || mode === 'production') {\n console.log('');\n const { hosting } = await inquirer.prompt([{\n type: 'list',\n name: 'hosting',\n message: '배포 환경:',\n choices: [\n { name: `Vercel ${c.dim('─ 자동 배포 (Preview + Production)')}`, value: 'vercel' },\n { name: `다른 서비스 사용 ${c.dim('─ AWS, GCP, Netlify 등)')}`, value: 'other' },\n { name: `나중에 정하기 ${c.dim('─ 배포 설정 없이 시작')}`, value: 'skip' },\n ],\n }]);\n if (hosting === 'vercel') extraTools.push('vercel');\n }\n\n // Production: DB + 테스트/검증 도구 자동 포함\n if (mode === 'production') {\n console.log('');\n const { database } = await inquirer.prompt([{\n type: 'list',\n name: 'database',\n message: '데이터베이스:',\n choices: [\n { name: `Supabase ${c.dim('─ PostgreSQL + Auth + Storage')}`, value: 'supabase' },\n { name: `다른 서비스 사용 ${c.dim('─ PlanetScale, Neon, Firebase 등')}`, value: 'other' },\n { name: `나중에 정하기 ${c.dim('─ DB 설정 없이 시작')}`, value: 'skip' },\n ],\n }]);\n if (database === 'supabase') extraTools.push('supabase');\n extraTools.push('gstack', 'harness');\n }\n\n // ── MCP 서버 기능 필요 여부 ──────────────────────\n let mcp: InterviewResult['mcp'];\n console.log('');\n const { mcpNeed } = await inquirer.prompt([{\n type: 'list',\n name: 'mcpNeed',\n message: 'MCP(Model Context Protocol) 서버 기능이 필요하신가요?',\n choices: [\n { name: `필요하다 ${c.dim('─ AI가 호출할 커스텀 도구/리소스/프롬프트 제공')}`, value: 'yes' },\n { name: '필요하지 않다', value: 'no' },\n ],\n default: 'yes',\n }]);\n const mcpDev = mcpNeed === 'yes';\n\n if (mcpDev) {\n console.log('');\n const hasSupabase = extraTools.includes('supabase');\n const typeChoices: Array<{ name: string; value: string }> = [\n { name: `Tools 서버 (개인용) ${c.dim('─ AI가 호출할 기능 제공')}`, value: 'tools' },\n ];\n if (hasSupabase) {\n typeChoices.push({\n name: `Tools 서버 (공개 배포) ${c.dim('─ API 키 + 관리화면 + 사용량 추적')}`,\n value: 'tools-public',\n });\n }\n typeChoices.push(\n { name: `Resources 서버 ${c.dim('─ AI가 읽을 컨텍스트 제공')}`, value: 'resources' },\n { name: `Prompts 서버 ${c.dim('─ 재사용 프롬프트 템플릿')}`, value: 'prompts' },\n { name: `All-in-one ${c.dim('─ 모두 포함')}`, value: 'all' },\n );\n\n const { mcpType } = await inquirer.prompt([{\n type: 'list',\n name: 'mcpType',\n message: 'MCP 서버 유형:',\n choices: typeChoices,\n }]);\n\n const { mcpName } = await inquirer.prompt([{\n type: 'input',\n name: 'mcpName',\n message: 'MCP 서버 이름:',\n default: `${projectName}-mcp`,\n validate: (v: string) => /^[a-z0-9][a-z0-9-]*$/.test(v.trim())\n ? true\n : '영문 소문자, 숫자, 하이픈(-)만 사용할 수 있습니다.',\n }]);\n\n mcp = {\n enabled: true,\n type: mcpType as 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all',\n name: mcpName.trim(),\n };\n extraTools.push('mcp');\n }\n\n // ── Step 3/3: 설치 확인 ─────────────────────────\n ui.step(3, 3, '설치 확인');\n console.log('');\n console.log(c.dim(' 설치될 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} GitHub 프로젝트 구조`);\n console.log(` ${c.success('✓')} PRD 설계 템플릿`);\n console.log(` ${c.success('✓')} AI 도메인 모델`);\n console.log(` ${c.success('✓')} AI 컨텍스트 (CLAUDE.md)`);\n console.log(` ${c.success('✓')} /pai 슬래시 커맨드`);\n\n if (extraTools.length > 0) {\n console.log('');\n if (extraTools.includes('omc')) console.log(` ${c.accent('+')} OMC (oh-my-claudecode) ${c.dim('─ AI 에이전트 오케스트레이션')}`);\n if (extraTools.includes('vercel')) console.log(` ${c.accent('+')} Vercel 자동 배포`);\n if (extraTools.includes('supabase')) console.log(` ${c.accent('+')} Supabase 데이터베이스`);\n if (extraTools.includes('gstack')) console.log(` ${c.accent('+')} gstack 테스트 자동화`);\n if (extraTools.includes('harness')) console.log(` ${c.accent('+')} Harness 품질 검증`);\n if (extraTools.includes('mcp') && mcp) {\n console.log(` ${c.accent('+')} MCP 서버 (${mcp.name}, ${mcp.type})`);\n }\n }\n\n if (authMethods.length > 0) {\n console.log('');\n console.log(` ${c.accent('+')} 로그인: ${authMethods.join(', ')}`);\n }\n\n console.log('');\n const { proceed } = await inquirer.prompt([{\n type: 'confirm',\n name: 'proceed',\n message: '이대로 설치를 시작할까요?',\n default: true,\n }]);\n\n if (!proceed) {\n ui.info('취소되었습니다. 다시 시작하려면: npx pai-zero init');\n process.exit(0);\n }\n\n const hasWebFramework = analysis.stack.frameworks.some((f) =>\n ['React', 'Vue', 'Next.js', 'Nuxt', 'Svelte', 'Angular'].includes(f),\n );\n\n return {\n mode,\n projectName,\n authMethods,\n customAuth,\n extraTools,\n mcp,\n setupDomains: {\n claudeEnv: true,\n processDocs: true,\n cicd: analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: true,\n githubMcp: analysis.git.remoteUrl?.includes('github.com') ?? false,\n harness: extraTools.includes('harness') || hasWebFramework,\n },\n autoGenerated: false,\n };\n}\n\nexport function autoInterview(\n analysis: AnalysisResult,\n _cwd: string,\n projectName: string,\n): InterviewResult {\n const hasWebFramework = analysis.stack.frameworks.some((f) =>\n ['React', 'Vue', 'Next.js', 'Nuxt', 'Svelte', 'Angular'].includes(f),\n );\n\n return {\n mode: hasWebFramework ? 'production' : 'prototype',\n projectName,\n authMethods: [],\n extraTools: hasWebFramework ? ['omc', 'vercel', 'supabase', 'gstack', 'harness'] : [],\n setupDomains: {\n claudeEnv: true,\n processDocs: true,\n cicd: analysis.git.isGitRepo,\n },\n tools: {\n omc: true,\n openspec: true,\n githubMcp: analysis.git.remoteUrl?.includes('github.com') ?? false,\n harness: hasWebFramework || analysis.structure.isMonorepo,\n },\n autoGenerated: true,\n };\n}\n","/**\n * Generator — CLAUDE.md, settings.json, 프로세스 문서 생성\n * roboco-cli의 generator 패턴을 PAI에 맞게 재구성\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { AnalysisResult } from '../../core/types/index.js';\nimport type { InterviewResult } from './interviewer.js';\nimport * as ui from '../../ui/index.js';\n\ninterface FileOperation {\n path: string;\n content: string;\n description: string;\n overwrite?: boolean;\n}\n\nexport async function generateFiles(\n cwd: string,\n analysis: AnalysisResult,\n interview: InterviewResult,\n): Promise<string[]> {\n const files: FileOperation[] = [];\n\n // CLAUDE.md\n files.push(generateClaudeMd(cwd, analysis, interview));\n\n // .claude/settings.json\n files.push(generateClaudeSettings(cwd, analysis));\n\n // Process docs (optional)\n if (interview.setupDomains.processDocs) {\n files.push(...generateProcessDocs(cwd));\n }\n\n // CI/CD (optional)\n if (interview.setupDomains.cicd) {\n files.push(...generateCicd(cwd, analysis));\n }\n\n const created: string[] = [];\n for (const file of files) {\n if ((await fs.pathExists(file.path)) && !file.overwrite) {\n continue;\n }\n await fs.ensureDir(join(file.path, '..'));\n await fs.writeFile(file.path, file.content, 'utf8');\n created.push(file.path);\n }\n\n return created;\n}\n\nfunction relativePath(base: string, full: string): string {\n return full.startsWith(base) ? full.slice(base.length + 1) : full;\n}\n\nfunction generateClaudeMd(\n cwd: string,\n analysis: AnalysisResult,\n interview: InterviewResult,\n): FileOperation {\n const stack = [...analysis.stack.languages, ...analysis.stack.frameworks].join(', ') || 'Not detected';\n const tools = Object.entries(interview.tools)\n .filter(([, v]) => v)\n .map(([k]) => k)\n .join(', ');\n\n const content = `# ${interview.projectName}\n\n## Project Overview\n\nDescribe your project here.\n\n<pai>\n## PAI Configuration\n\nThis project uses PAI (Plugin-based AI) for structured AI development.\n\n### Pipeline: 설계-실행-검증-평가-환경\n\n1. **Environment** — 프로젝트 환경 구성 (이 단계)\n2. **Design** — OpenSpec/OMC 기반 설계\n3. **Execution** — AI 코드 생성\n4. **Validation** — gstack 테스트 / harness 검증\n5. **Evaluation** — 품질 평가 (6카테고리)\n\n### Stack\n- **Languages**: ${stack}\n- **Tools**: ${tools}\n- **Mode**: ${interview.mode}\n- **Config**: \\`.pai/config.json\\`\n\nRun \\`pai env status\\` to check setup, \\`pai evaluate\\` for quality scoring.\n\n### Global Rules\n\n- **심층 인터뷰 자동 수행**: 컨텍스트가 부족하거나 모호한 경우, AskUserQuestion 도구를 사용하여 심층 인터뷰를 자동으로 진행합니다. 추측하지 말고 반드시 질문하세요.\n- **Ideation → PRD 파이프라인**: \\`/pai design\\` 실행 시 ideation.md → openspec.md 순서로 심층 인터뷰를 통해 작성합니다.\n- **기술 제약 파악**: 코드 생성 전 기술적 제약 사항을 심층 인터뷰로 확인합니다.\n- **하네스 엔지니어링**: AI 에이전트가 안전하게 작업할 수 있도록 테스트/검증 환경을 구성합니다.\n- **Git 커밋 규칙**: 작업 단위별로 의미 있는 커밋 메시지를 작성합니다.\n\n### Contribution Guide\n\n기여자는 \\`CONTRIBUTING.md\\`를 참고하세요. 이 가이드는 \\`.claude/skills/\\`에 스킬로 등록되어 자동 적용됩니다.\n</pai>\n`;\n\n return {\n path: join(cwd, 'CLAUDE.md'),\n content,\n description: 'CLAUDE.md',\n overwrite: false,\n };\n}\n\nfunction generateClaudeSettings(cwd: string, analysis: AnalysisResult): FileOperation {\n const hooks = generateHooksForStack(analysis.stack.languages);\n\n const settings: Record<string, unknown> = {\n permissions: {\n allow: [\n 'Read',\n 'Write',\n 'Edit',\n 'Glob',\n 'Grep',\n 'Bash(npm run *)',\n 'Bash(git status*)',\n 'Bash(git diff*)',\n 'Bash(git log*)',\n ],\n deny: [\n 'Bash(rm -rf *)',\n 'Bash(git push --force*)',\n 'Bash(git reset --hard*)',\n ],\n },\n ...(Object.keys(hooks).length > 0 ? { hooks } : {}),\n };\n\n // Merge with existing settings\n if (analysis.existingConfig.claudeSettings) {\n const existing = analysis.existingConfig.claudeSettings;\n return {\n path: join(cwd, '.claude', 'settings.json'),\n content: JSON.stringify(deepMergeSettings(existing, settings), null, 2) + '\\n',\n description: '.claude/settings.json (merged)',\n overwrite: true,\n };\n }\n\n return {\n path: join(cwd, '.claude', 'settings.json'),\n content: JSON.stringify(settings, null, 2) + '\\n',\n description: '.claude/settings.json',\n overwrite: false,\n };\n}\n\nfunction deepMergeSettings(\n existing: Record<string, unknown>,\n defaults: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...existing };\n\n for (const [key, value] of Object.entries(defaults)) {\n if (key === 'permissions' && result[key] && typeof result[key] === 'object') {\n const ep = result[key] as Record<string, unknown>;\n const dp = value as Record<string, unknown>;\n result[key] = {\n allow: [...new Set([\n ...((ep['allow'] as string[]) ?? []),\n ...((dp['allow'] as string[]) ?? []),\n ])],\n deny: [...new Set([\n ...((ep['deny'] as string[]) ?? []),\n ...((dp['deny'] as string[]) ?? []),\n ])],\n };\n } else if (!(key in result)) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\nfunction generateHooksForStack(languages: string[]): Record<string, unknown> {\n const hooks: Record<string, unknown> = {};\n\n if (languages.includes('TypeScript') || languages.includes('JavaScript')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'npx prettier --write $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n } else if (languages.includes('Python')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'black $CLAUDE_FILE_PATH 2>/dev/null || ruff format $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n } else if (languages.includes('Go')) {\n hooks['PostToolUse'] = [{\n matcher: 'Write|Edit',\n hooks: [{ type: 'command', command: 'gofmt -w $CLAUDE_FILE_PATH 2>/dev/null || true' }],\n }];\n }\n\n return hooks;\n}\n\nfunction generateProcessDocs(cwd: string): FileOperation[] {\n const stages = [\n { file: '01-intent.md', title: 'Intent', desc: '구현하고자 하는 것을 명확히 정의합니다.' },\n { file: '02-requirements.md', title: 'Requirements', desc: '상세 요구사항을 정의합니다.' },\n { file: '03-research.md', title: 'Research', desc: '접근 방법과 도구를 조사합니다.' },\n { file: '04-plan.md', title: 'Plan', desc: '단계별 구현 계획을 수립합니다.' },\n { file: '05-implement.md', title: 'Implement', desc: 'AI와 함께 솔루션을 구축합니다.' },\n ];\n\n return stages.map(({ file, title, desc }) => ({\n path: join(cwd, 'docs', 'vibe-coding', file),\n content: `# Stage: ${title}\\n\\n${desc}\\n\\n## Checklist\\n\\n- [ ] \\n`,\n description: `Process: ${title}`,\n }));\n}\n\nfunction generateCicd(cwd: string, analysis: AnalysisResult): FileOperation[] {\n const files: FileOperation[] = [];\n\n files.push({\n path: join(cwd, '.github', 'workflows', 'vibe-coding-check.yml'),\n content: `name: Vibe Coding Check\n\non:\n pull_request:\n branches: [main, dev]\n\njobs:\n check:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@v4\n - name: Check CLAUDE.md exists\n run: test -f CLAUDE.md\n - name: Check .claude directory\n run: test -d .claude\n`,\n description: 'GitHub Actions workflow',\n });\n\n const lintCmd = getLintCommand(analysis.stack.languages);\n files.push({\n path: join(cwd, '.husky', 'pre-commit'),\n content: `${lintCmd}\\n`,\n description: 'Pre-commit hook',\n });\n\n return files;\n}\n\nfunction getLintCommand(languages: string[]): string {\n if (languages.includes('TypeScript') || languages.includes('JavaScript')) return 'npx lint-staged';\n if (languages.includes('Python')) return 'ruff check --fix . && ruff format .';\n if (languages.includes('Go')) return 'gofmt -l . && go vet ./...';\n if (languages.includes('Rust')) return 'cargo fmt --check && cargo clippy';\n return 'echo \"No lint configured\"';\n}\n","/**\n * Installer — OMC는 npx로 직접 설치 (3회 재시도), 나머지는 안내\n */\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { createSpinner } from '../../ui/progress.js';\n\nexport interface InstallResult {\n tool: string;\n success: boolean;\n message: string;\n}\n\nexport interface ToolSelection {\n omc: boolean;\n openspec: boolean;\n githubMcp: boolean;\n harness: boolean;\n}\n\nexport async function installTools(tools: ToolSelection, _cwd: string): Promise<InstallResult[]> {\n // OMC는 Claude Code 시작 시 옵션으로 통합됨 — init 중 설치하지 않음\n return [];\n}\n\nasync function installOMCWithRetry(cwd: string): Promise<InstallResult> {\n const fsLib = (await import('fs-extra')).default;\n const { join } = await import('node:path');\n const { homedir } = await import('node:os');\n\n // Check if already installed\n const indicators = [\n join(cwd, '.omc'),\n join(homedir(), '.claude', 'plugins', 'oh-my-claudecode'),\n ];\n for (const path of indicators) {\n if (await fsLib.pathExists(path)) {\n ui.success('OMC 이미 설치됨');\n return { tool: 'oh-my-claudecode', success: true, message: 'OMC 이미 설치됨' };\n }\n }\n\n const spinner = createSpinner('OMC (oh-my-claudecode) 설치 중...');\n\n try {\n const { execa } = await import('execa');\n await execa('npx', ['-y', 'github:SoInKyu/oh-my-claudecode', 'install'], { timeout: 120000, cwd });\n spinner.succeed('OMC 설치 완료');\n return { tool: 'oh-my-claudecode', success: true, message: 'oh-my-claudecode install 완료' };\n } catch {\n spinner.warn('OMC 자동 설치를 건너뜁니다');\n ui.hint('Claude Code 터미널에서 설치: npx oh-my-claudecode install');\n return { tool: 'oh-my-claudecode', success: false, message: '수동 설치: npx oh-my-claudecode install' };\n }\n}\n\nexport function printInstallReport(results: InstallResult[], tools: ToolSelection): void {\n const manualSteps: Array<{ label: string; command: string }> = [];\n\n if (tools.githubMcp) {\n manualSteps.push({\n label: 'GitHub MCP 서버 (선택사항)',\n command: 'claude mcp add github -- npx -y @modelcontextprotocol/server-github',\n });\n }\n\n if (manualSteps.length === 0) return;\n\n console.log('');\n ui.info('아래 항목은 Claude Code 터미널에서 직접 설치하세요:');\n console.log('');\n\n for (const step of manualSteps) {\n console.log(` ${chalk.gray(step.label)}`);\n console.log(` $ ${chalk.white(step.command)}`);\n console.log('');\n }\n}\n","import os from 'node:os';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport { execFileSync } from 'node:child_process';\n\nexport const isWindows = process.platform === 'win32';\nexport const isMac = process.platform === 'darwin';\n\nexport interface WindowsDiagnostic {\n issues: Array<{ title: string; fix: string }>;\n warnings: Array<{ title: string; hint?: string }>;\n}\n\nexport function diagnoseWindowsEnv(): WindowsDiagnostic {\n const issues: WindowsDiagnostic['issues'] = [];\n const warnings: WindowsDiagnostic['warnings'] = [];\n\n if (!isWindows) return { issues, warnings };\n\n warnings.push({\n title: 'PowerShell 실행 정책',\n hint: '문제 발생 시: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser',\n });\n\n const pathEnv = process.env['PATH'] || process.env['Path'] || '';\n if (!pathEnv.toLowerCase().includes('node')) {\n issues.push({\n title: 'Node.js PATH 미등록',\n fix: 'Node.js를 재설치하거나 환경변수 PATH에 Node.js 경로를 추가하세요.',\n });\n }\n\n const home = process.env['HOME'] || process.env['USERPROFILE'];\n if (!home) {\n issues.push({\n title: 'HOME 환경변수 없음',\n fix: 'PowerShell에서: $env:HOME = $env:USERPROFILE 실행 후 재시도',\n });\n }\n\n return { issues, warnings };\n}\n\nexport function writeEnvFile(filePath: string, entries: Record<string, string>): void {\n const content = Object.entries(entries)\n .map(([k, v]) => `${k}=${v}`)\n .join('\\n');\n fs.writeFileSync(filePath, content + '\\n', { encoding: 'utf8' });\n}\n\nexport function getPlatformInfo() {\n return {\n isWindows,\n isMac,\n isLinux: !isWindows && !isMac,\n shell: isWindows ? 'PowerShell' : (process.env['SHELL'] || 'bash'),\n home: process.env['HOME'] || process.env['USERPROFILE'] || os.homedir(),\n nodeVersion: process.version,\n };\n}\n\n/**\n * 플랫폼별 쉘 RC 파일 경로\n * macOS/Linux: ~/.zshrc 또는 ~/.bashrc\n * Windows: PowerShell $PROFILE (Documents\\PowerShell\\Microsoft.PowerShell_profile.ps1)\n */\nexport function getShellRcPath(): string {\n const home = os.homedir();\n if (isWindows) {\n // PowerShell 7+ profile path\n const ps7 = path.join(home, 'Documents', 'PowerShell', 'Microsoft.PowerShell_profile.ps1');\n // Windows PowerShell 5.x profile path\n const ps5 = path.join(home, 'Documents', 'WindowsPowerShell', 'Microsoft.PowerShell_profile.ps1');\n // Prefer PS7, fallback to PS5\n if (fs.existsSync(path.dirname(ps7))) return ps7;\n return ps5;\n }\n const shell = process.env['SHELL'] || '';\n return shell.includes('zsh')\n ? path.join(home, '.zshrc')\n : path.join(home, '.bashrc');\n}\n\n/**\n * 플랫폼별 서브쉘 스폰 — cwd에서 새 쉘을 시작\n * macOS/Linux: zsh/bash -l\n * Windows: powershell.exe -NoExit\n */\nexport function spawnSubshell(cwd: string): void {\n try {\n if (isWindows) {\n execFileSync('powershell.exe', ['-NoExit', '-Command', `Set-Location '${cwd}'`], {\n stdio: 'inherit',\n cwd,\n });\n } else {\n const shell = process.env['SHELL'] || '/bin/zsh';\n execFileSync(shell, ['-l'], { stdio: 'inherit', cwd });\n }\n } catch {\n // user exited shell\n }\n}\n\n/**\n * 플랫폼별 YOLO alias 텍스트\n */\nexport function getYoloAliasLine(): string {\n if (isWindows) {\n return \"function claude-yolo { claude --dangerously-skip-permissions @args }\";\n }\n return \"alias claude-yolo='claude --dangerously-skip-permissions'\";\n}\n\n/**\n * 플랫폼별 YOLO alias 감지\n */\nexport function hasYoloAlias(rcContent: string): boolean {\n return rcContent.includes('claude-yolo') || rcContent.includes('dangerously-skip-permissions');\n}\n\n/**\n * Windows 파일시스템 금지 문자를 `-`로 치환.\n * 백업 파일명(ISO8601 `:` 포함) 등 크로스플랫폼 파일명 생성에 사용.\n *\n * 금지 문자: \\ / : * ? \" < > |\n */\nexport function sanitizeFilenameForWindows(name: string): string {\n return name.replace(/[\\\\/:*?\"<>|]/g, '-');\n}\n","/**\n * MCP Server Provisioner\n * MCP(Model Context Protocol) 서버 스캐폴딩 생성\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { ProvisionerContext } from './registry.js';\n\ntype McpType = 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n\nexport async function provisionMcp(ctx: ProvisionerContext): Promise<void> {\n const mcp = (ctx as ProvisionerContext & {\n mcp?: { enabled: boolean; type: McpType; name: string };\n }).mcp;\n\n if (!mcp?.enabled) return;\n\n const mcpDir = join(ctx.cwd, 'mcp-server');\n await fs.ensureDir(mcpDir);\n await fs.ensureDir(join(mcpDir, 'src'));\n await fs.ensureDir(join(mcpDir, 'tests'));\n\n // package.json\n const isPublicDeps = mcp.type === 'tools-public';\n const pkgJson = {\n name: mcp.name,\n version: '0.1.0',\n description: `MCP server for ${ctx.projectName}`,\n type: 'module',\n main: 'dist/index.js',\n bin: { [mcp.name]: './dist/index.js' },\n scripts: {\n build: 'tsc',\n dev: 'tsc --watch',\n test: 'vitest run',\n start: 'node dist/index.js',\n },\n dependencies: {\n '@modelcontextprotocol/sdk': '^1.0.0',\n ...(isPublicDeps ? { '@supabase/supabase-js': '^2.48.0' } : {}),\n },\n devDependencies: {\n typescript: '^5.7.0',\n '@types/node': '^20.17.0',\n vitest: '^3.0.0',\n },\n };\n const pkgPath = join(mcpDir, 'package.json');\n if (!(await fs.pathExists(pkgPath))) {\n await fs.writeJson(pkgPath, pkgJson, { spaces: 2 });\n }\n\n // tsconfig.json\n const tsconfig = {\n compilerOptions: {\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'bundler',\n outDir: './dist',\n rootDir: './src',\n strict: true,\n esModuleInterop: true,\n skipLibCheck: true,\n resolveJsonModule: true,\n declaration: true,\n },\n include: ['src/**/*'],\n exclude: ['node_modules', 'dist', 'tests'],\n };\n const tsPath = join(mcpDir, 'tsconfig.json');\n if (!(await fs.pathExists(tsPath))) {\n await fs.writeJson(tsPath, tsconfig, { spaces: 2 });\n }\n\n // src/index.ts\n const indexPath = join(mcpDir, 'src', 'index.ts');\n if (!(await fs.pathExists(indexPath))) {\n await fs.writeFile(indexPath, buildIndexTs(mcp), 'utf8');\n }\n\n // Type-specific files\n const isTools = mcp.type === 'tools' || mcp.type === 'tools-public' || mcp.type === 'all';\n const isPublic = mcp.type === 'tools-public';\n\n if (isTools) {\n const toolsPath = join(mcpDir, 'src', 'tools.ts');\n if (!(await fs.pathExists(toolsPath))) {\n await fs.writeFile(toolsPath, isPublic ? TOOLS_PUBLIC_TEMPLATE : TOOLS_TEMPLATE, 'utf8');\n }\n }\n\n // Public 배포 — auth 미들웨어, Supabase 마이그레이션, 대시보드\n if (isPublic) {\n const authPath = join(mcpDir, 'src', 'auth.ts');\n if (!(await fs.pathExists(authPath))) {\n await fs.writeFile(authPath, AUTH_MIDDLEWARE_TEMPLATE, 'utf8');\n }\n\n const rateLimitPath = join(mcpDir, 'src', 'rate-limit.ts');\n if (!(await fs.pathExists(rateLimitPath))) {\n await fs.writeFile(rateLimitPath, RATE_LIMIT_TEMPLATE, 'utf8');\n }\n\n // Supabase 마이그레이션\n const migDir = join(ctx.cwd, 'supabase', 'migrations');\n await fs.ensureDir(migDir);\n const migPath = join(migDir, '20260101_mcp_keys_and_usage.sql');\n if (!(await fs.pathExists(migPath))) {\n await fs.writeFile(migPath, SUPABASE_MIGRATION, 'utf8');\n }\n\n // 관리 대시보드 (Next.js App Router)\n const dashDir = join(ctx.cwd, 'src', 'app', 'dashboard');\n await fs.ensureDir(join(dashDir, 'keys'));\n await fs.ensureDir(join(dashDir, 'usage'));\n\n const dashLayoutPath = join(dashDir, 'layout.tsx');\n if (!(await fs.pathExists(dashLayoutPath))) {\n await fs.writeFile(dashLayoutPath, DASHBOARD_LAYOUT, 'utf8');\n }\n const dashPagePath = join(dashDir, 'page.tsx');\n if (!(await fs.pathExists(dashPagePath))) {\n await fs.writeFile(dashPagePath, DASHBOARD_PAGE, 'utf8');\n }\n const keysPagePath = join(dashDir, 'keys', 'page.tsx');\n if (!(await fs.pathExists(keysPagePath))) {\n await fs.writeFile(keysPagePath, KEYS_PAGE, 'utf8');\n }\n const usagePagePath = join(dashDir, 'usage', 'page.tsx');\n if (!(await fs.pathExists(usagePagePath))) {\n await fs.writeFile(usagePagePath, USAGE_PAGE, 'utf8');\n }\n\n // API 라우트\n const apiKeysDir = join(ctx.cwd, 'src', 'app', 'api', 'keys');\n await fs.ensureDir(apiKeysDir);\n const keysRoutePath = join(apiKeysDir, 'route.ts');\n if (!(await fs.pathExists(keysRoutePath))) {\n await fs.writeFile(keysRoutePath, KEYS_API_ROUTE, 'utf8');\n }\n }\n if (mcp.type === 'resources' || mcp.type === 'all') {\n const resPath = join(mcpDir, 'src', 'resources.ts');\n if (!(await fs.pathExists(resPath))) {\n await fs.writeFile(resPath, RESOURCES_TEMPLATE, 'utf8');\n }\n }\n if (mcp.type === 'prompts' || mcp.type === 'all') {\n const promptsPath = join(mcpDir, 'src', 'prompts.ts');\n if (!(await fs.pathExists(promptsPath))) {\n await fs.writeFile(promptsPath, PROMPTS_TEMPLATE, 'utf8');\n }\n }\n\n // tests/server.test.ts\n const testPath = join(mcpDir, 'tests', 'server.test.ts');\n if (!(await fs.pathExists(testPath))) {\n await fs.writeFile(testPath, TEST_TEMPLATE, 'utf8');\n }\n\n // README.md\n const readmePath = join(mcpDir, 'README.md');\n if (!(await fs.pathExists(readmePath))) {\n await fs.writeFile(readmePath, buildReadme(mcp), 'utf8');\n }\n\n // docs/openspec.md에 MCP 섹션 추가 (있으면 append)\n const openspecPath = join(ctx.cwd, 'docs', 'openspec.md');\n if (await fs.pathExists(openspecPath)) {\n const existing = await fs.readFile(openspecPath, 'utf8');\n if (!existing.includes('## MCP 서버')) {\n const section = buildOpenSpecMcpSection(mcp);\n await fs.appendFile(openspecPath, `\\n\\n${section}\\n`);\n }\n }\n\n // .mcp.json (프로젝트 루트)\n const mcpJsonPath = join(ctx.cwd, '.mcp.json');\n const mcpJson = (await fs.pathExists(mcpJsonPath))\n ? await fs.readJson(mcpJsonPath)\n : { mcpServers: {} };\n mcpJson.mcpServers[mcp.name] = {\n command: 'node',\n args: ['./mcp-server/dist/index.js'],\n };\n await fs.writeJson(mcpJsonPath, mcpJson, { spaces: 2 });\n\n // .gitignore (MCP 서버 디렉토리)\n const gitignorePath = join(mcpDir, '.gitignore');\n if (!(await fs.pathExists(gitignorePath))) {\n await fs.writeFile(gitignorePath, 'node_modules/\\ndist/\\n*.log\\n', 'utf8');\n }\n}\n\nfunction buildIndexTs(mcp: { type: McpType; name: string }): string {\n const imports: string[] = [];\n const registrations: string[] = [];\n\n if (mcp.type === 'tools' || mcp.type === 'all') {\n imports.push(\"import { registerTools } from './tools.js';\");\n registrations.push(' registerTools(server);');\n }\n if (mcp.type === 'resources' || mcp.type === 'all') {\n imports.push(\"import { registerResources } from './resources.js';\");\n registrations.push(' registerResources(server);');\n }\n if (mcp.type === 'prompts' || mcp.type === 'all') {\n imports.push(\"import { registerPrompts } from './prompts.js';\");\n registrations.push(' registerPrompts(server);');\n }\n\n return `#!/usr/bin/env node\n/**\n * ${mcp.name} — MCP Server\n * Generated by PAI\n */\nimport { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\n${imports.join('\\n')}\n\nasync function main() {\n const server = new Server(\n {\n name: '${mcp.name}',\n version: '0.1.0',\n },\n {\n capabilities: {\n${mcp.type === 'tools' || mcp.type === 'all' ? ' tools: {},' : ''}\n${mcp.type === 'resources' || mcp.type === 'all' ? ' resources: {},' : ''}\n${mcp.type === 'prompts' || mcp.type === 'all' ? ' prompts: {},' : ''}\n },\n },\n );\n\n${registrations.join('\\n')}\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error('${mcp.name} MCP server running on stdio');\n}\n\nmain().catch((err) => {\n console.error('Fatal error:', err);\n process.exit(1);\n});\n`;\n}\n\nconst TOOLS_PUBLIC_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { verifyApiKey } from './auth.js';\nimport { checkRateLimit, logUsage } from './rate-limit.js';\n\nexport function registerTools(server: Server): void {\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'hello',\n description: '인증된 도구 호출 — API 키 필요',\n inputSchema: {\n type: 'object',\n properties: {\n apiKey: { type: 'string', description: 'API 키' },\n name: { type: 'string', description: '인사할 대상' },\n },\n required: ['apiKey', 'name'],\n },\n },\n ],\n }));\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n const { apiKey, ...params } = (args as { apiKey?: string; [k: string]: unknown }) ?? {};\n\n if (!apiKey) throw new Error('API key required');\n const user = await verifyApiKey(apiKey);\n if (!user) throw new Error('Invalid API key');\n\n const allowed = await checkRateLimit(user.id);\n if (!allowed) throw new Error('Rate limit exceeded');\n\n if (name === 'hello') {\n const target = (params as { name?: string })?.name ?? 'world';\n const result = { content: [{ type: 'text' as const, text: \\`Hello, \\${target}!\\` }] };\n await logUsage(user.id, name);\n return result;\n }\n\n throw new Error(\\`Unknown tool: \\${name}\\`);\n });\n}\n`;\n\nconst AUTH_MIDDLEWARE_TEMPLATE = `import { createClient } from '@supabase/supabase-js';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nexport interface AuthUser {\n id: string;\n email: string;\n}\n\n/**\n * API 키 검증 — Supabase api_keys 테이블에서 조회\n */\nexport async function verifyApiKey(apiKey: string): Promise<AuthUser | null> {\n const { data, error } = await supabase\n .from('api_keys')\n .select('user_id, revoked_at, users(id, email)')\n .eq('key_hash', await hashKey(apiKey))\n .single();\n\n if (error || !data || data.revoked_at) return null;\n\n // 마지막 사용 시간 업데이트\n await supabase\n .from('api_keys')\n .update({ last_used_at: new Date().toISOString() })\n .eq('key_hash', await hashKey(apiKey));\n\n const users = (data as unknown as { users: { id: string; email: string } }).users;\n return { id: users.id, email: users.email };\n}\n\nasync function hashKey(key: string): Promise<string> {\n const crypto = await import('node:crypto');\n return crypto.createHash('sha256').update(key).digest('hex');\n}\n\nexport async function generateApiKey(): Promise<{ key: string; hash: string }> {\n const crypto = await import('node:crypto');\n const key = \\`mcp_\\${crypto.randomBytes(32).toString('hex')}\\`;\n const hash = crypto.createHash('sha256').update(key).digest('hex');\n return { key, hash };\n}\n`;\n\nconst RATE_LIMIT_TEMPLATE = `import { createClient } from '@supabase/supabase-js';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nconst RATE_LIMIT_PER_HOUR = 100;\n\n/**\n * Rate limit 체크 — 최근 1시간 내 호출 수 확인\n */\nexport async function checkRateLimit(userId: string): Promise<boolean> {\n const oneHourAgo = new Date(Date.now() - 60 * 60 * 1000).toISOString();\n const { count } = await supabase\n .from('usage_logs')\n .select('*', { count: 'exact', head: true })\n .eq('user_id', userId)\n .gte('created_at', oneHourAgo);\n\n return (count ?? 0) < RATE_LIMIT_PER_HOUR;\n}\n\n/**\n * 사용량 기록 — usage_logs 테이블에 저장\n */\nexport async function logUsage(userId: string, toolName: string): Promise<void> {\n await supabase.from('usage_logs').insert({\n user_id: userId,\n tool_name: toolName,\n created_at: new Date().toISOString(),\n });\n}\n`;\n\nconst SUPABASE_MIGRATION = `-- MCP Tools 공개 배포 — API 키 관리 + 사용량 추적\n-- Generated by PAI\n\n-- 사용자 테이블 (Supabase Auth와 연동)\ncreate table if not exists public.users (\n id uuid primary key references auth.users(id) on delete cascade,\n email text not null unique,\n created_at timestamptz default now()\n);\n\n-- API 키 테이블\ncreate table if not exists public.api_keys (\n id uuid primary key default gen_random_uuid(),\n user_id uuid not null references public.users(id) on delete cascade,\n key_hash text not null unique,\n name text not null,\n created_at timestamptz default now(),\n last_used_at timestamptz,\n revoked_at timestamptz\n);\n\ncreate index if not exists api_keys_user_id_idx on public.api_keys(user_id);\ncreate index if not exists api_keys_key_hash_idx on public.api_keys(key_hash);\n\n-- 사용량 로그 테이블\ncreate table if not exists public.usage_logs (\n id bigserial primary key,\n user_id uuid not null references public.users(id) on delete cascade,\n tool_name text not null,\n created_at timestamptz default now()\n);\n\ncreate index if not exists usage_logs_user_id_idx on public.usage_logs(user_id);\ncreate index if not exists usage_logs_created_at_idx on public.usage_logs(created_at);\n\n-- RLS (Row Level Security)\nalter table public.users enable row level security;\nalter table public.api_keys enable row level security;\nalter table public.usage_logs enable row level security;\n\ncreate policy \"Users can view own data\" on public.users\n for select using (auth.uid() = id);\n\ncreate policy \"Users can manage own api keys\" on public.api_keys\n for all using (auth.uid() = user_id);\n\ncreate policy \"Users can view own usage\" on public.usage_logs\n for select using (auth.uid() = user_id);\n`;\n\nconst DASHBOARD_LAYOUT = `import Link from 'next/link';\nimport type { ReactNode } from 'react';\n\nexport default function DashboardLayout({ children }: { children: ReactNode }) {\n return (\n <div style={{ display: 'flex', minHeight: '100vh' }}>\n <aside style={{ width: 240, borderRight: '1px solid #eee', padding: 24 }}>\n <h2 style={{ fontSize: 18, marginBottom: 16 }}>MCP 대시보드</h2>\n <nav>\n <Link href=\"/dashboard\" style={{ display: 'block', padding: '8px 0' }}>개요</Link>\n <Link href=\"/dashboard/keys\" style={{ display: 'block', padding: '8px 0' }}>API 키</Link>\n <Link href=\"/dashboard/usage\" style={{ display: 'block', padding: '8px 0' }}>사용량</Link>\n </nav>\n </aside>\n <main style={{ flex: 1, padding: 24 }}>{children}</main>\n </div>\n );\n}\n`;\n\nconst DASHBOARD_PAGE = `export default function DashboardPage() {\n return (\n <div>\n <h1>MCP 대시보드</h1>\n <p>API 키를 발급하고 사용량을 관리하세요.</p>\n <ul>\n <li><a href=\"/dashboard/keys\">API 키 발급</a></li>\n <li><a href=\"/dashboard/usage\">사용량 확인</a></li>\n </ul>\n </div>\n );\n}\n`;\n\nconst KEYS_PAGE = `'use client';\nimport { useEffect, useState } from 'react';\n\ninterface ApiKey {\n id: string;\n name: string;\n created_at: string;\n last_used_at?: string;\n}\n\nexport default function KeysPage() {\n const [keys, setKeys] = useState<ApiKey[]>([]);\n const [newKeyName, setNewKeyName] = useState('');\n const [newKey, setNewKey] = useState<string | null>(null);\n\n useEffect(() => {\n fetch('/api/keys').then(r => r.json()).then(setKeys);\n }, []);\n\n async function create() {\n const res = await fetch('/api/keys', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ name: newKeyName }),\n });\n const data = await res.json();\n setNewKey(data.key);\n setKeys([...keys, data.apiKey]);\n setNewKeyName('');\n }\n\n async function revoke(id: string) {\n await fetch(\\`/api/keys/\\${id}\\`, { method: 'DELETE' });\n setKeys(keys.filter(k => k.id !== id));\n }\n\n return (\n <div>\n <h1>API 키 관리</h1>\n <div style={{ marginBottom: 24 }}>\n <input\n placeholder=\"키 이름\"\n value={newKeyName}\n onChange={e => setNewKeyName(e.target.value)}\n />\n <button onClick={create}>새 키 발급</button>\n </div>\n {newKey && (\n <div style={{ padding: 16, background: '#fffbe6', marginBottom: 24 }}>\n <strong>새 API 키 (한 번만 표시):</strong>\n <pre>{newKey}</pre>\n </div>\n )}\n <table style={{ width: '100%' }}>\n <thead>\n <tr><th>이름</th><th>생성일</th><th>마지막 사용</th><th></th></tr>\n </thead>\n <tbody>\n {keys.map(k => (\n <tr key={k.id}>\n <td>{k.name}</td>\n <td>{new Date(k.created_at).toLocaleDateString()}</td>\n <td>{k.last_used_at ? new Date(k.last_used_at).toLocaleString() : '—'}</td>\n <td><button onClick={() => revoke(k.id)}>삭제</button></td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n`;\n\nconst USAGE_PAGE = `'use client';\nimport { useEffect, useState } from 'react';\n\ninterface UsageLog {\n tool_name: string;\n count: number;\n}\n\nexport default function UsagePage() {\n const [usage, setUsage] = useState<UsageLog[]>([]);\n const [total, setTotal] = useState(0);\n\n useEffect(() => {\n fetch('/api/usage').then(r => r.json()).then(data => {\n setUsage(data.byTool ?? []);\n setTotal(data.total ?? 0);\n });\n }, []);\n\n return (\n <div>\n <h1>사용량</h1>\n <p>최근 30일 총 호출: <strong>{total}</strong></p>\n <table style={{ width: '100%' }}>\n <thead>\n <tr><th>도구</th><th>호출 수</th></tr>\n </thead>\n <tbody>\n {usage.map(u => (\n <tr key={u.tool_name}>\n <td>{u.tool_name}</td>\n <td>{u.count}</td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n );\n}\n`;\n\nconst KEYS_API_ROUTE = `import { NextResponse } from 'next/server';\nimport { createClient } from '@supabase/supabase-js';\nimport crypto from 'node:crypto';\n\nconst supabase = createClient(\n process.env.NEXT_PUBLIC_SUPABASE_URL ?? '',\n process.env.SUPABASE_SERVICE_ROLE_KEY ?? '',\n);\n\nexport async function GET() {\n // TODO: 현재 로그인 사용자의 키만 조회 (auth 미들웨어 연동 필요)\n const { data, error } = await supabase\n .from('api_keys')\n .select('id, name, created_at, last_used_at')\n .is('revoked_at', null);\n if (error) return NextResponse.json({ error: error.message }, { status: 500 });\n return NextResponse.json(data);\n}\n\nexport async function POST(request: Request) {\n const { name } = await request.json();\n const key = \\`mcp_\\${crypto.randomBytes(32).toString('hex')}\\`;\n const key_hash = crypto.createHash('sha256').update(key).digest('hex');\n\n // TODO: 현재 로그인 사용자 ID 연동\n const user_id = 'TODO-REPLACE-WITH-AUTH-USER-ID';\n\n const { data, error } = await supabase\n .from('api_keys')\n .insert({ user_id, name, key_hash })\n .select('id, name, created_at')\n .single();\n if (error) return NextResponse.json({ error: error.message }, { status: 500 });\n\n return NextResponse.json({ apiKey: data, key });\n}\n`;\n\nconst TOOLS_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerTools(server: Server): void {\n // Tool 목록 정의\n server.setRequestHandler(ListToolsRequestSchema, async () => ({\n tools: [\n {\n name: 'hello',\n description: '테스트용 인사 도구 — 이 템플릿을 수정해서 실제 도구를 구현하세요',\n inputSchema: {\n type: 'object',\n properties: {\n name: { type: 'string', description: '인사할 대상' },\n },\n required: ['name'],\n },\n },\n ],\n }));\n\n // Tool 호출 처리\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n if (name === 'hello') {\n const target = (args as { name?: string })?.name ?? 'world';\n return {\n content: [{ type: 'text', text: \\`Hello, \\${target}!\\` }],\n };\n }\n\n throw new Error(\\`Unknown tool: \\${name}\\`);\n });\n}\n`;\n\nconst RESOURCES_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n ListResourcesRequestSchema,\n ReadResourceRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerResources(server: Server): void {\n // Resource 목록 정의\n server.setRequestHandler(ListResourcesRequestSchema, async () => ({\n resources: [\n {\n uri: 'example://sample',\n name: 'Sample Resource',\n description: '예제 리소스 — AI가 읽을 컨텍스트',\n mimeType: 'text/plain',\n },\n ],\n }));\n\n // Resource 읽기\n server.setRequestHandler(ReadResourceRequestSchema, async (request) => {\n const { uri } = request.params;\n\n if (uri === 'example://sample') {\n return {\n contents: [{\n uri,\n mimeType: 'text/plain',\n text: 'This is a sample resource content.',\n }],\n };\n }\n\n throw new Error(\\`Unknown resource: \\${uri}\\`);\n });\n}\n`;\n\nconst PROMPTS_TEMPLATE = `import type { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport {\n GetPromptRequestSchema,\n ListPromptsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\n\nexport function registerPrompts(server: Server): void {\n // Prompt 목록 정의\n server.setRequestHandler(ListPromptsRequestSchema, async () => ({\n prompts: [\n {\n name: 'review-code',\n description: '코드 리뷰 요청 프롬프트',\n arguments: [\n { name: 'code', description: '리뷰할 코드', required: true },\n ],\n },\n ],\n }));\n\n // Prompt 가져오기\n server.setRequestHandler(GetPromptRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n if (name === 'review-code') {\n const code = (args as { code?: string })?.code ?? '';\n return {\n messages: [{\n role: 'user',\n content: {\n type: 'text',\n text: \\`다음 코드를 리뷰해주세요:\\\\n\\\\n\\${code}\\`,\n },\n }],\n };\n }\n\n throw new Error(\\`Unknown prompt: \\${name}\\`);\n });\n}\n`;\n\nconst TEST_TEMPLATE = `import { describe, it, expect } from 'vitest';\n\ndescribe('MCP Server', () => {\n it('should be tested', () => {\n // TODO: MCP 서버 테스트 작성\n expect(true).toBe(true);\n });\n});\n`;\n\nfunction buildOpenSpecMcpSection(mcp: { name: string; type: McpType }): string {\n const isPublic = mcp.type === 'tools-public';\n const hasTools = mcp.type === 'tools' || mcp.type === 'tools-public' || mcp.type === 'all';\n const hasResources = mcp.type === 'resources' || mcp.type === 'all';\n const hasPrompts = mcp.type === 'prompts' || mcp.type === 'all';\n\n const lines: string[] = [\n '## MCP 서버 (자동 생성됨)',\n '',\n '이 프로젝트는 MCP(Model Context Protocol) 서버를 포함합니다.',\n '`/pai design` 실행 시 아래 표를 심층 인터뷰로 채우세요.',\n '',\n `- **이름**: ${mcp.name}`,\n `- **타입**: ${mcp.type}`,\n ];\n\n if (isPublic) {\n lines.push(\n '- **인프라**: Supabase (api_keys, usage_logs)',\n '- **레이트 리밋**: 100회/시간 (기본값)',\n '- **관리 화면**: `/dashboard/keys`, `/dashboard/usage`',\n );\n }\n\n lines.push('', '### MCP 도구 / 리소스 / 프롬프트 설계');\n\n if (hasTools) {\n lines.push(\n '',\n '#### Tools (AI가 호출할 기능)',\n '',\n '| 도구 이름 | 설명 | 입력 파라미터 | 출력 형식 | 내부 로직 |',\n '|----------|------|-------------|----------|----------|',\n '| TODO | TODO | TODO | TODO | TODO |',\n );\n }\n\n if (hasResources) {\n lines.push(\n '',\n '#### Resources (AI가 읽을 컨텍스트)',\n '',\n '| URI | 이름 | 설명 | MIME 타입 |',\n '|-----|------|------|----------|',\n '| TODO | TODO | TODO | TODO |',\n );\n }\n\n if (hasPrompts) {\n lines.push(\n '',\n '#### Prompts (재사용 프롬프트 템플릿)',\n '',\n '| 이름 | 설명 | 인자 |',\n '|------|------|------|',\n '| TODO | TODO | TODO |',\n );\n }\n\n if (isPublic) {\n lines.push(\n '',\n '### 공개 배포 설정',\n '',\n '- **레이트 리밋**: TODO (기본 100회/시간)',\n '- **요금제**: 무료 (Stripe 제외)',\n '- **API 키 정책**: 사용자당 복수 키 허용',\n );\n }\n\n return lines.join('\\n');\n}\n\nfunction buildReadme(mcp: { name: string; type: McpType }): string {\n const isPublic = mcp.type === 'tools-public';\n return `# ${mcp.name} — MCP Server\n\nPAI가 생성한 MCP(Model Context Protocol) 서버입니다.\n\n## 타입: ${mcp.type}\n\n${mcp.type === 'tools' || mcp.type === 'all' ? '- **Tools**: AI가 호출할 기능 제공 (src/tools.ts)' : ''}\n${isPublic ? '- **Tools (공개 배포)**: API 키 검증 + 레이트 리밋 + 사용량 추적 (src/tools.ts, auth.ts, rate-limit.ts)' : ''}\n${mcp.type === 'resources' || mcp.type === 'all' ? '- **Resources**: AI가 읽을 컨텍스트 제공 (src/resources.ts)' : ''}\n${mcp.type === 'prompts' || mcp.type === 'all' ? '- **Prompts**: 재사용 프롬프트 템플릿 (src/prompts.ts)' : ''}\n\n${isPublic ? `\n## 공개 배포 설정\n\n1. **Supabase 마이그레이션 실행**\n \\\\\\`\\\\\\`\\\\\\`bash\n supabase db push\n \\\\\\`\\\\\\`\\\\\\`\n (\\\\\\`supabase/migrations/\\\\\\` 참고)\n\n2. **환경 변수 설정 (.env.local)**\n \\\\\\`\\\\\\`\\\\\\`\n NEXT_PUBLIC_SUPABASE_URL=...\n NEXT_PUBLIC_SUPABASE_ANON_KEY=...\n SUPABASE_SERVICE_ROLE_KEY=...\n \\\\\\`\\\\\\`\\\\\\`\n\n3. **대시보드 접속**\n \\\\\\`\\\\\\`\\\\\\`bash\n npm run dev\n # → http://localhost:3000/dashboard\n \\\\\\`\\\\\\`\\\\\\`\n - API 키 발급 및 관리\n - 사용량 확인\n` : ''}\n\n## 개발\n\n\\`\\`\\`bash\ncd mcp-server\nnpm install\nnpm run build\nnpm test\n\\`\\`\\`\n\n## Claude Code 연결\n\n프로젝트 루트의 \\`.mcp.json\\` 파일에 이미 등록되어 있습니다.\nClaude Code를 재시작하면 자동으로 MCP 서버가 로드됩니다.\n\n수동 등록:\n\\`\\`\\`bash\nclaude mcp add ${mcp.name} -- node ./mcp-server/dist/index.js\n\\`\\`\\`\n\n## 다음 단계\n\n1. \\`npm install\\` — 의존성 설치\n2. \\`npm run build\\` — TypeScript 컴파일\n3. \\`src/\\` 디렉토리의 템플릿을 실제 로직으로 수정\n4. Claude Code 재시작 → MCP 서버 사용\n\n## 참고 문서\n\n- [MCP 공식 문서](https://modelcontextprotocol.io/)\n- [SDK 문서](https://github.com/modelcontextprotocol/sdk)\n`;\n}\n","/**\n * Provisioner Registry — 조용한 파일 생성 (로그 없음, 스피너가 대신 표시)\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport { writeEnvFile } from '../../../utils/platform.js';\nimport type { Mode } from '../../../core/types/index.js';\n\nexport interface ProvisionerContext {\n cwd: string;\n projectName: string;\n mode: Mode;\n envEntries: Record<string, string>;\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n}\n\nexport type Provisioner = (ctx: ProvisionerContext) => Promise<void>;\n\nasync function provisionGitHub(ctx: ProvisionerContext): Promise<void> {\n const gitDir = join(ctx.cwd, '.git');\n if (!(await fs.pathExists(gitDir))) {\n await fs.ensureDir(join(ctx.cwd, '.github', 'workflows'));\n try {\n const { execa } = await import('execa');\n await execa('git', ['init'], { cwd: ctx.cwd });\n await execa('git', ['checkout', '-b', 'main'], { cwd: ctx.cwd });\n } catch {\n // silent — git not available\n }\n }\n\n const dirs = ['src', 'docs', 'tests', 'public', '.pai'];\n await Promise.all(dirs.map((d) => fs.ensureDir(join(ctx.cwd, d))));\n\n // handoff.md 생성\n const handoffPath = join(ctx.cwd, 'handoff.md');\n if (!(await fs.pathExists(handoffPath))) {\n const now = new Date().toLocaleString('ko-KR');\n await fs.writeFile(handoffPath, [\n `# Handoff — ${ctx.projectName}`,\n '',\n `> 마지막 업데이트: ${now}`,\n '',\n '## 진행 중',\n '- [ ] Ideation 문서 작성 — 심층 인터뷰를 통해 아이디어를 구체화 (담당: PAI > Design)',\n '',\n '## 다음 단계',\n '- [ ] Ideation 기반 PRD 작성 — 심층 인터뷰로 맥락/기술 제약 보강',\n '- [ ] 하네스 엔지니어링 구성 확인 — 에이전트 작업 환경 검증',\n '- [ ] AI 코드 생성 시작',\n '',\n '## 완료',\n `- [x] 프로젝트 초기화 (${now}) (담당: PAI > Environment)`,\n '',\n '## 작업 파이프라인',\n '```',\n '1. /pai design → Ideation 심층 인터뷰 → docs/ideation.md 생성',\n '2. /pai design → PRD 심층 인터뷰 → docs/openspec.md 작성',\n '3. /pai design → 기술 제약 심층 인터뷰 → 하네스 엔지니어링 확인',\n '4. AI 코드 생성 → 검증 → 평가',\n '```',\n '',\n '## 메모',\n `- 모드: ${ctx.mode}`,\n '- 컨텍스트가 부족하면 AI가 자동으로 심층 인터뷰를 진행합니다',\n ].join('\\n') + '\\n');\n }\n\n // CONTRIBUTING.md 생성\n const contribPath = join(ctx.cwd, 'CONTRIBUTING.md');\n if (!(await fs.pathExists(contribPath))) {\n await fs.writeFile(contribPath, [\n `# Contributing to ${ctx.projectName}`,\n '',\n '이 프로젝트에 기여해 주셔서 감사합니다.',\n '',\n '## 개발 환경 설정',\n '',\n '```bash',\n 'git clone <repo-url>',\n 'cd ' + ctx.projectName,\n 'npm install',\n '```',\n '',\n '## 브랜치 규칙',\n '',\n '- `main` — 안정 버전',\n '- `feat/<기능명>` — 새 기능 개발',\n '- `fix/<이슈번호>` — 버그 수정',\n '',\n '## 커밋 메시지',\n '',\n '```',\n 'feat: 새 기능 추가',\n 'fix: 버그 수정',\n 'docs: 문서 수정',\n 'refactor: 리팩토링',\n 'test: 테스트 추가/수정',\n '```',\n '',\n '## PR 프로세스',\n '',\n '1. 브랜치 생성 → 작업 → 커밋',\n '2. `npm test` 로 테스트 통과 확인',\n '3. PR 생성 — 변경 사항 요약 작성',\n '4. 리뷰 후 머지',\n '',\n '## AI 협업 규칙',\n '',\n '- `CLAUDE.md` 를 읽고 프로젝트 컨텍스트를 파악하세요',\n '- `/pai evaluate` 로 AI 준비도를 확인하세요',\n '- 컨텍스트가 부족하면 추측하지 말고 질문하세요',\n '',\n ].join('\\n') + '\\n');\n }\n\n // CONTRIBUTING 스킬 등록\n const contribSkillDir = join(ctx.cwd, '.claude', 'skills');\n await fs.ensureDir(contribSkillDir);\n const contribSkillPath = join(contribSkillDir, 'contributing.md');\n if (!(await fs.pathExists(contribSkillPath))) {\n await fs.writeFile(contribSkillPath, [\n '---',\n 'name: contributing',\n 'description: \"기여자 가이드 — 브랜치 규칙, 커밋 메시지, PR 프로세스 자동 적용\"',\n '---',\n '',\n '# Contributing Guide',\n '',\n '프로젝트 기여 시 `CONTRIBUTING.md`의 규칙을 자동으로 적용합니다.',\n '',\n '## 자동 적용 규칙',\n '',\n '1. **브랜치**: `feat/`, `fix/`, `docs/`, `refactor/`, `test/` 접두사 사용',\n '2. **커밋**: `feat:`, `fix:`, `docs:`, `refactor:`, `test:` 형식',\n '3. **PR**: 변경 사항 요약 필수',\n '4. **테스트**: PR 전 `npm test` 통과 필수',\n '',\n '## 작업 시 확인',\n '',\n '- `CONTRIBUTING.md` 를 읽고 규칙을 따르세요',\n '- 커밋 메시지가 규칙에 맞는지 확인하세요',\n '- PR 생성 시 변경 사항을 요약하세요',\n '',\n ].join('\\n') + '\\n');\n }\n\n const gitignorePath = join(ctx.cwd, '.gitignore');\n if (!(await fs.pathExists(gitignorePath))) {\n await fs.writeFile(gitignorePath, [\n '# Dependencies',\n 'node_modules/',\n '',\n '# Environment',\n '.env',\n '.env.local',\n '.env*.local',\n '',\n '# Build',\n 'dist/',\n 'build/',\n '.next/',\n 'out/',\n '',\n '# Services',\n '.vercel',\n '.supabase',\n '',\n '# OS',\n '.DS_Store',\n 'Thumbs.db',\n '',\n '# IDE',\n '.idea/',\n '.vscode/settings.json',\n '*.swp',\n '*.swo',\n '',\n '# PAI / OMC state',\n '.omc/state/',\n '.omc/sessions/',\n '.omc/logs/',\n '',\n '# Logs',\n '*.log',\n 'npm-debug.log*',\n '',\n '# Windows',\n 'desktop.ini',\n '$RECYCLE.BIN/',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionVercel(ctx: ProvisionerContext): Promise<void> {\n const vercelJson = join(ctx.cwd, 'vercel.json');\n if (!(await fs.pathExists(vercelJson))) {\n await fs.writeJson(vercelJson, {\n version: 2, name: ctx.projectName,\n builds: [{ src: 'src/**', use: '@vercel/static' }],\n }, { spaces: 2 });\n }\n}\n\nasync function provisionSupabase(ctx: ProvisionerContext): Promise<void> {\n const supabaseDir = join(ctx.cwd, 'supabase');\n await fs.ensureDir(supabaseDir);\n const configToml = join(supabaseDir, 'config.toml');\n if (!(await fs.pathExists(configToml))) {\n await fs.writeFile(configToml, '[api]\\nschemas = [\"public\"]\\n[auth]\\nsite_url = \"http://localhost:3000\"\\n');\n }\n ctx.envEntries['NEXT_PUBLIC_SUPABASE_URL'] = 'YOUR_SUPABASE_URL';\n ctx.envEntries['NEXT_PUBLIC_SUPABASE_ANON_KEY'] = 'YOUR_SUPABASE_ANON_KEY';\n}\n\nasync function provisionOpenSpec(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, 'docs'));\n const openspecPath = join(ctx.cwd, 'docs', 'openspec.md');\n if (!(await fs.pathExists(openspecPath))) {\n await fs.writeFile(openspecPath, [\n `# OpenSpec — ${ctx.projectName}`,\n '', '## 1. 목적 (Purpose)', '> 이 서비스는 무엇을 해결하는가?',\n '', '## 2. 사용자 (Users)', '| 역할 | 설명 |', '|------|------|', '| - | - |',\n '', '## 3. 핵심 기능 (Features)', '- [ ] Feature 1',\n '', '## 4. 기술 스택 (Stack)', '- Frontend:', '- Backend:', '- DB:',\n '', '## 5. API 엔드포인트 (Endpoints)',\n '| Method | Path | 설명 |', '|--------|------|------|', '| GET | /api/health | 헬스체크 |',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionOMC(ctx: ProvisionerContext): Promise<void> {\n // 1. 도메인 객체 모델 템플릿 (PAI 관리 영역)\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n const omcPath = join(ctx.cwd, '.pai', 'omc.md');\n if (!(await fs.pathExists(omcPath))) {\n await fs.writeFile(omcPath, [\n `# OMC — Object Model Context (${ctx.projectName})`,\n '', '> AI가 이 프로젝트의 도메인을 이해하기 위한 핵심 객체 모델',\n '', '## 도메인 객체', '', '### User', '```', 'id: string',\n 'email: string', 'role: \"admin\" | \"member\"', '```',\n '', '## 비즈니스 규칙', '- (여기에 핵심 비즈니스 로직을 기술)',\n ].join('\\n') + '\\n');\n }\n\n // 2. OMC(oh-my-claudecode) 런타임 상태 디렉토리 스캐폴드\n // Claude Code + OMC 플러그인이 세부 파일을 채움.\n const omcDir = join(ctx.cwd, '.omc');\n await fs.ensureDir(omcDir);\n await fs.ensureDir(join(omcDir, 'state'));\n await fs.ensureDir(join(omcDir, 'sessions'));\n await fs.ensureDir(join(omcDir, 'logs'));\n\n const omcReadme = join(omcDir, 'README.md');\n if (!(await fs.pathExists(omcReadme))) {\n await fs.writeFile(omcReadme, [\n '# .omc/ — OMC 런타임 디렉토리',\n '',\n '이 폴더는 OMC(oh-my-claudecode)가 Claude Code 실행 중 사용하는',\n '상태/세션/로그 데이터를 저장합니다.',\n '',\n '- `state/` — 에이전트 실행 상태',\n '- `sessions/` — 세션 기록',\n '- `logs/` — 실행 로그',\n '',\n '각 하위 경로는 `.gitignore`에 포함되어 있습니다. (상위 디렉토리와',\n '이 README는 추적됨)',\n '',\n '## 참고',\n '',\n '- OMC 저장소: https://github.com/SoInKyu/oh-my-claudecode',\n '- 자동 설치: Claude Code 기동 시 `~/.claude/settings.json` 등록에',\n ' 따라 플러그인이 자동 로드됩니다.',\n '',\n ].join('\\n') + '\\n');\n }\n}\n\nasync function provisionGstack(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n await fs.writeJson(join(ctx.cwd, '.pai', 'gstack.json'), {\n version: '1.0', testRunner: 'jest',\n coverageThreshold: { global: { lines: 80 } },\n qualityGates: ['lint', 'typecheck', 'test'],\n }, { spaces: 2 });\n}\n\nasync function provisionRoboco(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n const robocoPath = join(ctx.cwd, '.pai', 'roboco.json');\n if (await fs.pathExists(robocoPath)) return;\n await fs.writeJson(robocoPath, {\n version: '1.0',\n checks: ['github', 'vercel', 'supabase', 'openspec', 'omc'],\n reportOutput: 'AI_READINESS_REPORT.md',\n note: 'PAI Zero에 내재화됨. `pai evaluate`로 진단 가능.',\n }, { spaces: 2 });\n}\n\nasync function provisionHarness(ctx: ProvisionerContext): Promise<void> {\n await fs.ensureDir(join(ctx.cwd, '.pai'));\n await fs.writeJson(join(ctx.cwd, '.pai', 'harness.json'), {\n version: '1.0', specFile: 'docs/openspec.md',\n checkOn: ['pre-commit', 'ci'],\n rules: ['spec-implementation-match', 'api-contract-test'],\n }, { spaces: 2 });\n}\n\nasync function provisionMcpWrapper(ctx: ProvisionerContext): Promise<void> {\n const { provisionMcp } = await import('./mcp.js');\n await provisionMcp(ctx);\n}\n\nexport const PROVISIONERS: Record<string, Provisioner> = {\n github: provisionGitHub,\n vercel: provisionVercel,\n supabase: provisionSupabase,\n openspec: provisionOpenSpec,\n omc: provisionOMC,\n gstack: provisionGstack,\n roboco: provisionRoboco,\n harness: provisionHarness,\n mcp: provisionMcpWrapper,\n};\n\nexport async function runProvisioners(\n keys: string[],\n ctx: ProvisionerContext,\n): Promise<Array<{ key: string; success: boolean; error?: string }>> {\n const results: Array<{ key: string; success: boolean; error?: string }> = [];\n\n for (const key of keys) {\n const provisioner = PROVISIONERS[key];\n if (!provisioner) {\n results.push({ key, success: false, error: 'unknown' });\n continue;\n }\n try {\n await provisioner(ctx);\n results.push({ key, success: true });\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n results.push({ key, success: false, error: msg });\n }\n }\n\n if (Object.keys(ctx.envEntries).length > 0) {\n writeEnvFile(join(ctx.cwd, '.env.local'), ctx.envEntries);\n }\n\n return results;\n}\n","/**\n * Claude Code 스킬/커맨드 프로비저너\n * 프로젝트의 .claude/ 디렉토리에 PAI 슬래시 커맨드를 설치\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../../ui/index.js';\n\nconst SKILL_CONTENT = `---\nname: pai\ndescription: \"PAI(Plugin-based AI) 빌드 오케스트레이터 — AI 개발을 5단계 파이프라인으로 구조화\"\nargument-hint: \"[init|help|status|check|design|test|grade|add|handoff|savetoken|wakeup]\"\n---\n\n# PAI — Plugin-based AI 빌드 오케스트레이터\n\n사용자가 \\`/pai\\` 또는 \\`/pai <명령>\\`을 입력하면 아래 프로세스를 수행하세요.\n\n## 명령어 라우팅 (v0.11+)\n\n사용자의 입력에 따라 적절한 작업을 수행하세요:\n\n- \\`/pai\\` 또는 \\`/pai help\\` → **안내 모드**: 명령어 목록, 파이프라인 설명, 시작 가이드 표시\n- \\`/pai init\\` → **초기화 모드**: 프로젝트 분석 → 사용자 인터뷰 → 파일 생성\n- \\`/pai status\\` → **상태 확인**: 플러그인 설치 상태 스캔 및 보고\n- \\`/pai check\\` → **환경 점검**: Node.js, Git, Claude Code 환경 점검\n- \\`/pai design\\` → **설계 관리**: OpenSpec/OMC 템플릿 생성 + PRD 완성도 검증\n- \\`/pai test\\` → **테스트·검증**: 테스트 실행 + 하네스(설계↔구현) 검증\n- \\`/pai grade\\` → **품질 평가**: 6카테고리 가중 점수 평가\n- \\`/pai add\\` → **플러그인 추가**: Mockup → Production 확장\n- \\`/pai savetoken\\` → **토큰 절감**: AI API 호출 분석 + 스크립트 대체 + 절감 리포트\n- \\`/pai wakeup\\` → **웨이크업**: Claude Code 세션 자동 시작 + 토큰 윈도우 리셋\n\n### 구 명령어 호환 (v0.13 까지 유지)\n\n\\`/pai info\\` → help, \\`/pai doctor\\` → check, \\`/pai validate\\` → test, \\`/pai evaluate\\` → grade, \\`/pai install\\` → add\n\n각 명령의 상세 지침은 \\`.claude/commands/pai/\\` 디렉토리에 있습니다.\n해당 파일을 읽고 지시에 따라 수행하세요.\n\n## 파이프라인 5단계\n\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n## 핵심 원칙\n\n1. **이미 존재하는 파일은 덮어쓰지 않음** — 건너뛰고 안내\n2. **컨텍스트 격리** — 각 파이프라인 단계는 독립적으로 수행\n3. **사용자 친화적** — 결과를 명확히 보고하고 다음 단계를 안내\n4. **PRD 시작 가능 상태가 목표** — 설치 후 \\`docs/openspec.md\\`로 안내\n\n## 품질 평가 기준 (evaluate)\n\n| 카테고리 | 분류 | 가중치 |\n|---------|------|--------|\n| 테스트 커버리지 | 필수 | 20% |\n| CI/CD | 필수 | 20% |\n| 훅 기반 검증 | 필수 | 20% |\n| 리포지토리 구조 | 선택 | 13.3% |\n| 문서화 수준 | 선택 | 13.3% |\n| 하네스 엔지니어링 | 선택 | 13.4% |\n\n등급: A(90+), B(80+), C(70+), D(50+), F(<50)\n페널티: 필수 카테고리 F등급 시 전체 등급 최대 C로 제한\n`;\n\nconst COMMANDS: Record<string, string> = {\n 'info.md': `---\nname: \"PAI: Info\"\ndescription: \"PAI 안내 — 명령어, 파이프라인, 핵심 파일 설명\"\n---\n\n# PAI 안내\n\n사용자에게 PAI(Plugin-based AI) 시스템을 안내합니다.\n\n## 수행할 작업\n\n아래 내용을 읽기 쉽게 사용자에게 설명하세요:\n\n### PAI란?\nPAI는 AI 개발을 5단계 파이프라인으로 구조화하는 빌드 오케스트레이터입니다.\n\n### 파이프라인 5단계\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n### 사용 가능한 명령어\n| 명령어 | 설명 | 사용 시점 |\n|--------|------|----------|\n| \\`/pai info\\` | PAI 안내 | PAI가 뭔지 알고 싶을 때 |\n| \\`/pai init\\` | 프로젝트 초기화 | 새 프로젝트 시작 시 |\n| \\`/pai status\\` | 상태 확인 | 설치 상태 점검 시 |\n| \\`/pai doctor\\` | 환경 진단 | 환경 문제 점검 시 |\n| \\`/pai design\\` | PRD/OMC 생성 | 설계 문서 관리 시 |\n| \\`/pai validate\\` | 테스트/검증 | 코드 작성 후 |\n| \\`/pai evaluate\\` | 품질 평가 | 준비도 평가 시 |\n| \\`/pai install\\` | 플러그인 추가 | Production 확장 시 |\n\n### 추천 시작 순서\n1. **처음이라면** → \\`/pai init\\`\n2. **PRD 작성** → \\`/pai design\\`\n3. **코드 작성 후** → \\`/pai validate\\`\n4. **품질 점검** → \\`/pai evaluate\\`\n`,\n\n 'init.md': `---\nname: \"PAI: Init\"\ndescription: \"프로젝트 초기화 — 분석, 인터뷰, 환경 파일 생성\"\n---\n\n# PAI 프로젝트 초기화\n\n이 프로젝트에 PAI(Plugin-based AI) 환경을 구축합니다.\n\n## 수행할 작업\n\n### 1단계: 프로젝트 분석\n현재 작업 디렉토리를 분석하세요:\n- \\`package.json\\` 존재 여부 → 언어/프레임워크 감지\n- \\`tsconfig.json\\` → TypeScript 여부\n- \\`.git\\` → Git 초기화 여부\n- \\`.pai/config.json\\` → 이미 PAI 초기화된 프로젝트인지 (있으면 \\`/pai status\\` 안내)\n\n분석 결과를 사용자에게 요약해 주세요.\n\n### 2단계: 사용자 인터뷰\n사용자에게 다음을 질문하세요:\n1. **프로젝트명** (현재 폴더명을 기본값으로 제안)\n2. **프로젝트 목적**: Mockup(프로토타입) vs Production(실서비스)\n3. **인증 방식** (필요 시): Google/Naver/Kakao OAuth2, 사내 인증, 없음\n\n### 3단계: 파일 생성\n사용자 답변에 따라 다음 파일을 생성하세요:\n\n**필수 (Mockup + Production):**\n- \\`docs/openspec.md\\` — PRD 템플릿 (목적/사용자/기능/스택/API)\n- \\`.pai/omc.md\\` — 도메인 객체 모델 템플릿\n- \\`.pai/config.json\\` — PAI 설정\n- \\`CLAUDE.md\\` — AI 컨텍스트\n- \\`.gitignore\\`, \\`src/\\`, \\`docs/\\`, \\`tests/\\` 디렉토리\n\n**Production 추가:**\n- \\`.pai/gstack.json\\` — QA 설정 (커버리지 80%)\n- \\`.pai/harness.json\\` — 검증 설정\n\n### 4단계: 완료 안내\n> 다음 단계: \\`docs/openspec.md\\`를 열어 PRD를 작성하세요.\n> PRD 작성 후: \\`/pai design validate\\`로 완성도를 검증할 수 있습니다.\n\n### 주의사항\n- **이미 존재하는 파일은 덮어쓰지 마세요**\n- **CLAUDE.md가 이미 있으면** \\`<pai>\\` 블록만 추가\n`,\n\n 'status.md': `---\nname: \"PAI: Status\"\ndescription: \"현재 프로젝트의 PAI 플러그인 설치 상태 확인\"\n---\n\n# PAI 프로젝트 상태 확인\n\n## 수행할 작업\n\n다음 파일/디렉토리 존재 여부를 확인하고 상태를 보고하세요:\n\n| 확인 경로 | 플러그인 |\n|-----------|---------|\n| \\`.git\\` 또는 \\`.github\\` | GitHub |\n| \\`vercel.json\\` | Vercel |\n| \\`supabase/\\` | Supabase |\n| \\`docs/openspec.md\\` | OpenSpec |\n| \\`.pai/omc.md\\` | OMC |\n| \\`.pai/gstack.json\\` | gstack |\n| \\`.pai/harness.json\\` | Harness |\n| \\`CLAUDE.md\\` | AI 컨텍스트 |\n| \\`.claude/settings.json\\` | AI 설정 |\n| \\`.pai/config.json\\` | PAI Core |\n\n\\`package.json\\`에서 스택도 감지하세요.\n\n보고 형식:\n\\`\\`\\`\n프로젝트 상태\n─────────────\n스택: TypeScript, React\n모드: production\n\n ✅ GitHub — 설치됨\n ✅ OpenSpec — 설치됨\n ⚠️ gstack — 미설치\n\\`\\`\\`\n`,\n\n 'doctor.md': `---\nname: \"PAI: Doctor\"\ndescription: \"개발 환경 진단 — Node.js, Git, Claude Code 점검\"\n---\n\n# PAI 환경 진단\n\n## 수행할 작업\n\n다음 항목을 점검하세요:\n\n1. **Node.js 버전**: \\`node --version\\` (v20 이상 필요)\n2. **패키지 매니저**: \\`npm --version\\`\n3. **Git 상태**: \\`git --version\\`, \\`git remote -v\\`\n4. **Claude Code 파일**: CLAUDE.md, .claude/settings.json, .claude/skills/ 존재 여부\n5. **PAI 설정**: .pai/config.json 내용 확인\n\n보고 형식:\n\\`\\`\\`\nPAI Doctor — 환경 진단\n══════════════════════\n ✅ Node.js v20.11.0 (>=20 OK)\n ✅ Git 2.43.0\n ⚠️ .claude/settings.json 없음\n → /pai init 으로 생성하세요\n\\`\\`\\`\n`,\n\n 'design.md': `---\nname: \"PAI: Design\"\ndescription: \"Ideation → PRD → 하네스 구성까지 심층 인터뷰 기반 설계\"\n---\n\n# PAI 설계 — 심층 인터뷰 기반 파이프라인\n\n## 인자: $ARGUMENTS\n- 인자 없음 → 전체 파이프라인 (Ideation → PRD → 하네스)\n- \\`ideation\\` → Ideation만 수행\n- \\`prd\\` → PRD만 수행\n- \\`validate\\` → 검증만 수행\n\n## Phase 1: Ideation (아이디어 구체화)\n\n**목표**: 사용자의 머릿속 아이디어를 \\`docs/ideation.md\\`로 구체화\n\nAskUserQuestion 도구로 심층 인터뷰를 진행하세요:\n1. \"어떤 문제를 해결하고 싶으세요?\" — 핵심 과제 파악\n2. \"이 서비스를 주로 사용할 사람은 누구인가요?\" — 대상 사용자\n3. \"비슷한 서비스가 있다면 뭐가 다른가요?\" — 차별점\n4. \"반드시 있어야 할 기능 3가지는?\" — 핵심 기능\n5. \"언제까지 만들고 싶으세요?\" — 일정 제약\n\n답변을 종합하여 \\`docs/ideation.md\\`를 생성하세요.\n\n## Phase 2: PRD 작성 (제품 요구사항)\n\n**목표**: Ideation을 기반으로 \\`docs/openspec.md\\` PRD 작성\n\n\\`docs/ideation.md\\`를 읽고, 부족한 맥락은 AskUserQuestion으로 보강:\n1. \"기술 스택 선호가 있으세요?\" — 프레임워크/언어 제약\n2. \"외부 API 연동이 필요한가요?\" — 의존성 파악\n3. \"데이터는 어떤 것을 저장해야 하나요?\" — DB 스키마 힌트\n4. \"로그인/회원가입이 필요한가요?\" — 인증 범위\n\n답변을 종합하여 \\`docs/openspec.md\\` 5개 섹션을 작성:\n- 목적 (Purpose)\n- 사용자 (Users)\n- 핵심 기능 (Features)\n- 기술 스택 (Stack)\n- API 엔드포인트\n\n## Phase 2.5: MCP 서버 설계 (MCP 프로젝트만)\n\n\\\\\\`.pai/config.json\\\\\\`의 \\\\\\`mcp.enabled\\\\\\`가 true이면 이 Phase를 수행하세요:\n\n1. \\\\\\`docs/openspec.md\\\\\\`의 \"## MCP 서버\" 섹션을 찾아 현재 정의된 도구/리소스/프롬프트 목록 확인\n2. TODO로 채워진 항목이 있으면 AskUserQuestion으로 심층 인터뷰:\n\n **Tools 서버 (tools / tools-public / all)**:\n - \"이 MCP 서버에서 제공할 도구 이름과 기능은?\"\n - \"각 도구의 입력 파라미터(JSON Schema)는?\"\n - \"출력 형식(text/json/image)은?\"\n - \"내부 로직은 어디에 구현? (src/lib/ 또는 외부 API 호출?)\"\n\n **Resources 서버 (resources / all)**:\n - \"AI에게 제공할 컨텍스트는 무엇인가요?\"\n - \"각 리소스의 URI 스키마(예: \\\\\\`wiki://pages/\\\\\\`)는?\"\n - \"MIME 타입(text/plain, application/json)은?\"\n\n **Prompts 서버 (prompts / all)**:\n - \"재사용 프롬프트 이름과 용도는?\"\n - \"각 프롬프트에 필요한 인자는?\"\n\n3. 답변을 종합하여 \\\\\\`openspec.md\\\\\\`의 MCP 섹션 테이블을 채웁니다.\n\n4. **공개 배포(tools-public)**인 경우 추가 질문:\n - \"시간당 레이트 리밋을 변경할까요? (기본 100회/시간)\"\n - \"각 도구별 비용이 다르게 설계되나요?\"\n - \"대시보드에서 사용자에게 표시할 무료 한도는?\"\n\n5. MCP 서버의 \\\\\\`src/tools.ts\\\\\\`, \\\\\\`src/resources.ts\\\\\\` 등에 설계된 도구를 구현하도록 사용자에게 안내하세요.\n\n## Phase 3: 기술 제약 + 하네스 엔지니어링\n\n**목표**: AI 에이전트가 안전하게 작업할 수 있는 환경 확인\n\nAskUserQuestion으로 기술적 제약 파악:\n1. \"기존에 사용 중인 DB나 서버가 있나요?\" — 기존 인프라\n2. \"배포 환경은 어디인가요?\" — 배포 제약\n3. \"팀에서 사용하는 코딩 규칙이 있나요?\" — 스타일 제약\n\n하네스 엔지니어링 확인:\n- \\`CLAUDE.md\\` — AI 컨텍스트 충분한지 검증\n- \\`.claude/settings.json\\` — 권한 설정 적절한지 확인\n- 테스트 환경 — \\`tests/\\` 디렉토리 + 테스트 프레임워크 존재 확인\n- 부족한 항목은 자동 생성 제안\n\n## Phase 4: 검증\n\n모든 Phase 완료 후:\n1. \\`docs/ideation.md\\` 존재 + 내용 확인\n2. \\`docs/openspec.md\\` 5개 섹션 완성도 검증\n3. \\`handoff.md\\` 업데이트 — 완료된 항목 체크, 다음 단계 갱신\n\n## 중요 원칙\n\n- **추측 금지**: 컨텍스트가 부족하면 반드시 AskUserQuestion으로 질문\n- **이미 존재하는 파일 덮어쓰지 않음** — 보강만 제안\n- **각 Phase 완료 시 사용자에게 결과 요약** 보고\n`,\n\n 'validate.md': `---\nname: \"PAI: Validate\"\ndescription: \"테스트 실행 + 하네스(설계↔구현 일치) 검증\"\n---\n\n# PAI 검증\n\n## 수행할 작업\n\n### 1. 테스트 실행\n\\`\\`\\`bash\nnpm test\n\\`\\`\\`\n결과를 보고하고, 실패 시 원인 설명 + 수정 제안.\n\n### 2. 하네스 검증\n\\`.pai/harness.json\\`이 있으면:\n- \\`docs/openspec.md\\`의 API 엔드포인트가 \\`src/\\`에 구현되어 있는지 검증\n- 테스트 디렉토리 존재 여부 확인\n\n없으면: \"Harness 미설정 — \\`/pai install\\`에서 추가 가능\" 안내\n`,\n\n 'evaluate.md': `---\nname: \"PAI: Evaluate\"\ndescription: \"6카테고리 가중 점수 기반 AI 개발 준비도 평가\"\n---\n\n# PAI 품질 평가\n\n## 수행할 작업\n\n6카테고리별로 파일 존재 여부와 설정 품질을 확인하고 0~100점으로 채점하세요.\n\n### [필수] 1. 테스트 커버리지 (20%)\n테스트 프레임워크 설정, 테스트 디렉토리, 커버리지 설정 확인\n\n### [필수] 2. CI/CD (20%)\n.github/workflows, .gitlab-ci.yml 등 파이프라인 설정 확인\n\n### [필수] 3. 훅 기반 검증 (20%)\n.husky, lint-staged, .claude/settings.json 훅 확인\n\n### [선택] 4. 리포지토리 구조 (13.3%)\nsrc/ 조직, 의존성 관리, .gitignore 확인\n\n### [선택] 5. 문서화 수준 (13.3%)\nREADME.md, CONTRIBUTING.md, docs/ 확인\n\n### [선택] 6. 하네스 엔지니어링 (13.4%)\nCLAUDE.md, AGENTS.md, .claude/ 설정 확인\n\n### 점수 계산\n종합 점수 = 가중 평균, 등급: A(90+) B(80+) C(70+) D(50+) F(<50)\n**페널티**: 필수 카테고리 F시 전체 최대 C\n\n각 카테고리별 개선 권고사항을 구체적으로 제시하세요.\n`,\n\n 'install.md': `---\nname: \"PAI: Install\"\ndescription: \"플러그인 추가 설치 — Mockup에서 Production 확장\"\n---\n\n# PAI 플러그인 추가 설치\n\n## 수행할 작업\n\n### 1. 현재 설치 상태 확인\n파일 존재 여부로 이미 설치된 플러그인을 파악하세요.\n\n### 2. 미설치 항목 안내\n이미 설치된 항목은 \\`(이미 설치됨)\\`으로, 미설치 항목만 선택 가능하게 안내하세요.\n\n### 3. 사용자 선택에 따라 파일 생성\n- **Vercel**: vercel.json\n- **Supabase**: supabase/config.toml + .env.local 키\n- **gstack**: .pai/gstack.json\n- **Harness**: .pai/harness.json\n\n### 4. .pai/config.json 업데이트\nplugins 배열에 새 플러그인 추가\n\n### 주의: 이미 존재하는 파일은 덮어쓰지 않음\n`,\n\n 'handoff.md': `---\nname: \"PAI: Handoff\"\ndescription: \"Task 현황 확인 및 handoff.md 관리\"\n---\n\n# PAI Handoff — Task 관리\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Handoff Manager\n 담당: handoff.md Task 기록/관리\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n### handoff.md 확인\n\\\\\\`handoff.md\\\\\\`를 읽고 현황을 보고하세요. 없으면 템플릿으로 생성하세요.\n\n### 현황 보기\n진행 중, 다음 단계, 완료 항목을 정리해서 보여주세요.\n\n### Task 추가\n사용자 요청 시 적절한 PAI Stage를 담당자로 지정하여 추가하세요.\n- PRD/설계 → PAI > Design\n- 코드 → PAI > Execution\n- 테스트 → PAI > Validation\n- 품질 → PAI > Evaluation\n- 환경 → PAI > Environment\n\n### Task 완료\n완료 섹션으로 이동하고 날짜를 기록하세요.\n`,\n\n 'vibe-ready.md': `---\nname: \"PAI: Vibe Ready\"\ndescription: \"바이브 코딩 준비도 측정 — 6카테고리 평가 + docs/p-reports/ 자동 저장\"\n---\n\n# PAI 바이브 코딩 준비도\n\n프로젝트의 바이브 코딩 준비 상태를 6카테고리로 분석하고, 상세 리포트를 자동 생성합니다.\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Evaluation Stage\n 담당: scorer (6카테고리 가중 평가)\n 출력: docs/p-reports/YYYY-MM-DD.md\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n\\\\\\`/pai evaluate\\\\\\` 와 동일하게 6카테고리를 평가하세요.\n평가가 끝나면 \\\\\\`docs/p-reports/\\\\\\` 폴더에 오늘 날짜(YYYY-MM-DD.md)로 상세 리포트를 저장하세요.\n`,\n\n 'upgrade.md': `---\nname: \"PAI: Upgrade\"\ndescription: \"PAI 슬래시 커맨드 & 스킬을 최신 버전으로 업그레이드\"\n---\n\n# PAI 업그레이드\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Environment Stage\n 담당: upgrade (시스템 파일 갱신)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n터미널에서 다음 명령을 실행하세요:\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero upgrade\n\\\\\\`\\\\\\`\\\\\\`\n\n강제 업그레이드 (이미 최신이어도):\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero upgrade --force\n\\\\\\`\\\\\\`\\\\\\`\n\n### 주의사항\n- 슬래시 커맨드와 SKILL.md는 최신으로 덮어씁니다.\n- 프로젝트 파일(openspec.md, omc.md, CLAUDE.md)은 건드리지 않습니다.\n`,\n\n 'savetoken.md': `---\nname: \"PAI: SaveToken\"\ndescription: \"AI 토큰 절감 분석 — API 호출 스캔, 대체 코드 생성, 절감 리포트\"\n---\n\n# PAI SaveToken — AI 토큰 절감 분석\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n💰 PAI > SaveToken\n 담당: savetoken (토큰 절감 분석)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 수행할 작업\n\n### Phase 1: 스캔\n\n1. 먼저 CLI 스캔 리포트가 있는지 확인하세요:\n \\\\\\`\\\\\\`\\\\\\`bash\n cat .pai/savetoken-report.md 2>/dev/null\n \\\\\\`\\\\\\`\\\\\\`\n 없으면 먼저 실행: \\\\\\`npx pai-zero savetoken\\\\\\`\n\n2. 프로젝트 전체에서 아래 패턴을 검색하세요:\n - AI SDK 임포트: \\\\\\`@anthropic-ai/sdk\\\\\\`, \\\\\\`openai\\\\\\`, \\\\\\`@google/generative-ai\\\\\\`, \\\\\\`langchain\\\\\\`\n - API 호출: \\\\\\`messages.create\\\\\\`, \\\\\\`chat.completions.create\\\\\\`, \\\\\\`generateContent\\\\\\`\n - Fetch: \\\\\\`api.anthropic.com\\\\\\`, \\\\\\`api.openai.com\\\\\\`\n\n### Phase 2: 각 호출 심층 분석\n\n발견된 각 API 호출에 대해:\n\n1. **목적 파악**: 이 호출이 무엇을 하는지 분석\n2. **프롬프트 분석**: 시스템 프롬프트와 사용자 프롬프트 내용 확인\n3. **입출력 패턴**: 입력 데이터 형태와 기대 출력 형태 파악\n4. **대체 가능성 판단**: 아래 기준으로 분류\n\n### Phase 3: 영향도 분류 및 대체 전략\n\n#### 🟢 영향도 낮음 — 즉시 대체 가능 (예상 절감: 해당 호출 100%)\n- 텍스트 포맷팅/변환 → \\\\\\`regex\\\\\\`, \\\\\\`string.replace()\\\\\\`\n- 데이터 유효성 검증 → \\\\\\`zod\\\\\\`, \\\\\\`joi\\\\\\`, JSON schema\n- 템플릿 기반 생성 → \\\\\\`handlebars\\\\\\`, 문자열 템플릿\n- 고정 카테고리 분류 → \\\\\\`switch-case\\\\\\`, lookup table\n- 설정 파일 생성 → 템플릿 + 변수 치환\n\n**대체 코드를 직접 작성**하여 \\\\\\`.pai/savetoken/\\\\\\` 디렉토리에 저장하세요.\n\n#### 🟡 영향도 중간 — 검토 후 대체 (예상 절감: 해당 호출 50-80%)\n- 텍스트 요약 → extractive 방식 (키워드 빈도 기반)\n- 간단한 분류 → TF-IDF, 키워드 매칭, 규칙 기반\n- 구조화된 데이터 추출 → regex, AST parser\n- 반복적 번역 → i18n 파일 + 사전\n\n**대체 로직의 의사코드**를 작성하고 구현 난이도를 평가하세요.\n\n#### 🔴 영향도 높음 — AI 필수 (프롬프트 최적화로 절감)\n- 코드 생성/리팩토링 → 프롬프트 캐싱, few-shot 최적화\n- 복잡한 추론/분석 → 프롬프트 압축, 컨텍스트 정리\n- 창의적 콘텐츠 생성 → 프롬프트 재설계\n- 멀티턴 대화 → 턴 수 최소화\n\n**프롬프트 최적화 방안**을 제시하세요.\n\n### Phase 4: 리포트 생성\n\n\\\\\\`.pai/savetoken/\\\\\\` 디렉토리에 다음을 저장:\n\n1. \\\\\\`analysis.md\\\\\\` — 전체 분석 리포트\n - 호출별 목적, 영향도, 대체 전략\n - 총 예상 절감률 (%)\n - 단계별 추진 로드맵\n2. \\\\\\`replacements/\\\\\\` — 대체 코드 파일들 (영향도 낮음)\n3. \\\\\\`optimizations.md\\\\\\` — 프롬프트 최적화 제안 (영향도 높음)\n\n## 리포트 형식\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# SaveToken 분석 결과\n\n## 요약\n- 총 API 호출: N건\n- 대체 가능: M건 (영향도 낮음 X건, 중간 Y건)\n- AI 필수: Z건\n- **예상 토큰 절감: ~XX%**\n\n## 단계별 추진 전략\n\n### 1단계: 즉시 적용 (영향도 낮음)\n영향도, 파일, 현재 방식, 대체 방식, 예상 절감\n\n### 2단계: 검토 후 적용 (영향도 중간)\n...\n\n### 3단계: 프롬프트 최적화 (영향도 높음)\n...\n\\\\\\`\\\\\\`\\\\\\`\n\n## 주의사항\n- 대체 코드는 기존 입출력 인터페이스를 유지해야 합니다\n- 영향도 중간 이상은 반드시 테스트와 함께 적용하세요\n- AI 호출이 필수인 경우, 프롬프트 캐싱(prompt caching)이 가장 효과적입니다\n`,\n\n 'wakeup.md': `---\nname: \"PAI: Wakeup\"\ndescription: \"매일 아침 영감 메시지 스케줄 설정\"\n---\n\n# PAI Wakeup\n\n매일 아침 영감을 주는 메시지를 스케줄링합니다.\n\n## 담당자 표시 (반드시 출력)\n\n\\\\\\`\\\\\\`\\\\\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n☀️ PAI > Wakeup\n 담당: wakeup (영감 메시지)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\\\\\`\\\\\\`\\\\\\`\n\n## 사용법\n\n터미널에서 실행:\n\\\\\\`\\\\\\`\\\\\\`bash\nnpx pai-zero wakeup 06:00 # 평일 오전 6시 (기본)\nnpx pai-zero wakeup 07:30 매일 # 매일 오전 7시 30분\nnpx pai-zero wakeup 08:00 주말 # 주말 오전 8시\nnpx pai-zero wakeup status # 현재 설정 확인\nnpx pai-zero wakeup off # 해제\nnpx pai-zero wakeup # 지금 랜덤 메시지 보기\n\\\\\\`\\\\\\`\\\\\\`\n\n## 스케줄 옵션\n\n| 옵션 | 설명 | cron |\n|------|------|------|\n| 평일 | 월~금 (기본값) | \\\\\\`* * * * 1-5\\\\\\` |\n| 매일 | 매일 | \\\\\\`* * * * *\\\\\\` |\n| 주말 | 토~일 | \\\\\\`* * * * 0,6\\\\\\` |\n\n## 동작 방식\n\n- 시스템 crontab에 스케줄 등록\n- 지정 시간에 macOS 알림 또는 Linux notify-send 전송\n- \\\\\\`~/.pai/wakeup-today.txt\\\\\\` 에 오늘의 메시지 저장\n`,\n\n // ─────────────────────────────────────────────────────────────\n // v0.11+ 신규 명령어 (구 명령어는 deprecation 경고와 함께 유지)\n // ─────────────────────────────────────────────────────────────\n\n 'help.md': `---\nname: \"PAI: Help\"\ndescription: \"PAI 안내 — 명령어, 파이프라인, 핵심 파일 설명\"\n---\n\n# PAI 안내\n\n사용자에게 PAI(Plugin-based AI) 시스템을 안내합니다.\n\n### PAI란?\nPAI는 AI 개발을 5단계 파이프라인으로 구조화하는 빌드 오케스트레이터입니다.\n\n### 파이프라인 5단계\n\\`\\`\\`\nEnvironment → Design → Execution → Validation → Evaluation\n(환경 구성) (설계) (AI 코드생성) (테스트/검증) (품질 평가)\n\\`\\`\\`\n\n### 사용 가능한 명령어 (v0.11+)\n| 명령어 | 설명 | 사용 시점 |\n|--------|------|----------|\n| \\`/pai help\\` | 이 안내 | PAI가 뭔지 알고 싶을 때 |\n| \\`/pai init\\` | 프로젝트 초기화 | 새 프로젝트 시작 시 |\n| \\`/pai status\\` | 상태 확인 | 설치 플러그인 점검 |\n| \\`/pai check\\` | 환경 점검 | Node/Git/Claude Code 검증 |\n| \\`/pai design\\` | PRD/OMC 생성 | 설계 문서 관리 |\n| \\`/pai test\\` | 테스트·검증 | 코드 작성 후 |\n| \\`/pai grade\\` | 품질 평가 | 준비도 평가 |\n| \\`/pai add\\` | 플러그인 추가 | Production 확장 |\n\n### 구 명령어 (v0.13 까지 유지)\n\\`/pai info → help\\`, \\`/pai doctor → check\\`, \\`/pai validate → test\\`, \\`/pai evaluate → grade\\`, \\`/pai install → add\\`\n\n### 핵심 파일\n- \\`docs/openspec.md\\` — PRD, \\`.pai/omc.md\\` — 도메인 모델, \\`.pai/config.json\\` — PAI 설정, \\`CLAUDE.md\\` — AI 컨텍스트\n`,\n\n 'check.md': `---\nname: \"PAI: Check\"\ndescription: \"개발 환경 점검 — Node.js, Git, Claude Code\"\n---\n\n# PAI 환경 점검\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Environment Stage\n 담당: check (환경 점검)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 점검 항목\n1. **Node.js** — \\`node --version\\` (v20+)\n2. **npm** — \\`npm --version\\`\n3. **Git** — \\`git --version\\` + \\`git remote -v\\`\n4. **Claude Code** — \\`CLAUDE.md\\`, \\`.claude/settings.json\\`, \\`~/.claude/settings.json\\`의 \\`enabledPlugins[\"oh-my-claudecode@omc\"]\\`\n5. **PAI 설정** — \\`.pai/config.json\\`, \\`.pai/omc.md\\`, \\`docs/openspec.md\\`\n\n### Windows 추가 점검\n- \\`Get-ExecutionPolicy\\` → RemoteSigned 이상\n- \\`$env:HOME\\` 또는 \\`$env:USERPROFILE\\` 설정\n- PowerShell 7 권장\n\n### 결과 보고\n각 항목 ✅/⚠️/❌ 표시 + 권장 조치 안내.\n`,\n\n 'test.md': `---\nname: \"PAI: Test\"\ndescription: \"테스트 실행 + 하네스(설계↔구현 일치) 검증\"\n---\n\n# PAI 테스트·검증\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Validation Stage\n 담당: gstack runner + harness checker\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 1단계: 테스트 실행\n- \\`.pai/gstack.json\\`의 \\`testRunner\\` 또는 \\`package.json\\`의 \\`scripts.test\\` 사용\n- \\`npm test\\` 실행 후 결과 보고\n\n### 2단계: 하네스 검증 (\\`.pai/harness.json\\` 존재 시)\n- \\`spec-implementation-match\\`: OpenSpec 엔드포인트 ↔ 구현 매칭\n- \\`api-contract-test\\`: 각 엔드포인트에 대한 테스트 존재 여부\n\n### 3단계: 결과 보고 + 개선 제안\n하네스 설정이 없으면 \\`/pai add\\`에서 Harness Engineering 선택 안내.\n`,\n\n 'grade.md': `---\nname: \"PAI: Grade\"\ndescription: \"6카테고리 가중 점수 기반 AI 개발 준비도 평가\"\n---\n\n# PAI 품질 평가\n\n\\`\\`\\`\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n🔧 PAI > Evaluation Stage\n 담당: scorer (6카테고리 가중 평가)\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\\`\\`\\`\n\n### 6카테고리 (0~100점 채점)\n| # | 카테고리 | 분류 | 가중치 |\n|---|---------|------|--------|\n| 1 | 테스트 커버리지 | 필수 | 20% |\n| 2 | CI/CD | 필수 | 20% |\n| 3 | 훅 기반 검증 | 필수 | 20% |\n| 4 | 리포지토리 구조 | 선택 | 13.3% |\n| 5 | 문서화 수준 | 선택 | 13.3% |\n| 6 | 하네스 엔지니어링 | 선택 | 13.4% |\n\n### 점수 계산\n\\`\\`\\`\n종합 점수 = Σ(카테고리 점수 × 가중치) / Σ(가중치)\n등급: A(90+), B(80+), C(70+), D(50+), F(<50)\n페널티: 필수 카테고리 중 F면 전체 등급 최대 C로 제한\n\\`\\`\\`\n\n### 결과 보고\n막대 그래프 + 점수/등급 + 카테고리별 개선 권고사항 제시.\n`,\n\n 'add.md': `---\nname: \"PAI: Add\"\ndescription: \"플러그인 추가 설치 — Mockup에서 Production 확장\"\n---\n\n# PAI 플러그인 추가 설치\n\n기존 프로젝트에 추가 플러그인을 설치합니다. (Mockup → Production 확장)\n\n### 1단계: 현재 설치 상태 스캔\n| 플러그인 | 감지 경로 |\n|---------|----------|\n| GitHub | \\`.git\\` / \\`.github\\` |\n| Vercel | \\`vercel.json\\` |\n| Supabase | \\`supabase/\\` |\n| OpenSpec | \\`docs/openspec.md\\` |\n| OMC | \\`.pai/omc.md\\` |\n| gstack | \\`.pai/gstack.json\\` |\n| Harness | \\`.pai/harness.json\\` |\n\n### 2단계: 미설치 항목 체크박스로 사용자에게 제시\n\n### 3단계: 선택된 플러그인 파일 생성\n- **Vercel**: \\`vercel.json\\`\n- **Supabase**: \\`supabase/config.toml\\` + \\`.env.local\\` (URL/KEY)\n- **gstack**: \\`.pai/gstack.json\\` (testRunner, coverageThreshold 80%)\n- **Harness**: \\`.pai/harness.json\\` (specFile, rules)\n\n### 4단계: \\`.pai/config.json\\`의 \\`plugins\\` 배열에 추가\n\n### 주의\n이미 존재하는 파일은 절대 덮어쓰지 않음. \\`.env.local\\`은 append only.\n`,\n};\n\n// ── Shared helper ─────────────────────────────────────\n\ninterface WriteResult {\n written: string[];\n skipped: string[];\n errors: Array<{ file: string; error: string }>;\n}\n\nasync function writeCommandFiles(\n cmdDir: string,\n entries: Record<string, string>,\n options: { skipIfExists: boolean },\n): Promise<WriteResult> {\n await fs.ensureDir(cmdDir);\n const written: string[] = [];\n const skipped: string[] = [];\n const errors: Array<{ file: string; error: string }> = [];\n\n for (const [filename, content] of Object.entries(entries)) {\n const filePath = join(cmdDir, filename);\n try {\n if (options.skipIfExists && await fs.pathExists(filePath)) {\n skipped.push(filename);\n continue;\n }\n await fs.writeFile(filePath, content);\n written.push(filename);\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ file: filename, error: msg });\n }\n }\n\n return { written, skipped, errors };\n}\n\n// ── Init (skip if exists) ─────────────────────────────\n\nexport async function provisionClaudeCommands(cwd: string): Promise<void> {\n const skillDir = join(cwd, '.claude', 'skills', 'pai');\n await fs.ensureDir(skillDir);\n const skillPath = join(skillDir, 'SKILL.md');\n if (!(await fs.pathExists(skillPath))) {\n await fs.writeFile(skillPath, SKILL_CONTENT);\n }\n\n const cmdDir = join(cwd, '.claude', 'commands', 'pai');\n await writeCommandFiles(cmdDir, COMMANDS, { skipIfExists: true });\n}\n\n// ── Upgrade (always overwrite) ────────────────────────\n\nexport interface UpgradeResult {\n skillUpdated: boolean;\n commandsWritten: string[];\n commandErrors: Array<{ file: string; error: string }>;\n}\n\nexport async function upgradeClaudeCommands(cwd: string): Promise<UpgradeResult> {\n const result: UpgradeResult = {\n skillUpdated: false,\n commandsWritten: [],\n commandErrors: [],\n };\n\n // Always overwrite SKILL.md\n const skillDir = join(cwd, '.claude', 'skills', 'pai');\n await fs.ensureDir(skillDir);\n try {\n await fs.writeFile(join(skillDir, 'SKILL.md'), SKILL_CONTENT);\n result.skillUpdated = true;\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n result.commandErrors.push({ file: 'SKILL.md', error: msg });\n }\n\n // Always overwrite all command files\n const cmdDir = join(cwd, '.claude', 'commands', 'pai');\n const { written, errors } = await writeCommandFiles(cmdDir, COMMANDS, { skipIfExists: false });\n result.commandsWritten = written;\n result.commandErrors.push(...errors);\n\n return result;\n}\n","/**\n * Doctor — 환경 헬스 체크\n */\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\ninterface Check {\n label: string;\n ok: boolean;\n detail: string;\n fix?: string;\n}\n\nexport async function runDoctor(): Promise<void> {\n ui.section('PAI Doctor — 환경 진단');\n\n const checks: Check[] = [];\n\n // Node.js version\n const nodeVersion = process.version;\n const nodeMajor = parseInt(nodeVersion.slice(1).split('.')[0]!, 10);\n checks.push({\n label: 'Node.js 버전',\n ok: nodeMajor >= 20,\n detail: `${nodeVersion} ${nodeMajor >= 20 ? '(>=20 OK)' : '(업그레이드 필요)'}`,\n fix: nodeMajor < 20 ? 'Node.js 20 이상으로 업그레이드하세요' : undefined,\n });\n\n // Claude Code CLI\n const claudeCheck = await checkCommand('claude', ['--version']);\n checks.push({\n label: 'Claude Code CLI',\n ok: claudeCheck.ok,\n detail: claudeCheck.detail,\n fix: claudeCheck.ok ? undefined : 'npm install -g @anthropic-ai/claude-code',\n });\n\n // Global config\n const globalConfigPath = join(homedir(), '.pai', 'config.json');\n const hasGlobalConfig = await fs.pathExists(globalConfigPath);\n checks.push({\n label: '글로벌 설정',\n ok: true,\n detail: hasGlobalConfig ? globalConfigPath : '미설정 (기본값 사용)',\n });\n\n // Claude Agent SDK (optional)\n let hasSdk = false;\n try {\n await import('@anthropic-ai/claude-agent-sdk');\n hasSdk = true;\n } catch {\n // not installed\n }\n checks.push({\n label: 'Agent SDK',\n ok: true, // optional이므로 항상 OK\n detail: hasSdk ? '설치됨 (AI 기능 활성화)' : '미설치 (정적 분석 모드)',\n });\n\n // Print results\n console.log('');\n let passed = 0;\n for (const check of checks) {\n const icon = check.ok ? '✓' : '✗';\n const pad = ' '.repeat(Math.max(1, 20 - check.label.length));\n if (check.ok) {\n ui.success(`${icon} ${check.label}${pad}${check.detail}`);\n passed++;\n } else {\n ui.error(`${icon} ${check.label}${pad}${check.detail}`);\n if (check.fix) {\n ui.info(` → ${check.fix}`);\n }\n }\n }\n\n console.log('');\n ui.info(`${passed}/${checks.length} 항목 통과`);\n\n if (passed < checks.length) {\n process.exitCode = 1;\n }\n}\n\nasync function checkCommand(cmd: string, args: string[]): Promise<{ ok: boolean; detail: string }> {\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa(cmd, args, { timeout: 10000 });\n return { ok: true, detail: stdout.trim().split('\\n')[0] ?? 'ok' };\n } catch {\n return { ok: false, detail: 'not found' };\n }\n}\n","/**\n * Environment Stage — 파이프라인 1단계\n * roboco-cli의 핵심 기능을 PAI Stage 인터페이스로 래핑\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { analyzeProject } from './analyzer.js';\nimport { runInterview } from './interviewer.js';\nimport { generateFiles } from './generator.js';\nimport { installTools, printInstallReport } from './installer.js';\nimport { runProvisioners, type ProvisionerContext } from './provisioners/registry.js';\nimport { provisionClaudeCommands } from './provisioners/claude-commands.js';\nimport { getPluginsForMode } from '../../core/detector.js';\nimport { saveConfig, createDefaultConfig } from '../../core/config.js';\nimport { withSpinner, withFileSpinner, sleep } from '../../ui/progress.js';\nimport * as ui from '../../ui/index.js';\n\nexport const environmentStage: Stage = {\n name: 'environment',\n\n canSkip(input: StageInput): boolean {\n return input.config.plugins.length > 0;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const artifacts: string[] = [];\n const errors: StageResult['errors'] = [];\n\n try {\n // 1. Analyze\n console.log('');\n const analysis = await withSpinner('프로젝트 분석 중...', async () => {\n const result = await analyzeProject(input.cwd);\n await sleep(500);\n return result;\n });\n\n console.log('');\n if (analysis.stack.languages.length > 0) {\n ui.success(`스택: ${analysis.stack.languages.join(', ')}`);\n }\n if (analysis.stack.frameworks.length > 0) {\n ui.success(`프레임워크: ${analysis.stack.frameworks.join(', ')}`);\n }\n ui.success(`Git: ${analysis.git.isGitRepo ? `${analysis.git.repoName ?? 'local'}` : '미초기화'}`);\n\n // 2. Interview (interactive — no spinner)\n const interview = await runInterview(analysis, input.cwd, input.config.projectName);\n\n // 3. Generate config files\n console.log('');\n const configFiles = ['CLAUDE.md', '.claude/settings.json', 'docs/vibe-coding/01-intent.md',\n 'docs/vibe-coding/02-requirements.md', 'docs/vibe-coding/03-research.md',\n 'docs/vibe-coding/04-plan.md', 'docs/vibe-coding/05-implement.md'];\n const generated = await withFileSpinner('설정 파일 생성 중...', configFiles, async () => {\n const files = await generateFiles(input.cwd, analysis, interview);\n await sleep(400);\n return files;\n });\n artifacts.push(...generated);\n\n // 4. Run provisioners — 모드별 basePlugins + extraTools\n // basePlugins: 모든 수준에서 설치되는 최소 세트\n // extraTools: 인터뷰어가 모드에 따라 omc/gstack/harness/vercel/supabase 추가\n const basePlugins = ['github', 'openspec', 'roboco'];\n const pluginKeys = [...new Set([...basePlugins, ...interview.extraTools])];\n\n const provCtx: ProvisionerContext = {\n cwd: input.cwd,\n projectName: interview.projectName,\n mode: interview.mode,\n envEntries: {\n PAI_PROJECT_NAME: interview.projectName,\n PAI_MODE: interview.mode,\n },\n mcp: interview.mcp,\n };\n\n if (interview.authMethods.includes('custom')) {\n provCtx.envEntries['OAUTH_CLIENT_ID'] = interview.customAuth?.clientId || 'YOUR_CLIENT_ID_HERE';\n provCtx.envEntries['OAUTH_CLIENT_SECRET'] = interview.customAuth?.clientSecret || 'YOUR_CLIENT_SECRET_HERE';\n provCtx.envEntries['OAUTH_REDIRECT_URI'] = 'http://localhost:3000/auth/callback';\n }\n\n const pluginFileNames = ['.gitignore', 'src/', 'docs/', 'tests/', 'public/',\n 'docs/openspec.md', '.pai/roboco.json',\n ...(interview.extraTools.includes('omc') ? ['.pai/omc.md', '.omc/'] : []),\n ...(interview.extraTools.includes('vercel') ? ['vercel.json'] : []),\n ...(interview.extraTools.includes('supabase') ? ['supabase/config.toml'] : []),\n ...(interview.extraTools.includes('gstack') ? ['.pai/gstack.json'] : []),\n ...(interview.extraTools.includes('harness') ? ['.pai/harness.json'] : []),\n ...(interview.extraTools.includes('mcp') ? ['mcp-server/', '.mcp.json'] : []),\n '.env.local'];\n\n console.log('');\n await withFileSpinner('프로젝트 구조 설치 중...', pluginFileNames, async () => {\n await runProvisioners(pluginKeys, provCtx);\n await sleep(500);\n });\n\n const cmdFiles = ['SKILL.md', 'info.md', 'init.md', 'status.md',\n 'doctor.md', 'design.md', 'validate.md', 'evaluate.md', 'install.md'];\n\n console.log('');\n await withFileSpinner('슬래시 커맨드 설치 중...', cmdFiles, async () => {\n await provisionClaudeCommands(input.cwd);\n await sleep(400);\n });\n\n // 5. OMC install (npx omc init)\n console.log('');\n const installResults = await installTools(interview.tools, input.cwd);\n printInstallReport(installResults, interview.tools);\n\n // 6. Save PAI config\n console.log('');\n await withSpinner('설정 저장 중...', async () => {\n const config = createDefaultConfig(interview.projectName, interview.mode);\n config.plugins = pluginKeys;\n if (interview.mcp) config.mcp = interview.mcp;\n await saveConfig(input.cwd, config);\n await sleep(300);\n });\n\n return {\n stage: 'environment',\n status: 'success',\n data: { analysis, interview, installResults },\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'ENV_SETUP_FAILED', message: msg, recoverable: true });\n return {\n stage: 'environment',\n status: 'failed',\n data: {},\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nexport { analyzeProject } from './analyzer.js';\nexport { runInterview } from './interviewer.js';\nexport { runDoctor } from './doctor.js';\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport type { Mode } from './types/index.js';\nimport { normalizeMode } from './config.js';\n\nexport interface PluginMeta {\n label: string;\n description: string;\n modes: Mode[];\n required: boolean;\n /** 선택 — 플러그인 소스 저장소 URL (참조용) */\n url?: string;\n}\n\nexport const PLUGIN_SIGNATURES: Record<string, string[]> = {\n github: ['.git', '.github'],\n vercel: ['.vercel', 'vercel.json'],\n supabase: ['supabase', '.supabase'],\n openspec: ['openspec.md', 'docs/openspec.md', '.pai/openspec.md'],\n omc: ['.pai/omc.md', 'omc.config.js', 'omc.config.json'],\n gstack: ['.pai/gstack.json', 'gstack.config.js'],\n roboco: ['.pai/roboco.json', 'roboco.config.js', '.roboco'],\n harness: ['.pai/harness.json', 'harness.config.js', '.harness'],\n};\n\n/**\n * PLUGIN_META — 플러그인별 메타데이터 + 모드 매트릭스.\n *\n * v0.11.1 3단계 모드 매트릭스:\n * - prototype: github, openspec, roboco (최소)\n * - poc: + omc + (vercel 선택)\n * - production: + gstack, harness + (vercel, supabase 선택)\n */\nexport const PLUGIN_META: Record<string, PluginMeta> = {\n github: {\n label: 'GitHub 레포 & 폴더 구조',\n description: '레포 초기화, .gitignore, 기본 브랜치 설정',\n modes: ['prototype', 'poc', 'production'],\n required: true,\n },\n openspec: {\n label: 'OpenSpec (PRD 설계)',\n description: 'AI 기반 PRD 생성 및 스펙 문서화',\n modes: ['prototype', 'poc', 'production'],\n required: true,\n },\n roboco: {\n label: 'roboco (AI 진단)',\n description: '설치 상태 평가 및 AI 준비도 리포트 생성',\n modes: ['prototype', 'poc', 'production'],\n required: false,\n url: 'https://github.com/SoInKyu/roboco-cli',\n },\n omc: {\n label: 'OMC (oh-my-claudecode)',\n description: '객체 모델 컨텍스트 + Claude Code 멀티 에이전트 오케스트레이션',\n modes: ['poc', 'production'],\n required: false,\n url: 'https://github.com/SoInKyu/oh-my-claudecode',\n },\n vercel: {\n label: 'Vercel 배포 연동',\n description: '자동 배포 파이프라인 및 Preview URL 설정',\n modes: ['poc', 'production'],\n required: false,\n },\n gstack: {\n label: 'gstack (QA / 품질관리)',\n description: '테스트 자동화 및 품질 기준 설정',\n modes: ['production'],\n required: false,\n url: 'https://github.com/SoInKyu/gstack',\n },\n harness: {\n label: 'Harness Engineering (검증 자동화)',\n description: '설계(OpenSpec)와 구현 일치 여부 자동 체크',\n modes: ['production'],\n required: false,\n },\n supabase: {\n label: 'Supabase (DB & Auth)',\n description: '데이터베이스, 인증, API 키 자동 연동',\n modes: ['production'],\n required: false,\n },\n};\n\nexport interface ProjectState {\n isNewProject: boolean;\n hasPaiConfig: boolean;\n projectMode: Mode | null;\n installedPlugins: string[];\n missingPlugins: string[];\n details: Record<string, { installed: boolean; signatures: string[] }>;\n}\n\nexport async function scanProjectState(cwd: string): Promise<ProjectState> {\n const result: ProjectState = {\n isNewProject: true,\n hasPaiConfig: false,\n projectMode: null,\n installedPlugins: [],\n missingPlugins: [],\n details: {},\n };\n\n const paiConfigPath = path.join(cwd, '.pai', 'config.json');\n if (await fs.pathExists(paiConfigPath)) {\n result.hasPaiConfig = true;\n try {\n const config = await fs.readJson(paiConfigPath);\n // 레거시 'mockup' 자동 정규화\n result.projectMode = config.mode != null ? normalizeMode(config.mode) : null;\n } catch {\n // ignore parse errors\n }\n }\n\n for (const [key, signatures] of Object.entries(PLUGIN_SIGNATURES)) {\n const installed = await Promise.any(\n signatures.map(async (sig) => {\n if (await fs.pathExists(path.join(cwd, sig))) return true;\n throw new Error('not found');\n }),\n ).catch(() => false);\n\n result.details[key] = { installed: installed as boolean, signatures };\n if (installed) {\n result.installedPlugins.push(key);\n } else {\n result.missingPlugins.push(key);\n }\n }\n\n const hasAnyContent =\n result.installedPlugins.length > 0 ||\n (await fs.pathExists(path.join(cwd, 'package.json'))) ||\n (await fs.pathExists(path.join(cwd, 'src'))) ||\n (await fs.pathExists(path.join(cwd, 'README.md')));\n\n result.isNewProject = !hasAnyContent;\n\n return result;\n}\n\nexport function getPluginsForMode(mode: Mode): Array<{ key: string } & PluginMeta> {\n return Object.entries(PLUGIN_META)\n .filter(([, meta]) => meta.modes.includes(mode))\n .map(([key, meta]) => ({ key, ...meta }));\n}\n\n/**\n * 모드별 기본(required=true) + 선택(required=false) 플러그인 키만 반환.\n * environment stage가 basePlugins 산출 시 사용.\n */\nexport function getBasePluginsForMode(mode: Mode): string[] {\n return Object.entries(PLUGIN_META)\n .filter(([, meta]) => meta.modes.includes(mode) && meta.required)\n .map(([key]) => key);\n}\n\n/**\n * 모드 승격 경로. prototype → poc → production.\n * 현재 모드의 다음 단계를 반환 (없으면 null).\n */\nexport function nextMode(current: Mode): Mode | null {\n if (current === 'prototype') return 'poc';\n if (current === 'poc') return 'production';\n return null;\n}\n\n/**\n * 모드 승격 시 새로 추가되는 플러그인 키 (required + optional 전체).\n */\nexport function pluginsAddedByPromotion(from: Mode, to: Mode): string[] {\n const fromSet = new Set(getPluginsForMode(from).map((p) => p.key));\n return getPluginsForMode(to)\n .map((p) => p.key)\n .filter((k) => !fromSet.has(k));\n}\n","/**\n * LLM Analysis Prompt — vibe-ready-cli에서 내재화\n */\nexport function buildAnalysisPrompt(repoPath: string): string {\n return `Analyze the repository at \"${repoPath}\" for vibe coding readiness.\n\nUse only Read, Glob, and Grep tools. Complete in ~20 tool calls.\nFocus on config files, not source code.\n\nEvaluate these 6 categories:\n\n### Must-Have (60% weight)\n1. **테스트 커버리지**: test framework config, test dirs, coverage thresholds\n - 0=none, 20=config only, 40=minimal files, 60=moderate, 80=good, 100=comprehensive\n2. **CI/CD**: pipeline configs, quality gates, multi-stage\n - 0=none, 20=exists but minimal, 40=basic, 60=tests+lint, 80=tests+lint+build, 100=comprehensive\n3. **훅 기반 검증**: git hooks, lint-staged, AI agent hooks (.claude/settings.json)\n - 0=none, 20=framework only, 40=single hook, 60=lint+format, 80=lint+test+format, 100=comprehensive+AI\n\n### Nice-to-Have (40% weight)\n4. **리포지토리 구조**: dir organization, deps management, env config\n - 0=flat/chaotic, 20=minimal, 40=basic, 60=reasonable, 80=well-organized, 100=exemplary\n5. **문서화 수준**: README, CONTRIBUTING, API docs, architecture docs\n - 0=none, 20=minimal, 40=basic, 60=good README, 80=README+API, 100=comprehensive\n6. **하네스 엔지니어링**: CLAUDE.md, AGENTS.md, .claude/ config, skills, commands\n - 0=none, 20=basic, 40=one AI config, 60=context+config, 80=context+safety+skills, 100=comprehensive\n\nOutput ONLY a JSON block:\n\\`\\`\\`json\n{\n \"categories\": [\n {\n \"name\": \"카테고리명 (Korean)\",\n \"tier\": \"must\" | \"nice\",\n \"score\": 0-100,\n \"recommendations\": [{ \"severity\": \"critical\"|\"warning\"|\"info\", \"message\": \"...\", \"action\": \"...\" }],\n \"rawFindings\": [{ \"item\": \"filename or concept\", \"found\": true|false, \"details\": \"...\" }]\n }\n ],\n \"summary\": \"2-3 sentence Korean summary\"\n}\n\\`\\`\\``;\n}\n","/**\n * Evaluation Analyzer\n * SDK 있을 때: LLM 기반 분석 / SDK 없을 때: 정적 파일 분석\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { LLMAnalysisOutput, LLMCategoryOutput } from '../../core/types/index.js';\n\nexport async function analyzeRepository(repoPath: string): Promise<LLMAnalysisOutput> {\n // Try AI analysis first\n try {\n return await aiAnalysis(repoPath);\n } catch {\n // Fall back to static analysis\n return staticAnalysis(repoPath);\n }\n}\n\nasync function aiAnalysis(repoPath: string): Promise<LLMAnalysisOutput> {\n const { query } = await import('@anthropic-ai/claude-agent-sdk');\n const { buildAnalysisPrompt } = await import('./prompts/analyze.js');\n\n const prompt = buildAnalysisPrompt(repoPath);\n let resultText = '';\n\n for await (const message of query({\n prompt,\n options: {\n maxTurns: 200,\n systemPrompt: 'You are a vibe coding readiness analyzer. Analyze the repository and output JSON.',\n allowedTools: ['Read', 'Glob', 'Grep'],\n permissionMode: 'plan',\n },\n })) {\n if ('result' in message) {\n resultText = message.result as string;\n }\n }\n\n return parseJsonFromText(resultText);\n}\n\nfunction parseJsonFromText(text: string): LLMAnalysisOutput {\n const jsonMatch = text.match(/```json\\s*([\\s\\S]*?)```/);\n if (jsonMatch?.[1]) {\n return JSON.parse(jsonMatch[1]) as LLMAnalysisOutput;\n }\n // Try parsing the whole text\n return JSON.parse(text) as LLMAnalysisOutput;\n}\n\nasync function staticAnalysis(repoPath: string): Promise<LLMAnalysisOutput> {\n const categories: LLMCategoryOutput[] = [];\n\n // 1. 테스트 커버리지\n categories.push(await checkTestCoverage(repoPath));\n // 2. CI/CD\n categories.push(await checkCiCd(repoPath));\n // 3. 훅 기반 검증\n categories.push(await checkHooks(repoPath));\n // 4. 리포지토리 구조\n categories.push(await checkRepoStructure(repoPath));\n // 5. 문서화 수준\n categories.push(await checkDocumentation(repoPath));\n // 6. 하네스 엔지니어링\n categories.push(await checkHarnessEngineering(repoPath));\n\n return {\n categories,\n summary: `정적 분석 완료. ${categories.filter((c) => c.score >= 60).length}/6 카테고리 통과.`,\n };\n}\n\nasync function checkTestCoverage(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const testConfigs = ['jest.config.ts', 'jest.config.js', 'vitest.config.ts', 'vitest.config.js',\n 'pytest.ini', 'phpunit.xml', '.nycrc'];\n for (const f of testConfigs) {\n const found = await fs.pathExists(join(repoPath, f));\n findings.push({ item: f, found, details: found ? '존재' : '없음' });\n if (found) score += 20;\n }\n\n const testDirs = ['tests', 'test', '__tests__', 'spec'];\n let hasTestDir = false;\n for (const d of testDirs) {\n if (await fs.pathExists(join(repoPath, d))) {\n findings.push({ item: d, found: true, details: '테스트 디렉토리 존재' });\n hasTestDir = true;\n score += 30;\n break;\n }\n }\n if (!hasTestDir) {\n findings.push({ item: 'test directory', found: false, details: '테스트 디렉토리 없음' });\n }\n\n score = Math.min(100, score);\n const recommendations = score < 60\n ? [{ severity: 'critical' as const, message: '테스트 환경 미구성', action: '테스트 프레임워크와 테스트 디렉토리를 추가하세요' }]\n : [];\n\n return { name: '테스트 커버리지', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkCiCd(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const ciConfigs = [\n { path: '.github/workflows', label: 'GitHub Actions' },\n { path: '.gitlab-ci.yml', label: 'GitLab CI' },\n { path: 'Jenkinsfile', label: 'Jenkins' },\n { path: '.circleci', label: 'CircleCI' },\n ];\n\n for (const { path, label } of ciConfigs) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 40;\n }\n\n score = Math.min(100, score);\n const recommendations = score === 0\n ? [{ severity: 'critical' as const, message: 'CI/CD 미구성', action: 'GitHub Actions 또는 다른 CI 파이프라인을 설정하세요' }]\n : [];\n\n return { name: 'CI/CD', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkHooks(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const hookConfigs = [\n { path: '.husky', label: 'Husky' },\n { path: '.lintstagedrc', label: 'lint-staged' },\n { path: '.lintstagedrc.json', label: 'lint-staged (json)' },\n { path: 'commitlint.config.js', label: 'commitlint' },\n { path: '.claude/settings.json', label: 'Claude Code settings' },\n ];\n\n for (const { path, label } of hookConfigs) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 20;\n }\n\n score = Math.min(100, score);\n const recommendations = score < 40\n ? [{ severity: 'warning' as const, message: '훅 기반 검증 부족', action: 'Husky + lint-staged를 설정하여 커밋 전 검증을 추가하세요' }]\n : [];\n\n return { name: '훅 기반 검증', tier: 'must', score, recommendations, rawFindings: findings };\n}\n\nasync function checkRepoStructure(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const structureChecks = [\n { path: 'src', label: 'src/ 디렉토리' },\n { path: 'package.json', label: '의존성 관리' },\n { path: '.env.example', label: '환경변수 예시' },\n { path: '.gitignore', label: '.gitignore' },\n ];\n\n for (const { path, label } of structureChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += 25;\n }\n\n score = Math.min(100, score);\n return { name: '리포지토리 구조', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n\nasync function checkDocumentation(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const docChecks = [\n { path: 'README.md', label: 'README.md', points: 30 },\n { path: 'CONTRIBUTING.md', label: 'CONTRIBUTING.md', points: 20 },\n { path: 'docs', label: 'docs/ 디렉토리', points: 25 },\n { path: 'docs/openspec.md', label: 'OpenSpec PRD', points: 25 },\n ];\n\n for (const { path, label, points } of docChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += points;\n }\n\n score = Math.min(100, score);\n return { name: '문서화 수준', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n\nasync function checkHarnessEngineering(repoPath: string): Promise<LLMCategoryOutput> {\n const findings: Array<{ item: string; found: boolean; details: string }> = [];\n let score = 0;\n\n const harnessChecks = [\n { path: 'CLAUDE.md', label: 'CLAUDE.md', points: 25 },\n { path: 'AGENTS.md', label: 'AGENTS.md', points: 15 },\n { path: '.claude/settings.json', label: '.claude/settings.json', points: 20 },\n { path: '.claude/skills', label: '.claude/skills/', points: 20 },\n { path: '.claude/commands', label: '.claude/commands/', points: 10 },\n { path: '.pai/config.json', label: 'PAI config', points: 10 },\n ];\n\n for (const { path, label, points } of harnessChecks) {\n const found = await fs.pathExists(join(repoPath, path));\n findings.push({ item: label, found, details: found ? '존재' : '없음' });\n if (found) score += points;\n }\n\n score = Math.min(100, score);\n return { name: '하네스 엔지니어링', tier: 'nice', score, recommendations: [], rawFindings: findings };\n}\n","/**\n * Stage — 파이프라인 단계의 계약\n *\n * 모든 파이프라인 단계는 이 인터페이스를 구현합니다.\n * Stage 간 직접 import는 금지 — previousResults를 통해서만 이전 결과 접근.\n */\n\nexport type StageName =\n | 'environment'\n | 'design'\n | 'execution'\n | 'validation'\n | 'evaluation';\n\nexport interface StageError {\n code: string;\n message: string;\n recoverable: boolean;\n}\n\nexport interface StageResult {\n stage: StageName;\n status: 'success' | 'partial' | 'failed' | 'skipped';\n data: Record<string, unknown>;\n artifacts: string[];\n duration: number;\n errors: StageError[];\n}\n\nexport interface StageInput {\n cwd: string;\n config: PaiConfig;\n previousResults: ReadonlyMap<StageName, StageResult>;\n}\n\nexport interface Stage {\n name: StageName;\n run(input: StageInput): Promise<StageResult>;\n canSkip(input: StageInput): boolean;\n}\n\n/**\n * PAI 프로젝트 개발 수준.\n * - `prototype` — 빠른 검증용 (아이디어 정리, UI 목업, 컨셉 시연)\n * - `poc` — PoC 웹개발 (동작 데모, 기본 기능 구현)\n * - `production`— 운영 서비스 (테스트/QA/배포/모니터링)\n *\n * v0.11.1 이전 버전은 `mockup | production` 이분법을 사용했다.\n * 레거시 `mockup`은 `loadConfig()`에서 `prototype`으로 자동 매핑된다.\n */\nexport type Mode = 'prototype' | 'poc' | 'production';\n\n/** 레거시 모드 — 로드 시 Mode로 정규화됨. 저장/코드 분기에는 사용 금지. */\nexport type LegacyMode = 'mockup';\n\nexport interface PaiConfig {\n version: string;\n mode: Mode;\n projectName: string;\n installedAt: string;\n plugins: string[];\n evaluation?: {\n categories?: Record<string, { weight?: number; tier?: 'must' | 'nice' }>;\n };\n mcp?: {\n enabled: boolean;\n type: 'tools' | 'tools-public' | 'resources' | 'prompts' | 'all';\n name: string;\n };\n}\n\nexport const STAGE_ORDER: readonly StageName[] = [\n 'environment',\n 'design',\n 'execution',\n 'validation',\n 'evaluation',\n] as const;\n","/**\n * Scoring types — vibe-ready-cli에서 내재화\n * 품질 평가 점수 시스템 타입들\n */\n\nexport type Grade = 'A' | 'B' | 'C' | 'D' | 'F';\nexport type CategoryTier = 'must' | 'nice';\n\nexport interface RawFinding {\n item: string;\n found: boolean;\n details: string;\n}\n\nexport interface Recommendation {\n severity: 'critical' | 'warning' | 'info';\n message: string;\n action: string;\n}\n\nexport interface CategoryResult {\n name: string;\n tier: CategoryTier;\n score: number;\n grade: Grade;\n recommendations: Recommendation[];\n rawFindings: RawFinding[];\n}\n\nexport interface EvaluationResult {\n categories: CategoryResult[];\n totalScore: number;\n totalGrade: Grade;\n summary: string;\n penaltyApplied: boolean;\n penaltyReason?: string;\n}\n\nexport interface LLMCategoryOutput {\n name: string;\n tier: CategoryTier;\n score: number;\n recommendations: Recommendation[];\n rawFindings: RawFinding[];\n}\n\nexport interface LLMAnalysisOutput {\n categories: LLMCategoryOutput[];\n summary: string;\n}\n\nexport interface CategoryWeight {\n name: string;\n tier: CategoryTier;\n weight: number;\n}\n\nexport const DEFAULT_CATEGORY_WEIGHTS: CategoryWeight[] = [\n { name: '테스트 커버리지', tier: 'must', weight: 0.20 },\n { name: 'CI/CD', tier: 'must', weight: 0.20 },\n { name: '훅 기반 검증', tier: 'must', weight: 0.20 },\n { name: '리포지토리 구조', tier: 'nice', weight: 0.133 },\n { name: '문서화 수준', tier: 'nice', weight: 0.133 },\n { name: '하네스 엔지니어링', tier: 'nice', weight: 0.134 },\n];\n\nexport function gradeFromScore(score: number): Grade {\n if (score >= 90) return 'A';\n if (score >= 80) return 'B';\n if (score >= 70) return 'C';\n if (score >= 50) return 'D';\n return 'F';\n}\n","export type {\n StageName,\n StageError,\n StageResult,\n StageInput,\n Stage,\n PaiConfig,\n Mode,\n LegacyMode,\n} from './stage.js';\nexport { STAGE_ORDER } from './stage.js';\n\nexport type {\n StackInfo,\n RepoStructure,\n ExistingConfig,\n GitInfo,\n AnalysisResult,\n} from './analysis.js';\n\nexport type {\n Grade,\n CategoryTier,\n RawFinding,\n Recommendation,\n CategoryResult,\n EvaluationResult,\n LLMCategoryOutput,\n LLMAnalysisOutput,\n CategoryWeight,\n} from './scoring.js';\nexport { gradeFromScore, DEFAULT_CATEGORY_WEIGHTS } from './scoring.js';\n","/**\n * Scorer — vibe-ready-cli에서 내재화\n * 가중 평균 + 페널티 로직\n */\nimport type {\n CategoryResult,\n CategoryTier,\n EvaluationResult,\n Grade,\n LLMAnalysisOutput,\n CategoryWeight,\n} from '../../core/types/index.js';\nimport { gradeFromScore, DEFAULT_CATEGORY_WEIGHTS } from '../../core/types/index.js';\n\nexport function computeResult(\n llmOutput: LLMAnalysisOutput,\n customWeights?: CategoryWeight[],\n): EvaluationResult {\n const weights = customWeights ?? DEFAULT_CATEGORY_WEIGHTS;\n\n const categories: CategoryResult[] = llmOutput.categories.map((cat) => ({\n name: cat.name,\n tier: cat.tier,\n score: Math.round(Math.max(0, Math.min(100, cat.score))),\n grade: gradeFromScore(Math.max(0, Math.min(100, cat.score))),\n recommendations: cat.recommendations,\n rawFindings: cat.rawFindings,\n }));\n\n const totalScore = computeWeightedAverage(categories, weights);\n let totalGrade = gradeFromScore(totalScore);\n\n const { penaltyApplied, penaltyReason } = checkPenalty(categories);\n if (penaltyApplied && gradeRank(totalGrade) > gradeRank('C')) {\n totalGrade = 'C';\n }\n\n return {\n categories,\n totalScore,\n totalGrade,\n summary: llmOutput.summary,\n penaltyApplied,\n penaltyReason,\n };\n}\n\nfunction computeWeightedAverage(\n categories: CategoryResult[],\n weights: CategoryWeight[],\n): number {\n let weightedSum = 0;\n let totalWeight = 0;\n\n for (const cat of categories) {\n const config = weights.find((w) => w.name === cat.name);\n const weight = config?.weight ?? (cat.tier === 'must' ? 0.20 : 0.133);\n weightedSum += cat.score * weight;\n totalWeight += weight;\n }\n\n if (totalWeight === 0) return 0;\n return Math.round((weightedSum / totalWeight) * 100) / 100;\n}\n\nfunction checkPenalty(categories: CategoryResult[]): {\n penaltyApplied: boolean;\n penaltyReason?: string;\n} {\n const failedMust = categories.filter(\n (c) => c.tier === 'must' && c.grade === 'F',\n );\n\n if (failedMust.length > 0) {\n const names = failedMust.map((c) => c.name).join(', ');\n return {\n penaltyApplied: true,\n penaltyReason: `필수 카테고리 F 등급: ${names} → 전체 등급 최대 C로 제한`,\n };\n }\n\n return { penaltyApplied: false };\n}\n\nfunction gradeRank(grade: Grade): number {\n const ranks: Record<Grade, number> = { A: 4, B: 3, C: 2, D: 1, F: 0 };\n return ranks[grade];\n}\n","/**\n * Reporter — 터미널/Markdown 출력\n */\nimport chalk from 'chalk';\nimport type { EvaluationResult, CategoryResult, Grade } from '../../core/types/index.js';\n\nconst GRADE_COLORS: Record<Grade, (s: string) => string> = {\n A: chalk.hex('#6BCB77'),\n B: chalk.hex('#7B93DB'),\n C: chalk.hex('#E2B340'),\n D: chalk.hex('#E06C75'),\n F: chalk.hex('#CC4444'),\n};\n\nexport function printReport(result: EvaluationResult): void {\n console.log('');\n console.log(chalk.hex('#7B93DB')(' PAI Evaluation Report'));\n console.log(chalk.gray(' ─────────────────────────────────'));\n console.log('');\n\n // Overall score\n const gradeColor = GRADE_COLORS[result.totalGrade];\n console.log(` 종합 점수: ${gradeColor(String(result.totalScore))} / 100 등급: ${gradeColor(result.totalGrade)}`);\n\n if (result.penaltyApplied) {\n console.log(chalk.red(` ⚠ ${result.penaltyReason}`));\n }\n\n console.log('');\n console.log(chalk.gray(' ─────────────────────────────────────'));\n\n // Category breakdown\n for (const cat of result.categories) {\n const color = GRADE_COLORS[cat.grade];\n const tierLabel = cat.tier === 'must' ? chalk.hex('#E06C75')('[필수]') : chalk.gray('[선택]');\n const bar = renderBar(cat.score);\n console.log(` ${tierLabel} ${cat.name.padEnd(16)} ${bar} ${color(`${cat.score}`).padStart(12)} ${color(cat.grade)}`);\n }\n\n console.log('');\n console.log(chalk.gray(` ${result.summary}`));\n console.log('');\n}\n\nexport function printVerboseFindings(result: EvaluationResult): void {\n for (const cat of result.categories) {\n console.log('');\n console.log(chalk.bold(` ${cat.name} (${cat.grade}, ${cat.score}점)`));\n\n for (const f of cat.rawFindings) {\n const icon = f.found ? chalk.green('✓') : chalk.red('✗');\n console.log(` ${icon} ${f.item} — ${f.details}`);\n }\n\n for (const r of cat.recommendations) {\n const severity = r.severity === 'critical' ? chalk.red('!') : r.severity === 'warning' ? chalk.yellow('!') : chalk.gray('i');\n console.log(` ${severity} ${r.message}`);\n console.log(chalk.gray(` → ${r.action}`));\n }\n }\n}\n\nfunction renderBar(score: number): string {\n const width = 20;\n const filled = Math.round((score / 100) * width);\n const empty = width - filled;\n const color = score >= 80 ? chalk.hex('#6BCB77') : score >= 60 ? chalk.hex('#E2B340') : chalk.hex('#E06C75');\n return color('█'.repeat(filled)) + chalk.gray('░'.repeat(empty));\n}\n\nexport function buildMarkdownReport(result: EvaluationResult): string {\n const lines: string[] = [\n '# PAI Evaluation Report',\n '',\n `> 생성일시: ${new Date().toLocaleString('ko-KR')}`,\n '',\n `## 종합 점수: ${result.totalScore}/100 — 등급 ${result.totalGrade}`,\n '',\n ];\n\n if (result.penaltyApplied) {\n lines.push(`> ⚠ ${result.penaltyReason}`);\n lines.push('');\n }\n\n lines.push('## 카테고리별 상세');\n lines.push('');\n lines.push('| 카테고리 | 분류 | 점수 | 등급 |');\n lines.push('|---------|------|------|------|');\n\n for (const cat of result.categories) {\n const tier = cat.tier === 'must' ? '필수' : '선택';\n lines.push(`| ${cat.name} | ${tier} | ${cat.score} | ${cat.grade} |`);\n }\n\n lines.push('');\n lines.push('## 권고사항');\n lines.push('');\n\n const allRecs = result.categories.flatMap((c) =>\n c.recommendations.map((r) => ({ ...r, category: c.name })),\n );\n\n if (allRecs.length === 0) {\n lines.push('모든 항목이 양호합니다!');\n } else {\n for (const r of allRecs) {\n const icon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : 'ℹ️';\n lines.push(`- ${icon} **${r.category}**: ${r.message}`);\n lines.push(` - ${r.action}`);\n }\n }\n\n lines.push('');\n lines.push(`## 요약`);\n lines.push('');\n lines.push(result.summary);\n lines.push('');\n lines.push('---');\n lines.push('*Generated by PAI (Plugin-based AI)*');\n\n return lines.join('\\n') + '\\n';\n}\n\nexport function buildDetailedReport(result: EvaluationResult, projectName: string): string {\n const now = new Date().toLocaleString('ko-KR');\n const mustCats = result.categories.filter((c) => c.tier === 'must');\n const niceCats = result.categories.filter((c) => c.tier === 'nice');\n\n const lines: string[] = [\n `# ${projectName} 바이브 코딩 준비도 분석 리포트`,\n '',\n `> 스캔 일시: ${now}`,\n `> 분석 대상: ${projectName}`,\n '',\n '---',\n '',\n '## 요약',\n '',\n `${projectName}의 바이브 코딩 준비도 종합 점수는 **${result.totalScore}/100 (${result.totalGrade}등급)**입니다.`,\n '',\n ];\n\n if (result.penaltyApplied) {\n lines.push(`> ⚠ ${result.penaltyReason}`);\n lines.push('');\n }\n\n // Grade description\n if (result.totalGrade === 'A') {\n lines.push('AI 지원 코딩 워크플로우를 활용할 준비가 잘 되어 있습니다.');\n } else if (result.totalGrade === 'B') {\n lines.push('대부분 준비되어 있으며, 일부 개선으로 최적의 바이브 코딩 환경을 구축할 수 있습니다.');\n } else if (result.totalGrade === 'C') {\n lines.push('기본적인 구조는 갖추고 있으나, 바이브 코딩의 잠재력을 충분히 활용하려면 개선이 필요합니다.');\n } else if (result.totalGrade === 'D') {\n lines.push('AI 지원 코딩 워크플로우를 본격적으로 활용하기에는 상당한 개선이 필요한 상태입니다.');\n } else {\n lines.push('바이브 코딩 환경이 거의 구성되지 않은 상태로, 기본 설정부터 시작해야 합니다.');\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // Category overview table\n lines.push('## 항목별 현황');\n lines.push('');\n lines.push('| 항목 | 분류 | 점수 | 등급 | 가중치 |');\n lines.push('|------|------|------|------|--------|');\n\n for (const cat of result.categories) {\n const tier = cat.tier === 'must' ? '**필수**' : '선택';\n lines.push(`| ${cat.name} | ${tier} | ${cat.score}/100 | ${cat.grade} | ${cat.tier === 'must' ? '20%' : '13.3%'} |`);\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n\n // Detailed analysis per category\n lines.push('## 항목별 상세 분석');\n lines.push('');\n\n for (const cat of result.categories) {\n const tierLabel = cat.tier === 'must' ? '필수' : '선택';\n lines.push(`### ${cat.name} (${tierLabel}, 가중치 ${cat.tier === 'must' ? '20%' : '13.3%'}) — ${cat.grade}등급`);\n lines.push('');\n\n // Raw findings\n if (cat.rawFindings.length > 0) {\n lines.push('**점검 결과:**');\n lines.push('');\n for (const f of cat.rawFindings) {\n const icon = f.found ? '✅' : '❌';\n lines.push(`- ${icon} ${f.item} — ${f.details}`);\n }\n lines.push('');\n }\n\n // Grade assessment\n if (cat.grade === 'A' || cat.grade === 'B') {\n lines.push(`**평가:** 양호한 상태입니다.`);\n } else if (cat.grade === 'C') {\n lines.push(`**평가:** 기본은 갖추고 있으나 추가 개선이 권장됩니다.`);\n } else if (cat.grade === 'D') {\n lines.push(`**평가:** 개선이 필요합니다.`);\n } else {\n lines.push(`**평가:** 시급한 개선이 필요합니다.`);\n }\n lines.push('');\n\n // Recommendations\n if (cat.recommendations.length > 0) {\n lines.push('**권고사항:**');\n lines.push('');\n for (const r of cat.recommendations) {\n const icon = r.severity === 'critical' ? '🔴' : r.severity === 'warning' ? '🟡' : 'ℹ️';\n lines.push(`- ${icon} ${r.message}`);\n lines.push(` - → ${r.action}`);\n }\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n }\n\n // Improvement roadmap\n lines.push('## 개선 로드맵');\n lines.push('');\n\n const critical = result.categories.filter((c) => c.grade === 'F');\n const warning = result.categories.filter((c) => c.grade === 'D');\n const ok = result.categories.filter((c) => c.grade === 'C' || c.grade === 'B' || c.grade === 'A');\n\n if (critical.length > 0) {\n lines.push('### 즉시 개선 필요 (F등급)');\n lines.push('');\n lines.push('| 항목 | 현재 점수 | 목표 | 조치 |');\n lines.push('|------|----------|------|------|');\n for (const c of critical) {\n const action = c.recommendations[0]?.action ?? '설정 추가 필요';\n lines.push(`| ${c.name} | ${c.score}점 (F) | 50점+ (D) | ${action} |`);\n }\n lines.push('');\n }\n\n if (warning.length > 0) {\n lines.push('### 단기 개선 권장 (D등급)');\n lines.push('');\n lines.push('| 항목 | 현재 점수 | 목표 | 조치 |');\n lines.push('|------|----------|------|------|');\n for (const c of warning) {\n const action = c.recommendations[0]?.action ?? '추가 설정 권장';\n lines.push(`| ${c.name} | ${c.score}점 (D) | 70점+ (C) | ${action} |`);\n }\n lines.push('');\n }\n\n if (ok.length > 0) {\n lines.push('### 양호 (C등급 이상)');\n lines.push('');\n for (const c of ok) {\n lines.push(`- ✅ ${c.name}: ${c.score}점 (${c.grade})`);\n }\n lines.push('');\n }\n\n lines.push('---');\n lines.push('');\n\n // Conclusion\n lines.push('## 결론');\n lines.push('');\n lines.push(result.summary);\n lines.push('');\n\n if (result.totalGrade === 'F' || result.totalGrade === 'D') {\n const immediateActions = critical.length + warning.length;\n lines.push(`즉시 개선 가능한 ${immediateActions}개 항목을 완료하면 점수를 크게 끌어올릴 수 있습니다.`);\n } else if (result.totalGrade === 'C') {\n lines.push('기본 구조가 잘 갖추어져 있으며, 단기 개선 항목을 마무리하면 B등급 달성이 가능합니다.');\n } else {\n lines.push('바이브 코딩 환경이 잘 구성되어 있습니다. 지속적인 품질 관리를 권장합니다.');\n }\n\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('*PAI Zero (Plugin AI for ProjectZero) + Claude Code로 생성됨*');\n\n return lines.join('\\n') + '\\n';\n}\n","/**\n * Shell CD Helper — 부모 쉘 디렉토리 자동 이동 지원\n * macOS/Linux: bash/zsh 함수 → .zshrc/.bashrc\n * Windows: PowerShell 함수 → $PROFILE\n */\nimport { join } from 'node:path';\nimport { homedir } from 'node:os';\nimport fs from 'fs-extra';\nimport { isWindows, getShellRcPath } from './platform.js';\n\nconst PAI_DIR = join(homedir(), '.pai');\nconst CD_FILE = join(PAI_DIR, '.cd-after');\nconst HELPER_FILE_SH = join(PAI_DIR, 'shell-helper.sh');\nconst HELPER_FILE_PS1 = join(PAI_DIR, 'shell-helper.ps1');\n\nconst BASH_HELPER = `# PAI shell helper — 자동 디렉토리 이동 지원\npai() {\n local cd_target=\"$HOME/.pai/.cd-after\"\n rm -f \"$cd_target\"\n PAI_CD_AFTER=\"$cd_target\" command npx pai-zero \"$@\"\n local exit_code=$?\n if [ -f \"$cd_target\" ]; then\n local dir\n dir=\"$(cat \"$cd_target\")\"\n rm -f \"$cd_target\"\n if [ -n \"$dir\" ] && [ -d \"$dir\" ]; then\n cd \"$dir\" || true\n echo \" → cd $dir\"\n fi\n fi\n return $exit_code\n}\n`;\n\nconst POWERSHELL_HELPER = `# PAI shell helper — 자동 디렉토리 이동 지원\nfunction pai {\n $cdTarget = Join-Path $env:USERPROFILE '.pai\\\\.cd-after'\n Remove-Item $cdTarget -ErrorAction SilentlyContinue\n $env:PAI_CD_AFTER = $cdTarget\n & npx pai-zero @args\n $exitCode = $LASTEXITCODE\n if (Test-Path $cdTarget) {\n $dir = Get-Content $cdTarget -Raw\n Remove-Item $cdTarget -ErrorAction SilentlyContinue\n if ($dir -and (Test-Path $dir)) {\n Set-Location $dir\n Write-Host \" -> cd $dir\"\n }\n }\n return $exitCode\n}\n`;\n\n/**\n * .cd-after 파일에 이동할 디렉토리를 기록\n */\nexport async function requestCdAfter(targetDir: string): Promise<void> {\n await fs.ensureDir(PAI_DIR);\n await fs.writeFile(CD_FILE, targetDir);\n}\n\n/**\n * 쉘 헬퍼 파일 생성 + RC 파일에 등록\n * @returns true if already installed\n */\nexport async function installShellHelper(): Promise<boolean> {\n await fs.ensureDir(PAI_DIR);\n\n if (isWindows) {\n return installPowerShellHelper();\n }\n return installBashHelper();\n}\n\nasync function installBashHelper(): Promise<boolean> {\n await fs.writeFile(HELPER_FILE_SH, BASH_HELPER);\n\n const rcFile = getShellRcPath();\n const sourceLine = 'source \"$HOME/.pai/shell-helper.sh\"';\n\n if (await fs.pathExists(rcFile)) {\n const content = await fs.readFile(rcFile, 'utf8');\n if (content.includes('shell-helper.sh')) {\n return true;\n }\n await fs.appendFile(rcFile, `\\n# PAI — 자동 디렉토리 이동\\n${sourceLine}\\n`);\n return false;\n }\n\n await fs.writeFile(rcFile, `${sourceLine}\\n`);\n return false;\n}\n\nasync function installPowerShellHelper(): Promise<boolean> {\n await fs.writeFile(HELPER_FILE_PS1, POWERSHELL_HELPER);\n\n const rcFile = getShellRcPath();\n const sourceLine = '. \"$env:USERPROFILE\\\\.pai\\\\shell-helper.ps1\"';\n\n await fs.ensureDir(join(rcFile, '..'));\n\n if (await fs.pathExists(rcFile)) {\n const content = await fs.readFile(rcFile, 'utf8');\n if (content.includes('shell-helper.ps1')) {\n return true;\n }\n await fs.appendFile(rcFile, `\\n# PAI — 자동 디렉토리 이동\\n${sourceLine}\\n`);\n return false;\n }\n\n await fs.writeFile(rcFile, `${sourceLine}\\n`);\n return false;\n}\n","/**\n * Claude Code ~/.claude/settings.json 안전 병합 유틸\n *\n * - 크로스플랫폼 (macOS / Windows / Linux) — 경로/파일명 차이 흡수\n * - 기존 필드 보존 (deep merge)\n * - BOM 포함 JSON 파싱 지원 (한국어 Windows 환경)\n * - 쓰기 전 타임스탬프 백업 생성\n */\nimport os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { sanitizeFilenameForWindows } from './platform.js';\n\nconst DEFAULT_MARKETPLACE_ID = 'omc';\nconst DEFAULT_MARKETPLACE_URL = 'https://github.com/SoInKyu/oh-my-claudecode.git';\nconst DEFAULT_PLUGIN_ID = 'oh-my-claudecode@omc';\n\nexport interface EnableOmcOptions {\n marketplaceId?: string; // 기본: omc\n marketplaceUrl?: string; // 기본: OMC GitHub repo\n pluginId?: string; // 기본: oh-my-claudecode@omc\n backup?: boolean; // 기본: true\n}\n\nexport type EnableOmcAction =\n | 'added' // 신규 등록\n | 'already-enabled' // 이미 등록됨 — 파일 수정 없음\n | 'created'; // settings.json 자체를 신규 생성\n\nexport interface EnableOmcResult {\n action: EnableOmcAction;\n settingsPath: string;\n backupPath?: string;\n}\n\nexport class ClaudeSettingsError extends Error {\n constructor(message: string, public readonly backupPath?: string) {\n super(message);\n this.name = 'ClaudeSettingsError';\n }\n}\n\n/**\n * ~/.claude/settings.json 경로. 플랫폼 독립.\n */\nexport function getClaudeSettingsPath(homeDir: string = os.homedir()): string {\n return path.join(homeDir, '.claude', 'settings.json');\n}\n\n/**\n * BOM(0xFEFF) 포함 JSON 안전 파싱. 한국어 Windows에서 일부 에디터가 UTF-8 BOM 삽입.\n */\nfunction parseJsonWithBom(raw: string): unknown {\n const stripped = raw.charCodeAt(0) === 0xfeff ? raw.slice(1) : raw;\n return JSON.parse(stripped);\n}\n\nfunction timestampSuffix(): string {\n // ISO8601에서 Windows 금지 문자(:) 제거\n return sanitizeFilenameForWindows(new Date().toISOString());\n}\n\n/**\n * OMC 마켓플레이스 + 플러그인 활성화 정보를 ~/.claude/settings.json 에 병합.\n *\n * - 파일 없음 → 최소 스켈레톤 생성\n * - 이미 등록됨 → no-op, 'already-enabled' 반환\n * - 기존 필드 → 모두 보존 (deep merge)\n * - 손상된 JSON → 백업 후 ClaudeSettingsError throw (덮어쓰지 않음)\n */\nexport async function enableOmcPlugin(\n options: EnableOmcOptions = {},\n): Promise<EnableOmcResult> {\n const marketplaceId = options.marketplaceId ?? DEFAULT_MARKETPLACE_ID;\n const marketplaceUrl = options.marketplaceUrl ?? DEFAULT_MARKETPLACE_URL;\n const pluginId = options.pluginId ?? DEFAULT_PLUGIN_ID;\n const wantBackup = options.backup ?? true;\n\n const settingsPath = getClaudeSettingsPath();\n await fs.ensureDir(path.dirname(settingsPath));\n\n // ── 1. 파일 없음 → 신규 생성 ────────────────\n if (!(await fs.pathExists(settingsPath))) {\n const skeleton = buildSkeleton(marketplaceId, marketplaceUrl, pluginId);\n await fs.writeFile(settingsPath, JSON.stringify(skeleton, null, 2) + '\\n', 'utf8');\n return { action: 'created', settingsPath };\n }\n\n // ── 2. 읽기 + BOM 처리 + 파싱 ────────────────\n const raw = await fs.readFile(settingsPath, 'utf8');\n let parsed: Record<string, unknown>;\n try {\n const value = parseJsonWithBom(raw);\n if (!value || typeof value !== 'object' || Array.isArray(value)) {\n throw new Error('settings.json is not a JSON object');\n }\n parsed = value as Record<string, unknown>;\n } catch (err) {\n // 손상된 JSON — 백업 후 중단 (절대 덮어쓰지 않음)\n const backupPath = `${settingsPath}.backup-${timestampSuffix()}`;\n await fs.copy(settingsPath, backupPath);\n throw new ClaudeSettingsError(\n `settings.json 파싱 실패: ${(err as Error).message}. 백업: ${backupPath}`,\n backupPath,\n );\n }\n\n // ── 3. 이미 등록됨? ────────────────\n if (isAlreadyEnabled(parsed, marketplaceId, pluginId)) {\n return { action: 'already-enabled', settingsPath };\n }\n\n // ── 4. 백업 ────────────────\n let backupPath: string | undefined;\n if (wantBackup) {\n backupPath = `${settingsPath}.backup-${timestampSuffix()}`;\n await fs.copy(settingsPath, backupPath);\n }\n\n // ── 5. deep merge 후 저장 ────────────────\n const merged = mergeOmcIntoSettings(parsed, marketplaceId, marketplaceUrl, pluginId);\n await fs.writeFile(settingsPath, JSON.stringify(merged, null, 2) + '\\n', 'utf8');\n\n return { action: 'added', settingsPath, backupPath };\n}\n\n/* ─────────────────────────────────────────────────────────────\n * 내부 헬퍼 (export는 테스트용)\n * ─────────────────────────────────────────────────────────── */\n\nexport function buildSkeleton(\n marketplaceId: string,\n marketplaceUrl: string,\n pluginId: string,\n): Record<string, unknown> {\n return {\n extraKnownMarketplaces: {\n [marketplaceId]: {\n source: { source: 'git', url: marketplaceUrl },\n },\n },\n enabledPlugins: {\n [pluginId]: true,\n },\n };\n}\n\nexport function isAlreadyEnabled(\n settings: Record<string, unknown>,\n marketplaceId: string,\n pluginId: string,\n): boolean {\n const markets = settings['extraKnownMarketplaces'];\n const enabled = settings['enabledPlugins'];\n const hasMarket =\n typeof markets === 'object' &&\n markets !== null &&\n marketplaceId in (markets as Record<string, unknown>);\n const hasPlugin =\n typeof enabled === 'object' &&\n enabled !== null &&\n (enabled as Record<string, unknown>)[pluginId] === true;\n return hasMarket && hasPlugin;\n}\n\nexport function mergeOmcIntoSettings(\n settings: Record<string, unknown>,\n marketplaceId: string,\n marketplaceUrl: string,\n pluginId: string,\n): Record<string, unknown> {\n const next: Record<string, unknown> = { ...settings };\n\n const existingMarkets =\n typeof next['extraKnownMarketplaces'] === 'object' && next['extraKnownMarketplaces'] !== null\n ? { ...(next['extraKnownMarketplaces'] as Record<string, unknown>) }\n : {};\n existingMarkets[marketplaceId] = {\n source: { source: 'git', url: marketplaceUrl },\n };\n next['extraKnownMarketplaces'] = existingMarkets;\n\n const existingPlugins =\n typeof next['enabledPlugins'] === 'object' && next['enabledPlugins'] !== null\n ? { ...(next['enabledPlugins'] as Record<string, unknown>) }\n : {};\n existingPlugins[pluginId] = true;\n next['enabledPlugins'] = existingPlugins;\n\n return next;\n}\n","/**\n * Cache — SHA256 기반 레포 해시, TTL 24시간\n */\nimport { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport type { LLMAnalysisOutput } from '../../core/types/index.js';\n\nconst CACHE_DIR = '.pai';\nconst CACHE_FILE = 'cache/evaluation.json';\nconst CACHE_TTL_MS = 24 * 60 * 60 * 1000;\n\ninterface CacheEntry {\n repoPath: string;\n repoHash: string;\n timestamp: number;\n llmOutput: LLMAnalysisOutput;\n}\n\ninterface CacheStore {\n version: 1;\n entries: Record<string, CacheEntry>;\n}\n\nconst FILES_TO_HASH = [\n 'package.json', 'pyproject.toml', 'go.mod', 'Cargo.toml',\n 'tsconfig.json', 'jest.config.ts', 'vitest.config.ts',\n '.github/workflows', '.gitlab-ci.yml',\n '.husky', '.lintstagedrc',\n 'CLAUDE.md', 'AGENTS.md', '.cursorrules',\n 'README.md', 'CONTRIBUTING.md',\n];\n\nexport function computeRepoHash(repoPath: string): string {\n const hash = createHash('sha256');\n for (const file of FILES_TO_HASH) {\n const fullPath = join(repoPath, file);\n try {\n const content = readFileSync(fullPath);\n hash.update(`${file}:${content.length}`);\n } catch {\n hash.update(`${file}:missing`);\n }\n }\n return hash.digest('hex').slice(0, 16);\n}\n\nfunction getCachePath(repoPath: string): string {\n return join(repoPath, CACHE_DIR, CACHE_FILE);\n}\n\nfunction loadCache(repoPath: string): CacheStore {\n try {\n const data = readFileSync(getCachePath(repoPath), 'utf-8');\n return JSON.parse(data) as CacheStore;\n } catch {\n return { version: 1, entries: {} };\n }\n}\n\nfunction saveCache(repoPath: string, store: CacheStore): void {\n const cacheDir = join(repoPath, CACHE_DIR, 'cache');\n if (!existsSync(cacheDir)) {\n mkdirSync(cacheDir, { recursive: true });\n }\n writeFileSync(getCachePath(repoPath), JSON.stringify(store, null, 2));\n}\n\nexport function getCachedResult(repoPath: string): LLMAnalysisOutput | null {\n const store = loadCache(repoPath);\n const repoHash = computeRepoHash(repoPath);\n const entry = store.entries[repoHash];\n\n if (!entry) return null;\n if (Date.now() - entry.timestamp > CACHE_TTL_MS) return null;\n\n return entry.llmOutput;\n}\n\nexport function setCachedResult(repoPath: string, llmOutput: LLMAnalysisOutput): void {\n const store = loadCache(repoPath);\n const repoHash = computeRepoHash(repoPath);\n\n // Cleanup expired entries\n const now = Date.now();\n for (const [key, entry] of Object.entries(store.entries)) {\n if (now - entry.timestamp > CACHE_TTL_MS) {\n delete store.entries[key];\n }\n }\n\n store.entries[repoHash] = { repoPath, repoHash, timestamp: now, llmOutput };\n saveCache(repoPath, store);\n}\n","import { join, basename } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\nimport { analyzeRepository } from '../../stages/evaluation/analyzer.js';\nimport { computeResult } from '../../stages/evaluation/scorer.js';\nimport { getCachedResult, setCachedResult } from '../../stages/evaluation/cache.js';\nimport { printReport, printVerboseFindings, buildDetailedReport } from '../../stages/evaluation/reporter.js';\nimport { loadConfig } from '../../core/config.js';\n\nexport interface EvaluateOptions {\n failUnder?: number;\n verbose?: boolean;\n output?: string;\n cache?: boolean;\n}\n\nexport async function evaluateCommand(cwd: string, options: EvaluateOptions): Promise<void> {\n const useCache = options.cache !== false;\n\n // Analyze\n let llmOutput = useCache ? getCachedResult(cwd) : null;\n if (llmOutput) {\n ui.info('캐시된 결과 사용 (24시간 이내)');\n } else {\n llmOutput = await analyzeRepository(cwd);\n if (useCache) {\n setCachedResult(cwd, llmOutput);\n }\n }\n\n const result = computeResult(llmOutput);\n\n // Print to terminal\n printReport(result);\n\n if (options.verbose) {\n printVerboseFindings(result);\n }\n\n // Auto-save detailed report to docs/p-reports/YYYY-MM-DD.md\n const config = await loadConfig(cwd);\n const projectName = config?.projectName ?? basename(cwd);\n const today = new Date().toISOString().slice(0, 10); // YYYY-MM-DD\n const reportDir = join(cwd, 'docs', 'p-reports');\n const reportPath = join(reportDir, `${today}.md`);\n\n await fs.ensureDir(reportDir);\n const detailedReport = buildDetailedReport(result, projectName);\n await fs.writeFile(reportPath, detailedReport, 'utf8');\n\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n console.log('');\n\n // Cat the report\n console.log(detailedReport);\n\n // Custom output path (optional)\n if (options.output) {\n await fs.writeFile(options.output, detailedReport, 'utf8');\n ui.success(`추가 저장: ${options.output}`);\n }\n\n // Fail-under check\n if (options.failUnder && result.totalScore < options.failUnder) {\n ui.error(`점수 ${result.totalScore}이 최소 기준 ${options.failUnder}에 미달합니다.`);\n process.exitCode = 1;\n }\n}\n","import * as ui from '../../ui/index.js';\nimport {\n scanProjectState,\n PLUGIN_META,\n getPluginsForMode,\n nextMode,\n pluginsAddedByPromotion,\n} from '../../core/detector.js';\nimport { loadConfig, createDefaultConfig, saveConfig } from '../../core/config.js';\nimport { runProvisioners, type ProvisionerContext } from '../../stages/environment/provisioners/registry.js';\nimport { runDoctor } from '../../stages/environment/doctor.js';\nimport { analyzeProject } from '../../stages/environment/analyzer.js';\nimport { colors as c } from '../../ui/logger.js';\nimport type { Mode } from '../../core/types/index.js';\n\nexport async function envSetupCommand(cwd: string): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const { basename } = await import('node:path');\n\n ui.section('플러그인 추가 · 모드 승격');\n const state = await scanProjectState(cwd);\n const existingConfig = await loadConfig(cwd);\n const currentMode: Mode = state.projectMode ?? existingConfig?.mode ?? 'prototype';\n\n // ── 1. 모드 승격 제안 ────────────────────────────\n const upgradeTarget = nextMode(currentMode);\n let promotedMode: Mode | null = null;\n const autoPluginsFromPromotion: string[] = [];\n\n if (upgradeTarget) {\n const addedPlugins = pluginsAddedByPromotion(currentMode, upgradeTarget);\n const notYetInstalled = addedPlugins.filter((k) => !(state.details[k]?.installed ?? false));\n\n console.log('');\n console.log(c.dim(` 현재 모드: ${c.accent(currentMode)}`));\n console.log(c.dim(` 다음 단계: ${c.accent(upgradeTarget)}`));\n if (notYetInstalled.length > 0) {\n console.log(c.dim(` 승격 시 추가되는 플러그인: ${notYetInstalled.join(', ')}`));\n }\n console.log('');\n\n const { promote } = await inquirer.prompt([{\n type: 'confirm',\n name: 'promote',\n message: `${upgradeTarget} 수준으로 승격하시겠어요?`,\n default: true,\n }]);\n\n if (promote) {\n promotedMode = upgradeTarget;\n autoPluginsFromPromotion.push(...notYetInstalled);\n }\n } else {\n ui.info(`이미 최상위 모드(${currentMode})입니다.`);\n }\n\n // ── 2. 개별 플러그인 추가 선택 ───────────────────\n // 승격 후에도 현재 모드에서 선택 가능한 미설치 플러그인을 추가로 고를 수 있음\n const targetMode = promotedMode ?? currentMode;\n const availableForMode = getPluginsForMode(targetMode).map((p) => p.key);\n const remaining = availableForMode.filter(\n (k) => !(state.details[k]?.installed ?? false) && !autoPluginsFromPromotion.includes(k),\n );\n\n let selectedKeys: string[] = [];\n if (remaining.length > 0) {\n console.log('');\n const choices = remaining.map((k) => {\n const meta = PLUGIN_META[k];\n const tag = meta?.required ? '[필수]' : '[선택]';\n return {\n name: `${meta?.label ?? k} ${c.dim(tag)}`,\n value: k,\n checked: meta?.required ?? false,\n };\n });\n const answer = await inquirer.prompt([{\n type: 'checkbox',\n name: 'selectedKeys',\n message: autoPluginsFromPromotion.length > 0\n ? '추가로 설치할 플러그인 (선택):'\n : '설치할 플러그인을 선택하세요:',\n choices,\n }]);\n selectedKeys = answer.selectedKeys as string[];\n }\n\n const allToInstall = [...new Set([...autoPluginsFromPromotion, ...selectedKeys])];\n if (allToInstall.length === 0) {\n ui.info('선택된 플러그인이 없습니다.');\n if (promotedMode) {\n // 승격만 저장\n const config = existingConfig ?? createDefaultConfig(basename(cwd), promotedMode);\n config.mode = promotedMode;\n await saveConfig(cwd, config);\n ui.success(`모드: ${currentMode} → ${promotedMode}`);\n }\n return;\n }\n\n // ── 3. 프로젝트명 (없으면) ───────────────────────\n const projectName = existingConfig?.projectName ?? basename(cwd);\n\n const ctx: ProvisionerContext = {\n cwd,\n projectName,\n mode: targetMode,\n envEntries: {},\n };\n\n // ── 4. 설치 ─────────────────────────────────────\n ui.section('플러그인 설치 중...');\n await runProvisioners(allToInstall, ctx);\n\n // ── 5. config 갱신 ──────────────────────────────\n const config = existingConfig ?? createDefaultConfig(projectName, targetMode);\n config.mode = targetMode;\n config.plugins = [...new Set([...config.plugins, ...allToInstall])];\n await saveConfig(cwd, config);\n\n ui.success('설치 완료');\n if (promotedMode) {\n ui.success(`모드: ${currentMode} → ${promotedMode}`);\n }\n console.log('');\n ui.hint('다음 단계: /pai status 또는 /pai grade');\n}\n\nexport async function envDoctorCommand(): Promise<void> {\n await runDoctor();\n}\n\nexport async function envStatusCommand(cwd: string): Promise<void> {\n ui.section('프로젝트 상태');\n\n const state = await scanProjectState(cwd);\n const analysis = await analyzeProject(cwd);\n\n if (state.isNewProject) {\n ui.info('신규 프로젝트 — `pai init` 으로 초기화하세요.');\n return;\n }\n\n // Stack info\n if (analysis.stack.languages.length > 0) {\n ui.success(`스택: ${analysis.stack.languages.join(', ')}`);\n }\n if (analysis.stack.frameworks.length > 0) {\n ui.success(`프레임워크: ${analysis.stack.frameworks.join(', ')}`);\n }\n if (analysis.git.isGitRepo) {\n ui.success(`Git: ${analysis.git.repoName ?? 'local'} (${analysis.git.currentBranch ?? 'unknown'})`);\n }\n\n // Plugin state\n console.log('');\n for (const [key, meta] of Object.entries(PLUGIN_META)) {\n const installed = state.details[key]?.installed ?? false;\n if (installed) {\n ui.success(`${meta.label}`);\n } else {\n ui.warn(`${meta.label} — 미설치`);\n }\n }\n\n if (state.projectMode) {\n console.log('');\n ui.info(`모드: ${state.projectMode}`);\n const next = nextMode(state.projectMode);\n if (next) {\n ui.hint(`승격 경로: ${state.projectMode} → ${next} (pai add 에서 승격 가능)`);\n }\n }\n}\n","import { join, basename } from 'node:path';\nimport fs from 'fs-extra';\nimport { printWelcomeBanner } from '../../ui/index.js';\nimport { environmentStage } from '../../stages/environment/index.js';\nimport { loadConfig, createDefaultConfig, saveConfig } from '../../core/config.js';\nimport { scanProjectState } from '../../core/detector.js';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport async function initCommand(cwd: string, nameArg?: string): Promise<void> {\n printWelcomeBanner();\n\n // Windows 환경 체크\n const { isWindows, diagnoseWindowsEnv } = await import('../../utils/platform.js');\n if (isWindows) {\n const { issues, warnings } = diagnoseWindowsEnv();\n if (issues.length > 0) {\n ui.section('Windows 환경 문제');\n for (const i of issues) {\n ui.error(i.title);\n ui.hint(` 해결: ${i.fix}`);\n }\n const { default: inquirer } = await import('inquirer');\n const { proceed } = await inquirer.prompt([{\n type: 'confirm',\n name: 'proceed',\n message: '문제가 있지만 계속 진행하시겠습니까?',\n default: true,\n }]);\n if (!proceed) return;\n }\n if (warnings.length > 0) {\n for (const w of warnings) {\n ui.warn(w.title);\n if (w.hint) ui.hint(w.hint);\n }\n }\n }\n\n // 이미 PAI 프로젝트 내부에서 실행한 경우\n const currentConfig = await loadConfig(cwd);\n if (currentConfig && !nameArg) {\n const state = await scanProjectState(cwd);\n await handleExistingProject(cwd, state);\n return;\n }\n\n // 레거시 프로젝트 감지 (PAI 미설치, 코드 존재)\n if (!nameArg) {\n const isLegacy = await detectLegacyProject(cwd);\n if (isLegacy) {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n console.log('');\n ui.info('기존 프로젝트가 감지되었습니다.');\n\n // 1. AI 바이브코딩 환경 리포트 제안\n console.log('');\n const { runReport } = await inquirer.prompt([{\n type: 'confirm',\n name: 'runReport',\n message: '현재 폴더의 AI 바이브코딩 환경을 먼저 진단할까요?',\n default: true,\n }]);\n\n if (runReport) {\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n console.log('');\n const llmOutput = await analyzeRepository(cwd);\n const evalResult = computeResult(llmOutput);\n printReport(evalResult);\n\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(cwd, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n const legacyName = basename(cwd);\n const detailedReport = buildDetailedReport(evalResult, legacyName);\n await fs.writeFile(join(reportDir, `${today}.md`), detailedReport, 'utf8');\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n } catch {\n ui.warn('진단을 건너뜁니다.');\n }\n }\n\n // 2. PAI 오케스트레이터 설치\n console.log('');\n const { installNow } = await inquirer.prompt([{\n type: 'confirm',\n name: 'installNow',\n message: 'PAI 빌드 오케스트레이터를 설치할까요?',\n default: true,\n }]);\n\n if (installNow) {\n return await installOrchestratorOnly(cwd, basename(cwd));\n }\n return;\n }\n }\n\n // Step 1: 프로젝트 이름\n ui.step(1, 3, '프로젝트 이름');\n ui.hint('이 이름으로 프로젝트 폴더가 생성됩니다.');\n ui.hint('영문 소문자, 숫자, 하이픈(-)을 사용해주세요.');\n console.log('');\n\n const { default: inquirer } = await import('inquirer');\n\n let projectName: string;\n if (nameArg) {\n projectName = nameArg;\n ui.success(`프로젝트: ${projectName}`);\n } else {\n const answer = await inquirer.prompt([{\n type: 'input',\n name: 'name',\n message: '프로젝트 이름:',\n default: 'my-project',\n validate: (v: string) => {\n if (!v.trim()) return '이름을 입력해주세요.';\n if (!/^[a-z0-9][a-z0-9-]*$/.test(v.trim())) {\n return '영문 소문자, 숫자, 하이픈(-)만 사용할 수 있습니다.';\n }\n return true;\n },\n }]);\n projectName = answer.name.trim();\n }\n\n // Step 2: 폴더 생성 또는 확인\n const projectDir = join(cwd, projectName);\n\n if (await fs.pathExists(projectDir)) {\n const existingConfig = await loadConfig(projectDir);\n if (existingConfig) {\n console.log('');\n ui.info(`${projectName}/ 에 이미 PAI 프로젝트가 있습니다.`);\n const state = await scanProjectState(projectDir);\n await handleExistingProject(projectDir, state);\n return;\n }\n\n console.log('');\n ui.warn(`${projectName}/ 폴더가 이미 존재합니다.`);\n ui.hint('이 폴더에 PAI를 설치합니다.');\n } else {\n await fs.ensureDir(projectDir);\n ui.success(`${projectName}/ 폴더 생성`);\n }\n\n // Step 3: 환경 설정 실행\n await setupInDirectory(projectDir, projectName);\n}\n\nasync function setupInDirectory(projectDir: string, projectName: string): Promise<void> {\n // 쉘 헬퍼 설치 (자동 cd 지원)\n const { installShellHelper } = await import('../../utils/shell-cd.js');\n const alreadyInstalled = await installShellHelper();\n if (!alreadyInstalled) {\n ui.success('쉘 헬퍼 설치 (~/.pai/shell-helper.sh)');\n ui.hint('새 터미널에서 pai 명령으로 자동 디렉토리 이동이 활성화됩니다.');\n console.log('');\n }\n\n ui.step(2, 3, '프로젝트 설정');\n\n const config = createDefaultConfig(projectName, 'prototype');\n const input = {\n cwd: projectDir,\n config,\n previousResults: new Map(),\n };\n\n const result = await environmentStage.run(input);\n\n if (result.status === 'success') {\n // 쉘 헬퍼를 통해 프로젝트 디렉토리로 자동 이동\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(projectDir);\n } catch { /* shell-cd not available */ }\n\n const interview = result.data.interview as { extraTools: string[] };\n const isCurrentDir = projectDir === process.cwd();\n await showCompletion(projectName, projectDir, interview.extraTools, isCurrentDir);\n } else {\n for (const err of result.errors) {\n ui.error(err.message);\n }\n }\n}\n\nasync function showCompletion(projectName: string, projectDir: string, extraTools: string[], isCurrentDir: boolean): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n const { sleep } = await import('../../ui/progress.js');\n\n ui.step(3, 3, '완료');\n\n console.log(c.success(' 프로젝트가 준비되었습니다!'));\n console.log('');\n console.log(c.dim(' 생성된 항목'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} PRD 템플릿 ${c.dim('docs/openspec.md')}`);\n console.log(` ${c.success('✓')} 도메인 모델 ${c.dim('.pai/omc.md')}`);\n console.log(` ${c.success('✓')} AI 컨텍스트 ${c.dim('CLAUDE.md')}`);\n console.log(` ${c.success('✓')} 슬래시 커맨드 ${c.dim('/pai init, /pai evaluate 등')}`);\n\n // ── 설치된 플러그인 & 기능 (비유 기반) ──────────\n console.log('');\n console.log(c.accent(' 설치된 플러그인 & 기능'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${chalk.cyan('OpenSpec+OMC')} 설계도 & 지형도 — 무엇을, 어디에 만들지 정의`);\n console.log(` ${chalk.cyan('RoboCo CLI')} 현장 소장 — 전체 공정 관리, AI에게 작업 지시`);\n console.log(` ${chalk.cyan('Vibe-Ready')} 품질 검수 — AI 개발 준비도 6카테고리 평가`);\n\n if (extraTools.includes('omc')) {\n console.log(` ${chalk.cyan('OMC')} AI 에이전트 오케스트레이션 (oh-my-claudecode)`);\n }\n if (extraTools.includes('gstack')) {\n console.log(` ${chalk.cyan('gstack')} 표준 자재 & 공법 — 기술 스택 표준 구조 제공`);\n }\n if (extraTools.includes('harness')) {\n console.log(` ${chalk.cyan('Harness')} 안전장치 & 검사대 — AI 코드 작동 테스트`);\n }\n if (extraTools.includes('vercel')) {\n console.log(` ${chalk.cyan('Vercel')} 자동 배포 — Preview + Production`);\n }\n if (extraTools.includes('supabase')) {\n console.log(` ${chalk.cyan('Supabase')} DB + 인증 + 스토리지 (PostgreSQL 기반)`);\n }\n if (extraTools.includes('mcp')) {\n console.log(` ${chalk.cyan('MCP 서버')} AI 도구 — Claude가 호출할 커스텀 기능/데이터`);\n }\n\n // ── 설치 확인 ──────────────────────────────────\n console.log('');\n console.log(c.accent(' 설치 확인'));\n console.log(c.dim(' ─────────────────────────────'));\n\n const checks = [\n { label: 'AI 컨텍스트', path: 'CLAUDE.md' },\n { label: 'PRD 템플릿', path: 'docs/openspec.md' },\n { label: '프로젝트 설정', path: '.pai/config.json' },\n { label: 'Claude 설정', path: '.claude/settings.json' },\n { label: '슬래시 커맨드', path: '.claude/skills/pai/SKILL.md' },\n ...(extraTools.includes('omc') ? [{ label: 'OMC 런타임', path: '.omc' }] : []),\n ];\n\n for (const check of checks) {\n const exists = await fs.pathExists(join(projectDir, check.path));\n console.log(` ${exists ? c.success('✓') : c.err('✗')} ${check.label.padEnd(16)} ${c.dim(check.path)}`);\n }\n\n // ── Vibe-Ready 평가 제안 ────────────────────────\n console.log('');\n const { runEval } = await inquirer.prompt([{\n type: 'confirm',\n name: 'runEval',\n message: 'AI를 통한 바이브코딩 상태 체크(Vibe-Ready) 평가를 진행할까요?',\n default: true,\n }]);\n\n if (runEval) {\n const { createSpinner } = await import('../../ui/progress.js');\n\n await sleep(2000);\n const spinner = createSpinner('바이브코딩 상태 체크 중...');\n\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n const llmOutput = await analyzeRepository(projectDir);\n const evalResult = computeResult(llmOutput);\n spinner.succeed('체크 완료');\n\n await sleep(500);\n printReport(evalResult);\n\n await sleep(500);\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(projectDir, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n const detailedReport = buildDetailedReport(evalResult, projectName);\n await fs.writeFile(join(reportDir, `${today}.md`), detailedReport, 'utf8');\n\n await sleep(500);\n console.log('');\n ui.success(`리포트 저장: docs/p-reports/${today}.md`);\n } catch {\n spinner.fail('평가 실패');\n await sleep(500);\n ui.hint('나중에 실행: pai evaluate');\n }\n } else {\n await sleep(500);\n ui.hint('나중에 실행: pai evaluate');\n }\n\n // 프로젝트 디렉토리로 이동\n if (!isCurrentDir) {\n process.chdir(projectDir);\n }\n\n // ── 안내 메시지 ────────────────────────────────\n console.log('');\n if (!isCurrentDir) {\n console.log(` ${chalk.green('→')} cd ${projectName} ${c.dim('이동 완료')}`);\n }\n console.log('');\n ui.success('이제 Claude Code와 함께 PRD 문서를 작성하세요.');\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n\n // ── OMC 플러그인 항상 등록 ───────────────────────\n // Claude Code 네이티브 마켓플레이스에 OMC 등록.\n // 실제 설치는 Claude Code 기동 시 자동 수행 (npx 호출 안 함).\n console.log('');\n const { createSpinner } = await import('../../ui/progress.js');\n const omcSpinner = createSpinner('OMC 플러그인 등록 중...');\n try {\n const { enableOmcPlugin } = await import('../../utils/claude-settings.js');\n const result = await enableOmcPlugin();\n if (result.action === 'already-enabled') {\n omcSpinner.succeed('OMC 플러그인 이미 등록됨');\n } else if (result.action === 'created') {\n omcSpinner.succeed('Claude 설정 신규 생성 + OMC 플러그인 등록 완료');\n } else {\n omcSpinner.succeed('OMC 플러그인 등록 완료');\n }\n ui.hint('Claude Code 기동 시 플러그인이 자동 설치됩니다.');\n if (result.backupPath) {\n ui.hint(`설정 백업: ${result.backupPath}`);\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n omcSpinner.warn(`OMC 플러그인 등록 실패 — ${msg}`);\n ui.hint('Claude Code 기동 후 직접 등록하세요:');\n ui.hint(' /plugin install SoInKyu/oh-my-claudecode');\n }\n\n // ── YOLO alias 사전 확인 (이미 있으면 재질문 안 함) ───\n const { getShellRcPath, hasYoloAlias: checkYolo } = await import('../../utils/platform.js');\n const shellRc = getShellRcPath();\n let yoloAlreadyAliased = false;\n try {\n const rcContent = await fs.readFile(shellRc, 'utf8');\n yoloAlreadyAliased = checkYolo(rcContent);\n } catch { /* rc 파일 없음 */ }\n\n // ── Claude Code 시작 (단일 프롬프트, 2개 선택지) ────\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n const { launch } = await inquirer.prompt([{\n type: 'list',\n name: 'launch',\n message: 'Claude Code를 어떤 모드로 시작할까요?',\n choices: [\n { name: `claude ${c.dim('─ 권한 확인 후 실행 (일반 모드)')}`, value: 'claude' },\n { name: `claude YOLO ${c.dim('─ 권한 확인 없이 자동 실행 (--dangerously-skip-permissions)')}`, value: 'yolo' },\n ],\n }]);\n\n const useYolo = launch === 'yolo';\n\n // YOLO 선택 시 alias가 없으면 쉘 rc에 설치\n if (useYolo && !yoloAlreadyAliased) {\n try {\n const { getYoloAliasLine } = await import('../../utils/platform.js');\n const aliasLine = getYoloAliasLine();\n const rcContent = await fs.readFile(shellRc, 'utf8').catch(() => '');\n if (!rcContent.includes('claude-yolo')) {\n await fs.ensureDir(join(shellRc, '..'));\n await fs.appendFile(shellRc, `\\n# PAI — claude-YOLO mode\\n${aliasLine}\\n`);\n await sleep(300);\n ui.success('claude-yolo alias 설정 완료');\n ui.hint('새 터미널에서 claude-yolo 로 실행 가능');\n }\n } catch { /* rc 파일 쓰기 실패 */ }\n }\n\n const cmd = useYolo ? 'claude --dangerously-skip-permissions' : 'claude';\n\n console.log('');\n if (!isCurrentDir) {\n console.log(c.dim(` → cd ${projectName}`));\n }\n console.log(c.dim(` → ${cmd}`));\n console.log('');\n\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(projectDir);\n\n const { execa } = await import('execa');\n process.chdir(projectDir);\n const parts = cmd.split(' ');\n await execa(parts[0]!, parts.slice(1), {\n stdio: 'inherit',\n cwd: projectDir,\n });\n\n // Claude Code 종료 후 프로젝트 디렉토리에서 서브쉘 시작\n if (!isCurrentDir) {\n const { spawnSubshell } = await import('../../utils/platform.js');\n spawnSubshell(projectDir);\n }\n } catch {\n ui.warn(`실행 실패. 직접 입력하세요: ${cmd}`);\n }\n}\n\nasync function handleExistingProject(\n cwd: string,\n state: Awaited<ReturnType<typeof scanProjectState>>,\n): Promise<void> {\n const { PLUGIN_META } = await import('../../core/detector.js');\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n\n ui.section('기존 프로젝트');\n\n const allPlugins = Object.entries(PLUGIN_META).map(([key, meta]) => ({\n key,\n label: meta.label,\n installed: state.details[key]?.installed ?? false,\n }));\n\n for (const p of allPlugins) {\n if (p.installed) {\n ui.success(p.label);\n } else {\n console.log(c.dim(` · ${p.label} ${chalk.gray('미설치')}`));\n }\n }\n\n // 현재 모드 표시 (승격 경로 안내용)\n const currentConfig = await loadConfig(cwd);\n if (currentConfig) {\n console.log('');\n console.log(c.dim(` 현재 모드: ${c.accent(currentConfig.mode)}`));\n }\n\n console.log('');\n const { action } = await inquirer.prompt([{\n type: 'list',\n name: 'action',\n message: '어떤 작업을 할까요?',\n choices: [\n {\n name: `📊 AI 개발 준비도 평가 ${c.dim('(pai grade — 6카테고리 점수)')}`,\n value: 'evaluate',\n },\n {\n name: `➕ 플러그인 추가·모드 승격 ${c.dim('(pai add — prototype → poc → production)')}`,\n value: 'install',\n },\n {\n name: `🩺 환경 점검 ${c.dim('(pai check — Node/Git/Claude/OMC)')}`,\n value: 'doctor',\n },\n { name: chalk.gray('🚪 종료'), value: 'exit' },\n ],\n }]);\n\n switch (action) {\n case 'evaluate': {\n const { evaluateCommand } = await import('./evaluate.cmd.js');\n await evaluateCommand(cwd, {});\n break;\n }\n case 'install': {\n const { envSetupCommand } = await import('./env.cmd.js');\n await envSetupCommand(cwd);\n break;\n }\n case 'doctor': {\n const { runDoctor } = await import('../../stages/environment/doctor.js');\n await runDoctor();\n break;\n }\n default:\n console.log('');\n }\n}\n\nasync function installOrchestratorOnly(projectDir: string, projectName: string): Promise<void> {\n const { default: inquirer } = await import('inquirer');\n const chalk = (await import('chalk')).default;\n const { generateFiles } = await import('../../stages/environment/generator.js');\n const { analyzeProject } = await import('../../stages/environment/analyzer.js');\n const { provisionClaudeCommands } = await import('../../stages/environment/provisioners/claude-commands.js');\n const { runProvisioners } = await import('../../stages/environment/provisioners/registry.js');\n const { withSpinner, withFileSpinner, sleep } = await import('../../ui/progress.js');\n\n // 쉘 헬퍼 설치\n const { installShellHelper } = await import('../../utils/shell-cd.js');\n await installShellHelper();\n\n // 1. 플러그인 선택\n console.log('');\n ui.hint('Space로 선택 · 선택 후 Enter로 완료');\n const Separator = (inquirer as unknown as { Separator: new (s?: string) => unknown }).Separator;\n const { plugins } = await inquirer.prompt([{\n type: 'checkbox',\n name: 'plugins',\n message: '설치할 플러그인을 선택하세요:',\n choices: [\n { name: `OpenSpec+OMC ${c.dim('─ 설계도 & 지형도')}`, value: 'openspec', checked: true },\n { name: `RoboCo CLI ${c.dim('─ 현장 소장 (공정 관리)')}`, value: 'roboco', checked: true },\n { name: `Vibe-Ready ${c.dim('─ 품질 검수 (6카테고리 평가)')}`, value: 'vibe-ready', checked: true },\n { name: `gstack ${c.dim('─ 표준 자재 & 공법 (기술 스택)')}`, value: 'gstack' },\n { name: `Harness ${c.dim('─ 안전장치 & 검사대 (테스트)')}`, value: 'harness' },\n new Separator('─────────────────────────'),\n { name: chalk.green('↵ 선택 완료'), value: '__done__' },\n ],\n }]);\n const selectedPlugins = (plugins as string[]).filter(p => p !== '__done__');\n\n // 2. 프로젝트 분석\n console.log('');\n const analysis = await withSpinner('프로젝트 분석 중...', async () => {\n const result = await analyzeProject(projectDir);\n await sleep(500);\n return result;\n });\n\n // 3. 설정 파일 생성 (인터뷰 없이 자동)\n const extraTools: string[] = [];\n if (selectedPlugins.includes('gstack')) extraTools.push('gstack');\n if (selectedPlugins.includes('harness')) extraTools.push('harness');\n\n const autoInterview = {\n mode: 'prototype' as const,\n projectName,\n authMethods: [],\n extraTools,\n setupDomains: { claudeEnv: true, processDocs: true, cicd: analysis.git.isGitRepo },\n tools: {\n omc: selectedPlugins.includes('openspec'),\n openspec: selectedPlugins.includes('openspec'),\n githubMcp: false,\n harness: selectedPlugins.includes('harness'),\n },\n autoGenerated: true,\n };\n\n console.log('');\n await withFileSpinner('AI 컨텍스트 생성 중...', ['CLAUDE.md', '.claude/settings.json'], async () => {\n await generateFiles(projectDir, analysis, autoInterview);\n await sleep(400);\n });\n\n // 4. 프로비저너 실행 (선택된 플러그인만)\n const basePlugins = ['github'];\n if (selectedPlugins.includes('openspec')) basePlugins.push('openspec', 'omc');\n if (selectedPlugins.includes('roboco')) basePlugins.push('roboco');\n const allPluginKeys = [...basePlugins, ...extraTools];\n\n const provCtx = {\n cwd: projectDir,\n projectName,\n mode: 'prototype' as const,\n envEntries: { PAI_PROJECT_NAME: projectName, PAI_MODE: 'prototype' },\n };\n\n console.log('');\n await withSpinner('플러그인 설치 중...', async () => {\n await runProvisioners(allPluginKeys, provCtx);\n await sleep(400);\n });\n\n // 5. 슬래시 커맨드 설치\n console.log('');\n await withFileSpinner('슬래시 커맨드 설치 중...', ['SKILL.md', 'evaluate.md', 'doctor.md'], async () => {\n await provisionClaudeCommands(projectDir);\n await sleep(400);\n });\n\n // 6. 설정 저장\n console.log('');\n await withSpinner('설정 저장 중...', async () => {\n const config = createDefaultConfig(projectName, 'prototype');\n config.plugins = allPluginKeys;\n await saveConfig(projectDir, config);\n await sleep(300);\n });\n\n console.log('');\n ui.success('PAI 빌드 오케스트레이터 설치 완료');\n\n // 7. AI 바이브코딩 수준 — 간략 그래프\n console.log('');\n try {\n const { analyzeRepository } = await import('../../stages/evaluation/analyzer.js');\n const { computeResult } = await import('../../stages/evaluation/scorer.js');\n const { printReport, buildDetailedReport } = await import('../../stages/evaluation/reporter.js');\n\n const llmOutput = await analyzeRepository(projectDir);\n const evalResult = computeResult(llmOutput);\n printReport(evalResult);\n\n const today = new Date().toISOString().slice(0, 10);\n const reportDir = join(projectDir, 'docs', 'p-reports');\n await fs.ensureDir(reportDir);\n await fs.writeFile(join(reportDir, `${today}.md`), buildDetailedReport(evalResult, projectName), 'utf8');\n\n console.log('');\n ui.hint(`상세 리포트: docs/p-reports/${today}.md`);\n } catch {\n ui.hint('AI 준비도 평가: /pai evaluate');\n }\n\n // 8. Claude Code 시작\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n\n const { launch } = await inquirer.prompt([{\n type: 'list',\n name: 'launch',\n message: 'Claude Code를 시작할까요?',\n choices: [\n { name: `Claude 바로 시작 ${c.dim('─ claude')}`, value: 'claude' },\n { name: chalk.gray('나중에 직접 실행'), value: 'none' },\n ],\n }]);\n\n if (launch === 'none') {\n console.log('');\n ui.hint('claude 를 입력하면 시작됩니다.');\n return;\n }\n\n console.log('');\n console.log(c.dim(' → claude'));\n console.log('');\n\n try {\n const { execa } = await import('execa');\n process.chdir(projectDir);\n await execa('claude', [], { stdio: 'inherit', cwd: projectDir });\n } catch {\n ui.warn('실행 실패. 직접 입력하세요: claude');\n }\n}\n\nasync function installDiagnosticOnly(projectDir: string, projectName: string): Promise<void> {\n const { provisionClaudeCommands } = await import('../../stages/environment/provisioners/claude-commands.js');\n const { withSpinner } = await import('../../ui/progress.js');\n\n console.log('');\n await withSpinner('진단 도구 설치 중...', async () => {\n await provisionClaudeCommands(projectDir);\n });\n\n const config = createDefaultConfig(projectName, 'prototype');\n config.plugins = ['roboco'];\n await saveConfig(projectDir, config);\n\n console.log('');\n ui.success('진단 도구 설치 완료');\n console.log('');\n console.log(c.dim(' 사용 가능한 슬래시 커맨드'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${c.success('✓')} /pai evaluate ${c.dim('AI 준비도 평가 (6카테고리 리포트)')}`);\n console.log(` ${c.success('✓')} /pai doctor ${c.dim('개발 환경 진단 (Node, Git, Claude)')}`);\n console.log(` ${c.success('✓')} /pai status ${c.dim('플러그인 설치 현황')}`);\n console.log(` ${c.success('✓')} /pai install ${c.dim('추가 플러그인 설치')}`);\n console.log('');\n ui.hint('전체 파이프라인이 필요하면: npx pai-zero init');\n}\n\nasync function detectLegacyProject(cwd: string): Promise<boolean> {\n const signals = [\n 'package.json', '.git', 'pom.xml', 'build.gradle',\n 'go.mod', 'Cargo.toml', 'requirements.txt', 'pyproject.toml',\n 'Gemfile', 'composer.json', 'Makefile', '.gitignore',\n ];\n\n for (const signal of signals) {\n if (await fs.pathExists(join(cwd, signal))) return true;\n }\n return false;\n}\n","/**\n * `pai add` — 플러그인 추가 (구 `pai env setup`).\n */\nexport { envSetupCommand as addCommand } from './env.cmd.js';\n","/**\n * `pai check` — 환경 점검 (구 `pai env doctor`).\n */\nexport { envDoctorCommand as checkCommand } from './env.cmd.js';\n","/**\n * `pai status` — 프로젝트 상태 (구 `pai env status`).\n */\nexport { envStatusCommand as statusCommand } from './env.cmd.js';\n","/**\n * `pai help` — 명령어 안내. 구 슬래시 `/pai info` 내용 통합.\n */\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport async function helpCommand(): Promise<void> {\n ui.section('PAI 명령어');\n const lines: Array<[string, string]> = [\n ['pai init', '프로젝트 초기화 (새/기존 자동 감지)'],\n ['pai add', '플러그인 추가 (Mockup → Production 확장)'],\n ['pai check', '환경 점검 (Node / Git / Claude Code)'],\n ['pai status', '현재 프로젝트 상태 확인'],\n ['pai design', 'PRD / OMC 템플릿 & 검증'],\n ['pai test', '테스트 실행 + 하네스 검증'],\n ['pai grade', 'AI 개발 준비도 평가 (6카테고리)'],\n ['pai run', '전체 5단계 파이프라인 실행'],\n ['pai remove', 'PAI 생성 파일 삭제'],\n ['pai upgrade', '슬래시 커맨드 최신화'],\n ['pai savetoken', 'AI 토큰 절감 분석'],\n ['pai wakeup', 'Claude 세션 자동 시작'],\n ['pai help', '이 안내'],\n ];\n for (const [cmd, desc] of lines) {\n console.log(` ${c.accent(cmd.padEnd(16))} ${c.dim(desc)}`);\n }\n console.log('');\n console.log(c.dim(' 파이프라인: Environment → Design → Execution → Validation → Evaluation'));\n console.log('');\n console.log(c.dim(' 구 명령어(env setup, evaluate, validate, pipeline, install) 는 v0.13 까지 유지됩니다.'));\n}\n","/**\n * OpenSpec — PRD 템플릿 생성 및 완성도 검증\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nconst REQUIRED_SECTIONS = [\n { marker: '## 1.', label: '목적 (Purpose)' },\n { marker: '## 2.', label: '사용자 (Users)' },\n { marker: '## 3.', label: '핵심 기능 (Features)' },\n { marker: '## 4.', label: '기술 스택 (Stack)' },\n { marker: '## 5.', label: 'API 엔드포인트 (Endpoints)' },\n];\n\nexport async function initOpenSpec(cwd: string, projectName: string): Promise<void> {\n const docsDir = join(cwd, 'docs');\n await fs.ensureDir(docsDir);\n\n const openspecPath = join(docsDir, 'openspec.md');\n if (await fs.pathExists(openspecPath)) {\n ui.info('docs/openspec.md 이미 존재 — 건너뜀');\n return;\n }\n\n await fs.writeFile(openspecPath, [\n `# OpenSpec — ${projectName}`,\n '', '## 1. 목적 (Purpose)', '> 이 서비스는 무엇을 해결하는가?',\n '', '## 2. 사용자 (Users)', '| 역할 | 설명 |', '|------|------|', '| - | - |',\n '', '## 3. 핵심 기능 (Features)', '- [ ] Feature 1',\n '', '## 4. 기술 스택 (Stack)', '- Frontend:', '- Backend:', '- DB:',\n '', '## 5. API 엔드포인트 (Endpoints)',\n '| Method | Path | 설명 |', '|--------|------|------|', '| GET | /api/health | 헬스체크 |',\n ].join('\\n') + '\\n');\n\n ui.success('OpenSpec 템플릿 생성 → docs/openspec.md');\n}\n\nexport interface ValidationResult {\n complete: boolean;\n totalSections: number;\n filledSections: number;\n missing: string[];\n warnings: string[];\n}\n\nexport async function validateOpenSpec(cwd: string): Promise<ValidationResult> {\n const candidates = [\n join(cwd, 'docs', 'openspec.md'),\n join(cwd, 'openspec.md'),\n join(cwd, '.pai', 'openspec.md'),\n ];\n\n let specPath: string | null = null;\n for (const p of candidates) {\n if (await fs.pathExists(p)) {\n specPath = p;\n break;\n }\n }\n\n if (!specPath) {\n return {\n complete: false,\n totalSections: REQUIRED_SECTIONS.length,\n filledSections: 0,\n missing: REQUIRED_SECTIONS.map((s) => s.label),\n warnings: ['openspec.md 파일이 없습니다. `pai design init` 을 실행하세요.'],\n };\n }\n\n const content = await fs.readFile(specPath, 'utf8');\n const missing: string[] = [];\n let filled = 0;\n\n for (const section of REQUIRED_SECTIONS) {\n const idx = content.indexOf(section.marker);\n if (idx === -1) {\n missing.push(section.label);\n continue;\n }\n\n // Check if section has content beyond template placeholders\n const nextSection = content.indexOf('\\n## ', idx + 1);\n const sectionContent = nextSection > 0\n ? content.slice(idx, nextSection)\n : content.slice(idx);\n\n const lines = sectionContent.split('\\n').filter((l) =>\n l.trim() && !l.startsWith('#') && !l.startsWith('|--') && l.trim() !== '| - | - |'\n && !l.startsWith('>'),\n );\n\n if (lines.length > 1) {\n filled++;\n } else {\n missing.push(`${section.label} (내용 미작성)`);\n }\n }\n\n const warnings: string[] = [];\n if (content.length < 200) {\n warnings.push('PRD가 너무 짧습니다. 최소 각 섹션별 2-3줄 이상 작성을 권장합니다.');\n }\n\n return {\n complete: missing.length === 0,\n totalSections: REQUIRED_SECTIONS.length,\n filledSections: filled,\n missing,\n warnings,\n };\n}\n","/**\n * OMC — Object Model Context 관리\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport async function initOMC(cwd: string, projectName: string): Promise<void> {\n const paiDir = join(cwd, '.pai');\n await fs.ensureDir(paiDir);\n\n const omcPath = join(paiDir, 'omc.md');\n if (await fs.pathExists(omcPath)) {\n ui.info('.pai/omc.md 이미 존재 — 건너뜀');\n return;\n }\n\n await fs.writeFile(omcPath, [\n `# OMC — Object Model Context (${projectName})`,\n '', '> AI가 이 프로젝트의 도메인을 이해하기 위한 핵심 객체 모델',\n '', '## 도메인 객체',\n '', '### User', '```', 'id: string', 'email: string', 'role: \"admin\" | \"member\"', '```',\n '', '## 관계 (Relations)', '- User → (owns) → Project',\n '', '## 비즈니스 규칙', '- (여기에 핵심 비즈니스 로직을 기술)',\n '', '## 용어 사전 (Glossary)', '| 용어 | 정의 |', '|------|------|',\n ].join('\\n') + '\\n');\n\n ui.success('OMC 템플릿 생성 → .pai/omc.md');\n}\n","import * as ui from '../../ui/index.js';\nimport { initOpenSpec, validateOpenSpec } from '../../stages/design/openspec.js';\nimport { initOMC } from '../../stages/design/omc.js';\nimport { loadConfig } from '../../core/config.js';\nimport { basename } from 'node:path';\n\nexport async function designInitCommand(cwd: string): Promise<void> {\n ui.section('설계 템플릿 생성');\n const config = await loadConfig(cwd);\n const projectName = config?.projectName ?? basename(cwd);\n\n await initOpenSpec(cwd, projectName);\n await initOMC(cwd, projectName);\n\n ui.info('');\n ui.info('다음 단계: docs/openspec.md를 열어 PRD를 작성하세요.');\n}\n\nexport async function designValidateCommand(cwd: string): Promise<void> {\n ui.section('PRD 완성도 검증');\n\n const result = await validateOpenSpec(cwd);\n\n ui.info(`섹션 완성도: ${result.filledSections}/${result.totalSections}`);\n\n if (result.missing.length > 0) {\n console.log('');\n ui.warn('미작성 섹션:');\n for (const m of result.missing) {\n ui.warn(` - ${m}`);\n }\n }\n\n for (const w of result.warnings) {\n ui.warn(w);\n }\n\n if (result.complete) {\n console.log('');\n ui.success('PRD 완성도 검증 통과!');\n } else {\n console.log('');\n ui.info('docs/openspec.md를 열어 미작성 섹션을 채워주세요.');\n }\n}\n","/**\n * Validation Runner — gstack 설정 기반 테스트 실행\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport interface TestRunResult {\n runner: string;\n passed: boolean;\n output: string;\n duration: number;\n}\n\nexport async function runTests(cwd: string): Promise<TestRunResult> {\n const start = Date.now();\n\n // Read gstack config\n const gstackPath = join(cwd, '.pai', 'gstack.json');\n let runner = 'npm test';\n\n if (await fs.pathExists(gstackPath)) {\n try {\n const config = await fs.readJson(gstackPath);\n if (config.testRunner === 'vitest') runner = 'npx vitest run';\n else if (config.testRunner === 'jest') runner = 'npx jest';\n else if (config.testRunner === 'mocha') runner = 'npx mocha';\n } catch {\n // use default\n }\n }\n\n // Check if test script exists\n const pkgPath = join(cwd, 'package.json');\n if (await fs.pathExists(pkgPath)) {\n try {\n const pkg = await fs.readJson(pkgPath);\n if (!pkg.scripts?.test || pkg.scripts.test.includes('no test specified')) {\n return {\n runner,\n passed: false,\n output: '테스트 스크립트가 정의되지 않았습니다. package.json의 scripts.test를 설정하세요.',\n duration: Date.now() - start,\n };\n }\n } catch {\n // continue\n }\n }\n\n try {\n const { execa } = await import('execa');\n const { stdout, stderr } = await execa('npm', ['test'], {\n cwd,\n timeout: 120000,\n env: { ...process.env, CI: 'true' },\n });\n return {\n runner,\n passed: true,\n output: stdout || stderr,\n duration: Date.now() - start,\n };\n } catch (err) {\n const output = err instanceof Error ? err.message : String(err);\n return {\n runner,\n passed: false,\n output,\n duration: Date.now() - start,\n };\n }\n}\n","/**\n * Harness — OpenSpec ↔ 구현 일치 검증\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\n\nexport interface HarnessResult {\n enabled: boolean;\n specFile: string | null;\n rules: string[];\n checks: Array<{ rule: string; passed: boolean; detail: string }>;\n}\n\nexport async function runHarnessCheck(cwd: string): Promise<HarnessResult> {\n const harnessPath = join(cwd, '.pai', 'harness.json');\n\n if (!(await fs.pathExists(harnessPath))) {\n return { enabled: false, specFile: null, rules: [], checks: [] };\n }\n\n let config: { specFile?: string; rules?: string[] };\n try {\n config = await fs.readJson(harnessPath);\n } catch {\n return { enabled: false, specFile: null, rules: [], checks: [] };\n }\n\n const specFile = config.specFile ?? 'docs/openspec.md';\n const rules = config.rules ?? [];\n const checks: HarnessResult['checks'] = [];\n\n // Rule: spec-implementation-match\n if (rules.includes('spec-implementation-match')) {\n const specExists = await fs.pathExists(join(cwd, specFile));\n const srcExists = await fs.pathExists(join(cwd, 'src'));\n checks.push({\n rule: 'spec-implementation-match',\n passed: specExists && srcExists,\n detail: specExists && srcExists\n ? '설계 문서와 소스 디렉토리 존재'\n : `${!specExists ? specFile + ' 없음' : ''} ${!srcExists ? 'src/ 없음' : ''}`.trim(),\n });\n }\n\n // Rule: api-contract-test\n if (rules.includes('api-contract-test')) {\n const testDir = await fs.pathExists(join(cwd, 'tests'));\n const testDir2 = await fs.pathExists(join(cwd, 'test'));\n checks.push({\n rule: 'api-contract-test',\n passed: testDir || testDir2,\n detail: testDir || testDir2\n ? '테스트 디렉토리 존재'\n : '테스트 디렉토리(tests/ 또는 test/) 없음',\n });\n }\n\n return { enabled: true, specFile, rules, checks };\n}\n","import * as ui from '../../ui/index.js';\nimport { runTests } from '../../stages/validation/runner.js';\nimport { runHarnessCheck } from '../../stages/validation/harness.js';\n\nexport async function validateCommand(cwd: string): Promise<void> {\n // 1. Tests\n ui.section('테스트 실행');\n const testResult = await runTests(cwd);\n\n if (testResult.passed) {\n ui.success(`테스트 통과 (${testResult.runner}, ${testResult.duration}ms)`);\n } else {\n ui.error('테스트 실패');\n ui.info(testResult.output.slice(0, 300));\n }\n\n // 2. Harness\n ui.section('하네스 검증');\n const harness = await runHarnessCheck(cwd);\n\n if (!harness.enabled) {\n ui.info('Harness 설정 없음 — 건너뜀');\n ui.info('설정 추가: `pai env setup` 에서 Harness Engineering 선택');\n } else {\n for (const check of harness.checks) {\n if (check.passed) {\n ui.success(`${check.rule}: ${check.detail}`);\n } else {\n ui.warn(`${check.rule}: ${check.detail}`);\n }\n }\n }\n\n // Summary\n const allPassed = testResult.passed && harness.checks.every((c) => c.passed);\n console.log('');\n if (allPassed) {\n ui.success('검증 통과!');\n } else if (!testResult.passed) {\n ui.error('검증 실패 — 테스트를 수정하세요.');\n process.exitCode = 1;\n } else {\n ui.warn('부분 통과 — 하네스 검증 항목을 확인하세요.');\n }\n}\n","/**\n * `pai test` — 테스트/검증 (구 `pai validate`).\n */\nexport { validateCommand as testCommand } from './validate.cmd.js';\n","/**\n * `pai grade` — 품질 평가 (구 `pai evaluate`).\n */\nexport { evaluateCommand as gradeCommand } from './evaluate.cmd.js';\n","/**\n * Pipeline Context — 불변 실행 컨텍스트\n */\nimport type { StageName, StageResult, PaiConfig } from '../core/types/index.js';\n\nexport class PipelineContext {\n private readonly results = new Map<StageName, StageResult>();\n\n constructor(\n public readonly cwd: string,\n public readonly config: PaiConfig,\n ) {}\n\n setResult(name: StageName, result: StageResult): void {\n this.results.set(name, result);\n }\n\n getResults(): ReadonlyMap<StageName, StageResult> {\n return this.results;\n }\n\n getResult(name: StageName): StageResult | undefined {\n return this.results.get(name);\n }\n}\n","/**\n * Design Stage — 파이프라인 2단계\n * OpenSpec/OMC 기반 설계 관리\n * Production 모드에서 PRD 생성 시 Harness 자동 설치\n */\nimport { join } from 'node:path';\nimport fs from 'fs-extra';\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { initOpenSpec, validateOpenSpec } from './openspec.js';\nimport { initOMC } from './omc.js';\nimport { withSpinner, sleep } from '../../ui/progress.js';\nimport * as ui from '../../ui/index.js';\n\nexport const designStage: Stage = {\n name: 'design',\n\n canSkip(input: StageInput): boolean {\n return input.config.plugins.includes('openspec') && input.config.plugins.includes('omc');\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const artifacts: string[] = [];\n const errors: StageResult['errors'] = [];\n\n try {\n const projectName = input.config.projectName;\n\n // Generate templates with spinner\n await withSpinner('설계 템플릿 생성 중...', async () => {\n await initOpenSpec(input.cwd, projectName);\n await initOMC(input.cwd, projectName);\n await sleep(300);\n });\n\n // Auto-install harness for production mode\n if (input.config.mode === 'production') {\n await autoInstallHarness(input.cwd);\n }\n\n // Validate\n console.log('');\n ui.section('PRD 완성도 검증');\n const validation = await validateOpenSpec(input.cwd);\n\n ui.info(`섹션 완성도: ${validation.filledSections}/${validation.totalSections}`);\n\n if (validation.missing.length > 0) {\n ui.warn('미작성 섹션:');\n for (const m of validation.missing) {\n ui.warn(` - ${m}`);\n }\n }\n\n for (const w of validation.warnings) {\n ui.warn(w);\n }\n\n if (validation.complete) {\n ui.success('PRD 완성도 검증 통과!');\n }\n\n return {\n stage: 'design',\n status: validation.complete ? 'success' : 'partial',\n data: { validation },\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'DESIGN_FAILED', message: msg, recoverable: true });\n return {\n stage: 'design',\n status: 'failed',\n data: {},\n artifacts,\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nasync function autoInstallHarness(cwd: string): Promise<void> {\n const harnessPath = join(cwd, '.pai', 'harness.json');\n if (await fs.pathExists(harnessPath)) return;\n\n await withSpinner('Harness Engineering 자동 설정 중...', async () => {\n await fs.ensureDir(join(cwd, '.pai'));\n await fs.writeJson(harnessPath, {\n version: '1.0',\n specFile: 'docs/openspec.md',\n checkOn: ['pre-commit', 'ci'],\n rules: ['spec-implementation-match', 'api-contract-test'],\n }, { spaces: 2 });\n await sleep(400);\n });\n\n ui.success('Production 모드 감지 → Harness 자동 설치 완료');\n}\n\nexport { initOpenSpec, validateOpenSpec } from './openspec.js';\nexport { initOMC } from './omc.js';\n","/**\n * Execution Stage — 파이프라인 3단계\n * OMC 기반 AI 코드 생성 (Claude Code에 위임)\n * 이 단계는 얇은 래퍼 — 실제 코드 생성은 사용자가 Claude Code로 수행\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport * as ui from '../../ui/index.js';\n\nexport const executionStage: Stage = {\n name: 'execution',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n\n ui.section('실행 단계');\n ui.info('이 단계는 Claude Code를 통해 수행합니다.');\n ui.info('OMC(.pai/omc.md)와 OpenSpec(docs/openspec.md)을 기반으로');\n ui.info('Claude Code에서 코드를 생성하세요.');\n ui.info('');\n ui.info('팁: Claude Code에서 다음 명령어를 사용하세요:');\n ui.info(' /pai design validate — PRD 기반 구현 검증');\n\n return {\n stage: 'execution',\n status: 'skipped',\n data: { message: 'Delegated to Claude Code' },\n artifacts: [],\n duration: Date.now() - start,\n errors: [],\n };\n },\n};\n","/**\n * Validation Stage — 파이프라인 4단계\n * gstack 테스트 + harness 검증\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { runTests } from './runner.js';\nimport { runHarnessCheck } from './harness.js';\nimport * as ui from '../../ui/index.js';\n\nexport const validationStage: Stage = {\n name: 'validation',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const errors: StageResult['errors'] = [];\n\n // 1. Run tests\n ui.section('테스트 실행');\n const testResult = await runTests(input.cwd);\n\n if (testResult.passed) {\n ui.success(`테스트 통과 (${testResult.runner}, ${testResult.duration}ms)`);\n } else {\n ui.error(`테스트 실패: ${testResult.output.slice(0, 200)}`);\n errors.push({ code: 'TEST_FAILED', message: testResult.output.slice(0, 500), recoverable: true });\n }\n\n // 2. Harness check\n ui.section('하네스 검증');\n const harness = await runHarnessCheck(input.cwd);\n\n if (!harness.enabled) {\n ui.info('Harness 설정 없음 (.pai/harness.json) — 건너뜀');\n } else {\n for (const check of harness.checks) {\n if (check.passed) {\n ui.success(`${check.rule}: ${check.detail}`);\n } else {\n ui.warn(`${check.rule}: ${check.detail}`);\n }\n }\n }\n\n const allPassed = testResult.passed && harness.checks.every((c) => c.passed);\n\n return {\n stage: 'validation',\n status: allPassed ? 'success' : testResult.passed ? 'partial' : 'failed',\n data: { testResult, harness },\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n },\n};\n\nexport { runTests } from './runner.js';\nexport { runHarnessCheck } from './harness.js';\n","/**\n * Evaluation Stage — 파이프라인 5단계\n * vibe-ready-cli 6카테고리 가중 점수 시스템\n */\nimport type { Stage, StageInput, StageResult } from '../../core/types/index.js';\nimport { analyzeRepository } from './analyzer.js';\nimport { computeResult } from './scorer.js';\nimport { getCachedResult, setCachedResult } from './cache.js';\nimport { printReport, printVerboseFindings, buildMarkdownReport, buildDetailedReport } from './reporter.js';\nimport * as ui from '../../ui/index.js';\n\nexport interface EvaluateOptions {\n failUnder?: number;\n verbose?: boolean;\n output?: string;\n cache?: boolean;\n}\n\nexport const evaluationStage: Stage = {\n name: 'evaluation',\n\n canSkip(): boolean {\n return false;\n },\n\n async run(input: StageInput): Promise<StageResult> {\n const start = Date.now();\n const errors: StageResult['errors'] = [];\n\n try {\n ui.section('AI 품질 평가');\n\n const llmOutput = await analyzeRepository(input.cwd);\n const result = computeResult(llmOutput);\n\n printReport(result);\n\n return {\n stage: 'evaluation',\n status: result.totalGrade === 'F' ? 'failed' : 'success',\n data: { result },\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n errors.push({ code: 'EVAL_FAILED', message: msg, recoverable: true });\n return {\n stage: 'evaluation',\n status: 'failed',\n data: {},\n artifacts: [],\n duration: Date.now() - start,\n errors,\n };\n }\n },\n};\n\nexport async function runEvaluation(cwd: string, options: EvaluateOptions = {}): Promise<void> {\n const useCache = options.cache !== false;\n\n // Try cache first\n let llmOutput = useCache ? getCachedResult(cwd) : null;\n if (llmOutput) {\n ui.info('캐시된 결과 사용 (24시간 이내)');\n } else {\n llmOutput = await analyzeRepository(cwd);\n if (useCache) {\n setCachedResult(cwd, llmOutput);\n }\n }\n\n const result = computeResult(llmOutput);\n\n // Print report\n printReport(result);\n\n if (options.verbose) {\n printVerboseFindings(result);\n }\n\n // Save to file\n if (options.output) {\n const fs = await import('fs-extra');\n const markdown = buildMarkdownReport(result);\n await fs.writeFile(options.output, markdown, 'utf8');\n ui.success(`리포트 저장: ${options.output}`);\n }\n\n // Fail-under check\n if (options.failUnder && result.totalScore < options.failUnder) {\n ui.error(`점수 ${result.totalScore}이 최소 기준 ${options.failUnder}에 미달합니다.`);\n process.exitCode = 1;\n }\n}\n\nexport { computeResult } from './scorer.js';\nexport { analyzeRepository } from './analyzer.js';\n","/**\n * Pipeline Runner — 5단계 순차 실행\n */\nimport type { Stage, StageName, StageInput, StageResult, PaiConfig } from '../core/types/index.js';\nimport { STAGE_ORDER } from '../core/types/index.js';\nimport { PipelineContext } from './context.js';\nimport { environmentStage } from '../stages/environment/index.js';\nimport { designStage } from '../stages/design/index.js';\nimport { executionStage } from '../stages/execution/index.js';\nimport { validationStage } from '../stages/validation/index.js';\nimport { evaluationStage } from '../stages/evaluation/index.js';\nimport * as ui from '../ui/index.js';\n\nconst STAGES: Record<StageName, Stage> = {\n environment: environmentStage,\n design: designStage,\n execution: executionStage,\n validation: validationStage,\n evaluation: evaluationStage,\n};\n\nexport interface PipelineOptions {\n from?: StageName;\n only?: StageName[];\n}\n\nexport async function runPipeline(\n cwd: string,\n config: PaiConfig,\n options: PipelineOptions = {},\n): Promise<Map<StageName, StageResult>> {\n const ctx = new PipelineContext(cwd, config);\n\n // Determine which stages to run\n let stagesToRun: StageName[];\n\n if (options.only) {\n stagesToRun = STAGE_ORDER.filter((s) => options.only!.includes(s));\n } else if (options.from) {\n const fromIdx = STAGE_ORDER.indexOf(options.from);\n stagesToRun = STAGE_ORDER.slice(fromIdx >= 0 ? fromIdx : 0);\n } else {\n stagesToRun = [...STAGE_ORDER];\n }\n\n ui.section(`파이프라인 실행 (${stagesToRun.length}단계)`);\n ui.info(`단계: ${stagesToRun.join(' → ')}`);\n\n const startTime = Date.now();\n\n let shouldStop = false;\n\n for (const stageName of stagesToRun) {\n const stage = STAGES[stageName];\n\n console.log('');\n ui.section(`[${STAGE_ORDER.indexOf(stageName) + 1}/${STAGE_ORDER.length}] ${stageName.toUpperCase()}`);\n\n const input: StageInput = {\n cwd,\n config,\n previousResults: ctx.getResults(),\n };\n\n // Check if stage can be skipped\n if (stage.canSkip(input)) {\n ui.info(`${stageName} — 건너뜀 (이미 완료)`);\n ctx.setResult(stageName, {\n stage: stageName,\n status: 'skipped',\n data: {},\n artifacts: [],\n duration: 0,\n errors: [],\n });\n continue;\n }\n\n const result = await stage.run(input);\n ctx.setResult(stageName, result);\n\n // Report stage result\n switch (result.status) {\n case 'success':\n ui.success(`${stageName} 완료 (${result.duration}ms)`);\n break;\n case 'partial':\n ui.warn(`${stageName} 부분 완료 (${result.duration}ms)`);\n break;\n case 'failed':\n ui.error(`${stageName} 실패 (${result.duration}ms)`);\n for (const err of result.errors) {\n ui.error(` ${err.message}`);\n }\n if (!result.errors.some((e) => e.recoverable)) {\n ui.error('복구 불가능한 오류 — 파이프라인 중단');\n shouldStop = true;\n }\n break;\n case 'skipped':\n ui.info(`${stageName} 건너뜀`);\n break;\n }\n\n if (shouldStop) break;\n }\n\n // Summary\n const totalDuration = Date.now() - startTime;\n console.log('');\n ui.section('파이프라인 요약');\n\n for (const stageName of stagesToRun) {\n const result = ctx.getResult(stageName);\n if (!result) continue;\n\n const icon =\n result.status === 'success' ? '✓' :\n result.status === 'partial' ? '△' :\n result.status === 'skipped' ? '○' : '✗';\n\n ui.info(`${icon} ${stageName.padEnd(14)} ${result.status} (${result.duration}ms)`);\n }\n\n console.log('');\n ui.info(`총 소요 시간: ${totalDuration}ms`);\n\n return ctx.getResults() as Map<StageName, StageResult>;\n}\n","import * as ui from '../../ui/index.js';\nimport { runPipeline, type PipelineOptions } from '../../pipeline/index.js';\nimport { loadConfig, createDefaultConfig } from '../../core/config.js';\nimport type { StageName } from '../../core/types/index.js';\nimport { printBanner } from '../../ui/index.js';\n\nexport interface PipelineCLIOptions {\n from?: string;\n only?: string;\n}\n\nexport async function pipelineCommand(cwd: string, options: PipelineCLIOptions): Promise<void> {\n printBanner();\n\n const config = (await loadConfig(cwd)) ?? createDefaultConfig('my-project', 'mockup');\n\n const pipelineOpts: PipelineOptions = {};\n\n if (options.from) {\n pipelineOpts.from = options.from as StageName;\n }\n\n if (options.only) {\n pipelineOpts.only = options.only.split(',').map((s) => s.trim()) as StageName[];\n }\n\n await runPipeline(cwd, config, pipelineOpts);\n}\n","/**\n * `pai run` — 전체 파이프라인 (구 `pai pipeline`).\n */\nexport { pipelineCommand as runCommand } from './pipeline.cmd.js';\n","import { basename, dirname } from 'node:path';\nimport fs from 'fs-extra';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\nimport { loadConfig } from '../../core/config.js';\n\nexport async function removeCommand(cwd: string, options: { force?: boolean }): Promise<void> {\n ui.section('프로젝트 삭제');\n\n // PAI 프로젝트인지 확인\n const config = await loadConfig(cwd);\n if (!config) {\n ui.error('PAI 프로젝트가 아닙니다.');\n ui.hint('.pai/config.json 을 찾을 수 없습니다.');\n return;\n }\n\n const folderName = basename(cwd);\n const parentDir = dirname(cwd);\n\n console.log('');\n if (config.version) {\n ui.info(`PAI v${config.version} 으로 설치된 프로젝트`);\n }\n console.log(c.err(` ${folderName}/ 폴더 전체가 삭제됩니다.`));\n ui.hint('이 작업은 되돌릴 수 없습니다.');\n console.log('');\n\n // 삭제할 내용 미리보기\n const items = await fs.readdir(cwd);\n const fileCount = items.filter((i) => !i.startsWith('.')).length;\n const hiddenCount = items.filter((i) => i.startsWith('.')).length;\n ui.info(`파일/폴더 ${fileCount}개, 숨김 항목 ${hiddenCount}개`);\n console.log('');\n\n if (!options.force) {\n const { default: inquirer } = await import('inquirer');\n const { confirmName } = await inquirer.prompt([{\n type: 'input',\n name: 'confirmName',\n message: `삭제하려면 프로젝트 이름을 입력하세요 (${folderName}):`,\n }]);\n\n if (confirmName.trim() !== folderName) {\n ui.info('이름이 일치하지 않습니다. 삭제를 취소합니다.');\n return;\n }\n }\n\n // 부모 디렉토리로 이동 후 폴더 삭제\n process.chdir(parentDir);\n\n try {\n await fs.remove(cwd);\n console.log('');\n ui.success(`${folderName}/ 프로젝트가 삭제되었습니다.`);\n\n // 쉘 헬퍼를 통해 부모 디렉토리로 자동 이동\n try {\n const { requestCdAfter } = await import('../../utils/shell-cd.js');\n await requestCdAfter(parentDir);\n } catch {\n // shell-cd not available\n }\n } catch (err) {\n const msg = err instanceof Error ? err.message : String(err);\n ui.error(`삭제 실패: ${msg}`);\n return;\n }\n\n // 새 프로젝트 생성 제안\n console.log('');\n const { default: inquirer } = await import('inquirer');\n const { createNew } = await inquirer.prompt([{\n type: 'confirm',\n name: 'createNew',\n message: '새로운 프로젝트를 만드시겠습니까?',\n default: true,\n }]);\n\n if (createNew) {\n const { initCommand } = await import('./init.cmd.js');\n await initCommand(process.cwd());\n } else {\n // 상위 폴더에서 서브쉘 시작 — 사용자 터미널이 실제로 이동\n console.log('');\n ui.success(`→ cd .. ${c.dim('상위 폴더로 이동')}`);\n const { spawnSubshell } = await import('../../utils/platform.js');\n spawnSubshell(parentDir);\n }\n}\n","export class PaiError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly recoverable: boolean = false,\n ) {\n super(message);\n this.name = 'PaiError';\n }\n}\n\nexport class StageExecutionError extends PaiError {\n constructor(\n public readonly stageName: string,\n message: string,\n recoverable = false,\n ) {\n super(message, `STAGE_${stageName.toUpperCase()}_ERROR`, recoverable);\n this.name = 'StageExecutionError';\n }\n}\n\nexport class ConfigNotFoundError extends PaiError {\n constructor(path: string) {\n super(\n `.pai/config.json not found at ${path}. Run 'pai init' first.`,\n 'CONFIG_NOT_FOUND',\n true,\n );\n this.name = 'ConfigNotFoundError';\n }\n}\n","import { createRequire } from 'node:module';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { loadConfig, saveConfig } from '../../core/config.js';\nimport { upgradeClaudeCommands } from '../../stages/environment/provisioners/claude-commands.js';\nimport { ConfigNotFoundError } from '../../core/errors.js';\nimport { withSpinner, sleep } from '../../ui/progress.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nfunction compareSemver(a: string, b: string): -1 | 0 | 1 {\n const pa = a.split('.').map(Number);\n const pb = b.split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n const na = pa[i] ?? 0;\n const nb = pb[i] ?? 0;\n if (na < nb) return -1;\n if (na > nb) return 1;\n }\n return 0;\n}\n\nexport async function upgradeCommand(\n cwd: string,\n options: { force?: boolean },\n): Promise<void> {\n ui.section('PAI 업그레이드');\n\n // 1. Load config\n const config = await loadConfig(cwd);\n if (!config) {\n throw new ConfigNotFoundError(cwd);\n }\n\n const currentVersion = pkg.version;\n const configVersion = config.version;\n\n console.log('');\n console.log(` 현재 버전: ${chalk.gray(`v${configVersion}`)}`);\n console.log(` 최신 버전: ${chalk.cyan(`v${currentVersion}`)}`);\n\n // 2. Version check\n if (!options.force && compareSemver(configVersion, currentVersion) >= 0) {\n console.log('');\n ui.success('이미 최신 버전입니다.');\n ui.info('강제 업그레이드: npx pai-zero upgrade --force');\n return;\n }\n\n // 3. Upgrade files\n console.log('');\n const result = await withSpinner('슬래시 커맨드 & 스킬 업그레이드 중...', async () => {\n const r = await upgradeClaudeCommands(cwd);\n await sleep(400);\n return r;\n });\n\n // 4. Report\n console.log('');\n if (result.skillUpdated) {\n ui.success('SKILL.md 업데이트');\n }\n if (result.commandsWritten.length > 0) {\n ui.success(`슬래시 커맨드 ${result.commandsWritten.length}개 업데이트`);\n for (const f of result.commandsWritten) {\n console.log(chalk.gray(` ${f}`));\n }\n }\n\n // 5. Error check\n if (result.commandErrors.length > 0) {\n console.log('');\n for (const e of result.commandErrors) {\n ui.error(`${e.file}: ${e.error}`);\n }\n ui.error('일부 파일 업데이트 실패. config.version을 변경하지 않습니다.');\n ui.info('문제 해결 후 다시 실행: npx pai-zero upgrade --force');\n return;\n }\n\n // 6. Update config version only after all writes succeed\n config.version = currentVersion;\n await saveConfig(cwd, config);\n\n console.log('');\n ui.success(`v${configVersion} → v${currentVersion} 업그레이드 완료!`);\n console.log('');\n}\n","/**\n * SaveToken — AI 토큰 절감 분석기\n * 프로젝트의 AI API 호출을 스캔하고 스크립트 대체 가능성을 분석\n */\nimport { join, relative } from 'node:path';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\ninterface CallSite {\n file: string;\n line: number;\n content: string;\n sdk: string;\n category: 'import' | 'api-call' | 'fetch';\n}\n\nconst SCAN_PATTERNS: Array<{ pattern: string; sdk: string; category: CallSite['category'] }> = [\n // SDK imports\n { pattern: '@anthropic-ai/sdk', sdk: 'Anthropic', category: 'import' },\n { pattern: '@anthropic-ai/claude-agent-sdk', sdk: 'Claude Agent SDK', category: 'import' },\n { pattern: \"from 'openai'\", sdk: 'OpenAI', category: 'import' },\n { pattern: 'from \"openai\"', sdk: 'OpenAI', category: 'import' },\n { pattern: '@google/generative-ai', sdk: 'Google AI', category: 'import' },\n { pattern: 'cohere-ai', sdk: 'Cohere', category: 'import' },\n { pattern: 'langchain', sdk: 'LangChain', category: 'import' },\n // API calls\n { pattern: 'messages.create', sdk: 'Anthropic', category: 'api-call' },\n { pattern: 'chat.completions.create', sdk: 'OpenAI', category: 'api-call' },\n { pattern: 'generateContent', sdk: 'Google AI', category: 'api-call' },\n { pattern: 'completions.create', sdk: 'OpenAI', category: 'api-call' },\n // Fetch to AI APIs\n { pattern: 'api.anthropic.com', sdk: 'Anthropic', category: 'fetch' },\n { pattern: 'api.openai.com', sdk: 'OpenAI', category: 'fetch' },\n { pattern: 'generativelanguage.googleapis.com', sdk: 'Google AI', category: 'fetch' },\n];\n\nexport async function savetokenCommand(cwd: string): Promise<void> {\n const { createSpinner } = await import('../../ui/progress.js');\n\n console.log('');\n ui.section('SaveToken — AI 토큰 절감 분석');\n console.log('');\n\n const spinner = createSpinner('프로젝트 스캔 중...');\n const callSites = await scanProject(cwd);\n spinner.succeed(`스캔 완료 — ${callSites.length}건 발견`);\n\n if (callSites.length === 0) {\n console.log('');\n ui.info('AI API 호출이 발견되지 않았습니다.');\n ui.hint('이 프로젝트에는 AI SDK 사용이 없거나, 지원하지 않는 패턴입니다.');\n return;\n }\n\n // Group by category\n const imports = callSites.filter(s => s.category === 'import');\n const apiCalls = callSites.filter(s => s.category === 'api-call');\n const fetchCalls = callSites.filter(s => s.category === 'fetch');\n\n // Group by SDK\n const sdks = [...new Set(callSites.map(s => s.sdk))];\n\n // Print summary\n console.log('');\n console.log(c.dim(' 사용 중인 AI SDK'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const sdk of sdks) {\n const count = callSites.filter(s => s.sdk === sdk).length;\n console.log(` ${chalk.cyan(sdk.padEnd(20))} ${chalk.white(String(count))}건`);\n }\n\n if (imports.length > 0) {\n console.log('');\n console.log(c.dim(' SDK 임포트'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of imports) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n if (apiCalls.length > 0) {\n console.log('');\n console.log(c.dim(' AI API 호출 지점'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of apiCalls) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))} ${chalk.cyan(site.sdk)}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n if (fetchCalls.length > 0) {\n console.log('');\n console.log(c.dim(' Fetch 기반 AI 호출'));\n console.log(c.dim(' ─────────────────────────────'));\n for (const site of fetchCalls) {\n console.log(` ${c.dim(site.file)}:${chalk.yellow(String(site.line))} ${chalk.cyan(site.sdk)}`);\n console.log(` ${site.content.trim().substring(0, 80)}`);\n }\n }\n\n // Estimate & impact summary\n const totalApiPoints = apiCalls.length + fetchCalls.length;\n console.log('');\n console.log(c.accent(' 절감 가능성 추정'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` 총 API 호출 지점 ${chalk.white(String(totalApiPoints))}건`);\n console.log(` 분석 필요 ${chalk.yellow('Claude Code에서 심층 분석 필요')}`);\n console.log('');\n console.log(c.dim(' 영향도별 대체 전략'));\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` ${chalk.green('●')} 낮음 텍스트 포맷팅, 유효성 검증, 템플릿 생성`);\n console.log(` → ${c.dim('regex, JSON schema, 템플릿 엔진으로 즉시 대체')}`);\n console.log(` ${chalk.yellow('●')} 중간 데이터 분류, 요약, 간단한 추출`);\n console.log(` → ${c.dim('룰 기반 로직, 키워드 매칭으로 검토 후 대체')}`);\n console.log(` ${chalk.red('●')} 높음 코드 생성, 복잡한 추론, 창의적 생성`);\n console.log(` → ${c.dim('AI 필수 — 프롬프트 최적화로 토큰 절감')}`);\n\n // Save report\n const reportDir = join(cwd, '.pai');\n await fs.ensureDir(reportDir);\n const report = buildReport(callSites, cwd);\n const reportPath = join(reportDir, 'savetoken-report.md');\n await fs.writeFile(reportPath, report, 'utf8');\n\n console.log('');\n ui.success('스캔 리포트 저장: .pai/savetoken-report.md');\n console.log('');\n ui.hint('심층 분석 + 대체 코드 생성은 Claude Code에서:');\n ui.info(' /pai savetoken');\n}\n\nasync function scanProject(cwd: string): Promise<CallSite[]> {\n const { execa } = await import('execa');\n const results: CallSite[] = [];\n const seen = new Set<string>();\n\n for (const { pattern, sdk, category } of SCAN_PATTERNS) {\n try {\n const { stdout } = await execa('grep', [\n '-rn',\n '--include=*.ts', '--include=*.tsx', '--include=*.js', '--include=*.jsx',\n '--include=*.py', '--include=*.java', '--include=*.go', '--include=*.rs',\n '--exclude-dir=node_modules', '--exclude-dir=dist', '--exclude-dir=.git',\n '--exclude-dir=build', '--exclude-dir=__pycache__', '--exclude-dir=.next',\n '--exclude-dir=.claude', '--exclude=savetoken.cmd.*',\n '--exclude=claude-commands.*',\n pattern, cwd,\n ]);\n\n for (const line of stdout.split('\\n').filter(Boolean)) {\n const match = line.match(/^(.+?):(\\d+):(.+)$/);\n if (!match) continue;\n\n const file = relative(cwd, match[1]!);\n const lineNum = parseInt(match[2]!);\n const content = match[3]!;\n const key = `${file}:${lineNum}`;\n\n if (seen.has(key)) continue;\n seen.add(key);\n\n results.push({ file, line: lineNum, content, sdk, category });\n }\n } catch {\n // grep exit 1 = no matches, expected\n }\n }\n\n return results.sort((a, b) => a.file.localeCompare(b.file) || a.line - b.line);\n}\n\nfunction buildReport(callSites: CallSite[], cwd: string): string {\n const imports = callSites.filter(s => s.category === 'import');\n const apiCalls = callSites.filter(s => s.category === 'api-call');\n const fetchCalls = callSites.filter(s => s.category === 'fetch');\n const sdks = [...new Set(callSites.map(s => s.sdk))];\n const totalApiPoints = apiCalls.length + fetchCalls.length;\n\n const lines: string[] = [\n '# PAI SaveToken — AI 토큰 절감 분석 리포트',\n '',\n `> 생성일: ${new Date().toISOString().slice(0, 10)}`,\n `> 프로젝트: ${cwd}`,\n '',\n '## 요약',\n '',\n `| 항목 | 건수 |`,\n `|------|------|`,\n `| SDK 임포트 | ${imports.length} |`,\n `| API 호출 지점 | ${apiCalls.length} |`,\n `| Fetch 기반 호출 | ${fetchCalls.length} |`,\n `| **합계** | **${callSites.length}** |`,\n '',\n '## 사용 중인 AI SDK',\n '',\n ];\n\n for (const sdk of sdks) {\n const count = callSites.filter(s => s.sdk === sdk).length;\n lines.push(`- **${sdk}**: ${count}건`);\n }\n\n if (apiCalls.length > 0 || fetchCalls.length > 0) {\n lines.push('', '## API 호출 지점 (대체 대상)', '');\n lines.push('| 파일 | 라인 | SDK | 코드 |');\n lines.push('|------|------|-----|------|');\n for (const site of [...apiCalls, ...fetchCalls]) {\n const code = site.content.trim().substring(0, 60).replace(/\\|/g, '\\\\|');\n lines.push(`| ${site.file} | ${site.line} | ${site.sdk} | \\`${code}\\` |`);\n }\n }\n\n lines.push(\n '',\n '## 영향도별 대체 전략',\n '',\n '### 영향도 낮음 (즉시 대체 가능)',\n '- 텍스트 포맷팅/변환 → regex, string template',\n '- 데이터 유효성 검증 → JSON schema, zod/joi',\n '- 템플릿 기반 생성 → handlebars, ejs',\n '- 고정 분류 → lookup table, switch-case',\n '',\n '### 영향도 중간 (검토 후 대체)',\n '- 텍스트 요약 → extractive 방식 (키워드 추출)',\n '- 간단한 분류 → TF-IDF, 키워드 매칭',\n '- 데이터 추출 → regex, DOM parser',\n '- 번역 (고정 문구) → i18n 파일',\n '',\n '### 영향도 높음 (AI 필수 — 프롬프트 최적화)',\n '- 코드 생성/리팩토링',\n '- 복잡한 추론/분석',\n '- 창의적 콘텐츠 생성',\n '- 멀티턴 대화',\n '',\n '## 다음 단계',\n '',\n `총 ${totalApiPoints}건의 API 호출 지점이 발견되었습니다.`,\n '',\n 'Claude Code에서 `/pai savetoken`을 실행하면:',\n '1. 각 호출의 목적을 AI가 분석합니다',\n '2. 대체 가능한 항목의 스크립트를 자동 생성합니다',\n '3. 영향도별 마이그레이션 계획을 제시합니다',\n '4. 예상 토큰 절감률을 산출합니다',\n '',\n );\n\n return lines.join('\\n');\n}\n","/**\n * Wakeup — Claude Code 세션 자동 시작 + 토큰 윈도우 리셋\n * macOS: launchd + pmset (wake-from-sleep) + osascript (Terminal)\n * Linux: crontab + terminal fallback\n */\nimport { join } from 'node:path';\nimport { homedir, platform as osPlatform } from 'node:os';\nimport fs from 'fs-extra';\nimport chalk from 'chalk';\nimport * as ui from '../../ui/index.js';\nimport { colors as c } from '../../ui/logger.js';\n\nexport type Schedule = '평일' | '매일' | '주말';\n\nconst PAI_DIR = join(homedir(), '.pai');\nconst CONFIG_FILE = join(PAI_DIR, 'wakeup-config.json');\nconst MESSAGES_FILE = join(PAI_DIR, 'wakeup-messages.json');\nconst SCRIPT_FILE = join(PAI_DIR, 'wakeup.sh');\nconst PLIST_NAME = 'com.pai.wakeup';\nconst PLIST_PATH = join(homedir(), 'Library', 'LaunchAgents', `${PLIST_NAME}.plist`);\nconst CRON_MARKER = '# PAI-WAKEUP';\n\ninterface WakeupConfig {\n time: string;\n schedule: Schedule;\n projectDir: string;\n launchMode: 'normal' | 'yolo';\n}\n\nconst MESSAGES: string[] = [\n `Here's to the crazy ones. The misfits. The rebels. The troublemakers.\nThe round pegs in the square holes. The ones who see things differently.\n\nThey're not fond of rules. And they have no respect for the status quo.\n\nYou can praise them, disagree with them, quote them, disbelieve them,\nglorify or vilify them. About the only thing you can't do is ignore them.\nBecause they change things.\n\nThey invent. They imagine. They heal. They explore. They create.\nThey inspire. They push the human race forward.\n\nMaybe they have to be crazy. How else can you stare at an empty canvas\nand see a work of art? Or sit in silence and hear a song that's never\nbeen written? Or gaze at a red planet and see a laboratory on wheels?\n\nBecause the people who are crazy enough to think they can change\nthe world, are the ones who do.\n\n— Think Different`,\n\n `\"Your work is going to fill a large part of your life,\nand the only way to be truly satisfied is to do what you\nbelieve is great work. And the only way to do great work\nis to love what you do.\"\n\n— Steve Jobs`,\n\n `\"The best way to predict the future is to invent it.\"\n\n— Alan Kay`,\n\n `\"Talk is cheap. Show me the code.\"\n\n— Linus Torvalds`,\n\n `\"The most dangerous phrase in the language is,\n'We've always done it this way.'\"\n\n— Grace Hopper`,\n\n `\"Premature optimization is the root of all evil.\"\n\n— Donald Knuth`,\n\n `\"Make it work, make it right, make it fast.\"\n\n— Kent Beck`,\n\n `\"Any fool can write code that a computer can understand.\nGood programmers write code that humans can understand.\"\n\n— Martin Fowler`,\n\n `\"Simplicity is prerequisite for reliability.\"\n\n— Edsger W. Dijkstra`,\n\n `\"First, solve the problem. Then, write the code.\"\n\n— John Johnson`,\n];\n\n// ── Main ────────────────────────────────────────\n\nexport async function wakeupCommand(timeOrAction?: string, schedule: Schedule = '평일'): Promise<void> {\n if (timeOrAction === 'off') {\n await disableWakeup();\n return;\n }\n\n if (timeOrAction === 'status') {\n await showStatus();\n return;\n }\n\n if (!timeOrAction) {\n showMessage();\n return;\n }\n\n // Validate time\n if (!/^\\d{1,2}:\\d{2}$/.test(timeOrAction)) {\n ui.error('시간 형식이 올바르지 않습니다. 예: 06:00, 22:30');\n return;\n }\n\n const [h, m] = timeOrAction.split(':').map(Number);\n if (h! < 0 || h! > 23 || m! < 0 || m! > 59) {\n ui.error('시간 범위를 확인해주세요. (00:00 ~ 23:59)');\n return;\n }\n\n // Interactive setup\n const { default: inquirer } = await import('inquirer');\n\n console.log('');\n const { projectDir } = await inquirer.prompt([{\n type: 'input',\n name: 'projectDir',\n message: 'Claude Code를 시작할 프로젝트 경로:',\n default: process.cwd(),\n }]);\n\n const { launchMode } = await inquirer.prompt([{\n type: 'list',\n name: 'launchMode',\n message: '실행 모드:',\n choices: [\n { name: `claude ${chalk.gray('일반 모드')}`, value: 'normal' },\n { name: `claude --dangerously-skip-permissions ${chalk.gray('claude-YOLO mode')}`, value: 'yolo' },\n ],\n }]);\n\n // Save config & files\n const config: WakeupConfig = {\n time: timeOrAction,\n schedule,\n projectDir,\n launchMode,\n };\n\n await fs.ensureDir(PAI_DIR);\n await fs.writeJson(CONFIG_FILE, config, { spaces: 2 });\n await fs.writeJson(MESSAGES_FILE, MESSAGES);\n await createWakeupScript(config);\n\n // Platform-specific scheduling\n if (osPlatform() === 'darwin') {\n await setupMacOS(config);\n } else if (osPlatform() === 'win32') {\n await setupWindows(config);\n } else {\n await setupLinux(config);\n }\n\n console.log('');\n ui.success('☀️ 웨이크업 설정 완료');\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n console.log(` 시간 ${chalk.white(config.time)}`);\n console.log(` 스케줄 ${chalk.white(scheduleToLabel(config.schedule))}`);\n console.log(` 프로젝트 ${chalk.white(config.projectDir)}`);\n console.log(` 모드 ${chalk.white(config.launchMode === 'yolo' ? 'claude-YOLO mode' : '일반 모드')}`);\n if (osPlatform() === 'darwin') {\n console.log(` 스케줄러 ${chalk.white('launchd + pmset (wake-from-sleep)')}`);\n }\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n ui.hint('해제: pai wakeup off');\n ui.hint('확인: pai wakeup status');\n\n console.log('');\n showMessage();\n}\n\n// ── macOS: launchd + pmset ──────────────────────\n\nasync function setupMacOS(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const [hour, minute] = config.time.split(':').map(Number);\n\n // 1. Create LaunchAgent plist\n const plistDir = join(homedir(), 'Library', 'LaunchAgents');\n await fs.ensureDir(plistDir);\n\n const weekdays = scheduleToWeekdays(config.schedule);\n let calendarEntries: string;\n\n if (weekdays.length === 7) {\n calendarEntries = ` <dict>\n <key>Hour</key><integer>${hour}</integer>\n <key>Minute</key><integer>${minute}</integer>\n </dict>`;\n } else {\n calendarEntries = ` <array>\n${weekdays.map(d => ` <dict>\n <key>Hour</key><integer>${hour}</integer>\n <key>Minute</key><integer>${minute}</integer>\n <key>Weekday</key><integer>${d}</integer>\n </dict>`).join('\\n')}\n </array>`;\n }\n\n const plist = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n <key>Label</key>\n <string>${PLIST_NAME}</string>\n <key>ProgramArguments</key>\n <array>\n <string>/bin/bash</string>\n <string>${SCRIPT_FILE}</string>\n </array>\n <key>StartCalendarInterval</key>\n${calendarEntries}\n <key>StandardOutPath</key>\n <string>${PAI_DIR}/wakeup.log</string>\n <key>StandardErrorPath</key>\n <string>${PAI_DIR}/wakeup.log</string>\n</dict>\n</plist>`;\n\n await fs.writeFile(PLIST_PATH, plist);\n\n // Load LaunchAgent\n await execa('launchctl', ['unload', PLIST_PATH]).catch(() => {});\n await execa('launchctl', ['load', PLIST_PATH]);\n ui.success('launchd 스케줄 등록 완료');\n\n // 2. pmset — wake from sleep\n const pmsetDays = scheduleToPmsetDays(config.schedule);\n console.log('');\n ui.info('Sleep 상태에서도 깨어나려면 관리자 권한이 필요합니다.');\n console.log('');\n\n try {\n await execa('sudo', ['pmset', 'repeat', 'wakeorpoweron', pmsetDays, `${config.time}:00`], {\n stdio: 'inherit',\n });\n ui.success('pmset wake-from-sleep 설정 완료');\n } catch {\n ui.warn('pmset 설정 실패 — sleep 상태에서는 깨어나지 않습니다.');\n ui.hint(`수동 설정: sudo pmset repeat wakeorpoweron ${pmsetDays} ${config.time}:00`);\n }\n}\n\n// ── Windows: Task Scheduler ─────────────────────\n\nasync function setupWindows(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const [hour, minute] = config.time.split(':').map(Number);\n\n // PowerShell wakeup script\n const psScriptDir = join(homedir(), '.pai');\n await fs.ensureDir(psScriptDir);\n const psScriptPath = join(psScriptDir, 'wakeup.ps1');\n\n const claudeCmd = config.launchMode === 'yolo'\n ? 'claude --dangerously-skip-permissions'\n : 'claude';\n\n const psScript = `# PAI Wakeup — Claude Code 세션 자동 시작\n$paiDir = \"$env:USERPROFILE\\\\.pai\"\n$msgFile = Join-Path $paiDir \"wakeup-messages.json\"\n$todayFile = Join-Path $paiDir \"wakeup-today.txt\"\n\n# Pick random message\ntry {\n $msgs = Get-Content $msgFile -Raw | ConvertFrom-Json\n $msg = $msgs[(Get-Random -Maximum $msgs.Count)]\n} catch {\n $msg = \"Make it work, make it right, make it fast. — Kent Beck\"\n}\nSet-Content -Path $todayFile -Value $msg\n\n# Windows notification\n[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null\n$template = [Windows.UI.Notifications.ToastTemplateType]::ToastText02\n$xml = [Windows.UI.Notifications.ToastNotificationManager]::GetTemplateContent($template)\n$text = $xml.GetElementsByTagName(\"text\")\n$text[0].AppendChild($xml.CreateTextNode(\"PAI Wakeup\")) | Out-Null\n$text[1].AppendChild($xml.CreateTextNode($msg.Substring(0, [Math]::Min(100, $msg.Length)))) | Out-Null\n$notifier = [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(\"PAI\")\n$notifier.Show([Windows.UI.Notifications.ToastNotification]::new($xml))\n\n# Open PowerShell with Claude Code\nStart-Process powershell -ArgumentList \"-NoExit\", \"-Command\", \"Get-Content '$todayFile'; Write-Host ''; Set-Location '${config.projectDir}'; ${claudeCmd}\"\n`;\n\n await fs.writeFile(psScriptPath, psScript, 'utf8');\n\n // schtasks — schedule\n const daysMap: Record<string, string> = {\n '평일': 'MON,TUE,WED,THU,FRI',\n '매일': 'MON,TUE,WED,THU,FRI,SAT,SUN',\n '주말': 'SAT,SUN',\n };\n const days = daysMap[config.schedule] || daysMap['평일'];\n\n // Remove existing task\n await execa('schtasks', ['/delete', '/tn', 'PAI-WAKEUP', '/f']).catch(() => {});\n\n try {\n await execa('schtasks', [\n '/create', '/tn', 'PAI-WAKEUP',\n '/tr', `powershell.exe -ExecutionPolicy Bypass -File \"${psScriptPath}\"`,\n '/sc', 'WEEKLY', '/d', days!,\n '/st', `${String(hour).padStart(2, '0')}:${String(minute).padStart(2, '0')}`,\n '/f',\n ]);\n ui.success('Windows Task Scheduler 등록 완료');\n } catch {\n ui.warn('Task Scheduler 등록 실패');\n ui.hint('관리자 권한으로 재시도하거나, 작업 스케줄러에서 직접 등록하세요');\n }\n}\n\n// ── Linux: crontab fallback ─────────────────────\n\nasync function setupLinux(config: WakeupConfig): Promise<void> {\n const { execa } = await import('execa');\n const cronExpr = scheduleToCron(config.time, config.schedule);\n const cronLine = `${cronExpr} ${SCRIPT_FILE} ${CRON_MARKER}`;\n\n await removeCronEntry();\n const existing = await execa('crontab', ['-l']).then(r => r.stdout).catch(() => '');\n const newCrontab = existing.trim() ? `${existing.trim()}\\n${cronLine}\\n` : `${cronLine}\\n`;\n await execa('crontab', ['-'], { input: newCrontab });\n\n ui.success('crontab 스케줄 등록 완료');\n}\n\n// ── Disable ─────────────────────────────────────\n\nasync function disableWakeup(): Promise<void> {\n const { execa } = await import('execa');\n\n if (osPlatform() === 'darwin') {\n await execa('launchctl', ['unload', PLIST_PATH]).catch(() => {});\n await fs.remove(PLIST_PATH).catch(() => {});\n ui.success('launchd 스케줄 제거');\n\n console.log('');\n ui.info('pmset wake-from-sleep 해제에 관리자 권한이 필요합니다.');\n try {\n await execa('sudo', ['pmset', 'repeat', 'cancel'], { stdio: 'inherit' });\n ui.success('pmset wake-from-sleep 해제 완료');\n } catch {\n ui.hint('수동 해제: sudo pmset repeat cancel');\n }\n } else if (osPlatform() === 'win32') {\n try {\n await execa('schtasks', ['/delete', '/tn', 'PAI-WAKEUP', '/f']);\n ui.success('Windows Task Scheduler 제거 완료');\n } catch {\n ui.hint('수동 해제: schtasks /delete /tn PAI-WAKEUP /f');\n }\n } else {\n await removeCronEntry();\n }\n\n await fs.remove(CONFIG_FILE).catch(() => {});\n console.log('');\n ui.success('☀️ 웨이크업 해제 완료');\n}\n\n// ── Status ──────────────────────────────────────\n\nasync function showStatus(): Promise<void> {\n if (await fs.pathExists(CONFIG_FILE)) {\n const config: WakeupConfig = await fs.readJson(CONFIG_FILE);\n\n console.log('');\n ui.success('☀️ 웨이크업 활성화');\n console.log(` 시간 ${chalk.white(config.time)}`);\n console.log(` 스케줄 ${chalk.white(scheduleToLabel(config.schedule))}`);\n console.log(` 프로젝트 ${chalk.white(config.projectDir)}`);\n console.log(` 모드 ${chalk.white(config.launchMode === 'yolo' ? 'claude-YOLO mode' : '일반 모드')}`);\n\n if (osPlatform() === 'darwin') {\n const plistExists = await fs.pathExists(PLIST_PATH);\n console.log(` launchd ${plistExists ? chalk.green('활성') : chalk.red('비활성')}`);\n }\n console.log('');\n } else {\n ui.info('웨이크업이 설정되지 않았습니다.');\n ui.hint('설정: pai wakeup 06:00');\n }\n}\n\n// ── Show Message ────────────────────────────────\n\nfunction showMessage(): void {\n const idx = Math.floor(Math.random() * MESSAGES.length);\n const msg = MESSAGES[idx]!;\n\n console.log(c.dim(' ─────────────────────────────'));\n console.log('');\n for (const line of msg.split('\\n')) {\n console.log(` ${line}`);\n }\n console.log('');\n console.log(c.dim(' ─────────────────────────────'));\n}\n\n// ── Helpers ─────────────────────────────────────\n\nfunction scheduleToLabel(schedule: Schedule): string {\n switch (schedule) {\n case '평일': return '평일 (월-금)';\n case '매일': return '매일';\n case '주말': return '주말 (토-일)';\n }\n}\n\nfunction scheduleToWeekdays(schedule: Schedule): number[] {\n switch (schedule) {\n case '평일': return [1, 2, 3, 4, 5];\n case '매일': return [0, 1, 2, 3, 4, 5, 6];\n case '주말': return [0, 6];\n }\n}\n\nfunction scheduleToPmsetDays(schedule: Schedule): string {\n switch (schedule) {\n case '평일': return 'MTWRF';\n case '매일': return 'MTWRFSU';\n case '주말': return 'SU';\n }\n}\n\nfunction scheduleToCron(time: string, schedule: Schedule): string {\n const [hour, minute] = time.split(':').map(Number);\n switch (schedule) {\n case '평일': return `${minute} ${hour} * * 1-5`;\n case '매일': return `${minute} ${hour} * * *`;\n case '주말': return `${minute} ${hour} * * 0,6`;\n }\n}\n\nasync function removeCronEntry(): Promise<void> {\n try {\n const { execa } = await import('execa');\n const { stdout } = await execa('crontab', ['-l']);\n const filtered = stdout.split('\\n').filter(l => !l.includes(CRON_MARKER)).join('\\n');\n if (filtered.trim()) {\n await execa('crontab', ['-'], { input: `${filtered.trim()}\\n` });\n } else {\n await execa('crontab', ['-r']).catch(() => {});\n }\n } catch {\n // No crontab exists\n }\n}\n\nasync function createWakeupScript(config: WakeupConfig): Promise<void> {\n const claudeCmd = config.launchMode === 'yolo'\n ? 'claude --dangerously-skip-permissions'\n : 'claude';\n\n const script = `#!/bin/bash\n# PAI Wakeup — Claude Code 세션 자동 시작\n# 설정 시간에 맥을 깨우고 터미널에서 Claude Code를 시작합니다\nPAI_DIR=\"$HOME/.pai\"\nMSG_FILE=\"$PAI_DIR/wakeup-messages.json\"\nTODAY_FILE=\"$PAI_DIR/wakeup-today.txt\"\nLOG_FILE=\"$PAI_DIR/wakeup.log\"\n\necho \"[$(date)] PAI Wakeup triggered\" >> \"$LOG_FILE\"\n\n# Pick random message via Node.js\nMSG=$(node -e \"\nconst fs = require('fs');\ntry {\n const msgs = JSON.parse(fs.readFileSync('$MSG_FILE', 'utf8'));\n const msg = msgs[Math.floor(Math.random() * msgs.length)];\n process.stdout.write(msg);\n} catch(e) {\n process.stdout.write('Make it work, make it right, make it fast. — Kent Beck');\n}\n\" 2>/dev/null)\n\necho \"$MSG\" > \"$TODAY_FILE\"\n\n# macOS: GUI 세션 대기 후 Terminal 실행\nif [[ \"$(uname)\" == \"Darwin\" ]]; then\n # Sleep에서 깨어난 직후 GUI가 아직 준비 안 됨 — 로그인 화면 잠금 해제 대기\n MAX_WAIT=300 # 최대 5분 대기\n WAITED=0\n while [ $WAITED -lt $MAX_WAIT ]; do\n # WindowServer 프로세스가 있고 콘솔 사용자가 있으면 GUI 준비 완료\n if pgrep -q \"WindowServer\" && [ \"$(stat -f%Su /dev/console 2>/dev/null)\" = \"$(whoami)\" ]; then\n echo \"[$(date)] GUI session ready (waited \\${WAITED}s)\" >> \"$LOG_FILE\"\n break\n fi\n sleep 5\n WAITED=$((WAITED + 5))\n done\n\n if [ $WAITED -ge $MAX_WAIT ]; then\n echo \"[$(date)] GUI session timeout — skipping Terminal launch\" >> \"$LOG_FILE\"\n exit 0\n fi\n\n # 추가 안정화 대기\n sleep 10\n\n # Notification\n FIRST_LINE=$(echo \"$MSG\" | head -1 | cut -c1-80)\n osascript -e \"display notification \\\\\"$FIRST_LINE\\\\\" with title \\\\\"☀️ PAI Wakeup\\\\\" subtitle \\\\\"Claude Code 세션을 시작합니다\\\\\"\" 2>/dev/null\n\n # Open Terminal.app with Claude Code (재시도 3회)\n for attempt in 1 2 3; do\n osascript <<'APPLESCRIPT' 2>>\"$LOG_FILE\" && break\ntell application \"Terminal\"\n activate\n do script \"clear; echo ''; cat '$TODAY_FILE'; echo ''; echo '─────────────────────────────'; echo ''; cd '${config.projectDir}' && ${claudeCmd}\"\nend tell\nAPPLESCRIPT\n echo \"[$(date)] Terminal launch attempt $attempt failed, retrying...\" >> \"$LOG_FILE\"\n sleep 10\n done\nfi\n\n# Linux: Open terminal + Claude Code\nif [[ \"$(uname)\" == \"Linux\" ]]; then\n if command -v gnome-terminal &>/dev/null; then\n gnome-terminal -- bash -c \"cat '$TODAY_FILE'; echo ''; cd '${config.projectDir}' && ${claudeCmd}; exec bash\"\n elif command -v xterm &>/dev/null; then\n xterm -e \"cat '$TODAY_FILE'; echo ''; cd '${config.projectDir}' && ${claudeCmd}\"\n fi\nfi\n\necho \"[$(date)] PAI Wakeup completed\" >> \"$LOG_FILE\"\n`;\n\n await fs.writeFile(SCRIPT_FILE, script, { mode: 0o755 });\n}\n","import { Command } from 'commander';\nimport { createRequire } from 'node:module';\nimport { warnDeprecated } from './deprecation.js';\n\nconst require = createRequire(import.meta.url);\nconst pkg = require('../../package.json') as { version: string };\n\nexport function createProgram(): Command {\n const program = new Command();\n\n program\n .name('pai')\n .description('PAI Zero (Plugin AI for ProjectZero) — AI 개발 빌드 오케스트레이터')\n .version(pkg.version, '-v, --version')\n .action(async () => {\n // 인자 없이 `pai` 실행 시 welcome 화면 출력\n const { welcomeCommand } = await import('./commands/welcome.cmd.js');\n await welcomeCommand(process.cwd());\n });\n\n /* ───────────────────────── 신규 동사 (v0.11+) ───────────────────────── */\n\n // pai init [project-name]\n program\n .command('init [project-name]')\n .description('프로젝트 초기화 (새 프로젝트 / 기존 프로젝트 자동 감지)')\n .action(async (projectName?: string) => {\n const { initCommand } = await import('./commands/init.cmd.js');\n await initCommand(process.cwd(), projectName);\n });\n\n // pai add\n program\n .command('add')\n .description('플러그인 추가 (Mockup → Production 확장)')\n .action(async () => {\n const { addCommand } = await import('./commands/add.cmd.js');\n await addCommand(process.cwd());\n });\n\n // pai check\n program\n .command('check')\n .description('환경 점검 (Node / Git / Claude Code)')\n .action(async () => {\n const { checkCommand } = await import('./commands/check.cmd.js');\n await checkCommand();\n });\n\n // pai status\n program\n .command('status')\n .description('현재 프로젝트 상태 확인 (설치된 플러그인)')\n .action(async () => {\n const { statusCommand } = await import('./commands/status.cmd.js');\n await statusCommand(process.cwd());\n });\n\n // pai help\n program\n .command('help')\n .description('명령어 안내')\n .action(async () => {\n const { helpCommand } = await import('./commands/help.cmd.js');\n await helpCommand();\n });\n\n // pai design <subcommand>\n const design = program\n .command('design')\n .description('설계 관리 (OpenSpec / OMC)');\n\n design\n .command('init')\n .description('PRD/OMC 템플릿 생성')\n .action(async () => {\n const { designInitCommand } = await import('./commands/design.cmd.js');\n await designInitCommand(process.cwd());\n });\n\n design\n .command('validate')\n .description('PRD 완성도 검증')\n .action(async () => {\n const { designValidateCommand } = await import('./commands/design.cmd.js');\n await designValidateCommand(process.cwd());\n });\n\n // pai test\n program\n .command('test')\n .description('테스트 / 하네스 검증 실행')\n .action(async () => {\n const { testCommand } = await import('./commands/test.cmd.js');\n await testCommand(process.cwd());\n });\n\n // pai grade\n program\n .command('grade')\n .description('AI 개발 준비도 평가 (6카테고리 점수)')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n const { gradeCommand } = await import('./commands/grade.cmd.js');\n await gradeCommand(process.cwd(), options);\n });\n\n // pai run\n program\n .command('run')\n .description('전체 5단계 파이프라인 실행')\n .option('--from <stage>', '특정 단계부터 실행')\n .option('--only <stages>', '선택적 단계 실행 (쉼표 구분)')\n .action(async (options) => {\n const { runCommand } = await import('./commands/run.cmd.js');\n await runCommand(process.cwd(), options);\n });\n\n // pai remove\n program\n .command('remove')\n .description('PAI 생성 파일 전체 삭제 (초기화)')\n .option('--force', '확인 없이 강제 삭제')\n .action(async (options) => {\n const { removeCommand } = await import('./commands/remove.cmd.js');\n await removeCommand(process.cwd(), options);\n });\n\n // pai upgrade\n program\n .command('upgrade')\n .description('PAI 슬래시 커맨드 & 스킬을 최신 버전으로 업그레이드')\n .option('--force', '버전 체크 무시하고 강제 업그레이드')\n .action(async (options) => {\n const { upgradeCommand } = await import('./commands/upgrade.cmd.js');\n await upgradeCommand(process.cwd(), options);\n });\n\n // pai savetoken\n program\n .command('savetoken')\n .description('AI 토큰 절감 분석')\n .action(async () => {\n const { savetokenCommand } = await import('./commands/savetoken.cmd.js');\n await savetokenCommand(process.cwd());\n });\n\n // pai wakeup [time] [schedule]\n program\n .command('wakeup [time] [schedule]')\n .description('Claude Code 세션 자동 시작 + 토큰 윈도우 리셋')\n .action(async (time?: string, schedule?: string) => {\n const { wakeupCommand } = await import('./commands/wakeup.cmd.js');\n type Schedule = '평일' | '매일' | '주말';\n const validSchedules: Schedule[] = ['평일', '매일', '주말'];\n const sched: Schedule = validSchedules.includes(schedule as Schedule) ? schedule as Schedule : '평일';\n await wakeupCommand(time, sched);\n });\n\n /* ───────────────────────── 구 명령어 (deprecation alias) ─────────────\n * v0.11 경고 → v0.13 제거 예정\n * 기존 사용자 스크립트/블로그 호환 위해 유지\n * ──────────────────────────────────────────────────────────────────── */\n\n // env 그룹 (구): setup / doctor / status\n const env = program\n .command('env')\n .description('[구] 환경 관리 — pai add / check / status 권장');\n\n env\n .command('setup')\n .description('[구] → pai add')\n .action(async () => {\n warnDeprecated('pai env setup', 'pai add');\n const { envSetupCommand } = await import('./commands/env.cmd.js');\n await envSetupCommand(process.cwd());\n });\n\n env\n .command('doctor')\n .description('[구] → pai check')\n .action(async () => {\n warnDeprecated('pai env doctor', 'pai check');\n const { envDoctorCommand } = await import('./commands/env.cmd.js');\n await envDoctorCommand();\n });\n\n env\n .command('status')\n .description('[구] → pai status')\n .action(async () => {\n warnDeprecated('pai env status', 'pai status');\n const { envStatusCommand } = await import('./commands/env.cmd.js');\n await envStatusCommand(process.cwd());\n });\n\n // pai validate → pai test\n program\n .command('validate')\n .description('[구] → pai test')\n .action(async () => {\n warnDeprecated('pai validate', 'pai test');\n const { validateCommand } = await import('./commands/validate.cmd.js');\n await validateCommand(process.cwd());\n });\n\n // pai evaluate → pai grade\n program\n .command('evaluate')\n .description('[구] → pai grade')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n warnDeprecated('pai evaluate', 'pai grade');\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), options);\n });\n\n // pai pipeline → pai run\n program\n .command('pipeline')\n .description('[구] → pai run')\n .option('--from <stage>', '특정 단계부터 실행')\n .option('--only <stages>', '선택적 단계 실행 (쉼표 구분)')\n .action(async (options) => {\n warnDeprecated('pai pipeline', 'pai run');\n const { pipelineCommand } = await import('./commands/pipeline.cmd.js');\n await pipelineCommand(process.cwd(), options);\n });\n\n // pai install → pai add (가장 오독되던 이름)\n program\n .command('install')\n .description('[구] → pai add')\n .action(async () => {\n warnDeprecated('pai install', 'pai add');\n const { envSetupCommand } = await import('./commands/env.cmd.js');\n await envSetupCommand(process.cwd());\n });\n\n // 이전 레거시 유지\n program\n .command('diagnose')\n .description('[구] → pai grade')\n .action(async () => {\n warnDeprecated('pai diagnose', 'pai grade');\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), {});\n });\n\n program\n .command('vibe-ready')\n .description('바이브 코딩 준비도 측정 (= pai grade)')\n .option('--fail-under <score>', '최소 점수 (미달 시 exit 1)', parseInt)\n .option('--verbose', '상세 findings 출력')\n .option('-o, --output <file>', '결과를 파일로 저장')\n .option('--no-cache', '캐시 무시하고 새로 분석')\n .action(async (options) => {\n const { evaluateCommand } = await import('./commands/evaluate.cmd.js');\n await evaluateCommand(process.cwd(), options);\n });\n\n return program;\n}\n","/**\n * 구 명령어 deprecation 경고 — 세션 내 1회만 출력.\n * v0.11 alias 도입, v0.13 제거 스케줄.\n */\nconst warned = new Set<string>();\n\nexport function warnDeprecated(oldCmd: string, newCmd: string): void {\n if (warned.has(oldCmd)) return;\n warned.add(oldCmd);\n process.stderr.write(\n `\\x1b[33m⚠ '${oldCmd}' is deprecated. Use '${newCmd}' (see 'pai help'). Removed in v0.13.\\x1b[0m\\n`,\n );\n}\n","#!/usr/bin/env node\n\nimport { createProgram } from '../src/cli/index.js';\n\nconst program = createProgram();\n\nprogram.parseAsync(process.argv).catch((err: Error) => {\n console.error('\\n[PAI Error]', err.message || err);\n if (process.env['PAI_DEBUG']) {\n console.error(err.stack);\n }\n process.exit(1);\n});\n"],"mappings":"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A;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,MAiDX,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;AAAA;AAAA;AAAA,MAuCb,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,MA4Bb,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;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;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,MAuGb,eAAe;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAuBf,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,MAoCf,cAAc;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,MA2Bd,cAAc;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,MAoCd,iBAAiB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAyBjB,cAAc;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,MAiCd,gBAAgB;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;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;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,MA2GhB,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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAiDb,WAAW;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,MAqCX,YAAY;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,MA8BZ,WAAW;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,MA0BX,YAAY;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,MAmCZ,UAAU;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,IAiCZ;AAAA;AAAA;;;AC3zBA;AAAA;AAAA;AAAA;AAGA,SAAS,QAAAE,aAAY;AACrB,SAAS,eAAe;AACxB,OAAOC,SAAQ;AAUf,eAAsB,YAA2B;AAC/C,EAAG,QAAQ,6CAAoB;AAE/B,QAAM,SAAkB,CAAC;AAGzB,QAAM,cAAc,QAAQ;AAC5B,QAAM,YAAY,SAAS,YAAY,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC,GAAI,EAAE;AAClE,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,IACP,IAAI,aAAa;AAAA,IACjB,QAAQ,GAAG,WAAW,IAAI,aAAa,KAAK,cAAc,+CAAY;AAAA,IACtE,KAAK,YAAY,KAAK,yFAA6B;AAAA,EACrD,CAAC;AAGD,QAAM,cAAc,MAAM,aAAa,UAAU,CAAC,WAAW,CAAC;AAC9D,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,IACP,IAAI,YAAY;AAAA,IAChB,QAAQ,YAAY;AAAA,IACpB,KAAK,YAAY,KAAK,SAAY;AAAA,EACpC,CAAC;AAGD,QAAM,mBAAmBD,MAAK,QAAQ,GAAG,QAAQ,aAAa;AAC9D,QAAM,kBAAkB,MAAMC,IAAG,WAAW,gBAAgB;AAC5D,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,IACP,IAAI;AAAA,IACJ,QAAQ,kBAAkB,mBAAmB;AAAA,EAC/C,CAAC;AAGD,MAAI,SAAS;AACb,MAAI;AACF,UAAM,OAAO,gCAAgC;AAC7C,aAAS;AAAA,EACX,QAAQ;AAAA,EAER;AACA,SAAO,KAAK;AAAA,IACV,OAAO;AAAA,IACP,IAAI;AAAA;AAAA,IACJ,QAAQ,SAAS,4DAAoB;AAAA,EACvC,CAAC;AAGD,UAAQ,IAAI,EAAE;AACd,MAAI,SAAS;AACb,aAAW,SAAS,QAAQ;AAC1B,UAAM,OAAO,MAAM,KAAK,WAAM;AAC9B,UAAM,MAAM,IAAI,OAAO,KAAK,IAAI,GAAG,KAAK,MAAM,MAAM,MAAM,CAAC;AAC3D,QAAI,MAAM,IAAI;AACZ,MAAG,QAAQ,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,MAAM,EAAE;AACxD;AAAA,IACF,OAAO;AACL,MAAG,MAAM,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,GAAG,GAAG,MAAM,MAAM,EAAE;AACtD,UAAI,MAAM,KAAK;AACb,QAAG,KAAK,YAAO,MAAM,GAAG,EAAE;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,GAAG,MAAM,IAAI,OAAO,MAAM,4BAAQ;AAE1C,MAAI,SAAS,OAAO,QAAQ;AAC1B,YAAQ,WAAW;AAAA,EACrB;AACF;AAEA,eAAe,aAAa,KAAa,MAA0D;AACjG,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,UAAM,EAAE,OAAO,IAAI,MAAM,MAAM,KAAK,MAAM,EAAE,SAAS,IAAM,CAAC;AAC5D,WAAO,EAAE,IAAI,MAAM,QAAQ,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK,KAAK;AAAA,EAClE,QAAQ;AACN,WAAO,EAAE,IAAI,OAAO,QAAQ,YAAY;AAAA,EAC1C;AACF;AA/FA;AAAA;AAAA;AAMA;AAAA;AAAA;;;ACNA,IAgBa;AAhBb;AAAA;AAAA;AAKA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAqIA;AACA;AACA;AArIO,IAAM,mBAA0B;AAAA,MACrC,MAAM;AAAA,MAEN,QAAQ,OAA4B;AAClC,eAAO,MAAM,OAAO,QAAQ,SAAS;AAAA,MACvC;AAAA,MAEA,MAAM,IAAI,OAAyC;AACjD,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,YAAsB,CAAC;AAC7B,cAAM,SAAgC,CAAC;AAEvC,YAAI;AAEF,kBAAQ,IAAI,EAAE;AACd,gBAAM,WAAW,MAAM,YAAY,mDAAgB,YAAY;AAC7D,kBAAM,SAAS,MAAM,eAAe,MAAM,GAAG;AAC7C,kBAAM,MAAM,GAAG;AACf,mBAAO;AAAA,UACT,CAAC;AAED,kBAAQ,IAAI,EAAE;AACd,cAAI,SAAS,MAAM,UAAU,SAAS,GAAG;AACvC,YAAG,QAAQ,iBAAO,SAAS,MAAM,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,UACzD;AACA,cAAI,SAAS,MAAM,WAAW,SAAS,GAAG;AACxC,YAAG,QAAQ,mCAAU,SAAS,MAAM,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,UAC7D;AACA,UAAG,QAAQ,QAAQ,SAAS,IAAI,YAAY,GAAG,SAAS,IAAI,YAAY,OAAO,KAAK,0BAAM,EAAE;AAG5F,gBAAM,YAAY,MAAM,aAAa,UAAU,MAAM,KAAK,MAAM,OAAO,WAAW;AAGlF,kBAAQ,IAAI,EAAE;AACd,gBAAM,cAAc;AAAA,YAAC;AAAA,YAAa;AAAA,YAAyB;AAAA,YACzD;AAAA,YAAuC;AAAA,YACvC;AAAA,YAA+B;AAAA,UAAkC;AACnE,gBAAM,YAAY,MAAM,gBAAgB,oDAAiB,aAAa,YAAY;AAChF,kBAAM,QAAQ,MAAM,cAAc,MAAM,KAAK,UAAU,SAAS;AAChE,kBAAM,MAAM,GAAG;AACf,mBAAO;AAAA,UACT,CAAC;AACD,oBAAU,KAAK,GAAG,SAAS;AAK3B,gBAAM,cAAc,CAAC,UAAU,YAAY,QAAQ;AACnD,gBAAM,aAAa,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,aAAa,GAAG,UAAU,UAAU,CAAC,CAAC;AAEzE,gBAAM,UAA8B;AAAA,YAClC,KAAK,MAAM;AAAA,YACX,aAAa,UAAU;AAAA,YACvB,MAAM,UAAU;AAAA,YAChB,YAAY;AAAA,cACV,kBAAkB,UAAU;AAAA,cAC5B,UAAU,UAAU;AAAA,YACtB;AAAA,YACA,KAAK,UAAU;AAAA,UACjB;AAEA,cAAI,UAAU,YAAY,SAAS,QAAQ,GAAG;AAC5C,oBAAQ,WAAW,iBAAiB,IAAI,UAAU,YAAY,YAAY;AAC1E,oBAAQ,WAAW,qBAAqB,IAAI,UAAU,YAAY,gBAAgB;AAClF,oBAAQ,WAAW,oBAAoB,IAAI;AAAA,UAC7C;AAEA,gBAAM,kBAAkB;AAAA,YAAC;AAAA,YAAc;AAAA,YAAQ;AAAA,YAAS;AAAA,YAAU;AAAA,YAChE;AAAA,YAAoB;AAAA,YACpB,GAAI,UAAU,WAAW,SAAS,KAAK,IAAI,CAAC,eAAe,OAAO,IAAI,CAAC;AAAA,YACvE,GAAI,UAAU,WAAW,SAAS,QAAQ,IAAI,CAAC,aAAa,IAAI,CAAC;AAAA,YACjE,GAAI,UAAU,WAAW,SAAS,UAAU,IAAI,CAAC,sBAAsB,IAAI,CAAC;AAAA,YAC5E,GAAI,UAAU,WAAW,SAAS,QAAQ,IAAI,CAAC,kBAAkB,IAAI,CAAC;AAAA,YACtE,GAAI,UAAU,WAAW,SAAS,SAAS,IAAI,CAAC,mBAAmB,IAAI,CAAC;AAAA,YACxE,GAAI,UAAU,WAAW,SAAS,KAAK,IAAI,CAAC,eAAe,WAAW,IAAI,CAAC;AAAA,YAC3E;AAAA,UAAY;AAEd,kBAAQ,IAAI,EAAE;AACd,gBAAM,gBAAgB,gEAAmB,iBAAiB,YAAY;AACpE,kBAAM,gBAAgB,YAAY,OAAO;AACzC,kBAAM,MAAM,GAAG;AAAA,UACjB,CAAC;AAED,gBAAM,WAAW;AAAA,YAAC;AAAA,YAAY;AAAA,YAAW;AAAA,YAAW;AAAA,YAClD;AAAA,YAAa;AAAA,YAAa;AAAA,YAAe;AAAA,YAAe;AAAA,UAAY;AAEtE,kBAAQ,IAAI,EAAE;AACd,gBAAM,gBAAgB,gEAAmB,UAAU,YAAY;AAC7D,kBAAM,wBAAwB,MAAM,GAAG;AACvC,kBAAM,MAAM,GAAG;AAAA,UACjB,CAAC;AAGD,kBAAQ,IAAI,EAAE;AACd,gBAAM,iBAAiB,MAAM,aAAa,UAAU,OAAO,MAAM,GAAG;AACpE,6BAAmB,gBAAgB,UAAU,KAAK;AAGlD,kBAAQ,IAAI,EAAE;AACd,gBAAM,YAAY,uCAAc,YAAY;AAC1C,kBAAM,SAAS,oBAAoB,UAAU,aAAa,UAAU,IAAI;AACxE,mBAAO,UAAU;AACjB,gBAAI,UAAU,IAAK,QAAO,MAAM,UAAU;AAC1C,kBAAM,WAAW,MAAM,KAAK,MAAM;AAClC,kBAAM,MAAM,GAAG;AAAA,UACjB,CAAC;AAED,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM,EAAE,UAAU,WAAW,eAAe;AAAA,YAC5C;AAAA,YACA,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,gBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,iBAAO,KAAK,EAAE,MAAM,oBAAoB,SAAS,KAAK,aAAa,KAAK,CAAC;AACzE,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM,CAAC;AAAA,YACP;AAAA,YACA,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACjJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAOC,WAAU;AACjB,OAAOC,UAAQ;AA+Ff,eAAsB,iBAAiB,KAAoC;AACzE,QAAM,SAAuB;AAAA,IAC3B,cAAc;AAAA,IACd,cAAc;AAAA,IACd,aAAa;AAAA,IACb,kBAAkB,CAAC;AAAA,IACnB,gBAAgB,CAAC;AAAA,IACjB,SAAS,CAAC;AAAA,EACZ;AAEA,QAAM,gBAAgBD,MAAK,KAAK,KAAK,QAAQ,aAAa;AAC1D,MAAI,MAAMC,KAAG,WAAW,aAAa,GAAG;AACtC,WAAO,eAAe;AACtB,QAAI;AACF,YAAM,SAAS,MAAMA,KAAG,SAAS,aAAa;AAE9C,aAAO,cAAc,OAAO,QAAQ,OAAO,cAAc,OAAO,IAAI,IAAI;AAAA,IAC1E,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,aAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,iBAAiB,GAAG;AACjE,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,WAAW,IAAI,OAAO,QAAQ;AAC5B,YAAI,MAAMA,KAAG,WAAWD,MAAK,KAAK,KAAK,GAAG,CAAC,EAAG,QAAO;AACrD,cAAM,IAAI,MAAM,WAAW;AAAA,MAC7B,CAAC;AAAA,IACH,EAAE,MAAM,MAAM,KAAK;AAEnB,WAAO,QAAQ,GAAG,IAAI,EAAE,WAAiC,WAAW;AACpE,QAAI,WAAW;AACb,aAAO,iBAAiB,KAAK,GAAG;AAAA,IAClC,OAAO;AACL,aAAO,eAAe,KAAK,GAAG;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,gBACJ,OAAO,iBAAiB,SAAS,KAChC,MAAMC,KAAG,WAAWD,MAAK,KAAK,KAAK,cAAc,CAAC,KAClD,MAAMC,KAAG,WAAWD,MAAK,KAAK,KAAK,KAAK,CAAC,KACzC,MAAMC,KAAG,WAAWD,MAAK,KAAK,KAAK,WAAW,CAAC;AAElD,SAAO,eAAe,CAAC;AAEvB,SAAO;AACT;AAEO,SAAS,kBAAkB,MAAiD;AACjF,SAAO,OAAO,QAAQ,WAAW,EAC9B,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,MAAM,SAAS,IAAI,CAAC,EAC9C,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE;AAC5C;AAMO,SAAS,sBAAsB,MAAsB;AAC1D,SAAO,OAAO,QAAQ,WAAW,EAC9B,OAAO,CAAC,CAAC,EAAE,IAAI,MAAM,KAAK,MAAM,SAAS,IAAI,KAAK,KAAK,QAAQ,EAC/D,IAAI,CAAC,CAAC,GAAG,MAAM,GAAG;AACvB;AAMO,SAAS,SAAS,SAA4B;AACnD,MAAI,YAAY,YAAa,QAAO;AACpC,MAAI,YAAY,MAAO,QAAO;AAC9B,SAAO;AACT;AAKO,SAAS,wBAAwB,MAAY,IAAoB;AACtE,QAAM,UAAU,IAAI,IAAI,kBAAkB,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AACjE,SAAO,kBAAkB,EAAE,EACxB,IAAI,CAAC,MAAM,EAAE,GAAG,EAChB,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC;AAClC;AAnLA,IAca,mBAmBA;AAjCb;AAAA;AAAA;AAGA;AAWO,IAAM,oBAA8C;AAAA,MACzD,QAAQ,CAAC,QAAQ,SAAS;AAAA,MAC1B,QAAQ,CAAC,WAAW,aAAa;AAAA,MACjC,UAAU,CAAC,YAAY,WAAW;AAAA,MAClC,UAAU,CAAC,eAAe,oBAAoB,kBAAkB;AAAA,MAChE,KAAK,CAAC,eAAe,iBAAiB,iBAAiB;AAAA,MACvD,QAAQ,CAAC,oBAAoB,kBAAkB;AAAA,MAC/C,QAAQ,CAAC,oBAAoB,oBAAoB,SAAS;AAAA,MAC1D,SAAS,CAAC,qBAAqB,qBAAqB,UAAU;AAAA,IAChE;AAUO,IAAM,cAA0C;AAAA,MACrD,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,aAAa,OAAO,YAAY;AAAA,QACxC,UAAU;AAAA,MACZ;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,aAAa,OAAO,YAAY;AAAA,QACxC,UAAU;AAAA,MACZ;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,aAAa,OAAO,YAAY;AAAA,QACxC,UAAU;AAAA,QACV,KAAK;AAAA,MACP;AAAA,MACA,KAAK;AAAA,QACH,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,OAAO,YAAY;AAAA,QAC3B,UAAU;AAAA,QACV,KAAK;AAAA,MACP;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,OAAO,YAAY;AAAA,QAC3B,UAAU;AAAA,MACZ;AAAA,MACA,QAAQ;AAAA,QACN,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,YAAY;AAAA,QACpB,UAAU;AAAA,QACV,KAAK;AAAA,MACP;AAAA,MACA,SAAS;AAAA,QACP,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,YAAY;AAAA,QACpB,UAAU;AAAA,MACZ;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,aAAa;AAAA,QACb,OAAO,CAAC,YAAY;AAAA,QACpB,UAAU;AAAA,MACZ;AAAA,IACF;AAAA;AAAA;;;ACrFA;AAAA;AAAA;AAAA;AAGO,SAAS,oBAAoB,UAA0B;AAC5D,SAAO,8BAA8B,QAAQ;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;AAAA;AAsC/C;AA1CA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAE,oBAAA;AAAA,SAAAA,mBAAA;AAAA;AAAA;AAIA,SAAS,QAAAC,aAAY;AACrB,OAAOC,UAAQ;AAGf,eAAsB,kBAAkB,UAA8C;AAEpF,MAAI;AACF,WAAO,MAAM,WAAW,QAAQ;AAAA,EAClC,QAAQ;AAEN,WAAO,eAAe,QAAQ;AAAA,EAChC;AACF;AAEA,eAAe,WAAW,UAA8C;AACtE,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,gCAAgC;AAC/D,QAAM,EAAE,qBAAAC,qBAAoB,IAAI,MAAM;AAEtC,QAAM,SAASA,qBAAoB,QAAQ;AAC3C,MAAI,aAAa;AAEjB,mBAAiB,WAAW,MAAM;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,MACP,UAAU;AAAA,MACV,cAAc;AAAA,MACd,cAAc,CAAC,QAAQ,QAAQ,MAAM;AAAA,MACrC,gBAAgB;AAAA,IAClB;AAAA,EACF,CAAC,GAAG;AACF,QAAI,YAAY,SAAS;AACvB,mBAAa,QAAQ;AAAA,IACvB;AAAA,EACF;AAEA,SAAO,kBAAkB,UAAU;AACrC;AAEA,SAAS,kBAAkB,MAAiC;AAC1D,QAAM,YAAY,KAAK,MAAM,yBAAyB;AACtD,MAAI,YAAY,CAAC,GAAG;AAClB,WAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAAA,EAChC;AAEA,SAAO,KAAK,MAAM,IAAI;AACxB;AAEA,eAAe,eAAe,UAA8C;AAC1E,QAAM,aAAkC,CAAC;AAGzC,aAAW,KAAK,MAAM,kBAAkB,QAAQ,CAAC;AAEjD,aAAW,KAAK,MAAM,UAAU,QAAQ,CAAC;AAEzC,aAAW,KAAK,MAAM,WAAW,QAAQ,CAAC;AAE1C,aAAW,KAAK,MAAM,mBAAmB,QAAQ,CAAC;AAElD,aAAW,KAAK,MAAM,mBAAmB,QAAQ,CAAC;AAElD,aAAW,KAAK,MAAM,wBAAwB,QAAQ,CAAC;AAEvD,SAAO;AAAA,IACL;AAAA,IACA,SAAS,2CAAa,WAAW,OAAO,CAACC,OAAMA,GAAE,SAAS,EAAE,EAAE,MAAM;AAAA,EACtE;AACF;AAEA,eAAe,kBAAkB,UAA8C;AAC7E,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,cAAc;AAAA,IAAC;AAAA,IAAkB;AAAA,IAAkB;AAAA,IAAoB;AAAA,IAC3E;AAAA,IAAc;AAAA,IAAe;AAAA,EAAQ;AACvC,aAAW,KAAK,aAAa;AAC3B,UAAM,QAAQ,MAAMF,KAAG,WAAWD,MAAK,UAAU,CAAC,CAAC;AACnD,aAAS,KAAK,EAAE,MAAM,GAAG,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAC9D,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,QAAM,WAAW,CAAC,SAAS,QAAQ,aAAa,MAAM;AACtD,MAAI,aAAa;AACjB,aAAW,KAAK,UAAU;AACxB,QAAI,MAAMC,KAAG,WAAWD,MAAK,UAAU,CAAC,CAAC,GAAG;AAC1C,eAAS,KAAK,EAAE,MAAM,GAAG,OAAO,MAAM,SAAS,2DAAc,CAAC;AAC9D,mBAAa;AACb,eAAS;AACT;AAAA,IACF;AAAA,EACF;AACA,MAAI,CAAC,YAAY;AACf,aAAS,KAAK,EAAE,MAAM,kBAAkB,OAAO,OAAO,SAAS,2DAAc,CAAC;AAAA,EAChF;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,QAAM,kBAAkB,QAAQ,KAC5B,CAAC,EAAE,UAAU,YAAqB,SAAS,sDAAc,QAAQ,2IAA6B,CAAC,IAC/F,CAAC;AAEL,SAAO,EAAE,MAAM,+CAAY,MAAM,QAAQ,OAAO,iBAAiB,aAAa,SAAS;AACzF;AAEA,eAAe,UAAU,UAA8C;AACrE,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,YAAY;AAAA,IAChB,EAAE,MAAM,qBAAqB,OAAO,iBAAiB;AAAA,IACrD,EAAE,MAAM,kBAAkB,OAAO,YAAY;AAAA,IAC7C,EAAE,MAAM,eAAe,OAAO,UAAU;AAAA,IACxC,EAAE,MAAM,aAAa,OAAO,WAAW;AAAA,EACzC;AAEA,aAAW,EAAE,MAAAI,OAAM,MAAM,KAAK,WAAW;AACvC,UAAM,QAAQ,MAAMH,KAAG,WAAWD,MAAK,UAAUI,KAAI,CAAC;AACtD,aAAS,KAAK,EAAE,MAAM,OAAO,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAClE,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,QAAM,kBAAkB,UAAU,IAC9B,CAAC,EAAE,UAAU,YAAqB,SAAS,4BAAa,QAAQ,kHAAuC,CAAC,IACxG,CAAC;AAEL,SAAO,EAAE,MAAM,SAAS,MAAM,QAAQ,OAAO,iBAAiB,aAAa,SAAS;AACtF;AAEA,eAAe,WAAW,UAA8C;AACtE,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,cAAc;AAAA,IAClB,EAAE,MAAM,UAAU,OAAO,QAAQ;AAAA,IACjC,EAAE,MAAM,iBAAiB,OAAO,cAAc;AAAA,IAC9C,EAAE,MAAM,sBAAsB,OAAO,qBAAqB;AAAA,IAC1D,EAAE,MAAM,wBAAwB,OAAO,aAAa;AAAA,IACpD,EAAE,MAAM,yBAAyB,OAAO,uBAAuB;AAAA,EACjE;AAEA,aAAW,EAAE,MAAAA,OAAM,MAAM,KAAK,aAAa;AACzC,UAAM,QAAQ,MAAMH,KAAG,WAAWD,MAAK,UAAUI,KAAI,CAAC;AACtD,aAAS,KAAK,EAAE,MAAM,OAAO,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAClE,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,QAAM,kBAAkB,QAAQ,KAC5B,CAAC,EAAE,UAAU,WAAoB,SAAS,iDAAc,QAAQ,2HAA2C,CAAC,IAC5G,CAAC;AAEL,SAAO,EAAE,MAAM,oCAAW,MAAM,QAAQ,OAAO,iBAAiB,aAAa,SAAS;AACxF;AAEA,eAAe,mBAAmB,UAA8C;AAC9E,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,kBAAkB;AAAA,IACtB,EAAE,MAAM,OAAO,OAAO,gCAAY;AAAA,IAClC,EAAE,MAAM,gBAAgB,OAAO,kCAAS;AAAA,IACxC,EAAE,MAAM,gBAAgB,OAAO,wCAAU;AAAA,IACzC,EAAE,MAAM,cAAc,OAAO,aAAa;AAAA,EAC5C;AAEA,aAAW,EAAE,MAAAA,OAAM,MAAM,KAAK,iBAAiB;AAC7C,UAAM,QAAQ,MAAMH,KAAG,WAAWD,MAAK,UAAUI,KAAI,CAAC;AACtD,aAAS,KAAK,EAAE,MAAM,OAAO,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAClE,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,SAAO,EAAE,MAAM,+CAAY,MAAM,QAAQ,OAAO,iBAAiB,CAAC,GAAG,aAAa,SAAS;AAC7F;AAEA,eAAe,mBAAmB,UAA8C;AAC9E,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,YAAY;AAAA,IAChB,EAAE,MAAM,aAAa,OAAO,aAAa,QAAQ,GAAG;AAAA,IACpD,EAAE,MAAM,mBAAmB,OAAO,mBAAmB,QAAQ,GAAG;AAAA,IAChE,EAAE,MAAM,QAAQ,OAAO,kCAAc,QAAQ,GAAG;AAAA,IAChD,EAAE,MAAM,oBAAoB,OAAO,gBAAgB,QAAQ,GAAG;AAAA,EAChE;AAEA,aAAW,EAAE,MAAAA,OAAM,OAAO,OAAO,KAAK,WAAW;AAC/C,UAAM,QAAQ,MAAMH,KAAG,WAAWD,MAAK,UAAUI,KAAI,CAAC;AACtD,aAAS,KAAK,EAAE,MAAM,OAAO,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAClE,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,SAAO,EAAE,MAAM,mCAAU,MAAM,QAAQ,OAAO,iBAAiB,CAAC,GAAG,aAAa,SAAS;AAC3F;AAEA,eAAe,wBAAwB,UAA8C;AACnF,QAAM,WAAqE,CAAC;AAC5E,MAAI,QAAQ;AAEZ,QAAM,gBAAgB;AAAA,IACpB,EAAE,MAAM,aAAa,OAAO,aAAa,QAAQ,GAAG;AAAA,IACpD,EAAE,MAAM,aAAa,OAAO,aAAa,QAAQ,GAAG;AAAA,IACpD,EAAE,MAAM,yBAAyB,OAAO,yBAAyB,QAAQ,GAAG;AAAA,IAC5E,EAAE,MAAM,kBAAkB,OAAO,mBAAmB,QAAQ,GAAG;AAAA,IAC/D,EAAE,MAAM,oBAAoB,OAAO,qBAAqB,QAAQ,GAAG;AAAA,IACnE,EAAE,MAAM,oBAAoB,OAAO,cAAc,QAAQ,GAAG;AAAA,EAC9D;AAEA,aAAW,EAAE,MAAAA,OAAM,OAAO,OAAO,KAAK,eAAe;AACnD,UAAM,QAAQ,MAAMH,KAAG,WAAWD,MAAK,UAAUI,KAAI,CAAC;AACtD,aAAS,KAAK,EAAE,MAAM,OAAO,OAAO,SAAS,QAAQ,iBAAO,eAAK,CAAC;AAClE,QAAI,MAAO,UAAS;AAAA,EACtB;AAEA,UAAQ,KAAK,IAAI,KAAK,KAAK;AAC3B,SAAO,EAAE,MAAM,qDAAa,MAAM,QAAQ,OAAO,iBAAiB,CAAC,GAAG,aAAa,SAAS;AAC9F;AA7NA,IAAAC,iBAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAuEa;AAvEb;AAAA;AAAA;AAuEO,IAAM,cAAoC;AAAA,MAC/C;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA;AAAA;;;ACXO,SAAS,eAAe,OAAsB;AACnD,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,SAAS,GAAI,QAAO;AACxB,MAAI,SAAS,GAAI,QAAO;AACxB,SAAO;AACT;AAxEA,IAyDa;AAzDb;AAAA;AAAA;AAyDO,IAAM,2BAA6C;AAAA,MACxD,EAAE,MAAM,+CAAY,MAAM,QAAQ,QAAQ,IAAK;AAAA,MAC/C,EAAE,MAAM,SAAS,MAAM,QAAQ,QAAQ,IAAK;AAAA,MAC5C,EAAE,MAAM,oCAAW,MAAM,QAAQ,QAAQ,IAAK;AAAA,MAC9C,EAAE,MAAM,+CAAY,MAAM,QAAQ,QAAQ,MAAM;AAAA,MAChD,EAAE,MAAM,mCAAU,MAAM,QAAQ,QAAQ,MAAM;AAAA,MAC9C,EAAE,MAAM,qDAAa,MAAM,QAAQ,QAAQ,MAAM;AAAA,IACnD;AAAA;AAAA;;;AChEA;AAAA;AAAA;AAUA;AAqBA;AAAA;AAAA;;;AC/BA;AAAA;AAAA;AAAA;AAcO,SAAS,cACd,WACA,eACkB;AAClB,QAAM,UAAU,iBAAiB;AAEjC,QAAM,aAA+B,UAAU,WAAW,IAAI,CAAC,SAAS;AAAA,IACtE,MAAM,IAAI;AAAA,IACV,MAAM,IAAI;AAAA,IACV,OAAO,KAAK,MAAM,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC;AAAA,IACvD,OAAO,eAAe,KAAK,IAAI,GAAG,KAAK,IAAI,KAAK,IAAI,KAAK,CAAC,CAAC;AAAA,IAC3D,iBAAiB,IAAI;AAAA,IACrB,aAAa,IAAI;AAAA,EACnB,EAAE;AAEF,QAAM,aAAa,uBAAuB,YAAY,OAAO;AAC7D,MAAI,aAAa,eAAe,UAAU;AAE1C,QAAM,EAAE,gBAAgB,cAAc,IAAI,aAAa,UAAU;AACjE,MAAI,kBAAkB,UAAU,UAAU,IAAI,UAAU,GAAG,GAAG;AAC5D,iBAAa;AAAA,EACf;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS,UAAU;AAAA,IACnB;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,uBACP,YACA,SACQ;AACR,MAAI,cAAc;AAClB,MAAI,cAAc;AAElB,aAAW,OAAO,YAAY;AAC5B,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI,IAAI;AACtD,UAAM,SAAS,QAAQ,WAAW,IAAI,SAAS,SAAS,MAAO;AAC/D,mBAAe,IAAI,QAAQ;AAC3B,mBAAe;AAAA,EACjB;AAEA,MAAI,gBAAgB,EAAG,QAAO;AAC9B,SAAO,KAAK,MAAO,cAAc,cAAe,GAAG,IAAI;AACzD;AAEA,SAAS,aAAa,YAGpB;AACA,QAAM,aAAa,WAAW;AAAA,IAC5B,CAACC,OAAMA,GAAE,SAAS,UAAUA,GAAE,UAAU;AAAA,EAC1C;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,UAAM,QAAQ,WAAW,IAAI,CAACA,OAAMA,GAAE,IAAI,EAAE,KAAK,IAAI;AACrD,WAAO;AAAA,MACL,gBAAgB;AAAA,MAChB,eAAe,yDAAiB,KAAK;AAAA,IACvC;AAAA,EACF;AAEA,SAAO,EAAE,gBAAgB,MAAM;AACjC;AAEA,SAAS,UAAU,OAAsB;AACvC,QAAM,QAA+B,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACpE,SAAO,MAAM,KAAK;AACpB;AAvFA;AAAA;AAAA;AAYA;AAAA;AAAA;;;ACZA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA,OAAOC,YAAW;AAWX,SAAS,YAAY,QAAgC;AAC1D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,IAAI,SAAS,EAAE,yBAAyB,CAAC;AAC3D,UAAQ,IAAIA,OAAM,KAAK,0MAAqC,CAAC;AAC7D,UAAQ,IAAI,EAAE;AAGd,QAAM,aAAa,aAAa,OAAO,UAAU;AACjD,UAAQ,IAAI,gCAAY,WAAW,OAAO,OAAO,UAAU,CAAC,CAAC,yBAAe,WAAW,OAAO,UAAU,CAAC,EAAE;AAE3G,MAAI,OAAO,gBAAgB;AACzB,YAAQ,IAAIA,OAAM,IAAI,YAAO,OAAO,aAAa,EAAE,CAAC;AAAA,EACtD;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,kOAAyC,CAAC;AAGjE,aAAW,OAAO,OAAO,YAAY;AACnC,UAAM,QAAQ,aAAa,IAAI,KAAK;AACpC,UAAM,YAAY,IAAI,SAAS,SAASA,OAAM,IAAI,SAAS,EAAE,gBAAM,IAAIA,OAAM,KAAK,gBAAM;AACxF,UAAM,MAAM,UAAU,IAAI,KAAK;AAC/B,YAAQ,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC,IAAI,GAAG,IAAI,MAAM,GAAG,IAAI,KAAK,EAAE,EAAE,SAAS,EAAE,CAAC,IAAI,MAAM,IAAI,KAAK,CAAC,EAAE;AAAA,EACtH;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAIA,OAAM,KAAK,KAAK,OAAO,OAAO,EAAE,CAAC;AAC7C,UAAQ,IAAI,EAAE;AAChB;AAEO,SAAS,qBAAqB,QAAgC;AACnE,aAAW,OAAO,OAAO,YAAY;AACnC,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAIA,OAAM,KAAK,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,IAAI,KAAK,SAAI,CAAC;AAErE,eAAW,KAAK,IAAI,aAAa;AAC/B,YAAM,OAAO,EAAE,QAAQA,OAAM,MAAM,QAAG,IAAIA,OAAM,IAAI,QAAG;AACvD,cAAQ,IAAI,OAAO,IAAI,IAAI,EAAE,IAAI,WAAM,EAAE,OAAO,EAAE;AAAA,IACpD;AAEA,eAAW,KAAK,IAAI,iBAAiB;AACnC,YAAM,WAAW,EAAE,aAAa,aAAaA,OAAM,IAAI,GAAG,IAAI,EAAE,aAAa,YAAYA,OAAM,OAAO,GAAG,IAAIA,OAAM,KAAK,GAAG;AAC3H,cAAQ,IAAI,OAAO,QAAQ,IAAI,EAAE,OAAO,EAAE;AAC1C,cAAQ,IAAIA,OAAM,KAAK,gBAAW,EAAE,MAAM,EAAE,CAAC;AAAA,IAC/C;AAAA,EACF;AACF;AAEA,SAAS,UAAU,OAAuB;AACxC,QAAM,QAAQ;AACd,QAAM,SAAS,KAAK,MAAO,QAAQ,MAAO,KAAK;AAC/C,QAAM,QAAQ,QAAQ;AACtB,QAAM,QAAQ,SAAS,KAAKA,OAAM,IAAI,SAAS,IAAI,SAAS,KAAKA,OAAM,IAAI,SAAS,IAAIA,OAAM,IAAI,SAAS;AAC3G,SAAO,MAAM,SAAI,OAAO,MAAM,CAAC,IAAIA,OAAM,KAAK,SAAI,OAAO,KAAK,CAAC;AACjE;AAEO,SAAS,oBAAoB,QAAkC;AACpE,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,gCAAW,oBAAI,KAAK,GAAE,eAAe,OAAO,CAAC;AAAA,IAC7C;AAAA,IACA,iCAAa,OAAO,UAAU,4BAAa,OAAO,UAAU;AAAA,IAC5D;AAAA,EACF;AAEA,MAAI,OAAO,gBAAgB;AACzB,UAAM,KAAK,YAAO,OAAO,aAAa,EAAE;AACxC,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,gDAAa;AACxB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,2EAAyB;AACpC,QAAM,KAAK,kCAAkC;AAE7C,aAAW,OAAO,OAAO,YAAY;AACnC,UAAM,OAAO,IAAI,SAAS,SAAS,iBAAO;AAC1C,UAAM,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,MAAM,IAAI,KAAK,IAAI;AAAA,EACtE;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,6BAAS;AACpB,QAAM,KAAK,EAAE;AAEb,QAAM,UAAU,OAAO,WAAW;AAAA,IAAQ,CAACC,OACzCA,GAAE,gBAAgB,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,UAAUA,GAAE,KAAK,EAAE;AAAA,EAC3D;AAEA,MAAI,QAAQ,WAAW,GAAG;AACxB,UAAM,KAAK,iEAAe;AAAA,EAC5B,OAAO;AACL,eAAW,KAAK,SAAS;AACvB,YAAM,OAAO,EAAE,aAAa,aAAa,cAAO,EAAE,aAAa,YAAY,cAAO;AAClF,YAAM,KAAK,KAAK,IAAI,MAAM,EAAE,QAAQ,OAAO,EAAE,OAAO,EAAE;AACtD,YAAM,KAAK,OAAO,EAAE,MAAM,EAAE;AAAA,IAC9B;AAAA,EACF;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,iBAAO;AAClB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,OAAO,OAAO;AACzB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,sCAAsC;AAEjD,SAAO,MAAM,KAAK,IAAI,IAAI;AAC5B;AAEO,SAAS,oBAAoB,QAA0B,aAA6B;AACzF,QAAM,OAAM,oBAAI,KAAK,GAAE,eAAe,OAAO;AAC7C,QAAM,WAAW,OAAO,WAAW,OAAO,CAACA,OAAMA,GAAE,SAAS,MAAM;AAClE,QAAM,WAAW,OAAO,WAAW,OAAO,CAACA,OAAMA,GAAE,SAAS,MAAM;AAElE,QAAM,QAAkB;AAAA,IACtB,KAAK,WAAW;AAAA,IAChB;AAAA,IACA,gCAAY,GAAG;AAAA,IACf,gCAAY,WAAW;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,WAAW,+FAAyB,OAAO,UAAU,SAAS,OAAO,UAAU;AAAA,IAClF;AAAA,EACF;AAEA,MAAI,OAAO,gBAAgB;AACzB,UAAM,KAAK,YAAO,OAAO,aAAa,EAAE;AACxC,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,MAAI,OAAO,eAAe,KAAK;AAC7B,UAAM,KAAK,uJAAoC;AAAA,EACjD,WAAW,OAAO,eAAe,KAAK;AACpC,UAAM,KAAK,iOAAkD;AAAA,EAC/D,WAAW,OAAO,eAAe,KAAK;AACpC,UAAM,KAAK,wPAAqD;AAAA,EAClE,WAAW,OAAO,eAAe,KAAK;AACpC,UAAM,KAAK,gOAAiD;AAAA,EAC9D,OAAO;AACL,UAAM,KAAK,8MAA8C;AAAA,EAC3D;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,oCAAW;AACtB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,oFAA6B;AACxC,QAAM,KAAK,wCAAwC;AAEnD,aAAW,OAAO,OAAO,YAAY;AACnC,UAAM,OAAO,IAAI,SAAS,SAAS,qBAAW;AAC9C,UAAM,KAAK,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,IAAI,KAAK,UAAU,IAAI,KAAK,MAAM,IAAI,SAAS,SAAS,QAAQ,OAAO,IAAI;AAAA,EACrH;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,iDAAc;AACzB,QAAM,KAAK,EAAE;AAEb,aAAW,OAAO,OAAO,YAAY;AACnC,UAAM,YAAY,IAAI,SAAS,SAAS,iBAAO;AAC/C,UAAM,KAAK,OAAO,IAAI,IAAI,KAAK,SAAS,wBAAS,IAAI,SAAS,SAAS,QAAQ,OAAO,YAAO,IAAI,KAAK,cAAI;AAC1G,UAAM,KAAK,EAAE;AAGb,QAAI,IAAI,YAAY,SAAS,GAAG;AAC9B,YAAM,KAAK,gCAAY;AACvB,YAAM,KAAK,EAAE;AACb,iBAAW,KAAK,IAAI,aAAa;AAC/B,cAAM,OAAO,EAAE,QAAQ,WAAM;AAC7B,cAAM,KAAK,KAAK,IAAI,IAAI,EAAE,IAAI,WAAM,EAAE,OAAO,EAAE;AAAA,MACjD;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAGA,QAAI,IAAI,UAAU,OAAO,IAAI,UAAU,KAAK;AAC1C,YAAM,KAAK,sEAAoB;AAAA,IACjC,WAAW,IAAI,UAAU,KAAK;AAC5B,YAAM,KAAK,4IAAmC;AAAA,IAChD,WAAW,IAAI,UAAU,KAAK;AAC5B,YAAM,KAAK,sEAAoB;AAAA,IACjC,OAAO;AACL,YAAM,KAAK,yFAAwB;AAAA,IACrC;AACA,UAAM,KAAK,EAAE;AAGb,QAAI,IAAI,gBAAgB,SAAS,GAAG;AAClC,YAAM,KAAK,+BAAW;AACtB,YAAM,KAAK,EAAE;AACb,iBAAW,KAAK,IAAI,iBAAiB;AACnC,cAAM,OAAO,EAAE,aAAa,aAAa,cAAO,EAAE,aAAa,YAAY,cAAO;AAClF,cAAM,KAAK,KAAK,IAAI,IAAI,EAAE,OAAO,EAAE;AACnC,cAAM,KAAK,cAAS,EAAE,MAAM,EAAE;AAAA,MAChC;AACA,YAAM,KAAK,EAAE;AAAA,IACf;AAEA,UAAM,KAAK,KAAK;AAChB,UAAM,KAAK,EAAE;AAAA,EACf;AAGA,QAAM,KAAK,oCAAW;AACtB,QAAM,KAAK,EAAE;AAEb,QAAM,WAAW,OAAO,WAAW,OAAO,CAACA,OAAMA,GAAE,UAAU,GAAG;AAChE,QAAM,UAAU,OAAO,WAAW,OAAO,CAACA,OAAMA,GAAE,UAAU,GAAG;AAC/D,QAAM,KAAK,OAAO,WAAW,OAAO,CAACA,OAAMA,GAAE,UAAU,OAAOA,GAAE,UAAU,OAAOA,GAAE,UAAU,GAAG;AAEhG,MAAI,SAAS,SAAS,GAAG;AACvB,UAAM,KAAK,4DAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,4EAA0B;AACrC,UAAM,KAAK,mCAAmC;AAC9C,eAAWA,MAAK,UAAU;AACxB,YAAM,SAASA,GAAE,gBAAgB,CAAC,GAAG,UAAU;AAC/C,YAAM,KAAK,KAAKA,GAAE,IAAI,MAAMA,GAAE,KAAK,gCAAsB,MAAM,IAAI;AAAA,IACrE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,UAAM,KAAK,4DAAoB;AAC/B,UAAM,KAAK,EAAE;AACb,UAAM,KAAK,4EAA0B;AACrC,UAAM,KAAK,mCAAmC;AAC9C,eAAWA,MAAK,SAAS;AACvB,YAAM,SAASA,GAAE,gBAAgB,CAAC,GAAG,UAAU;AAC/C,YAAM,KAAK,KAAKA,GAAE,IAAI,MAAMA,GAAE,KAAK,gCAAsB,MAAM,IAAI;AAAA,IACrE;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,MAAI,GAAG,SAAS,GAAG;AACjB,UAAM,KAAK,+CAAiB;AAC5B,UAAM,KAAK,EAAE;AACb,eAAWA,MAAK,IAAI;AAClB,YAAM,KAAK,YAAOA,GAAE,IAAI,KAAKA,GAAE,KAAK,WAAMA,GAAE,KAAK,GAAG;AAAA,IACtD;AACA,UAAM,KAAK,EAAE;AAAA,EACf;AAEA,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AAGb,QAAM,KAAK,iBAAO;AAClB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,OAAO,OAAO;AACzB,QAAM,KAAK,EAAE;AAEb,MAAI,OAAO,eAAe,OAAO,OAAO,eAAe,KAAK;AAC1D,UAAM,mBAAmB,SAAS,SAAS,QAAQ;AACnD,UAAM,KAAK,gDAAa,gBAAgB,8IAAgC;AAAA,EAC1E,WAAW,OAAO,eAAe,KAAK;AACpC,UAAM,KAAK,kOAAmD;AAAA,EAChE,OAAO;AACL,UAAM,KAAK,uMAA4C;AAAA,EACzD;AAEA,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,KAAK;AAChB,QAAM,KAAK,EAAE;AACb,QAAM,KAAK,+EAA2D;AAEtE,SAAO,MAAM,KAAK,IAAI,IAAI;AAC5B;AArSA,IAMM;AANN;AAAA;AAAA;AAMA,IAAM,eAAqD;AAAA,MACzD,GAAGD,OAAM,IAAI,SAAS;AAAA,MACtB,GAAGA,OAAM,IAAI,SAAS;AAAA,MACtB,GAAGA,OAAM,IAAI,SAAS;AAAA,MACtB,GAAGA,OAAM,IAAI,SAAS;AAAA,MACtB,GAAGA,OAAM,IAAI,SAAS;AAAA,IACxB;AAAA;AAAA;;;ACZA;AAAA;AAAA;AAAA;AAAA;AAKA,SAAS,QAAAE,aAAY;AACrB,SAAS,WAAAC,gBAAe;AACxB,OAAOC,UAAQ;AAiDf,eAAsB,eAAe,WAAkC;AACrE,QAAMA,KAAG,UAAU,OAAO;AAC1B,QAAMA,KAAG,UAAU,SAAS,SAAS;AACvC;AAMA,eAAsB,qBAAuC;AAC3D,QAAMA,KAAG,UAAU,OAAO;AAE1B,MAAI,WAAW;AACb,WAAO,wBAAwB;AAAA,EACjC;AACA,SAAO,kBAAkB;AAC3B;AAEA,eAAe,oBAAsC;AACnD,QAAMA,KAAG,UAAU,gBAAgB,WAAW;AAE9C,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa;AAEnB,MAAI,MAAMA,KAAG,WAAW,MAAM,GAAG;AAC/B,UAAM,UAAU,MAAMA,KAAG,SAAS,QAAQ,MAAM;AAChD,QAAI,QAAQ,SAAS,iBAAiB,GAAG;AACvC,aAAO;AAAA,IACT;AACA,UAAMA,KAAG,WAAW,QAAQ;AAAA;AAAA,EAAyB,UAAU;AAAA,CAAI;AACnE,WAAO;AAAA,EACT;AAEA,QAAMA,KAAG,UAAU,QAAQ,GAAG,UAAU;AAAA,CAAI;AAC5C,SAAO;AACT;AAEA,eAAe,0BAA4C;AACzD,QAAMA,KAAG,UAAU,iBAAiB,iBAAiB;AAErD,QAAM,SAAS,eAAe;AAC9B,QAAM,aAAa;AAEnB,QAAMA,KAAG,UAAUF,MAAK,QAAQ,IAAI,CAAC;AAErC,MAAI,MAAME,KAAG,WAAW,MAAM,GAAG;AAC/B,UAAM,UAAU,MAAMA,KAAG,SAAS,QAAQ,MAAM;AAChD,QAAI,QAAQ,SAAS,kBAAkB,GAAG;AACxC,aAAO;AAAA,IACT;AACA,UAAMA,KAAG,WAAW,QAAQ;AAAA;AAAA,EAAyB,UAAU;AAAA,CAAI;AACnE,WAAO;AAAA,EACT;AAEA,QAAMA,KAAG,UAAU,QAAQ,GAAG,UAAU;AAAA,CAAI;AAC5C,SAAO;AACT;AAhHA,IAUM,SACA,SACA,gBACA,iBAEA,aAmBA;AAlCN;AAAA;AAAA;AAQA;AAEA,IAAM,UAAUF,MAAKC,SAAQ,GAAG,MAAM;AACtC,IAAM,UAAUD,MAAK,SAAS,WAAW;AACzC,IAAM,iBAAiBA,MAAK,SAAS,iBAAiB;AACtD,IAAM,kBAAkBA,MAAK,SAAS,kBAAkB;AAExD,IAAM,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBpB,IAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AClC1B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQA,OAAOG,SAAQ;AACf,OAAOC,WAAU;AACjB,OAAOC,UAAQ;AAmCR,SAAS,sBAAsB,UAAkBF,IAAG,QAAQ,GAAW;AAC5E,SAAOC,MAAK,KAAK,SAAS,WAAW,eAAe;AACtD;AAKA,SAAS,iBAAiB,KAAsB;AAC9C,QAAM,WAAW,IAAI,WAAW,CAAC,MAAM,QAAS,IAAI,MAAM,CAAC,IAAI;AAC/D,SAAO,KAAK,MAAM,QAAQ;AAC5B;AAEA,SAAS,kBAA0B;AAEjC,SAAO,4BAA2B,oBAAI,KAAK,GAAE,YAAY,CAAC;AAC5D;AAUA,eAAsB,gBACpB,UAA4B,CAAC,GACH;AAC1B,QAAM,gBAAgB,QAAQ,iBAAiB;AAC/C,QAAM,iBAAiB,QAAQ,kBAAkB;AACjD,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,aAAa,QAAQ,UAAU;AAErC,QAAM,eAAe,sBAAsB;AAC3C,QAAMC,KAAG,UAAUD,MAAK,QAAQ,YAAY,CAAC;AAG7C,MAAI,CAAE,MAAMC,KAAG,WAAW,YAAY,GAAI;AACxC,UAAM,WAAW,cAAc,eAAe,gBAAgB,QAAQ;AACtE,UAAMA,KAAG,UAAU,cAAc,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI,MAAM,MAAM;AACjF,WAAO,EAAE,QAAQ,WAAW,aAAa;AAAA,EAC3C;AAGA,QAAM,MAAM,MAAMA,KAAG,SAAS,cAAc,MAAM;AAClD,MAAI;AACJ,MAAI;AACF,UAAM,QAAQ,iBAAiB,GAAG;AAClC,QAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,IAAI,MAAM,oCAAoC;AAAA,IACtD;AACA,aAAS;AAAA,EACX,SAAS,KAAK;AAEZ,UAAMC,cAAa,GAAG,YAAY,WAAW,gBAAgB,CAAC;AAC9D,UAAMD,KAAG,KAAK,cAAcC,WAAU;AACtC,UAAM,IAAI;AAAA,MACR,4CAAyB,IAAc,OAAO,mBAASA,WAAU;AAAA,MACjEA;AAAA,IACF;AAAA,EACF;AAGA,MAAI,iBAAiB,QAAQ,eAAe,QAAQ,GAAG;AACrD,WAAO,EAAE,QAAQ,mBAAmB,aAAa;AAAA,EACnD;AAGA,MAAI;AACJ,MAAI,YAAY;AACd,iBAAa,GAAG,YAAY,WAAW,gBAAgB,CAAC;AACxD,UAAMD,KAAG,KAAK,cAAc,UAAU;AAAA,EACxC;AAGA,QAAM,SAAS,qBAAqB,QAAQ,eAAe,gBAAgB,QAAQ;AACnF,QAAMA,KAAG,UAAU,cAAc,KAAK,UAAU,QAAQ,MAAM,CAAC,IAAI,MAAM,MAAM;AAE/E,SAAO,EAAE,QAAQ,SAAS,cAAc,WAAW;AACrD;AAMO,SAAS,cACd,eACA,gBACA,UACyB;AACzB,SAAO;AAAA,IACL,wBAAwB;AAAA,MACtB,CAAC,aAAa,GAAG;AAAA,QACf,QAAQ,EAAE,QAAQ,OAAO,KAAK,eAAe;AAAA,MAC/C;AAAA,IACF;AAAA,IACA,gBAAgB;AAAA,MACd,CAAC,QAAQ,GAAG;AAAA,IACd;AAAA,EACF;AACF;AAEO,SAAS,iBACd,UACA,eACA,UACS;AACT,QAAM,UAAU,SAAS,wBAAwB;AACjD,QAAM,UAAU,SAAS,gBAAgB;AACzC,QAAM,YACJ,OAAO,YAAY,YACnB,YAAY,QACZ,iBAAkB;AACpB,QAAM,YACJ,OAAO,YAAY,YACnB,YAAY,QACX,QAAoC,QAAQ,MAAM;AACrD,SAAO,aAAa;AACtB;AAEO,SAAS,qBACd,UACA,eACA,gBACA,UACyB;AACzB,QAAM,OAAgC,EAAE,GAAG,SAAS;AAEpD,QAAM,kBACJ,OAAO,KAAK,wBAAwB,MAAM,YAAY,KAAK,wBAAwB,MAAM,OACrF,EAAE,GAAI,KAAK,wBAAwB,EAA8B,IACjE,CAAC;AACP,kBAAgB,aAAa,IAAI;AAAA,IAC/B,QAAQ,EAAE,QAAQ,OAAO,KAAK,eAAe;AAAA,EAC/C;AACA,OAAK,wBAAwB,IAAI;AAEjC,QAAM,kBACJ,OAAO,KAAK,gBAAgB,MAAM,YAAY,KAAK,gBAAgB,MAAM,OACrE,EAAE,GAAI,KAAK,gBAAgB,EAA8B,IACzD,CAAC;AACP,kBAAgB,QAAQ,IAAI;AAC5B,OAAK,gBAAgB,IAAI;AAEzB,SAAO;AACT;AA9LA,IAaM,wBACA,yBACA,mBAoBO;AAnCb;AAAA;AAAA;AAWA;AAEA,IAAM,yBAAyB;AAC/B,IAAM,0BAA0B;AAChC,IAAM,oBAAoB;AAoBnB,IAAM,sBAAN,cAAkC,MAAM;AAAA,MAC7C,YAAY,SAAiC,YAAqB;AAChE,cAAM,OAAO;AAD8B;AAE3C,aAAK,OAAO;AAAA,MACd;AAAA,MAH6C;AAAA,IAI/C;AAAA;AAAA;;;ACrCA,SAAS,cAAc,eAAe,WAAW,kBAAkB;AACnE,SAAS,QAAAE,aAAY;AACrB,SAAS,kBAAkB;AA4BpB,SAAS,gBAAgB,UAA0B;AACxD,QAAM,OAAO,WAAW,QAAQ;AAChC,aAAW,QAAQ,eAAe;AAChC,UAAM,WAAWA,MAAK,UAAU,IAAI;AACpC,QAAI;AACF,YAAM,UAAU,aAAa,QAAQ;AACrC,WAAK,OAAO,GAAG,IAAI,IAAI,QAAQ,MAAM,EAAE;AAAA,IACzC,QAAQ;AACN,WAAK,OAAO,GAAG,IAAI,UAAU;AAAA,IAC/B;AAAA,EACF;AACA,SAAO,KAAK,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACvC;AAEA,SAAS,aAAa,UAA0B;AAC9C,SAAOA,MAAK,UAAU,WAAW,UAAU;AAC7C;AAEA,SAAS,UAAU,UAA8B;AAC/C,MAAI;AACF,UAAM,OAAO,aAAa,aAAa,QAAQ,GAAG,OAAO;AACzD,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO,EAAE,SAAS,GAAG,SAAS,CAAC,EAAE;AAAA,EACnC;AACF;AAEA,SAAS,UAAU,UAAkB,OAAyB;AAC5D,QAAM,WAAWA,MAAK,UAAU,WAAW,OAAO;AAClD,MAAI,CAAC,WAAW,QAAQ,GAAG;AACzB,cAAU,UAAU,EAAE,WAAW,KAAK,CAAC;AAAA,EACzC;AACA,gBAAc,aAAa,QAAQ,GAAG,KAAK,UAAU,OAAO,MAAM,CAAC,CAAC;AACtE;AAEO,SAAS,gBAAgB,UAA4C;AAC1E,QAAM,QAAQ,UAAU,QAAQ;AAChC,QAAM,WAAW,gBAAgB,QAAQ;AACzC,QAAM,QAAQ,MAAM,QAAQ,QAAQ;AAEpC,MAAI,CAAC,MAAO,QAAO;AACnB,MAAI,KAAK,IAAI,IAAI,MAAM,YAAY,aAAc,QAAO;AAExD,SAAO,MAAM;AACf;AAEO,SAAS,gBAAgB,UAAkB,WAAoC;AACpF,QAAM,QAAQ,UAAU,QAAQ;AAChC,QAAM,WAAW,gBAAgB,QAAQ;AAGzC,QAAM,MAAM,KAAK,IAAI;AACrB,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,OAAO,GAAG;AACxD,QAAI,MAAM,MAAM,YAAY,cAAc;AACxC,aAAO,MAAM,QAAQ,GAAG;AAAA,IAC1B;AAAA,EACF;AAEA,QAAM,QAAQ,QAAQ,IAAI,EAAE,UAAU,UAAU,WAAW,KAAK,UAAU;AAC1E,YAAU,UAAU,KAAK;AAC3B;AA7FA,IAQM,WACA,YACA,cAcA;AAxBN;AAAA;AAAA;AAQA,IAAM,YAAY;AAClB,IAAM,aAAa;AACnB,IAAM,eAAe,KAAK,KAAK,KAAK;AAcpC,IAAM,gBAAgB;AAAA,MACpB;AAAA,MAAgB;AAAA,MAAkB;AAAA,MAAU;AAAA,MAC5C;AAAA,MAAiB;AAAA,MAAkB;AAAA,MACnC;AAAA,MAAqB;AAAA,MACrB;AAAA,MAAU;AAAA,MACV;AAAA,MAAa;AAAA,MAAa;AAAA,MAC1B;AAAA,MAAa;AAAA,IACf;AAAA;AAAA;;;AC/BA;AAAA;AAAA;AAAA;AAAA,SAAS,QAAAC,QAAM,gBAAgB;AAC/B,OAAOC,UAAQ;AAef,eAAsB,gBAAgB,KAAa,SAAyC;AAC1F,QAAM,WAAW,QAAQ,UAAU;AAGnC,MAAI,YAAY,WAAW,gBAAgB,GAAG,IAAI;AAClD,MAAI,WAAW;AACb,IAAG,KAAK,4EAAqB;AAAA,EAC/B,OAAO;AACL,gBAAY,MAAM,kBAAkB,GAAG;AACvC,QAAI,UAAU;AACZ,sBAAgB,KAAK,SAAS;AAAA,IAChC;AAAA,EACF;AAEA,QAAM,SAAS,cAAc,SAAS;AAGtC,cAAY,MAAM;AAElB,MAAI,QAAQ,SAAS;AACnB,yBAAqB,MAAM;AAAA,EAC7B;AAGA,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,cAAc,QAAQ,eAAe,SAAS,GAAG;AACvD,QAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,QAAM,YAAYD,OAAK,KAAK,QAAQ,WAAW;AAC/C,QAAM,aAAaA,OAAK,WAAW,GAAG,KAAK,KAAK;AAEhD,QAAMC,KAAG,UAAU,SAAS;AAC5B,QAAM,iBAAiB,oBAAoB,QAAQ,WAAW;AAC9D,QAAMA,KAAG,UAAU,YAAY,gBAAgB,MAAM;AAErD,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,mDAA0B,KAAK,KAAK;AAC/C,UAAQ,IAAI,EAAE;AAGd,UAAQ,IAAI,cAAc;AAG1B,MAAI,QAAQ,QAAQ;AAClB,UAAMA,KAAG,UAAU,QAAQ,QAAQ,gBAAgB,MAAM;AACzD,IAAG,QAAQ,8BAAU,QAAQ,MAAM,EAAE;AAAA,EACvC;AAGA,MAAI,QAAQ,aAAa,OAAO,aAAa,QAAQ,WAAW;AAC9D,IAAG,MAAM,gBAAM,OAAO,UAAU,oCAAW,QAAQ,SAAS,wCAAU;AACtE,YAAQ,WAAW;AAAA,EACrB;AACF;AApEA;AAAA;AAAA;AAEA;AACA,IAAAC;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACPA;AAAA;AAAA;AAAA;AAAA;AAAA;AAeA,eAAsB,gBAAgB,KAA4B;AAChE,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAM,EAAE,UAAAC,UAAS,IAAI,MAAM,OAAO,MAAW;AAE7C,EAAG,QAAQ,sEAAiB;AAC5B,QAAM,QAAQ,MAAM,iBAAiB,GAAG;AACxC,QAAM,iBAAiB,MAAM,WAAW,GAAG;AAC3C,QAAM,cAAoB,MAAM,eAAe,gBAAgB,QAAQ;AAGvE,QAAM,gBAAgB,SAAS,WAAW;AAC1C,MAAI,eAA4B;AAChC,QAAM,2BAAqC,CAAC;AAE5C,MAAI,eAAe;AACjB,UAAM,eAAe,wBAAwB,aAAa,aAAa;AACvE,UAAM,kBAAkB,aAAa,OAAO,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,aAAa,MAAM;AAE1F,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,gCAAY,OAAE,OAAO,WAAW,CAAC,EAAE,CAAC;AACtD,YAAQ,IAAI,OAAE,IAAI,gCAAY,OAAE,OAAO,aAAa,CAAC,EAAE,CAAC;AACxD,QAAI,gBAAgB,SAAS,GAAG;AAC9B,cAAQ,IAAI,OAAE,IAAI,4EAAqB,gBAAgB,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,IACtE;AACA,YAAQ,IAAI,EAAE;AAEd,UAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,MACzC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,GAAG,aAAa;AAAA,MACzB,SAAS;AAAA,IACX,CAAC,CAAC;AAEF,QAAI,SAAS;AACX,qBAAe;AACf,+BAAyB,KAAK,GAAG,eAAe;AAAA,IAClD;AAAA,EACF,OAAO;AACL,IAAG,KAAK,gDAAa,WAAW,sBAAO;AAAA,EACzC;AAIA,QAAM,aAAa,gBAAgB;AACnC,QAAM,mBAAmB,kBAAkB,UAAU,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AACvE,QAAM,YAAY,iBAAiB;AAAA,IACjC,CAAC,MAAM,EAAE,MAAM,QAAQ,CAAC,GAAG,aAAa,UAAU,CAAC,yBAAyB,SAAS,CAAC;AAAA,EACxF;AAEA,MAAI,eAAyB,CAAC;AAC9B,MAAI,UAAU,SAAS,GAAG;AACxB,YAAQ,IAAI,EAAE;AACd,UAAM,UAAU,UAAU,IAAI,CAAC,MAAM;AACnC,YAAM,OAAO,YAAY,CAAC;AAC1B,YAAM,MAAM,MAAM,WAAW,mBAAS;AACtC,aAAO;AAAA,QACL,MAAM,GAAG,MAAM,SAAS,CAAC,KAAK,OAAE,IAAI,GAAG,CAAC;AAAA,QACxC,OAAO;AAAA,QACP,SAAS,MAAM,YAAY;AAAA,MAC7B;AAAA,IACF,CAAC;AACD,UAAM,SAAS,MAAM,SAAS,OAAO,CAAC;AAAA,MACpC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,yBAAyB,SAAS,IACvC,mFACA;AAAA,MACJ;AAAA,IACF,CAAC,CAAC;AACF,mBAAe,OAAO;AAAA,EACxB;AAEA,QAAM,eAAe,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,0BAA0B,GAAG,YAAY,CAAC,CAAC;AAChF,MAAI,aAAa,WAAW,GAAG;AAC7B,IAAG,KAAK,6EAAiB;AACzB,QAAI,cAAc;AAEhB,YAAMC,UAAS,kBAAkB,oBAAoBD,UAAS,GAAG,GAAG,YAAY;AAChF,MAAAC,QAAO,OAAO;AACd,YAAM,WAAW,KAAKA,OAAM;AAC5B,MAAG,QAAQ,iBAAO,WAAW,WAAM,YAAY,EAAE;AAAA,IACnD;AACA;AAAA,EACF;AAGA,QAAM,cAAc,gBAAgB,eAAeD,UAAS,GAAG;AAE/D,QAAM,MAA0B;AAAA,IAC9B;AAAA,IACA;AAAA,IACA,MAAM;AAAA,IACN,YAAY,CAAC;AAAA,EACf;AAGA,EAAG,QAAQ,iDAAc;AACzB,QAAM,gBAAgB,cAAc,GAAG;AAGvC,QAAM,SAAS,kBAAkB,oBAAoB,aAAa,UAAU;AAC5E,SAAO,OAAO;AACd,SAAO,UAAU,CAAC,GAAG,oBAAI,IAAI,CAAC,GAAG,OAAO,SAAS,GAAG,YAAY,CAAC,CAAC;AAClE,QAAM,WAAW,KAAK,MAAM;AAE5B,EAAG,QAAQ,2BAAO;AAClB,MAAI,cAAc;AAChB,IAAG,QAAQ,iBAAO,WAAW,WAAM,YAAY,EAAE;AAAA,EACnD;AACA,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,gEAAkC;AAC5C;AAEA,eAAsB,mBAAkC;AACtD,QAAM,UAAU;AAClB;AAEA,eAAsB,iBAAiB,KAA4B;AACjE,EAAG,QAAQ,uCAAS;AAEpB,QAAM,QAAQ,MAAM,iBAAiB,GAAG;AACxC,QAAM,WAAW,MAAM,eAAe,GAAG;AAEzC,MAAI,MAAM,cAAc;AACtB,IAAG,KAAK,4GAAiC;AACzC;AAAA,EACF;AAGA,MAAI,SAAS,MAAM,UAAU,SAAS,GAAG;AACvC,IAAG,QAAQ,iBAAO,SAAS,MAAM,UAAU,KAAK,IAAI,CAAC,EAAE;AAAA,EACzD;AACA,MAAI,SAAS,MAAM,WAAW,SAAS,GAAG;AACxC,IAAG,QAAQ,mCAAU,SAAS,MAAM,WAAW,KAAK,IAAI,CAAC,EAAE;AAAA,EAC7D;AACA,MAAI,SAAS,IAAI,WAAW;AAC1B,IAAG,QAAQ,QAAQ,SAAS,IAAI,YAAY,OAAO,KAAK,SAAS,IAAI,iBAAiB,SAAS,GAAG;AAAA,EACpG;AAGA,UAAQ,IAAI,EAAE;AACd,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,WAAW,GAAG;AACrD,UAAM,YAAY,MAAM,QAAQ,GAAG,GAAG,aAAa;AACnD,QAAI,WAAW;AACb,MAAG,QAAQ,GAAG,KAAK,KAAK,EAAE;AAAA,IAC5B,OAAO;AACL,MAAG,KAAK,GAAG,KAAK,KAAK,4BAAQ;AAAA,IAC/B;AAAA,EACF;AAEA,MAAI,MAAM,aAAa;AACrB,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,iBAAO,MAAM,WAAW,EAAE;AAClC,UAAM,OAAO,SAAS,MAAM,WAAW;AACvC,QAAI,MAAM;AACR,MAAG,KAAK,8BAAU,MAAM,WAAW,WAAM,IAAI,mDAAqB;AAAA,IACpE;AAAA,EACF;AACF;AA7KA;AAAA;AAAA;AAAA;AACA;AAOA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACZA;AAAA;AAAA;AAAA;AAAA,SAAS,QAAAE,QAAM,YAAAC,iBAAgB;AAC/B,OAAOC,UAAQ;AAQf,eAAsB,YAAY,KAAa,SAAiC;AAC9E,qBAAmB;AAGnB,QAAM,EAAE,WAAAC,YAAW,oBAAAC,oBAAmB,IAAI,MAAM;AAChD,MAAID,YAAW;AACb,UAAM,EAAE,QAAQ,SAAS,IAAIC,oBAAmB;AAChD,QAAI,OAAO,SAAS,GAAG;AACrB,MAAG,QAAQ,mCAAe;AAC1B,iBAAW,KAAK,QAAQ;AACtB,QAAG,MAAM,EAAE,KAAK;AAChB,QAAG,KAAK,mBAAS,EAAE,GAAG,EAAE;AAAA,MAC1B;AACA,YAAM,EAAE,SAASC,UAAS,IAAI,MAAM,OAAO,UAAU;AACrD,YAAM,EAAE,QAAQ,IAAI,MAAMA,UAAS,OAAO,CAAC;AAAA,QACzC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC,CAAC;AACF,UAAI,CAAC,QAAS;AAAA,IAChB;AACA,QAAI,SAAS,SAAS,GAAG;AACvB,iBAAW,KAAK,UAAU;AACxB,QAAG,KAAK,EAAE,KAAK;AACf,YAAI,EAAE,KAAM,CAAG,KAAK,EAAE,IAAI;AAAA,MAC5B;AAAA,IACF;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,WAAW,GAAG;AAC1C,MAAI,iBAAiB,CAAC,SAAS;AAC7B,UAAM,QAAQ,MAAM,iBAAiB,GAAG;AACxC,UAAM,sBAAsB,KAAK,KAAK;AACtC;AAAA,EACF;AAGA,MAAI,CAAC,SAAS;AACZ,UAAM,WAAW,MAAM,oBAAoB,GAAG;AAC9C,QAAI,UAAU;AACZ,YAAM,EAAE,SAASA,UAAS,IAAI,MAAM,OAAO,UAAU;AACrD,YAAMC,UAAS,MAAM,OAAO,OAAO,GAAG;AACtC,cAAQ,IAAI,EAAE;AACd,MAAG,KAAK,yFAAmB;AAG3B,cAAQ,IAAI,EAAE;AACd,YAAM,EAAE,UAAU,IAAI,MAAMD,UAAS,OAAO,CAAC;AAAA,QAC3C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC,CAAC;AAEF,UAAI,WAAW;AACb,YAAI;AACF,gBAAM,EAAE,mBAAAE,mBAAkB,IAAI,MAAM;AACpC,gBAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,gBAAM,EAAE,aAAAC,cAAa,qBAAAC,qBAAoB,IAAI,MAAM;AAEnD,kBAAQ,IAAI,EAAE;AACd,gBAAM,YAAY,MAAMH,mBAAkB,GAAG;AAC7C,gBAAM,aAAaC,eAAc,SAAS;AAC1C,UAAAC,aAAY,UAAU;AAEtB,gBAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,gBAAM,YAAYT,OAAK,KAAK,QAAQ,WAAW;AAC/C,gBAAME,KAAG,UAAU,SAAS;AAC5B,gBAAM,aAAaD,UAAS,GAAG;AAC/B,gBAAM,iBAAiBS,qBAAoB,YAAY,UAAU;AACjE,gBAAMR,KAAG,UAAUF,OAAK,WAAW,GAAG,KAAK,KAAK,GAAG,gBAAgB,MAAM;AACzE,kBAAQ,IAAI,EAAE;AACd,UAAG,QAAQ,mDAA0B,KAAK,KAAK;AAAA,QACjD,QAAQ;AACN,UAAG,KAAK,oDAAY;AAAA,QACtB;AAAA,MACF;AAGA,cAAQ,IAAI,EAAE;AACd,YAAM,EAAE,WAAW,IAAI,MAAMK,UAAS,OAAO,CAAC;AAAA,QAC5C,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX,CAAC,CAAC;AAEF,UAAI,YAAY;AACd,eAAO,MAAM,wBAAwB,KAAKJ,UAAS,GAAG,CAAC;AAAA,MACzD;AACA;AAAA,IACF;AAAA,EACF;AAGA,EAAG,KAAK,GAAG,GAAG,uCAAS;AACvB,EAAG,KAAK,6GAAwB;AAChC,EAAG,KAAK,kHAA6B;AACrC,UAAQ,IAAI,EAAE;AAEd,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AAErD,MAAI;AACJ,MAAI,SAAS;AACX,kBAAc;AACd,IAAG,QAAQ,6BAAS,WAAW,EAAE;AAAA,EACnC,OAAO;AACL,UAAM,SAAS,MAAM,SAAS,OAAO,CAAC;AAAA,MACpC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,MACT,UAAU,CAAC,MAAc;AACvB,YAAI,CAAC,EAAE,KAAK,EAAG,QAAO;AACtB,YAAI,CAAC,uBAAuB,KAAK,EAAE,KAAK,CAAC,GAAG;AAC1C,iBAAO;AAAA,QACT;AACA,eAAO;AAAA,MACT;AAAA,IACF,CAAC,CAAC;AACF,kBAAc,OAAO,KAAK,KAAK;AAAA,EACjC;AAGA,QAAM,aAAaD,OAAK,KAAK,WAAW;AAExC,MAAI,MAAME,KAAG,WAAW,UAAU,GAAG;AACnC,UAAM,iBAAiB,MAAM,WAAW,UAAU;AAClD,QAAI,gBAAgB;AAClB,cAAQ,IAAI,EAAE;AACd,MAAG,KAAK,GAAG,WAAW,oFAAwB;AAC9C,YAAM,QAAQ,MAAM,iBAAiB,UAAU;AAC/C,YAAM,sBAAsB,YAAY,KAAK;AAC7C;AAAA,IACF;AAEA,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,GAAG,WAAW,mEAAiB;AACvC,IAAG,KAAK,qEAAmB;AAAA,EAC7B,OAAO;AACL,UAAMA,KAAG,UAAU,UAAU;AAC7B,IAAG,QAAQ,GAAG,WAAW,6BAAS;AAAA,EACpC;AAGA,QAAM,iBAAiB,YAAY,WAAW;AAChD;AAEA,eAAe,iBAAiB,YAAoB,aAAoC;AAEtF,QAAM,EAAE,oBAAAS,oBAAmB,IAAI,MAAM;AACrC,QAAM,mBAAmB,MAAMA,oBAAmB;AAClD,MAAI,CAAC,kBAAkB;AACrB,IAAG,QAAQ,2DAAkC;AAC7C,IAAG,KAAK,mKAAsC;AAC9C,YAAQ,IAAI,EAAE;AAAA,EAChB;AAEA,EAAG,KAAK,GAAG,GAAG,uCAAS;AAEvB,QAAM,SAAS,oBAAoB,aAAa,WAAW;AAC3D,QAAM,QAAQ;AAAA,IACZ,KAAK;AAAA,IACL;AAAA,IACA,iBAAiB,oBAAI,IAAI;AAAA,EAC3B;AAEA,QAAM,SAAS,MAAM,iBAAiB,IAAI,KAAK;AAE/C,MAAI,OAAO,WAAW,WAAW;AAE/B,QAAI;AACF,YAAM,EAAE,gBAAAC,gBAAe,IAAI,MAAM;AACjC,YAAMA,gBAAe,UAAU;AAAA,IACjC,QAAQ;AAAA,IAA+B;AAEvC,UAAM,YAAY,OAAO,KAAK;AAC9B,UAAM,eAAe,eAAe,QAAQ,IAAI;AAChD,UAAM,eAAe,aAAa,YAAY,UAAU,YAAY,YAAY;AAAA,EAClF,OAAO;AACL,eAAW,OAAO,OAAO,QAAQ;AAC/B,MAAG,MAAM,IAAI,OAAO;AAAA,IACtB;AAAA,EACF;AACF;AAEA,eAAe,eAAe,aAAqB,YAAoB,YAAsB,cAAsC;AACjI,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAMN,UAAS,MAAM,OAAO,OAAO,GAAG;AACtC,QAAM,EAAE,OAAAO,OAAM,IAAI,MAAM;AAExB,EAAG,KAAK,GAAG,GAAG,cAAI;AAElB,UAAQ,IAAI,OAAE,QAAQ,8EAAkB,CAAC;AACzC,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,mCAAU,CAAC;AAC7B,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,mCAAoB,OAAE,IAAI,kBAAkB,CAAC,EAAE;AAC9E,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,2CAAkB,OAAE,IAAI,aAAa,CAAC,EAAE;AACvE,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,uCAAmB,OAAE,IAAI,WAAW,CAAC,EAAE;AACtE,UAAQ,IAAI,KAAK,OAAE,QAAQ,QAAG,CAAC,+CAAiB,OAAE,IAAI,iCAA4B,CAAC,EAAE;AAGrF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,OAAO,8DAAiB,CAAC;AACvC,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,KAAKP,OAAM,KAAK,cAAc,CAAC,2HAAiC;AAC5E,UAAQ,IAAI,KAAKA,OAAM,KAAK,YAAY,CAAC,yHAAoC;AAC7E,UAAQ,IAAI,KAAKA,OAAM,KAAK,YAAY,CAAC,kHAAkC;AAE3E,MAAI,WAAW,SAAS,KAAK,GAAG;AAC9B,YAAQ,IAAI,KAAKA,OAAM,KAAK,KAAK,CAAC,wGAAiD;AAAA,EACrF;AACA,MAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,YAAQ,IAAI,KAAKA,OAAM,KAAK,QAAQ,CAAC,4HAAuC;AAAA,EAC9E;AACA,MAAI,WAAW,SAAS,SAAS,GAAG;AAClC,YAAQ,IAAI,KAAKA,OAAM,KAAK,SAAS,CAAC,+GAAoC;AAAA,EAC5E;AACA,MAAI,WAAW,SAAS,QAAQ,GAAG;AACjC,YAAQ,IAAI,KAAKA,OAAM,KAAK,QAAQ,CAAC,iEAAwC;AAAA,EAC/E;AACA,MAAI,WAAW,SAAS,UAAU,GAAG;AACnC,YAAQ,IAAI,KAAKA,OAAM,KAAK,UAAU,CAAC,gFAAwC;AAAA,EACjF;AACA,MAAI,WAAW,SAAS,KAAK,GAAG;AAC9B,YAAQ,IAAI,KAAKA,OAAM,KAAK,kBAAQ,CAAC,kHAAuC;AAAA,EAC9E;AAGA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,OAAO,6BAAS,CAAC;AAC/B,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AAEpD,QAAM,SAAS;AAAA,IACb,EAAE,OAAO,+BAAW,MAAM,YAAY;AAAA,IACtC,EAAE,OAAO,0BAAW,MAAM,mBAAmB;AAAA,IAC7C,EAAE,OAAO,yCAAW,MAAM,mBAAmB;AAAA,IAC7C,EAAE,OAAO,uBAAa,MAAM,wBAAwB;AAAA,IACpD,EAAE,OAAO,yCAAW,MAAM,8BAA8B;AAAA,IACxD,GAAI,WAAW,SAAS,KAAK,IAAI,CAAC,EAAE,OAAO,0BAAW,MAAM,OAAO,CAAC,IAAI,CAAC;AAAA,EAC3E;AAEA,aAAW,SAAS,QAAQ;AAC1B,UAAM,SAAS,MAAMJ,KAAG,WAAWF,OAAK,YAAY,MAAM,IAAI,CAAC;AAC/D,YAAQ,IAAI,KAAK,SAAS,OAAE,QAAQ,QAAG,IAAI,OAAE,IAAI,QAAG,CAAC,IAAI,MAAM,MAAM,OAAO,EAAE,CAAC,IAAI,OAAE,IAAI,MAAM,IAAI,CAAC,EAAE;AAAA,EACxG;AAGA,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACzC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC,CAAC;AAEF,MAAI,SAAS;AACX,UAAM,EAAE,eAAAc,eAAc,IAAI,MAAM;AAEhC,UAAMD,OAAM,GAAI;AAChB,UAAM,UAAUC,eAAc,oEAAkB;AAEhD,QAAI;AACF,YAAM,EAAE,mBAAAP,mBAAkB,IAAI,MAAM;AACpC,YAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,YAAM,EAAE,aAAAC,cAAa,qBAAAC,qBAAoB,IAAI,MAAM;AAEnD,YAAM,YAAY,MAAMH,mBAAkB,UAAU;AACpD,YAAM,aAAaC,eAAc,SAAS;AAC1C,cAAQ,QAAQ,2BAAO;AAEvB,YAAMK,OAAM,GAAG;AACf,MAAAJ,aAAY,UAAU;AAEtB,YAAMI,OAAM,GAAG;AACf,YAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,YAAM,YAAYb,OAAK,YAAY,QAAQ,WAAW;AACtD,YAAME,KAAG,UAAU,SAAS;AAC5B,YAAM,iBAAiBQ,qBAAoB,YAAY,WAAW;AAClE,YAAMR,KAAG,UAAUF,OAAK,WAAW,GAAG,KAAK,KAAK,GAAG,gBAAgB,MAAM;AAEzE,YAAMa,OAAM,GAAG;AACf,cAAQ,IAAI,EAAE;AACd,MAAG,QAAQ,mDAA0B,KAAK,KAAK;AAAA,IACjD,QAAQ;AACN,cAAQ,KAAK,2BAAO;AACpB,YAAMA,OAAM,GAAG;AACf,MAAG,KAAK,+CAAsB;AAAA,IAChC;AAAA,EACF,OAAO;AACL,UAAMA,OAAM,GAAG;AACf,IAAG,KAAK,+CAAsB;AAAA,EAChC;AAGA,MAAI,CAAC,cAAc;AACjB,YAAQ,MAAM,UAAU;AAAA,EAC1B;AAGA,UAAQ,IAAI,EAAE;AACd,MAAI,CAAC,cAAc;AACjB,YAAQ,IAAI,KAAKP,OAAM,MAAM,QAAG,CAAC,OAAO,WAAW,IAAI,OAAE,IAAI,2BAAO,CAAC,EAAE;AAAA,EACzE;AACA,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,oGAAmC;AAC9C,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AAKpD,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,eAAAQ,eAAc,IAAI,MAAM;AAChC,QAAM,aAAaA,eAAc,qDAAkB;AACnD,MAAI;AACF,UAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,UAAM,SAAS,MAAMA,iBAAgB;AACrC,QAAI,OAAO,WAAW,mBAAmB;AACvC,iBAAW,QAAQ,8DAAiB;AAAA,IACtC,WAAW,OAAO,WAAW,WAAW;AACtC,iBAAW,QAAQ,wGAAkC;AAAA,IACvD,OAAO;AACL,iBAAW,QAAQ,wDAAgB;AAAA,IACrC;AACA,IAAG,KAAK,6GAAkC;AAC1C,QAAI,OAAO,YAAY;AACrB,MAAG,KAAK,8BAAU,OAAO,UAAU,EAAE;AAAA,IACvC;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,eAAW,KAAK,iEAAoB,GAAG,EAAE;AACzC,IAAG,KAAK,8EAA4B;AACpC,IAAG,KAAK,4CAA4C;AAAA,EACtD;AAGA,QAAM,EAAE,gBAAAC,iBAAgB,cAAc,UAAU,IAAI,MAAM;AAC1D,QAAM,UAAUA,gBAAe;AAC/B,MAAI,qBAAqB;AACzB,MAAI;AACF,UAAM,YAAY,MAAMd,KAAG,SAAS,SAAS,MAAM;AACnD,yBAAqB,UAAU,SAAS;AAAA,EAC1C,QAAQ;AAAA,EAAiB;AAGzB,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,QAAM,EAAE,OAAO,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACxC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,oBAAoB,OAAE,IAAI,mFAAuB,CAAC,IAAI,OAAO,SAAS;AAAA,MAC9E,EAAE,MAAM,oBAAoB,OAAE,IAAI,2GAAoD,CAAC,IAAI,OAAO,OAAO;AAAA,IAC3G;AAAA,EACF,CAAC,CAAC;AAEF,QAAM,UAAU,WAAW;AAG3B,MAAI,WAAW,CAAC,oBAAoB;AAClC,QAAI;AACF,YAAM,EAAE,kBAAAe,kBAAiB,IAAI,MAAM;AACnC,YAAM,YAAYA,kBAAiB;AACnC,YAAM,YAAY,MAAMf,KAAG,SAAS,SAAS,MAAM,EAAE,MAAM,MAAM,EAAE;AACnE,UAAI,CAAC,UAAU,SAAS,aAAa,GAAG;AACtC,cAAMA,KAAG,UAAUF,OAAK,SAAS,IAAI,CAAC;AACtC,cAAME,KAAG,WAAW,SAAS;AAAA;AAAA,EAA+B,SAAS;AAAA,CAAI;AACzE,cAAMW,OAAM,GAAG;AACf,QAAG,QAAQ,6CAAyB;AACpC,QAAG,KAAK,oFAA6B;AAAA,MACvC;AAAA,IACF,QAAQ;AAAA,IAAoB;AAAA,EAC9B;AAEA,QAAM,MAAM,UAAU,0CAA0C;AAEhE,UAAQ,IAAI,EAAE;AACd,MAAI,CAAC,cAAc;AACjB,YAAQ,IAAI,OAAE,IAAI,eAAU,WAAW,EAAE,CAAC;AAAA,EAC5C;AACA,UAAQ,IAAI,OAAE,IAAI,YAAO,GAAG,EAAE,CAAC;AAC/B,UAAQ,IAAI,EAAE;AAEd,MAAI;AACF,UAAM,EAAE,gBAAAD,gBAAe,IAAI,MAAM;AACjC,UAAMA,gBAAe,UAAU;AAE/B,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,YAAQ,MAAM,UAAU;AACxB,UAAM,QAAQ,IAAI,MAAM,GAAG;AAC3B,UAAM,MAAM,MAAM,CAAC,GAAI,MAAM,MAAM,CAAC,GAAG;AAAA,MACrC,OAAO;AAAA,MACP,KAAK;AAAA,IACP,CAAC;AAGD,QAAI,CAAC,cAAc;AACjB,YAAM,EAAE,eAAAM,eAAc,IAAI,MAAM;AAChC,MAAAA,eAAc,UAAU;AAAA,IAC1B;AAAA,EACF,QAAQ;AACN,IAAG,KAAK,2EAAoB,GAAG,EAAE;AAAA,EACnC;AACF;AAEA,eAAe,sBACb,KACA,OACe;AACf,QAAM,EAAE,aAAAC,aAAY,IAAI,MAAM;AAC9B,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAMb,UAAS,MAAM,OAAO,OAAO,GAAG;AAEtC,EAAG,QAAQ,uCAAS;AAEpB,QAAM,aAAa,OAAO,QAAQa,YAAW,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,OAAO;AAAA,IACnE;AAAA,IACA,OAAO,KAAK;AAAA,IACZ,WAAW,MAAM,QAAQ,GAAG,GAAG,aAAa;AAAA,EAC9C,EAAE;AAEF,aAAW,KAAK,YAAY;AAC1B,QAAI,EAAE,WAAW;AACf,MAAG,QAAQ,EAAE,KAAK;AAAA,IACpB,OAAO;AACL,cAAQ,IAAI,OAAE,IAAI,UAAO,EAAE,KAAK,IAAIb,OAAM,KAAK,oBAAK,CAAC,EAAE,CAAC;AAAA,IAC1D;AAAA,EACF;AAGA,QAAM,gBAAgB,MAAM,WAAW,GAAG;AAC1C,MAAI,eAAe;AACjB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,gCAAY,OAAE,OAAO,cAAc,IAAI,CAAC,EAAE,CAAC;AAAA,EAC/D;AAEA,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,OAAO,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACxC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP;AAAA,QACE,MAAM,mEAAyB,OAAE,IAAI,2DAAwB,CAAC;AAAA,QAC9D,OAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM,+EAAqB,OAAE,IAAI,yDAA0C,CAAC;AAAA,QAC5E,OAAO;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM,sDAA2B,OAAE,IAAI,wCAAmC,CAAC;AAAA,QAC3E,OAAO;AAAA,MACT;AAAA,MACA,EAAE,MAAMA,OAAM,KAAK,wBAAO,GAAG,OAAO,OAAO;AAAA,IAC7C;AAAA,EACF,CAAC,CAAC;AAEF,UAAQ,QAAQ;AAAA,IACd,KAAK,YAAY;AACf,YAAM,EAAE,iBAAAc,iBAAgB,IAAI,MAAM;AAClC,YAAMA,iBAAgB,KAAK,CAAC,CAAC;AAC7B;AAAA,IACF;AAAA,IACA,KAAK,WAAW;AACd,YAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,YAAMA,iBAAgB,GAAG;AACzB;AAAA,IACF;AAAA,IACA,KAAK,UAAU;AACb,YAAM,EAAE,WAAAC,WAAU,IAAI,MAAM;AAC5B,YAAMA,WAAU;AAChB;AAAA,IACF;AAAA,IACA;AACE,cAAQ,IAAI,EAAE;AAAA,EAClB;AACF;AAEA,eAAe,wBAAwB,YAAoB,aAAoC;AAC7F,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAMhB,UAAS,MAAM,OAAO,OAAO,GAAG;AACtC,QAAM,EAAE,eAAAiB,eAAc,IAAI,MAAM;AAChC,QAAM,EAAE,gBAAAC,gBAAe,IAAI,MAAM;AACjC,QAAM,EAAE,yBAAAC,yBAAwB,IAAI,MAAM;AAC1C,QAAM,EAAE,iBAAAC,iBAAgB,IAAI,MAAM;AAClC,QAAM,EAAE,aAAAC,cAAa,iBAAAC,kBAAiB,OAAAf,OAAM,IAAI,MAAM;AAGtD,QAAM,EAAE,oBAAAF,oBAAmB,IAAI,MAAM;AACrC,QAAMA,oBAAmB;AAGzB,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,4EAA4B;AACpC,QAAM,YAAa,SAAmE;AACtF,QAAM,EAAE,QAAQ,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACzC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,mBAAmB,OAAE,IAAI,iDAAc,CAAC,IAAI,OAAO,YAAY,SAAS,KAAK;AAAA,MACrF,EAAE,MAAM,mBAAmB,OAAE,IAAI,+DAAkB,CAAC,IAAI,OAAO,UAAU,SAAS,KAAK;AAAA,MACvF,EAAE,MAAM,mBAAmB,OAAE,IAAI,4EAAqB,CAAC,IAAI,OAAO,cAAc,SAAS,KAAK;AAAA,MAC9F,EAAE,MAAM,mBAAmB,OAAE,IAAI,8EAAuB,CAAC,IAAI,OAAO,SAAS;AAAA,MAC7E,EAAE,MAAM,mBAAmB,OAAE,IAAI,4EAAqB,CAAC,IAAI,OAAO,UAAU;AAAA,MAC5E,IAAI,UAAU,wJAA2B;AAAA,MACzC,EAAE,MAAML,OAAM,MAAM,kCAAS,GAAG,OAAO,WAAW;AAAA,IACpD;AAAA,EACF,CAAC,CAAC;AACF,QAAM,kBAAmB,QAAqB,OAAO,OAAK,MAAM,UAAU;AAG1E,UAAQ,IAAI,EAAE;AACd,QAAM,WAAW,MAAMqB,aAAY,mDAAgB,YAAY;AAC7D,UAAM,SAAS,MAAMH,gBAAe,UAAU;AAC9C,UAAMX,OAAM,GAAG;AACf,WAAO;AAAA,EACT,CAAC;AAGD,QAAM,aAAuB,CAAC;AAC9B,MAAI,gBAAgB,SAAS,QAAQ,EAAG,YAAW,KAAK,QAAQ;AAChE,MAAI,gBAAgB,SAAS,SAAS,EAAG,YAAW,KAAK,SAAS;AAElE,QAAM,gBAAgB;AAAA,IACpB,MAAM;AAAA,IACN;AAAA,IACA,aAAa,CAAC;AAAA,IACd;AAAA,IACA,cAAc,EAAE,WAAW,MAAM,aAAa,MAAM,MAAM,SAAS,IAAI,UAAU;AAAA,IACjF,OAAO;AAAA,MACL,KAAK,gBAAgB,SAAS,UAAU;AAAA,MACxC,UAAU,gBAAgB,SAAS,UAAU;AAAA,MAC7C,WAAW;AAAA,MACX,SAAS,gBAAgB,SAAS,SAAS;AAAA,IAC7C;AAAA,IACA,eAAe;AAAA,EACjB;AAEA,UAAQ,IAAI,EAAE;AACd,QAAMe,iBAAgB,sDAAmB,CAAC,aAAa,uBAAuB,GAAG,YAAY;AAC3F,UAAML,eAAc,YAAY,UAAU,aAAa;AACvD,UAAMV,OAAM,GAAG;AAAA,EACjB,CAAC;AAGD,QAAM,cAAc,CAAC,QAAQ;AAC7B,MAAI,gBAAgB,SAAS,UAAU,EAAG,aAAY,KAAK,YAAY,KAAK;AAC5E,MAAI,gBAAgB,SAAS,QAAQ,EAAG,aAAY,KAAK,QAAQ;AACjE,QAAM,gBAAgB,CAAC,GAAG,aAAa,GAAG,UAAU;AAEpD,QAAM,UAAU;AAAA,IACd,KAAK;AAAA,IACL;AAAA,IACA,MAAM;AAAA,IACN,YAAY,EAAE,kBAAkB,aAAa,UAAU,YAAY;AAAA,EACrE;AAEA,UAAQ,IAAI,EAAE;AACd,QAAMc,aAAY,mDAAgB,YAAY;AAC5C,UAAMD,iBAAgB,eAAe,OAAO;AAC5C,UAAMb,OAAM,GAAG;AAAA,EACjB,CAAC;AAGD,UAAQ,IAAI,EAAE;AACd,QAAMe,iBAAgB,gEAAmB,CAAC,YAAY,eAAe,WAAW,GAAG,YAAY;AAC7F,UAAMH,yBAAwB,UAAU;AACxC,UAAMZ,OAAM,GAAG;AAAA,EACjB,CAAC;AAGD,UAAQ,IAAI,EAAE;AACd,QAAMc,aAAY,uCAAc,YAAY;AAC1C,UAAM,SAAS,oBAAoB,aAAa,WAAW;AAC3D,WAAO,UAAU;AACjB,UAAM,WAAW,YAAY,MAAM;AACnC,UAAMd,OAAM,GAAG;AAAA,EACjB,CAAC;AAED,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,uFAAsB;AAGjC,UAAQ,IAAI,EAAE;AACd,MAAI;AACF,UAAM,EAAE,mBAAAN,mBAAkB,IAAI,MAAM;AACpC,UAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,UAAM,EAAE,aAAAC,cAAa,qBAAAC,qBAAoB,IAAI,MAAM;AAEnD,UAAM,YAAY,MAAMH,mBAAkB,UAAU;AACpD,UAAM,aAAaC,eAAc,SAAS;AAC1C,IAAAC,aAAY,UAAU;AAEtB,UAAM,SAAQ,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AAClD,UAAM,YAAYT,OAAK,YAAY,QAAQ,WAAW;AACtD,UAAME,KAAG,UAAU,SAAS;AAC5B,UAAMA,KAAG,UAAUF,OAAK,WAAW,GAAG,KAAK,KAAK,GAAGU,qBAAoB,YAAY,WAAW,GAAG,MAAM;AAEvG,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,mDAA0B,KAAK,KAAK;AAAA,EAC9C,QAAQ;AACN,IAAG,KAAK,mDAA0B;AAAA,EACpC;AAGA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,EAAE;AAEd,QAAM,EAAE,OAAO,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IACxC,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,wCAAoB,OAAE,IAAI,gBAAW,CAAC,IAAI,OAAO,SAAS;AAAA,MAClE,EAAE,MAAMJ,OAAM,KAAK,8CAAW,GAAG,OAAO,OAAO;AAAA,IACjD;AAAA,EACF,CAAC,CAAC;AAEF,MAAI,WAAW,QAAQ;AACrB,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,wEAAsB;AAC9B;AAAA,EACF;AAEA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,iBAAY,CAAC;AAC/B,UAAQ,IAAI,EAAE;AAEd,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,YAAQ,MAAM,UAAU;AACxB,UAAM,MAAM,UAAU,CAAC,GAAG,EAAE,OAAO,WAAW,KAAK,WAAW,CAAC;AAAA,EACjE,QAAQ;AACN,IAAG,KAAK,gFAAyB;AAAA,EACnC;AACF;AA4BA,eAAe,oBAAoB,KAA+B;AAChE,QAAM,UAAU;AAAA,IACd;AAAA,IAAgB;AAAA,IAAQ;AAAA,IAAW;AAAA,IACnC;AAAA,IAAU;AAAA,IAAc;AAAA,IAAoB;AAAA,IAC5C;AAAA,IAAW;AAAA,IAAiB;AAAA,IAAY;AAAA,EAC1C;AAEA,aAAW,UAAU,SAAS;AAC5B,QAAI,MAAMJ,KAAG,WAAWF,OAAK,KAAK,MAAM,CAAC,EAAG,QAAO;AAAA,EACrD;AACA,SAAO;AACT;AAnrBA;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AACA;AAAA;AAAA;;;ACPA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAMA,eAAsB,cAA6B;AACjD,EAAG,QAAQ,wBAAS;AACpB,QAAM,QAAiC;AAAA,IACrC,CAAC,YAAmB,6FAAuB;AAAA,IAC3C,CAAC,WAAmB,+EAAkC;AAAA,IACtD,CAAC,aAAmB,sDAAkC;AAAA,IACtD,CAAC,cAAmB,iEAAe;AAAA,IACnC,CAAC,cAAmB,6CAAoB;AAAA,IACxC,CAAC,YAAmB,mEAAiB;AAAA,IACrC,CAAC,aAAmB,6EAAsB;AAAA,IAC1C,CAAC,WAAmB,wEAAiB;AAAA,IACrC,CAAC,cAAmB,4CAAc;AAAA,IAClC,CAAC,eAAmB,0DAAa;AAAA,IACjC,CAAC,iBAAmB,2CAAa;AAAA,IACjC,CAAC,cAAmB,+CAAiB;AAAA,IACrC,CAAC,YAAmB,qBAAM;AAAA,EAC5B;AACA,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO;AAC/B,YAAQ,IAAI,KAAK,OAAE,OAAO,IAAI,OAAO,EAAE,CAAC,CAAC,IAAI,OAAE,IAAI,IAAI,CAAC,EAAE;AAAA,EAC5D;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kHAAqE,CAAC;AACxF,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,yIAA6E,CAAC;AAClG;AA9BA;AAAA;AAAA;AAGA;AACA;AAAA;AAAA;;;ACDA,SAAS,QAAA6B,cAAY;AACrB,OAAOC,UAAQ;AAWf,eAAsB,aAAa,KAAa,aAAoC;AAClF,QAAM,UAAUD,OAAK,KAAK,MAAM;AAChC,QAAMC,KAAG,UAAU,OAAO;AAE1B,QAAM,eAAeD,OAAK,SAAS,aAAa;AAChD,MAAI,MAAMC,KAAG,WAAW,YAAY,GAAG;AACrC,IAAG,KAAK,sEAA8B;AACtC;AAAA,EACF;AAEA,QAAMA,KAAG,UAAU,cAAc;AAAA,IAC/B,qBAAgB,WAAW;AAAA,IAC3B;AAAA,IAAI;AAAA,IAAsB;AAAA,IAC1B;AAAA,IAAI;AAAA,IAAqB;AAAA,IAAe;AAAA,IAAmB;AAAA,IAC3D;AAAA,IAAI;AAAA,IAA0B;AAAA,IAC9B;AAAA,IAAI;AAAA,IAAuB;AAAA,IAAe;AAAA,IAAc;AAAA,IACxD;AAAA,IAAI;AAAA,IACJ;AAAA,IAA0B;AAAA,IAA4B;AAAA,EACxD,EAAE,KAAK,IAAI,IAAI,IAAI;AAEnB,EAAG,QAAQ,kEAAoC;AACjD;AAUA,eAAsB,iBAAiB,KAAwC;AAC7E,QAAM,aAAa;AAAA,IACjBD,OAAK,KAAK,QAAQ,aAAa;AAAA,IAC/BA,OAAK,KAAK,aAAa;AAAA,IACvBA,OAAK,KAAK,QAAQ,aAAa;AAAA,EACjC;AAEA,MAAI,WAA0B;AAC9B,aAAW,KAAK,YAAY;AAC1B,QAAI,MAAMC,KAAG,WAAW,CAAC,GAAG;AAC1B,iBAAW;AACX;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,MACL,UAAU;AAAA,MACV,eAAe,kBAAkB;AAAA,MACjC,gBAAgB;AAAA,MAChB,SAAS,kBAAkB,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,MAC7C,UAAU,CAAC,mHAAkD;AAAA,IAC/D;AAAA,EACF;AAEA,QAAM,UAAU,MAAMA,KAAG,SAAS,UAAU,MAAM;AAClD,QAAM,UAAoB,CAAC;AAC3B,MAAI,SAAS;AAEb,aAAWC,YAAW,mBAAmB;AACvC,UAAM,MAAM,QAAQ,QAAQA,SAAQ,MAAM;AAC1C,QAAI,QAAQ,IAAI;AACd,cAAQ,KAAKA,SAAQ,KAAK;AAC1B;AAAA,IACF;AAGA,UAAM,cAAc,QAAQ,QAAQ,SAAS,MAAM,CAAC;AACpD,UAAM,iBAAiB,cAAc,IACjC,QAAQ,MAAM,KAAK,WAAW,IAC9B,QAAQ,MAAM,GAAG;AAErB,UAAM,QAAQ,eAAe,MAAM,IAAI,EAAE;AAAA,MAAO,CAAC,MAC/C,EAAE,KAAK,KAAK,CAAC,EAAE,WAAW,GAAG,KAAK,CAAC,EAAE,WAAW,KAAK,KAAK,EAAE,KAAK,MAAM,eACpE,CAAC,EAAE,WAAW,GAAG;AAAA,IACtB;AAEA,QAAI,MAAM,SAAS,GAAG;AACpB;AAAA,IACF,OAAO;AACL,cAAQ,KAAK,GAAGA,SAAQ,KAAK,oCAAW;AAAA,IAC1C;AAAA,EACF;AAEA,QAAM,WAAqB,CAAC;AAC5B,MAAI,QAAQ,SAAS,KAAK;AACxB,aAAS,KAAK,mKAA2C;AAAA,EAC3D;AAEA,SAAO;AAAA,IACL,UAAU,QAAQ,WAAW;AAAA,IAC7B,eAAe,kBAAkB;AAAA,IACjC,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,EACF;AACF;AAhHA,IAOM;AAPN;AAAA;AAAA;AAKA;AAEA,IAAM,oBAAoB;AAAA,MACxB,EAAE,QAAQ,SAAS,OAAO,yBAAe;AAAA,MACzC,EAAE,QAAQ,SAAS,OAAO,6BAAc;AAAA,MACxC,EAAE,QAAQ,SAAS,OAAO,uCAAmB;AAAA,MAC7C,EAAE,QAAQ,SAAS,OAAO,oCAAgB;AAAA,MAC1C,EAAE,QAAQ,SAAS,OAAO,iDAAwB;AAAA,IACpD;AAAA;AAAA;;;ACVA,SAAS,QAAAC,cAAY;AACrB,OAAOC,UAAQ;AAGf,eAAsB,QAAQ,KAAa,aAAoC;AAC7E,QAAM,SAASD,OAAK,KAAK,MAAM;AAC/B,QAAMC,KAAG,UAAU,MAAM;AAEzB,QAAM,UAAUD,OAAK,QAAQ,QAAQ;AACrC,MAAI,MAAMC,KAAG,WAAW,OAAO,GAAG;AAChC,IAAG,KAAK,iEAAyB;AACjC;AAAA,EACF;AAEA,QAAMA,KAAG,UAAU,SAAS;AAAA,IAC1B,sCAAiC,WAAW;AAAA,IAC5C;AAAA,IAAI;AAAA,IACJ;AAAA,IAAI;AAAA,IACJ;AAAA,IAAI;AAAA,IAAY;AAAA,IAAO;AAAA,IAAc;AAAA,IAAiB;AAAA,IAA4B;AAAA,IAClF;AAAA,IAAI;AAAA,IAAqB;AAAA,IACzB;AAAA,IAAI;AAAA,IAAc;AAAA,IAClB;AAAA,IAAI;AAAA,IAAuB;AAAA,IAAe;AAAA,EAC5C,EAAE,KAAK,IAAI,IAAI,IAAI;AAEnB,EAAG,QAAQ,wDAA0B;AACvC;AA5BA;AAAA;AAAA;AAKA;AAAA;AAAA;;;ACLA;AAAA;AAAA;AAAA;AAAA;AAIA,SAAS,YAAAC,iBAAgB;AAEzB,eAAsB,kBAAkB,KAA4B;AAClE,EAAG,QAAQ,8CAAW;AACtB,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,QAAM,cAAc,QAAQ,eAAeA,UAAS,GAAG;AAEvD,QAAM,aAAa,KAAK,WAAW;AACnC,QAAM,QAAQ,KAAK,WAAW;AAE9B,EAAG,KAAK,EAAE;AACV,EAAG,KAAK,0GAAyC;AACnD;AAEA,eAAsB,sBAAsB,KAA4B;AACtE,EAAG,QAAQ,qCAAY;AAEvB,QAAM,SAAS,MAAM,iBAAiB,GAAG;AAEzC,EAAG,KAAK,oCAAW,OAAO,cAAc,IAAI,OAAO,aAAa,EAAE;AAElE,MAAI,OAAO,QAAQ,SAAS,GAAG;AAC7B,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,kCAAS;AACjB,eAAW,KAAK,OAAO,SAAS;AAC9B,MAAG,KAAK,OAAO,CAAC,EAAE;AAAA,IACpB;AAAA,EACF;AAEA,aAAW,KAAK,OAAO,UAAU;AAC/B,IAAG,KAAK,CAAC;AAAA,EACX;AAEA,MAAI,OAAO,UAAU;AACnB,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,mDAAgB;AAAA,EAC7B,OAAO;AACL,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,2GAAqC;AAAA,EAC/C;AACF;AA5CA;AAAA;AAAA;AAAA;AACA;AACA;AACA;AAAA;AAAA;;;ACAA,SAAS,QAAAC,cAAY;AACrB,OAAOC,UAAQ;AAUf,eAAsB,SAAS,KAAqC;AAClE,QAAM,QAAQ,KAAK,IAAI;AAGvB,QAAM,aAAaD,OAAK,KAAK,QAAQ,aAAa;AAClD,MAAI,SAAS;AAEb,MAAI,MAAMC,KAAG,WAAW,UAAU,GAAG;AACnC,QAAI;AACF,YAAM,SAAS,MAAMA,KAAG,SAAS,UAAU;AAC3C,UAAI,OAAO,eAAe,SAAU,UAAS;AAAA,eACpC,OAAO,eAAe,OAAQ,UAAS;AAAA,eACvC,OAAO,eAAe,QAAS,UAAS;AAAA,IACnD,QAAQ;AAAA,IAER;AAAA,EACF;AAGA,QAAM,UAAUD,OAAK,KAAK,cAAc;AACxC,MAAI,MAAMC,KAAG,WAAW,OAAO,GAAG;AAChC,QAAI;AACF,YAAMC,OAAM,MAAMD,KAAG,SAAS,OAAO;AACrC,UAAI,CAACC,KAAI,SAAS,QAAQA,KAAI,QAAQ,KAAK,SAAS,mBAAmB,GAAG;AACxE,eAAO;AAAA,UACL;AAAA,UACA,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,UAAU,KAAK,IAAI,IAAI;AAAA,QACzB;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,UAAM,EAAE,QAAQ,OAAO,IAAI,MAAM,MAAM,OAAO,CAAC,MAAM,GAAG;AAAA,MACtD;AAAA,MACA,SAAS;AAAA,MACT,KAAK,EAAE,GAAG,QAAQ,KAAK,IAAI,OAAO;AAAA,IACpC,CAAC;AACD,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ,UAAU;AAAA,MAClB,UAAU,KAAK,IAAI,IAAI;AAAA,IACzB;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC9D,WAAO;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR;AAAA,MACA,UAAU,KAAK,IAAI,IAAI;AAAA,IACzB;AAAA,EACF;AACF;AAxEA;AAAA;AAAA;AAAA;AAAA;;;ACGA,SAAS,QAAAC,cAAY;AACrB,OAAOC,UAAQ;AAUf,eAAsB,gBAAgB,KAAqC;AACzE,QAAM,cAAcD,OAAK,KAAK,QAAQ,cAAc;AAEpD,MAAI,CAAE,MAAMC,KAAG,WAAW,WAAW,GAAI;AACvC,WAAO,EAAE,SAAS,OAAO,UAAU,MAAM,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,EACjE;AAEA,MAAI;AACJ,MAAI;AACF,aAAS,MAAMA,KAAG,SAAS,WAAW;AAAA,EACxC,QAAQ;AACN,WAAO,EAAE,SAAS,OAAO,UAAU,MAAM,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AAAA,EACjE;AAEA,QAAM,WAAW,OAAO,YAAY;AACpC,QAAM,QAAQ,OAAO,SAAS,CAAC;AAC/B,QAAM,SAAkC,CAAC;AAGzC,MAAI,MAAM,SAAS,2BAA2B,GAAG;AAC/C,UAAM,aAAa,MAAMA,KAAG,WAAWD,OAAK,KAAK,QAAQ,CAAC;AAC1D,UAAM,YAAY,MAAMC,KAAG,WAAWD,OAAK,KAAK,KAAK,CAAC;AACtD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,cAAc;AAAA,MACtB,QAAQ,cAAc,YAClB,uFACA,GAAG,CAAC,aAAa,WAAW,kBAAQ,EAAE,IAAI,CAAC,YAAY,sBAAY,EAAE,GAAG,KAAK;AAAA,IACnF,CAAC;AAAA,EACH;AAGA,MAAI,MAAM,SAAS,mBAAmB,GAAG;AACvC,UAAM,UAAU,MAAMC,KAAG,WAAWD,OAAK,KAAK,OAAO,CAAC;AACtD,UAAM,WAAW,MAAMC,KAAG,WAAWD,OAAK,KAAK,MAAM,CAAC;AACtD,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN,QAAQ,WAAW;AAAA,MACnB,QAAQ,WAAW,WACf,6DACA;AAAA,IACN,CAAC;AAAA,EACH;AAEA,SAAO,EAAE,SAAS,MAAM,UAAU,OAAO,OAAO;AAClD;AA3DA;AAAA;AAAA;AAAA;AAAA;;;ACAA;AAAA;AAAA;AAAA;AAIA,eAAsB,gBAAgB,KAA4B;AAEhE,EAAG,QAAQ,iCAAQ;AACnB,QAAM,aAAa,MAAM,SAAS,GAAG;AAErC,MAAI,WAAW,QAAQ;AACrB,IAAG,QAAQ,oCAAW,WAAW,MAAM,KAAK,WAAW,QAAQ,KAAK;AAAA,EACtE,OAAO;AACL,IAAG,MAAM,iCAAQ;AACjB,IAAG,KAAK,WAAW,OAAO,MAAM,GAAG,GAAG,CAAC;AAAA,EACzC;AAGA,EAAG,QAAQ,iCAAQ;AACnB,QAAM,UAAU,MAAM,gBAAgB,GAAG;AAEzC,MAAI,CAAC,QAAQ,SAAS;AACpB,IAAG,KAAK,6DAAqB;AAC7B,IAAG,KAAK,0FAAkD;AAAA,EAC5D,OAAO;AACL,eAAW,SAAS,QAAQ,QAAQ;AAClC,UAAI,MAAM,QAAQ;AAChB,QAAG,QAAQ,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,EAAE;AAAA,MAC7C,OAAO;AACL,QAAG,KAAK,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,EAAE;AAAA,MAC1C;AAAA,IACF;AAAA,EACF;AAGA,QAAM,YAAY,WAAW,UAAU,QAAQ,OAAO,MAAM,CAACE,OAAMA,GAAE,MAAM;AAC3E,UAAQ,IAAI,EAAE;AACd,MAAI,WAAW;AACb,IAAG,QAAQ,4BAAQ;AAAA,EACrB,WAAW,CAAC,WAAW,QAAQ;AAC7B,IAAG,MAAM,2FAAqB;AAC9B,YAAQ,WAAW;AAAA,EACrB,OAAO;AACL,IAAG,KAAK,qHAA2B;AAAA,EACrC;AACF;AA5CA;AAAA;AAAA;AAAA;AACA;AACA;AAAA;AAAA;;;ACFA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA,IAKa;AALb;AAAA;AAAA;AAKO,IAAM,kBAAN,MAAsB;AAAA,MAG3B,YACkB,KACA,QAChB;AAFgB;AACA;AAAA,MACf;AAAA,MAFe;AAAA,MACA;AAAA,MAJD,UAAU,oBAAI,IAA4B;AAAA,MAO3D,UAAU,MAAiB,QAA2B;AACpD,aAAK,QAAQ,IAAI,MAAM,MAAM;AAAA,MAC/B;AAAA,MAEA,aAAkD;AAChD,eAAO,KAAK;AAAA,MACd;AAAA,MAEA,UAAU,MAA0C;AAClD,eAAO,KAAK,QAAQ,IAAI,IAAI;AAAA,MAC9B;AAAA,IACF;AAAA;AAAA;;;ACnBA,SAAS,QAAAC,cAAY;AACrB,OAAOC,UAAQ;AA+Ef,eAAe,mBAAmB,KAA4B;AAC5D,QAAM,cAAcD,OAAK,KAAK,QAAQ,cAAc;AACpD,MAAI,MAAMC,KAAG,WAAW,WAAW,EAAG;AAEtC,QAAM,YAAY,2DAAkC,YAAY;AAC9D,UAAMA,KAAG,UAAUD,OAAK,KAAK,MAAM,CAAC;AACpC,UAAMC,KAAG,UAAU,aAAa;AAAA,MAC9B,SAAS;AAAA,MACT,UAAU;AAAA,MACV,SAAS,CAAC,cAAc,IAAI;AAAA,MAC5B,OAAO,CAAC,6BAA6B,mBAAmB;AAAA,IAC1D,GAAG,EAAE,QAAQ,EAAE,CAAC;AAChB,UAAM,MAAM,GAAG;AAAA,EACjB,CAAC;AAED,EAAG,QAAQ,4FAAqC;AAClD;AArGA,IAaa;AAbb;AAAA;AAAA;AAQA;AACA;AACA;AACA;AA4FA;AACA;AA3FO,IAAM,cAAqB;AAAA,MAChC,MAAM;AAAA,MAEN,QAAQ,OAA4B;AAClC,eAAO,MAAM,OAAO,QAAQ,SAAS,UAAU,KAAK,MAAM,OAAO,QAAQ,SAAS,KAAK;AAAA,MACzF;AAAA,MAEA,MAAM,IAAI,OAAyC;AACjD,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,YAAsB,CAAC;AAC7B,cAAM,SAAgC,CAAC;AAEvC,YAAI;AACF,gBAAM,cAAc,MAAM,OAAO;AAGjC,gBAAM,YAAY,0DAAkB,YAAY;AAC9C,kBAAM,aAAa,MAAM,KAAK,WAAW;AACzC,kBAAM,QAAQ,MAAM,KAAK,WAAW;AACpC,kBAAM,MAAM,GAAG;AAAA,UACjB,CAAC;AAGD,cAAI,MAAM,OAAO,SAAS,cAAc;AACtC,kBAAM,mBAAmB,MAAM,GAAG;AAAA,UACpC;AAGA,kBAAQ,IAAI,EAAE;AACd,UAAG,QAAQ,qCAAY;AACvB,gBAAM,aAAa,MAAM,iBAAiB,MAAM,GAAG;AAEnD,UAAG,KAAK,oCAAW,WAAW,cAAc,IAAI,WAAW,aAAa,EAAE;AAE1E,cAAI,WAAW,QAAQ,SAAS,GAAG;AACjC,YAAG,KAAK,kCAAS;AACjB,uBAAW,KAAK,WAAW,SAAS;AAClC,cAAG,KAAK,OAAO,CAAC,EAAE;AAAA,YACpB;AAAA,UACF;AAEA,qBAAW,KAAK,WAAW,UAAU;AACnC,YAAG,KAAK,CAAC;AAAA,UACX;AAEA,cAAI,WAAW,UAAU;AACvB,YAAG,QAAQ,mDAAgB;AAAA,UAC7B;AAEA,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ,WAAW,WAAW,YAAY;AAAA,YAC1C,MAAM,EAAE,WAAW;AAAA,YACnB;AAAA,YACA,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,gBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,iBAAO,KAAK,EAAE,MAAM,iBAAiB,SAAS,KAAK,aAAa,KAAK,CAAC;AACtE,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM,CAAC;AAAA,YACP;AAAA,YACA,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACnFA,IAQa;AARb;AAAA;AAAA;AAMA;AAEO,IAAM,iBAAwB;AAAA,MACnC,MAAM;AAAA,MAEN,UAAmB;AACjB,eAAO;AAAA,MACT;AAAA,MAEA,MAAM,IAAI,OAAyC;AACjD,cAAM,QAAQ,KAAK,IAAI;AAEvB,QAAG,QAAQ,2BAAO;AAClB,QAAG,KAAK,0FAA8B;AACtC,QAAG,KAAK,kFAAoD;AAC5D,QAAG,KAAK,4EAA0B;AAClC,QAAG,KAAK,EAAE;AACV,QAAG,KAAK,uGAAiC;AACzC,QAAG,KAAK,2EAAwC;AAEhD,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,MAAM,EAAE,SAAS,2BAA2B;AAAA,UAC5C,WAAW,CAAC;AAAA,UACZ,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB,QAAQ,CAAC;AAAA,QACX;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACnCA,IASa;AATb;AAAA;AAAA;AAKA;AACA;AACA;AAqDA;AACA;AApDO,IAAM,kBAAyB;AAAA,MACpC,MAAM;AAAA,MAEN,UAAmB;AACjB,eAAO;AAAA,MACT;AAAA,MAEA,MAAM,IAAI,OAAyC;AACjD,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,SAAgC,CAAC;AAGvC,QAAG,QAAQ,iCAAQ;AACnB,cAAM,aAAa,MAAM,SAAS,MAAM,GAAG;AAE3C,YAAI,WAAW,QAAQ;AACrB,UAAG,QAAQ,oCAAW,WAAW,MAAM,KAAK,WAAW,QAAQ,KAAK;AAAA,QACtE,OAAO;AACL,UAAG,MAAM,oCAAW,WAAW,OAAO,MAAM,GAAG,GAAG,CAAC,EAAE;AACrD,iBAAO,KAAK,EAAE,MAAM,eAAe,SAAS,WAAW,OAAO,MAAM,GAAG,GAAG,GAAG,aAAa,KAAK,CAAC;AAAA,QAClG;AAGA,QAAG,QAAQ,iCAAQ;AACnB,cAAM,UAAU,MAAM,gBAAgB,MAAM,GAAG;AAE/C,YAAI,CAAC,QAAQ,SAAS;AACpB,UAAG,KAAK,iFAAyC;AAAA,QACnD,OAAO;AACL,qBAAW,SAAS,QAAQ,QAAQ;AAClC,gBAAI,MAAM,QAAQ;AAChB,cAAG,QAAQ,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,EAAE;AAAA,YAC7C,OAAO;AACL,cAAG,KAAK,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM,EAAE;AAAA,YAC1C;AAAA,UACF;AAAA,QACF;AAEA,cAAM,YAAY,WAAW,UAAU,QAAQ,OAAO,MAAM,CAACC,OAAMA,GAAE,MAAM;AAE3E,eAAO;AAAA,UACL,OAAO;AAAA,UACP,QAAQ,YAAY,YAAY,WAAW,SAAS,YAAY;AAAA,UAChE,MAAM,EAAE,YAAY,QAAQ;AAAA,UAC5B,WAAW,CAAC;AAAA,UACZ,UAAU,KAAK,IAAI,IAAI;AAAA,UACvB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC1DA,IAkBa;AAlBb;AAAA;AAAA;AAKA,IAAAC;AACA;AACA;AACA;AACA;AAyFA;AACA,IAAAA;AAjFO,IAAM,kBAAyB;AAAA,MACpC,MAAM;AAAA,MAEN,UAAmB;AACjB,eAAO;AAAA,MACT;AAAA,MAEA,MAAM,IAAI,OAAyC;AACjD,cAAM,QAAQ,KAAK,IAAI;AACvB,cAAM,SAAgC,CAAC;AAEvC,YAAI;AACF,UAAG,QAAQ,8BAAU;AAErB,gBAAM,YAAY,MAAM,kBAAkB,MAAM,GAAG;AACnD,gBAAM,SAAS,cAAc,SAAS;AAEtC,sBAAY,MAAM;AAElB,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ,OAAO,eAAe,MAAM,WAAW;AAAA,YAC/C,MAAM,EAAE,OAAO;AAAA,YACf,WAAW,CAAC;AAAA,YACZ,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF,SAAS,KAAK;AACZ,gBAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,iBAAO,KAAK,EAAE,MAAM,eAAe,SAAS,KAAK,aAAa,KAAK,CAAC;AACpE,iBAAO;AAAA,YACL,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM,CAAC;AAAA,YACP,WAAW,CAAC;AAAA,YACZ,UAAU,KAAK,IAAI,IAAI;AAAA,YACvB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AChCA,eAAsB,YACpB,KACA,QACA,UAA2B,CAAC,GACU;AACtC,QAAM,MAAM,IAAI,gBAAgB,KAAK,MAAM;AAG3C,MAAI;AAEJ,MAAI,QAAQ,MAAM;AAChB,kBAAc,YAAY,OAAO,CAAC,MAAM,QAAQ,KAAM,SAAS,CAAC,CAAC;AAAA,EACnE,WAAW,QAAQ,MAAM;AACvB,UAAM,UAAU,YAAY,QAAQ,QAAQ,IAAI;AAChD,kBAAc,YAAY,MAAM,WAAW,IAAI,UAAU,CAAC;AAAA,EAC5D,OAAO;AACL,kBAAc,CAAC,GAAG,WAAW;AAAA,EAC/B;AAEA,EAAG,QAAQ,gDAAa,YAAY,MAAM,eAAK;AAC/C,EAAG,KAAK,iBAAO,YAAY,KAAK,UAAK,CAAC,EAAE;AAExC,QAAM,YAAY,KAAK,IAAI;AAE3B,MAAI,aAAa;AAEjB,aAAW,aAAa,aAAa;AACnC,UAAM,QAAQ,OAAO,SAAS;AAE9B,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,IAAI,YAAY,QAAQ,SAAS,IAAI,CAAC,IAAI,YAAY,MAAM,KAAK,UAAU,YAAY,CAAC,EAAE;AAErG,UAAM,QAAoB;AAAA,MACxB;AAAA,MACA;AAAA,MACA,iBAAiB,IAAI,WAAW;AAAA,IAClC;AAGA,QAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,MAAG,KAAK,GAAG,SAAS,wDAAgB;AACpC,UAAI,UAAU,WAAW;AAAA,QACvB,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,MAAM,CAAC;AAAA,QACP,WAAW,CAAC;AAAA,QACZ,UAAU;AAAA,QACV,QAAQ,CAAC;AAAA,MACX,CAAC;AACD;AAAA,IACF;AAEA,UAAM,SAAS,MAAM,MAAM,IAAI,KAAK;AACpC,QAAI,UAAU,WAAW,MAAM;AAG/B,YAAQ,OAAO,QAAQ;AAAA,MACrB,KAAK;AACH,QAAG,QAAQ,GAAG,SAAS,kBAAQ,OAAO,QAAQ,KAAK;AACnD;AAAA,MACF,KAAK;AACH,QAAG,KAAK,GAAG,SAAS,+BAAW,OAAO,QAAQ,KAAK;AACnD;AAAA,MACF,KAAK;AACH,QAAG,MAAM,GAAG,SAAS,kBAAQ,OAAO,QAAQ,KAAK;AACjD,mBAAW,OAAO,OAAO,QAAQ;AAC/B,UAAG,MAAM,KAAK,IAAI,OAAO,EAAE;AAAA,QAC7B;AACA,YAAI,CAAC,OAAO,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG;AAC7C,UAAG,MAAM,uGAAuB;AAChC,uBAAa;AAAA,QACf;AACA;AAAA,MACF,KAAK;AACH,QAAG,KAAK,GAAG,SAAS,qBAAM;AAC1B;AAAA,IACJ;AAEA,QAAI,WAAY;AAAA,EAClB;AAGA,QAAM,gBAAgB,KAAK,IAAI,IAAI;AACnC,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,6CAAU;AAErB,aAAW,aAAa,aAAa;AACnC,UAAM,SAAS,IAAI,UAAU,SAAS;AACtC,QAAI,CAAC,OAAQ;AAEb,UAAM,OACJ,OAAO,WAAW,YAAY,WAC9B,OAAO,WAAW,YAAY,WAC9B,OAAO,WAAW,YAAY,WAAM;AAEtC,IAAG,KAAK,GAAG,IAAI,IAAI,UAAU,OAAO,EAAE,CAAC,IAAI,OAAO,MAAM,KAAK,OAAO,QAAQ,KAAK;AAAA,EACnF;AAEA,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,qCAAY,aAAa,IAAI;AAErC,SAAO,IAAI,WAAW;AACxB;AAhIA,IAaM;AAbN;AAAA;AAAA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,IAAM,SAAmC;AAAA,MACvC,aAAa;AAAA,MACb,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,YAAY;AAAA,MACZ,YAAY;AAAA,IACd;AAAA;AAAA;;;ACnBA;AAAA;AAAA;AAAA;AAWA,eAAsB,gBAAgB,KAAa,SAA4C;AAC7F,cAAY;AAEZ,QAAM,SAAU,MAAM,WAAW,GAAG,KAAM,oBAAoB,cAAc,QAAQ;AAEpF,QAAM,eAAgC,CAAC;AAEvC,MAAI,QAAQ,MAAM;AAChB,iBAAa,OAAO,QAAQ;AAAA,EAC9B;AAEA,MAAI,QAAQ,MAAM;AAChB,iBAAa,OAAO,QAAQ,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC;AAAA,EACjE;AAEA,QAAM,YAAY,KAAK,QAAQ,YAAY;AAC7C;AA3BA;AAAA;AAAA;AACA;AACA;AAEA;AAAA;AAAA;;;ACJA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAGA;AAAA;AAAA;;;ACHA;AAAA;AAAA;AAAA;AAAA,SAAS,YAAAC,WAAU,eAAe;AAClC,OAAOC,UAAQ;AAKf,eAAsB,cAAc,KAAa,SAA6C;AAC5F,EAAG,QAAQ,uCAAS;AAGpB,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,MAAI,CAAC,QAAQ;AACX,IAAG,MAAM,8DAAiB;AAC1B,IAAG,KAAK,uEAA+B;AACvC;AAAA,EACF;AAEA,QAAM,aAAaD,UAAS,GAAG;AAC/B,QAAM,YAAY,QAAQ,GAAG;AAE7B,UAAQ,IAAI,EAAE;AACd,MAAI,OAAO,SAAS;AAClB,IAAG,KAAK,QAAQ,OAAO,OAAO,2DAAc;AAAA,EAC9C;AACA,UAAQ,IAAI,OAAE,IAAI,KAAK,UAAU,mEAAiB,CAAC;AACnD,EAAG,KAAK,+EAAmB;AAC3B,UAAQ,IAAI,EAAE;AAGd,QAAM,QAAQ,MAAMC,KAAG,QAAQ,GAAG;AAClC,QAAM,YAAY,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC,EAAE;AAC1D,QAAM,cAAc,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC,EAAE;AAC3D,EAAG,KAAK,6BAAS,SAAS,qCAAY,WAAW,QAAG;AACpD,UAAQ,IAAI,EAAE;AAEd,MAAI,CAAC,QAAQ,OAAO;AAClB,UAAM,EAAE,SAASC,UAAS,IAAI,MAAM,OAAO,UAAU;AACrD,UAAM,EAAE,YAAY,IAAI,MAAMA,UAAS,OAAO,CAAC;AAAA,MAC7C,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS,8GAAyB,UAAU;AAAA,IAC9C,CAAC,CAAC;AAEF,QAAI,YAAY,KAAK,MAAM,YAAY;AACrC,MAAG,KAAK,0HAA2B;AACnC;AAAA,IACF;AAAA,EACF;AAGA,UAAQ,MAAM,SAAS;AAEvB,MAAI;AACF,UAAMD,KAAG,OAAO,GAAG;AACnB,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,GAAG,UAAU,8EAAkB;AAG1C,QAAI;AACF,YAAM,EAAE,gBAAAE,gBAAe,IAAI,MAAM;AACjC,YAAMA,gBAAe,SAAS;AAAA,IAChC,QAAQ;AAAA,IAER;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,MAAM,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG;AAC3D,IAAG,MAAM,8BAAU,GAAG,EAAE;AACxB;AAAA,EACF;AAGA,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AACrD,QAAM,EAAE,UAAU,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IAC3C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,EACX,CAAC,CAAC;AAEF,MAAI,WAAW;AACb,UAAM,EAAE,aAAAC,aAAY,IAAI,MAAM;AAC9B,UAAMA,aAAY,QAAQ,IAAI,CAAC;AAAA,EACjC,OAAO;AAEL,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,gBAAW,OAAE,IAAI,8CAAW,CAAC,EAAE;AAC1C,UAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAChC,IAAAA,eAAc,SAAS;AAAA,EACzB;AACF;AA1FA;AAAA;AAAA;AAEA;AACA;AACA;AAAA;AAAA;;;ACJA,IAAa,UAsBA;AAtBb;AAAA;AAAA;AAAO,IAAM,WAAN,cAAuB,MAAM;AAAA,MAClC,YACE,SACgB,MACA,cAAuB,OACvC;AACA,cAAM,OAAO;AAHG;AACA;AAGhB,aAAK,OAAO;AAAA,MACd;AAAA,MALkB;AAAA,MACA;AAAA,IAKpB;AAaO,IAAM,sBAAN,cAAkC,SAAS;AAAA,MAChD,YAAYC,OAAc;AACxB;AAAA,UACE,iCAAiCA,KAAI;AAAA,UACrC;AAAA,UACA;AAAA,QACF;AACA,aAAK,OAAO;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;AC/BA;AAAA;AAAA;AAAA;AAAA,SAAS,iBAAAC,sBAAqB;AAC9B,OAAOC,YAAW;AAUlB,SAAS,cAAc,GAAW,GAAuB;AACvD,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAClC,QAAM,KAAK,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AAClC,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,UAAM,KAAK,GAAG,CAAC,KAAK;AACpB,UAAM,KAAK,GAAG,CAAC,KAAK;AACpB,QAAI,KAAK,GAAI,QAAO;AACpB,QAAI,KAAK,GAAI,QAAO;AAAA,EACtB;AACA,SAAO;AACT;AAEA,eAAsB,eACpB,KACA,SACe;AACf,EAAG,QAAQ,oCAAW;AAGtB,QAAM,SAAS,MAAM,WAAW,GAAG;AACnC,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,oBAAoB,GAAG;AAAA,EACnC;AAEA,QAAM,iBAAiBC,KAAI;AAC3B,QAAM,gBAAgB,OAAO;AAE7B,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,gCAAYD,OAAM,KAAK,IAAI,aAAa,EAAE,CAAC,EAAE;AACzD,UAAQ,IAAI,gCAAYA,OAAM,KAAK,IAAI,cAAc,EAAE,CAAC,EAAE;AAG1D,MAAI,CAAC,QAAQ,SAAS,cAAc,eAAe,cAAc,KAAK,GAAG;AACvE,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,2DAAc;AACzB,IAAG,KAAK,2EAAwC;AAChD;AAAA,EACF;AAGA,UAAQ,IAAI,EAAE;AACd,QAAM,SAAS,MAAM,YAAY,iGAA2B,YAAY;AACtE,UAAM,IAAI,MAAM,sBAAsB,GAAG;AACzC,UAAM,MAAM,GAAG;AACf,WAAO;AAAA,EACT,CAAC;AAGD,UAAQ,IAAI,EAAE;AACd,MAAI,OAAO,cAAc;AACvB,IAAG,QAAQ,mCAAe;AAAA,EAC5B;AACA,MAAI,OAAO,gBAAgB,SAAS,GAAG;AACrC,IAAG,QAAQ,yCAAW,OAAO,gBAAgB,MAAM,iCAAQ;AAC3D,eAAW,KAAK,OAAO,iBAAiB;AACtC,cAAQ,IAAIA,OAAM,KAAK,OAAO,CAAC,EAAE,CAAC;AAAA,IACpC;AAAA,EACF;AAGA,MAAI,OAAO,cAAc,SAAS,GAAG;AACnC,YAAQ,IAAI,EAAE;AACd,eAAW,KAAK,OAAO,eAAe;AACpC,MAAG,MAAM,GAAG,EAAE,IAAI,KAAK,EAAE,KAAK,EAAE;AAAA,IAClC;AACA,IAAG,MAAM,0IAA2C;AACpD,IAAG,KAAK,0FAA6C;AACrD;AAAA,EACF;AAGA,SAAO,UAAU;AACjB,QAAM,WAAW,KAAK,MAAM;AAE5B,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,IAAI,aAAa,YAAO,cAAc,+CAAY;AAC7D,UAAQ,IAAI,EAAE;AAChB;AAxFA,IAQME,UACAD;AATN;AAAA;AAAA;AAEA;AACA;AACA;AACA;AACA;AAEA,IAAMC,WAAUH,eAAc,YAAY,GAAG;AAC7C,IAAME,OAAMC,SAAQ,oBAAoB;AAAA;AAAA;;;ACTxC;AAAA;AAAA;AAAA;AAIA,SAAS,QAAAC,QAAM,gBAAgB;AAC/B,OAAOC,UAAQ;AACf,OAAOC,YAAW;AAgClB,eAAsB,iBAAiB,KAA4B;AACjE,QAAM,EAAE,eAAAC,eAAc,IAAI,MAAM;AAEhC,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,4DAAyB;AACpC,UAAQ,IAAI,EAAE;AAEd,QAAM,UAAUA,eAAc,iDAAc;AAC5C,QAAM,YAAY,MAAM,YAAY,GAAG;AACvC,UAAQ,QAAQ,oCAAW,UAAU,MAAM,qBAAM;AAEjD,MAAI,UAAU,WAAW,GAAG;AAC1B,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,oFAAwB;AAChC,IAAG,KAAK,iKAAyC;AACjD;AAAA,EACF;AAGA,QAAM,UAAU,UAAU,OAAO,OAAK,EAAE,aAAa,QAAQ;AAC7D,QAAM,WAAW,UAAU,OAAO,OAAK,EAAE,aAAa,UAAU;AAChE,QAAM,aAAa,UAAU,OAAO,OAAK,EAAE,aAAa,OAAO;AAG/D,QAAM,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,IAAI,OAAK,EAAE,GAAG,CAAC,CAAC;AAGnD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,oCAAgB,CAAC;AACnC,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,UAAU,OAAO,OAAK,EAAE,QAAQ,GAAG,EAAE;AACnD,YAAQ,IAAI,KAAKD,OAAM,KAAK,IAAI,OAAO,EAAE,CAAC,CAAC,IAAIA,OAAM,MAAM,OAAO,KAAK,CAAC,CAAC,QAAG;AAAA,EAC9E;AAEA,MAAI,QAAQ,SAAS,GAAG;AACtB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,0BAAW,CAAC;AAC9B,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,eAAW,QAAQ,SAAS;AAC1B,cAAQ,IAAI,KAAK,OAAE,IAAI,KAAK,IAAI,CAAC,IAAIA,OAAM,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,EAAE;AACtE,cAAQ,IAAI,OAAO,KAAK,QAAQ,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,oCAAgB,CAAC;AACnC,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,eAAW,QAAQ,UAAU;AAC3B,cAAQ,IAAI,KAAK,OAAE,IAAI,KAAK,IAAI,CAAC,IAAIA,OAAM,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,KAAKA,OAAM,KAAK,KAAK,GAAG,CAAC,EAAE;AAC/F,cAAQ,IAAI,OAAO,KAAK,QAAQ,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF;AAEA,MAAI,WAAW,SAAS,GAAG;AACzB,YAAQ,IAAI,EAAE;AACd,YAAQ,IAAI,OAAE,IAAI,sCAAkB,CAAC;AACrC,YAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,eAAW,QAAQ,YAAY;AAC7B,cAAQ,IAAI,KAAK,OAAE,IAAI,KAAK,IAAI,CAAC,IAAIA,OAAM,OAAO,OAAO,KAAK,IAAI,CAAC,CAAC,KAAKA,OAAM,KAAK,KAAK,GAAG,CAAC,EAAE;AAC/F,cAAQ,IAAI,OAAO,KAAK,QAAQ,KAAK,EAAE,UAAU,GAAG,EAAE,CAAC,EAAE;AAAA,IAC3D;AAAA,EACF;AAGA,QAAM,iBAAiB,SAAS,SAAS,WAAW;AACpD,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,OAAO,gDAAa,CAAC;AACnC,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,2CAAkBA,OAAM,MAAM,OAAO,cAAc,CAAC,CAAC,QAAG;AACpE,UAAQ,IAAI,uCAAmBA,OAAM,OAAO,gEAAwB,CAAC,EAAE;AACvE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,sDAAc,CAAC;AACjC,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,KAAKA,OAAM,MAAM,QAAG,CAAC,yHAA+B;AAChE,UAAQ,IAAI,mBAAc,OAAE,IAAI,2FAAoC,CAAC,EAAE;AACvE,UAAQ,IAAI,KAAKA,OAAM,OAAO,QAAG,CAAC,gGAA0B;AAC5D,UAAQ,IAAI,mBAAc,OAAE,IAAI,gHAA2B,CAAC,EAAE;AAC9D,UAAQ,IAAI,KAAKA,OAAM,IAAI,QAAG,CAAC,6GAA6B;AAC5D,UAAQ,IAAI,mBAAc,OAAE,IAAI,oGAAyB,CAAC,EAAE;AAG5D,QAAM,YAAYF,OAAK,KAAK,MAAM;AAClC,QAAMC,KAAG,UAAU,SAAS;AAC5B,QAAM,SAAS,YAAY,WAAW,GAAG;AACzC,QAAM,aAAaD,OAAK,WAAW,qBAAqB;AACxD,QAAMC,KAAG,UAAU,YAAY,QAAQ,MAAM;AAE7C,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,wEAAqC;AAChD,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,mGAAkC;AAC1C,EAAG,KAAK,kBAAkB;AAC5B;AAEA,eAAe,YAAY,KAAkC;AAC3D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,QAAM,UAAsB,CAAC;AAC7B,QAAM,OAAO,oBAAI,IAAY;AAE7B,aAAW,EAAE,SAAS,KAAK,SAAS,KAAK,eAAe;AACtD,QAAI;AACF,YAAM,EAAE,OAAO,IAAI,MAAM,MAAM,QAAQ;AAAA,QACrC;AAAA,QACA;AAAA,QAAkB;AAAA,QAAmB;AAAA,QAAkB;AAAA,QACvD;AAAA,QAAkB;AAAA,QAAoB;AAAA,QAAkB;AAAA,QACxD;AAAA,QAA8B;AAAA,QAAsB;AAAA,QACpD;AAAA,QAAuB;AAAA,QAA6B;AAAA,QACpD;AAAA,QAAyB;AAAA,QACzB;AAAA,QACA;AAAA,QAAS;AAAA,MACX,CAAC;AAED,iBAAW,QAAQ,OAAO,MAAM,IAAI,EAAE,OAAO,OAAO,GAAG;AACrD,cAAM,QAAQ,KAAK,MAAM,oBAAoB;AAC7C,YAAI,CAAC,MAAO;AAEZ,cAAM,OAAO,SAAS,KAAK,MAAM,CAAC,CAAE;AACpC,cAAM,UAAU,SAAS,MAAM,CAAC,CAAE;AAClC,cAAM,UAAU,MAAM,CAAC;AACvB,cAAM,MAAM,GAAG,IAAI,IAAI,OAAO;AAE9B,YAAI,KAAK,IAAI,GAAG,EAAG;AACnB,aAAK,IAAI,GAAG;AAEZ,gBAAQ,KAAK,EAAE,MAAM,MAAM,SAAS,SAAS,KAAK,SAAS,CAAC;AAAA,MAC9D;AAAA,IACF,QAAQ;AAAA,IAER;AAAA,EACF;AAEA,SAAO,QAAQ,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,KAAK,EAAE,OAAO,EAAE,IAAI;AAC/E;AAEA,SAAS,YAAY,WAAuB,KAAqB;AAC/D,QAAM,UAAU,UAAU,OAAO,OAAK,EAAE,aAAa,QAAQ;AAC7D,QAAM,WAAW,UAAU,OAAO,OAAK,EAAE,aAAa,UAAU;AAChE,QAAM,aAAa,UAAU,OAAO,OAAK,EAAE,aAAa,OAAO;AAC/D,QAAM,OAAO,CAAC,GAAG,IAAI,IAAI,UAAU,IAAI,OAAK,EAAE,GAAG,CAAC,CAAC;AACnD,QAAM,iBAAiB,SAAS,SAAS,WAAW;AAEpD,QAAM,QAAkB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,0BAAU,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA,IAC/C,+BAAW,GAAG;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,8BAAe,QAAQ,MAAM;AAAA,IAC7B,qCAAiB,SAAS,MAAM;AAAA,IAChC,uCAAmB,WAAW,MAAM;AAAA,IACpC,0BAAgB,UAAU,MAAM;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,OAAO,MAAM;AACtB,UAAM,QAAQ,UAAU,OAAO,OAAK,EAAE,QAAQ,GAAG,EAAE;AACnD,UAAM,KAAK,OAAO,GAAG,OAAO,KAAK,QAAG;AAAA,EACtC;AAEA,MAAI,SAAS,SAAS,KAAK,WAAW,SAAS,GAAG;AAChD,UAAM,KAAK,IAAI,gEAAwB,EAAE;AACzC,UAAM,KAAK,sDAAwB;AACnC,UAAM,KAAK,8BAA8B;AACzC,eAAW,QAAQ,CAAC,GAAG,UAAU,GAAG,UAAU,GAAG;AAC/C,YAAM,OAAO,KAAK,QAAQ,KAAK,EAAE,UAAU,GAAG,EAAE,EAAE,QAAQ,OAAO,KAAK;AACtE,YAAM,KAAK,KAAK,KAAK,IAAI,MAAM,KAAK,IAAI,MAAM,KAAK,GAAG,QAAQ,IAAI,MAAM;AAAA,IAC1E;AAAA,EACF;AAEA,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAK,cAAc;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,SAAO,MAAM,KAAK,IAAI;AACxB;AA1PA,IAkBM;AAlBN;AAAA;AAAA;AAOA;AACA;AAUA,IAAM,gBAAyF;AAAA;AAAA,MAE7F,EAAE,SAAS,qBAAqB,KAAK,aAAa,UAAU,SAAS;AAAA,MACrE,EAAE,SAAS,kCAAkC,KAAK,oBAAoB,UAAU,SAAS;AAAA,MACzF,EAAE,SAAS,iBAAiB,KAAK,UAAU,UAAU,SAAS;AAAA,MAC9D,EAAE,SAAS,iBAAiB,KAAK,UAAU,UAAU,SAAS;AAAA,MAC9D,EAAE,SAAS,yBAAyB,KAAK,aAAa,UAAU,SAAS;AAAA,MACzE,EAAE,SAAS,aAAa,KAAK,UAAU,UAAU,SAAS;AAAA,MAC1D,EAAE,SAAS,aAAa,KAAK,aAAa,UAAU,SAAS;AAAA;AAAA,MAE7D,EAAE,SAAS,mBAAmB,KAAK,aAAa,UAAU,WAAW;AAAA,MACrE,EAAE,SAAS,2BAA2B,KAAK,UAAU,UAAU,WAAW;AAAA,MAC1E,EAAE,SAAS,mBAAmB,KAAK,aAAa,UAAU,WAAW;AAAA,MACrE,EAAE,SAAS,sBAAsB,KAAK,UAAU,UAAU,WAAW;AAAA;AAAA,MAErE,EAAE,SAAS,qBAAqB,KAAK,aAAa,UAAU,QAAQ;AAAA,MACpE,EAAE,SAAS,kBAAkB,KAAK,UAAU,UAAU,QAAQ;AAAA,MAC9D,EAAE,SAAS,qCAAqC,KAAK,aAAa,UAAU,QAAQ;AAAA,IACtF;AAAA;AAAA;;;ACpCA;AAAA;AAAA;AAAA;AAKA,SAAS,QAAAG,cAAY;AACrB,SAAS,WAAAC,UAAS,YAAY,kBAAkB;AAChD,OAAOC,UAAQ;AACf,OAAOC,YAAW;AAuFlB,eAAsB,cAAc,cAAuB,WAAqB,gBAAqB;AACnG,MAAI,iBAAiB,OAAO;AAC1B,UAAM,cAAc;AACpB;AAAA,EACF;AAEA,MAAI,iBAAiB,UAAU;AAC7B,UAAM,WAAW;AACjB;AAAA,EACF;AAEA,MAAI,CAAC,cAAc;AACjB,gBAAY;AACZ;AAAA,EACF;AAGA,MAAI,CAAC,kBAAkB,KAAK,YAAY,GAAG;AACzC,IAAG,MAAM,yGAAmC;AAC5C;AAAA,EACF;AAEA,QAAM,CAAC,GAAG,CAAC,IAAI,aAAa,MAAM,GAAG,EAAE,IAAI,MAAM;AACjD,MAAI,IAAK,KAAK,IAAK,MAAM,IAAK,KAAK,IAAK,IAAI;AAC1C,IAAG,MAAM,uFAAgC;AACzC;AAAA,EACF;AAGA,QAAM,EAAE,SAAS,SAAS,IAAI,MAAM,OAAO,UAAU;AAErD,UAAQ,IAAI,EAAE;AACd,QAAM,EAAE,WAAW,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IAC5C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS,QAAQ,IAAI;AAAA,EACvB,CAAC,CAAC;AAEF,QAAM,EAAE,WAAW,IAAI,MAAM,SAAS,OAAO,CAAC;AAAA,IAC5C,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS;AAAA,IACT,SAAS;AAAA,MACP,EAAE,MAAM,wCAAwCA,OAAM,KAAK,2BAAO,CAAC,IAAI,OAAO,SAAS;AAAA,MACvF,EAAE,MAAM,yCAAyCA,OAAM,KAAK,kBAAkB,CAAC,IAAI,OAAO,OAAO;AAAA,IACnG;AAAA,EACF,CAAC,CAAC;AAGF,QAAM,SAAuB;AAAA,IAC3B,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,QAAMD,KAAG,UAAUE,QAAO;AAC1B,QAAMF,KAAG,UAAUG,cAAa,QAAQ,EAAE,QAAQ,EAAE,CAAC;AACrD,QAAMH,KAAG,UAAU,eAAe,QAAQ;AAC1C,QAAM,mBAAmB,MAAM;AAG/B,MAAI,WAAW,MAAM,UAAU;AAC7B,UAAM,WAAW,MAAM;AAAA,EACzB,WAAW,WAAW,MAAM,SAAS;AACnC,UAAM,aAAa,MAAM;AAAA,EAC3B,OAAO;AACL,UAAM,WAAW,MAAM;AAAA,EACzB;AAEA,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,iEAAe;AAC1B,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,wBAAcC,OAAM,MAAM,OAAO,IAAI,CAAC,EAAE;AACpD,UAAQ,IAAI,4BAAaA,OAAM,MAAM,gBAAgB,OAAO,QAAQ,CAAC,CAAC,EAAE;AACxE,UAAQ,IAAI,gCAAYA,OAAM,MAAM,OAAO,UAAU,CAAC,EAAE;AACxD,UAAQ,IAAI,wBAAcA,OAAM,MAAM,OAAO,eAAe,SAAS,qBAAqB,2BAAO,CAAC,EAAE;AACpG,MAAI,WAAW,MAAM,UAAU;AAC7B,YAAQ,IAAI,gCAAYA,OAAM,MAAM,mCAAmC,CAAC,EAAE;AAAA,EAC5E;AACA,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,8BAAoB;AAC5B,EAAG,KAAK,iCAAuB;AAE/B,UAAQ,IAAI,EAAE;AACd,cAAY;AACd;AAIA,eAAe,WAAW,QAAqC;AAC7D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,QAAM,CAAC,MAAM,MAAM,IAAI,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AAGxD,QAAM,WAAWH,OAAKC,SAAQ,GAAG,WAAW,cAAc;AAC1D,QAAMC,KAAG,UAAU,QAAQ;AAE3B,QAAM,WAAW,mBAAmB,OAAO,QAAQ;AACnD,MAAI;AAEJ,MAAI,SAAS,WAAW,GAAG;AACzB,sBAAkB;AAAA,gCACU,IAAI;AAAA,kCACF,MAAM;AAAA;AAAA,EAEtC,OAAO;AACL,sBAAkB;AAAA,EACpB,SAAS,IAAI,OAAK;AAAA,kCACc,IAAI;AAAA,oCACF,MAAM;AAAA,qCACL,CAAC;AAAA,cACxB,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA,EAExB;AAEA,QAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA,YAKJ,UAAU;AAAA;AAAA;AAAA;AAAA,cAIR,WAAW;AAAA;AAAA;AAAA,EAGvB,eAAe;AAAA;AAAA,YAELE,QAAO;AAAA;AAAA,YAEPA,QAAO;AAAA;AAAA;AAIjB,QAAMF,KAAG,UAAU,YAAY,KAAK;AAGpC,QAAM,MAAM,aAAa,CAAC,UAAU,UAAU,CAAC,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAC/D,QAAM,MAAM,aAAa,CAAC,QAAQ,UAAU,CAAC;AAC7C,EAAG,QAAQ,sDAAmB;AAG9B,QAAM,YAAY,oBAAoB,OAAO,QAAQ;AACrD,UAAQ,IAAI,EAAE;AACd,EAAG,KAAK,2IAAkC;AAC1C,UAAQ,IAAI,EAAE;AAEd,MAAI;AACF,UAAM,MAAM,QAAQ,CAAC,SAAS,UAAU,iBAAiB,WAAW,GAAG,OAAO,IAAI,KAAK,GAAG;AAAA,MACxF,OAAO;AAAA,IACT,CAAC;AACD,IAAG,QAAQ,iDAA6B;AAAA,EAC1C,QAAQ;AACN,IAAG,KAAK,gIAAsC;AAC9C,IAAG,KAAK,8DAA0C,SAAS,IAAI,OAAO,IAAI,KAAK;AAAA,EACjF;AACF;AAIA,eAAe,aAAa,QAAqC;AAC/D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,QAAM,CAAC,MAAM,MAAM,IAAI,OAAO,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AAGxD,QAAM,cAAcF,OAAKC,SAAQ,GAAG,MAAM;AAC1C,QAAMC,KAAG,UAAU,WAAW;AAC9B,QAAM,eAAeF,OAAK,aAAa,YAAY;AAEnD,QAAM,YAAY,OAAO,eAAe,SACpC,0CACA;AAEJ,QAAM,WAAW;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,wHAyBqG,OAAO,UAAU,MAAM,SAAS;AAAA;AAGtJ,QAAME,KAAG,UAAU,cAAc,UAAU,MAAM;AAGjD,QAAM,UAAkC;AAAA,IACtC,gBAAM;AAAA,IACN,gBAAM;AAAA,IACN,gBAAM;AAAA,EACR;AACA,QAAM,OAAO,QAAQ,OAAO,QAAQ,KAAK,QAAQ,cAAI;AAGrD,QAAM,MAAM,YAAY,CAAC,WAAW,OAAO,cAAc,IAAI,CAAC,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAE9E,MAAI;AACF,UAAM,MAAM,YAAY;AAAA,MACtB;AAAA,MAAW;AAAA,MAAO;AAAA,MAClB;AAAA,MAAO,iDAAiD,YAAY;AAAA,MACpE;AAAA,MAAO;AAAA,MAAU;AAAA,MAAM;AAAA,MACvB;AAAA,MAAO,GAAG,OAAO,IAAI,EAAE,SAAS,GAAG,GAAG,CAAC,IAAI,OAAO,MAAM,EAAE,SAAS,GAAG,GAAG,CAAC;AAAA,MAC1E;AAAA,IACF,CAAC;AACD,IAAG,QAAQ,kDAA8B;AAAA,EAC3C,QAAQ;AACN,IAAG,KAAK,0CAAsB;AAC9B,IAAG,KAAK,iLAAqC;AAAA,EAC/C;AACF;AAIA,eAAe,WAAW,QAAqC;AAC7D,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,QAAM,WAAW,eAAe,OAAO,MAAM,OAAO,QAAQ;AAC5D,QAAM,WAAW,GAAG,QAAQ,IAAI,WAAW,IAAI,WAAW;AAE1D,QAAM,gBAAgB;AACtB,QAAM,WAAW,MAAM,MAAM,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,OAAK,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE;AAClF,QAAM,aAAa,SAAS,KAAK,IAAI,GAAG,SAAS,KAAK,CAAC;AAAA,EAAK,QAAQ;AAAA,IAAO,GAAG,QAAQ;AAAA;AACtF,QAAM,MAAM,WAAW,CAAC,GAAG,GAAG,EAAE,OAAO,WAAW,CAAC;AAEnD,EAAG,QAAQ,sDAAmB;AAChC;AAIA,eAAe,gBAA+B;AAC5C,QAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AAEtC,MAAI,WAAW,MAAM,UAAU;AAC7B,UAAM,MAAM,aAAa,CAAC,UAAU,UAAU,CAAC,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAC/D,UAAMA,KAAG,OAAO,UAAU,EAAE,MAAM,MAAM;AAAA,IAAC,CAAC;AAC1C,IAAG,QAAQ,yCAAgB;AAE3B,YAAQ,IAAI,EAAE;AACd,IAAG,KAAK,gHAA0C;AAClD,QAAI;AACF,YAAM,MAAM,QAAQ,CAAC,SAAS,UAAU,QAAQ,GAAG,EAAE,OAAO,UAAU,CAAC;AACvE,MAAG,QAAQ,iDAA6B;AAAA,IAC1C,QAAQ;AACN,MAAG,KAAK,qDAAiC;AAAA,IAC3C;AAAA,EACF,WAAW,WAAW,MAAM,SAAS;AACnC,QAAI;AACF,YAAM,MAAM,YAAY,CAAC,WAAW,OAAO,cAAc,IAAI,CAAC;AAC9D,MAAG,QAAQ,kDAA8B;AAAA,IAC3C,QAAQ;AACN,MAAG,KAAK,+DAA2C;AAAA,IACrD;AAAA,EACF,OAAO;AACL,UAAM,gBAAgB;AAAA,EACxB;AAEA,QAAMA,KAAG,OAAOG,YAAW,EAAE,MAAM,MAAM;AAAA,EAAC,CAAC;AAC3C,UAAQ,IAAI,EAAE;AACd,EAAG,QAAQ,iEAAe;AAC5B;AAIA,eAAe,aAA4B;AACzC,MAAI,MAAMH,KAAG,WAAWG,YAAW,GAAG;AACpC,UAAM,SAAuB,MAAMH,KAAG,SAASG,YAAW;AAE1D,YAAQ,IAAI,EAAE;AACd,IAAG,QAAQ,0DAAa;AACxB,YAAQ,IAAI,wBAAcF,OAAM,MAAM,OAAO,IAAI,CAAC,EAAE;AACpD,YAAQ,IAAI,4BAAaA,OAAM,MAAM,gBAAgB,OAAO,QAAQ,CAAC,CAAC,EAAE;AACxE,YAAQ,IAAI,gCAAYA,OAAM,MAAM,OAAO,UAAU,CAAC,EAAE;AACxD,YAAQ,IAAI,wBAAcA,OAAM,MAAM,OAAO,eAAe,SAAS,qBAAqB,2BAAO,CAAC,EAAE;AAEpG,QAAI,WAAW,MAAM,UAAU;AAC7B,YAAM,cAAc,MAAMD,KAAG,WAAW,UAAU;AAClD,cAAQ,IAAI,gBAAgB,cAAcC,OAAM,MAAM,cAAI,IAAIA,OAAM,IAAI,oBAAK,CAAC,EAAE;AAAA,IAClF;AACA,YAAQ,IAAI,EAAE;AAAA,EAChB,OAAO;AACL,IAAG,KAAK,yFAAmB;AAC3B,IAAG,KAAK,gCAAsB;AAAA,EAChC;AACF;AAIA,SAAS,cAAoB;AAC3B,QAAM,MAAM,KAAK,MAAM,KAAK,OAAO,IAAI,SAAS,MAAM;AACtD,QAAM,MAAM,SAAS,GAAG;AAExB,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACpD,UAAQ,IAAI,EAAE;AACd,aAAW,QAAQ,IAAI,MAAM,IAAI,GAAG;AAClC,YAAQ,IAAI,KAAK,IAAI,EAAE;AAAA,EACzB;AACA,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,OAAE,IAAI,kLAAiC,CAAC;AACtD;AAIA,SAAS,gBAAgB,UAA4B;AACnD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,EACpB;AACF;AAEA,SAAS,mBAAmB,UAA8B;AACxD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAM,aAAO,CAAC,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IAChC,KAAK;AAAM,aAAO,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAAA,IACtC,KAAK;AAAM,aAAO,CAAC,GAAG,CAAC;AAAA,EACzB;AACF;AAEA,SAAS,oBAAoB,UAA4B;AACvD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,IAClB,KAAK;AAAM,aAAO;AAAA,EACpB;AACF;AAEA,SAAS,eAAe,MAAc,UAA4B;AAChE,QAAM,CAAC,MAAM,MAAM,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,MAAM;AACjD,UAAQ,UAAU;AAAA,IAChB,KAAK;AAAM,aAAO,GAAG,MAAM,IAAI,IAAI;AAAA,IACnC,KAAK;AAAM,aAAO,GAAG,MAAM,IAAI,IAAI;AAAA,IACnC,KAAK;AAAM,aAAO,GAAG,MAAM,IAAI,IAAI;AAAA,EACrC;AACF;AAEA,eAAe,kBAAiC;AAC9C,MAAI;AACF,UAAM,EAAE,MAAM,IAAI,MAAM,OAAO,OAAO;AACtC,UAAM,EAAE,OAAO,IAAI,MAAM,MAAM,WAAW,CAAC,IAAI,CAAC;AAChD,UAAM,WAAW,OAAO,MAAM,IAAI,EAAE,OAAO,OAAK,CAAC,EAAE,SAAS,WAAW,CAAC,EAAE,KAAK,IAAI;AACnF,QAAI,SAAS,KAAK,GAAG;AACnB,YAAM,MAAM,WAAW,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,SAAS,KAAK,CAAC;AAAA,EAAK,CAAC;AAAA,IACjE,OAAO;AACL,YAAM,MAAM,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAAA,IAC/C;AAAA,EACF,QAAQ;AAAA,EAER;AACF;AAEA,eAAe,mBAAmB,QAAqC;AACrE,QAAM,YAAY,OAAO,eAAe,SACpC,0CACA;AAEJ,QAAM,SAAS;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;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,+PAwD6F,OAAO,UAAU,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,iEAW/E,OAAO,UAAU,QAAQ,SAAS;AAAA;AAAA,gDAEnD,OAAO,UAAU,QAAQ,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAOhF,QAAMD,KAAG,UAAU,aAAa,QAAQ,EAAE,MAAM,IAAM,CAAC;AACzD;AAriBA,IAcME,UACAC,cACA,eACA,aACA,YACA,YACA,aASA;AA7BN;AAAA;AAAA;AASA;AACA;AAIA,IAAMD,WAAUJ,OAAKC,SAAQ,GAAG,MAAM;AACtC,IAAMI,eAAcL,OAAKI,UAAS,oBAAoB;AACtD,IAAM,gBAAgBJ,OAAKI,UAAS,sBAAsB;AAC1D,IAAM,cAAcJ,OAAKI,UAAS,WAAW;AAC7C,IAAM,aAAa;AACnB,IAAM,aAAaJ,OAAKC,SAAQ,GAAG,WAAW,gBAAgB,GAAG,UAAU,QAAQ;AACnF,IAAM,cAAc;AASpB,IAAM,WAAqB;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAqBA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAOA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA;AAAA,MAKA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA;AAAA,MAKA;AAAA;AAAA;AAAA,MAIA;AAAA;AAAA;AAAA,IAGF;AAAA;AAAA;;;AC3FA,SAAS,eAAe;AACxB,SAAS,iBAAAK,sBAAqB;;;ACG9B,IAAM,SAAS,oBAAI,IAAY;AAExB,SAAS,eAAe,QAAgB,QAAsB;AACnE,MAAI,OAAO,IAAI,MAAM,EAAG;AACxB,SAAO,IAAI,MAAM;AACjB,UAAQ,OAAO;AAAA,IACb,oBAAe,MAAM,yBAAyB,MAAM;AAAA;AAAA,EACtD;AACF;;;ADRA,IAAMC,WAAUC,eAAc,YAAY,GAAG;AAC7C,IAAMC,OAAMF,SAAQ,oBAAoB;AAEjC,SAAS,gBAAyB;AACvC,QAAMG,WAAU,IAAI,QAAQ;AAE5B,EAAAA,SACG,KAAK,KAAK,EACV,YAAY,qHAAyD,EACrE,QAAQD,KAAI,SAAS,eAAe,EACpC,OAAO,YAAY;AAElB,UAAM,EAAE,gBAAAE,gBAAe,IAAI,MAAM;AACjC,UAAMA,gBAAe,QAAQ,IAAI,CAAC;AAAA,EACpC,CAAC;AAKH,EAAAD,SACG,QAAQ,qBAAqB,EAC7B,YAAY,iJAAmC,EAC/C,OAAO,OAAO,gBAAyB;AACtC,UAAM,EAAE,aAAAE,aAAY,IAAI,MAAM;AAC9B,UAAMA,aAAY,QAAQ,IAAI,GAAG,WAAW;AAAA,EAC9C,CAAC;AAGH,EAAAF,SACG,QAAQ,KAAK,EACb,YAAY,+EAAkC,EAC9C,OAAO,YAAY;AAClB,UAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,UAAM,WAAW,QAAQ,IAAI,CAAC;AAAA,EAChC,CAAC;AAGH,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,sDAAkC,EAC9C,OAAO,YAAY;AAClB,UAAM,EAAE,cAAAG,cAAa,IAAI,MAAM;AAC/B,UAAMA,cAAa;AAAA,EACrB,CAAC;AAGH,EAAAH,SACG,QAAQ,QAAQ,EAChB,YAAY,+GAA0B,EACtC,OAAO,YAAY;AAClB,UAAM,EAAE,cAAc,IAAI,MAAM;AAChC,UAAM,cAAc,QAAQ,IAAI,CAAC;AAAA,EACnC,CAAC;AAGH,EAAAA,SACG,QAAQ,MAAM,EACd,YAAY,iCAAQ,EACpB,OAAO,YAAY;AAClB,UAAM,EAAE,aAAAI,aAAY,IAAI,MAAM;AAC9B,UAAMA,aAAY;AAAA,EACpB,CAAC;AAGH,QAAM,SAASJ,SACZ,QAAQ,QAAQ,EAChB,YAAY,4CAAwB;AAEvC,SACG,QAAQ,MAAM,EACd,YAAY,yCAAgB,EAC5B,OAAO,YAAY;AAClB,UAAM,EAAE,mBAAAK,mBAAkB,IAAI,MAAM;AACpC,UAAMA,mBAAkB,QAAQ,IAAI,CAAC;AAAA,EACvC,CAAC;AAEH,SACG,QAAQ,UAAU,EAClB,YAAY,qCAAY,EACxB,OAAO,YAAY;AAClB,UAAM,EAAE,uBAAAC,uBAAsB,IAAI,MAAM;AACxC,UAAMA,uBAAsB,QAAQ,IAAI,CAAC;AAAA,EAC3C,CAAC;AAGH,EAAAN,SACG,QAAQ,MAAM,EACd,YAAY,mEAAiB,EAC7B,OAAO,YAAY;AAClB,UAAM,EAAE,YAAY,IAAI,MAAM;AAC9B,UAAM,YAAY,QAAQ,IAAI,CAAC;AAAA,EACjC,CAAC;AAGH,EAAAA,SACG,QAAQ,OAAO,EACf,YAAY,0FAAyB,EACrC,OAAO,wBAAwB,0DAAuB,QAAQ,EAC9D,OAAO,aAAa,oCAAgB,EACpC,OAAO,uBAAuB,oDAAY,EAC1C,OAAO,cAAc,iEAAe,EACpC,OAAO,OAAO,YAAY;AACzB,UAAM,EAAE,aAAa,IAAI,MAAM;AAC/B,UAAM,aAAa,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC3C,CAAC;AAGH,EAAAA,SACG,QAAQ,KAAK,EACb,YAAY,wEAAiB,EAC7B,OAAO,kBAAkB,oDAAY,EACrC,OAAO,mBAAmB,0EAAmB,EAC7C,OAAO,OAAO,YAAY;AACzB,UAAM,EAAE,WAAW,IAAI,MAAM;AAC7B,UAAM,WAAW,QAAQ,IAAI,GAAG,OAAO;AAAA,EACzC,CAAC;AAGH,EAAAA,SACG,QAAQ,QAAQ,EAChB,YAAY,8EAAuB,EACnC,OAAO,WAAW,qDAAa,EAC/B,OAAO,OAAO,YAAY;AACzB,UAAM,EAAE,eAAAO,eAAc,IAAI,MAAM;AAChC,UAAMA,eAAc,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC5C,CAAC;AAGH,EAAAP,SACG,QAAQ,SAAS,EACjB,YAAY,qIAAiC,EAC7C,OAAO,WAAW,gGAAqB,EACvC,OAAO,OAAO,YAAY;AACzB,UAAM,EAAE,gBAAAQ,gBAAe,IAAI,MAAM;AACjC,UAAMA,gBAAe,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC7C,CAAC;AAGH,EAAAR,SACG,QAAQ,WAAW,EACnB,YAAY,2CAAa,EACzB,OAAO,YAAY;AAClB,UAAM,EAAE,kBAAAS,kBAAiB,IAAI,MAAM;AACnC,UAAMA,kBAAiB,QAAQ,IAAI,CAAC;AAAA,EACtC,CAAC;AAGH,EAAAT,SACG,QAAQ,0BAA0B,EAClC,YAAY,mGAAkC,EAC9C,OAAO,OAAO,MAAe,aAAsB;AAClD,UAAM,EAAE,eAAAU,eAAc,IAAI,MAAM;AAEhC,UAAM,iBAA6B,CAAC,gBAAM,gBAAM,cAAI;AACpD,UAAM,QAAkB,eAAe,SAAS,QAAoB,IAAI,WAAuB;AAC/F,UAAMA,eAAc,MAAM,KAAK;AAAA,EACjC,CAAC;AAQH,QAAM,MAAMV,SACT,QAAQ,KAAK,EACb,YAAY,iFAAyC;AAExD,MACG,QAAQ,OAAO,EACf,YAAY,yBAAe,EAC3B,OAAO,YAAY;AAClB,mBAAe,iBAAiB,SAAS;AACzC,UAAM,EAAE,iBAAAW,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,CAAC;AAAA,EACrC,CAAC;AAEH,MACG,QAAQ,QAAQ,EAChB,YAAY,2BAAiB,EAC7B,OAAO,YAAY;AAClB,mBAAe,kBAAkB,WAAW;AAC5C,UAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,UAAMA,kBAAiB;AAAA,EACzB,CAAC;AAEH,MACG,QAAQ,QAAQ,EAChB,YAAY,4BAAkB,EAC9B,OAAO,YAAY;AAClB,mBAAe,kBAAkB,YAAY;AAC7C,UAAM,EAAE,kBAAAC,kBAAiB,IAAI,MAAM;AACnC,UAAMA,kBAAiB,QAAQ,IAAI,CAAC;AAAA,EACtC,CAAC;AAGH,EAAAb,SACG,QAAQ,UAAU,EAClB,YAAY,0BAAgB,EAC5B,OAAO,YAAY;AAClB,mBAAe,gBAAgB,UAAU;AACzC,UAAM,EAAE,iBAAAc,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,CAAC;AAAA,EACrC,CAAC;AAGH,EAAAd,SACG,QAAQ,UAAU,EAClB,YAAY,2BAAiB,EAC7B,OAAO,wBAAwB,0DAAuB,QAAQ,EAC9D,OAAO,aAAa,oCAAgB,EACpC,OAAO,uBAAuB,oDAAY,EAC1C,OAAO,cAAc,iEAAe,EACpC,OAAO,OAAO,YAAY;AACzB,mBAAe,gBAAgB,WAAW;AAC1C,UAAM,EAAE,iBAAAe,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC9C,CAAC;AAGH,EAAAf,SACG,QAAQ,UAAU,EAClB,YAAY,yBAAe,EAC3B,OAAO,kBAAkB,oDAAY,EACrC,OAAO,mBAAmB,0EAAmB,EAC7C,OAAO,OAAO,YAAY;AACzB,mBAAe,gBAAgB,SAAS;AACxC,UAAM,EAAE,iBAAAgB,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC9C,CAAC;AAGH,EAAAhB,SACG,QAAQ,SAAS,EACjB,YAAY,yBAAe,EAC3B,OAAO,YAAY;AAClB,mBAAe,eAAe,SAAS;AACvC,UAAM,EAAE,iBAAAW,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,CAAC;AAAA,EACrC,CAAC;AAGH,EAAAX,SACG,QAAQ,UAAU,EAClB,YAAY,2BAAiB,EAC7B,OAAO,YAAY;AAClB,mBAAe,gBAAgB,WAAW;AAC1C,UAAM,EAAE,iBAAAe,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,GAAG,CAAC,CAAC;AAAA,EACzC,CAAC;AAEH,EAAAf,SACG,QAAQ,YAAY,EACpB,YAAY,+EAA6B,EACzC,OAAO,wBAAwB,0DAAuB,QAAQ,EAC9D,OAAO,aAAa,oCAAgB,EACpC,OAAO,uBAAuB,oDAAY,EAC1C,OAAO,cAAc,iEAAe,EACpC,OAAO,OAAO,YAAY;AACzB,UAAM,EAAE,iBAAAe,iBAAgB,IAAI,MAAM;AAClC,UAAMA,iBAAgB,QAAQ,IAAI,GAAG,OAAO;AAAA,EAC9C,CAAC;AAEH,SAAOf;AACT;;;AExQA,IAAM,UAAU,cAAc;AAE9B,QAAQ,WAAW,QAAQ,IAAI,EAAE,MAAM,CAAC,QAAe;AACrD,UAAQ,MAAM,iBAAiB,IAAI,WAAW,GAAG;AACjD,MAAI,QAAQ,IAAI,WAAW,GAAG;AAC5B,YAAQ,MAAM,IAAI,KAAK;AAAA,EACzB;AACA,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["require","createRequire","fs","path","pkg","require","c","chalk","fs","info","pkg","chalk","join","fs","chalk","step","fs","path","join","fs","section","join","fs","provisionMcp","join","fs","join","fs","path","fs","analyzer_exports","join","fs","buildAnalysisPrompt","c","path","init_analyzer","c","chalk","c","join","homedir","fs","os","path","fs","backupPath","join","join","fs","init_analyzer","basename","config","join","basename","fs","isWindows","diagnoseWindowsEnv","inquirer","chalk","analyzeRepository","computeResult","printReport","buildDetailedReport","installShellHelper","requestCdAfter","sleep","createSpinner","enableOmcPlugin","getShellRcPath","getYoloAliasLine","spawnSubshell","PLUGIN_META","evaluateCommand","envSetupCommand","runDoctor","generateFiles","analyzeProject","provisionClaudeCommands","runProvisioners","withSpinner","withFileSpinner","join","fs","section","join","fs","basename","join","fs","pkg","join","fs","c","join","fs","c","init_analyzer","basename","fs","inquirer","requestCdAfter","initCommand","spawnSubshell","path","createRequire","chalk","pkg","require","join","fs","chalk","createSpinner","join","homedir","fs","chalk","PAI_DIR","CONFIG_FILE","createRequire","require","createRequire","pkg","program","welcomeCommand","initCommand","checkCommand","helpCommand","designInitCommand","designValidateCommand","removeCommand","upgradeCommand","savetokenCommand","wakeupCommand","envSetupCommand","envDoctorCommand","envStatusCommand","validateCommand","evaluateCommand","pipelineCommand"]}