sales-frontend-gemini-cli 0.4.3 β†’ 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/common/helper.cjs +227 -20
  2. package/dist/common/helper.cjs.map +1 -1
  3. package/dist/common/helper.d.cts +30 -1
  4. package/dist/common/helper.d.ts +30 -1
  5. package/dist/common/helper.js +226 -21
  6. package/dist/common/helper.js.map +1 -1
  7. package/dist/common/types.d.cts +3 -1
  8. package/dist/common/types.d.ts +3 -1
  9. package/dist/pr-review/claude/claude-commander.cjs +10 -3
  10. package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
  11. package/dist/pr-review/claude/claude-commander.js +10 -3
  12. package/dist/pr-review/claude/claude-commander.js.map +1 -1
  13. package/dist/pr-review/claude/installation-claude.cjs +1 -1
  14. package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
  15. package/dist/pr-review/claude/installation-claude.js +1 -1
  16. package/dist/pr-review/claude/installation-claude.js.map +1 -1
  17. package/dist/pr-review/codex/codex-commander.cjs +14 -4
  18. package/dist/pr-review/codex/codex-commander.cjs.map +1 -1
  19. package/dist/pr-review/codex/codex-commander.d.cts +1 -1
  20. package/dist/pr-review/codex/codex-commander.d.ts +1 -1
  21. package/dist/pr-review/codex/codex-commander.js +14 -4
  22. package/dist/pr-review/codex/codex-commander.js.map +1 -1
  23. package/dist/pr-review/codex/installation-codex.cjs +1 -1
  24. package/dist/pr-review/codex/installation-codex.cjs.map +1 -1
  25. package/dist/pr-review/codex/installation-codex.js +1 -1
  26. package/dist/pr-review/codex/installation-codex.js.map +1 -1
  27. package/dist/pr-review/gemini/gemini-commander.cjs +12 -12
  28. package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
  29. package/dist/pr-review/gemini/gemini-commander.js +12 -12
  30. package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
  31. package/dist/pr-review/gemini/installation-gemini.cjs +1 -1
  32. package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
  33. package/dist/pr-review/gemini/installation-gemini.js +1 -1
  34. package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
  35. package/dist/pr-review/review-one-by-one.cjs +296 -42
  36. package/dist/pr-review/review-one-by-one.cjs.map +1 -1
  37. package/dist/pr-review/review-one-by-one.js +296 -42
  38. package/dist/pr-review/review-one-by-one.js.map +1 -1
  39. package/dist/pr-review/review.cjs +327 -42
  40. package/dist/pr-review/review.cjs.map +1 -1
  41. package/dist/pr-review/review.js +327 -42
  42. package/dist/pr-review/review.js.map +1 -1
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/common/helper.ts"],"names":["__dirname","path","fileURLToPath","fs","execFileSync","inspect","execSync","readline"],"mappings":"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","file":"helper.cjs","sourcesContent":["import { execFileSync, execSync } from 'child_process';\nimport fs from 'fs';\nimport path from 'path';\nimport readline from 'readline';\nimport { fileURLToPath } from 'url';\nimport { inspect } from 'util';\n\nimport { AIServiceType, CommitOption, MultiSelectOption } from './types';\n\ntype ErrorReportSection = {\n heading: string;\n markdown: string;\n};\n\ntype WriteErrorReportOptions = {\n title?: string;\n scope?: string;\n args?: string[];\n traceMessages?: string[];\n extraSections?: ErrorReportSection[];\n};\n\ntype GitCommandOptions = {\n allowFailure?: boolean;\n trimOutput?: boolean;\n};\n\ntype ShellCommandProgressOptions = {\n progressIntervalMs?: number;\n progressMessage?: string;\n streamOutput?: boolean;\n};\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst traceMessages: string[] = [];\nconst GEMINI_CLI_PACKAGE_NAME = 'sales-frontend-gemini-cli';\nlet cachedPackageRootPath = '';\n\n/**\n * @description\n * ν˜„μž¬ 디렉터리가 gemini-cli νŒ¨ν‚€μ§€ λ£¨νŠΈμΈμ§€ ν™•μΈν•©λ‹ˆλ‹€.\n * λ²ˆλ“€ κ²°κ³Όλ¬Όμ—μ„œ helper μ½”λ“œκ°€ 각 μ—”νŠΈλ¦¬ 파일둜 인라인되면 `__dirname` 기쀀점이 λ‹¬λΌμ§€λ―€λ‘œ,\n * package.json μ΄λ¦„μœΌλ‘œ μ‹€μ œ νŒ¨ν‚€μ§€ 루트λ₯Ό 식별해야 κ·œμΉ™/양식 파일 κ²½λ‘œκ°€ κΉ¨μ§€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.\n * @param directory 검사할 디렉터리 경둜\n * @returns ν˜„μž¬ 디렉터리가 gemini-cli νŒ¨ν‚€μ§€ 루트이면 true\n */\nfunction isGeminiCliPackageRoot(directory: string) {\n const packageJsonPath = path.join(directory, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string };\n\n return packageJson.name === GEMINI_CLI_PACKAGE_NAME;\n } catch {\n return false;\n }\n}\n\n/**\n * @description\n * ν˜„μž¬ μ‹€ν–‰ 쀑인 λ²ˆλ“€ μ—”νŠΈλ¦¬ κΈ°μ€€μœΌλ‘œ gemini-cli νŒ¨ν‚€μ§€ 루트λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.\n * `dist/pr-review/review.js`, `dist/pr-review/gemini/gemini-commander.js`처럼\n * μ—”νŠΈλ¦¬ μœ„μΉ˜κ°€ 달라도 μƒμœ„ 디렉터리λ₯Ό μˆœνšŒν•˜λ©° package rootλ₯Ό 찾도둝 μ„€κ³„ν•©λ‹ˆλ‹€.\n * @param startDirectory νŒ¨ν‚€μ§€ 루트 탐색을 μ‹œμž‘ν•  디렉터리\n * @returns κ·œμΉ™/양식 파일이 μ‘΄μž¬ν•˜λŠ” gemini-cli νŒ¨ν‚€μ§€ 루트 경둜\n */\nfunction resolveGeminiCliPackageRoot(startDirectory: string = __dirname) {\n if (cachedPackageRootPath) {\n return cachedPackageRootPath;\n }\n\n let currentDirectory = startDirectory;\n\n while (true) {\n if (isGeminiCliPackageRoot(currentDirectory)) {\n cachedPackageRootPath = currentDirectory;\n\n return cachedPackageRootPath;\n }\n\n const parentDirectory = path.dirname(currentDirectory);\n\n if (parentDirectory === currentDirectory) {\n break;\n }\n\n currentDirectory = parentDirectory;\n }\n\n /**\n * @description\n * package.json 탐색이 μ‹€νŒ¨ν•΄λ„ κΈ°μ‘΄ μ„€μΉ˜ ꡬ쑰(dist/common -> package root)λ₯Ό μš°μ„  fallback으둜 μ‚¬μš©ν•©λ‹ˆλ‹€.\n * μ˜ˆμƒμΉ˜ λͺ»ν•œ 배포 ν™˜κ²½μ—μ„œλ„ μ΅œλŒ€ν•œ κΈ°μ‘΄ λ™μž‘μ„ μœ μ§€ν•˜κΈ° μœ„ν•œ 보수적 μ•ˆμ „μž₯μΉ˜μž…λ‹ˆλ‹€.\n */\n cachedPackageRootPath = path.resolve(startDirectory, '../..');\n\n return cachedPackageRootPath;\n}\n\n/**\n * @description\n * gemini-cli νŒ¨ν‚€μ§€ 루트λ₯Ό κΈ°μ€€μœΌλ‘œ 정적 asset 파일의 μ ˆλŒ€ 경둜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.\n * λ²ˆλ“€ κ³Όμ •μ—μ„œ helper μ½”λ“œκ°€ λ‹€λ₯Έ μ—”νŠΈλ¦¬μ— μΈλΌμΈλ˜μ–΄λ„ 항상 같은 μ‹€μ œ νŒŒμΌμ„ κ°€λ¦¬ν‚€κ²Œ ν•©λ‹ˆλ‹€.\n * @param relativeFilePath νŒ¨ν‚€μ§€ 루트 κΈ°μ€€ μƒλŒ€ 경둜\n * @returns asset 파일의 μ ˆλŒ€ 경둜\n */\nfunction resolvePackageAssetPath(relativeFilePath: string) {\n return path.resolve(resolveGeminiCliPackageRoot(), relativeFilePath);\n}\n\nexport const rulesPath = resolvePackageAssetPath('src/common/rules/review-rules.md');\nexport const namingRulesPath = resolvePackageAssetPath('src/common/rules/naming-rule.md');\nexport const codingConventionRulesPath = resolvePackageAssetPath('src/common/rules/coding-convention.md');\nexport const reviewFormPath = resolvePackageAssetPath('src/common/form/review-form.md');\nexport const reviewFormOneByOnePath = resolvePackageAssetPath('src/common/form/review-form-one-by-one.md');\nexport const REPORT_DIR = '.review-report';\nexport const tempDiffPath = 'temp_diff.txt';\nexport const AIServices: AIServiceType[] = ['gemini', 'claude', 'codex'];\nexport const COMMIT_FETCH_LIMIT = 20;\nexport const COMMIT_SELECTION_WINDOW = 8;\nexport const ignoreList = [\n 'package.json',\n '*.yml',\n '*.md',\n '*.lock',\n 'dist/',\n 'node_modules/',\n 'assets/',\n 'public/',\n '*.json',\n '*.yaml',\n '.review-report/' // μƒμ„±λ˜λŠ” 리포트 폴더도 μ œμ™Έ\n];\n\nexport function isTestMode(args: string[] = process.argv.slice(2)) {\n return args.includes('--test');\n}\n\nexport function clearTraceMessages() {\n traceMessages.length = 0;\n}\n\nexport function getTraceMessages() {\n return [...traceMessages];\n}\n\n/**\n * @description\n * 터미널 선택 UIμ—μ„œ λ™μΌν•œ 색상 토큰을 μž¬μ‚¬μš©ν•  수 μžˆλ„λ‘ ANSI escape codeλ₯Ό μƒμˆ˜ν™”ν•©λ‹ˆλ‹€.\n * μ„œλΉ„μŠ€ 선택과 컀밋 선택이 같은 μ‹œκ° μ–Έμ–΄λ₯Ό μ‚¬μš©ν•˜λ„λ‘ helper λ‚΄λΆ€μ—μ„œλ§Œ κ³΅μœ ν•©λ‹ˆλ‹€.\n */\nconst ANSI = {\n bold: '\\u001b[1m',\n cyan: '\\u001b[36m',\n dim: '\\u001b[2m',\n green: '\\u001b[32m',\n reset: '\\u001b[0m',\n yellow: '\\u001b[33m'\n} as const;\nconst ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-9;]*m`, 'g');\nconst COMBINING_MARK_PATTERN = /\\p{Mark}/u;\nconst GRAPHEME_SEGMENTER =\n typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter('ko', { granularity: 'grapheme' }) : null;\n\ntype VisibleToken = {\n value: string;\n visibleWidth: number;\n};\n\n/**\n * @description\n * 리뷰 λŒ€μƒ 파일 ν•„ν„°λ₯Ό pathspec λ°°μ—΄ ν˜•νƒœλ‘œ μ •μ˜ν•©λ‹ˆλ‹€.\n * λ¬Έμžμ—΄ μ»€λ§¨λ“œμ™€ argv 기반 git 싀행이 λͺ¨λ‘ 같은 기쀀을 κ³΅μœ ν•˜λ„λ‘ 원본 νŒ¨ν„΄μ€ λ°°μ—΄λ‘œ μœ μ§€ν•©λ‹ˆλ‹€.\n */\nfunction getGitDiffPathspecs() {\n return {\n excludePatterns: ignoreList.map((item) => `:(exclude)${item}`),\n includePatterns: ['*.ts', '*.tsx', '*.js', '*.jsx']\n };\n}\n\nfunction segmentGraphemes(value: string) {\n if (!GRAPHEME_SEGMENTER) {\n return [...value];\n }\n\n return [...GRAPHEME_SEGMENTER.segment(value)].map(({ segment }) => segment);\n}\n\nfunction isWideCodePoint(codePoint: number) {\n return (\n codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0x3247 && codePoint !== 0x303f) ||\n (codePoint >= 0x3250 && codePoint <= 0x4dbf) ||\n (codePoint >= 0x4e00 && codePoint <= 0xa4c6) ||\n (codePoint >= 0xa960 && codePoint <= 0xa97c) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||\n (codePoint >= 0xfe30 && codePoint <= 0xfe6b) ||\n (codePoint >= 0xff01 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x1f200 && codePoint <= 0x1f251) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n );\n}\n\nfunction isEmojiCodePoint(codePoint: number) {\n return (\n (codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff) ||\n (codePoint >= 0x1f300 && codePoint <= 0x1faff) ||\n (codePoint >= 0x2600 && codePoint <= 0x27bf)\n );\n}\n\nfunction getGraphemeWidth(grapheme: string) {\n let width = 0;\n\n for (const character of grapheme) {\n const codePoint = character.codePointAt(0);\n\n if (!codePoint || COMBINING_MARK_PATTERN.test(character) || codePoint === 0x200d) {\n continue;\n }\n\n if ((codePoint >= 0xfe00 && codePoint <= 0xfe0f) || (codePoint >= 0xe0100 && codePoint <= 0xe01ef)) {\n continue;\n }\n\n if (isWideCodePoint(codePoint) || isEmojiCodePoint(codePoint)) {\n width = Math.max(width, 2);\n\n continue;\n }\n\n width = Math.max(width, 1);\n }\n\n return width;\n}\n\nfunction tokenizePlainText(value: string) {\n return segmentGraphemes(value).map((segment) => ({\n value: segment,\n visibleWidth: getGraphemeWidth(segment)\n }));\n}\n\nfunction tokenizeVisibleText(value: string) {\n const tokens: VisibleToken[] = [];\n let lastIndex = 0;\n\n for (const match of value.matchAll(ANSI_PATTERN)) {\n const index = match.index ?? 0;\n\n if (index > lastIndex) {\n tokens.push(...tokenizePlainText(value.slice(lastIndex, index)));\n }\n\n tokens.push({\n value: match[0],\n visibleWidth: 0\n });\n lastIndex = index + match[0].length;\n }\n\n if (lastIndex < value.length) {\n tokens.push(...tokenizePlainText(value.slice(lastIndex)));\n }\n\n return tokens;\n}\n\n/**\n * @description\n * λͺ¨λ‹¬ 각 쀄이 터미널 μ‹€μ œ 폭을 λ„˜μ§€ μ•Šλ„λ‘ ANSI μ½”λ“œλ₯Ό λ³΄μ‘΄ν•œ 채 μž˜λΌλƒ…λ‹ˆλ‹€.\n * μ€„λ°”κΏˆμ΄ λ°œμƒν•˜λ©΄ λ Œλ” 쀄 수 계산이 μ–΄κΈ‹λ‚˜λ―€λ‘œ, λͺ¨λ“  선택 쀄을 1 physical line둜 κ°•μ œν•©λ‹ˆλ‹€.\n * @param value λ Œλ”ν•  λ¬Έμžμ—΄\n * @param maxWidth ν—ˆμš© μ΅œλŒ€ ν‘œμ‹œ 폭\n * @returns 터미널 폭 μ•ˆμœΌλ‘œ μ •λ¦¬λœ λ¬Έμžμ—΄\n */\nfunction truncateLineForTerminal(value: string, maxWidth: number) {\n if (maxWidth <= 0) {\n return '';\n }\n\n const tokens = tokenizeVisibleText(value);\n const totalWidth = tokens.reduce((sum, token) => sum + token.visibleWidth, 0);\n\n if (totalWidth <= maxWidth) {\n return value;\n }\n\n const ellipsis = '...';\n const ellipsisWidth = 3;\n const targetWidth = Math.max(0, maxWidth - ellipsisWidth);\n let usedWidth = 0;\n let result = '';\n\n for (const token of tokens) {\n if (token.visibleWidth === 0) {\n result += token.value;\n\n continue;\n }\n\n if (usedWidth + token.visibleWidth > targetWidth) {\n break;\n }\n\n result += token.value;\n usedWidth += token.visibleWidth;\n }\n\n return `${result}${ellipsis}${ANSI.reset}`;\n}\n\nfunction fitLinesToTerminal(lines: string[]) {\n const maxWidth = Math.max(20, (process.stdout.columns || 120) - 1);\n\n return lines.map((line) => truncateLineForTerminal(line, maxWidth));\n}\n\n/**\n * @description\n * git μ„œλΈŒν”„λ‘œμ„ΈμŠ€λ₯Ό argv λ°°μ—΄ 기반으둜 μ‹€ν–‰ν•©λ‹ˆλ‹€.\n * 컀밋 ν•΄μ‹œλ‚˜ 파일 κ²½λ‘œμ— 곡백이 μ„žμ—¬λ„ shell quoting 문제 없이 λ™μΌν•œ λ™μž‘μ„ 보μž₯ν•˜κΈ° μœ„ν•΄ 곡톡 helper둜 λΆ„λ¦¬ν•©λ‹ˆλ‹€.\n * @param args git 인자 λ°°μ—΄\n * @param options μ‹€νŒ¨ ν—ˆμš© 여뢀와 좜λ ₯ trim μ—¬λΆ€\n * @returns git ν‘œμ€€μΆœλ ₯ λ¬Έμžμ—΄\n */\nfunction runGitCommand(args: string[], options: GitCommandOptions = {}) {\n const { allowFailure = false, trimOutput = true } = options;\n\n try {\n const output = execFileSync('git', args, {\n encoding: 'utf8',\n maxBuffer: 1024 * 1024 * 20,\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n return trimOutput ? output.trim() : output;\n } catch (error) {\n helperTrace('git-command:failed', `${args.join(' ')} | ${getErrorSummary(error)}`);\n\n if (allowFailure) {\n return '';\n }\n\n throw error;\n }\n}\n\n/**\n * @description\n * shell λͺ…령을 λΉ„λ™κΈ°λ‘œ μ‹€ν–‰ν•˜λ©΄μ„œ stdout/stderrλ₯Ό κ·ΈλŒ€λ‘œ ν˜λ €λ³΄λ‚΄κ³ , μž₯μ‹œκ°„ μž‘μ—…μ—λŠ” κ²½κ³Ό μ‹œκ°„μ„ 주기적으둜 좜λ ₯ν•©λ‹ˆλ‹€.\n * review μ‹€ν–‰μ²˜λŸΌ 응닡 μƒμ„±κΉŒμ§€ 였래 κ±Έλ¦¬λŠ” CLIλ₯Ό 버퍼링 없이 κΈ°λ‹€λ¦¬κ²Œ ν•΄ μ‚¬μš©μžκ°€ 멈좀으둜 μ˜€ν•΄ν•˜μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.\n * @param command μ‹€ν–‰ν•  shell command λ¬Έμžμ—΄\n * @param options μ§„ν–‰ λ©”μ‹œμ§€μ™€ 좜λ ₯ μ£ΌκΈ° μ˜΅μ…˜\n * @returns μ΅œμ’… stdout/stderr 캑처 κ²°κ³Ό\n */\nexport async function executeShellCommandWithProgress(command: string, options: ShellCommandProgressOptions = {}) {\n const { progressIntervalMs = 10000, progressMessage = '⏳ λͺ…령을 μ‹€ν–‰ν•˜λŠ” μ€‘μž…λ‹ˆλ‹€...', streamOutput = false } = options;\n const { spawn } = await import('child_process');\n\n return new Promise<{ stderr: string; stdout: string }>((resolve, reject) => {\n let stdout = '';\n let stderr = '';\n const startedAt = Date.now();\n console.log(progressMessage);\n\n const child = spawn('/bin/zsh', ['-lc', command], {\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n const progressTimer = setInterval(() => {\n const elapsedSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000));\n console.log(`${progressMessage} (${elapsedSeconds}s κ²½κ³Ό)`);\n }, progressIntervalMs);\n\n child.stdout.on('data', (chunk: Buffer | string) => {\n const text = chunk.toString();\n stdout += text;\n\n if (streamOutput) {\n process.stdout.write(text);\n }\n });\n\n child.stderr.on('data', (chunk: Buffer | string) => {\n const text = chunk.toString();\n stderr += text;\n\n if (streamOutput) {\n process.stderr.write(text);\n }\n });\n\n child.on('error', (error) => {\n clearInterval(progressTimer);\n reject(error);\n });\n\n child.on('close', (code, signal) => {\n clearInterval(progressTimer);\n\n if (code === 0) {\n resolve({\n stderr,\n stdout\n });\n\n return;\n }\n\n const exitSummary = signal ? `signal=${signal}` : `code=${String(code ?? 'unknown')}`;\n reject(new Error(`μ‰˜ λͺ…λ Ή μ‹€ν–‰ μ‹€νŒ¨ (${exitSummary})${stderr.trim() ? `\\n${stderr.trim()}` : ''}`));\n });\n });\n}\n\n/**\n * @description\n * 리뷰 λŒ€μƒ 파일 λͺ©λ‘μ„ ν•œ 쀄 μš”μ•½ λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.\n * 파일이 λ§Žμ„ λ•ŒλŠ” μΌλΆ€λ§Œ λ…ΈμΆœν•˜κ³  λ‚˜λ¨Έμ§€λŠ” 개수둜 μΆ•μ•½ν•΄ 터미널 좜λ ₯이 κ³Όλ„ν•˜κ²Œ κΈΈμ–΄μ§€μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.\n * @param files 리뷰 λŒ€μƒ 파일 λͺ©λ‘\n * @param visibleCount 터미널에 직접 보여쀄 μ΅œλŒ€ 파일 수\n * @returns ν™”λ©΄ ν‘œμ‹œμš© μš”μ•½ λ¬Έμžμ—΄\n */\nexport function formatReviewTargetFiles(files: string[], visibleCount = 5) {\n if (files.length === 0) {\n return '(μ—†μŒ)';\n }\n\n const visibleFiles = files.slice(0, visibleCount);\n const hiddenCount = Math.max(0, files.length - visibleFiles.length);\n\n if (hiddenCount === 0) {\n return visibleFiles.join(', ');\n }\n\n return `${visibleFiles.join(', ')} μ™Έ ${hiddenCount}개`;\n}\n\nexport function createTraceLogger(scope: string, args: string[] = process.argv.slice(2)) {\n const enabled = isTestMode(args);\n\n return (step: string, detail?: string) => {\n const timestamp = new Date().toISOString();\n const message = `[${timestamp}][TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ''}`;\n traceMessages.push(message);\n\n if (!enabled) {\n return;\n }\n\n console.log(message);\n };\n}\n\nconst helperTrace = createTraceLogger('helper');\n\nfunction getTimestampParts(now = new Date()) {\n return {\n YYYY: now.getFullYear(),\n MM: String(now.getMonth() + 1).padStart(2, '0'),\n DD: String(now.getDate()).padStart(2, '0'),\n HH: String(now.getHours()).padStart(2, '0'),\n mm: String(now.getMinutes()).padStart(2, '0'),\n ss: String(now.getSeconds()).padStart(2, '0')\n };\n}\n\nfunction getHumanReadableNowString(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`;\n}\n\nfunction stringifyUnknown(value: unknown) {\n if (value === undefined || value === null) {\n return '';\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (Buffer.isBuffer(value)) {\n return value.toString();\n }\n\n if (value instanceof Error) {\n return value.stack || value.message;\n }\n\n return inspect(value, { depth: 5, breakLength: 120 });\n}\n\nexport function getErrorSummary(error: unknown) {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n\n return stringifyUnknown(error) || 'Unknown error';\n}\n\nfunction serializeError(error: unknown) {\n const serialized: Record<string, unknown> = {\n summary: getErrorSummary(error)\n };\n\n if (error instanceof Error) {\n serialized.name = error.name;\n serialized.message = error.message;\n serialized.stack = error.stack;\n } else {\n serialized.value = stringifyUnknown(error);\n }\n\n if (error && typeof error === 'object') {\n const errorLike = error as Record<string, unknown>;\n const extraKeys = ['code', 'errno', 'syscall', 'path', 'cmd', 'status', 'signal', 'spawnargs'];\n\n extraKeys.forEach((key) => {\n if (errorLike[key] !== undefined) {\n serialized[key] = errorLike[key];\n }\n });\n\n const stdout = stringifyUnknown(errorLike.stdout);\n if (stdout) {\n serialized.stdout = stdout;\n }\n\n const stderr = stringifyUnknown(errorLike.stderr);\n if (stderr) {\n serialized.stderr = stderr;\n }\n\n const cause = stringifyUnknown(errorLike.cause);\n if (cause) {\n serialized.cause = cause;\n }\n }\n\n return serialized;\n}\n\nexport function getNextFilePath(dir: string, baseName: string, extension: string) {\n let counter = 1;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const filePath = path.join(dir, `${baseName}-${counter}${extension}`);\n if (!fs.existsSync(filePath)) {\n return filePath;\n }\n counter++;\n }\n}\n\nexport function getAvailableFilePath(dir: string, baseName: string, extension: string) {\n const firstFilePath = path.join(dir, `${baseName}${extension}`);\n if (!fs.existsSync(firstFilePath)) {\n return firstFilePath;\n }\n\n return getNextFilePath(dir, baseName, extension);\n}\n\nexport function deleteFile(filePath: string) {\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n}\n\n/**\n * μž„μ‹œνŒŒμΌ μ‚­μ œ\n */\nexport function deleteTempDiff() {\n deleteFile(tempDiffPath);\n}\n\n/**\n * 리뷰 κ²°κ³Ό 폴더 생성\n */\nexport function createReportDirectory() {\n if (!fs.existsSync(REPORT_DIR)) {\n fs.mkdirSync(REPORT_DIR, { recursive: true });\n }\n}\n\n/**\n * ν˜„μž¬ μ‹œκ°„ λ¬Έμžμ—΄ 생성\n */\nexport function getNowString(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD}_${HH}-${mm}-${ss}`;\n}\n\nexport function getErrorLogTimestamp(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD}-${HH}μ‹œ-${mm}λΆ„-${ss}초`;\n}\n\nexport function writeErrorReport(error: unknown, options: WriteErrorReportOptions = {}) {\n try {\n const now = new Date();\n helperTrace('error-report:write:start', options.scope || 'unknown');\n createReportDirectory();\n\n const reportPath = getAvailableFilePath(REPORT_DIR, `error-log-${getErrorLogTimestamp(now)}`, '.md');\n const serializedError = serializeError(error);\n const traceSnapshot = options.traceMessages ?? getTraceMessages();\n const extraSections = options.extraSections || [];\n\n const report = `# Error Log\n\n- λ°œμƒ μ‹œκ°: ${getHumanReadableNowString(now)}\n- Scope: \\`${options.scope || 'unknown'}\\`\n- μž‘μ—… 경둜: \\`${process.cwd()}\\`\n- μ‹€ν–‰ 인자: \\`${JSON.stringify(options.args ?? process.argv.slice(2))}\\`\n- μ‹€ν–‰ ν™˜κ²½: \\`${process.platform} ${process.arch} / Node ${process.version}\\`\n\n## Summary\n\n${options.title || serializedError.summary || 'Unknown error'}\n\n## Error\n\n\\`\\`\\`json\n${JSON.stringify(serializedError, null, 2)}\n\\`\\`\\`\n\n## Trace\n\n\\`\\`\\`json\n${JSON.stringify(traceSnapshot, null, 2)}\n\\`\\`\\`${extraSections.length ? `\\n${extraSections.map((section) => `\\n## ${section.heading}\\n\\n${section.markdown}`).join('\\n')}\\n` : '\\n'}\n`;\n\n fs.writeFileSync(reportPath, report);\n helperTrace('error-report:write:done', reportPath);\n\n return reportPath;\n } catch (writeError) {\n console.error('⚠️ μ—λŸ¬ 둜그 파일 생성에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');\n console.error(writeError);\n\n return '';\n }\n}\n\nexport function exitWithError(\n message: string,\n options: Omit<WriteErrorReportOptions, 'title'> & { error?: unknown } = {}\n): never {\n const reportPath = writeErrorReport(options.error || new Error(message), {\n ...options,\n title: message\n });\n\n console.error(message);\n\n if (options.error) {\n console.error(options.error);\n }\n\n if (reportPath) {\n console.error(`πŸ“„ μ—λŸ¬ 둜그 μ €μž₯ μœ„μΉ˜: ${reportPath}`);\n }\n\n process.exit(1);\n}\n\nfunction parseServiceFromArgs(args: string[] = process.argv.slice(2)): AIServiceType | '' {\n helperTrace('parse-service:start', `args=${JSON.stringify(args)}`);\n const serviceIndex = args.indexOf('--service');\n const rawService = serviceIndex !== -1 ? args[serviceIndex + 1] : '';\n\n if (!rawService) {\n helperTrace('parse-service:empty');\n\n return '';\n }\n\n const normalizedService = rawService.toLowerCase();\n\n if (AIServices.includes(normalizedService as AIServiceType)) {\n helperTrace('parse-service:resolved', normalizedService);\n\n return normalizedService as AIServiceType;\n }\n\n helperTrace('parse-service:invalid', rawService);\n exitWithError(\n `❌ μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ„œλΉ„μŠ€μž…λ‹ˆλ‹€: ${rawService}. μ‚¬μš© κ°€λŠ₯ κ°’: ${AIServices.join(', ')} (예: --service codex)`,\n {\n scope: 'helper:parseServiceFromArgs',\n args,\n extraSections: [\n {\n heading: 'Allowed Services',\n markdown: `\\`\\`\\`json\\n${JSON.stringify(AIServices, null, 2)}\\n\\`\\`\\``\n }\n ]\n }\n );\n}\n\nexport function getGitDiffFilter() {\n const { includePatterns, excludePatterns } = getGitDiffPathspecs();\n const quote = (pattern: string) => `\"${pattern}\"`;\n const includeParams = includePatterns.map(quote).join(' ');\n const excludeParams = excludePatterns.map(quote).join(' ');\n\n return { includeParams, excludeParams };\n}\n\n/**\n * @description\n * 컀밋 선택 λͺ©λ‘μ—μ„œ subjectκ°€ κ³Όν•˜κ²Œ κΈΈμ–΄μ§€λŠ” 것을 막기 μœ„ν•΄ ν‘œμ‹œ 길이λ₯Ό μ œν•œν•©λ‹ˆλ‹€.\n * commit hash와 λ©”νƒ€λ°μ΄ν„°λŠ” 별도 ν•„λ“œλ‘œ μœ μ§€ν•˜λ―€λ‘œ UI 가독성에 ν•„μš”ν•œ subject만 μžλ¦…λ‹ˆλ‹€.\n * @param subject 원본 컀밋 제λͺ©\n * @returns ν™”λ©΄ ν‘œμ‹œμš© 제λͺ©\n */\nfunction truncateCommitSubject(subject: string) {\n if (subject.length <= 72) {\n return subject;\n }\n\n return `${subject.slice(0, 69)}...`;\n}\n\n/**\n * @description\n * 졜근 컀밋 λͺ©λ‘μ„ 리뷰 선택 UIμ—μ„œ λ°”λ‘œ μ‚¬μš©ν•  수 μžˆλŠ” ꡬ쑰둜 λ³€ν™˜ν•©λ‹ˆλ‹€.\n * git log 포맷을 ν•œ κ³³μ—μ„œ 관리해 main review와 one-by-one reviewκ°€ 같은 컀밋 메타데이터λ₯Ό κ³΅μœ ν•˜κ²Œ ν•©λ‹ˆλ‹€.\n * @returns 졜근 컀밋 μ˜΅μ…˜ λͺ©λ‘\n */\nexport function getRecentCommitOptions(): CommitOption[] {\n const output = runGitCommand(\n ['log', `-${COMMIT_FETCH_LIMIT}`, '--date=relative', '--pretty=format:%h%x09%an%x09%ar%x09%s'],\n { allowFailure: true }\n );\n\n if (!output) {\n return [];\n }\n\n return output.split('\\n').map((line) => {\n const [hash = '', author = '', relativeDate = '', ...subjectParts] = line.split('\\t');\n const subject = subjectParts.join('\\t').trim();\n\n return {\n author,\n description: `${author} | ${relativeDate}`,\n hash,\n label: `${hash} | ${truncateCommitSubject(subject)}`,\n relativeDate,\n subject\n };\n });\n}\n\n/**\n * @description\n * μ„ νƒλœ 컀밋 λͺ©λ‘μ„ 리포트 및 diff 헀더에 μž¬μ‚¬μš©ν•  수 μžˆλŠ” markdown bullet λ¬Έμžμ—΄λ‘œ μ •λ¦¬ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 컀밋 μš”μ•½ markdown\n */\nexport function buildSelectedCommitSummary(commits: CommitOption[]) {\n return commits.map((commit) => `- ${commit.hash} | ${commit.subject} | ${commit.author} | ${commit.relativeDate}`).join('\\n');\n}\n\n/**\n * @description\n * 리뷰 λŒ€μƒ pathspec 배열을 git argv에 λ°”λ‘œ 뢙일 수 있게 ν‰νƒ„ν™”ν•©λ‹ˆλ‹€.\n * λ¬Έμžμ—΄ μ»€λ§¨λ“œμ™€ λ‹€λ₯Έ 경둜 기반 helper도 같은 ν•„ν„°λ₯Ό κ³΅μœ ν•˜λ„λ‘ helper ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν•©λ‹ˆλ‹€.\n * @returns include/exclude pathspec λ°°μ—΄\n */\nfunction getReviewPathspecArgs() {\n const { includePatterns, excludePatterns } = getGitDiffPathspecs();\n\n return [...includePatterns, ...excludePatterns];\n}\n\n/**\n * @description\n * μ„ νƒλœ μ—¬λŸ¬ μ»€λ°‹μ˜ 전체 diffλ₯Ό ν•œ νŒŒμΌμ— ν•©μΉ©λ‹ˆλ‹€.\n * 각 컀밋을 별도 μ„Ήμ…˜μœΌλ‘œ 감싸 AIκ°€ 컀밋 경계λ₯Ό μžƒμ§€ μ•Šλ„λ‘ ν•˜λ©°, κΈ°μ‘΄ 리뷰 λŒ€μƒ ν™•μž₯자 필터도 κ·ΈλŒ€λ‘œ μ μš©ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 리뷰용 톡합 diff ν…μŠ€νŠΈ\n */\nexport function buildSelectedCommitDiff(commits: CommitOption[]) {\n const reviewPathspecArgs = getReviewPathspecArgs();\n const sections = commits\n .map((commit) => {\n const diff = runGitCommand(['show', '--stat', '--patch', '--format=', commit.hash, '--', ...reviewPathspecArgs], {\n allowFailure: true,\n trimOutput: false\n }).trim();\n\n if (!diff) {\n return '';\n }\n\n return [`## ${commit.hash} ${commit.subject}`, diff].join('\\n\\n');\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n if (!sections) {\n return '';\n }\n\n return ['# μ„ νƒν•œ 컀밋', buildSelectedCommitSummary(commits), '', '# 리뷰 λŒ€μƒ diff', sections].join('\\n');\n}\n\n/**\n * @description\n * μ„ νƒλœ μ»€λ°‹μ—μ„œ μ‹€μ œ 리뷰 λŒ€μƒ 파일 λͺ©λ‘λ§Œ μΆ”μΆœν•©λ‹ˆλ‹€.\n * one-by-one 리뷰가 ν˜„μž¬ μ„ νƒλœ 컀밋 μ§‘ν•©μ—λ§Œ λ°˜μ‘ν•˜λ„λ‘ commit별 name-only κ²°κ³Όλ₯Ό ν•©μ§‘ν•©μœΌλ‘œ κ³„μ‚°ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 쀑볡 제거된 파일 λͺ©λ‘\n */\nexport function getSelectedCommitFiles(commits: CommitOption[]) {\n const reviewPathspecArgs = getReviewPathspecArgs();\n const files = new Set<string>();\n\n commits.forEach((commit) => {\n const output = runGitCommand(['show', '--pretty=format:', '--name-only', commit.hash, '--', ...reviewPathspecArgs], {\n allowFailure: true\n });\n\n output\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean)\n .forEach((filePath) => files.add(filePath));\n });\n\n return [...files];\n}\n\n/**\n * @description\n * νŠΉμ • νŒŒμΌμ— λŒ€ν•œ 선택 μ»€λ°‹λ“€μ˜ diff만 λͺ¨μ•„μ„œ one-by-one 리뷰 μž…λ ₯으둜 λ§Œλ“­λ‹ˆλ‹€.\n * 동일 파일이 μ—¬λŸ¬ μ»€λ°‹μ—μ„œ 바뀐 경우 commit section을 λ‚˜λˆ  λ³΄μ—¬μ€˜ 파일 리뷰 응닡이 μ–΄λŠ 변경을 λ‹€λ£¨λŠ”μ§€ 좔적 κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @param filePath 리뷰할 파일 경둜\n * @returns 단일 파일 리뷰용 diff ν…μŠ€νŠΈ\n */\nexport function buildSelectedFileDiff(commits: CommitOption[], filePath: string) {\n const sections = commits\n .map((commit) => {\n const diff = runGitCommand(['show', '--stat', '--patch', '--format=', commit.hash, '--', filePath], {\n allowFailure: true,\n trimOutput: false\n }).trim();\n\n if (!diff) {\n return '';\n }\n\n return [`## ${commit.hash} ${commit.subject}`, diff].join('\\n\\n');\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n if (!sections) {\n return '';\n }\n\n return ['# μ„ νƒν•œ 컀밋', buildSelectedCommitSummary(commits), '', `# 파일: ${filePath}`, sections].join('\\n\\n');\n}\n\n/**\n * openReportλ₯Ό OSλ³„λ‘œ λ™μž‘ν•˜λ„λ‘ λ³€κ²½\n * μš°μ„ μˆœμœ„:\n * 1. Chrome μ‹œλ„\n * - macOS: open -a \"Google Chrome\" \"<path>\"\n * - Ubuntu/Linux: google-chrome \"<path>\"\n * 2. μ‹€νŒ¨ μ‹œ κΈ°λ³Έ λΈŒλΌμš°μ €λ‘œ 폴백\n * - macOS: open \"<path>\"\n * - Ubuntu/Linux: xdg-open \"<path>\"\n * 3. λ‘˜ λ‹€ μ‹€νŒ¨ν•˜λ©΄ μ—λŸ¬ 좜λ ₯\n * 4. 미지원 ν”Œλž«νΌμ΄λ©΄ ν”Œλž«νΌ κ²½κ³  좜λ ₯\n */\nexport function openReport(reportPath: string) {\n const resolvedPath = path.resolve(reportPath);\n const { platform } = process;\n helperTrace('open-report:start', resolvedPath);\n\n const openWithChrome = () => {\n if (platform === 'darwin') {\n execSync(`open -a \"Google Chrome\" \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n if (platform === 'linux') {\n execSync(`google-chrome \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n return false;\n };\n\n const openWithDefaultBrowser = () => {\n if (platform === 'darwin') {\n execSync(`open \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n if (platform === 'linux') {\n execSync(`xdg-open \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n return false;\n };\n\n try {\n if (openWithChrome()) {\n helperTrace('open-report:chrome:success', platform);\n console.log('πŸš€ Google Chromeμ—μ„œ 리포트λ₯Ό μ—΄μ—ˆμŠ΅λ‹ˆλ‹€.');\n\n return;\n }\n } catch (error) {\n helperTrace('open-report:chrome:failed', getErrorSummary(error));\n // Chrome μ‹€ν–‰ μ‹€νŒ¨ μ‹œ κΈ°λ³Έ λΈŒλΌμš°μ €λ‘œ 폴백\n }\n\n try {\n if (openWithDefaultBrowser()) {\n helperTrace('open-report:default-browser:success', platform);\n console.log('πŸš€ κΈ°λ³Έ λΈŒλΌμš°μ €μ—μ„œ 리포트λ₯Ό μ—΄μ—ˆμŠ΅λ‹ˆλ‹€.');\n\n return;\n }\n } catch (error) {\n helperTrace('open-report:default-browser:failed', getErrorSummary(error));\n console.error('⚠️ λΈŒλΌμš°μ € μ—΄κΈ° μ‹€νŒ¨:', error);\n\n return;\n }\n\n helperTrace('open-report:unsupported-platform', platform);\n console.error(`⚠️ μ§€μ›ν•˜μ§€ μ•ŠλŠ” ν”Œλž«νΌμž…λ‹ˆλ‹€: ${platform}`);\n}\n\n/**\n * @description\n * raw mode 기반 선택 UIλ₯Ό μ•ˆμ „ν•˜κ²Œ μ—΄ 수 μžˆλŠ” TTY ν™˜κ²½μΈμ§€ κ²€μ¦ν•©λ‹ˆλ‹€.\n * CIλ‚˜ pipe ν™˜κ²½μ—μ„œλŠ” μ»€μ„œλ₯Ό μ œμ–΄ν•  수 μ—†μœΌλ―€λ‘œ μ¦‰μ‹œ μ—λŸ¬ 리포트λ₯Ό 남기고 μ’…λ£Œν•©λ‹ˆλ‹€.\n * @param scope μ—λŸ¬ 리포트 κ΅¬λΆ„μš© scope\n * @param message μ‚¬μš©μžμ—κ²Œ 보여쀄 μ—λŸ¬ λ©”μ‹œμ§€\n */\nfunction ensureInteractiveSelectionAvailable(scope: string, message: string) {\n if (process.stdin.isTTY && process.stdout.isTTY && typeof process.stdin.setRawMode === 'function') {\n return;\n }\n\n helperTrace(`${scope}:tty-missing`);\n exitWithError(message, {\n scope: `helper:${scope}`\n });\n}\n\n/**\n * @description\n * 선택 λͺ¨λ‹¬μ„ ν˜„μž¬ μœ„μΉ˜μ—μ„œ λ‹€μ‹œ κ·Έλ¦½λ‹ˆλ‹€.\n * 각 쀄은 미리 터미널 폭 μ•ˆμœΌλ‘œ 잘라 physical line이 1μ€„λ‘œ μœ μ§€λ˜λ―€λ‘œ,\n * 직전 λ Œλ” 쀄 수만큼 μœ„λ‘œ μ΄λ™ν•œ λ’€ clearScreenDown 해도 쀑볡 없이 μ•ˆμ •μ μœΌλ‘œ κ°±μ‹ λ©λ‹ˆλ‹€.\n * @param lines μƒˆλ‘œ λ Œλ”ν•  λ¬Έμžμ—΄ 쀄 λͺ©λ‘\n * @param previousLineCount 직전 λ Œλ” 쀄 수\n * @returns ν˜„μž¬ λ Œλ” 쀄 수\n */\nfunction renderSelectionBlock(lines: string[], previousLineCount: number) {\n if (previousLineCount > 0) {\n readline.moveCursor(process.stdout, 0, -previousLineCount);\n readline.clearScreenDown(process.stdout);\n }\n\n const fittedLines = fitLinesToTerminal(lines);\n process.stdout.write(`${fittedLines.join('\\n')}\\n`);\n\n return fittedLines.length;\n}\n\n/**\n * @description\n * ν˜„μž¬ μ»€μ„œ κΈ°μ€€ visible windowλ₯Ό 계산해 κΈ΄ 컀밋 λͺ©λ‘λ„ κ³ μ • λ†’μ΄λ‘œ 탐색할 수 있게 λ§Œλ“­λ‹ˆλ‹€.\n * @param optionCount 전체 μ˜΅μ…˜ 개수\n * @param selectedIndex ν˜„μž¬ 포컀슀 인덱슀\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns μ‹œμž‘/끝 인덱슀\n */\nfunction getSelectionWindowRange(optionCount: number, selectedIndex: number, windowSize: number) {\n if (optionCount <= windowSize) {\n return {\n end: optionCount,\n start: 0\n };\n }\n\n const halfWindow = Math.floor(windowSize / 2);\n const maxStart = optionCount - windowSize;\n const start = Math.max(0, Math.min(selectedIndex - halfWindow, maxStart));\n\n return {\n end: Math.min(optionCount, start + windowSize),\n start\n };\n}\n\n/**\n * @description\n * 곡톡 multi-select UI λ Œλ”λ§μ— ν•„μš”ν•œ λ¬Έμžμ—΄ λͺ©λ‘μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.\n * μ„€λͺ… ν…μŠ€νŠΈλŠ” dim μ²˜λ¦¬ν•΄ subject와 author/dateκ°€ ν•œ μ€„μ—μ„œ κ΅¬λΆ„λ˜λ„λ‘ ν•©λ‹ˆλ‹€.\n * @param question 질문 헀더\n * @param options ν‘œμ‹œν•  μ˜΅μ…˜ λͺ©λ‘\n * @param selectedIndex ν˜„μž¬ 포컀슀 인덱슀\n * @param toggled μ„ νƒλœ 인덱슀 Set\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns 좜λ ₯ 쀄 λͺ©λ‘\n */\nfunction buildMultiSelectLines<T>(\n question: string,\n options: MultiSelectOption<T>[],\n selectedIndex: number,\n toggled: Set<number>,\n windowSize: number\n) {\n const { start, end } = getSelectionWindowRange(options.length, selectedIndex, windowSize);\n const lines = [\n `${ANSI.bold}${question}${ANSI.reset}`,\n `${ANSI.dim}↑↓ 이동 | Space 선택/ν•΄μ œ | Enter μ™„λ£Œ | Esc μ·¨μ†Œ${ANSI.reset}`,\n `${ANSI.dim}선택됨: ${toggled.size}개 / 전체: ${options.length}개${ANSI.reset}`\n ];\n\n for (let index = start; index < end; index += 1) {\n const option = options[index];\n\n if (!option) {\n continue;\n }\n\n const cursor = index === selectedIndex ? `${ANSI.cyan}>${ANSI.reset}` : ' ';\n const checked = toggled.has(index) ? `${ANSI.green}β˜‘${ANSI.reset}` : '☐';\n const description = option.description ? ` ${ANSI.dim}${option.description}${ANSI.reset}` : '';\n lines.push(`${cursor} ${checked} ${option.label}${description}`);\n }\n\n if (options.length > windowSize) {\n lines.push(`${ANSI.dim}ν‘œμ‹œ λ²”μœ„: ${start + 1}-${end} / ${options.length}${ANSI.reset}`);\n }\n\n return lines;\n}\n\n/**\n * @description\n * 컀밋 μ„ νƒμ²˜λŸΌ 볡수 선택이 ν•„μš”ν•œ 터미널 λͺ¨λ‹¬μ„ κ³΅ν†΅μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.\n * raw modeλ₯Ό 직접 μ œμ–΄ν•΄ λ°©ν–₯ν‚€, Space, Enter, Escλ₯Ό 읽고 μ„ νƒλœ value λͺ©λ‘λ§Œ λ°˜ν™˜ν•©λ‹ˆλ‹€.\n * @param question μ‚¬μš©μž μ•ˆλ‚΄ 문ꡬ\n * @param options 선택 μ˜΅μ…˜ λͺ©λ‘\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns μ‚¬μš©μžκ°€ ν™•μ •ν•œ 선택 κ°’ λ°°μ—΄\n */\nexport async function showMultiSelect<T>(question: string, options: MultiSelectOption<T>[], windowSize = COMMIT_SELECTION_WINDOW) {\n ensureInteractiveSelectionAvailable('showMultiSelect', '❌ 컀밋 선택 λͺ¨λ‹¬μ€ TTY ν™˜κ²½μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.');\n let selectedIndex = 0;\n let renderedLineCount = 0;\n const toggled = new Set<number>();\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true\n });\n\n process.stdout.write('\\u001b[?25l');\n\n const cleanup = () => {\n if (renderedLineCount > 0) {\n readline.moveCursor(process.stdout, 0, -renderedLineCount);\n readline.clearScreenDown(process.stdout);\n renderedLineCount = 0;\n }\n process.stdin.removeListener('data', onData);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n rl.close();\n process.stdout.write('\\u001b[?25h');\n };\n\n const render = () => {\n const lines = buildMultiSelectLines(question, options, selectedIndex, toggled, windowSize);\n renderedLineCount = renderSelectionBlock(lines, renderedLineCount);\n };\n\n const confirmSelection = (resolve: (value: T[]) => void) => {\n const values = [...toggled]\n .sort((left, right) => left - right)\n .map((index) => options[index]?.value)\n .filter((value): value is T => value !== undefined);\n\n cleanup();\n resolve(values);\n };\n\n const cancelSelection = (resolve: (value: T[]) => void) => {\n cleanup();\n resolve([]);\n };\n\n let onData = (_data: Buffer) => {\n // μ‹€μ œ κ΅¬ν˜„μ€ Promise 생성 μ‹œμ μ— λ°”μΈλ”©ν•©λ‹ˆλ‹€.\n };\n\n render();\n\n return new Promise<T[]>((resolve) => {\n onData = (data: Buffer) => {\n const key = data.toString();\n\n if (key === '\\u0003') {\n cleanup();\n process.exit(0);\n }\n\n if (key === '\\u001b') {\n cancelSelection(resolve);\n\n return;\n }\n\n if (key === '\\x1b[A') {\n selectedIndex = (selectedIndex - 1 + options.length) % options.length;\n render();\n\n return;\n }\n\n if (key === '\\x1b[B') {\n selectedIndex = (selectedIndex + 1) % options.length;\n render();\n\n return;\n }\n\n if (key === ' ') {\n if (toggled.has(selectedIndex)) {\n toggled.delete(selectedIndex);\n } else {\n toggled.add(selectedIndex);\n }\n render();\n\n return;\n }\n\n if (key === '\\r' || key === '\\n') {\n confirmSelection(resolve);\n }\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', onData);\n });\n}\n\n/**\n * @description\n * 졜근 컀밋 λͺ©λ‘μ„ modal UI둜 선택받아 review μ—”νŠΈλ¦¬ν¬μΈνŠΈμ—μ„œ λ°”λ‘œ μž¬μ‚¬μš©ν•  수 있게 λ°˜ν™˜ν•©λ‹ˆλ‹€.\n * @returns μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n */\nexport async function selectReviewCommits() {\n const commits = getRecentCommitOptions();\n\n if (commits.length === 0) {\n console.log('ℹ️ 리뷰할 졜근 컀밋이 μ—†μŠ΅λ‹ˆλ‹€.');\n\n return [];\n }\n\n return showMultiSelect<CommitOption>(\n '리뷰할 컀밋을 μ„ νƒν•΄μ£Όμ„Έμš”.',\n commits.map((commit) => ({\n description: commit.description,\n label: commit.label,\n value: commit\n })),\n COMMIT_SELECTION_WINDOW\n );\n}\n\n/**\n * AI μ„œλΉ„μŠ€ 선택\n */\nexport function selectAIService() {\n const service = parseServiceFromArgs();\n\n if (!service) {\n helperTrace('select-service:missing');\n exitWithError('❌ μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.', {\n scope: 'helper:selectAIService'\n });\n }\n\n helperTrace('select-service:done', service);\n\n return service;\n}\n\n/**\n * ν„°λ―Έλ„μ—μ„œ λΌλ””μ˜€ λ²„νŠΌ ν˜•νƒœλ‘œ AI μ„œλΉ„μŠ€λ₯Ό μ„ νƒν•©λ‹ˆλ‹€.\n */\nexport async function showSelectionAIService(): Promise<AIServiceType> {\n const selectedServiceFromArgs = parseServiceFromArgs();\n\n if (selectedServiceFromArgs) {\n helperTrace('show-selection:from-args', selectedServiceFromArgs);\n console.log(`\\nβœ… ${ANSI.green}${selectedServiceFromArgs}${ANSI.reset} μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€. (--service)\\n`);\n\n return selectedServiceFromArgs;\n }\n\n ensureInteractiveSelectionAvailable('showSelectionAIService', '❌ AI μ„œλΉ„μŠ€ 선택 UIλŠ” TTY ν™˜κ²½μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.');\n helperTrace('show-selection:interactive:start');\n let selectedIndex = 0;\n\n // Use readline to handle keypresses\n // ν‚€ μž…λ ₯을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ readline μΈν„°νŽ˜μ΄μŠ€ μ‚¬μš©\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true\n });\n\n let firstRender = true;\n\n // Hide cursor\n process.stdout.write('\\u001b[?25l');\n\n const render = () => {\n if (!firstRender) {\n // Move cursor back to the starting line of the selection UI\n // We print (1 question line + services.length lines)\n // 선택 UI의 μ‹œμž‘ 라인으둜 μ»€μ„œ 이동 (질문 1쀄 + μ„œλΉ„μŠ€ λͺ©λ‘ N쀄)\n readline.moveCursor(process.stdout, 0, -(AIServices.length + 1));\n }\n firstRender = false;\n helperTrace('show-selection:interactive:render', AIServices[selectedIndex] || 'unknown');\n\n // Clear everything from cursor down to avoid ghosting/overlaps\n // μž”μƒμ΄λ‚˜ 겹침을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ μ»€μ„œ μœ„μΉ˜λΆ€ν„° μ•„λž˜μͺ½ λͺ¨λ‘ 지움\n readline.clearScreenDown(process.stdout);\n\n process.stdout.write(\n `πŸ€– AI μ„œλΉ„μŠ€λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš” (${ANSI.yellow}↑↓ λ°©ν–₯ν‚€${ANSI.reset} 이동, ${ANSI.yellow}Enter${ANSI.reset} 선택):\\n`\n );\n AIServices.forEach((service, index) => {\n if (index === selectedIndex) {\n process.stdout.write(` ${ANSI.cyan}>${ANSI.reset} ${ANSI.cyan}β—‰${ANSI.reset} ${ANSI.bold}${service}${ANSI.reset}\\n`);\n } else {\n process.stdout.write(` β—― ${service}\\n`);\n }\n });\n };\n\n render();\n\n return new Promise((resolve) => {\n const onData = (data: Buffer) => {\n const key = data.toString();\n if (key === '\\u0003') {\n // Ctrl+C\n helperTrace('show-selection:interactive:ctrl-c');\n process.stdout.write('\\u001b[?25h'); // Show cursor\n process.exit(0);\n }\n if (key === '\\x1b[A') {\n // Up arrow\n selectedIndex = (selectedIndex - 1 + AIServices.length) % AIServices.length;\n render();\n } else if (key === '\\x1b[B') {\n // Down arrow\n selectedIndex = (selectedIndex + 1) % AIServices.length;\n render();\n } else if (key === '\\r' || key === '\\n') {\n // Enter\n process.stdin.removeListener('data', onData);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n rl.close();\n\n // Show cursor\n process.stdout.write('\\u001b[?25h');\n\n console.log(`\\nβœ… ${ANSI.green}${AIServices[selectedIndex]}${ANSI.reset} μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.\\n`);\n const result = AIServices[selectedIndex];\n if (result) {\n helperTrace('show-selection:interactive:confirmed', result);\n resolve(result);\n }\n }\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', onData);\n });\n}\n"]}
1
+ {"version":3,"sources":["../../src/common/helper.ts"],"names":["__dirname","path","fileURLToPath","fs","execFileSync","inspect","execSync","readline"],"mappings":"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","file":"helper.cjs","sourcesContent":["import { execFileSync, execSync } from 'child_process';\nimport fs from 'fs';\nimport path from 'path';\nimport readline from 'readline';\nimport { fileURLToPath } from 'url';\nimport { inspect } from 'util';\n\nimport { AIServiceType, CommitOption, MultiSelectOption, ReviewTargetKind } from './types';\n\ntype ErrorReportSection = {\n heading: string;\n markdown: string;\n};\n\ntype WriteErrorReportOptions = {\n title?: string;\n scope?: string;\n args?: string[];\n traceMessages?: string[];\n extraSections?: ErrorReportSection[];\n};\n\ntype ExecutionLogStatus = 'cancelled' | 'failed' | 'partial_failure' | 'success';\n\ntype WriteExecutionLogOptions = {\n title?: string;\n scope?: string;\n status?: ExecutionLogStatus;\n args?: string[];\n startedAt?: Date;\n finishedAt?: Date;\n traceMessages?: string[];\n extraSections?: ErrorReportSection[];\n error?: unknown;\n};\n\ntype GitCommandOptions = {\n allowFailure?: boolean;\n trimOutput?: boolean;\n};\n\ntype ShellCommandProgressOptions = {\n progressIntervalMs?: number;\n progressMessage?: string;\n streamOutput?: boolean;\n};\n\ntype ShellCommandFailureDetails = {\n code: number | null;\n command: string;\n signal: NodeJS.Signals | null;\n stderr: string;\n stdout: string;\n};\n\ntype ShellLaunchConfig = {\n executable: string;\n shellArgs: string[];\n};\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\nconst traceMessages: string[] = [];\nconst GEMINI_CLI_PACKAGE_NAME = 'sales-frontend-gemini-cli';\nlet cachedPackageRootPath = '';\n\n/**\n * @description\n * ν˜„μž¬ 디렉터리가 gemini-cli νŒ¨ν‚€μ§€ λ£¨νŠΈμΈμ§€ ν™•μΈν•©λ‹ˆλ‹€.\n * λ²ˆλ“€ κ²°κ³Όλ¬Όμ—μ„œ helper μ½”λ“œκ°€ 각 μ—”νŠΈλ¦¬ 파일둜 인라인되면 `__dirname` 기쀀점이 λ‹¬λΌμ§€λ―€λ‘œ,\n * package.json μ΄λ¦„μœΌλ‘œ μ‹€μ œ νŒ¨ν‚€μ§€ 루트λ₯Ό 식별해야 κ·œμΉ™/양식 파일 κ²½λ‘œκ°€ κΉ¨μ§€μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.\n * @param directory 검사할 디렉터리 경둜\n * @returns ν˜„μž¬ 디렉터리가 gemini-cli νŒ¨ν‚€μ§€ 루트이면 true\n */\nfunction isGeminiCliPackageRoot(directory: string) {\n const packageJsonPath = path.join(directory, 'package.json');\n\n if (!fs.existsSync(packageJsonPath)) {\n return false;\n }\n\n try {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8')) as { name?: string };\n\n return packageJson.name === GEMINI_CLI_PACKAGE_NAME;\n } catch {\n return false;\n }\n}\n\n/**\n * @description\n * ν˜„μž¬ μ‹€ν–‰ 쀑인 λ²ˆλ“€ μ—”νŠΈλ¦¬ κΈ°μ€€μœΌλ‘œ gemini-cli νŒ¨ν‚€μ§€ 루트λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.\n * `dist/pr-review/review.js`, `dist/pr-review/gemini/gemini-commander.js`처럼\n * μ—”νŠΈλ¦¬ μœ„μΉ˜κ°€ 달라도 μƒμœ„ 디렉터리λ₯Ό μˆœνšŒν•˜λ©° package rootλ₯Ό 찾도둝 μ„€κ³„ν•©λ‹ˆλ‹€.\n * @param startDirectory νŒ¨ν‚€μ§€ 루트 탐색을 μ‹œμž‘ν•  디렉터리\n * @returns κ·œμΉ™/양식 파일이 μ‘΄μž¬ν•˜λŠ” gemini-cli νŒ¨ν‚€μ§€ 루트 경둜\n */\nfunction resolveGeminiCliPackageRoot(startDirectory: string = __dirname) {\n if (cachedPackageRootPath) {\n return cachedPackageRootPath;\n }\n\n let currentDirectory = startDirectory;\n\n while (true) {\n if (isGeminiCliPackageRoot(currentDirectory)) {\n cachedPackageRootPath = currentDirectory;\n\n return cachedPackageRootPath;\n }\n\n const parentDirectory = path.dirname(currentDirectory);\n\n if (parentDirectory === currentDirectory) {\n break;\n }\n\n currentDirectory = parentDirectory;\n }\n\n /**\n * @description\n * package.json 탐색이 μ‹€νŒ¨ν•΄λ„ κΈ°μ‘΄ μ„€μΉ˜ ꡬ쑰(dist/common -> package root)λ₯Ό μš°μ„  fallback으둜 μ‚¬μš©ν•©λ‹ˆλ‹€.\n * μ˜ˆμƒμΉ˜ λͺ»ν•œ 배포 ν™˜κ²½μ—μ„œλ„ μ΅œλŒ€ν•œ κΈ°μ‘΄ λ™μž‘μ„ μœ μ§€ν•˜κΈ° μœ„ν•œ 보수적 μ•ˆμ „μž₯μΉ˜μž…λ‹ˆλ‹€.\n */\n cachedPackageRootPath = path.resolve(startDirectory, '../..');\n\n return cachedPackageRootPath;\n}\n\n/**\n * @description\n * gemini-cli νŒ¨ν‚€μ§€ 루트λ₯Ό κΈ°μ€€μœΌλ‘œ 정적 asset 파일의 μ ˆλŒ€ 경둜λ₯Ό κ³„μ‚°ν•©λ‹ˆλ‹€.\n * λ²ˆλ“€ κ³Όμ •μ—μ„œ helper μ½”λ“œκ°€ λ‹€λ₯Έ μ—”νŠΈλ¦¬μ— μΈλΌμΈλ˜μ–΄λ„ 항상 같은 μ‹€μ œ νŒŒμΌμ„ κ°€λ¦¬ν‚€κ²Œ ν•©λ‹ˆλ‹€.\n * @param relativeFilePath νŒ¨ν‚€μ§€ 루트 κΈ°μ€€ μƒλŒ€ 경둜\n * @returns asset 파일의 μ ˆλŒ€ 경둜\n */\nfunction resolvePackageAssetPath(relativeFilePath: string) {\n return path.resolve(resolveGeminiCliPackageRoot(), relativeFilePath);\n}\n\nexport const rulesPath = resolvePackageAssetPath('src/common/rules/review-rules.md');\nexport const namingRulesPath = resolvePackageAssetPath('src/common/rules/naming-rule.md');\nexport const codingConventionRulesPath = resolvePackageAssetPath('src/common/rules/coding-convention.md');\nexport const reviewFormPath = resolvePackageAssetPath('src/common/form/review-form.md');\nexport const reviewFormOneByOnePath = resolvePackageAssetPath('src/common/form/review-form-one-by-one.md');\nexport const REPORT_DIR = '.review-report';\nexport const tempDiffPath = 'temp_diff.txt';\nexport const AIServices: AIServiceType[] = ['gemini', 'claude', 'codex'];\nexport const COMMIT_FETCH_LIMIT = 20;\nexport const COMMIT_SELECTION_WINDOW = 8;\nexport const ignoreList = [\n 'package.json',\n '*.yml',\n '*.md',\n '*.lock',\n 'dist/',\n 'node_modules/',\n 'assets/',\n 'public/',\n '*.json',\n '*.yaml',\n '.review-report/' // μƒμ„±λ˜λŠ” 리포트 폴더도 μ œμ™Έ\n];\n\nexport function isTestMode(args: string[] = process.argv.slice(2)) {\n return args.includes('--test');\n}\n\n/**\n * @description\n * AI CLI의 쀑간 stdout/stderrλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ 터미널에 λ…ΈμΆœν• μ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•©λ‹ˆλ‹€.\n * κΈ°λ³Έ 싀행은 μ‘°μš©ν•œ λͺ¨λ“œλ‘œ μœ μ§€ν•˜κ³ , μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ ν”Œλž˜κ·Έλ₯Ό 쀄 λ•Œλ§Œ\n * AI 응닡을 κ·ΈλŒ€λ‘œ μŠ€νŠΈλ¦¬λ°ν•©λ‹ˆλ‹€.\n * @param args ν˜„μž¬ μ‹€ν–‰ 인자 λͺ©λ‘\n * @returns μ‹€μ‹œκ°„ AI 좜λ ₯ λ…ΈμΆœ μ—¬λΆ€\n */\nexport function shouldStreamAIOutput(args: string[] = process.argv.slice(2)) {\n return args.includes('--stream-output');\n}\n\nexport function clearTraceMessages() {\n traceMessages.length = 0;\n}\n\nexport function getTraceMessages() {\n return [...traceMessages];\n}\n\n/**\n * @description\n * 터미널 선택 UIμ—μ„œ λ™μΌν•œ 색상 토큰을 μž¬μ‚¬μš©ν•  수 μžˆλ„λ‘ ANSI escape codeλ₯Ό μƒμˆ˜ν™”ν•©λ‹ˆλ‹€.\n * μ„œλΉ„μŠ€ 선택과 컀밋 선택이 같은 μ‹œκ° μ–Έμ–΄λ₯Ό μ‚¬μš©ν•˜λ„λ‘ helper λ‚΄λΆ€μ—μ„œλ§Œ κ³΅μœ ν•©λ‹ˆλ‹€.\n */\nconst ANSI = {\n bold: '\\u001b[1m',\n cyan: '\\u001b[36m',\n dim: '\\u001b[2m',\n green: '\\u001b[32m',\n reset: '\\u001b[0m',\n yellow: '\\u001b[33m'\n} as const;\nconst ANSI_PATTERN = new RegExp(`${String.fromCharCode(27)}\\\\[[0-9;]*m`, 'g');\nconst COMBINING_MARK_PATTERN = /\\p{Mark}/u;\nconst GRAPHEME_SEGMENTER =\n typeof Intl !== 'undefined' && 'Segmenter' in Intl ? new Intl.Segmenter('ko', { granularity: 'grapheme' }) : null;\n\ntype VisibleToken = {\n value: string;\n visibleWidth: number;\n};\n\n/**\n * @description\n * 리뷰 λŒ€μƒ 파일 ν•„ν„°λ₯Ό pathspec λ°°μ—΄ ν˜•νƒœλ‘œ μ •μ˜ν•©λ‹ˆλ‹€.\n * λ¬Έμžμ—΄ μ»€λ§¨λ“œμ™€ argv 기반 git 싀행이 λͺ¨λ‘ 같은 기쀀을 κ³΅μœ ν•˜λ„λ‘ 원본 νŒ¨ν„΄μ€ λ°°μ—΄λ‘œ μœ μ§€ν•©λ‹ˆλ‹€.\n */\nfunction getGitDiffPathspecs() {\n return {\n excludePatterns: ignoreList.map((item) => `:(exclude)${item}`),\n includePatterns: ['*.ts', '*.tsx', '*.js', '*.jsx']\n };\n}\n\nfunction segmentGraphemes(value: string) {\n if (!GRAPHEME_SEGMENTER) {\n return [...value];\n }\n\n return [...GRAPHEME_SEGMENTER.segment(value)].map(({ segment }) => segment);\n}\n\nfunction isWideCodePoint(codePoint: number) {\n return (\n codePoint >= 0x1100 &&\n (codePoint <= 0x115f ||\n codePoint === 0x2329 ||\n codePoint === 0x232a ||\n (codePoint >= 0x2e80 && codePoint <= 0x3247 && codePoint !== 0x303f) ||\n (codePoint >= 0x3250 && codePoint <= 0x4dbf) ||\n (codePoint >= 0x4e00 && codePoint <= 0xa4c6) ||\n (codePoint >= 0xa960 && codePoint <= 0xa97c) ||\n (codePoint >= 0xac00 && codePoint <= 0xd7a3) ||\n (codePoint >= 0xf900 && codePoint <= 0xfaff) ||\n (codePoint >= 0xfe10 && codePoint <= 0xfe19) ||\n (codePoint >= 0xfe30 && codePoint <= 0xfe6b) ||\n (codePoint >= 0xff01 && codePoint <= 0xff60) ||\n (codePoint >= 0xffe0 && codePoint <= 0xffe6) ||\n (codePoint >= 0x1f200 && codePoint <= 0x1f251) ||\n (codePoint >= 0x20000 && codePoint <= 0x3fffd))\n );\n}\n\nfunction isEmojiCodePoint(codePoint: number) {\n return (\n (codePoint >= 0x1f1e6 && codePoint <= 0x1f1ff) ||\n (codePoint >= 0x1f300 && codePoint <= 0x1faff) ||\n (codePoint >= 0x2600 && codePoint <= 0x27bf)\n );\n}\n\nfunction getGraphemeWidth(grapheme: string) {\n let width = 0;\n\n for (const character of grapheme) {\n const codePoint = character.codePointAt(0);\n\n if (!codePoint || COMBINING_MARK_PATTERN.test(character) || codePoint === 0x200d) {\n continue;\n }\n\n if ((codePoint >= 0xfe00 && codePoint <= 0xfe0f) || (codePoint >= 0xe0100 && codePoint <= 0xe01ef)) {\n continue;\n }\n\n if (isWideCodePoint(codePoint) || isEmojiCodePoint(codePoint)) {\n width = Math.max(width, 2);\n\n continue;\n }\n\n width = Math.max(width, 1);\n }\n\n return width;\n}\n\nfunction tokenizePlainText(value: string) {\n return segmentGraphemes(value).map((segment) => ({\n value: segment,\n visibleWidth: getGraphemeWidth(segment)\n }));\n}\n\nfunction tokenizeVisibleText(value: string) {\n const tokens: VisibleToken[] = [];\n let lastIndex = 0;\n\n for (const match of value.matchAll(ANSI_PATTERN)) {\n const index = match.index ?? 0;\n\n if (index > lastIndex) {\n tokens.push(...tokenizePlainText(value.slice(lastIndex, index)));\n }\n\n tokens.push({\n value: match[0],\n visibleWidth: 0\n });\n lastIndex = index + match[0].length;\n }\n\n if (lastIndex < value.length) {\n tokens.push(...tokenizePlainText(value.slice(lastIndex)));\n }\n\n return tokens;\n}\n\n/**\n * @description\n * λͺ¨λ‹¬ 각 쀄이 터미널 μ‹€μ œ 폭을 λ„˜μ§€ μ•Šλ„λ‘ ANSI μ½”λ“œλ₯Ό λ³΄μ‘΄ν•œ 채 μž˜λΌλƒ…λ‹ˆλ‹€.\n * μ€„λ°”κΏˆμ΄ λ°œμƒν•˜λ©΄ λ Œλ” 쀄 수 계산이 μ–΄κΈ‹λ‚˜λ―€λ‘œ, λͺ¨λ“  선택 쀄을 1 physical line둜 κ°•μ œν•©λ‹ˆλ‹€.\n * @param value λ Œλ”ν•  λ¬Έμžμ—΄\n * @param maxWidth ν—ˆμš© μ΅œλŒ€ ν‘œμ‹œ 폭\n * @returns 터미널 폭 μ•ˆμœΌλ‘œ μ •λ¦¬λœ λ¬Έμžμ—΄\n */\nfunction truncateLineForTerminal(value: string, maxWidth: number) {\n if (maxWidth <= 0) {\n return '';\n }\n\n const tokens = tokenizeVisibleText(value);\n const totalWidth = tokens.reduce((sum, token) => sum + token.visibleWidth, 0);\n\n if (totalWidth <= maxWidth) {\n return value;\n }\n\n const ellipsis = '...';\n const ellipsisWidth = 3;\n const targetWidth = Math.max(0, maxWidth - ellipsisWidth);\n let usedWidth = 0;\n let result = '';\n\n for (const token of tokens) {\n if (token.visibleWidth === 0) {\n result += token.value;\n\n continue;\n }\n\n if (usedWidth + token.visibleWidth > targetWidth) {\n break;\n }\n\n result += token.value;\n usedWidth += token.visibleWidth;\n }\n\n return `${result}${ellipsis}${ANSI.reset}`;\n}\n\nfunction fitLinesToTerminal(lines: string[]) {\n const maxWidth = Math.max(20, (process.stdout.columns || 120) - 1);\n\n return lines.map((line) => truncateLineForTerminal(line, maxWidth));\n}\n\n/**\n * @description\n * git μ„œλΈŒν”„λ‘œμ„ΈμŠ€λ₯Ό argv λ°°μ—΄ 기반으둜 μ‹€ν–‰ν•©λ‹ˆλ‹€.\n * 컀밋 ν•΄μ‹œλ‚˜ 파일 κ²½λ‘œμ— 곡백이 μ„žμ—¬λ„ shell quoting 문제 없이 λ™μΌν•œ λ™μž‘μ„ 보μž₯ν•˜κΈ° μœ„ν•΄ 곡톡 helper둜 λΆ„λ¦¬ν•©λ‹ˆλ‹€.\n * @param args git 인자 λ°°μ—΄\n * @param options μ‹€νŒ¨ ν—ˆμš© 여뢀와 좜λ ₯ trim μ—¬λΆ€\n * @returns git ν‘œμ€€μΆœλ ₯ λ¬Έμžμ—΄\n */\nfunction runGitCommand(args: string[], options: GitCommandOptions = {}) {\n const { allowFailure = false, trimOutput = true } = options;\n\n try {\n const output = execFileSync('git', args, {\n encoding: 'utf8',\n maxBuffer: 1024 * 1024 * 20,\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n return trimOutput ? output.trim() : output;\n } catch (error) {\n helperTrace('git-command:failed', `${args.join(' ')} | ${getErrorSummary(error)}`);\n\n if (allowFailure) {\n return '';\n }\n\n throw error;\n }\n}\n\n/**\n * @description\n * ν˜„μž¬ ν™˜κ²½μ—μ„œ μ‹€μ œλ‘œ μ‹€ν–‰ κ°€λŠ₯ν•œ POSIX shell을 κ³ λ¦…λ‹ˆλ‹€.\n * 리뷰 λͺ…령은 `||`, pipe, single quote escaping을 ν¬ν•¨ν•œ shell 문법을 μ‚¬μš©ν•˜λ―€λ‘œ\n * bash/zshκ°€ 있으면 login shell둜 μ‹€ν–‰ν•˜κ³ , μ—†μœΌλ©΄ sh둜 μ•ˆμ „ν•˜κ²Œ ν΄λ°±ν•©λ‹ˆλ‹€.\n * @returns spawn 싀행에 μ‚¬μš©ν•  shell κ²½λ‘œμ™€ prefix 인자\n */\nfunction resolveShellLaunchConfig(): ShellLaunchConfig {\n const candidates: ShellLaunchConfig[] = [];\n const seen = new Set<string>();\n\n /**\n * @description\n * 쀑볡 없이 shell 후보λ₯Ό λ“±λ‘ν•©λ‹ˆλ‹€.\n * μ ˆλŒ€ 경둜 ν›„λ³΄λŠ” μ‹€μ œ 파일이 μ‘΄μž¬ν•  λ•Œλ§Œ μΆ”κ°€ν•΄ ENOENTλ₯Ό 사전에 μ°¨λ‹¨ν•©λ‹ˆλ‹€.\n * @param executable shell μ‹€ν–‰ 파일 경둜 λ˜λŠ” λͺ…λ Ήμ–΄\n * @param shellArgs shell μ•žλ‹¨ 인자\n */\n const appendCandidate = (executable: string | undefined, shellArgs: string[]) => {\n const normalizedExecutable = executable?.trim();\n\n if (!normalizedExecutable) {\n return;\n }\n\n if (path.isAbsolute(normalizedExecutable) && !fs.existsSync(normalizedExecutable)) {\n return;\n }\n\n const key = `${normalizedExecutable}::${shellArgs.join('\\u0000')}`;\n\n if (seen.has(key)) {\n return;\n }\n\n seen.add(key);\n candidates.push({\n executable: normalizedExecutable,\n shellArgs\n });\n };\n\n const shellFromEnv = process.env.SHELL?.trim();\n const envShellName = shellFromEnv ? path.basename(shellFromEnv) : '';\n\n if (['bash', 'zsh', 'ksh'].includes(envShellName)) {\n appendCandidate(shellFromEnv, ['-lc']);\n }\n\n ['/bin/bash', '/usr/bin/bash', 'bash', '/bin/zsh', '/usr/bin/zsh', 'zsh'].forEach((shellPath) => {\n appendCandidate(shellPath, ['-lc']);\n });\n ['/bin/sh', '/usr/bin/sh', 'sh'].forEach((shellPath) => {\n appendCandidate(shellPath, ['-c']);\n });\n\n return candidates[0] || { executable: 'sh', shellArgs: ['-c'] };\n}\n\n/**\n * @description\n * shell λͺ…령을 λΉ„λ™κΈ°λ‘œ μ‹€ν–‰ν•˜λ©΄μ„œ stdout/stderrλ₯Ό κ·ΈλŒ€λ‘œ ν˜λ €λ³΄λ‚΄κ³ , μž₯μ‹œκ°„ μž‘μ—…μ—λŠ” κ²½κ³Ό μ‹œκ°„μ„ 주기적으둜 좜λ ₯ν•©λ‹ˆλ‹€.\n * review μ‹€ν–‰μ²˜λŸΌ 응닡 μƒμ„±κΉŒμ§€ 였래 κ±Έλ¦¬λŠ” CLIλ₯Ό 버퍼링 없이 κΈ°λ‹€λ¦¬κ²Œ ν•΄ μ‚¬μš©μžκ°€ 멈좀으둜 μ˜€ν•΄ν•˜μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.\n * @param command μ‹€ν–‰ν•  shell command λ¬Έμžμ—΄\n * @param options μ§„ν–‰ λ©”μ‹œμ§€μ™€ 좜λ ₯ μ£ΌκΈ° μ˜΅μ…˜\n * @returns μ΅œμ’… stdout/stderr 캑처 κ²°κ³Ό\n */\nexport async function executeShellCommandWithProgress(command: string, options: ShellCommandProgressOptions = {}) {\n const { progressIntervalMs = 10000, progressMessage = '⏳ λͺ…령을 μ‹€ν–‰ν•˜λŠ” μ€‘μž…λ‹ˆλ‹€...', streamOutput = false } = options;\n const { spawn } = await import('child_process');\n const shellLaunchConfig = resolveShellLaunchConfig();\n\n return new Promise<{ stderr: string; stdout: string }>((resolve, reject) => {\n let stdout = '';\n let stderr = '';\n const startedAt = Date.now();\n console.log(progressMessage);\n helperTrace('shell-command:launcher', `${shellLaunchConfig.executable} ${shellLaunchConfig.shellArgs.join(' ')}`);\n\n const child = spawn(shellLaunchConfig.executable, [...shellLaunchConfig.shellArgs, command], {\n stdio: ['ignore', 'pipe', 'pipe']\n });\n\n const progressTimer = setInterval(() => {\n const elapsedSeconds = Math.max(1, Math.floor((Date.now() - startedAt) / 1000));\n console.log(`${progressMessage} (${elapsedSeconds}s κ²½κ³Ό)`);\n }, progressIntervalMs);\n\n child.stdout.on('data', (chunk: Buffer | string) => {\n const text = chunk.toString();\n stdout += text;\n\n if (streamOutput) {\n process.stdout.write(text);\n }\n });\n\n child.stderr.on('data', (chunk: Buffer | string) => {\n const text = chunk.toString();\n stderr += text;\n\n if (streamOutput) {\n process.stderr.write(text);\n }\n });\n\n child.on('error', (error) => {\n clearInterval(progressTimer);\n reject(error);\n });\n\n child.on('close', (code, signal) => {\n clearInterval(progressTimer);\n\n if (code === 0) {\n resolve({\n stderr,\n stdout\n });\n\n return;\n }\n\n const exitSummary = signal ? `signal=${signal}` : `code=${String(code ?? 'unknown')}`;\n const failureDetails: ShellCommandFailureDetails = {\n code,\n command,\n signal,\n stderr,\n stdout\n };\n\n reject(createShellCommandExecutionError(failureDetails, exitSummary));\n });\n });\n}\n\n/**\n * @description\n * shell λͺ…λ Ή μ‹€νŒ¨ μ‹œ μ—λŸ¬ λ©”μ‹œμ§€μ— 포함할 좜λ ₯ 미리보기λ₯Ό μƒμ„±ν•©λ‹ˆλ‹€.\n * 일뢀 CLIλŠ” μ‹€νŒ¨ μ‚¬μœ λ₯Ό stderrκ°€ μ•„λ‹ˆλΌ stdout으둜만 좜λ ₯ν•˜λ―€λ‘œ, 두 채널을 ν•¨κ»˜ 확인해야\n * 원인 νŒŒμ•…μ΄ κ°€λŠ₯ν•©λ‹ˆλ‹€. λ„ˆλ¬΄ κΈ΄ 응닡이 κ·ΈλŒ€λ‘œ μ—λŸ¬ 제λͺ©μ— λΆ™μ§€ μ•Šλ„λ‘ λ§ˆμ§€λ§‰ μΌλΆ€λ§Œ μž˜λΌλƒ…λ‹ˆλ‹€.\n * @param failureDetails μ‹€νŒ¨ν•œ shell λͺ…λ Ήμ˜ μ‹€ν–‰ κ²°κ³Ό\n * @returns μ—λŸ¬ λ©”μ‹œμ§€μ— 뢙일 좜λ ₯ μš”μ•½ λ¬Έμžμ—΄\n */\nfunction getShellCommandFailurePreview(failureDetails: ShellCommandFailureDetails) {\n const stderrText = failureDetails.stderr.trim();\n const stdoutText = failureDetails.stdout.trim();\n const combinedOutput = stderrText || stdoutText;\n\n if (!combinedOutput) {\n return '';\n }\n\n const MAX_PREVIEW_LENGTH = 4000;\n\n if (combinedOutput.length <= MAX_PREVIEW_LENGTH) {\n return combinedOutput;\n }\n\n return combinedOutput.slice(-MAX_PREVIEW_LENGTH);\n}\n\n/**\n * @description\n * shell λͺ…λ Ή μ‹€νŒ¨ 정보λ₯Ό Error 객체둜 μŠΉκ²©ν•©λ‹ˆλ‹€.\n * μ—λŸ¬ λ¦¬ν¬νŠΈμ—μ„œ μ‹€μ œ μ‹€νŒ¨ 원인을 확인할 수 μžˆλ„λ‘ stdout/stderr/command/exit codeλ₯Ό\n * Error μΈμŠ€ν„΄μŠ€μ— 직접 λΆ€μ°©ν•©λ‹ˆλ‹€.\n * @param failureDetails μ‹€νŒ¨ν•œ shell λͺ…λ Ήμ˜ μ‹€ν–‰ κ²°κ³Ό\n * @param exitSummary μ’…λ£Œ μ½”λ“œ λ˜λŠ” μ‹œκ·Έλ„ μš”μ•½\n * @returns μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ λΆ€μ°©λœ Error 객체\n */\nfunction createShellCommandExecutionError(failureDetails: ShellCommandFailureDetails, exitSummary: string) {\n const failurePreview = getShellCommandFailurePreview(failureDetails);\n const error = new Error(`μ‰˜ λͺ…λ Ή μ‹€ν–‰ μ‹€νŒ¨ (${exitSummary})${failurePreview ? `\\n${failurePreview}` : ''}`) as Error &\n Record<string, unknown>;\n\n error.code = failureDetails.code;\n error.signal = failureDetails.signal;\n error.stdout = failureDetails.stdout;\n error.stderr = failureDetails.stderr;\n error.command = failureDetails.command;\n\n return error;\n}\n\n/**\n * @description\n * 리뷰 λŒ€μƒ 파일 λͺ©λ‘μ„ ν•œ 쀄 μš”μ•½ λ¬Έμžμ—΄λ‘œ λ³€ν™˜ν•©λ‹ˆλ‹€.\n * 파일이 λ§Žμ„ λ•ŒλŠ” μΌλΆ€λ§Œ λ…ΈμΆœν•˜κ³  λ‚˜λ¨Έμ§€λŠ” 개수둜 μΆ•μ•½ν•΄ 터미널 좜λ ₯이 κ³Όλ„ν•˜κ²Œ κΈΈμ–΄μ§€μ§€ μ•Šλ„λ‘ ν•©λ‹ˆλ‹€.\n * @param files 리뷰 λŒ€μƒ 파일 λͺ©λ‘\n * @param visibleCount 터미널에 직접 보여쀄 μ΅œλŒ€ 파일 수\n * @returns ν™”λ©΄ ν‘œμ‹œμš© μš”μ•½ λ¬Έμžμ—΄\n */\nexport function formatReviewTargetFiles(files: string[], visibleCount = 5) {\n if (files.length === 0) {\n return '(μ—†μŒ)';\n }\n\n const visibleFiles = files.slice(0, visibleCount);\n const hiddenCount = Math.max(0, files.length - visibleFiles.length);\n\n if (hiddenCount === 0) {\n return visibleFiles.join(', ');\n }\n\n return `${visibleFiles.join(', ')} μ™Έ ${hiddenCount}개`;\n}\n\nexport function createTraceLogger(scope: string, args: string[] = process.argv.slice(2)) {\n const enabled = isTestMode(args);\n\n return (step: string, detail?: string) => {\n const timestamp = new Date().toISOString();\n const message = `[${timestamp}][TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ''}`;\n traceMessages.push(message);\n\n if (!enabled) {\n return;\n }\n\n console.log(message);\n };\n}\n\nconst helperTrace = createTraceLogger('helper');\n\nfunction getTimestampParts(now = new Date()) {\n return {\n YYYY: now.getFullYear(),\n MM: String(now.getMonth() + 1).padStart(2, '0'),\n DD: String(now.getDate()).padStart(2, '0'),\n HH: String(now.getHours()).padStart(2, '0'),\n mm: String(now.getMinutes()).padStart(2, '0'),\n ss: String(now.getSeconds()).padStart(2, '0')\n };\n}\n\nfunction getHumanReadableNowString(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`;\n}\n\nfunction stringifyUnknown(value: unknown) {\n if (value === undefined || value === null) {\n return '';\n }\n\n if (typeof value === 'string') {\n return value;\n }\n\n if (Buffer.isBuffer(value)) {\n return value.toString();\n }\n\n if (value instanceof Error) {\n return value.stack || value.message;\n }\n\n return inspect(value, { depth: 5, breakLength: 120 });\n}\n\nexport function getErrorSummary(error: unknown) {\n if (error instanceof Error) {\n return `${error.name}: ${error.message}`;\n }\n\n return stringifyUnknown(error) || 'Unknown error';\n}\n\nfunction serializeError(error: unknown) {\n const serialized: Record<string, unknown> = {\n summary: getErrorSummary(error)\n };\n\n if (error instanceof Error) {\n serialized.name = error.name;\n serialized.message = error.message;\n serialized.stack = error.stack;\n } else {\n serialized.value = stringifyUnknown(error);\n }\n\n if (error && typeof error === 'object') {\n const errorLike = error as Record<string, unknown>;\n const extraKeys = ['code', 'errno', 'syscall', 'path', 'cmd', 'status', 'signal', 'spawnargs', 'command'];\n\n extraKeys.forEach((key) => {\n if (errorLike[key] !== undefined) {\n serialized[key] = errorLike[key];\n }\n });\n\n const stdout = stringifyUnknown(errorLike.stdout);\n if (stdout) {\n serialized.stdout = stdout;\n }\n\n const stderr = stringifyUnknown(errorLike.stderr);\n if (stderr) {\n serialized.stderr = stderr;\n }\n\n const cause = stringifyUnknown(errorLike.cause);\n if (cause) {\n serialized.cause = cause;\n }\n }\n\n return serialized;\n}\n\nexport function getNextFilePath(dir: string, baseName: string, extension: string) {\n let counter = 1;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n const filePath = path.join(dir, `${baseName}-${counter}${extension}`);\n if (!fs.existsSync(filePath)) {\n return filePath;\n }\n counter++;\n }\n}\n\nexport function getAvailableFilePath(dir: string, baseName: string, extension: string) {\n const firstFilePath = path.join(dir, `${baseName}${extension}`);\n if (!fs.existsSync(firstFilePath)) {\n return firstFilePath;\n }\n\n return getNextFilePath(dir, baseName, extension);\n}\n\nexport function deleteFile(filePath: string) {\n if (fs.existsSync(filePath)) {\n fs.unlinkSync(filePath);\n }\n}\n\n/**\n * μž„μ‹œνŒŒμΌ μ‚­μ œ\n */\nexport function deleteTempDiff() {\n deleteFile(tempDiffPath);\n}\n\n/**\n * 리뷰 κ²°κ³Ό 폴더 생성\n */\nexport function createReportDirectory() {\n if (!fs.existsSync(REPORT_DIR)) {\n fs.mkdirSync(REPORT_DIR, { recursive: true });\n }\n}\n\n/**\n * ν˜„μž¬ μ‹œκ°„ λ¬Έμžμ—΄ 생성\n */\nexport function getNowString(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD}_${HH}-${mm}-${ss}`;\n}\n\nexport function getErrorLogTimestamp(now = new Date()) {\n const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);\n\n return `${YYYY}-${MM}-${DD}-${HH}μ‹œ-${mm}λΆ„-${ss}초`;\n}\n\nexport function writeErrorReport(error: unknown, options: WriteErrorReportOptions = {}) {\n try {\n const now = new Date();\n helperTrace('error-report:write:start', options.scope || 'unknown');\n createReportDirectory();\n\n const reportPath = getAvailableFilePath(REPORT_DIR, `error-log-${getErrorLogTimestamp(now)}`, '.md');\n const serializedError = serializeError(error);\n const traceSnapshot = options.traceMessages ?? getTraceMessages();\n const extraSections = options.extraSections || [];\n\n const report = `# Error Log\n\n- λ°œμƒ μ‹œκ°: ${getHumanReadableNowString(now)}\n- Scope: \\`${options.scope || 'unknown'}\\`\n- μž‘μ—… 경둜: \\`${process.cwd()}\\`\n- μ‹€ν–‰ 인자: \\`${JSON.stringify(options.args ?? process.argv.slice(2))}\\`\n- μ‹€ν–‰ ν™˜κ²½: \\`${process.platform} ${process.arch} / Node ${process.version}\\`\n\n## Summary\n\n${options.title || serializedError.summary || 'Unknown error'}\n\n## Error\n\n\\`\\`\\`json\n${JSON.stringify(serializedError, null, 2)}\n\\`\\`\\`\n\n## Trace\n\n\\`\\`\\`json\n${JSON.stringify(traceSnapshot, null, 2)}\n\\`\\`\\`${extraSections.length ? `\\n${extraSections.map((section) => `\\n## ${section.heading}\\n\\n${section.markdown}`).join('\\n')}\\n` : '\\n'}\n`;\n\n fs.writeFileSync(reportPath, report);\n helperTrace('error-report:write:done', reportPath);\n\n return reportPath;\n } catch (writeError) {\n console.error('⚠️ μ—λŸ¬ 둜그 파일 생성에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');\n console.error(writeError);\n\n return '';\n }\n}\n\nfunction getExecutionLogSummary(status: ExecutionLogStatus, title?: string) {\n if (title) {\n return title;\n }\n\n switch (status) {\n case 'success':\n return '리뷰 싀행이 μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.';\n case 'failed':\n return '리뷰 μ‹€ν–‰ 쀑 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.';\n case 'partial_failure':\n return '리뷰 싀행은 μ™„λ£Œλ˜μ—ˆμ§€λ§Œ 일뢀 λ‹¨κ³„μ—μ„œ 였λ₯˜κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.';\n default:\n return '리뷰 싀행이 μ·¨μ†Œλ˜μ—ˆκ±°λ‚˜ 리뷰 λŒ€μƒμ΄ μ—†μ–΄ μ’…λ£Œλ˜μ—ˆμŠ΅λ‹ˆλ‹€.';\n }\n}\n\nfunction formatExecutionDuration(startedAt: Date, finishedAt: Date) {\n const durationMs = Math.max(0, finishedAt.getTime() - startedAt.getTime());\n\n if (durationMs < 1000) {\n return `${durationMs}ms`;\n }\n\n const durationSeconds = durationMs / 1000;\n\n if (durationSeconds < 60) {\n return `${durationSeconds.toFixed(1)}s`;\n }\n\n const minutes = Math.floor(durationSeconds / 60);\n const seconds = Math.round(durationSeconds % 60);\n\n return `${minutes}m ${seconds}s`;\n}\n\n/**\n * @description\n * 성곡/μ‹€νŒ¨ 여뢀와 λ¬΄κ΄€ν•˜κ²Œ 리뷰 μ‹€ν–‰ 자체의 진단 둜그λ₯Ό `.review-report`에 λ‚¨κΉλ‹ˆλ‹€.\n * μ—λŸ¬ λ‘œκ·Έμ™€ λ³„λ„λ‘œ μ‹€ν–‰ λ§₯락, μƒμ„±λœ λͺ…λ Ήμ–΄, traceλ₯Ό 항상 λ³΄μ‘΄ν•˜μ—¬ μž¬ν˜„κ³Ό 원인 뢄석에 ν™œμš©ν•©λ‹ˆλ‹€.\n * @param options μ‹€ν–‰ μƒνƒœ, μ‹œμž‘/μ’…λ£Œ μ‹œκ°, μ—λŸ¬, μΆ”κ°€ μ„Ήμ…˜ λ“± μ‹€ν–‰ 둜그 μž‘μ„± μ˜΅μ…˜\n * @returns μƒμ„±λœ μ‹€ν–‰ 둜그 파일 경둜. μ‹€νŒ¨ μ‹œ 빈 λ¬Έμžμ—΄\n */\nexport function writeExecutionLog(options: WriteExecutionLogOptions = {}) {\n try {\n const startedAt = options.startedAt ?? new Date();\n const finishedAt = options.finishedAt ?? new Date();\n const status = options.status ?? 'success';\n helperTrace('execution-log:write:start', options.scope || 'unknown');\n createReportDirectory();\n\n const reportPath = getAvailableFilePath(REPORT_DIR, `${getNowString(finishedAt)}-execution-log`, '.md');\n const traceSnapshot = options.traceMessages ?? getTraceMessages();\n const extraSections = options.extraSections || [];\n const serializedError = options.error ? serializeError(options.error) : null;\n\n const report = `# Execution Log\n\n- μ‹œμž‘ μ‹œκ°: ${getHumanReadableNowString(startedAt)}\n- μ’…λ£Œ μ‹œκ°: ${getHumanReadableNowString(finishedAt)}\n- μ‹€ν–‰ μ‹œκ°„: ${formatExecutionDuration(startedAt, finishedAt)}\n- μƒνƒœ: \\`${status}\\`\n- Scope: \\`${options.scope || 'unknown'}\\`\n- μž‘μ—… 경둜: \\`${process.cwd()}\\`\n- μ‹€ν–‰ 인자: \\`${JSON.stringify(options.args ?? process.argv.slice(2))}\\`\n- μ‹€ν–‰ ν™˜κ²½: \\`${process.platform} ${process.arch} / Node ${process.version}\\`\n\n## Summary\n\n${getExecutionLogSummary(status, options.title)}\n${serializedError ? `\\n\\n## Error\\n\\n\\`\\`\\`json\\n${JSON.stringify(serializedError, null, 2)}\\n\\`\\`\\`` : ''}\n\n## Trace\n\n\\`\\`\\`json\n${JSON.stringify(traceSnapshot, null, 2)}\n\\`\\`\\`${extraSections.length ? `\\n${extraSections.map((section) => `\\n## ${section.heading}\\n\\n${section.markdown}`).join('\\n')}\\n` : '\\n'}\n`;\n\n fs.writeFileSync(reportPath, report);\n helperTrace('execution-log:write:done', reportPath);\n\n return reportPath;\n } catch (writeError) {\n console.error('⚠️ μ‹€ν–‰ 둜그 파일 생성에 μ‹€νŒ¨ν–ˆμŠ΅λ‹ˆλ‹€.');\n console.error(writeError);\n\n return '';\n }\n}\n\nexport function exitWithError(\n message: string,\n options: Omit<WriteErrorReportOptions, 'title'> & { error?: unknown } = {}\n): never {\n const reportPath = writeErrorReport(options.error || new Error(message), {\n ...options,\n title: message\n });\n\n console.error(message);\n\n if (options.error) {\n console.error(options.error);\n }\n\n if (reportPath) {\n console.error(`πŸ“„ μ—λŸ¬ 둜그 μ €μž₯ μœ„μΉ˜: ${reportPath}`);\n }\n\n process.exit(1);\n}\n\nfunction parseServiceFromArgs(args: string[] = process.argv.slice(2)): AIServiceType | '' {\n helperTrace('parse-service:start', `args=${JSON.stringify(args)}`);\n const serviceIndex = args.indexOf('--service');\n const rawService = serviceIndex !== -1 ? args[serviceIndex + 1] : '';\n\n if (!rawService) {\n helperTrace('parse-service:empty');\n\n return '';\n }\n\n const normalizedService = rawService.toLowerCase();\n\n if (AIServices.includes(normalizedService as AIServiceType)) {\n helperTrace('parse-service:resolved', normalizedService);\n\n return normalizedService as AIServiceType;\n }\n\n helperTrace('parse-service:invalid', rawService);\n exitWithError(\n `❌ μ§€μ›ν•˜μ§€ μ•ŠλŠ” μ„œλΉ„μŠ€μž…λ‹ˆλ‹€: ${rawService}. μ‚¬μš© κ°€λŠ₯ κ°’: ${AIServices.join(', ')} (예: --service codex)`,\n {\n scope: 'helper:parseServiceFromArgs',\n args,\n extraSections: [\n {\n heading: 'Allowed Services',\n markdown: `\\`\\`\\`json\\n${JSON.stringify(AIServices, null, 2)}\\n\\`\\`\\``\n }\n ]\n }\n );\n}\n\nexport function getGitDiffFilter() {\n const { includePatterns, excludePatterns } = getGitDiffPathspecs();\n const quote = (pattern: string) => `\"${pattern}\"`;\n const includeParams = includePatterns.map(quote).join(' ');\n const excludeParams = excludePatterns.map(quote).join(' ');\n\n return { includeParams, excludeParams };\n}\n\n/**\n * @description\n * 컀밋 선택 λͺ©λ‘μ—μ„œ subjectκ°€ κ³Όν•˜κ²Œ κΈΈμ–΄μ§€λŠ” 것을 막기 μœ„ν•΄ ν‘œμ‹œ 길이λ₯Ό μ œν•œν•©λ‹ˆλ‹€.\n * commit hash와 λ©”νƒ€λ°μ΄ν„°λŠ” 별도 ν•„λ“œλ‘œ μœ μ§€ν•˜λ―€λ‘œ UI 가독성에 ν•„μš”ν•œ subject만 μžλ¦…λ‹ˆλ‹€.\n * @param subject 원본 컀밋 제λͺ©\n * @returns ν™”λ©΄ ν‘œμ‹œμš© 제λͺ©\n */\nfunction truncateCommitSubject(subject: string) {\n if (subject.length <= 72) {\n return subject;\n }\n\n return `${subject.slice(0, 69)}...`;\n}\n\nfunction formatReviewTargetFileCount(fileCount: number) {\n return fileCount === 0 ? 'λ³€κ²½ μ—†μŒ' : `${fileCount}개 파일`;\n}\n\nfunction buildReviewTargetSectionTitle(target: CommitOption) {\n return target.kind === 'commit' ? `${target.hash} ${target.subject}` : `${target.hash} | ${target.subject}`;\n}\n\nfunction buildReviewTargetSummaryLine(target: CommitOption) {\n if (target.kind === 'commit') {\n return `- ${target.hash} | ${target.subject} | ${target.author} | ${target.relativeDate}`;\n }\n\n return `- ${target.hash} | ${target.subject}`;\n}\n\nfunction buildReviewTargetDiffArgs(target: CommitOption, filePath?: string) {\n const reviewPathspecArgs = getReviewPathspecArgs();\n\n if (target.kind === 'commit') {\n return filePath\n ? ['show', '--stat', '--patch', '--format=', target.hash, '--', filePath]\n : ['show', '--stat', '--patch', '--format=', target.hash, '--', ...reviewPathspecArgs];\n }\n\n const diffArgs = ['diff'];\n\n if (target.kind === 'staged') {\n diffArgs.push('--cached');\n }\n\n diffArgs.push('--stat', '--patch', '--');\n\n return filePath ? [...diffArgs, filePath] : [...diffArgs, ...reviewPathspecArgs];\n}\n\nfunction buildReviewTargetFileArgs(target: CommitOption) {\n const reviewPathspecArgs = getReviewPathspecArgs();\n\n if (target.kind === 'commit') {\n return ['show', '--pretty=format:', '--name-only', target.hash, '--', ...reviewPathspecArgs];\n }\n\n const diffArgs = ['diff'];\n\n if (target.kind === 'staged') {\n diffArgs.push('--cached');\n }\n\n return [...diffArgs, '--name-only', '--', ...reviewPathspecArgs];\n}\n\nfunction getReviewTargetFiles(target: CommitOption) {\n const output = runGitCommand(buildReviewTargetFileArgs(target), {\n allowFailure: true\n });\n\n return output\n .split('\\n')\n .map((line) => line.trim())\n .filter(Boolean);\n}\n\nfunction createWorkingTreeReviewOption(kind: Extract<ReviewTargetKind, 'staged' | 'unstaged'>): CommitOption {\n const files = getReviewTargetFiles({\n author: '',\n description: '',\n hash: kind,\n kind,\n label: kind,\n relativeDate: '',\n subject: ''\n });\n const subject = kind === 'unstaged' ? '아직 git add ν•˜μ§€ μ•Šμ€ 변경사항' : 'git add 된 변경사항';\n\n return {\n author: '',\n description: `${subject} | ${formatReviewTargetFileCount(files.length)}`,\n hash: kind,\n kind,\n label: kind,\n relativeDate: '',\n subject\n };\n}\n\n/**\n * @description\n * 졜근 컀밋 λͺ©λ‘μ„ 리뷰 선택 UIμ—μ„œ λ°”λ‘œ μ‚¬μš©ν•  수 μžˆλŠ” ꡬ쑰둜 λ³€ν™˜ν•©λ‹ˆλ‹€.\n * git log 포맷을 ν•œ κ³³μ—μ„œ 관리해 main review와 one-by-one reviewκ°€ 같은 컀밋 메타데이터λ₯Ό κ³΅μœ ν•˜κ²Œ ν•©λ‹ˆλ‹€.\n * @returns 졜근 컀밋 μ˜΅μ…˜ λͺ©λ‘\n */\nexport function getRecentCommitOptions(): CommitOption[] {\n const output = runGitCommand(\n ['log', `-${COMMIT_FETCH_LIMIT}`, '--date=relative', '--pretty=format:%h%x09%an%x09%ar%x09%s'],\n { allowFailure: true }\n );\n\n if (!output) {\n return [];\n }\n\n return output.split('\\n').map((line) => {\n const [hash = '', author = '', relativeDate = '', ...subjectParts] = line.split('\\t');\n const subject = subjectParts.join('\\t').trim();\n\n return {\n author,\n description: `${author} | ${relativeDate}`,\n hash,\n kind: 'commit',\n label: `${hash} | ${truncateCommitSubject(subject)}`,\n relativeDate,\n subject\n };\n });\n}\n\nfunction getReviewTargetOptions() {\n return [createWorkingTreeReviewOption('unstaged'), createWorkingTreeReviewOption('staged'), ...getRecentCommitOptions()];\n}\n\n/**\n * @description\n * μ„ νƒλœ 컀밋 λͺ©λ‘μ„ 리포트 및 diff 헀더에 μž¬μ‚¬μš©ν•  수 μžˆλŠ” markdown bullet λ¬Έμžμ—΄λ‘œ μ •λ¦¬ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 컀밋 μš”μ•½ markdown\n */\nexport function buildSelectedCommitSummary(commits: CommitOption[]) {\n return commits.map((commit) => buildReviewTargetSummaryLine(commit)).join('\\n');\n}\n\n/**\n * @description\n * 리뷰 λŒ€μƒ pathspec 배열을 git argv에 λ°”λ‘œ 뢙일 수 있게 ν‰νƒ„ν™”ν•©λ‹ˆλ‹€.\n * λ¬Έμžμ—΄ μ»€λ§¨λ“œμ™€ λ‹€λ₯Έ 경둜 기반 helper도 같은 ν•„ν„°λ₯Ό κ³΅μœ ν•˜λ„λ‘ helper ν•¨μˆ˜λ‘œ λΆ„λ¦¬ν•©λ‹ˆλ‹€.\n * @returns include/exclude pathspec λ°°μ—΄\n */\nfunction getReviewPathspecArgs() {\n const { includePatterns, excludePatterns } = getGitDiffPathspecs();\n\n return [...includePatterns, ...excludePatterns];\n}\n\n/**\n * @description\n * μ„ νƒλœ μ—¬λŸ¬ μ»€λ°‹μ˜ 전체 diffλ₯Ό ν•œ νŒŒμΌμ— ν•©μΉ©λ‹ˆλ‹€.\n * 각 컀밋을 별도 μ„Ήμ…˜μœΌλ‘œ 감싸 AIκ°€ 컀밋 경계λ₯Ό μžƒμ§€ μ•Šλ„λ‘ ν•˜λ©°, κΈ°μ‘΄ 리뷰 λŒ€μƒ ν™•μž₯자 필터도 κ·ΈλŒ€λ‘œ μ μš©ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 리뷰용 톡합 diff ν…μŠ€νŠΈ\n */\nexport function buildSelectedCommitDiff(commits: CommitOption[]) {\n const sections = commits\n .map((commit) => {\n const diff = runGitCommand(buildReviewTargetDiffArgs(commit), {\n allowFailure: true,\n trimOutput: false\n }).trim();\n\n if (!diff) {\n return '';\n }\n\n return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join('\\n\\n');\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n if (!sections) {\n return '';\n }\n\n return ['# μ„ νƒν•œ 리뷰 λŒ€μƒ', buildSelectedCommitSummary(commits), '', '# 리뷰 λŒ€μƒ diff', sections].join('\\n');\n}\n\n/**\n * @description\n * μ„ νƒλœ μ»€λ°‹μ—μ„œ μ‹€μ œ 리뷰 λŒ€μƒ 파일 λͺ©λ‘λ§Œ μΆ”μΆœν•©λ‹ˆλ‹€.\n * one-by-one 리뷰가 ν˜„μž¬ μ„ νƒλœ 컀밋 μ§‘ν•©μ—λ§Œ λ°˜μ‘ν•˜λ„λ‘ commit별 name-only κ²°κ³Όλ₯Ό ν•©μ§‘ν•©μœΌλ‘œ κ³„μ‚°ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @returns 쀑볡 제거된 파일 λͺ©λ‘\n */\nexport function getSelectedCommitFiles(commits: CommitOption[]) {\n const files = new Set<string>();\n\n commits.forEach((commit) => {\n getReviewTargetFiles(commit).forEach((filePath) => files.add(filePath));\n });\n\n return [...files];\n}\n\n/**\n * @description\n * νŠΉμ • νŒŒμΌμ— λŒ€ν•œ 선택 μ»€λ°‹λ“€μ˜ diff만 λͺ¨μ•„μ„œ one-by-one 리뷰 μž…λ ₯으둜 λ§Œλ“­λ‹ˆλ‹€.\n * 동일 파일이 μ—¬λŸ¬ μ»€λ°‹μ—μ„œ 바뀐 경우 commit section을 λ‚˜λˆ  λ³΄μ—¬μ€˜ 파일 리뷰 응닡이 μ–΄λŠ 변경을 λ‹€λ£¨λŠ”μ§€ 좔적 κ°€λŠ₯ν•˜κ²Œ ν•©λ‹ˆλ‹€.\n * @param commits μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n * @param filePath 리뷰할 파일 경둜\n * @returns 단일 파일 리뷰용 diff ν…μŠ€νŠΈ\n */\nexport function buildSelectedFileDiff(commits: CommitOption[], filePath: string) {\n const sections = commits\n .map((commit) => {\n const diff = runGitCommand(buildReviewTargetDiffArgs(commit, filePath), {\n allowFailure: true,\n trimOutput: false\n }).trim();\n\n if (!diff) {\n return '';\n }\n\n return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join('\\n\\n');\n })\n .filter(Boolean)\n .join('\\n\\n');\n\n if (!sections) {\n return '';\n }\n\n return ['# μ„ νƒν•œ 리뷰 λŒ€μƒ', buildSelectedCommitSummary(commits), '', `# 파일: ${filePath}`, sections].join('\\n\\n');\n}\n\n/**\n * openReportλ₯Ό OSλ³„λ‘œ λ™μž‘ν•˜λ„λ‘ λ³€κ²½\n * μš°μ„ μˆœμœ„:\n * 1. Chrome μ‹œλ„\n * - macOS: open -a \"Google Chrome\" \"<path>\"\n * - Ubuntu/Linux: google-chrome \"<path>\"\n * 2. μ‹€νŒ¨ μ‹œ κΈ°λ³Έ λΈŒλΌμš°μ €λ‘œ 폴백\n * - macOS: open \"<path>\"\n * - Ubuntu/Linux: xdg-open \"<path>\"\n * 3. λ‘˜ λ‹€ μ‹€νŒ¨ν•˜λ©΄ μ—λŸ¬ 좜λ ₯\n * 4. 미지원 ν”Œλž«νΌμ΄λ©΄ ν”Œλž«νΌ κ²½κ³  좜λ ₯\n */\nexport function openReport(reportPath: string) {\n const resolvedPath = path.resolve(reportPath);\n const { platform } = process;\n helperTrace('open-report:start', resolvedPath);\n\n const openWithChrome = () => {\n if (platform === 'darwin') {\n execSync(`open -a \"Google Chrome\" \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n if (platform === 'linux') {\n execSync(`google-chrome \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n return false;\n };\n\n const openWithDefaultBrowser = () => {\n if (platform === 'darwin') {\n execSync(`open \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n if (platform === 'linux') {\n execSync(`xdg-open \"${resolvedPath}\"`, { stdio: 'ignore' });\n\n return true;\n }\n\n return false;\n };\n\n try {\n if (openWithChrome()) {\n helperTrace('open-report:chrome:success', platform);\n console.log('πŸš€ Google Chromeμ—μ„œ 리포트λ₯Ό μ—΄μ—ˆμŠ΅λ‹ˆλ‹€.');\n\n return;\n }\n } catch (error) {\n helperTrace('open-report:chrome:failed', getErrorSummary(error));\n // Chrome μ‹€ν–‰ μ‹€νŒ¨ μ‹œ κΈ°λ³Έ λΈŒλΌμš°μ €λ‘œ 폴백\n }\n\n try {\n if (openWithDefaultBrowser()) {\n helperTrace('open-report:default-browser:success', platform);\n console.log('πŸš€ κΈ°λ³Έ λΈŒλΌμš°μ €μ—μ„œ 리포트λ₯Ό μ—΄μ—ˆμŠ΅λ‹ˆλ‹€.');\n\n return;\n }\n } catch (error) {\n helperTrace('open-report:default-browser:failed', getErrorSummary(error));\n console.error('⚠️ λΈŒλΌμš°μ € μ—΄κΈ° μ‹€νŒ¨:', error);\n\n return;\n }\n\n helperTrace('open-report:unsupported-platform', platform);\n console.error(`⚠️ μ§€μ›ν•˜μ§€ μ•ŠλŠ” ν”Œλž«νΌμž…λ‹ˆλ‹€: ${platform}`);\n}\n\n/**\n * @description\n * raw mode 기반 선택 UIλ₯Ό μ•ˆμ „ν•˜κ²Œ μ—΄ 수 μžˆλŠ” TTY ν™˜κ²½μΈμ§€ κ²€μ¦ν•©λ‹ˆλ‹€.\n * CIλ‚˜ pipe ν™˜κ²½μ—μ„œλŠ” μ»€μ„œλ₯Ό μ œμ–΄ν•  수 μ—†μœΌλ―€λ‘œ μ¦‰μ‹œ μ—λŸ¬ 리포트λ₯Ό 남기고 μ’…λ£Œν•©λ‹ˆλ‹€.\n * @param scope μ—λŸ¬ 리포트 κ΅¬λΆ„μš© scope\n * @param message μ‚¬μš©μžμ—κ²Œ 보여쀄 μ—λŸ¬ λ©”μ‹œμ§€\n */\nfunction ensureInteractiveSelectionAvailable(scope: string, message: string) {\n if (process.stdin.isTTY && process.stdout.isTTY && typeof process.stdin.setRawMode === 'function') {\n return;\n }\n\n helperTrace(`${scope}:tty-missing`);\n exitWithError(message, {\n scope: `helper:${scope}`\n });\n}\n\n/**\n * @description\n * 선택 λͺ¨λ‹¬μ„ ν˜„μž¬ μœ„μΉ˜μ—μ„œ λ‹€μ‹œ κ·Έλ¦½λ‹ˆλ‹€.\n * 각 쀄은 미리 터미널 폭 μ•ˆμœΌλ‘œ 잘라 physical line이 1μ€„λ‘œ μœ μ§€λ˜λ―€λ‘œ,\n * 직전 λ Œλ” 쀄 수만큼 μœ„λ‘œ μ΄λ™ν•œ λ’€ clearScreenDown 해도 쀑볡 없이 μ•ˆμ •μ μœΌλ‘œ κ°±μ‹ λ©λ‹ˆλ‹€.\n * @param lines μƒˆλ‘œ λ Œλ”ν•  λ¬Έμžμ—΄ 쀄 λͺ©λ‘\n * @param previousLineCount 직전 λ Œλ” 쀄 수\n * @returns ν˜„μž¬ λ Œλ” 쀄 수\n */\nfunction renderSelectionBlock(lines: string[], previousLineCount: number) {\n if (previousLineCount > 0) {\n readline.moveCursor(process.stdout, 0, -previousLineCount);\n readline.clearScreenDown(process.stdout);\n }\n\n const fittedLines = fitLinesToTerminal(lines);\n process.stdout.write(`${fittedLines.join('\\n')}\\n`);\n\n return fittedLines.length;\n}\n\n/**\n * @description\n * ν˜„μž¬ μ»€μ„œ κΈ°μ€€ visible windowλ₯Ό 계산해 κΈ΄ 컀밋 λͺ©λ‘λ„ κ³ μ • λ†’μ΄λ‘œ 탐색할 수 있게 λ§Œλ“­λ‹ˆλ‹€.\n * @param optionCount 전체 μ˜΅μ…˜ 개수\n * @param selectedIndex ν˜„μž¬ 포컀슀 인덱슀\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns μ‹œμž‘/끝 인덱슀\n */\nfunction getSelectionWindowRange(optionCount: number, selectedIndex: number, windowSize: number) {\n if (optionCount <= windowSize) {\n return {\n end: optionCount,\n start: 0\n };\n }\n\n const halfWindow = Math.floor(windowSize / 2);\n const maxStart = optionCount - windowSize;\n const start = Math.max(0, Math.min(selectedIndex - halfWindow, maxStart));\n\n return {\n end: Math.min(optionCount, start + windowSize),\n start\n };\n}\n\n/**\n * @description\n * 곡톡 multi-select UI λ Œλ”λ§μ— ν•„μš”ν•œ λ¬Έμžμ—΄ λͺ©λ‘μ„ κ΅¬μ„±ν•©λ‹ˆλ‹€.\n * μ„€λͺ… ν…μŠ€νŠΈλŠ” dim μ²˜λ¦¬ν•΄ subject와 author/dateκ°€ ν•œ μ€„μ—μ„œ κ΅¬λΆ„λ˜λ„λ‘ ν•©λ‹ˆλ‹€.\n * @param question 질문 헀더\n * @param options ν‘œμ‹œν•  μ˜΅μ…˜ λͺ©λ‘\n * @param selectedIndex ν˜„μž¬ 포컀슀 인덱슀\n * @param toggled μ„ νƒλœ 인덱슀 Set\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns 좜λ ₯ 쀄 λͺ©λ‘\n */\nfunction buildMultiSelectLines<T>(\n question: string,\n options: MultiSelectOption<T>[],\n selectedIndex: number,\n toggled: Set<number>,\n windowSize: number\n) {\n const { start, end } = getSelectionWindowRange(options.length, selectedIndex, windowSize);\n const lines = [\n `${ANSI.bold}${question}${ANSI.reset}`,\n `${ANSI.dim}↑↓ 이동 | Space 선택/ν•΄μ œ | Enter μ™„λ£Œ | Esc μ·¨μ†Œ${ANSI.reset}`,\n `${ANSI.dim}선택됨: ${toggled.size}개 / 전체: ${options.length}개${ANSI.reset}`\n ];\n\n for (let index = start; index < end; index += 1) {\n const option = options[index];\n\n if (!option) {\n continue;\n }\n\n const cursor = index === selectedIndex ? `${ANSI.cyan}>${ANSI.reset}` : ' ';\n const checked = toggled.has(index) ? `${ANSI.green}β˜‘${ANSI.reset}` : '☐';\n const description = option.description ? ` ${ANSI.dim}${option.description}${ANSI.reset}` : '';\n lines.push(`${cursor} ${checked} ${option.label}${description}`);\n }\n\n if (options.length > windowSize) {\n lines.push(`${ANSI.dim}ν‘œμ‹œ λ²”μœ„: ${start + 1}-${end} / ${options.length}${ANSI.reset}`);\n }\n\n return lines;\n}\n\n/**\n * @description\n * 컀밋 μ„ νƒμ²˜λŸΌ 볡수 선택이 ν•„μš”ν•œ 터미널 λͺ¨λ‹¬μ„ κ³΅ν†΅μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.\n * raw modeλ₯Ό 직접 μ œμ–΄ν•΄ λ°©ν–₯ν‚€, Space, Enter, Escλ₯Ό 읽고 μ„ νƒλœ value λͺ©λ‘λ§Œ λ°˜ν™˜ν•©λ‹ˆλ‹€.\n * @param question μ‚¬μš©μž μ•ˆλ‚΄ 문ꡬ\n * @param options 선택 μ˜΅μ…˜ λͺ©λ‘\n * @param windowSize λ™μ‹œμ— 보여쀄 μ΅œλŒ€ μ˜΅μ…˜ 개수\n * @returns μ‚¬μš©μžκ°€ ν™•μ •ν•œ 선택 κ°’ λ°°μ—΄\n */\nexport async function showMultiSelect<T>(question: string, options: MultiSelectOption<T>[], windowSize = COMMIT_SELECTION_WINDOW) {\n ensureInteractiveSelectionAvailable('showMultiSelect', '❌ 컀밋 선택 λͺ¨λ‹¬μ€ TTY ν™˜κ²½μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.');\n let selectedIndex = 0;\n let renderedLineCount = 0;\n const toggled = new Set<number>();\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true\n });\n\n process.stdout.write('\\u001b[?25l');\n\n const cleanup = () => {\n if (renderedLineCount > 0) {\n readline.moveCursor(process.stdout, 0, -renderedLineCount);\n readline.clearScreenDown(process.stdout);\n renderedLineCount = 0;\n }\n process.stdin.removeListener('data', onData);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n rl.close();\n process.stdout.write('\\u001b[?25h');\n };\n\n const render = () => {\n const lines = buildMultiSelectLines(question, options, selectedIndex, toggled, windowSize);\n renderedLineCount = renderSelectionBlock(lines, renderedLineCount);\n };\n\n const confirmSelection = (resolve: (value: T[]) => void) => {\n const values = [...toggled]\n .sort((left, right) => left - right)\n .map((index) => options[index]?.value)\n .filter((value): value is T => value !== undefined);\n\n cleanup();\n resolve(values);\n };\n\n const cancelSelection = (resolve: (value: T[]) => void) => {\n cleanup();\n resolve([]);\n };\n\n let onData = (_data: Buffer) => {\n // μ‹€μ œ κ΅¬ν˜„μ€ Promise 생성 μ‹œμ μ— λ°”μΈλ”©ν•©λ‹ˆλ‹€.\n };\n\n render();\n\n return new Promise<T[]>((resolve) => {\n onData = (data: Buffer) => {\n const key = data.toString();\n\n if (key === '\\u0003') {\n cleanup();\n process.exit(0);\n }\n\n if (key === '\\u001b') {\n cancelSelection(resolve);\n\n return;\n }\n\n if (key === '\\x1b[A') {\n selectedIndex = (selectedIndex - 1 + options.length) % options.length;\n render();\n\n return;\n }\n\n if (key === '\\x1b[B') {\n selectedIndex = (selectedIndex + 1) % options.length;\n render();\n\n return;\n }\n\n if (key === ' ') {\n if (toggled.has(selectedIndex)) {\n toggled.delete(selectedIndex);\n } else {\n toggled.add(selectedIndex);\n }\n render();\n\n return;\n }\n\n if (key === '\\r' || key === '\\n') {\n confirmSelection(resolve);\n }\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', onData);\n });\n}\n\n/**\n * @description\n * 졜근 컀밋 λͺ©λ‘μ„ modal UI둜 선택받아 review μ—”νŠΈλ¦¬ν¬μΈνŠΈμ—μ„œ λ°”λ‘œ μž¬μ‚¬μš©ν•  수 있게 λ°˜ν™˜ν•©λ‹ˆλ‹€.\n * @returns μ‚¬μš©μžκ°€ κ³ λ₯Έ 컀밋 λͺ©λ‘\n */\nexport async function selectReviewCommits() {\n const commits = getReviewTargetOptions();\n\n if (commits.length === 0) {\n console.log('ℹ️ 리뷰할 λŒ€μƒμ΄ μ—†μŠ΅λ‹ˆλ‹€.');\n\n return [];\n }\n\n return showMultiSelect<CommitOption>(\n '리뷰할 λŒ€μƒμ„ μ„ νƒν•΄μ£Όμ„Έμš”.',\n commits.map((commit) => ({\n description: commit.description,\n label: commit.label,\n value: commit\n })),\n COMMIT_SELECTION_WINDOW\n );\n}\n\n/**\n * AI μ„œλΉ„μŠ€ 선택\n */\nexport function selectAIService() {\n const service = parseServiceFromArgs();\n\n if (!service) {\n helperTrace('select-service:missing');\n exitWithError('❌ μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.', {\n scope: 'helper:selectAIService'\n });\n }\n\n helperTrace('select-service:done', service);\n\n return service;\n}\n\n/**\n * ν„°λ―Έλ„μ—μ„œ λΌλ””μ˜€ λ²„νŠΌ ν˜•νƒœλ‘œ AI μ„œλΉ„μŠ€λ₯Ό μ„ νƒν•©λ‹ˆλ‹€.\n */\nexport async function showSelectionAIService(): Promise<AIServiceType> {\n const selectedServiceFromArgs = parseServiceFromArgs();\n\n if (selectedServiceFromArgs) {\n helperTrace('show-selection:from-args', selectedServiceFromArgs);\n console.log(`\\nβœ… ${ANSI.green}${selectedServiceFromArgs}${ANSI.reset} μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€. (--service)\\n`);\n\n return selectedServiceFromArgs;\n }\n\n ensureInteractiveSelectionAvailable('showSelectionAIService', '❌ AI μ„œλΉ„μŠ€ 선택 UIλŠ” TTY ν™˜κ²½μ—μ„œλ§Œ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.');\n helperTrace('show-selection:interactive:start');\n let selectedIndex = 0;\n\n // Use readline to handle keypresses\n // ν‚€ μž…λ ₯을 μ²˜λ¦¬ν•˜κΈ° μœ„ν•΄ readline μΈν„°νŽ˜μ΄μŠ€ μ‚¬μš©\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stdout,\n terminal: true\n });\n\n let firstRender = true;\n\n // Hide cursor\n process.stdout.write('\\u001b[?25l');\n\n const render = () => {\n if (!firstRender) {\n // Move cursor back to the starting line of the selection UI\n // We print (1 question line + services.length lines)\n // 선택 UI의 μ‹œμž‘ 라인으둜 μ»€μ„œ 이동 (질문 1쀄 + μ„œλΉ„μŠ€ λͺ©λ‘ N쀄)\n readline.moveCursor(process.stdout, 0, -(AIServices.length + 1));\n }\n firstRender = false;\n helperTrace('show-selection:interactive:render', AIServices[selectedIndex] || 'unknown');\n\n // Clear everything from cursor down to avoid ghosting/overlaps\n // μž”μƒμ΄λ‚˜ 겹침을 λ°©μ§€ν•˜κΈ° μœ„ν•΄ μ»€μ„œ μœ„μΉ˜λΆ€ν„° μ•„λž˜μͺ½ λͺ¨λ‘ 지움\n readline.clearScreenDown(process.stdout);\n\n process.stdout.write(\n `πŸ€– AI μ„œλΉ„μŠ€λ₯Ό μ„ νƒν•΄μ£Όμ„Έμš” (${ANSI.yellow}↑↓ λ°©ν–₯ν‚€${ANSI.reset} 이동, ${ANSI.yellow}Enter${ANSI.reset} 선택):\\n`\n );\n AIServices.forEach((service, index) => {\n if (index === selectedIndex) {\n process.stdout.write(` ${ANSI.cyan}>${ANSI.reset} ${ANSI.cyan}β—‰${ANSI.reset} ${ANSI.bold}${service}${ANSI.reset}\\n`);\n } else {\n process.stdout.write(` β—― ${service}\\n`);\n }\n });\n };\n\n render();\n\n return new Promise((resolve) => {\n const onData = (data: Buffer) => {\n const key = data.toString();\n if (key === '\\u0003') {\n // Ctrl+C\n helperTrace('show-selection:interactive:ctrl-c');\n process.stdout.write('\\u001b[?25h'); // Show cursor\n process.exit(0);\n }\n if (key === '\\x1b[A') {\n // Up arrow\n selectedIndex = (selectedIndex - 1 + AIServices.length) % AIServices.length;\n render();\n } else if (key === '\\x1b[B') {\n // Down arrow\n selectedIndex = (selectedIndex + 1) % AIServices.length;\n render();\n } else if (key === '\\r' || key === '\\n') {\n // Enter\n process.stdin.removeListener('data', onData);\n process.stdin.setRawMode(false);\n process.stdin.pause();\n rl.close();\n\n // Show cursor\n process.stdout.write('\\u001b[?25h');\n\n console.log(`\\nβœ… ${ANSI.green}${AIServices[selectedIndex]}${ANSI.reset} μ„œλΉ„μŠ€κ°€ μ„ νƒλ˜μ—ˆμŠ΅λ‹ˆλ‹€.\\n`);\n const result = AIServices[selectedIndex];\n if (result) {\n helperTrace('show-selection:interactive:confirmed', result);\n resolve(result);\n }\n }\n };\n\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', onData);\n });\n}\n"]}
@@ -11,6 +11,18 @@ type WriteErrorReportOptions = {
11
11
  traceMessages?: string[];
12
12
  extraSections?: ErrorReportSection[];
13
13
  };
14
+ type ExecutionLogStatus = 'cancelled' | 'failed' | 'partial_failure' | 'success';
15
+ type WriteExecutionLogOptions = {
16
+ title?: string;
17
+ scope?: string;
18
+ status?: ExecutionLogStatus;
19
+ args?: string[];
20
+ startedAt?: Date;
21
+ finishedAt?: Date;
22
+ traceMessages?: string[];
23
+ extraSections?: ErrorReportSection[];
24
+ error?: unknown;
25
+ };
14
26
  type ShellCommandProgressOptions = {
15
27
  progressIntervalMs?: number;
16
28
  progressMessage?: string;
@@ -28,6 +40,15 @@ declare const COMMIT_FETCH_LIMIT = 20;
28
40
  declare const COMMIT_SELECTION_WINDOW = 8;
29
41
  declare const ignoreList: string[];
30
42
  declare function isTestMode(args?: string[]): boolean;
43
+ /**
44
+ * @description
45
+ * AI CLI의 쀑간 stdout/stderrλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ 터미널에 λ…ΈμΆœν• μ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•©λ‹ˆλ‹€.
46
+ * κΈ°λ³Έ 싀행은 μ‘°μš©ν•œ λͺ¨λ“œλ‘œ μœ μ§€ν•˜κ³ , μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ ν”Œλž˜κ·Έλ₯Ό 쀄 λ•Œλ§Œ
47
+ * AI 응닡을 κ·ΈλŒ€λ‘œ μŠ€νŠΈλ¦¬λ°ν•©λ‹ˆλ‹€.
48
+ * @param args ν˜„μž¬ μ‹€ν–‰ 인자 λͺ©λ‘
49
+ * @returns μ‹€μ‹œκ°„ AI 좜λ ₯ λ…ΈμΆœ μ—¬λΆ€
50
+ */
51
+ declare function shouldStreamAIOutput(args?: string[]): boolean;
31
52
  declare function clearTraceMessages(): void;
32
53
  declare function getTraceMessages(): string[];
33
54
  /**
@@ -70,6 +91,14 @@ declare function createReportDirectory(): void;
70
91
  declare function getNowString(now?: Date): string;
71
92
  declare function getErrorLogTimestamp(now?: Date): string;
72
93
  declare function writeErrorReport(error: unknown, options?: WriteErrorReportOptions): string;
94
+ /**
95
+ * @description
96
+ * 성곡/μ‹€νŒ¨ 여뢀와 λ¬΄κ΄€ν•˜κ²Œ 리뷰 μ‹€ν–‰ 자체의 진단 둜그λ₯Ό `.review-report`에 λ‚¨κΉλ‹ˆλ‹€.
97
+ * μ—λŸ¬ λ‘œκ·Έμ™€ λ³„λ„λ‘œ μ‹€ν–‰ λ§₯락, μƒμ„±λœ λͺ…λ Ήμ–΄, traceλ₯Ό 항상 λ³΄μ‘΄ν•˜μ—¬ μž¬ν˜„κ³Ό 원인 뢄석에 ν™œμš©ν•©λ‹ˆλ‹€.
98
+ * @param options μ‹€ν–‰ μƒνƒœ, μ‹œμž‘/μ’…λ£Œ μ‹œκ°, μ—λŸ¬, μΆ”κ°€ μ„Ήμ…˜ λ“± μ‹€ν–‰ 둜그 μž‘μ„± μ˜΅μ…˜
99
+ * @returns μƒμ„±λœ μ‹€ν–‰ 둜그 파일 경둜. μ‹€νŒ¨ μ‹œ 빈 λ¬Έμžμ—΄
100
+ */
101
+ declare function writeExecutionLog(options?: WriteExecutionLogOptions): string;
73
102
  declare function exitWithError(message: string, options?: Omit<WriteErrorReportOptions, 'title'> & {
74
103
  error?: unknown;
75
104
  }): never;
@@ -154,4 +183,4 @@ declare function selectAIService(): AIServiceType;
154
183
  */
155
184
  declare function showSelectionAIService(): Promise<AIServiceType>;
156
185
 
157
- export { AIServices, COMMIT_FETCH_LIMIT, COMMIT_SELECTION_WINDOW, REPORT_DIR, buildSelectedCommitDiff, buildSelectedCommitSummary, buildSelectedFileDiff, clearTraceMessages, codingConventionRulesPath, createReportDirectory, createTraceLogger, deleteFile, deleteTempDiff, executeShellCommandWithProgress, exitWithError, formatReviewTargetFiles, getAvailableFilePath, getErrorLogTimestamp, getErrorSummary, getGitDiffFilter, getNextFilePath, getNowString, getRecentCommitOptions, getSelectedCommitFiles, getTraceMessages, ignoreList, isTestMode, namingRulesPath, openReport, reviewFormOneByOnePath, reviewFormPath, rulesPath, selectAIService, selectReviewCommits, showMultiSelect, showSelectionAIService, tempDiffPath, writeErrorReport };
186
+ export { AIServices, COMMIT_FETCH_LIMIT, COMMIT_SELECTION_WINDOW, REPORT_DIR, buildSelectedCommitDiff, buildSelectedCommitSummary, buildSelectedFileDiff, clearTraceMessages, codingConventionRulesPath, createReportDirectory, createTraceLogger, deleteFile, deleteTempDiff, executeShellCommandWithProgress, exitWithError, formatReviewTargetFiles, getAvailableFilePath, getErrorLogTimestamp, getErrorSummary, getGitDiffFilter, getNextFilePath, getNowString, getRecentCommitOptions, getSelectedCommitFiles, getTraceMessages, ignoreList, isTestMode, namingRulesPath, openReport, reviewFormOneByOnePath, reviewFormPath, rulesPath, selectAIService, selectReviewCommits, shouldStreamAIOutput, showMultiSelect, showSelectionAIService, tempDiffPath, writeErrorReport, writeExecutionLog };
@@ -11,6 +11,18 @@ type WriteErrorReportOptions = {
11
11
  traceMessages?: string[];
12
12
  extraSections?: ErrorReportSection[];
13
13
  };
14
+ type ExecutionLogStatus = 'cancelled' | 'failed' | 'partial_failure' | 'success';
15
+ type WriteExecutionLogOptions = {
16
+ title?: string;
17
+ scope?: string;
18
+ status?: ExecutionLogStatus;
19
+ args?: string[];
20
+ startedAt?: Date;
21
+ finishedAt?: Date;
22
+ traceMessages?: string[];
23
+ extraSections?: ErrorReportSection[];
24
+ error?: unknown;
25
+ };
14
26
  type ShellCommandProgressOptions = {
15
27
  progressIntervalMs?: number;
16
28
  progressMessage?: string;
@@ -28,6 +40,15 @@ declare const COMMIT_FETCH_LIMIT = 20;
28
40
  declare const COMMIT_SELECTION_WINDOW = 8;
29
41
  declare const ignoreList: string[];
30
42
  declare function isTestMode(args?: string[]): boolean;
43
+ /**
44
+ * @description
45
+ * AI CLI의 쀑간 stdout/stderrλ₯Ό μ‹€μ‹œκ°„μœΌλ‘œ 터미널에 λ…ΈμΆœν• μ§€ μ—¬λΆ€λ₯Ό νŒλ‹¨ν•©λ‹ˆλ‹€.
46
+ * κΈ°λ³Έ 싀행은 μ‘°μš©ν•œ λͺ¨λ“œλ‘œ μœ μ§€ν•˜κ³ , μ‚¬μš©μžκ°€ λͺ…μ‹œμ μœΌλ‘œ ν”Œλž˜κ·Έλ₯Ό 쀄 λ•Œλ§Œ
47
+ * AI 응닡을 κ·ΈλŒ€λ‘œ μŠ€νŠΈλ¦¬λ°ν•©λ‹ˆλ‹€.
48
+ * @param args ν˜„μž¬ μ‹€ν–‰ 인자 λͺ©λ‘
49
+ * @returns μ‹€μ‹œκ°„ AI 좜λ ₯ λ…ΈμΆœ μ—¬λΆ€
50
+ */
51
+ declare function shouldStreamAIOutput(args?: string[]): boolean;
31
52
  declare function clearTraceMessages(): void;
32
53
  declare function getTraceMessages(): string[];
33
54
  /**
@@ -70,6 +91,14 @@ declare function createReportDirectory(): void;
70
91
  declare function getNowString(now?: Date): string;
71
92
  declare function getErrorLogTimestamp(now?: Date): string;
72
93
  declare function writeErrorReport(error: unknown, options?: WriteErrorReportOptions): string;
94
+ /**
95
+ * @description
96
+ * 성곡/μ‹€νŒ¨ 여뢀와 λ¬΄κ΄€ν•˜κ²Œ 리뷰 μ‹€ν–‰ 자체의 진단 둜그λ₯Ό `.review-report`에 λ‚¨κΉλ‹ˆλ‹€.
97
+ * μ—λŸ¬ λ‘œκ·Έμ™€ λ³„λ„λ‘œ μ‹€ν–‰ λ§₯락, μƒμ„±λœ λͺ…λ Ήμ–΄, traceλ₯Ό 항상 λ³΄μ‘΄ν•˜μ—¬ μž¬ν˜„κ³Ό 원인 뢄석에 ν™œμš©ν•©λ‹ˆλ‹€.
98
+ * @param options μ‹€ν–‰ μƒνƒœ, μ‹œμž‘/μ’…λ£Œ μ‹œκ°, μ—λŸ¬, μΆ”κ°€ μ„Ήμ…˜ λ“± μ‹€ν–‰ 둜그 μž‘μ„± μ˜΅μ…˜
99
+ * @returns μƒμ„±λœ μ‹€ν–‰ 둜그 파일 경둜. μ‹€νŒ¨ μ‹œ 빈 λ¬Έμžμ—΄
100
+ */
101
+ declare function writeExecutionLog(options?: WriteExecutionLogOptions): string;
73
102
  declare function exitWithError(message: string, options?: Omit<WriteErrorReportOptions, 'title'> & {
74
103
  error?: unknown;
75
104
  }): never;
@@ -154,4 +183,4 @@ declare function selectAIService(): AIServiceType;
154
183
  */
155
184
  declare function showSelectionAIService(): Promise<AIServiceType>;
156
185
 
157
- export { AIServices, COMMIT_FETCH_LIMIT, COMMIT_SELECTION_WINDOW, REPORT_DIR, buildSelectedCommitDiff, buildSelectedCommitSummary, buildSelectedFileDiff, clearTraceMessages, codingConventionRulesPath, createReportDirectory, createTraceLogger, deleteFile, deleteTempDiff, executeShellCommandWithProgress, exitWithError, formatReviewTargetFiles, getAvailableFilePath, getErrorLogTimestamp, getErrorSummary, getGitDiffFilter, getNextFilePath, getNowString, getRecentCommitOptions, getSelectedCommitFiles, getTraceMessages, ignoreList, isTestMode, namingRulesPath, openReport, reviewFormOneByOnePath, reviewFormPath, rulesPath, selectAIService, selectReviewCommits, showMultiSelect, showSelectionAIService, tempDiffPath, writeErrorReport };
186
+ export { AIServices, COMMIT_FETCH_LIMIT, COMMIT_SELECTION_WINDOW, REPORT_DIR, buildSelectedCommitDiff, buildSelectedCommitSummary, buildSelectedFileDiff, clearTraceMessages, codingConventionRulesPath, createReportDirectory, createTraceLogger, deleteFile, deleteTempDiff, executeShellCommandWithProgress, exitWithError, formatReviewTargetFiles, getAvailableFilePath, getErrorLogTimestamp, getErrorSummary, getGitDiffFilter, getNextFilePath, getNowString, getRecentCommitOptions, getSelectedCommitFiles, getTraceMessages, ignoreList, isTestMode, namingRulesPath, openReport, reviewFormOneByOnePath, reviewFormPath, rulesPath, selectAIService, selectReviewCommits, shouldStreamAIOutput, showMultiSelect, showSelectionAIService, tempDiffPath, writeErrorReport, writeExecutionLog };