@xdevops/issue-auto-finish 1.0.86 → 1.0.87

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 (129) hide show
  1. package/dist/AIRunnerRegistry-II3WWSFN.js +31 -0
  2. package/dist/PtyRunner-6UGI5STW.js +22 -0
  3. package/dist/TerminalManager-RT2N7N5R.js +8 -0
  4. package/dist/ai-runner/AIRunner.d.ts +9 -1
  5. package/dist/ai-runner/AIRunner.d.ts.map +1 -1
  6. package/dist/ai-runner/AIRunnerRegistry.d.ts +37 -1
  7. package/dist/ai-runner/AIRunnerRegistry.d.ts.map +1 -1
  8. package/dist/ai-runner/PtyRunner.d.ts +114 -0
  9. package/dist/ai-runner/PtyRunner.d.ts.map +1 -0
  10. package/dist/ai-runner/index.d.ts +3 -1
  11. package/dist/ai-runner/index.d.ts.map +1 -1
  12. package/dist/{ai-runner-SVUNA3FX.js → ai-runner-HLA44WI6.js} +12 -3
  13. package/dist/{analyze-SXXPE5XL.js → analyze-ZIXNC5GN.js} +10 -8
  14. package/dist/{analyze-SXXPE5XL.js.map → analyze-ZIXNC5GN.js.map} +1 -1
  15. package/dist/{braindump-4E5SDMSZ.js → braindump-56WAY2RD.js} +10 -8
  16. package/dist/{braindump-4E5SDMSZ.js.map → braindump-56WAY2RD.js.map} +1 -1
  17. package/dist/{chunk-ICXB2WP5.js → chunk-2MESXJEZ.js} +3 -3
  18. package/dist/{chunk-P4O4ZXEC.js → chunk-2YQHKXLL.js} +40 -19
  19. package/dist/chunk-2YQHKXLL.js.map +1 -0
  20. package/dist/chunk-AVGZH64A.js +211 -0
  21. package/dist/chunk-AVGZH64A.js.map +1 -0
  22. package/dist/{chunk-OUPJMHAL.js → chunk-IP3QTP5A.js} +1026 -764
  23. package/dist/chunk-IP3QTP5A.js.map +1 -0
  24. package/dist/chunk-KC5S66OZ.js +177 -0
  25. package/dist/chunk-KC5S66OZ.js.map +1 -0
  26. package/dist/{chunk-4QV6D34Y.js → chunk-M5C2WILQ.js} +8 -6
  27. package/dist/{chunk-4QV6D34Y.js.map → chunk-M5C2WILQ.js.map} +1 -1
  28. package/dist/{chunk-FWEW5E3B.js → chunk-NZHKAPU6.js} +35 -5
  29. package/dist/chunk-NZHKAPU6.js.map +1 -0
  30. package/dist/{chunk-KTYPZTF4.js → chunk-O3WEV5W3.js} +10 -2
  31. package/dist/chunk-O3WEV5W3.js.map +1 -0
  32. package/dist/{chunk-QO5VTSMI.js → chunk-QZZGIZWC.js} +455 -202
  33. package/dist/chunk-QZZGIZWC.js.map +1 -0
  34. package/dist/{chunk-4LFNFRCL.js → chunk-SAMTXC4A.js} +91 -214
  35. package/dist/chunk-SAMTXC4A.js.map +1 -0
  36. package/dist/chunk-U237JSLB.js +1 -0
  37. package/dist/chunk-U237JSLB.js.map +1 -0
  38. package/dist/chunk-U6GWFTKA.js +657 -0
  39. package/dist/chunk-U6GWFTKA.js.map +1 -0
  40. package/dist/{chunk-HOFYJEJ4.js → chunk-UBQLXQ7I.js} +11 -11
  41. package/dist/cli/setup/env-metadata.d.ts.map +1 -1
  42. package/dist/cli.js +8 -7
  43. package/dist/cli.js.map +1 -1
  44. package/dist/{config-QLINHCHD.js → config-WTRSZLOC.js} +4 -3
  45. package/dist/config-WTRSZLOC.js.map +1 -0
  46. package/dist/config-schema.d.ts +17 -1
  47. package/dist/config-schema.d.ts.map +1 -1
  48. package/dist/config.d.ts +20 -0
  49. package/dist/config.d.ts.map +1 -1
  50. package/dist/errors/PhaseAbortedError.d.ts +3 -3
  51. package/dist/errors/PhaseAbortedError.d.ts.map +1 -1
  52. package/dist/errors-S3BWYA4I.js +43 -0
  53. package/dist/errors-S3BWYA4I.js.map +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +14 -11
  56. package/dist/{init-TDKDC6YP.js → init-QQDXGTPB.js} +7 -6
  57. package/dist/{init-TDKDC6YP.js.map → init-QQDXGTPB.js.map} +1 -1
  58. package/dist/lib.js +9 -7
  59. package/dist/lib.js.map +1 -1
  60. package/dist/orchestrator/IssueProcessingContext.d.ts +39 -21
  61. package/dist/orchestrator/IssueProcessingContext.d.ts.map +1 -1
  62. package/dist/orchestrator/PipelineOrchestrator.d.ts +10 -1
  63. package/dist/orchestrator/PipelineOrchestrator.d.ts.map +1 -1
  64. package/dist/orchestrator/steps/PhaseLoopStep.d.ts +1 -1
  65. package/dist/orchestrator/steps/PhaseLoopStep.d.ts.map +1 -1
  66. package/dist/orchestrator/steps/SetupStep.d.ts.map +1 -1
  67. package/dist/persistence/PlanPersistence.d.ts +7 -1
  68. package/dist/persistence/PlanPersistence.d.ts.map +1 -1
  69. package/dist/phases/BasePhase.d.ts +31 -42
  70. package/dist/phases/BasePhase.d.ts.map +1 -1
  71. package/dist/phases/BuildPhase.d.ts.map +1 -1
  72. package/dist/phases/PhaseFactory.d.ts +2 -3
  73. package/dist/phases/PhaseFactory.d.ts.map +1 -1
  74. package/dist/phases/PhaseOutcome.d.ts +42 -0
  75. package/dist/phases/PhaseOutcome.d.ts.map +1 -0
  76. package/dist/phases/PlanPhase.d.ts +1 -1
  77. package/dist/phases/PlanPhase.d.ts.map +1 -1
  78. package/dist/phases/ReleasePhase.d.ts +8 -18
  79. package/dist/phases/ReleasePhase.d.ts.map +1 -1
  80. package/dist/phases/UatPhase.d.ts +7 -24
  81. package/dist/phases/UatPhase.d.ts.map +1 -1
  82. package/dist/phases/VerifyPhase.d.ts +4 -4
  83. package/dist/phases/VerifyPhase.d.ts.map +1 -1
  84. package/dist/poller/IssuePoller.d.ts.map +1 -1
  85. package/dist/prompts/release-templates.d.ts.map +1 -1
  86. package/dist/prompts/templates.d.ts.map +1 -1
  87. package/dist/{restart-4NSHDOX3.js → restart-BMILTP5X.js} +6 -5
  88. package/dist/{restart-4NSHDOX3.js.map → restart-BMILTP5X.js.map} +1 -1
  89. package/dist/run.js +14 -11
  90. package/dist/run.js.map +1 -1
  91. package/dist/settings/ExperimentalSettings.d.ts +1 -1
  92. package/dist/settings/ExperimentalSettings.d.ts.map +1 -1
  93. package/dist/start-6QRW6IJI.js +15 -0
  94. package/dist/start-6QRW6IJI.js.map +1 -0
  95. package/dist/terminal/TerminalManager.d.ts +62 -0
  96. package/dist/terminal/TerminalManager.d.ts.map +1 -0
  97. package/dist/terminal/TerminalWebSocket.d.ts +9 -0
  98. package/dist/terminal/TerminalWebSocket.d.ts.map +1 -0
  99. package/dist/tracker/ExecutableTask.d.ts +4 -2
  100. package/dist/tracker/ExecutableTask.d.ts.map +1 -1
  101. package/dist/tracker/IssueState.d.ts +11 -1
  102. package/dist/tracker/IssueState.d.ts.map +1 -1
  103. package/dist/tracker/IssueTracker.d.ts +19 -1
  104. package/dist/tracker/IssueTracker.d.ts.map +1 -1
  105. package/dist/web/WebServer.d.ts +4 -0
  106. package/dist/web/WebServer.d.ts.map +1 -1
  107. package/dist/web/routes/terminal.d.ts +11 -0
  108. package/dist/web/routes/terminal.d.ts.map +1 -0
  109. package/dist/webhook/CommandExecutor.d.ts.map +1 -1
  110. package/package.json +7 -1
  111. package/src/web/frontend/dist/assets/index-COYziOhv.css +1 -0
  112. package/src/web/frontend/dist/assets/index-D_oTMuJU.js +151 -0
  113. package/src/web/frontend/dist/index.html +2 -2
  114. package/dist/chunk-4LFNFRCL.js.map +0 -1
  115. package/dist/chunk-DADQSKPL.js +0 -1
  116. package/dist/chunk-FWEW5E3B.js.map +0 -1
  117. package/dist/chunk-KTYPZTF4.js.map +0 -1
  118. package/dist/chunk-OUPJMHAL.js.map +0 -1
  119. package/dist/chunk-P4O4ZXEC.js.map +0 -1
  120. package/dist/chunk-QO5VTSMI.js.map +0 -1
  121. package/dist/start-XZIBPLC2.js +0 -14
  122. package/src/web/frontend/dist/assets/index-BWVpNmFm.js +0 -133
  123. package/src/web/frontend/dist/assets/index-C7lorIa0.css +0 -1
  124. /package/dist/{ai-runner-SVUNA3FX.js.map → AIRunnerRegistry-II3WWSFN.js.map} +0 -0
  125. /package/dist/{chunk-DADQSKPL.js.map → PtyRunner-6UGI5STW.js.map} +0 -0
  126. /package/dist/{config-QLINHCHD.js.map → TerminalManager-RT2N7N5R.js.map} +0 -0
  127. /package/dist/{start-XZIBPLC2.js.map → ai-runner-HLA44WI6.js.map} +0 -0
  128. /package/dist/{chunk-ICXB2WP5.js.map → chunk-2MESXJEZ.js.map} +0 -0
  129. /package/dist/{chunk-HOFYJEJ4.js.map → chunk-UBQLXQ7I.js.map} +0 -0
@@ -5,8 +5,8 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
6
  <link rel="icon" type="image/png" href="/favicon.png">
7
7
  <title>Issue Auto-Finish Dashboard</title>
8
- <script type="module" crossorigin src="/assets/index-BWVpNmFm.js"></script>
9
- <link rel="stylesheet" crossorigin href="/assets/index-C7lorIa0.css">
8
+ <script type="module" crossorigin src="/assets/index-D_oTMuJU.js"></script>
9
+ <link rel="stylesheet" crossorigin href="/assets/index-COYziOhv.css">
10
10
  </head>
11
11
  <body class="bg-gray-50 min-h-screen">
12
12
  <div id="app"></div>
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/ai-runner/ModelMapping.ts","../src/shutdown/ShutdownSignal.ts","../src/ai-runner/BaseAIRunner.ts","../src/ai-runner/ClaudeInternalRunner.ts","../src/ai-runner/CursorAgentRunner.ts","../src/ai-runner/CodebuddyRunner.ts","../src/ai-runner/CodebuddyAcpRunner.ts","../src/ai-runner/acp/AcpProtocol.ts","../src/ai-runner/AIRunnerRegistry.ts","../src/errors/BaseError.ts","../src/errors/ApiError.ts","../src/errors/AIExecutionError.ts","../src/errors/NotFoundError.ts","../src/errors/InvalidOperationError.ts","../src/errors/ShutdownError.ts","../src/errors/PhaseAbortedError.ts","../src/errors/ParseError.ts","../src/errors/RegistryError.ts"],"sourcesContent":["// ---------------------------------------------------------------------------\n// 模型名称映射:规范名 (AI_MODEL 配置值) → 各 Runner CLI 接受的模型 ID\n// ---------------------------------------------------------------------------\n\nimport { logger as rootLogger } from '../logger.js';\n\nconst logger = rootLogger.child('ModelMapping');\n\ntype RunnerModelMap = Record<string, string>;\n\n/**\n * 每个 Runner 的模型名映射表。\n * key = runner mode(如 'codebuddy'),value = { 规范名 → CLI 模型名 }。\n * 未列出的 runner(如 claude-internal、cursor-agent)表示无需映射,直接透传。\n */\nconst MODEL_MAPS: Record<string, RunnerModelMap> = {\n codebuddy: {\n // Claude 系列\n 'Claude-4.6-Opus': 'claude-opus-4.6',\n 'claude-4.6-opus-high-thinking': 'claude-opus-4.6',\n 'claude-opus-4.6-1m': 'claude-opus-4.6-1m',\n 'Claude-Sonnet-4.6': 'claude-sonnet-4.6',\n 'claude-sonnet-4.6-1m': 'claude-sonnet-4.6-1m',\n 'Claude-4.5': 'claude-4.5',\n 'Claude-Opus-4.5': 'claude-opus-4.5',\n 'Claude-Haiku-4.5': 'claude-haiku-4.5',\n // GPT 系列\n 'GPT-5.4': 'gpt-5.4',\n 'GPT-5.3': 'gpt-5.3',\n 'GPT-5.3-Codex': 'gpt-5.3-codex',\n 'GPT-5.2': 'gpt-5.2',\n 'GPT-5.2-Codex': 'gpt-5.2-codex',\n 'GPT-5.1': 'gpt-5.1',\n 'GPT-5.1-Codex': 'gpt-5.1-codex',\n 'GPT-5.1-Codex-Max': 'gpt-5.1-codex-max',\n 'GPT-5.1-Codex-Mini': 'gpt-5.1-codex-mini',\n // Gemini 系列\n 'Gemini-2.5-Pro': 'gemini-2.5-pro',\n 'Gemini-3.0-Flash': 'gemini-3.0-flash',\n 'Gemini-3.1-Pro': 'gemini-3.1-pro',\n 'Gemini-3.1-Flash-Lite': 'gemini-3.1-flash-lite',\n // GLM 系列\n 'GLM-5.0-Turbo': 'glm-5.0-turbo-ioa',\n 'GLM-5.0': 'glm-5.0-ioa',\n 'GLM-4.7': 'glm-4.7-ioa',\n // 其他国产模型\n 'MiniMax-M2.7': 'minimax-m2.7-ioa',\n 'MiniMax-M2.5': 'minimax-m2.5-ioa',\n 'Kimi-K2.5': 'kimi-k2.5-ioa',\n 'DeepSeek-V3-2': 'deepseek-v3-2-volc-ioa',\n 'Hunyuan-2.0': 'hunyuan-2.0-thinking-ioa',\n },\n // claude-internal 和 cursor-agent 无需映射,直接透传\n};\n\n// codebuddy-acp 复用 codebuddy 的模型映射\nMODEL_MAPS['codebuddy-acp'] = MODEL_MAPS['codebuddy'];\n\n/**\n * 根据 runner mode 将规范模型名映射为该 CLI 接受的模型 ID。\n * 如果该 runner 没有映射表,则原样返回。\n * 如果有映射表但找不到对应条目,返回 undefined(由调用方使用默认模型)。\n */\nexport function resolveModelForRunner(runnerMode: string, model: string): string | undefined {\n const map = MODEL_MAPS[runnerMode];\n if (!map) return model;\n const resolved = map[model];\n if (resolved) return resolved;\n logger.warn('Model not in mapping table, will use runner default', {\n runnerMode,\n requestedModel: model,\n availableModels: Object.keys(map),\n });\n return undefined;\n}\n","let _shuttingDown = false;\n\nexport function isShuttingDown(): boolean {\n return _shuttingDown;\n}\n\nexport function setShuttingDown(): void {\n _shuttingDown = true;\n}\n","import { spawn, type ChildProcess, type SpawnOptions } from 'node:child_process';\nimport { logger as rootLogger } from '../logger.js';\nimport { isShuttingDown } from '../shutdown/ShutdownSignal.js';\nimport type { RunOptions, RunResult, StreamEvent } from './AIRunner.js';\n\nconst logger = rootLogger.child('AIRunner');\n\nconst SIGKILL_GRACE_MS = 10_000;\nconst IDLE_CHECK_INTERVAL_MS = 5_000;\nconst RESULT_EXIT_GRACE_MS = 30_000;\n\ninterface ActiveChild {\n child: ChildProcess;\n workDir: string;\n}\n\nexport abstract class BaseAIRunner {\n protected abstract getBinary(): string;\n protected abstract buildArgs(options: RunOptions): string[];\n protected abstract getSpawnOptions(options: RunOptions): SpawnOptions;\n\n private activeChildren = new Map<ChildProcess, ActiveChild>();\n\n async run(options: RunOptions): Promise<RunResult> {\n if (isShuttingDown()) {\n logger.warn('AI runner skipped — service is shutting down');\n return { success: false, output: 'Service shutting down', exitCode: null };\n }\n\n const { prompt, workDir, timeoutMs, sessionId, continueSession, idleTimeoutMs, onStreamEvent } = options;\n\n logger.info('Running AI runner', {\n workDir,\n timeoutMs,\n idleTimeoutMs,\n continueSession: !!continueSession,\n sessionId,\n });\n\n return new Promise<RunResult>((resolve) => {\n const chunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n let timedOut = false;\n let timeoutType: 'wall-clock' | 'idle' | undefined;\n let lineBuffer = '';\n let killTimer: ReturnType<typeof setTimeout> | undefined;\n let lastActivityTime = Date.now();\n let resultGraceTimer: ReturnType<typeof setTimeout> | undefined;\n\n const binary = this.getBinary();\n const args = this.buildArgs(options);\n const spawnOpts = this.getSpawnOptions(options);\n\n const child = spawn(binary, args, {\n ...spawnOpts,\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.activeChildren.set(child, { child, workDir });\n\n const timer = setTimeout(() => {\n timedOut = true;\n timeoutType = 'wall-clock';\n child.kill('SIGTERM');\n logger.warn('AI runner timed out', { timeoutMs });\n\n killTimer = setTimeout(() => {\n if (child.exitCode === null) {\n child.kill('SIGKILL');\n child.stdout?.destroy();\n child.stderr?.destroy();\n logger.warn('AI runner force-killed (SIGKILL fallback)', { workDir });\n }\n }, SIGKILL_GRACE_MS);\n }, timeoutMs);\n\n // Idle timeout: kill process if no stdout/stderr activity for idleTimeoutMs\n const idleCheckInterval = idleTimeoutMs\n ? setInterval(() => {\n const idleMs = Date.now() - lastActivityTime;\n if (idleMs >= idleTimeoutMs) {\n timedOut = true;\n timeoutType = 'idle';\n child.kill('SIGTERM');\n logger.warn('AI runner idle timed out', {\n idleTimeoutMs,\n idleSinceMs: idleMs,\n });\n clearInterval(idleCheckInterval!);\n\n killTimer = setTimeout(() => {\n if (child.exitCode === null) {\n child.kill('SIGKILL');\n child.stdout?.destroy();\n child.stderr?.destroy();\n logger.warn('AI runner force-killed after idle timeout (SIGKILL fallback)', { workDir });\n }\n }, SIGKILL_GRACE_MS);\n }\n }, IDLE_CHECK_INTERVAL_MS)\n : undefined;\n\n const flushInterval = onStreamEvent\n ? setInterval(() => {\n if (lineBuffer.trim()) {\n onStreamEvent({ type: 'partial', content: lineBuffer.trim(), timestamp: new Date().toISOString() });\n }\n }, 200)\n : undefined;\n\n child.stdout.on('data', (chunk: Buffer) => {\n lastActivityTime = Date.now();\n chunks.push(chunk);\n\n lineBuffer += chunk.toString();\n let newlineIdx: number;\n while ((newlineIdx = lineBuffer.indexOf('\\n')) !== -1) {\n const line = lineBuffer.slice(0, newlineIdx).trim();\n lineBuffer = lineBuffer.slice(newlineIdx + 1);\n if (!line) continue;\n\n if (onStreamEvent) {\n this.emitStreamLine(line, onStreamEvent);\n }\n\n // Detect result event: start grace timer to kill hanging process\n if (!resultGraceTimer) {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n if (parsed.type === 'result') {\n resultGraceTimer = setTimeout(() => {\n if (child.exitCode === null) {\n logger.warn('AI runner process did not exit after result event, sending SIGTERM', {\n graceMs: RESULT_EXIT_GRACE_MS,\n });\n child.kill('SIGTERM');\n\n killTimer = setTimeout(() => {\n if (child.exitCode === null) {\n child.kill('SIGKILL');\n child.stdout?.destroy();\n child.stderr?.destroy();\n logger.warn('AI runner force-killed after result grace (SIGKILL fallback)', { workDir });\n }\n }, SIGKILL_GRACE_MS);\n }\n }, RESULT_EXIT_GRACE_MS);\n }\n } catch {\n // not JSON, ignore\n }\n }\n }\n });\n\n child.stderr.on('data', (chunk: Buffer) => {\n lastActivityTime = Date.now();\n stderrChunks.push(chunk);\n const text = chunk.toString();\n logger.debug('AI runner stderr: ' + text);\n if (onStreamEvent) {\n onStreamEvent({ type: 'stderr', content: text, timestamp: new Date().toISOString() });\n }\n });\n\n child.on('close', (code) => {\n this.activeChildren.delete(child);\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n if (resultGraceTimer) clearTimeout(resultGraceTimer);\n if (idleCheckInterval) clearInterval(idleCheckInterval);\n if (flushInterval) clearInterval(flushInterval);\n\n if (onStreamEvent && lineBuffer.trim()) {\n this.emitStreamLine(lineBuffer.trim(), onStreamEvent);\n }\n\n const rawOutput = Buffer.concat(chunks as unknown as Uint8Array[]).toString('utf-8');\n const { output, resolvedSessionId, hasError, errorMessage: parsedErrorMessage } = this.parseOutput(rawOutput, sessionId);\n\n const success = code === 0 && !timedOut && !hasError;\n logger.info('AI runner finished', { exitCode: code, success, timedOut });\n\n const stderrText = stderrChunks.length > 0 ? Buffer.concat(stderrChunks as unknown as Uint8Array[]).toString('utf-8').trim() : '';\n const finalOutput = (!success && !output.trim() && stderrText) ? stderrText : output;\n\n // 组装真正的错误原因\n let errorMessage: string | undefined;\n if (!success) {\n const parts: string[] = [];\n if (timedOut) parts.push(timeoutType === 'idle' ? 'AI 长时间无响应,已超时终止' : '执行超时');\n if (parsedErrorMessage) parts.push(parsedErrorMessage);\n if (code !== 0 && code !== null) parts.push(`进程退出码: ${code}`);\n if (!parts.length && stderrText) parts.push(stderrText.slice(0, 500));\n errorMessage = parts.join(' | ') || undefined;\n }\n\n resolve({\n success,\n output: finalOutput,\n errorMessage,\n sessionId: resolvedSessionId ?? sessionId,\n exitCode: code,\n timeoutType,\n });\n });\n\n child.on('error', (err) => {\n this.activeChildren.delete(child);\n clearTimeout(timer);\n if (killTimer) clearTimeout(killTimer);\n if (resultGraceTimer) clearTimeout(resultGraceTimer);\n if (idleCheckInterval) clearInterval(idleCheckInterval);\n if (flushInterval) clearInterval(flushInterval);\n logger.error('AI runner spawn error', { error: err.message });\n resolve({\n success: false,\n output: err.message,\n errorMessage: err.message,\n exitCode: null,\n });\n });\n\n child.stdin.write(prompt);\n child.stdin.end();\n });\n }\n\n killAll(): void {\n for (const [child] of this.activeChildren) {\n this.forceKillChild(child);\n }\n logger.info('Killed all active AI runner children', { count: this.activeChildren.size });\n }\n\n killByWorkDir(targetWorkDir: string): number {\n let killed = 0;\n for (const [child, entry] of this.activeChildren) {\n if (entry.workDir === targetWorkDir) {\n this.forceKillChild(child);\n killed++;\n }\n }\n if (killed > 0) {\n logger.info('Killed AI runner children by workDir', { workDir: targetWorkDir, killed });\n }\n return killed;\n }\n\n private forceKillChild(child: ChildProcess): void {\n try {\n if (child.exitCode === null) {\n child.kill('SIGTERM');\n setTimeout(() => {\n if (child.exitCode === null) {\n child.kill('SIGKILL');\n }\n }, SIGKILL_GRACE_MS);\n }\n } catch {\n // process may have already exited\n }\n }\n\n private emitStreamLine(line: string, onStreamEvent: (event: StreamEvent) => void): void {\n try {\n const parsed = JSON.parse(line) as Record<string, unknown>;\n onStreamEvent({\n type: (typeof parsed.type === 'string' ? parsed.type : 'raw'),\n content: parsed,\n timestamp: new Date().toISOString(),\n });\n } catch {\n onStreamEvent({ type: 'raw', content: line, timestamp: new Date().toISOString() });\n }\n }\n\n /**\n * Handles both stream-json (one JSON object per line) and legacy single-JSON formats.\n */\n parseOutput(rawOutput: string, _sessionId?: string): { output: string; resolvedSessionId?: string; hasError?: boolean; errorMessage?: string } {\n let output = rawOutput;\n let resolvedSessionId: string | undefined;\n\n const events = this.tryParseStreamJson(rawOutput);\n if (events) {\n output = events\n .filter((item: { type?: string }) => item.type === 'result')\n .map((item: { result?: string }) => item.result ?? '')\n .join('\\n');\n const sessionItem = events.find(\n (item: { type?: string; session_id?: string }) => item.session_id != null,\n );\n if (sessionItem) {\n resolvedSessionId = (sessionItem as { session_id: string }).session_id;\n }\n if (!output) {\n output = this.extractAssistantText(events);\n }\n if (!output) {\n output = this.summarizeStreamEvents(events);\n }\n\n // 始终检查 error 事件,不论 output 是否有值\n const hasError = this.hasErrorEvents(events);\n const errorMessage = hasError ? this.extractErrorMessage(events) : undefined;\n return { output, resolvedSessionId, hasError, errorMessage };\n }\n\n try {\n const parsed = JSON.parse(rawOutput);\n if (Array.isArray(parsed)) {\n output = parsed\n .filter((item: { type?: string }) => item.type === 'result')\n .map((item: { result?: string }) => item.result ?? '')\n .join('\\n');\n const sessionItem = parsed.find(\n (item: { type?: string; session_id?: string }) => item.session_id != null,\n );\n if (sessionItem) {\n resolvedSessionId = sessionItem.session_id;\n }\n if (!output) {\n output = this.extractAssistantText(parsed);\n }\n // 始终检查 error 事件\n const hasError = this.hasErrorEvents(parsed);\n const errorMessage = hasError ? this.extractErrorMessage(parsed) : undefined;\n return { output, resolvedSessionId, hasError, errorMessage };\n } else if (parsed.result != null) {\n output = parsed.result;\n resolvedSessionId = parsed.session_id;\n }\n } catch {\n // raw text output\n }\n\n return { output, resolvedSessionId };\n }\n\n /**\n * Extract plain text from assistant events as fallback when result.result is empty.\n * Looks for message.content[].text in assistant-type events.\n */\n private extractAssistantText(events: Record<string, unknown>[]): string {\n const texts: string[] = [];\n for (const evt of events) {\n if (evt.type !== 'assistant') continue;\n const message = evt.message as { content?: Array<{ type?: string; text?: string }> } | undefined;\n if (!message?.content || !Array.isArray(message.content)) continue;\n for (const block of message.content) {\n if (block.type === 'text' && block.text) {\n texts.push(block.text);\n }\n }\n }\n return texts.join('');\n }\n\n private hasErrorEvents(events: Record<string, unknown>[]): boolean {\n return events.some(e => e.type === 'error' || e.subtype === 'error');\n }\n\n /** 提取 error 事件中的错误描述信息 */\n private extractErrorMessage(events: Record<string, unknown>[]): string {\n const errorEvents = events.filter(e => e.type === 'error' || e.subtype === 'error');\n if (errorEvents.length === 0) return '';\n return errorEvents.map(e => String(e.message ?? e.error ?? JSON.stringify(e))).join('; ');\n }\n\n private summarizeStreamEvents(events: Record<string, unknown>[]): string {\n const errorEvents = events.filter(\n (e) => e.type === 'error' || e.subtype === 'error',\n );\n if (errorEvents.length > 0) {\n const messages = errorEvents.map(\n (e) => String(e.message ?? e.error ?? JSON.stringify(e)),\n );\n return `AI runner 错误: ${messages.join('; ')}`;\n }\n\n const types = events.map((e) => String(e.type ?? 'unknown'));\n const typeCounts: Record<string, number> = {};\n for (const t of types) {\n typeCounts[t] = (typeCounts[t] ?? 0) + 1;\n }\n const summary = Object.entries(typeCounts)\n .map(([t, c]) => `${t}(${c})`)\n .join(', ');\n return `AI runner 未返回结果 (收到 ${events.length} 个事件: ${summary})`;\n }\n\n private tryParseStreamJson(raw: string): Record<string, unknown>[] | null {\n const lines = raw.split('\\n').filter((l) => l.trim());\n if (lines.length < 2) return null;\n\n const objects: Record<string, unknown>[] = [];\n for (const line of lines) {\n try {\n objects.push(JSON.parse(line) as Record<string, unknown>);\n } catch {\n return null;\n }\n }\n return objects;\n }\n}\n","import type { SpawnOptions } from 'node:child_process';\nimport { BaseAIRunner } from './BaseAIRunner.js';\nimport type { RunOptions } from './AIRunner.js';\n\nexport class ClaudeInternalRunner extends BaseAIRunner {\n private readonly binary: string;\n private readonly nvmNodeVersion: string;\n private readonly model?: string;\n\n constructor(binary: string, nvmNodeVersion: string, model?: string) {\n super();\n this.binary = binary;\n this.nvmNodeVersion = nvmNodeVersion;\n this.model = model;\n }\n\n protected getBinary(): string {\n return this.binary;\n }\n\n protected buildArgs(options: RunOptions): string[] {\n const args = ['-p', '-', '--output-format', 'stream-json', '--verbose'];\n if (options.mode === 'plan') {\n args.push('--permission-mode', 'plan', '--allowedTools', 'Read,Grep,Glob,WebSearch');\n } else {\n args.push('--dangerously-skip-permissions');\n }\n if (this.model) {\n args.push('--model', this.model);\n }\n if (options.continueSession && options.sessionId) {\n args.push('--resume', options.sessionId);\n }\n return args;\n }\n\n protected getSpawnOptions(options: RunOptions): SpawnOptions {\n const { CLAUDECODE, ...env } = process.env;\n return {\n cwd: options.workDir,\n env: {\n ...env,\n NODE_VERSION: this.nvmNodeVersion,\n },\n };\n }\n}\n","import type { SpawnOptions } from 'node:child_process';\nimport { BaseAIRunner } from './BaseAIRunner.js';\nimport type { RunOptions } from './AIRunner.js';\n\nexport class CursorAgentRunner extends BaseAIRunner {\n private readonly binary: string;\n private readonly nvmNodeVersion: string;\n private readonly model?: string;\n\n constructor(binary: string, nvmNodeVersion: string, model?: string) {\n super();\n this.binary = binary;\n this.nvmNodeVersion = nvmNodeVersion;\n this.model = model;\n }\n\n protected getBinary(): string {\n return this.binary;\n }\n\n protected buildArgs(options: RunOptions): string[] {\n const args = [\n 'agent',\n '-p',\n '--force',\n '--trust',\n '--output-format',\n 'stream-json',\n '--workspace',\n options.workDir,\n ];\n if (options.mode === 'plan') {\n args.push('--mode', 'plan');\n }\n if (this.model) {\n args.push('--model', this.model);\n }\n if (options.continueSession && options.sessionId) {\n args.push('--resume', options.sessionId);\n }\n return args;\n }\n\n protected getSpawnOptions(_options: RunOptions): SpawnOptions {\n return {\n cwd: process.cwd(),\n env: {\n ...process.env,\n NODE_VERSION: this.nvmNodeVersion,\n },\n };\n }\n}\n","import type { SpawnOptions } from 'node:child_process';\nimport { BaseAIRunner } from './BaseAIRunner.js';\nimport type { RunOptions } from './AIRunner.js';\n\nexport class CodebuddyRunner extends BaseAIRunner {\n private readonly binary: string;\n private readonly nvmNodeVersion: string;\n private readonly model?: string;\n\n constructor(binary: string, nvmNodeVersion: string, model?: string) {\n super();\n this.binary = binary;\n this.nvmNodeVersion = nvmNodeVersion;\n this.model = model;\n }\n\n protected getBinary(): string {\n return this.binary;\n }\n\n protected buildArgs(options: RunOptions): string[] {\n const args = ['-p', '-', '--output-format', 'stream-json', '--verbose'];\n if (this.model) {\n args.push('--model', this.model);\n }\n if (options.continueSession && options.sessionId) {\n args.push('--resume', options.sessionId);\n }\n // CodeBuddy 的 --permission-mode plan 设计为交互式审批,与 -p 非交互模式不兼容,\n // 会导致进程卡死。plan 阶段的行为约束通过 Prompt 层(planModeFallback)控制。\n args.push('-y');\n return args;\n }\n\n protected getSpawnOptions(options: RunOptions): SpawnOptions {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const { CLAUDECODE, ...env } = process.env;\n return {\n cwd: options.workDir,\n env: {\n ...env,\n NODE_VERSION: this.nvmNodeVersion,\n },\n };\n }\n}\n","/**\n * CodeBuddy ACP Runner — uses the Agent Client Protocol (JSON-RPC 2.0 over stdio)\n * for native plan-mode support with programmatic input/output control.\n *\n * Unlike CodebuddyRunner (pipe mode), this runner maintains a persistent session\n * with three-step handshake (initialize → session/new → session/prompt) and handles\n * permission requests from the agent.\n */\nimport { spawn, type ChildProcess } from 'node:child_process';\nimport { logger as rootLogger } from '../logger.js';\nimport { isShuttingDown } from '../shutdown/ShutdownSignal.js';\nimport type { RunOptions, RunResult, StreamEvent } from './AIRunner.js';\nimport { BaseAIRunner } from './BaseAIRunner.js';\nimport {\n AcpProtocol,\n isNotification,\n isAgentRequest,\n isResponse,\n isPermissionRequest,\n isSessionUpdate,\n type AcpInboundMessage,\n type AcpUpdatePayload,\n type AcpUpdateChunk,\n type AcpUpdateToolCall,\n type AcpUpdateToolCallUpdate,\n} from './acp/AcpProtocol.js';\n\nconst logger = rootLogger.child('CodebuddyAcpRunner');\n\nconst SIGKILL_GRACE_MS = 10_000;\nconst IDLE_CHECK_INTERVAL_MS = 5_000;\n\ninterface ActiveChild {\n child: ChildProcess;\n workDir: string;\n}\n\n/** Handshake FSM states */\ntype HandshakeState = 'init' | 'session_new' | 'prompting' | 'done';\n\nexport class CodebuddyAcpRunner extends BaseAIRunner {\n private readonly binary: string;\n private readonly nvmNodeVersion: string;\n private readonly model?: string;\n private acpActiveChildren = new Map<ChildProcess, ActiveChild>();\n\n constructor(binary: string, nvmNodeVersion: string, model?: string) {\n super();\n this.binary = binary;\n this.nvmNodeVersion = nvmNodeVersion;\n this.model = model;\n }\n\n // ── Overrides required by BaseAIRunner (kept for compatibility) ──\n\n protected getBinary(): string {\n return this.binary;\n }\n\n protected buildArgs(_options: RunOptions): string[] {\n const args = ['--acp', '--acp-transport', 'stdio', '--permission-mode', 'plan', '--verbose'];\n if (this.model) args.push('--model', this.model);\n return args;\n }\n\n protected getSpawnOptions(options: RunOptions): Record<string, unknown> {\n const { CLAUDECODE, ...env } = process.env;\n void CLAUDECODE;\n return {\n cwd: options.workDir,\n env: { ...env, NODE_VERSION: this.nvmNodeVersion },\n };\n }\n\n // ── Main entry: override BaseAIRunner.run() for ACP session lifecycle ──\n\n async run(options: RunOptions): Promise<RunResult> {\n if (isShuttingDown()) {\n logger.warn('ACP runner skipped — service is shutting down');\n return { success: false, output: 'Service shutting down', exitCode: null };\n }\n\n const { prompt, workDir, timeoutMs, idleTimeoutMs, onStreamEvent } = options;\n\n logger.info('Starting CodeBuddy ACP session', {\n workDir,\n timeoutMs,\n idleTimeoutMs,\n model: this.model,\n });\n\n return new Promise<RunResult>((resolve) => {\n const protocol = new AcpProtocol();\n let rpcId = 1;\n let sessionId: string | undefined;\n let handshake: HandshakeState = 'init';\n const outputChunks: string[] = [];\n let timedOut = false;\n let timeoutType: 'wall-clock' | 'idle' | undefined;\n let lastActivityTime = Date.now();\n let resolved = false;\n const stderrChunks: string[] = [];\n\n const safeResolve = (result: RunResult) => {\n if (resolved) return;\n resolved = true;\n cleanup();\n resolve(result);\n };\n\n const binary = this.getBinary();\n const args = this.buildArgs(options);\n const spawnOpts = this.getSpawnOptions(options);\n\n const child = spawn(binary, args, {\n ...(spawnOpts as Record<string, unknown>),\n stdio: ['pipe', 'pipe', 'pipe'],\n });\n\n this.acpActiveChildren.set(child, { child, workDir });\n\n // ── Timers ──\n\n const wallTimer = setTimeout(() => {\n timedOut = true;\n timeoutType = 'wall-clock';\n logger.warn('ACP runner wall-clock timeout', { timeoutMs });\n killChild(child);\n }, timeoutMs);\n\n let killTimer: ReturnType<typeof setTimeout> | undefined;\n\n const idleInterval = idleTimeoutMs\n ? setInterval(() => {\n if (Date.now() - lastActivityTime >= idleTimeoutMs) {\n timedOut = true;\n timeoutType = 'idle';\n logger.warn('ACP runner idle timeout', { idleTimeoutMs });\n clearInterval(idleInterval!);\n killChild(child);\n }\n }, IDLE_CHECK_INTERVAL_MS)\n : undefined;\n\n const cleanup = () => {\n clearTimeout(wallTimer);\n if (killTimer) clearTimeout(killTimer);\n if (idleInterval) clearInterval(idleInterval);\n this.acpActiveChildren.delete(child);\n };\n\n const killChild = (proc: ChildProcess) => {\n try {\n proc.kill('SIGTERM');\n killTimer = setTimeout(() => {\n if (proc.exitCode === null) {\n proc.kill('SIGKILL');\n proc.stdout?.destroy();\n proc.stderr?.destroy();\n }\n }, SIGKILL_GRACE_MS);\n } catch { /* already exited */ }\n };\n\n // ── Send initialize as first message ──\n child.stdin!.write(protocol.encodeRequest('initialize', { protocolVersion: 1 }, rpcId++));\n\n // ── Stdout handler ──\n child.stdout!.on('data', (chunk: Buffer) => {\n lastActivityTime = Date.now();\n\n for (const msg of protocol.parseChunk(chunk)) {\n this.handleMessage(\n msg, child, protocol, handshake,\n () => rpcId++,\n (s) => { sessionId = s; },\n () => sessionId,\n (h) => { handshake = h; },\n () => handshake,\n workDir, prompt, outputChunks, onStreamEvent,\n (result) => safeResolve(result),\n options,\n );\n }\n });\n\n child.stderr!.on('data', (chunk: Buffer) => {\n lastActivityTime = Date.now();\n const text = chunk.toString();\n stderrChunks.push(text);\n logger.debug('ACP runner stderr: ' + text.slice(0, 500));\n if (onStreamEvent) {\n onStreamEvent({ type: 'stderr', content: text, timestamp: new Date().toISOString() });\n }\n });\n\n child.on('close', (code) => {\n // Flush remaining buffer\n for (const msg of protocol.flush()) {\n this.handleMessage(\n msg, child, protocol, handshake,\n () => rpcId++,\n (s) => { sessionId = s; },\n () => sessionId,\n (h) => { handshake = h; },\n () => handshake,\n workDir, prompt, outputChunks, onStreamEvent,\n (result) => safeResolve(result),\n options,\n );\n }\n\n const output = outputChunks.join('');\n const stderrText = stderrChunks.join('').trim();\n const success = code === 0 && !timedOut;\n\n let errorMessage: string | undefined;\n if (!success) {\n const parts: string[] = [];\n if (timedOut) parts.push(timeoutType === 'idle' ? 'AI 长时间无响应,已超时终止' : '执行超时');\n if (code !== 0 && code !== null) parts.push(`进程退出码: ${code}`);\n if (!parts.length && stderrText) parts.push(stderrText.slice(0, 500));\n errorMessage = parts.join(' | ') || undefined;\n }\n\n logger.info('ACP runner finished', { exitCode: code, success, timedOut });\n safeResolve({\n success,\n output: output || stderrText,\n errorMessage,\n sessionId,\n exitCode: code,\n timeoutType,\n });\n });\n\n child.on('error', (err) => {\n logger.error('ACP runner spawn error', { error: err.message });\n safeResolve({\n success: false,\n output: err.message,\n errorMessage: err.message,\n exitCode: null,\n });\n });\n });\n }\n\n // ── Message dispatch ──\n\n private handleMessage(\n msg: AcpInboundMessage,\n child: ChildProcess,\n protocol: AcpProtocol,\n _handshake: HandshakeState,\n nextId: () => number,\n setSessionId: (s: string) => void,\n getSessionId: () => string | undefined,\n setHandshake: (h: HandshakeState) => void,\n getHandshake: () => HandshakeState,\n workDir: string,\n prompt: string,\n outputChunks: string[],\n onStreamEvent: ((event: StreamEvent) => void) | undefined,\n onComplete: (result: RunResult) => void,\n options: RunOptions,\n ): void {\n if (isResponse(msg)) {\n this.handleResponse(\n msg, child, protocol, nextId, setSessionId, getSessionId,\n setHandshake, getHandshake, workDir, prompt, outputChunks,\n onStreamEvent, onComplete, options,\n );\n } else if (isNotification(msg)) {\n this.handleNotification(msg, outputChunks, onStreamEvent);\n } else if (isAgentRequest(msg)) {\n this.handleAgentRequest(msg, child, protocol, onStreamEvent, options);\n }\n }\n\n private handleResponse(\n msg: AcpInboundMessage,\n child: ChildProcess,\n protocol: AcpProtocol,\n nextId: () => number,\n setSessionId: (s: string) => void,\n getSessionId: () => string | undefined,\n setHandshake: (h: HandshakeState) => void,\n getHandshake: () => HandshakeState,\n workDir: string,\n prompt: string,\n outputChunks: string[],\n onStreamEvent: ((event: StreamEvent) => void) | undefined,\n _onComplete: (result: RunResult) => void,\n _options: RunOptions,\n ): void {\n const result = msg.result as Record<string, unknown> | undefined;\n const state = getHandshake();\n\n if (state === 'init' && result?.protocolVersion !== undefined) {\n // initialize response → send session/new\n setHandshake('session_new');\n child.stdin!.write(\n protocol.encodeRequest('session/new', { cwd: workDir, mcpServers: [] }, nextId()),\n );\n } else if (state === 'session_new' && result?.sessionId) {\n // session/new response → send session/prompt\n setSessionId(result.sessionId as string);\n setHandshake('prompting');\n child.stdin!.write(\n protocol.encodeRequest(\n 'session/prompt',\n {\n sessionId: result.sessionId,\n prompt: [{ type: 'text', text: prompt }],\n },\n nextId(),\n ),\n );\n } else if (state === 'prompting') {\n // session/prompt final response\n setHandshake('done');\n const stopReason = (result as Record<string, unknown> | undefined)?.stopReason as string | undefined;\n logger.info('ACP session/prompt completed', {\n stopReason,\n sessionId: getSessionId(),\n });\n if (onStreamEvent) {\n onStreamEvent({\n type: 'system',\n content: `ACP session completed: ${stopReason ?? 'unknown'}`,\n timestamp: new Date().toISOString(),\n });\n }\n // Collect final output text\n if (stopReason === 'refusal') {\n outputChunks.push('[REFUSED] Agent 拒绝执行');\n }\n }\n }\n\n private handleNotification(\n msg: AcpInboundMessage,\n outputChunks: string[],\n onStreamEvent: ((event: StreamEvent) => void) | undefined,\n ): void {\n if (!isSessionUpdate(msg)) return;\n\n const update = msg.params?.update as AcpUpdatePayload | undefined;\n if (!update) return;\n\n const event = this.mapUpdateToStreamEvent(update, outputChunks);\n if (event && onStreamEvent) {\n onStreamEvent(event);\n }\n }\n\n private handleAgentRequest(\n msg: AcpInboundMessage,\n child: ChildProcess,\n protocol: AcpProtocol,\n onStreamEvent: ((event: StreamEvent) => void) | undefined,\n options: RunOptions,\n ): void {\n if (!isPermissionRequest(msg)) {\n // Unknown agent request — send empty result to avoid blocking\n child.stdin!.write(protocol.encodeResponse(msg.id as number, {}));\n return;\n }\n\n const toolTitle = msg.params.toolCall.rawInput\n ? JSON.stringify(msg.params.toolCall.rawInput).slice(0, 200)\n : msg.params.toolCall.toolCallId;\n\n if (onStreamEvent) {\n onStreamEvent({\n type: 'system',\n content: `Permission requested: ${toolTitle}`,\n timestamp: new Date().toISOString(),\n });\n }\n\n if (options.onInputRequired) {\n const permissionContent = JSON.stringify({\n toolCallId: msg.params.toolCall.toolCallId,\n options: msg.params.options,\n rawInput: msg.params.toolCall.rawInput,\n });\n\n options.onInputRequired({ type: 'plan-approval', content: permissionContent })\n .then((decision) => {\n const optionId = decision === 'reject' ? 'reject' : 'allow';\n child.stdin!.write(\n protocol.encodeResponse(msg.id, {\n outcome: { outcome: 'selected', optionId },\n }),\n );\n })\n .catch((err) => {\n logger.warn('onInputRequired callback failed, auto-approving', { error: (err as Error).message });\n this.autoApprove(child, protocol, msg.id, msg.params.options);\n });\n return;\n }\n\n // No callback: auto-approve all permissions\n this.autoApprove(child, protocol, msg.id, msg.params.options);\n }\n\n private autoApprove(\n child: ChildProcess,\n protocol: AcpProtocol,\n requestId: number,\n options: Array<{ optionId: string; kind: string }>,\n ): void {\n const allowOption = options.find(\n (o) => o.kind === 'allow_always' || o.kind === 'allow_once',\n );\n child.stdin!.write(\n protocol.encodeResponse(requestId, {\n outcome: { outcome: 'selected', optionId: allowOption?.optionId ?? 'allow' },\n }),\n );\n }\n\n // ── StreamEvent mapping (reuses existing frontend log pipeline) ──\n\n private mapUpdateToStreamEvent(\n update: AcpUpdatePayload,\n outputChunks: string[],\n ): StreamEvent | null {\n switch (update.sessionUpdate) {\n case 'agent_message_chunk': {\n const chunk = update as AcpUpdateChunk;\n if (chunk.content.type === 'thinking') {\n return {\n type: 'thinking',\n content: { text: chunk.content.text },\n timestamp: new Date().toISOString(),\n };\n }\n outputChunks.push(chunk.content.text);\n return {\n type: 'assistant',\n content: {\n message: { content: [{ type: 'text', text: chunk.content.text }] },\n },\n timestamp: new Date().toISOString(),\n };\n }\n\n case 'tool_call': {\n const tc = update as AcpUpdateToolCall;\n return {\n type: 'tool_use',\n content: { tool: { name: tc.title, input: tc.rawInput ?? {} } },\n timestamp: new Date().toISOString(),\n };\n }\n\n case 'tool_call_update': {\n const tcu = update as AcpUpdateToolCallUpdate;\n return {\n type: 'tool_result',\n content: tcu.status,\n timestamp: new Date().toISOString(),\n };\n }\n\n default:\n return null;\n }\n }\n\n // ── Process management ──\n\n killAll(): void {\n for (const [child] of this.acpActiveChildren) {\n this.forceKill(child);\n }\n logger.info('Killed all ACP runner children', { count: this.acpActiveChildren.size });\n }\n\n killByWorkDir(targetWorkDir: string): number {\n let killed = 0;\n for (const [child, entry] of this.acpActiveChildren) {\n if (entry.workDir === targetWorkDir) {\n this.forceKill(child);\n killed++;\n }\n }\n if (killed > 0) {\n logger.info('Killed ACP runner children by workDir', { workDir: targetWorkDir, killed });\n }\n return killed;\n }\n\n private forceKill(child: ChildProcess): void {\n try {\n if (child.exitCode === null) {\n child.kill('SIGTERM');\n setTimeout(() => {\n if (child.exitCode === null) child.kill('SIGKILL');\n }, SIGKILL_GRACE_MS);\n }\n } catch { /* already exited */ }\n }\n}\n","/**\n * ACP (Agent Client Protocol) JSON-RPC 2.0 codec.\n *\n * Handles line-buffered parsing of newline-delimited JSON messages from\n * CodeBuddy's stdin/stdout ACP transport and encoding of outbound requests/responses.\n *\n * Protocol reference: https://agentclientprotocol.com/protocol/schema\n */\n\n// ---------------------------------------------------------------------------\n// Outbound types (Agent → Client)\n// ---------------------------------------------------------------------------\n\nexport interface AcpUpdateChunk {\n sessionUpdate: 'agent_message_chunk';\n content: { type: 'text' | 'thinking'; text: string };\n}\n\nexport interface AcpUpdateToolCall {\n sessionUpdate: 'tool_call';\n toolCallId: string;\n title: string;\n kind: string;\n status: string;\n content?: Array<{\n type: string;\n path?: string;\n oldText?: string | null;\n newText?: string;\n text?: string;\n }>;\n rawInput?: Record<string, unknown>;\n}\n\nexport interface AcpUpdateToolCallUpdate {\n sessionUpdate: 'tool_call_update';\n toolCallId: string;\n status: string;\n}\n\nexport interface AcpUpdateGeneric {\n sessionUpdate: string;\n [key: string]: unknown;\n}\n\nexport type AcpUpdatePayload =\n | AcpUpdateChunk\n | AcpUpdateToolCall\n | AcpUpdateToolCallUpdate\n | AcpUpdateGeneric;\n\nexport interface AcpSessionUpdate {\n jsonrpc: '2.0';\n method: 'session/update';\n params: {\n sessionId: string;\n update: AcpUpdatePayload;\n };\n}\n\nexport interface AcpPermissionOption {\n optionId: string;\n name: string;\n kind: string;\n}\n\nexport interface AcpPermissionRequest {\n jsonrpc: '2.0';\n id: number;\n method: 'session/request_permission';\n params: {\n sessionId: string;\n options: AcpPermissionOption[];\n toolCall: {\n toolCallId: string;\n rawInput?: Record<string, unknown>;\n };\n };\n}\n\nexport interface AcpResponse {\n jsonrpc: '2.0';\n id: number;\n result: Record<string, unknown>;\n}\n\nexport interface AcpError {\n jsonrpc: '2.0';\n id: number;\n error: { code: number; message: string; data?: unknown };\n}\n\n// Discriminated message type from the agent\nexport type AcpInboundMessage = Record<string, unknown>;\n\n// ---------------------------------------------------------------------------\n// Message classification helpers\n// ---------------------------------------------------------------------------\n\nexport function isNotification(msg: AcpInboundMessage): boolean {\n return typeof msg.method === 'string' && msg.id === undefined;\n}\n\nexport function isAgentRequest(msg: AcpInboundMessage): boolean {\n return typeof msg.method === 'string' && msg.id !== undefined;\n}\n\nexport function isResponse(msg: AcpInboundMessage): boolean {\n return msg.method === undefined && msg.id !== undefined;\n}\n\nexport function isPermissionRequest(msg: AcpInboundMessage): msg is AcpPermissionRequest & AcpInboundMessage {\n return isAgentRequest(msg) && msg.method === 'session/request_permission';\n}\n\nexport function isSessionUpdate(msg: AcpInboundMessage): msg is AcpSessionUpdate & AcpInboundMessage {\n return isNotification(msg) && msg.method === 'session/update';\n}\n\n// ---------------------------------------------------------------------------\n// Protocol codec\n// ---------------------------------------------------------------------------\n\nexport class AcpProtocol {\n private lineBuffer = '';\n\n /** Parse incoming data chunk into zero or more complete JSON-RPC messages. */\n parseChunk(chunk: Buffer | string): AcpInboundMessage[] {\n this.lineBuffer += typeof chunk === 'string' ? chunk : chunk.toString('utf-8');\n\n const messages: AcpInboundMessage[] = [];\n let newlineIdx: number;\n\n while ((newlineIdx = this.lineBuffer.indexOf('\\n')) !== -1) {\n const line = this.lineBuffer.slice(0, newlineIdx).trim();\n this.lineBuffer = this.lineBuffer.slice(newlineIdx + 1);\n\n if (!line) continue;\n\n try {\n messages.push(JSON.parse(line) as AcpInboundMessage);\n } catch {\n // Malformed line — skip silently (could be debug output from --verbose)\n }\n }\n\n return messages;\n }\n\n /** Flush any remaining buffered data (e.g. on stream end). */\n flush(): AcpInboundMessage[] {\n const remaining = this.lineBuffer.trim();\n this.lineBuffer = '';\n if (!remaining) return [];\n\n try {\n return [JSON.parse(remaining) as AcpInboundMessage];\n } catch {\n return [];\n }\n }\n\n /** Encode a JSON-RPC request (Client → Agent). */\n encodeRequest(method: string, params: Record<string, unknown>, id: number): string {\n return JSON.stringify({ jsonrpc: '2.0', method, params, id }) + '\\n';\n }\n\n /** Encode a JSON-RPC response (Client → Agent, replying to agent request). */\n encodeResponse(id: number, result: Record<string, unknown>): string {\n return JSON.stringify({ jsonrpc: '2.0', id, result }) + '\\n';\n }\n}\n","import { spawn } from 'node:child_process';\nimport type { AIRunner } from './AIRunner.js';\nimport type { BaseAIRunner } from './BaseAIRunner.js';\nimport { RunnerNotRegisteredError } from '../errors/index.js';\nimport { resolveModelForRunner } from './ModelMapping.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AIConfig {\n mode: string;\n binary: string;\n phaseTimeoutMs: number;\n nvmNodeVersion: string;\n model?: string;\n}\n\ntype RunnerConstructor = new (binary: string, nvmNodeVersion: string, model?: string) => BaseAIRunner;\n\nexport interface RunnerCapabilities {\n /** Whether the runner natively supports plan mode (AI enters planning mindset) */\n nativePlanMode: boolean;\n}\n\nexport interface RunnerRegistryEntry {\n ctor: RunnerConstructor;\n defaultBinary: string;\n binaryEnvKey: string;\n capabilities: RunnerCapabilities;\n}\n\n// ---------------------------------------------------------------------------\n// Registry\n// ---------------------------------------------------------------------------\n\nconst AI_RUNNER_REGISTRY: Record<string, RunnerRegistryEntry> = {};\n\nexport function registerAIRunner(mode: string, entry: RunnerRegistryEntry): void {\n AI_RUNNER_REGISTRY[mode] = entry;\n}\n\nexport function getRegisteredRunnerModes(): string[] {\n return Object.keys(AI_RUNNER_REGISTRY);\n}\n\nexport function isRegisteredRunner(mode: string): boolean {\n return mode in AI_RUNNER_REGISTRY;\n}\n\n// ---------------------------------------------------------------------------\n// Resolve helpers (replace config.ts switch/case)\n// ---------------------------------------------------------------------------\n\nexport function resolveRunnerMode(raw: string): string {\n return raw || 'claude-internal';\n}\n\nexport function getDefaultBinary(mode: string): string {\n const entry = AI_RUNNER_REGISTRY[mode];\n return entry?.defaultBinary ?? mode;\n}\n\nexport function getBinaryEnvKey(mode: string): string | undefined {\n return AI_RUNNER_REGISTRY[mode]?.binaryEnvKey;\n}\n\nexport function getRunnerCapabilities(mode: string): RunnerCapabilities | undefined {\n return AI_RUNNER_REGISTRY[mode]?.capabilities;\n}\n\n// ---------------------------------------------------------------------------\n// Factory\n// ---------------------------------------------------------------------------\n\nexport function createAIRunner(ai: AIConfig): AIRunner {\n const entry = AI_RUNNER_REGISTRY[ai.mode];\n if (!entry) {\n throw new RunnerNotRegisteredError(ai.mode, getRegisteredRunnerModes());\n }\n const resolvedModel = ai.model ? resolveModelForRunner(ai.mode, ai.model) : undefined;\n return new entry.ctor(ai.binary, ai.nvmNodeVersion, resolvedModel);\n}\n\n// ---------------------------------------------------------------------------\n// Startup validation\n// ---------------------------------------------------------------------------\n\nexport function validateRunnerRegistry(modes: string[]): void {\n const missing = modes.filter((m) => !isRegisteredRunner(m));\n if (missing.length > 0) {\n throw new RunnerNotRegisteredError(\n missing.join(', '),\n getRegisteredRunnerModes(),\n );\n }\n}\n\n// ---------------------------------------------------------------------------\n// Binary availability check\n// ---------------------------------------------------------------------------\n\n/** Check if a binary is available on the system PATH. */\nexport function isBinaryAvailable(binary: string): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn('which', [binary], { stdio: ['ignore', 'pipe', 'ignore'] });\n proc.on('close', (code) => resolve(code === 0));\n proc.on('error', () => resolve(false));\n });\n}\n\n// ---------------------------------------------------------------------------\n// Built-in registrations\n// ---------------------------------------------------------------------------\n\nimport { ClaudeInternalRunner } from './ClaudeInternalRunner.js';\nimport { CursorAgentRunner } from './CursorAgentRunner.js';\nimport { CodebuddyRunner } from './CodebuddyRunner.js';\nimport { CodebuddyAcpRunner } from './CodebuddyAcpRunner.js';\n\nregisterAIRunner('claude-internal', {\n ctor: ClaudeInternalRunner,\n defaultBinary: 'claude-internal',\n binaryEnvKey: 'CLAUDE_BINARY',\n capabilities: { nativePlanMode: false },\n});\n\nregisterAIRunner('cursor-agent', {\n ctor: CursorAgentRunner,\n defaultBinary: 'cursor-agent',\n binaryEnvKey: 'CURSOR_BINARY',\n capabilities: { nativePlanMode: true },\n});\n\nregisterAIRunner('codebuddy', {\n ctor: CodebuddyRunner,\n defaultBinary: 'codebuddy',\n binaryEnvKey: 'CODEBUDDY_BINARY',\n capabilities: { nativePlanMode: false },\n});\n\nregisterAIRunner('codebuddy-acp', {\n ctor: CodebuddyAcpRunner,\n defaultBinary: 'codebuddy',\n binaryEnvKey: 'CODEBUDDY_BINARY',\n capabilities: { nativePlanMode: true },\n});\n","/**\n * Base application error with structured error code and cause chain.\n */\nexport class AppError extends Error {\n /** Unique error code for programmatic matching (e.g. 'GONGFENG_API_ERROR'). */\n public readonly code: string;\n /** Original cause, if any. */\n public override readonly cause?: Error;\n\n constructor(code: string, message: string, cause?: Error) {\n super(message, { cause });\n this.name = this.constructor.name;\n this.code = code;\n this.cause = cause;\n }\n\n toJSON(): Record<string, unknown> {\n return {\n name: this.name,\n code: this.code,\n message: this.message,\n ...(this.cause ? { cause: this.cause.message } : {}),\n };\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class GongfengApiError extends AppError {\n public readonly statusCode: number;\n public readonly responseBody?: string;\n\n constructor(statusCode: number, message: string, responseBody?: string) {\n super('GONGFENG_API_ERROR', message);\n this.statusCode = statusCode;\n this.responseBody = responseBody;\n }\n\n /** Whether this error is potentially retryable (5xx or network). */\n get isRetryable(): boolean {\n return this.statusCode >= 500 || this.statusCode === 0;\n }\n}\n\nexport class GongfengUploadError extends GongfengApiError {\n constructor(statusCode: number, message: string, responseBody?: string) {\n super(statusCode, message, responseBody);\n this.name = 'GongfengUploadError';\n // Override code\n Object.defineProperty(this, 'code', { value: 'GONGFENG_UPLOAD_ERROR' });\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class AIExecutionError extends AppError {\n public readonly phase: string;\n public readonly output?: string;\n public readonly exitCode?: number | null;\n public readonly isRetryable: boolean;\n\n constructor(phase: string, message: string, opts?: { output?: string; exitCode?: number | null; cause?: Error; isRetryable?: boolean }) {\n super('AI_EXECUTION_ERROR', message, opts?.cause);\n this.phase = phase;\n this.output = opts?.output;\n this.exitCode = opts?.exitCode;\n this.isRetryable = opts?.isRetryable ?? true;\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class IssueNotFoundError extends AppError {\n public readonly issueIid: number;\n constructor(issueIid: number) {\n super('ISSUE_NOT_FOUND', `Issue ${issueIid} not found in tracker`);\n this.issueIid = issueIid;\n }\n}\n\nexport class BatchNotFoundError extends AppError {\n public readonly batchId: string;\n constructor(batchId: string) {\n super('BATCH_NOT_FOUND', `Braindump batch not found: ${batchId}`);\n this.batchId = batchId;\n }\n}\n\nexport class SessionNotFoundError extends AppError {\n public readonly sessionId: string;\n constructor(sessionId: string) {\n super('SESSION_NOT_FOUND', `Chat session not found: ${sessionId}`);\n this.sessionId = sessionId;\n }\n}\n\nexport class TaskNotFoundError extends AppError {\n public readonly taskId: string;\n constructor(taskId: string) {\n super('TASK_NOT_FOUND', `Braindump task not found: ${taskId}`);\n this.taskId = taskId;\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class InvalidPhaseError extends AppError {\n public readonly phase: string;\n constructor(phase: string, message?: string) {\n super('INVALID_PHASE', message ?? `Invalid phase for retry: ${phase}`);\n this.phase = phase;\n }\n}\n\nexport class InvalidStateError extends AppError {\n public readonly state: string;\n constructor(state: string, message?: string) {\n super('INVALID_STATE', message ?? `Invalid state: ${state}`);\n this.state = state;\n }\n}\n\nexport class PortExhaustionError extends AppError {\n constructor(message?: string) {\n super('PORT_EXHAUSTION', message ?? 'No available ports in the configured range');\n }\n}\n\nexport class SessionLimitError extends AppError {\n public readonly limit: number;\n constructor(limit: number) {\n super('SESSION_LIMIT', `Session message limit reached (${limit})`);\n this.limit = limit;\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class ServiceShutdownError extends AppError {\n constructor() {\n super('SERVICE_SHUTDOWN', 'Service shutting down');\n }\n}\n","import { AppError } from './BaseError.js';\n\n/**\n * 用户主动中止/重做阶段时抛出,中断 PhaseLoopStep 循环。\n *\n * 在 PipelineOrchestrator 的 catch 块中被特殊处理,\n * 不会进入 handleFailure 路径。\n */\nexport class PhaseAbortedError extends AppError {\n public readonly phaseName: string;\n public readonly action: 'abort' | 'redo';\n\n constructor(phaseName: string, action: 'abort' | 'redo') {\n super('PHASE_ABORTED', `Phase '${phaseName}' interrupted by user action '${action}'`);\n this.phaseName = phaseName;\n this.action = action;\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class AIOutputParseError extends AppError {\n public readonly rawOutput?: string;\n constructor(message: string, rawOutput?: string) {\n super('AI_OUTPUT_PARSE_ERROR', message);\n this.rawOutput = rawOutput;\n }\n}\n","import { AppError } from './BaseError.js';\n\nexport class PhaseNotRegisteredError extends AppError {\n public readonly phaseName: string;\n public readonly registeredPhases: string[];\n constructor(phaseName: string, registeredPhases: string[]) {\n super(\n 'PHASE_NOT_REGISTERED',\n `Unknown phase: ${phaseName}. Registered phases: ${registeredPhases.join(', ')}`,\n );\n this.phaseName = phaseName;\n this.registeredPhases = registeredPhases;\n }\n}\n\nexport class RunnerNotRegisteredError extends AppError {\n public readonly mode: string;\n public readonly registeredModes: string[];\n constructor(mode: string, registeredModes: string[]) {\n super(\n 'RUNNER_NOT_REGISTERED',\n `Unknown AI runner mode: ${mode}. Registered modes: ${registeredModes.join(', ')}`,\n );\n this.mode = mode;\n this.registeredModes = registeredModes;\n }\n}\n\nexport class PipelineNotFoundError extends AppError {\n public readonly pipelineMode: string;\n constructor(pipelineMode: string) {\n super('PIPELINE_NOT_FOUND', `Unknown pipeline mode: ${pipelineMode}`);\n this.pipelineMode = pipelineMode;\n }\n}\n\nexport class UnregisteredPhasesError extends AppError {\n public readonly missingPhases: string[];\n public readonly registeredPhases: string[];\n constructor(missingPhases: string[], registeredPhases: string[]) {\n super(\n 'UNREGISTERED_PHASES',\n `Pipeline defines unregistered phases: ${missingPhases.join(', ')}. Registered: ${registeredPhases.join(', ')}`,\n );\n this.missingPhases = missingPhases;\n this.registeredPhases = registeredPhases;\n }\n}\n"],"mappings":"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","names":["logger","logger","spawn","logger","SIGKILL_GRACE_MS","IDLE_CHECK_INTERVAL_MS","spawn","spawn","spawn"]}
@@ -1 +0,0 @@
1
- //# sourceMappingURL=chunk-DADQSKPL.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/config.ts","../src/config-schema.ts"],"sourcesContent":["import { config as loadDotenv } from 'dotenv';\nimport path from 'node:path';\nimport fs from 'node:fs';\nimport { fileURLToPath } from 'node:url';\nimport {\n envSchema,\n extractEnvSubset,\n transformEnvToConfig,\n ConfigValidationError,\n} from './config-schema.js';\nimport { getGlobalDir } from './paths.js';\n\nexport type {\n Config,\n AIRunnerMode,\n BrainstormAgentConfig,\n ChatAgentConfig,\n // Sub-type aliases for interface segregation\n GongfengConfig,\n ProjectConfig,\n AIConfig,\n PollConfig,\n PipelineConfig,\n ReviewConfig,\n WebConfig,\n IssueNoteSyncConfig,\n WebhookConfig,\n E2eConfig,\n PreviewConfig,\n BrainstormConfig,\n ChatConfig,\n BraindumpConfig,\n AutoUpdateConfig,\n IWikiConfig,\n KnowledgeConfig,\n DistillConfig,\n SyncConfig,\n WorkspaceEnvConfig,\n} from './config-schema.js';\nexport { ConfigValidationError } from './config-schema.js';\n\nconst __dirname = path.dirname(fileURLToPath(import.meta.url));\n\n/**\n * Resolve the path to the .env configuration file.\n *\n * Priority (first match wins):\n * 1. Explicit `configPath` argument (e.g. --config CLI flag)\n * 2. `IAF_CONFIG_PATH` environment variable\n * 3. Source-mode: `.env` next to compiled output (`dist/../.env`)\n * 4. Global config written by `issue-auto-finish init` (`{IAF_HOME}/.env`)\n * 5. CWD `.env` (legacy / manual setup)\n * 6. Fallback: global path (even if it doesn't exist yet)\n *\n * `IAF_HOME` defaults to `~/.issue-auto-finish` and can be overridden via env.\n *\n * This is the **single source of truth** for .env path resolution.\n * CLI commands and route handlers should call this instead of\n * rolling their own lookup logic.\n */\nexport function resolveConfigFilePath(configPath?: string): string {\n if (configPath) return configPath;\n if (process.env.IAF_CONFIG_PATH) return process.env.IAF_CONFIG_PATH;\n\n // Source-mode: .env next to the compiled output\n const localEnv = path.resolve(__dirname, '../.env');\n if (fs.existsSync(localEnv)) return localEnv;\n\n // Global config written by `issue-auto-finish init`\n // Checked before CWD to avoid picking up unrelated project .env files\n const globalEnv = path.join(getGlobalDir(), '.env');\n if (fs.existsSync(globalEnv)) return globalEnv;\n\n // Fallback: CWD .env (legacy / manual setup)\n const cwdEnv = path.resolve(process.cwd(), '.env');\n if (fs.existsSync(cwdEnv)) return cwdEnv;\n\n return globalEnv;\n}\n\nlet _dotenvLoaded = false;\nfunction ensureDotenvLoaded(): void {\n if (_dotenvLoaded) return;\n _dotenvLoaded = true;\n loadDotenv({ path: resolveConfigFilePath() });\n}\n\nexport function loadConfig() {\n ensureDotenvLoaded();\n\n const subset = extractEnvSubset(process.env);\n const result = envSchema.safeParse(subset);\n\n if (!result.success) {\n throw new ConfigValidationError(result.error);\n }\n\n return transformEnvToConfig(result.data, __dirname);\n}\n\n/**\n * Reset dotenv cache so the next loadConfig() re-reads the .env file.\n */\nexport function resetDotenvCache(): void {\n _dotenvLoaded = false;\n}\n\n/**\n * Reload config from .env file.\n * Clears dotenv cache, removes stale IAF env vars from process.env,\n * then re-reads and re-parses everything.\n */\nexport function reloadConfig() {\n resetDotenvCache();\n // Clear process.env of IAF-related keys so dotenv can overwrite them\n const iafKeys = extractEnvSubset(process.env);\n for (const key of Object.keys(iafKeys)) {\n delete process.env[key];\n }\n return loadConfig();\n}\n","/**\n * Zod-based configuration schema and transformation layer.\n *\n * Architecture:\n * process.env → extractEnvSubset() → envSchema.safeParse() → transformEnvToConfig() → Config\n *\n * The schema is kept flat (keys = env var names) so that validation errors\n * directly reference environment variable names without extra mapping.\n */\nimport { z } from 'zod';\nimport { getDefaultBinary, getBinaryEnvKey } from './ai-runner/AIRunnerRegistry.js';\nimport { getLocalIP } from './utils/network.js';\nimport path from 'node:path';\n\n// ---------------------------------------------------------------------------\n// Reusable zod helpers\n// ---------------------------------------------------------------------------\n\n/** Boolean env var: only `'true'` (case-sensitive) is truthy. */\nfunction envBoolean(defaultValue: string = 'false') {\n return z\n .string()\n .optional()\n .default(defaultValue)\n .transform((v) => v === 'true');\n}\n\n/** Integer env var with optional min/max bounds. */\nfunction envInt(defaultValue: string, opts?: { min?: number; max?: number }) {\n let schema = z.coerce.number().int();\n if (opts?.min !== undefined) schema = schema.min(opts.min);\n if (opts?.max !== undefined) schema = schema.max(opts.max);\n return schema.optional().default(Number(defaultValue));\n}\n\n/** Port number: integer 1–65535. */\nfunction envPort(defaultValue: string) {\n return z.coerce\n .number()\n .int()\n .min(1, 'Port must be >= 1')\n .max(65535, 'Port must be <= 65535')\n .optional()\n .default(Number(defaultValue));\n}\n\n/** Millisecond duration: integer >= 1000. */\nfunction envMs(defaultValue: string) {\n return z.coerce\n .number()\n .int()\n .min(1000, 'Duration must be >= 1000ms')\n .optional()\n .default(Number(defaultValue));\n}\n\n// ---------------------------------------------------------------------------\n// Flat environment schema\n// ---------------------------------------------------------------------------\n\nexport const envSchema = z.object({\n // --- Required ---\n GONGFENG_API_URL: z.string().url('GONGFENG_API_URL must be a valid URL'),\n GONGFENG_PRIVATE_TOKEN: z.string().min(1, 'GONGFENG_PRIVATE_TOKEN is required'),\n GONGFENG_PROJECT_PATH: z.string().min(1, 'GONGFENG_PROJECT_PATH is required'),\n PROJECT_WORK_DIR: z.string().min(1, 'PROJECT_WORK_DIR is required'),\n\n // --- Paths (override auto-detected data/logs directories) ---\n DATA_DIR: z.string().optional(),\n LOGS_DIR: z.string().optional(),\n\n // --- Project ---\n GIT_ROOT_DIR: z.string().optional(),\n BASE_BRANCH: z.string().optional().default('master'),\n BRANCH_PREFIX: z.string().optional().default('feat/issue'),\n WORKTREE_BASE_DIR: z.string().optional().default(''),\n PROJECT_SUBDIR: z.string().optional().default(''),\n\n // --- AI ---\n AI_RUNNER_MODE: z\n .string()\n .optional()\n .default('claude-internal'),\n AI_MODEL: z.string().optional().default('Claude-4.6-Opus'),\n CLAUDE_BINARY: z.string().optional(),\n CURSOR_BINARY: z.string().optional(),\n CODEBUDDY_BINARY: z.string().optional(),\n CODEBUDDY_ACP_AUTO_APPROVE: envBoolean('true'),\n CLAUDE_PHASE_TIMEOUT_MS: envMs('1800000'),\n AI_IDLE_TIMEOUT_MS: z.coerce\n .number()\n .int()\n .min(0, 'AI_IDLE_TIMEOUT_MS must be >= 0 (0 to disable)')\n .optional()\n .default(1200000),\n NVM_NODE_VERSION: z.string().optional().default('20'),\n\n // --- Pipeline ---\n PIPELINE_MODE: z\n .string()\n .optional()\n .default('auto'),\n\n // --- Poll ---\n POLL_DISCOVERY_INTERVAL_MS: envMs('60000'),\n POLL_DRIVE_INTERVAL_MS: envMs('15000'),\n MAX_RETRIES: envInt('3', { min: 0, max: 100 }),\n MAX_CONCURRENT_ISSUES: envInt('3', { min: 1 }),\n\n // --- Review ---\n REVIEW_ENABLED: envBoolean('true'),\n REVIEW_AUTO_APPROVE_LABELS: z.string().optional().default(''),\n\n // --- Web ---\n WEB_ENABLED: envBoolean('true'),\n WEB_HOST: z.string().optional().default('0.0.0.0'),\n WEB_PORT: envPort('3000'),\n FRONTEND_DIST_DIR: z.string().optional(),\n\n // --- Issue Note Sync ---\n ISSUE_NOTE_SYNC_ENABLED: envBoolean('true'),\n WEB_BASE_URL: z.string().optional(),\n\n // --- Webhook ---\n WEBHOOK_ENABLED: envBoolean('false'),\n WEBHOOK_HOST: z.string().optional().default('0.0.0.0'),\n WEBHOOK_PORT: envPort('8081'),\n WEBHOOK_SECRET: z.string().optional().default(''),\n WEBHOOK_LLM_FALLBACK: envBoolean('true'),\n WEBHOOK_LLM_BINARY: z.string().optional().default('claude-internal'),\n\n // --- E2E ---\n E2E_UI_ENABLED: envBoolean('false'),\n E2E_BASE_URL: z.string().optional().default('https://localhost:8890'),\n E2E_BACKEND_URL: z.string().optional().default('http://127.0.0.1:3000'),\n E2E_AUTH_COOKIES: z.string().optional().default('[]'),\n E2E_BACKEND_PORT_BASE: envPort('4000'),\n E2E_FRONTEND_PORT_BASE: envPort('9000'),\n E2E_UAT_VENDOR_DIR: z.string().optional().default(''),\n E2E_UAT_CONFIG_FILE: z.string().optional().default(''),\n E2E_PYTHON_BIN: z.string().optional().default('python3'),\n E2E_AI_RUNNER_MODE: z.string().optional().default('codebuddy'),\n E2E_AI_MODEL: z.string().optional(),\n\n // --- Preview ---\n PREVIEW_ENABLED: envBoolean('false'),\n PREVIEW_HOST: z.string().optional().default(''),\n PREVIEW_TTL_MS: envMs(String(24 * 60 * 60 * 1000)),\n PREVIEW_KEEP_AFTER_COMPLETE: envBoolean('false'),\n PREVIEW_REAP_INTERVAL_MS: envMs('300000'),\n\n // --- Brainstorm ---\n BRAINSTORM_ENABLED: envBoolean('false'),\n BRAINSTORM_MAX_ROUNDS: envInt('5', { min: 1, max: 20 }),\n BRAINSTORM_TIMEOUT_MS: envMs('600000'),\n BRAINSTORM_GENERATOR_MODE: z\n .string()\n .optional(),\n BRAINSTORM_GENERATOR_BINARY: z.string().optional(),\n BRAINSTORM_GENERATOR_MODEL: z.string().optional(),\n BRAINSTORM_REVIEWER_MODE: z\n .string()\n .optional(),\n BRAINSTORM_REVIEWER_BINARY: z.string().optional(),\n BRAINSTORM_REVIEWER_MODEL: z.string().optional(),\n\n // --- Chat ---\n CHAT_ENABLED: envBoolean('false'),\n CHAT_TIMEOUT_MS: envMs('300000'),\n CHAT_MAX_SESSION_MESSAGES: envInt('100', { min: 1 }),\n CHAT_AGENT_MODE: z\n .string()\n .optional(),\n CHAT_AGENT_BINARY: z.string().optional(),\n CHAT_AGENT_MODEL: z.string().optional(),\n\n // --- Braindump ---\n BRAINDUMP_ENABLED: envBoolean('false'),\n BRAINDUMP_MAX_CONCURRENT: z.coerce.number().int().min(1).optional(),\n BRAINDUMP_SPLIT_TIMEOUT_MS: envMs('300000'),\n BRAINDUMP_TASK_TIMEOUT_MS: z.coerce.number().int().min(1000).optional(),\n BRAINDUMP_MAX_CONFLICT_ATTEMPTS: envInt('20', { min: 1 }),\n BRAINDUMP_CREATE_MR: envBoolean('false'),\n\n // --- Auto Update ---\n AUTO_UPDATE_ENABLED: envBoolean('true'),\n AUTO_UPDATE_INTERVAL_MS: envMs('600000'),\n AUTO_UPDATE_REGISTRY: z\n .string()\n .url('AUTO_UPDATE_REGISTRY must be a valid URL')\n .optional()\n .default('https://registry.npmjs.org'),\n AUTO_UPDATE_DRAIN_TIMEOUT_MS: envMs('300000'),\n\n // --- iWiki ---\n IWIKI_AUTH_COOKIE: z.string().optional(),\n IWIKI_AUTH_TOKEN: z.string().optional(),\n IWIKI_BASE_URL: z.string().optional(),\n\n // --- Locale ---\n LOCALE: z.enum(['zh-CN', 'en']).optional().default('zh-CN'),\n\n // --- Knowledge ---\n KNOWLEDGE_ENABLED: envBoolean('false'),\n KNOWLEDGE_PATH: z.string().optional(),\n KNOWLEDGE_ORPHAN_BRANCH: z.string().optional().default('iaf/knowledge'),\n KNOWLEDGE_SYNC_VECTORS: envBoolean('false'),\n KNOWLEDGE_AUTO_RESTORE: envBoolean('true'),\n\n // --- Distill (知识蒸馏) ---\n DISTILL_ENABLED: envBoolean('false'),\n DISTILL_INTERVAL_MS: envMs('86400000'),\n DISTILL_DIARY_SUMMARIZE: envBoolean('false'),\n DISTILL_MIN_DIARIES_FOR_DISTILL: envInt('3', { min: 1 }),\n DISTILL_MEMORY_CONFIDENCE_THRESHOLD: z.coerce.number().min(0).max(1).optional().default(0.7),\n DISTILL_VECTOR_ENABLED: envBoolean('true'),\n\n // --- Sync (生成文件同步到目标项目) ---\n SYNC_KNOWLEDGE_TO_PROJECT: envBoolean('false'),\n SYNC_RULES_TO_PROJECT: envBoolean('false'),\n\n // --- Release (发布) ---\n RELEASE_ENABLED: envBoolean('false'),\n RELEASE_DETECT_CACHE_TTL_MS: envMs('604800000'),\n\n // --- Verify-Fix Loop (验证-修复循环) ---\n VERIFY_FIX_LOOP_ENABLED: envBoolean('true'),\n VERIFY_FIX_MAX_ITERATIONS: envInt('3', { min: 1, max: 10 }),\n VERIFY_TODOLIST_CHECK_ENABLED: envBoolean('true'),\n\n // --- Analytics (运营分析) ---\n ANALYTICS_ENABLED: envBoolean('false'),\n ANALYTICS_TARGET_API_URL: z.string().url().optional(),\n ANALYTICS_TARGET_API_TOKEN: z.string().optional(),\n ANALYTICS_CACHE_TTL_MS: envMs('300000'),\n ANALYTICS_SKILL_AUTO_DISCOVER: envBoolean('true'),\n\n // --- Coordination (多节点协调) ---\n NODE_ID: z.string().optional(),\n\n // --- Workspace (多仓库) ---\n WORKSPACE_CONFIG_PATH: z.string().optional(),\n\n // --- Tenants (多租户) ---\n TENANTS_CONFIG_PATH: z.string().optional(),\n});\n\nexport type ParsedEnv = z.infer<typeof envSchema>;\n\n// ---------------------------------------------------------------------------\n// Extract env subset\n// ---------------------------------------------------------------------------\n\n/**\n * Picks only the keys declared in `envSchema` from the given env object.\n * Empty strings are converted to `undefined` to preserve the existing\n * \"empty = unset\" behavior.\n */\nexport function extractEnvSubset(\n env: Record<string, string | undefined>,\n): Record<string, string | undefined> {\n const keys = Object.keys(envSchema.shape) as (keyof typeof envSchema.shape)[];\n const subset: Record<string, string | undefined> = {};\n for (const key of keys) {\n const val = env[key as string];\n subset[key as string] = val || undefined; // empty string → undefined\n }\n return subset;\n}\n\n// ---------------------------------------------------------------------------\n// AI Runner helpers\n// ---------------------------------------------------------------------------\n\nexport type AIRunnerMode = string;\n\nfunction resolveAIBinary(\n mode: AIRunnerMode,\n env: ParsedEnv,\n): string {\n const envKey = getBinaryEnvKey(mode);\n if (envKey) {\n const envVal = (env as Record<string, unknown>)[envKey];\n if (typeof envVal === 'string' && envVal) return envVal;\n }\n return getDefaultBinary(mode);\n}\n\nexport interface BrainstormAgentConfig {\n mode: AIRunnerMode;\n binary: string;\n nvmNodeVersion: string;\n model?: string;\n}\n\nexport type ChatAgentConfig = BrainstormAgentConfig;\n\nfunction buildBrainstormAgent(\n role: 'GENERATOR' | 'REVIEWER',\n env: ParsedEnv,\n): BrainstormAgentConfig {\n const roleMode =\n (role === 'GENERATOR' ? env.BRAINSTORM_GENERATOR_MODE : env.BRAINSTORM_REVIEWER_MODE) ??\n env.AI_RUNNER_MODE;\n return {\n mode: roleMode,\n binary:\n (role === 'GENERATOR' ? env.BRAINSTORM_GENERATOR_BINARY : env.BRAINSTORM_REVIEWER_BINARY) ??\n resolveAIBinary(roleMode, env),\n nvmNodeVersion: env.NVM_NODE_VERSION,\n model:\n (role === 'GENERATOR' ? env.BRAINSTORM_GENERATOR_MODEL : env.BRAINSTORM_REVIEWER_MODEL) ??\n env.AI_MODEL,\n };\n}\n\nfunction buildChatAgent(env: ParsedEnv): ChatAgentConfig {\n // Chat defaults to claude-internal for lightweight conversational use,\n // independent of the global AI_RUNNER_MODE (which may be cursor-agent).\n const chatMode = env.CHAT_AGENT_MODE ?? 'claude-internal';\n return {\n mode: chatMode,\n binary: env.CHAT_AGENT_BINARY ?? resolveAIBinary(chatMode, env),\n nvmNodeVersion: env.NVM_NODE_VERSION,\n model: env.CHAT_AGENT_MODEL ?? env.AI_MODEL,\n };\n}\n\n// ---------------------------------------------------------------------------\n// Transform parsed env → nested Config\n// ---------------------------------------------------------------------------\n\nexport function transformEnvToConfig(env: ParsedEnv, dirname: string) {\n const aiMode = env.AI_RUNNER_MODE;\n const webPort = env.WEB_PORT;\n\n const gitRootDir = env.GIT_ROOT_DIR ?? env.PROJECT_WORK_DIR;\n\n return {\n gongfeng: {\n apiUrl: env.GONGFENG_API_URL,\n privateToken: env.GONGFENG_PRIVATE_TOKEN,\n projectPath: env.GONGFENG_PROJECT_PATH,\n },\n project: {\n workDir: env.PROJECT_WORK_DIR,\n gitRootDir,\n baseBranch: env.BASE_BRANCH,\n branchPrefix: env.BRANCH_PREFIX,\n worktreeBaseDir: env.WORKTREE_BASE_DIR,\n projectSubDir: env.PROJECT_SUBDIR,\n },\n ai: {\n mode: aiMode,\n binary: resolveAIBinary(aiMode, env),\n phaseTimeoutMs: env.CLAUDE_PHASE_TIMEOUT_MS,\n idleTimeoutMs: env.AI_IDLE_TIMEOUT_MS || undefined,\n nvmNodeVersion: env.NVM_NODE_VERSION,\n model: env.AI_MODEL,\n codebuddyAcpAutoApprove: env.CODEBUDDY_ACP_AUTO_APPROVE,\n },\n poll: {\n discoveryIntervalMs: env.POLL_DISCOVERY_INTERVAL_MS,\n driveIntervalMs: env.POLL_DRIVE_INTERVAL_MS,\n maxRetries: env.MAX_RETRIES,\n maxConcurrent: env.MAX_CONCURRENT_ISSUES,\n },\n pipeline: {\n mode: env.PIPELINE_MODE,\n },\n review: {\n enabled: env.REVIEW_ENABLED,\n autoApproveLabels: env.REVIEW_AUTO_APPROVE_LABELS\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean),\n },\n web: {\n enabled: env.WEB_ENABLED,\n host: env.WEB_HOST,\n port: webPort,\n frontendDistDir:\n env.FRONTEND_DIST_DIR ??\n path.resolve(dirname, '..', 'src/web/frontend/dist'),\n },\n issueNoteSync: {\n enabled: env.ISSUE_NOTE_SYNC_ENABLED,\n webBaseUrl: env.WEB_BASE_URL ?? `http://${getLocalIP()}:${webPort}`,\n },\n webhook: {\n enabled: env.WEBHOOK_ENABLED,\n host: env.WEBHOOK_HOST,\n port: env.WEBHOOK_PORT,\n secret: env.WEBHOOK_SECRET,\n llmFallback: env.WEBHOOK_LLM_FALLBACK,\n llmBinary: env.WEBHOOK_LLM_BINARY,\n },\n e2e: {\n enabled: env.E2E_UI_ENABLED,\n baseUrl: env.E2E_BASE_URL,\n backendUrl: env.E2E_BACKEND_URL,\n authCookies: env.E2E_AUTH_COOKIES,\n backendPortBase: env.E2E_BACKEND_PORT_BASE,\n frontendPortBase: env.E2E_FRONTEND_PORT_BASE,\n uatVendorDir: env.E2E_UAT_VENDOR_DIR,\n uatConfigFile: env.E2E_UAT_CONFIG_FILE,\n pythonBin: env.E2E_PYTHON_BIN,\n aiRunnerMode: env.E2E_AI_RUNNER_MODE,\n aiModel: env.E2E_AI_MODEL,\n },\n preview: {\n enabled: env.PREVIEW_ENABLED,\n host: env.PREVIEW_HOST,\n ttlMs: env.PREVIEW_TTL_MS,\n keepAfterComplete: env.PREVIEW_KEEP_AFTER_COMPLETE,\n reapIntervalMs: env.PREVIEW_REAP_INTERVAL_MS,\n },\n brainstorm: {\n enabled: env.BRAINSTORM_ENABLED,\n maxRefinementRounds: env.BRAINSTORM_MAX_ROUNDS,\n timeoutMs: env.BRAINSTORM_TIMEOUT_MS,\n generator: buildBrainstormAgent('GENERATOR', env),\n reviewer: buildBrainstormAgent('REVIEWER', env),\n },\n chat: {\n enabled: env.CHAT_ENABLED,\n timeoutMs: env.CHAT_TIMEOUT_MS,\n maxSessionMessages: env.CHAT_MAX_SESSION_MESSAGES,\n agent: buildChatAgent(env),\n },\n braindump: {\n enabled: env.BRAINDUMP_ENABLED,\n maxConcurrent: env.BRAINDUMP_MAX_CONCURRENT ?? env.MAX_CONCURRENT_ISSUES,\n splitTimeoutMs: env.BRAINDUMP_SPLIT_TIMEOUT_MS,\n taskTimeoutMs: env.BRAINDUMP_TASK_TIMEOUT_MS ?? env.CLAUDE_PHASE_TIMEOUT_MS,\n maxConflictAttempts: env.BRAINDUMP_MAX_CONFLICT_ATTEMPTS,\n createMr: env.BRAINDUMP_CREATE_MR,\n },\n autoUpdate: {\n enabled: env.AUTO_UPDATE_ENABLED,\n intervalMs: env.AUTO_UPDATE_INTERVAL_MS,\n registry: env.AUTO_UPDATE_REGISTRY,\n drainTimeoutMs: env.AUTO_UPDATE_DRAIN_TIMEOUT_MS,\n },\n iwiki: {\n authCookie: env.IWIKI_AUTH_COOKIE,\n authToken: env.IWIKI_AUTH_TOKEN,\n baseUrl: env.IWIKI_BASE_URL,\n },\n locale: env.LOCALE,\n knowledge: {\n enabled: env.KNOWLEDGE_ENABLED,\n path: env.KNOWLEDGE_PATH,\n orphanBranch: env.KNOWLEDGE_ORPHAN_BRANCH,\n syncVectors: env.KNOWLEDGE_SYNC_VECTORS,\n autoRestore: env.KNOWLEDGE_AUTO_RESTORE,\n },\n distill: {\n enabled: env.DISTILL_ENABLED,\n intervalMs: env.DISTILL_INTERVAL_MS,\n diarySummarize: env.DISTILL_DIARY_SUMMARIZE,\n minDiariesForDistill: env.DISTILL_MIN_DIARIES_FOR_DISTILL,\n memoryConfidenceThreshold: env.DISTILL_MEMORY_CONFIDENCE_THRESHOLD,\n vectorEnabled: env.DISTILL_VECTOR_ENABLED,\n },\n coordination: {\n nodeId: env.NODE_ID,\n },\n sync: {\n knowledgeToProject: env.SYNC_KNOWLEDGE_TO_PROJECT,\n rulesToProject: env.SYNC_RULES_TO_PROJECT,\n },\n release: {\n enabled: env.RELEASE_ENABLED,\n detectCacheTtlMs: env.RELEASE_DETECT_CACHE_TTL_MS,\n },\n verifyFixLoop: {\n enabled: env.VERIFY_FIX_LOOP_ENABLED,\n maxIterations: env.VERIFY_FIX_MAX_ITERATIONS,\n todolistCheckEnabled: env.VERIFY_TODOLIST_CHECK_ENABLED,\n },\n analytics: {\n enabled: env.ANALYTICS_ENABLED,\n targetApiUrl: env.ANALYTICS_TARGET_API_URL,\n targetApiToken: env.ANALYTICS_TARGET_API_TOKEN,\n cacheTtlMs: env.ANALYTICS_CACHE_TTL_MS,\n skillAutoDiscover: env.ANALYTICS_SKILL_AUTO_DISCOVER,\n },\n workspace: {\n configPath: env.WORKSPACE_CONFIG_PATH,\n },\n tenants: {\n configPath: env.TENANTS_CONFIG_PATH,\n },\n } as const;\n}\n\n// ---------------------------------------------------------------------------\n// Config type (derived from transform)\n// ---------------------------------------------------------------------------\n\n// We use a widened version so the type is writable and compatible with existing\n// code that assigns to Config properties.\ntype TransformResult = ReturnType<typeof transformEnvToConfig>;\n\n// Deeply writable version of the transform result\ntype DeepWritable<T> = {\n -readonly [K in keyof T]: T[K] extends object ? DeepWritable<T[K]> : T[K];\n};\n\nexport type Config = DeepWritable<TransformResult>;\n\n// ---------------------------------------------------------------------------\n// Sub-type aliases for interface segregation\n// ---------------------------------------------------------------------------\n\n/** Gongfeng API connection settings. */\nexport type GongfengConfig = Config['gongfeng'];\n/** Project / repository settings. */\nexport type ProjectConfig = Config['project'];\n/** AI runner settings. */\nexport type AIConfig = Config['ai'];\n/** Polling intervals and concurrency limits. */\nexport type PollConfig = Config['poll'];\n/** Pipeline mode settings. */\nexport type PipelineConfig = Config['pipeline'];\n/** Review / gate settings. */\nexport type ReviewConfig = Config['review'];\n/** Web dashboard settings. */\nexport type WebConfig = Config['web'];\n/** Issue note-sync settings. */\nexport type IssueNoteSyncConfig = Config['issueNoteSync'];\n/** Webhook settings. */\nexport type WebhookConfig = Config['webhook'];\n/** E2E test settings. */\nexport type E2eConfig = Config['e2e'];\n/** Preview environment settings. */\nexport type PreviewConfig = Config['preview'];\n/** Brainstorm agent settings. */\nexport type BrainstormConfig = Config['brainstorm'];\n/** Chat agent settings. */\nexport type ChatConfig = Config['chat'];\n/** Braindump batch settings. */\nexport type BraindumpConfig = Config['braindump'];\n/** Auto-update settings. */\nexport type AutoUpdateConfig = Config['autoUpdate'];\n/** iWiki settings. */\nexport type IWikiConfig = Config['iwiki'];\n/** Knowledge settings. */\nexport type KnowledgeConfig = Config['knowledge'];\n/** Distill (knowledge distillation) settings. */\nexport type DistillConfig = Config['distill'];\n/** Coordination (multi-node claiming) settings. */\nexport type CoordinationConfig = Config['coordination'];\n/** Sync (generated files sync to project) settings. */\nexport type SyncConfig = Config['sync'];\n/** Verify-fix loop settings. */\nexport type VerifyFixLoopConfig = Config['verifyFixLoop'];\n/** Release (发布) settings. */\nexport type ReleaseConfig = Config['release'];\n/** Analytics (operational analysis) settings. */\nexport type AnalyticsConfig = Config['analytics'];\n/** Workspace (multi-repo) settings. */\nexport type WorkspaceEnvConfig = Config['workspace'];\n/** Tenants (multi-tenant) settings. */\nexport type TenantsEnvConfig = Config['tenants'];\n\n// ---------------------------------------------------------------------------\n// ConfigValidationError\n// ---------------------------------------------------------------------------\n\nexport class ConfigValidationError extends Error {\n public readonly issues: z.ZodIssue[];\n\n constructor(zodError: z.ZodError) {\n const lines = zodError.issues.map((issue) => {\n const envVar = issue.path.length > 0 ? issue.path.join('.') : '(root)';\n return ` - ${envVar}: ${issue.message}`;\n });\n super(\n `Configuration validation failed:\\n${lines.join('\\n')}`,\n );\n this.name = 'ConfigValidationError';\n this.issues = zodError.issues;\n }\n}\n"],"mappings":"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","names":["path","path"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/cli/setup/PreflightChecker.ts","../src/cli/setup/ConfigGenerator.ts","../src/cli/setup/env-metadata.ts"],"sourcesContent":["/**\n * Preflight checker — validates environment before first `start`.\n *\n * Runs a battery of checks (git repo, branches, AI auth, Gongfeng creds,\n * port availability) and returns structured results so the init wizard and\n * CLI `start` command can surface actionable errors.\n */\n\nimport fs from 'node:fs';\nimport net from 'node:net';\nimport { spawn } from 'node:child_process';\nimport type { SetupConfig } from './ConfigGenerator.js';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport type CheckSeverity = 'error' | 'warn';\n\nexport interface PreflightResult {\n name: string;\n passed: boolean;\n severity: CheckSeverity;\n message: string;\n fix?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction run(cmd: string, args: string[], opts?: { cwd?: string; timeoutMs?: number }): Promise<{ code: number; stdout: string; stderr: string }> {\n return new Promise((resolve) => {\n const proc = spawn(cmd, args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n cwd: opts?.cwd,\n });\n\n let stdout = '';\n let stderr = '';\n proc.stdout.on('data', (d: Buffer) => { stdout += d.toString(); });\n proc.stderr.on('data', (d: Buffer) => { stderr += d.toString(); });\n\n const timer = setTimeout(() => {\n proc.kill('SIGTERM');\n }, opts?.timeoutMs ?? 15_000);\n\n proc.on('close', (code) => {\n clearTimeout(timer);\n resolve({ code: code ?? 1, stdout: stdout.trim(), stderr: stderr.trim() });\n });\n proc.on('error', () => {\n clearTimeout(timer);\n resolve({ code: 1, stdout: '', stderr: 'spawn error' });\n });\n });\n}\n\nfunction checkPortAvailable(port: number): Promise<boolean> {\n return new Promise((resolve) => {\n const server = net.createServer();\n server.once('error', () => resolve(false));\n server.once('listening', () => {\n server.close(() => resolve(true));\n });\n server.listen(port, '0.0.0.0');\n });\n}\n\n// ---------------------------------------------------------------------------\n// PreflightChecker\n// ---------------------------------------------------------------------------\n\nexport class PreflightChecker {\n constructor(private config: SetupConfig) {}\n\n async runAll(): Promise<PreflightResult[]> {\n const checks = await Promise.all([\n this.checkGitRepo(),\n this.checkOriginRemote(),\n this.checkBaseBranch(),\n this.checkWorktreeDir(),\n this.checkAIRunnerBinary(),\n this.checkGongfengToken(),\n this.checkGongfengProject(),\n this.checkWebPort(),\n ]);\n return checks;\n }\n\n hasErrors(results: PreflightResult[]): boolean {\n return results.some(r => !r.passed && r.severity === 'error');\n }\n\n // -------------------------------------------------------------------------\n // Individual checks\n // -------------------------------------------------------------------------\n\n async checkGitRepo(): Promise<PreflightResult> {\n const workDir = this.config.project.workDir;\n const gitDir = this.config.project.gitRootDir || workDir;\n\n if (!gitDir) {\n return { name: 'git-repo', passed: false, severity: 'error', message: 'PROJECT_WORK_DIR 未设置' };\n }\n\n if (!fs.existsSync(gitDir)) {\n return {\n name: 'git-repo', passed: false, severity: 'error',\n message: `目录不存在: ${gitDir}`,\n fix: `请创建目录或检查 PROJECT_WORK_DIR / GIT_ROOT_DIR 配置`,\n };\n }\n\n const { code } = await run('git', ['-C', gitDir, 'rev-parse', '--git-dir']);\n if (code !== 0) {\n return {\n name: 'git-repo', passed: false, severity: 'error',\n message: `${gitDir} 不是有效的 Git 仓库`,\n fix: `cd ${gitDir} && git init 或检查路径配置`,\n };\n }\n\n return { name: 'git-repo', passed: true, severity: 'error', message: 'Git 仓库有效' };\n }\n\n async checkOriginRemote(): Promise<PreflightResult> {\n const gitDir = this.config.project.gitRootDir || this.config.project.workDir;\n if (!gitDir || !fs.existsSync(gitDir)) {\n return { name: 'git-origin', passed: false, severity: 'error', message: '跳过 (Git 目录无效)' };\n }\n\n const { code, stdout } = await run('git', ['-C', gitDir, 'remote', 'get-url', 'origin']);\n if (code !== 0) {\n return {\n name: 'git-origin', passed: false, severity: 'error',\n message: '未找到 origin remote',\n fix: `git -C ${gitDir} remote add origin <仓库URL>`,\n };\n }\n\n return { name: 'git-origin', passed: true, severity: 'error', message: `origin: ${stdout.split('\\n')[0]}` };\n }\n\n async checkBaseBranch(): Promise<PreflightResult> {\n const gitDir = this.config.project.gitRootDir || this.config.project.workDir;\n const branch = this.config.project.baseBranch || 'master';\n\n if (!gitDir || !fs.existsSync(gitDir)) {\n return { name: 'base-branch', passed: false, severity: 'error', message: '跳过 (Git 目录无效)' };\n }\n\n // Check local branch first\n const { code: localCode } = await run('git', ['-C', gitDir, 'rev-parse', '--verify', branch]);\n if (localCode === 0) {\n return { name: 'base-branch', passed: true, severity: 'error', message: `分支 ${branch} 存在` };\n }\n\n // Check remote\n const { code: remoteCode } = await run('git', [\n '-C', gitDir, 'ls-remote', '--exit-code', '--heads', 'origin', branch,\n ]);\n if (remoteCode === 0) {\n return { name: 'base-branch', passed: true, severity: 'error', message: `远程分支 origin/${branch} 存在` };\n }\n\n return {\n name: 'base-branch', passed: false, severity: 'error',\n message: `分支 ${branch} 不存在 (本地和远程均未找到)`,\n fix: `请检查 BASE_BRANCH 配置,或执行 git fetch origin`,\n };\n }\n\n async checkWorktreeDir(): Promise<PreflightResult> {\n const dir = this.config.project.worktreeBaseDir;\n if (!dir) {\n return { name: 'worktree-dir', passed: true, severity: 'error', message: '使用默认 worktree 目录' };\n }\n\n if (!fs.existsSync(dir)) {\n // Try to create\n try {\n fs.mkdirSync(dir, { recursive: true });\n return { name: 'worktree-dir', passed: true, severity: 'error', message: `已创建 worktree 目录: ${dir}` };\n } catch {\n return {\n name: 'worktree-dir', passed: false, severity: 'error',\n message: `无法创建 worktree 目录: ${dir}`,\n fix: `请手动创建目录或检查权限`,\n };\n }\n }\n\n try {\n fs.accessSync(dir, fs.constants.W_OK);\n } catch {\n return {\n name: 'worktree-dir', passed: false, severity: 'error',\n message: `worktree 目录无写入权限: ${dir}`,\n fix: `chmod u+w ${dir}`,\n };\n }\n\n return { name: 'worktree-dir', passed: true, severity: 'error', message: `worktree 目录可写: ${dir}` };\n }\n\n async checkAIRunnerBinary(): Promise<PreflightResult> {\n const mode = this.config.ai.mode;\n const binaryMap: Record<string, string> = {\n 'claude-internal': 'claude-internal',\n 'cursor-agent': 'cursor-agent',\n 'codebuddy': 'codebuddy',\n };\n const binary = binaryMap[mode] ?? mode;\n\n const { code } = await run('which', [binary]);\n if (code !== 0) {\n const installHints: Record<string, string> = {\n 'claude-internal': 'npm install -g claude-code-internal',\n 'cursor-agent': 'curl -fsSL https://www.cursor.com/install-agent | bash',\n 'codebuddy': 'npm install -g codebuddy-code',\n };\n return {\n name: 'ai-runner', passed: false, severity: 'error',\n message: `AI Runner 二进制未找到: ${binary}`,\n fix: installHints[mode] ?? `请安装 ${binary} 并确保在 PATH 中`,\n };\n }\n\n return { name: 'ai-runner', passed: true, severity: 'error', message: `AI Runner 可用: ${binary}` };\n }\n\n async checkGongfengToken(): Promise<PreflightResult> {\n const { apiUrl, privateToken } = this.config.gongfeng;\n if (!apiUrl || !privateToken) {\n return {\n name: 'gongfeng-token', passed: false, severity: 'error',\n message: '工蜂 API URL 或 Token 未配置',\n fix: '请在配置中填写 GONGFENG_API_URL 和 GONGFENG_PRIVATE_TOKEN',\n };\n }\n\n try {\n const url = `${apiUrl.replace(/\\/$/, '')}/api/v3/user`;\n const response = await fetch(url, {\n headers: { 'PRIVATE-TOKEN': privateToken },\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n return {\n name: 'gongfeng-token', passed: false, severity: 'error',\n message: `工蜂 Token 验证失败 (HTTP ${response.status})`,\n fix: '请检查 GONGFENG_PRIVATE_TOKEN 是否有效 (需 api scope)',\n };\n }\n\n const user = await response.json() as { username?: string };\n return {\n name: 'gongfeng-token', passed: true, severity: 'error',\n message: `工蜂认证成功 (用户: ${user.username ?? 'unknown'})`,\n };\n } catch (err) {\n return {\n name: 'gongfeng-token', passed: false, severity: 'error',\n message: `工蜂 API 连接失败: ${(err as Error).message}`,\n fix: '请检查 GONGFENG_API_URL 是否可达,以及网络连接',\n };\n }\n }\n\n async checkGongfengProject(): Promise<PreflightResult> {\n const { apiUrl, privateToken, projectPath } = this.config.gongfeng;\n if (!apiUrl || !privateToken || !projectPath) {\n return {\n name: 'gongfeng-project', passed: false, severity: 'error',\n message: '工蜂项目路径未配置',\n fix: '请填写 GONGFENG_PROJECT_PATH (如 team/project)',\n };\n }\n\n try {\n const encoded = encodeURIComponent(projectPath);\n const url = `${apiUrl.replace(/\\/$/, '')}/api/v3/projects/${encoded}`;\n const response = await fetch(url, {\n headers: { 'PRIVATE-TOKEN': privateToken },\n signal: AbortSignal.timeout(10_000),\n });\n\n if (!response.ok) {\n return {\n name: 'gongfeng-project', passed: false, severity: 'error',\n message: `无法访问项目 ${projectPath} (HTTP ${response.status})`,\n fix: '请检查 GONGFENG_PROJECT_PATH,确保 Token 有权限访问该项目',\n };\n }\n\n return {\n name: 'gongfeng-project', passed: true, severity: 'error',\n message: `项目 ${projectPath} 可访问`,\n };\n } catch (err) {\n return {\n name: 'gongfeng-project', passed: false, severity: 'error',\n message: `项目验证请求失败: ${(err as Error).message}`,\n fix: '请检查网络连接和 GONGFENG_API_URL',\n };\n }\n }\n\n async checkWebPort(): Promise<PreflightResult> {\n const port = this.config.web?.port ?? 3000;\n const available = await checkPortAvailable(port);\n if (!available) {\n return {\n name: 'web-port', passed: false, severity: 'warn',\n message: `Web 端口 ${port} 被占用`,\n fix: `修改 WEB_PORT 或释放端口: lsof -i :${port}`,\n };\n }\n return { name: 'web-port', passed: true, severity: 'warn', message: `Web 端口 ${port} 可用` };\n }\n}\n","import fs from 'node:fs';\nimport path from 'node:path';\nimport { getLocalIP } from '../../utils/network.js';\nimport { getGlobalDir, resolveDataDir } from '../../paths.js';\nimport type { WorkspaceConfig } from '../../workspace/WorkspaceConfig.js';\nimport { envSchema } from '../../config-schema.js';\nimport { ENV_GROUPS, ENV_VAR_META } from './env-metadata.js';\n\nexport { getLocalIP };\n\nexport interface SetupConfig {\n gongfeng: {\n apiUrl: string;\n privateToken: string;\n projectPath: string;\n };\n project: {\n workDir: string;\n gitRootDir?: string;\n baseBranch?: string;\n branchPrefix?: string;\n worktreeBaseDir?: string;\n projectSubDir?: string;\n };\n ai: {\n mode: string;\n model?: string;\n phaseTimeoutMs?: number;\n };\n poll?: {\n discoveryIntervalMs?: number;\n driveIntervalMs?: number;\n maxRetries?: number;\n maxConcurrent?: number;\n };\n web?: {\n port?: number;\n };\n pipeline?: {\n mode?: string;\n };\n review?: {\n enabled?: boolean;\n };\n e2e?: {\n uatVendorDir?: string;\n uatConfigFile?: string;\n pythonBin?: string;\n };\n release?: {\n enabled?: boolean;\n };\n}\n\nexport class ConfigGenerator {\n /** @deprecated Use `getLocalIP()` from `../../utils/network.js` instead */\n static getLocalIP(): string {\n return getLocalIP();\n }\n\n static getGlobalConfigDir(): string {\n return getGlobalDir();\n }\n\n static getGlobalConfigPath(): string {\n return path.join(ConfigGenerator.getGlobalConfigDir(), '.env');\n }\n\n static isInitialized(configPath?: string): boolean {\n const envPath = configPath ?? ConfigGenerator.getGlobalConfigPath();\n return fs.existsSync(envPath);\n }\n\n /** @deprecated Use `generateFull()` for new files. Kept for backward compat in mergeWrite(). */\n static generate(config: SetupConfig): string {\n const lines: string[] = [];\n\n const addSection = (title: string) => {\n if (lines.length > 0) lines.push('');\n lines.push('# ' + title);\n };\n\n const addVar = (\n key: string,\n value: string | number | boolean | undefined,\n ) => {\n if (value === undefined) return;\n lines.push(key + '=' + String(value));\n };\n\n const addNonDefault = (\n key: string,\n value: string | number | boolean | undefined,\n defaultValue: string | number | boolean,\n ) => {\n if (value === undefined || value === '' || value === defaultValue) return;\n lines.push(key + '=' + String(value));\n };\n\n addSection('Gongfeng');\n addVar('GONGFENG_API_URL', config.gongfeng.apiUrl);\n addVar('GONGFENG_PRIVATE_TOKEN', config.gongfeng.privateToken);\n addVar('GONGFENG_PROJECT_PATH', config.gongfeng.projectPath);\n\n addSection('Project');\n addVar('PROJECT_WORK_DIR', config.project.workDir);\n addNonDefault('GIT_ROOT_DIR', config.project.gitRootDir, '');\n addNonDefault('BASE_BRANCH', config.project.baseBranch, 'master');\n addNonDefault('BRANCH_PREFIX', config.project.branchPrefix, 'feat/issue');\n addNonDefault('WORKTREE_BASE_DIR', config.project.worktreeBaseDir, '');\n addNonDefault('PROJECT_SUBDIR', config.project.projectSubDir, '');\n\n addSection('AI');\n addVar('AI_RUNNER_MODE', config.ai.mode);\n addNonDefault('AI_MODEL', config.ai.model, 'Claude-4.6-Opus');\n\n addNonDefault('CLAUDE_PHASE_TIMEOUT_MS', config.ai.phaseTimeoutMs, 1800000);\n addNonDefault('POLL_DISCOVERY_INTERVAL_MS', config.poll?.discoveryIntervalMs, 60000);\n addNonDefault('POLL_DRIVE_INTERVAL_MS', config.poll?.driveIntervalMs, 15000);\n addNonDefault('MAX_RETRIES', config.poll?.maxRetries, 3);\n addNonDefault('MAX_CONCURRENT_ISSUES', config.poll?.maxConcurrent, 3);\n addNonDefault('PIPELINE_MODE', config.pipeline?.mode, 'auto');\n addNonDefault('REVIEW_ENABLED', config.review?.enabled, true);\n addNonDefault('RELEASE_ENABLED', config.release?.enabled, false);\n\n const port = config.web?.port ?? 3000;\n if (port !== 3000) {\n addNonDefault('WEB_PORT', port, 3000);\n }\n\n addNonDefault('E2E_UAT_VENDOR_DIR', config.e2e?.uatVendorDir, '');\n addNonDefault('E2E_UAT_CONFIG_FILE', config.e2e?.uatConfigFile, '');\n addNonDefault('E2E_PYTHON_BIN', config.e2e?.pythonBin, 'python3');\n\n addSection('Workspace');\n addVar('WORKSPACE_CONFIG_PATH', ConfigGenerator.getWorkspaceConfigPath());\n\n return lines.join('\\n') + '\\n';\n }\n\n static readCurrent(): SetupConfig {\n const env = process.env;\n const aiMode = env.AI_RUNNER_MODE || 'claude-internal';\n return {\n gongfeng: {\n apiUrl: env.GONGFENG_API_URL || '',\n privateToken: env.GONGFENG_PRIVATE_TOKEN || '',\n projectPath: env.GONGFENG_PROJECT_PATH || '',\n },\n project: {\n workDir: env.PROJECT_WORK_DIR || '',\n gitRootDir: env.GIT_ROOT_DIR || undefined,\n baseBranch: env.BASE_BRANCH || undefined,\n branchPrefix: env.BRANCH_PREFIX || undefined,\n worktreeBaseDir: env.WORKTREE_BASE_DIR || undefined,\n projectSubDir: env.PROJECT_SUBDIR || undefined,\n },\n ai: {\n mode: aiMode,\n model: env.AI_MODEL || undefined,\n phaseTimeoutMs: env.CLAUDE_PHASE_TIMEOUT_MS\n ? parseInt(env.CLAUDE_PHASE_TIMEOUT_MS, 10)\n : undefined,\n },\n poll: {\n discoveryIntervalMs: env.POLL_DISCOVERY_INTERVAL_MS\n ? parseInt(env.POLL_DISCOVERY_INTERVAL_MS, 10)\n : undefined,\n driveIntervalMs: env.POLL_DRIVE_INTERVAL_MS\n ? parseInt(env.POLL_DRIVE_INTERVAL_MS, 10)\n : undefined,\n maxRetries: env.MAX_RETRIES\n ? parseInt(env.MAX_RETRIES, 10)\n : undefined,\n maxConcurrent: env.MAX_CONCURRENT_ISSUES\n ? parseInt(env.MAX_CONCURRENT_ISSUES, 10)\n : undefined,\n },\n web: {\n port: env.WEB_PORT ? parseInt(env.WEB_PORT, 10) : undefined,\n },\n pipeline: {\n mode: env.PIPELINE_MODE || undefined,\n },\n review: {\n enabled: env.REVIEW_ENABLED !== undefined\n ? env.REVIEW_ENABLED === 'true'\n : undefined,\n },\n release: {\n enabled: env.RELEASE_ENABLED !== undefined\n ? env.RELEASE_ENABLED === 'true'\n : undefined,\n },\n e2e: {\n uatVendorDir: env.E2E_UAT_VENDOR_DIR || undefined,\n uatConfigFile: env.E2E_UAT_CONFIG_FILE || undefined,\n pythonBin: env.E2E_PYTHON_BIN || undefined,\n },\n };\n }\n\n static getWorkspaceConfigPath(): string {\n return path.join(resolveDataDir(), 'workspace.json');\n }\n\n static buildWorkspaceConfig(config: SetupConfig): WorkspaceConfig {\n return {\n primary: {\n name: 'primary',\n projectPath: config.gongfeng.projectPath,\n localGitRoot: config.project.gitRootDir ?? config.project.workDir,\n projectSubDir: config.project.projectSubDir ?? '',\n baseBranch: config.project.baseBranch,\n branchPrefix: config.project.branchPrefix,\n role: '',\n },\n associates: [],\n };\n }\n\n static writeWorkspaceConfig(config: SetupConfig): string {\n const wsPath = ConfigGenerator.getWorkspaceConfigPath();\n const dir = path.dirname(wsPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const wsConfig = ConfigGenerator.buildWorkspaceConfig(config);\n fs.writeFileSync(wsPath, JSON.stringify(wsConfig, null, 2) + '\\n', 'utf-8');\n return wsPath;\n }\n\n static write(config: SetupConfig, outputPath?: string): string {\n const targetPath = outputPath ?? ConfigGenerator.getGlobalConfigPath();\n const dir = path.dirname(targetPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n const userValues = ConfigGenerator.setupConfigToEnvMap(config);\n const content = ConfigGenerator.generateFull(userValues);\n fs.writeFileSync(targetPath, content, 'utf-8');\n ConfigGenerator.writeWorkspaceConfig(config);\n return targetPath;\n }\n\n // ---------------------------------------------------------------------------\n // Full .env generation (complete, self-documenting)\n // ---------------------------------------------------------------------------\n\n /**\n * Extract the raw default value from a Zod v4 schema field.\n *\n * Handles three patterns used in `envSchema`:\n * - `def.type === 'default'` → `def.defaultValue` (string/number/enum defaults)\n * - `def.type === 'pipe'` → `def.in._zod.def.defaultValue` (envBoolean: .default().transform())\n * - anything else (optional / required without default) → `undefined`\n */\n static extractDefault(field: unknown): string | undefined {\n const def = (field as { _zod?: { def?: { type?: string; defaultValue?: unknown; in?: unknown } } })?._zod?.def;\n if (!def) return undefined;\n\n if (def.type === 'default' && def.defaultValue !== undefined) {\n return String(def.defaultValue);\n }\n\n // envBoolean pattern: pipe wraps a default schema\n if (def.type === 'pipe' && def.in) {\n const innerDef = (def.in as { _zod?: { def?: { type?: string; defaultValue?: unknown } } })?._zod?.def;\n if (innerDef?.type === 'default' && innerDef.defaultValue !== undefined) {\n return String(innerDef.defaultValue);\n }\n }\n\n return undefined;\n }\n\n /**\n * Generate a complete, self-documenting `.env` file containing ALL\n * variables from `envSchema`, grouped and commented in Chinese.\n *\n * Priority: `userValues[key]` > schema default > commented-out placeholder.\n *\n * @param userValues — key/value pairs from the setup wizard (flat env keys)\n */\n static generateFull(userValues?: Record<string, string>): string {\n const shape = envSchema.shape as Record<string, unknown>;\n const allKeys = Object.keys(shape);\n const user = userValues ?? {};\n\n // Build set of keys that belong to a known group\n const groupedKeys = new Set<string>();\n\n const lines: string[] = [\n '# ============================================================',\n '# Issue Auto-Finish 配置文件',\n '# 由 issue-auto-finish init 自动生成',\n '# ============================================================',\n ];\n\n for (const group of ENV_GROUPS) {\n // Collect keys in this group\n const keysInGroup = allKeys.filter(k => ENV_VAR_META[k]?.group === group.key);\n if (keysInGroup.length === 0) continue;\n\n lines.push('');\n lines.push(`# -----------------------------------------------------------`);\n lines.push(`# ${group.title}`);\n lines.push(`# -----------------------------------------------------------`);\n\n for (const key of keysInGroup) {\n groupedKeys.add(key);\n const meta = ENV_VAR_META[key];\n const desc = meta?.description ?? key;\n const isRequired = meta?.required === true;\n const schemaDefault = ConfigGenerator.extractDefault(shape[key]);\n const userVal = user[key];\n\n lines.push(`# ${desc}`);\n\n if (userVal !== undefined && userVal !== '') {\n // User provided a value\n lines.push(`${key}=${userVal}`);\n } else if (isRequired) {\n // Required, no value — placeholder\n lines.push(`${key}=<请填写>`);\n } else if (schemaDefault !== undefined) {\n // Has default — write it\n lines.push(`${key}=${schemaDefault}`);\n } else {\n // Optional, no default — comment out\n lines.push(`# ${key}=`);\n }\n }\n }\n\n // Safety net: any envSchema keys NOT in ENV_VAR_META (shouldn't happen,\n // but the sync test will catch it)\n const ungrouped = allKeys.filter(k => !groupedKeys.has(k));\n if (ungrouped.length > 0) {\n lines.push('');\n lines.push('# --- 其他 / Other ---');\n for (const key of ungrouped) {\n const schemaDefault = ConfigGenerator.extractDefault(shape[key]);\n const userVal = user[key];\n if (userVal !== undefined && userVal !== '') {\n lines.push(`${key}=${userVal}`);\n } else if (schemaDefault !== undefined) {\n lines.push(`${key}=${schemaDefault}`);\n } else {\n lines.push(`# ${key}=`);\n }\n }\n }\n\n return lines.join('\\n') + '\\n';\n }\n\n /**\n * Convert a `SetupConfig` (wizard output) to a flat `Record<string, string>`\n * suitable for `generateFull()`.\n */\n static setupConfigToEnvMap(config: SetupConfig): Record<string, string> {\n const m: Record<string, string> = {};\n\n const set = (key: string, val: string | number | boolean | undefined) => {\n if (val !== undefined && val !== '') m[key] = String(val);\n };\n\n set('GONGFENG_API_URL', config.gongfeng.apiUrl);\n set('GONGFENG_PRIVATE_TOKEN', config.gongfeng.privateToken);\n set('GONGFENG_PROJECT_PATH', config.gongfeng.projectPath);\n set('PROJECT_WORK_DIR', config.project.workDir);\n set('GIT_ROOT_DIR', config.project.gitRootDir);\n set('BASE_BRANCH', config.project.baseBranch);\n set('BRANCH_PREFIX', config.project.branchPrefix);\n set('WORKTREE_BASE_DIR', config.project.worktreeBaseDir);\n set('PROJECT_SUBDIR', config.project.projectSubDir);\n set('AI_RUNNER_MODE', config.ai.mode);\n set('AI_MODEL', config.ai.model);\n set('CLAUDE_PHASE_TIMEOUT_MS', config.ai.phaseTimeoutMs);\n set('POLL_DISCOVERY_INTERVAL_MS', config.poll?.discoveryIntervalMs);\n set('POLL_DRIVE_INTERVAL_MS', config.poll?.driveIntervalMs);\n set('MAX_RETRIES', config.poll?.maxRetries);\n set('MAX_CONCURRENT_ISSUES', config.poll?.maxConcurrent);\n set('PIPELINE_MODE', config.pipeline?.mode);\n set('REVIEW_ENABLED', config.review?.enabled);\n set('RELEASE_ENABLED', config.release?.enabled);\n set('WEB_PORT', config.web?.port);\n set('E2E_UAT_VENDOR_DIR', config.e2e?.uatVendorDir);\n set('E2E_UAT_CONFIG_FILE', config.e2e?.uatConfigFile);\n set('E2E_PYTHON_BIN', config.e2e?.pythonBin);\n set('WORKSPACE_CONFIG_PATH', ConfigGenerator.getWorkspaceConfigPath());\n\n return m;\n }\n\n /**\n * 增量更新 .env 文件:只更新 SetupConfig 涉及的 key,保留其余内容。\n * 如果文件不存在,退化为全量写入。\n */\n static mergeWrite(config: SetupConfig, outputPath?: string): string {\n const targetPath = outputPath ?? ConfigGenerator.getGlobalConfigPath();\n\n if (!fs.existsSync(targetPath)) {\n return ConfigGenerator.write(config, targetPath);\n }\n\n const existing = fs.readFileSync(targetPath, 'utf-8');\n const updates = ConfigGenerator.toEnvEntries(config);\n const merged = ConfigGenerator.mergeEnvContent(existing, updates);\n\n const dir = path.dirname(targetPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n fs.writeFileSync(targetPath, merged, 'utf-8');\n ConfigGenerator.writeWorkspaceConfig(config);\n return targetPath;\n }\n\n /**\n * 将 SetupConfig 转换为 env key-value 对。\n * null 值表示该 key 应从文件中删除(用户恢复为默认值时)。\n */\n static toEnvEntries(config: SetupConfig): Map<string, string | null> {\n const entries = new Map<string, string | null>();\n\n // 必填项始终写入\n entries.set('GONGFENG_API_URL', config.gongfeng.apiUrl);\n entries.set('GONGFENG_PRIVATE_TOKEN', config.gongfeng.privateToken);\n entries.set('GONGFENG_PROJECT_PATH', config.gongfeng.projectPath);\n entries.set('PROJECT_WORK_DIR', config.project.workDir);\n entries.set('AI_RUNNER_MODE', config.ai.mode);\n\n // 可选项:有值写入,值为默认值或空时标记删除\n const optionals: Array<[string, string | number | boolean | undefined, string | number | boolean]> = [\n ['GIT_ROOT_DIR', config.project.gitRootDir, ''],\n ['BASE_BRANCH', config.project.baseBranch, 'master'],\n ['BRANCH_PREFIX', config.project.branchPrefix, 'feat/issue'],\n ['WORKTREE_BASE_DIR', config.project.worktreeBaseDir, ''],\n ['PROJECT_SUBDIR', config.project.projectSubDir, ''],\n ['AI_MODEL', config.ai.model, 'Claude-4.6-Opus'],\n ['CLAUDE_PHASE_TIMEOUT_MS', config.ai.phaseTimeoutMs, 1800000],\n ['POLL_DISCOVERY_INTERVAL_MS', config.poll?.discoveryIntervalMs, 60000],\n ['POLL_DRIVE_INTERVAL_MS', config.poll?.driveIntervalMs, 15000],\n ['MAX_RETRIES', config.poll?.maxRetries, 3],\n ['MAX_CONCURRENT_ISSUES', config.poll?.maxConcurrent, 3],\n ['PIPELINE_MODE', config.pipeline?.mode, 'auto'],\n ['REVIEW_ENABLED', config.review?.enabled, true],\n ['RELEASE_ENABLED', config.release?.enabled, false],\n ['WEB_PORT', config.web?.port, 3000],\n ['E2E_UAT_VENDOR_DIR', config.e2e?.uatVendorDir, ''],\n ['E2E_UAT_CONFIG_FILE', config.e2e?.uatConfigFile, ''],\n ['E2E_PYTHON_BIN', config.e2e?.pythonBin, 'python3'],\n ['WORKSPACE_CONFIG_PATH', ConfigGenerator.getWorkspaceConfigPath(), ''],\n ];\n\n for (const [key, value, defaultValue] of optionals) {\n if (value === undefined || value === '' || value === defaultValue) {\n entries.set(key, null);\n } else {\n entries.set(key, String(value));\n }\n }\n\n return entries;\n }\n\n /**\n * 将 updates 合并到现有 .env 内容中。\n * - 已有的 key:原地更新值或删除行\n * - 新增的 key:追加到文件末尾\n * - 注释和空行:原样保留\n */\n static mergeEnvContent(\n existing: string,\n updates: Map<string, string | null>,\n ): string {\n const remaining = new Map(updates);\n const lines = existing.split('\\n');\n const result: string[] = [];\n\n for (const line of lines) {\n const trimmed = line.trim();\n // 空行或注释:保留\n if (trimmed === '' || trimmed.startsWith('#')) {\n result.push(line);\n continue;\n }\n // 解析 KEY=VALUE\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx === -1) {\n result.push(line);\n continue;\n }\n const key = trimmed.substring(0, eqIdx).trim();\n if (remaining.has(key)) {\n const newValue = remaining.get(key);\n remaining.delete(key);\n if (newValue !== null) {\n result.push(`${key}=${newValue}`);\n }\n // newValue === null → 删除该行\n } else {\n // 不在 updates 范围内:原样保留\n result.push(line);\n }\n }\n\n // 追加新增的 key(原文件中不存在的)\n const newEntries = [...remaining.entries()].filter(([, v]) => v !== null);\n if (newEntries.length > 0) {\n if (result.length > 0 && result[result.length - 1]?.trim() !== '') {\n result.push('');\n }\n for (const [key, value] of newEntries) {\n result.push(`${key}=${value}`);\n }\n }\n\n return result.join('\\n');\n }\n}\n","/**\n * Environment variable metadata registry.\n *\n * Provides grouping and Chinese descriptions for every key in `envSchema`.\n * Used by `ConfigGenerator.generateFull()` to produce a complete, self-documenting\n * `.env` file. A CI test (`env-metadata-sync.test.ts`) ensures this registry\n * stays in sync with the schema.\n */\n\nexport interface EnvVarMeta {\n /** Group key — must reference an entry in ENV_GROUPS. */\n group: string;\n /** Chinese description shown as a comment above the variable. */\n description: string;\n /** Mark as required (no default, must be user-provided). */\n required?: boolean;\n}\n\n/**\n * Ordered group definitions. The array order determines the section order\n * in the generated `.env` file.\n */\nexport const ENV_GROUPS: Array<{ key: string; title: string }> = [\n { key: 'required', title: '必填项 / Required' },\n { key: 'paths', title: '路径覆盖 / Path Overrides' },\n { key: 'project', title: '项目 / Project' },\n { key: 'ai', title: 'AI 运行器 / AI Runner' },\n { key: 'pipeline', title: '流水线 / Pipeline' },\n { key: 'poll', title: '轮询与并发 / Polling & Concurrency' },\n { key: 'review', title: '审核 / Review Gate' },\n { key: 'web', title: 'Web 面板 / Dashboard' },\n { key: 'issueNoteSync', title: 'Issue 评论同步 / Note Sync' },\n { key: 'webhook', title: 'Webhook' },\n { key: 'e2e', title: 'E2E 测试 / E2E Testing' },\n { key: 'preview', title: '预览环境 / Preview' },\n { key: 'brainstorm', title: '头脑风暴 / Brainstorm' },\n { key: 'chat', title: '智能助手 / Chat Agent' },\n { key: 'braindump', title: '批量任务 / Braindump' },\n { key: 'autoUpdate', title: '自动更新 / Auto Update' },\n { key: 'iwiki', title: 'iWiki' },\n { key: 'locale', title: '语言 / Locale' },\n { key: 'knowledge', title: '知识管理 / Knowledge' },\n { key: 'distill', title: '知识蒸馏 / Distill' },\n { key: 'sync', title: '文件同步 / Sync' },\n { key: 'release', title: '发布 / Release' },\n { key: 'verifyFixLoop', title: '验证修复循环 / Verify-Fix Loop' },\n { key: 'analytics', title: '运营分析 / Analytics' },\n { key: 'coordination', title: '多节点 / Multi-Node' },\n { key: 'workspace', title: '工作区 / Workspace' },\n { key: 'tenants', title: '多租户 / Multi-Tenant' },\n];\n\n/**\n * Per-variable metadata. Keys must match `envSchema.shape` exactly.\n */\nexport const ENV_VAR_META: Record<string, EnvVarMeta> = {\n // --- 必填 ---\n GONGFENG_API_URL: { group: 'required', description: '工蜂 GitLab API 地址', required: true },\n GONGFENG_PRIVATE_TOKEN: { group: 'required', description: '工蜂 API 访问令牌 (需 api scope)', required: true },\n GONGFENG_PROJECT_PATH: { group: 'required', description: '工蜂项目路径 (如 team/project)', required: true },\n PROJECT_WORK_DIR: { group: 'required', description: '项目本地工作目录 (绝对路径)', required: true },\n\n // --- 路径覆盖 ---\n DATA_DIR: { group: 'paths', description: '数据目录 (覆盖自动检测)' },\n LOGS_DIR: { group: 'paths', description: '日志目录 (覆盖自动检测)' },\n\n // --- 项目 ---\n GIT_ROOT_DIR: { group: 'project', description: 'Git 仓库根目录 (默认同 PROJECT_WORK_DIR)' },\n BASE_BRANCH: { group: 'project', description: '基础分支' },\n BRANCH_PREFIX: { group: 'project', description: '特性分支名前缀' },\n WORKTREE_BASE_DIR:{ group: 'project', description: 'Worktree 存放目录 (为空则使用默认位置)' },\n PROJECT_SUBDIR: { group: 'project', description: 'Monorepo 中项目子目录' },\n\n // --- AI ---\n AI_RUNNER_MODE: { group: 'ai', description: 'AI 运行模式 (claude-internal / cursor-agent / codebuddy)' },\n AI_MODEL: { group: 'ai', description: 'AI 模型' },\n CLAUDE_BINARY: { group: 'ai', description: 'Claude CLI 二进制路径 (覆盖默认)' },\n CURSOR_BINARY: { group: 'ai', description: 'Cursor Agent CLI 二进制路径 (覆盖默认)' },\n CODEBUDDY_BINARY: { group: 'ai', description: 'CodeBuddy CLI 二进制路径 (覆盖默认)' },\n CODEBUDDY_ACP_AUTO_APPROVE: { group: 'ai', description: 'CodeBuddy ACP 自动批准' },\n CLAUDE_PHASE_TIMEOUT_MS: { group: 'ai', description: 'AI 阶段执行超时 (毫秒)' },\n AI_IDLE_TIMEOUT_MS: { group: 'ai', description: 'AI 空闲超时 (毫秒, 0 禁用)' },\n NVM_NODE_VERSION: { group: 'ai', description: 'AI Runner 使用的 Node.js 版本' },\n\n // --- 流水线 ---\n PIPELINE_MODE: { group: 'pipeline', description: '流水线模式 (auto 始终解析为 plan-mode)' },\n\n // --- 轮询 ---\n POLL_DISCOVERY_INTERVAL_MS: { group: 'poll', description: '新 Issue 发现间隔 (毫秒)' },\n POLL_DRIVE_INTERVAL_MS: { group: 'poll', description: '任务驱动间隔 (毫秒)' },\n MAX_RETRIES: { group: 'poll', description: '最大重试次数' },\n MAX_CONCURRENT_ISSUES: { group: 'poll', description: '最大并行 Issue 数' },\n\n // --- 审核 ---\n REVIEW_ENABLED: { group: 'review', description: '启用方案审核门禁' },\n REVIEW_AUTO_APPROVE_LABELS:{ group: 'review', description: '自动批准的标签 (逗号分隔)' },\n\n // --- Web ---\n WEB_ENABLED: { group: 'web', description: '启用 Web 监控面板' },\n WEB_HOST: { group: 'web', description: 'Web 监听地址' },\n WEB_PORT: { group: 'web', description: 'Web 面板端口' },\n FRONTEND_DIST_DIR: { group: 'web', description: '前端构建产物目录 (覆盖默认)' },\n\n // --- Issue 评论同步 ---\n ISSUE_NOTE_SYNC_ENABLED: { group: 'issueNoteSync', description: '启用 Issue 评论同步' },\n WEB_BASE_URL: { group: 'issueNoteSync', description: 'Web 面板外部访问地址 (默认自动检测)' },\n\n // --- Webhook ---\n WEBHOOK_ENABLED: { group: 'webhook', description: '启用 Webhook 接收工蜂推送事件' },\n WEBHOOK_HOST: { group: 'webhook', description: 'Webhook 监听地址' },\n WEBHOOK_PORT: { group: 'webhook', description: 'Webhook 端口 (需满足工蜂要求: 80/443/8080/8081)' },\n WEBHOOK_SECRET: { group: 'webhook', description: 'Webhook 密钥' },\n WEBHOOK_LLM_FALLBACK: { group: 'webhook', description: '正则匹配失败时用 LLM 解析自然语言意图' },\n WEBHOOK_LLM_BINARY: { group: 'webhook', description: '意图识别使用的 AI CLI (独立于 AI_RUNNER_MODE)' },\n\n // --- E2E ---\n E2E_UI_ENABLED: { group: 'e2e', description: '启用 E2E 测试功能' },\n E2E_BASE_URL: { group: 'e2e', description: 'E2E 测试目标 URL' },\n E2E_BACKEND_URL: { group: 'e2e', description: 'E2E 后端 URL' },\n E2E_AUTH_COOKIES: { group: 'e2e', description: 'E2E 认证 Cookies (JSON 数组)' },\n E2E_BACKEND_PORT_BASE: { group: 'e2e', description: 'E2E 后端端口基数' },\n E2E_FRONTEND_PORT_BASE: { group: 'e2e', description: 'E2E 前端端口基数' },\n E2E_UAT_VENDOR_DIR: { group: 'e2e', description: 'UAT 测试框架目录' },\n E2E_UAT_CONFIG_FILE: { group: 'e2e', description: 'UAT 配置文件路径' },\n E2E_PYTHON_BIN: { group: 'e2e', description: 'Python 可执行文件路径' },\n E2E_AI_RUNNER_MODE: { group: 'e2e', description: 'E2E 阶段使用的 AI Runner 模式' },\n E2E_AI_MODEL: { group: 'e2e', description: 'E2E 阶段使用的 AI 模型(默认复用 AI_MODEL)' },\n\n // --- 预览环境 ---\n PREVIEW_ENABLED: { group: 'preview', description: '启用预览环境' },\n PREVIEW_HOST: { group: 'preview', description: '预览环境主机名' },\n PREVIEW_TTL_MS: { group: 'preview', description: '预览环境存活时间 (毫秒)' },\n PREVIEW_KEEP_AFTER_COMPLETE:{ group: 'preview', description: 'Issue 完成后保留预览环境' },\n PREVIEW_REAP_INTERVAL_MS: { group: 'preview', description: '预览环境清理检查间隔 (毫秒)' },\n\n // --- 头脑风暴 ---\n BRAINSTORM_ENABLED: { group: 'brainstorm', description: '启用头脑风暴功能' },\n BRAINSTORM_MAX_ROUNDS: { group: 'brainstorm', description: '最大精炼轮数' },\n BRAINSTORM_TIMEOUT_MS: { group: 'brainstorm', description: '头脑风暴超时 (毫秒)' },\n BRAINSTORM_GENERATOR_MODE: { group: 'brainstorm', description: '生成器 AI Runner 模式 (默认跟随全局)' },\n BRAINSTORM_GENERATOR_BINARY: { group: 'brainstorm', description: '生成器 AI 二进制路径' },\n BRAINSTORM_GENERATOR_MODEL: { group: 'brainstorm', description: '生成器 AI 模型' },\n BRAINSTORM_REVIEWER_MODE: { group: 'brainstorm', description: '审核器 AI Runner 模式 (默认跟随全局)' },\n BRAINSTORM_REVIEWER_BINARY: { group: 'brainstorm', description: '审核器 AI 二进制路径' },\n BRAINSTORM_REVIEWER_MODEL: { group: 'brainstorm', description: '审核器 AI 模型' },\n\n // --- 智能助手 ---\n CHAT_ENABLED: { group: 'chat', description: '启用智能助手 (Chat Agent)' },\n CHAT_TIMEOUT_MS: { group: 'chat', description: '对话超时 (毫秒)' },\n CHAT_MAX_SESSION_MESSAGES: { group: 'chat', description: '单会话最大消息数' },\n CHAT_AGENT_MODE: { group: 'chat', description: 'Chat AI Runner 模式 (默认 claude-internal)' },\n CHAT_AGENT_BINARY: { group: 'chat', description: 'Chat AI 二进制路径' },\n CHAT_AGENT_MODEL: { group: 'chat', description: 'Chat AI 模型' },\n\n // --- 批量任务 ---\n BRAINDUMP_ENABLED: { group: 'braindump', description: '启用批量任务拆分 (Braindump)' },\n BRAINDUMP_MAX_CONCURRENT: { group: 'braindump', description: '批量任务最大并发 (默认跟随 MAX_CONCURRENT_ISSUES)' },\n BRAINDUMP_SPLIT_TIMEOUT_MS: { group: 'braindump', description: '任务拆分超时 (毫秒)' },\n BRAINDUMP_TASK_TIMEOUT_MS: { group: 'braindump', description: '单任务超时 (默认跟随 CLAUDE_PHASE_TIMEOUT_MS)' },\n BRAINDUMP_MAX_CONFLICT_ATTEMPTS:{ group: 'braindump', description: '合并冲突最大重试次数' },\n BRAINDUMP_CREATE_MR: { group: 'braindump', description: '任务完成后自动创建合并请求' },\n\n // --- 自动更新 ---\n AUTO_UPDATE_ENABLED: { group: 'autoUpdate', description: '启用自动检查 npm 新版本并升级' },\n AUTO_UPDATE_INTERVAL_MS: { group: 'autoUpdate', description: '检查更新间隔 (毫秒)' },\n AUTO_UPDATE_REGISTRY: { group: 'autoUpdate', description: 'npm 仓库地址' },\n AUTO_UPDATE_DRAIN_TIMEOUT_MS:{ group: 'autoUpdate', description: '更新前等待活跃任务完成的超时 (毫秒)' },\n\n // --- iWiki ---\n IWIKI_AUTH_COOKIE: { group: 'iwiki', description: 'iWiki 认证 Cookie' },\n IWIKI_AUTH_TOKEN: { group: 'iwiki', description: 'iWiki 认证 Token' },\n IWIKI_BASE_URL: { group: 'iwiki', description: 'iWiki 基础 URL' },\n\n // --- 语言 ---\n LOCALE: { group: 'locale', description: '界面语言 (zh-CN / en)' },\n\n // --- 知识管理 ---\n KNOWLEDGE_ENABLED: { group: 'knowledge', description: '启用知识管理' },\n KNOWLEDGE_PATH: { group: 'knowledge', description: '知识库路径 (覆盖默认)' },\n KNOWLEDGE_ORPHAN_BRANCH: { group: 'knowledge', description: '知识 Git 同步分支名' },\n KNOWLEDGE_SYNC_VECTORS: { group: 'knowledge', description: '同步时包含向量文件 (大文件)' },\n KNOWLEDGE_AUTO_RESTORE: { group: 'knowledge', description: '启动时自动从 orphan branch 恢复知识' },\n\n // --- 知识蒸馏 ---\n DISTILL_ENABLED: { group: 'distill', description: '启用知识蒸馏' },\n DISTILL_INTERVAL_MS: { group: 'distill', description: '蒸馏调度间隔 (毫秒)' },\n DISTILL_DIARY_SUMMARIZE: { group: 'distill', description: '蒸馏时总结日记' },\n DISTILL_MIN_DIARIES_FOR_DISTILL: { group: 'distill', description: '触发蒸馏所需最少日记数' },\n DISTILL_MEMORY_CONFIDENCE_THRESHOLD:{ group: 'distill', description: '记忆置信度阈值 (0-1)' },\n DISTILL_VECTOR_ENABLED: { group: 'distill', description: '启用向量存储' },\n\n // --- 文件同步 ---\n SYNC_KNOWLEDGE_TO_PROJECT: { group: 'sync', description: '将知识文件同步到目标项目' },\n SYNC_RULES_TO_PROJECT: { group: 'sync', description: '将规则文件同步到目标项目' },\n\n // --- 发布 ---\n RELEASE_ENABLED: { group: 'release', description: '启用发布功能' },\n RELEASE_DETECT_CACHE_TTL_MS:{ group: 'release', description: '发布检测缓存有效期 (毫秒)' },\n\n // --- 验证修复循环 ---\n VERIFY_FIX_LOOP_ENABLED: { group: 'verifyFixLoop', description: '启用验证失败后自动修复循环' },\n VERIFY_FIX_MAX_ITERATIONS: { group: 'verifyFixLoop', description: '最大修复迭代次数' },\n VERIFY_TODOLIST_CHECK_ENABLED: { group: 'verifyFixLoop', description: '启用 Todolist 完成度检查' },\n\n // --- 运营分析 ---\n ANALYTICS_ENABLED: { group: 'analytics', description: '启用运营分析' },\n ANALYTICS_TARGET_API_URL: { group: 'analytics', description: '分析数据上报 API 地址' },\n ANALYTICS_TARGET_API_TOKEN: { group: 'analytics', description: '分析数据上报 API Token' },\n ANALYTICS_CACHE_TTL_MS: { group: 'analytics', description: '分析数据缓存有效期 (毫秒)' },\n ANALYTICS_SKILL_AUTO_DISCOVER:{ group: 'analytics', description: '自动发现 Skill 文件' },\n\n // --- 多节点 ---\n NODE_ID: { group: 'coordination', description: '节点标识 (多节点部署时区分实例)' },\n\n // --- 工作区 ---\n WORKSPACE_CONFIG_PATH: { group: 'workspace', description: '多仓库工作区配置文件路径' },\n\n // --- 多租户 ---\n TENANTS_CONFIG_PATH: { group: 'tenants', description: '多租户配置文件路径' },\n};\n"],"mappings":"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","names":["fs","fs"]}