hamster-wheel-cli 0.2.0-beta.1 → 0.2.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/README.md +7 -0
- package/dist/cli.js +171 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.js +171 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli.ts +222 -5
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/utils.ts","../src/global-config.ts","../src/git.ts","../src/logs.ts","../src/alias-viewer.ts","../src/logs-viewer.ts","../src/loop.ts","../src/ai.ts","../src/deps.ts","../src/gh.ts","../src/logger.ts","../src/plan.ts","../src/quality.ts","../src/runtime-tracker.ts","../src/summary.ts","../src/webhook.ts","../src/multi-task.ts","../src/monitor.ts","../src/log-tailer.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'fs-extra';\nimport { Command } from 'commander';\nimport { buildLoopConfig, CliOptions, defaultNotesPath, defaultPlanPath, defaultWorkflowDoc } from './config';\nimport { applyShortcutArgv, loadGlobalConfig, normalizeAliasName, upsertAliasEntry } from './global-config';\nimport { getCurrentBranch } from './git';\nimport { buildAutoLogFilePath, formatCommandLine } from './logs';\nimport { runAliasViewer } from './alias-viewer';\nimport { runLogsViewer } from './logs-viewer';\nimport { runLoop } from './loop';\nimport { defaultLogger } from './logger';\nimport { buildTaskPlans, normalizeTaskList, parseMultiTaskMode } from './multi-task';\nimport { resolveTerminationTarget, runMonitor } from './monitor';\nimport { tailLogFile } from './log-tailer';\nimport { resolvePath } from './utils';\n\nconst FOREGROUND_CHILD_ENV = 'WHEEL_AI_FOREGROUND_CHILD';\n\nfunction parseInteger(value: string, defaultValue: number): number {\n const parsed = Number.parseInt(value, 10);\n if (Number.isNaN(parsed)) return defaultValue;\n return parsed;\n}\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction normalizeOptional(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction hasOption(argv: string[], option: string): boolean {\n return argv.some(arg => arg === option || arg.startsWith(`${option}=`));\n}\n\nfunction buildBackgroundArgs(argv: string[], logFile: string, branchName?: string, injectBranch = false): string[] {\n const rawArgs = argv.slice(1);\n const filtered = rawArgs.filter(arg => !(arg === '--background' || arg.startsWith('--background=')));\n if (!hasOption(filtered, '--log-file')) {\n filtered.push('--log-file', logFile);\n }\n if (injectBranch && branchName && !hasOption(filtered, '--branch')) {\n filtered.push('--branch', branchName);\n }\n return filtered;\n}\n\nfunction extractAliasCommandArgs(argv: string[], name: string): string[] {\n const args = argv.slice(2);\n const start = args.findIndex((arg, index) => arg === 'set' && args[index + 1] === 'alias' && args[index + 2] === name);\n if (start < 0) return [];\n const rest = args.slice(start + 3);\n if (rest[0] === '--') return rest.slice(1);\n return rest;\n}\n\nasync function runForegroundWithDetach(options: {\n argv: string[];\n logFile: string;\n branchName?: string;\n injectBranch: boolean;\n isMultiTask: boolean;\n}): Promise<void> {\n const args = buildBackgroundArgs(options.argv, options.logFile, options.branchName, options.injectBranch);\n const child = spawn(process.execPath, [...process.execArgv, ...args], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n [FOREGROUND_CHILD_ENV]: '1'\n }\n });\n child.unref();\n\n const resolvedLogFile = resolvePath(process.cwd(), options.logFile);\n const existed = await fs.pathExists(resolvedLogFile);\n const tailer = await tailLogFile({\n filePath: resolvedLogFile,\n startFromEnd: existed,\n onLine: line => {\n process.stdout.write(`${line}\\n`);\n },\n onError: message => {\n defaultLogger.warn(`日志读取失败:${message}`);\n }\n });\n\n const suffixNote = options.isMultiTask ? '(多任务将追加序号)' : '';\n console.log(`已进入前台日志查看,按 Esc 切到后台运行,日志输出至 ${resolvedLogFile}${suffixNote}`);\n\n let cleaned = false;\n const cleanup = async (): Promise<void> => {\n if (cleaned) return;\n cleaned = true;\n await tailer.stop();\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n };\n\n const detach = async (): Promise<void> => {\n await cleanup();\n console.log(`已切入后台运行,日志输出至 ${resolvedLogFile}${suffixNote}`);\n process.exit(0);\n };\n\n const terminate = async (): Promise<void> => {\n if (child.pid) {\n try {\n const target = resolveTerminationTarget(child.pid);\n process.kill(target, 'SIGTERM');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n defaultLogger.warn(`终止子进程失败:${message}`);\n }\n }\n await cleanup();\n process.exit(0);\n };\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (input === '\\u001b') {\n void detach();\n return;\n }\n if (input === '\\u0003') {\n void terminate();\n }\n });\n }\n\n process.on('SIGINT', () => {\n void terminate();\n });\n process.on('SIGTERM', () => {\n void terminate();\n });\n\n child.on('exit', async code => {\n await cleanup();\n process.exit(code ?? 0);\n });\n}\n\n/**\n * CLI 入口。\n */\nexport async function runCli(argv: string[]): Promise<void> {\n const globalConfig = await loadGlobalConfig(defaultLogger);\n const effectiveArgv = applyShortcutArgv(argv, globalConfig);\n const program = new Command();\n\n program\n .name('wheel-ai')\n .description('基于 AI CLI 的持续迭代开发工具')\n .version('1.0.0');\n\n program\n .command('run')\n .option('-t, --task <task>', '需要完成的任务描述(可重复传入,独立处理)', collect, [])\n .option('-i, --iterations <number>', '最大迭代次数', value => parseInteger(value, 5), 5)\n .option('--ai-cli <command>', 'AI CLI 命令', 'claude')\n .option('--ai-args <args...>', 'AI CLI 参数', [])\n .option('--ai-prompt-arg <flag>', '用于传入 prompt 的参数(为空则使用 stdin)')\n .option('--notes-file <path>', '持久化记忆文件', defaultNotesPath())\n .option('--plan-file <path>', '计划文件', defaultPlanPath())\n .option('--workflow-doc <path>', 'AI 工作流程说明文件', defaultWorkflowDoc())\n .option('--worktree', '在独立 worktree 上执行', false)\n .option('--branch <name>', 'worktree 分支名(默认自动生成或当前分支)')\n .option('--worktree-path <path>', 'worktree 路径,默认 ../worktrees/<branch>')\n .option('--base-branch <name>', '创建分支的基线分支', 'main')\n .option('--skip-install', '跳过开始任务前的依赖检查', false)\n .option('--run-tests', '运行单元测试命令', false)\n .option('--run-e2e', '运行 e2e 测试命令', false)\n .option('--unit-command <cmd>', '单元测试命令', 'yarn test')\n .option('--e2e-command <cmd>', 'e2e 测试命令', 'yarn e2e')\n .option('--auto-commit', '自动 git commit', false)\n .option('--auto-push', '自动 git push', false)\n .option('--pr', '使用 gh 创建 PR', false)\n .option('--pr-title <title>', 'PR 标题')\n .option('--pr-body <path>', 'PR 描述文件路径(可留空自动生成)')\n .option('--draft', '以草稿形式创建 PR', false)\n .option('--reviewer <user...>', 'PR reviewers', collect, [])\n .option('--auto-merge', 'PR 检查通过后自动合并', false)\n .option('--webhook <url>', 'webhook 通知 URL(可重复)', collect, [])\n .option('--webhook-timeout <ms>', 'webhook 请求超时(毫秒)', value => parseInteger(value, 8000))\n .option('--multi-task-mode <mode>', '多任务执行模式(relay/serial/serial-continue/parallel,或中文描述)', 'relay')\n .option('--stop-signal <token>', 'AI 输出中的停止标记', '<<DONE>>')\n .option('--log-file <path>', '日志输出文件路径')\n .option('--background', '切入后台运行', false)\n .option('-v, --verbose', '输出调试日志', false)\n .option('--skip-quality', '跳过代码质量检查', false)\n .action(async (options) => {\n const tasks = normalizeTaskList(options.task as string[] | string | undefined);\n if (tasks.length === 0) {\n throw new Error('需要至少提供一个任务描述');\n }\n\n const multiTaskMode = parseMultiTaskMode(options.multiTaskMode as string | undefined);\n const useWorktree = Boolean(options.worktree);\n if (multiTaskMode === 'parallel' && !useWorktree) {\n throw new Error('并行模式必须启用 --worktree');\n }\n\n const branchInput = normalizeOptional(options.branch);\n const logFileInput = normalizeOptional(options.logFile);\n const worktreePathInput = normalizeOptional(options.worktreePath);\n const background = Boolean(options.background);\n const isMultiTask = tasks.length > 1;\n const isForegroundChild = process.env[FOREGROUND_CHILD_ENV] === '1';\n const canForegroundDetach = !background && !isForegroundChild && process.stdout.isTTY && process.stdin.isTTY;\n\n const shouldInjectBranch = Boolean(useWorktree && branchInput && !isMultiTask);\n const branchNameForBackground = branchInput;\n\n let logFile = logFileInput;\n if ((background || canForegroundDetach) && !logFile) {\n let branchForLog = 'multi-task';\n if (!isMultiTask) {\n branchForLog = branchNameForBackground ?? '';\n if (!branchForLog) {\n try {\n const current = await getCurrentBranch(process.cwd(), defaultLogger);\n branchForLog = current || 'detached';\n } catch {\n branchForLog = 'unknown';\n }\n }\n } else if (branchInput) {\n branchForLog = `${branchInput}-multi`;\n }\n logFile = buildAutoLogFilePath(branchForLog);\n }\n\n if (background) {\n if (!logFile) {\n throw new Error('后台运行需要指定日志文件');\n }\n const args = buildBackgroundArgs(effectiveArgv, logFile, branchNameForBackground, shouldInjectBranch);\n const child = spawn(process.execPath, [...process.execArgv, ...args], {\n detached: true,\n stdio: 'ignore'\n });\n child.unref();\n const displayLogFile = resolvePath(process.cwd(), logFile);\n const suffixNote = isMultiTask ? '(多任务将追加序号)' : '';\n console.log(`已切入后台运行,日志输出至 ${displayLogFile}${suffixNote}`);\n return;\n }\n\n if (canForegroundDetach) {\n if (!logFile) {\n throw new Error('切入后台需要指定日志文件');\n }\n await runForegroundWithDetach({\n argv: effectiveArgv,\n logFile,\n branchName: branchNameForBackground,\n injectBranch: shouldInjectBranch,\n isMultiTask\n });\n return;\n }\n\n const taskPlans = buildTaskPlans({\n tasks,\n mode: multiTaskMode,\n useWorktree,\n baseBranch: options.baseBranch as string,\n branchInput,\n worktreePath: worktreePathInput,\n logFile: logFileInput\n });\n\n const baseOptions = {\n iterations: options.iterations as number,\n aiCli: options.aiCli as string,\n aiArgs: (options.aiArgs as string[]) ?? [],\n aiPromptArg: options.aiPromptArg as string | undefined,\n notesFile: options.notesFile as string,\n planFile: options.planFile as string,\n workflowDoc: options.workflowDoc as string,\n useWorktree,\n runTests: Boolean(options.runTests),\n runE2e: Boolean(options.runE2e),\n unitCommand: options.unitCommand as string | undefined,\n e2eCommand: options.e2eCommand as string | undefined,\n autoCommit: Boolean(options.autoCommit),\n autoPush: Boolean(options.autoPush),\n pr: Boolean(options.pr),\n prTitle: options.prTitle as string | undefined,\n prBody: options.prBody as string | undefined,\n draft: Boolean(options.draft),\n reviewers: (options.reviewer as string[]) ?? [],\n autoMerge: Boolean(options.autoMerge),\n webhookUrls: (options.webhook as string[]) ?? [],\n webhookTimeout: options.webhookTimeout as number | undefined,\n stopSignal: options.stopSignal as string,\n verbose: Boolean(options.verbose),\n skipInstall: Boolean(options.skipInstall),\n skipQuality: Boolean(options.skipQuality)\n };\n\n const dynamicRelay = useWorktree && multiTaskMode === 'relay' && !branchInput;\n let relayBaseBranch = options.baseBranch as string;\n\n const runPlan = async (plan: typeof taskPlans[number], baseBranchOverride?: string): Promise<Awaited<ReturnType<typeof runLoop>>> => {\n const cliOptions: CliOptions = {\n task: plan.task,\n ...baseOptions,\n branch: plan.branchName,\n worktreePath: plan.worktreePath,\n baseBranch: baseBranchOverride ?? plan.baseBranch,\n logFile: plan.logFile\n };\n const config = buildLoopConfig(cliOptions, process.cwd());\n return runLoop(config);\n };\n\n if (multiTaskMode === 'parallel') {\n const results = await Promise.allSettled(taskPlans.map(plan => runPlan(plan)));\n const errors = results.flatMap((result, index) => {\n if (result.status === 'fulfilled') return [];\n const reason = result.reason instanceof Error ? result.reason.message : String(result.reason);\n return [`任务 ${index + 1} 失败: ${reason}`];\n });\n if (errors.length > 0) {\n errors.forEach(message => defaultLogger.warn(message));\n throw new Error(errors.join('\\n'));\n }\n return;\n }\n\n if (multiTaskMode === 'serial-continue') {\n const errors: string[] = [];\n for (const plan of taskPlans) {\n try {\n const baseBranch = dynamicRelay ? relayBaseBranch : plan.baseBranch;\n const result = await runPlan(plan, baseBranch);\n if (dynamicRelay && result.branchName) {\n relayBaseBranch = result.branchName;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n errors.push(`任务 ${plan.index + 1} 失败: ${message}`);\n defaultLogger.warn(`任务 ${plan.index + 1} 执行失败,继续下一任务:${message}`);\n }\n }\n if (errors.length > 0) {\n throw new Error(errors.join('\\n'));\n }\n return;\n }\n\n for (const plan of taskPlans) {\n const baseBranch = dynamicRelay ? relayBaseBranch : plan.baseBranch;\n const result = await runPlan(plan, baseBranch);\n if (dynamicRelay && result.branchName) {\n relayBaseBranch = result.branchName;\n }\n }\n });\n\n program\n .command('monitor')\n .description('查看后台运行日志(t 终止任务)')\n .action(async () => {\n await runMonitor();\n });\n\n program\n .command('logs')\n .description('查看历史日志')\n .action(async () => {\n await runLogsViewer();\n });\n\n program\n .command('set')\n .description('写入全局配置')\n .command('alias <name> [options...]')\n .description('设置 alias')\n .allowUnknownOption(true)\n .action(async (name: string) => {\n const normalized = normalizeAliasName(name);\n if (!normalized) {\n throw new Error('alias 名称不能为空且不能包含空白字符');\n }\n const commandArgs = extractAliasCommandArgs(effectiveArgv, name);\n const commandLine = formatCommandLine(commandArgs);\n if (!commandLine) {\n throw new Error('alias 命令不能为空');\n }\n await upsertAliasEntry(normalized, commandLine);\n console.log(`已写入 alias:${normalized}`);\n });\n\n program\n .command('alias')\n .alias('aliases')\n .description('浏览全局 alias 配置')\n .action(async () => {\n await runAliasViewer();\n });\n\n await program.parseAsync(effectiveArgv);\n}\n\nif (require.main === module) {\n runCli(process.argv).catch(error => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n defaultLogger.error(message);\n process.exitCode = 1;\n });\n}\n","import path from 'node:path';\nimport { AiCliConfig, LoopConfig, PrConfig, TestConfig, WebhookConfig, WorktreeConfig, WorkflowFiles } from './types';\nimport { resolvePath } from './utils';\n\n/**\n * CLI 参数解析后的配置。\n */\nexport interface CliOptions {\n readonly task: string;\n readonly iterations: number;\n readonly aiCli: string;\n readonly aiArgs: string[];\n readonly aiPromptArg?: string;\n readonly notesFile: string;\n readonly planFile: string;\n readonly workflowDoc: string;\n readonly useWorktree: boolean;\n readonly branch?: string;\n readonly worktreePath?: string;\n readonly baseBranch: string;\n readonly runTests: boolean;\n readonly runE2e: boolean;\n readonly unitCommand?: string;\n readonly e2eCommand?: string;\n readonly autoCommit: boolean;\n readonly autoPush: boolean;\n readonly pr: boolean;\n readonly prTitle?: string;\n readonly prBody?: string;\n readonly draft: boolean;\n readonly reviewers?: string[];\n readonly autoMerge: boolean;\n readonly webhookUrls: string[];\n readonly webhookTimeout?: number;\n readonly stopSignal: string;\n readonly logFile?: string;\n readonly verbose: boolean;\n readonly skipInstall: boolean;\n readonly skipQuality: boolean;\n}\n\nfunction buildAiConfig(options: CliOptions): AiCliConfig {\n return {\n command: options.aiCli,\n args: options.aiArgs,\n promptArg: options.aiPromptArg\n };\n}\n\nfunction buildWorktreeConfig(options: CliOptions): WorktreeConfig {\n return {\n useWorktree: options.useWorktree,\n branchName: options.branch,\n worktreePath: options.worktreePath,\n baseBranch: options.baseBranch\n };\n}\n\nfunction buildTestConfig(options: CliOptions): TestConfig {\n return {\n unitCommand: options.unitCommand,\n e2eCommand: options.e2eCommand\n };\n}\n\nfunction buildPrConfig(options: CliOptions): PrConfig {\n return {\n enable: options.pr,\n title: options.prTitle,\n bodyPath: options.prBody,\n draft: options.draft,\n reviewers: options.reviewers,\n autoMerge: options.autoMerge\n };\n}\n\nfunction buildWebhookConfig(options: CliOptions): WebhookConfig | undefined {\n if (!options.webhookUrls || options.webhookUrls.length === 0) return undefined;\n return {\n urls: options.webhookUrls,\n timeoutMs: options.webhookTimeout\n };\n}\n\nfunction buildWorkflowFiles(options: CliOptions, cwd: string): WorkflowFiles {\n return {\n workflowDoc: resolvePath(cwd, options.workflowDoc),\n notesFile: resolvePath(cwd, options.notesFile),\n planFile: resolvePath(cwd, options.planFile)\n };\n}\n\n/**\n * 构建循环执行所需的配置对象。\n */\nexport function buildLoopConfig(options: CliOptions, cwd: string): LoopConfig {\n return {\n task: options.task,\n iterations: options.iterations,\n stopSignal: options.stopSignal,\n ai: buildAiConfig(options),\n workflowFiles: buildWorkflowFiles(options, cwd),\n git: buildWorktreeConfig(options),\n tests: buildTestConfig(options),\n pr: buildPrConfig(options),\n webhooks: buildWebhookConfig(options),\n cwd,\n logFile: options.logFile ? resolvePath(cwd, options.logFile) : undefined,\n verbose: options.verbose,\n runTests: options.runTests,\n runE2e: options.runE2e,\n autoCommit: options.autoCommit,\n autoPush: options.autoPush,\n skipInstall: options.skipInstall,\n skipQuality: options.skipQuality\n };\n}\n\n/**\n * 默认 notes 文件路径。\n */\nexport function defaultNotesPath(): string {\n return path.join('memory', 'notes.md');\n}\n\n/**\n * 默认 plan 文件路径。\n */\nexport function defaultPlanPath(): string {\n return path.join('memory', 'plan.md');\n}\n\n/**\n * 默认工作流说明文件路径。\n */\nexport function defaultWorkflowDoc(): string {\n return path.join('docs', 'ai-workflow.md');\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { CommandOptions, CommandResult } from './types';\n\ntype ExecaModule = typeof import('execa');\ntype ExecaError = import('execa').ExecaError;\n\nconst importExeca = async (): Promise<ExecaModule> => {\n // 通过运行时动态 import 兼容 CommonJS 下加载 ESM 包\n const importer = new Function('specifier', 'return import(specifier)') as (specifier: string) => Promise<ExecaModule>;\n return importer('execa');\n};\n\n/**\n * 执行外部命令,支持日志与流式输出。\n */\nexport async function runCommand(command: string, args: string[], options: CommandOptions = {}): Promise<CommandResult> {\n const label = options.verboseLabel ?? 'cmd';\n const displayCmd = options.verboseCommand ?? [command, ...args].join(' ');\n const cwd = options.cwd ?? process.cwd();\n options.logger?.debug(`[${label}] ${displayCmd} (cwd: ${cwd})`);\n\n const logger = options.logger;\n const streamEnabled = Boolean(options.stream?.enabled && logger);\n const stdoutPrefix = options.stream?.stdoutPrefix ?? `[${label}] `;\n const stderrPrefix = options.stream?.stderrPrefix ?? `[${label} stderr] `;\n\n const createLineStreamer = (prefix: string) => {\n let buffer = '';\n const emit = (line: string): void => {\n logger?.info(`${prefix}${line}`);\n };\n const push = (chunk: string | Buffer): void => {\n const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n buffer += text.replace(/\\r/g, '\\n');\n const parts = buffer.split('\\n');\n buffer = parts.pop() ?? '';\n parts.forEach(emit);\n };\n const flush = (): void => {\n if (buffer.length === 0) return;\n emit(buffer);\n buffer = '';\n };\n return { push, flush };\n };\n\n const attachStream = (stream: NodeJS.ReadableStream | null | undefined, streamer: ReturnType<typeof createLineStreamer>): void => {\n if (!stream) return;\n if (typeof stream.setEncoding === 'function') {\n stream.setEncoding('utf8');\n }\n stream.on('data', streamer.push);\n stream.on('end', streamer.flush);\n };\n\n const stdoutStreamer = streamEnabled ? createLineStreamer(stdoutPrefix) : null;\n const stderrStreamer = streamEnabled ? createLineStreamer(stderrPrefix) : null;\n\n try {\n const { execa } = await importExeca();\n const subprocess = execa(command, args, {\n cwd: options.cwd,\n env: options.env,\n input: options.input,\n all: false\n });\n if (stdoutStreamer) {\n attachStream(subprocess.stdout, stdoutStreamer);\n }\n if (stderrStreamer) {\n attachStream(subprocess.stderr, stderrStreamer);\n }\n const result = await subprocess;\n stdoutStreamer?.flush();\n stderrStreamer?.flush();\n const commandResult: CommandResult = {\n stdout: String(result.stdout ?? ''),\n stderr: String(result.stderr ?? ''),\n exitCode: result.exitCode ?? 0\n };\n if (logger) {\n const stdout = commandResult.stdout.trim();\n const stderr = commandResult.stderr.trim();\n if (stdout.length > 0) {\n logger.debug(`[${label}] stdout: ${stdout}`);\n }\n if (stderr.length > 0) {\n logger.debug(`[${label}] stderr: ${stderr}`);\n }\n logger.debug(`[${label}] exit ${commandResult.exitCode}`);\n }\n return commandResult;\n } catch (error) {\n const execaError = error as ExecaError;\n stdoutStreamer?.flush();\n stderrStreamer?.flush();\n const commandResult: CommandResult = {\n stdout: String(execaError.stdout ?? ''),\n stderr: String(execaError.stderr ?? String(error)),\n exitCode: execaError.exitCode ?? 1\n };\n if (logger) {\n const stdout = commandResult.stdout.trim();\n const stderr = commandResult.stderr.trim();\n if (stdout.length > 0) {\n logger.debug(`[${label}] stdout: ${stdout}`);\n }\n if (stderr.length > 0) {\n logger.debug(`[${label}] stderr: ${stderr}`);\n }\n logger.debug(`[${label}] exit ${commandResult.exitCode}`);\n }\n return commandResult;\n }\n}\n\n/**\n * 返回 ISO 格式时间戳。\n */\nexport function isoNow(): string {\n return new Date().toISOString();\n}\n\n/**\n * 基于 cwd 解析相对路径。\n */\nexport function resolvePath(cwd: string, target: string): string {\n return path.isAbsolute(target) ? target : path.join(cwd, target);\n}\n\n/**\n * 确保目录存在。\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdirp(dirPath);\n}\n\n/**\n * 确保文件存在(必要时创建)。\n */\nexport async function ensureFile(filePath: string, initialContent = ''): Promise<void> {\n await ensureDir(path.dirname(filePath));\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n await fs.writeFile(filePath, initialContent, 'utf8');\n }\n}\n\n/**\n * 向文件末尾追加一段内容(包含换行)。\n */\nexport async function appendSection(filePath: string, content: string): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.appendFile(filePath, `\\n${content}\\n`, 'utf8');\n}\n\n/**\n * 安全读取文件内容,若不存在则返回空字符串。\n */\nexport async function readFileSafe(filePath: string): Promise<string> {\n const exists = await fs.pathExists(filePath);\n if (!exists) return '';\n return fs.readFile(filePath, 'utf8');\n}\n\n/**\n * 格式化 Markdown 标题。\n */\nexport function formatHeading(title: string): string {\n return `## ${title}\\n`;\n}\n\n/**\n * 补齐两位数字字符串。\n */\nexport function pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n","import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport type { Logger } from './logger';\n\n/**\n * 全局快捷指令配置。\n */\nexport interface ShortcutConfig {\n readonly name: string;\n readonly command: string;\n}\n\n/**\n * 全局 alias 配置条目。\n */\nexport interface AliasEntry {\n readonly name: string;\n readonly command: string;\n readonly source: 'alias' | 'shortcut';\n}\n\n/**\n * 全局配置结构。\n */\nexport interface GlobalConfig {\n readonly shortcut?: ShortcutConfig;\n}\n\n/**\n * 获取全局配置文件路径。\n */\nexport function getGlobalConfigPath(): string {\n return path.join(os.homedir(), '.wheel-ai', 'config.toml');\n}\n\nfunction stripTomlComment(line: string): string {\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n for (let i = 0; i < line.length; i += 1) {\n const char = line[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n if (char === '#' || char === ';') {\n return line.slice(0, i);\n }\n }\n return line;\n}\n\nfunction findUnquotedIndex(text: string, target: string): number {\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n for (let i = 0; i < text.length; i += 1) {\n const char = text[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n if (char === target) {\n return i;\n }\n }\n return -1;\n}\n\nfunction parseTomlString(raw: string): string | null {\n const value = raw.trim();\n if (value.length < 2) return null;\n const quote = value[0];\n if (quote !== '\"' && quote !== '\\'') return null;\n let result = '';\n let escaped = false;\n for (let i = 1; i < value.length; i += 1) {\n const char = value[i];\n if (quote === '\"') {\n if (escaped) {\n switch (char) {\n case 'n':\n result += '\\n';\n break;\n case 't':\n result += '\\t';\n break;\n case 'r':\n result += '\\r';\n break;\n case '\"':\n case '\\\\':\n result += char;\n break;\n default:\n result += char;\n break;\n }\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n const rest = value.slice(i + 1).trim();\n if (rest.length > 0) return null;\n return result;\n }\n result += char;\n continue;\n }\n\n if (char === quote) {\n const rest = value.slice(i + 1).trim();\n if (rest.length > 0) return null;\n return result;\n }\n result += char;\n }\n return null;\n}\n\nfunction parseTomlKeyValue(line: string): { key: string; value: string } | null {\n const equalIndex = findUnquotedIndex(line, '=');\n if (equalIndex <= 0) return null;\n\n const key = line.slice(0, equalIndex).trim();\n const valuePart = line.slice(equalIndex + 1).trim();\n if (!key || !valuePart) return null;\n\n const parsedValue = parseTomlString(valuePart);\n if (parsedValue === null) return null;\n\n return { key, value: parsedValue };\n}\n\nfunction normalizeShortcutName(name: string): string | null {\n const trimmed = name.trim();\n if (!trimmed) return null;\n if (/\\s/.test(trimmed)) return null;\n return trimmed;\n}\n\n/**\n * 规范化 alias 名称。\n */\nexport function normalizeAliasName(name: string): string | null {\n return normalizeShortcutName(name);\n}\n\nfunction formatTomlString(value: string): string {\n const escaped = value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n return `\"${escaped}\"`;\n}\n\n/**\n * 更新 alias 配置内容,返回新文本。\n */\nexport function updateAliasContent(content: string, name: string, command: string): string {\n const lines = content.split(/\\r?\\n/);\n const entryLine = `${name} = ${formatTomlString(command)}`;\n let currentSection: string | null = null;\n let aliasStart = -1;\n let aliasEnd = lines.length;\n\n for (let i = 0; i < lines.length; i += 1) {\n const match = /^\\s*\\[(.+?)\\]\\s*$/.exec(lines[i]);\n if (!match) continue;\n if (currentSection === 'alias' && aliasStart >= 0 && aliasEnd === lines.length) {\n aliasEnd = i;\n }\n currentSection = match[1].trim();\n if (currentSection === 'alias') {\n aliasStart = i;\n }\n }\n\n if (aliasStart < 0) {\n const trimmed = content.trimEnd();\n const prefix = trimmed.length > 0 ? `${trimmed}\\n\\n` : '';\n return `${prefix}[alias]\\n${entryLine}\\n`;\n }\n\n let replaced = false;\n for (let i = aliasStart + 1; i < aliasEnd; i += 1) {\n const parsed = parseTomlKeyValue(stripTomlComment(lines[i]).trim());\n if (!parsed) continue;\n if (parsed.key === name) {\n lines[i] = entryLine;\n replaced = true;\n break;\n }\n }\n\n if (!replaced) {\n lines.splice(aliasEnd, 0, entryLine);\n }\n\n const output = lines.join('\\n');\n return output.endsWith('\\n') ? output : `${output}\\n`;\n}\n\n/**\n * 写入或更新 alias 配置。\n */\nexport async function upsertAliasEntry(name: string, command: string, filePath: string = getGlobalConfigPath()): Promise<void> {\n const exists = await fs.pathExists(filePath);\n const content = exists ? await fs.readFile(filePath, 'utf8') : '';\n const nextContent = updateAliasContent(content, name, command);\n await fs.mkdirp(path.dirname(filePath));\n await fs.writeFile(filePath, nextContent, 'utf8');\n}\n\n/**\n * 解析全局 TOML 配置文本。\n */\nexport function parseGlobalConfig(content: string): GlobalConfig {\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n const shortcut: Record<string, string> = {};\n\n for (const rawLine of lines) {\n const line = stripTomlComment(rawLine).trim();\n if (!line) continue;\n\n const sectionMatch = /^\\[(.+)\\]$/.exec(line);\n if (sectionMatch) {\n currentSection = sectionMatch[1].trim();\n continue;\n }\n\n if (currentSection !== 'shortcut') continue;\n const parsed = parseTomlKeyValue(line);\n if (!parsed) continue;\n\n shortcut[parsed.key] = parsed.value;\n }\n\n const name = normalizeShortcutName(shortcut.name ?? '');\n const command = (shortcut.command ?? '').trim();\n if (!name || !command) {\n return {};\n }\n\n return {\n shortcut: {\n name,\n command\n }\n };\n}\n\n/**\n * 解析 alias 配置条目(含 shortcut 作为补充来源)。\n */\nexport function parseAliasEntries(content: string): AliasEntry[] {\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n const entries: AliasEntry[] = [];\n const names = new Set<string>();\n\n for (const rawLine of lines) {\n const line = stripTomlComment(rawLine).trim();\n if (!line) continue;\n\n const sectionMatch = /^\\[(.+)\\]$/.exec(line);\n if (sectionMatch) {\n currentSection = sectionMatch[1].trim();\n continue;\n }\n\n if (currentSection !== 'alias') continue;\n const parsed = parseTomlKeyValue(line);\n if (!parsed) continue;\n\n const name = normalizeShortcutName(parsed.key);\n const command = parsed.value.trim();\n if (!name || !command) continue;\n if (names.has(name)) continue;\n\n names.add(name);\n entries.push({\n name,\n command,\n source: 'alias'\n });\n }\n\n const shortcut = parseGlobalConfig(content).shortcut;\n if (shortcut && !names.has(shortcut.name)) {\n entries.push({\n name: shortcut.name,\n command: shortcut.command,\n source: 'shortcut'\n });\n }\n\n return entries;\n}\n\n/**\n * 读取用户目录下的全局配置。\n */\nexport async function loadGlobalConfig(logger?: Logger): Promise<GlobalConfig | null> {\n const filePath = getGlobalConfigPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) return null;\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n return parseGlobalConfig(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`读取全局配置失败,已忽略:${message}`);\n return null;\n }\n}\n\n/**\n * 将命令行字符串拆解为参数数组(支持引号与转义)。\n */\nexport function splitCommandArgs(command: string): string[] {\n const args: string[] = [];\n let current = '';\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n\n for (let i = 0; i < command.length; i += 1) {\n const char = command[i];\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n continue;\n }\n current += char;\n continue;\n }\n\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n\n if (/\\s/.test(char)) {\n if (current.length > 0) {\n args.push(current);\n current = '';\n }\n continue;\n }\n\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n\n current += char;\n }\n\n if (current.length > 0) {\n args.push(current);\n }\n\n return args;\n}\n\nfunction normalizeShortcutArgs(args: string[]): string[] {\n if (args.length > 0 && args[0] === 'run') {\n return args.slice(1);\n }\n return args;\n}\n\n/**\n * 应用全局快捷指令,将别名替换为 run 子命令参数。\n */\nexport function applyShortcutArgv(argv: string[], config: GlobalConfig | null): string[] {\n if (!config?.shortcut) return argv;\n if (argv.length < 3) return argv;\n const commandIndex = 2;\n if (argv[commandIndex] !== config.shortcut.name) return argv;\n\n const shortcutArgs = normalizeShortcutArgs(splitCommandArgs(config.shortcut.command));\n return [\n ...argv.slice(0, commandIndex),\n 'run',\n ...shortcutArgs,\n ...argv.slice(commandIndex + 1)\n ];\n}\n","import path from 'node:path';\nimport { Logger } from './logger';\nimport { CommitMessage, WorktreeConfig, WorktreeResult } from './types';\nimport { runCommand, resolvePath } from './utils';\n\nasync function branchExists(branch: string, cwd: string, logger?: Logger): Promise<boolean> {\n const result = await runCommand('git', ['rev-parse', '--verify', branch], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-parse --verify ${branch}`\n });\n return result.exitCode === 0;\n}\n\nasync function resolveBaseBranch(baseBranch: string, repoRoot: string, logger: Logger): Promise<string> {\n const baseExists = await branchExists(baseBranch, repoRoot, logger);\n if (baseExists) return baseBranch;\n\n const current = await getCurrentBranch(repoRoot, logger);\n const currentExists = await branchExists(current, repoRoot, logger);\n if (currentExists) {\n logger.warn(`基线分支 ${baseBranch} 不存在,改用当前分支 ${current} 作为基线`);\n return current;\n }\n\n throw new Error(`基线分支 ${baseBranch} 不存在,且无法确定可用的当前分支`);\n}\n\n/**\n * 获取仓库根目录。\n */\nexport async function getRepoRoot(cwd: string, logger?: Logger): Promise<string> {\n const result = await runCommand('git', ['rev-parse', '--show-toplevel'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git rev-parse --show-toplevel'\n });\n if (result.exitCode !== 0) {\n throw new Error('当前目录不是 git 仓库,无法继续');\n }\n return result.stdout.trim();\n}\n\n/**\n * 获取当前分支名。\n */\nexport async function getCurrentBranch(cwd: string, logger?: Logger): Promise<string> {\n const result = await runCommand('git', ['branch', '--show-current'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git branch --show-current'\n });\n if (result.exitCode !== 0) {\n throw new Error(`无法获取当前分支: ${result.stderr}`);\n }\n return result.stdout.trim();\n}\n\nasync function getUpstreamBranch(branchName: string, cwd: string, logger?: Logger): Promise<string | null> {\n const result = await runCommand('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', `${branchName}@{u}`], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-parse --abbrev-ref --symbolic-full-name ${branchName}@{u}`\n });\n if (result.exitCode !== 0) {\n logger?.warn(`分支 ${branchName} 没有关联的 upstream: ${result.stderr || result.stdout}`);\n return null;\n }\n return result.stdout.trim();\n}\n\nfunction defaultWorktreePath(repoRoot: string, branchName: string): string {\n return path.join(repoRoot, '..', 'worktrees', branchName);\n}\n\n/**\n * 确保目标分支存在。\n */\nexport async function ensureBranchExists(branchName: string, baseBranch: string, repoRoot: string, logger: Logger): Promise<void> {\n const exists = await branchExists(branchName, repoRoot, logger);\n if (exists) return;\n const create = await runCommand('git', ['branch', branchName, baseBranch], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git branch ${branchName} ${baseBranch}`\n });\n if (create.exitCode !== 0) {\n throw new Error(`创建分支失败: ${create.stderr}`);\n }\n logger.info(`已基于 ${baseBranch} 创建分支 ${branchName}`);\n}\n\n/**\n * 根据配置创建或复用 worktree。\n */\nexport async function ensureWorktree(config: WorktreeConfig, repoRoot: string, logger: Logger): Promise<WorktreeResult> {\n if (!config.useWorktree) {\n return { path: repoRoot, created: false };\n }\n\n const branchName = config.branchName ?? generateBranchName();\n const baseBranch = await resolveBaseBranch(config.baseBranch, repoRoot, logger);\n const worktreePath = resolvePath(repoRoot, config.worktreePath ?? defaultWorktreePath(repoRoot, branchName));\n\n await ensureBranchExists(branchName, baseBranch, repoRoot, logger);\n\n const addResult = await runCommand('git', ['worktree', 'add', worktreePath, branchName], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git worktree add ${worktreePath} ${branchName}`\n });\n if (addResult.exitCode !== 0) {\n const alreadyExists = addResult.stderr.includes('already exists') || addResult.stdout.includes('already exists');\n if (alreadyExists) {\n logger.warn(`worktree 路径已存在,跳过创建: ${worktreePath}`);\n return { path: worktreePath, created: false };\n }\n throw new Error(`创建 worktree 失败: ${addResult.stderr || addResult.stdout}`);\n }\n\n logger.success(`已在 ${worktreePath} 创建并挂载 worktree (${branchName})`);\n return { path: worktreePath, created: true };\n}\n\n/**\n * 判断 worktree 是否干净。\n */\nexport async function isWorktreeClean(cwd: string, logger?: Logger): Promise<boolean> {\n const status = await runCommand('git', ['status', '--porcelain'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git status --porcelain'\n });\n if (status.exitCode !== 0) {\n logger?.warn(`无法获取 git 状态: ${status.stderr || status.stdout}`);\n return false;\n }\n return status.stdout.trim().length === 0;\n}\n\n/**\n * 判断分支是否已推送到远端。\n */\nexport async function isBranchPushed(branchName: string, cwd: string, logger: Logger): Promise<boolean> {\n const upstream = await getUpstreamBranch(branchName, cwd, logger);\n if (!upstream) return false;\n\n const countResult = await runCommand('git', ['rev-list', '--left-right', '--count', `${upstream}...${branchName}`], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-list --left-right --count ${upstream}...${branchName}`\n });\n if (countResult.exitCode !== 0) {\n logger.warn(`无法比较分支 ${branchName} 与 ${upstream}: ${countResult.stderr || countResult.stdout}`);\n return false;\n }\n\n const [behindStr, aheadStr] = countResult.stdout.trim().split(/\\s+/);\n const ahead = Number.parseInt(aheadStr ?? '0', 10);\n if (Number.isNaN(ahead)) {\n logger.warn(`无法解析分支推送状态: ${countResult.stdout}`);\n return false;\n }\n if (ahead > 0) {\n logger.warn(`分支 ${branchName} 仍有 ${ahead} 个本地提交未推送`);\n return false;\n }\n return true;\n}\n\nfunction normalizeCommitTitle(title: string): string {\n return title.replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeCommitBody(body?: string): string | undefined {\n if (!body) return undefined;\n const normalized = body.replace(/\\r\\n?/g, '\\n').trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction formatCommitCommand(message: CommitMessage): string {\n const title = normalizeCommitTitle(message.title) || 'chore: 更新迭代产出';\n const parts = ['git commit -m', JSON.stringify(title)];\n const body = normalizeCommitBody(message.body);\n if (body) {\n parts.push('-m', JSON.stringify(body));\n }\n return parts.join(' ');\n}\n\nfunction buildCommitArgs(message: CommitMessage): string[] {\n const title = normalizeCommitTitle(message.title) || 'chore: 更新迭代产出';\n const args = ['commit', '-m', title];\n const body = normalizeCommitBody(message.body);\n if (body) {\n args.push('-m', body);\n }\n return args;\n}\n\n/**\n * 提交当前变更。\n */\nexport async function commitAll(message: CommitMessage, cwd: string, logger: Logger): Promise<boolean> {\n const add = await runCommand('git', ['add', '-A'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git add -A'\n });\n if (add.exitCode !== 0) {\n throw new Error(`git add 失败: ${add.stderr}`);\n }\n const commit = await runCommand('git', buildCommitArgs(message), {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: formatCommitCommand(message)\n });\n if (commit.exitCode !== 0) {\n logger.warn(`git commit 跳过或失败: ${commit.stderr}`);\n return false;\n }\n logger.success('已提交当前变更');\n return true;\n}\n\n/**\n * 推送分支到远端。\n */\nexport async function pushBranch(branchName: string, cwd: string, logger: Logger): Promise<void> {\n const push = await runCommand('git', ['push', '-u', 'origin', branchName], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git push -u origin ${branchName}`\n });\n if (push.exitCode !== 0) {\n throw new Error(`git push 失败: ${push.stderr}`);\n }\n logger.success(`已推送分支 ${branchName}`);\n}\n\n/**\n * 删除 worktree 并清理。\n */\nexport async function removeWorktree(worktreePath: string, repoRoot: string, logger: Logger): Promise<void> {\n const remove = await runCommand('git', ['worktree', 'remove', '--force', worktreePath], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git worktree remove --force ${worktreePath}`\n });\n if (remove.exitCode !== 0) {\n throw new Error(`删除 worktree 失败: ${remove.stderr || remove.stdout}`);\n }\n\n const prune = await runCommand('git', ['worktree', 'prune'], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git worktree prune'\n });\n if (prune.exitCode !== 0) {\n logger.warn(`worktree prune 失败: ${prune.stderr || prune.stdout}`);\n }\n\n logger.success(`已删除 worktree: ${worktreePath}`);\n}\n\n/**\n * 生成默认分支名。\n */\nexport function generateBranchName(): string {\n const now = new Date();\n const stamp = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}-${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;\n return `wheel-ai/${stamp}`;\n}\n\nfunction guessBranchType(task: string): string {\n const text = task.toLowerCase();\n if (/fix|bug|修复|错误|异常|问题/.test(text)) return 'fix';\n if (/docs|readme|changelog|文档/.test(text)) return 'docs';\n if (/test|e2e|单测|测试/.test(text)) return 'test';\n if (/refactor|重构/.test(text)) return 'refactor';\n if (/chore|构建|依赖|配置/.test(text)) return 'chore';\n return 'feat';\n}\n\nfunction slugifyTask(task: string): string {\n const slug = task\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug.slice(0, 40);\n}\n\nfunction buildTimestampSlug(now: Date): string {\n const stamp = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}-${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;\n return `auto-${stamp}`;\n}\n\n/**\n * 基于任务生成分支名(AI 失败时兜底)。\n */\nexport function generateBranchNameFromTask(task: string, now: Date = new Date()): string {\n const slug = slugifyTask(task);\n const type = guessBranchType(task);\n const suffix = slug || buildTimestampSlug(now);\n return `${type}/${suffix}`;\n}\n","import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { pad2 } from './utils';\n\nexport interface RunMetadata {\n readonly command: string;\n readonly round: number;\n readonly tokenUsed: number;\n readonly path: string;\n readonly pid?: number;\n}\n\nexport interface CurrentRegistryEntry extends RunMetadata {\n readonly logFile?: string;\n}\n\nexport type CurrentRegistry = Record<string, CurrentRegistryEntry>;\n\nconst LOGS_DIR = path.join(os.homedir(), '.wheel-ai', 'logs');\n\nexport function getLogsDir(): string {\n return LOGS_DIR;\n}\n\nexport function getCurrentRegistryPath(): string {\n return path.join(LOGS_DIR, 'current.json');\n}\n\nexport async function ensureLogsDir(): Promise<void> {\n await fs.mkdirp(LOGS_DIR);\n}\n\n/**\n * 生成时间字符串(YYYYMMDDHHmmss)。\n */\nexport function formatTimeString(date: Date = new Date()): string {\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}${month}${day}${hours}${minutes}${seconds}`;\n}\n\n/**\n * 清理分支名中的非法字符。\n */\nexport function sanitizeBranchName(branchName: string): string {\n const normalized = branchName.trim();\n if (!normalized) return '';\n const replaced = normalized.replace(/[\\\\/:*?\"<>|\\s]+/g, '-');\n return replaced.replace(/-+/g, '-').replace(/^-+|-+$/g, '');\n}\n\nexport function buildAutoLogFilePath(branchName: string, date: Date = new Date()): string {\n const safeBranch = sanitizeBranchName(branchName) || 'unknown';\n return path.join(LOGS_DIR, `wheel-ai-auto-log-${formatTimeString(date)}-${safeBranch}.log`);\n}\n\nexport function getLogMetaPath(logFile: string): string {\n const baseName = path.basename(logFile, path.extname(logFile));\n return path.join(LOGS_DIR, `${baseName}.json`);\n}\n\nfunction buildLogKey(logFile: string): string {\n return path.basename(logFile);\n}\n\n/**\n * 格式化命令行字符串(用于写入元信息)。\n */\nexport function formatCommandLine(argv: string[]): string {\n const quote = (value: string): string => {\n if (/[\\s\"'\\\\]/.test(value)) {\n return JSON.stringify(value);\n }\n return value;\n };\n return argv.map(quote).join(' ').trim();\n}\n\nasync function writeJsonFile(filePath: string, data: unknown): Promise<void> {\n await ensureLogsDir();\n await fs.writeFile(filePath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n}\n\n/**\n * 写入单次运行的元信息。\n */\nexport async function writeRunMetadata(logFile: string, metadata: RunMetadata): Promise<void> {\n const metaPath = getLogMetaPath(logFile);\n await writeJsonFile(metaPath, metadata);\n}\n\n/**\n * 读取 current.json 注册表。\n */\nexport async function readCurrentRegistry(): Promise<CurrentRegistry> {\n const filePath = getCurrentRegistryPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) return {};\n try {\n const content = await fs.readFile(filePath, 'utf8');\n const parsed = JSON.parse(content) as CurrentRegistry;\n if (!parsed || typeof parsed !== 'object') return {};\n return parsed;\n } catch {\n return {};\n }\n}\n\n/**\n * 更新 current.json 中的运行记录。\n */\nexport async function upsertCurrentRegistry(logFile: string, metadata: RunMetadata): Promise<void> {\n const registry = await readCurrentRegistry();\n const key = buildLogKey(logFile);\n registry[key] = { ...metadata, logFile };\n await writeJsonFile(getCurrentRegistryPath(), registry);\n}\n\n/**\n * 从 current.json 中移除运行记录。\n */\nexport async function removeCurrentRegistry(logFile: string): Promise<void> {\n const registry = await readCurrentRegistry();\n const key = buildLogKey(logFile);\n if (!(key in registry)) return;\n delete registry[key];\n await writeJsonFile(getCurrentRegistryPath(), registry);\n}\n","import fs from 'fs-extra';\nimport { AliasEntry, getGlobalConfigPath, parseAliasEntries } from './global-config';\n\ninterface AliasViewerState {\n aliases: AliasEntry[];\n selectedIndex: number;\n listOffset: number;\n missingConfig: boolean;\n lastError?: string;\n}\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nfunction buildAliasLabel(entry: AliasEntry): string {\n if (entry.source === 'shortcut') {\n return `${entry.name}(shortcut)`;\n }\n return entry.name;\n}\n\nfunction buildHeader(state: AliasViewerState, columns: number): string {\n const total = state.aliases.length;\n const title = `别名列表(${total} 条)|↑/↓ 选择 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildStatus(state: AliasViewerState, columns: number): string {\n if (state.aliases.length === 0) {\n if (state.lastError) {\n return truncateLine(`读取失败:${state.lastError}`, columns);\n }\n if (state.missingConfig) {\n return truncateLine(`未找到配置文件:${getGlobalConfigPath()}`, columns);\n }\n return truncateLine('未发现 alias 配置', columns);\n }\n\n const entry = state.aliases[state.selectedIndex];\n const sourceText = entry.source === 'shortcut' ? '(shortcut)' : '';\n return truncateLine(`命令${sourceText}:${entry.command}`, columns);\n}\n\nfunction buildListLine(entry: AliasEntry, selected: boolean, columns: number): string {\n const marker = selected ? '>' : ' ';\n return truncateLine(`${marker} ${buildAliasLabel(entry)}`, columns);\n}\n\nfunction ensureListOffset(state: AliasViewerState, pageSize: number): void {\n const total = state.aliases.length;\n if (total === 0) {\n state.listOffset = 0;\n state.selectedIndex = 0;\n return;\n }\n const maxOffset = Math.max(0, total - pageSize);\n if (state.selectedIndex < state.listOffset) {\n state.listOffset = state.selectedIndex;\n }\n if (state.selectedIndex >= state.listOffset + pageSize) {\n state.listOffset = state.selectedIndex - pageSize + 1;\n }\n state.listOffset = Math.min(Math.max(state.listOffset, 0), maxOffset);\n}\n\nfunction render(state: AliasViewerState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildHeader(state, columns);\n ensureListOffset(state, pageSize);\n\n if (state.aliases.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const status = buildStatus(state, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const start = state.listOffset;\n const slice = state.aliases.slice(start, start + pageSize);\n const lines = slice.map((entry, index) => {\n const selected = start + index === state.selectedIndex;\n return buildListLine(entry, selected, columns);\n });\n while (lines.length < pageSize) {\n lines.push('');\n }\n const status = buildStatus(state, columns);\n const content = [header, ...lines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction isArrowUp(input: string): boolean {\n return input.includes('\\u001b[A');\n}\n\nfunction isArrowDown(input: string): boolean {\n return input.includes('\\u001b[B');\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\nfunction clampIndex(value: number, total: number): number {\n if (total <= 0) return 0;\n return Math.min(Math.max(value, 0), total - 1);\n}\n\n/**\n * 启动 alias 浏览界面。\n */\nexport async function runAliasViewer(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 alias。');\n return;\n }\n\n const state: AliasViewerState = {\n aliases: [],\n selectedIndex: 0,\n listOffset: 0,\n missingConfig: false\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n const loadAliases = async (): Promise<void> => {\n const filePath = getGlobalConfigPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n state.aliases = [];\n state.selectedIndex = 0;\n state.lastError = undefined;\n state.missingConfig = true;\n return;\n }\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n state.aliases = parseAliasEntries(content);\n state.selectedIndex = clampIndex(state.selectedIndex, state.aliases.length);\n state.lastError = undefined;\n state.missingConfig = false;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.aliases = [];\n state.selectedIndex = 0;\n state.lastError = message;\n state.missingConfig = false;\n }\n };\n\n await loadAliases();\n render(state);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n cleanup();\n process.exit(0);\n }\n\n if (isArrowUp(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex - 1, state.aliases.length);\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex + 1, state.aliases.length);\n render(state);\n }\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport { CurrentRegistry, RunMetadata, getLogsDir, readCurrentRegistry } from './logs';\nimport { pad2 } from './utils';\n\nexport interface LogEntry {\n readonly fileName: string;\n readonly filePath: string;\n readonly size: number;\n readonly mtimeMs: number;\n readonly meta?: RunMetadata;\n}\n\ninterface ViewState {\n entry: LogEntry;\n lines: string[];\n lineOffset: number;\n}\n\ninterface LogsViewerState {\n mode: 'list' | 'view';\n logs: LogEntry[];\n selectedIndex: number;\n listOffset: number;\n view?: ViewState;\n lastError?: string;\n}\n\nfunction isRunMetadata(value: unknown): value is RunMetadata {\n if (!value || typeof value !== 'object') return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.command === 'string' &&\n typeof record.round === 'number' &&\n typeof record.tokenUsed === 'number' &&\n typeof record.path === 'string'\n );\n}\n\nfunction buildLogMetaPath(logsDir: string, logFile: string): string {\n const baseName = path.basename(logFile, path.extname(logFile));\n return path.join(logsDir, `${baseName}.json`);\n}\n\nasync function readLogMetadata(logsDir: string, logFile: string): Promise<RunMetadata | undefined> {\n const metaPath = buildLogMetaPath(logsDir, logFile);\n const exists = await fs.pathExists(metaPath);\n if (!exists) return undefined;\n try {\n const content = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(content) as unknown;\n return isRunMetadata(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function buildRunningLogKeys(registry: CurrentRegistry): Set<string> {\n const keys = new Set<string>();\n for (const [key, entry] of Object.entries(registry)) {\n keys.add(key);\n if (entry.logFile) {\n keys.add(path.basename(entry.logFile));\n }\n }\n return keys;\n}\n\nexport async function loadLogEntries(logsDir: string, registry: CurrentRegistry): Promise<LogEntry[]> {\n const exists = await fs.pathExists(logsDir);\n if (!exists) return [];\n const running = buildRunningLogKeys(registry);\n const names = await fs.readdir(logsDir);\n const entries: LogEntry[] = [];\n for (const name of names) {\n if (path.extname(name).toLowerCase() !== '.log') continue;\n if (running.has(name)) continue;\n const filePath = path.join(logsDir, name);\n let stat: fs.Stats;\n try {\n stat = await fs.stat(filePath);\n } catch {\n continue;\n }\n if (!stat.isFile()) continue;\n const meta = await readLogMetadata(logsDir, filePath);\n entries.push({\n fileName: name,\n filePath,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n meta\n });\n }\n return entries.sort((a, b) => b.mtimeMs - a.mtimeMs);\n}\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction formatTimestamp(ms: number): string {\n const date = new Date(ms);\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\nfunction formatBytes(size: number): string {\n if (size < 1024) return `${size}B`;\n const kb = size / 1024;\n if (kb < 1024) return `${kb.toFixed(1)}KB`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)}MB`;\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nasync function readLogLines(logFile: string): Promise<string[]> {\n try {\n const content = await fs.readFile(logFile, 'utf8');\n const normalized = content.replace(/\\r\\n?/g, '\\n');\n const lines = normalized.split('\\n');\n return lines.length > 0 ? lines : [''];\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`(无法读取日志文件:${message})`];\n }\n}\n\nfunction buildListHeader(state: LogsViewerState, columns: number): string {\n const total = state.logs.length;\n const title = `日志列表(${total} 条)|↑/↓ 选择 Enter 查看 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildListStatus(state: LogsViewerState, columns: number): string {\n if (state.logs.length === 0) {\n const text = state.lastError ? `加载失败:${state.lastError}` : '暂无可查看的日志';\n return truncateLine(text, columns);\n }\n const entry = state.logs[state.selectedIndex];\n const meta = entry.meta;\n const detail = meta ? `项目 ${meta.path}` : `文件 ${entry.fileName}`;\n const suffix = state.lastError ? ` | 加载失败:${state.lastError}` : '';\n return truncateLine(`${detail}${suffix}`, columns);\n}\n\nfunction buildListLine(entry: LogEntry, selected: boolean, columns: number): string {\n const marker = selected ? '>' : ' ';\n const time = formatTimestamp(entry.mtimeMs);\n const metaInfo = entry.meta\n ? `轮次 ${entry.meta.round} | Token ${entry.meta.tokenUsed}`\n : `大小 ${formatBytes(entry.size)}`;\n return truncateLine(`${marker} ${entry.fileName} | ${time} | ${metaInfo}`, columns);\n}\n\nfunction buildViewHeader(entry: LogEntry, columns: number): string {\n const title = `日志查看|${entry.fileName}|↑/↓ 上下 1 行 PageUp/PageDown 翻页 b 返回 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildViewStatus(entry: LogEntry, page: { current: number; total: number }, columns: number): string {\n const meta = entry.meta;\n const metaInfo = meta\n ? `轮次 ${meta.round} | Token ${meta.tokenUsed} | 项目 ${meta.path}`\n : `文件 ${entry.fileName}`;\n const status = `页 ${page.current}/${page.total} | ${metaInfo}`;\n return truncateLine(status, columns);\n}\n\nfunction ensureListOffset(state: LogsViewerState, pageSize: number): void {\n const total = state.logs.length;\n if (total === 0) {\n state.listOffset = 0;\n state.selectedIndex = 0;\n return;\n }\n const maxOffset = Math.max(0, total - pageSize);\n if (state.selectedIndex < state.listOffset) {\n state.listOffset = state.selectedIndex;\n }\n if (state.selectedIndex >= state.listOffset + pageSize) {\n state.listOffset = state.selectedIndex - pageSize + 1;\n }\n state.listOffset = Math.min(Math.max(state.listOffset, 0), maxOffset);\n}\n\nfunction renderList(state: LogsViewerState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildListHeader(state, columns);\n ensureListOffset(state, pageSize);\n\n if (state.logs.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const status = buildListStatus(state, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const start = state.listOffset;\n const slice = state.logs.slice(start, start + pageSize);\n const lines = slice.map((entry, index) => {\n const selected = start + index === state.selectedIndex;\n return buildListLine(entry, selected, columns);\n });\n while (lines.length < pageSize) {\n lines.push('');\n }\n const status = buildListStatus(state, columns);\n const content = [header, ...lines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction renderView(view: ViewState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildViewHeader(view.entry, columns);\n const maxOffset = Math.max(0, view.lines.length - pageSize);\n view.lineOffset = Math.min(Math.max(view.lineOffset, 0), maxOffset);\n\n const start = view.lineOffset;\n const pageLines = view.lines.slice(start, start + pageSize).map(line => truncateLine(line, columns));\n while (pageLines.length < pageSize) {\n pageLines.push('');\n }\n\n const totalPages = Math.max(1, Math.ceil(view.lines.length / pageSize));\n const currentPage = Math.min(totalPages, Math.floor(view.lineOffset / pageSize) + 1);\n const status = buildViewStatus(view.entry, { current: currentPage, total: totalPages }, columns);\n const content = [header, ...pageLines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction render(state: LogsViewerState): void {\n if (state.mode === 'view' && state.view) {\n renderView(state.view);\n return;\n }\n renderList(state);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction isEnter(input: string): boolean {\n return input.includes('\\r') || input.includes('\\n');\n}\n\nfunction isArrowUp(input: string): boolean {\n return input.includes('\\u001b[A');\n}\n\nfunction isArrowDown(input: string): boolean {\n return input.includes('\\u001b[B');\n}\n\nfunction isPageUp(input: string): boolean {\n return input.includes('\\u001b[5~');\n}\n\nfunction isPageDown(input: string): boolean {\n return input.includes('\\u001b[6~');\n}\n\nfunction isEscape(input: string): boolean {\n return input === '\\u001b';\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\nfunction clampIndex(value: number, total: number): number {\n if (total <= 0) return 0;\n return Math.min(Math.max(value, 0), total - 1);\n}\n\n/**\n * 启动日志列表查看界面。\n */\nexport async function runLogsViewer(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 logs。');\n return;\n }\n\n const logsDir = getLogsDir();\n const state: LogsViewerState = {\n mode: 'list',\n logs: [],\n selectedIndex: 0,\n listOffset: 0\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n let loading = false;\n\n const loadLogs = async (): Promise<void> => {\n try {\n const registry = await readCurrentRegistry();\n state.logs = await loadLogEntries(logsDir, registry);\n state.selectedIndex = clampIndex(state.selectedIndex, state.logs.length);\n state.lastError = undefined;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.lastError = message;\n state.logs = [];\n state.selectedIndex = 0;\n }\n };\n\n const openView = async (): Promise<void> => {\n if (loading || state.logs.length === 0) return;\n loading = true;\n const entry = state.logs[state.selectedIndex];\n state.mode = 'view';\n state.view = {\n entry,\n lines: ['加载中…'],\n lineOffset: 0\n };\n render(state);\n const lines = await readLogLines(entry.filePath);\n const pageSize = getPageSize(getTerminalSize().rows);\n const maxOffset = Math.max(0, lines.length - pageSize);\n state.view = {\n entry,\n lines,\n lineOffset: maxOffset\n };\n loading = false;\n render(state);\n };\n\n await loadLogs();\n render(state);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n cleanup();\n process.exit(0);\n }\n\n if (state.mode === 'list') {\n if (isArrowUp(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex - 1, state.logs.length);\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex + 1, state.logs.length);\n render(state);\n return;\n }\n if (isEnter(input)) {\n void openView();\n return;\n }\n return;\n }\n\n if (state.mode === 'view' && state.view) {\n if (isArrowUp(input)) {\n state.view.lineOffset -= 1;\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.view.lineOffset += 1;\n render(state);\n return;\n }\n if (isPageUp(input)) {\n const pageSize = getPageSize(getTerminalSize().rows);\n state.view.lineOffset -= pageSize;\n render(state);\n return;\n }\n if (isPageDown(input)) {\n const pageSize = getPageSize(getTerminalSize().rows);\n state.view.lineOffset += pageSize;\n render(state);\n return;\n }\n if (input.toLowerCase() === 'b' || isEscape(input)) {\n state.mode = 'list';\n state.view = undefined;\n render(state);\n return;\n }\n }\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport {\n buildBranchNamePrompt,\n buildDocsPrompt,\n buildFixPrompt,\n buildPlanItemPrompt,\n buildPlanningPrompt,\n buildQualityPrompt,\n buildTestPrompt,\n formatIterationRecord,\n mergeTokenUsage,\n parseBranchName,\n runAi\n} from './ai';\nimport { ensureDependencies } from './deps';\nimport { GhPrInfo, createPr, enableAutoMerge, listFailedRuns, viewPr } from './gh';\nimport { Logger } from './logger';\nimport { commitAll, ensureWorktree, generateBranchNameFromTask, getCurrentBranch, getRepoRoot, isBranchPushed, isWorktreeClean, pushBranch, removeWorktree } from './git';\nimport { formatCommandLine } from './logs';\nimport { getPendingPlanItems } from './plan';\nimport { detectQualityCommands } from './quality';\nimport { createRunTracker } from './runtime-tracker';\nimport { buildFallbackSummary, buildSummaryPrompt, ensurePrBodySections, parseDeliverySummary } from './summary';\nimport { CheckRunResult, CommitMessage, DeliverySummary, LoopConfig, LoopResult, TestRunResult, TokenUsage, WorkflowFiles, WorktreeResult } from './types';\nimport { appendSection, ensureFile, isoNow, readFileSafe, runCommand } from './utils';\nimport { buildWebhookPayload, sendWebhookNotifications } from './webhook';\n\nasync function ensureWorkflowFiles(workflowFiles: WorkflowFiles): Promise<void> {\n await ensureFile(workflowFiles.workflowDoc, '# AI 工作流程基线\\n');\n await ensureFile(workflowFiles.planFile, '# 计划\\n');\n await ensureFile(workflowFiles.notesFile, '# 持久化记忆\\n');\n}\n\nconst MAX_LOG_LENGTH = 4000;\n\nfunction trimOutput(output: string, limit = MAX_LOG_LENGTH): string {\n if (!output) return '';\n if (output.length <= limit) return output;\n return `${output.slice(0, limit)}\\n……(输出已截断,原始长度 ${output.length} 字符)`;\n}\n\nfunction truncateText(text: string, limit = 24): string {\n const trimmed = text.trim();\n if (trimmed.length <= limit) return trimmed;\n return `${trimmed.slice(0, limit)}...`;\n}\n\nasync function safeCommandOutput(command: string, args: string[], cwd: string, logger: Logger, label: string, verboseCommand: string): Promise<string> {\n const result = await runCommand(command, args, {\n cwd,\n logger,\n verboseLabel: label,\n verboseCommand\n });\n if (result.exitCode !== 0) {\n logger.warn(`${label} 命令失败: ${result.stderr || result.stdout}`);\n return '';\n }\n return result.stdout.trim();\n}\n\nasync function runSingleTest(kind: 'unit' | 'e2e', command: string, cwd: string, logger: Logger): Promise<TestRunResult> {\n const label = kind === 'unit' ? '单元测试' : 'e2e 测试';\n logger.info(`执行${label}: ${command}`);\n const result = await runCommand('bash', ['-lc', command], {\n cwd,\n logger,\n verboseLabel: 'shell',\n verboseCommand: `bash -lc \"${command}\"`\n });\n const success = result.exitCode === 0;\n if (success) {\n logger.success(`${label}完成`);\n } else {\n logger.warn(`${label}失败(退出码 ${result.exitCode})`);\n }\n\n return {\n kind,\n command,\n success,\n exitCode: result.exitCode,\n stdout: trimOutput(result.stdout.trim()),\n stderr: trimOutput(result.stderr.trim())\n };\n}\n\nasync function runQualityChecks(commands: { name: string; command: string }[], cwd: string, logger: Logger): Promise<CheckRunResult[]> {\n const results: CheckRunResult[] = [];\n for (const item of commands) {\n logger.info(`执行质量检查: ${item.command}`);\n const result = await runCommand('bash', ['-lc', item.command], {\n cwd,\n logger,\n verboseLabel: 'shell',\n verboseCommand: `bash -lc \"${item.command}\"`\n });\n results.push({\n name: item.name,\n command: item.command,\n success: result.exitCode === 0,\n exitCode: result.exitCode,\n stdout: trimOutput(result.stdout.trim()),\n stderr: trimOutput(result.stderr.trim())\n });\n }\n return results;\n}\n\nfunction buildCheckResultSummary(results: CheckRunResult[]): string {\n if (results.length === 0) return '(未执行质量检查)';\n return results\n .map(result => {\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const output = result.success ? '' : `\\n${result.stderr || result.stdout || '(无输出)'}`;\n return `- ${result.name}: ${status}|命令: ${result.command}${output}`;\n })\n .join('\\n');\n}\n\nfunction buildFailedCheckSummary(results: CheckRunResult[]): string {\n return buildCheckResultSummary(results.filter(result => !result.success));\n}\n\nfunction buildTestResultSummary(results: TestRunResult[]): string {\n if (results.length === 0) return '(未执行测试)';\n return results\n .map(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const output = result.success ? '' : `\\n${result.stderr || result.stdout || '(无输出)'}`;\n return `- ${label}: ${status}|命令: ${result.command}${output}`;\n })\n .join('\\n');\n}\n\nfunction buildFailedTestSummary(results: TestRunResult[]): string {\n return buildTestResultSummary(results.filter(result => !result.success));\n}\n\nfunction formatSystemRecord(stage: string, detail: string, timestamp: string): string {\n return [\n `### 记录 | ${timestamp} | ${stage}`,\n '',\n detail,\n ''\n ].join('\\n');\n}\n\nfunction shouldSkipQuality(content: string, cliSkip: boolean): boolean {\n if (cliSkip) return true;\n const normalized = content.replace(/\\s+/g, '');\n if (!normalized) return false;\n return normalized.includes('不要检查代码质量')\n || normalized.includes('不检查代码质量')\n || normalized.includes('跳过代码质量');\n}\n\nasync function runTests(config: LoopConfig, workDir: string, logger: Logger): Promise<TestRunResult[]> {\n const results: TestRunResult[] = [];\n\n if (config.runTests && config.tests.unitCommand) {\n const unitResult = await runSingleTest('unit', config.tests.unitCommand, workDir, logger);\n results.push(unitResult);\n }\n\n if (config.runE2e && config.tests.e2eCommand) {\n const e2eResult = await runSingleTest('e2e', config.tests.e2eCommand, workDir, logger);\n results.push(e2eResult);\n }\n\n return results;\n}\n\nasync function runTestsSafely(config: LoopConfig, workDir: string, logger: Logger): Promise<TestRunResult[]> {\n try {\n return await runTests(config, workDir, logger);\n } catch (error) {\n const errorMessage = String(error);\n logger.warn(`测试执行异常: ${errorMessage}`);\n return [{\n kind: 'unit',\n command: config.tests.unitCommand ?? '未知测试命令',\n success: false,\n exitCode: -1,\n stdout: '',\n stderr: trimOutput(errorMessage)\n }];\n }\n}\n\nfunction reRootPath(filePath: string, repoRoot: string, workDir: string): string {\n const relative = path.relative(repoRoot, filePath);\n if (relative.startsWith('..')) return filePath;\n return path.join(workDir, relative);\n}\n\nfunction reRootWorkflowFiles(workflowFiles: WorkflowFiles, repoRoot: string, workDir: string): WorkflowFiles {\n if (repoRoot === workDir) return workflowFiles;\n return {\n workflowDoc: reRootPath(workflowFiles.workflowDoc, repoRoot, workDir),\n notesFile: reRootPath(workflowFiles.notesFile, repoRoot, workDir),\n planFile: reRootPath(workflowFiles.planFile, repoRoot, workDir)\n };\n}\n\nfunction buildBodyFile(workDir: string): string {\n return path.join(workDir, 'memory', 'pr-body.md');\n}\n\nasync function writePrBody(bodyPath: string, content: string, appendExisting: boolean): Promise<void> {\n await fs.mkdirp(path.dirname(bodyPath));\n let finalContent = content.trim();\n if (appendExisting) {\n const existing = await readFileSafe(bodyPath);\n const trimmedExisting = existing.trim();\n if (trimmedExisting.length > 0) {\n finalContent = `${trimmedExisting}\\n\\n---\\n\\n${finalContent}`;\n }\n }\n await fs.writeFile(bodyPath, `${finalContent}\\n`, 'utf8');\n}\n\ninterface WorktreeCleanupContext {\n readonly repoRoot: string;\n readonly workDir: string;\n readonly branchName?: string;\n readonly prInfo: GhPrInfo | null;\n readonly worktreeCreated: boolean;\n readonly logger: Logger;\n}\n\nasync function cleanupWorktreeIfSafe(context: WorktreeCleanupContext): Promise<void> {\n const { repoRoot, workDir, branchName, prInfo, worktreeCreated, logger } = context;\n if (!worktreeCreated) {\n logger.debug('worktree 并非本次创建,跳过自动清理');\n return;\n }\n if (workDir === repoRoot) {\n logger.debug('当前未使用独立 worktree,跳过自动清理');\n return;\n }\n if (!branchName) {\n logger.warn('未能确定 worktree 分支名,保留工作目录以免丢失进度');\n return;\n }\n\n const clean = await isWorktreeClean(workDir, logger);\n if (!clean) {\n logger.warn('worktree 仍有未提交变更,已保留工作目录');\n return;\n }\n\n const pushed = await isBranchPushed(branchName, workDir, logger);\n if (!pushed) {\n logger.warn(`分支 ${branchName} 尚未推送到远端,已保留 worktree`);\n return;\n }\n\n if (!prInfo) {\n logger.warn('未检测到关联 PR,已保留 worktree');\n return;\n }\n\n await removeWorktree(workDir, repoRoot, logger);\n}\n\n/**\n * 执行主迭代循环。\n */\nexport async function runLoop(config: LoopConfig): Promise<LoopResult> {\n const logger = new Logger({ verbose: config.verbose, logFile: config.logFile });\n const repoRoot = await getRepoRoot(config.cwd, logger);\n logger.debug(`仓库根目录: ${repoRoot}`);\n\n let branchName = config.git.branchName;\n let workDir = repoRoot;\n let worktreeCreated = false;\n\n const commandLine = formatCommandLine(process.argv);\n let runTracker: Awaited<ReturnType<typeof createRunTracker>> | null = null;\n\n let accumulatedUsage: TokenUsage | null = null;\n let lastTestResults: TestRunResult[] | null = null;\n let lastAiOutput = '';\n let lastRound = 0;\n let runError: string | null = null;\n let prInfo: GhPrInfo | null = null;\n let prFailed = false;\n let sessionIndex = 0;\n\n const preWorktreeRecords: string[] = [];\n\n const notifyWebhook = async (event: 'task_start' | 'iteration_start' | 'task_end', iteration: number, stage: string): Promise<void> => {\n const payload = buildWebhookPayload({\n event,\n task: config.task,\n branch: branchName,\n iteration,\n stage\n });\n await sendWebhookNotifications(config.webhooks, payload, logger);\n };\n\n try {\n await notifyWebhook('task_start', 0, '任务开始');\n\n if (config.git.useWorktree && !branchName) {\n const branchPrompt = buildBranchNamePrompt({ task: config.task });\n await notifyWebhook('iteration_start', sessionIndex + 1, '分支名生成');\n logger.info('分支名生成提示构建完成,调用 AI CLI...');\n const aiResult = await runAi(branchPrompt, config.ai, logger, repoRoot);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, aiResult.usage);\n lastAiOutput = aiResult.output;\n sessionIndex += 1;\n lastRound = sessionIndex;\n\n const record = formatIterationRecord({\n iteration: sessionIndex,\n stage: '分支名生成',\n prompt: branchPrompt,\n aiOutput: aiResult.output,\n timestamp: isoNow()\n });\n preWorktreeRecords.push(record);\n\n const parsed = parseBranchName(aiResult.output);\n if (parsed) {\n branchName = parsed;\n logger.info(`AI 生成分支名:${branchName}`);\n } else {\n branchName = generateBranchNameFromTask(config.task);\n logger.warn(`未解析到 AI 分支名,使用兜底分支:${branchName}`);\n }\n }\n\n const worktreeResult: WorktreeResult = config.git.useWorktree\n ? await ensureWorktree({ ...config.git, branchName }, repoRoot, logger)\n : { path: repoRoot, created: false };\n workDir = worktreeResult.path;\n worktreeCreated = worktreeResult.created;\n logger.debug(`工作目录: ${workDir}`);\n\n runTracker = await createRunTracker({\n logFile: config.logFile,\n command: commandLine,\n path: workDir,\n logger\n });\n\n if (runTracker && sessionIndex > 0) {\n await runTracker.update(sessionIndex, accumulatedUsage?.totalTokens ?? 0);\n }\n\n if (config.skipInstall) {\n logger.info('已跳过依赖检查');\n } else {\n await ensureDependencies(workDir, logger);\n }\n\n const workflowFiles = reRootWorkflowFiles(config.workflowFiles, repoRoot, workDir);\n await ensureWorkflowFiles(workflowFiles);\n\n if (preWorktreeRecords.length > 0) {\n for (const record of preWorktreeRecords) {\n await appendSection(workflowFiles.notesFile, record);\n }\n logger.success(`已写入分支名生成记录至 ${workflowFiles.notesFile}`);\n }\n\n const planContent = await readFileSafe(workflowFiles.planFile);\n if (planContent.trim().length === 0) {\n logger.warn('plan 文件为空,建议 AI 首轮生成计划');\n }\n\n if (!branchName) {\n try {\n branchName = await getCurrentBranch(workDir, logger);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(`读取分支名失败,webhook 中将缺失分支信息:${message}`);\n }\n }\n\n const aiConfig = config.ai;\n const loadContext = async (): Promise<{ workflowGuide: string; plan: string; notes: string }> => ({\n workflowGuide: await readFileSafe(workflowFiles.workflowDoc),\n plan: await readFileSafe(workflowFiles.planFile),\n notes: await readFileSafe(workflowFiles.notesFile)\n });\n\n const runAiSession = async (\n stage: string,\n prompt: string,\n extras?: { testResults?: TestRunResult[]; checkResults?: CheckRunResult[]; cwd?: string }\n ): Promise<void> => {\n sessionIndex += 1;\n await notifyWebhook('iteration_start', sessionIndex, stage);\n logger.info(`${stage} 提示构建完成,调用 AI CLI...`);\n\n const aiResult = await runAi(prompt, aiConfig, logger, extras?.cwd ?? workDir);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, aiResult.usage);\n lastAiOutput = aiResult.output;\n\n const record = formatIterationRecord({\n iteration: sessionIndex,\n stage,\n prompt,\n aiOutput: aiResult.output,\n timestamp: isoNow(),\n testResults: extras?.testResults,\n checkResults: extras?.checkResults\n });\n\n await appendSection(workflowFiles.notesFile, record);\n logger.success(`已将${stage}输出写入 ${workflowFiles.notesFile}`);\n\n lastRound = sessionIndex;\n await runTracker?.update(sessionIndex, accumulatedUsage?.totalTokens ?? 0);\n };\n\n {\n const { workflowGuide, plan, notes } = await loadContext();\n const planningPrompt = buildPlanningPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n branchName\n });\n await runAiSession('计划生成', planningPrompt);\n }\n\n let refreshedPlan = await readFileSafe(workflowFiles.planFile);\n if (/(测试|test|e2e|单测)/i.test(refreshedPlan)) {\n logger.warn('检测到 plan 中可能包含测试相关事项,建议保留开发内容并移除测试项。');\n }\n\n let pendingItems = getPendingPlanItems(refreshedPlan);\n if (pendingItems.length === 0) {\n logger.info('计划暂无待执行项,跳过计划执行循环');\n const record = formatSystemRecord('计划执行', '未发现待执行计划项,已跳过执行循环。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n }\n\n let planRounds = 0;\n while (pendingItems.length > 0) {\n if (planRounds >= config.iterations) {\n throw new Error('计划执行达到最大迭代次数,仍有未完成项');\n }\n const lastItem = pendingItems[pendingItems.length - 1];\n const { workflowGuide, plan, notes } = await loadContext();\n const itemPrompt = buildPlanItemPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n item: lastItem.text\n });\n await runAiSession(`执行计划项:${truncateText(lastItem.text)}`, itemPrompt);\n planRounds += 1;\n refreshedPlan = await readFileSafe(workflowFiles.planFile);\n pendingItems = getPendingPlanItems(refreshedPlan);\n }\n\n const agentsContent = await readFileSafe(path.join(workDir, 'AGENTS.md'));\n const skipQuality = shouldSkipQuality(agentsContent, config.skipQuality);\n if (skipQuality) {\n const record = formatSystemRecord('代码质量检查', '已按配置/AGENTS.md 跳过代码质量检查。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('已跳过代码质量检查');\n } else {\n const qualityCommands = await detectQualityCommands(workDir);\n if (qualityCommands.length === 0) {\n const record = formatSystemRecord('代码质量检查', '未检测到可执行的质量检查命令,已跳过。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('未检测到质量检查命令,跳过该阶段');\n } else {\n let qualityResults = await runQualityChecks(qualityCommands, workDir, logger);\n const { workflowGuide, plan, notes } = await loadContext();\n const qualityPrompt = buildQualityPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n commands: qualityCommands.map(item => item.command),\n results: buildCheckResultSummary(qualityResults)\n });\n await runAiSession('代码质量检查', qualityPrompt, { checkResults: qualityResults });\n\n let hasQualityFailure = qualityResults.some(result => !result.success);\n let fixRounds = 0;\n while (hasQualityFailure) {\n if (fixRounds >= config.iterations) {\n throw new Error('代码质量修复达到最大轮次,仍未通过');\n }\n const latest = await loadContext();\n const fixPrompt = buildFixPrompt({\n task: config.task,\n workflowGuide: latest.workflowGuide,\n plan: latest.plan,\n notes: latest.notes,\n stage: '代码质量',\n errors: buildFailedCheckSummary(qualityResults)\n });\n await runAiSession('代码质量修复', fixPrompt);\n fixRounds += 1;\n qualityResults = await runQualityChecks(qualityCommands, workDir, logger);\n hasQualityFailure = qualityResults.some(result => !result.success);\n\n const recheckRecord = formatSystemRecord('代码质量复核', buildCheckResultSummary(qualityResults), isoNow());\n await appendSection(workflowFiles.notesFile, recheckRecord);\n }\n }\n }\n\n if (config.runTests || config.runE2e) {\n let testResults = await runTestsSafely(config, workDir, logger);\n\n lastTestResults = testResults;\n const testCommands: string[] = [];\n if (config.runTests && config.tests.unitCommand) {\n testCommands.push(config.tests.unitCommand);\n }\n if (config.runE2e && config.tests.e2eCommand) {\n testCommands.push(config.tests.e2eCommand);\n }\n\n const { workflowGuide, plan, notes } = await loadContext();\n const testPrompt = buildTestPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n commands: testCommands,\n results: buildTestResultSummary(testResults)\n });\n await runAiSession('测试执行', testPrompt, { testResults });\n\n let hasTestFailure = testResults.some(result => !result.success);\n let fixRounds = 0;\n while (hasTestFailure) {\n if (fixRounds >= config.iterations) {\n throw new Error('测试修复达到最大轮次,仍未通过');\n }\n const latest = await loadContext();\n const fixPrompt = buildFixPrompt({\n task: config.task,\n workflowGuide: latest.workflowGuide,\n plan: latest.plan,\n notes: latest.notes,\n stage: '测试',\n errors: buildFailedTestSummary(testResults)\n });\n await runAiSession('测试修复', fixPrompt, { testResults });\n fixRounds += 1;\n\n testResults = await runTestsSafely(config, workDir, logger);\n lastTestResults = testResults;\n hasTestFailure = testResults.some(result => !result.success);\n\n const recheckRecord = formatSystemRecord('测试复核', buildTestResultSummary(testResults), isoNow());\n await appendSection(workflowFiles.notesFile, recheckRecord);\n }\n } else {\n const record = formatSystemRecord('测试执行', '未开启单元测试或 e2e 测试,已跳过。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('未开启测试阶段');\n }\n\n {\n const { workflowGuide, plan, notes } = await loadContext();\n const docsPrompt = buildDocsPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes\n });\n await runAiSession('文档更新', docsPrompt);\n }\n\n const lastTestFailed = lastTestResults?.some(result => !result.success) ?? false;\n if (lastTestFailed) {\n logger.warn('存在未通过的测试,已跳过自动提交/推送/PR');\n }\n\n let deliverySummary: DeliverySummary | null = null;\n const deliveryNotes: string[] = [];\n const shouldPrepareDelivery = !lastTestFailed && (config.autoCommit || config.pr.enable);\n if (shouldPrepareDelivery) {\n const [gitStatus, diffStat] = await Promise.all([\n safeCommandOutput('git', ['status', '--short'], workDir, logger, 'git', 'git status --short'),\n safeCommandOutput('git', ['diff', '--stat'], workDir, logger, 'git', 'git diff --stat')\n ]);\n const summaryPrompt = buildSummaryPrompt({\n task: config.task,\n plan: await readFileSafe(workflowFiles.planFile),\n notes: await readFileSafe(workflowFiles.notesFile),\n lastAiOutput,\n testResults: lastTestResults,\n gitStatus,\n diffStat,\n branchName\n });\n try {\n const summaryResult = await runAi(summaryPrompt, aiConfig, logger, workDir);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, summaryResult.usage);\n deliverySummary = parseDeliverySummary(summaryResult.output);\n if (!deliverySummary) {\n logger.warn('AI 总结输出解析失败,使用兜底文案');\n }\n } catch (error) {\n logger.warn(`AI 总结生成失败: ${String(error)}`);\n }\n if (!deliverySummary) {\n deliverySummary = buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n }\n if (deliverySummary) {\n deliveryNotes.push(`交付摘要:提交 ${deliverySummary.commitTitle}|PR ${deliverySummary.prTitle}`);\n }\n }\n await runTracker?.update(lastRound, accumulatedUsage?.totalTokens ?? 0);\n\n if (config.autoCommit) {\n if (lastTestFailed) {\n deliveryNotes.push('自动提交:已跳过(测试未通过)');\n } else {\n const summary = deliverySummary ?? buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n const commitMessage: CommitMessage = {\n title: summary.commitTitle,\n body: summary.commitBody\n };\n try {\n const committed = await commitAll(commitMessage, workDir, logger);\n deliveryNotes.push(committed ? `自动提交:已提交(${commitMessage.title})` : '自动提交:未生成提交(可能无变更或提交失败)');\n } catch (error) {\n deliveryNotes.push(`自动提交:失败(${String(error)})`);\n }\n }\n } else {\n deliveryNotes.push('自动提交:未开启');\n }\n\n if (config.autoPush) {\n if (lastTestFailed) {\n deliveryNotes.push('自动推送:已跳过(测试未通过)');\n } else if (!branchName) {\n deliveryNotes.push('自动推送:已跳过(缺少分支名)');\n } else {\n try {\n await pushBranch(branchName, workDir, logger);\n deliveryNotes.push(`自动推送:已推送(${branchName})`);\n } catch (error) {\n deliveryNotes.push(`自动推送:失败(${String(error)})`);\n }\n }\n } else {\n deliveryNotes.push('自动推送:未开启');\n }\n\n if (config.pr.enable) {\n if (lastTestFailed) {\n deliveryNotes.push('PR 创建:已跳过(测试未通过)');\n } else if (!branchName) {\n deliveryNotes.push('PR 创建:已跳过(缺少分支名)');\n } else {\n logger.info('开始创建 PR...');\n const summary = deliverySummary ?? buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n const prTitleCandidate = config.pr.title?.trim() || summary.prTitle;\n const prBodyContent = ensurePrBodySections(summary.prBody, {\n commitTitle: summary.commitTitle,\n commitBody: summary.commitBody,\n testResults: lastTestResults\n });\n const bodyFile = config.pr.bodyPath ?? buildBodyFile(workDir);\n await writePrBody(bodyFile, prBodyContent, Boolean(config.pr.bodyPath));\n\n const createdPr = await createPr(branchName, { ...config.pr, title: prTitleCandidate, bodyPath: bodyFile }, workDir, logger);\n prInfo = createdPr;\n if (createdPr) {\n logger.success(`PR 已创建: ${createdPr.url}`);\n deliveryNotes.push(`PR 创建:已完成(${createdPr.url})`);\n if (config.pr.autoMerge) {\n const target = createdPr.number > 0 ? createdPr.number : createdPr.url;\n const merged = await enableAutoMerge(target, workDir, logger);\n if (merged) {\n deliveryNotes.push('PR 自动合并:已启用');\n } else {\n deliveryNotes.push('PR 自动合并:启用失败');\n prFailed = true;\n }\n } else {\n deliveryNotes.push('PR 自动合并:未开启');\n }\n const failedRuns = await listFailedRuns(branchName, workDir, logger);\n if (failedRuns.length > 0) {\n failedRuns.forEach(run => {\n logger.warn(`Actions 失败: ${run.name} (${run.status}/${run.conclusion ?? 'unknown'}) ${run.url}`);\n });\n }\n } else {\n prFailed = true;\n deliveryNotes.push('PR 创建:失败(详见 gh 输出)');\n logger.error('PR 创建失败,详见上方 gh 输出');\n }\n }\n } else if (branchName) {\n logger.info('未开启 PR 创建(--pr 未传),尝试查看已有 PR');\n const existingPr = await viewPr(branchName, workDir, logger);\n prInfo = existingPr;\n if (existingPr) {\n logger.info(`已有 PR: ${existingPr.url}`);\n deliveryNotes.push(`PR 创建:未开启(已存在 PR:${existingPr.url})`);\n } else {\n deliveryNotes.push('PR 创建:未开启(未检测到已有 PR)');\n }\n } else {\n deliveryNotes.push('PR 创建:未开启(缺少分支名)');\n }\n\n if (deliveryNotes.length > 0) {\n const record = formatSystemRecord('提交与PR', deliveryNotes.join('\\n'), isoNow());\n await appendSection(workflowFiles.notesFile, record);\n }\n\n if (accumulatedUsage) {\n const input = accumulatedUsage.inputTokens ?? '-';\n const output = accumulatedUsage.outputTokens ?? '-';\n logger.info(`Token 消耗汇总:输入 ${input}|输出 ${output}|总计 ${accumulatedUsage.totalTokens}`);\n } else {\n logger.info('未解析到 Token 消耗信息,可检查 AI CLI 输出格式是否包含 token 提示');\n }\n\n if (lastTestFailed || prFailed) {\n throw new Error('流程存在未解决的问题(测试未通过或 PR 创建失败)');\n }\n\n if (config.git.useWorktree && workDir !== repoRoot) {\n await cleanupWorktreeIfSafe({\n repoRoot,\n workDir,\n branchName,\n prInfo,\n worktreeCreated,\n logger\n });\n }\n\n logger.success(`wheel-ai 迭代流程结束|Token 总计 ${accumulatedUsage?.totalTokens ?? '未知'}`);\n return { branchName };\n } catch (error) {\n runError = error instanceof Error ? error.message : String(error);\n throw error;\n } finally {\n const stage = runError ? '任务结束(失败)' : '任务结束';\n await notifyWebhook('task_end', lastRound, stage);\n await runTracker?.finalize();\n }\n}\n","import { AiCliConfig, AiResult, IterationRecord, TokenUsage } from './types';\nimport { runCommand } from './utils';\nimport { Logger } from './logger';\n\ninterface PromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly iteration: number;\n}\n\n/**\n * 构建 AI 提示文本。\n */\nexport function buildPrompt(input: PromptInput): string {\n const sections = [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前持久化计划',\n input.plan || '(暂无计划,首轮请生成可执行计划并写入 plan 文件)',\n '# 历史迭代与记忆',\n input.notes || '(首次执行,暂无历史)',\n '# 本轮执行要求',\n [\n '1. 自我检查并补全需求;明确交付物与验收标准。',\n '2. 更新/细化计划,必要时在 plan 文件中重写任务树与优先级。',\n '3. 设计开发步骤并直接生成代码(无需再次请求确认)。',\n '4. 进行代码自审,给出风险与改进清单。',\n '5. 生成单元测试与 e2e 测试代码并给出运行命令;如果环境允许可直接运行命令。',\n '6. 维护持久化记忆文件:摘要本轮关键结论、遗留问题、下一步建议。',\n '7. 准备提交 PR 所需的标题与描述(含变更摘要、测试结果、风险)。',\n '8. 当所有目标完成时,在输出中加入标记 <<DONE>> 以便外层停止循环。'\n ].join('\\n')\n ];\n\n return sections.join('\\n\\n');\n}\n\nfunction compactLine(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\ninterface BranchNamePromptInput {\n readonly task: string;\n}\n\n/**\n * 构建分支名生成提示。\n */\nexport function buildBranchNamePrompt(input: BranchNamePromptInput): string {\n return [\n '# 角色',\n '你是资深工程师,需要根据任务生成规范的 git 分支名。',\n '# 规则',\n '- 输出格式仅限严格 JSON(不要 markdown、不要代码块、不要解释)。',\n '- 分支名格式:<type>/<slug>。',\n '- type 可选:feat、fix、docs、refactor、chore、test。',\n '- slug 使用小写英文、数字、连字符,长度 3~40,避免空格与中文。',\n '# 输出 JSON',\n '{\"branch\":\"...\"}',\n '# 任务描述',\n compactLine(input.task) || '(空)'\n ].join('\\n\\n');\n}\n\ninterface PlanningPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly branchName?: string;\n}\n\n/**\n * 构建计划生成提示。\n */\nexport function buildPlanningPrompt(input: PlanningPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 分支信息',\n input.branchName ? `计划使用分支:${input.branchName}` : '未指定分支名,请按任务语义给出建议',\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮执行要求',\n [\n '1. 分析任务输入/输出/约束/验收标准,必要时补充合理假设(写入 notes)。',\n '2. 若 plan.md 已存在,请判断是否合理;合理则不修改,不合理则优化或重写。',\n '3. 计划只包含开发相关任务(设计/实现/重构/配置/文档更新),不要包含测试、自审、PR、提交等内容。',\n '4. 计划项需可执行、颗粒度清晰,已完成项使用 ✅ 标记。',\n '5. 更新 memory/plan.md 与 memory/notes.md 后结束本轮。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface PlanItemPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly item: string;\n}\n\n/**\n * 构建单条计划执行提示。\n */\nexport function buildPlanItemPrompt(input: PlanItemPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮要执行的计划项(仅此一条)',\n input.item,\n '# 本轮执行要求',\n [\n '1. 只执行上述计划项,避免提前处理其它计划项。',\n '2. 完成后立即在 plan.md 中将该项标记为 ✅。',\n '3. 必要时可对计划项进行微调,但仍需确保当前项完成。',\n '4. 本轮不执行测试或质量检查。',\n '5. 将进展、关键改动与风险写入 notes。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface QualityPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly commands: string[];\n readonly results?: string;\n}\n\n/**\n * 构建质量检查提示。\n */\nexport function buildQualityPrompt(input: QualityPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮代码质量检查',\n input.commands.length > 0 ? input.commands.map(cmd => `- ${cmd}`).join('\\n') : '未检测到可执行的质量检查命令。',\n input.results ? `# 命令执行结果\\n${input.results}` : '',\n '# 本轮执行要求',\n [\n '1. 本轮仅进行代码质量检查,不要修复问题。',\n '2. 若出现失败,记录失败要点,等待下一轮修复。',\n '3. 将结论与风险写入 notes。'\n ].join('\\n')\n ].filter(Boolean).join('\\n\\n');\n}\n\ninterface FixPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly stage: string;\n readonly errors: string;\n}\n\n/**\n * 构建问题修复提示(质量检查 / 测试)。\n */\nexport function buildFixPrompt(input: FixPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n `# 需要修复的问题(${input.stage})`,\n input.errors || '(无错误信息)',\n '# 本轮执行要求',\n [\n '1. 聚焦修复当前问题,不要扩展范围。',\n '2. 修复完成后更新 notes,说明修改点与影响。',\n '3. 如需调整计划,请同步更新 plan.md。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface TestPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly commands: string[];\n readonly results?: string;\n}\n\n/**\n * 构建测试执行提示。\n */\nexport function buildTestPrompt(input: TestPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮测试命令',\n input.commands.length > 0 ? input.commands.map(cmd => `- ${cmd}`).join('\\n') : '未配置测试命令。',\n input.results ? `# 测试结果\\n${input.results}` : '',\n '# 本轮执行要求',\n [\n '1. 本轮仅执行测试,不要修复问题。',\n '2. 若出现失败,记录失败要点,等待下一轮修复。',\n '3. 将测试结论写入 notes。'\n ].join('\\n')\n ].filter(Boolean).join('\\n\\n');\n}\n\ninterface DocsPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n}\n\n/**\n * 构建文档更新提示。\n */\nexport function buildDocsPrompt(input: DocsPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮执行要求',\n [\n '1. 根据本次改动更新版本号、CHANGELOG、README、docs 等相关文档。',\n '2. 仅更新确有变化的文档,保持中文说明。',\n '3. 将更新摘要写入 notes。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\nfunction extractJson(text: string): string | null {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (fenced?.[1]) return fenced[1].trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1).trim();\n }\n return null;\n}\n\nconst BRANCH_TYPES = ['feat', 'fix', 'docs', 'refactor', 'chore', 'test'] as const;\ntype BranchType = typeof BRANCH_TYPES[number];\n\nconst BRANCH_TYPE_ALIASES: Record<string, BranchType> = {\n feature: 'feat',\n features: 'feat',\n bugfix: 'fix',\n hotfix: 'fix',\n doc: 'docs',\n documentation: 'docs',\n refactoring: 'refactor',\n chores: 'chore',\n tests: 'test'\n};\n\nfunction isBranchType(value: string): value is BranchType {\n return BRANCH_TYPES.includes(value as BranchType);\n}\n\nfunction normalizeBranchType(value: string): BranchType | null {\n const trimmed = value.trim().toLowerCase();\n if (!trimmed) return null;\n if (isBranchType(trimmed)) return trimmed;\n return BRANCH_TYPE_ALIASES[trimmed] ?? null;\n}\n\nfunction normalizeBranchSlug(value: string): string | null {\n const cleaned = value\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/_/g, '-')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!cleaned) return null;\n const trimmed = cleaned.slice(0, 40);\n if (trimmed.length < 3) return null;\n return trimmed;\n}\n\nfunction normalizeBranchNameCandidate(value: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n const lowered = trimmed.toLowerCase();\n const parts = lowered.split('/').filter(part => part.length > 0);\n const hasExplicitType = lowered.includes('/') && parts.length >= 2;\n const rawType = hasExplicitType ? parts.shift() ?? '' : '';\n const rawSlug = hasExplicitType ? parts.join('-') : lowered;\n\n const type = rawType ? normalizeBranchType(rawType) : 'feat';\n if (!type) return null;\n\n const slug = normalizeBranchSlug(rawSlug);\n if (!slug) return null;\n\n return `${type}/${slug}`;\n}\n\n/**\n * 解析 AI 输出中的分支名。\n */\nexport function parseBranchName(output: string): string | null {\n const jsonText = extractJson(output);\n if (jsonText) {\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>;\n const raw = typeof parsed.branch === 'string'\n ? parsed.branch\n : typeof parsed.branchName === 'string'\n ? parsed.branchName\n : typeof parsed['分支'] === 'string'\n ? (parsed['分支'] as string)\n : typeof parsed['分支名'] === 'string'\n ? (parsed['分支名'] as string)\n : null;\n if (raw) {\n const normalized = normalizeBranchNameCandidate(raw);\n if (normalized) return normalized;\n }\n } catch {\n // 忽略解析失败,回退到文本匹配\n }\n }\n\n const lineMatch = output.match(/(?:branch(?:name)?|分支名|分支)\\s*[::]\\s*([^\\s]+)/i);\n if (lineMatch?.[1]) {\n const normalized = normalizeBranchNameCandidate(lineMatch[1]);\n if (normalized) return normalized;\n }\n return null;\n}\n\nfunction pickNumber(pattern: RegExp, text: string): number | undefined {\n const match = pattern.exec(text);\n if (!match || match.length < 2) return undefined;\n const value = Number.parseInt(match[match.length - 1], 10);\n return Number.isNaN(value) ? undefined : value;\n}\n\n/**\n * 从日志文本中解析 token 使用量。\n */\nexport function parseTokenUsage(logs: string): TokenUsage | null {\n const total = pickNumber(/total[_\\s]tokens:\\s*(\\d+)/i, logs);\n const input = pickNumber(/(input|prompt)[_\\s]tokens:\\s*(\\d+)/i, logs);\n const output = pickNumber(/(output|completion)[_\\s]tokens:\\s*(\\d+)/i, logs);\n const consumed = pickNumber(/tokens?\\s+used:\\s*(\\d+)/i, logs) ?? pickNumber(/consumed\\s+(\\d+)\\s+tokens?/i, logs);\n\n const totalTokens = total ?? (input !== undefined || output !== undefined ? (input ?? 0) + (output ?? 0) : consumed);\n if (totalTokens === undefined) return null;\n\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens\n };\n}\n\nfunction addOptional(a?: number, b?: number): number | undefined {\n if (typeof a !== 'number' && typeof b !== 'number') return undefined;\n return (a ?? 0) + (b ?? 0);\n}\n\n/**\n * 合并多轮 token 统计。\n */\nexport function mergeTokenUsage(previous: TokenUsage | null, current?: TokenUsage | null): TokenUsage | null {\n if (!current) return previous;\n if (!previous) return { ...current };\n return {\n inputTokens: addOptional(previous.inputTokens, current.inputTokens),\n outputTokens: addOptional(previous.outputTokens, current.outputTokens),\n totalTokens: previous.totalTokens + current.totalTokens\n };\n}\n\n/**\n * 调用 AI CLI 并返回输出。\n */\nexport async function runAi(prompt: string, ai: AiCliConfig, logger: Logger, cwd: string): Promise<AiResult> {\n const args = [...ai.args];\n const verboseCommand = ai.promptArg\n ? [ai.command, ...ai.args, ai.promptArg, '<prompt>'].join(' ')\n : [ai.command, ...ai.args, '<stdin>'].join(' ');\n const streamPrefix = `[${ai.command}] `;\n const streamErrorPrefix = `[${ai.command} stderr] `;\n\n let result;\n if (ai.promptArg) {\n args.push(ai.promptArg, prompt);\n result = await runCommand(ai.command, args, {\n cwd,\n logger,\n verboseLabel: 'ai',\n verboseCommand,\n stream: {\n enabled: true,\n stdoutPrefix: streamPrefix,\n stderrPrefix: streamErrorPrefix\n }\n });\n } else {\n result = await runCommand(ai.command, args, {\n cwd,\n input: prompt,\n logger,\n verboseLabel: 'ai',\n verboseCommand,\n stream: {\n enabled: true,\n stdoutPrefix: streamPrefix,\n stderrPrefix: streamErrorPrefix\n }\n });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`AI CLI 执行失败: ${result.stderr || result.stdout}`);\n }\n\n logger.success('AI 输出完成');\n const usage = parseTokenUsage([result.stdout, result.stderr].filter(Boolean).join('\\n'));\n return {\n output: result.stdout.trim(),\n usage\n };\n}\n\n/**\n * 生成 notes 迭代记录文本。\n */\nexport function formatIterationRecord(record: IterationRecord): string {\n const title = record.stage\n ? `### 迭代 ${record.iteration} | ${record.timestamp} | ${record.stage}`\n : `### 迭代 ${record.iteration} | ${record.timestamp}`;\n const lines = [\n title,\n '',\n '#### 提示上下文',\n '```',\n record.prompt,\n '```',\n '',\n '#### AI 输出',\n '```',\n record.aiOutput,\n '```',\n ''\n ];\n\n if (record.checkResults && record.checkResults.length > 0) {\n lines.push('#### 质量检查结果');\n record.checkResults.forEach(result => {\n const status = result.success ? '✅ 通过' : '❌ 失败';\n lines.push(`${status} | ${result.name} | 命令: ${result.command} | 退出码: ${result.exitCode}`);\n if (!result.success) {\n lines.push('```');\n lines.push(result.stderr || result.stdout || '(无输出)');\n lines.push('```');\n lines.push('');\n }\n });\n }\n\n if (record.testResults && record.testResults.length > 0) {\n lines.push('#### 测试结果');\n record.testResults.forEach(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '✅ 通过' : '❌ 失败';\n lines.push(`${status} | ${label} | 命令: ${result.command} | 退出码: ${result.exitCode}`);\n if (!result.success) {\n lines.push('```');\n lines.push(result.stderr || result.stdout || '(无输出)');\n lines.push('```');\n lines.push('');\n }\n });\n }\n\n return lines.join('\\n');\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { Logger } from './logger';\nimport { runCommand } from './utils';\n\n/**\n * 支持的包管理器类型。\n */\nexport type PackageManager = 'yarn' | 'pnpm' | 'npm';\n\ntype PackageManagerSource = 'packageManager' | 'lockfile' | 'default';\n\n/**\n * 解析包管理器所需的提示信息。\n */\nexport interface PackageManagerHints {\n readonly packageManagerField?: string;\n readonly hasYarnLock: boolean;\n readonly hasPnpmLock: boolean;\n readonly hasNpmLock: boolean;\n readonly hasNpmShrinkwrap: boolean;\n}\n\n/**\n * 包管理器解析结果。\n */\nexport interface PackageManagerResolution {\n readonly manager: PackageManager;\n readonly source: PackageManagerSource;\n readonly hasLock: boolean;\n}\n\nfunction parsePackageManagerField(value?: string): PackageManager | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === 'yarn' || normalized.startsWith('yarn@')) return 'yarn';\n if (normalized === 'pnpm' || normalized.startsWith('pnpm@')) return 'pnpm';\n if (normalized === 'npm' || normalized.startsWith('npm@')) return 'npm';\n return null;\n}\n\nfunction hasLockForManager(manager: PackageManager, hints: PackageManagerHints): boolean {\n if (manager === 'yarn') return hints.hasYarnLock;\n if (manager === 'pnpm') return hints.hasPnpmLock;\n return hints.hasNpmLock || hints.hasNpmShrinkwrap;\n}\n\n/**\n * 根据 packageManager 字段或锁文件推断包管理器。\n */\nexport function resolvePackageManager(hints: PackageManagerHints): PackageManagerResolution {\n const fromField = parsePackageManagerField(hints.packageManagerField);\n if (fromField) {\n return {\n manager: fromField,\n source: 'packageManager',\n hasLock: hasLockForManager(fromField, hints)\n };\n }\n\n if (hints.hasYarnLock) {\n return {\n manager: 'yarn',\n source: 'lockfile',\n hasLock: true\n };\n }\n if (hints.hasPnpmLock) {\n return {\n manager: 'pnpm',\n source: 'lockfile',\n hasLock: true\n };\n }\n if (hints.hasNpmLock || hints.hasNpmShrinkwrap) {\n return {\n manager: 'npm',\n source: 'lockfile',\n hasLock: true\n };\n }\n\n return {\n manager: 'yarn',\n source: 'default',\n hasLock: false\n };\n}\n\n/**\n * 生成安装依赖命令。\n */\nexport function buildInstallCommand(resolution: PackageManagerResolution): string {\n switch (resolution.manager) {\n case 'yarn': {\n const args = ['yarn', 'install'];\n if (resolution.hasLock) {\n args.push('--frozen-lockfile');\n } else {\n args.push('--no-lockfile');\n }\n return args.join(' ');\n }\n case 'pnpm': {\n const args = ['pnpm', 'install'];\n if (resolution.hasLock) {\n args.push('--frozen-lockfile');\n }\n return args.join(' ');\n }\n case 'npm': {\n const args = resolution.hasLock ? ['npm', 'ci'] : ['npm', 'install'];\n args.push('--no-audit', '--no-fund');\n return args.join(' ');\n }\n default: {\n return 'yarn install';\n }\n }\n}\n\nfunction resolveSourceLabel(source: PackageManagerSource): string {\n switch (source) {\n case 'packageManager':\n return 'packageManager 字段';\n case 'lockfile':\n return '锁文件';\n case 'default':\n return '默认策略';\n default:\n return '未知来源';\n }\n}\n\nfunction extractPackageManagerField(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const candidate = value as Record<string, unknown>;\n const field = candidate.packageManager;\n return typeof field === 'string' ? field : undefined;\n}\n\nasync function readPackageManagerHints(cwd: string, logger: Logger): Promise<PackageManagerHints | null> {\n const packageJsonPath = path.join(cwd, 'package.json');\n const hasPackageJson = await fs.pathExists(packageJsonPath);\n if (!hasPackageJson) return null;\n\n let packageManagerField: string | undefined;\n try {\n const packageJson = await fs.readJson(packageJsonPath);\n packageManagerField = extractPackageManagerField(packageJson);\n } catch (error) {\n logger.warn(`读取 package.json 失败,将改用锁文件判断包管理器: ${String(error)}`);\n }\n\n const [hasYarnLock, hasPnpmLock, hasNpmLock, hasNpmShrinkwrap] = await Promise.all([\n fs.pathExists(path.join(cwd, 'yarn.lock')),\n fs.pathExists(path.join(cwd, 'pnpm-lock.yaml')),\n fs.pathExists(path.join(cwd, 'package-lock.json')),\n fs.pathExists(path.join(cwd, 'npm-shrinkwrap.json'))\n ]);\n\n return {\n packageManagerField,\n hasYarnLock,\n hasPnpmLock,\n hasNpmLock,\n hasNpmShrinkwrap\n };\n}\n\n/**\n * 确保依赖已安装(按锁文件或 packageManager 字段选择包管理器)。\n */\nexport async function ensureDependencies(cwd: string, logger: Logger): Promise<void> {\n const hints = await readPackageManagerHints(cwd, logger);\n if (!hints) {\n logger.info('未检测到 package.json,跳过依赖检查');\n return;\n }\n\n const resolution = resolvePackageManager(hints);\n const sourceLabel = resolveSourceLabel(resolution.source);\n logger.info(`依赖检查:使用 ${resolution.manager}(来源:${sourceLabel})`);\n\n if (resolution.source === 'default') {\n logger.warn('未检测到 packageManager 配置或锁文件,将按默认策略安装依赖');\n }\n\n const command = buildInstallCommand(resolution);\n logger.info(`开始安装依赖: ${command}`);\n\n const result = await runCommand('bash', ['-lc', command], {\n cwd,\n logger,\n verboseLabel: 'deps',\n verboseCommand: `bash -lc \"${command}\"`,\n stream: {\n enabled: true,\n stdoutPrefix: '[deps] ',\n stderrPrefix: '[deps err] '\n }\n });\n\n if (result.exitCode !== 0) {\n const details = result.stderr || result.stdout || '无输出';\n throw new Error(`依赖安装失败: ${details}`);\n }\n\n logger.success('依赖检查完成');\n}\n","import { Logger } from './logger';\nimport { PrConfig } from './types';\nimport { runCommand } from './utils';\n\n/**\n * PR 基础信息。\n */\nexport interface GhPrInfo {\n readonly number: number;\n readonly url: string;\n readonly title: string;\n readonly state: string;\n readonly headRefName: string;\n}\n\n/**\n * Actions 运行信息。\n */\nexport interface GhRunInfo {\n readonly databaseId: number;\n readonly name: string;\n readonly status: string;\n readonly conclusion?: string | null;\n readonly url: string;\n}\n\nfunction isGhPrInfo(input: unknown): input is GhPrInfo {\n if (typeof input !== 'object' || input === null) return false;\n const candidate = input as Record<string, unknown>;\n return typeof candidate.number === 'number'\n && typeof candidate.url === 'string'\n && typeof candidate.title === 'string'\n && typeof candidate.state === 'string'\n && typeof candidate.headRefName === 'string';\n}\n\nfunction resolveRunDatabaseId(candidate: Record<string, unknown>): number | null {\n const databaseId = candidate.databaseId;\n if (typeof databaseId === 'number' && Number.isFinite(databaseId)) return databaseId;\n const id = candidate.id;\n if (typeof id === 'number' && Number.isFinite(id)) return id;\n if (typeof id === 'string') {\n const parsed = Number(id);\n if (Number.isFinite(parsed)) return parsed;\n }\n return null;\n}\n\nfunction parseGhRunInfo(input: unknown): GhRunInfo | null {\n if (typeof input !== 'object' || input === null) return null;\n const candidate = input as Record<string, unknown>;\n const databaseId = resolveRunDatabaseId(candidate);\n if (databaseId === null) return null;\n if (typeof candidate.name !== 'string') return null;\n if (typeof candidate.status !== 'string') return null;\n if (typeof candidate.url !== 'string') return null;\n const conclusion = candidate.conclusion;\n const hasValidConclusion = conclusion === undefined || conclusion === null || typeof conclusion === 'string';\n if (!hasValidConclusion) return null;\n return {\n databaseId,\n name: candidate.name,\n status: candidate.status,\n conclusion: conclusion ?? null,\n url: candidate.url\n };\n}\n\n/**\n * 解析 gh run list 的 JSON 输出。\n */\nexport function parseGhRunList(output: string): GhRunInfo[] {\n try {\n const parsed = JSON.parse(output);\n if (!Array.isArray(parsed)) return [];\n return parsed\n .map(parseGhRunInfo)\n .filter((run): run is GhRunInfo => run !== null);\n } catch {\n return [];\n }\n}\n\n/**\n * 解析 PR 标题,必要时给出兜底标题。\n */\nexport function resolvePrTitle(branch: string, title?: string): string {\n const trimmed = title?.trim();\n if (trimmed) return trimmed;\n return `chore: 自动 PR (${branch})`;\n}\n\n/**\n * 组装 gh pr create 所需参数。\n */\nexport function buildPrCreateArgs(branch: string, config: PrConfig): string[] {\n const args = ['pr', 'create', '--head', branch, '--title', resolvePrTitle(branch, config.title)];\n if (config.bodyPath) {\n args.push('--body-file', config.bodyPath);\n } else {\n args.push('--body', '自动生成 PR(未提供 body 文件)');\n }\n if (config.draft) {\n args.push('--draft');\n }\n if (config.reviewers && config.reviewers.length > 0) {\n args.push('--reviewer', config.reviewers.join(','));\n }\n return args;\n}\n\n/**\n * 判断 gh pr create 是否提示 PR 已存在。\n */\nexport function isPrAlreadyExistsMessage(output: string): boolean {\n const trimmed = output.trim();\n if (!trimmed) return false;\n const ghPattern =\n /a pull request for branch [\"']?[^\"']+[\"']? into branch [\"']?[^\"']+[\"']? already exists/i;\n if (ghPattern.test(trimmed)) return true;\n\n const hasAlreadyExists = /already exists/i.test(trimmed);\n const hasPrKeyword = /\\b(pull request|pr)\\b/i.test(trimmed);\n const hasBranch = /\\bbranch\\b/i.test(trimmed);\n if (hasAlreadyExists && hasPrKeyword && hasBranch) return true;\n\n const hasChineseExists = trimmed.includes('已存在');\n const hasChinesePr = trimmed.includes('拉取请求') || trimmed.includes('合并请求') || /\\bPR\\b/i.test(trimmed);\n const hasChineseBranch = trimmed.includes('分支');\n if (hasChineseExists && hasChinesePr && hasChineseBranch) return true;\n return false;\n}\n\nfunction extractPrUrl(output: string): string | null {\n const match = output.match(/https?:\\/\\/\\S+/);\n if (!match) return null;\n return match[0].replace(/[),.]+$/, '');\n}\n\n/**\n * 读取当前分支 PR 信息。\n */\nexport async function viewPr(branch: string, cwd: string, logger: Logger): Promise<GhPrInfo | null> {\n const result = await runCommand('gh', ['pr', 'view', branch, '--json', 'number,title,url,state,headRefName'], {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh pr view ${branch} --json number,title,url,state,headRefName`\n });\n if (result.exitCode !== 0) {\n logger.warn(`gh pr view 失败: ${result.stderr}`);\n return null;\n }\n try {\n const parsed = JSON.parse(result.stdout);\n if (isGhPrInfo(parsed)) return parsed;\n logger.warn('gh pr view 返回格式异常');\n return null;\n } catch (error) {\n logger.warn(`解析 gh pr view 输出失败: ${String(error)}`);\n return null;\n }\n}\n\n/**\n * 创建 PR 并返回 PR 信息。\n */\nexport async function createPr(branch: string, config: PrConfig, cwd: string, logger: Logger): Promise<GhPrInfo | null> {\n if (!config.enable) return null;\n const args = buildPrCreateArgs(branch, config);\n\n const result = await runCommand('gh', args, {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh ${args.join(' ')}`\n });\n if (result.exitCode !== 0) {\n const output = `${result.stderr}\\n${result.stdout}`.trim();\n if (isPrAlreadyExistsMessage(output)) {\n const existingPr = await viewPr(branch, cwd, logger);\n if (existingPr) {\n logger.warn(`创建 PR 失败,但检测到已有 PR,视为创建完成: ${existingPr.url}`);\n return existingPr;\n }\n const fallbackUrl = extractPrUrl(output);\n logger.warn('创建 PR 失败,提示已存在 PR,但读取 PR 信息失败,视为创建完成');\n return {\n number: 0,\n url: fallbackUrl ?? '未获取到链接',\n title: '已存在 PR(未获取详情)',\n state: 'unknown',\n headRefName: branch\n };\n }\n logger.warn(`创建 PR 失败: ${output || '未知错误'}`);\n return null;\n }\n\n return viewPr(branch, cwd, logger);\n}\n\n/**\n * 获取最近失败的 Actions 运行。\n */\nexport async function listFailedRuns(branch: string, cwd: string, logger: Logger): Promise<GhRunInfo[]> {\n const result = await runCommand('gh', ['run', 'list', '--branch', branch, '--json', 'databaseId,name,status,conclusion,url', '--limit', '5'], {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh run list --branch ${branch} --json databaseId,name,status,conclusion,url --limit 5`\n });\n if (result.exitCode !== 0) {\n logger.warn(`获取 Actions 运行失败: ${result.stderr}`);\n return [];\n }\n try {\n const runs = parseGhRunList(result.stdout);\n const failed = runs.filter(run => run.conclusion && run.conclusion !== 'success');\n if (failed.length === 0) {\n logger.info('最近 5 次 Actions 运行无失败');\n }\n return failed;\n } catch (error) {\n logger.warn(`解析 Actions 输出失败: ${String(error)}`);\n return [];\n }\n}\n\n/**\n * 启用 PR 自动合并。\n */\nexport async function enableAutoMerge(target: string | number, cwd: string, logger: Logger): Promise<boolean> {\n const targetValue = String(target);\n const args = ['pr', 'merge', targetValue, '--auto', '--merge'];\n const result = await runCommand('gh', args, {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh ${args.join(' ')}`\n });\n if (result.exitCode !== 0) {\n logger.warn(`启用自动合并失败: ${result.stderr || result.stdout}`);\n return false;\n }\n logger.success('已启用 PR 自动合并');\n return true;\n}\n","import fs from 'fs-extra';\nimport { pad2 } from './utils';\n\ntype Colorizer = (value: string) => string;\ntype ConsoleMethodName = 'log' | 'warn' | 'error';\n\nconst wrap = (code: string): Colorizer => (value: string) => `\\u001b[${code}m${value}\\u001b[0m`;\n\nconst colors = {\n blue: wrap('34'),\n green: wrap('32'),\n yellow: wrap('33'),\n red: wrap('31'),\n magenta: wrap('35'),\n gray: wrap('90')\n} as const;\n\n/**\n * 日志器配置项。\n */\nexport interface LoggerOptions {\n readonly verbose?: boolean;\n readonly logFile?: string;\n}\n\n/**\n * 带颜色的日志输出器,可选写入日志文件。\n */\nexport class Logger {\n private readonly verbose: boolean;\n private readonly logFile?: string;\n private logFileEnabled: boolean;\n private logFileErrored: boolean;\n\n constructor(options: LoggerOptions = {}) {\n this.verbose = options.verbose ?? false;\n const trimmedPath = options.logFile?.trim();\n this.logFile = trimmedPath && trimmedPath.length > 0 ? trimmedPath : undefined;\n this.logFileEnabled = Boolean(this.logFile);\n this.logFileErrored = false;\n\n if (this.logFile) {\n try {\n fs.ensureFileSync(this.logFile);\n } catch (error) {\n this.disableFileWithError(error);\n }\n }\n }\n\n info(message: string): void {\n this.emit('log', colors.blue, 'info', ' ', message);\n }\n\n success(message: string): void {\n this.emit('log', colors.green, 'ok', ' ', message);\n }\n\n warn(message: string): void {\n this.emit('warn', colors.yellow, 'warn', ' ', message);\n }\n\n error(message: string): void {\n this.emit('error', colors.red, 'err', ' ', message);\n }\n\n debug(message: string): void {\n if (!this.verbose) return;\n this.emit('log', colors.magenta, 'dbg', ' ', message);\n }\n\n private emit(method: ConsoleMethodName, colorizer: Colorizer, label: string, padding: string, message: string): void {\n const now = new Date();\n const consoleLine = this.formatConsoleLine(now, colorizer(label), padding, message);\n const fileLine = this.formatFileLine(now, label, padding, message);\n console[method](consoleLine);\n this.writeFileLine(fileLine);\n }\n\n private formatConsoleLine(date: Date, label: string, padding: string, message: string): string {\n const timestamp = this.formatTimestamp(date);\n return `${colors.gray(timestamp)} ${label}${padding}${message}`;\n }\n\n private formatFileLine(date: Date, label: string, padding: string, message: string): string {\n const timestamp = this.formatTimestamp(date);\n return `${timestamp} ${label}${padding}${message}`;\n }\n\n private writeFileLine(line: string): void {\n if (!this.logFileEnabled || !this.logFile) return;\n try {\n fs.appendFileSync(this.logFile, `${line}\\n`, 'utf8');\n } catch (error) {\n this.disableFileWithError(error);\n }\n }\n\n private disableFileWithError(error: unknown): void {\n this.logFileEnabled = false;\n if (this.logFileErrored) return;\n this.logFileErrored = true;\n const message = error instanceof Error ? error.message : String(error);\n const target = this.logFile ? ` (${this.logFile})` : '';\n console.warn(`日志文件写入失败${target},已停止写入:${message}`);\n }\n\n private formatTimestamp(date: Date): string {\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n }\n}\n\n/**\n * 默认日志器实例。\n */\nexport const defaultLogger = new Logger();\n","export interface PlanItem {\n readonly index: number;\n readonly raw: string;\n readonly text: string;\n readonly completed: boolean;\n}\n\nconst ITEM_PATTERN = /^(\\s*)([-*+]|\\d+\\.)\\s+(.*)$/;\n\nfunction isCompleted(content: string): boolean {\n if (content.includes('✅')) return true;\n if (/\\[[xX]\\]/.test(content)) return true;\n return false;\n}\n\nfunction normalizeText(content: string): string {\n return content\n .replace(/\\[[xX ]\\]\\s*/g, '')\n .replace(/✅/g, '')\n .trim();\n}\n\n/**\n * 解析 plan.md 中的计划项。\n */\nexport function parsePlanItems(plan: string): PlanItem[] {\n const lines = plan.split(/\\r?\\n/);\n const items: PlanItem[] = [];\n\n lines.forEach((line, index) => {\n const match = line.match(ITEM_PATTERN);\n if (!match) return;\n const content = match[3] ?? '';\n const text = normalizeText(content);\n if (!text) return;\n items.push({\n index,\n raw: line,\n text,\n completed: isCompleted(content)\n });\n });\n\n return items;\n}\n\n/**\n * 获取尚未完成的计划项。\n */\nexport function getPendingPlanItems(plan: string): PlanItem[] {\n return parsePlanItems(plan).filter(item => !item.completed);\n}\n\n/**\n * 获取最后一条未完成的计划项。\n */\nexport function getLastPendingPlanItem(plan: string): PlanItem | null {\n const pending = getPendingPlanItems(plan);\n if (pending.length === 0) return null;\n return pending[pending.length - 1] ?? null;\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\n\nexport interface QualityCommand {\n readonly name: string;\n readonly command: string;\n}\n\nfunction hasScript(scripts: Record<string, string>, name: string): boolean {\n return typeof scripts[name] === 'string' && scripts[name].trim().length > 0;\n}\n\n/**\n * 读取 package.json,解析可用的代码质量检查命令。\n */\nexport async function detectQualityCommands(workDir: string): Promise<QualityCommand[]> {\n const packagePath = path.join(workDir, 'package.json');\n const exists = await fs.pathExists(packagePath);\n if (!exists) return [];\n\n const pkg = await fs.readJson(packagePath);\n const scripts = typeof pkg === 'object' && pkg && typeof (pkg as { scripts?: unknown }).scripts === 'object'\n ? ((pkg as { scripts: Record<string, string> }).scripts ?? {})\n : {};\n\n const commands: QualityCommand[] = [];\n const seen = new Set<string>();\n\n const append = (name: string, command: string): void => {\n if (seen.has(name)) return;\n if (!hasScript(scripts, name)) return;\n commands.push({ name, command });\n seen.add(name);\n };\n\n append('lint', 'yarn lint');\n append('lint:ci', 'yarn lint:ci');\n append('lint:check', 'yarn lint:check');\n append('typecheck', 'yarn typecheck');\n append('format:check', 'yarn format:check');\n append('format:ci', 'yarn format:ci');\n\n if (!hasScript(scripts, 'format:check') && !hasScript(scripts, 'format:ci')) {\n append('format', 'yarn format');\n }\n\n return commands;\n}\n","import { Logger } from './logger';\nimport { RunMetadata, removeCurrentRegistry, upsertCurrentRegistry, writeRunMetadata } from './logs';\n\nexport interface RunTracker {\n readonly update: (round: number, tokenUsed: number) => Promise<void>;\n readonly finalize: () => Promise<void>;\n}\n\ninterface RunTrackerOptions {\n readonly logFile?: string;\n readonly command: string;\n readonly path: string;\n readonly logger?: Logger;\n}\n\nasync function safeWrite(logFile: string, metadata: RunMetadata, logger?: Logger): Promise<void> {\n try {\n await writeRunMetadata(logFile, metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`写入运行元信息失败: ${message}`);\n }\n try {\n await upsertCurrentRegistry(logFile, metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`更新 current.json 失败: ${message}`);\n }\n}\n\nasync function safeRemove(logFile: string, logger?: Logger): Promise<void> {\n try {\n await removeCurrentRegistry(logFile);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`清理 current.json 失败: ${message}`);\n }\n}\n\n/**\n * 创建运行中任务的追踪器(写入 JSON 元数据)。\n */\nexport async function createRunTracker(options: RunTrackerOptions): Promise<RunTracker | null> {\n const { logFile, command, path, logger } = options;\n if (!logFile) return null;\n\n const update = async (round: number, tokenUsed: number): Promise<void> => {\n const metadata: RunMetadata = {\n command,\n round,\n tokenUsed,\n path,\n pid: process.pid\n };\n await safeWrite(logFile, metadata, logger);\n };\n\n await update(0, 0);\n\n return {\n update,\n finalize: async (): Promise<void> => {\n await safeRemove(logFile, logger);\n }\n };\n}\n","import { DeliverySummary, TestRunResult } from './types';\n\n/**\n * 生成交付摘要提示的输入。\n */\nexport interface SummaryPromptInput {\n readonly task: string;\n readonly plan: string;\n readonly notes: string;\n readonly lastAiOutput: string;\n readonly testResults: TestRunResult[] | null;\n readonly gitStatus: string;\n readonly diffStat: string;\n readonly branchName?: string;\n}\n\n/**\n * 兜底摘要输入。\n */\nexport interface SummaryFallbackInput {\n readonly task: string;\n readonly testResults: TestRunResult[] | null;\n}\n\n/**\n * PR 文案兜底输入。\n */\nexport interface PrBodyFallbackInput {\n readonly commitTitle: string;\n readonly commitBody?: string;\n readonly testResults: TestRunResult[] | null;\n}\n\nconst REQUIRED_SECTIONS = ['# 变更摘要', '# 测试结果', '# 风险与回滚'] as const;\n\nfunction normalizeText(text: string): string {\n return text.replace(/\\r\\n?/g, '\\n');\n}\n\nfunction compactLine(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\nfunction trimTail(text: string, limit: number, emptyFallback: string): string {\n const normalized = normalizeText(text).trim();\n if (!normalized) return emptyFallback;\n if (normalized.length <= limit) return normalized;\n return `(内容过长,保留最后 ${limit} 字符)\\n${normalized.slice(-limit)}`;\n}\n\nfunction formatTestResultLines(testResults: TestRunResult[] | null): string[] {\n if (!testResults || testResults.length === 0) {\n return ['- 未运行(本次未执行测试)'];\n }\n return testResults.map(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const command = result.command ? `|命令: ${result.command}` : '';\n return `- ${label}: ${status} ${command}`.trim();\n });\n}\n\nfunction formatTestResultsForPrompt(testResults: TestRunResult[] | null): string {\n return formatTestResultLines(testResults).join('\\n');\n}\n\nfunction buildSummaryLinesFromCommit(commitTitle: string, commitBody?: string): string[] {\n const bulletLines = extractBulletLines(commitBody);\n if (bulletLines.length > 0) return bulletLines;\n const summary = stripCommitType(commitTitle);\n return [`- ${summary}`];\n}\n\nfunction stripCommitType(title: string): string {\n const trimmed = compactLine(title);\n if (!trimmed) return '更新迭代产出';\n const match = trimmed.match(/^[^:]+:\\s*(.+)$/);\n return match?.[1]?.trim() || trimmed;\n}\n\nfunction buildPrBody(summaryLines: string[], testLines: string[]): string {\n const riskLines = ['- 风险:待评估', '- 回滚:git revert 对应提交或关闭 PR'];\n return [\n '# 变更摘要',\n summaryLines.join('\\n'),\n '',\n '# 测试结果',\n testLines.join('\\n'),\n '',\n '# 风险与回滚',\n riskLines.join('\\n')\n ].join('\\n');\n}\n\n/**\n * 构建交付摘要提示词。\n */\nexport function buildSummaryPrompt(input: SummaryPromptInput): string {\n const planSnippet = trimTail(input.plan, 2000, '(计划为空)');\n const notesSnippet = trimTail(input.notes, 4000, '(notes 为空)');\n const aiSnippet = trimTail(input.lastAiOutput, 3000, '(本轮无 AI 输出)');\n const statusSnippet = trimTail(input.gitStatus, 1000, '(git status 为空)');\n const diffSnippet = trimTail(input.diffStat, 1000, '(diff 统计为空)');\n const testSummary = formatTestResultsForPrompt(input.testResults);\n\n return [\n '# 角色',\n '你是资深工程师,需要为本次迭代生成提交信息与 PR 文案。',\n '# 任务',\n '基于输入信息输出严格 JSON(不要 markdown、不要代码块、不要多余文字)。',\n '要求:',\n '- 全部中文。',\n '- commitTitle / prTitle 使用 Conventional Commits 格式:<type>: <概要>,简洁具体,不要出现“自动迭代提交/自动 PR”等字样。',\n '- commitBody 为多行要点列表(可为空字符串)。',\n '- prBody 为 Markdown,必须包含标题:# 变更摘要、# 测试结果、# 风险与回滚,并在变更摘要中体现工作总结。',\n '- 不确定处可基于现有信息合理推断,但不要编造测试结果。',\n '# 输出 JSON',\n '{\"commitTitle\":\"...\",\"commitBody\":\"...\",\"prTitle\":\"...\",\"prBody\":\"...\"}',\n '# 输入信息',\n `任务: ${compactLine(input.task) || '(空)'}`,\n `分支: ${input.branchName ?? '(未知)'}`,\n '计划(节选):',\n planSnippet,\n 'notes(节选):',\n notesSnippet,\n '最近一次 AI 输出(节选):',\n aiSnippet,\n '测试结果:',\n testSummary,\n 'git status --short:',\n statusSnippet,\n 'git diff --stat:',\n diffSnippet\n ].join('\\n\\n');\n}\n\nfunction pickString(record: Record<string, unknown>, keys: string[]): string | null {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim();\n }\n }\n return null;\n}\n\nfunction extractJson(text: string): string | null {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (fenced?.[1]) return fenced[1].trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1).trim();\n }\n return null;\n}\n\nfunction normalizeTitle(title: string): string {\n return compactLine(title);\n}\n\nfunction normalizeBody(body?: string | null): string | undefined {\n if (!body) return undefined;\n const normalized = normalizeText(body).trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction extractBulletLines(text?: string | null): string[] {\n if (!text) return [];\n const lines = normalizeText(text)\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n const bullets = lines.filter(line => line.startsWith('- ') || line.startsWith('* '));\n return bullets.map(line => (line.startsWith('* ') ? `- ${line.slice(2).trim()}` : line));\n}\n\n/**\n * 解析 AI 输出的交付摘要 JSON。\n */\nexport function parseDeliverySummary(output: string): DeliverySummary | null {\n const jsonText = extractJson(output);\n if (!jsonText) return null;\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>;\n let commitTitle = pickString(parsed, ['commitTitle', 'commit_message', 'commitMessage', 'commit_title']);\n let commitBody = pickString(parsed, ['commitBody', 'commit_body']);\n let prTitle = pickString(parsed, ['prTitle', 'pr_title']);\n let prBody = pickString(parsed, ['prBody', 'pr_body']);\n\n const commitObj = parsed.commit;\n if ((!commitTitle || !commitBody) && typeof commitObj === 'object' && commitObj !== null) {\n const commitRecord = commitObj as Record<string, unknown>;\n commitTitle = commitTitle ?? pickString(commitRecord, ['title', 'commitTitle']);\n commitBody = commitBody ?? pickString(commitRecord, ['body', 'commitBody']);\n }\n\n const prObj = parsed.pr;\n if ((!prTitle || !prBody) && typeof prObj === 'object' && prObj !== null) {\n const prRecord = prObj as Record<string, unknown>;\n prTitle = prTitle ?? pickString(prRecord, ['title', 'prTitle']);\n prBody = prBody ?? pickString(prRecord, ['body', 'prBody']);\n }\n\n if (!commitTitle || !prTitle || !prBody) return null;\n\n const normalizedCommitTitle = normalizeTitle(commitTitle);\n const normalizedPrTitle = normalizeTitle(prTitle);\n const normalizedCommitBody = normalizeBody(commitBody);\n const normalizedPrBody = normalizeText(prBody).trim();\n\n if (!normalizedCommitTitle || !normalizedPrTitle || !normalizedPrBody) return null;\n\n return {\n commitTitle: normalizedCommitTitle,\n commitBody: normalizedCommitBody,\n prTitle: normalizedPrTitle,\n prBody: normalizedPrBody\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 构建兜底交付摘要。\n */\nexport function buildFallbackSummary(input: SummaryFallbackInput): DeliverySummary {\n const taskLine = compactLine(input.task);\n const shortTask = taskLine.length > 50 ? `${taskLine.slice(0, 50)}...` : taskLine;\n const baseTitle = shortTask || '更新迭代产出';\n const title = `chore: ${baseTitle}`;\n const summaryLines = [`- ${baseTitle}`];\n const testLines = formatTestResultLines(input.testResults);\n const prBody = buildPrBody(summaryLines, testLines);\n return {\n commitTitle: title,\n commitBody: summaryLines.join('\\n'),\n prTitle: title,\n prBody\n };\n}\n\n/**\n * 确保 PR 文案包含必要章节。\n */\nexport function ensurePrBodySections(prBody: string, fallback: PrBodyFallbackInput): string {\n const normalized = normalizeText(prBody).trim();\n const hasAll = REQUIRED_SECTIONS.every(section => normalized.includes(section));\n if (hasAll) return normalized;\n\n const summaryLines = buildSummaryLinesFromCommit(fallback.commitTitle, fallback.commitBody);\n const testLines = formatTestResultLines(fallback.testResults);\n return buildPrBody(summaryLines, testLines);\n}\n","import { Logger } from './logger';\nimport { isoNow } from './utils';\nimport type { WebhookConfig } from './types';\n\nexport type WebhookEvent = 'task_start' | 'iteration_start' | 'task_end';\n\nexport interface WebhookPayload {\n readonly event: WebhookEvent;\n readonly task: string;\n readonly branch: string;\n readonly iteration: number;\n readonly stage: string;\n readonly timestamp: string;\n}\n\nexport interface WebhookPayloadInput {\n readonly event: WebhookEvent;\n readonly task: string;\n readonly branch?: string;\n readonly iteration: number;\n readonly stage: string;\n readonly timestamp?: string;\n}\n\nexport type FetchLikeResponse = {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n};\n\nexport type FetchLike = (url: string, init: {\n readonly method: string;\n readonly headers: Record<string, string>;\n readonly body: string;\n readonly signal?: AbortSignal;\n}) => Promise<FetchLikeResponse>;\n\nconst DEFAULT_TIMEOUT_MS = 8000;\n\nexport function normalizeWebhookUrls(urls?: string[]): string[] {\n if (!urls || urls.length === 0) return [];\n return urls\n .map(url => url.trim())\n .filter(url => url.length > 0);\n}\n\nexport function buildWebhookPayload(input: WebhookPayloadInput): WebhookPayload {\n return {\n event: input.event,\n task: input.task,\n branch: input.branch ?? '',\n iteration: input.iteration,\n stage: input.stage,\n timestamp: input.timestamp ?? isoNow()\n };\n}\n\nfunction resolveFetcher(fetcher?: FetchLike): FetchLike | null {\n if (fetcher) return fetcher;\n const globalFetcher = globalThis.fetch;\n if (typeof globalFetcher !== 'function') return null;\n return (globalFetcher as typeof fetch) as FetchLike;\n}\n\nasync function postWebhook(url: string, payload: WebhookPayload, timeoutMs: number, logger: Logger, fetcher: FetchLike): Promise<void> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetcher(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json'\n },\n body: JSON.stringify(payload),\n signal: controller.signal\n });\n if (!response.ok) {\n logger.warn(`webhook 请求失败(${response.status} ${response.statusText}):${url}`);\n } else {\n logger.debug(`webhook 通知成功:${url}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(`webhook 通知异常:${url}|${message}`);\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function sendWebhookNotifications(\n config: WebhookConfig | null | undefined,\n payload: WebhookPayload,\n logger: Logger,\n fetcher?: FetchLike\n): Promise<void> {\n const urls = normalizeWebhookUrls(config?.urls);\n if (urls.length === 0) return;\n\n const resolvedFetcher = resolveFetcher(fetcher);\n if (!resolvedFetcher) {\n logger.warn('当前 Node 环境不支持 fetch,已跳过 webhook 通知');\n return;\n }\n\n const timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n await Promise.all(urls.map(url => postWebhook(url, payload, timeoutMs, logger, resolvedFetcher)));\n}\n","import path from 'node:path';\n\nexport type MultiTaskMode = 'relay' | 'serial' | 'serial-continue' | 'parallel';\n\nconst MODE_ALIASES: Record<string, MultiTaskMode> = {\n relay: 'relay',\n serial: 'serial',\n 'serial-continue': 'serial-continue',\n parallel: 'parallel',\n 接力模式: 'relay',\n 接力: 'relay',\n 串行执行: 'serial',\n 串行: 'serial',\n 串行执行但是失败也继续: 'serial-continue',\n 串行继续: 'serial-continue',\n 并行执行: 'parallel',\n 并行: 'parallel'\n};\n\n/**\n * 解析多任务执行模式。\n */\nexport function parseMultiTaskMode(raw?: string): MultiTaskMode {\n if (!raw) return 'relay';\n const trimmed = raw.trim();\n if (!trimmed) return 'relay';\n const resolved = MODE_ALIASES[trimmed];\n if (!resolved) {\n throw new Error(`未知 multi-task 模式: ${raw}`);\n }\n return resolved;\n}\n\n/**\n * 规范化任务列表(去空白、剔除空项)。\n */\nexport function normalizeTaskList(input: string[] | string | undefined): string[] {\n if (Array.isArray(input)) {\n return input.map(task => task.trim()).filter(task => task.length > 0);\n }\n if (typeof input === 'string') {\n const trimmed = input.trim();\n return trimmed.length > 0 ? [trimmed] : [];\n }\n return [];\n}\n\nexport interface TaskPlanInput {\n readonly tasks: string[];\n readonly mode: MultiTaskMode;\n readonly useWorktree: boolean;\n readonly baseBranch: string;\n readonly branchInput?: string;\n readonly worktreePath?: string;\n readonly logFile?: string;\n}\n\nexport interface TaskPlan {\n readonly task: string;\n readonly index: number;\n readonly branchName?: string;\n readonly baseBranch: string;\n readonly worktreePath?: string;\n readonly logFile?: string;\n}\n\nfunction buildBranchNameSeries(branchInput: string | undefined, total: number): Array<string | undefined> {\n if (total <= 0) return [];\n if (!branchInput) {\n return Array.from({ length: total }, () => undefined);\n }\n const baseName = branchInput;\n const names: Array<string | undefined> = [baseName];\n for (let i = 1; i < total; i += 1) {\n names.push(`${baseName}-${i + 1}`);\n }\n return names;\n}\n\nfunction appendPathSuffix(filePath: string, suffix: string): string {\n const parsed = path.parse(filePath);\n const nextName = parsed.name ? `${parsed.name}-${suffix}` : suffix;\n return path.join(parsed.dir, `${nextName}${parsed.ext}`);\n}\n\nfunction deriveIndexedPath(basePath: string | undefined, index: number, total: number, label: string): string | undefined {\n if (!basePath) return undefined;\n if (total <= 1 || index === 0) return basePath;\n return appendPathSuffix(basePath, `${label}-${index + 1}`);\n}\n\n/**\n * 构建多任务执行计划。\n */\nexport function buildTaskPlans(input: TaskPlanInput): TaskPlan[] {\n const total = input.tasks.length;\n if (total === 0) return [];\n\n const branchNames: Array<string | undefined> = input.useWorktree\n ? buildBranchNameSeries(input.branchInput, total)\n : input.tasks.map(() => input.branchInput);\n\n return input.tasks.map((task, index) => {\n const relayBaseBranch = input.useWorktree && input.mode === 'relay' && index > 0\n ? branchNames[index - 1] ?? input.baseBranch\n : input.baseBranch;\n\n return {\n task,\n index,\n branchName: branchNames[index],\n baseBranch: relayBaseBranch,\n worktreePath: deriveIndexedPath(input.worktreePath, index, total, 'task'),\n logFile: deriveIndexedPath(input.logFile, index, total, 'task')\n };\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport { CurrentRegistryEntry, getLogsDir, readCurrentRegistry, removeCurrentRegistry } from './logs';\n\ninterface TaskView {\n readonly key: string;\n readonly logFile: string;\n readonly meta: CurrentRegistryEntry;\n readonly lines: string[];\n}\n\ninterface ConfirmState {\n readonly key: string;\n}\n\ninterface TerminationResult {\n readonly message: string;\n readonly isError: boolean;\n readonly removed: boolean;\n}\n\ninterface MonitorState {\n tasks: TaskView[];\n selectedIndex: number;\n selectedKey?: string;\n lineOffsets: Map<string, number>;\n stickToBottom: Map<string, boolean>;\n lastError?: string;\n confirm?: ConfirmState;\n statusMessage?: string;\n statusIsError?: boolean;\n}\n\nconst REFRESH_INTERVAL = 1000;\nconst TERMINATE_GRACE_MS = 800;\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction padLine(text: string, width: number): string {\n if (width <= 0) return '';\n const truncated = text.length > width ? text.slice(0, width) : text;\n const padding = width - truncated.length;\n const left = Math.floor(padding / 2);\n const right = padding - left;\n return `${' '.repeat(left)}${truncated}${' '.repeat(right)}`;\n}\n\nexport function buildConfirmDialogLines(taskKey: string, columns: number): string[] {\n if (columns <= 0) return [];\n const message = `确认终止任务 ${taskKey}?`;\n const hint = 'y 确认 / n 取消';\n const minWidth = Math.max(message.length, hint.length, 4);\n const innerWidth = Math.min(columns - 2, minWidth);\n if (innerWidth <= 0) {\n return [truncateLine(message, columns), truncateLine(hint, columns)];\n }\n const border = `+${'-'.repeat(innerWidth)}+`;\n const lines = [\n border,\n `|${padLine(message, innerWidth)}|`,\n `|${padLine(hint, innerWidth)}|`,\n border\n ];\n return lines.map(line => truncateLine(line, columns));\n}\n\nfunction applyDialogOverlay(lines: string[], dialogLines: string[]): void {\n if (lines.length === 0 || dialogLines.length === 0) return;\n const start = Math.max(0, Math.floor((lines.length - dialogLines.length) / 2));\n for (let i = 0; i < dialogLines.length && start + i < lines.length; i += 1) {\n lines[start + i] = dialogLines[i];\n }\n}\n\nexport function resolveTerminationTarget(pid: number, platform: NodeJS.Platform = process.platform): number {\n return platform === 'win32' ? pid : -pid;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n if (!Number.isFinite(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code === 'ESRCH') return false;\n return true;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction setStatus(state: MonitorState, message?: string, isError = false): void {\n state.statusMessage = message;\n state.statusIsError = message ? isError : false;\n}\n\nfunction findTaskByKey(state: MonitorState, key: string): TaskView | undefined {\n return state.tasks.find(task => task.key === key);\n}\n\nasync function safeRemoveRegistry(logFile: string): Promise<void> {\n try {\n await removeCurrentRegistry(logFile);\n } catch {\n // 忽略清理失败,避免阻断 monitor 刷新\n }\n}\n\nasync function readLogLines(logFile: string): Promise<string[]> {\n try {\n const content = await fs.readFile(logFile, 'utf8');\n const normalized = content.replace(/\\r\\n?/g, '\\n');\n const lines = normalized.split('\\n');\n return lines.length > 0 ? lines : [''];\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`(无法读取日志文件:${message})`];\n }\n}\n\nasync function loadTasks(logsDir: string): Promise<TaskView[]> {\n const registry = await readCurrentRegistry();\n const entries = Object.entries(registry).sort(([a], [b]) => a.localeCompare(b));\n const aliveEntries: Array<[string, CurrentRegistryEntry]> = [];\n for (const [key, meta] of entries) {\n const pid = typeof meta.pid === 'number' ? meta.pid : undefined;\n if (pid && !isProcessAlive(pid)) {\n const logFile = meta.logFile ?? path.join(logsDir, key);\n await safeRemoveRegistry(logFile);\n continue;\n }\n aliveEntries.push([key, meta]);\n }\n const tasks = await Promise.all(aliveEntries.map(async ([key, meta]) => {\n const logFile = meta.logFile ?? path.join(logsDir, key);\n const lines = await readLogLines(logFile);\n return {\n key,\n logFile,\n meta,\n lines\n } satisfies TaskView;\n }));\n return tasks;\n}\n\nfunction buildHeader(state: MonitorState, columns: number): string {\n if (state.tasks.length === 0) {\n return truncateLine('暂无运行中的任务,按 q 退出', columns);\n }\n const current = state.tasks[state.selectedIndex];\n const total = state.tasks.length;\n const index = state.selectedIndex + 1;\n const title = `任务 ${index}/${total} | ${current.key} | ←/→ 切换任务 ↑/↓ 上下 1 行 PageUp/PageDown 翻页 t 终止 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildStatus(\n task: TaskView,\n page: { current: number; total: number },\n columns: number,\n errorMessage?: string,\n statusMessage?: string,\n statusIsError?: boolean\n): string {\n const meta = task.meta;\n const status = `轮次 ${meta.round} | Token ${meta.tokenUsed} | 页 ${page.current}/${page.total} | 项目 ${meta.path}`;\n const extras: string[] = [];\n if (errorMessage) {\n extras.push(`刷新失败:${errorMessage}`);\n }\n if (statusMessage) {\n extras.push(statusIsError ? `操作失败:${statusMessage}` : statusMessage);\n }\n const suffix = extras.length > 0 ? ` | ${extras.join(' | ')}` : '';\n return truncateLine(`${status}${suffix}`, columns);\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nfunction render(state: MonitorState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildHeader(state, columns);\n\n if (state.tasks.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const statusText = state.lastError\n ? `刷新失败:${state.lastError}`\n : state.statusMessage\n ? (state.statusIsError ? `操作失败:${state.statusMessage}` : state.statusMessage)\n : '等待后台任务启动…';\n const status = truncateLine(statusText, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const stick = state.stickToBottom.get(current.key) ?? true;\n const nextOffset = Math.min(Math.max(stick ? maxOffset : offset, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n\n const start = nextOffset;\n const pageLines = lines.slice(start, start + pageSize).map(line => truncateLine(line, columns));\n while (pageLines.length < pageSize) {\n pageLines.push('');\n }\n\n const totalPages = Math.max(1, Math.ceil(lines.length / pageSize));\n const currentPage = Math.min(totalPages, Math.floor(nextOffset / pageSize) + 1);\n const status = buildStatus(\n current,\n { current: currentPage, total: totalPages },\n columns,\n state.lastError,\n state.statusMessage,\n state.statusIsError\n );\n if (state.confirm) {\n const dialogLines = buildConfirmDialogLines(state.confirm.key, columns);\n applyDialogOverlay(pageLines, dialogLines);\n }\n const content = [header, ...pageLines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction updateSelection(state: MonitorState, tasks: TaskView[]): void {\n state.tasks = tasks;\n if (tasks.length === 0) {\n state.selectedIndex = 0;\n state.selectedKey = undefined;\n return;\n }\n\n if (state.selectedKey) {\n const index = tasks.findIndex(task => task.key === state.selectedKey);\n if (index >= 0) {\n state.selectedIndex = index;\n } else {\n state.selectedIndex = 0;\n }\n } else {\n state.selectedIndex = 0;\n }\n\n state.selectedKey = tasks[state.selectedIndex]?.key;\n\n const existing = new Set(tasks.map(task => task.key));\n for (const key of state.lineOffsets.keys()) {\n if (!existing.has(key)) {\n state.lineOffsets.delete(key);\n }\n }\n for (const key of state.stickToBottom.keys()) {\n if (!existing.has(key)) {\n state.stickToBottom.delete(key);\n }\n }\n if (state.confirm && !existing.has(state.confirm.key)) {\n state.confirm = undefined;\n }\n}\n\nfunction moveSelection(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const total = state.tasks.length;\n state.selectedIndex = (state.selectedIndex + direction + total) % total;\n state.selectedKey = state.tasks[state.selectedIndex]?.key;\n}\n\nfunction moveLine(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const { rows } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const nextOffset = Math.min(Math.max(offset + direction, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n}\n\nfunction movePage(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const { rows } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const nextOffset = Math.min(Math.max(offset + direction * pageSize, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n}\n\nasync function terminateTask(task: TaskView): Promise<TerminationResult> {\n const pid = typeof task.meta.pid === 'number' ? task.meta.pid : undefined;\n if (!pid || pid <= 0) {\n return { message: '任务未记录 PID,无法终止', isError: true, removed: false };\n }\n const target = resolveTerminationTarget(pid);\n try {\n process.kill(target, 'SIGTERM');\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code === 'ESRCH') {\n await safeRemoveRegistry(task.logFile);\n return { message: `任务 ${task.key} 已结束`, isError: false, removed: true };\n }\n const message = error instanceof Error ? error.message : String(error);\n return { message: `发送终止信号失败:${message}`, isError: true, removed: false };\n }\n\n await sleep(TERMINATE_GRACE_MS);\n if (!isProcessAlive(pid)) {\n await safeRemoveRegistry(task.logFile);\n return { message: `任务 ${task.key} 已终止`, isError: false, removed: true };\n }\n return { message: `已发送终止信号,任务仍在运行`, isError: false, removed: false };\n}\n\nasync function terminateTaskByKey(state: MonitorState, key: string, refresh: () => Promise<void>): Promise<void> {\n const task = findTaskByKey(state, key);\n if (!task) {\n setStatus(state, `任务 ${key} 已不存在`, true);\n render(state);\n return;\n }\n const result = await terminateTask(task);\n setStatus(state, result.message, result.isError);\n if (result.removed) {\n await refresh();\n render(state);\n return;\n }\n render(state);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction handleInput(state: MonitorState, input: string, refresh: () => Promise<void>): void {\n const lower = input.toLowerCase();\n if (state.confirm) {\n if (lower.includes('y')) {\n const key = state.confirm.key;\n state.confirm = undefined;\n setStatus(state, `正在终止任务 ${key}...`);\n void terminateTaskByKey(state, key, refresh);\n return;\n }\n if (lower.includes('n') || input === '\\u001b') {\n state.confirm = undefined;\n setStatus(state, '已取消终止');\n return;\n }\n return;\n }\n\n if (input.includes('\\u001b[D')) {\n moveSelection(state, -1);\n return;\n }\n if (input.includes('\\u001b[C')) {\n moveSelection(state, 1);\n return;\n }\n if (input.includes('\\u001b[A')) {\n moveLine(state, -1);\n return;\n }\n if (input.includes('\\u001b[B')) {\n moveLine(state, 1);\n return;\n }\n if (input.includes('\\u001b[5~')) {\n movePage(state, -1);\n return;\n }\n if (input.includes('\\u001b[6~')) {\n movePage(state, 1);\n return;\n }\n if (lower.includes('t')) {\n if (state.tasks.length === 0) {\n setStatus(state, '暂无可终止的任务', true);\n return;\n }\n const current = state.tasks[state.selectedIndex];\n if (typeof current.meta.pid !== 'number' || current.meta.pid <= 0) {\n setStatus(state, '任务未记录 PID,无法终止', true);\n return;\n }\n state.confirm = { key: current.key };\n setStatus(state, undefined);\n }\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\n/**\n * 启动 monitor 终端界面。\n */\nexport async function runMonitor(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 monitor。');\n return;\n }\n\n const logsDir = getLogsDir();\n const state: MonitorState = {\n tasks: [],\n selectedIndex: 0,\n lineOffsets: new Map(),\n stickToBottom: new Map()\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n let refreshing = false;\n\n const refresh = async (): Promise<void> => {\n if (refreshing) return;\n refreshing = true;\n try {\n const tasks = await loadTasks(logsDir);\n state.lastError = undefined;\n updateSelection(state, tasks);\n render(state);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.lastError = message;\n render(state);\n } finally {\n refreshing = false;\n }\n };\n\n await refresh();\n\n const timer = setInterval(refresh, REFRESH_INTERVAL);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n clearInterval(timer);\n cleanup();\n process.exit(0);\n }\n handleInput(state, input, refresh);\n render(state);\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import { open as openFile } from 'node:fs/promises';\nimport fs from 'fs-extra';\n\nexport interface LogTailOptions {\n readonly filePath: string;\n readonly startFromEnd?: boolean;\n readonly pollIntervalMs?: number;\n readonly onLine: (line: string) => void;\n readonly onError?: (message: string) => void;\n}\n\nexport interface LogTailHandle {\n stop: () => Promise<void>;\n}\n\nfunction normalizeChunk(chunk: string): string {\n return chunk.replace(/\\r\\n?/g, '\\n');\n}\n\n/**\n * 轮询尾读日志文件,按行输出。\n */\nexport async function tailLogFile(options: LogTailOptions): Promise<LogTailHandle> {\n const intervalMs = options.pollIntervalMs ?? 200;\n let offset = 0;\n let buffer = '';\n let reading = false;\n let stopped = false;\n\n if (options.startFromEnd) {\n try {\n const stat = await fs.stat(options.filePath);\n offset = stat.size;\n } catch {\n offset = 0;\n }\n }\n\n const flushBuffer = (): void => {\n if (!buffer) return;\n options.onLine(buffer);\n buffer = '';\n };\n\n const emitChunk = (chunk: string): void => {\n buffer += normalizeChunk(chunk);\n const parts = buffer.split('\\n');\n buffer = parts.pop() ?? '';\n for (const line of parts) {\n options.onLine(line);\n }\n };\n\n const readNew = async (): Promise<void> => {\n if (reading || stopped) return;\n reading = true;\n try {\n const stat = await fs.stat(options.filePath);\n if (stat.size < offset) {\n offset = stat.size;\n buffer = '';\n }\n if (stat.size > offset) {\n const length = stat.size - offset;\n const handle = await openFile(options.filePath, 'r');\n try {\n const payload = Buffer.alloc(length);\n const result = await handle.read(payload, 0, length, offset);\n offset += result.bytesRead;\n if (result.bytesRead > 0) {\n const text = payload.subarray(0, result.bytesRead).toString('utf8');\n emitChunk(text);\n }\n } finally {\n await handle.close();\n }\n }\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code !== 'ENOENT') {\n const message = err instanceof Error ? err.message : String(err);\n options.onError?.(message);\n }\n } finally {\n reading = false;\n }\n };\n\n const timer = setInterval(() => {\n void readNew();\n }, intervalMs);\n\n await readNew();\n\n return {\n stop: async () => {\n if (stopped) return;\n stopped = true;\n clearInterval(timer);\n flushBuffer();\n }\n };\n}\n"],"mappings":"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","names":["import_fs_extra","import_node_path","path","fs","path","import_node_path","import_fs_extra","path","os","fs","import_node_path","path","import_node_os","import_node_path","import_fs_extra","path","os","fs","import_fs_extra","status","content","fs","import_fs_extra","import_node_path","path","fs","getTerminalSize","truncateLine","getPageSize","buildListLine","ensureListOffset","status","content","render","shouldExit","isArrowUp","isArrowDown","setupCleanup","clampIndex","import_fs_extra","import_node_path","import_node_path","import_fs_extra","path","fs","import_fs_extra","fs","import_fs_extra","import_node_path","path","fs","path","normalizeText","compactLine","extractJson","path","fs","import_node_path","path","import_fs_extra","import_node_path","getTerminalSize","truncateLine","readLogLines","fs","path","buildHeader","buildStatus","getPageSize","render","status","content","shouldExit","setupCleanup","import_fs_extra","fs","openFile","fs"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/config.ts","../src/utils.ts","../src/global-config.ts","../src/git.ts","../src/logs.ts","../src/alias-viewer.ts","../src/logs-viewer.ts","../src/loop.ts","../src/ai.ts","../src/deps.ts","../src/gh.ts","../src/logger.ts","../src/plan.ts","../src/quality.ts","../src/runtime-tracker.ts","../src/summary.ts","../src/webhook.ts","../src/multi-task.ts","../src/monitor.ts","../src/log-tailer.ts"],"sourcesContent":["import { spawn } from 'node:child_process';\nimport fs from 'fs-extra';\nimport { Command } from 'commander';\nimport { buildLoopConfig, CliOptions, defaultNotesPath, defaultPlanPath, defaultWorkflowDoc } from './config';\nimport {\n applyShortcutArgv,\n getGlobalConfigPath,\n loadGlobalConfig,\n normalizeAliasName,\n parseAliasEntries,\n splitCommandArgs,\n upsertAliasEntry\n} from './global-config';\nimport { getCurrentBranch } from './git';\nimport { buildAutoLogFilePath, formatCommandLine } from './logs';\nimport { runAliasViewer } from './alias-viewer';\nimport { runLogsViewer } from './logs-viewer';\nimport { runLoop } from './loop';\nimport { defaultLogger } from './logger';\nimport { buildTaskPlans, normalizeTaskList, parseMultiTaskMode } from './multi-task';\nimport { resolveTerminationTarget, runMonitor } from './monitor';\nimport { tailLogFile } from './log-tailer';\nimport { resolvePath } from './utils';\n\nconst FOREGROUND_CHILD_ENV = 'WHEEL_AI_FOREGROUND_CHILD';\n\ntype OptionValueMode = 'none' | 'single' | 'variadic';\n\ninterface RunOptionSpec {\n readonly name: string;\n readonly flags: readonly string[];\n readonly valueMode: OptionValueMode;\n}\n\ninterface ParsedArgSegment {\n readonly name?: string;\n readonly tokens: string[];\n}\n\nconst RUN_OPTION_SPECS: RunOptionSpec[] = [\n { name: 'task', flags: ['-t', '--task'], valueMode: 'single' },\n { name: 'iterations', flags: ['-i', '--iterations'], valueMode: 'single' },\n { name: 'ai-cli', flags: ['--ai-cli'], valueMode: 'single' },\n { name: 'ai-args', flags: ['--ai-args'], valueMode: 'variadic' },\n { name: 'ai-prompt-arg', flags: ['--ai-prompt-arg'], valueMode: 'single' },\n { name: 'notes-file', flags: ['--notes-file'], valueMode: 'single' },\n { name: 'plan-file', flags: ['--plan-file'], valueMode: 'single' },\n { name: 'workflow-doc', flags: ['--workflow-doc'], valueMode: 'single' },\n { name: 'worktree', flags: ['--worktree'], valueMode: 'none' },\n { name: 'branch', flags: ['--branch'], valueMode: 'single' },\n { name: 'worktree-path', flags: ['--worktree-path'], valueMode: 'single' },\n { name: 'base-branch', flags: ['--base-branch'], valueMode: 'single' },\n { name: 'skip-install', flags: ['--skip-install'], valueMode: 'none' },\n { name: 'run-tests', flags: ['--run-tests'], valueMode: 'none' },\n { name: 'run-e2e', flags: ['--run-e2e'], valueMode: 'none' },\n { name: 'unit-command', flags: ['--unit-command'], valueMode: 'single' },\n { name: 'e2e-command', flags: ['--e2e-command'], valueMode: 'single' },\n { name: 'auto-commit', flags: ['--auto-commit'], valueMode: 'none' },\n { name: 'auto-push', flags: ['--auto-push'], valueMode: 'none' },\n { name: 'pr', flags: ['--pr'], valueMode: 'none' },\n { name: 'pr-title', flags: ['--pr-title'], valueMode: 'single' },\n { name: 'pr-body', flags: ['--pr-body'], valueMode: 'single' },\n { name: 'draft', flags: ['--draft'], valueMode: 'none' },\n { name: 'reviewer', flags: ['--reviewer'], valueMode: 'variadic' },\n { name: 'auto-merge', flags: ['--auto-merge'], valueMode: 'none' },\n { name: 'webhook', flags: ['--webhook'], valueMode: 'single' },\n { name: 'webhook-timeout', flags: ['--webhook-timeout'], valueMode: 'single' },\n { name: 'multi-task-mode', flags: ['--multi-task-mode'], valueMode: 'single' },\n { name: 'stop-signal', flags: ['--stop-signal'], valueMode: 'single' },\n { name: 'log-file', flags: ['--log-file'], valueMode: 'single' },\n { name: 'background', flags: ['--background'], valueMode: 'none' },\n { name: 'verbose', flags: ['-v', '--verbose'], valueMode: 'none' },\n { name: 'skip-quality', flags: ['--skip-quality'], valueMode: 'none' }\n];\n\nconst RUN_OPTION_FLAG_MAP = new Map<string, RunOptionSpec>(\n RUN_OPTION_SPECS.flatMap(spec => spec.flags.map(flag => [flag, spec] as const))\n);\n\nfunction parseInteger(value: string, defaultValue: number): number {\n const parsed = Number.parseInt(value, 10);\n if (Number.isNaN(parsed)) return defaultValue;\n return parsed;\n}\n\nfunction collect(value: string, previous: string[]): string[] {\n return [...previous, value];\n}\n\nfunction normalizeOptional(value: unknown): string | undefined {\n if (typeof value !== 'string') return undefined;\n const trimmed = value.trim();\n return trimmed.length > 0 ? trimmed : undefined;\n}\n\nfunction hasOption(argv: string[], option: string): boolean {\n return argv.some(arg => arg === option || arg.startsWith(`${option}=`));\n}\n\nfunction buildBackgroundArgs(argv: string[], logFile: string, branchName?: string, injectBranch = false): string[] {\n const rawArgs = argv.slice(1);\n const filtered = rawArgs.filter(arg => !(arg === '--background' || arg.startsWith('--background=')));\n if (!hasOption(filtered, '--log-file')) {\n filtered.push('--log-file', logFile);\n }\n if (injectBranch && branchName && !hasOption(filtered, '--branch')) {\n filtered.push('--branch', branchName);\n }\n return filtered;\n}\n\nfunction extractAliasCommandArgs(argv: string[], name: string): string[] {\n const args = argv.slice(2);\n const start = args.findIndex((arg, index) => arg === 'set' && args[index + 1] === 'alias' && args[index + 2] === name);\n if (start < 0) return [];\n const rest = args.slice(start + 3);\n if (rest[0] === '--') return rest.slice(1);\n return rest;\n}\n\nfunction isAliasCommandToken(token: string): boolean {\n return token === 'alias' || token === 'aliases';\n}\n\nfunction extractAliasRunArgs(argv: string[], name: string): string[] {\n const args = argv.slice(2);\n const start = args.findIndex(\n (arg, index) => isAliasCommandToken(arg) && args[index + 1] === 'run' && args[index + 2] === name\n );\n if (start < 0) return [];\n const rest = args.slice(start + 3);\n if (rest[0] === '--') return rest.slice(1);\n return rest;\n}\n\nfunction normalizeAliasCommandArgs(args: string[]): string[] {\n let start = 0;\n if (args[start] === 'wheel-ai') {\n start += 1;\n }\n if (args[start] === 'run') {\n start += 1;\n }\n return args.slice(start);\n}\n\nfunction resolveRunOptionSpec(token: string): { spec: RunOptionSpec; inlineValue?: string } | null {\n const equalIndex = token.indexOf('=');\n const flag = equalIndex > 0 ? token.slice(0, equalIndex) : token;\n const spec = RUN_OPTION_FLAG_MAP.get(flag);\n if (!spec) return null;\n if (equalIndex > 0) {\n return { spec, inlineValue: token.slice(equalIndex + 1) };\n }\n return { spec };\n}\n\nfunction parseArgSegments(tokens: string[]): ParsedArgSegment[] {\n const segments: ParsedArgSegment[] = [];\n let index = 0;\n while (index < tokens.length) {\n const token = tokens[index];\n if (token === '--') {\n segments.push({ tokens: tokens.slice(index) });\n break;\n }\n\n const match = resolveRunOptionSpec(token);\n if (!match) {\n segments.push({ tokens: [token] });\n index += 1;\n continue;\n }\n\n if (match.inlineValue !== undefined) {\n segments.push({ name: match.spec.name, tokens: [token] });\n index += 1;\n continue;\n }\n\n if (match.spec.valueMode === 'none') {\n segments.push({ name: match.spec.name, tokens: [token] });\n index += 1;\n continue;\n }\n\n if (match.spec.valueMode === 'single') {\n const next = tokens[index + 1];\n if (next !== undefined) {\n segments.push({ name: match.spec.name, tokens: [token, next] });\n index += 2;\n } else {\n segments.push({ name: match.spec.name, tokens: [token] });\n index += 1;\n }\n continue;\n }\n\n const values: string[] = [];\n let cursor = index + 1;\n while (cursor < tokens.length) {\n const next = tokens[cursor];\n if (next === '--') break;\n const nextMatch = resolveRunOptionSpec(next);\n if (nextMatch) break;\n values.push(next);\n cursor += 1;\n }\n segments.push({ name: match.spec.name, tokens: [token, ...values] });\n index = cursor;\n }\n\n return segments;\n}\n\nfunction mergeAliasCommandArgs(aliasTokens: string[], additionTokens: string[]): string[] {\n const aliasSegments = parseArgSegments(aliasTokens);\n const additionSegments = parseArgSegments(additionTokens);\n const overrideNames = new Set(\n additionSegments.flatMap(segment => (segment.name ? [segment.name] : []))\n );\n\n const merged = [\n ...aliasSegments.filter(segment => !segment.name || !overrideNames.has(segment.name)),\n ...additionSegments\n ];\n\n return merged.flatMap(segment => segment.tokens);\n}\n\nasync function runForegroundWithDetach(options: {\n argv: string[];\n logFile: string;\n branchName?: string;\n injectBranch: boolean;\n isMultiTask: boolean;\n}): Promise<void> {\n const args = buildBackgroundArgs(options.argv, options.logFile, options.branchName, options.injectBranch);\n const child = spawn(process.execPath, [...process.execArgv, ...args], {\n detached: true,\n stdio: 'ignore',\n env: {\n ...process.env,\n [FOREGROUND_CHILD_ENV]: '1'\n }\n });\n child.unref();\n\n const resolvedLogFile = resolvePath(process.cwd(), options.logFile);\n const existed = await fs.pathExists(resolvedLogFile);\n const tailer = await tailLogFile({\n filePath: resolvedLogFile,\n startFromEnd: existed,\n onLine: line => {\n process.stdout.write(`${line}\\n`);\n },\n onError: message => {\n defaultLogger.warn(`日志读取失败:${message}`);\n }\n });\n\n const suffixNote = options.isMultiTask ? '(多任务将追加序号)' : '';\n console.log(`已进入前台日志查看,按 Esc 切到后台运行,日志输出至 ${resolvedLogFile}${suffixNote}`);\n\n let cleaned = false;\n const cleanup = async (): Promise<void> => {\n if (cleaned) return;\n cleaned = true;\n await tailer.stop();\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n };\n\n const detach = async (): Promise<void> => {\n await cleanup();\n console.log(`已切入后台运行,日志输出至 ${resolvedLogFile}${suffixNote}`);\n process.exit(0);\n };\n\n const terminate = async (): Promise<void> => {\n if (child.pid) {\n try {\n const target = resolveTerminationTarget(child.pid);\n process.kill(target, 'SIGTERM');\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n defaultLogger.warn(`终止子进程失败:${message}`);\n }\n }\n await cleanup();\n process.exit(0);\n };\n\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(true);\n process.stdin.resume();\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (input === '\\u001b') {\n void detach();\n return;\n }\n if (input === '\\u0003') {\n void terminate();\n }\n });\n }\n\n process.on('SIGINT', () => {\n void terminate();\n });\n process.on('SIGTERM', () => {\n void terminate();\n });\n\n child.on('exit', async code => {\n await cleanup();\n process.exit(code ?? 0);\n });\n}\n\n/**\n * CLI 入口。\n */\nexport async function runCli(argv: string[]): Promise<void> {\n const globalConfig = await loadGlobalConfig(defaultLogger);\n const effectiveArgv = applyShortcutArgv(argv, globalConfig);\n const program = new Command();\n\n program\n .name('wheel-ai')\n .description('基于 AI CLI 的持续迭代开发工具')\n .version('1.0.0');\n program.addHelpText(\n 'after',\n '\\n别名执行:\\n wheel-ai alias run <alias> <addition...>\\n 追加命令与 alias 重叠时,以追加为准。\\n'\n );\n\n program\n .command('run')\n .option('-t, --task <task>', '需要完成的任务描述(可重复传入,独立处理)', collect, [])\n .option('-i, --iterations <number>', '最大迭代次数', value => parseInteger(value, 5), 5)\n .option('--ai-cli <command>', 'AI CLI 命令', 'claude')\n .option('--ai-args <args...>', 'AI CLI 参数', [])\n .option('--ai-prompt-arg <flag>', '用于传入 prompt 的参数(为空则使用 stdin)')\n .option('--notes-file <path>', '持久化记忆文件', defaultNotesPath())\n .option('--plan-file <path>', '计划文件', defaultPlanPath())\n .option('--workflow-doc <path>', 'AI 工作流程说明文件', defaultWorkflowDoc())\n .option('--worktree', '在独立 worktree 上执行', false)\n .option('--branch <name>', 'worktree 分支名(默认自动生成或当前分支)')\n .option('--worktree-path <path>', 'worktree 路径,默认 ../worktrees/<branch>')\n .option('--base-branch <name>', '创建分支的基线分支', 'main')\n .option('--skip-install', '跳过开始任务前的依赖检查', false)\n .option('--run-tests', '运行单元测试命令', false)\n .option('--run-e2e', '运行 e2e 测试命令', false)\n .option('--unit-command <cmd>', '单元测试命令', 'yarn test')\n .option('--e2e-command <cmd>', 'e2e 测试命令', 'yarn e2e')\n .option('--auto-commit', '自动 git commit', false)\n .option('--auto-push', '自动 git push', false)\n .option('--pr', '使用 gh 创建 PR', false)\n .option('--pr-title <title>', 'PR 标题')\n .option('--pr-body <path>', 'PR 描述文件路径(可留空自动生成)')\n .option('--draft', '以草稿形式创建 PR', false)\n .option('--reviewer <user...>', 'PR reviewers', collect, [])\n .option('--auto-merge', 'PR 检查通过后自动合并', false)\n .option('--webhook <url>', 'webhook 通知 URL(可重复)', collect, [])\n .option('--webhook-timeout <ms>', 'webhook 请求超时(毫秒)', value => parseInteger(value, 8000))\n .option('--multi-task-mode <mode>', '多任务执行模式(relay/serial/serial-continue/parallel,或中文描述)', 'relay')\n .option('--stop-signal <token>', 'AI 输出中的停止标记', '<<DONE>>')\n .option('--log-file <path>', '日志输出文件路径')\n .option('--background', '切入后台运行', false)\n .option('-v, --verbose', '输出调试日志', false)\n .option('--skip-quality', '跳过代码质量检查', false)\n .action(async (options) => {\n const tasks = normalizeTaskList(options.task as string[] | string | undefined);\n if (tasks.length === 0) {\n throw new Error('需要至少提供一个任务描述');\n }\n\n const multiTaskMode = parseMultiTaskMode(options.multiTaskMode as string | undefined);\n const useWorktree = Boolean(options.worktree);\n if (multiTaskMode === 'parallel' && !useWorktree) {\n throw new Error('并行模式必须启用 --worktree');\n }\n\n const branchInput = normalizeOptional(options.branch);\n const logFileInput = normalizeOptional(options.logFile);\n const worktreePathInput = normalizeOptional(options.worktreePath);\n const background = Boolean(options.background);\n const isMultiTask = tasks.length > 1;\n const isForegroundChild = process.env[FOREGROUND_CHILD_ENV] === '1';\n const canForegroundDetach = !background && !isForegroundChild && process.stdout.isTTY && process.stdin.isTTY;\n\n const shouldInjectBranch = Boolean(useWorktree && branchInput && !isMultiTask);\n const branchNameForBackground = branchInput;\n\n let logFile = logFileInput;\n if ((background || canForegroundDetach) && !logFile) {\n let branchForLog = 'multi-task';\n if (!isMultiTask) {\n branchForLog = branchNameForBackground ?? '';\n if (!branchForLog) {\n try {\n const current = await getCurrentBranch(process.cwd(), defaultLogger);\n branchForLog = current || 'detached';\n } catch {\n branchForLog = 'unknown';\n }\n }\n } else if (branchInput) {\n branchForLog = `${branchInput}-multi`;\n }\n logFile = buildAutoLogFilePath(branchForLog);\n }\n\n if (background) {\n if (!logFile) {\n throw new Error('后台运行需要指定日志文件');\n }\n const args = buildBackgroundArgs(effectiveArgv, logFile, branchNameForBackground, shouldInjectBranch);\n const child = spawn(process.execPath, [...process.execArgv, ...args], {\n detached: true,\n stdio: 'ignore'\n });\n child.unref();\n const displayLogFile = resolvePath(process.cwd(), logFile);\n const suffixNote = isMultiTask ? '(多任务将追加序号)' : '';\n console.log(`已切入后台运行,日志输出至 ${displayLogFile}${suffixNote}`);\n return;\n }\n\n if (canForegroundDetach) {\n if (!logFile) {\n throw new Error('切入后台需要指定日志文件');\n }\n await runForegroundWithDetach({\n argv: effectiveArgv,\n logFile,\n branchName: branchNameForBackground,\n injectBranch: shouldInjectBranch,\n isMultiTask\n });\n return;\n }\n\n const taskPlans = buildTaskPlans({\n tasks,\n mode: multiTaskMode,\n useWorktree,\n baseBranch: options.baseBranch as string,\n branchInput,\n worktreePath: worktreePathInput,\n logFile: logFileInput\n });\n\n const baseOptions = {\n iterations: options.iterations as number,\n aiCli: options.aiCli as string,\n aiArgs: (options.aiArgs as string[]) ?? [],\n aiPromptArg: options.aiPromptArg as string | undefined,\n notesFile: options.notesFile as string,\n planFile: options.planFile as string,\n workflowDoc: options.workflowDoc as string,\n useWorktree,\n runTests: Boolean(options.runTests),\n runE2e: Boolean(options.runE2e),\n unitCommand: options.unitCommand as string | undefined,\n e2eCommand: options.e2eCommand as string | undefined,\n autoCommit: Boolean(options.autoCommit),\n autoPush: Boolean(options.autoPush),\n pr: Boolean(options.pr),\n prTitle: options.prTitle as string | undefined,\n prBody: options.prBody as string | undefined,\n draft: Boolean(options.draft),\n reviewers: (options.reviewer as string[]) ?? [],\n autoMerge: Boolean(options.autoMerge),\n webhookUrls: (options.webhook as string[]) ?? [],\n webhookTimeout: options.webhookTimeout as number | undefined,\n stopSignal: options.stopSignal as string,\n verbose: Boolean(options.verbose),\n skipInstall: Boolean(options.skipInstall),\n skipQuality: Boolean(options.skipQuality)\n };\n\n const dynamicRelay = useWorktree && multiTaskMode === 'relay' && !branchInput;\n let relayBaseBranch = options.baseBranch as string;\n\n const runPlan = async (plan: typeof taskPlans[number], baseBranchOverride?: string): Promise<Awaited<ReturnType<typeof runLoop>>> => {\n const cliOptions: CliOptions = {\n task: plan.task,\n ...baseOptions,\n branch: plan.branchName,\n worktreePath: plan.worktreePath,\n baseBranch: baseBranchOverride ?? plan.baseBranch,\n logFile: plan.logFile\n };\n const config = buildLoopConfig(cliOptions, process.cwd());\n return runLoop(config);\n };\n\n if (multiTaskMode === 'parallel') {\n const results = await Promise.allSettled(taskPlans.map(plan => runPlan(plan)));\n const errors = results.flatMap((result, index) => {\n if (result.status === 'fulfilled') return [];\n const reason = result.reason instanceof Error ? result.reason.message : String(result.reason);\n return [`任务 ${index + 1} 失败: ${reason}`];\n });\n if (errors.length > 0) {\n errors.forEach(message => defaultLogger.warn(message));\n throw new Error(errors.join('\\n'));\n }\n return;\n }\n\n if (multiTaskMode === 'serial-continue') {\n const errors: string[] = [];\n for (const plan of taskPlans) {\n try {\n const baseBranch = dynamicRelay ? relayBaseBranch : plan.baseBranch;\n const result = await runPlan(plan, baseBranch);\n if (dynamicRelay && result.branchName) {\n relayBaseBranch = result.branchName;\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n errors.push(`任务 ${plan.index + 1} 失败: ${message}`);\n defaultLogger.warn(`任务 ${plan.index + 1} 执行失败,继续下一任务:${message}`);\n }\n }\n if (errors.length > 0) {\n throw new Error(errors.join('\\n'));\n }\n return;\n }\n\n for (const plan of taskPlans) {\n const baseBranch = dynamicRelay ? relayBaseBranch : plan.baseBranch;\n const result = await runPlan(plan, baseBranch);\n if (dynamicRelay && result.branchName) {\n relayBaseBranch = result.branchName;\n }\n }\n });\n\n program\n .command('monitor')\n .description('查看后台运行日志(t 终止任务)')\n .action(async () => {\n await runMonitor();\n });\n\n program\n .command('logs')\n .description('查看历史日志')\n .action(async () => {\n await runLogsViewer();\n });\n\n program\n .command('set')\n .description('写入全局配置')\n .command('alias <name> [options...]')\n .description('设置 alias')\n .allowUnknownOption(true)\n .action(async (name: string) => {\n const normalized = normalizeAliasName(name);\n if (!normalized) {\n throw new Error('alias 名称不能为空且不能包含空白字符');\n }\n const commandArgs = extractAliasCommandArgs(effectiveArgv, name);\n const commandLine = formatCommandLine(commandArgs);\n if (!commandLine) {\n throw new Error('alias 命令不能为空');\n }\n await upsertAliasEntry(normalized, commandLine);\n console.log(`已写入 alias:${normalized}`);\n });\n\n const aliasCommand = program\n .command('alias')\n .alias('aliases')\n .description('浏览全局 alias 配置(alias run 可执行并追加命令)');\n\n aliasCommand\n .command('run <name> [addition...]')\n .description('执行 alias 并追加命令')\n .allowUnknownOption(true)\n .allowExcessArguments(true)\n .action(async (name: string) => {\n const normalized = normalizeAliasName(name);\n if (!normalized) {\n throw new Error('alias 名称不能为空且不能包含空白字符');\n }\n\n const filePath = getGlobalConfigPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n throw new Error(`未找到 alias 配置文件:${filePath}`);\n }\n\n const content = await fs.readFile(filePath, 'utf8');\n const entries = parseAliasEntries(content);\n const entry = entries.find(item => item.name === normalized);\n if (!entry) {\n throw new Error(`未找到 alias:${normalized}`);\n }\n\n const aliasTokens = normalizeAliasCommandArgs(splitCommandArgs(entry.command));\n const additionTokens = extractAliasRunArgs(effectiveArgv, normalized);\n const mergedTokens = mergeAliasCommandArgs(aliasTokens, additionTokens);\n if (mergedTokens.length === 0) {\n throw new Error('alias 命令不能为空');\n }\n\n const nextArgv = [process.argv[0], process.argv[1], 'run', ...mergedTokens];\n const originalArgv = process.argv;\n process.argv = nextArgv;\n try {\n await runCli(nextArgv);\n } finally {\n process.argv = originalArgv;\n }\n });\n\n aliasCommand.action(async () => {\n await runAliasViewer();\n });\n\n await program.parseAsync(effectiveArgv);\n}\n\nif (require.main === module) {\n runCli(process.argv).catch(error => {\n const message = error instanceof Error ? error.stack ?? error.message : String(error);\n defaultLogger.error(message);\n process.exitCode = 1;\n });\n}\n","import path from 'node:path';\nimport { AiCliConfig, LoopConfig, PrConfig, TestConfig, WebhookConfig, WorktreeConfig, WorkflowFiles } from './types';\nimport { resolvePath } from './utils';\n\n/**\n * CLI 参数解析后的配置。\n */\nexport interface CliOptions {\n readonly task: string;\n readonly iterations: number;\n readonly aiCli: string;\n readonly aiArgs: string[];\n readonly aiPromptArg?: string;\n readonly notesFile: string;\n readonly planFile: string;\n readonly workflowDoc: string;\n readonly useWorktree: boolean;\n readonly branch?: string;\n readonly worktreePath?: string;\n readonly baseBranch: string;\n readonly runTests: boolean;\n readonly runE2e: boolean;\n readonly unitCommand?: string;\n readonly e2eCommand?: string;\n readonly autoCommit: boolean;\n readonly autoPush: boolean;\n readonly pr: boolean;\n readonly prTitle?: string;\n readonly prBody?: string;\n readonly draft: boolean;\n readonly reviewers?: string[];\n readonly autoMerge: boolean;\n readonly webhookUrls: string[];\n readonly webhookTimeout?: number;\n readonly stopSignal: string;\n readonly logFile?: string;\n readonly verbose: boolean;\n readonly skipInstall: boolean;\n readonly skipQuality: boolean;\n}\n\nfunction buildAiConfig(options: CliOptions): AiCliConfig {\n return {\n command: options.aiCli,\n args: options.aiArgs,\n promptArg: options.aiPromptArg\n };\n}\n\nfunction buildWorktreeConfig(options: CliOptions): WorktreeConfig {\n return {\n useWorktree: options.useWorktree,\n branchName: options.branch,\n worktreePath: options.worktreePath,\n baseBranch: options.baseBranch\n };\n}\n\nfunction buildTestConfig(options: CliOptions): TestConfig {\n return {\n unitCommand: options.unitCommand,\n e2eCommand: options.e2eCommand\n };\n}\n\nfunction buildPrConfig(options: CliOptions): PrConfig {\n return {\n enable: options.pr,\n title: options.prTitle,\n bodyPath: options.prBody,\n draft: options.draft,\n reviewers: options.reviewers,\n autoMerge: options.autoMerge\n };\n}\n\nfunction buildWebhookConfig(options: CliOptions): WebhookConfig | undefined {\n if (!options.webhookUrls || options.webhookUrls.length === 0) return undefined;\n return {\n urls: options.webhookUrls,\n timeoutMs: options.webhookTimeout\n };\n}\n\nfunction buildWorkflowFiles(options: CliOptions, cwd: string): WorkflowFiles {\n return {\n workflowDoc: resolvePath(cwd, options.workflowDoc),\n notesFile: resolvePath(cwd, options.notesFile),\n planFile: resolvePath(cwd, options.planFile)\n };\n}\n\n/**\n * 构建循环执行所需的配置对象。\n */\nexport function buildLoopConfig(options: CliOptions, cwd: string): LoopConfig {\n return {\n task: options.task,\n iterations: options.iterations,\n stopSignal: options.stopSignal,\n ai: buildAiConfig(options),\n workflowFiles: buildWorkflowFiles(options, cwd),\n git: buildWorktreeConfig(options),\n tests: buildTestConfig(options),\n pr: buildPrConfig(options),\n webhooks: buildWebhookConfig(options),\n cwd,\n logFile: options.logFile ? resolvePath(cwd, options.logFile) : undefined,\n verbose: options.verbose,\n runTests: options.runTests,\n runE2e: options.runE2e,\n autoCommit: options.autoCommit,\n autoPush: options.autoPush,\n skipInstall: options.skipInstall,\n skipQuality: options.skipQuality\n };\n}\n\n/**\n * 默认 notes 文件路径。\n */\nexport function defaultNotesPath(): string {\n return path.join('memory', 'notes.md');\n}\n\n/**\n * 默认 plan 文件路径。\n */\nexport function defaultPlanPath(): string {\n return path.join('memory', 'plan.md');\n}\n\n/**\n * 默认工作流说明文件路径。\n */\nexport function defaultWorkflowDoc(): string {\n return path.join('docs', 'ai-workflow.md');\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { CommandOptions, CommandResult } from './types';\n\ntype ExecaModule = typeof import('execa');\ntype ExecaError = import('execa').ExecaError;\n\nconst importExeca = async (): Promise<ExecaModule> => {\n // 通过运行时动态 import 兼容 CommonJS 下加载 ESM 包\n const importer = new Function('specifier', 'return import(specifier)') as (specifier: string) => Promise<ExecaModule>;\n return importer('execa');\n};\n\n/**\n * 执行外部命令,支持日志与流式输出。\n */\nexport async function runCommand(command: string, args: string[], options: CommandOptions = {}): Promise<CommandResult> {\n const label = options.verboseLabel ?? 'cmd';\n const displayCmd = options.verboseCommand ?? [command, ...args].join(' ');\n const cwd = options.cwd ?? process.cwd();\n options.logger?.debug(`[${label}] ${displayCmd} (cwd: ${cwd})`);\n\n const logger = options.logger;\n const streamEnabled = Boolean(options.stream?.enabled && logger);\n const stdoutPrefix = options.stream?.stdoutPrefix ?? `[${label}] `;\n const stderrPrefix = options.stream?.stderrPrefix ?? `[${label} stderr] `;\n\n const createLineStreamer = (prefix: string) => {\n let buffer = '';\n const emit = (line: string): void => {\n logger?.info(`${prefix}${line}`);\n };\n const push = (chunk: string | Buffer): void => {\n const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');\n buffer += text.replace(/\\r/g, '\\n');\n const parts = buffer.split('\\n');\n buffer = parts.pop() ?? '';\n parts.forEach(emit);\n };\n const flush = (): void => {\n if (buffer.length === 0) return;\n emit(buffer);\n buffer = '';\n };\n return { push, flush };\n };\n\n const attachStream = (stream: NodeJS.ReadableStream | null | undefined, streamer: ReturnType<typeof createLineStreamer>): void => {\n if (!stream) return;\n if (typeof stream.setEncoding === 'function') {\n stream.setEncoding('utf8');\n }\n stream.on('data', streamer.push);\n stream.on('end', streamer.flush);\n };\n\n const stdoutStreamer = streamEnabled ? createLineStreamer(stdoutPrefix) : null;\n const stderrStreamer = streamEnabled ? createLineStreamer(stderrPrefix) : null;\n\n try {\n const { execa } = await importExeca();\n const subprocess = execa(command, args, {\n cwd: options.cwd,\n env: options.env,\n input: options.input,\n all: false\n });\n if (stdoutStreamer) {\n attachStream(subprocess.stdout, stdoutStreamer);\n }\n if (stderrStreamer) {\n attachStream(subprocess.stderr, stderrStreamer);\n }\n const result = await subprocess;\n stdoutStreamer?.flush();\n stderrStreamer?.flush();\n const commandResult: CommandResult = {\n stdout: String(result.stdout ?? ''),\n stderr: String(result.stderr ?? ''),\n exitCode: result.exitCode ?? 0\n };\n if (logger) {\n const stdout = commandResult.stdout.trim();\n const stderr = commandResult.stderr.trim();\n if (stdout.length > 0) {\n logger.debug(`[${label}] stdout: ${stdout}`);\n }\n if (stderr.length > 0) {\n logger.debug(`[${label}] stderr: ${stderr}`);\n }\n logger.debug(`[${label}] exit ${commandResult.exitCode}`);\n }\n return commandResult;\n } catch (error) {\n const execaError = error as ExecaError;\n stdoutStreamer?.flush();\n stderrStreamer?.flush();\n const commandResult: CommandResult = {\n stdout: String(execaError.stdout ?? ''),\n stderr: String(execaError.stderr ?? String(error)),\n exitCode: execaError.exitCode ?? 1\n };\n if (logger) {\n const stdout = commandResult.stdout.trim();\n const stderr = commandResult.stderr.trim();\n if (stdout.length > 0) {\n logger.debug(`[${label}] stdout: ${stdout}`);\n }\n if (stderr.length > 0) {\n logger.debug(`[${label}] stderr: ${stderr}`);\n }\n logger.debug(`[${label}] exit ${commandResult.exitCode}`);\n }\n return commandResult;\n }\n}\n\n/**\n * 返回 ISO 格式时间戳。\n */\nexport function isoNow(): string {\n return new Date().toISOString();\n}\n\n/**\n * 基于 cwd 解析相对路径。\n */\nexport function resolvePath(cwd: string, target: string): string {\n return path.isAbsolute(target) ? target : path.join(cwd, target);\n}\n\n/**\n * 确保目录存在。\n */\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.mkdirp(dirPath);\n}\n\n/**\n * 确保文件存在(必要时创建)。\n */\nexport async function ensureFile(filePath: string, initialContent = ''): Promise<void> {\n await ensureDir(path.dirname(filePath));\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n await fs.writeFile(filePath, initialContent, 'utf8');\n }\n}\n\n/**\n * 向文件末尾追加一段内容(包含换行)。\n */\nexport async function appendSection(filePath: string, content: string): Promise<void> {\n await ensureDir(path.dirname(filePath));\n await fs.appendFile(filePath, `\\n${content}\\n`, 'utf8');\n}\n\n/**\n * 安全读取文件内容,若不存在则返回空字符串。\n */\nexport async function readFileSafe(filePath: string): Promise<string> {\n const exists = await fs.pathExists(filePath);\n if (!exists) return '';\n return fs.readFile(filePath, 'utf8');\n}\n\n/**\n * 格式化 Markdown 标题。\n */\nexport function formatHeading(title: string): string {\n return `## ${title}\\n`;\n}\n\n/**\n * 补齐两位数字字符串。\n */\nexport function pad2(value: number): string {\n return String(value).padStart(2, '0');\n}\n","import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport type { Logger } from './logger';\n\n/**\n * 全局快捷指令配置。\n */\nexport interface ShortcutConfig {\n readonly name: string;\n readonly command: string;\n}\n\n/**\n * 全局 alias 配置条目。\n */\nexport interface AliasEntry {\n readonly name: string;\n readonly command: string;\n readonly source: 'alias' | 'shortcut';\n}\n\n/**\n * 全局配置结构。\n */\nexport interface GlobalConfig {\n readonly shortcut?: ShortcutConfig;\n}\n\n/**\n * 获取全局配置文件路径。\n */\nexport function getGlobalConfigPath(): string {\n return path.join(os.homedir(), '.wheel-ai', 'config.toml');\n}\n\nfunction stripTomlComment(line: string): string {\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n for (let i = 0; i < line.length; i += 1) {\n const char = line[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n if (char === '#' || char === ';') {\n return line.slice(0, i);\n }\n }\n return line;\n}\n\nfunction findUnquotedIndex(text: string, target: string): number {\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n for (let i = 0; i < text.length; i += 1) {\n const char = text[i];\n if (escaped) {\n escaped = false;\n continue;\n }\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n }\n continue;\n }\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n if (char === target) {\n return i;\n }\n }\n return -1;\n}\n\nfunction parseTomlString(raw: string): string | null {\n const value = raw.trim();\n if (value.length < 2) return null;\n const quote = value[0];\n if (quote !== '\"' && quote !== '\\'') return null;\n let result = '';\n let escaped = false;\n for (let i = 1; i < value.length; i += 1) {\n const char = value[i];\n if (quote === '\"') {\n if (escaped) {\n switch (char) {\n case 'n':\n result += '\\n';\n break;\n case 't':\n result += '\\t';\n break;\n case 'r':\n result += '\\r';\n break;\n case '\"':\n case '\\\\':\n result += char;\n break;\n default:\n result += char;\n break;\n }\n escaped = false;\n continue;\n }\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n const rest = value.slice(i + 1).trim();\n if (rest.length > 0) return null;\n return result;\n }\n result += char;\n continue;\n }\n\n if (char === quote) {\n const rest = value.slice(i + 1).trim();\n if (rest.length > 0) return null;\n return result;\n }\n result += char;\n }\n return null;\n}\n\nfunction parseTomlKeyValue(line: string): { key: string; value: string } | null {\n const equalIndex = findUnquotedIndex(line, '=');\n if (equalIndex <= 0) return null;\n\n const key = line.slice(0, equalIndex).trim();\n const valuePart = line.slice(equalIndex + 1).trim();\n if (!key || !valuePart) return null;\n\n const parsedValue = parseTomlString(valuePart);\n if (parsedValue === null) return null;\n\n return { key, value: parsedValue };\n}\n\nfunction normalizeShortcutName(name: string): string | null {\n const trimmed = name.trim();\n if (!trimmed) return null;\n if (/\\s/.test(trimmed)) return null;\n return trimmed;\n}\n\n/**\n * 规范化 alias 名称。\n */\nexport function normalizeAliasName(name: string): string | null {\n return normalizeShortcutName(name);\n}\n\nfunction formatTomlString(value: string): string {\n const escaped = value\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n return `\"${escaped}\"`;\n}\n\n/**\n * 更新 alias 配置内容,返回新文本。\n */\nexport function updateAliasContent(content: string, name: string, command: string): string {\n const lines = content.split(/\\r?\\n/);\n const entryLine = `${name} = ${formatTomlString(command)}`;\n let currentSection: string | null = null;\n let aliasStart = -1;\n let aliasEnd = lines.length;\n\n for (let i = 0; i < lines.length; i += 1) {\n const match = /^\\s*\\[(.+?)\\]\\s*$/.exec(lines[i]);\n if (!match) continue;\n if (currentSection === 'alias' && aliasStart >= 0 && aliasEnd === lines.length) {\n aliasEnd = i;\n }\n currentSection = match[1].trim();\n if (currentSection === 'alias') {\n aliasStart = i;\n }\n }\n\n if (aliasStart < 0) {\n const trimmed = content.trimEnd();\n const prefix = trimmed.length > 0 ? `${trimmed}\\n\\n` : '';\n return `${prefix}[alias]\\n${entryLine}\\n`;\n }\n\n let replaced = false;\n for (let i = aliasStart + 1; i < aliasEnd; i += 1) {\n const parsed = parseTomlKeyValue(stripTomlComment(lines[i]).trim());\n if (!parsed) continue;\n if (parsed.key === name) {\n lines[i] = entryLine;\n replaced = true;\n break;\n }\n }\n\n if (!replaced) {\n lines.splice(aliasEnd, 0, entryLine);\n }\n\n const output = lines.join('\\n');\n return output.endsWith('\\n') ? output : `${output}\\n`;\n}\n\n/**\n * 写入或更新 alias 配置。\n */\nexport async function upsertAliasEntry(name: string, command: string, filePath: string = getGlobalConfigPath()): Promise<void> {\n const exists = await fs.pathExists(filePath);\n const content = exists ? await fs.readFile(filePath, 'utf8') : '';\n const nextContent = updateAliasContent(content, name, command);\n await fs.mkdirp(path.dirname(filePath));\n await fs.writeFile(filePath, nextContent, 'utf8');\n}\n\n/**\n * 解析全局 TOML 配置文本。\n */\nexport function parseGlobalConfig(content: string): GlobalConfig {\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n const shortcut: Record<string, string> = {};\n\n for (const rawLine of lines) {\n const line = stripTomlComment(rawLine).trim();\n if (!line) continue;\n\n const sectionMatch = /^\\[(.+)\\]$/.exec(line);\n if (sectionMatch) {\n currentSection = sectionMatch[1].trim();\n continue;\n }\n\n if (currentSection !== 'shortcut') continue;\n const parsed = parseTomlKeyValue(line);\n if (!parsed) continue;\n\n shortcut[parsed.key] = parsed.value;\n }\n\n const name = normalizeShortcutName(shortcut.name ?? '');\n const command = (shortcut.command ?? '').trim();\n if (!name || !command) {\n return {};\n }\n\n return {\n shortcut: {\n name,\n command\n }\n };\n}\n\n/**\n * 解析 alias 配置条目(含 shortcut 作为补充来源)。\n */\nexport function parseAliasEntries(content: string): AliasEntry[] {\n const lines = content.split(/\\r?\\n/);\n let currentSection: string | null = null;\n const entries: AliasEntry[] = [];\n const names = new Set<string>();\n\n for (const rawLine of lines) {\n const line = stripTomlComment(rawLine).trim();\n if (!line) continue;\n\n const sectionMatch = /^\\[(.+)\\]$/.exec(line);\n if (sectionMatch) {\n currentSection = sectionMatch[1].trim();\n continue;\n }\n\n if (currentSection !== 'alias') continue;\n const parsed = parseTomlKeyValue(line);\n if (!parsed) continue;\n\n const name = normalizeShortcutName(parsed.key);\n const command = parsed.value.trim();\n if (!name || !command) continue;\n if (names.has(name)) continue;\n\n names.add(name);\n entries.push({\n name,\n command,\n source: 'alias'\n });\n }\n\n const shortcut = parseGlobalConfig(content).shortcut;\n if (shortcut && !names.has(shortcut.name)) {\n entries.push({\n name: shortcut.name,\n command: shortcut.command,\n source: 'shortcut'\n });\n }\n\n return entries;\n}\n\n/**\n * 读取用户目录下的全局配置。\n */\nexport async function loadGlobalConfig(logger?: Logger): Promise<GlobalConfig | null> {\n const filePath = getGlobalConfigPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) return null;\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n return parseGlobalConfig(content);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`读取全局配置失败,已忽略:${message}`);\n return null;\n }\n}\n\n/**\n * 将命令行字符串拆解为参数数组(支持引号与转义)。\n */\nexport function splitCommandArgs(command: string): string[] {\n const args: string[] = [];\n let current = '';\n let quote: '\"' | '\\'' | null = null;\n let escaped = false;\n\n for (let i = 0; i < command.length; i += 1) {\n const char = command[i];\n if (escaped) {\n current += char;\n escaped = false;\n continue;\n }\n\n if (quote) {\n if (quote === '\"' && char === '\\\\') {\n escaped = true;\n continue;\n }\n if (char === quote) {\n quote = null;\n continue;\n }\n current += char;\n continue;\n }\n\n if (char === '\"' || char === '\\'') {\n quote = char;\n continue;\n }\n\n if (/\\s/.test(char)) {\n if (current.length > 0) {\n args.push(current);\n current = '';\n }\n continue;\n }\n\n if (char === '\\\\') {\n escaped = true;\n continue;\n }\n\n current += char;\n }\n\n if (current.length > 0) {\n args.push(current);\n }\n\n return args;\n}\n\nfunction normalizeShortcutArgs(args: string[]): string[] {\n if (args.length > 0 && args[0] === 'run') {\n return args.slice(1);\n }\n return args;\n}\n\n/**\n * 应用全局快捷指令,将别名替换为 run 子命令参数。\n */\nexport function applyShortcutArgv(argv: string[], config: GlobalConfig | null): string[] {\n if (!config?.shortcut) return argv;\n if (argv.length < 3) return argv;\n const commandIndex = 2;\n if (argv[commandIndex] !== config.shortcut.name) return argv;\n\n const shortcutArgs = normalizeShortcutArgs(splitCommandArgs(config.shortcut.command));\n return [\n ...argv.slice(0, commandIndex),\n 'run',\n ...shortcutArgs,\n ...argv.slice(commandIndex + 1)\n ];\n}\n","import path from 'node:path';\nimport { Logger } from './logger';\nimport { CommitMessage, WorktreeConfig, WorktreeResult } from './types';\nimport { runCommand, resolvePath } from './utils';\n\nasync function branchExists(branch: string, cwd: string, logger?: Logger): Promise<boolean> {\n const result = await runCommand('git', ['rev-parse', '--verify', branch], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-parse --verify ${branch}`\n });\n return result.exitCode === 0;\n}\n\nasync function resolveBaseBranch(baseBranch: string, repoRoot: string, logger: Logger): Promise<string> {\n const baseExists = await branchExists(baseBranch, repoRoot, logger);\n if (baseExists) return baseBranch;\n\n const current = await getCurrentBranch(repoRoot, logger);\n const currentExists = await branchExists(current, repoRoot, logger);\n if (currentExists) {\n logger.warn(`基线分支 ${baseBranch} 不存在,改用当前分支 ${current} 作为基线`);\n return current;\n }\n\n throw new Error(`基线分支 ${baseBranch} 不存在,且无法确定可用的当前分支`);\n}\n\n/**\n * 获取仓库根目录。\n */\nexport async function getRepoRoot(cwd: string, logger?: Logger): Promise<string> {\n const result = await runCommand('git', ['rev-parse', '--show-toplevel'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git rev-parse --show-toplevel'\n });\n if (result.exitCode !== 0) {\n throw new Error('当前目录不是 git 仓库,无法继续');\n }\n return result.stdout.trim();\n}\n\n/**\n * 获取当前分支名。\n */\nexport async function getCurrentBranch(cwd: string, logger?: Logger): Promise<string> {\n const result = await runCommand('git', ['branch', '--show-current'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git branch --show-current'\n });\n if (result.exitCode !== 0) {\n throw new Error(`无法获取当前分支: ${result.stderr}`);\n }\n return result.stdout.trim();\n}\n\nasync function getUpstreamBranch(branchName: string, cwd: string, logger?: Logger): Promise<string | null> {\n const result = await runCommand('git', ['rev-parse', '--abbrev-ref', '--symbolic-full-name', `${branchName}@{u}`], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-parse --abbrev-ref --symbolic-full-name ${branchName}@{u}`\n });\n if (result.exitCode !== 0) {\n logger?.warn(`分支 ${branchName} 没有关联的 upstream: ${result.stderr || result.stdout}`);\n return null;\n }\n return result.stdout.trim();\n}\n\nfunction defaultWorktreePath(repoRoot: string, branchName: string): string {\n return path.join(repoRoot, '..', 'worktrees', branchName);\n}\n\n/**\n * 确保目标分支存在。\n */\nexport async function ensureBranchExists(branchName: string, baseBranch: string, repoRoot: string, logger: Logger): Promise<void> {\n const exists = await branchExists(branchName, repoRoot, logger);\n if (exists) return;\n const create = await runCommand('git', ['branch', branchName, baseBranch], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git branch ${branchName} ${baseBranch}`\n });\n if (create.exitCode !== 0) {\n throw new Error(`创建分支失败: ${create.stderr}`);\n }\n logger.info(`已基于 ${baseBranch} 创建分支 ${branchName}`);\n}\n\n/**\n * 根据配置创建或复用 worktree。\n */\nexport async function ensureWorktree(config: WorktreeConfig, repoRoot: string, logger: Logger): Promise<WorktreeResult> {\n if (!config.useWorktree) {\n return { path: repoRoot, created: false };\n }\n\n const branchName = config.branchName ?? generateBranchName();\n const baseBranch = await resolveBaseBranch(config.baseBranch, repoRoot, logger);\n const worktreePath = resolvePath(repoRoot, config.worktreePath ?? defaultWorktreePath(repoRoot, branchName));\n\n await ensureBranchExists(branchName, baseBranch, repoRoot, logger);\n\n const addResult = await runCommand('git', ['worktree', 'add', worktreePath, branchName], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git worktree add ${worktreePath} ${branchName}`\n });\n if (addResult.exitCode !== 0) {\n const alreadyExists = addResult.stderr.includes('already exists') || addResult.stdout.includes('already exists');\n if (alreadyExists) {\n logger.warn(`worktree 路径已存在,跳过创建: ${worktreePath}`);\n return { path: worktreePath, created: false };\n }\n throw new Error(`创建 worktree 失败: ${addResult.stderr || addResult.stdout}`);\n }\n\n logger.success(`已在 ${worktreePath} 创建并挂载 worktree (${branchName})`);\n return { path: worktreePath, created: true };\n}\n\n/**\n * 判断 worktree 是否干净。\n */\nexport async function isWorktreeClean(cwd: string, logger?: Logger): Promise<boolean> {\n const status = await runCommand('git', ['status', '--porcelain'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git status --porcelain'\n });\n if (status.exitCode !== 0) {\n logger?.warn(`无法获取 git 状态: ${status.stderr || status.stdout}`);\n return false;\n }\n return status.stdout.trim().length === 0;\n}\n\n/**\n * 判断分支是否已推送到远端。\n */\nexport async function isBranchPushed(branchName: string, cwd: string, logger: Logger): Promise<boolean> {\n const upstream = await getUpstreamBranch(branchName, cwd, logger);\n if (!upstream) return false;\n\n const countResult = await runCommand('git', ['rev-list', '--left-right', '--count', `${upstream}...${branchName}`], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git rev-list --left-right --count ${upstream}...${branchName}`\n });\n if (countResult.exitCode !== 0) {\n logger.warn(`无法比较分支 ${branchName} 与 ${upstream}: ${countResult.stderr || countResult.stdout}`);\n return false;\n }\n\n const [behindStr, aheadStr] = countResult.stdout.trim().split(/\\s+/);\n const ahead = Number.parseInt(aheadStr ?? '0', 10);\n if (Number.isNaN(ahead)) {\n logger.warn(`无法解析分支推送状态: ${countResult.stdout}`);\n return false;\n }\n if (ahead > 0) {\n logger.warn(`分支 ${branchName} 仍有 ${ahead} 个本地提交未推送`);\n return false;\n }\n return true;\n}\n\nfunction normalizeCommitTitle(title: string): string {\n return title.replace(/\\s+/g, ' ').trim();\n}\n\nfunction normalizeCommitBody(body?: string): string | undefined {\n if (!body) return undefined;\n const normalized = body.replace(/\\r\\n?/g, '\\n').trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction formatCommitCommand(message: CommitMessage): string {\n const title = normalizeCommitTitle(message.title) || 'chore: 更新迭代产出';\n const parts = ['git commit -m', JSON.stringify(title)];\n const body = normalizeCommitBody(message.body);\n if (body) {\n parts.push('-m', JSON.stringify(body));\n }\n return parts.join(' ');\n}\n\nfunction buildCommitArgs(message: CommitMessage): string[] {\n const title = normalizeCommitTitle(message.title) || 'chore: 更新迭代产出';\n const args = ['commit', '-m', title];\n const body = normalizeCommitBody(message.body);\n if (body) {\n args.push('-m', body);\n }\n return args;\n}\n\n/**\n * 提交当前变更。\n */\nexport async function commitAll(message: CommitMessage, cwd: string, logger: Logger): Promise<boolean> {\n const add = await runCommand('git', ['add', '-A'], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git add -A'\n });\n if (add.exitCode !== 0) {\n throw new Error(`git add 失败: ${add.stderr}`);\n }\n const commit = await runCommand('git', buildCommitArgs(message), {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: formatCommitCommand(message)\n });\n if (commit.exitCode !== 0) {\n logger.warn(`git commit 跳过或失败: ${commit.stderr}`);\n return false;\n }\n logger.success('已提交当前变更');\n return true;\n}\n\n/**\n * 推送分支到远端。\n */\nexport async function pushBranch(branchName: string, cwd: string, logger: Logger): Promise<void> {\n const push = await runCommand('git', ['push', '-u', 'origin', branchName], {\n cwd,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git push -u origin ${branchName}`\n });\n if (push.exitCode !== 0) {\n throw new Error(`git push 失败: ${push.stderr}`);\n }\n logger.success(`已推送分支 ${branchName}`);\n}\n\n/**\n * 删除 worktree 并清理。\n */\nexport async function removeWorktree(worktreePath: string, repoRoot: string, logger: Logger): Promise<void> {\n const remove = await runCommand('git', ['worktree', 'remove', '--force', worktreePath], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: `git worktree remove --force ${worktreePath}`\n });\n if (remove.exitCode !== 0) {\n throw new Error(`删除 worktree 失败: ${remove.stderr || remove.stdout}`);\n }\n\n const prune = await runCommand('git', ['worktree', 'prune'], {\n cwd: repoRoot,\n logger,\n verboseLabel: 'git',\n verboseCommand: 'git worktree prune'\n });\n if (prune.exitCode !== 0) {\n logger.warn(`worktree prune 失败: ${prune.stderr || prune.stdout}`);\n }\n\n logger.success(`已删除 worktree: ${worktreePath}`);\n}\n\n/**\n * 生成默认分支名。\n */\nexport function generateBranchName(): string {\n const now = new Date();\n const stamp = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}-${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;\n return `wheel-ai/${stamp}`;\n}\n\nfunction guessBranchType(task: string): string {\n const text = task.toLowerCase();\n if (/fix|bug|修复|错误|异常|问题/.test(text)) return 'fix';\n if (/docs|readme|changelog|文档/.test(text)) return 'docs';\n if (/test|e2e|单测|测试/.test(text)) return 'test';\n if (/refactor|重构/.test(text)) return 'refactor';\n if (/chore|构建|依赖|配置/.test(text)) return 'chore';\n return 'feat';\n}\n\nfunction slugifyTask(task: string): string {\n const slug = task\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n return slug.slice(0, 40);\n}\n\nfunction buildTimestampSlug(now: Date): string {\n const stamp = `${now.getFullYear()}${(now.getMonth() + 1).toString().padStart(2, '0')}${now.getDate().toString().padStart(2, '0')}-${now.getHours().toString().padStart(2, '0')}${now.getMinutes().toString().padStart(2, '0')}`;\n return `auto-${stamp}`;\n}\n\n/**\n * 基于任务生成分支名(AI 失败时兜底)。\n */\nexport function generateBranchNameFromTask(task: string, now: Date = new Date()): string {\n const slug = slugifyTask(task);\n const type = guessBranchType(task);\n const suffix = slug || buildTimestampSlug(now);\n return `${type}/${suffix}`;\n}\n","import os from 'node:os';\nimport path from 'node:path';\nimport fs from 'fs-extra';\nimport { pad2 } from './utils';\n\nexport interface RunMetadata {\n readonly command: string;\n readonly round: number;\n readonly tokenUsed: number;\n readonly path: string;\n readonly pid?: number;\n}\n\nexport interface CurrentRegistryEntry extends RunMetadata {\n readonly logFile?: string;\n}\n\nexport type CurrentRegistry = Record<string, CurrentRegistryEntry>;\n\nconst LOGS_DIR = path.join(os.homedir(), '.wheel-ai', 'logs');\n\nexport function getLogsDir(): string {\n return LOGS_DIR;\n}\n\nexport function getCurrentRegistryPath(): string {\n return path.join(LOGS_DIR, 'current.json');\n}\n\nexport async function ensureLogsDir(): Promise<void> {\n await fs.mkdirp(LOGS_DIR);\n}\n\n/**\n * 生成时间字符串(YYYYMMDDHHmmss)。\n */\nexport function formatTimeString(date: Date = new Date()): string {\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}${month}${day}${hours}${minutes}${seconds}`;\n}\n\n/**\n * 清理分支名中的非法字符。\n */\nexport function sanitizeBranchName(branchName: string): string {\n const normalized = branchName.trim();\n if (!normalized) return '';\n const replaced = normalized.replace(/[\\\\/:*?\"<>|\\s]+/g, '-');\n return replaced.replace(/-+/g, '-').replace(/^-+|-+$/g, '');\n}\n\nexport function buildAutoLogFilePath(branchName: string, date: Date = new Date()): string {\n const safeBranch = sanitizeBranchName(branchName) || 'unknown';\n return path.join(LOGS_DIR, `wheel-ai-auto-log-${formatTimeString(date)}-${safeBranch}.log`);\n}\n\nexport function getLogMetaPath(logFile: string): string {\n const baseName = path.basename(logFile, path.extname(logFile));\n return path.join(LOGS_DIR, `${baseName}.json`);\n}\n\nfunction buildLogKey(logFile: string): string {\n return path.basename(logFile);\n}\n\n/**\n * 格式化命令行字符串(用于写入元信息)。\n */\nexport function formatCommandLine(argv: string[]): string {\n const quote = (value: string): string => {\n if (/[\\s\"'\\\\]/.test(value)) {\n return JSON.stringify(value);\n }\n return value;\n };\n return argv.map(quote).join(' ').trim();\n}\n\nasync function writeJsonFile(filePath: string, data: unknown): Promise<void> {\n await ensureLogsDir();\n await fs.writeFile(filePath, `${JSON.stringify(data, null, 2)}\\n`, 'utf8');\n}\n\n/**\n * 写入单次运行的元信息。\n */\nexport async function writeRunMetadata(logFile: string, metadata: RunMetadata): Promise<void> {\n const metaPath = getLogMetaPath(logFile);\n await writeJsonFile(metaPath, metadata);\n}\n\n/**\n * 读取 current.json 注册表。\n */\nexport async function readCurrentRegistry(): Promise<CurrentRegistry> {\n const filePath = getCurrentRegistryPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) return {};\n try {\n const content = await fs.readFile(filePath, 'utf8');\n const parsed = JSON.parse(content) as CurrentRegistry;\n if (!parsed || typeof parsed !== 'object') return {};\n return parsed;\n } catch {\n return {};\n }\n}\n\n/**\n * 更新 current.json 中的运行记录。\n */\nexport async function upsertCurrentRegistry(logFile: string, metadata: RunMetadata): Promise<void> {\n const registry = await readCurrentRegistry();\n const key = buildLogKey(logFile);\n registry[key] = { ...metadata, logFile };\n await writeJsonFile(getCurrentRegistryPath(), registry);\n}\n\n/**\n * 从 current.json 中移除运行记录。\n */\nexport async function removeCurrentRegistry(logFile: string): Promise<void> {\n const registry = await readCurrentRegistry();\n const key = buildLogKey(logFile);\n if (!(key in registry)) return;\n delete registry[key];\n await writeJsonFile(getCurrentRegistryPath(), registry);\n}\n","import fs from 'fs-extra';\nimport { AliasEntry, getGlobalConfigPath, parseAliasEntries } from './global-config';\n\ninterface AliasViewerState {\n aliases: AliasEntry[];\n selectedIndex: number;\n listOffset: number;\n missingConfig: boolean;\n lastError?: string;\n}\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nfunction buildAliasLabel(entry: AliasEntry): string {\n if (entry.source === 'shortcut') {\n return `${entry.name}(shortcut)`;\n }\n return entry.name;\n}\n\nfunction buildHeader(state: AliasViewerState, columns: number): string {\n const total = state.aliases.length;\n const title = `别名列表(${total} 条)|↑/↓ 选择 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildStatus(state: AliasViewerState, columns: number): string {\n if (state.aliases.length === 0) {\n if (state.lastError) {\n return truncateLine(`读取失败:${state.lastError}`, columns);\n }\n if (state.missingConfig) {\n return truncateLine(`未找到配置文件:${getGlobalConfigPath()}`, columns);\n }\n return truncateLine('未发现 alias 配置', columns);\n }\n\n const entry = state.aliases[state.selectedIndex];\n const sourceText = entry.source === 'shortcut' ? '(shortcut)' : '';\n return truncateLine(`命令${sourceText}:${entry.command}`, columns);\n}\n\nfunction buildListLine(entry: AliasEntry, selected: boolean, columns: number): string {\n const marker = selected ? '>' : ' ';\n return truncateLine(`${marker} ${buildAliasLabel(entry)}`, columns);\n}\n\nfunction ensureListOffset(state: AliasViewerState, pageSize: number): void {\n const total = state.aliases.length;\n if (total === 0) {\n state.listOffset = 0;\n state.selectedIndex = 0;\n return;\n }\n const maxOffset = Math.max(0, total - pageSize);\n if (state.selectedIndex < state.listOffset) {\n state.listOffset = state.selectedIndex;\n }\n if (state.selectedIndex >= state.listOffset + pageSize) {\n state.listOffset = state.selectedIndex - pageSize + 1;\n }\n state.listOffset = Math.min(Math.max(state.listOffset, 0), maxOffset);\n}\n\nfunction render(state: AliasViewerState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildHeader(state, columns);\n ensureListOffset(state, pageSize);\n\n if (state.aliases.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const status = buildStatus(state, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const start = state.listOffset;\n const slice = state.aliases.slice(start, start + pageSize);\n const lines = slice.map((entry, index) => {\n const selected = start + index === state.selectedIndex;\n return buildListLine(entry, selected, columns);\n });\n while (lines.length < pageSize) {\n lines.push('');\n }\n const status = buildStatus(state, columns);\n const content = [header, ...lines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction isArrowUp(input: string): boolean {\n return input.includes('\\u001b[A');\n}\n\nfunction isArrowDown(input: string): boolean {\n return input.includes('\\u001b[B');\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\nfunction clampIndex(value: number, total: number): number {\n if (total <= 0) return 0;\n return Math.min(Math.max(value, 0), total - 1);\n}\n\n/**\n * 启动 alias 浏览界面。\n */\nexport async function runAliasViewer(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 alias。');\n return;\n }\n\n const state: AliasViewerState = {\n aliases: [],\n selectedIndex: 0,\n listOffset: 0,\n missingConfig: false\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n const loadAliases = async (): Promise<void> => {\n const filePath = getGlobalConfigPath();\n const exists = await fs.pathExists(filePath);\n if (!exists) {\n state.aliases = [];\n state.selectedIndex = 0;\n state.lastError = undefined;\n state.missingConfig = true;\n return;\n }\n\n try {\n const content = await fs.readFile(filePath, 'utf8');\n state.aliases = parseAliasEntries(content);\n state.selectedIndex = clampIndex(state.selectedIndex, state.aliases.length);\n state.lastError = undefined;\n state.missingConfig = false;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.aliases = [];\n state.selectedIndex = 0;\n state.lastError = message;\n state.missingConfig = false;\n }\n };\n\n await loadAliases();\n render(state);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n cleanup();\n process.exit(0);\n }\n\n if (isArrowUp(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex - 1, state.aliases.length);\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex + 1, state.aliases.length);\n render(state);\n }\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport { CurrentRegistry, RunMetadata, getLogsDir, readCurrentRegistry } from './logs';\nimport { pad2 } from './utils';\n\nexport interface LogEntry {\n readonly fileName: string;\n readonly filePath: string;\n readonly size: number;\n readonly mtimeMs: number;\n readonly meta?: RunMetadata;\n}\n\ninterface ViewState {\n entry: LogEntry;\n lines: string[];\n lineOffset: number;\n}\n\ninterface LogsViewerState {\n mode: 'list' | 'view';\n logs: LogEntry[];\n selectedIndex: number;\n listOffset: number;\n view?: ViewState;\n lastError?: string;\n}\n\nfunction isRunMetadata(value: unknown): value is RunMetadata {\n if (!value || typeof value !== 'object') return false;\n const record = value as Record<string, unknown>;\n return (\n typeof record.command === 'string' &&\n typeof record.round === 'number' &&\n typeof record.tokenUsed === 'number' &&\n typeof record.path === 'string'\n );\n}\n\nfunction buildLogMetaPath(logsDir: string, logFile: string): string {\n const baseName = path.basename(logFile, path.extname(logFile));\n return path.join(logsDir, `${baseName}.json`);\n}\n\nasync function readLogMetadata(logsDir: string, logFile: string): Promise<RunMetadata | undefined> {\n const metaPath = buildLogMetaPath(logsDir, logFile);\n const exists = await fs.pathExists(metaPath);\n if (!exists) return undefined;\n try {\n const content = await fs.readFile(metaPath, 'utf8');\n const parsed = JSON.parse(content) as unknown;\n return isRunMetadata(parsed) ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nexport function buildRunningLogKeys(registry: CurrentRegistry): Set<string> {\n const keys = new Set<string>();\n for (const [key, entry] of Object.entries(registry)) {\n keys.add(key);\n if (entry.logFile) {\n keys.add(path.basename(entry.logFile));\n }\n }\n return keys;\n}\n\nexport async function loadLogEntries(logsDir: string, registry: CurrentRegistry): Promise<LogEntry[]> {\n const exists = await fs.pathExists(logsDir);\n if (!exists) return [];\n const running = buildRunningLogKeys(registry);\n const names = await fs.readdir(logsDir);\n const entries: LogEntry[] = [];\n for (const name of names) {\n if (path.extname(name).toLowerCase() !== '.log') continue;\n if (running.has(name)) continue;\n const filePath = path.join(logsDir, name);\n let stat: fs.Stats;\n try {\n stat = await fs.stat(filePath);\n } catch {\n continue;\n }\n if (!stat.isFile()) continue;\n const meta = await readLogMetadata(logsDir, filePath);\n entries.push({\n fileName: name,\n filePath,\n size: stat.size,\n mtimeMs: stat.mtimeMs,\n meta\n });\n }\n return entries.sort((a, b) => b.mtimeMs - a.mtimeMs);\n}\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction formatTimestamp(ms: number): string {\n const date = new Date(ms);\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n}\n\nfunction formatBytes(size: number): string {\n if (size < 1024) return `${size}B`;\n const kb = size / 1024;\n if (kb < 1024) return `${kb.toFixed(1)}KB`;\n const mb = kb / 1024;\n return `${mb.toFixed(1)}MB`;\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nasync function readLogLines(logFile: string): Promise<string[]> {\n try {\n const content = await fs.readFile(logFile, 'utf8');\n const normalized = content.replace(/\\r\\n?/g, '\\n');\n const lines = normalized.split('\\n');\n return lines.length > 0 ? lines : [''];\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`(无法读取日志文件:${message})`];\n }\n}\n\nfunction buildListHeader(state: LogsViewerState, columns: number): string {\n const total = state.logs.length;\n const title = `日志列表(${total} 条)|↑/↓ 选择 Enter 查看 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildListStatus(state: LogsViewerState, columns: number): string {\n if (state.logs.length === 0) {\n const text = state.lastError ? `加载失败:${state.lastError}` : '暂无可查看的日志';\n return truncateLine(text, columns);\n }\n const entry = state.logs[state.selectedIndex];\n const meta = entry.meta;\n const detail = meta ? `项目 ${meta.path}` : `文件 ${entry.fileName}`;\n const suffix = state.lastError ? ` | 加载失败:${state.lastError}` : '';\n return truncateLine(`${detail}${suffix}`, columns);\n}\n\nfunction buildListLine(entry: LogEntry, selected: boolean, columns: number): string {\n const marker = selected ? '>' : ' ';\n const time = formatTimestamp(entry.mtimeMs);\n const metaInfo = entry.meta\n ? `轮次 ${entry.meta.round} | Token ${entry.meta.tokenUsed}`\n : `大小 ${formatBytes(entry.size)}`;\n return truncateLine(`${marker} ${entry.fileName} | ${time} | ${metaInfo}`, columns);\n}\n\nfunction buildViewHeader(entry: LogEntry, columns: number): string {\n const title = `日志查看|${entry.fileName}|↑/↓ 上下 1 行 PageUp/PageDown 翻页 b 返回 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildViewStatus(entry: LogEntry, page: { current: number; total: number }, columns: number): string {\n const meta = entry.meta;\n const metaInfo = meta\n ? `轮次 ${meta.round} | Token ${meta.tokenUsed} | 项目 ${meta.path}`\n : `文件 ${entry.fileName}`;\n const status = `页 ${page.current}/${page.total} | ${metaInfo}`;\n return truncateLine(status, columns);\n}\n\nfunction ensureListOffset(state: LogsViewerState, pageSize: number): void {\n const total = state.logs.length;\n if (total === 0) {\n state.listOffset = 0;\n state.selectedIndex = 0;\n return;\n }\n const maxOffset = Math.max(0, total - pageSize);\n if (state.selectedIndex < state.listOffset) {\n state.listOffset = state.selectedIndex;\n }\n if (state.selectedIndex >= state.listOffset + pageSize) {\n state.listOffset = state.selectedIndex - pageSize + 1;\n }\n state.listOffset = Math.min(Math.max(state.listOffset, 0), maxOffset);\n}\n\nfunction renderList(state: LogsViewerState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildListHeader(state, columns);\n ensureListOffset(state, pageSize);\n\n if (state.logs.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const status = buildListStatus(state, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const start = state.listOffset;\n const slice = state.logs.slice(start, start + pageSize);\n const lines = slice.map((entry, index) => {\n const selected = start + index === state.selectedIndex;\n return buildListLine(entry, selected, columns);\n });\n while (lines.length < pageSize) {\n lines.push('');\n }\n const status = buildListStatus(state, columns);\n const content = [header, ...lines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction renderView(view: ViewState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildViewHeader(view.entry, columns);\n const maxOffset = Math.max(0, view.lines.length - pageSize);\n view.lineOffset = Math.min(Math.max(view.lineOffset, 0), maxOffset);\n\n const start = view.lineOffset;\n const pageLines = view.lines.slice(start, start + pageSize).map(line => truncateLine(line, columns));\n while (pageLines.length < pageSize) {\n pageLines.push('');\n }\n\n const totalPages = Math.max(1, Math.ceil(view.lines.length / pageSize));\n const currentPage = Math.min(totalPages, Math.floor(view.lineOffset / pageSize) + 1);\n const status = buildViewStatus(view.entry, { current: currentPage, total: totalPages }, columns);\n const content = [header, ...pageLines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction render(state: LogsViewerState): void {\n if (state.mode === 'view' && state.view) {\n renderView(state.view);\n return;\n }\n renderList(state);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction isEnter(input: string): boolean {\n return input.includes('\\r') || input.includes('\\n');\n}\n\nfunction isArrowUp(input: string): boolean {\n return input.includes('\\u001b[A');\n}\n\nfunction isArrowDown(input: string): boolean {\n return input.includes('\\u001b[B');\n}\n\nfunction isPageUp(input: string): boolean {\n return input.includes('\\u001b[5~');\n}\n\nfunction isPageDown(input: string): boolean {\n return input.includes('\\u001b[6~');\n}\n\nfunction isEscape(input: string): boolean {\n return input === '\\u001b';\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\nfunction clampIndex(value: number, total: number): number {\n if (total <= 0) return 0;\n return Math.min(Math.max(value, 0), total - 1);\n}\n\n/**\n * 启动日志列表查看界面。\n */\nexport async function runLogsViewer(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 logs。');\n return;\n }\n\n const logsDir = getLogsDir();\n const state: LogsViewerState = {\n mode: 'list',\n logs: [],\n selectedIndex: 0,\n listOffset: 0\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n let loading = false;\n\n const loadLogs = async (): Promise<void> => {\n try {\n const registry = await readCurrentRegistry();\n state.logs = await loadLogEntries(logsDir, registry);\n state.selectedIndex = clampIndex(state.selectedIndex, state.logs.length);\n state.lastError = undefined;\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.lastError = message;\n state.logs = [];\n state.selectedIndex = 0;\n }\n };\n\n const openView = async (): Promise<void> => {\n if (loading || state.logs.length === 0) return;\n loading = true;\n const entry = state.logs[state.selectedIndex];\n state.mode = 'view';\n state.view = {\n entry,\n lines: ['加载中…'],\n lineOffset: 0\n };\n render(state);\n const lines = await readLogLines(entry.filePath);\n const pageSize = getPageSize(getTerminalSize().rows);\n const maxOffset = Math.max(0, lines.length - pageSize);\n state.view = {\n entry,\n lines,\n lineOffset: maxOffset\n };\n loading = false;\n render(state);\n };\n\n await loadLogs();\n render(state);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n cleanup();\n process.exit(0);\n }\n\n if (state.mode === 'list') {\n if (isArrowUp(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex - 1, state.logs.length);\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.selectedIndex = clampIndex(state.selectedIndex + 1, state.logs.length);\n render(state);\n return;\n }\n if (isEnter(input)) {\n void openView();\n return;\n }\n return;\n }\n\n if (state.mode === 'view' && state.view) {\n if (isArrowUp(input)) {\n state.view.lineOffset -= 1;\n render(state);\n return;\n }\n if (isArrowDown(input)) {\n state.view.lineOffset += 1;\n render(state);\n return;\n }\n if (isPageUp(input)) {\n const pageSize = getPageSize(getTerminalSize().rows);\n state.view.lineOffset -= pageSize;\n render(state);\n return;\n }\n if (isPageDown(input)) {\n const pageSize = getPageSize(getTerminalSize().rows);\n state.view.lineOffset += pageSize;\n render(state);\n return;\n }\n if (input.toLowerCase() === 'b' || isEscape(input)) {\n state.mode = 'list';\n state.view = undefined;\n render(state);\n return;\n }\n }\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport {\n buildBranchNamePrompt,\n buildDocsPrompt,\n buildFixPrompt,\n buildPlanItemPrompt,\n buildPlanningPrompt,\n buildQualityPrompt,\n buildTestPrompt,\n formatIterationRecord,\n mergeTokenUsage,\n parseBranchName,\n runAi\n} from './ai';\nimport { ensureDependencies } from './deps';\nimport { GhPrInfo, createPr, enableAutoMerge, listFailedRuns, viewPr } from './gh';\nimport { Logger } from './logger';\nimport { commitAll, ensureWorktree, generateBranchNameFromTask, getCurrentBranch, getRepoRoot, isBranchPushed, isWorktreeClean, pushBranch, removeWorktree } from './git';\nimport { formatCommandLine } from './logs';\nimport { getPendingPlanItems } from './plan';\nimport { detectQualityCommands } from './quality';\nimport { createRunTracker } from './runtime-tracker';\nimport { buildFallbackSummary, buildSummaryPrompt, ensurePrBodySections, parseDeliverySummary } from './summary';\nimport { CheckRunResult, CommitMessage, DeliverySummary, LoopConfig, LoopResult, TestRunResult, TokenUsage, WorkflowFiles, WorktreeResult } from './types';\nimport { appendSection, ensureFile, isoNow, readFileSafe, runCommand } from './utils';\nimport { buildWebhookPayload, sendWebhookNotifications } from './webhook';\n\nasync function ensureWorkflowFiles(workflowFiles: WorkflowFiles): Promise<void> {\n await ensureFile(workflowFiles.workflowDoc, '# AI 工作流程基线\\n');\n await ensureFile(workflowFiles.planFile, '# 计划\\n');\n await ensureFile(workflowFiles.notesFile, '# 持久化记忆\\n');\n}\n\nconst MAX_LOG_LENGTH = 4000;\n\nfunction trimOutput(output: string, limit = MAX_LOG_LENGTH): string {\n if (!output) return '';\n if (output.length <= limit) return output;\n return `${output.slice(0, limit)}\\n……(输出已截断,原始长度 ${output.length} 字符)`;\n}\n\nfunction truncateText(text: string, limit = 24): string {\n const trimmed = text.trim();\n if (trimmed.length <= limit) return trimmed;\n return `${trimmed.slice(0, limit)}...`;\n}\n\nasync function safeCommandOutput(command: string, args: string[], cwd: string, logger: Logger, label: string, verboseCommand: string): Promise<string> {\n const result = await runCommand(command, args, {\n cwd,\n logger,\n verboseLabel: label,\n verboseCommand\n });\n if (result.exitCode !== 0) {\n logger.warn(`${label} 命令失败: ${result.stderr || result.stdout}`);\n return '';\n }\n return result.stdout.trim();\n}\n\nasync function runSingleTest(kind: 'unit' | 'e2e', command: string, cwd: string, logger: Logger): Promise<TestRunResult> {\n const label = kind === 'unit' ? '单元测试' : 'e2e 测试';\n logger.info(`执行${label}: ${command}`);\n const result = await runCommand('bash', ['-lc', command], {\n cwd,\n logger,\n verboseLabel: 'shell',\n verboseCommand: `bash -lc \"${command}\"`\n });\n const success = result.exitCode === 0;\n if (success) {\n logger.success(`${label}完成`);\n } else {\n logger.warn(`${label}失败(退出码 ${result.exitCode})`);\n }\n\n return {\n kind,\n command,\n success,\n exitCode: result.exitCode,\n stdout: trimOutput(result.stdout.trim()),\n stderr: trimOutput(result.stderr.trim())\n };\n}\n\nasync function runQualityChecks(commands: { name: string; command: string }[], cwd: string, logger: Logger): Promise<CheckRunResult[]> {\n const results: CheckRunResult[] = [];\n for (const item of commands) {\n logger.info(`执行质量检查: ${item.command}`);\n const result = await runCommand('bash', ['-lc', item.command], {\n cwd,\n logger,\n verboseLabel: 'shell',\n verboseCommand: `bash -lc \"${item.command}\"`\n });\n results.push({\n name: item.name,\n command: item.command,\n success: result.exitCode === 0,\n exitCode: result.exitCode,\n stdout: trimOutput(result.stdout.trim()),\n stderr: trimOutput(result.stderr.trim())\n });\n }\n return results;\n}\n\nfunction buildCheckResultSummary(results: CheckRunResult[]): string {\n if (results.length === 0) return '(未执行质量检查)';\n return results\n .map(result => {\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const output = result.success ? '' : `\\n${result.stderr || result.stdout || '(无输出)'}`;\n return `- ${result.name}: ${status}|命令: ${result.command}${output}`;\n })\n .join('\\n');\n}\n\nfunction buildFailedCheckSummary(results: CheckRunResult[]): string {\n return buildCheckResultSummary(results.filter(result => !result.success));\n}\n\nfunction buildTestResultSummary(results: TestRunResult[]): string {\n if (results.length === 0) return '(未执行测试)';\n return results\n .map(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const output = result.success ? '' : `\\n${result.stderr || result.stdout || '(无输出)'}`;\n return `- ${label}: ${status}|命令: ${result.command}${output}`;\n })\n .join('\\n');\n}\n\nfunction buildFailedTestSummary(results: TestRunResult[]): string {\n return buildTestResultSummary(results.filter(result => !result.success));\n}\n\nfunction formatSystemRecord(stage: string, detail: string, timestamp: string): string {\n return [\n `### 记录 | ${timestamp} | ${stage}`,\n '',\n detail,\n ''\n ].join('\\n');\n}\n\nfunction shouldSkipQuality(content: string, cliSkip: boolean): boolean {\n if (cliSkip) return true;\n const normalized = content.replace(/\\s+/g, '');\n if (!normalized) return false;\n return normalized.includes('不要检查代码质量')\n || normalized.includes('不检查代码质量')\n || normalized.includes('跳过代码质量');\n}\n\nasync function runTests(config: LoopConfig, workDir: string, logger: Logger): Promise<TestRunResult[]> {\n const results: TestRunResult[] = [];\n\n if (config.runTests && config.tests.unitCommand) {\n const unitResult = await runSingleTest('unit', config.tests.unitCommand, workDir, logger);\n results.push(unitResult);\n }\n\n if (config.runE2e && config.tests.e2eCommand) {\n const e2eResult = await runSingleTest('e2e', config.tests.e2eCommand, workDir, logger);\n results.push(e2eResult);\n }\n\n return results;\n}\n\nasync function runTestsSafely(config: LoopConfig, workDir: string, logger: Logger): Promise<TestRunResult[]> {\n try {\n return await runTests(config, workDir, logger);\n } catch (error) {\n const errorMessage = String(error);\n logger.warn(`测试执行异常: ${errorMessage}`);\n return [{\n kind: 'unit',\n command: config.tests.unitCommand ?? '未知测试命令',\n success: false,\n exitCode: -1,\n stdout: '',\n stderr: trimOutput(errorMessage)\n }];\n }\n}\n\nfunction reRootPath(filePath: string, repoRoot: string, workDir: string): string {\n const relative = path.relative(repoRoot, filePath);\n if (relative.startsWith('..')) return filePath;\n return path.join(workDir, relative);\n}\n\nfunction reRootWorkflowFiles(workflowFiles: WorkflowFiles, repoRoot: string, workDir: string): WorkflowFiles {\n if (repoRoot === workDir) return workflowFiles;\n return {\n workflowDoc: reRootPath(workflowFiles.workflowDoc, repoRoot, workDir),\n notesFile: reRootPath(workflowFiles.notesFile, repoRoot, workDir),\n planFile: reRootPath(workflowFiles.planFile, repoRoot, workDir)\n };\n}\n\nfunction buildBodyFile(workDir: string): string {\n return path.join(workDir, 'memory', 'pr-body.md');\n}\n\nasync function writePrBody(bodyPath: string, content: string, appendExisting: boolean): Promise<void> {\n await fs.mkdirp(path.dirname(bodyPath));\n let finalContent = content.trim();\n if (appendExisting) {\n const existing = await readFileSafe(bodyPath);\n const trimmedExisting = existing.trim();\n if (trimmedExisting.length > 0) {\n finalContent = `${trimmedExisting}\\n\\n---\\n\\n${finalContent}`;\n }\n }\n await fs.writeFile(bodyPath, `${finalContent}\\n`, 'utf8');\n}\n\ninterface WorktreeCleanupContext {\n readonly repoRoot: string;\n readonly workDir: string;\n readonly branchName?: string;\n readonly prInfo: GhPrInfo | null;\n readonly worktreeCreated: boolean;\n readonly logger: Logger;\n}\n\nasync function cleanupWorktreeIfSafe(context: WorktreeCleanupContext): Promise<void> {\n const { repoRoot, workDir, branchName, prInfo, worktreeCreated, logger } = context;\n if (!worktreeCreated) {\n logger.debug('worktree 并非本次创建,跳过自动清理');\n return;\n }\n if (workDir === repoRoot) {\n logger.debug('当前未使用独立 worktree,跳过自动清理');\n return;\n }\n if (!branchName) {\n logger.warn('未能确定 worktree 分支名,保留工作目录以免丢失进度');\n return;\n }\n\n const clean = await isWorktreeClean(workDir, logger);\n if (!clean) {\n logger.warn('worktree 仍有未提交变更,已保留工作目录');\n return;\n }\n\n const pushed = await isBranchPushed(branchName, workDir, logger);\n if (!pushed) {\n logger.warn(`分支 ${branchName} 尚未推送到远端,已保留 worktree`);\n return;\n }\n\n if (!prInfo) {\n logger.warn('未检测到关联 PR,已保留 worktree');\n return;\n }\n\n await removeWorktree(workDir, repoRoot, logger);\n}\n\n/**\n * 执行主迭代循环。\n */\nexport async function runLoop(config: LoopConfig): Promise<LoopResult> {\n const logger = new Logger({ verbose: config.verbose, logFile: config.logFile });\n const repoRoot = await getRepoRoot(config.cwd, logger);\n logger.debug(`仓库根目录: ${repoRoot}`);\n\n let branchName = config.git.branchName;\n let workDir = repoRoot;\n let worktreeCreated = false;\n\n const commandLine = formatCommandLine(process.argv);\n let runTracker: Awaited<ReturnType<typeof createRunTracker>> | null = null;\n\n let accumulatedUsage: TokenUsage | null = null;\n let lastTestResults: TestRunResult[] | null = null;\n let lastAiOutput = '';\n let lastRound = 0;\n let runError: string | null = null;\n let prInfo: GhPrInfo | null = null;\n let prFailed = false;\n let sessionIndex = 0;\n\n const preWorktreeRecords: string[] = [];\n\n const notifyWebhook = async (event: 'task_start' | 'iteration_start' | 'task_end', iteration: number, stage: string): Promise<void> => {\n const payload = buildWebhookPayload({\n event,\n task: config.task,\n branch: branchName,\n iteration,\n stage\n });\n await sendWebhookNotifications(config.webhooks, payload, logger);\n };\n\n try {\n await notifyWebhook('task_start', 0, '任务开始');\n\n if (config.git.useWorktree && !branchName) {\n const branchPrompt = buildBranchNamePrompt({ task: config.task });\n await notifyWebhook('iteration_start', sessionIndex + 1, '分支名生成');\n logger.info('分支名生成提示构建完成,调用 AI CLI...');\n const aiResult = await runAi(branchPrompt, config.ai, logger, repoRoot);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, aiResult.usage);\n lastAiOutput = aiResult.output;\n sessionIndex += 1;\n lastRound = sessionIndex;\n\n const record = formatIterationRecord({\n iteration: sessionIndex,\n stage: '分支名生成',\n prompt: branchPrompt,\n aiOutput: aiResult.output,\n timestamp: isoNow()\n });\n preWorktreeRecords.push(record);\n\n const parsed = parseBranchName(aiResult.output);\n if (parsed) {\n branchName = parsed;\n logger.info(`AI 生成分支名:${branchName}`);\n } else {\n branchName = generateBranchNameFromTask(config.task);\n logger.warn(`未解析到 AI 分支名,使用兜底分支:${branchName}`);\n }\n }\n\n const worktreeResult: WorktreeResult = config.git.useWorktree\n ? await ensureWorktree({ ...config.git, branchName }, repoRoot, logger)\n : { path: repoRoot, created: false };\n workDir = worktreeResult.path;\n worktreeCreated = worktreeResult.created;\n logger.debug(`工作目录: ${workDir}`);\n\n runTracker = await createRunTracker({\n logFile: config.logFile,\n command: commandLine,\n path: workDir,\n logger\n });\n\n if (runTracker && sessionIndex > 0) {\n await runTracker.update(sessionIndex, accumulatedUsage?.totalTokens ?? 0);\n }\n\n if (config.skipInstall) {\n logger.info('已跳过依赖检查');\n } else {\n await ensureDependencies(workDir, logger);\n }\n\n const workflowFiles = reRootWorkflowFiles(config.workflowFiles, repoRoot, workDir);\n await ensureWorkflowFiles(workflowFiles);\n\n if (preWorktreeRecords.length > 0) {\n for (const record of preWorktreeRecords) {\n await appendSection(workflowFiles.notesFile, record);\n }\n logger.success(`已写入分支名生成记录至 ${workflowFiles.notesFile}`);\n }\n\n const planContent = await readFileSafe(workflowFiles.planFile);\n if (planContent.trim().length === 0) {\n logger.warn('plan 文件为空,建议 AI 首轮生成计划');\n }\n\n if (!branchName) {\n try {\n branchName = await getCurrentBranch(workDir, logger);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(`读取分支名失败,webhook 中将缺失分支信息:${message}`);\n }\n }\n\n const aiConfig = config.ai;\n const loadContext = async (): Promise<{ workflowGuide: string; plan: string; notes: string }> => ({\n workflowGuide: await readFileSafe(workflowFiles.workflowDoc),\n plan: await readFileSafe(workflowFiles.planFile),\n notes: await readFileSafe(workflowFiles.notesFile)\n });\n\n const runAiSession = async (\n stage: string,\n prompt: string,\n extras?: { testResults?: TestRunResult[]; checkResults?: CheckRunResult[]; cwd?: string }\n ): Promise<void> => {\n sessionIndex += 1;\n await notifyWebhook('iteration_start', sessionIndex, stage);\n logger.info(`${stage} 提示构建完成,调用 AI CLI...`);\n\n const aiResult = await runAi(prompt, aiConfig, logger, extras?.cwd ?? workDir);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, aiResult.usage);\n lastAiOutput = aiResult.output;\n\n const record = formatIterationRecord({\n iteration: sessionIndex,\n stage,\n prompt,\n aiOutput: aiResult.output,\n timestamp: isoNow(),\n testResults: extras?.testResults,\n checkResults: extras?.checkResults\n });\n\n await appendSection(workflowFiles.notesFile, record);\n logger.success(`已将${stage}输出写入 ${workflowFiles.notesFile}`);\n\n lastRound = sessionIndex;\n await runTracker?.update(sessionIndex, accumulatedUsage?.totalTokens ?? 0);\n };\n\n {\n const { workflowGuide, plan, notes } = await loadContext();\n const planningPrompt = buildPlanningPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n branchName\n });\n await runAiSession('计划生成', planningPrompt);\n }\n\n let refreshedPlan = await readFileSafe(workflowFiles.planFile);\n if (/(测试|test|e2e|单测)/i.test(refreshedPlan)) {\n logger.warn('检测到 plan 中可能包含测试相关事项,建议保留开发内容并移除测试项。');\n }\n\n let pendingItems = getPendingPlanItems(refreshedPlan);\n if (pendingItems.length === 0) {\n logger.info('计划暂无待执行项,跳过计划执行循环');\n const record = formatSystemRecord('计划执行', '未发现待执行计划项,已跳过执行循环。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n }\n\n let planRounds = 0;\n while (pendingItems.length > 0) {\n if (planRounds >= config.iterations) {\n throw new Error('计划执行达到最大迭代次数,仍有未完成项');\n }\n const lastItem = pendingItems[pendingItems.length - 1];\n const { workflowGuide, plan, notes } = await loadContext();\n const itemPrompt = buildPlanItemPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n item: lastItem.text\n });\n await runAiSession(`执行计划项:${truncateText(lastItem.text)}`, itemPrompt);\n planRounds += 1;\n refreshedPlan = await readFileSafe(workflowFiles.planFile);\n pendingItems = getPendingPlanItems(refreshedPlan);\n }\n\n const agentsContent = await readFileSafe(path.join(workDir, 'AGENTS.md'));\n const skipQuality = shouldSkipQuality(agentsContent, config.skipQuality);\n if (skipQuality) {\n const record = formatSystemRecord('代码质量检查', '已按配置/AGENTS.md 跳过代码质量检查。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('已跳过代码质量检查');\n } else {\n const qualityCommands = await detectQualityCommands(workDir);\n if (qualityCommands.length === 0) {\n const record = formatSystemRecord('代码质量检查', '未检测到可执行的质量检查命令,已跳过。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('未检测到质量检查命令,跳过该阶段');\n } else {\n let qualityResults = await runQualityChecks(qualityCommands, workDir, logger);\n const { workflowGuide, plan, notes } = await loadContext();\n const qualityPrompt = buildQualityPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n commands: qualityCommands.map(item => item.command),\n results: buildCheckResultSummary(qualityResults)\n });\n await runAiSession('代码质量检查', qualityPrompt, { checkResults: qualityResults });\n\n let hasQualityFailure = qualityResults.some(result => !result.success);\n let fixRounds = 0;\n while (hasQualityFailure) {\n if (fixRounds >= config.iterations) {\n throw new Error('代码质量修复达到最大轮次,仍未通过');\n }\n const latest = await loadContext();\n const fixPrompt = buildFixPrompt({\n task: config.task,\n workflowGuide: latest.workflowGuide,\n plan: latest.plan,\n notes: latest.notes,\n stage: '代码质量',\n errors: buildFailedCheckSummary(qualityResults)\n });\n await runAiSession('代码质量修复', fixPrompt);\n fixRounds += 1;\n qualityResults = await runQualityChecks(qualityCommands, workDir, logger);\n hasQualityFailure = qualityResults.some(result => !result.success);\n\n const recheckRecord = formatSystemRecord('代码质量复核', buildCheckResultSummary(qualityResults), isoNow());\n await appendSection(workflowFiles.notesFile, recheckRecord);\n }\n }\n }\n\n if (config.runTests || config.runE2e) {\n let testResults = await runTestsSafely(config, workDir, logger);\n\n lastTestResults = testResults;\n const testCommands: string[] = [];\n if (config.runTests && config.tests.unitCommand) {\n testCommands.push(config.tests.unitCommand);\n }\n if (config.runE2e && config.tests.e2eCommand) {\n testCommands.push(config.tests.e2eCommand);\n }\n\n const { workflowGuide, plan, notes } = await loadContext();\n const testPrompt = buildTestPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes,\n commands: testCommands,\n results: buildTestResultSummary(testResults)\n });\n await runAiSession('测试执行', testPrompt, { testResults });\n\n let hasTestFailure = testResults.some(result => !result.success);\n let fixRounds = 0;\n while (hasTestFailure) {\n if (fixRounds >= config.iterations) {\n throw new Error('测试修复达到最大轮次,仍未通过');\n }\n const latest = await loadContext();\n const fixPrompt = buildFixPrompt({\n task: config.task,\n workflowGuide: latest.workflowGuide,\n plan: latest.plan,\n notes: latest.notes,\n stage: '测试',\n errors: buildFailedTestSummary(testResults)\n });\n await runAiSession('测试修复', fixPrompt, { testResults });\n fixRounds += 1;\n\n testResults = await runTestsSafely(config, workDir, logger);\n lastTestResults = testResults;\n hasTestFailure = testResults.some(result => !result.success);\n\n const recheckRecord = formatSystemRecord('测试复核', buildTestResultSummary(testResults), isoNow());\n await appendSection(workflowFiles.notesFile, recheckRecord);\n }\n } else {\n const record = formatSystemRecord('测试执行', '未开启单元测试或 e2e 测试,已跳过。', isoNow());\n await appendSection(workflowFiles.notesFile, record);\n logger.info('未开启测试阶段');\n }\n\n {\n const { workflowGuide, plan, notes } = await loadContext();\n const docsPrompt = buildDocsPrompt({\n task: config.task,\n workflowGuide,\n plan,\n notes\n });\n await runAiSession('文档更新', docsPrompt);\n }\n\n const lastTestFailed = lastTestResults?.some(result => !result.success) ?? false;\n if (lastTestFailed) {\n logger.warn('存在未通过的测试,已跳过自动提交/推送/PR');\n }\n\n let deliverySummary: DeliverySummary | null = null;\n const deliveryNotes: string[] = [];\n const shouldPrepareDelivery = !lastTestFailed && (config.autoCommit || config.pr.enable);\n if (shouldPrepareDelivery) {\n const [gitStatus, diffStat] = await Promise.all([\n safeCommandOutput('git', ['status', '--short'], workDir, logger, 'git', 'git status --short'),\n safeCommandOutput('git', ['diff', '--stat'], workDir, logger, 'git', 'git diff --stat')\n ]);\n const summaryPrompt = buildSummaryPrompt({\n task: config.task,\n plan: await readFileSafe(workflowFiles.planFile),\n notes: await readFileSafe(workflowFiles.notesFile),\n lastAiOutput,\n testResults: lastTestResults,\n gitStatus,\n diffStat,\n branchName\n });\n try {\n const summaryResult = await runAi(summaryPrompt, aiConfig, logger, workDir);\n accumulatedUsage = mergeTokenUsage(accumulatedUsage, summaryResult.usage);\n deliverySummary = parseDeliverySummary(summaryResult.output);\n if (!deliverySummary) {\n logger.warn('AI 总结输出解析失败,使用兜底文案');\n }\n } catch (error) {\n logger.warn(`AI 总结生成失败: ${String(error)}`);\n }\n if (!deliverySummary) {\n deliverySummary = buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n }\n if (deliverySummary) {\n deliveryNotes.push(`交付摘要:提交 ${deliverySummary.commitTitle}|PR ${deliverySummary.prTitle}`);\n }\n }\n await runTracker?.update(lastRound, accumulatedUsage?.totalTokens ?? 0);\n\n if (config.autoCommit) {\n if (lastTestFailed) {\n deliveryNotes.push('自动提交:已跳过(测试未通过)');\n } else {\n const summary = deliverySummary ?? buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n const commitMessage: CommitMessage = {\n title: summary.commitTitle,\n body: summary.commitBody\n };\n try {\n const committed = await commitAll(commitMessage, workDir, logger);\n deliveryNotes.push(committed ? `自动提交:已提交(${commitMessage.title})` : '自动提交:未生成提交(可能无变更或提交失败)');\n } catch (error) {\n deliveryNotes.push(`自动提交:失败(${String(error)})`);\n }\n }\n } else {\n deliveryNotes.push('自动提交:未开启');\n }\n\n if (config.autoPush) {\n if (lastTestFailed) {\n deliveryNotes.push('自动推送:已跳过(测试未通过)');\n } else if (!branchName) {\n deliveryNotes.push('自动推送:已跳过(缺少分支名)');\n } else {\n try {\n await pushBranch(branchName, workDir, logger);\n deliveryNotes.push(`自动推送:已推送(${branchName})`);\n } catch (error) {\n deliveryNotes.push(`自动推送:失败(${String(error)})`);\n }\n }\n } else {\n deliveryNotes.push('自动推送:未开启');\n }\n\n if (config.pr.enable) {\n if (lastTestFailed) {\n deliveryNotes.push('PR 创建:已跳过(测试未通过)');\n } else if (!branchName) {\n deliveryNotes.push('PR 创建:已跳过(缺少分支名)');\n } else {\n logger.info('开始创建 PR...');\n const summary = deliverySummary ?? buildFallbackSummary({ task: config.task, testResults: lastTestResults });\n const prTitleCandidate = config.pr.title?.trim() || summary.prTitle;\n const prBodyContent = ensurePrBodySections(summary.prBody, {\n commitTitle: summary.commitTitle,\n commitBody: summary.commitBody,\n testResults: lastTestResults\n });\n const bodyFile = config.pr.bodyPath ?? buildBodyFile(workDir);\n await writePrBody(bodyFile, prBodyContent, Boolean(config.pr.bodyPath));\n\n const createdPr = await createPr(branchName, { ...config.pr, title: prTitleCandidate, bodyPath: bodyFile }, workDir, logger);\n prInfo = createdPr;\n if (createdPr) {\n logger.success(`PR 已创建: ${createdPr.url}`);\n deliveryNotes.push(`PR 创建:已完成(${createdPr.url})`);\n if (config.pr.autoMerge) {\n const target = createdPr.number > 0 ? createdPr.number : createdPr.url;\n const merged = await enableAutoMerge(target, workDir, logger);\n if (merged) {\n deliveryNotes.push('PR 自动合并:已启用');\n } else {\n deliveryNotes.push('PR 自动合并:启用失败');\n prFailed = true;\n }\n } else {\n deliveryNotes.push('PR 自动合并:未开启');\n }\n const failedRuns = await listFailedRuns(branchName, workDir, logger);\n if (failedRuns.length > 0) {\n failedRuns.forEach(run => {\n logger.warn(`Actions 失败: ${run.name} (${run.status}/${run.conclusion ?? 'unknown'}) ${run.url}`);\n });\n }\n } else {\n prFailed = true;\n deliveryNotes.push('PR 创建:失败(详见 gh 输出)');\n logger.error('PR 创建失败,详见上方 gh 输出');\n }\n }\n } else if (branchName) {\n logger.info('未开启 PR 创建(--pr 未传),尝试查看已有 PR');\n const existingPr = await viewPr(branchName, workDir, logger);\n prInfo = existingPr;\n if (existingPr) {\n logger.info(`已有 PR: ${existingPr.url}`);\n deliveryNotes.push(`PR 创建:未开启(已存在 PR:${existingPr.url})`);\n } else {\n deliveryNotes.push('PR 创建:未开启(未检测到已有 PR)');\n }\n } else {\n deliveryNotes.push('PR 创建:未开启(缺少分支名)');\n }\n\n if (deliveryNotes.length > 0) {\n const record = formatSystemRecord('提交与PR', deliveryNotes.join('\\n'), isoNow());\n await appendSection(workflowFiles.notesFile, record);\n }\n\n if (accumulatedUsage) {\n const input = accumulatedUsage.inputTokens ?? '-';\n const output = accumulatedUsage.outputTokens ?? '-';\n logger.info(`Token 消耗汇总:输入 ${input}|输出 ${output}|总计 ${accumulatedUsage.totalTokens}`);\n } else {\n logger.info('未解析到 Token 消耗信息,可检查 AI CLI 输出格式是否包含 token 提示');\n }\n\n if (lastTestFailed || prFailed) {\n throw new Error('流程存在未解决的问题(测试未通过或 PR 创建失败)');\n }\n\n if (config.git.useWorktree && workDir !== repoRoot) {\n await cleanupWorktreeIfSafe({\n repoRoot,\n workDir,\n branchName,\n prInfo,\n worktreeCreated,\n logger\n });\n }\n\n logger.success(`wheel-ai 迭代流程结束|Token 总计 ${accumulatedUsage?.totalTokens ?? '未知'}`);\n return { branchName };\n } catch (error) {\n runError = error instanceof Error ? error.message : String(error);\n throw error;\n } finally {\n const stage = runError ? '任务结束(失败)' : '任务结束';\n await notifyWebhook('task_end', lastRound, stage);\n await runTracker?.finalize();\n }\n}\n","import { AiCliConfig, AiResult, IterationRecord, TokenUsage } from './types';\nimport { runCommand } from './utils';\nimport { Logger } from './logger';\n\ninterface PromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly iteration: number;\n}\n\n/**\n * 构建 AI 提示文本。\n */\nexport function buildPrompt(input: PromptInput): string {\n const sections = [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前持久化计划',\n input.plan || '(暂无计划,首轮请生成可执行计划并写入 plan 文件)',\n '# 历史迭代与记忆',\n input.notes || '(首次执行,暂无历史)',\n '# 本轮执行要求',\n [\n '1. 自我检查并补全需求;明确交付物与验收标准。',\n '2. 更新/细化计划,必要时在 plan 文件中重写任务树与优先级。',\n '3. 设计开发步骤并直接生成代码(无需再次请求确认)。',\n '4. 进行代码自审,给出风险与改进清单。',\n '5. 生成单元测试与 e2e 测试代码并给出运行命令;如果环境允许可直接运行命令。',\n '6. 维护持久化记忆文件:摘要本轮关键结论、遗留问题、下一步建议。',\n '7. 准备提交 PR 所需的标题与描述(含变更摘要、测试结果、风险)。',\n '8. 当所有目标完成时,在输出中加入标记 <<DONE>> 以便外层停止循环。'\n ].join('\\n')\n ];\n\n return sections.join('\\n\\n');\n}\n\nfunction compactLine(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\ninterface BranchNamePromptInput {\n readonly task: string;\n}\n\n/**\n * 构建分支名生成提示。\n */\nexport function buildBranchNamePrompt(input: BranchNamePromptInput): string {\n return [\n '# 角色',\n '你是资深工程师,需要根据任务生成规范的 git 分支名。',\n '# 规则',\n '- 输出格式仅限严格 JSON(不要 markdown、不要代码块、不要解释)。',\n '- 分支名格式:<type>/<slug>。',\n '- type 可选:feat、fix、docs、refactor、chore、test。',\n '- slug 使用小写英文、数字、连字符,长度 3~40,避免空格与中文。',\n '# 输出 JSON',\n '{\"branch\":\"...\"}',\n '# 任务描述',\n compactLine(input.task) || '(空)'\n ].join('\\n\\n');\n}\n\ninterface PlanningPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly branchName?: string;\n}\n\n/**\n * 构建计划生成提示。\n */\nexport function buildPlanningPrompt(input: PlanningPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 分支信息',\n input.branchName ? `计划使用分支:${input.branchName}` : '未指定分支名,请按任务语义给出建议',\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮执行要求',\n [\n '1. 分析任务输入/输出/约束/验收标准,必要时补充合理假设(写入 notes)。',\n '2. 若 plan.md 已存在,请判断是否合理;合理则不修改,不合理则优化或重写。',\n '3. 计划只包含开发相关任务(设计/实现/重构/配置/文档更新),不要包含测试、自审、PR、提交等内容。',\n '4. 计划项需可执行、颗粒度清晰,已完成项使用 ✅ 标记。',\n '5. 更新 memory/plan.md 与 memory/notes.md 后结束本轮。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface PlanItemPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly item: string;\n}\n\n/**\n * 构建单条计划执行提示。\n */\nexport function buildPlanItemPrompt(input: PlanItemPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮要执行的计划项(仅此一条)',\n input.item,\n '# 本轮执行要求',\n [\n '1. 只执行上述计划项,避免提前处理其它计划项。',\n '2. 完成后立即在 plan.md 中将该项标记为 ✅。',\n '3. 必要时可对计划项进行微调,但仍需确保当前项完成。',\n '4. 本轮不执行测试或质量检查。',\n '5. 将进展、关键改动与风险写入 notes。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface QualityPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly commands: string[];\n readonly results?: string;\n}\n\n/**\n * 构建质量检查提示。\n */\nexport function buildQualityPrompt(input: QualityPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮代码质量检查',\n input.commands.length > 0 ? input.commands.map(cmd => `- ${cmd}`).join('\\n') : '未检测到可执行的质量检查命令。',\n input.results ? `# 命令执行结果\\n${input.results}` : '',\n '# 本轮执行要求',\n [\n '1. 本轮仅进行代码质量检查,不要修复问题。',\n '2. 若出现失败,记录失败要点,等待下一轮修复。',\n '3. 将结论与风险写入 notes。'\n ].join('\\n')\n ].filter(Boolean).join('\\n\\n');\n}\n\ninterface FixPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly stage: string;\n readonly errors: string;\n}\n\n/**\n * 构建问题修复提示(质量检查 / 测试)。\n */\nexport function buildFixPrompt(input: FixPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n `# 需要修复的问题(${input.stage})`,\n input.errors || '(无错误信息)',\n '# 本轮执行要求',\n [\n '1. 聚焦修复当前问题,不要扩展范围。',\n '2. 修复完成后更新 notes,说明修改点与影响。',\n '3. 如需调整计划,请同步更新 plan.md。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\ninterface TestPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n readonly commands: string[];\n readonly results?: string;\n}\n\n/**\n * 构建测试执行提示。\n */\nexport function buildTestPrompt(input: TestPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮测试命令',\n input.commands.length > 0 ? input.commands.map(cmd => `- ${cmd}`).join('\\n') : '未配置测试命令。',\n input.results ? `# 测试结果\\n${input.results}` : '',\n '# 本轮执行要求',\n [\n '1. 本轮仅执行测试,不要修复问题。',\n '2. 若出现失败,记录失败要点,等待下一轮修复。',\n '3. 将测试结论写入 notes。'\n ].join('\\n')\n ].filter(Boolean).join('\\n\\n');\n}\n\ninterface DocsPromptInput {\n readonly task: string;\n readonly workflowGuide: string;\n readonly plan: string;\n readonly notes: string;\n}\n\n/**\n * 构建文档更新提示。\n */\nexport function buildDocsPrompt(input: DocsPromptInput): string {\n return [\n '# 背景任务',\n input.task,\n '# 工作流程基线(供 AI 自主执行)',\n input.workflowGuide,\n '# 当前计划',\n input.plan || '(暂无计划)',\n '# 历史记忆',\n input.notes || '(暂无历史)',\n '# 本轮执行要求',\n [\n '1. 根据本次改动更新版本号、CHANGELOG、README、docs 等相关文档。',\n '2. 仅更新确有变化的文档,保持中文说明。',\n '3. 将更新摘要写入 notes。'\n ].join('\\n')\n ].join('\\n\\n');\n}\n\nfunction extractJson(text: string): string | null {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (fenced?.[1]) return fenced[1].trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1).trim();\n }\n return null;\n}\n\nconst BRANCH_TYPES = ['feat', 'fix', 'docs', 'refactor', 'chore', 'test'] as const;\ntype BranchType = typeof BRANCH_TYPES[number];\n\nconst BRANCH_TYPE_ALIASES: Record<string, BranchType> = {\n feature: 'feat',\n features: 'feat',\n bugfix: 'fix',\n hotfix: 'fix',\n doc: 'docs',\n documentation: 'docs',\n refactoring: 'refactor',\n chores: 'chore',\n tests: 'test'\n};\n\nfunction isBranchType(value: string): value is BranchType {\n return BRANCH_TYPES.includes(value as BranchType);\n}\n\nfunction normalizeBranchType(value: string): BranchType | null {\n const trimmed = value.trim().toLowerCase();\n if (!trimmed) return null;\n if (isBranchType(trimmed)) return trimmed;\n return BRANCH_TYPE_ALIASES[trimmed] ?? null;\n}\n\nfunction normalizeBranchSlug(value: string): string | null {\n const cleaned = value\n .toLowerCase()\n .replace(/\\s+/g, '-')\n .replace(/_/g, '-')\n .replace(/[^a-z0-9-]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n if (!cleaned) return null;\n const trimmed = cleaned.slice(0, 40);\n if (trimmed.length < 3) return null;\n return trimmed;\n}\n\nfunction normalizeBranchNameCandidate(value: string): string | null {\n const trimmed = value.trim();\n if (!trimmed) return null;\n const lowered = trimmed.toLowerCase();\n const parts = lowered.split('/').filter(part => part.length > 0);\n const hasExplicitType = lowered.includes('/') && parts.length >= 2;\n const rawType = hasExplicitType ? parts.shift() ?? '' : '';\n const rawSlug = hasExplicitType ? parts.join('-') : lowered;\n\n const type = rawType ? normalizeBranchType(rawType) : 'feat';\n if (!type) return null;\n\n const slug = normalizeBranchSlug(rawSlug);\n if (!slug) return null;\n\n return `${type}/${slug}`;\n}\n\n/**\n * 解析 AI 输出中的分支名。\n */\nexport function parseBranchName(output: string): string | null {\n const jsonText = extractJson(output);\n if (jsonText) {\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>;\n const raw = typeof parsed.branch === 'string'\n ? parsed.branch\n : typeof parsed.branchName === 'string'\n ? parsed.branchName\n : typeof parsed['分支'] === 'string'\n ? (parsed['分支'] as string)\n : typeof parsed['分支名'] === 'string'\n ? (parsed['分支名'] as string)\n : null;\n if (raw) {\n const normalized = normalizeBranchNameCandidate(raw);\n if (normalized) return normalized;\n }\n } catch {\n // 忽略解析失败,回退到文本匹配\n }\n }\n\n const lineMatch = output.match(/(?:branch(?:name)?|分支名|分支)\\s*[::]\\s*([^\\s]+)/i);\n if (lineMatch?.[1]) {\n const normalized = normalizeBranchNameCandidate(lineMatch[1]);\n if (normalized) return normalized;\n }\n return null;\n}\n\nfunction pickNumber(pattern: RegExp, text: string): number | undefined {\n const match = pattern.exec(text);\n if (!match || match.length < 2) return undefined;\n const value = Number.parseInt(match[match.length - 1], 10);\n return Number.isNaN(value) ? undefined : value;\n}\n\n/**\n * 从日志文本中解析 token 使用量。\n */\nexport function parseTokenUsage(logs: string): TokenUsage | null {\n const total = pickNumber(/total[_\\s]tokens:\\s*(\\d+)/i, logs);\n const input = pickNumber(/(input|prompt)[_\\s]tokens:\\s*(\\d+)/i, logs);\n const output = pickNumber(/(output|completion)[_\\s]tokens:\\s*(\\d+)/i, logs);\n const consumed = pickNumber(/tokens?\\s+used:\\s*(\\d+)/i, logs) ?? pickNumber(/consumed\\s+(\\d+)\\s+tokens?/i, logs);\n\n const totalTokens = total ?? (input !== undefined || output !== undefined ? (input ?? 0) + (output ?? 0) : consumed);\n if (totalTokens === undefined) return null;\n\n return {\n inputTokens: input,\n outputTokens: output,\n totalTokens\n };\n}\n\nfunction addOptional(a?: number, b?: number): number | undefined {\n if (typeof a !== 'number' && typeof b !== 'number') return undefined;\n return (a ?? 0) + (b ?? 0);\n}\n\n/**\n * 合并多轮 token 统计。\n */\nexport function mergeTokenUsage(previous: TokenUsage | null, current?: TokenUsage | null): TokenUsage | null {\n if (!current) return previous;\n if (!previous) return { ...current };\n return {\n inputTokens: addOptional(previous.inputTokens, current.inputTokens),\n outputTokens: addOptional(previous.outputTokens, current.outputTokens),\n totalTokens: previous.totalTokens + current.totalTokens\n };\n}\n\n/**\n * 调用 AI CLI 并返回输出。\n */\nexport async function runAi(prompt: string, ai: AiCliConfig, logger: Logger, cwd: string): Promise<AiResult> {\n const args = [...ai.args];\n const verboseCommand = ai.promptArg\n ? [ai.command, ...ai.args, ai.promptArg, '<prompt>'].join(' ')\n : [ai.command, ...ai.args, '<stdin>'].join(' ');\n const streamPrefix = `[${ai.command}] `;\n const streamErrorPrefix = `[${ai.command} stderr] `;\n\n let result;\n if (ai.promptArg) {\n args.push(ai.promptArg, prompt);\n result = await runCommand(ai.command, args, {\n cwd,\n logger,\n verboseLabel: 'ai',\n verboseCommand,\n stream: {\n enabled: true,\n stdoutPrefix: streamPrefix,\n stderrPrefix: streamErrorPrefix\n }\n });\n } else {\n result = await runCommand(ai.command, args, {\n cwd,\n input: prompt,\n logger,\n verboseLabel: 'ai',\n verboseCommand,\n stream: {\n enabled: true,\n stdoutPrefix: streamPrefix,\n stderrPrefix: streamErrorPrefix\n }\n });\n }\n\n if (result.exitCode !== 0) {\n throw new Error(`AI CLI 执行失败: ${result.stderr || result.stdout}`);\n }\n\n logger.success('AI 输出完成');\n const usage = parseTokenUsage([result.stdout, result.stderr].filter(Boolean).join('\\n'));\n return {\n output: result.stdout.trim(),\n usage\n };\n}\n\n/**\n * 生成 notes 迭代记录文本。\n */\nexport function formatIterationRecord(record: IterationRecord): string {\n const title = record.stage\n ? `### 迭代 ${record.iteration} | ${record.timestamp} | ${record.stage}`\n : `### 迭代 ${record.iteration} | ${record.timestamp}`;\n const lines = [\n title,\n '',\n '#### 提示上下文',\n '```',\n record.prompt,\n '```',\n '',\n '#### AI 输出',\n '```',\n record.aiOutput,\n '```',\n ''\n ];\n\n if (record.checkResults && record.checkResults.length > 0) {\n lines.push('#### 质量检查结果');\n record.checkResults.forEach(result => {\n const status = result.success ? '✅ 通过' : '❌ 失败';\n lines.push(`${status} | ${result.name} | 命令: ${result.command} | 退出码: ${result.exitCode}`);\n if (!result.success) {\n lines.push('```');\n lines.push(result.stderr || result.stdout || '(无输出)');\n lines.push('```');\n lines.push('');\n }\n });\n }\n\n if (record.testResults && record.testResults.length > 0) {\n lines.push('#### 测试结果');\n record.testResults.forEach(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '✅ 通过' : '❌ 失败';\n lines.push(`${status} | ${label} | 命令: ${result.command} | 退出码: ${result.exitCode}`);\n if (!result.success) {\n lines.push('```');\n lines.push(result.stderr || result.stdout || '(无输出)');\n lines.push('```');\n lines.push('');\n }\n });\n }\n\n return lines.join('\\n');\n}\n","import path from 'node:path';\nimport fs from 'fs-extra';\nimport { Logger } from './logger';\nimport { runCommand } from './utils';\n\n/**\n * 支持的包管理器类型。\n */\nexport type PackageManager = 'yarn' | 'pnpm' | 'npm';\n\ntype PackageManagerSource = 'packageManager' | 'lockfile' | 'default';\n\n/**\n * 解析包管理器所需的提示信息。\n */\nexport interface PackageManagerHints {\n readonly packageManagerField?: string;\n readonly hasYarnLock: boolean;\n readonly hasPnpmLock: boolean;\n readonly hasNpmLock: boolean;\n readonly hasNpmShrinkwrap: boolean;\n}\n\n/**\n * 包管理器解析结果。\n */\nexport interface PackageManagerResolution {\n readonly manager: PackageManager;\n readonly source: PackageManagerSource;\n readonly hasLock: boolean;\n}\n\nfunction parsePackageManagerField(value?: string): PackageManager | null {\n if (!value) return null;\n const normalized = value.trim().toLowerCase();\n if (normalized === 'yarn' || normalized.startsWith('yarn@')) return 'yarn';\n if (normalized === 'pnpm' || normalized.startsWith('pnpm@')) return 'pnpm';\n if (normalized === 'npm' || normalized.startsWith('npm@')) return 'npm';\n return null;\n}\n\nfunction hasLockForManager(manager: PackageManager, hints: PackageManagerHints): boolean {\n if (manager === 'yarn') return hints.hasYarnLock;\n if (manager === 'pnpm') return hints.hasPnpmLock;\n return hints.hasNpmLock || hints.hasNpmShrinkwrap;\n}\n\n/**\n * 根据 packageManager 字段或锁文件推断包管理器。\n */\nexport function resolvePackageManager(hints: PackageManagerHints): PackageManagerResolution {\n const fromField = parsePackageManagerField(hints.packageManagerField);\n if (fromField) {\n return {\n manager: fromField,\n source: 'packageManager',\n hasLock: hasLockForManager(fromField, hints)\n };\n }\n\n if (hints.hasYarnLock) {\n return {\n manager: 'yarn',\n source: 'lockfile',\n hasLock: true\n };\n }\n if (hints.hasPnpmLock) {\n return {\n manager: 'pnpm',\n source: 'lockfile',\n hasLock: true\n };\n }\n if (hints.hasNpmLock || hints.hasNpmShrinkwrap) {\n return {\n manager: 'npm',\n source: 'lockfile',\n hasLock: true\n };\n }\n\n return {\n manager: 'yarn',\n source: 'default',\n hasLock: false\n };\n}\n\n/**\n * 生成安装依赖命令。\n */\nexport function buildInstallCommand(resolution: PackageManagerResolution): string {\n switch (resolution.manager) {\n case 'yarn': {\n const args = ['yarn', 'install'];\n if (resolution.hasLock) {\n args.push('--frozen-lockfile');\n } else {\n args.push('--no-lockfile');\n }\n return args.join(' ');\n }\n case 'pnpm': {\n const args = ['pnpm', 'install'];\n if (resolution.hasLock) {\n args.push('--frozen-lockfile');\n }\n return args.join(' ');\n }\n case 'npm': {\n const args = resolution.hasLock ? ['npm', 'ci'] : ['npm', 'install'];\n args.push('--no-audit', '--no-fund');\n return args.join(' ');\n }\n default: {\n return 'yarn install';\n }\n }\n}\n\nfunction resolveSourceLabel(source: PackageManagerSource): string {\n switch (source) {\n case 'packageManager':\n return 'packageManager 字段';\n case 'lockfile':\n return '锁文件';\n case 'default':\n return '默认策略';\n default:\n return '未知来源';\n }\n}\n\nfunction extractPackageManagerField(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const candidate = value as Record<string, unknown>;\n const field = candidate.packageManager;\n return typeof field === 'string' ? field : undefined;\n}\n\nasync function readPackageManagerHints(cwd: string, logger: Logger): Promise<PackageManagerHints | null> {\n const packageJsonPath = path.join(cwd, 'package.json');\n const hasPackageJson = await fs.pathExists(packageJsonPath);\n if (!hasPackageJson) return null;\n\n let packageManagerField: string | undefined;\n try {\n const packageJson = await fs.readJson(packageJsonPath);\n packageManagerField = extractPackageManagerField(packageJson);\n } catch (error) {\n logger.warn(`读取 package.json 失败,将改用锁文件判断包管理器: ${String(error)}`);\n }\n\n const [hasYarnLock, hasPnpmLock, hasNpmLock, hasNpmShrinkwrap] = await Promise.all([\n fs.pathExists(path.join(cwd, 'yarn.lock')),\n fs.pathExists(path.join(cwd, 'pnpm-lock.yaml')),\n fs.pathExists(path.join(cwd, 'package-lock.json')),\n fs.pathExists(path.join(cwd, 'npm-shrinkwrap.json'))\n ]);\n\n return {\n packageManagerField,\n hasYarnLock,\n hasPnpmLock,\n hasNpmLock,\n hasNpmShrinkwrap\n };\n}\n\n/**\n * 确保依赖已安装(按锁文件或 packageManager 字段选择包管理器)。\n */\nexport async function ensureDependencies(cwd: string, logger: Logger): Promise<void> {\n const hints = await readPackageManagerHints(cwd, logger);\n if (!hints) {\n logger.info('未检测到 package.json,跳过依赖检查');\n return;\n }\n\n const resolution = resolvePackageManager(hints);\n const sourceLabel = resolveSourceLabel(resolution.source);\n logger.info(`依赖检查:使用 ${resolution.manager}(来源:${sourceLabel})`);\n\n if (resolution.source === 'default') {\n logger.warn('未检测到 packageManager 配置或锁文件,将按默认策略安装依赖');\n }\n\n const command = buildInstallCommand(resolution);\n logger.info(`开始安装依赖: ${command}`);\n\n const result = await runCommand('bash', ['-lc', command], {\n cwd,\n logger,\n verboseLabel: 'deps',\n verboseCommand: `bash -lc \"${command}\"`,\n stream: {\n enabled: true,\n stdoutPrefix: '[deps] ',\n stderrPrefix: '[deps err] '\n }\n });\n\n if (result.exitCode !== 0) {\n const details = result.stderr || result.stdout || '无输出';\n throw new Error(`依赖安装失败: ${details}`);\n }\n\n logger.success('依赖检查完成');\n}\n","import { Logger } from './logger';\nimport { PrConfig } from './types';\nimport { runCommand } from './utils';\n\n/**\n * PR 基础信息。\n */\nexport interface GhPrInfo {\n readonly number: number;\n readonly url: string;\n readonly title: string;\n readonly state: string;\n readonly headRefName: string;\n}\n\n/**\n * Actions 运行信息。\n */\nexport interface GhRunInfo {\n readonly databaseId: number;\n readonly name: string;\n readonly status: string;\n readonly conclusion?: string | null;\n readonly url: string;\n}\n\nfunction isGhPrInfo(input: unknown): input is GhPrInfo {\n if (typeof input !== 'object' || input === null) return false;\n const candidate = input as Record<string, unknown>;\n return typeof candidate.number === 'number'\n && typeof candidate.url === 'string'\n && typeof candidate.title === 'string'\n && typeof candidate.state === 'string'\n && typeof candidate.headRefName === 'string';\n}\n\nfunction resolveRunDatabaseId(candidate: Record<string, unknown>): number | null {\n const databaseId = candidate.databaseId;\n if (typeof databaseId === 'number' && Number.isFinite(databaseId)) return databaseId;\n const id = candidate.id;\n if (typeof id === 'number' && Number.isFinite(id)) return id;\n if (typeof id === 'string') {\n const parsed = Number(id);\n if (Number.isFinite(parsed)) return parsed;\n }\n return null;\n}\n\nfunction parseGhRunInfo(input: unknown): GhRunInfo | null {\n if (typeof input !== 'object' || input === null) return null;\n const candidate = input as Record<string, unknown>;\n const databaseId = resolveRunDatabaseId(candidate);\n if (databaseId === null) return null;\n if (typeof candidate.name !== 'string') return null;\n if (typeof candidate.status !== 'string') return null;\n if (typeof candidate.url !== 'string') return null;\n const conclusion = candidate.conclusion;\n const hasValidConclusion = conclusion === undefined || conclusion === null || typeof conclusion === 'string';\n if (!hasValidConclusion) return null;\n return {\n databaseId,\n name: candidate.name,\n status: candidate.status,\n conclusion: conclusion ?? null,\n url: candidate.url\n };\n}\n\n/**\n * 解析 gh run list 的 JSON 输出。\n */\nexport function parseGhRunList(output: string): GhRunInfo[] {\n try {\n const parsed = JSON.parse(output);\n if (!Array.isArray(parsed)) return [];\n return parsed\n .map(parseGhRunInfo)\n .filter((run): run is GhRunInfo => run !== null);\n } catch {\n return [];\n }\n}\n\n/**\n * 解析 PR 标题,必要时给出兜底标题。\n */\nexport function resolvePrTitle(branch: string, title?: string): string {\n const trimmed = title?.trim();\n if (trimmed) return trimmed;\n return `chore: 自动 PR (${branch})`;\n}\n\n/**\n * 组装 gh pr create 所需参数。\n */\nexport function buildPrCreateArgs(branch: string, config: PrConfig): string[] {\n const args = ['pr', 'create', '--head', branch, '--title', resolvePrTitle(branch, config.title)];\n if (config.bodyPath) {\n args.push('--body-file', config.bodyPath);\n } else {\n args.push('--body', '自动生成 PR(未提供 body 文件)');\n }\n if (config.draft) {\n args.push('--draft');\n }\n if (config.reviewers && config.reviewers.length > 0) {\n args.push('--reviewer', config.reviewers.join(','));\n }\n return args;\n}\n\n/**\n * 判断 gh pr create 是否提示 PR 已存在。\n */\nexport function isPrAlreadyExistsMessage(output: string): boolean {\n const trimmed = output.trim();\n if (!trimmed) return false;\n const ghPattern =\n /a pull request for branch [\"']?[^\"']+[\"']? into branch [\"']?[^\"']+[\"']? already exists/i;\n if (ghPattern.test(trimmed)) return true;\n\n const hasAlreadyExists = /already exists/i.test(trimmed);\n const hasPrKeyword = /\\b(pull request|pr)\\b/i.test(trimmed);\n const hasBranch = /\\bbranch\\b/i.test(trimmed);\n if (hasAlreadyExists && hasPrKeyword && hasBranch) return true;\n\n const hasChineseExists = trimmed.includes('已存在');\n const hasChinesePr = trimmed.includes('拉取请求') || trimmed.includes('合并请求') || /\\bPR\\b/i.test(trimmed);\n const hasChineseBranch = trimmed.includes('分支');\n if (hasChineseExists && hasChinesePr && hasChineseBranch) return true;\n return false;\n}\n\nfunction extractPrUrl(output: string): string | null {\n const match = output.match(/https?:\\/\\/\\S+/);\n if (!match) return null;\n return match[0].replace(/[),.]+$/, '');\n}\n\n/**\n * 读取当前分支 PR 信息。\n */\nexport async function viewPr(branch: string, cwd: string, logger: Logger): Promise<GhPrInfo | null> {\n const result = await runCommand('gh', ['pr', 'view', branch, '--json', 'number,title,url,state,headRefName'], {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh pr view ${branch} --json number,title,url,state,headRefName`\n });\n if (result.exitCode !== 0) {\n logger.warn(`gh pr view 失败: ${result.stderr}`);\n return null;\n }\n try {\n const parsed = JSON.parse(result.stdout);\n if (isGhPrInfo(parsed)) return parsed;\n logger.warn('gh pr view 返回格式异常');\n return null;\n } catch (error) {\n logger.warn(`解析 gh pr view 输出失败: ${String(error)}`);\n return null;\n }\n}\n\n/**\n * 创建 PR 并返回 PR 信息。\n */\nexport async function createPr(branch: string, config: PrConfig, cwd: string, logger: Logger): Promise<GhPrInfo | null> {\n if (!config.enable) return null;\n const args = buildPrCreateArgs(branch, config);\n\n const result = await runCommand('gh', args, {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh ${args.join(' ')}`\n });\n if (result.exitCode !== 0) {\n const output = `${result.stderr}\\n${result.stdout}`.trim();\n if (isPrAlreadyExistsMessage(output)) {\n const existingPr = await viewPr(branch, cwd, logger);\n if (existingPr) {\n logger.warn(`创建 PR 失败,但检测到已有 PR,视为创建完成: ${existingPr.url}`);\n return existingPr;\n }\n const fallbackUrl = extractPrUrl(output);\n logger.warn('创建 PR 失败,提示已存在 PR,但读取 PR 信息失败,视为创建完成');\n return {\n number: 0,\n url: fallbackUrl ?? '未获取到链接',\n title: '已存在 PR(未获取详情)',\n state: 'unknown',\n headRefName: branch\n };\n }\n logger.warn(`创建 PR 失败: ${output || '未知错误'}`);\n return null;\n }\n\n return viewPr(branch, cwd, logger);\n}\n\n/**\n * 获取最近失败的 Actions 运行。\n */\nexport async function listFailedRuns(branch: string, cwd: string, logger: Logger): Promise<GhRunInfo[]> {\n const result = await runCommand('gh', ['run', 'list', '--branch', branch, '--json', 'databaseId,name,status,conclusion,url', '--limit', '5'], {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh run list --branch ${branch} --json databaseId,name,status,conclusion,url --limit 5`\n });\n if (result.exitCode !== 0) {\n logger.warn(`获取 Actions 运行失败: ${result.stderr}`);\n return [];\n }\n try {\n const runs = parseGhRunList(result.stdout);\n const failed = runs.filter(run => run.conclusion && run.conclusion !== 'success');\n if (failed.length === 0) {\n logger.info('最近 5 次 Actions 运行无失败');\n }\n return failed;\n } catch (error) {\n logger.warn(`解析 Actions 输出失败: ${String(error)}`);\n return [];\n }\n}\n\n/**\n * 启用 PR 自动合并。\n */\nexport async function enableAutoMerge(target: string | number, cwd: string, logger: Logger): Promise<boolean> {\n const targetValue = String(target);\n const args = ['pr', 'merge', targetValue, '--auto', '--merge'];\n const result = await runCommand('gh', args, {\n cwd,\n logger,\n verboseLabel: 'gh',\n verboseCommand: `gh ${args.join(' ')}`\n });\n if (result.exitCode !== 0) {\n logger.warn(`启用自动合并失败: ${result.stderr || result.stdout}`);\n return false;\n }\n logger.success('已启用 PR 自动合并');\n return true;\n}\n","import fs from 'fs-extra';\nimport { pad2 } from './utils';\n\ntype Colorizer = (value: string) => string;\ntype ConsoleMethodName = 'log' | 'warn' | 'error';\n\nconst wrap = (code: string): Colorizer => (value: string) => `\\u001b[${code}m${value}\\u001b[0m`;\n\nconst colors = {\n blue: wrap('34'),\n green: wrap('32'),\n yellow: wrap('33'),\n red: wrap('31'),\n magenta: wrap('35'),\n gray: wrap('90')\n} as const;\n\n/**\n * 日志器配置项。\n */\nexport interface LoggerOptions {\n readonly verbose?: boolean;\n readonly logFile?: string;\n}\n\n/**\n * 带颜色的日志输出器,可选写入日志文件。\n */\nexport class Logger {\n private readonly verbose: boolean;\n private readonly logFile?: string;\n private logFileEnabled: boolean;\n private logFileErrored: boolean;\n\n constructor(options: LoggerOptions = {}) {\n this.verbose = options.verbose ?? false;\n const trimmedPath = options.logFile?.trim();\n this.logFile = trimmedPath && trimmedPath.length > 0 ? trimmedPath : undefined;\n this.logFileEnabled = Boolean(this.logFile);\n this.logFileErrored = false;\n\n if (this.logFile) {\n try {\n fs.ensureFileSync(this.logFile);\n } catch (error) {\n this.disableFileWithError(error);\n }\n }\n }\n\n info(message: string): void {\n this.emit('log', colors.blue, 'info', ' ', message);\n }\n\n success(message: string): void {\n this.emit('log', colors.green, 'ok', ' ', message);\n }\n\n warn(message: string): void {\n this.emit('warn', colors.yellow, 'warn', ' ', message);\n }\n\n error(message: string): void {\n this.emit('error', colors.red, 'err', ' ', message);\n }\n\n debug(message: string): void {\n if (!this.verbose) return;\n this.emit('log', colors.magenta, 'dbg', ' ', message);\n }\n\n private emit(method: ConsoleMethodName, colorizer: Colorizer, label: string, padding: string, message: string): void {\n const now = new Date();\n const consoleLine = this.formatConsoleLine(now, colorizer(label), padding, message);\n const fileLine = this.formatFileLine(now, label, padding, message);\n console[method](consoleLine);\n this.writeFileLine(fileLine);\n }\n\n private formatConsoleLine(date: Date, label: string, padding: string, message: string): string {\n const timestamp = this.formatTimestamp(date);\n return `${colors.gray(timestamp)} ${label}${padding}${message}`;\n }\n\n private formatFileLine(date: Date, label: string, padding: string, message: string): string {\n const timestamp = this.formatTimestamp(date);\n return `${timestamp} ${label}${padding}${message}`;\n }\n\n private writeFileLine(line: string): void {\n if (!this.logFileEnabled || !this.logFile) return;\n try {\n fs.appendFileSync(this.logFile, `${line}\\n`, 'utf8');\n } catch (error) {\n this.disableFileWithError(error);\n }\n }\n\n private disableFileWithError(error: unknown): void {\n this.logFileEnabled = false;\n if (this.logFileErrored) return;\n this.logFileErrored = true;\n const message = error instanceof Error ? error.message : String(error);\n const target = this.logFile ? ` (${this.logFile})` : '';\n console.warn(`日志文件写入失败${target},已停止写入:${message}`);\n }\n\n private formatTimestamp(date: Date): string {\n const year = date.getFullYear();\n const month = pad2(date.getMonth() + 1);\n const day = pad2(date.getDate());\n const hours = pad2(date.getHours());\n const minutes = pad2(date.getMinutes());\n const seconds = pad2(date.getSeconds());\n return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;\n }\n}\n\n/**\n * 默认日志器实例。\n */\nexport const defaultLogger = new Logger();\n","export interface PlanItem {\n readonly index: number;\n readonly raw: string;\n readonly text: string;\n readonly completed: boolean;\n}\n\nconst ITEM_PATTERN = /^(\\s*)([-*+]|\\d+\\.)\\s+(.*)$/;\n\nfunction isCompleted(content: string): boolean {\n if (content.includes('✅')) return true;\n if (/\\[[xX]\\]/.test(content)) return true;\n return false;\n}\n\nfunction normalizeText(content: string): string {\n return content\n .replace(/\\[[xX ]\\]\\s*/g, '')\n .replace(/✅/g, '')\n .trim();\n}\n\n/**\n * 解析 plan.md 中的计划项。\n */\nexport function parsePlanItems(plan: string): PlanItem[] {\n const lines = plan.split(/\\r?\\n/);\n const items: PlanItem[] = [];\n\n lines.forEach((line, index) => {\n const match = line.match(ITEM_PATTERN);\n if (!match) return;\n const content = match[3] ?? '';\n const text = normalizeText(content);\n if (!text) return;\n items.push({\n index,\n raw: line,\n text,\n completed: isCompleted(content)\n });\n });\n\n return items;\n}\n\n/**\n * 获取尚未完成的计划项。\n */\nexport function getPendingPlanItems(plan: string): PlanItem[] {\n return parsePlanItems(plan).filter(item => !item.completed);\n}\n\n/**\n * 获取最后一条未完成的计划项。\n */\nexport function getLastPendingPlanItem(plan: string): PlanItem | null {\n const pending = getPendingPlanItems(plan);\n if (pending.length === 0) return null;\n return pending[pending.length - 1] ?? null;\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\n\nexport interface QualityCommand {\n readonly name: string;\n readonly command: string;\n}\n\nfunction hasScript(scripts: Record<string, string>, name: string): boolean {\n return typeof scripts[name] === 'string' && scripts[name].trim().length > 0;\n}\n\n/**\n * 读取 package.json,解析可用的代码质量检查命令。\n */\nexport async function detectQualityCommands(workDir: string): Promise<QualityCommand[]> {\n const packagePath = path.join(workDir, 'package.json');\n const exists = await fs.pathExists(packagePath);\n if (!exists) return [];\n\n const pkg = await fs.readJson(packagePath);\n const scripts = typeof pkg === 'object' && pkg && typeof (pkg as { scripts?: unknown }).scripts === 'object'\n ? ((pkg as { scripts: Record<string, string> }).scripts ?? {})\n : {};\n\n const commands: QualityCommand[] = [];\n const seen = new Set<string>();\n\n const append = (name: string, command: string): void => {\n if (seen.has(name)) return;\n if (!hasScript(scripts, name)) return;\n commands.push({ name, command });\n seen.add(name);\n };\n\n append('lint', 'yarn lint');\n append('lint:ci', 'yarn lint:ci');\n append('lint:check', 'yarn lint:check');\n append('typecheck', 'yarn typecheck');\n append('format:check', 'yarn format:check');\n append('format:ci', 'yarn format:ci');\n\n if (!hasScript(scripts, 'format:check') && !hasScript(scripts, 'format:ci')) {\n append('format', 'yarn format');\n }\n\n return commands;\n}\n","import { Logger } from './logger';\nimport { RunMetadata, removeCurrentRegistry, upsertCurrentRegistry, writeRunMetadata } from './logs';\n\nexport interface RunTracker {\n readonly update: (round: number, tokenUsed: number) => Promise<void>;\n readonly finalize: () => Promise<void>;\n}\n\ninterface RunTrackerOptions {\n readonly logFile?: string;\n readonly command: string;\n readonly path: string;\n readonly logger?: Logger;\n}\n\nasync function safeWrite(logFile: string, metadata: RunMetadata, logger?: Logger): Promise<void> {\n try {\n await writeRunMetadata(logFile, metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`写入运行元信息失败: ${message}`);\n }\n try {\n await upsertCurrentRegistry(logFile, metadata);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`更新 current.json 失败: ${message}`);\n }\n}\n\nasync function safeRemove(logFile: string, logger?: Logger): Promise<void> {\n try {\n await removeCurrentRegistry(logFile);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger?.warn(`清理 current.json 失败: ${message}`);\n }\n}\n\n/**\n * 创建运行中任务的追踪器(写入 JSON 元数据)。\n */\nexport async function createRunTracker(options: RunTrackerOptions): Promise<RunTracker | null> {\n const { logFile, command, path, logger } = options;\n if (!logFile) return null;\n\n const update = async (round: number, tokenUsed: number): Promise<void> => {\n const metadata: RunMetadata = {\n command,\n round,\n tokenUsed,\n path,\n pid: process.pid\n };\n await safeWrite(logFile, metadata, logger);\n };\n\n await update(0, 0);\n\n return {\n update,\n finalize: async (): Promise<void> => {\n await safeRemove(logFile, logger);\n }\n };\n}\n","import { DeliverySummary, TestRunResult } from './types';\n\n/**\n * 生成交付摘要提示的输入。\n */\nexport interface SummaryPromptInput {\n readonly task: string;\n readonly plan: string;\n readonly notes: string;\n readonly lastAiOutput: string;\n readonly testResults: TestRunResult[] | null;\n readonly gitStatus: string;\n readonly diffStat: string;\n readonly branchName?: string;\n}\n\n/**\n * 兜底摘要输入。\n */\nexport interface SummaryFallbackInput {\n readonly task: string;\n readonly testResults: TestRunResult[] | null;\n}\n\n/**\n * PR 文案兜底输入。\n */\nexport interface PrBodyFallbackInput {\n readonly commitTitle: string;\n readonly commitBody?: string;\n readonly testResults: TestRunResult[] | null;\n}\n\nconst REQUIRED_SECTIONS = ['# 变更摘要', '# 测试结果', '# 风险与回滚'] as const;\n\nfunction normalizeText(text: string): string {\n return text.replace(/\\r\\n?/g, '\\n');\n}\n\nfunction compactLine(text: string): string {\n return text.replace(/\\s+/g, ' ').trim();\n}\n\nfunction trimTail(text: string, limit: number, emptyFallback: string): string {\n const normalized = normalizeText(text).trim();\n if (!normalized) return emptyFallback;\n if (normalized.length <= limit) return normalized;\n return `(内容过长,保留最后 ${limit} 字符)\\n${normalized.slice(-limit)}`;\n}\n\nfunction formatTestResultLines(testResults: TestRunResult[] | null): string[] {\n if (!testResults || testResults.length === 0) {\n return ['- 未运行(本次未执行测试)'];\n }\n return testResults.map(result => {\n const label = result.kind === 'unit' ? '单元测试' : 'e2e 测试';\n const status = result.success ? '通过' : `失败(退出码 ${result.exitCode})`;\n const command = result.command ? `|命令: ${result.command}` : '';\n return `- ${label}: ${status} ${command}`.trim();\n });\n}\n\nfunction formatTestResultsForPrompt(testResults: TestRunResult[] | null): string {\n return formatTestResultLines(testResults).join('\\n');\n}\n\nfunction buildSummaryLinesFromCommit(commitTitle: string, commitBody?: string): string[] {\n const bulletLines = extractBulletLines(commitBody);\n if (bulletLines.length > 0) return bulletLines;\n const summary = stripCommitType(commitTitle);\n return [`- ${summary}`];\n}\n\nfunction stripCommitType(title: string): string {\n const trimmed = compactLine(title);\n if (!trimmed) return '更新迭代产出';\n const match = trimmed.match(/^[^:]+:\\s*(.+)$/);\n return match?.[1]?.trim() || trimmed;\n}\n\nfunction buildPrBody(summaryLines: string[], testLines: string[]): string {\n const riskLines = ['- 风险:待评估', '- 回滚:git revert 对应提交或关闭 PR'];\n return [\n '# 变更摘要',\n summaryLines.join('\\n'),\n '',\n '# 测试结果',\n testLines.join('\\n'),\n '',\n '# 风险与回滚',\n riskLines.join('\\n')\n ].join('\\n');\n}\n\n/**\n * 构建交付摘要提示词。\n */\nexport function buildSummaryPrompt(input: SummaryPromptInput): string {\n const planSnippet = trimTail(input.plan, 2000, '(计划为空)');\n const notesSnippet = trimTail(input.notes, 4000, '(notes 为空)');\n const aiSnippet = trimTail(input.lastAiOutput, 3000, '(本轮无 AI 输出)');\n const statusSnippet = trimTail(input.gitStatus, 1000, '(git status 为空)');\n const diffSnippet = trimTail(input.diffStat, 1000, '(diff 统计为空)');\n const testSummary = formatTestResultsForPrompt(input.testResults);\n\n return [\n '# 角色',\n '你是资深工程师,需要为本次迭代生成提交信息与 PR 文案。',\n '# 任务',\n '基于输入信息输出严格 JSON(不要 markdown、不要代码块、不要多余文字)。',\n '要求:',\n '- 全部中文。',\n '- commitTitle / prTitle 使用 Conventional Commits 格式:<type>: <概要>,简洁具体,不要出现“自动迭代提交/自动 PR”等字样。',\n '- commitBody 为多行要点列表(可为空字符串)。',\n '- prBody 为 Markdown,必须包含标题:# 变更摘要、# 测试结果、# 风险与回滚,并在变更摘要中体现工作总结。',\n '- 不确定处可基于现有信息合理推断,但不要编造测试结果。',\n '# 输出 JSON',\n '{\"commitTitle\":\"...\",\"commitBody\":\"...\",\"prTitle\":\"...\",\"prBody\":\"...\"}',\n '# 输入信息',\n `任务: ${compactLine(input.task) || '(空)'}`,\n `分支: ${input.branchName ?? '(未知)'}`,\n '计划(节选):',\n planSnippet,\n 'notes(节选):',\n notesSnippet,\n '最近一次 AI 输出(节选):',\n aiSnippet,\n '测试结果:',\n testSummary,\n 'git status --short:',\n statusSnippet,\n 'git diff --stat:',\n diffSnippet\n ].join('\\n\\n');\n}\n\nfunction pickString(record: Record<string, unknown>, keys: string[]): string | null {\n for (const key of keys) {\n const value = record[key];\n if (typeof value === 'string' && value.trim().length > 0) {\n return value.trim();\n }\n }\n return null;\n}\n\nfunction extractJson(text: string): string | null {\n const fenced = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i);\n if (fenced?.[1]) return fenced[1].trim();\n const start = text.indexOf('{');\n const end = text.lastIndexOf('}');\n if (start >= 0 && end > start) {\n return text.slice(start, end + 1).trim();\n }\n return null;\n}\n\nfunction normalizeTitle(title: string): string {\n return compactLine(title);\n}\n\nfunction normalizeBody(body?: string | null): string | undefined {\n if (!body) return undefined;\n const normalized = normalizeText(body).trim();\n return normalized.length > 0 ? normalized : undefined;\n}\n\nfunction extractBulletLines(text?: string | null): string[] {\n if (!text) return [];\n const lines = normalizeText(text)\n .split('\\n')\n .map(line => line.trim())\n .filter(Boolean);\n const bullets = lines.filter(line => line.startsWith('- ') || line.startsWith('* '));\n return bullets.map(line => (line.startsWith('* ') ? `- ${line.slice(2).trim()}` : line));\n}\n\n/**\n * 解析 AI 输出的交付摘要 JSON。\n */\nexport function parseDeliverySummary(output: string): DeliverySummary | null {\n const jsonText = extractJson(output);\n if (!jsonText) return null;\n try {\n const parsed = JSON.parse(jsonText) as Record<string, unknown>;\n let commitTitle = pickString(parsed, ['commitTitle', 'commit_message', 'commitMessage', 'commit_title']);\n let commitBody = pickString(parsed, ['commitBody', 'commit_body']);\n let prTitle = pickString(parsed, ['prTitle', 'pr_title']);\n let prBody = pickString(parsed, ['prBody', 'pr_body']);\n\n const commitObj = parsed.commit;\n if ((!commitTitle || !commitBody) && typeof commitObj === 'object' && commitObj !== null) {\n const commitRecord = commitObj as Record<string, unknown>;\n commitTitle = commitTitle ?? pickString(commitRecord, ['title', 'commitTitle']);\n commitBody = commitBody ?? pickString(commitRecord, ['body', 'commitBody']);\n }\n\n const prObj = parsed.pr;\n if ((!prTitle || !prBody) && typeof prObj === 'object' && prObj !== null) {\n const prRecord = prObj as Record<string, unknown>;\n prTitle = prTitle ?? pickString(prRecord, ['title', 'prTitle']);\n prBody = prBody ?? pickString(prRecord, ['body', 'prBody']);\n }\n\n if (!commitTitle || !prTitle || !prBody) return null;\n\n const normalizedCommitTitle = normalizeTitle(commitTitle);\n const normalizedPrTitle = normalizeTitle(prTitle);\n const normalizedCommitBody = normalizeBody(commitBody);\n const normalizedPrBody = normalizeText(prBody).trim();\n\n if (!normalizedCommitTitle || !normalizedPrTitle || !normalizedPrBody) return null;\n\n return {\n commitTitle: normalizedCommitTitle,\n commitBody: normalizedCommitBody,\n prTitle: normalizedPrTitle,\n prBody: normalizedPrBody\n };\n } catch {\n return null;\n }\n}\n\n/**\n * 构建兜底交付摘要。\n */\nexport function buildFallbackSummary(input: SummaryFallbackInput): DeliverySummary {\n const taskLine = compactLine(input.task);\n const shortTask = taskLine.length > 50 ? `${taskLine.slice(0, 50)}...` : taskLine;\n const baseTitle = shortTask || '更新迭代产出';\n const title = `chore: ${baseTitle}`;\n const summaryLines = [`- ${baseTitle}`];\n const testLines = formatTestResultLines(input.testResults);\n const prBody = buildPrBody(summaryLines, testLines);\n return {\n commitTitle: title,\n commitBody: summaryLines.join('\\n'),\n prTitle: title,\n prBody\n };\n}\n\n/**\n * 确保 PR 文案包含必要章节。\n */\nexport function ensurePrBodySections(prBody: string, fallback: PrBodyFallbackInput): string {\n const normalized = normalizeText(prBody).trim();\n const hasAll = REQUIRED_SECTIONS.every(section => normalized.includes(section));\n if (hasAll) return normalized;\n\n const summaryLines = buildSummaryLinesFromCommit(fallback.commitTitle, fallback.commitBody);\n const testLines = formatTestResultLines(fallback.testResults);\n return buildPrBody(summaryLines, testLines);\n}\n","import { Logger } from './logger';\nimport { isoNow } from './utils';\nimport type { WebhookConfig } from './types';\n\nexport type WebhookEvent = 'task_start' | 'iteration_start' | 'task_end';\n\nexport interface WebhookPayload {\n readonly event: WebhookEvent;\n readonly task: string;\n readonly branch: string;\n readonly iteration: number;\n readonly stage: string;\n readonly timestamp: string;\n}\n\nexport interface WebhookPayloadInput {\n readonly event: WebhookEvent;\n readonly task: string;\n readonly branch?: string;\n readonly iteration: number;\n readonly stage: string;\n readonly timestamp?: string;\n}\n\nexport type FetchLikeResponse = {\n readonly ok: boolean;\n readonly status: number;\n readonly statusText: string;\n};\n\nexport type FetchLike = (url: string, init: {\n readonly method: string;\n readonly headers: Record<string, string>;\n readonly body: string;\n readonly signal?: AbortSignal;\n}) => Promise<FetchLikeResponse>;\n\nconst DEFAULT_TIMEOUT_MS = 8000;\n\nexport function normalizeWebhookUrls(urls?: string[]): string[] {\n if (!urls || urls.length === 0) return [];\n return urls\n .map(url => url.trim())\n .filter(url => url.length > 0);\n}\n\nexport function buildWebhookPayload(input: WebhookPayloadInput): WebhookPayload {\n return {\n event: input.event,\n task: input.task,\n branch: input.branch ?? '',\n iteration: input.iteration,\n stage: input.stage,\n timestamp: input.timestamp ?? isoNow()\n };\n}\n\nfunction resolveFetcher(fetcher?: FetchLike): FetchLike | null {\n if (fetcher) return fetcher;\n const globalFetcher = globalThis.fetch;\n if (typeof globalFetcher !== 'function') return null;\n return (globalFetcher as typeof fetch) as FetchLike;\n}\n\nasync function postWebhook(url: string, payload: WebhookPayload, timeoutMs: number, logger: Logger, fetcher: FetchLike): Promise<void> {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n try {\n const response = await fetcher(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json'\n },\n body: JSON.stringify(payload),\n signal: controller.signal\n });\n if (!response.ok) {\n logger.warn(`webhook 请求失败(${response.status} ${response.statusText}):${url}`);\n } else {\n logger.debug(`webhook 通知成功:${url}`);\n }\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n logger.warn(`webhook 通知异常:${url}|${message}`);\n } finally {\n clearTimeout(timer);\n }\n}\n\nexport async function sendWebhookNotifications(\n config: WebhookConfig | null | undefined,\n payload: WebhookPayload,\n logger: Logger,\n fetcher?: FetchLike\n): Promise<void> {\n const urls = normalizeWebhookUrls(config?.urls);\n if (urls.length === 0) return;\n\n const resolvedFetcher = resolveFetcher(fetcher);\n if (!resolvedFetcher) {\n logger.warn('当前 Node 环境不支持 fetch,已跳过 webhook 通知');\n return;\n }\n\n const timeoutMs = config?.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n await Promise.all(urls.map(url => postWebhook(url, payload, timeoutMs, logger, resolvedFetcher)));\n}\n","import path from 'node:path';\n\nexport type MultiTaskMode = 'relay' | 'serial' | 'serial-continue' | 'parallel';\n\nconst MODE_ALIASES: Record<string, MultiTaskMode> = {\n relay: 'relay',\n serial: 'serial',\n 'serial-continue': 'serial-continue',\n parallel: 'parallel',\n 接力模式: 'relay',\n 接力: 'relay',\n 串行执行: 'serial',\n 串行: 'serial',\n 串行执行但是失败也继续: 'serial-continue',\n 串行继续: 'serial-continue',\n 并行执行: 'parallel',\n 并行: 'parallel'\n};\n\n/**\n * 解析多任务执行模式。\n */\nexport function parseMultiTaskMode(raw?: string): MultiTaskMode {\n if (!raw) return 'relay';\n const trimmed = raw.trim();\n if (!trimmed) return 'relay';\n const resolved = MODE_ALIASES[trimmed];\n if (!resolved) {\n throw new Error(`未知 multi-task 模式: ${raw}`);\n }\n return resolved;\n}\n\n/**\n * 规范化任务列表(去空白、剔除空项)。\n */\nexport function normalizeTaskList(input: string[] | string | undefined): string[] {\n if (Array.isArray(input)) {\n return input.map(task => task.trim()).filter(task => task.length > 0);\n }\n if (typeof input === 'string') {\n const trimmed = input.trim();\n return trimmed.length > 0 ? [trimmed] : [];\n }\n return [];\n}\n\nexport interface TaskPlanInput {\n readonly tasks: string[];\n readonly mode: MultiTaskMode;\n readonly useWorktree: boolean;\n readonly baseBranch: string;\n readonly branchInput?: string;\n readonly worktreePath?: string;\n readonly logFile?: string;\n}\n\nexport interface TaskPlan {\n readonly task: string;\n readonly index: number;\n readonly branchName?: string;\n readonly baseBranch: string;\n readonly worktreePath?: string;\n readonly logFile?: string;\n}\n\nfunction buildBranchNameSeries(branchInput: string | undefined, total: number): Array<string | undefined> {\n if (total <= 0) return [];\n if (!branchInput) {\n return Array.from({ length: total }, () => undefined);\n }\n const baseName = branchInput;\n const names: Array<string | undefined> = [baseName];\n for (let i = 1; i < total; i += 1) {\n names.push(`${baseName}-${i + 1}`);\n }\n return names;\n}\n\nfunction appendPathSuffix(filePath: string, suffix: string): string {\n const parsed = path.parse(filePath);\n const nextName = parsed.name ? `${parsed.name}-${suffix}` : suffix;\n return path.join(parsed.dir, `${nextName}${parsed.ext}`);\n}\n\nfunction deriveIndexedPath(basePath: string | undefined, index: number, total: number, label: string): string | undefined {\n if (!basePath) return undefined;\n if (total <= 1 || index === 0) return basePath;\n return appendPathSuffix(basePath, `${label}-${index + 1}`);\n}\n\n/**\n * 构建多任务执行计划。\n */\nexport function buildTaskPlans(input: TaskPlanInput): TaskPlan[] {\n const total = input.tasks.length;\n if (total === 0) return [];\n\n const branchNames: Array<string | undefined> = input.useWorktree\n ? buildBranchNameSeries(input.branchInput, total)\n : input.tasks.map(() => input.branchInput);\n\n return input.tasks.map((task, index) => {\n const relayBaseBranch = input.useWorktree && input.mode === 'relay' && index > 0\n ? branchNames[index - 1] ?? input.baseBranch\n : input.baseBranch;\n\n return {\n task,\n index,\n branchName: branchNames[index],\n baseBranch: relayBaseBranch,\n worktreePath: deriveIndexedPath(input.worktreePath, index, total, 'task'),\n logFile: deriveIndexedPath(input.logFile, index, total, 'task')\n };\n });\n}\n","import fs from 'fs-extra';\nimport path from 'node:path';\nimport { CurrentRegistryEntry, getLogsDir, readCurrentRegistry, removeCurrentRegistry } from './logs';\n\ninterface TaskView {\n readonly key: string;\n readonly logFile: string;\n readonly meta: CurrentRegistryEntry;\n readonly lines: string[];\n}\n\ninterface ConfirmState {\n readonly key: string;\n}\n\ninterface TerminationResult {\n readonly message: string;\n readonly isError: boolean;\n readonly removed: boolean;\n}\n\ninterface MonitorState {\n tasks: TaskView[];\n selectedIndex: number;\n selectedKey?: string;\n lineOffsets: Map<string, number>;\n stickToBottom: Map<string, boolean>;\n lastError?: string;\n confirm?: ConfirmState;\n statusMessage?: string;\n statusIsError?: boolean;\n}\n\nconst REFRESH_INTERVAL = 1000;\nconst TERMINATE_GRACE_MS = 800;\n\nfunction getTerminalSize(): { rows: number; columns: number } {\n const rows = process.stdout.rows ?? 24;\n const columns = process.stdout.columns ?? 80;\n return { rows, columns };\n}\n\nfunction truncateLine(line: string, width: number): string {\n if (width <= 0) return '';\n if (line.length <= width) return line;\n return line.slice(0, width);\n}\n\nfunction padLine(text: string, width: number): string {\n if (width <= 0) return '';\n const truncated = text.length > width ? text.slice(0, width) : text;\n const padding = width - truncated.length;\n const left = Math.floor(padding / 2);\n const right = padding - left;\n return `${' '.repeat(left)}${truncated}${' '.repeat(right)}`;\n}\n\nexport function buildConfirmDialogLines(taskKey: string, columns: number): string[] {\n if (columns <= 0) return [];\n const message = `确认终止任务 ${taskKey}?`;\n const hint = 'y 确认 / n 取消';\n const minWidth = Math.max(message.length, hint.length, 4);\n const innerWidth = Math.min(columns - 2, minWidth);\n if (innerWidth <= 0) {\n return [truncateLine(message, columns), truncateLine(hint, columns)];\n }\n const border = `+${'-'.repeat(innerWidth)}+`;\n const lines = [\n border,\n `|${padLine(message, innerWidth)}|`,\n `|${padLine(hint, innerWidth)}|`,\n border\n ];\n return lines.map(line => truncateLine(line, columns));\n}\n\nfunction applyDialogOverlay(lines: string[], dialogLines: string[]): void {\n if (lines.length === 0 || dialogLines.length === 0) return;\n const start = Math.max(0, Math.floor((lines.length - dialogLines.length) / 2));\n for (let i = 0; i < dialogLines.length && start + i < lines.length; i += 1) {\n lines[start + i] = dialogLines[i];\n }\n}\n\nexport function resolveTerminationTarget(pid: number, platform: NodeJS.Platform = process.platform): number {\n return platform === 'win32' ? pid : -pid;\n}\n\nfunction isProcessAlive(pid: number): boolean {\n if (!Number.isFinite(pid) || pid <= 0) return false;\n try {\n process.kill(pid, 0);\n return true;\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code === 'ESRCH') return false;\n return true;\n }\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nfunction setStatus(state: MonitorState, message?: string, isError = false): void {\n state.statusMessage = message;\n state.statusIsError = message ? isError : false;\n}\n\nfunction findTaskByKey(state: MonitorState, key: string): TaskView | undefined {\n return state.tasks.find(task => task.key === key);\n}\n\nasync function safeRemoveRegistry(logFile: string): Promise<void> {\n try {\n await removeCurrentRegistry(logFile);\n } catch {\n // 忽略清理失败,避免阻断 monitor 刷新\n }\n}\n\nasync function readLogLines(logFile: string): Promise<string[]> {\n try {\n const content = await fs.readFile(logFile, 'utf8');\n const normalized = content.replace(/\\r\\n?/g, '\\n');\n const lines = normalized.split('\\n');\n return lines.length > 0 ? lines : [''];\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return [`(无法读取日志文件:${message})`];\n }\n}\n\nasync function loadTasks(logsDir: string): Promise<TaskView[]> {\n const registry = await readCurrentRegistry();\n const entries = Object.entries(registry).sort(([a], [b]) => a.localeCompare(b));\n const aliveEntries: Array<[string, CurrentRegistryEntry]> = [];\n for (const [key, meta] of entries) {\n const pid = typeof meta.pid === 'number' ? meta.pid : undefined;\n if (pid && !isProcessAlive(pid)) {\n const logFile = meta.logFile ?? path.join(logsDir, key);\n await safeRemoveRegistry(logFile);\n continue;\n }\n aliveEntries.push([key, meta]);\n }\n const tasks = await Promise.all(aliveEntries.map(async ([key, meta]) => {\n const logFile = meta.logFile ?? path.join(logsDir, key);\n const lines = await readLogLines(logFile);\n return {\n key,\n logFile,\n meta,\n lines\n } satisfies TaskView;\n }));\n return tasks;\n}\n\nfunction buildHeader(state: MonitorState, columns: number): string {\n if (state.tasks.length === 0) {\n return truncateLine('暂无运行中的任务,按 q 退出', columns);\n }\n const current = state.tasks[state.selectedIndex];\n const total = state.tasks.length;\n const index = state.selectedIndex + 1;\n const title = `任务 ${index}/${total} | ${current.key} | ←/→ 切换任务 ↑/↓ 上下 1 行 PageUp/PageDown 翻页 t 终止 q 退出`;\n return truncateLine(title, columns);\n}\n\nfunction buildStatus(\n task: TaskView,\n page: { current: number; total: number },\n columns: number,\n errorMessage?: string,\n statusMessage?: string,\n statusIsError?: boolean\n): string {\n const meta = task.meta;\n const status = `轮次 ${meta.round} | Token ${meta.tokenUsed} | 页 ${page.current}/${page.total} | 项目 ${meta.path}`;\n const extras: string[] = [];\n if (errorMessage) {\n extras.push(`刷新失败:${errorMessage}`);\n }\n if (statusMessage) {\n extras.push(statusIsError ? `操作失败:${statusMessage}` : statusMessage);\n }\n const suffix = extras.length > 0 ? ` | ${extras.join(' | ')}` : '';\n return truncateLine(`${status}${suffix}`, columns);\n}\n\nfunction getPageSize(rows: number): number {\n return Math.max(1, rows - 2);\n}\n\nfunction render(state: MonitorState): void {\n const { rows, columns } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const header = buildHeader(state, columns);\n\n if (state.tasks.length === 0) {\n const filler = Array.from({ length: pageSize }, () => '');\n const statusText = state.lastError\n ? `刷新失败:${state.lastError}`\n : state.statusMessage\n ? (state.statusIsError ? `操作失败:${state.statusMessage}` : state.statusMessage)\n : '等待后台任务启动…';\n const status = truncateLine(statusText, columns);\n const content = [header, ...filler, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n return;\n }\n\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const stick = state.stickToBottom.get(current.key) ?? true;\n const nextOffset = Math.min(Math.max(stick ? maxOffset : offset, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n\n const start = nextOffset;\n const pageLines = lines.slice(start, start + pageSize).map(line => truncateLine(line, columns));\n while (pageLines.length < pageSize) {\n pageLines.push('');\n }\n\n const totalPages = Math.max(1, Math.ceil(lines.length / pageSize));\n const currentPage = Math.min(totalPages, Math.floor(nextOffset / pageSize) + 1);\n const status = buildStatus(\n current,\n { current: currentPage, total: totalPages },\n columns,\n state.lastError,\n state.statusMessage,\n state.statusIsError\n );\n if (state.confirm) {\n const dialogLines = buildConfirmDialogLines(state.confirm.key, columns);\n applyDialogOverlay(pageLines, dialogLines);\n }\n const content = [header, ...pageLines, status].join('\\n');\n process.stdout.write(`\\u001b[2J\\u001b[H${content}`);\n}\n\nfunction updateSelection(state: MonitorState, tasks: TaskView[]): void {\n state.tasks = tasks;\n if (tasks.length === 0) {\n state.selectedIndex = 0;\n state.selectedKey = undefined;\n return;\n }\n\n if (state.selectedKey) {\n const index = tasks.findIndex(task => task.key === state.selectedKey);\n if (index >= 0) {\n state.selectedIndex = index;\n } else {\n state.selectedIndex = 0;\n }\n } else {\n state.selectedIndex = 0;\n }\n\n state.selectedKey = tasks[state.selectedIndex]?.key;\n\n const existing = new Set(tasks.map(task => task.key));\n for (const key of state.lineOffsets.keys()) {\n if (!existing.has(key)) {\n state.lineOffsets.delete(key);\n }\n }\n for (const key of state.stickToBottom.keys()) {\n if (!existing.has(key)) {\n state.stickToBottom.delete(key);\n }\n }\n if (state.confirm && !existing.has(state.confirm.key)) {\n state.confirm = undefined;\n }\n}\n\nfunction moveSelection(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const total = state.tasks.length;\n state.selectedIndex = (state.selectedIndex + direction + total) % total;\n state.selectedKey = state.tasks[state.selectedIndex]?.key;\n}\n\nfunction moveLine(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const { rows } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const nextOffset = Math.min(Math.max(offset + direction, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n}\n\nfunction movePage(state: MonitorState, direction: -1 | 1): void {\n if (state.tasks.length === 0) return;\n const { rows } = getTerminalSize();\n const pageSize = getPageSize(rows);\n const current = state.tasks[state.selectedIndex];\n const lines = current.lines;\n const maxOffset = Math.max(0, lines.length - pageSize);\n const offset = state.lineOffsets.get(current.key) ?? maxOffset;\n const nextOffset = Math.min(Math.max(offset + direction * pageSize, 0), maxOffset);\n state.lineOffsets.set(current.key, nextOffset);\n state.stickToBottom.set(current.key, nextOffset === maxOffset);\n}\n\nasync function terminateTask(task: TaskView): Promise<TerminationResult> {\n const pid = typeof task.meta.pid === 'number' ? task.meta.pid : undefined;\n if (!pid || pid <= 0) {\n return { message: '任务未记录 PID,无法终止', isError: true, removed: false };\n }\n const target = resolveTerminationTarget(pid);\n try {\n process.kill(target, 'SIGTERM');\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code === 'ESRCH') {\n await safeRemoveRegistry(task.logFile);\n return { message: `任务 ${task.key} 已结束`, isError: false, removed: true };\n }\n const message = error instanceof Error ? error.message : String(error);\n return { message: `发送终止信号失败:${message}`, isError: true, removed: false };\n }\n\n await sleep(TERMINATE_GRACE_MS);\n if (!isProcessAlive(pid)) {\n await safeRemoveRegistry(task.logFile);\n return { message: `任务 ${task.key} 已终止`, isError: false, removed: true };\n }\n return { message: `已发送终止信号,任务仍在运行`, isError: false, removed: false };\n}\n\nasync function terminateTaskByKey(state: MonitorState, key: string, refresh: () => Promise<void>): Promise<void> {\n const task = findTaskByKey(state, key);\n if (!task) {\n setStatus(state, `任务 ${key} 已不存在`, true);\n render(state);\n return;\n }\n const result = await terminateTask(task);\n setStatus(state, result.message, result.isError);\n if (result.removed) {\n await refresh();\n render(state);\n return;\n }\n render(state);\n}\n\nfunction shouldExit(input: string): boolean {\n if (input === '\\u0003') return true;\n if (input.toLowerCase() === 'q') return true;\n return false;\n}\n\nfunction handleInput(state: MonitorState, input: string, refresh: () => Promise<void>): void {\n const lower = input.toLowerCase();\n if (state.confirm) {\n if (lower.includes('y')) {\n const key = state.confirm.key;\n state.confirm = undefined;\n setStatus(state, `正在终止任务 ${key}...`);\n void terminateTaskByKey(state, key, refresh);\n return;\n }\n if (lower.includes('n') || input === '\\u001b') {\n state.confirm = undefined;\n setStatus(state, '已取消终止');\n return;\n }\n return;\n }\n\n if (input.includes('\\u001b[D')) {\n moveSelection(state, -1);\n return;\n }\n if (input.includes('\\u001b[C')) {\n moveSelection(state, 1);\n return;\n }\n if (input.includes('\\u001b[A')) {\n moveLine(state, -1);\n return;\n }\n if (input.includes('\\u001b[B')) {\n moveLine(state, 1);\n return;\n }\n if (input.includes('\\u001b[5~')) {\n movePage(state, -1);\n return;\n }\n if (input.includes('\\u001b[6~')) {\n movePage(state, 1);\n return;\n }\n if (lower.includes('t')) {\n if (state.tasks.length === 0) {\n setStatus(state, '暂无可终止的任务', true);\n return;\n }\n const current = state.tasks[state.selectedIndex];\n if (typeof current.meta.pid !== 'number' || current.meta.pid <= 0) {\n setStatus(state, '任务未记录 PID,无法终止', true);\n return;\n }\n state.confirm = { key: current.key };\n setStatus(state, undefined);\n }\n}\n\nfunction setupCleanup(cleanup: () => void): void {\n const exitHandler = (): void => {\n cleanup();\n };\n const signalHandler = (): void => {\n cleanup();\n process.exit(0);\n };\n process.on('SIGINT', signalHandler);\n process.on('SIGTERM', signalHandler);\n process.on('exit', exitHandler);\n}\n\n/**\n * 启动 monitor 终端界面。\n */\nexport async function runMonitor(): Promise<void> {\n if (!process.stdout.isTTY || !process.stdin.isTTY) {\n console.log('当前终端不支持交互式 monitor。');\n return;\n }\n\n const logsDir = getLogsDir();\n const state: MonitorState = {\n tasks: [],\n selectedIndex: 0,\n lineOffsets: new Map(),\n stickToBottom: new Map()\n };\n\n let cleaned = false;\n const cleanup = (): void => {\n if (cleaned) return;\n cleaned = true;\n if (process.stdin.isTTY) {\n process.stdin.setRawMode(false);\n process.stdin.pause();\n }\n process.stdout.write('\\u001b[?25h');\n };\n\n setupCleanup(cleanup);\n process.stdout.write('\\u001b[?25l');\n process.stdin.setRawMode(true);\n process.stdin.resume();\n\n let refreshing = false;\n\n const refresh = async (): Promise<void> => {\n if (refreshing) return;\n refreshing = true;\n try {\n const tasks = await loadTasks(logsDir);\n state.lastError = undefined;\n updateSelection(state, tasks);\n render(state);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n state.lastError = message;\n render(state);\n } finally {\n refreshing = false;\n }\n };\n\n await refresh();\n\n const timer = setInterval(refresh, REFRESH_INTERVAL);\n\n process.stdin.on('data', (data: Buffer) => {\n const input = data.toString('utf8');\n if (shouldExit(input)) {\n clearInterval(timer);\n cleanup();\n process.exit(0);\n }\n handleInput(state, input, refresh);\n render(state);\n });\n\n process.stdout.on('resize', () => {\n render(state);\n });\n}\n","import { open as openFile } from 'node:fs/promises';\nimport fs from 'fs-extra';\n\nexport interface LogTailOptions {\n readonly filePath: string;\n readonly startFromEnd?: boolean;\n readonly pollIntervalMs?: number;\n readonly onLine: (line: string) => void;\n readonly onError?: (message: string) => void;\n}\n\nexport interface LogTailHandle {\n stop: () => Promise<void>;\n}\n\nfunction normalizeChunk(chunk: string): string {\n return chunk.replace(/\\r\\n?/g, '\\n');\n}\n\n/**\n * 轮询尾读日志文件,按行输出。\n */\nexport async function tailLogFile(options: LogTailOptions): Promise<LogTailHandle> {\n const intervalMs = options.pollIntervalMs ?? 200;\n let offset = 0;\n let buffer = '';\n let reading = false;\n let stopped = false;\n\n if (options.startFromEnd) {\n try {\n const stat = await fs.stat(options.filePath);\n offset = stat.size;\n } catch {\n offset = 0;\n }\n }\n\n const flushBuffer = (): void => {\n if (!buffer) return;\n options.onLine(buffer);\n buffer = '';\n };\n\n const emitChunk = (chunk: string): void => {\n buffer += normalizeChunk(chunk);\n const parts = buffer.split('\\n');\n buffer = parts.pop() ?? '';\n for (const line of parts) {\n options.onLine(line);\n }\n };\n\n const readNew = async (): Promise<void> => {\n if (reading || stopped) return;\n reading = true;\n try {\n const stat = await fs.stat(options.filePath);\n if (stat.size < offset) {\n offset = stat.size;\n buffer = '';\n }\n if (stat.size > offset) {\n const length = stat.size - offset;\n const handle = await openFile(options.filePath, 'r');\n try {\n const payload = Buffer.alloc(length);\n const result = await handle.read(payload, 0, length, offset);\n offset += result.bytesRead;\n if (result.bytesRead > 0) {\n const text = payload.subarray(0, result.bytesRead).toString('utf8');\n emitChunk(text);\n }\n } finally {\n await handle.close();\n }\n }\n } catch (error) {\n const err = error as NodeJS.ErrnoException;\n if (err?.code !== 'ENOENT') {\n const message = err instanceof Error ? err.message : String(err);\n options.onError?.(message);\n }\n } finally {\n reading = false;\n }\n };\n\n const timer = setInterval(() => {\n void readNew();\n }, intervalMs);\n\n await readNew();\n\n return {\n stop: async () => {\n if (stopped) return;\n stopped = true;\n clearInterval(timer);\n flushBuffer();\n }\n };\n}\n"],"mappings":"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","names":["import_fs_extra","import_node_path","path","fs","path","import_node_path","import_fs_extra","path","os","fs","import_node_path","path","import_node_os","import_node_path","import_fs_extra","path","os","fs","import_fs_extra","status","content","fs","import_fs_extra","import_node_path","path","fs","getTerminalSize","truncateLine","getPageSize","buildListLine","ensureListOffset","status","content","render","shouldExit","isArrowUp","isArrowDown","setupCleanup","clampIndex","import_fs_extra","import_node_path","import_node_path","import_fs_extra","path","fs","import_fs_extra","fs","import_fs_extra","import_node_path","path","fs","path","normalizeText","compactLine","extractJson","path","fs","import_node_path","path","import_fs_extra","import_node_path","getTerminalSize","truncateLine","readLogLines","fs","path","buildHeader","buildStatus","getPageSize","render","status","content","shouldExit","setupCleanup","import_fs_extra","fs","openFile","fs"]}
|