yg-team-cli 2.1.2 → 2.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +3 -3
- package/dist/cli.js.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/logger.ts","../src/lib/utils.ts","../src/lib/claude.ts","../src/lib/template-version.ts","../src/lib/user-config.ts","../src/lib/gitlab-api.ts","../src/commands/init.ts","../src/commands/breakdown.ts","../src/commands/dev.ts","../src/commands/add-feature.ts","../src/commands/split-prd.ts","../src/commands/bugfix.ts","../src/commands/lint.ts","../src/commands/status.ts","../src/commands/detect-deps.ts","../src/commands/sync-memory.ts","../src/commands/check-api.ts","../src/commands/logs.ts","../src/commands/update.ts","../src/commands/config.ts","../src/commands/diff.ts","../src/index.ts","../src/cli.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import chalk from 'chalk';\nimport ora, { Ora } from 'ora';\n\n/**\n * 颜色输出类\n */\nexport class Logger {\n private spinner: Ora | null = null;\n\n /**\n * 打印标题(加粗)\n */\n header(text: string): void {\n console.log(chalk.bold(text));\n }\n\n /**\n * 打印成功信息(绿色)\n */\n success(text: string): void {\n console.log(chalk.green('✓'), text);\n }\n\n /**\n * 打印错误信息(红色)\n */\n error(text: string): void {\n console.error(chalk.red('✗'), text);\n }\n\n /**\n * 打印警告信息(黄色)\n */\n warn(text: string): void {\n console.warn(chalk.yellow('⚠'), text);\n }\n\n /**\n * 打印信息(蓝色)\n */\n info(text: string): void {\n console.info(chalk.blue('ℹ'), text);\n }\n\n /**\n * 打印步骤信息\n */\n step(text: string): void {\n console.log(chalk.cyan('→'), text);\n }\n\n /**\n * 打印空行\n */\n newLine(): void {\n console.log('');\n }\n\n /**\n * 打印分隔线\n */\n separator(char = '─', length = 50): void {\n console.log(chalk.gray(char.repeat(length)));\n }\n\n /**\n * 开始加载动画\n */\n startLoading(text: string): Ora {\n this.spinner = ora({\n text,\n color: 'cyan',\n }).start();\n return this.spinner;\n }\n\n /**\n * 更新加载文本\n */\n updateLoading(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * 停止加载并显示成功\n */\n succeedLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示失败\n */\n failLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示警告\n */\n warnLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示信息\n */\n infoLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * 打印表格\n */\n table(headers: string[], rows: string[][]): void {\n const columnWidths = headers.map((h, i) => {\n const maxWidth = Math.max(\n h.length,\n ...rows.map((row) => (row[i] || '').length)\n );\n return maxWidth + 2;\n });\n\n // 打印表头\n const headerRow = headers\n .map((h, i) => chalk.bold(h.padEnd(columnWidths[i])))\n .join('');\n console.log(headerRow);\n\n // 打印分隔线\n const separator = columnWidths.map((w) => '─'.repeat(w)).join('┼');\n console.log(chalk.gray(separator));\n\n // 打印数据行\n rows.forEach((row) => {\n const dataRow = row\n .map((cell, i) => (cell || '').padEnd(columnWidths[i]))\n .join('');\n console.log(dataRow);\n });\n }\n\n /**\n * 打印代码块\n */\n code(code: string, language = ''): void {\n if (language) {\n console.log(chalk.gray(`\\`\\`\\`${language}`));\n }\n console.log(chalk.gray(code));\n if (language) {\n console.log(chalk.gray('```'));\n }\n }\n\n /**\n * 打印列表\n */\n list(items: string[], indent = 2): void {\n items.forEach((item) => {\n console.log(' '.repeat(indent) + chalk.gray('•') + ' ' + item);\n });\n }\n\n /**\n * 打印带标签的文本\n */\n labeled(label: string, text: string, labelColor = 'blue'): void {\n const coloredLabel = chalk[labelColor as keyof typeof chalk](`[${label}]`);\n console.log(`${coloredLabel} ${text}`);\n }\n}\n\n// 导出单例\nexport const logger = new Logger();\n\n/**\n * 确认提示(用于重要操作)\n */\nexport async function confirm(message: string): Promise<boolean> {\n const inquirer = await import('inquirer');\n const { confirm } = await inquirer.default.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message,\n default: false,\n },\n ]);\n return confirm;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport type { Spec } from '../types/index.js';\n\n/**\n * 文件工具类\n */\nexport class FileUtils {\n /**\n * 确保目录存在\n */\n static async ensureDir(dir: string): Promise<void> {\n await fs.ensureDir(dir);\n }\n\n /**\n * 读取文件内容\n */\n static async read(file: string): Promise<string> {\n return await fs.readFile(file, 'utf-8');\n }\n\n /**\n * 写入文件内容\n */\n static async write(file: string, content: string): Promise<void> {\n await fs.writeFile(file, content, 'utf-8');\n }\n\n /**\n * 检查文件是否存在\n */\n static async exists(file: string): Promise<boolean> {\n return await fs.pathExists(file);\n }\n\n /**\n * 复制文件\n */\n static async copy(src: string, dest: string): Promise<void> {\n await fs.copy(src, dest);\n }\n\n /**\n * 删除文件或目录\n */\n static async remove(file: string): Promise<void> {\n await fs.remove(file);\n }\n\n /**\n * 移动文件\n */\n static async move(src: string, dest: string): Promise<void> {\n await fs.move(src, dest);\n }\n\n /**\n * 使用 glob 查找文件\n */\n static async findFiles(pattern: string, cwd?: string): Promise<string[]> {\n return await glob(pattern, {\n cwd,\n absolute: false,\n nodir: true,\n });\n }\n\n /**\n * 读取 JSON 文件\n */\n static async readJson<T = any>(file: string): Promise<T> {\n return await fs.readJson(file);\n }\n\n /**\n * 写入 JSON 文件\n */\n static async writeJson(file: string, data: any): Promise<void> {\n await fs.writeJson(file, data, { spaces: 2 });\n }\n}\n\n/**\n * 字符串工具类\n */\nexport class StringUtils {\n /**\n * 转换为 kebab-case\n */\n static toKebabCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^\\w\\-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 转换为 PascalCase\n */\n static toPascalCase(str: string): string {\n return str\n .replace(/[-_\\s](\\w)/g, (_, c) => c.toUpperCase())\n .replace(/^\\w/, (c) => c.toUpperCase());\n }\n\n /**\n * 转换为 camelCase\n */\n static toCamelCase(str: string): string {\n const pascal = this.toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n }\n\n /**\n * 转换为 snake_case\n */\n static toSnakeCase(str: string): string {\n return str\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .replace(/^_/, '')\n .replace(/-+/g, '_')\n .replace(/[\\s]+/g, '_');\n }\n\n /**\n * 首字母大写\n */\n static capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * 截断字符串\n */\n static truncate(str: string, length: number, suffix = '...'): string {\n if (str.length <= length) return str;\n return str.slice(0, length - suffix.length) + suffix;\n }\n\n /**\n * 生成 slug\n */\n static slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n}\n\n/**\n * 数组工具类\n */\nexport class ArrayUtils {\n /**\n * 数组去重\n */\n static unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n }\n\n /**\n * 数组分组\n */\n static groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]> {\n return arr.reduce((result, item) => {\n const key = keyFn(item);\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n return result;\n }, {} as Record<string, T[]>);\n }\n\n /**\n * 数组分块\n */\n static chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n }\n\n /**\n * 数组乱序\n */\n static shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n}\n\n/**\n * 日期工具类\n */\nexport class DateUtils {\n /**\n * 格式化日期\n */\n static format(date: Date = new Date(), format = 'YYYY-MM-DD HH:mm:ss'): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n\n return format\n .replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds);\n }\n\n /**\n * 获取相对时间\n */\n static relative(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 7) {\n return DateUtils.format(date, 'YYYY-MM-DD');\n } else if (days > 0) {\n return `${days} 天前`;\n } else if (hours > 0) {\n return `${hours} 小时前`;\n } else if (minutes > 0) {\n return `${minutes} 分钟前`;\n } else {\n return '刚刚';\n }\n }\n}\n\n/**\n * Git 工具类\n */\nexport class GitUtils {\n /**\n * 检查是否在 Git 仓库中\n */\n static async isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n const gitDir = path.join(cwd, '.git');\n return await FileUtils.exists(gitDir);\n }\n\n /**\n * 获取当前分支名\n */\n static async getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd,\n });\n return stdout.trim();\n }\n\n /**\n * 获取当前 commit hash\n */\n static async getCurrentCommit(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd });\n return stdout.trim().slice(0, 7);\n }\n}\n\n/**\n * Spec 解析工具类\n */\nexport class SpecUtils {\n /**\n * 解析 spec 文件\n */\n static async parseSpec(file: string): Promise<Partial<Spec>> {\n const content = await FileUtils.read(file);\n const spec: Partial<Spec> = {};\n\n // 解析标题\n const titleMatch = content.match(/^#\\s+(.+)$/m);\n if (titleMatch) {\n spec.title = titleMatch[1];\n }\n\n // 解析功能名称\n const nameMatch = content.match(/\\*\\*功能名称\\*\\*:\\s*(.+)$/m);\n if (nameMatch) {\n spec.name = nameMatch[1];\n }\n\n // 解析优先级\n const priorityMatch = content.match(/\\*\\*优先级\\*\\*:\\s*(P[0-2])/);\n if (priorityMatch) {\n spec.priority = priorityMatch[1] as 'P0' | 'P1' | 'P2';\n }\n\n // 解析状态\n const statusMatch = content.match(/\\*\\*状态\\*\\*:\\s*(.+)$/m);\n if (statusMatch) {\n spec.status = statusMatch[1] as Spec['status'];\n }\n\n // 解析依赖\n const depSection = content.match(/## 依赖关系\\s+([\\s\\S]+?)##/m);\n if (depSection) {\n const depMatches = depSection[1].matchAll(/- \\[([ x])\\]\\s*(.+)$/gm);\n spec.dependencies = Array.from(depMatches).map((m) => ({\n completed: m[1] === 'x',\n name: m[2],\n }));\n }\n\n return spec;\n }\n\n /**\n * 获取 spec 状态\n */\n static async getSpecStatus(file: string): Promise<string> {\n try {\n const spec = await this.parseSpec(file);\n return spec.status || '未知';\n } catch {\n return '错误';\n }\n }\n}\n\n/**\n * 模板工具类\n */\nexport class TemplateUtils {\n /**\n * 渲染模板(简单变量替换)\n */\n static render(template: string, data: Record<string, any>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n return data[key] !== undefined ? String(data[key]) : '';\n });\n }\n\n /**\n * 渲染 Handlebars 模板\n */\n static async renderHandlebars(\n template: string,\n data: Record<string, any>\n ): Promise<string> {\n const Handlebars = await import('handlebars');\n const compiled = Handlebars.default.compile(template);\n return compiled(data);\n }\n}\n\n/**\n * 验证工具类\n */\nexport class ValidationUtils {\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n\n /**\n * 验证邮箱\n */\n static validateEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n }\n\n /**\n * 验证 URL\n */\n static validateUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { execa } from 'execa';\nimport path from 'path';\nimport { logger } from './logger.js';\nimport { FileUtils } from './utils.js';\n\n/**\n * Claude AI 集成类\n */\nexport class ClaudeAI {\n private verbose: boolean;\n\n constructor(verbose = false) {\n this.verbose = verbose;\n }\n\n /**\n * 检查 Claude CLI 是否已安装\n */\n async checkInstalled(): Promise<boolean> {\n try {\n await execa('claude', ['--version'], { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 获取 Claude 版本\n */\n async getVersion(): Promise<string> {\n try {\n const { stdout } = await execa('claude', ['--version'], { stdio: 'pipe' });\n return stdout.trim();\n } catch {\n throw new Error('无法获取 Claude 版本');\n }\n }\n\n /**\n * 发送 prompt 到 Claude\n */\n async prompt(promptText: string, options?: PromptOptions): Promise<string> {\n const spinner = logger.startLoading('正在调用 Claude...');\n\n try {\n // 构建最终的 prompt(包含上下文文件内容)\n let finalPrompt = promptText;\n const validContextFiles: string[] = [];\n\n // 验证并读取上下文文件\n if (options?.contextFiles && options.contextFiles.length > 0) {\n for (const file of options.contextFiles) {\n const exists = await FileUtils.exists(file);\n if (exists) {\n validContextFiles.push(file);\n } else {\n logger.warn(`上下文文件不存在,已跳过: ${file}`);\n }\n }\n\n // 将上下文文件内容添加到 prompt 开头\n if (validContextFiles.length > 0) {\n const contextParts: string[] = [];\n for (const file of validContextFiles) {\n try {\n const content = await FileUtils.read(file);\n const fileName = path.basename(file);\n contextParts.push(`## Context from ${fileName}\\n\\n${content}`);\n } catch (error) {\n logger.warn(`无法读取文件 ${file},已跳过`);\n }\n }\n\n if (contextParts.length > 0) {\n finalPrompt = `${contextParts.join('\\n\\n---\\n\\n')}\\n\\n---\\n\\n${promptText}`;\n }\n }\n }\n\n // 构建参数数组\n const args: string[] = ['--no-confirm', '-p', finalPrompt];\n\n const result = await execa('claude', args, {\n stdio: this.verbose ? 'inherit' : 'pipe',\n timeout: options?.timeout || 300000, // 默认 5 分钟\n reject: false, // 不自动拒绝非零退出码\n });\n\n spinner.succeed('Claude 响应完成');\n\n // 检查退出码\n if (result.exitCode !== 0 && !result.stdout) {\n const stderr = result.stderr || '';\n throw new Error(`Claude 命令执行失败 (退出码: ${result.exitCode})${stderr ? `\\n${stderr}` : ''}`);\n }\n\n return result.stdout || '';\n } catch (error: any) {\n spinner.fail('Claude 调用失败');\n if (error.killed && error.signal === 'SIGTERM') {\n throw new Error('Claude 执行超时');\n }\n // 提供更详细的错误信息\n const stderr = error.stderr || '';\n const exitCode = error.exitCode !== undefined ? ` (退出码: ${error.exitCode})` : '';\n throw new Error(`Claude 调用失败: ${error.message}${exitCode}${stderr ? `\\n${stderr}` : ''}`);\n }\n }\n\n /**\n * 使用 prompt 模板和参数发送请求\n */\n async promptWithTemplate(\n template: string,\n data: Record<string, any>,\n options?: PromptOptions\n ): Promise<string> {\n // 简单的模板替换\n let promptText = template;\n for (const [key, value] of Object.entries(data)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n promptText = promptText.replace(regex, String(value));\n }\n\n return await this.prompt(promptText, options);\n }\n\n /**\n * 发送对话(支持上下文)\n */\n async chat(messages: ChatMessage[], options?: PromptOptions): Promise<string> {\n const spinner = logger.startLoading('正在调用 Claude...');\n\n try {\n // 构建完整的 prompt\n const fullPrompt = messages\n .map((msg) => {\n const role = msg.role === 'system' ? '系统指令' : `${msg.role === 'user' ? '用户' : '助手'}`;\n return `[${role}]: ${msg.content}`;\n })\n .join('\\n\\n');\n\n const args: string[] = ['--no-confirm', '-p', fullPrompt];\n\n const result = await execa('claude', args, {\n stdio: this.verbose ? 'inherit' : 'pipe',\n timeout: options?.timeout || 300000,\n reject: false,\n });\n\n spinner.succeed('Claude 响应完成');\n\n if (result.exitCode !== 0 && !result.stdout) {\n throw new Error(`Claude 命令执行失败 (退出码: ${result.exitCode})`);\n }\n\n return result.stdout || '';\n } catch (error: any) {\n spinner.fail('Claude 调用失败');\n throw error;\n }\n }\n\n /**\n * 分析代码\n */\n async analyzeCode(code: string, language: string, question?: string): Promise<string> {\n const prompt = `请分析以下 ${language} 代码:${question ? `并回答:${question}` : ''}\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请提供:\n1. 代码功能概述\n2. 潜在问题\n3. 改进建议\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 生成代码\n */\n async generateCode(\n description: string,\n language: string,\n context?: string\n ): Promise<string> {\n let prompt = `请用 ${language} 编写代码实现以下功能:\\n\\n${description}\\n\\n`;\n\n if (context) {\n prompt += `参考上下文:\\n\\n${context}\\n\\n`;\n }\n\n prompt += `要求:\n1. 代码简洁易读\n2. 包含必要的注释\n3. 遵循最佳实践\n4. 只返回代码,不要额外解释\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 审查代码\n */\n async reviewCode(code: string, language: string): Promise<CodeReviewResult> {\n const prompt = `请审查以下 ${language} 代码,提供详细反馈:\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请按以下格式回复:\n## 发现的问题\n- [严重程度] 问题描述\n\n## 改进建议\n- 建议内容\n\n## 亮点\n- 做得好的地方\n\n请用 JSON 格式回复:\n{\n \"issues\": [{\"severity\": \"high|medium|low\", \"message\": \"问题描述\"}],\n \"suggestions\": [\"建议1\", \"建议2\"],\n \"highlights\": [\"亮点1\", \"亮点2\"]\n}\n`;\n\n const response = await this.prompt(prompt);\n try {\n // 尝试从响应中提取 JSON\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // 如果解析失败,返回默认结构\n }\n\n return {\n issues: [],\n suggestions: [response],\n highlights: [],\n };\n }\n\n /**\n * 生成 Spec 文档\n */\n async generateSpec(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies?: string[]\n ): Promise<string> {\n let prompt = `Role: Senior Fullstack Developer\n\n你是一个资深的全栈工程师,现在需要为一个新功能生成规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n`;\n\n if (dependencies && dependencies.length > 0) {\n prompt += `\n## 依赖功能\n此功能依赖以下已完成的功能:${dependencies.join('、')}\n`;\n }\n\n prompt += `\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n${dependencies ? dependencies.map((d) => `- [x] ${d}`).join('\\n') : '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${StringUtils.toKebabCase(featureName)}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: {{TIMESTAMP}} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n`;\n\n return await this.prompt(prompt, { timeout: 180000 });\n }\n\n /**\n * 生成 Bugfix 报告\n */\n async generateBugfixReport(\n bugDescription: string,\n reproductionSteps: string[],\n projectContext: string\n ): Promise<string> {\n const prompt = `Role: Senior Fullstack Developer\n\n用户报告了一个 Bug,需要你生成 Bugfix 规格文档。\n\n## Bug 描述\n${bugDescription}\n\n## 复现步骤\n${reproductionSteps.map((step, i) => `${i + 1}. ${step}`).join('\\n')}\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请生成一个完整的 Bugfix 报告,包括:\n1. 问题分析\n2. 根本原因推测\n3. 修复建议\n4. 测试计划\n`;\n\n return await this.prompt(prompt, { timeout: 120000 });\n }\n}\n\n/**\n * Prompt 选项\n */\nexport interface PromptOptions {\n contextFiles?: string[];\n timeout?: number;\n model?: string;\n}\n\n/**\n * 聊天消息\n */\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\n/**\n * 代码审查结果\n */\nexport interface CodeReviewResult {\n issues: Array<{\n severity: 'high' | 'medium' | 'low';\n message: string;\n }>;\n suggestions: string[];\n highlights: string[];\n}\n\n// 导出单例\nexport const claudeAI = new ClaudeAI();\n","import { execa } from 'execa';\nimport path from 'path';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 模板类型\n */\nexport type TemplateType = 'frontend' | 'backend';\n\n/**\n * 模板信息接口\n */\nexport interface TemplateInfo {\n type: TemplateType;\n repository: string;\n currentCommit?: string;\n currentTag?: string;\n latestCommit?: string;\n latestTag?: string;\n needsUpdate: boolean;\n}\n\n/**\n * 模板版本信息接口\n */\nexport interface TemplateVersionInfo {\n commit: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n}\n\n/**\n * 模板配置接口\n */\nexport interface TemplateConfig {\n frontend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n backend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n}\n\n/**\n * 默认模板配置\n */\nconst DEFAULT_TEMPLATES: TemplateConfig = {\n frontend: {\n repository: 'https://gitlab.yungu-inc.org/static/fe-tpl-ai',\n },\n backend: {\n repository: 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git',\n },\n};\n\n/**\n * 获取项目配置文件路径\n */\nfunction getConfigPath(projectPath: string): string {\n return path.join(projectPath, '.team-cli', 'template.json');\n}\n\n/**\n * 读取项目的模板配置\n */\nexport async function readTemplateConfig(projectPath: string): Promise<TemplateConfig | null> {\n const configPath = getConfigPath(projectPath);\n const exists = await FileUtils.exists(configPath);\n\n if (!exists) {\n return null;\n }\n\n try {\n const content = await FileUtils.read(configPath);\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * 保存项目的模板配置\n */\nexport async function saveTemplateConfig(projectPath: string, config: TemplateConfig): Promise<void> {\n const configDir = path.join(projectPath, '.team-cli');\n await FileUtils.ensureDir(configDir);\n\n const configPath = getConfigPath(projectPath);\n const content = JSON.stringify(config, null, 2);\n await FileUtils.write(configPath, content);\n}\n\n/**\n * 初始化模板配置\n */\nexport async function initTemplateConfig(projectPath: string): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (config) {\n return; // 已存在配置\n }\n\n // 保存当前使用的模板信息\n await saveTemplateConfig(projectPath, DEFAULT_TEMPLATES);\n}\n\n/**\n * 获取远程仓库的最新 commit\n */\nexport async function getLatestCommit(repository: string): Promise<string> {\n try {\n // 使用 git ls-remote 获取最新 commit\n const { stdout } = await execa('git', ['ls-remote', repository, 'HEAD'], {\n stdio: 'pipe',\n });\n\n const commit = stdout.split('\\t')[0];\n return commit;\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 commit 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 获取远程仓库的最新 tag\n */\nexport async function getLatestTag(repository: string): Promise<string> {\n try {\n // 获取所有 tags 并按版本排序\n const { stdout } = await execa(\n 'git',\n ['ls-remote', '--tags', repository],\n {\n stdio: 'pipe',\n }\n );\n\n const tags = stdout\n .split('\\n')\n .filter((line) => line.includes('refs/tags/') && !line.includes('^{}'))\n .map((line) => {\n const [, ref] = line.split('\\t');\n return ref.replace('refs/tags/', '');\n })\n .filter((tag) => /^v?\\d+\\.\\d+\\.\\d+/.test(tag))\n .sort((a, b) => {\n // 简单的版本排序\n const va = a.replace(/^v/, '').split('.').map(Number);\n const vb = b.replace(/^v/, '').split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n if ((va[i] || 0) > (vb[i] || 0)) return 1;\n if ((va[i] || 0) < (vb[i] || 0)) return -1;\n }\n return 0;\n });\n\n return tags[tags.length - 1] || '';\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 tag 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 检查模板是否需要更新\n */\nexport async function checkTemplateUpdate(\n projectPath: string,\n type: TemplateType\n): Promise<TemplateInfo | null> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config || !config[type]) {\n return null;\n }\n\n const repository = config[type].repository;\n const currentCommit = config[type].commit;\n const currentTag = config[type].tag;\n\n // 获取最新版本\n const latestCommit = await getLatestCommit(repository);\n const latestTag = await getLatestTag(repository);\n\n if (!latestCommit) {\n return null;\n }\n\n // 判断是否需要更新\n const needsUpdate = currentCommit && currentCommit !== latestCommit;\n\n return {\n type,\n repository,\n currentCommit,\n currentTag,\n latestCommit,\n latestTag,\n needsUpdate: needsUpdate || false,\n };\n}\n\n/**\n * 更新模板配置中的版本信息\n */\nexport async function updateTemplateVersion(\n projectPath: string,\n type: TemplateType,\n commit: string,\n options?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config) {\n return;\n }\n\n config[type].commit = commit;\n if (options?.tag) {\n config[type].tag = options.tag;\n }\n if (options?.branch) {\n config[type].branch = options.branch;\n }\n config[type].lastUpdate = new Date().toISOString();\n\n await saveTemplateConfig(projectPath, config);\n}\n\n/**\n * 获取默认模板配置\n */\nexport function getDefaultTemplates(): TemplateConfig {\n return DEFAULT_TEMPLATES;\n}\n","import path from 'path';\nimport os from 'os';\nimport crypto from 'crypto';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 用户配置接口\n */\nexport interface UserConfig {\n gitlab: {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n };\n preferences?: {\n defaultBackendBranch?: string;\n defaultFrontendBranch?: string;\n };\n}\n\n/**\n * 用户配置管理类\n */\nexport class UserConfigManager {\n private configPath: string;\n\n constructor() {\n const configDir = path.join(os.homedir(), '.team-cli');\n this.configPath = path.join(configDir, 'config.json');\n }\n\n /**\n * 加载用户配置\n */\n async load(): Promise<UserConfig | null> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (!exists) {\n return null;\n }\n\n const content = await FileUtils.read(this.configPath);\n const config = JSON.parse(content);\n\n // 解密 access token\n if (config.gitlab?.accessToken) {\n config.gitlab.accessToken = this.decrypt(config.gitlab.accessToken);\n }\n\n return config;\n } catch (error) {\n logger.debug(`加载用户配置失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 保存用户配置\n */\n async save(config: UserConfig): Promise<void> {\n try {\n const configDir = path.dirname(this.configPath);\n await FileUtils.ensureDir(configDir);\n\n // 加密 access token\n const configToSave = { ...config };\n if (configToSave.gitlab?.accessToken) {\n configToSave.gitlab.accessToken = this.encrypt(configToSave.gitlab.accessToken);\n }\n\n const content = JSON.stringify(configToSave, null, 2);\n await FileUtils.write(this.configPath, content);\n } catch (error) {\n throw new Error(`保存用户配置失败: ${error}`);\n }\n }\n\n /**\n * 更新 GitLab Token\n */\n async updateGitLabToken(token: string, baseUrl?: string): Promise<void> {\n const config = (await this.load()) || {\n gitlab: {\n accessToken: '',\n baseUrl: 'https://gitlab.com',\n timeout: 30000,\n },\n };\n\n config.gitlab.accessToken = token;\n if (baseUrl) {\n config.gitlab.baseUrl = baseUrl;\n }\n\n await this.save(config);\n }\n\n /**\n * 获取 GitLab Token\n */\n async getGitLabToken(): Promise<string | null> {\n const config = await this.load();\n return config?.gitlab?.accessToken || null;\n }\n\n /**\n * 获取 GitLab 配置\n */\n async getGitLabConfig(): Promise<{ accessToken: string; baseUrl: string; timeout?: number } | null> {\n const config = await this.load();\n return config?.gitlab || null;\n }\n\n /**\n * 检查是否已有配置\n */\n async hasConfig(): Promise<boolean> {\n const config = await this.load();\n return config !== null && config.gitlab?.accessToken !== undefined;\n }\n\n /**\n * 删除配置\n */\n async removeConfig(): Promise<void> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (exists) {\n await FileUtils.remove(this.configPath);\n }\n } catch (error) {\n throw new Error(`删除配置失败: ${error}`);\n }\n }\n\n /**\n * 简单加密 (使用机器特定密钥)\n */\n private encrypt(text: string): string {\n const key = this.getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return iv.toString('hex') + ':' + encrypted;\n }\n\n /**\n * 简单解密\n */\n private decrypt(encryptedText: string): string {\n try {\n const key = this.getMachineKey();\n const parts = encryptedText.split(':');\n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n } catch {\n // 如果解密失败,可能是旧版本的明文存储\n return encryptedText;\n }\n }\n\n /**\n * 获取机器特定密钥\n */\n private getMachineKey(): Buffer {\n const hostname = os.hostname();\n const platform = os.platform();\n const arch = os.arch();\n const cpus = os.cpus();\n\n // 使用机器信息生成密钥\n const machineInfo = `${hostname}-${platform}-${arch}-${cpus[0]?.model || 'unknown'}`;\n return crypto.createHash('sha256').update(machineInfo).digest();\n }\n\n /**\n * 获取配置目录\n */\n getConfigDir(): string {\n return path.dirname(this.configPath);\n }\n\n /**\n * 获取配置文件路径\n */\n getConfigPath(): string {\n return this.configPath;\n }\n}\n\n// 导出单例\nexport const userConfigManager = new UserConfigManager();\n","/**\n * GitLab API 客户端\n */\n\n/**\n * GitLab Tag 信息\n */\nexport interface GitLabTag {\n name: string;\n commit: {\n id: string;\n short_id: string;\n created_at: string;\n };\n message: string;\n release: {\n tag_name: string;\n description: string;\n } | null;\n}\n\n/**\n * GitLab Branch 信息\n */\nexport interface GitLabBranch {\n name: string;\n commit: {\n id: string;\n short_id: string;\n title: string;\n created_at: string;\n author_name: string;\n author_email: string;\n };\n protected: boolean;\n default: boolean;\n}\n\n/**\n * GitLab Diff 结果\n */\nexport interface GitLabDiffResult {\n from: string;\n to: string;\n commits: Array<{\n id: string;\n short_id: string;\n title: string;\n author_name: string;\n created_at: string;\n message: string;\n }>;\n diffs: Array<{\n old_path: string;\n new_path: string;\n diff: string;\n new_file: boolean;\n renamed_file: boolean;\n deleted_file: boolean;\n }>;\n}\n\n/**\n * GitLab 项目信息\n */\nexport interface GitLabProject {\n id: number;\n name: string;\n path: string;\n path_with_namespace: string;\n http_url_to_repo: string;\n ssh_url_to_repo: string;\n default_branch: string;\n last_activity_at: string;\n}\n\n/**\n * GitLab API 配置\n */\nexport interface GitLabConfig {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n}\n\n/**\n * GitLab API 客户端类\n */\nexport class GitLabAPI {\n private config: GitLabConfig;\n private readonly defaultTimeout = 30000;\n\n constructor(config: GitLabConfig) {\n this.config = {\n ...config,\n timeout: config.timeout || this.defaultTimeout,\n };\n }\n\n /**\n * 验证 Token 是否有效\n */\n async authenticate(): Promise<boolean> {\n try {\n const response = await this.request('/user');\n return response.ok;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * 列出项目的所有 Tags\n */\n async listTags(projectPath: string): Promise<GitLabTag[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/tags?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const tags: GitLabTag[] = await response.json();\n return tags.sort((a, b) => {\n // 按版本号排序(降序)\n return this.compareVersionStrings(b.name, a.name);\n });\n } catch (error) {\n throw new Error(`获取 Tags 失败: ${error}`);\n }\n }\n\n /**\n * 列出项目的所有 Branches\n */\n async listBranches(projectPath: string): Promise<GitLabBranch[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/branches?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const branches: GitLabBranch[] = await response.json();\n\n // 将默认分支放在最前面\n return branches.sort((a, b) => {\n if (a.default) return -1;\n if (b.default) return 1;\n return a.name.localeCompare(b.name);\n });\n } catch (error) {\n throw new Error(`获取 Branches 失败: ${error}`);\n }\n }\n\n /**\n * 验证 Tag 是否存在\n */\n async validateTag(projectPath: string, tag: string): Promise<boolean> {\n try {\n const tags = await this.listTags(projectPath);\n return tags.some((t) => t.name === tag);\n } catch {\n return false;\n }\n }\n\n /**\n * 验证 Branch 是否存在\n */\n async validateBranch(projectPath: string, branch: string): Promise<boolean> {\n try {\n const branches = await this.listBranches(projectPath);\n return branches.some((b) => b.name === branch);\n } catch {\n return false;\n }\n }\n\n /**\n * 获取项目信息\n */\n async getProject(projectPath: string): Promise<GitLabProject | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}`);\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Tag 的 commit 信息\n */\n async getTagCommit(projectPath: string, tag: string): Promise<string | null> {\n try {\n const tags = await this.listTags(projectPath);\n const targetTag = tags.find((t) => t.name === tag);\n return targetTag?.commit.id || null;\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Branch 的最新 commit 信息\n */\n async getBranchCommit(projectPath: string, branch: string): Promise<string | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/branches/${encodeURIComponent(branch)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n const branchInfo: GitLabBranch = await response.json();\n return branchInfo.commit.id;\n } catch {\n return null;\n }\n }\n\n /**\n * 对比两个版本之间的差异\n */\n async compareVersions(\n projectPath: string,\n from: string,\n to: string\n ): Promise<GitLabDiffResult | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/compare?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 比较两个版本号(用于排序)\n * 返回值: -1 (v1 < v2), 0 (v1 == v2), 1 (v1 > v2)\n */\n private compareVersionStrings(v1: string, v2: string): number {\n // 移除 'v' 前缀\n const version1 = v1.replace(/^v/, '');\n const version2 = v2.replace(/^v/, '');\n\n const parts1 = version1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = version2.split('.').map((p) => parseInt(p, 10) || 0);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n\n if (p1 > p2) return 1;\n if (p1 < p2) return -1;\n }\n\n return 0;\n }\n\n /**\n * 获取最新的版本(优先 Tag,否则 latest commit)\n */\n async getLatestVersion(projectPath: string): Promise<{ type: 'tag' | 'commit'; name: string; commit: string } | null> {\n try {\n const tags = await this.listTags(projectPath);\n const branches = await this.listBranches(projectPath);\n\n // 优先返回最新的 tag\n if (tags.length > 0) {\n const latestTag = tags[0];\n return {\n type: 'tag',\n name: latestTag.name,\n commit: latestTag.commit.id,\n };\n }\n\n // 如果没有 tag,返回默认分支的最新 commit\n const defaultBranch = branches.find((b) => b.default);\n if (defaultBranch) {\n return {\n type: 'commit',\n name: defaultBranch.name,\n commit: defaultBranch.commit.id,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * 解析项目路径\n * 从 Git URL 中提取项目路径\n */\n static parseProjectPath(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n // - gitlab.com/group/project\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n }\n\n /**\n * 编码项目路径用于 API 请求\n */\n private encodeProjectPath(projectPath: string): string {\n // GitLab API 需要对项目路径进行 URL 编码\n // 并且需要将 / 替换为 %2F\n return encodeURIComponent(projectPath).replace(/%2F/g, '%2F');\n }\n\n /**\n * 发送 HTTP 请求\n */\n private async request(endpoint: string, options: RequestInit = {}): Promise<Response> {\n const url = `${this.config.baseUrl}/api/v4${endpoint}`;\n\n const headers: HeadersInit = {\n 'PRIVATE-TOKEN': this.config.accessToken,\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n return response;\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('请求超时');\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 获取默认分支\n */\n async getDefaultBranch(projectPath: string): Promise<string | null> {\n try {\n const project = await this.getProject(projectPath);\n return project?.default_branch || null;\n } catch {\n return null;\n }\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { FileUtils, StringUtils, GitUtils } from '../lib/utils.js';\nimport { Listr } from 'listr2';\nimport {\n initTemplateConfig,\n updateTemplateVersion,\n getDefaultTemplates,\n} from '../lib/template-version.js';\n\n/**\n * Init 命令\n */\nexport const initCommand = new Command('init')\n .argument('[project-name]', '项目名称')\n .description('初始化新项目')\n .option('-d, --dir <directory>', '项目目录', '.')\n .option('--no-docker', '不生成 Docker 配置')\n .option('--no-git', '不初始化 Git')\n .option('--tag <tag>', '指定模板标签 (前后端通用)')\n .option('--backend-tag <tag>', '指定后端模板标签')\n .option('--frontend-tag <tag>', '指定前端模板标签')\n .option('--backend-branch <branch>', '指定后端模板分支')\n .option('--frontend-branch <branch>', '指定前端模板分支')\n .action(async (projectName, options) => {\n try {\n // 如果没有提供项目名,交互式输入\n if (!projectName) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: '请输入项目名称:',\n default: 'my-project',\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '项目名称只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n projectName = answers.projectName;\n }\n\n // 验证项目名\n if (!StringUtils.validateProjectName(projectName)) {\n logger.error('项目名称只能包含小写字母、数字和连字符');\n process.exit(1);\n }\n\n logger.header('初始化项目');\n logger.newLine();\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n const projectPath = path.resolve(options.dir, projectName);\n\n // 检查目录是否存在\n if (await FileUtils.exists(projectPath)) {\n logger.error(`目录已存在: ${projectPath}`);\n logger.info('请选择其他项目名称或删除现有目录');\n process.exit(1);\n }\n\n // 创建任务列表\n const tasks = new Listr(\n [\n {\n title: '检查环境',\n task: async () => {\n const version = await claudeAI.getVersion();\n logger.info(`Claude 版本: ${version}`);\n },\n },\n {\n title: '创建项目目录',\n task: async () => {\n await FileUtils.ensureDir(projectPath);\n await FileUtils.ensureDir(path.join(projectPath, 'frontend'));\n await FileUtils.ensureDir(path.join(projectPath, 'backend'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/specs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/api'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/sessions'));\n },\n },\n {\n title: '生成技术栈文档',\n task: async () => {\n await generateTechStack(projectPath);\n },\n },\n {\n title: '生成开发规范文档',\n task: async () => {\n await generateConventions(projectPath);\n },\n },\n {\n title: '生成 AI Memory',\n task: async () => {\n await generateAIMemory(projectPath, projectName);\n },\n },\n {\n title: '生成 Spec 模板',\n task: async () => {\n await generateSpecTemplate(projectPath);\n },\n },\n {\n title: '克隆后端模板',\n task: async () => {\n // 处理后端版本选项\n const backendTag = options.backendTag || options.tag;\n const backendBranch = options.backendBranch;\n await cloneBackendTemplate(projectPath, {\n tag: backendTag,\n branch: backendBranch,\n });\n },\n },\n {\n title: '生成前端脚手架',\n task: async () => {\n await generateFrontendScaffold(projectPath);\n },\n },\n ...(options.docker\n ? [\n {\n title: '生成 Docker 配置',\n task: async () => {\n await generateDockerFiles(projectPath);\n },\n },\n ]\n : []),\n ...(options.git\n ? [\n {\n title: '初始化 Git',\n task: async () => {\n await initGit(projectPath, projectName);\n },\n },\n ]\n : []),\n ],\n {\n concurrent: false,\n exitOnError: true,\n }\n );\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`项目 ${projectName} 初始化完成!`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(`cd ${projectName}`);\n logger.step('team-cli add-feature <feature-name>');\n logger.step('team-cli breakdown docs/specs/xxx.md');\n logger.step('team-cli dev');\n logger.newLine();\n } catch (error: any) {\n logger.error(`初始化失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成技术栈文档\n */\nasync function generateTechStack(projectPath: string): Promise<void> {\n const content = `# 技术栈\n\n## 后端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 语言 | Java | 17 | LTS 版本 |\n| 框架 | Spring Boot | 3.2 | 现代化 Java 框架 |\n| 构建工具 | Gradle | 8.x | 快速、灵活的构建工具 |\n| ORM | MyBatis Plus | 3.5 | 增强 MyBatis,简化 CRUD |\n| 数据库 | MySQL | 8.0 | 关系型数据库 |\n| 缓存 | Redis | 7.x | 缓存和会话存储 |\n| 文档 | SpringDoc OpenAPI | 2.3 | API 文档自动生成 |\n\n## 前端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 框架 | Next.js | 14 | React 全栈框架 |\n| 语言 | TypeScript | 5.x | 类型安全 |\n| 样式 | Tailwind CSS | 3.x | 原子化 CSS |\n| UI 库 | Shadcn/UI | latest | 基于 Radix UI 的组件库 |\n| 图标 | Lucide React | latest | 一致性图标库 |\n| 状态管理 | React Context + Hooks | - | 轻量级状态管理 |\n| 表单 | React Hook Form | 7.x | 高性能表单 |\n| 数据验证 | Zod | 3.x | TypeScript 优先的验证库 |\n\n## 开发工具\n\n| 工具 | 用途 |\n|------|------|\n| ESLint | 代码检查 |\n| Prettier | 代码格式化 |\n| Husky | Git Hooks |\n| Commitlint | 提交信息规范 |\n| Docker | 容器化部署 |\n\n## 代码规范\n\n### 后端规范\n\n- 使用 DTO 模式进行数据传输\n- Controller 负责接收请求,Service 处理业务逻辑\n- 使用 @Validated 进行参数校验\n- 统一异常处理和响应格式\n- API 路径使用 kebab-case\n- 类名使用 PascalCase\n- 方法名使用 camelCase\n\n### 前端规范\n\n- 组件使用 PascalCase\n- 文件名使用 kebab-case\n- 使用 TypeScript 类型定义\n- Props 接口定义在组件内部\n- 使用 Semantic HTML\n- 响应式设计优先\n\n### Git 规范\n\n- 分支命名: \\`feature/xxx\\`, \\`bugfix/xxx\\`, \\`hotfix/xxx\\`\n- 提交信息: \\`feat: xxx\\`, \\`fix: xxx\\`, \\`docs: xxx\\`\n- 提交前必须通过 lint 检查\n\n## 目录结构\n\n\\`\\`\\`\nbackend/\n├── src/main/java/com/example/demo/\n│ ├── controller/ # API 控制器\n│ ├── service/ # 业务逻辑\n│ ├── mapper/ # 数据访问\n│ ├── entity/ # 数据模型\n│ ├── dto/ # 数据传输对象\n│ ├── config/ # 配置类\n│ └── util/ # 工具类\n├── src/main/resources/\n│ ├── mapper/ # MyBatis XML\n│ └── application.yml # 配置文件\n└── src/test/ # 测试代码\n\nfrontend/\n├── src/\n│ ├── app/ # Next.js App Router\n│ ├── components/ # React 组件\n│ ├── lib/ # 工具库\n│ └── types/ # TypeScript 类型\n└── public/ # 静态资源\n\ndocs/\n├── specs/ # 功能规格文档\n├── api/ # API 文档\n└── sessions/ # 开发会话记录\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'TECH_STACK.md'), content);\n}\n\n/**\n * 生成开发规范文档\n */\nasync function generateConventions(projectPath: string): Promise<void> {\n const content = `# 开发规范\n\n## 后端开发规范\n\n### 1. 分层架构\n\n\\`\\`\\`\nController → Service → Mapper → Database\n ↓ ↓\n DTO Entity\n\\`\\`\\`\n\n**职责划分:**\n- **Controller**: 接收 HTTP 请求,参数校验,调用 Service\n- **Service**: 业务逻辑处理,事务管理\n- **Mapper**: 数据库操作,SQL 执行\n- **DTO**: 数据传输对象,用于 API 接口\n- **Entity**: 数据库实体映射\n\n### 2. 命名规范\n\n| 类型 | 规范 | 示例 |\n|------|------|------|\n| 类名 | PascalCase | \\`UserController\\` |\n| 方法名 | camelCase | \\`getUserById\\` |\n| 常量 | UPPER_SNAKE_CASE | \\`MAX_RETRY_COUNT\\` |\n| 包名 | 小写点分隔 | \\`com.example.demo.controller\\` |\n| API 路径 | kebab-case | \\`/api/users\\` |\n\n### 3. API 设计\n\n**RESTful 风格:**\n\n\\`\\`\\`\nGET /api/users # 列表\nGET /api/users/{id} # 详情\nPOST /api/users # 创建\nPUT /api/users/{id} # 更新\nDELETE /api/users/{id} # 删除\n\\`\\`\\`\n\n**统一响应格式:**\n\n\\`\\`\\`json\n{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {...}\n}\n\\`\\`\\`\n\n### 4. 异常处理\n\n使用 \\`@ControllerAdvice\\` 统一处理异常:\n\n\\`\\`\\`java\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n\n @ExceptionHandler(BusinessException.class)\n public Result<Void> handleBusinessException(BusinessException e) {\n return Result.error(e.getMessage());\n }\n}\n\\`\\`\\`\n\n### 5. 参数校验\n\n使用 \\`@Validated\\` 和 JSR-303 注解:\n\n\\`\\`\\`java\n@PostMapping(\"/users\")\npublic Result<User> createUser(@Validated @RequestBody UserDTO dto) {\n // ...\n}\n\\`\\`\\`\n\n### 6. 事务管理\n\n在 Service 层使用 \\`@Transactional\\`:\n\n\\`\\`\\`java\n@Service\npublic class UserService {\n\n @Transactional(rollbackFor = Exception.class)\n public void createUserWithRole(User user, Role role) {\n // ...\n }\n}\n\\`\\`\\`\n\n## 前端开发规范\n\n### 1. 组件设计\n\n**组件结构:**\n\n\\`\\`\\`typescript\n// 组件定义\ninterface Props {\n // props 类型定义\n}\n\nexport function ComponentName({ prop1, prop2 }: Props) {\n // 组件逻辑\n\n return (\n // JSX\n );\n}\n\\`\\`\\`\n\n**命名规范:**\n- 组件文件: kebab-case (\\`user-card.tsx\\`)\n- 组件名: PascalCase (\\`UserCard\\`)\n- Hook 文件: kebab-case, 以 \\`use-\\` 开头 (\\`use-user-data.ts\\`)\n\n### 2. TypeScript 使用\n\n**定义接口:**\n\n\\`\\`\\`typescript\ninterface User {\n id: string;\n name: string;\n email: string;\n}\n\ninterface CreateUserDto {\n name: string;\n email: string;\n}\n\\`\\`\\`\n\n**避免使用 \\`any\\`:**\n\n\\`\\`\\`typescript\n// ❌ 不好\nconst data: any = await fetchData();\n\n// ✅ 好\nconst data: User = await fetchData();\n\\`\\`\\`\n\n### 3. 状态管理\n\n**使用 React Context:**\n\n\\`\\`\\`typescript\nconst UserContext = createContext<UserContextType>({\n user: null,\n login: async () => {},\n logout: () => {},\n});\n\\`\\`\\`\n\n**优先使用本地状态:**\n\n\\`\\`\\`typescript\n// 简单状态使用 useState\nconst [count, setCount] = useState(0);\n\n// 复杂逻辑使用 useReducer\nconst [state, dispatch] = useReducer(reducer, initialState);\n\\`\\`\\`\n\n### 4. 样式规范\n\n**使用 Tailwind CSS:**\n\n\\`\\`\\`tsx\n<div className=\"flex items-center gap-4 p-4 bg-white rounded-lg\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n**响应式设计:**\n\n\\`\\`\\`tsx\n<div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n### 5. 表单处理\n\n**使用 React Hook Form:**\n\n\\`\\`\\`typescript\nconst { register, handleSubmit, formState: { errors } } = useForm<FormData>();\n\nconst onSubmit = (data: FormData) => {\n console.log(data);\n};\n\nreturn (\n <form onSubmit={handleSubmit(onSubmit)}>\n <input {...register('name', { required: true })} />\n {errors.name && <span>必填</span>}\n </form>\n);\n\\`\\`\\`\n\n### 6. 数据获取\n\n**使用 Server Components (Next.js 14):**\n\n\\`\\`\\`typescript\nasync function getUser(id: string) {\n const res = await fetch(\\`/api/users/\\${id}\\`);\n if (!res.ok) throw new Error('Failed to fetch');\n return res.json();\n}\n\nexport default async function UserPage({ params }) {\n const user = await getUser(params.id);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Git 工作流\n\n### 分支策略\n\n\\`\\`\\`\nmain # 主分支,始终保持稳定\n ├── feature/xxx # 功能分支\n ├── bugfix/xxx # Bug 修复分支\n └── hotfix/xxx # 紧急修复分支\n\\`\\`\\`\n\n### 提交信息规范\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\n**类型 (type):**\n- \\`feat\\`: 新功能\n- \\`fix\\`: Bug 修复\n- \\`docs\\`: 文档更新\n- \\`style\\`: 代码格式调整\n- \\`refactor\\`: 代码重构\n- \\`test\\`: 测试相关\n- \\`chore\\`: 构建/工具相关\n\n**示例:**\n\n\\`\\`\\`\nfeat(auth): add user login feature\n\nimplement JWT based authentication with:\n- login endpoint\n- token refresh\n- logout handling\n\nCloses #123\n\\`\\`\\`\n\n## 测试规范\n\n### 后端测试\n\n\\`\\`\\`java\n@SpringBootTest\nclass UserServiceTest {\n\n @Autowired\n private UserService userService;\n\n @Test\n void shouldCreateUser() {\n // given\n User user = new User(\"John\");\n\n // when\n User saved = userService.save(user);\n\n // then\n assertNotNull(saved.getId());\n }\n}\n\\`\\`\\`\n\n### 前端测试\n\n\\`\\`\\`typescript\nimport { render, screen } from '@testing-library/react';\n\ntest('renders user name', () => {\n render(<UserProfile name=\"John\" />);\n expect(screen.getByText('John')).toBeInTheDocument();\n});\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'CONVENTIONS.md'), content);\n}\n\n/**\n * 生成 AI Memory\n */\nasync function generateAIMemory(projectPath: string, projectName: string): Promise<void> {\n const content = `# AI Memory - 项目状态记录\n\n## 项目信息\n- **项目名称**: ${projectName}\n- **创建时间**: ${new Date().toISOString().split('T')[0]}\n- **当前阶段**: 初始化\n- **最后更新**: ${new Date().toISOString().split('T')[0]}\n\n## 模板版本信息\n\n> 本部分由 team-cli 自动管理,记录使用的前后端模板版本\n\n| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |\n|------|------|-----|--------|--------|----------|\n| 前端 | - | - | - | - | - |\n| 后端 | - | - | - | - | - |\n\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n\n## API 列表 (API Inventory)\n\n> 本部分由 team-cli 自动扫描后端 Controller 生成\n\n## 数据模型概览\n\n| 表名 | 说明 | 字段数 | 关联表 | 状态 |\n|------|------|--------|--------|------|\n| user | 用户表 | - | - | - |\n\n## 已完成的 Milestones\n\n## 当前任务\n\n## 待处理任务\n\n## 技术债务\n\n| 日期 | 问题 | 计划修复 |\n|------|------|---------|\n\n## 关键决策记录\n\n| 日期 | 决策 | 原因 |\n|------|------|------|\n| ${new Date().toISOString().split('T')[0]} | 初始化项目 | 使用 Spring Boot 3 + Next.js 14 技术栈 |\n\n## 注意事项\n\n## Bugfix 记录\n\n| Bug ID | 日期 | 问题描述 | 状态 |\n|--------|------|---------|------|\n`;\n\n await FileUtils.write(path.join(projectPath, 'AI_MEMORY.md'), content);\n}\n\n/**\n * 生成 Spec 模板\n */\nasync function generateSpecTemplate(projectPath: string): Promise<void> {\n const content = `# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n- [ ] dependency-1.md\n- [ ] dependency-2.md\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n1. 功能点一\n2. 功能点二\n3. 功能点三\n\n## 技术设计\n\n### API 设计\n- \\`POST /api/xxx\\` - 创建 XXX\n- \\`GET /api/xxx/{id}\\` - 获取 XXX 详情\n- \\`PUT /api/xxx/{id}\\` - 更新 XXX\n- \\`DELETE /api/xxx/{id}\\` - 删除 XXX\n\n### 数据模型\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n\n> 注: 使用 \\`team-cli breakdown\\` 拆分此 spec 为 milestones 和 todos\n\n### Milestone 1: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n\n### Milestone 2: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n\n----\n*生成于: {{TIMESTAMP}} by team-cli*\n`;\n\n await FileUtils.write(path.join(projectPath, 'docs/specs/template.md'), content);\n}\n\n/**\n * 克隆后端模板\n */\nasync function cloneBackendTemplate(\n projectPath: string,\n versionOptions?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const templateRepo = process.env.TEMPLATE_REPO || 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git';\n const backendPath = path.join(projectPath, 'backend');\n\n try {\n const { execaCommand } = await import('execa');\n const tempDir = path.join(projectPath, '.template-temp');\n\n // 如果指定了 tag 或 branch,先验证\n if (versionOptions?.tag || versionOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(templateRepo);\n\n if (versionOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, versionOptions.tag);\n if (!isValid) {\n logger.error(`后端模板 tag \"${versionOptions.tag}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板 tag: ${versionOptions.tag}`);\n }\n\n if (versionOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, versionOptions.branch);\n if (!isValid) {\n logger.error(`后端模板分支 \"${versionOptions.branch}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板分支: ${versionOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = versionOptions?.tag || versionOptions?.branch || 'HEAD';\n\n // 克隆到临时目录\n await execaCommand(`git clone --depth=1 --branch ${ref} ${templateRepo} ${tempDir}`, {\n stdio: 'inherit',\n timeout: 60000,\n });\n\n // 获取 commit 和 tag\n const { execa: e } = await import('execa');\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const { stdout: tags } = await e('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, backendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 删除 .git 目录\n const gitDir = path.join(backendPath, '.git');\n if (await FileUtils.exists(gitDir)) {\n await FileUtils.remove(gitDir);\n }\n\n // 保存模板版本信息\n await initTemplateConfig(projectPath);\n await updateTemplateVersion(projectPath, 'backend', commit.trim(), {\n tag: versionOptions?.tag || latestTag,\n branch: versionOptions?.branch,\n });\n } catch (error) {\n // 如果克隆失败,创建基础结构\n logger.warn('克隆后端模板失败,创建基础结构');\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/java/com/example'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/resources'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/test/java'));\n }\n}\n\n/**\n * 生成前端脚手架\n */\nasync function generateFrontendScaffold(projectPath: string): Promise<void> {\n const frontendPath = path.join(projectPath, 'frontend');\n\n // 使用 Claude 生成前端脚手架\n try {\n const prompt = `Read TECH_STACK.md and CONVENTIONS.md.\nInitialize a Next.js 14 frontend in ./frontend with:\n- TypeScript\n- Tailwind CSS\n- App Router structure\n- ESLint and Prettier configured\n- Basic layout and page components\n\nDo not run any servers, just generate the folder structure and configuration files.`;\n\n await claudeAI.prompt(prompt, {\n contextFiles: [\n path.join(projectPath, 'TECH_STACK.md'),\n path.join(projectPath, 'CONVENTIONS.md'),\n ],\n });\n } catch (error) {\n logger.warn('Claude 生成前端失败,将创建基础结构');\n await FileUtils.ensureDir(path.join(frontendPath, 'src/app'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/components'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/lib'));\n await FileUtils.ensureDir(path.join(frontendPath, 'public'));\n }\n}\n\n/**\n * 生成 Docker 配置\n */\nasync function generateDockerFiles(projectPath: string): Promise<void> {\n // TODO: 实现 Docker 文件生成\n logger.info('Docker 配置生成待实现');\n}\n\n/**\n * 初始化 Git\n */\nasync function initGit(projectPath: string, projectName: string): Promise<void> {\n try {\n const { execaCommand } = await import('execa');\n\n await execaCommand('git init', { cwd: projectPath, stdio: 'pipe' });\n await execaCommand('git add .', { cwd: projectPath, stdio: 'pipe' });\n await execaCommand(\n `git commit -m \"feat: initialize ${projectName} project with team-cli\"`,\n { cwd: projectPath, stdio: 'pipe' }\n );\n\n logger.success('Git 仓库初始化完成');\n } catch (error: any) {\n logger.warn(`Git 初始化失败: ${error.message}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Breakdown 命令 - 将 spec 拆分为 milestones 和 todos\n */\nexport const breakdownCommand = new Command('breakdown')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('将 spec 拆分为 milestones 和 todos')\n .action(async (specFile) => {\n try {\n logger.header('Spec 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 扫描 spec 文件\n const tasks = new Listr([\n {\n title: '扫描 spec 文件',\n task: async () => {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error(`specs 目录不存在: ${specDir}`);\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n return files.filter((f) => !f.includes('template'));\n },\n },\n {\n title: '选择 spec 文件',\n task: async (ctx) => {\n if (ctx.specs.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果没有指定文件,交互式选择\n if (!specFile) {\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '请选择要拆分的 spec 文件:',\n choices: ctx.specs,\n },\n ]);\n return path.join('docs/specs', selectedFile);\n }\n\n // 验证指定的文件\n const fullPath = specFile.startsWith('docs/specs/')\n ? specFile\n : path.join('docs/specs', specFile);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${specFile}`);\n }\n\n return fullPath;\n },\n },\n {\n title: '读取 spec 内容',\n task: async (ctx) => {\n ctx.specContent = await FileUtils.read(ctx.selectedFile);\n logger.success(`已选择: ${ctx.selectedFile}`);\n },\n },\n {\n title: '调用 Claude 拆分 spec',\n task: async (ctx) => {\n const prompt = buildBreakdownPrompt(ctx.specContent);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n // 调用 Claude 执行拆分\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '更新 spec 文件',\n task: async (ctx) => {\n // Claude 的输出已经是更新后的完整内容\n // 直接写入文件\n await FileUtils.write(ctx.selectedFile, ctx.breakdownResult);\n },\n },\n ]);\n\n try {\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.header('Spec 拆分完成!');\n logger.success(`Milestones 已添加到: ctx.selectedFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 检查拆分结果,根据需要调整');\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n } catch (error: any) {\n if (error.message) {\n logger.error(error.message);\n }\n throw error;\n }\n } catch (error: any) {\n logger.error(`拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 构建拆分 prompt\n */\nfunction buildBreakdownPrompt(specContent: string): string {\n return `Role: Senior Technical Lead and Agile Coach\n\nTask: Break down the following feature spec into milestones and todo lists.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each milestone should be completable in 1-3 days\n- Each todo should be a concrete, actionable task\n\nSpec Content:\n\\`\\`\\`\n${specContent}\n\\`\\`\\`\n\nOutput Requirements:\n1. Parse the existing spec content\n2. Break it down into 2-5 milestones\n3. Each milestone should have:\n - Clear name and objective\n - Estimated days (1-3 days per milestone)\n - Todo list with 3-8 actionable items\n4. Todo items should be:\n - Concrete and specific\n - Testable\n - Independent as much as possible\n\nFormat the milestones section as:\n\n\\`\\`\\`markdown\n## 里程碑 (Milestones)\n\n### Milestone 1: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 2 天\n\n- [ ] Todo 1 - 具体可执行的任务\n- [ ] Todo 2 - 具体可执行的任务\n- [ ] Todo 3 - 具体可执行的任务\n\n### Milestone 2: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 3 天\n\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n- [ ] Todo 4\n\\`\\`\\`\n\nImportant Instructions:\n1. Update the spec file directly with the milestone breakdown\n2. Keep all existing content, just add/update the milestones section\n3. If milestones section exists, replace it with new breakdown\n4. If milestones section doesn't exist, add it after \"技术设计\" section\n5. After updating the file, exit immediately\n6. Do not ask any questions\n7. Make sure todos are actionable and can be completed independently\n8. Consider dependencies when ordering todos within a milestone`;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\ninterface SpecInfo {\n file: string;\n name: string;\n status: '未开始' | '进行中' | '已拆分' | '已完成';\n dependencies: string[];\n index: number;\n}\n\ninterface MilestoneInfo {\n title: string;\n todos: string[];\n}\n\n/**\n * Dev 命令 - 开发模式\n */\nexport const devCommand = new Command('dev')\n .description('开发模式,执行具体任务')\n .action(async () => {\n try {\n logger.header('开发模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 步骤 1: 扫描并选择 spec\n const selectedSpec = await selectSpec();\n\n // 步骤 2: 解析并选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 选择 todo(如果选择了具体 milestone)\n const selectedTodo = await selectTodo(selectedSpec, selectedMilestone);\n\n // 步骤 4: 调用 Claude 执行开发\n await executeDevelopment(selectedSpec, selectedMilestone, selectedTodo);\n } catch (error: any) {\n logger.error(`开发模式执行失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(): Promise<string> {\n logger.step('步骤 1/3: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 解析 spec 信息(状态、依赖)\n const specs: SpecInfo[] = [];\n for (let i = 0; i < specFiles.length; i++) {\n const file = path.join(specDir, specFiles[i]);\n const spec = await FileUtils.read(file);\n\n const status = parseSpecStatus(spec);\n const dependencies = parseDependencies(spec);\n\n specs.push({\n file,\n name: specFiles[i],\n status,\n dependencies,\n index: i,\n });\n }\n\n // 拓扑排序推荐开发顺序\n const sortedSpecs = topologicalSort(specs);\n\n // 显示选项\n logger.info('可用的 spec 文件:');\n logger.newLine();\n\n const choices = sortedSpecs.map((spec, idx) => {\n const statusIcon = getStatusIcon(spec.status);\n const statusColor = getStatusColor(spec.status);\n const recommendInfo = idx === 0 ? '[推荐从这开始] ' : '';\n const depInfo =\n spec.dependencies.length > 0 ? `[依赖: ${spec.dependencies.join(', ')}] ` : '';\n\n return {\n name: `${statusIcon} [${spec.status}] ${recommendInfo}${depInfo}${spec.name}`,\n value: spec.file,\n short: spec.name,\n };\n });\n\n logger.info(' ✓ = 已完成 ⟳ = 进行中 ◉ = 已拆分 ○ = 未开始');\n logger.info(' 根据依赖关系推荐的开发顺序已标注');\n logger.newLine();\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要开发的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 解析并选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/3: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const milestones = parseMilestones(specContent);\n\n if (milestones.length === 0) {\n logger.info('该 spec 尚未拆分 milestones');\n\n const { breakdownNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'breakdownNow',\n message: '是否现在拆分?',\n default: true,\n },\n ]);\n\n if (breakdownNow) {\n // 调用 breakdown 命令\n logger.info('正在调用 breakdown...');\n // TODO: 调用 breakdown 命令\n throw new Error('breakdown 命令需要进一步实现');\n } else {\n logger.info('将直接实现整个 spec');\n return '整个 spec';\n }\n }\n\n // 显示 milestones\n const choices = milestones.map((m, idx) => ({\n name: `${idx + 1}. ${m.title} (${m.todos.length} 个任务)`,\n value: m.title,\n short: m.title,\n }));\n\n choices.push({\n name: `${milestones.length + 1}. 整个 spec (全部 milestones)`,\n value: '整个 spec',\n short: '整个 spec',\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 选择 todo 任务\n */\nasync function selectTodo(\n specFile: string,\n milestone: string\n): Promise<string> {\n if (milestone === '整个 spec') {\n return '全部功能';\n }\n\n logger.newLine();\n logger.step('步骤 3/3: 选择 todo 任务...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const todos = parseTodos(specContent, milestone);\n\n if (todos.length === 0) {\n logger.warn('该 milestone 没有 todo 任务');\n const { implementAll } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'implementAll',\n message: '实现整个 milestone?',\n default: true,\n },\n ]);\n\n return implementAll ? '全部功能' : milestone;\n }\n\n const choices = todos.map((todo, idx) => ({\n name: `${idx + 1}. ${todo}`,\n value: todo,\n short: todo,\n }));\n\n choices.push({\n name: `${todos.length + 1}. 全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 步骤 4: 调用 Claude 执行开发\n */\nasync function executeDevelopment(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n logger.newLine();\n logger.step('构建 Prompt 并调用 Claude...');\n\n let taskDescription: string;\n if (milestone === '整个 spec') {\n taskDescription = '实现整个 spec 的所有功能';\n } else if (todo === '全部功能' || todo === '全部任务') {\n taskDescription = `实现 milestone '${milestone}' 的所有任务`;\n } else {\n taskDescription = `实现 milestone '${milestone}' 的任务: ${todo}`;\n }\n\n const prompt = buildDevPrompt(specFile, milestone, todo, taskDescription);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n logger.info(` 任务描述: ${taskDescription}`);\n logger.info(` Spec 文件: ${specFile}`);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md', specFile],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n // 生成会话日志\n await generateSessionLog(specFile, milestone, todo, taskDescription, result);\n\n logger.header('开发任务完成!');\n logger.success('会话日志已保存');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查生成的代码');\n logger.step(\"2. 运行 'team-cli dev' 继续下一个任务\");\n logger.newLine();\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): '未开始' | '进行中' | '已拆分' | '已完成' {\n // 匹配 \"状态: xxx\" 格式\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '已完成';\n if (status.includes('进行中')) return '进行中';\n if (status.includes('已拆分')) return '已拆分';\n }\n return '未开始';\n}\n\n/**\n * 解析依赖关系\n */\nfunction parseDependencies(spec: string): string[] {\n const deps: string[] = [];\n let inDepsSection = false;\n\n const lines = spec.split('\\n');\n for (const line of lines) {\n // 检测依赖关系部分\n if (line.includes('## 依赖关系') || line.includes('## 依赖')) {\n inDepsSection = true;\n continue;\n }\n\n // 遇到其他二级标题,退出\n if (inDepsSection && line.startsWith('## ')) {\n break;\n }\n\n // 匹配 - [xxx] dependency.md 格式\n const match = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+\\.md)/);\n if (inDepsSection && match) {\n const dep = match[1];\n if (dep !== '无' && dep) {\n deps.push(dep);\n }\n }\n }\n\n return deps;\n}\n\n/**\n * 解析 milestones\n */\nfunction parseMilestones(spec: string): MilestoneInfo[] {\n const milestones: MilestoneInfo[] = [];\n const lines = spec.split('\\n');\n let currentMilestone: MilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n // 检测 milestone 开始\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = { title, todos: [] };\n inMilestone = true;\n continue;\n }\n\n // 在 milestone 内部\n if (inMilestone && currentMilestone) {\n // 遇到下一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n milestones.push(currentMilestone);\n currentMilestone = null;\n continue;\n }\n\n // 匹配 todo 行\n const todoMatch = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+)/);\n if (todoMatch) {\n currentMilestone.todos.push(todoMatch[1].trim());\n }\n }\n }\n\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n\n return milestones;\n}\n\n/**\n * 解析指定 milestone 的 todos\n */\nfunction parseTodos(spec: string, milestoneTitle: string): string[] {\n const lines = spec.split('\\n');\n const todos: string[] = [];\n let inTargetMilestone = false;\n\n for (const line of lines) {\n // 找到目标 milestone\n if (line.includes(milestoneTitle)) {\n inTargetMilestone = true;\n continue;\n }\n\n if (inTargetMilestone) {\n // 遇到另一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n\n // 匹配 todo 行\n const todoMatch = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+)/);\n if (todoMatch) {\n todos.push(todoMatch[1].trim());\n }\n }\n }\n\n return todos;\n}\n\n/**\n * 拓扑排序 - 根据依赖关系排序 specs\n */\nfunction topologicalSort(specs: SpecInfo[]): SpecInfo[] {\n const sorted: SpecInfo[] = [];\n const visited = new Set<number>();\n\n function visit(spec: SpecInfo) {\n if (visited.has(spec.index)) return;\n visited.add(spec.index);\n\n // 先访问依赖\n for (const depName of spec.dependencies) {\n const dep = specs.find((s) => s.name === depName);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(spec);\n }\n\n for (const spec of specs) {\n visit(spec);\n }\n\n return sorted;\n}\n\n/**\n * 获取状态图标\n */\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case '已完成':\n return '✓';\n case '进行中':\n return '⟳';\n case '已拆分':\n return '◉';\n default:\n return '○';\n }\n}\n\n/**\n * 获取状态颜色\n */\nfunction getStatusColor(status: string): string {\n // 用于终端颜色显示的辅助函数\n return status; // 实际实现中可以使用 chalk\n}\n\n/**\n * 构建开发 prompt\n */\nfunction buildDevPrompt(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string\n): string {\n return `Role: Senior Fullstack Developer\n\nContext:\n- Read and follow TECH_STACK.md for technology choices\n- Read and follow CONVENTIONS.md for coding standards\n- Check AI_MEMORY.md for project context and history\n\nTask: ${taskDescription}\n\nSpec File: ${specFile}\nMilestone: ${milestone}\nTodo: ${todo}\n\nProcess:\n1. First, read and analyze the full spec file\n2. Focus on the selected milestone/todo\n3. Define API endpoints and data models if needed\n4. Write tests first (TDD approach)\n5. Implement the backend code in ./backend\n6. Implement the frontend integration in ./frontend\n7. Update AI_MEMORY.md with completed tasks\n8. Update the spec file to mark completed todos (if applicable)\n\nImportant:\n- Follow the tech stack exactly (Java 17, Spring Boot 3, MyBatis Plus, Next.js 14, TypeScript)\n- Use DTO pattern for all API requests/responses\n- Write clean, well-documented code\n- After completing the task, exit immediately without waiting for further input\n`;\n}\n\n/**\n * 生成会话日志\n */\nasync function generateSessionLog(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string,\n result: string\n): Promise<void> {\n const sessionDir = 'docs/sessions';\n await FileUtils.ensureDir(sessionDir);\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const specName = path.basename(specFile, '.md');\n const logFile = path.join(sessionDir, `${timestamp}_${specName}.md`);\n\n const content = `# 开发会话记录\n\n**时间**: ${new Date().toLocaleString('zh-CN')}\n**Spec**: ${specFile}\n**Milestone**: ${milestone}\n**Todo**: ${todo}\n\n## 任务描述\n\n${taskDescription}\n\n## 执行结果\n\n\\`\\`\\`\n${result}\n\\`\\`\\`\n\n## 生成的文件\n\n<!-- TODO: 列出生成的文件 -->\n\n## 下一步\n\n- [ ] 测试生成的代码\n- [ ] 更新 spec 文件中的 todo 状态\n- [ ] 继续下一个任务\n`;\n\n await FileUtils.write(logFile, content);\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { FileUtils, StringUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Add-feature 命令 - 添加新功能\n */\nexport const addFeatureCommand = new Command('add-feature')\n .argument('<feature-name>', '功能名称')\n .description('添加新功能(支持 PRD 或简单描述模式)')\n .action(async (featureName) => {\n try {\n logger.header('添加新功能');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 转换为 kebab-case\n const featureSlug = StringUtils.toKebabCase(featureName);\n\n // 检查 spec 是否已存在\n const specFile = path.join('docs/specs', `${featureSlug}.md`);\n const specExists = await FileUtils.exists(specFile);\n if (specExists) {\n logger.error(`Spec 文件已存在: ${specFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${specFile}`);\n process.exit(1);\n }\n\n // 选择模式\n const { mode } = await inquirer.prompt([\n {\n type: 'list',\n name: 'mode',\n message: '选择需求输入模式:',\n choices: [\n { name: 'PRD 文档模式 (已有详细 PRD 文档)', value: 'prd' },\n { name: '简单描述模式 (一句话需求 + 模块依赖)', value: 'simple' },\n ],\n },\n ]);\n\n // 执行对应模式\n if (mode === 'prd') {\n await addFeatureFromPrd(featureName, featureSlug, specFile);\n } else {\n await addFeatureSimple(featureName, featureSlug, specFile);\n }\n } catch (error: any) {\n logger.error(`添加功能失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * PRD 文档模式\n */\nasync function addFeatureFromPrd(\n featureName: string,\n featureSlug: string,\n specFile: string\n): Promise<void> {\n const { prdPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prdPath',\n message: '请输入 PRD 文档路径:',\n validate: async (input: string) => {\n const exists = await FileUtils.exists(input);\n return exists || 'PRD 文档不存在';\n },\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '读取 PRD 文档',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdPath);\n },\n },\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 spec',\n task: async (ctx) => {\n const prompt = buildPrdPrompt(\n featureName,\n ctx.prdContent,\n ctx.projectContext,\n ctx.completedSpecs\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 生成 spec 中...');\n logger.separator('─', 60);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '保存 spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.generatedSpec);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(featureName, featureSlug);\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.success(`Spec 文件已生成: ${specFile}`);\n await showSpecPreview(specFile);\n await askToAdjust(specFile);\n}\n\n/**\n * 简单描述模式\n */\nasync function addFeatureSimple(\n featureName: string,\n featureSlug: string,\n specFile: string\n): Promise<void> {\n // 收集功能描述\n const { description } = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '功能描述 (一句话说明):',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '选择依赖功能',\n task: async (ctx) => {\n if (ctx.completedSpecs.length === 0) {\n ctx.selectedDeps = [];\n return;\n }\n\n const { dependencies } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'dependencies',\n message: '选择此功能依赖的已有功能 (可多选,直接回车跳过):',\n choices: ctx.completedSpecs,\n },\n ]);\n\n ctx.selectedDeps = dependencies;\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 spec',\n task: async (ctx) => {\n const prompt = buildSimplePrompt(\n featureName,\n description,\n ctx.projectContext,\n ctx.selectedDeps\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 生成 spec 中...');\n logger.separator('─', 60);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '保存 spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.generatedSpec);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(featureName, featureSlug);\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.success(`Spec 文件已生成: ${specFile}`);\n await showSpecPreview(specFile);\n await askToAdjust(specFile);\n}\n\n/**\n * 构建项目上下文\n */\nasync function buildProjectContext(): Promise<string> {\n const context: string[] = [];\n\n // 扫描后端目录\n if (await FileUtils.exists('backend/src/main/java')) {\n context.push('### 后端结构');\n const backendDirs = await FileUtils.findFiles('*/', 'backend/src/main/java');\n const limited = backendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - backend/src/main/java/${dir}`);\n });\n }\n\n // 扫描前端目录\n if (await FileUtils.exists('frontend/src')) {\n context.push('');\n context.push('### 前端结构');\n const frontendDirs = await FileUtils.findFiles('*/', 'frontend/src');\n const limited = frontendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - frontend/src/${dir}`);\n });\n }\n\n // 扫描已有 specs\n if (await FileUtils.exists('docs/specs')) {\n context.push('');\n context.push('### 已有功能');\n const files = await FileUtils.findFiles('*.md', 'docs/specs');\n const specs = files.filter((f) => !f.includes('template'));\n\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join('docs/specs', file));\n context.push(` - ${file.replace('.md', '')} [${status}]`);\n }\n }\n\n return context.join('\\n');\n}\n\n/**\n * 构建 PRD 模式 prompt\n */\nfunction buildPrdPrompt(\n featureName: string,\n prdContent: string,\n projectContext: string,\n completedSpecs: string[]\n): string {\n const deps = completedSpecs.length > 0 ? completedSpecs.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n你现在需要根据 PRD 文档生成一个功能规格(Spec)文档。\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 功能名称\n${featureName}\n\n## PRD 文档内容\n${prdContent}\n\n## 依赖功能\n此功能可能依赖以下已完成的功能:${deps}\n\n## 任务\n请根据 PRD 文档,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${completedSpecs.map((s) => `- [x] ${s}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n6. 从 PRD 中提取关键信息,保持简洁`;\n}\n\n/**\n * 构建简单描述模式 prompt\n */\nfunction buildSimplePrompt(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies: string[]\n): string {\n const deps = dependencies.length > 0 ? dependencies.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n用户想要添加一个新功能,需要你生成功能规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n\n## 依赖功能\n此功能依赖以下已完成的功能:${deps}\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${dependencies.map((d) => `- [x] ${d}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断要合理,避免全部是 P0\n3. 工时评估要实际,不要过于乐观\n4. 功能点要具体可执行\n5. 根据功能描述推断合理的 API 和数据模型\n6. 参考已有功能的技术风格保持一致性`;\n}\n\n/**\n * 更新 AI_MEMORY\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否有功能清单部分\n if (!content.includes('## 功能清单')) {\n // 添加功能清单部分\n const featureList = `\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n| ${featureName} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |\n`;\n content = content.replace('(/项目信息/[^#]*)', `$1\\n${featureList}`);\n } else {\n // 在功能清单中添加新功能\n const newRow = `| ${featureName} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n content = content.replace(\n /(\\| 功能 \\| Spec 文件 \\| 状态 \\| 进度 \\| 完成日期 \\| 备注 \\|)/,\n `$1\\n${newRow}`\n );\n }\n\n await FileUtils.write(aiMemoryFile, content);\n logger.success('AI_MEMORY.md 已更新');\n}\n\n/**\n * 显示 spec 预览\n */\nasync function showSpecPreview(specFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 Spec 预览:');\n logger.newLine();\n\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n}\n\n/**\n * 询问是否需要调整\n */\nasync function askToAdjust(specFile: string): Promise<void> {\n const { needAdjust } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'needAdjust',\n message: '是否需要调整 Spec 内容?',\n default: false,\n },\n ]);\n\n if (needAdjust) {\n logger.info('正在打开编辑器...');\n const editor = process.env.EDITOR || 'vim';\n const { execaCommand } = await import('execa');\n await execaCommand(`${editor} ${specFile}`, { stdio: 'inherit' });\n }\n\n logger.newLine();\n logger.info('下一步:');\n logger.step(`1. 运行 'team-cli breakdown ${specFile}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Split-prd 命令 - 将 PRD 拆分为多个 specs\n */\nexport const splitPrdCommand = new Command('split-prd')\n .argument('<prd-folder>', 'PRD 文档目录')\n .description('将 PRD 拆分成多个 specs')\n .action(async (prdFolder) => {\n try {\n logger.header('PRD 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 检查文件夹是否存在\n const folderExists = await FileUtils.exists(prdFolder);\n if (!folderExists) {\n throw new Error(`PRD 文件夹不存在: ${prdFolder}`);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 执行 PRD 拆分任务\n const tasks = new Listr([\n {\n title: '扫描 PRD 文件',\n task: async (ctx) => {\n const supportedExtensions = ['md', 'txt', 'markdown'];\n ctx.prdFiles = [];\n\n for (const ext of supportedExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, prdFolder);\n ctx.prdFiles.push(...files.map((f) => path.join(prdFolder, f)));\n }\n\n if (ctx.prdFiles.length === 0) {\n throw new Error(\n '未找到 PRD 文档 (支持 .md, .txt, .markdown)'\n );\n }\n\n ctx.prdFile = ctx.prdFiles[0];\n if (ctx.prdFiles.length > 1) {\n logger.info(`找到多个 PRD 文档,使用: ${ctx.prdFile}`);\n } else {\n logger.success(`找到 PRD 文档: ${ctx.prdFile}`);\n }\n },\n },\n {\n title: '扫描截图文件',\n task: async (ctx) => {\n const screenshotDir = path.join(prdFolder, 'screenshots');\n const dirExists = await FileUtils.exists(screenshotDir);\n\n if (!dirExists) {\n logger.info('未找到 screenshots 目录,跳过截图');\n ctx.screenshots = [];\n return;\n }\n\n const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];\n ctx.screenshots = [];\n\n for (const ext of imageExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, screenshotDir);\n ctx.screenshots.push(...files.map((f) => path.join(screenshotDir, f)));\n }\n\n logger.success(`找到 ${ctx.screenshots.length} 个截图文件`);\n },\n },\n {\n title: '扫描 demo 代码仓库',\n task: async (ctx) => {\n const entries = await FileUtils.findFiles('*/', prdFolder);\n ctx.demoRepos = [];\n\n for (const entry of entries) {\n const dirPath = path.join(prdFolder, entry);\n const gitDir = path.join(dirPath, '.git');\n const hasGit = await FileUtils.exists(gitDir);\n if (hasGit) {\n ctx.demoRepos.push(dirPath);\n }\n }\n\n if (ctx.demoRepos.length > 0) {\n logger.success(`找到 demo 仓库: ${ctx.demoRepos.join(', ')}`);\n } else {\n logger.info('未找到 demo 代码仓库,跳过');\n }\n },\n },\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(ctx.prdFile);\n },\n },\n {\n title: '调用 Claude 拆分 PRD',\n task: async (ctx) => {\n const prompt = buildSplitPrdPrompt(\n ctx.prdContent,\n ctx.screenshots,\n ctx.demoRepos\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n return await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD 拆分完成!');\n logger.success('Spec 文件已生成到 docs/specs/ 目录');\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(\"1. 检查生成的 spec 文件\");\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分 milestones\");\n logger.step(\"3. 运行 'team-cli dev' 开始开发\");\n logger.newLine();\n } catch (error: any) {\n logger.error(`PRD 拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 构建 PRD 拆分 prompt\n */\nfunction buildSplitPrdPrompt(\n prdContent: string,\n screenshots: string[],\n demoRepos: string[]\n): string {\n let prompt = `Role: Senior Product Manager and Technical Architect\n\nTask: Analyze the following PRD and split it into multiple independent feature specifications (specs).\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each spec should be a standalone feature that can be developed independently\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n`;\n\n // 添加截图信息\n if (screenshots.length > 0) {\n prompt += `\nScreenshots available (${screenshots.length} files):\n`;\n for (const screenshot of screenshots) {\n prompt += ` - ${screenshot}\\n`;\n }\n prompt += `You can use the Read tool to view these screenshots for visual reference.\n`;\n }\n\n // 添加 demo 仓库信息\n if (demoRepos.length > 0) {\n prompt += `\nDemo Code Repos available:\n`;\n for (const repo of demoRepos) {\n prompt += ` - ${repo}\\n`;\n }\n prompt += `You can explore these repos to understand existing implementation patterns.\n`;\n }\n\n prompt += `\nOutput Requirements:\n1. Split the PRD into multiple feature specs based on functionality\n2. Each spec should follow the template format (see docs/specs/template.md)\n3. Create each spec as a separate markdown file in docs/specs/\n4. Use kebab-case for filenames (e.g., user-authentication.md, data-export.md)\n5. Each spec must include:\n - Feature Overview (功能概述)\n - Background & Goals (背景与目标)\n - Functional Requirements (功能需求)\n - Technical Design (技术设计)\n - Acceptance Criteria (验收标准)\n\nSpec Format Template:\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他 spec)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点\n\n## 技术设计\n\n### API 设计\n列出主要的 API 端点\n\n### 数据模型\n列出需要的数据表\n\n## 验收标准\n- [ ] 验收标准 1\n- [ ] 验收标准 2\n- [ ] 验收标准 3\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n- After generating all spec files, exit immediately without waiting for further input\n- Do not ask any questions\n- Each spec should be implementable in 1-3 days\n- Dependencies between features should be clearly noted in the 依赖关系 section\n`;\n\n return prompt;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\n\n/**\n * Bugfix 命令 - 创建 Bugfix 记录\n */\nexport const bugfixCommand = new Command('bugfix')\n .description('创建 Bugfix 记录')\n .action(async () => {\n try {\n logger.header('创建 Bugfix 记录');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式收集 bug 信息\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'severity',\n message: 'Bug 严重程度:',\n choices: [\n { name: '高 - 阻塞功能或影响核心流程', value: '高' },\n { name: '中 - 影响功能但不阻塞', value: '中' },\n { name: '低 - 小问题或体验问题', value: '低' },\n ],\n default: '中',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Bug 描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'input',\n name: 'reproduction',\n message: '复现步骤:',\n default: '1. 步骤一\\n2. 步骤二\\n3. 步骤三',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['全部用户', '部分用户', '个别用户', '未知'],\n default: '部分用户',\n },\n ]);\n\n // 生成 bug ID\n const bugId = generateBugId();\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD');\n\n // 查找可能关联的 spec\n const relatedSpec = await findRelatedSpec(answers.description);\n\n // 创建 bugfix 文档\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n const bugfixFile = path.join(bugfixDir, `${timestamp}_${bugId}.md`);\n\n const content = formatBugfixDocument({\n id: bugId,\n severity: answers.severity,\n description: answers.description,\n reproduction: answers.reproduction,\n scope: answers.scope,\n relatedSpec,\n timestamp,\n });\n\n await FileUtils.write(bugfixFile, content);\n\n logger.success(`Bugfix 记录已创建: ${bugfixFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 分析 bug 根本原因');\n logger.step(\"2. 运行 'team-cli dev' 选择关联的 spec 进行修复\");\n logger.step('3. 修复后更新 bugfix 文档状态');\n logger.newLine();\n } catch (error: any) {\n logger.error(`创建 bugfix 失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Hotfix 命令 - 紧急修复\n */\nexport const hotfixCommand = new Command('hotfix')\n .description('紧急修复流程')\n .action(async () => {\n try {\n logger.header('紧急修复流程');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.warn('注意: hotfix 用于紧急问题修复');\n logger.warn('修复后需要创建规范 bugfix 记录');\n logger.newLine();\n\n // 交互式收集信息\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '紧急问题描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['所有用户', '部分用户', '特定用户'],\n default: '所有用户',\n },\n {\n type: 'input',\n name: 'solution',\n message: '临时解决方案:',\n validate: (input: string) => input.trim().length > 0 || '方案不能为空',\n },\n ]);\n\n // 生成 hotfix ID\n const hotfixId = generateHotfixId();\n const branchName = `hotfix/${hotfixId}`;\n\n // 创建 hotfix 分支并提交\n const tasks = new Listr([\n {\n title: '创建 hotfix 分支',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['checkout', '-b', branchName], { stdio: 'inherit' });\n },\n },\n {\n title: '创建 hotfix 记录',\n task: async () => {\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n const hotfixDir = 'docs/hotfixes';\n await FileUtils.ensureDir(hotfixDir);\n\n const hotfixFile = path.join(hotfixDir, `${timestamp}_${hotfixId}.md`);\n const content = formatHotfixDocument({\n id: hotfixId,\n description: answers.description,\n scope: answers.scope,\n solution: answers.solution,\n branch: branchName,\n timestamp,\n });\n\n await FileUtils.write(hotfixFile, content);\n },\n },\n {\n title: '创建初始 commit',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['add', 'docs/hotfixes'], { stdio: 'pipe' });\n await execa(\n 'git',\n [\n 'commit',\n '-m',\n `hotfix: ${answers.description}\\n\\nTemporary solution: ${answers.solution}`,\n ],\n { stdio: 'pipe' }\n );\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`Hotfix 分支已创建: ${branchName}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 实施修复');\n logger.step(\"2. 运行 'team-cli lint' 检查代码\");\n logger.step('3. 提交并推送到远程');\n logger.step('4. 创建 PR 进行 code review');\n logger.step('5. 合并后创建规范 bugfix 记录');\n logger.newLine();\n } catch (error: any) {\n logger.error(`Hotfix 流程失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成 Bug ID\n */\nfunction generateBugId(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n // 简单的序号生成(实际应该从已有文件中获取最大序号)\n return `BUG-${year}${month}${day}-001`;\n}\n\n/**\n * 生成 Hotfix ID\n */\nfunction generateHotfixId(): string {\n const date = new Date();\n const timestamp = date.getTime().toString().slice(-6);\n return `HF-${timestamp}`;\n}\n\n/**\n * 查找可能关联的 spec\n */\nasync function findRelatedSpec(description: string): Promise<string> {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n return '';\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n return '';\n }\n\n // 简单的关键词匹配\n const keywords = extractKeywords(description);\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n\n for (const keyword of keywords) {\n if (content.toLowerCase().includes(keyword.toLowerCase())) {\n return file.replace('.md', '');\n }\n }\n }\n\n return '';\n}\n\n/**\n * 提取关键词\n */\nfunction extractKeywords(text: string): string[] {\n // 简单的分词和过滤\n const stopWords = ['的', '是', '在', '有', '和', '或', '了', '不', '吗', '呢'];\n const words = text\n .toLowerCase()\n .replace(/[^\\w\\s\\u4e00-\\u9fa5]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !stopWords.includes(w));\n\n return words.slice(0, 5);\n}\n\n/**\n * 格式化 bugfix 文档\n */\nfunction formatBugfixDocument(data: {\n id: string;\n severity: string;\n description: string;\n reproduction: string;\n scope: string;\n relatedSpec: string;\n timestamp: string;\n}): string {\n return `# Bugfix: ${data.description}\n\n## Bug 信息\n- **ID**: ${data.id}\n- **严重程度**: ${data.severity}\n- **状态**: 待修复\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 复现步骤\n${data.reproduction}\n\n## 影响范围\n${data.scope}\n\n## 关联 Spec\n${data.relatedSpec ? `- ${data.relatedSpec}` : '- (无)'}\n\n## 修复方案\n- [ ] 分析根本原因\n- [ ] 设计修复方案\n- [ ] 实施修复\n- [ ] 编写测试\n- [ ] 验证修复\n\n## 验证清单\n- [ ] 本地测试通过\n- [ ] 单元测试覆盖\n- [ ] 回归测试通过\n- [ ] 更新相关文档\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n\n/**\n * 格式化 hotfix 文档\n */\nfunction formatHotfixDocument(data: {\n id: string;\n description: string;\n scope: string;\n solution: string;\n branch: string;\n timestamp: string;\n}): string {\n return `# Hotfix: ${data.description}\n\n## Hotfix 信息\n- **ID**: ${data.id}\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 影响范围\n${data.scope}\n\n## 临时解决方案\n${data.solution}\n\n## 修复分支\n\\`\\`\\`\ngit checkout ${data.branch}\n\\`\\`\\`\n\n## 后续步骤\n- [ ] 实施紧急修复\n- [ ] 推送到远程\n- [ ] 创建 PR 进行 code review\n- [ ] 紧急合并到主分支\n- [ ] 创建规范 bugfix 记录\n- [ ] 计划彻底修复方案\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\nimport { execa } from 'execa';\n\n/**\n * Lint 命令 - 代码质量检查\n */\nexport const lintCommand = new Command('lint')\n .option('--fix', '自动修复问题')\n .description('代码质量检查 (前端 + 后端)')\n .action(async (options) => {\n try {\n logger.header('代码质量检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const results = {\n frontend: { exists: false, passed: false, errors: [] },\n backend: { exists: false, passed: false, errors: [] },\n };\n\n // 检查前端\n const frontendExists = await FileUtils.exists('frontend/package.json');\n if (frontendExists) {\n results.frontend.exists = true;\n try {\n logger.step('检查前端代码...');\n\n // ESLint 检查\n if (options.fix) {\n await execa('npm', ['run', 'lint', '--', '--fix'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n } else {\n await execa('npm', ['run', 'lint'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n }\n\n // TypeScript 类型检查\n await execa('npx', ['tsc', '--noEmit'], {\n cwd: 'frontend',\n stdio: 'pipe',\n });\n\n results.frontend.passed = true;\n logger.success('前端代码检查通过');\n } catch (error: any) {\n results.frontend.errors.push(error.message);\n logger.error('前端代码检查失败');\n }\n } else {\n logger.info('未找到前端项目 (frontend/package.json)');\n }\n\n logger.newLine();\n\n // 检查后端\n const backendExists = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/pom.xml');\n if (backendExists) {\n results.backend.exists = true;\n\n // 检查构建工具\n const hasGradle = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/build.gradle.kts');\n const hasMaven = await FileUtils.exists('backend/pom.xml');\n\n try {\n logger.step('检查后端代码...');\n\n if (hasGradle) {\n // Gradle 构建\n if (options.fix) {\n await execa('./gradlew', ['spotlessApply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./gradlew', ['checkstyleMain', 'compileJava'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n } else if (hasMaven) {\n // Maven 构建\n if (options.fix) {\n await execa('./mvnw', ['spotless:apply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./mvnw', ['checkstyle:check', 'compile'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n\n results.backend.passed = true;\n logger.success('后端代码检查通过');\n } catch (error: any) {\n results.backend.errors.push(error.message);\n logger.error('后端代码检查失败');\n }\n } else {\n logger.info('未找到后端项目 (build.gradle 或 pom.xml)');\n }\n\n logger.newLine();\n logger.separator('=', 50);\n logger.newLine();\n\n // 汇总结果\n let hasErrors = false;\n\n if (results.frontend.exists) {\n if (results.frontend.passed) {\n logger.success('前端: ✓ 通过');\n } else {\n logger.error('前端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n if (results.backend.exists) {\n if (results.backend.passed) {\n logger.success('后端: ✓ 通过');\n } else {\n logger.error('后端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n logger.newLine();\n\n if (hasErrors) {\n logger.error('代码检查失败');\n logger.info(\"运行 'team-cli lint --fix' 尝试自动修复\");\n process.exit(1);\n } else {\n logger.success('代码检查全部通过');\n }\n } catch (error: any) {\n logger.error(`代码检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, GitUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * Status 命令 - 查看项目状态\n */\nexport const statusCommand = new Command('status')\n .description('查看项目状态')\n .action(async () => {\n try {\n logger.header('项目状态');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 显示项目信息\n await displayProjectInfo();\n\n // 显示功能清单\n await displayFeatureInventory();\n\n // 显示 Git 状态\n await displayGitStatus();\n\n // 显示最近活动\n await displayRecentActivity();\n } catch (error: any) {\n logger.error(`获取状态失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示项目信息\n */\nasync function displayProjectInfo(): Promise<void> {\n logger.info('项目信息:');\n logger.newLine();\n\n // 读取项目名称\n if (await FileUtils.exists('AI_MEMORY.md')) {\n const content = await FileUtils.read('AI_MEMORY.md');\n const projectName = content.match(/项目名称.*[::]\\s*(.+)/);\n const currentPhase = content.match(/当前阶段.*[::]\\s*(.+)/);\n const lastUpdated = content.match(/最后更新.*[::]\\s*(.+)/);\n\n if (projectName) logger.step(`名称: ${projectName[1].trim()}`);\n if (currentPhase) logger.step(`阶段: ${currentPhase[1].trim()}`);\n if (lastUpdated) logger.step(`更新: ${lastUpdated[1].trim()}`);\n } else {\n logger.step('AI_MEMORY.md 不存在');\n }\n\n logger.newLine();\n}\n\n/**\n * 显示功能清单\n */\nasync function displayFeatureInventory(): Promise<void> {\n logger.info('功能清单:');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n // 解析每个 spec 的状态\n const inventory: Array<{\n name: string;\n status: string;\n progress: string;\n }> = [];\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n const status = parseSpecStatus(content);\n\n inventory.push({\n name: file.replace('.md', ''),\n status,\n progress: getProgress(content),\n });\n }\n\n // 显示表格\n const tableData = inventory.map((item) => [\n item.name,\n item.status,\n item.progress,\n ]);\n\n logger.table(['功能', '状态', '进度'], tableData);\n logger.newLine();\n\n // 统计\n const completed = inventory.filter((i) => i.status === '已完成').length;\n const inProgress = inventory.filter((i) => i.status === '进行中').length;\n const pending = inventory.filter((i) => i.status === '未开始').length;\n\n logger.info(`总计: ${inventory.length} | 已完成: ${completed} | 进行中: ${inProgress} | 未开始: ${pending}`);\n logger.newLine();\n}\n\n/**\n * 显示 Git 状态\n */\nasync function displayGitStatus(): Promise<void> {\n const isRepo = await GitUtils.isGitRepo();\n\n if (!isRepo) {\n logger.info('Git 状态: 非 Git 仓库');\n logger.newLine();\n return;\n }\n\n try {\n const branch = await GitUtils.getCurrentBranch();\n const commit = await GitUtils.getCurrentCommit();\n\n logger.info('Git 状态:');\n logger.step(`分支: ${branch}`);\n logger.step(`提交: ${commit}`);\n logger.newLine();\n } catch {\n logger.info('Git 状态: 无法获取');\n logger.newLine();\n }\n}\n\n/**\n * 显示最近活动\n */\nasync function displayRecentActivity(): Promise<void> {\n logger.info('最近活动:');\n logger.newLine();\n\n // 检查会话日志\n const sessionDir = 'docs/sessions';\n const exists = await FileUtils.exists(sessionDir);\n\n if (!exists) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', sessionDir);\n if (files.length === 0) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n // 按时间排序,取最近 5 个\n const sorted = files.sort().reverse().slice(0, 5);\n\n for (const file of sorted) {\n const filePath = path.join(sessionDir, file);\n const stat = await FileUtils.read(filePath);\n const specMatch = stat.match(/\\*\\*Spec\\*\\*:\\s*(.+)/);\n const spec = specMatch ? specMatch[1].trim() : '未知';\n\n // 从文件名提取时间\n const match = file.match(/(\\d{4}-\\d{2}-\\d{2})/);\n const date = match ? match[1] : '未知';\n\n logger.step(`${date} - ${spec}`);\n }\n\n logger.newLine();\n\n if (files.length > 5) {\n logger.info(`(还有 ${files.length - 5} 个历史会话记录)`);\n logger.newLine();\n }\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): string {\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '✓ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n }\n return '○ 未开始';\n}\n\n/**\n * 获取进度\n */\nfunction getProgress(spec: string): string {\n // 解析里程碑和 todos\n const milestoneMatches = spec.match(/###\\s+Milestone\\s+\\d+:/g);\n const milestones = milestoneMatches ? milestoneMatches.length : 0;\n\n const todoMatches = spec.match(/-\\s+\\[[ x ]\\]/g);\n const totalTodos = todoMatches ? todoMatches.length : 0;\n\n const completedMatches = spec.match(/-\\s+\\[x\\]/g);\n const completedTodos = completedMatches ? completedMatches.length : 0;\n\n if (totalTodos === 0) {\n return '-';\n }\n\n return `${completedTodos}/${totalTodos}`;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Detect-deps 命令 - 检测依赖关系\n */\nexport const detectDepsCommand = new Command('detect-deps')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('检测依赖关系')\n .action(async (specFile) => {\n try {\n logger.header('检测依赖关系');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 如果没有指定 spec,扫描所有 specs\n if (!specFile) {\n logger.info('未指定 spec 文件,将扫描所有 specs...');\n logger.newLine();\n\n const specsDir = 'docs/specs';\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n if (specs.length === 0) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n for (const spec of specs) {\n const specPath = path.join(specsDir, spec);\n logger.step(`处理: ${spec}`);\n await detectDependencies(specPath);\n logger.newLine();\n }\n } else {\n // 检查文件是否存在\n const exists = await FileUtils.exists(specFile);\n if (!exists) {\n logger.error(`Spec 文件不存在: ${specFile}`);\n process.exit(1);\n }\n\n await detectDependencies(specFile);\n }\n\n logger.header('依赖检测完成');\n } catch (error: any) {\n logger.error(`依赖检测失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测依赖关系\n */\nasync function detectDependencies(specFile: string): Promise<void> {\n logger.step('自动检测依赖关系...');\n\n const projectDir = '.';\n const allDeps = new Set<string>();\n\n // 1. 扫描后端依赖\n const backendDir = path.join(projectDir, 'backend');\n const backendExists = await FileUtils.exists(backendDir);\n\n if (backendExists) {\n // 扫描 API 调用\n const apiDeps = await scanBackendApiCalls(backendDir);\n apiDeps.forEach((d) => allDeps.add(d));\n\n // 扫描实体关联\n const entityDeps = await scanBackendEntityRelations(backendDir);\n entityDeps.forEach((d) => allDeps.add(d));\n\n // 扫描服务引用\n const serviceDeps = await scanBackendServiceRefs(backendDir);\n serviceDeps.forEach((d) => allDeps.add(d));\n }\n\n // 2. 扫描前端依赖\n const frontendDir = path.join(projectDir, 'frontend');\n const frontendExists = await FileUtils.exists(frontendDir);\n\n if (frontendExists) {\n const frontendDeps = await scanFrontendApiCalls(frontendDir);\n frontendDeps.forEach((d) => allDeps.add(d));\n }\n\n if (allDeps.size === 0) {\n logger.info('未检测到明确的依赖关系');\n return;\n }\n\n // 3. 匹配到对应的 spec 文件\n const detectedSpecs: string[] = [];\n for (const dep of allDeps) {\n const matchedSpec = await findSpecByKeyword(dep, 'docs/specs');\n if (matchedSpec && !detectedSpecs.includes(matchedSpec)) {\n detectedSpecs.push(matchedSpec);\n }\n }\n\n if (detectedSpecs.length === 0) {\n logger.info('检测到依赖,但未找到对应的 spec 文件');\n return;\n }\n\n // 4. 输出检测结果\n logger.success(`检测到 ${detectedSpecs.length} 个潜在依赖:`);\n for (const spec of detectedSpecs) {\n logger.step(`- ${spec}`);\n }\n logger.newLine();\n\n // 5. 询问是否自动更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'autoUpdate',\n message: '是否自动更新依赖关系到 spec 文件?',\n default: true,\n },\n ]);\n\n if (answers.autoUpdate) {\n await updateSpecDependencies(specFile, detectedSpecs);\n logger.success('依赖关系已更新');\n }\n}\n\n/**\n * 扫描后端 API 调用\n */\nasync function scanBackendApiCalls(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n // 查找 Java 文件中的 RestTemplate/WebClient/RestClient 调用\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n // 提取模块名 (如 /api/users -> users)\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]); // 'api' 后面的部分\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端实体关联\n */\nasync function scanBackendEntityRelations(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 @JoinColumn, @ManyToOne, @OneToMany\n if (\n content.includes('@JoinColumn') ||\n content.includes('@ManyToOne') ||\n content.includes('@OneToMany')\n ) {\n // 提取关联的实体类型\n const typeRegex = /type\\s*=\\s*(\\w+)/g;\n let match;\n while ((match = typeRegex.exec(content)) !== null) {\n deps.push(match[1].toLowerCase());\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端服务引用\n */\nasync function scanBackendServiceRefs(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 Service 注入\n const serviceRegex = /private\\s+(\\w+)Service/g;\n let match;\n while ((match = serviceRegex.exec(content)) !== null) {\n const serviceName = match[1];\n // 提取模块名 (UserService -> user)\n const moduleName = serviceName.replace(/Service$/, '').toLowerCase();\n deps.push(moduleName);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描前端 API 调用\n */\nasync function scanFrontendApiCalls(frontendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(frontendDir, 'src');\n\n try {\n // 查找 TypeScript/JavaScript 文件\n const tsFiles = await FileUtils.findFiles('*.{ts,tsx,js,jsx}', srcDir);\n\n for (const file of tsFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]);\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 根据关键词查找 spec\n */\nasync function findSpecByKeyword(\n keyword: string,\n specsDir: string\n): Promise<string | null> {\n const exists = await FileUtils.exists(specsDir);\n if (!exists) {\n return null;\n }\n\n try {\n const files = await FileUtils.findFiles('*.md', specsDir);\n\n for (const file of files) {\n if (file === 'template.md') continue;\n\n const name = file.replace('.md', '');\n // 模糊匹配\n if (name.includes(keyword) || keyword.includes(name)) {\n return name;\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return null;\n}\n\n/**\n * 更新 spec 的依赖关系\n */\nasync function updateSpecDependencies(\n specFile: string,\n deps: string[]\n): Promise<void> {\n let content = await FileUtils.read(specFile);\n\n // 检查是否有依赖关系部分\n if (!content.includes('## 依赖关系')) {\n // 在背景与目标前插入依赖关系部分\n const targetSection = '## 背景与目标';\n const insertIndex = content.indexOf(targetSection);\n\n if (insertIndex !== -1) {\n const depsSection = `\\n## 依赖关系\\n\\n**前置依赖**:\\n${deps.map((d) => ` - [x] ${d}`).join('\\n')}\\n\\n**被依赖于**:\\n - (自动生成,表示哪些 spec 依赖本功能)\\n\\n`;\n content =\n content.slice(0, insertIndex) + depsSection + content.slice(insertIndex);\n }\n } else {\n // 更新现有依赖关系\n const lines = content.split('\\n');\n let inDeps = false;\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('## 依赖关系')) {\n inDeps = true;\n result.push(line);\n result.push('');\n result.push('**前置依赖**:');\n for (const dep of deps) {\n result.push(` - [x] ${dep}`);\n }\n result.push('');\n result.push('**被依赖于**:');\n result.push(' - (自动生成,表示哪些 spec 依赖本功能)');\n continue;\n }\n\n if (inDeps) {\n // 跳过旧的前置依赖内容,直到遇到下一个章节\n if (line.startsWith('## ') && !line.startsWith('## 依赖关系')) {\n inDeps = false;\n result.push(line);\n }\n continue;\n }\n\n result.push(line);\n }\n\n content = result.join('\\n');\n }\n\n await FileUtils.write(specFile, content);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { readTemplateConfig } from '../lib/template-version.js';\n\n/**\n * Sync-memory 命令 - 同步 AI_MEMORY.md\n */\nexport const syncMemoryCommand = new Command('sync-memory')\n .description('同步 AI_MEMORY.md')\n .action(async () => {\n try {\n logger.header('同步 AI_MEMORY.md');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.info('AI_MEMORY.md 不存在,跳过同步');\n process.exit(0);\n }\n\n // 1. 同步功能清单\n await syncFeatureInventory(aiMemoryFile, '.');\n\n // 2. 同步 API 列表\n await syncApiInventory(aiMemoryFile, '.');\n\n // 3. 同步数据模型\n await syncDataModels(aiMemoryFile, '.');\n\n // 4. 同步模板版本信息\n await syncTemplateVersions(aiMemoryFile, '.');\n\n // 5. 更新最后同步时间\n await updateSyncTime(aiMemoryFile);\n\n logger.success('AI_MEMORY.md 已同步');\n } catch (error: any) {\n logger.error(`同步失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 同步功能清单\n */\nasync function syncFeatureInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步功能清单...');\n\n const specsDir = path.join(projectDir, 'docs/specs');\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n return;\n }\n\n // 读取所有 specs\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n // 构建功能清单表格\n const lines: string[] = [];\n lines.push('## 功能清单 (Feature Inventory)');\n lines.push('');\n lines.push('| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |');\n lines.push('|------|----------|------|------|---------|------|');\n\n for (const specFile of specs) {\n const name = specFile.replace('.md', '');\n const displayName = name\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const specPath = path.join(specsDir, specFile);\n const content = await FileUtils.read(specPath);\n\n // 获取状态\n const status = parseSpecStatus(content);\n\n // 获取进度\n const progress = getSpecProgress(content);\n\n // 获取完成日期\n let completionDate = '-';\n if (status === '✅ 已完成') {\n const dateMatch = content.match(/完成日期.*[::]\\s*(.+)/);\n if (dateMatch) {\n completionDate = dateMatch[1].trim();\n }\n }\n\n lines.push(`| ${displayName} | ${name}.md | ${status} | ${progress} | ${completionDate} | |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 功能清单', newContent);\n}\n\n/**\n * 同步 API 列表\n */\nasync function syncApiInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步 API 列表...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## API 列表 (API Inventory)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Controller 生成');\n lines.push('');\n\n // 查找所有 Controller\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n if (controllers.length === 0) {\n lines.push('暂无 API');\n } else {\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n lines.push(`### ${module} 模块`);\n lines.push('');\n lines.push('| 方法 | 路径 | 说明 | 状态 | 日期 |');\n lines.push('|------|------|------|------|------|');\n\n // 扫描 API\n const apis = await scanControllerApis(controllerPath);\n for (const api of apis) {\n lines.push(`| ${api.method} | ${api.path} | ${api.description} | ✅ | ${api.date} |`);\n }\n lines.push('');\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## API 列表', newContent);\n}\n\n/**\n * 扫描 Controller 中的 API\n */\nasync function scanControllerApis(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string; date: string }>> {\n const apis: Array<{ method: string; path: string; description: string; date: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n date: DateUtils.format(new Date(), 'YYYY-MM-DD'),\n });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n // 查找方法定义前的注释\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n // 向前查找注释\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n\n/**\n * 同步数据模型\n */\nasync function syncDataModels(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步数据模型...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 数据模型 (Data Models)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Entity 生成');\n lines.push('');\n\n // 查找所有 Entity\n const srcDir = path.join(backendDir, 'src');\n const entities = await FileUtils.findFiles('*Entity.java', srcDir);\n\n if (entities.length === 0) {\n lines.push('暂无数据模型');\n } else {\n lines.push('| 模型 | 说明 | 字段 | 关联 |');\n lines.push('|------|------|------|------|');\n\n for (const entityFile of entities) {\n const entityPath = path.join(srcDir, entityFile);\n const entityName = entityFile.replace('.java', '').replace(/Entity$/, '');\n const displayName = entityName\n .split(/(?=[A-Z])/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n // 读取实体内容\n const content = await FileUtils.read(entityPath);\n\n // 提取注释\n const classCommentMatch = content.match(/\\/\\*\\*\\s*\\n([^*]|\\*[^/])*\\*\\//);\n const description = classCommentMatch\n ? classCommentMatch[0].replace(/\\/\\*\\*|\\*\\/|\\*/g, '').trim()\n : '';\n\n // 计算字段数\n const fieldCount = (content.match(/private\\s+\\w+/g) || []).length;\n\n // 检查关联\n const relations: string[] = [];\n if (content.includes('@ManyToOne')) relations.push('Many-to-One');\n if (content.includes('@OneToMany')) relations.push('One-to-Many');\n if (content.includes('@OneToOne')) relations.push('One-to-One');\n if (content.includes('@ManyToMany')) relations.push('Many-to-Many');\n\n lines.push(`| ${displayName} | ${description} | ${fieldCount} | ${relations.join(', ') || '-'} |`);\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 数据模型', newContent);\n}\n\n/**\n * 更新同步时间\n */\nasync function updateSyncTime(aiMemoryFile: string): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n\n let updated = content;\n\n // 查找并更新最后同步时间\n if (content.includes('最后同步')) {\n updated = content.replace(\n /最后同步.*[::]\\s*.+/,\n `最后同步: ${timestamp}`\n );\n } else {\n // 在文件末尾添加\n updated = content.trimEnd() + `\\n\\n---\\n\\n*最后同步: ${timestamp} by team-cli*\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, updated);\n}\n\n/**\n * 替换或插入章节\n */\nasync function replaceOrInsertSection(\n aiMemoryFile: string,\n sectionTitle: string,\n newContent: string\n): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否存在该章节\n if (content.includes(sectionTitle)) {\n // 替换现有章节\n const lines = content.split('\\n');\n const result: string[] = [];\n let inSection = false;\n let skip = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith(sectionTitle)) {\n inSection = true;\n result.push(newContent);\n skip = true;\n continue;\n }\n\n if (inSection) {\n if (line.startsWith('## ') && !line.startsWith(sectionTitle)) {\n inSection = false;\n skip = false;\n result.push(line);\n }\n continue;\n }\n\n if (!skip) {\n result.push(line);\n }\n }\n\n await FileUtils.write(aiMemoryFile, result.join('\\n'));\n } else {\n // 插入新章节\n await FileUtils.write(aiMemoryFile, content.trimEnd() + '\\n\\n' + newContent + '\\n');\n }\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): string {\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '✅ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n }\n return '○ 未开始';\n}\n\n/**\n * 获取 spec 进度\n */\nfunction getSpecProgress(spec: string): string {\n const todoMatches = spec.match(/-\\s+\\[[ x ]\\]/g);\n const totalTodos = todoMatches ? todoMatches.length : 0;\n\n const completedMatches = spec.match(/-\\s+\\[x\\]/g);\n const completedTodos = completedMatches ? completedMatches.length : 0;\n\n if (totalTodos === 0) {\n return '-';\n }\n\n return `${completedTodos}/${totalTodos}`;\n}\n\n/**\n * 同步模板版本信息\n */\nasync function syncTemplateVersions(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步模板版本信息...');\n\n const config = await readTemplateConfig(projectDir);\n\n if (!config) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 模板版本信息');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动管理,记录使用的前后端模板版本');\n lines.push('');\n lines.push('| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |');\n lines.push('|------|------|-----|--------|--------|----------|');\n\n // 前端模板\n if (config.frontend) {\n const repoName = extractRepoName(config.frontend.repository);\n const commit = config.frontend.commit?.substring(0, 8) || '-';\n const tag = config.frontend.tag || '-';\n const branch = config.frontend.branch || '-';\n const updateDate = config.frontend.lastUpdate\n ? new Date(config.frontend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 前端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n // 后端模板\n if (config.backend) {\n const repoName = extractRepoName(config.backend.repository);\n const commit = config.backend.commit?.substring(0, 8) || '-';\n const tag = config.backend.tag || '-';\n const branch = config.backend.branch || '-';\n const updateDate = config.backend.lastUpdate\n ? new Date(config.backend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 后端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 模板版本信息', newContent);\n}\n\n/**\n * 从仓库 URL 中提取仓库名\n */\nfunction extractRepoName(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名部分\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\n\n/**\n * Check-api 命令 - API 检查\n */\nexport const checkApiCommand = new Command('check-api')\n .description('API 检查(冲突/变更/Registry)')\n .action(async () => {\n try {\n logger.header('API 检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式选择\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'checkType',\n message: '选择检查类型:',\n choices: [\n { name: '检测 API 冲突', value: 'conflicts' },\n { name: '检测 API 变更', value: 'changes' },\n { name: '生成 API Registry', value: 'registry' },\n { name: '全部执行', value: 'all' },\n ],\n default: 'all',\n },\n ]);\n\n const tasks = new Listr([]);\n\n // 根据选择添加任务\n if (answers.checkType === 'conflicts' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 冲突',\n task: async () => {\n await checkApiConflicts('.');\n },\n });\n }\n\n if (answers.checkType === 'changes' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 变更',\n task: async () => {\n await detectApiChanges('.');\n },\n });\n }\n\n if (answers.checkType === 'registry' || answers.checkType === 'all') {\n tasks.add({\n title: '生成 API Registry',\n task: async () => {\n await generateApiRegistry('.');\n },\n });\n }\n\n await tasks.run();\n\n logger.newLine();\n logger.header('API 检查完成');\n } catch (error: any) {\n logger.error(`API 检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测 API 冲突\n */\nasync function checkApiConflicts(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n logger.info('未找到后端项目');\n return;\n }\n\n logger.step('扫描后端 API...');\n logger.newLine();\n\n const apiMap = new Map<string, string[]>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 收集所有 API\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n if (!apiMap.has(key)) {\n apiMap.set(key, []);\n }\n apiMap.get(key)!.push(controllerFile);\n }\n }\n\n // 检查冲突\n const conflicts: Array<{ key: string; controllers: string[] }> = [];\n for (const [key, controllers] of apiMap.entries()) {\n if (controllers.length > 1) {\n conflicts.push({ key, controllers });\n }\n }\n\n if (conflicts.length === 0) {\n logger.success('未发现 API 冲突');\n } else {\n logger.error(`发现 ${conflicts.length} 个 API 冲突:`);\n logger.newLine();\n\n for (const conflict of conflicts) {\n logger.error(`冲突: ${conflict.key}`);\n for (const controller of conflict.controllers) {\n logger.step(` - ${controller}`);\n }\n logger.newLine();\n }\n }\n}\n\n/**\n * 检测 API 变更\n */\nasync function detectApiChanges(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n const registryExists = await FileUtils.exists(registryFile);\n\n if (!registryExists) {\n logger.info('API Registry 不存在,跳过变更检测');\n logger.info(\"运行 'team-cli check-api' 选择 '生成 API Registry'\");\n return;\n }\n\n logger.step('检测 API 变更...');\n logger.newLine();\n\n // 读取现有 Registry\n const registryContent = await FileUtils.read(registryFile);\n const existingApis = extractApisFromRegistry(registryContent);\n\n // 扫描当前 API\n const currentApis = new Map<string, { method: string; path: string; description: string }>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n currentApis.set(key, api);\n }\n }\n\n // 比较差异\n const added: Array<{ method: string; path: string }> = [];\n const removed: Array<{ method: string; path: string }> = [];\n const modified: Array<{ method: string; path: string; oldDesc: string; newDesc: string }> = [];\n\n for (const [key, api] of currentApis.entries()) {\n if (!existingApis.has(key)) {\n added.push({ method: api.method, path: api.path });\n } else {\n const existingApi = existingApis.get(key)!;\n if (existingApi.description !== api.description) {\n modified.push({\n method: api.method,\n path: api.path,\n oldDesc: existingApi.description,\n newDesc: api.description,\n });\n }\n }\n }\n\n for (const [key, api] of existingApis.entries()) {\n if (!currentApis.has(key)) {\n removed.push({ method: api.method, path: api.path });\n }\n }\n\n // 输出结果\n let hasChanges = false;\n\n if (added.length > 0) {\n hasChanges = true;\n logger.success(`新增 API (${added.length}):`);\n for (const api of added) {\n logger.step(` + ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (removed.length > 0) {\n hasChanges = true;\n logger.error(`删除 API (${removed.length}):`);\n for (const api of removed) {\n logger.step(` - ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (modified.length > 0) {\n hasChanges = true;\n logger.warn(`修改 API (${modified.length}):`);\n for (const api of modified) {\n logger.step(` ~ ${api.method} ${api.path}`);\n logger.step(` 旧: ${api.oldDesc}`);\n logger.step(` 新: ${api.newDesc}`);\n }\n logger.newLine();\n }\n\n if (!hasChanges) {\n logger.success('未检测到 API 变更');\n }\n}\n\n/**\n * 生成 API Registry\n */\nasync function generateApiRegistry(projectDir: string): Promise<void> {\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n\n logger.step('扫描并生成 API Registry...');\n\n // 创建 docs 目录\n await FileUtils.ensureDir(path.dirname(registryFile));\n\n // 写入文件头\n const header = `# API Registry\n\n> 本文件记录所有 API 的定义、版本和变更历史\n\n## API 规范\n\n### 基础信息\n- **Base URL**: \\`/api\\`\n- **认证方式**: JWT Bearer Token\n- **数据格式**: JSON\n- **字符编码**: UTF-8\n\n### 响应码规范\n| 状态码 | 说明 |\n|--------|------|\n| 200 | 成功 |\n| 201 | 创建成功 |\n| 400 | 请求参数错误 |\n| 401 | 未认证 |\n| 403 | 无权限 |\n| 404 | 资源不存在 |\n| 500 | 服务器错误 |\n\n---\n\n*最后更新: ${DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss')}*\n`;\n\n // 扫描 Controller 并生成 API 文档\n let content = header;\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (exists) {\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 按模块分组\n const moduleMap = new Map<string, Array<{ method: string; path: string; description: string }>>();\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n if (!moduleMap.has(module)) {\n moduleMap.set(module, []);\n }\n\n const apis = await extractApisFromController(controllerPath);\n moduleMap.get(module)!.push(...apis);\n }\n\n // 生成文档\n for (const [module, apis] of moduleMap.entries()) {\n content += `\\n## ${module.charAt(0).toUpperCase() + module.slice(1)} 模块\\n\\n`;\n\n for (const api of apis) {\n content += `### ${api.method} ${api.path}\\n\\n`;\n content += `**版本**: v1.0\\n\\n`;\n content += `**说明**: ${api.description || '-'}\\n\\n`;\n content += `---\\n\\n`;\n }\n }\n }\n\n await FileUtils.write(registryFile, content);\n\n logger.success(`API Registry 已生成: ${registryFile}`);\n}\n\n/**\n * 从 Controller 提取 API\n */\nasync function extractApisFromController(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string }>> {\n const apis: Array<{ method: string; path: string; description: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n });\n }\n\n return apis;\n}\n\n/**\n * 从 Registry 提取 API\n */\nfunction extractApisFromRegistry(\n registryContent: string\n): Map<string, { method: string; path: string; description: string }> {\n const apis = new Map<string, { method: string; path: string; description: string }>();\n\n // 匹配 API 条目\n const apiRegex = /### (GET|POST|PUT|DELETE|PATCH) ([^\\n]+)\\n\\n\\*\\*版本\\*\\*:.+?\\n\\n\\*\\*说明\\*\\*:\\s*([^\\n-]+)/g;\n let match;\n\n while ((match = apiRegex.exec(registryContent)) !== null) {\n const method = match[1];\n const path = match[2].trim();\n const description = match[3].trim();\n const key = `${method}:${path}`;\n apis.set(key, { method, path, description });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Logs 命令 - 查看会话日志\n */\nexport const logsCommand = new Command('logs')\n .argument('[filter]', '过滤器 (today, --all, 或日期 YYYY-MM-DD)')\n .description('查看会话日志')\n .action(async (filter = 'today') => {\n try {\n logger.header('会话日志');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const sessionsDir = 'docs/sessions';\n const dirExists = await FileUtils.exists(sessionsDir);\n\n if (!dirExists) {\n logger.info('暂无会话日志');\n logger.info(\"运行 'team-cli dev' 后会自动生成日志\");\n process.exit(0);\n }\n\n // 确定目标目录\n let targetDir = '';\n let displayTitle = '';\n\n switch (filter) {\n case '':\n case 'today': {\n const today = new Date().toISOString().split('T')[0];\n targetDir = path.join(sessionsDir, today);\n const todayExists = await FileUtils.exists(targetDir);\n if (!todayExists) {\n logger.info('今日暂无会话日志');\n process.exit(0);\n }\n displayTitle = '显示今日会话日志:';\n break;\n }\n case '--all':\n case '-a': {\n targetDir = sessionsDir;\n displayTitle = '显示所有会话日志:';\n break;\n }\n default: {\n // 假设是日期格式\n targetDir = path.join(sessionsDir, filter);\n const dateExists = await FileUtils.exists(targetDir);\n if (!dateExists) {\n logger.error(`未找到日期 '${filter}' 的日志`);\n logger.info('可用日期:');\n\n // 列出可用日期\n const entries = await FileUtils.findFiles('*/', sessionsDir);\n const dates = entries.slice(0, 10);\n for (const date of dates) {\n logger.info(` ${date.replace('/', '')}`);\n }\n process.exit(1);\n }\n displayTitle = `显示 ${filter} 的会话日志:`;\n break;\n }\n }\n\n logger.info(displayTitle);\n logger.newLine();\n\n // 收集日志文件\n const logs = await collectLogFiles(targetDir);\n\n if (logs.length === 0) {\n logger.info('无日志文件');\n process.exit(0);\n }\n\n // 显示日志列表\n for (let i = 0; i < logs.length; i++) {\n const relPath = path.relative(sessionsDir, logs[i]);\n logger.step(`${i + 1}) ${relPath}`);\n }\n\n logger.newLine();\n\n // 询问选择\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'selection',\n message: '输入编号查看详情 (或 Enter 退出):',\n default: '',\n },\n ]);\n\n const selection = answers.selection.trim();\n\n if (selection === '') {\n process.exit(0);\n }\n\n const selectionNum = parseInt(selection, 10);\n\n if (isNaN(selectionNum) || selectionNum < 1 || selectionNum > logs.length) {\n logger.error('无效的选择');\n process.exit(1);\n }\n\n // 显示选中的日志\n const selectedLog = logs[selectionNum - 1];\n logger.newLine();\n logger.header('日志详情');\n logger.newLine();\n\n const content = await FileUtils.read(selectedLog);\n console.log(content);\n } catch (error: any) {\n logger.error(`查看日志失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 收集日志文件\n */\nasync function collectLogFiles(targetDir: string): Promise<string[]> {\n const logs: string[] = [];\n\n try {\n // 查找所有 markdown 文件,排除 index.md\n const allFiles = await FileUtils.findFiles('*.md', targetDir);\n const filtered = allFiles.filter((f) => f !== 'index.md');\n\n for (const file of filtered) {\n const filePath = path.join(targetDir, file);\n // 确保是文件而不是目录\n const stat = await FileUtils.exists(filePath);\n if (stat) {\n logs.push(filePath);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return logs;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport {\n checkTemplateUpdate,\n updateTemplateVersion,\n readTemplateConfig,\n type TemplateType,\n} from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { execa } from 'execa';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\nimport fs from 'fs-extra';\n\n/**\n * Update 命令选项接口\n */\ninterface UpdateOptions {\n tag?: string;\n branch?: string;\n dryRun?: boolean;\n}\n\n/**\n * Update 命令 - 检查并更新模板版本\n */\nexport const updateCommand = new Command('update')\n .description('检查并更新模板版本')\n .option('-f, --frontend', '检查前端模板更新')\n .option('-b, --backend', '检查后端模板更新')\n .option('-a, --all', '检查所有模板 (默认)')\n .option('-t, --tag <tag>', '更新到指定标签')\n .option('-B, --branch <branch>', '更新到指定分支')\n .option('--dry-run', '预览更新,不实际执行')\n .action(async (options) => {\n try {\n logger.header('模板版本检查');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n // 如果指定了 tag 或 branch,则强制更新到指定版本\n const forceUpdate = options.tag || options.branch;\n\n const updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }> = [];\n const updateOptions: UpdateOptions = {\n tag: options.tag,\n branch: options.branch,\n dryRun: options.dryRun,\n };\n\n // 检查前端模板\n if (checkFrontend) {\n logger.step('检查前端模板...');\n const frontendInfo = await checkTemplateUpdate(projectPath, 'frontend');\n\n if (frontendInfo) {\n if (frontendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || frontendInfo.latestTag || frontendInfo.latestCommit?.substring(0, 8);\n logger.success(`前端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'frontend', info: frontendInfo, updateOptions });\n } else {\n logger.info('前端模板已是最新版本');\n }\n } else {\n logger.info('前端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 检查后端模板\n if (checkBackend) {\n logger.step('检查后端模板...');\n const backendInfo = await checkTemplateUpdate(projectPath, 'backend');\n\n if (backendInfo) {\n if (backendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || backendInfo.latestTag || backendInfo.latestCommit?.substring(0, 8);\n logger.success(`后端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'backend', info: backendInfo, updateOptions });\n } else {\n logger.info('后端模板已是最新版本');\n }\n } else {\n logger.info('后端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 显示总结\n if (updates.length === 0) {\n logger.success('所有模板已是最新版本!');\n return;\n }\n\n if (options.dryRun) {\n logger.header(`[Dry Run] 发现 ${updates.length} 个模板`);\n } else {\n logger.header(`发现 ${updates.length} 个模板更新`);\n }\n logger.newLine();\n\n for (const update of updates) {\n const version = update.updateOptions?.tag || update.updateOptions?.branch || update.info.latestTag || update.info.latestCommit?.substring(0, 8);\n logger.step(`${update.type === 'frontend' ? '前端' : '后端'}模板: ${version}`);\n }\n logger.newLine();\n\n // 如果是 dry-run 模式,直接显示信息并退出\n if (options.dryRun) {\n logger.info('Dry run 模式,不执行实际更新');\n return;\n }\n\n // 询问是否更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '是否更新模板?',\n default: false,\n },\n ]);\n\n if (answers.shouldUpdate) {\n await performUpdate(projectPath, updates);\n } else {\n logger.info('已取消更新');\n }\n } catch (error: any) {\n logger.error(`更新检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 执行模板更新\n */\nasync function performUpdate(\n projectPath: string,\n updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }>\n): Promise<void> {\n logger.newLine();\n logger.info('开始更新模板...');\n\n for (const update of updates) {\n const { type, info, updateOptions } = update;\n const targetDir = type === 'frontend' ? 'frontend' : 'backend';\n const targetPath = path.join(projectPath, targetDir);\n\n logger.newLine();\n logger.step(`更新 ${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n // 如果指定了 tag 或 branch,先验证\n if (updateOptions?.tag || updateOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(info.repository);\n\n if (updateOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, updateOptions.tag);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板 tag \"${updateOptions.tag}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板 tag: ${updateOptions.tag}`);\n }\n\n if (updateOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, updateOptions.branch);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板分支 \"${updateOptions.branch}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板分支: ${updateOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = updateOptions?.tag || updateOptions?.branch || 'HEAD';\n\n // 创建备份\n const backupDir = path.join(projectPath, `.backup-${Date.now()}`);\n await fs.copy(targetPath, path.join(backupDir, targetDir));\n logger.info(`已创建备份: ${backupDir}`);\n\n // Dry run 模式\n if (updateOptions?.dryRun) {\n logger.info('[Dry Run] 将会更新到以下版本:');\n logger.info(` Ref: ${ref}`);\n logger.info(` 仓库: ${info.repository}`);\n logger.info('备份已创建,跳过实际更新');\n continue;\n }\n\n try {\n // 克隆最新模板到临时目录\n const tempDir = path.join(projectPath, `.template-update-${Date.now()}`);\n\n await execa('git', ['clone', '--depth=1', '--branch', ref, info.repository, tempDir], {\n stdio: 'pipe',\n });\n\n // 获取最新 commit\n const { stdout: commit } = await execa('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n\n // 获取最新 tag\n const { stdout: tags } = await execa('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 删除旧内容(保留配置文件)\n const keepFiles = ['.env.local', 'package-lock.json', 'node_modules'];\n const currentFiles = await FileUtils.findFiles('*', targetPath);\n\n for (const file of currentFiles) {\n if (!keepFiles.includes(file)) {\n const filePath = path.join(targetPath, file);\n try {\n await fs.remove(filePath);\n } catch {\n // 忽略删除失败\n }\n }\n }\n\n // 复制新模板内容\n await fs.copy(tempDir, targetPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 更新配置\n await updateTemplateVersion(projectPath, type, commit.trim(), {\n tag: updateOptions?.tag || latestTag,\n branch: updateOptions?.branch,\n });\n\n logger.success(`${type === 'frontend' ? '前端' : '后端'}模板更新完成!`);\n logger.info(`新版本: ${updateOptions?.tag || updateOptions?.branch || latestTag || commit.substring(0, 8)}`);\n logger.info(`备份位置: ${backupDir}`);\n } catch (error: any) {\n logger.error(`更新失败: ${error.message}`);\n logger.info('正在恢复备份...');\n\n // 恢复备份\n await fs.remove(targetPath);\n await fs.copy(path.join(backupDir, targetDir), targetPath);\n await fs.remove(backupDir);\n\n logger.info('已恢复到更新前的状态');\n }\n }\n\n logger.newLine();\n logger.header('模板更新完成!');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查更新后的代码');\n logger.step('2. 运行 npm install 安装新依赖');\n logger.step('3. 测试应用是否正常运行');\n logger.step('4. 提交代码到 Git');\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI } from '../lib/gitlab-api.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 设置 GitLab Access Token\n */\nexport const setTokenCommand = new Command('set-token')\n .description('设置 GitLab Access Token')\n .option('-t, --token <token>', 'Access Token')\n .option('-u, --url <url>', 'GitLab Base URL', 'https://gitlab.com')\n .action(async (options) => {\n try {\n logger.header('GitLab Access Token 配置');\n logger.newLine();\n\n let { token, url } = options;\n\n // 如果没有提供 token,交互式输入\n if (!token) {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: '请输入 GitLab Access Token:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'Token 不能为空';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'url',\n message: '请输入 GitLab Base URL:',\n default: 'https://gitlab.com',\n validate: (input: string) => {\n try {\n new URL(input);\n return true;\n } catch {\n return '请输入有效的 URL';\n }\n },\n },\n ]);\n token = answers.token;\n url = answers.url;\n }\n\n // 验证 URL 格式\n try {\n new URL(url);\n } catch {\n logger.error('无效的 GitLab URL');\n process.exit(1);\n }\n\n // 移除 URL 末尾的斜杠\n url = url.replace(/\\/+$/, '');\n\n logger.info('验证 Token...');\n const gitlabAPI = new GitLabAPI({ accessToken: token, baseUrl: url });\n const isValid = await gitlabAPI.authenticate();\n\n if (!isValid) {\n logger.error('Token 验证失败,请检查:');\n logger.info('1. Token 是否正确');\n logger.info('2. Token 是否有 api 权限');\n logger.info('3. GitLab URL 是否正确');\n process.exit(1);\n }\n\n logger.success('Token 验证成功!');\n\n // 保存配置\n await userConfigManager.updateGitLabToken(token, url);\n logger.success('配置已保存!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(url)}`);\n logger.info(`配置文件: ${chalk.gray(userConfigManager.getConfigPath())}`);\n } catch (error: any) {\n logger.error(`配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示当前配置\n */\nexport const showConfigCommand = new Command('show')\n .description('显示当前配置')\n .action(async () => {\n try {\n logger.header('GitLab 配置');\n logger.newLine();\n\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n } else {\n const config = await userConfigManager.load();\n\n if (config?.gitlab) {\n const token = config.gitlab.accessToken;\n const maskedToken = token ? `${token.substring(0, 8)}${'*'.repeat(Math.min(16, token.length - 8))}` : '';\n\n logger.info(`GitLab URL: ${chalk.cyan(config.gitlab.baseUrl)}`);\n logger.info(`Access Token: ${chalk.yellow(maskedToken)}`);\n logger.info(`Timeout: ${chalk.gray(config.gitlab.timeout || 30000)}ms`);\n\n if (config.preferences) {\n logger.newLine();\n logger.info('偏好设置:');\n if (config.preferences.defaultBackendBranch) {\n logger.info(` 默认后端分支: ${chalk.cyan(config.preferences.defaultBackendBranch)}`);\n }\n if (config.preferences.defaultFrontendBranch) {\n logger.info(` 默认前端分支: ${chalk.cyan(config.preferences.defaultFrontendBranch)}`);\n }\n }\n\n logger.newLine();\n logger.info('配置文件位置:');\n logger.info(` ${chalk.gray(userConfigManager.getConfigPath())}`);\n }\n }\n } catch (error: any) {\n logger.error(`读取配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 删除配置\n */\nexport const removeConfigCommand = new Command('remove')\n .alias('rm')\n .description('删除 GitLab 配置')\n .action(async () => {\n try {\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n return;\n }\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确定要删除 GitLab 配置吗?',\n default: false,\n },\n ]);\n\n if (!answers.confirm) {\n logger.info('已取消');\n return;\n }\n\n await userConfigManager.removeConfig();\n logger.success('配置已删除');\n } catch (error: any) {\n logger.error(`删除配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 验证 Token\n */\nexport const validateTokenCommand = new Command('validate')\n .alias('test')\n .description('验证当前 Token 是否有效')\n .action(async () => {\n try {\n logger.header('验证 GitLab Token');\n logger.newLine();\n\n const config = await userConfigManager.getGitLabConfig();\n\n if (!config) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n process.exit(1);\n }\n\n logger.info('正在验证...');\n\n const gitlabAPI = new GitLabAPI(config);\n const isValid = await gitlabAPI.authenticate();\n\n if (isValid) {\n logger.success('Token 有效!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(config.baseUrl)}`);\n } else {\n logger.error('Token 验证失败');\n logger.info('请检查 Token 是否正确或已过期');\n process.exit(1);\n }\n } catch (error: any) {\n logger.error(`验证失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Config 命令 - 管理 GitLab 配置\n */\nexport const configCommand = new Command('config')\n .description('管理 GitLab 配置')\n .addCommand(setTokenCommand)\n .addCommand(showConfigCommand)\n .addCommand(removeConfigCommand)\n .addCommand(validateTokenCommand);\n","import { Command } from 'commander';\nimport path from 'path';\nimport chalk from 'chalk';\nimport table from 'cli-table3';\nimport { readTemplateConfig, type TemplateType } from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI, GitLabDiffResult } from '../lib/gitlab-api.js';\n\n/**\n * Diff 命令 - 对比本地与远程模板差异\n */\nexport const diffCommand = new Command('diff')\n .description('对比本地与远程模板差异')\n .option('-f, --frontend', '对比前端模板')\n .option('-b, --backend', '对比后端模板')\n .option('-t, --tag <tag>', '指定远程标签')\n .option('-B, --branch <branch>', '指定远程分支')\n .option('-o, --output <format>', '输出格式 (table|json|diff)', 'table')\n .action(async (options) => {\n try {\n logger.header('模板版本对比');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n const config = await readTemplateConfig(projectPath);\n if (!config) {\n logger.error('未找到模板配置');\n process.exit(1);\n }\n\n const gitlabConfig = await userConfigManager.getGitLabConfig();\n if (!gitlabConfig) {\n logger.warn('未配置 GitLab Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n logger.info(\"将使用基本 git 命令进行对比\");\n }\n\n const results: Array<{\n type: TemplateType;\n local: any;\n remote: any;\n diff?: GitLabDiffResult;\n }> = [];\n\n // 对比前端模板\n if (checkFrontend && config.frontend) {\n const result = await compareTemplate(\n projectPath,\n 'frontend',\n config.frontend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n // 对比后端模板\n if (checkBackend && config.backend) {\n const result = await compareTemplate(\n projectPath,\n 'backend',\n config.backend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n if (results.length === 0) {\n logger.info('没有可对比的模板');\n return;\n }\n\n // 根据输出格式显示结果\n switch (options.output) {\n case 'json':\n outputJson(results);\n break;\n case 'diff':\n outputDiff(results);\n break;\n case 'table':\n default:\n outputTable(results);\n break;\n }\n } catch (error: any) {\n logger.error(`对比失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 对比模板版本\n */\nasync function compareTemplate(\n projectPath: string,\n type: TemplateType,\n localConfig: any,\n remoteTag?: string,\n remoteBranch?: string,\n gitlabConfig?: { accessToken: string; baseUrl: string; timeout?: number }\n): Promise<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult } | null> {\n try {\n logger.step(`对比${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n const repository = localConfig.repository;\n const localCommit = localConfig.commit;\n const localTag = localConfig.tag;\n const localBranch = localConfig.branch;\n\n let remoteCommit: string | null = null;\n let remoteTagName: string | undefined;\n let remoteBranchName: string | undefined;\n\n // 如果有 GitLab 配置,使用 API 获取远程信息\n if (gitlabConfig) {\n const gitlabAPI = new GitLabAPI(gitlabConfig);\n const projectPathEncoded = GitLabAPI.parseProjectPath(repository);\n\n if (remoteTag) {\n // 获取指定 tag 的 commit\n remoteCommit = await gitlabAPI.getTagCommit(projectPathEncoded, remoteTag);\n remoteTagName = remoteTag;\n } else if (remoteBranch) {\n // 获取指定 branch 的 commit\n remoteCommit = await gitlabAPI.getBranchCommit(projectPathEncoded, remoteBranch);\n remoteBranchName = remoteBranch;\n } else {\n // 获取最新版本\n const latest = await gitlabAPI.getLatestVersion(projectPathEncoded);\n if (latest) {\n remoteCommit = latest.commit;\n if (latest.type === 'tag') {\n remoteTagName = latest.name;\n } else {\n remoteBranchName = latest.name;\n }\n }\n }\n\n // 获取 diff 信息\n if (remoteCommit && localCommit && remoteCommit !== localCommit) {\n const from = localTag || localBranch || localCommit;\n const to = remoteTagName || remoteBranchName || remoteCommit;\n const diff = await gitlabAPI.compareVersions(projectPathEncoded, from, to);\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n diff: diff || undefined,\n };\n }\n }\n\n // 如果没有 GitLab 配置,使用 git 命令获取基本信息\n if (!remoteCommit) {\n // 使用 git ls-remote 获取远程最新 commit\n const { execa } = await import('execa');\n const ref = remoteTag || remoteBranch || 'HEAD';\n const { stdout } = await execa('git', ['ls-remote', repository, ref], {\n stdio: 'pipe',\n });\n remoteCommit = stdout.split('\\t')[0];\n remoteTagName = remoteTag;\n remoteBranchName = remoteBranch;\n }\n\n const needsUpdate = localCommit !== remoteCommit;\n\n logger.info(\n `${type === 'frontend' ? '前端' : '后端'}模板: ${needsUpdate ? chalk.yellow('有更新') : chalk.green('已是最新')}`\n );\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit || undefined,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n };\n } catch (error) {\n logger.error(`对比${type === 'frontend' ? '前端' : '后端'}模板失败: ${error}`);\n return null;\n }\n}\n\n/**\n * 输出表格格式\n */\nfunction outputTable(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const t = new Table({\n head: [chalk.cyan('项目'), chalk.cyan('版本')],\n colWidths: [20, 50],\n });\n\n // 本地版本\n const localVersion = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || '-';\n const localInfo = `Commit: ${result.local.commit?.substring(0, 8) || '-'}${result.local.tag ? `\\nTag: ${result.local.tag}` : ''}${result.local.branch ? `\\nBranch: ${result.local.branch}` : ''}`;\n t.push(['本地', localInfo]);\n\n // 远程版本\n const remoteVersion = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || '-';\n const remoteInfo = `Commit: ${result.remote.commit?.substring(0, 8) || '-'}${result.remote.tag ? `\\nTag: ${result.remote.tag}` : ''}${result.remote.branch ? `\\nBranch: ${result.remote.branch}` : ''}`;\n t.push(['远程', remoteInfo]);\n\n console.log(t.toString());\n\n // 显示 diff 信息\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('新增提交:'));\n\n const commitsTable = new Table({\n head: [chalk.cyan('Commit'), chalk.cyan('作者'), chalk.cyan('时间'), chalk.cyan('描述')],\n colWidths: [10, 15, 20, 50],\n wordWrap: true,\n });\n\n for (const commit of result.diff.commits.slice(0, 10)) {\n commitsTable.push([\n commit.short_id,\n commit.author_name,\n new Date(commit.created_at).toLocaleDateString('zh-CN'),\n commit.title,\n ]);\n }\n\n console.log(commitsTable.toString());\n\n if (result.diff.commits.length > 10) {\n console.log(chalk.gray(`... 还有 ${result.diff.commits.length - 10} 个提交`));\n }\n\n // 文件变更统计\n const files = result.diff.diffs;\n const added = files.filter((f) => f.new_file).length;\n const deleted = files.filter((f) => f.deleted_file).length;\n const modified = files.length - added - deleted;\n\n console.log('');\n console.log(chalk.bold('文件变更:'));\n console.log(` ${chalk.green('+')} 新增: ${added}`);\n console.log(` ${chalk.red('-')} 删除: ${deleted}`);\n console.log(` ${chalk.yellow('~')} 修改: ${modified}`);\n }\n\n console.log('');\n }\n}\n\n/**\n * 输出 JSON 格式\n */\nfunction outputJson(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n console.log(JSON.stringify(results, null, 2));\n}\n\n/**\n * 输出 diff 格式\n */\nfunction outputDiff(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const from = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || 'unknown';\n const to = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || 'unknown';\n\n console.log(`本地版本: ${chalk.cyan(from)}`);\n console.log(`远程版本: ${chalk.cyan(to)}`);\n\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('提交历史:'));\n\n for (const commit of result.diff.commits) {\n console.log('');\n console.log(chalk.yellow(`commit ${commit.id}`));\n console.log(`Author: ${commit.author_name} <${commit.author_email}>`);\n console.log(`Date: ${new Date(commit.created_at).toLocaleString('zh-CN')}`);\n console.log('');\n console.log(` ${commit.title}`);\n if (commit.message) {\n console.log(` ${commit.message.split('\\n').join('\\n ')}`);\n }\n }\n }\n\n console.log('');\n }\n}\n\n/**\n * 简单的 Table 类(如果 cli-table3 不可用)\n */\nclass Table {\n private options: any;\n private rows: any[][] = [];\n\n constructor(options: any) {\n this.options = options;\n }\n\n push(row: any[]): void {\n this.rows.push(row);\n }\n\n toString(): string {\n if (this.rows.length === 0) return '';\n\n let result = '';\n const colWidths = this.options.colWidths || [];\n\n // 表头\n if (this.options.head) {\n result += '| ';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n const cell = this.options.head[i] || '';\n result += cell.padEnd(width) + ' | ';\n }\n result += '\\n';\n\n // 分隔线\n result += '|';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n result += '-'.repeat(width + 2) + '|';\n }\n result += '\\n';\n }\n\n // 数据行\n for (const row of this.rows) {\n result += '| ';\n for (let i = 0; i < row.length; i++) {\n const width = colWidths[i] || 20;\n const cell = String(row[i] || '');\n const displayCell = this.options.wordWrap && cell.length > width ? cell.substring(0, width - 3) + '...' : cell;\n result += displayCell.padEnd(width) + ' | ';\n }\n result += '\\n';\n }\n\n return result;\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { logger } from './lib/logger.js';\nimport { initCommand } from './commands/init.js';\nimport { breakdownCommand } from './commands/breakdown.js';\nimport { devCommand } from './commands/dev.js';\nimport { addFeatureCommand } from './commands/add-feature.js';\nimport { splitPrdCommand } from './commands/split-prd.js';\nimport { bugfixCommand } from './commands/bugfix.js';\nimport { hotfixCommand } from './commands/bugfix.js';\nimport { lintCommand } from './commands/lint.js';\nimport { statusCommand } from './commands/status.js';\nimport { detectDepsCommand } from './commands/detect-deps.js';\nimport { syncMemoryCommand } from './commands/sync-memory.js';\nimport { checkApiCommand } from './commands/check-api.js';\nimport { logsCommand } from './commands/logs.js';\nimport { updateCommand } from './commands/update.js';\nimport { configCommand } from './commands/config.js';\nimport { diffCommand } from './commands/diff.js';\n\n/**\n * team-cli - AI-Native 团队研发脚手架\n * Node.js 版本\n */\n\nconst program = new Command();\n\n// 基本信息\nprogram\n .name('team-cli')\n .description('AI-Native 团队研发脚手架')\n .version('2.1.2');\n\n// 全局选项\nprogram.option('-v, --verbose', '详细输出模式').option('--debug', '调试模式');\n\n// 注册命令\nprogram.addCommand(initCommand);\nprogram.addCommand(splitPrdCommand);\nprogram.addCommand(breakdownCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(addFeatureCommand);\nprogram.addCommand(bugfixCommand);\nprogram.addCommand(hotfixCommand);\nprogram.addCommand(lintCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(detectDepsCommand);\nprogram.addCommand(syncMemoryCommand);\nprogram.addCommand(checkApiCommand);\nprogram.addCommand(logsCommand);\nprogram.addCommand(updateCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(diffCommand);\n\n// 默认显示帮助\nprogram.action(() => {\n showHelp();\n});\n\n/**\n * 显示帮助信息\n */\nfunction showHelp() {\n console.log('');\n logger.header('team-cli - AI-Native 团队研发脚手架');\n console.log('');\n console.log(chalk.bold('使用方法:'));\n console.log(' team-cli init [project-name] 初始化新项目');\n console.log(' team-cli split-prd <prd-folder> 将 PRD 拆分成多个 specs');\n console.log(' team-cli breakdown [spec-file] 将 spec 拆分为 milestones 和 todos');\n console.log(' team-cli dev 开发模式,执行具体任务');\n console.log(' team-cli add-feature <name> 添加新功能');\n console.log(' team-cli bugfix 创建 Bugfix 记录');\n console.log(' team-cli hotfix 创建 Hotfix');\n console.log(' team-cli detect-deps [spec] 检测依赖关系');\n console.log(' team-cli sync-memory 同步 AI_MEMORY.md');\n console.log(' team-cli check-api API 检查(冲突/变更/Registry)');\n console.log(' team-cli status 查看项目状态');\n console.log(' team-cli lint 代码质量检查 (前端+后端)');\n console.log(' team-cli logs [date] 查看会话日志');\n console.log(' team-cli update 检查并更新模板版本');\n console.log(' team-cli config 管理 GitLab 配置');\n console.log(' team-cli diff 对比本地与远程模板差异');\n console.log(' team-cli --help 显示帮助信息');\n console.log('');\n console.log(chalk.bold('示例:'));\n console.log(' team-cli init my-project');\n console.log(' cd my-project');\n console.log(' team-cli add-feature payment-system');\n console.log(' team-cli breakdown docs/specs/xxx.md');\n console.log(' team-cli dev');\n console.log('');\n console.log(chalk.bold('开发流程:'));\n console.log(' 1. PRD → specs (split-prd)');\n console.log(' 2. spec → milestones + todos (breakdown)');\n console.log(' 3. 选择 milestone/todo → 实现 (dev)');\n console.log('');\n console.log(chalk.bold('迭代流程:'));\n console.log(' team-cli add-feature <name> # 添加新功能');\n console.log(' team-cli detect-deps [spec] # 检测依赖关系');\n console.log(' team-cli sync-memory # 同步 AI_MEMORY');\n console.log(' team-cli check-api # API 检查');\n console.log(' team-cli bugfix # 创建 bugfix');\n console.log(' team-cli hotfix # 紧急修复');\n console.log(' team-cli status # 查看项目状态');\n console.log('');\n console.log(chalk.bold('模板管理:'));\n console.log(' team-cli config set-token # 设置 GitLab Access Token');\n console.log(' team-cli config show # 显示当前配置');\n console.log(' team-cli init --tag v1.0.0 # 使用指定 tag 初始化');\n console.log(' team-cli update --tag v1.1.0 # 更新到指定版本');\n console.log(' team-cli diff # 对比模板差异');\n console.log('');\n console.log(chalk.gray('更多信息: https://github.com/yungu/team-cli'));\n console.log('');\n}\n\n/**\n * 错误处理\n */\nprocess.on('uncaughtException', (error) => {\n logger.error('未捕获的异常');\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('未处理的 Promise 拒绝');\n if (process.env.DEBUG) {\n console.error(reason);\n }\n process.exit(1);\n});\n\n// 解析命令行参数\nprogram.parse(process.argv);\n","#!/usr/bin/env node\n// CLI 入口文件\nimport('./index.js').catch((error) => {\n console.error('Failed to start team-cli:', error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;AACA,OAAO,UAAU;AACjB,SAAS,qBAAqB;AAF9B;AAAA;AAAA;AAAA;AAAA;;;ACAA,OAAO,WAAW;AAClB,OAAO,SAAkB;AADzB,IAMa,QAsLA;AA5Lb;AAAA;AAAA;AAAA;AAMO,IAAM,SAAN,MAAa;AAAA,MACV,UAAsB;AAAA;AAAA;AAAA;AAAA,MAK9B,OAAO,MAAoB;AACzB,gBAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAAA,MAC9B;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,MAAoB;AAC1B,gBAAQ,IAAI,MAAM,MAAM,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,MAAoB;AACxB,gBAAQ,MAAM,MAAM,IAAI,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,KAAK,MAAM,OAAO,QAAG,GAAG,IAAI;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,KAAK,MAAM,KAAK,QAAG,GAAG,IAAI;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAoB;AACvB,gBAAQ,IAAI,MAAM,KAAK,QAAG,GAAG,IAAI;AAAA,MACnC;AAAA;AAAA;AAAA;AAAA,MAKA,UAAgB;AACd,gBAAQ,IAAI,EAAE;AAAA,MAChB;AAAA;AAAA;AAAA;AAAA,MAKA,UAAU,OAAO,UAAK,SAAS,IAAU;AACvC,gBAAQ,IAAI,MAAM,KAAK,KAAK,OAAO,MAAM,CAAC,CAAC;AAAA,MAC7C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,MAAmB;AAC9B,aAAK,UAAU,IAAI;AAAA,UACjB;AAAA,UACA,OAAO;AAAA,QACT,CAAC,EAAE,MAAM;AACT,eAAO,KAAK;AAAA,MACd;AAAA;AAAA;AAAA;AAAA,MAKA,cAAc,MAAoB;AAChC,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,OAAO;AAAA,QACtB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,eAAe,MAAqB;AAClC,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,QAAQ,IAAI;AACzB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,YAAY,MAAqB;AAC/B,YAAI,KAAK,SAAS;AAChB,eAAK,QAAQ,KAAK,IAAI;AACtB,eAAK,UAAU;AAAA,QACjB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAmB,MAAwB;AAC/C,cAAM,eAAe,QAAQ,IAAI,CAAC,GAAG,MAAM;AACzC,gBAAM,WAAW,KAAK;AAAA,YACpB,EAAE;AAAA,YACF,GAAG,KAAK,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,IAAI,MAAM;AAAA,UAC5C;AACA,iBAAO,WAAW;AAAA,QACpB,CAAC;AAGD,cAAM,YAAY,QACf,IAAI,CAAC,GAAG,MAAM,MAAM,KAAK,EAAE,OAAO,aAAa,CAAC,CAAC,CAAC,CAAC,EACnD,KAAK,EAAE;AACV,gBAAQ,IAAI,SAAS;AAGrB,cAAM,YAAY,aAAa,IAAI,CAAC,MAAM,SAAI,OAAO,CAAC,CAAC,EAAE,KAAK,QAAG;AACjE,gBAAQ,IAAI,MAAM,KAAK,SAAS,CAAC;AAGjC,aAAK,QAAQ,CAAC,QAAQ;AACpB,gBAAM,UAAU,IACb,IAAI,CAAC,MAAM,OAAO,QAAQ,IAAI,OAAO,aAAa,CAAC,CAAC,CAAC,EACrD,KAAK,EAAE;AACV,kBAAQ,IAAI,OAAO;AAAA,QACrB,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,MAAc,WAAW,IAAU;AACtC,YAAI,UAAU;AACZ,kBAAQ,IAAI,MAAM,KAAK,SAAS,QAAQ,EAAE,CAAC;AAAA,QAC7C;AACA,gBAAQ,IAAI,MAAM,KAAK,IAAI,CAAC;AAC5B,YAAI,UAAU;AACZ,kBAAQ,IAAI,MAAM,KAAK,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,KAAK,OAAiB,SAAS,GAAS;AACtC,cAAM,QAAQ,CAAC,SAAS;AACtB,kBAAQ,IAAI,IAAI,OAAO,MAAM,IAAI,MAAM,KAAK,QAAG,IAAI,MAAM,IAAI;AAAA,QAC/D,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,QAAQ,OAAe,MAAc,aAAa,QAAc;AAC9D,cAAM,eAAe,MAAM,UAAgC,EAAE,IAAI,KAAK,GAAG;AACzE,gBAAQ,IAAI,GAAG,YAAY,IAAI,IAAI,EAAE;AAAA,MACvC;AAAA,IACF;AAGO,IAAM,SAAS,IAAI,OAAO;AAAA;AAAA;;;AC5LjC,OAAO,QAAQ;AACf,OAAOA,WAAU;AACjB,SAAS,YAAY;AAFrB,IAQa,WA+EAC,cAyHA,WAiDA,UAiCA;AAlSb;AAAA;AAAA;AAAA;AAQO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,MAIrB,aAAa,UAAU,KAA4B;AACjD,cAAM,GAAG,UAAU,GAAG;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,MAA+B;AAC/C,eAAO,MAAM,GAAG,SAAS,MAAM,OAAO;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,MAAM,MAAc,SAAgC;AAC/D,cAAM,GAAG,UAAU,MAAM,SAAS,OAAO;AAAA,MAC3C;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,OAAO,MAAgC;AAClD,eAAO,MAAM,GAAG,WAAW,IAAI;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,KAAa,MAA6B;AAC1D,cAAM,GAAG,KAAK,KAAK,IAAI;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,OAAO,MAA6B;AAC/C,cAAM,GAAG,OAAO,IAAI;AAAA,MACtB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,KAAK,KAAa,MAA6B;AAC1D,cAAM,GAAG,KAAK,KAAK,IAAI;AAAA,MACzB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,UAAU,SAAiB,KAAiC;AACvE,eAAO,MAAM,KAAK,SAAS;AAAA,UACzB;AAAA,UACA,UAAU;AAAA,UACV,OAAO;AAAA,QACT,CAAC;AAAA,MACH;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,SAAkB,MAA0B;AACvD,eAAO,MAAM,GAAG,SAAS,IAAI;AAAA,MAC/B;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,UAAU,MAAc,MAA0B;AAC7D,cAAM,GAAG,UAAU,MAAM,MAAM,EAAE,QAAQ,EAAE,CAAC;AAAA,MAC9C;AAAA,IACF;AAKO,IAAMA,eAAN,MAAkB;AAAA;AAAA;AAAA;AAAA,MAIvB,OAAO,YAAY,KAAqB;AACtC,eAAO,IACJ,YAAY,EACZ,QAAQ,WAAW,GAAG,EACtB,QAAQ,YAAY,EAAE,EACtB,QAAQ,OAAO,GAAG,EAClB,QAAQ,YAAY,EAAE;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,aAAa,KAAqB;AACvC,eAAO,IACJ,QAAQ,eAAe,CAAC,GAAG,MAAM,EAAE,YAAY,CAAC,EAChD,QAAQ,OAAO,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,MAC1C;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,YAAY,KAAqB;AACtC,cAAM,SAAS,KAAK,aAAa,GAAG;AACpC,eAAO,OAAO,OAAO,CAAC,EAAE,YAAY,IAAI,OAAO,MAAM,CAAC;AAAA,MACxD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,YAAY,KAAqB;AACtC,eAAO,IACJ,QAAQ,UAAU,CAAC,WAAW,IAAI,OAAO,YAAY,CAAC,EAAE,EACxD,QAAQ,MAAM,EAAE,EAChB,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,GAAG;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,WAAW,KAAqB;AACrC,eAAO,IAAI,OAAO,CAAC,EAAE,YAAY,IAAI,IAAI,MAAM,CAAC;AAAA,MAClD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,SAAS,KAAa,QAAgB,SAAS,OAAe;AACnE,YAAI,IAAI,UAAU,OAAQ,QAAO;AACjC,eAAO,IAAI,MAAM,GAAG,SAAS,OAAO,MAAM,IAAI;AAAA,MAChD;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,QAAQ,KAAqB;AAClC,eAAO,IACJ,YAAY,EACZ,KAAK,EACL,QAAQ,aAAa,EAAE,EACvB,QAAQ,YAAY,GAAG,EACvB,QAAQ,YAAY,EAAE;AAAA,MAC3B;AAAA,IACF;AAsDO,IAAM,YAAN,MAAM,WAAU;AAAA;AAAA;AAAA;AAAA,MAIrB,OAAO,OAAO,OAAa,oBAAI,KAAK,GAAG,SAAS,uBAA+B;AAC7E,cAAM,OAAO,KAAK,YAAY;AAC9B,cAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,cAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,cAAM,QAAQ,OAAO,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AACrD,cAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,cAAM,UAAU,OAAO,KAAK,WAAW,CAAC,EAAE,SAAS,GAAG,GAAG;AAEzD,eAAO,OACJ,QAAQ,QAAQ,OAAO,IAAI,CAAC,EAC5B,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,GAAG,EACjB,QAAQ,MAAM,KAAK,EACnB,QAAQ,MAAM,OAAO,EACrB,QAAQ,MAAM,OAAO;AAAA,MAC1B;AAAA;AAAA;AAAA;AAAA,MAKA,OAAO,SAAS,MAAoB;AAClC,cAAM,MAAM,oBAAI,KAAK;AACrB,cAAM,OAAO,IAAI,QAAQ,IAAI,KAAK,QAAQ;AAC1C,cAAM,UAAU,KAAK,MAAM,OAAO,GAAI;AACtC,cAAM,UAAU,KAAK,MAAM,UAAU,EAAE;AACvC,cAAM,QAAQ,KAAK,MAAM,UAAU,EAAE;AACrC,cAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAElC,YAAI,OAAO,GAAG;AACZ,iBAAO,WAAU,OAAO,MAAM,YAAY;AAAA,QAC5C,WAAW,OAAO,GAAG;AACnB,iBAAO,GAAG,IAAI;AAAA,QAChB,WAAW,QAAQ,GAAG;AACpB,iBAAO,GAAG,KAAK;AAAA,QACjB,WAAW,UAAU,GAAG;AACtB,iBAAO,GAAG,OAAO;AAAA,QACnB,OAAO;AACL,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAKO,IAAM,WAAN,MAAe;AAAA;AAAA;AAAA;AAAA,MAIpB,aAAa,UAAU,MAAc,QAAQ,IAAI,GAAqB;AACpE,cAAM,SAASD,MAAK,KAAK,KAAK,MAAM;AACpC,eAAO,MAAM,UAAU,OAAO,MAAM;AAAA,MACtC;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,iBAAiB,MAAc,QAAQ,IAAI,GAAoB;AAC1E,cAAM,EAAE,OAAAE,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,cAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,gBAAgB,MAAM,GAAG;AAAA,UAC3E;AAAA,QACF,CAAC;AACD,eAAO,OAAO,KAAK;AAAA,MACrB;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,iBAAiB,MAAc,QAAQ,IAAI,GAAoB;AAC1E,cAAM,EAAE,OAAAA,OAAM,IAAI,MAAM,OAAO,OAAO;AACtC,cAAM,EAAE,OAAO,IAAI,MAAMA,OAAM,OAAO,CAAC,aAAa,MAAM,GAAG,EAAE,IAAI,CAAC;AACpE,eAAO,OAAO,KAAK,EAAE,MAAM,GAAG,CAAC;AAAA,MACjC;AAAA,IACF;AAKO,IAAM,YAAN,MAAgB;AAAA;AAAA;AAAA;AAAA,MAIrB,aAAa,UAAU,MAAsC;AAC3D,cAAM,UAAU,MAAM,UAAU,KAAK,IAAI;AACzC,cAAM,OAAsB,CAAC;AAG7B,cAAM,aAAa,QAAQ,MAAM,aAAa;AAC9C,YAAI,YAAY;AACd,eAAK,QAAQ,WAAW,CAAC;AAAA,QAC3B;AAGA,cAAM,YAAY,QAAQ,MAAM,wBAAwB;AACxD,YAAI,WAAW;AACb,eAAK,OAAO,UAAU,CAAC;AAAA,QACzB;AAGA,cAAM,gBAAgB,QAAQ,MAAM,yBAAyB;AAC7D,YAAI,eAAe;AACjB,eAAK,WAAW,cAAc,CAAC;AAAA,QACjC;AAGA,cAAM,cAAc,QAAQ,MAAM,sBAAsB;AACxD,YAAI,aAAa;AACf,eAAK,SAAS,YAAY,CAAC;AAAA,QAC7B;AAGA,cAAM,aAAa,QAAQ,MAAM,yBAAyB;AAC1D,YAAI,YAAY;AACd,gBAAM,aAAa,WAAW,CAAC,EAAE,SAAS,wBAAwB;AAClE,eAAK,eAAe,MAAM,KAAK,UAAU,EAAE,IAAI,CAAC,OAAO;AAAA,YACrD,WAAW,EAAE,CAAC,MAAM;AAAA,YACpB,MAAM,EAAE,CAAC;AAAA,UACX,EAAE;AAAA,QACJ;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,aAAa,cAAc,MAA+B;AACxD,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,UAAU,IAAI;AACtC,iBAAO,KAAK,UAAU;AAAA,QACxB,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC1VA,SAAS,aAAa;AACtB,OAAOC,WAAU;AADjB,IAQa,UA2ZA;AAnab;AAAA;AAAA;AAAA;AAEA;AACA;AAKO,IAAM,WAAN,MAAe;AAAA,MACZ;AAAA,MAER,YAAY,UAAU,OAAO;AAC3B,aAAK,UAAU;AAAA,MACjB;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAmC;AACvC,YAAI;AACF,gBAAM,MAAM,UAAU,CAAC,WAAW,GAAG,EAAE,OAAO,OAAO,CAAC;AACtD,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAA8B;AAClC,YAAI;AACF,gBAAM,EAAE,OAAO,IAAI,MAAM,MAAM,UAAU,CAAC,WAAW,GAAG,EAAE,OAAO,OAAO,CAAC;AACzE,iBAAO,OAAO,KAAK;AAAA,QACrB,QAAQ;AACN,gBAAM,IAAI,MAAM,8CAAgB;AAAA,QAClC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,OAAO,YAAoB,SAA0C;AACzE,cAAM,UAAU,OAAO,aAAa,oCAAgB;AAEpD,YAAI;AAEF,cAAI,cAAc;AAClB,gBAAM,oBAA8B,CAAC;AAGrC,cAAI,SAAS,gBAAgB,QAAQ,aAAa,SAAS,GAAG;AAC5D,uBAAW,QAAQ,QAAQ,cAAc;AACvC,oBAAM,SAAS,MAAM,UAAU,OAAO,IAAI;AAC1C,kBAAI,QAAQ;AACV,kCAAkB,KAAK,IAAI;AAAA,cAC7B,OAAO;AACL,uBAAO,KAAK,6EAAiB,IAAI,EAAE;AAAA,cACrC;AAAA,YACF;AAGA,gBAAI,kBAAkB,SAAS,GAAG;AAChC,oBAAM,eAAyB,CAAC;AAChC,yBAAW,QAAQ,mBAAmB;AACpC,oBAAI;AACF,wBAAM,UAAU,MAAM,UAAU,KAAK,IAAI;AACzC,wBAAM,WAAWA,MAAK,SAAS,IAAI;AACnC,+BAAa,KAAK,mBAAmB,QAAQ;AAAA;AAAA,EAAO,OAAO,EAAE;AAAA,gBAC/D,SAAS,OAAO;AACd,yBAAO,KAAK,wCAAU,IAAI,0BAAM;AAAA,gBAClC;AAAA,cACF;AAEA,kBAAI,aAAa,SAAS,GAAG;AAC3B,8BAAc,GAAG,aAAa,KAAK,aAAa,CAAC;AAAA;AAAA;AAAA;AAAA,EAAc,UAAU;AAAA,cAC3E;AAAA,YACF;AAAA,UACF;AAGA,gBAAM,OAAiB,CAAC,gBAAgB,MAAM,WAAW;AAEzD,gBAAM,SAAS,MAAM,MAAM,UAAU,MAAM;AAAA,YACzC,OAAO,KAAK,UAAU,YAAY;AAAA,YAClC,SAAS,SAAS,WAAW;AAAA;AAAA,YAC7B,QAAQ;AAAA;AAAA,UACV,CAAC;AAED,kBAAQ,QAAQ,iCAAa;AAG7B,cAAI,OAAO,aAAa,KAAK,CAAC,OAAO,QAAQ;AAC3C,kBAAM,SAAS,OAAO,UAAU;AAChC,kBAAM,IAAI,MAAM,oEAAuB,OAAO,QAAQ,IAAI,SAAS;AAAA,EAAK,MAAM,KAAK,EAAE,EAAE;AAAA,UACzF;AAEA,iBAAO,OAAO,UAAU;AAAA,QAC1B,SAAS,OAAY;AACnB,kBAAQ,KAAK,iCAAa;AAC1B,cAAI,MAAM,UAAU,MAAM,WAAW,WAAW;AAC9C,kBAAM,IAAI,MAAM,iCAAa;AAAA,UAC/B;AAEA,gBAAM,SAAS,MAAM,UAAU;AAC/B,gBAAM,WAAW,MAAM,aAAa,SAAY,yBAAU,MAAM,QAAQ,MAAM;AAC9E,gBAAM,IAAI,MAAM,oCAAgB,MAAM,OAAO,GAAG,QAAQ,GAAG,SAAS;AAAA,EAAK,MAAM,KAAK,EAAE,EAAE;AAAA,QAC1F;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,mBACJ,UACA,MACA,SACiB;AAEjB,YAAI,aAAa;AACjB,mBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC/C,gBAAM,QAAQ,IAAI,OAAO,SAAS,GAAG,UAAU,GAAG;AAClD,uBAAa,WAAW,QAAQ,OAAO,OAAO,KAAK,CAAC;AAAA,QACtD;AAEA,eAAO,MAAM,KAAK,OAAO,YAAY,OAAO;AAAA,MAC9C;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,KAAK,UAAyB,SAA0C;AAC5E,cAAM,UAAU,OAAO,aAAa,oCAAgB;AAEpD,YAAI;AAEF,gBAAM,aAAa,SAChB,IAAI,CAAC,QAAQ;AACZ,kBAAM,OAAO,IAAI,SAAS,WAAW,6BAAS,GAAG,IAAI,SAAS,SAAS,iBAAO,cAAI;AAClF,mBAAO,IAAI,IAAI,MAAM,IAAI,OAAO;AAAA,UAClC,CAAC,EACA,KAAK,MAAM;AAEd,gBAAM,OAAiB,CAAC,gBAAgB,MAAM,UAAU;AAExD,gBAAM,SAAS,MAAM,MAAM,UAAU,MAAM;AAAA,YACzC,OAAO,KAAK,UAAU,YAAY;AAAA,YAClC,SAAS,SAAS,WAAW;AAAA,YAC7B,QAAQ;AAAA,UACV,CAAC;AAED,kBAAQ,QAAQ,iCAAa;AAE7B,cAAI,OAAO,aAAa,KAAK,CAAC,OAAO,QAAQ;AAC3C,kBAAM,IAAI,MAAM,oEAAuB,OAAO,QAAQ,GAAG;AAAA,UAC3D;AAEA,iBAAO,OAAO,UAAU;AAAA,QAC1B,SAAS,OAAY;AACnB,kBAAQ,KAAK,iCAAa;AAC1B,gBAAM;AAAA,QACR;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,MAAc,UAAkB,UAAoC;AACpF,cAAM,SAAS,kCAAS,QAAQ,sBAAO,WAAW,2BAAO,QAAQ,KAAK,EAAE;AAAA;AAAA,QAEpE,QAAQ;AAAA,EACd,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AASF,eAAO,MAAM,KAAK,OAAO,MAAM;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aACJ,aACA,UACA,SACiB;AACjB,YAAI,SAAS,gBAAM,QAAQ;AAAA;AAAA,EAAmB,WAAW;AAAA;AAAA;AAEzD,YAAI,SAAS;AACX,oBAAU;AAAA;AAAA,EAAa,OAAO;AAAA;AAAA;AAAA,QAChC;AAEA,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAOV,eAAO,MAAM,KAAK,OAAO,MAAM;AAAA,MACjC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAAW,MAAc,UAA6C;AAC1E,cAAM,SAAS,kCAAS,QAAQ;AAAA;AAAA,QAE5B,QAAQ;AAAA,EACd,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBF,cAAM,WAAW,MAAM,KAAK,OAAO,MAAM;AACzC,YAAI;AAEF,gBAAM,YAAY,SAAS,MAAM,aAAa;AAC9C,cAAI,WAAW;AACb,mBAAO,KAAK,MAAM,UAAU,CAAC,CAAC;AAAA,UAChC;AAAA,QACF,QAAQ;AAAA,QAER;AAEA,eAAO;AAAA,UACL,QAAQ,CAAC;AAAA,UACT,aAAa,CAAC,QAAQ;AAAA,UACtB,YAAY,CAAC;AAAA,QACf;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aACJ,aACA,aACA,gBACA,cACiB;AACjB,YAAI,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKf,WAAW;AAAA;AAAA;AAAA,EAGX,WAAW;AAAA;AAGT,YAAI,gBAAgB,aAAa,SAAS,GAAG;AAC3C,oBAAU;AAAA;AAAA,sFAEA,aAAa,KAAK,QAAG,CAAC;AAAA;AAAA,QAElC;AAEA,kBAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkBd,eAAe,aAAa,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,EAAE,KAAK,IAAI,IAAI,YAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,8CA6B5C,YAAY,YAAY,WAAW,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoB/D,eAAO,MAAM,KAAK,OAAO,QAAQ,EAAE,SAAS,KAAO,CAAC;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,qBACJ,gBACA,mBACA,gBACiB;AACjB,cAAM,SAAS;AAAA;AAAA;AAAA;AAAA;AAAA,EAKjB,cAAc;AAAA;AAAA;AAAA,EAGd,kBAAkB,IAAI,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA;AAAA;AAAA,EAGlE,cAAc;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUZ,eAAO,MAAM,KAAK,OAAO,QAAQ,EAAE,SAAS,KAAO,CAAC;AAAA,MACtD;AAAA,IACF;AAgCO,IAAM,WAAW,IAAI,SAAS;AAAA;AAAA;;;ACnarC,SAAS,SAAAC,cAAa;AACtB,OAAOC,WAAU;AAmEjB,SAAS,cAAc,aAA6B;AAClD,SAAOA,MAAK,KAAK,aAAa,aAAa,eAAe;AAC5D;AAKA,eAAsB,mBAAmB,aAAqD;AAC5F,QAAM,aAAa,cAAc,WAAW;AAC5C,QAAM,SAAS,MAAM,UAAU,OAAO,UAAU;AAEhD,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,EACT;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,UAAU,KAAK,UAAU;AAC/C,WAAO,KAAK,MAAM,OAAO;AAAA,EAC3B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,mBAAmB,aAAqB,QAAuC;AACnG,QAAM,YAAYA,MAAK,KAAK,aAAa,WAAW;AACpD,QAAM,UAAU,UAAU,SAAS;AAEnC,QAAM,aAAa,cAAc,WAAW;AAC5C,QAAM,UAAU,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC9C,QAAM,UAAU,MAAM,YAAY,OAAO;AAC3C;AAKA,eAAsB,mBAAmB,aAAoC;AAC3E,QAAM,SAAS,MAAM,mBAAmB,WAAW;AAEnD,MAAI,QAAQ;AACV;AAAA,EACF;AAGA,QAAM,mBAAmB,aAAa,iBAAiB;AACzD;AAKA,eAAsB,gBAAgB,YAAqC;AACzE,MAAI;AAEF,UAAM,EAAE,OAAO,IAAI,MAAMD,OAAM,OAAO,CAAC,aAAa,YAAY,MAAM,GAAG;AAAA,MACvE,OAAO;AAAA,IACT,CAAC;AAED,UAAM,SAAS,OAAO,MAAM,GAAI,EAAE,CAAC;AACnC,WAAO;AAAA,EACT,SAAS,OAAO;AACd,WAAO,MAAM,gBAAM,UAAU,sCAAkB,KAAK,EAAE;AACtD,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,aAAa,YAAqC;AACtE,MAAI;AAEF,UAAM,EAAE,OAAO,IAAI,MAAMA;AAAA,MACvB;AAAA,MACA,CAAC,aAAa,UAAU,UAAU;AAAA,MAClC;AAAA,QACE,OAAO;AAAA,MACT;AAAA,IACF;AAEA,UAAM,OAAO,OACV,MAAM,IAAI,EACV,OAAO,CAAC,SAAS,KAAK,SAAS,YAAY,KAAK,CAAC,KAAK,SAAS,KAAK,CAAC,EACrE,IAAI,CAAC,SAAS;AACb,YAAM,CAAC,EAAE,GAAG,IAAI,KAAK,MAAM,GAAI;AAC/B,aAAO,IAAI,QAAQ,cAAc,EAAE;AAAA,IACrC,CAAC,EACA,OAAO,CAAC,QAAQ,mBAAmB,KAAK,GAAG,CAAC,EAC5C,KAAK,CAAC,GAAG,MAAM;AAEd,YAAM,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,YAAM,KAAK,EAAE,QAAQ,MAAM,EAAE,EAAE,MAAM,GAAG,EAAE,IAAI,MAAM;AACpD,eAAS,IAAI,GAAG,IAAI,GAAG,KAAK;AAC1B,aAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AACxC,aAAK,GAAG,CAAC,KAAK,MAAM,GAAG,CAAC,KAAK,GAAI,QAAO;AAAA,MAC1C;AACA,aAAO;AAAA,IACT,CAAC;AAEH,WAAO,KAAK,KAAK,SAAS,CAAC,KAAK;AAAA,EAClC,SAAS,OAAO;AACd,WAAO,MAAM,gBAAM,UAAU,mCAAe,KAAK,EAAE;AACnD,WAAO;AAAA,EACT;AACF;AAKA,eAAsB,oBACpB,aACA,MAC8B;AAC9B,QAAM,SAAS,MAAM,mBAAmB,WAAW;AAEnD,MAAI,CAAC,UAAU,CAAC,OAAO,IAAI,GAAG;AAC5B,WAAO;AAAA,EACT;AAEA,QAAM,aAAa,OAAO,IAAI,EAAE;AAChC,QAAM,gBAAgB,OAAO,IAAI,EAAE;AACnC,QAAM,aAAa,OAAO,IAAI,EAAE;AAGhC,QAAM,eAAe,MAAM,gBAAgB,UAAU;AACrD,QAAM,YAAY,MAAM,aAAa,UAAU;AAE/C,MAAI,CAAC,cAAc;AACjB,WAAO;AAAA,EACT;AAGA,QAAM,cAAc,iBAAiB,kBAAkB;AAEvD,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,aAAa,eAAe;AAAA,EAC9B;AACF;AAKA,eAAsB,sBACpB,aACA,MACA,QACA,SAIe;AACf,QAAM,SAAS,MAAM,mBAAmB,WAAW;AAEnD,MAAI,CAAC,QAAQ;AACX;AAAA,EACF;AAEA,SAAO,IAAI,EAAE,SAAS;AACtB,MAAI,SAAS,KAAK;AAChB,WAAO,IAAI,EAAE,MAAM,QAAQ;AAAA,EAC7B;AACA,MAAI,SAAS,QAAQ;AACnB,WAAO,IAAI,EAAE,SAAS,QAAQ;AAAA,EAChC;AACA,SAAO,IAAI,EAAE,cAAa,oBAAI,KAAK,GAAE,YAAY;AAEjD,QAAM,mBAAmB,aAAa,MAAM;AAC9C;AAlPA,IAwDM;AAxDN;AAAA;AAAA;AAAA;AAEA;AACA;AAqDA,IAAM,oBAAoC;AAAA,MACxC,UAAU;AAAA,QACR,YAAY;AAAA,MACd;AAAA,MACA,SAAS;AAAA,QACP,YAAY;AAAA,MACd;AAAA,IACF;AAAA;AAAA;;;AC/DA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAOE,WAAU;AACjB,OAAO,QAAQ;AACf,OAAO,YAAY;AAFnB,IAwBa,mBA6KA;AArMb;AAAA;AAAA;AAAA;AAGA;AACA;AAoBO,IAAM,oBAAN,MAAwB;AAAA,MACrB;AAAA,MAER,cAAc;AACZ,cAAM,YAAYA,MAAK,KAAK,GAAG,QAAQ,GAAG,WAAW;AACrD,aAAK,aAAaA,MAAK,KAAK,WAAW,aAAa;AAAA,MACtD;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,OAAmC;AACvC,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU,OAAO,KAAK,UAAU;AACrD,cAAI,CAAC,QAAQ;AACX,mBAAO;AAAA,UACT;AAEA,gBAAM,UAAU,MAAM,UAAU,KAAK,KAAK,UAAU;AACpD,gBAAM,SAAS,KAAK,MAAM,OAAO;AAGjC,cAAI,OAAO,QAAQ,aAAa;AAC9B,mBAAO,OAAO,cAAc,KAAK,QAAQ,OAAO,OAAO,WAAW;AAAA,UACpE;AAEA,iBAAO;AAAA,QACT,SAAS,OAAO;AACd,iBAAO,MAAM,qDAAa,KAAK,EAAE;AACjC,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,KAAK,QAAmC;AAC5C,YAAI;AACF,gBAAM,YAAYA,MAAK,QAAQ,KAAK,UAAU;AAC9C,gBAAM,UAAU,UAAU,SAAS;AAGnC,gBAAM,eAAe,EAAE,GAAG,OAAO;AACjC,cAAI,aAAa,QAAQ,aAAa;AACpC,yBAAa,OAAO,cAAc,KAAK,QAAQ,aAAa,OAAO,WAAW;AAAA,UAChF;AAEA,gBAAM,UAAU,KAAK,UAAU,cAAc,MAAM,CAAC;AACpD,gBAAM,UAAU,MAAM,KAAK,YAAY,OAAO;AAAA,QAChD,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,qDAAa,KAAK,EAAE;AAAA,QACtC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAAkB,OAAe,SAAiC;AACtE,cAAM,SAAU,MAAM,KAAK,KAAK,KAAM;AAAA,UACpC,QAAQ;AAAA,YACN,aAAa;AAAA,YACb,SAAS;AAAA,YACT,SAAS;AAAA,UACX;AAAA,QACF;AAEA,eAAO,OAAO,cAAc;AAC5B,YAAI,SAAS;AACX,iBAAO,OAAO,UAAU;AAAA,QAC1B;AAEA,cAAM,KAAK,KAAK,MAAM;AAAA,MACxB;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAyC;AAC7C,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,QAAQ,QAAQ,eAAe;AAAA,MACxC;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,kBAA8F;AAClG,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,QAAQ,UAAU;AAAA,MAC3B;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAA8B;AAClC,cAAM,SAAS,MAAM,KAAK,KAAK;AAC/B,eAAO,WAAW,QAAQ,OAAO,QAAQ,gBAAgB;AAAA,MAC3D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAA8B;AAClC,YAAI;AACF,gBAAM,SAAS,MAAM,UAAU,OAAO,KAAK,UAAU;AACrD,cAAI,QAAQ;AACV,kBAAM,UAAU,OAAO,KAAK,UAAU;AAAA,UACxC;AAAA,QACF,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,yCAAW,KAAK,EAAE;AAAA,QACpC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,MAAsB;AACpC,cAAM,MAAM,KAAK,cAAc;AAC/B,cAAM,KAAK,OAAO,YAAY,EAAE;AAChC,cAAM,SAAS,OAAO,eAAe,eAAe,KAAK,EAAE;AAC3D,YAAI,YAAY,OAAO,OAAO,MAAM,QAAQ,KAAK;AACjD,qBAAa,OAAO,MAAM,KAAK;AAC/B,eAAO,GAAG,SAAS,KAAK,IAAI,MAAM;AAAA,MACpC;AAAA;AAAA;AAAA;AAAA,MAKQ,QAAQ,eAA+B;AAC7C,YAAI;AACF,gBAAM,MAAM,KAAK,cAAc;AAC/B,gBAAM,QAAQ,cAAc,MAAM,GAAG;AACrC,gBAAM,KAAK,OAAO,KAAK,MAAM,CAAC,GAAG,KAAK;AACtC,gBAAM,YAAY,MAAM,CAAC;AACzB,gBAAM,WAAW,OAAO,iBAAiB,eAAe,KAAK,EAAE;AAC/D,cAAI,YAAY,SAAS,OAAO,WAAW,OAAO,MAAM;AACxD,uBAAa,SAAS,MAAM,MAAM;AAClC,iBAAO;AAAA,QACT,QAAQ;AAEN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKQ,gBAAwB;AAC9B,cAAM,WAAW,GAAG,SAAS;AAC7B,cAAM,WAAW,GAAG,SAAS;AAC7B,cAAM,OAAO,GAAG,KAAK;AACrB,cAAM,OAAO,GAAG,KAAK;AAGrB,cAAM,cAAc,GAAG,QAAQ,IAAI,QAAQ,IAAI,IAAI,IAAI,KAAK,CAAC,GAAG,SAAS,SAAS;AAClF,eAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,WAAW,EAAE,OAAO;AAAA,MAChE;AAAA;AAAA;AAAA;AAAA,MAKA,eAAuB;AACrB,eAAOA,MAAK,QAAQ,KAAK,UAAU;AAAA,MACrC;AAAA;AAAA;AAAA;AAAA,MAKA,gBAAwB;AACtB,eAAO,KAAK;AAAA,MACd;AAAA,IACF;AAGO,IAAM,oBAAoB,IAAI,kBAAkB;AAAA;AAAA;;;ACrMvD;AAAA;AAAA;AAAA;AAAA,IAwFa;AAxFb;AAAA;AAAA;AAAA;AAwFO,IAAM,YAAN,MAAgB;AAAA,MACb;AAAA,MACS,iBAAiB;AAAA,MAElC,YAAY,QAAsB;AAChC,aAAK,SAAS;AAAA,UACZ,GAAG;AAAA,UACH,SAAS,OAAO,WAAW,KAAK;AAAA,QAClC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAiC;AACrC,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,QAAQ,OAAO;AAC3C,iBAAO,SAAS;AAAA,QAClB,SAAS,OAAO;AACd,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,SAAS,aAA2C;AACxD,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,+BAA+B;AAE3F,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,wCAAoB,SAAS,MAAM,EAAE;AAAA,UACvD;AAEA,gBAAM,OAAoB,MAAM,SAAS,KAAK;AAC9C,iBAAO,KAAK,KAAK,CAAC,GAAG,MAAM;AAEzB,mBAAO,KAAK,sBAAsB,EAAE,MAAM,EAAE,IAAI;AAAA,UAClD,CAAC;AAAA,QACH,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,mCAAe,KAAK,EAAE;AAAA,QACxC;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAAa,aAA8C;AAC/D,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,mCAAmC;AAE/F,cAAI,CAAC,SAAS,IAAI;AAChB,kBAAM,IAAI,MAAM,wCAAoB,SAAS,MAAM,EAAE;AAAA,UACvD;AAEA,gBAAM,WAA2B,MAAM,SAAS,KAAK;AAGrD,iBAAO,SAAS,KAAK,CAAC,GAAG,MAAM;AAC7B,gBAAI,EAAE,QAAS,QAAO;AACtB,gBAAI,EAAE,QAAS,QAAO;AACtB,mBAAO,EAAE,KAAK,cAAc,EAAE,IAAI;AAAA,UACpC,CAAC;AAAA,QACH,SAAS,OAAO;AACd,gBAAM,IAAI,MAAM,uCAAmB,KAAK,EAAE;AAAA,QAC5C;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,YAAY,aAAqB,KAA+B;AACpE,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,iBAAO,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AAAA,QACxC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,eAAe,aAAqB,QAAkC;AAC1E,YAAI;AACF,gBAAM,WAAW,MAAM,KAAK,aAAa,WAAW;AACpD,iBAAO,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAAA,QAC/C,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,WAAW,aAAoD;AACnE,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK,QAAQ,aAAa,WAAW,EAAE;AAE9D,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,aAAa,aAAqB,KAAqC;AAC3E,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,gBAAM,YAAY,KAAK,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG;AACjD,iBAAO,WAAW,OAAO,MAAM;AAAA,QACjC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,gBAAgB,aAAqB,QAAwC;AACjF,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK;AAAA,YAC1B,aAAa,WAAW,wBAAwB,mBAAmB,MAAM,CAAC;AAAA,UAC5E;AAEA,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,gBAAM,aAA2B,MAAM,SAAS,KAAK;AACrD,iBAAO,WAAW,OAAO;AAAA,QAC3B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,gBACJ,aACA,MACA,IACkC;AAClC,YAAI;AACF,gBAAM,cAAc,KAAK,kBAAkB,WAAW;AACtD,gBAAM,WAAW,MAAM,KAAK;AAAA,YAC1B,aAAa,WAAW,4BAA4B,mBAAmB,IAAI,CAAC,OAAO,mBAAmB,EAAE,CAAC;AAAA,UAC3G;AAEA,cAAI,CAAC,SAAS,IAAI;AAChB,mBAAO;AAAA,UACT;AAEA,iBAAO,MAAM,SAAS,KAAK;AAAA,QAC7B,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMQ,sBAAsB,IAAY,IAAoB;AAE5D,cAAM,WAAW,GAAG,QAAQ,MAAM,EAAE;AACpC,cAAM,WAAW,GAAG,QAAQ,MAAM,EAAE;AAEpC,cAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AAClE,cAAM,SAAS,SAAS,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,SAAS,GAAG,EAAE,KAAK,CAAC;AAElE,iBAAS,IAAI,GAAG,IAAI,KAAK,IAAI,OAAO,QAAQ,OAAO,MAAM,GAAG,KAAK;AAC/D,gBAAM,KAAK,OAAO,CAAC,KAAK;AACxB,gBAAM,KAAK,OAAO,CAAC,KAAK;AAExB,cAAI,KAAK,GAAI,QAAO;AACpB,cAAI,KAAK,GAAI,QAAO;AAAA,QACtB;AAEA,eAAO;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAiB,aAA+F;AACpH,YAAI;AACF,gBAAM,OAAO,MAAM,KAAK,SAAS,WAAW;AAC5C,gBAAM,WAAW,MAAM,KAAK,aAAa,WAAW;AAGpD,cAAI,KAAK,SAAS,GAAG;AACnB,kBAAM,YAAY,KAAK,CAAC;AACxB,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,UAAU;AAAA,cAChB,QAAQ,UAAU,OAAO;AAAA,YAC3B;AAAA,UACF;AAGA,gBAAM,gBAAgB,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO;AACpD,cAAI,eAAe;AACjB,mBAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,cAAc;AAAA,cACpB,QAAQ,cAAc,OAAO;AAAA,YAC/B;AAAA,UACF;AAEA,iBAAO;AAAA,QACT,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA;AAAA;AAAA;AAAA;AAAA,MAMA,OAAO,iBAAiB,YAA4B;AAMlD,YAAIC,SAAO;AAGX,QAAAA,SAAOA,OAAK,QAAQ,gBAAgB,EAAE;AACtC,QAAAA,SAAOA,OAAK,QAAQ,SAAS,EAAE;AAG/B,cAAM,QAAQA,OAAK,MAAM,GAAG;AAC5B,YAAI,MAAM,SAAS,GAAG;AACpB,UAAAA,SAAO,MAAM,MAAM,CAAC,EAAE,KAAK,GAAG;AAAA,QAChC;AAGA,QAAAA,SAAOA,OAAK,QAAQ,UAAU,EAAE;AAEhC,eAAOA;AAAA,MACT;AAAA;AAAA;AAAA;AAAA,MAKQ,kBAAkB,aAA6B;AAGrD,eAAO,mBAAmB,WAAW,EAAE,QAAQ,QAAQ,KAAK;AAAA,MAC9D;AAAA;AAAA;AAAA;AAAA,MAKA,MAAc,QAAQ,UAAkB,UAAuB,CAAC,GAAsB;AACpF,cAAM,MAAM,GAAG,KAAK,OAAO,OAAO,UAAU,QAAQ;AAEpD,cAAM,UAAuB;AAAA,UAC3B,iBAAiB,KAAK,OAAO;AAAA,UAC7B,gBAAgB;AAAA,UAChB,GAAG,QAAQ;AAAA,QACb;AAEA,cAAM,aAAa,IAAI,gBAAgB;AACvC,cAAM,YAAY,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO,OAAO;AAE1E,YAAI;AACF,gBAAM,WAAW,MAAM,MAAM,KAAK;AAAA,YAChC,GAAG;AAAA,YACH;AAAA,YACA,QAAQ,WAAW;AAAA,UACrB,CAAC;AAED,iBAAO;AAAA,QACT,SAAS,OAAY;AACnB,cAAI,MAAM,SAAS,cAAc;AAC/B,kBAAM,IAAI,MAAM,0BAAM;AAAA,UACxB;AACA,gBAAM;AAAA,QACR,UAAE;AACA,uBAAa,SAAS;AAAA,QACxB;AAAA,MACF;AAAA;AAAA;AAAA;AAAA,MAKA,MAAM,iBAAiB,aAA6C;AAClE,YAAI;AACF,gBAAM,UAAU,MAAM,KAAK,WAAW,WAAW;AACjD,iBAAO,SAAS,kBAAkB;AAAA,QACpC,QAAQ;AACN,iBAAO;AAAA,QACT;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC5YA,SAAS,eAAe;AACxB,OAAO,cAAc;AACrB,OAAOC,WAAU;AACjB,OAAOC,SAAQ;AAIf,SAAS,aAAa;AAsLtB,eAAe,kBAAkB,aAAoC;AACnE,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAgGhB,QAAM,UAAU,MAAMD,MAAK,KAAK,aAAa,eAAe,GAAG,OAAO;AACxE;AAKA,eAAe,oBAAoB,aAAoC;AACrE,QAAM,UAAU;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6ShB,QA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","names":["path","StringUtils","execa","path","execa","path","path","path","path","fs","userConfigManager","GitLabAPI","StringUtils","Command","inquirer","path","Listr","Command","inquirer","path","todo","Command","inquirer","path","Listr","ctx","StringUtils","Command","path","Listr","ctx","Command","inquirer","path","Listr","execa","Command","execa","Command","path","parseSpecStatus","Command","path","inquirer","Command","path","parseSpecStatus","Command","path","inquirer","Listr","controllers","extractMethodComment","Command","path","inquirer","Command","path","execa","inquirer","fs","userConfigManager","GitLabAPI","Command","inquirer","chalk","Command","chalk","execa","Command","chalk"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/tsup/assets/esm_shims.js","../src/lib/logger.ts","../src/lib/utils.ts","../src/lib/claude.ts","../src/lib/template-version.ts","../src/lib/user-config.ts","../src/lib/gitlab-api.ts","../src/commands/init.ts","../src/commands/breakdown.ts","../src/commands/dev.ts","../src/commands/add-feature.ts","../src/commands/split-prd.ts","../src/commands/bugfix.ts","../src/commands/lint.ts","../src/commands/status.ts","../src/commands/detect-deps.ts","../src/commands/sync-memory.ts","../src/commands/check-api.ts","../src/commands/logs.ts","../src/commands/update.ts","../src/commands/config.ts","../src/commands/diff.ts","../src/index.ts","../src/cli.ts"],"sourcesContent":["// Shim globals in esm bundle\nimport path from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst getFilename = () => fileURLToPath(import.meta.url)\nconst getDirname = () => path.dirname(getFilename())\n\nexport const __dirname = /* @__PURE__ */ getDirname()\nexport const __filename = /* @__PURE__ */ getFilename()\n","import chalk from 'chalk';\nimport ora, { Ora } from 'ora';\n\n/**\n * 颜色输出类\n */\nexport class Logger {\n private spinner: Ora | null = null;\n\n /**\n * 打印标题(加粗)\n */\n header(text: string): void {\n console.log(chalk.bold(text));\n }\n\n /**\n * 打印成功信息(绿色)\n */\n success(text: string): void {\n console.log(chalk.green('✓'), text);\n }\n\n /**\n * 打印错误信息(红色)\n */\n error(text: string): void {\n console.error(chalk.red('✗'), text);\n }\n\n /**\n * 打印警告信息(黄色)\n */\n warn(text: string): void {\n console.warn(chalk.yellow('⚠'), text);\n }\n\n /**\n * 打印信息(蓝色)\n */\n info(text: string): void {\n console.info(chalk.blue('ℹ'), text);\n }\n\n /**\n * 打印步骤信息\n */\n step(text: string): void {\n console.log(chalk.cyan('→'), text);\n }\n\n /**\n * 打印空行\n */\n newLine(): void {\n console.log('');\n }\n\n /**\n * 打印分隔线\n */\n separator(char = '─', length = 50): void {\n console.log(chalk.gray(char.repeat(length)));\n }\n\n /**\n * 开始加载动画\n */\n startLoading(text: string): Ora {\n this.spinner = ora({\n text,\n color: 'cyan',\n }).start();\n return this.spinner;\n }\n\n /**\n * 更新加载文本\n */\n updateLoading(text: string): void {\n if (this.spinner) {\n this.spinner.text = text;\n }\n }\n\n /**\n * 停止加载并显示成功\n */\n succeedLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.succeed(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示失败\n */\n failLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.fail(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示警告\n */\n warnLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.warn(text);\n this.spinner = null;\n }\n }\n\n /**\n * 停止加载并显示信息\n */\n infoLoading(text?: string): void {\n if (this.spinner) {\n this.spinner.info(text);\n this.spinner = null;\n }\n }\n\n /**\n * 打印表格\n */\n table(headers: string[], rows: string[][]): void {\n const columnWidths = headers.map((h, i) => {\n const maxWidth = Math.max(\n h.length,\n ...rows.map((row) => (row[i] || '').length)\n );\n return maxWidth + 2;\n });\n\n // 打印表头\n const headerRow = headers\n .map((h, i) => chalk.bold(h.padEnd(columnWidths[i])))\n .join('');\n console.log(headerRow);\n\n // 打印分隔线\n const separator = columnWidths.map((w) => '─'.repeat(w)).join('┼');\n console.log(chalk.gray(separator));\n\n // 打印数据行\n rows.forEach((row) => {\n const dataRow = row\n .map((cell, i) => (cell || '').padEnd(columnWidths[i]))\n .join('');\n console.log(dataRow);\n });\n }\n\n /**\n * 打印代码块\n */\n code(code: string, language = ''): void {\n if (language) {\n console.log(chalk.gray(`\\`\\`\\`${language}`));\n }\n console.log(chalk.gray(code));\n if (language) {\n console.log(chalk.gray('```'));\n }\n }\n\n /**\n * 打印列表\n */\n list(items: string[], indent = 2): void {\n items.forEach((item) => {\n console.log(' '.repeat(indent) + chalk.gray('•') + ' ' + item);\n });\n }\n\n /**\n * 打印带标签的文本\n */\n labeled(label: string, text: string, labelColor = 'blue'): void {\n const coloredLabel = chalk[labelColor as keyof typeof chalk](`[${label}]`);\n console.log(`${coloredLabel} ${text}`);\n }\n}\n\n// 导出单例\nexport const logger = new Logger();\n\n/**\n * 确认提示(用于重要操作)\n */\nexport async function confirm(message: string): Promise<boolean> {\n const inquirer = await import('inquirer');\n const { confirm } = await inquirer.default.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message,\n default: false,\n },\n ]);\n return confirm;\n}\n","import fs from 'fs-extra';\nimport path from 'path';\nimport { glob } from 'glob';\nimport type { Spec } from '../types/index.js';\n\n/**\n * 文件工具类\n */\nexport class FileUtils {\n /**\n * 确保目录存在\n */\n static async ensureDir(dir: string): Promise<void> {\n await fs.ensureDir(dir);\n }\n\n /**\n * 读取文件内容\n */\n static async read(file: string): Promise<string> {\n return await fs.readFile(file, 'utf-8');\n }\n\n /**\n * 写入文件内容\n */\n static async write(file: string, content: string): Promise<void> {\n await fs.writeFile(file, content, 'utf-8');\n }\n\n /**\n * 检查文件是否存在\n */\n static async exists(file: string): Promise<boolean> {\n return await fs.pathExists(file);\n }\n\n /**\n * 复制文件\n */\n static async copy(src: string, dest: string): Promise<void> {\n await fs.copy(src, dest);\n }\n\n /**\n * 删除文件或目录\n */\n static async remove(file: string): Promise<void> {\n await fs.remove(file);\n }\n\n /**\n * 移动文件\n */\n static async move(src: string, dest: string): Promise<void> {\n await fs.move(src, dest);\n }\n\n /**\n * 使用 glob 查找文件\n */\n static async findFiles(pattern: string, cwd?: string): Promise<string[]> {\n return await glob(pattern, {\n cwd,\n absolute: false,\n nodir: true,\n });\n }\n\n /**\n * 读取 JSON 文件\n */\n static async readJson<T = any>(file: string): Promise<T> {\n return await fs.readJson(file);\n }\n\n /**\n * 写入 JSON 文件\n */\n static async writeJson(file: string, data: any): Promise<void> {\n await fs.writeJson(file, data, { spaces: 2 });\n }\n}\n\n/**\n * 字符串工具类\n */\nexport class StringUtils {\n /**\n * 转换为 kebab-case\n */\n static toKebabCase(str: string): string {\n return str\n .toLowerCase()\n .replace(/[\\s_]+/g, '-')\n .replace(/[^\\w\\-]/g, '')\n .replace(/-+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n\n /**\n * 转换为 PascalCase\n */\n static toPascalCase(str: string): string {\n return str\n .replace(/[-_\\s](\\w)/g, (_, c) => c.toUpperCase())\n .replace(/^\\w/, (c) => c.toUpperCase());\n }\n\n /**\n * 转换为 camelCase\n */\n static toCamelCase(str: string): string {\n const pascal = this.toPascalCase(str);\n return pascal.charAt(0).toLowerCase() + pascal.slice(1);\n }\n\n /**\n * 转换为 snake_case\n */\n static toSnakeCase(str: string): string {\n return str\n .replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`)\n .replace(/^_/, '')\n .replace(/-+/g, '_')\n .replace(/[\\s]+/g, '_');\n }\n\n /**\n * 首字母大写\n */\n static capitalize(str: string): string {\n return str.charAt(0).toUpperCase() + str.slice(1);\n }\n\n /**\n * 截断字符串\n */\n static truncate(str: string, length: number, suffix = '...'): string {\n if (str.length <= length) return str;\n return str.slice(0, length - suffix.length) + suffix;\n }\n\n /**\n * 生成 slug\n */\n static slugify(str: string): string {\n return str\n .toLowerCase()\n .trim()\n .replace(/[^\\w\\s-]/g, '')\n .replace(/[\\s_-]+/g, '-')\n .replace(/^-+|-+$/g, '');\n }\n}\n\n/**\n * 数组工具类\n */\nexport class ArrayUtils {\n /**\n * 数组去重\n */\n static unique<T>(arr: T[]): T[] {\n return Array.from(new Set(arr));\n }\n\n /**\n * 数组分组\n */\n static groupBy<T>(arr: T[], keyFn: (item: T) => string): Record<string, T[]> {\n return arr.reduce((result, item) => {\n const key = keyFn(item);\n if (!result[key]) {\n result[key] = [];\n }\n result[key].push(item);\n return result;\n }, {} as Record<string, T[]>);\n }\n\n /**\n * 数组分块\n */\n static chunk<T>(arr: T[], size: number): T[][] {\n const chunks: T[][] = [];\n for (let i = 0; i < arr.length; i += size) {\n chunks.push(arr.slice(i, i + size));\n }\n return chunks;\n }\n\n /**\n * 数组乱序\n */\n static shuffle<T>(arr: T[]): T[] {\n const result = [...arr];\n for (let i = result.length - 1; i > 0; i--) {\n const j = Math.floor(Math.random() * (i + 1));\n [result[i], result[j]] = [result[j], result[i]];\n }\n return result;\n }\n}\n\n/**\n * 日期工具类\n */\nexport class DateUtils {\n /**\n * 格式化日期\n */\n static format(date: Date = new Date(), format = 'YYYY-MM-DD HH:mm:ss'): string {\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n const hours = String(date.getHours()).padStart(2, '0');\n const minutes = String(date.getMinutes()).padStart(2, '0');\n const seconds = String(date.getSeconds()).padStart(2, '0');\n\n return format\n .replace('YYYY', String(year))\n .replace('MM', month)\n .replace('DD', day)\n .replace('HH', hours)\n .replace('mm', minutes)\n .replace('ss', seconds);\n }\n\n /**\n * 获取相对时间\n */\n static relative(date: Date): string {\n const now = new Date();\n const diff = now.getTime() - date.getTime();\n const seconds = Math.floor(diff / 1000);\n const minutes = Math.floor(seconds / 60);\n const hours = Math.floor(minutes / 60);\n const days = Math.floor(hours / 24);\n\n if (days > 7) {\n return DateUtils.format(date, 'YYYY-MM-DD');\n } else if (days > 0) {\n return `${days} 天前`;\n } else if (hours > 0) {\n return `${hours} 小时前`;\n } else if (minutes > 0) {\n return `${minutes} 分钟前`;\n } else {\n return '刚刚';\n }\n }\n}\n\n/**\n * Git 工具类\n */\nexport class GitUtils {\n /**\n * 检查是否在 Git 仓库中\n */\n static async isGitRepo(cwd: string = process.cwd()): Promise<boolean> {\n const gitDir = path.join(cwd, '.git');\n return await FileUtils.exists(gitDir);\n }\n\n /**\n * 获取当前分支名\n */\n static async getCurrentBranch(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', '--abbrev-ref', 'HEAD'], {\n cwd,\n });\n return stdout.trim();\n }\n\n /**\n * 获取当前 commit hash\n */\n static async getCurrentCommit(cwd: string = process.cwd()): Promise<string> {\n const { execa } = await import('execa');\n const { stdout } = await execa('git', ['rev-parse', 'HEAD'], { cwd });\n return stdout.trim().slice(0, 7);\n }\n}\n\n/**\n * Spec 解析工具类\n */\nexport class SpecUtils {\n /**\n * 解析 spec 文件\n */\n static async parseSpec(file: string): Promise<Partial<Spec>> {\n const content = await FileUtils.read(file);\n const spec: Partial<Spec> = {};\n\n // 解析标题\n const titleMatch = content.match(/^#\\s+(.+)$/m);\n if (titleMatch) {\n spec.title = titleMatch[1];\n }\n\n // 解析功能名称\n const nameMatch = content.match(/\\*\\*功能名称\\*\\*:\\s*(.+)$/m);\n if (nameMatch) {\n spec.name = nameMatch[1];\n }\n\n // 解析优先级\n const priorityMatch = content.match(/\\*\\*优先级\\*\\*:\\s*(P[0-2])/);\n if (priorityMatch) {\n spec.priority = priorityMatch[1] as 'P0' | 'P1' | 'P2';\n }\n\n // 解析状态\n const statusMatch = content.match(/\\*\\*状态\\*\\*:\\s*(.+)$/m);\n if (statusMatch) {\n spec.status = statusMatch[1] as Spec['status'];\n }\n\n // 解析依赖\n const depSection = content.match(/## 依赖关系\\s+([\\s\\S]+?)##/m);\n if (depSection) {\n const depMatches = depSection[1].matchAll(/- \\[([ x])\\]\\s*(.+)$/gm);\n spec.dependencies = Array.from(depMatches).map((m) => ({\n completed: m[1] === 'x',\n name: m[2],\n }));\n }\n\n return spec;\n }\n\n /**\n * 获取 spec 状态\n */\n static async getSpecStatus(file: string): Promise<string> {\n try {\n const spec = await this.parseSpec(file);\n return spec.status || '未知';\n } catch {\n return '错误';\n }\n }\n}\n\n/**\n * 模板工具类\n */\nexport class TemplateUtils {\n /**\n * 渲染模板(简单变量替换)\n */\n static render(template: string, data: Record<string, any>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key) => {\n return data[key] !== undefined ? String(data[key]) : '';\n });\n }\n\n /**\n * 渲染 Handlebars 模板\n */\n static async renderHandlebars(\n template: string,\n data: Record<string, any>\n ): Promise<string> {\n const Handlebars = await import('handlebars');\n const compiled = Handlebars.default.compile(template);\n return compiled(data);\n }\n}\n\n/**\n * 验证工具类\n */\nexport class ValidationUtils {\n /**\n * 验证项目名称\n */\n static validateProjectName(name: string): boolean {\n return /^[a-z0-9-]+$/.test(name);\n }\n\n /**\n * 验证邮箱\n */\n static validateEmail(email: string): boolean {\n return /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email);\n }\n\n /**\n * 验证 URL\n */\n static validateUrl(url: string): boolean {\n try {\n new URL(url);\n return true;\n } catch {\n return false;\n }\n }\n}\n","import { execa } from 'execa';\nimport path from 'path';\nimport { logger } from './logger.js';\nimport { FileUtils } from './utils.js';\n\n/**\n * Claude AI 集成类\n */\nexport class ClaudeAI {\n private verbose: boolean;\n\n constructor(verbose = false) {\n this.verbose = verbose;\n }\n\n /**\n * 检查 Claude CLI 是否已安装\n */\n async checkInstalled(): Promise<boolean> {\n try {\n await execa('claude', ['--version'], { stdio: 'pipe' });\n return true;\n } catch {\n return false;\n }\n }\n\n /**\n * 获取 Claude 版本\n */\n async getVersion(): Promise<string> {\n try {\n const { stdout } = await execa('claude', ['--version'], { stdio: 'pipe' });\n return stdout.trim();\n } catch {\n throw new Error('无法获取 Claude 版本');\n }\n }\n\n /**\n * 发送 prompt 到 Claude\n */\n async prompt(promptText: string, options?: PromptOptions): Promise<string> {\n const spinner = logger.startLoading('正在调用 Claude...');\n\n try {\n // 构建最终的 prompt(包含上下文文件内容)\n let finalPrompt = promptText;\n const validContextFiles: string[] = [];\n\n // 验证并读取上下文文件\n if (options?.contextFiles && options.contextFiles.length > 0) {\n for (const file of options.contextFiles) {\n const exists = await FileUtils.exists(file);\n if (exists) {\n validContextFiles.push(file);\n } else {\n logger.warn(`上下文文件不存在,已跳过: ${file}`);\n }\n }\n\n // 将上下文文件内容添加到 prompt 开头\n if (validContextFiles.length > 0) {\n const contextParts: string[] = [];\n for (const file of validContextFiles) {\n try {\n const content = await FileUtils.read(file);\n const fileName = path.basename(file);\n contextParts.push(`## Context from ${fileName}\\n\\n${content}`);\n } catch (error) {\n logger.warn(`无法读取文件 ${file},已跳过`);\n }\n }\n\n if (contextParts.length > 0) {\n finalPrompt = `${contextParts.join('\\n\\n---\\n\\n')}\\n\\n---\\n\\n${promptText}`;\n }\n }\n }\n\n // 构建参数数组\n const args: string[] = ['-p', finalPrompt];\n\n const result = await execa('claude', args, {\n stdio: this.verbose ? 'inherit' : 'pipe',\n timeout: options?.timeout || 300000, // 默认 5 分钟\n reject: false, // 不自动拒绝非零退出码\n });\n\n spinner.succeed('Claude 响应完成');\n\n // 检查退出码\n if (result.exitCode !== 0 && !result.stdout) {\n const stderr = result.stderr || '';\n throw new Error(`Claude 命令执行失败 (退出码: ${result.exitCode})${stderr ? `\\n${stderr}` : ''}`);\n }\n\n return result.stdout || '';\n } catch (error: any) {\n spinner.fail('Claude 调用失败');\n if (error.killed && error.signal === 'SIGTERM') {\n throw new Error('Claude 执行超时');\n }\n // 提供更详细的错误信息\n const stderr = error.stderr || '';\n const exitCode = error.exitCode !== undefined ? ` (退出码: ${error.exitCode})` : '';\n throw new Error(`Claude 调用失败: ${error.message}${exitCode}${stderr ? `\\n${stderr}` : ''}`);\n }\n }\n\n /**\n * 使用 prompt 模板和参数发送请求\n */\n async promptWithTemplate(\n template: string,\n data: Record<string, any>,\n options?: PromptOptions\n ): Promise<string> {\n // 简单的模板替换\n let promptText = template;\n for (const [key, value] of Object.entries(data)) {\n const regex = new RegExp(`\\\\{\\\\{${key}\\\\}\\\\}`, 'g');\n promptText = promptText.replace(regex, String(value));\n }\n\n return await this.prompt(promptText, options);\n }\n\n /**\n * 发送对话(支持上下文)\n */\n async chat(messages: ChatMessage[], options?: PromptOptions): Promise<string> {\n const spinner = logger.startLoading('正在调用 Claude...');\n\n try {\n // 构建完整的 prompt\n const fullPrompt = messages\n .map((msg) => {\n const role = msg.role === 'system' ? '系统指令' : `${msg.role === 'user' ? '用户' : '助手'}`;\n return `[${role}]: ${msg.content}`;\n })\n .join('\\n\\n');\n\n const args: string[] = ['-p', fullPrompt];\n\n const result = await execa('claude', args, {\n stdio: this.verbose ? 'inherit' : 'pipe',\n timeout: options?.timeout || 300000,\n reject: false,\n });\n\n spinner.succeed('Claude 响应完成');\n\n if (result.exitCode !== 0 && !result.stdout) {\n throw new Error(`Claude 命令执行失败 (退出码: ${result.exitCode})`);\n }\n\n return result.stdout || '';\n } catch (error: any) {\n spinner.fail('Claude 调用失败');\n throw error;\n }\n }\n\n /**\n * 分析代码\n */\n async analyzeCode(code: string, language: string, question?: string): Promise<string> {\n const prompt = `请分析以下 ${language} 代码:${question ? `并回答:${question}` : ''}\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请提供:\n1. 代码功能概述\n2. 潜在问题\n3. 改进建议\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 生成代码\n */\n async generateCode(\n description: string,\n language: string,\n context?: string\n ): Promise<string> {\n let prompt = `请用 ${language} 编写代码实现以下功能:\\n\\n${description}\\n\\n`;\n\n if (context) {\n prompt += `参考上下文:\\n\\n${context}\\n\\n`;\n }\n\n prompt += `要求:\n1. 代码简洁易读\n2. 包含必要的注释\n3. 遵循最佳实践\n4. 只返回代码,不要额外解释\n`;\n\n return await this.prompt(prompt);\n }\n\n /**\n * 审查代码\n */\n async reviewCode(code: string, language: string): Promise<CodeReviewResult> {\n const prompt = `请审查以下 ${language} 代码,提供详细反馈:\n\n\\`\\`\\`${language}\n${code}\n\\`\\`\\`\n\n请按以下格式回复:\n## 发现的问题\n- [严重程度] 问题描述\n\n## 改进建议\n- 建议内容\n\n## 亮点\n- 做得好的地方\n\n请用 JSON 格式回复:\n{\n \"issues\": [{\"severity\": \"high|medium|low\", \"message\": \"问题描述\"}],\n \"suggestions\": [\"建议1\", \"建议2\"],\n \"highlights\": [\"亮点1\", \"亮点2\"]\n}\n`;\n\n const response = await this.prompt(prompt);\n try {\n // 尝试从响应中提取 JSON\n const jsonMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonMatch) {\n return JSON.parse(jsonMatch[0]);\n }\n } catch {\n // 如果解析失败,返回默认结构\n }\n\n return {\n issues: [],\n suggestions: [response],\n highlights: [],\n };\n }\n\n /**\n * 生成 Spec 文档\n */\n async generateSpec(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies?: string[]\n ): Promise<string> {\n let prompt = `Role: Senior Fullstack Developer\n\n你是一个资深的全栈工程师,现在需要为一个新功能生成规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n`;\n\n if (dependencies && dependencies.length > 0) {\n prompt += `\n## 依赖功能\n此功能依赖以下已完成的功能:${dependencies.join('、')}\n`;\n }\n\n prompt += `\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n${dependencies ? dependencies.map((d) => `- [x] ${d}`).join('\\n') : '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${StringUtils.toKebabCase(featureName)}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: {{TIMESTAMP}} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n`;\n\n return await this.prompt(prompt, { timeout: 180000 });\n }\n\n /**\n * 生成 Bugfix 报告\n */\n async generateBugfixReport(\n bugDescription: string,\n reproductionSteps: string[],\n projectContext: string\n ): Promise<string> {\n const prompt = `Role: Senior Fullstack Developer\n\n用户报告了一个 Bug,需要你生成 Bugfix 规格文档。\n\n## Bug 描述\n${bugDescription}\n\n## 复现步骤\n${reproductionSteps.map((step, i) => `${i + 1}. ${step}`).join('\\n')}\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请生成一个完整的 Bugfix 报告,包括:\n1. 问题分析\n2. 根本原因推测\n3. 修复建议\n4. 测试计划\n`;\n\n return await this.prompt(prompt, { timeout: 120000 });\n }\n}\n\n/**\n * Prompt 选项\n */\nexport interface PromptOptions {\n contextFiles?: string[];\n timeout?: number;\n model?: string;\n}\n\n/**\n * 聊天消息\n */\nexport interface ChatMessage {\n role: 'system' | 'user' | 'assistant';\n content: string;\n}\n\n/**\n * 代码审查结果\n */\nexport interface CodeReviewResult {\n issues: Array<{\n severity: 'high' | 'medium' | 'low';\n message: string;\n }>;\n suggestions: string[];\n highlights: string[];\n}\n\n// 导出单例\nexport const claudeAI = new ClaudeAI();\n","import { execa } from 'execa';\nimport path from 'path';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 模板类型\n */\nexport type TemplateType = 'frontend' | 'backend';\n\n/**\n * 模板信息接口\n */\nexport interface TemplateInfo {\n type: TemplateType;\n repository: string;\n currentCommit?: string;\n currentTag?: string;\n latestCommit?: string;\n latestTag?: string;\n needsUpdate: boolean;\n}\n\n/**\n * 模板版本信息接口\n */\nexport interface TemplateVersionInfo {\n commit: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n}\n\n/**\n * 模板配置接口\n */\nexport interface TemplateConfig {\n frontend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n backend: {\n repository: string;\n commit?: string;\n tag?: string;\n branch?: string;\n lastUpdate?: string;\n };\n}\n\n/**\n * 默认模板配置\n */\nconst DEFAULT_TEMPLATES: TemplateConfig = {\n frontend: {\n repository: 'https://gitlab.yungu-inc.org/static/fe-tpl-ai',\n },\n backend: {\n repository: 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git',\n },\n};\n\n/**\n * 获取项目配置文件路径\n */\nfunction getConfigPath(projectPath: string): string {\n return path.join(projectPath, '.team-cli', 'template.json');\n}\n\n/**\n * 读取项目的模板配置\n */\nexport async function readTemplateConfig(projectPath: string): Promise<TemplateConfig | null> {\n const configPath = getConfigPath(projectPath);\n const exists = await FileUtils.exists(configPath);\n\n if (!exists) {\n return null;\n }\n\n try {\n const content = await FileUtils.read(configPath);\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\n/**\n * 保存项目的模板配置\n */\nexport async function saveTemplateConfig(projectPath: string, config: TemplateConfig): Promise<void> {\n const configDir = path.join(projectPath, '.team-cli');\n await FileUtils.ensureDir(configDir);\n\n const configPath = getConfigPath(projectPath);\n const content = JSON.stringify(config, null, 2);\n await FileUtils.write(configPath, content);\n}\n\n/**\n * 初始化模板配置\n */\nexport async function initTemplateConfig(projectPath: string): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (config) {\n return; // 已存在配置\n }\n\n // 保存当前使用的模板信息\n await saveTemplateConfig(projectPath, DEFAULT_TEMPLATES);\n}\n\n/**\n * 获取远程仓库的最新 commit\n */\nexport async function getLatestCommit(repository: string): Promise<string> {\n try {\n // 使用 git ls-remote 获取最新 commit\n const { stdout } = await execa('git', ['ls-remote', repository, 'HEAD'], {\n stdio: 'pipe',\n });\n\n const commit = stdout.split('\\t')[0];\n return commit;\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 commit 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 获取远程仓库的最新 tag\n */\nexport async function getLatestTag(repository: string): Promise<string> {\n try {\n // 获取所有 tags 并按版本排序\n const { stdout } = await execa(\n 'git',\n ['ls-remote', '--tags', repository],\n {\n stdio: 'pipe',\n }\n );\n\n const tags = stdout\n .split('\\n')\n .filter((line) => line.includes('refs/tags/') && !line.includes('^{}'))\n .map((line) => {\n const [, ref] = line.split('\\t');\n return ref.replace('refs/tags/', '');\n })\n .filter((tag) => /^v?\\d+\\.\\d+\\.\\d+/.test(tag))\n .sort((a, b) => {\n // 简单的版本排序\n const va = a.replace(/^v/, '').split('.').map(Number);\n const vb = b.replace(/^v/, '').split('.').map(Number);\n for (let i = 0; i < 3; i++) {\n if ((va[i] || 0) > (vb[i] || 0)) return 1;\n if ((va[i] || 0) < (vb[i] || 0)) return -1;\n }\n return 0;\n });\n\n return tags[tags.length - 1] || '';\n } catch (error) {\n logger.debug(`获取 ${repository} 最新 tag 失败: ${error}`);\n return '';\n }\n}\n\n/**\n * 检查模板是否需要更新\n */\nexport async function checkTemplateUpdate(\n projectPath: string,\n type: TemplateType\n): Promise<TemplateInfo | null> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config || !config[type]) {\n return null;\n }\n\n const repository = config[type].repository;\n const currentCommit = config[type].commit;\n const currentTag = config[type].tag;\n\n // 获取最新版本\n const latestCommit = await getLatestCommit(repository);\n const latestTag = await getLatestTag(repository);\n\n if (!latestCommit) {\n return null;\n }\n\n // 判断是否需要更新\n const needsUpdate = currentCommit && currentCommit !== latestCommit;\n\n return {\n type,\n repository,\n currentCommit,\n currentTag,\n latestCommit,\n latestTag,\n needsUpdate: needsUpdate || false,\n };\n}\n\n/**\n * 更新模板配置中的版本信息\n */\nexport async function updateTemplateVersion(\n projectPath: string,\n type: TemplateType,\n commit: string,\n options?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const config = await readTemplateConfig(projectPath);\n\n if (!config) {\n return;\n }\n\n config[type].commit = commit;\n if (options?.tag) {\n config[type].tag = options.tag;\n }\n if (options?.branch) {\n config[type].branch = options.branch;\n }\n config[type].lastUpdate = new Date().toISOString();\n\n await saveTemplateConfig(projectPath, config);\n}\n\n/**\n * 获取默认模板配置\n */\nexport function getDefaultTemplates(): TemplateConfig {\n return DEFAULT_TEMPLATES;\n}\n","import path from 'path';\nimport os from 'os';\nimport crypto from 'crypto';\nimport { FileUtils } from './utils.js';\nimport { logger } from './logger.js';\n\n/**\n * 用户配置接口\n */\nexport interface UserConfig {\n gitlab: {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n };\n preferences?: {\n defaultBackendBranch?: string;\n defaultFrontendBranch?: string;\n };\n}\n\n/**\n * 用户配置管理类\n */\nexport class UserConfigManager {\n private configPath: string;\n\n constructor() {\n const configDir = path.join(os.homedir(), '.team-cli');\n this.configPath = path.join(configDir, 'config.json');\n }\n\n /**\n * 加载用户配置\n */\n async load(): Promise<UserConfig | null> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (!exists) {\n return null;\n }\n\n const content = await FileUtils.read(this.configPath);\n const config = JSON.parse(content);\n\n // 解密 access token\n if (config.gitlab?.accessToken) {\n config.gitlab.accessToken = this.decrypt(config.gitlab.accessToken);\n }\n\n return config;\n } catch (error) {\n logger.debug(`加载用户配置失败: ${error}`);\n return null;\n }\n }\n\n /**\n * 保存用户配置\n */\n async save(config: UserConfig): Promise<void> {\n try {\n const configDir = path.dirname(this.configPath);\n await FileUtils.ensureDir(configDir);\n\n // 加密 access token\n const configToSave = { ...config };\n if (configToSave.gitlab?.accessToken) {\n configToSave.gitlab.accessToken = this.encrypt(configToSave.gitlab.accessToken);\n }\n\n const content = JSON.stringify(configToSave, null, 2);\n await FileUtils.write(this.configPath, content);\n } catch (error) {\n throw new Error(`保存用户配置失败: ${error}`);\n }\n }\n\n /**\n * 更新 GitLab Token\n */\n async updateGitLabToken(token: string, baseUrl?: string): Promise<void> {\n const config = (await this.load()) || {\n gitlab: {\n accessToken: '',\n baseUrl: 'https://gitlab.com',\n timeout: 30000,\n },\n };\n\n config.gitlab.accessToken = token;\n if (baseUrl) {\n config.gitlab.baseUrl = baseUrl;\n }\n\n await this.save(config);\n }\n\n /**\n * 获取 GitLab Token\n */\n async getGitLabToken(): Promise<string | null> {\n const config = await this.load();\n return config?.gitlab?.accessToken || null;\n }\n\n /**\n * 获取 GitLab 配置\n */\n async getGitLabConfig(): Promise<{ accessToken: string; baseUrl: string; timeout?: number } | null> {\n const config = await this.load();\n return config?.gitlab || null;\n }\n\n /**\n * 检查是否已有配置\n */\n async hasConfig(): Promise<boolean> {\n const config = await this.load();\n return config !== null && config.gitlab?.accessToken !== undefined;\n }\n\n /**\n * 删除配置\n */\n async removeConfig(): Promise<void> {\n try {\n const exists = await FileUtils.exists(this.configPath);\n if (exists) {\n await FileUtils.remove(this.configPath);\n }\n } catch (error) {\n throw new Error(`删除配置失败: ${error}`);\n }\n }\n\n /**\n * 简单加密 (使用机器特定密钥)\n */\n private encrypt(text: string): string {\n const key = this.getMachineKey();\n const iv = crypto.randomBytes(16);\n const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);\n let encrypted = cipher.update(text, 'utf8', 'hex');\n encrypted += cipher.final('hex');\n return iv.toString('hex') + ':' + encrypted;\n }\n\n /**\n * 简单解密\n */\n private decrypt(encryptedText: string): string {\n try {\n const key = this.getMachineKey();\n const parts = encryptedText.split(':');\n const iv = Buffer.from(parts[0], 'hex');\n const encrypted = parts[1];\n const decipher = crypto.createDecipheriv('aes-256-cbc', key, iv);\n let decrypted = decipher.update(encrypted, 'hex', 'utf8');\n decrypted += decipher.final('utf8');\n return decrypted;\n } catch {\n // 如果解密失败,可能是旧版本的明文存储\n return encryptedText;\n }\n }\n\n /**\n * 获取机器特定密钥\n */\n private getMachineKey(): Buffer {\n const hostname = os.hostname();\n const platform = os.platform();\n const arch = os.arch();\n const cpus = os.cpus();\n\n // 使用机器信息生成密钥\n const machineInfo = `${hostname}-${platform}-${arch}-${cpus[0]?.model || 'unknown'}`;\n return crypto.createHash('sha256').update(machineInfo).digest();\n }\n\n /**\n * 获取配置目录\n */\n getConfigDir(): string {\n return path.dirname(this.configPath);\n }\n\n /**\n * 获取配置文件路径\n */\n getConfigPath(): string {\n return this.configPath;\n }\n}\n\n// 导出单例\nexport const userConfigManager = new UserConfigManager();\n","/**\n * GitLab API 客户端\n */\n\n/**\n * GitLab Tag 信息\n */\nexport interface GitLabTag {\n name: string;\n commit: {\n id: string;\n short_id: string;\n created_at: string;\n };\n message: string;\n release: {\n tag_name: string;\n description: string;\n } | null;\n}\n\n/**\n * GitLab Branch 信息\n */\nexport interface GitLabBranch {\n name: string;\n commit: {\n id: string;\n short_id: string;\n title: string;\n created_at: string;\n author_name: string;\n author_email: string;\n };\n protected: boolean;\n default: boolean;\n}\n\n/**\n * GitLab Diff 结果\n */\nexport interface GitLabDiffResult {\n from: string;\n to: string;\n commits: Array<{\n id: string;\n short_id: string;\n title: string;\n author_name: string;\n created_at: string;\n message: string;\n }>;\n diffs: Array<{\n old_path: string;\n new_path: string;\n diff: string;\n new_file: boolean;\n renamed_file: boolean;\n deleted_file: boolean;\n }>;\n}\n\n/**\n * GitLab 项目信息\n */\nexport interface GitLabProject {\n id: number;\n name: string;\n path: string;\n path_with_namespace: string;\n http_url_to_repo: string;\n ssh_url_to_repo: string;\n default_branch: string;\n last_activity_at: string;\n}\n\n/**\n * GitLab API 配置\n */\nexport interface GitLabConfig {\n accessToken: string;\n baseUrl: string;\n timeout?: number;\n}\n\n/**\n * GitLab API 客户端类\n */\nexport class GitLabAPI {\n private config: GitLabConfig;\n private readonly defaultTimeout = 30000;\n\n constructor(config: GitLabConfig) {\n this.config = {\n ...config,\n timeout: config.timeout || this.defaultTimeout,\n };\n }\n\n /**\n * 验证 Token 是否有效\n */\n async authenticate(): Promise<boolean> {\n try {\n const response = await this.request('/user');\n return response.ok;\n } catch (error) {\n return false;\n }\n }\n\n /**\n * 列出项目的所有 Tags\n */\n async listTags(projectPath: string): Promise<GitLabTag[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/tags?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const tags: GitLabTag[] = await response.json();\n return tags.sort((a, b) => {\n // 按版本号排序(降序)\n return this.compareVersionStrings(b.name, a.name);\n });\n } catch (error) {\n throw new Error(`获取 Tags 失败: ${error}`);\n }\n }\n\n /**\n * 列出项目的所有 Branches\n */\n async listBranches(projectPath: string): Promise<GitLabBranch[]> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}/repository/branches?per_page=100`);\n\n if (!response.ok) {\n throw new Error(`GitLab API 请求失败: ${response.status}`);\n }\n\n const branches: GitLabBranch[] = await response.json();\n\n // 将默认分支放在最前面\n return branches.sort((a, b) => {\n if (a.default) return -1;\n if (b.default) return 1;\n return a.name.localeCompare(b.name);\n });\n } catch (error) {\n throw new Error(`获取 Branches 失败: ${error}`);\n }\n }\n\n /**\n * 验证 Tag 是否存在\n */\n async validateTag(projectPath: string, tag: string): Promise<boolean> {\n try {\n const tags = await this.listTags(projectPath);\n return tags.some((t) => t.name === tag);\n } catch {\n return false;\n }\n }\n\n /**\n * 验证 Branch 是否存在\n */\n async validateBranch(projectPath: string, branch: string): Promise<boolean> {\n try {\n const branches = await this.listBranches(projectPath);\n return branches.some((b) => b.name === branch);\n } catch {\n return false;\n }\n }\n\n /**\n * 获取项目信息\n */\n async getProject(projectPath: string): Promise<GitLabProject | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(`/projects/${encodedPath}`);\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Tag 的 commit 信息\n */\n async getTagCommit(projectPath: string, tag: string): Promise<string | null> {\n try {\n const tags = await this.listTags(projectPath);\n const targetTag = tags.find((t) => t.name === tag);\n return targetTag?.commit.id || null;\n } catch {\n return null;\n }\n }\n\n /**\n * 获取指定 Branch 的最新 commit 信息\n */\n async getBranchCommit(projectPath: string, branch: string): Promise<string | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/branches/${encodeURIComponent(branch)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n const branchInfo: GitLabBranch = await response.json();\n return branchInfo.commit.id;\n } catch {\n return null;\n }\n }\n\n /**\n * 对比两个版本之间的差异\n */\n async compareVersions(\n projectPath: string,\n from: string,\n to: string\n ): Promise<GitLabDiffResult | null> {\n try {\n const encodedPath = this.encodeProjectPath(projectPath);\n const response = await this.request(\n `/projects/${encodedPath}/repository/compare?from=${encodeURIComponent(from)}&to=${encodeURIComponent(to)}`\n );\n\n if (!response.ok) {\n return null;\n }\n\n return await response.json();\n } catch {\n return null;\n }\n }\n\n /**\n * 比较两个版本号(用于排序)\n * 返回值: -1 (v1 < v2), 0 (v1 == v2), 1 (v1 > v2)\n */\n private compareVersionStrings(v1: string, v2: string): number {\n // 移除 'v' 前缀\n const version1 = v1.replace(/^v/, '');\n const version2 = v2.replace(/^v/, '');\n\n const parts1 = version1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = version2.split('.').map((p) => parseInt(p, 10) || 0);\n\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const p1 = parts1[i] || 0;\n const p2 = parts2[i] || 0;\n\n if (p1 > p2) return 1;\n if (p1 < p2) return -1;\n }\n\n return 0;\n }\n\n /**\n * 获取最新的版本(优先 Tag,否则 latest commit)\n */\n async getLatestVersion(projectPath: string): Promise<{ type: 'tag' | 'commit'; name: string; commit: string } | null> {\n try {\n const tags = await this.listTags(projectPath);\n const branches = await this.listBranches(projectPath);\n\n // 优先返回最新的 tag\n if (tags.length > 0) {\n const latestTag = tags[0];\n return {\n type: 'tag',\n name: latestTag.name,\n commit: latestTag.commit.id,\n };\n }\n\n // 如果没有 tag,返回默认分支的最新 commit\n const defaultBranch = branches.find((b) => b.default);\n if (defaultBranch) {\n return {\n type: 'commit',\n name: defaultBranch.name,\n commit: defaultBranch.commit.id,\n };\n }\n\n return null;\n } catch {\n return null;\n }\n }\n\n /**\n * 解析项目路径\n * 从 Git URL 中提取项目路径\n */\n static parseProjectPath(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n // - gitlab.com/group/project\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n }\n\n /**\n * 编码项目路径用于 API 请求\n */\n private encodeProjectPath(projectPath: string): string {\n // GitLab API 需要对项目路径进行 URL 编码\n // 并且需要将 / 替换为 %2F\n return encodeURIComponent(projectPath).replace(/%2F/g, '%2F');\n }\n\n /**\n * 发送 HTTP 请求\n */\n private async request(endpoint: string, options: RequestInit = {}): Promise<Response> {\n const url = `${this.config.baseUrl}/api/v4${endpoint}`;\n\n const headers: HeadersInit = {\n 'PRIVATE-TOKEN': this.config.accessToken,\n 'Content-Type': 'application/json',\n ...options.headers,\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);\n\n try {\n const response = await fetch(url, {\n ...options,\n headers,\n signal: controller.signal,\n });\n\n return response;\n } catch (error: any) {\n if (error.name === 'AbortError') {\n throw new Error('请求超时');\n }\n throw error;\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 获取默认分支\n */\n async getDefaultBranch(projectPath: string): Promise<string | null> {\n try {\n const project = await this.getProject(projectPath);\n return project?.default_branch || null;\n } catch {\n return null;\n }\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { FileUtils, StringUtils, GitUtils } from '../lib/utils.js';\nimport { Listr } from 'listr2';\nimport {\n initTemplateConfig,\n updateTemplateVersion,\n getDefaultTemplates,\n} from '../lib/template-version.js';\n\n/**\n * Init 命令\n */\nexport const initCommand = new Command('init')\n .argument('[project-name]', '项目名称')\n .description('初始化新项目')\n .option('-d, --dir <directory>', '项目目录', '.')\n .option('--no-docker', '不生成 Docker 配置')\n .option('--no-git', '不初始化 Git')\n .option('--tag <tag>', '指定模板标签 (前后端通用)')\n .option('--backend-tag <tag>', '指定后端模板标签')\n .option('--frontend-tag <tag>', '指定前端模板标签')\n .option('--backend-branch <branch>', '指定后端模板分支')\n .option('--frontend-branch <branch>', '指定前端模板分支')\n .action(async (projectName, options) => {\n try {\n // 如果没有提供项目名,交互式输入\n if (!projectName) {\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: '请输入项目名称:',\n default: 'my-project',\n validate: (input: string) => {\n if (!/^[a-z0-9-]+$/.test(input)) {\n return '项目名称只能包含小写字母、数字和连字符';\n }\n return true;\n },\n },\n ]);\n projectName = answers.projectName;\n }\n\n // 验证项目名\n if (!StringUtils.validateProjectName(projectName)) {\n logger.error('项目名称只能包含小写字母、数字和连字符');\n process.exit(1);\n }\n\n logger.header('初始化项目');\n logger.newLine();\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n const projectPath = path.resolve(options.dir, projectName);\n\n // 检查目录是否存在\n if (await FileUtils.exists(projectPath)) {\n logger.error(`目录已存在: ${projectPath}`);\n logger.info('请选择其他项目名称或删除现有目录');\n process.exit(1);\n }\n\n // 创建任务列表\n const tasks = new Listr(\n [\n {\n title: '检查环境',\n task: async () => {\n const version = await claudeAI.getVersion();\n logger.info(`Claude 版本: ${version}`);\n },\n },\n {\n title: '创建项目目录',\n task: async () => {\n await FileUtils.ensureDir(projectPath);\n await FileUtils.ensureDir(path.join(projectPath, 'frontend'));\n await FileUtils.ensureDir(path.join(projectPath, 'backend'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/specs'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/api'));\n await FileUtils.ensureDir(path.join(projectPath, 'docs/sessions'));\n },\n },\n {\n title: '生成技术栈文档',\n task: async () => {\n await generateTechStack(projectPath);\n },\n },\n {\n title: '生成开发规范文档',\n task: async () => {\n await generateConventions(projectPath);\n },\n },\n {\n title: '生成 AI Memory',\n task: async () => {\n await generateAIMemory(projectPath, projectName);\n },\n },\n {\n title: '生成 Spec 模板',\n task: async () => {\n await generateSpecTemplate(projectPath);\n },\n },\n {\n title: '克隆后端模板',\n task: async () => {\n // 处理后端版本选项\n const backendTag = options.backendTag || options.tag;\n const backendBranch = options.backendBranch;\n await cloneBackendTemplate(projectPath, {\n tag: backendTag,\n branch: backendBranch,\n });\n },\n },\n {\n title: '生成前端脚手架',\n task: async () => {\n await generateFrontendScaffold(projectPath);\n },\n },\n ...(options.docker\n ? [\n {\n title: '生成 Docker 配置',\n task: async () => {\n await generateDockerFiles(projectPath);\n },\n },\n ]\n : []),\n ...(options.git\n ? [\n {\n title: '初始化 Git',\n task: async () => {\n await initGit(projectPath, projectName);\n },\n },\n ]\n : []),\n ],\n {\n concurrent: false,\n exitOnError: true,\n }\n );\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`项目 ${projectName} 初始化完成!`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(`cd ${projectName}`);\n logger.step('team-cli add-feature <feature-name>');\n logger.step('team-cli breakdown docs/specs/xxx.md');\n logger.step('team-cli dev');\n logger.newLine();\n } catch (error: any) {\n logger.error(`初始化失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成技术栈文档\n */\nasync function generateTechStack(projectPath: string): Promise<void> {\n const content = `# 技术栈\n\n## 后端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 语言 | Java | 17 | LTS 版本 |\n| 框架 | Spring Boot | 3.2 | 现代化 Java 框架 |\n| 构建工具 | Gradle | 8.x | 快速、灵活的构建工具 |\n| ORM | MyBatis Plus | 3.5 | 增强 MyBatis,简化 CRUD |\n| 数据库 | MySQL | 8.0 | 关系型数据库 |\n| 缓存 | Redis | 7.x | 缓存和会话存储 |\n| 文档 | SpringDoc OpenAPI | 2.3 | API 文档自动生成 |\n\n## 前端技术栈\n\n| 组件 | 技术选型 | 版本 | 说明 |\n|------|---------|------|------|\n| 框架 | Next.js | 14 | React 全栈框架 |\n| 语言 | TypeScript | 5.x | 类型安全 |\n| 样式 | Tailwind CSS | 3.x | 原子化 CSS |\n| UI 库 | Shadcn/UI | latest | 基于 Radix UI 的组件库 |\n| 图标 | Lucide React | latest | 一致性图标库 |\n| 状态管理 | React Context + Hooks | - | 轻量级状态管理 |\n| 表单 | React Hook Form | 7.x | 高性能表单 |\n| 数据验证 | Zod | 3.x | TypeScript 优先的验证库 |\n\n## 开发工具\n\n| 工具 | 用途 |\n|------|------|\n| ESLint | 代码检查 |\n| Prettier | 代码格式化 |\n| Husky | Git Hooks |\n| Commitlint | 提交信息规范 |\n| Docker | 容器化部署 |\n\n## 代码规范\n\n### 后端规范\n\n- 使用 DTO 模式进行数据传输\n- Controller 负责接收请求,Service 处理业务逻辑\n- 使用 @Validated 进行参数校验\n- 统一异常处理和响应格式\n- API 路径使用 kebab-case\n- 类名使用 PascalCase\n- 方法名使用 camelCase\n\n### 前端规范\n\n- 组件使用 PascalCase\n- 文件名使用 kebab-case\n- 使用 TypeScript 类型定义\n- Props 接口定义在组件内部\n- 使用 Semantic HTML\n- 响应式设计优先\n\n### Git 规范\n\n- 分支命名: \\`feature/xxx\\`, \\`bugfix/xxx\\`, \\`hotfix/xxx\\`\n- 提交信息: \\`feat: xxx\\`, \\`fix: xxx\\`, \\`docs: xxx\\`\n- 提交前必须通过 lint 检查\n\n## 目录结构\n\n\\`\\`\\`\nbackend/\n├── src/main/java/com/example/demo/\n│ ├── controller/ # API 控制器\n│ ├── service/ # 业务逻辑\n│ ├── mapper/ # 数据访问\n│ ├── entity/ # 数据模型\n│ ├── dto/ # 数据传输对象\n│ ├── config/ # 配置类\n│ └── util/ # 工具类\n├── src/main/resources/\n│ ├── mapper/ # MyBatis XML\n│ └── application.yml # 配置文件\n└── src/test/ # 测试代码\n\nfrontend/\n├── src/\n│ ├── app/ # Next.js App Router\n│ ├── components/ # React 组件\n│ ├── lib/ # 工具库\n│ └── types/ # TypeScript 类型\n└── public/ # 静态资源\n\ndocs/\n├── specs/ # 功能规格文档\n├── api/ # API 文档\n└── sessions/ # 开发会话记录\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'TECH_STACK.md'), content);\n}\n\n/**\n * 生成开发规范文档\n */\nasync function generateConventions(projectPath: string): Promise<void> {\n const content = `# 开发规范\n\n## 后端开发规范\n\n### 1. 分层架构\n\n\\`\\`\\`\nController → Service → Mapper → Database\n ↓ ↓\n DTO Entity\n\\`\\`\\`\n\n**职责划分:**\n- **Controller**: 接收 HTTP 请求,参数校验,调用 Service\n- **Service**: 业务逻辑处理,事务管理\n- **Mapper**: 数据库操作,SQL 执行\n- **DTO**: 数据传输对象,用于 API 接口\n- **Entity**: 数据库实体映射\n\n### 2. 命名规范\n\n| 类型 | 规范 | 示例 |\n|------|------|------|\n| 类名 | PascalCase | \\`UserController\\` |\n| 方法名 | camelCase | \\`getUserById\\` |\n| 常量 | UPPER_SNAKE_CASE | \\`MAX_RETRY_COUNT\\` |\n| 包名 | 小写点分隔 | \\`com.example.demo.controller\\` |\n| API 路径 | kebab-case | \\`/api/users\\` |\n\n### 3. API 设计\n\n**RESTful 风格:**\n\n\\`\\`\\`\nGET /api/users # 列表\nGET /api/users/{id} # 详情\nPOST /api/users # 创建\nPUT /api/users/{id} # 更新\nDELETE /api/users/{id} # 删除\n\\`\\`\\`\n\n**统一响应格式:**\n\n\\`\\`\\`json\n{\n \"code\": 200,\n \"message\": \"success\",\n \"data\": {...}\n}\n\\`\\`\\`\n\n### 4. 异常处理\n\n使用 \\`@ControllerAdvice\\` 统一处理异常:\n\n\\`\\`\\`java\n@RestControllerAdvice\npublic class GlobalExceptionHandler {\n\n @ExceptionHandler(BusinessException.class)\n public Result<Void> handleBusinessException(BusinessException e) {\n return Result.error(e.getMessage());\n }\n}\n\\`\\`\\`\n\n### 5. 参数校验\n\n使用 \\`@Validated\\` 和 JSR-303 注解:\n\n\\`\\`\\`java\n@PostMapping(\"/users\")\npublic Result<User> createUser(@Validated @RequestBody UserDTO dto) {\n // ...\n}\n\\`\\`\\`\n\n### 6. 事务管理\n\n在 Service 层使用 \\`@Transactional\\`:\n\n\\`\\`\\`java\n@Service\npublic class UserService {\n\n @Transactional(rollbackFor = Exception.class)\n public void createUserWithRole(User user, Role role) {\n // ...\n }\n}\n\\`\\`\\`\n\n## 前端开发规范\n\n### 1. 组件设计\n\n**组件结构:**\n\n\\`\\`\\`typescript\n// 组件定义\ninterface Props {\n // props 类型定义\n}\n\nexport function ComponentName({ prop1, prop2 }: Props) {\n // 组件逻辑\n\n return (\n // JSX\n );\n}\n\\`\\`\\`\n\n**命名规范:**\n- 组件文件: kebab-case (\\`user-card.tsx\\`)\n- 组件名: PascalCase (\\`UserCard\\`)\n- Hook 文件: kebab-case, 以 \\`use-\\` 开头 (\\`use-user-data.ts\\`)\n\n### 2. TypeScript 使用\n\n**定义接口:**\n\n\\`\\`\\`typescript\ninterface User {\n id: string;\n name: string;\n email: string;\n}\n\ninterface CreateUserDto {\n name: string;\n email: string;\n}\n\\`\\`\\`\n\n**避免使用 \\`any\\`:**\n\n\\`\\`\\`typescript\n// ❌ 不好\nconst data: any = await fetchData();\n\n// ✅ 好\nconst data: User = await fetchData();\n\\`\\`\\`\n\n### 3. 状态管理\n\n**使用 React Context:**\n\n\\`\\`\\`typescript\nconst UserContext = createContext<UserContextType>({\n user: null,\n login: async () => {},\n logout: () => {},\n});\n\\`\\`\\`\n\n**优先使用本地状态:**\n\n\\`\\`\\`typescript\n// 简单状态使用 useState\nconst [count, setCount] = useState(0);\n\n// 复杂逻辑使用 useReducer\nconst [state, dispatch] = useReducer(reducer, initialState);\n\\`\\`\\`\n\n### 4. 样式规范\n\n**使用 Tailwind CSS:**\n\n\\`\\`\\`tsx\n<div className=\"flex items-center gap-4 p-4 bg-white rounded-lg\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n**响应式设计:**\n\n\\`\\`\\`tsx\n<div className=\"grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4\">\n {/* ... */}\n</div>\n\\`\\`\\`\n\n### 5. 表单处理\n\n**使用 React Hook Form:**\n\n\\`\\`\\`typescript\nconst { register, handleSubmit, formState: { errors } } = useForm<FormData>();\n\nconst onSubmit = (data: FormData) => {\n console.log(data);\n};\n\nreturn (\n <form onSubmit={handleSubmit(onSubmit)}>\n <input {...register('name', { required: true })} />\n {errors.name && <span>必填</span>}\n </form>\n);\n\\`\\`\\`\n\n### 6. 数据获取\n\n**使用 Server Components (Next.js 14):**\n\n\\`\\`\\`typescript\nasync function getUser(id: string) {\n const res = await fetch(\\`/api/users/\\${id}\\`);\n if (!res.ok) throw new Error('Failed to fetch');\n return res.json();\n}\n\nexport default async function UserPage({ params }) {\n const user = await getUser(params.id);\n return <div>{user.name}</div>;\n}\n\\`\\`\\`\n\n## Git 工作流\n\n### 分支策略\n\n\\`\\`\\`\nmain # 主分支,始终保持稳定\n ├── feature/xxx # 功能分支\n ├── bugfix/xxx # Bug 修复分支\n └── hotfix/xxx # 紧急修复分支\n\\`\\`\\`\n\n### 提交信息规范\n\n\\`\\`\\`\n<type>(<scope>): <subject>\n\n<body>\n\n<footer>\n\\`\\`\\`\n\n**类型 (type):**\n- \\`feat\\`: 新功能\n- \\`fix\\`: Bug 修复\n- \\`docs\\`: 文档更新\n- \\`style\\`: 代码格式调整\n- \\`refactor\\`: 代码重构\n- \\`test\\`: 测试相关\n- \\`chore\\`: 构建/工具相关\n\n**示例:**\n\n\\`\\`\\`\nfeat(auth): add user login feature\n\nimplement JWT based authentication with:\n- login endpoint\n- token refresh\n- logout handling\n\nCloses #123\n\\`\\`\\`\n\n## 测试规范\n\n### 后端测试\n\n\\`\\`\\`java\n@SpringBootTest\nclass UserServiceTest {\n\n @Autowired\n private UserService userService;\n\n @Test\n void shouldCreateUser() {\n // given\n User user = new User(\"John\");\n\n // when\n User saved = userService.save(user);\n\n // then\n assertNotNull(saved.getId());\n }\n}\n\\`\\`\\`\n\n### 前端测试\n\n\\`\\`\\`typescript\nimport { render, screen } from '@testing-library/react';\n\ntest('renders user name', () => {\n render(<UserProfile name=\"John\" />);\n expect(screen.getByText('John')).toBeInTheDocument();\n});\n\\`\\`\\`\n`;\n\n await FileUtils.write(path.join(projectPath, 'CONVENTIONS.md'), content);\n}\n\n/**\n * 生成 AI Memory\n */\nasync function generateAIMemory(projectPath: string, projectName: string): Promise<void> {\n const content = `# AI Memory - 项目状态记录\n\n## 项目信息\n- **项目名称**: ${projectName}\n- **创建时间**: ${new Date().toISOString().split('T')[0]}\n- **当前阶段**: 初始化\n- **最后更新**: ${new Date().toISOString().split('T')[0]}\n\n## 模板版本信息\n\n> 本部分由 team-cli 自动管理,记录使用的前后端模板版本\n\n| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |\n|------|------|-----|--------|--------|----------|\n| 前端 | - | - | - | - | - |\n| 后端 | - | - | - | - | - |\n\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n\n## API 列表 (API Inventory)\n\n> 本部分由 team-cli 自动扫描后端 Controller 生成\n\n## 数据模型概览\n\n| 表名 | 说明 | 字段数 | 关联表 | 状态 |\n|------|------|--------|--------|------|\n| user | 用户表 | - | - | - |\n\n## 已完成的 Milestones\n\n## 当前任务\n\n## 待处理任务\n\n## 技术债务\n\n| 日期 | 问题 | 计划修复 |\n|------|------|---------|\n\n## 关键决策记录\n\n| 日期 | 决策 | 原因 |\n|------|------|------|\n| ${new Date().toISOString().split('T')[0]} | 初始化项目 | 使用 Spring Boot 3 + Next.js 14 技术栈 |\n\n## 注意事项\n\n## Bugfix 记录\n\n| Bug ID | 日期 | 问题描述 | 状态 |\n|--------|------|---------|------|\n`;\n\n await FileUtils.write(path.join(projectPath, 'AI_MEMORY.md'), content);\n}\n\n/**\n * 生成 Spec 模板\n */\nasync function generateSpecTemplate(projectPath: string): Promise<void> {\n const content = `# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: {{DATE}}\n\n## 依赖关系\n**前置依赖**:\n- [ ] dependency-1.md\n- [ ] dependency-2.md\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n1. 功能点一\n2. 功能点二\n3. 功能点三\n\n## 技术设计\n\n### API 设计\n- \\`POST /api/xxx\\` - 创建 XXX\n- \\`GET /api/xxx/{id}\\` - 获取 XXX 详情\n- \\`PUT /api/xxx/{id}\\` - 更新 XXX\n- \\`DELETE /api/xxx/{id}\\` - 删除 XXX\n\n### 数据模型\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n\n> 注: 使用 \\`team-cli breakdown\\` 拆分此 spec 为 milestones 和 todos\n\n### Milestone 1: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n\n### Milestone 2: [里程碑名称]\n- [ ] Todo 1\n- [ ] Todo 2\n\n----\n*生成于: {{TIMESTAMP}} by team-cli*\n`;\n\n await FileUtils.write(path.join(projectPath, 'docs/specs/template.md'), content);\n}\n\n/**\n * 克隆后端模板\n */\nasync function cloneBackendTemplate(\n projectPath: string,\n versionOptions?: {\n tag?: string;\n branch?: string;\n }\n): Promise<void> {\n const templateRepo = process.env.TEMPLATE_REPO || 'git@gitlab.yungu-inc.org:yungu-app/java-scaffold-template.git';\n const backendPath = path.join(projectPath, 'backend');\n\n try {\n const { execaCommand } = await import('execa');\n const tempDir = path.join(projectPath, '.template-temp');\n\n // 如果指定了 tag 或 branch,先验证\n if (versionOptions?.tag || versionOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(templateRepo);\n\n if (versionOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, versionOptions.tag);\n if (!isValid) {\n logger.error(`后端模板 tag \"${versionOptions.tag}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板 tag: ${versionOptions.tag}`);\n }\n\n if (versionOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, versionOptions.branch);\n if (!isValid) {\n logger.error(`后端模板分支 \"${versionOptions.branch}\" 不存在`);\n process.exit(1);\n }\n logger.info(`使用后端模板分支: ${versionOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = versionOptions?.tag || versionOptions?.branch || 'HEAD';\n\n // 克隆到临时目录\n await execaCommand(`git clone --depth=1 --branch ${ref} ${templateRepo} ${tempDir}`, {\n stdio: 'inherit',\n timeout: 60000,\n });\n\n // 获取 commit 和 tag\n const { execa: e } = await import('execa');\n const { stdout: commit } = await e('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const { stdout: tags } = await e('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 复制内容(排除 .git)\n await fs.copy(tempDir, backendPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 删除 .git 目录\n const gitDir = path.join(backendPath, '.git');\n if (await FileUtils.exists(gitDir)) {\n await FileUtils.remove(gitDir);\n }\n\n // 保存模板版本信息\n await initTemplateConfig(projectPath);\n await updateTemplateVersion(projectPath, 'backend', commit.trim(), {\n tag: versionOptions?.tag || latestTag,\n branch: versionOptions?.branch,\n });\n } catch (error) {\n // 如果克隆失败,创建基础结构\n logger.warn('克隆后端模板失败,创建基础结构');\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/java/com/example'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/main/resources'));\n await FileUtils.ensureDir(path.join(backendPath, 'src/test/java'));\n }\n}\n\n/**\n * 生成前端脚手架\n */\nasync function generateFrontendScaffold(projectPath: string): Promise<void> {\n const frontendPath = path.join(projectPath, 'frontend');\n\n // 使用 Claude 生成前端脚手架\n try {\n const prompt = `Read TECH_STACK.md and CONVENTIONS.md.\nInitialize a Next.js 14 frontend in ./frontend with:\n- TypeScript\n- Tailwind CSS\n- App Router structure\n- ESLint and Prettier configured\n- Basic layout and page components\n\nDo not run any servers, just generate the folder structure and configuration files.`;\n\n await claudeAI.prompt(prompt, {\n contextFiles: [\n path.join(projectPath, 'TECH_STACK.md'),\n path.join(projectPath, 'CONVENTIONS.md'),\n ],\n });\n } catch (error) {\n logger.warn('Claude 生成前端失败,将创建基础结构');\n await FileUtils.ensureDir(path.join(frontendPath, 'src/app'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/components'));\n await FileUtils.ensureDir(path.join(frontendPath, 'src/lib'));\n await FileUtils.ensureDir(path.join(frontendPath, 'public'));\n }\n}\n\n/**\n * 生成 Docker 配置\n */\nasync function generateDockerFiles(projectPath: string): Promise<void> {\n // TODO: 实现 Docker 文件生成\n logger.info('Docker 配置生成待实现');\n}\n\n/**\n * 初始化 Git\n */\nasync function initGit(projectPath: string, projectName: string): Promise<void> {\n try {\n const { execaCommand } = await import('execa');\n\n await execaCommand('git init', { cwd: projectPath, stdio: 'pipe' });\n await execaCommand('git add .', { cwd: projectPath, stdio: 'pipe' });\n await execaCommand(\n `git commit -m \"feat: initialize ${projectName} project with team-cli\"`,\n { cwd: projectPath, stdio: 'pipe' }\n );\n\n logger.success('Git 仓库初始化完成');\n } catch (error: any) {\n logger.warn(`Git 初始化失败: ${error.message}`);\n }\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Breakdown 命令 - 将 spec 拆分为 milestones 和 todos\n */\nexport const breakdownCommand = new Command('breakdown')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('将 spec 拆分为 milestones 和 todos')\n .action(async (specFile) => {\n try {\n logger.header('Spec 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 扫描 spec 文件\n const tasks = new Listr([\n {\n title: '扫描 spec 文件',\n task: async () => {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error(`specs 目录不存在: ${specDir}`);\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n return files.filter((f) => !f.includes('template'));\n },\n },\n {\n title: '选择 spec 文件',\n task: async (ctx) => {\n if (ctx.specs.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 如果没有指定文件,交互式选择\n if (!specFile) {\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '请选择要拆分的 spec 文件:',\n choices: ctx.specs,\n },\n ]);\n return path.join('docs/specs', selectedFile);\n }\n\n // 验证指定的文件\n const fullPath = specFile.startsWith('docs/specs/')\n ? specFile\n : path.join('docs/specs', specFile);\n\n const exists = await FileUtils.exists(fullPath);\n if (!exists) {\n throw new Error(`Spec 文件不存在: ${specFile}`);\n }\n\n return fullPath;\n },\n },\n {\n title: '读取 spec 内容',\n task: async (ctx) => {\n ctx.specContent = await FileUtils.read(ctx.selectedFile);\n logger.success(`已选择: ${ctx.selectedFile}`);\n },\n },\n {\n title: '调用 Claude 拆分 spec',\n task: async (ctx) => {\n const prompt = buildBreakdownPrompt(ctx.specContent);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n // 调用 Claude 执行拆分\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '更新 spec 文件',\n task: async (ctx) => {\n // Claude 的输出已经是更新后的完整内容\n // 直接写入文件\n await FileUtils.write(ctx.selectedFile, ctx.breakdownResult);\n },\n },\n ]);\n\n try {\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.header('Spec 拆分完成!');\n logger.success(`Milestones 已添加到: ctx.selectedFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 检查拆分结果,根据需要调整');\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n } catch (error: any) {\n if (error.message) {\n logger.error(error.message);\n }\n throw error;\n }\n } catch (error: any) {\n logger.error(`拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 构建拆分 prompt\n */\nfunction buildBreakdownPrompt(specContent: string): string {\n return `Role: Senior Technical Lead and Agile Coach\n\nTask: Break down the following feature spec into milestones and todo lists.\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each milestone should be completable in 1-3 days\n- Each todo should be a concrete, actionable task\n\nSpec Content:\n\\`\\`\\`\n${specContent}\n\\`\\`\\`\n\nOutput Requirements:\n1. Parse the existing spec content\n2. Break it down into 2-5 milestones\n3. Each milestone should have:\n - Clear name and objective\n - Estimated days (1-3 days per milestone)\n - Todo list with 3-8 actionable items\n4. Todo items should be:\n - Concrete and specific\n - Testable\n - Independent as much as possible\n\nFormat the milestones section as:\n\n\\`\\`\\`markdown\n## 里程碑 (Milestones)\n\n### Milestone 1: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 2 天\n\n- [ ] Todo 1 - 具体可执行的任务\n- [ ] Todo 2 - 具体可执行的任务\n- [ ] Todo 3 - 具体可执行的任务\n\n### Milestone 2: [里程碑名称]\n**目标**: [简短描述这个里程碑的目标]\n**预估**: 3 天\n\n- [ ] Todo 1\n- [ ] Todo 2\n- [ ] Todo 3\n- [ ] Todo 4\n\\`\\`\\`\n\nImportant Instructions:\n1. Update the spec file directly with the milestone breakdown\n2. Keep all existing content, just add/update the milestones section\n3. If milestones section exists, replace it with new breakdown\n4. If milestones section doesn't exist, add it after \"技术设计\" section\n5. After updating the file, exit immediately\n6. Do not ask any questions\n7. Make sure todos are actionable and can be completed independently\n8. Consider dependencies when ordering todos within a milestone`;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\ninterface SpecInfo {\n file: string;\n name: string;\n status: '未开始' | '进行中' | '已拆分' | '已完成';\n dependencies: string[];\n index: number;\n}\n\ninterface MilestoneInfo {\n title: string;\n todos: string[];\n}\n\n/**\n * Dev 命令 - 开发模式\n */\nexport const devCommand = new Command('dev')\n .description('开发模式,执行具体任务')\n .action(async () => {\n try {\n logger.header('开发模式');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.success('检测到项目上下文');\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 步骤 1: 扫描并选择 spec\n const selectedSpec = await selectSpec();\n\n // 步骤 2: 解析并选择 milestone\n const selectedMilestone = await selectMilestone(selectedSpec);\n\n // 步骤 3: 选择 todo(如果选择了具体 milestone)\n const selectedTodo = await selectTodo(selectedSpec, selectedMilestone);\n\n // 步骤 4: 调用 Claude 执行开发\n await executeDevelopment(selectedSpec, selectedMilestone, selectedTodo);\n } catch (error: any) {\n logger.error(`开发模式执行失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 步骤 1: 选择 spec 文件\n */\nasync function selectSpec(): Promise<string> {\n logger.step('步骤 1/3: 选择 spec 文件...');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n if (!exists) {\n throw new Error('docs/specs 目录不存在');\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specFiles = files.filter((f) => !f.includes('template'));\n\n if (specFiles.length === 0) {\n throw new Error('未找到 spec 文件');\n }\n\n // 解析 spec 信息(状态、依赖)\n const specs: SpecInfo[] = [];\n for (let i = 0; i < specFiles.length; i++) {\n const file = path.join(specDir, specFiles[i]);\n const spec = await FileUtils.read(file);\n\n const status = parseSpecStatus(spec);\n const dependencies = parseDependencies(spec);\n\n specs.push({\n file,\n name: specFiles[i],\n status,\n dependencies,\n index: i,\n });\n }\n\n // 拓扑排序推荐开发顺序\n const sortedSpecs = topologicalSort(specs);\n\n // 显示选项\n logger.info('可用的 spec 文件:');\n logger.newLine();\n\n const choices = sortedSpecs.map((spec, idx) => {\n const statusIcon = getStatusIcon(spec.status);\n const statusColor = getStatusColor(spec.status);\n const recommendInfo = idx === 0 ? '[推荐从这开始] ' : '';\n const depInfo =\n spec.dependencies.length > 0 ? `[依赖: ${spec.dependencies.join(', ')}] ` : '';\n\n return {\n name: `${statusIcon} [${spec.status}] ${recommendInfo}${depInfo}${spec.name}`,\n value: spec.file,\n short: spec.name,\n };\n });\n\n logger.info(' ✓ = 已完成 ⟳ = 进行中 ◉ = 已拆分 ○ = 未开始');\n logger.info(' 根据依赖关系推荐的开发顺序已标注');\n logger.newLine();\n\n const { selectedFile } = await inquirer.prompt([\n {\n type: 'list',\n name: 'selectedFile',\n message: '选择要开发的 spec:',\n choices,\n },\n ]);\n\n logger.success(`已选择: ${selectedFile}`);\n return selectedFile;\n}\n\n/**\n * 步骤 2: 解析并选择 milestone\n */\nasync function selectMilestone(specFile: string): Promise<string> {\n logger.newLine();\n logger.step('步骤 2/3: 解析 milestones...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const milestones = parseMilestones(specContent);\n\n if (milestones.length === 0) {\n logger.info('该 spec 尚未拆分 milestones');\n\n const { breakdownNow } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'breakdownNow',\n message: '是否现在拆分?',\n default: true,\n },\n ]);\n\n if (breakdownNow) {\n // 调用 breakdown 命令\n logger.info('正在调用 breakdown...');\n // TODO: 调用 breakdown 命令\n throw new Error('breakdown 命令需要进一步实现');\n } else {\n logger.info('将直接实现整个 spec');\n return '整个 spec';\n }\n }\n\n // 显示 milestones\n const choices = milestones.map((m, idx) => ({\n name: `${idx + 1}. ${m.title} (${m.todos.length} 个任务)`,\n value: m.title,\n short: m.title,\n }));\n\n choices.push({\n name: `${milestones.length + 1}. 整个 spec (全部 milestones)`,\n value: '整个 spec',\n short: '整个 spec',\n });\n\n const { milestone } = await inquirer.prompt([\n {\n type: 'list',\n name: 'milestone',\n message: '选择 milestone:',\n choices,\n },\n ]);\n\n return milestone;\n}\n\n/**\n * 步骤 3: 选择 todo 任务\n */\nasync function selectTodo(\n specFile: string,\n milestone: string\n): Promise<string> {\n if (milestone === '整个 spec') {\n return '全部功能';\n }\n\n logger.newLine();\n logger.step('步骤 3/3: 选择 todo 任务...');\n logger.newLine();\n\n const specContent = await FileUtils.read(specFile);\n const todos = parseTodos(specContent, milestone);\n\n if (todos.length === 0) {\n logger.warn('该 milestone 没有 todo 任务');\n const { implementAll } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'implementAll',\n message: '实现整个 milestone?',\n default: true,\n },\n ]);\n\n return implementAll ? '全部功能' : milestone;\n }\n\n const choices = todos.map((todo, idx) => ({\n name: `${idx + 1}. ${todo}`,\n value: todo,\n short: todo,\n }));\n\n choices.push({\n name: `${todos.length + 1}. 全部任务 (整个 milestone)`,\n value: '全部任务',\n short: '全部任务',\n });\n\n const { todo } = await inquirer.prompt([\n {\n type: 'list',\n name: 'todo',\n message: '选择 todo 任务:',\n choices,\n },\n ]);\n\n return todo;\n}\n\n/**\n * 步骤 4: 调用 Claude 执行开发\n */\nasync function executeDevelopment(\n specFile: string,\n milestone: string,\n todo: string\n): Promise<void> {\n logger.newLine();\n logger.step('构建 Prompt 并调用 Claude...');\n\n let taskDescription: string;\n if (milestone === '整个 spec') {\n taskDescription = '实现整个 spec 的所有功能';\n } else if (todo === '全部功能' || todo === '全部任务') {\n taskDescription = `实现 milestone '${milestone}' 的所有任务`;\n } else {\n taskDescription = `实现 milestone '${milestone}' 的任务: ${todo}`;\n }\n\n const prompt = buildDevPrompt(specFile, milestone, todo, taskDescription);\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n logger.info(` 任务描述: ${taskDescription}`);\n logger.info(` Spec 文件: ${specFile}`);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md', specFile],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n // 生成会话日志\n await generateSessionLog(specFile, milestone, todo, taskDescription, result);\n\n logger.header('开发任务完成!');\n logger.success('会话日志已保存');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查生成的代码');\n logger.step(\"2. 运行 'team-cli dev' 继续下一个任务\");\n logger.newLine();\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): '未开始' | '进行中' | '已拆分' | '已完成' {\n // 匹配 \"状态: xxx\" 格式\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '已完成';\n if (status.includes('进行中')) return '进行中';\n if (status.includes('已拆分')) return '已拆分';\n }\n return '未开始';\n}\n\n/**\n * 解析依赖关系\n */\nfunction parseDependencies(spec: string): string[] {\n const deps: string[] = [];\n let inDepsSection = false;\n\n const lines = spec.split('\\n');\n for (const line of lines) {\n // 检测依赖关系部分\n if (line.includes('## 依赖关系') || line.includes('## 依赖')) {\n inDepsSection = true;\n continue;\n }\n\n // 遇到其他二级标题,退出\n if (inDepsSection && line.startsWith('## ')) {\n break;\n }\n\n // 匹配 - [xxx] dependency.md 格式\n const match = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+\\.md)/);\n if (inDepsSection && match) {\n const dep = match[1];\n if (dep !== '无' && dep) {\n deps.push(dep);\n }\n }\n }\n\n return deps;\n}\n\n/**\n * 解析 milestones\n */\nfunction parseMilestones(spec: string): MilestoneInfo[] {\n const milestones: MilestoneInfo[] = [];\n const lines = spec.split('\\n');\n let currentMilestone: MilestoneInfo | null = null;\n let inMilestone = false;\n\n for (const line of lines) {\n // 检测 milestone 开始\n if (line.match(/^###\\s+Milestone\\s+\\d+:/)) {\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n const title = line.replace(/^###\\s+/, '').trim();\n currentMilestone = { title, todos: [] };\n inMilestone = true;\n continue;\n }\n\n // 在 milestone 内部\n if (inMilestone && currentMilestone) {\n // 遇到下一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n milestones.push(currentMilestone);\n currentMilestone = null;\n continue;\n }\n\n // 匹配 todo 行\n const todoMatch = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+)/);\n if (todoMatch) {\n currentMilestone.todos.push(todoMatch[1].trim());\n }\n }\n }\n\n if (currentMilestone) {\n milestones.push(currentMilestone);\n }\n\n return milestones;\n}\n\n/**\n * 解析指定 milestone 的 todos\n */\nfunction parseTodos(spec: string, milestoneTitle: string): string[] {\n const lines = spec.split('\\n');\n const todos: string[] = [];\n let inTargetMilestone = false;\n\n for (const line of lines) {\n // 找到目标 milestone\n if (line.includes(milestoneTitle)) {\n inTargetMilestone = true;\n continue;\n }\n\n if (inTargetMilestone) {\n // 遇到另一个 milestone,退出\n if (line.match(/^###\\s+Milestone/)) {\n break;\n }\n\n // 匹配 todo 行\n const todoMatch = line.match(/^-\\s+\\[[ x ]\\]\\s*(.+)/);\n if (todoMatch) {\n todos.push(todoMatch[1].trim());\n }\n }\n }\n\n return todos;\n}\n\n/**\n * 拓扑排序 - 根据依赖关系排序 specs\n */\nfunction topologicalSort(specs: SpecInfo[]): SpecInfo[] {\n const sorted: SpecInfo[] = [];\n const visited = new Set<number>();\n\n function visit(spec: SpecInfo) {\n if (visited.has(spec.index)) return;\n visited.add(spec.index);\n\n // 先访问依赖\n for (const depName of spec.dependencies) {\n const dep = specs.find((s) => s.name === depName);\n if (dep) {\n visit(dep);\n }\n }\n\n sorted.push(spec);\n }\n\n for (const spec of specs) {\n visit(spec);\n }\n\n return sorted;\n}\n\n/**\n * 获取状态图标\n */\nfunction getStatusIcon(status: string): string {\n switch (status) {\n case '已完成':\n return '✓';\n case '进行中':\n return '⟳';\n case '已拆分':\n return '◉';\n default:\n return '○';\n }\n}\n\n/**\n * 获取状态颜色\n */\nfunction getStatusColor(status: string): string {\n // 用于终端颜色显示的辅助函数\n return status; // 实际实现中可以使用 chalk\n}\n\n/**\n * 构建开发 prompt\n */\nfunction buildDevPrompt(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string\n): string {\n return `Role: Senior Fullstack Developer\n\nContext:\n- Read and follow TECH_STACK.md for technology choices\n- Read and follow CONVENTIONS.md for coding standards\n- Check AI_MEMORY.md for project context and history\n\nTask: ${taskDescription}\n\nSpec File: ${specFile}\nMilestone: ${milestone}\nTodo: ${todo}\n\nProcess:\n1. First, read and analyze the full spec file\n2. Focus on the selected milestone/todo\n3. Define API endpoints and data models if needed\n4. Write tests first (TDD approach)\n5. Implement the backend code in ./backend\n6. Implement the frontend integration in ./frontend\n7. Update AI_MEMORY.md with completed tasks\n8. Update the spec file to mark completed todos (if applicable)\n\nImportant:\n- Follow the tech stack exactly (Java 17, Spring Boot 3, MyBatis Plus, Next.js 14, TypeScript)\n- Use DTO pattern for all API requests/responses\n- Write clean, well-documented code\n- After completing the task, exit immediately without waiting for further input\n`;\n}\n\n/**\n * 生成会话日志\n */\nasync function generateSessionLog(\n specFile: string,\n milestone: string,\n todo: string,\n taskDescription: string,\n result: string\n): Promise<void> {\n const sessionDir = 'docs/sessions';\n await FileUtils.ensureDir(sessionDir);\n\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-');\n const specName = path.basename(specFile, '.md');\n const logFile = path.join(sessionDir, `${timestamp}_${specName}.md`);\n\n const content = `# 开发会话记录\n\n**时间**: ${new Date().toLocaleString('zh-CN')}\n**Spec**: ${specFile}\n**Milestone**: ${milestone}\n**Todo**: ${todo}\n\n## 任务描述\n\n${taskDescription}\n\n## 执行结果\n\n\\`\\`\\`\n${result}\n\\`\\`\\`\n\n## 生成的文件\n\n<!-- TODO: 列出生成的文件 -->\n\n## 下一步\n\n- [ ] 测试生成的代码\n- [ ] 更新 spec 文件中的 todo 状态\n- [ ] 继续下一个任务\n`;\n\n await FileUtils.write(logFile, content);\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport fs from 'fs-extra';\nimport { FileUtils, StringUtils, SpecUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Add-feature 命令 - 添加新功能\n */\nexport const addFeatureCommand = new Command('add-feature')\n .argument('<feature-name>', '功能名称')\n .description('添加新功能(支持 PRD 或简单描述模式)')\n .action(async (featureName) => {\n try {\n logger.header('添加新功能');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info('请先运行 team-cli init 或切换到项目目录');\n process.exit(1);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 转换为 kebab-case\n const featureSlug = StringUtils.toKebabCase(featureName);\n\n // 检查 spec 是否已存在\n const specFile = path.join('docs/specs', `${featureSlug}.md`);\n const specExists = await FileUtils.exists(specFile);\n if (specExists) {\n logger.error(`Spec 文件已存在: ${specFile}`);\n logger.info('如需重新生成,请先删除:');\n logger.info(` rm ${specFile}`);\n process.exit(1);\n }\n\n // 选择模式\n const { mode } = await inquirer.prompt([\n {\n type: 'list',\n name: 'mode',\n message: '选择需求输入模式:',\n choices: [\n { name: 'PRD 文档模式 (已有详细 PRD 文档)', value: 'prd' },\n { name: '简单描述模式 (一句话需求 + 模块依赖)', value: 'simple' },\n ],\n },\n ]);\n\n // 执行对应模式\n if (mode === 'prd') {\n await addFeatureFromPrd(featureName, featureSlug, specFile);\n } else {\n await addFeatureSimple(featureName, featureSlug, specFile);\n }\n } catch (error: any) {\n logger.error(`添加功能失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * PRD 文档模式\n */\nasync function addFeatureFromPrd(\n featureName: string,\n featureSlug: string,\n specFile: string\n): Promise<void> {\n const { prdPath } = await inquirer.prompt([\n {\n type: 'input',\n name: 'prdPath',\n message: '请输入 PRD 文档路径:',\n validate: async (input: string) => {\n const exists = await FileUtils.exists(input);\n return exists || 'PRD 文档不存在';\n },\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '读取 PRD 文档',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(prdPath);\n },\n },\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 spec',\n task: async (ctx) => {\n const prompt = buildPrdPrompt(\n featureName,\n ctx.prdContent,\n ctx.projectContext,\n ctx.completedSpecs\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 生成 spec 中...');\n logger.separator('─', 60);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '保存 spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.generatedSpec);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(featureName, featureSlug);\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.success(`Spec 文件已生成: ${specFile}`);\n await showSpecPreview(specFile);\n await askToAdjust(specFile);\n}\n\n/**\n * 简单描述模式\n */\nasync function addFeatureSimple(\n featureName: string,\n featureSlug: string,\n specFile: string\n): Promise<void> {\n // 收集功能描述\n const { description } = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '功能描述 (一句话说明):',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n ]);\n\n const tasks = new Listr([\n {\n title: '扫描已完成功能',\n task: async (ctx) => {\n const specDir = 'docs/specs';\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n ctx.completedSpecs = [];\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join(specDir, file));\n if (status === '已完成') {\n ctx.completedSpecs.push(file.replace('.md', ''));\n }\n }\n },\n },\n {\n title: '选择依赖功能',\n task: async (ctx) => {\n if (ctx.completedSpecs.length === 0) {\n ctx.selectedDeps = [];\n return;\n }\n\n const { dependencies } = await inquirer.prompt([\n {\n type: 'checkbox',\n name: 'dependencies',\n message: '选择此功能依赖的已有功能 (可多选,直接回车跳过):',\n choices: ctx.completedSpecs,\n },\n ]);\n\n ctx.selectedDeps = dependencies;\n },\n },\n {\n title: '构建项目上下文',\n task: async (ctx) => {\n ctx.projectContext = await buildProjectContext();\n },\n },\n {\n title: '调用 Claude 生成 spec',\n task: async (ctx) => {\n const prompt = buildSimplePrompt(\n featureName,\n description,\n ctx.projectContext,\n ctx.selectedDeps\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 生成 spec 中...');\n logger.separator('─', 60);\n logger.newLine();\n\n const result = await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md', 'AI_MEMORY.md'],\n });\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n return result;\n },\n },\n {\n title: '保存 spec 文件',\n task: async (ctx) => {\n await FileUtils.write(specFile, ctx.generatedSpec);\n },\n },\n {\n title: '更新 AI_MEMORY',\n task: async () => {\n await updateAiMemory(featureName, featureSlug);\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.success(`Spec 文件已生成: ${specFile}`);\n await showSpecPreview(specFile);\n await askToAdjust(specFile);\n}\n\n/**\n * 构建项目上下文\n */\nasync function buildProjectContext(): Promise<string> {\n const context: string[] = [];\n\n // 扫描后端目录\n if (await FileUtils.exists('backend/src/main/java')) {\n context.push('### 后端结构');\n const backendDirs = await FileUtils.findFiles('*/', 'backend/src/main/java');\n const limited = backendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - backend/src/main/java/${dir}`);\n });\n }\n\n // 扫描前端目录\n if (await FileUtils.exists('frontend/src')) {\n context.push('');\n context.push('### 前端结构');\n const frontendDirs = await FileUtils.findFiles('*/', 'frontend/src');\n const limited = frontendDirs.slice(0, 10);\n limited.forEach((dir) => {\n context.push(` - frontend/src/${dir}`);\n });\n }\n\n // 扫描已有 specs\n if (await FileUtils.exists('docs/specs')) {\n context.push('');\n context.push('### 已有功能');\n const files = await FileUtils.findFiles('*.md', 'docs/specs');\n const specs = files.filter((f) => !f.includes('template'));\n\n for (const file of specs) {\n const status = await SpecUtils.getSpecStatus(path.join('docs/specs', file));\n context.push(` - ${file.replace('.md', '')} [${status}]`);\n }\n }\n\n return context.join('\\n');\n}\n\n/**\n * 构建 PRD 模式 prompt\n */\nfunction buildPrdPrompt(\n featureName: string,\n prdContent: string,\n projectContext: string,\n completedSpecs: string[]\n): string {\n const deps = completedSpecs.length > 0 ? completedSpecs.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n你现在需要根据 PRD 文档生成一个功能规格(Spec)文档。\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 功能名称\n${featureName}\n\n## PRD 文档内容\n${prdContent}\n\n## 依赖功能\n此功能可能依赖以下已完成的功能:${deps}\n\n## 任务\n请根据 PRD 文档,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${completedSpecs.map((s) => `- [x] ${s}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据 PRD 提取背景和目标]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n[从 PRD 提取 3-8 个主要功能点]\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断标准:\n - P0: 核心功能,阻塞其他功能\n - P1: 重要功能,影响用户体验\n - P2: 增强功能,锦上添花\n3. 工时评估标准:\n - 简单功能: 1-2 天\n - 中等功能: 3-5 天\n - 复杂功能: 5-10 天\n4. 功能点要具体可执行,避免过于抽象\n5. API 和数据模型要符合实际技术栈\n6. 从 PRD 中提取关键信息,保持简洁`;\n}\n\n/**\n * 构建简单描述模式 prompt\n */\nfunction buildSimplePrompt(\n featureName: string,\n description: string,\n projectContext: string,\n dependencies: string[]\n): string {\n const deps = dependencies.length > 0 ? dependencies.join('、') : '(无)';\n\n return `Role: Senior Fullstack Developer\n\n用户想要添加一个新功能,需要你生成功能规格文档(Spec)。\n\n## 功能名称\n${featureName}\n\n## 功能描述\n${description}\n\n## 依赖功能\n此功能依赖以下已完成的功能:${deps}\n\n## 项目技术栈\n后端: Java 17 + Spring Boot 3 + MyBatis Plus + MySQL 8.0\n前端: Next.js 14 (App Router) + TypeScript + Tailwind CSS\n\n## 项目当前状态\n${projectContext}\n\n## 任务\n请根据功能描述,生成一个完整的功能规格文档 Spec。\n\n## Spec 文档格式要求\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: ${featureName}\n**优先级**: P0/P1/P2 (根据功能重要性判断)\n**预估工时**: X 天 (根据复杂度评估:简单1-2天,中等3-5天,复杂5-10天)\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n${dependencies.map((d) => `- [x] ${d}`).join('\\n') || '- (无)'}\n\n**被依赖于**:\n- (自动生成,表示哪些 spec 依赖本功能)\n\n## 背景与目标\n[根据功能描述,简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点,每个功能点用一句话描述。\n\n## 技术设计\n### API 设计\n列出主要的 API 端点,格式:\n- \\`METHOD /api/path\\` - 简短说明\n\n### 数据模型\n列出需要的数据表,格式:\n- \\`table_name\\` (表说明) - 字段说明\n\n## 里程碑 (Milestones)\n> 注: 使用 \\`team-cli breakdown ${featureName}.md\\` 拆分此 spec 为 milestones 和 todos\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\n## 注意事项\n1. 只生成 Spec 文档,不要实现任何代码\n2. 优先级判断要合理,避免全部是 P0\n3. 工时评估要实际,不要过于乐观\n4. 功能点要具体可执行\n5. 根据功能描述推断合理的 API 和数据模型\n6. 参考已有功能的技术风格保持一致性`;\n}\n\n/**\n * 更新 AI_MEMORY\n */\nasync function updateAiMemory(featureName: string, featureSlug: string): Promise<void> {\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.warn('AI_MEMORY.md 不存在,跳过更新');\n return;\n }\n\n let content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否有功能清单部分\n if (!content.includes('## 功能清单')) {\n // 添加功能清单部分\n const featureList = `\n## 功能清单 (Feature Inventory)\n\n| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |\n|------|----------|------|------|---------|------|\n| ${featureName} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |\n`;\n content = content.replace('(/项目信息/[^#]*)', `$1\\n${featureList}`);\n } else {\n // 在功能清单中添加新功能\n const newRow = `| ${featureName} | ${featureSlug}.md | ○ 未开始 | 0/0 | - | |`;\n content = content.replace(\n /(\\| 功能 \\| Spec 文件 \\| 状态 \\| 进度 \\| 完成日期 \\| 备注 \\|)/,\n `$1\\n${newRow}`\n );\n }\n\n await FileUtils.write(aiMemoryFile, content);\n logger.success('AI_MEMORY.md 已更新');\n}\n\n/**\n * 显示 spec 预览\n */\nasync function showSpecPreview(specFile: string): Promise<void> {\n logger.newLine();\n logger.header('生成的 Spec 预览:');\n logger.newLine();\n\n const content = await FileUtils.read(specFile);\n const lines = content.split('\\n');\n const preview = lines.slice(0, 40).join('\\n');\n\n console.log(preview);\n if (lines.length > 40) {\n console.log('...');\n console.log(`(共 ${lines.length} 行)`);\n }\n console.log('');\n}\n\n/**\n * 询问是否需要调整\n */\nasync function askToAdjust(specFile: string): Promise<void> {\n const { needAdjust } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'needAdjust',\n message: '是否需要调整 Spec 内容?',\n default: false,\n },\n ]);\n\n if (needAdjust) {\n logger.info('正在打开编辑器...');\n const editor = process.env.EDITOR || 'vim';\n const { execaCommand } = await import('execa');\n await execaCommand(`${editor} ${specFile}`, { stdio: 'inherit' });\n }\n\n logger.newLine();\n logger.info('下一步:');\n logger.step(`1. 运行 'team-cli breakdown ${specFile}' 拆分为 milestones`);\n logger.step(\"2. 运行 'team-cli dev' 选择 milestone 进行开发\");\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { claudeAI } from '../lib/claude.js';\nimport { Listr } from 'listr2';\n\n/**\n * Split-prd 命令 - 将 PRD 拆分为多个 specs\n */\nexport const splitPrdCommand = new Command('split-prd')\n .argument('<prd-folder>', 'PRD 文档目录')\n .description('将 PRD 拆分成多个 specs')\n .action(async (prdFolder) => {\n try {\n logger.header('PRD 拆分');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 检查文件夹是否存在\n const folderExists = await FileUtils.exists(prdFolder);\n if (!folderExists) {\n throw new Error(`PRD 文件夹不存在: ${prdFolder}`);\n }\n\n // 检查 Claude 是否安装\n const hasClaude = await claudeAI.checkInstalled();\n if (!hasClaude) {\n logger.error('未检测到 Claude CLI');\n logger.info('请安装 Claude CLI: npm install -g @anthropic-ai/claude-code');\n process.exit(1);\n }\n\n // 执行 PRD 拆分任务\n const tasks = new Listr([\n {\n title: '扫描 PRD 文件',\n task: async (ctx) => {\n const supportedExtensions = ['md', 'txt', 'markdown'];\n ctx.prdFiles = [];\n\n for (const ext of supportedExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, prdFolder);\n ctx.prdFiles.push(...files.map((f) => path.join(prdFolder, f)));\n }\n\n if (ctx.prdFiles.length === 0) {\n throw new Error(\n '未找到 PRD 文档 (支持 .md, .txt, .markdown)'\n );\n }\n\n ctx.prdFile = ctx.prdFiles[0];\n if (ctx.prdFiles.length > 1) {\n logger.info(`找到多个 PRD 文档,使用: ${ctx.prdFile}`);\n } else {\n logger.success(`找到 PRD 文档: ${ctx.prdFile}`);\n }\n },\n },\n {\n title: '扫描截图文件',\n task: async (ctx) => {\n const screenshotDir = path.join(prdFolder, 'screenshots');\n const dirExists = await FileUtils.exists(screenshotDir);\n\n if (!dirExists) {\n logger.info('未找到 screenshots 目录,跳过截图');\n ctx.screenshots = [];\n return;\n }\n\n const imageExtensions = ['png', 'jpg', 'jpeg', 'gif', 'webp'];\n ctx.screenshots = [];\n\n for (const ext of imageExtensions) {\n const files = await FileUtils.findFiles(`*.${ext}`, screenshotDir);\n ctx.screenshots.push(...files.map((f) => path.join(screenshotDir, f)));\n }\n\n logger.success(`找到 ${ctx.screenshots.length} 个截图文件`);\n },\n },\n {\n title: '扫描 demo 代码仓库',\n task: async (ctx) => {\n const entries = await FileUtils.findFiles('*/', prdFolder);\n ctx.demoRepos = [];\n\n for (const entry of entries) {\n const dirPath = path.join(prdFolder, entry);\n const gitDir = path.join(dirPath, '.git');\n const hasGit = await FileUtils.exists(gitDir);\n if (hasGit) {\n ctx.demoRepos.push(dirPath);\n }\n }\n\n if (ctx.demoRepos.length > 0) {\n logger.success(`找到 demo 仓库: ${ctx.demoRepos.join(', ')}`);\n } else {\n logger.info('未找到 demo 代码仓库,跳过');\n }\n },\n },\n {\n title: '读取 PRD 内容',\n task: async (ctx) => {\n ctx.prdContent = await FileUtils.read(ctx.prdFile);\n },\n },\n {\n title: '调用 Claude 拆分 PRD',\n task: async (ctx) => {\n const prompt = buildSplitPrdPrompt(\n ctx.prdContent,\n ctx.screenshots,\n ctx.demoRepos\n );\n\n logger.newLine();\n logger.separator('─', 60);\n logger.info('Claude 执行中...');\n logger.separator('─', 60);\n logger.newLine();\n\n return await claudeAI.prompt(prompt, {\n contextFiles: ['TECH_STACK.md', 'CONVENTIONS.md'],\n });\n },\n },\n ]);\n\n const ctx = await tasks.run();\n\n logger.newLine();\n logger.separator('─', 60);\n logger.newLine();\n\n logger.header('PRD 拆分完成!');\n logger.success('Spec 文件已生成到 docs/specs/ 目录');\n logger.newLine();\n\n logger.info('下一步:');\n logger.step(\"1. 检查生成的 spec 文件\");\n logger.step(\"2. 运行 'team-cli breakdown <spec-file>' 拆分 milestones\");\n logger.step(\"3. 运行 'team-cli dev' 开始开发\");\n logger.newLine();\n } catch (error: any) {\n logger.error(`PRD 拆分失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 构建 PRD 拆分 prompt\n */\nfunction buildSplitPrdPrompt(\n prdContent: string,\n screenshots: string[],\n demoRepos: string[]\n): string {\n let prompt = `Role: Senior Product Manager and Technical Architect\n\nTask: Analyze the following PRD and split it into multiple independent feature specifications (specs).\n\nContext:\n- Read TECH_STACK.md for technology constraints\n- Read CONVENTIONS.md for coding standards\n- Each spec should be a standalone feature that can be developed independently\n\nPRD Content:\n\\`\\`\\`\n${prdContent}\n\\`\\`\\`\n`;\n\n // 添加截图信息\n if (screenshots.length > 0) {\n prompt += `\nScreenshots available (${screenshots.length} files):\n`;\n for (const screenshot of screenshots) {\n prompt += ` - ${screenshot}\\n`;\n }\n prompt += `You can use the Read tool to view these screenshots for visual reference.\n`;\n }\n\n // 添加 demo 仓库信息\n if (demoRepos.length > 0) {\n prompt += `\nDemo Code Repos available:\n`;\n for (const repo of demoRepos) {\n prompt += ` - ${repo}\\n`;\n }\n prompt += `You can explore these repos to understand existing implementation patterns.\n`;\n }\n\n prompt += `\nOutput Requirements:\n1. Split the PRD into multiple feature specs based on functionality\n2. Each spec should follow the template format (see docs/specs/template.md)\n3. Create each spec as a separate markdown file in docs/specs/\n4. Use kebab-case for filenames (e.g., user-authentication.md, data-export.md)\n5. Each spec must include:\n - Feature Overview (功能概述)\n - Background & Goals (背景与目标)\n - Functional Requirements (功能需求)\n - Technical Design (技术设计)\n - Acceptance Criteria (验收标准)\n\nSpec Format Template:\n\\`\\`\\`markdown\n# [功能标题]\n\n## 功能概述\n**功能名称**: [功能中文名]\n**优先级**: P0/P1/P2\n**预估工时**: X 天\n**状态**: 待拆分\n**创建日期**: ${new Date().toISOString().split('T')[0]}\n\n## 依赖关系\n**前置依赖**:\n- (列出依赖的其他 spec)\n\n**被依赖于**:\n- (自动生成)\n\n## 背景与目标\n[简明扼要地说明功能的背景和要解决的问题]\n\n## 功能需求\n\n### 用户故事\n\\`\\`\\`\n作为 [具体角色]\n我希望 [具体功能]\n以便 [实现的价值]\n\\`\\`\\`\n\n### 功能点\n列出 3-8 个主要功能点\n\n## 技术设计\n\n### API 设计\n列出主要的 API 端点\n\n### 数据模型\n列出需要的数据表\n\n## 验收标准\n- [ ] 验收标准 1\n- [ ] 验收标准 2\n- [ ] 验收标准 3\n\n----\n*生成于: ${new Date().toISOString()} by Claude*\n\\`\\`\\`\n\nIMPORTANT:\n- After generating all spec files, exit immediately without waiting for further input\n- Do not ask any questions\n- Each spec should be implementable in 1-3 days\n- Dependencies between features should be clearly noted in the 依赖关系 section\n`;\n\n return prompt;\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport path from 'path';\nimport { FileUtils, StringUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\n\n/**\n * Bugfix 命令 - 创建 Bugfix 记录\n */\nexport const bugfixCommand = new Command('bugfix')\n .description('创建 Bugfix 记录')\n .action(async () => {\n try {\n logger.header('创建 Bugfix 记录');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式收集 bug 信息\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'severity',\n message: 'Bug 严重程度:',\n choices: [\n { name: '高 - 阻塞功能或影响核心流程', value: '高' },\n { name: '中 - 影响功能但不阻塞', value: '中' },\n { name: '低 - 小问题或体验问题', value: '低' },\n ],\n default: '中',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Bug 描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'input',\n name: 'reproduction',\n message: '复现步骤:',\n default: '1. 步骤一\\n2. 步骤二\\n3. 步骤三',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['全部用户', '部分用户', '个别用户', '未知'],\n default: '部分用户',\n },\n ]);\n\n // 生成 bug ID\n const bugId = generateBugId();\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD');\n\n // 查找可能关联的 spec\n const relatedSpec = await findRelatedSpec(answers.description);\n\n // 创建 bugfix 文档\n const bugfixDir = 'docs/bugfixes';\n await FileUtils.ensureDir(bugfixDir);\n\n const bugfixFile = path.join(bugfixDir, `${timestamp}_${bugId}.md`);\n\n const content = formatBugfixDocument({\n id: bugId,\n severity: answers.severity,\n description: answers.description,\n reproduction: answers.reproduction,\n scope: answers.scope,\n relatedSpec,\n timestamp,\n });\n\n await FileUtils.write(bugfixFile, content);\n\n logger.success(`Bugfix 记录已创建: ${bugfixFile}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 分析 bug 根本原因');\n logger.step(\"2. 运行 'team-cli dev' 选择关联的 spec 进行修复\");\n logger.step('3. 修复后更新 bugfix 文档状态');\n logger.newLine();\n } catch (error: any) {\n logger.error(`创建 bugfix 失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Hotfix 命令 - 紧急修复\n */\nexport const hotfixCommand = new Command('hotfix')\n .description('紧急修复流程')\n .action(async () => {\n try {\n logger.header('紧急修复流程');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n logger.warn('注意: hotfix 用于紧急问题修复');\n logger.warn('修复后需要创建规范 bugfix 记录');\n logger.newLine();\n\n // 交互式收集信息\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'description',\n message: '紧急问题描述:',\n validate: (input: string) => input.trim().length > 0 || '描述不能为空',\n },\n {\n type: 'list',\n name: 'scope',\n message: '影响范围:',\n choices: ['所有用户', '部分用户', '特定用户'],\n default: '所有用户',\n },\n {\n type: 'input',\n name: 'solution',\n message: '临时解决方案:',\n validate: (input: string) => input.trim().length > 0 || '方案不能为空',\n },\n ]);\n\n // 生成 hotfix ID\n const hotfixId = generateHotfixId();\n const branchName = `hotfix/${hotfixId}`;\n\n // 创建 hotfix 分支并提交\n const tasks = new Listr([\n {\n title: '创建 hotfix 分支',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['checkout', '-b', branchName], { stdio: 'inherit' });\n },\n },\n {\n title: '创建 hotfix 记录',\n task: async () => {\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n const hotfixDir = 'docs/hotfixes';\n await FileUtils.ensureDir(hotfixDir);\n\n const hotfixFile = path.join(hotfixDir, `${timestamp}_${hotfixId}.md`);\n const content = formatHotfixDocument({\n id: hotfixId,\n description: answers.description,\n scope: answers.scope,\n solution: answers.solution,\n branch: branchName,\n timestamp,\n });\n\n await FileUtils.write(hotfixFile, content);\n },\n },\n {\n title: '创建初始 commit',\n task: async () => {\n const { execa } = await import('execa');\n await execa('git', ['add', 'docs/hotfixes'], { stdio: 'pipe' });\n await execa(\n 'git',\n [\n 'commit',\n '-m',\n `hotfix: ${answers.description}\\n\\nTemporary solution: ${answers.solution}`,\n ],\n { stdio: 'pipe' }\n );\n },\n },\n ]);\n\n await tasks.run();\n\n logger.newLine();\n logger.success(`Hotfix 分支已创建: ${branchName}`);\n logger.newLine();\n\n logger.info('下一步:');\n logger.step('1. 实施修复');\n logger.step(\"2. 运行 'team-cli lint' 检查代码\");\n logger.step('3. 提交并推送到远程');\n logger.step('4. 创建 PR 进行 code review');\n logger.step('5. 合并后创建规范 bugfix 记录');\n logger.newLine();\n } catch (error: any) {\n logger.error(`Hotfix 流程失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 生成 Bug ID\n */\nfunction generateBugId(): string {\n const date = new Date();\n const year = date.getFullYear();\n const month = String(date.getMonth() + 1).padStart(2, '0');\n const day = String(date.getDate()).padStart(2, '0');\n\n // 简单的序号生成(实际应该从已有文件中获取最大序号)\n return `BUG-${year}${month}${day}-001`;\n}\n\n/**\n * 生成 Hotfix ID\n */\nfunction generateHotfixId(): string {\n const date = new Date();\n const timestamp = date.getTime().toString().slice(-6);\n return `HF-${timestamp}`;\n}\n\n/**\n * 查找可能关联的 spec\n */\nasync function findRelatedSpec(description: string): Promise<string> {\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n return '';\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n return '';\n }\n\n // 简单的关键词匹配\n const keywords = extractKeywords(description);\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n\n for (const keyword of keywords) {\n if (content.toLowerCase().includes(keyword.toLowerCase())) {\n return file.replace('.md', '');\n }\n }\n }\n\n return '';\n}\n\n/**\n * 提取关键词\n */\nfunction extractKeywords(text: string): string[] {\n // 简单的分词和过滤\n const stopWords = ['的', '是', '在', '有', '和', '或', '了', '不', '吗', '呢'];\n const words = text\n .toLowerCase()\n .replace(/[^\\w\\s\\u4e00-\\u9fa5]/g, '')\n .split(/\\s+/)\n .filter((w) => w.length > 1 && !stopWords.includes(w));\n\n return words.slice(0, 5);\n}\n\n/**\n * 格式化 bugfix 文档\n */\nfunction formatBugfixDocument(data: {\n id: string;\n severity: string;\n description: string;\n reproduction: string;\n scope: string;\n relatedSpec: string;\n timestamp: string;\n}): string {\n return `# Bugfix: ${data.description}\n\n## Bug 信息\n- **ID**: ${data.id}\n- **严重程度**: ${data.severity}\n- **状态**: 待修复\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 复现步骤\n${data.reproduction}\n\n## 影响范围\n${data.scope}\n\n## 关联 Spec\n${data.relatedSpec ? `- ${data.relatedSpec}` : '- (无)'}\n\n## 修复方案\n- [ ] 分析根本原因\n- [ ] 设计修复方案\n- [ ] 实施修复\n- [ ] 编写测试\n- [ ] 验证修复\n\n## 验证清单\n- [ ] 本地测试通过\n- [ ] 单元测试覆盖\n- [ ] 回归测试通过\n- [ ] 更新相关文档\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n\n/**\n * 格式化 hotfix 文档\n */\nfunction formatHotfixDocument(data: {\n id: string;\n description: string;\n scope: string;\n solution: string;\n branch: string;\n timestamp: string;\n}): string {\n return `# Hotfix: ${data.description}\n\n## Hotfix 信息\n- **ID**: ${data.id}\n- **创建时间**: ${data.timestamp}\n\n## 问题描述\n${data.description}\n\n## 影响范围\n${data.scope}\n\n## 临时解决方案\n${data.solution}\n\n## 修复分支\n\\`\\`\\`\ngit checkout ${data.branch}\n\\`\\`\\`\n\n## 后续步骤\n- [ ] 实施紧急修复\n- [ ] 推送到远程\n- [ ] 创建 PR 进行 code review\n- [ ] 紧急合并到主分支\n- [ ] 创建规范 bugfix 记录\n- [ ] 计划彻底修复方案\n\n---\n*创建于: ${data.timestamp} by team-cli*\n`;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { Listr } from 'listr2';\nimport { execa } from 'execa';\n\n/**\n * Lint 命令 - 代码质量检查\n */\nexport const lintCommand = new Command('lint')\n .option('--fix', '自动修复问题')\n .description('代码质量检查 (前端 + 后端)')\n .action(async (options) => {\n try {\n logger.header('代码质量检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const results = {\n frontend: { exists: false, passed: false, errors: [] },\n backend: { exists: false, passed: false, errors: [] },\n };\n\n // 检查前端\n const frontendExists = await FileUtils.exists('frontend/package.json');\n if (frontendExists) {\n results.frontend.exists = true;\n try {\n logger.step('检查前端代码...');\n\n // ESLint 检查\n if (options.fix) {\n await execa('npm', ['run', 'lint', '--', '--fix'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n } else {\n await execa('npm', ['run', 'lint'], {\n cwd: 'frontend',\n stdio: 'inherit',\n });\n }\n\n // TypeScript 类型检查\n await execa('npx', ['tsc', '--noEmit'], {\n cwd: 'frontend',\n stdio: 'pipe',\n });\n\n results.frontend.passed = true;\n logger.success('前端代码检查通过');\n } catch (error: any) {\n results.frontend.errors.push(error.message);\n logger.error('前端代码检查失败');\n }\n } else {\n logger.info('未找到前端项目 (frontend/package.json)');\n }\n\n logger.newLine();\n\n // 检查后端\n const backendExists = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/pom.xml');\n if (backendExists) {\n results.backend.exists = true;\n\n // 检查构建工具\n const hasGradle = await FileUtils.exists('backend/build.gradle') ||\n await FileUtils.exists('backend/build.gradle.kts');\n const hasMaven = await FileUtils.exists('backend/pom.xml');\n\n try {\n logger.step('检查后端代码...');\n\n if (hasGradle) {\n // Gradle 构建\n if (options.fix) {\n await execa('./gradlew', ['spotlessApply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./gradlew', ['checkstyleMain', 'compileJava'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n } else if (hasMaven) {\n // Maven 构建\n if (options.fix) {\n await execa('./mvnw', ['spotless:apply'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n await execa('./mvnw', ['checkstyle:check', 'compile'], {\n cwd: 'backend',\n stdio: 'inherit',\n });\n }\n\n results.backend.passed = true;\n logger.success('后端代码检查通过');\n } catch (error: any) {\n results.backend.errors.push(error.message);\n logger.error('后端代码检查失败');\n }\n } else {\n logger.info('未找到后端项目 (build.gradle 或 pom.xml)');\n }\n\n logger.newLine();\n logger.separator('=', 50);\n logger.newLine();\n\n // 汇总结果\n let hasErrors = false;\n\n if (results.frontend.exists) {\n if (results.frontend.passed) {\n logger.success('前端: ✓ 通过');\n } else {\n logger.error('前端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n if (results.backend.exists) {\n if (results.backend.passed) {\n logger.success('后端: ✓ 通过');\n } else {\n logger.error('后端: ✗ 失败');\n hasErrors = true;\n }\n }\n\n logger.newLine();\n\n if (hasErrors) {\n logger.error('代码检查失败');\n logger.info(\"运行 'team-cli lint --fix' 尝试自动修复\");\n process.exit(1);\n } else {\n logger.success('代码检查全部通过');\n }\n } catch (error: any) {\n logger.error(`代码检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, GitUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * Status 命令 - 查看项目状态\n */\nexport const statusCommand = new Command('status')\n .description('查看项目状态')\n .action(async () => {\n try {\n logger.header('项目状态');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 显示项目信息\n await displayProjectInfo();\n\n // 显示功能清单\n await displayFeatureInventory();\n\n // 显示 Git 状态\n await displayGitStatus();\n\n // 显示最近活动\n await displayRecentActivity();\n } catch (error: any) {\n logger.error(`获取状态失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示项目信息\n */\nasync function displayProjectInfo(): Promise<void> {\n logger.info('项目信息:');\n logger.newLine();\n\n // 读取项目名称\n if (await FileUtils.exists('AI_MEMORY.md')) {\n const content = await FileUtils.read('AI_MEMORY.md');\n const projectName = content.match(/项目名称.*[::]\\s*(.+)/);\n const currentPhase = content.match(/当前阶段.*[::]\\s*(.+)/);\n const lastUpdated = content.match(/最后更新.*[::]\\s*(.+)/);\n\n if (projectName) logger.step(`名称: ${projectName[1].trim()}`);\n if (currentPhase) logger.step(`阶段: ${currentPhase[1].trim()}`);\n if (lastUpdated) logger.step(`更新: ${lastUpdated[1].trim()}`);\n } else {\n logger.step('AI_MEMORY.md 不存在');\n }\n\n logger.newLine();\n}\n\n/**\n * 显示功能清单\n */\nasync function displayFeatureInventory(): Promise<void> {\n logger.info('功能清单:');\n logger.newLine();\n\n const specDir = 'docs/specs';\n const exists = await FileUtils.exists(specDir);\n\n if (!exists) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', specDir);\n const specs = files.filter((f) => !f.includes('template'));\n\n if (specs.length === 0) {\n logger.info(' (无 spec 文件)');\n logger.newLine();\n return;\n }\n\n // 解析每个 spec 的状态\n const inventory: Array<{\n name: string;\n status: string;\n progress: string;\n }> = [];\n\n for (const file of specs) {\n const filePath = path.join(specDir, file);\n const content = await FileUtils.read(filePath);\n const status = parseSpecStatus(content);\n\n inventory.push({\n name: file.replace('.md', ''),\n status,\n progress: getProgress(content),\n });\n }\n\n // 显示表格\n const tableData = inventory.map((item) => [\n item.name,\n item.status,\n item.progress,\n ]);\n\n logger.table(['功能', '状态', '进度'], tableData);\n logger.newLine();\n\n // 统计\n const completed = inventory.filter((i) => i.status === '已完成').length;\n const inProgress = inventory.filter((i) => i.status === '进行中').length;\n const pending = inventory.filter((i) => i.status === '未开始').length;\n\n logger.info(`总计: ${inventory.length} | 已完成: ${completed} | 进行中: ${inProgress} | 未开始: ${pending}`);\n logger.newLine();\n}\n\n/**\n * 显示 Git 状态\n */\nasync function displayGitStatus(): Promise<void> {\n const isRepo = await GitUtils.isGitRepo();\n\n if (!isRepo) {\n logger.info('Git 状态: 非 Git 仓库');\n logger.newLine();\n return;\n }\n\n try {\n const branch = await GitUtils.getCurrentBranch();\n const commit = await GitUtils.getCurrentCommit();\n\n logger.info('Git 状态:');\n logger.step(`分支: ${branch}`);\n logger.step(`提交: ${commit}`);\n logger.newLine();\n } catch {\n logger.info('Git 状态: 无法获取');\n logger.newLine();\n }\n}\n\n/**\n * 显示最近活动\n */\nasync function displayRecentActivity(): Promise<void> {\n logger.info('最近活动:');\n logger.newLine();\n\n // 检查会话日志\n const sessionDir = 'docs/sessions';\n const exists = await FileUtils.exists(sessionDir);\n\n if (!exists) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n const files = await FileUtils.findFiles('*.md', sessionDir);\n if (files.length === 0) {\n logger.info(' (无会话记录)');\n logger.newLine();\n return;\n }\n\n // 按时间排序,取最近 5 个\n const sorted = files.sort().reverse().slice(0, 5);\n\n for (const file of sorted) {\n const filePath = path.join(sessionDir, file);\n const stat = await FileUtils.read(filePath);\n const specMatch = stat.match(/\\*\\*Spec\\*\\*:\\s*(.+)/);\n const spec = specMatch ? specMatch[1].trim() : '未知';\n\n // 从文件名提取时间\n const match = file.match(/(\\d{4}-\\d{2}-\\d{2})/);\n const date = match ? match[1] : '未知';\n\n logger.step(`${date} - ${spec}`);\n }\n\n logger.newLine();\n\n if (files.length > 5) {\n logger.info(`(还有 ${files.length - 5} 个历史会话记录)`);\n logger.newLine();\n }\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): string {\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '✓ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n }\n return '○ 未开始';\n}\n\n/**\n * 获取进度\n */\nfunction getProgress(spec: string): string {\n // 解析里程碑和 todos\n const milestoneMatches = spec.match(/###\\s+Milestone\\s+\\d+:/g);\n const milestones = milestoneMatches ? milestoneMatches.length : 0;\n\n const todoMatches = spec.match(/-\\s+\\[[ x ]\\]/g);\n const totalTodos = todoMatches ? todoMatches.length : 0;\n\n const completedMatches = spec.match(/-\\s+\\[x\\]/g);\n const completedTodos = completedMatches ? completedMatches.length : 0;\n\n if (totalTodos === 0) {\n return '-';\n }\n\n return `${completedTodos}/${totalTodos}`;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Detect-deps 命令 - 检测依赖关系\n */\nexport const detectDepsCommand = new Command('detect-deps')\n .argument('[spec-file]', 'Spec 文件路径')\n .description('检测依赖关系')\n .action(async (specFile) => {\n try {\n logger.header('检测依赖关系');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 如果没有指定 spec,扫描所有 specs\n if (!specFile) {\n logger.info('未指定 spec 文件,将扫描所有 specs...');\n logger.newLine();\n\n const specsDir = 'docs/specs';\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n if (specs.length === 0) {\n logger.error('未找到 spec 文件');\n process.exit(1);\n }\n\n for (const spec of specs) {\n const specPath = path.join(specsDir, spec);\n logger.step(`处理: ${spec}`);\n await detectDependencies(specPath);\n logger.newLine();\n }\n } else {\n // 检查文件是否存在\n const exists = await FileUtils.exists(specFile);\n if (!exists) {\n logger.error(`Spec 文件不存在: ${specFile}`);\n process.exit(1);\n }\n\n await detectDependencies(specFile);\n }\n\n logger.header('依赖检测完成');\n } catch (error: any) {\n logger.error(`依赖检测失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测依赖关系\n */\nasync function detectDependencies(specFile: string): Promise<void> {\n logger.step('自动检测依赖关系...');\n\n const projectDir = '.';\n const allDeps = new Set<string>();\n\n // 1. 扫描后端依赖\n const backendDir = path.join(projectDir, 'backend');\n const backendExists = await FileUtils.exists(backendDir);\n\n if (backendExists) {\n // 扫描 API 调用\n const apiDeps = await scanBackendApiCalls(backendDir);\n apiDeps.forEach((d) => allDeps.add(d));\n\n // 扫描实体关联\n const entityDeps = await scanBackendEntityRelations(backendDir);\n entityDeps.forEach((d) => allDeps.add(d));\n\n // 扫描服务引用\n const serviceDeps = await scanBackendServiceRefs(backendDir);\n serviceDeps.forEach((d) => allDeps.add(d));\n }\n\n // 2. 扫描前端依赖\n const frontendDir = path.join(projectDir, 'frontend');\n const frontendExists = await FileUtils.exists(frontendDir);\n\n if (frontendExists) {\n const frontendDeps = await scanFrontendApiCalls(frontendDir);\n frontendDeps.forEach((d) => allDeps.add(d));\n }\n\n if (allDeps.size === 0) {\n logger.info('未检测到明确的依赖关系');\n return;\n }\n\n // 3. 匹配到对应的 spec 文件\n const detectedSpecs: string[] = [];\n for (const dep of allDeps) {\n const matchedSpec = await findSpecByKeyword(dep, 'docs/specs');\n if (matchedSpec && !detectedSpecs.includes(matchedSpec)) {\n detectedSpecs.push(matchedSpec);\n }\n }\n\n if (detectedSpecs.length === 0) {\n logger.info('检测到依赖,但未找到对应的 spec 文件');\n return;\n }\n\n // 4. 输出检测结果\n logger.success(`检测到 ${detectedSpecs.length} 个潜在依赖:`);\n for (const spec of detectedSpecs) {\n logger.step(`- ${spec}`);\n }\n logger.newLine();\n\n // 5. 询问是否自动更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'autoUpdate',\n message: '是否自动更新依赖关系到 spec 文件?',\n default: true,\n },\n ]);\n\n if (answers.autoUpdate) {\n await updateSpecDependencies(specFile, detectedSpecs);\n logger.success('依赖关系已更新');\n }\n}\n\n/**\n * 扫描后端 API 调用\n */\nasync function scanBackendApiCalls(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n // 查找 Java 文件中的 RestTemplate/WebClient/RestClient 调用\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n // 提取模块名 (如 /api/users -> users)\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]); // 'api' 后面的部分\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端实体关联\n */\nasync function scanBackendEntityRelations(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 @JoinColumn, @ManyToOne, @OneToMany\n if (\n content.includes('@JoinColumn') ||\n content.includes('@ManyToOne') ||\n content.includes('@OneToMany')\n ) {\n // 提取关联的实体类型\n const typeRegex = /type\\s*=\\s*(\\w+)/g;\n let match;\n while ((match = typeRegex.exec(content)) !== null) {\n deps.push(match[1].toLowerCase());\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描后端服务引用\n */\nasync function scanBackendServiceRefs(backendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(backendDir, 'src');\n\n try {\n const javaFiles = await FileUtils.findFiles('*.java', srcDir);\n\n for (const file of javaFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 Service 注入\n const serviceRegex = /private\\s+(\\w+)Service/g;\n let match;\n while ((match = serviceRegex.exec(content)) !== null) {\n const serviceName = match[1];\n // 提取模块名 (UserService -> user)\n const moduleName = serviceName.replace(/Service$/, '').toLowerCase();\n deps.push(moduleName);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 扫描前端 API 调用\n */\nasync function scanFrontendApiCalls(frontendDir: string): Promise<string[]> {\n const deps: string[] = [];\n const srcDir = path.join(frontendDir, 'src');\n\n try {\n // 查找 TypeScript/JavaScript 文件\n const tsFiles = await FileUtils.findFiles('*.{ts,tsx,js,jsx}', srcDir);\n\n for (const file of tsFiles) {\n const filePath = path.join(srcDir, file);\n const content = await FileUtils.read(filePath);\n\n // 查找 API 路径\n const pathRegex = /\"(\\/api\\/[^\"]+)\"/g;\n let match;\n while ((match = pathRegex.exec(content)) !== null) {\n const fullPath = match[1];\n const parts = fullPath.split('/').filter(Boolean);\n if (parts.length > 1) {\n deps.push(parts[1]);\n }\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return deps;\n}\n\n/**\n * 根据关键词查找 spec\n */\nasync function findSpecByKeyword(\n keyword: string,\n specsDir: string\n): Promise<string | null> {\n const exists = await FileUtils.exists(specsDir);\n if (!exists) {\n return null;\n }\n\n try {\n const files = await FileUtils.findFiles('*.md', specsDir);\n\n for (const file of files) {\n if (file === 'template.md') continue;\n\n const name = file.replace('.md', '');\n // 模糊匹配\n if (name.includes(keyword) || keyword.includes(name)) {\n return name;\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return null;\n}\n\n/**\n * 更新 spec 的依赖关系\n */\nasync function updateSpecDependencies(\n specFile: string,\n deps: string[]\n): Promise<void> {\n let content = await FileUtils.read(specFile);\n\n // 检查是否有依赖关系部分\n if (!content.includes('## 依赖关系')) {\n // 在背景与目标前插入依赖关系部分\n const targetSection = '## 背景与目标';\n const insertIndex = content.indexOf(targetSection);\n\n if (insertIndex !== -1) {\n const depsSection = `\\n## 依赖关系\\n\\n**前置依赖**:\\n${deps.map((d) => ` - [x] ${d}`).join('\\n')}\\n\\n**被依赖于**:\\n - (自动生成,表示哪些 spec 依赖本功能)\\n\\n`;\n content =\n content.slice(0, insertIndex) + depsSection + content.slice(insertIndex);\n }\n } else {\n // 更新现有依赖关系\n const lines = content.split('\\n');\n let inDeps = false;\n const result: string[] = [];\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith('## 依赖关系')) {\n inDeps = true;\n result.push(line);\n result.push('');\n result.push('**前置依赖**:');\n for (const dep of deps) {\n result.push(` - [x] ${dep}`);\n }\n result.push('');\n result.push('**被依赖于**:');\n result.push(' - (自动生成,表示哪些 spec 依赖本功能)');\n continue;\n }\n\n if (inDeps) {\n // 跳过旧的前置依赖内容,直到遇到下一个章节\n if (line.startsWith('## ') && !line.startsWith('## 依赖关系')) {\n inDeps = false;\n result.push(line);\n }\n continue;\n }\n\n result.push(line);\n }\n\n content = result.join('\\n');\n }\n\n await FileUtils.write(specFile, content);\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport { readTemplateConfig } from '../lib/template-version.js';\n\n/**\n * Sync-memory 命令 - 同步 AI_MEMORY.md\n */\nexport const syncMemoryCommand = new Command('sync-memory')\n .description('同步 AI_MEMORY.md')\n .action(async () => {\n try {\n logger.header('同步 AI_MEMORY.md');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const aiMemoryFile = 'AI_MEMORY.md';\n const exists = await FileUtils.exists(aiMemoryFile);\n\n if (!exists) {\n logger.info('AI_MEMORY.md 不存在,跳过同步');\n process.exit(0);\n }\n\n // 1. 同步功能清单\n await syncFeatureInventory(aiMemoryFile, '.');\n\n // 2. 同步 API 列表\n await syncApiInventory(aiMemoryFile, '.');\n\n // 3. 同步数据模型\n await syncDataModels(aiMemoryFile, '.');\n\n // 4. 同步模板版本信息\n await syncTemplateVersions(aiMemoryFile, '.');\n\n // 5. 更新最后同步时间\n await updateSyncTime(aiMemoryFile);\n\n logger.success('AI_MEMORY.md 已同步');\n } catch (error: any) {\n logger.error(`同步失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 同步功能清单\n */\nasync function syncFeatureInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步功能清单...');\n\n const specsDir = path.join(projectDir, 'docs/specs');\n const exists = await FileUtils.exists(specsDir);\n\n if (!exists) {\n return;\n }\n\n // 读取所有 specs\n const files = await FileUtils.findFiles('*.md', specsDir);\n const specs = files.filter((f) => f !== 'template.md');\n\n // 构建功能清单表格\n const lines: string[] = [];\n lines.push('## 功能清单 (Feature Inventory)');\n lines.push('');\n lines.push('| 功能 | Spec 文件 | 状态 | 进度 | 完成日期 | 备注 |');\n lines.push('|------|----------|------|------|---------|------|');\n\n for (const specFile of specs) {\n const name = specFile.replace('.md', '');\n const displayName = name\n .split('-')\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n\n const specPath = path.join(specsDir, specFile);\n const content = await FileUtils.read(specPath);\n\n // 获取状态\n const status = parseSpecStatus(content);\n\n // 获取进度\n const progress = getSpecProgress(content);\n\n // 获取完成日期\n let completionDate = '-';\n if (status === '✅ 已完成') {\n const dateMatch = content.match(/完成日期.*[::]\\s*(.+)/);\n if (dateMatch) {\n completionDate = dateMatch[1].trim();\n }\n }\n\n lines.push(`| ${displayName} | ${name}.md | ${status} | ${progress} | ${completionDate} | |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 功能清单', newContent);\n}\n\n/**\n * 同步 API 列表\n */\nasync function syncApiInventory(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步 API 列表...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## API 列表 (API Inventory)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Controller 生成');\n lines.push('');\n\n // 查找所有 Controller\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n if (controllers.length === 0) {\n lines.push('暂无 API');\n } else {\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n lines.push(`### ${module} 模块`);\n lines.push('');\n lines.push('| 方法 | 路径 | 说明 | 状态 | 日期 |');\n lines.push('|------|------|------|------|------|');\n\n // 扫描 API\n const apis = await scanControllerApis(controllerPath);\n for (const api of apis) {\n lines.push(`| ${api.method} | ${api.path} | ${api.description} | ✅ | ${api.date} |`);\n }\n lines.push('');\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## API 列表', newContent);\n}\n\n/**\n * 扫描 Controller 中的 API\n */\nasync function scanControllerApis(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string; date: string }>> {\n const apis: Array<{ method: string; path: string; description: string; date: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n date: DateUtils.format(new Date(), 'YYYY-MM-DD'),\n });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n // 查找方法定义前的注释\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n // 向前查找注释\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n\n/**\n * 同步数据模型\n */\nasync function syncDataModels(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步数据模型...');\n\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 数据模型 (Data Models)');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动扫描后端 Entity 生成');\n lines.push('');\n\n // 查找所有 Entity\n const srcDir = path.join(backendDir, 'src');\n const entities = await FileUtils.findFiles('*Entity.java', srcDir);\n\n if (entities.length === 0) {\n lines.push('暂无数据模型');\n } else {\n lines.push('| 模型 | 说明 | 字段 | 关联 |');\n lines.push('|------|------|------|------|');\n\n for (const entityFile of entities) {\n const entityPath = path.join(srcDir, entityFile);\n const entityName = entityFile.replace('.java', '').replace(/Entity$/, '');\n const displayName = entityName\n .split(/(?=[A-Z])/)\n .map((word) => word.charAt(0).toUpperCase() + word.slice(1).toLowerCase())\n .join(' ');\n\n // 读取实体内容\n const content = await FileUtils.read(entityPath);\n\n // 提取注释\n const classCommentMatch = content.match(/\\/\\*\\*\\s*\\n([^*]|\\*[^/])*\\*\\//);\n const description = classCommentMatch\n ? classCommentMatch[0].replace(/\\/\\*\\*|\\*\\/|\\*/g, '').trim()\n : '';\n\n // 计算字段数\n const fieldCount = (content.match(/private\\s+\\w+/g) || []).length;\n\n // 检查关联\n const relations: string[] = [];\n if (content.includes('@ManyToOne')) relations.push('Many-to-One');\n if (content.includes('@OneToMany')) relations.push('One-to-Many');\n if (content.includes('@OneToOne')) relations.push('One-to-One');\n if (content.includes('@ManyToMany')) relations.push('Many-to-Many');\n\n lines.push(`| ${displayName} | ${description} | ${fieldCount} | ${relations.join(', ') || '-'} |`);\n }\n }\n\n const newContent = lines.join('\\n');\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 数据模型', newContent);\n}\n\n/**\n * 更新同步时间\n */\nasync function updateSyncTime(aiMemoryFile: string): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n const timestamp = DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss');\n\n let updated = content;\n\n // 查找并更新最后同步时间\n if (content.includes('最后同步')) {\n updated = content.replace(\n /最后同步.*[::]\\s*.+/,\n `最后同步: ${timestamp}`\n );\n } else {\n // 在文件末尾添加\n updated = content.trimEnd() + `\\n\\n---\\n\\n*最后同步: ${timestamp} by team-cli*\\n`;\n }\n\n await FileUtils.write(aiMemoryFile, updated);\n}\n\n/**\n * 替换或插入章节\n */\nasync function replaceOrInsertSection(\n aiMemoryFile: string,\n sectionTitle: string,\n newContent: string\n): Promise<void> {\n const content = await FileUtils.read(aiMemoryFile);\n\n // 检查是否存在该章节\n if (content.includes(sectionTitle)) {\n // 替换现有章节\n const lines = content.split('\\n');\n const result: string[] = [];\n let inSection = false;\n let skip = false;\n\n for (let i = 0; i < lines.length; i++) {\n const line = lines[i];\n\n if (line.startsWith(sectionTitle)) {\n inSection = true;\n result.push(newContent);\n skip = true;\n continue;\n }\n\n if (inSection) {\n if (line.startsWith('## ') && !line.startsWith(sectionTitle)) {\n inSection = false;\n skip = false;\n result.push(line);\n }\n continue;\n }\n\n if (!skip) {\n result.push(line);\n }\n }\n\n await FileUtils.write(aiMemoryFile, result.join('\\n'));\n } else {\n // 插入新章节\n await FileUtils.write(aiMemoryFile, content.trimEnd() + '\\n\\n' + newContent + '\\n');\n }\n}\n\n/**\n * 解析 spec 状态\n */\nfunction parseSpecStatus(spec: string): string {\n const statusMatch = spec.match(/状态.*[::]\\s*(.+)/);\n if (statusMatch) {\n const status = statusMatch[1].replace(/\\*\\*/g, '').trim();\n if (status.includes('已完成')) return '✅ 已完成';\n if (status.includes('进行中')) return '⟳ 进行中';\n if (status.includes('已拆分')) return '◉ 已拆分';\n }\n return '○ 未开始';\n}\n\n/**\n * 获取 spec 进度\n */\nfunction getSpecProgress(spec: string): string {\n const todoMatches = spec.match(/-\\s+\\[[ x ]\\]/g);\n const totalTodos = todoMatches ? todoMatches.length : 0;\n\n const completedMatches = spec.match(/-\\s+\\[x\\]/g);\n const completedTodos = completedMatches ? completedMatches.length : 0;\n\n if (totalTodos === 0) {\n return '-';\n }\n\n return `${completedTodos}/${totalTodos}`;\n}\n\n/**\n * 同步模板版本信息\n */\nasync function syncTemplateVersions(\n aiMemoryFile: string,\n projectDir: string\n): Promise<void> {\n logger.step('同步模板版本信息...');\n\n const config = await readTemplateConfig(projectDir);\n\n if (!config) {\n return;\n }\n\n const lines: string[] = [];\n lines.push('## 模板版本信息');\n lines.push('');\n lines.push('> 本部分由 team-cli 自动管理,记录使用的前后端模板版本');\n lines.push('');\n lines.push('| 类型 | 仓库 | Tag | Branch | Commit | 更新时间 |');\n lines.push('|------|------|-----|--------|--------|----------|');\n\n // 前端模板\n if (config.frontend) {\n const repoName = extractRepoName(config.frontend.repository);\n const commit = config.frontend.commit?.substring(0, 8) || '-';\n const tag = config.frontend.tag || '-';\n const branch = config.frontend.branch || '-';\n const updateDate = config.frontend.lastUpdate\n ? new Date(config.frontend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 前端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n // 后端模板\n if (config.backend) {\n const repoName = extractRepoName(config.backend.repository);\n const commit = config.backend.commit?.substring(0, 8) || '-';\n const tag = config.backend.tag || '-';\n const branch = config.backend.branch || '-';\n const updateDate = config.backend.lastUpdate\n ? new Date(config.backend.lastUpdate).toLocaleDateString('zh-CN')\n : '-';\n\n lines.push(`| 后端 | ${repoName} | ${tag} | ${branch} | ${commit} | ${updateDate} |`);\n }\n\n const newContent = lines.join('\\n') + '\\n';\n\n // 替换或插入到 AI_MEMORY.md\n await replaceOrInsertSection(aiMemoryFile, '## 模板版本信息', newContent);\n}\n\n/**\n * 从仓库 URL 中提取仓库名\n */\nfunction extractRepoName(repository: string): string {\n // 支持的格式:\n // - git@gitlab.com:group/project.git\n // - https://gitlab.com/group/project.git\n\n let path = repository;\n\n // 移除协议前缀\n path = path.replace(/^https?:\\/\\//, '');\n path = path.replace(/^git@/, '');\n\n // 移除域名部分\n const parts = path.split('/');\n if (parts.length > 1) {\n path = parts.slice(1).join('/');\n }\n\n // 移除 .git 后缀\n path = path.replace(/\\.git$/, '');\n\n return path;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils, DateUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\n\n/**\n * Check-api 命令 - API 检查\n */\nexport const checkApiCommand = new Command('check-api')\n .description('API 检查(冲突/变更/Registry)')\n .action(async () => {\n try {\n logger.header('API 检查');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n // 交互式选择\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'checkType',\n message: '选择检查类型:',\n choices: [\n { name: '检测 API 冲突', value: 'conflicts' },\n { name: '检测 API 变更', value: 'changes' },\n { name: '生成 API Registry', value: 'registry' },\n { name: '全部执行', value: 'all' },\n ],\n default: 'all',\n },\n ]);\n\n const tasks = new Listr([]);\n\n // 根据选择添加任务\n if (answers.checkType === 'conflicts' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 冲突',\n task: async () => {\n await checkApiConflicts('.');\n },\n });\n }\n\n if (answers.checkType === 'changes' || answers.checkType === 'all') {\n tasks.add({\n title: '检测 API 变更',\n task: async () => {\n await detectApiChanges('.');\n },\n });\n }\n\n if (answers.checkType === 'registry' || answers.checkType === 'all') {\n tasks.add({\n title: '生成 API Registry',\n task: async () => {\n await generateApiRegistry('.');\n },\n });\n }\n\n await tasks.run();\n\n logger.newLine();\n logger.header('API 检查完成');\n } catch (error: any) {\n logger.error(`API 检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 检测 API 冲突\n */\nasync function checkApiConflicts(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (!exists) {\n logger.info('未找到后端项目');\n return;\n }\n\n logger.step('扫描后端 API...');\n logger.newLine();\n\n const apiMap = new Map<string, string[]>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 收集所有 API\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n if (!apiMap.has(key)) {\n apiMap.set(key, []);\n }\n apiMap.get(key)!.push(controllerFile);\n }\n }\n\n // 检查冲突\n const conflicts: Array<{ key: string; controllers: string[] }> = [];\n for (const [key, controllers] of apiMap.entries()) {\n if (controllers.length > 1) {\n conflicts.push({ key, controllers });\n }\n }\n\n if (conflicts.length === 0) {\n logger.success('未发现 API 冲突');\n } else {\n logger.error(`发现 ${conflicts.length} 个 API 冲突:`);\n logger.newLine();\n\n for (const conflict of conflicts) {\n logger.error(`冲突: ${conflict.key}`);\n for (const controller of conflict.controllers) {\n logger.step(` - ${controller}`);\n }\n logger.newLine();\n }\n }\n}\n\n/**\n * 检测 API 变更\n */\nasync function detectApiChanges(projectDir: string): Promise<void> {\n const backendDir = path.join(projectDir, 'backend');\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n const registryExists = await FileUtils.exists(registryFile);\n\n if (!registryExists) {\n logger.info('API Registry 不存在,跳过变更检测');\n logger.info(\"运行 'team-cli check-api' 选择 '生成 API Registry'\");\n return;\n }\n\n logger.step('检测 API 变更...');\n logger.newLine();\n\n // 读取现有 Registry\n const registryContent = await FileUtils.read(registryFile);\n const existingApis = extractApisFromRegistry(registryContent);\n\n // 扫描当前 API\n const currentApis = new Map<string, { method: string; path: string; description: string }>();\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const apis = await extractApisFromController(controllerPath);\n\n for (const api of apis) {\n const key = `${api.method}:${api.path}`;\n currentApis.set(key, api);\n }\n }\n\n // 比较差异\n const added: Array<{ method: string; path: string }> = [];\n const removed: Array<{ method: string; path: string }> = [];\n const modified: Array<{ method: string; path: string; oldDesc: string; newDesc: string }> = [];\n\n for (const [key, api] of currentApis.entries()) {\n if (!existingApis.has(key)) {\n added.push({ method: api.method, path: api.path });\n } else {\n const existingApi = existingApis.get(key)!;\n if (existingApi.description !== api.description) {\n modified.push({\n method: api.method,\n path: api.path,\n oldDesc: existingApi.description,\n newDesc: api.description,\n });\n }\n }\n }\n\n for (const [key, api] of existingApis.entries()) {\n if (!currentApis.has(key)) {\n removed.push({ method: api.method, path: api.path });\n }\n }\n\n // 输出结果\n let hasChanges = false;\n\n if (added.length > 0) {\n hasChanges = true;\n logger.success(`新增 API (${added.length}):`);\n for (const api of added) {\n logger.step(` + ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (removed.length > 0) {\n hasChanges = true;\n logger.error(`删除 API (${removed.length}):`);\n for (const api of removed) {\n logger.step(` - ${api.method} ${api.path}`);\n }\n logger.newLine();\n }\n\n if (modified.length > 0) {\n hasChanges = true;\n logger.warn(`修改 API (${modified.length}):`);\n for (const api of modified) {\n logger.step(` ~ ${api.method} ${api.path}`);\n logger.step(` 旧: ${api.oldDesc}`);\n logger.step(` 新: ${api.newDesc}`);\n }\n logger.newLine();\n }\n\n if (!hasChanges) {\n logger.success('未检测到 API 变更');\n }\n}\n\n/**\n * 生成 API Registry\n */\nasync function generateApiRegistry(projectDir: string): Promise<void> {\n const registryFile = path.join(projectDir, 'docs/api-registry.md');\n\n logger.step('扫描并生成 API Registry...');\n\n // 创建 docs 目录\n await FileUtils.ensureDir(path.dirname(registryFile));\n\n // 写入文件头\n const header = `# API Registry\n\n> 本文件记录所有 API 的定义、版本和变更历史\n\n## API 规范\n\n### 基础信息\n- **Base URL**: \\`/api\\`\n- **认证方式**: JWT Bearer Token\n- **数据格式**: JSON\n- **字符编码**: UTF-8\n\n### 响应码规范\n| 状态码 | 说明 |\n|--------|------|\n| 200 | 成功 |\n| 201 | 创建成功 |\n| 400 | 请求参数错误 |\n| 401 | 未认证 |\n| 403 | 无权限 |\n| 404 | 资源不存在 |\n| 500 | 服务器错误 |\n\n---\n\n*最后更新: ${DateUtils.format(new Date(), 'YYYY-MM-DD HH:mm:ss')}*\n`;\n\n // 扫描 Controller 并生成 API 文档\n let content = header;\n const backendDir = path.join(projectDir, 'backend');\n const exists = await FileUtils.exists(backendDir);\n\n if (exists) {\n const srcDir = path.join(backendDir, 'src');\n const controllers = await FileUtils.findFiles('*Controller.java', srcDir);\n\n // 按模块分组\n const moduleMap = new Map<string, Array<{ method: string; path: string; description: string }>>();\n\n for (const controllerFile of controllers) {\n const controllerPath = path.join(srcDir, controllerFile);\n const controllerName = controllerFile.replace('.java', '');\n const module = controllerName.replace(/Controller$/, '').toLowerCase();\n\n if (!moduleMap.has(module)) {\n moduleMap.set(module, []);\n }\n\n const apis = await extractApisFromController(controllerPath);\n moduleMap.get(module)!.push(...apis);\n }\n\n // 生成文档\n for (const [module, apis] of moduleMap.entries()) {\n content += `\\n## ${module.charAt(0).toUpperCase() + module.slice(1)} 模块\\n\\n`;\n\n for (const api of apis) {\n content += `### ${api.method} ${api.path}\\n\\n`;\n content += `**版本**: v1.0\\n\\n`;\n content += `**说明**: ${api.description || '-'}\\n\\n`;\n content += `---\\n\\n`;\n }\n }\n }\n\n await FileUtils.write(registryFile, content);\n\n logger.success(`API Registry 已生成: ${registryFile}`);\n}\n\n/**\n * 从 Controller 提取 API\n */\nasync function extractApisFromController(\n controllerPath: string\n): Promise<Array<{ method: string; path: string; description: string }>> {\n const apis: Array<{ method: string; path: string; description: string }> = [];\n const content = await FileUtils.read(controllerPath);\n\n // 提取类级别的 @RequestMapping\n let classPath = '';\n const classRequestMappingMatch = content.match(/@RequestMapping\\(\"([^\"]+)\"\\)/);\n if (classRequestMappingMatch) {\n classPath = classRequestMappingMatch[1];\n }\n\n // 扫描方法级别的映射\n const methodRegex =\n /@(GetMapping|PostMapping|PutMapping|DeleteMapping|PatchMapping)\\(\"([^\"]+)\"\\)\\s*\\n\\s*public\\s+(\\w+)\\s*\\(([^)]*)\\)/g;\n let match;\n\n while ((match = methodRegex.exec(content)) !== null) {\n const mappingType = match[1];\n const methodPath = match[2];\n const methodName = match[3];\n\n // 确定 HTTP 方法\n let httpMethod = '';\n switch (mappingType) {\n case 'GetMapping':\n httpMethod = 'GET';\n break;\n case 'PostMapping':\n httpMethod = 'POST';\n break;\n case 'PutMapping':\n httpMethod = 'PUT';\n break;\n case 'DeleteMapping':\n httpMethod = 'DELETE';\n break;\n case 'PatchMapping':\n httpMethod = 'PATCH';\n break;\n }\n\n // 组合完整路径\n let fullPath = methodPath;\n if (classPath && !methodPath.startsWith('/api')) {\n fullPath = `${classPath}${methodPath}`;\n }\n\n // 提取方法注释\n const description = extractMethodComment(content, methodName);\n\n apis.push({\n method: httpMethod,\n path: fullPath,\n description,\n });\n }\n\n return apis;\n}\n\n/**\n * 从 Registry 提取 API\n */\nfunction extractApisFromRegistry(\n registryContent: string\n): Map<string, { method: string; path: string; description: string }> {\n const apis = new Map<string, { method: string; path: string; description: string }>();\n\n // 匹配 API 条目\n const apiRegex = /### (GET|POST|PUT|DELETE|PATCH) ([^\\n]+)\\n\\n\\*\\*版本\\*\\*:.+?\\n\\n\\*\\*说明\\*\\*:\\s*([^\\n-]+)/g;\n let match;\n\n while ((match = apiRegex.exec(registryContent)) !== null) {\n const method = match[1];\n const path = match[2].trim();\n const description = match[3].trim();\n const key = `${method}:${path}`;\n apis.set(key, { method, path, description });\n }\n\n return apis;\n}\n\n/**\n * 提取方法注释\n */\nfunction extractMethodComment(content: string, methodName: string): string {\n const methodIndex = content.indexOf(`${methodName}(`);\n if (methodIndex === -1) {\n return '';\n }\n\n const beforeMethod = content.substring(Math.max(0, methodIndex - 500), methodIndex);\n const commentMatch = beforeMethod.match(/\\*\\s*([^\\n*]+)/g);\n\n if (commentMatch && commentMatch.length > 0) {\n return commentMatch[0].replace(/\\*\\s?/, '').trim();\n }\n\n return '';\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport { FileUtils } from '../lib/utils.js';\nimport { logger } from '../lib/logger.js';\nimport inquirer from 'inquirer';\n\n/**\n * Logs 命令 - 查看会话日志\n */\nexport const logsCommand = new Command('logs')\n .argument('[filter]', '过滤器 (today, --all, 或日期 YYYY-MM-DD)')\n .description('查看会话日志')\n .action(async (filter = 'today') => {\n try {\n logger.header('会话日志');\n logger.newLine();\n\n // 上下文检查\n const hasTechStack = await FileUtils.exists('TECH_STACK.md');\n if (!hasTechStack) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先运行 'team-cli init <project-name>' 或切换到项目目录\");\n process.exit(1);\n }\n\n const sessionsDir = 'docs/sessions';\n const dirExists = await FileUtils.exists(sessionsDir);\n\n if (!dirExists) {\n logger.info('暂无会话日志');\n logger.info(\"运行 'team-cli dev' 后会自动生成日志\");\n process.exit(0);\n }\n\n // 确定目标目录\n let targetDir = '';\n let displayTitle = '';\n\n switch (filter) {\n case '':\n case 'today': {\n const today = new Date().toISOString().split('T')[0];\n targetDir = path.join(sessionsDir, today);\n const todayExists = await FileUtils.exists(targetDir);\n if (!todayExists) {\n logger.info('今日暂无会话日志');\n process.exit(0);\n }\n displayTitle = '显示今日会话日志:';\n break;\n }\n case '--all':\n case '-a': {\n targetDir = sessionsDir;\n displayTitle = '显示所有会话日志:';\n break;\n }\n default: {\n // 假设是日期格式\n targetDir = path.join(sessionsDir, filter);\n const dateExists = await FileUtils.exists(targetDir);\n if (!dateExists) {\n logger.error(`未找到日期 '${filter}' 的日志`);\n logger.info('可用日期:');\n\n // 列出可用日期\n const entries = await FileUtils.findFiles('*/', sessionsDir);\n const dates = entries.slice(0, 10);\n for (const date of dates) {\n logger.info(` ${date.replace('/', '')}`);\n }\n process.exit(1);\n }\n displayTitle = `显示 ${filter} 的会话日志:`;\n break;\n }\n }\n\n logger.info(displayTitle);\n logger.newLine();\n\n // 收集日志文件\n const logs = await collectLogFiles(targetDir);\n\n if (logs.length === 0) {\n logger.info('无日志文件');\n process.exit(0);\n }\n\n // 显示日志列表\n for (let i = 0; i < logs.length; i++) {\n const relPath = path.relative(sessionsDir, logs[i]);\n logger.step(`${i + 1}) ${relPath}`);\n }\n\n logger.newLine();\n\n // 询问选择\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'selection',\n message: '输入编号查看详情 (或 Enter 退出):',\n default: '',\n },\n ]);\n\n const selection = answers.selection.trim();\n\n if (selection === '') {\n process.exit(0);\n }\n\n const selectionNum = parseInt(selection, 10);\n\n if (isNaN(selectionNum) || selectionNum < 1 || selectionNum > logs.length) {\n logger.error('无效的选择');\n process.exit(1);\n }\n\n // 显示选中的日志\n const selectedLog = logs[selectionNum - 1];\n logger.newLine();\n logger.header('日志详情');\n logger.newLine();\n\n const content = await FileUtils.read(selectedLog);\n console.log(content);\n } catch (error: any) {\n logger.error(`查看日志失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 收集日志文件\n */\nasync function collectLogFiles(targetDir: string): Promise<string[]> {\n const logs: string[] = [];\n\n try {\n // 查找所有 markdown 文件,排除 index.md\n const allFiles = await FileUtils.findFiles('*.md', targetDir);\n const filtered = allFiles.filter((f) => f !== 'index.md');\n\n for (const file of filtered) {\n const filePath = path.join(targetDir, file);\n // 确保是文件而不是目录\n const stat = await FileUtils.exists(filePath);\n if (stat) {\n logs.push(filePath);\n }\n }\n } catch (error) {\n // 忽略错误\n }\n\n return logs;\n}\n","import { Command } from 'commander';\nimport path from 'path';\nimport {\n checkTemplateUpdate,\n updateTemplateVersion,\n readTemplateConfig,\n type TemplateType,\n} from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { execa } from 'execa';\nimport inquirer from 'inquirer';\nimport { Listr } from 'listr2';\nimport fs from 'fs-extra';\n\n/**\n * Update 命令选项接口\n */\ninterface UpdateOptions {\n tag?: string;\n branch?: string;\n dryRun?: boolean;\n}\n\n/**\n * Update 命令 - 检查并更新模板版本\n */\nexport const updateCommand = new Command('update')\n .description('检查并更新模板版本')\n .option('-f, --frontend', '检查前端模板更新')\n .option('-b, --backend', '检查后端模板更新')\n .option('-a, --all', '检查所有模板 (默认)')\n .option('-t, --tag <tag>', '更新到指定标签')\n .option('-B, --branch <branch>', '更新到指定分支')\n .option('--dry-run', '预览更新,不实际执行')\n .action(async (options) => {\n try {\n logger.header('模板版本检查');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n // 如果指定了 tag 或 branch,则强制更新到指定版本\n const forceUpdate = options.tag || options.branch;\n\n const updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }> = [];\n const updateOptions: UpdateOptions = {\n tag: options.tag,\n branch: options.branch,\n dryRun: options.dryRun,\n };\n\n // 检查前端模板\n if (checkFrontend) {\n logger.step('检查前端模板...');\n const frontendInfo = await checkTemplateUpdate(projectPath, 'frontend');\n\n if (frontendInfo) {\n if (frontendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || frontendInfo.latestTag || frontendInfo.latestCommit?.substring(0, 8);\n logger.success(`前端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'frontend', info: frontendInfo, updateOptions });\n } else {\n logger.info('前端模板已是最新版本');\n }\n } else {\n logger.info('前端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 检查后端模板\n if (checkBackend) {\n logger.step('检查后端模板...');\n const backendInfo = await checkTemplateUpdate(projectPath, 'backend');\n\n if (backendInfo) {\n if (backendInfo.needsUpdate || forceUpdate) {\n const version = updateOptions.tag || updateOptions.branch || backendInfo.latestTag || backendInfo.latestCommit?.substring(0, 8);\n logger.success(`后端模板${forceUpdate ? '将更新' : '有更新'} (${version})`);\n updates.push({ type: 'backend', info: backendInfo, updateOptions });\n } else {\n logger.info('后端模板已是最新版本');\n }\n } else {\n logger.info('后端模板未配置或无法检查');\n }\n logger.newLine();\n }\n\n // 显示总结\n if (updates.length === 0) {\n logger.success('所有模板已是最新版本!');\n return;\n }\n\n if (options.dryRun) {\n logger.header(`[Dry Run] 发现 ${updates.length} 个模板`);\n } else {\n logger.header(`发现 ${updates.length} 个模板更新`);\n }\n logger.newLine();\n\n for (const update of updates) {\n const version = update.updateOptions?.tag || update.updateOptions?.branch || update.info.latestTag || update.info.latestCommit?.substring(0, 8);\n logger.step(`${update.type === 'frontend' ? '前端' : '后端'}模板: ${version}`);\n }\n logger.newLine();\n\n // 如果是 dry-run 模式,直接显示信息并退出\n if (options.dryRun) {\n logger.info('Dry run 模式,不执行实际更新');\n return;\n }\n\n // 询问是否更新\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'shouldUpdate',\n message: '是否更新模板?',\n default: false,\n },\n ]);\n\n if (answers.shouldUpdate) {\n await performUpdate(projectPath, updates);\n } else {\n logger.info('已取消更新');\n }\n } catch (error: any) {\n logger.error(`更新检查失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 执行模板更新\n */\nasync function performUpdate(\n projectPath: string,\n updates: Array<{ type: TemplateType; info: any; updateOptions?: UpdateOptions }>\n): Promise<void> {\n logger.newLine();\n logger.info('开始更新模板...');\n\n for (const update of updates) {\n const { type, info, updateOptions } = update;\n const targetDir = type === 'frontend' ? 'frontend' : 'backend';\n const targetPath = path.join(projectPath, targetDir);\n\n logger.newLine();\n logger.step(`更新 ${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n // 如果指定了 tag 或 branch,先验证\n if (updateOptions?.tag || updateOptions?.branch) {\n const { userConfigManager } = await import('../lib/user-config.js');\n const { GitLabAPI } = await import('../lib/gitlab-api.js');\n\n const config = await userConfigManager.getGitLabConfig();\n if (config) {\n const gitlabAPI = new GitLabAPI(config);\n const projectPathEncoded = GitLabAPI.parseProjectPath(info.repository);\n\n if (updateOptions.tag) {\n const isValid = await gitlabAPI.validateTag(projectPathEncoded, updateOptions.tag);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板 tag \"${updateOptions.tag}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板 tag: ${updateOptions.tag}`);\n }\n\n if (updateOptions.branch) {\n const isValid = await gitlabAPI.validateBranch(projectPathEncoded, updateOptions.branch);\n if (!isValid) {\n logger.error(`${type === 'frontend' ? '前端' : '后端'}模板分支 \"${updateOptions.branch}\" 不存在`);\n continue;\n }\n logger.info(`使用 ${type === 'frontend' ? '前端' : '后端'}模板分支: ${updateOptions.branch}`);\n }\n } else {\n logger.warn('未配置 GitLab Token,跳过版本验证');\n }\n }\n\n // 确定要克隆的 ref\n const ref = updateOptions?.tag || updateOptions?.branch || 'HEAD';\n\n // 创建备份\n const backupDir = path.join(projectPath, `.backup-${Date.now()}`);\n await fs.copy(targetPath, path.join(backupDir, targetDir));\n logger.info(`已创建备份: ${backupDir}`);\n\n // Dry run 模式\n if (updateOptions?.dryRun) {\n logger.info('[Dry Run] 将会更新到以下版本:');\n logger.info(` Ref: ${ref}`);\n logger.info(` 仓库: ${info.repository}`);\n logger.info('备份已创建,跳过实际更新');\n continue;\n }\n\n try {\n // 克隆最新模板到临时目录\n const tempDir = path.join(projectPath, `.template-update-${Date.now()}`);\n\n await execa('git', ['clone', '--depth=1', '--branch', ref, info.repository, tempDir], {\n stdio: 'pipe',\n });\n\n // 获取最新 commit\n const { stdout: commit } = await execa('git', ['rev-parse', 'HEAD'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n\n // 获取最新 tag\n const { stdout: tags } = await execa('git', ['tag', '-l', '--sort=-v:refname'], {\n cwd: tempDir,\n stdio: 'pipe',\n });\n const latestTag = tags.split('\\n')[0] || undefined;\n\n // 删除旧内容(保留配置文件)\n const keepFiles = ['.env.local', 'package-lock.json', 'node_modules'];\n const currentFiles = await FileUtils.findFiles('*', targetPath);\n\n for (const file of currentFiles) {\n if (!keepFiles.includes(file)) {\n const filePath = path.join(targetPath, file);\n try {\n await fs.remove(filePath);\n } catch {\n // 忽略删除失败\n }\n }\n }\n\n // 复制新模板内容\n await fs.copy(tempDir, targetPath, {\n filter: (src) => !src.includes('.git'),\n });\n\n // 删除临时目录\n await fs.remove(tempDir);\n\n // 更新配置\n await updateTemplateVersion(projectPath, type, commit.trim(), {\n tag: updateOptions?.tag || latestTag,\n branch: updateOptions?.branch,\n });\n\n logger.success(`${type === 'frontend' ? '前端' : '后端'}模板更新完成!`);\n logger.info(`新版本: ${updateOptions?.tag || updateOptions?.branch || latestTag || commit.substring(0, 8)}`);\n logger.info(`备份位置: ${backupDir}`);\n } catch (error: any) {\n logger.error(`更新失败: ${error.message}`);\n logger.info('正在恢复备份...');\n\n // 恢复备份\n await fs.remove(targetPath);\n await fs.copy(path.join(backupDir, targetDir), targetPath);\n await fs.remove(backupDir);\n\n logger.info('已恢复到更新前的状态');\n }\n }\n\n logger.newLine();\n logger.header('模板更新完成!');\n logger.newLine();\n logger.info('下一步:');\n logger.step('1. 检查更新后的代码');\n logger.step('2. 运行 npm install 安装新依赖');\n logger.step('3. 测试应用是否正常运行');\n logger.step('4. 提交代码到 Git');\n logger.newLine();\n}\n","import { Command } from 'commander';\nimport inquirer from 'inquirer';\nimport chalk from 'chalk';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI } from '../lib/gitlab-api.js';\nimport { logger } from '../lib/logger.js';\n\n/**\n * 设置 GitLab Access Token\n */\nexport const setTokenCommand = new Command('set-token')\n .description('设置 GitLab Access Token')\n .option('-t, --token <token>', 'Access Token')\n .option('-u, --url <url>', 'GitLab Base URL', 'https://gitlab.com')\n .action(async (options) => {\n try {\n logger.header('GitLab Access Token 配置');\n logger.newLine();\n\n let { token, url } = options;\n\n // 如果没有提供 token,交互式输入\n if (!token) {\n const answers = await inquirer.prompt([\n {\n type: 'password',\n name: 'token',\n message: '请输入 GitLab Access Token:',\n mask: '*',\n validate: (input: string) => {\n if (!input || input.trim().length === 0) {\n return 'Token 不能为空';\n }\n return true;\n },\n },\n {\n type: 'input',\n name: 'url',\n message: '请输入 GitLab Base URL:',\n default: 'https://gitlab.com',\n validate: (input: string) => {\n try {\n new URL(input);\n return true;\n } catch {\n return '请输入有效的 URL';\n }\n },\n },\n ]);\n token = answers.token;\n url = answers.url;\n }\n\n // 验证 URL 格式\n try {\n new URL(url);\n } catch {\n logger.error('无效的 GitLab URL');\n process.exit(1);\n }\n\n // 移除 URL 末尾的斜杠\n url = url.replace(/\\/+$/, '');\n\n logger.info('验证 Token...');\n const gitlabAPI = new GitLabAPI({ accessToken: token, baseUrl: url });\n const isValid = await gitlabAPI.authenticate();\n\n if (!isValid) {\n logger.error('Token 验证失败,请检查:');\n logger.info('1. Token 是否正确');\n logger.info('2. Token 是否有 api 权限');\n logger.info('3. GitLab URL 是否正确');\n process.exit(1);\n }\n\n logger.success('Token 验证成功!');\n\n // 保存配置\n await userConfigManager.updateGitLabToken(token, url);\n logger.success('配置已保存!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(url)}`);\n logger.info(`配置文件: ${chalk.gray(userConfigManager.getConfigPath())}`);\n } catch (error: any) {\n logger.error(`配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 显示当前配置\n */\nexport const showConfigCommand = new Command('show')\n .description('显示当前配置')\n .action(async () => {\n try {\n logger.header('GitLab 配置');\n logger.newLine();\n\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n } else {\n const config = await userConfigManager.load();\n\n if (config?.gitlab) {\n const token = config.gitlab.accessToken;\n const maskedToken = token ? `${token.substring(0, 8)}${'*'.repeat(Math.min(16, token.length - 8))}` : '';\n\n logger.info(`GitLab URL: ${chalk.cyan(config.gitlab.baseUrl)}`);\n logger.info(`Access Token: ${chalk.yellow(maskedToken)}`);\n logger.info(`Timeout: ${chalk.gray(config.gitlab.timeout || 30000)}ms`);\n\n if (config.preferences) {\n logger.newLine();\n logger.info('偏好设置:');\n if (config.preferences.defaultBackendBranch) {\n logger.info(` 默认后端分支: ${chalk.cyan(config.preferences.defaultBackendBranch)}`);\n }\n if (config.preferences.defaultFrontendBranch) {\n logger.info(` 默认前端分支: ${chalk.cyan(config.preferences.defaultFrontendBranch)}`);\n }\n }\n\n logger.newLine();\n logger.info('配置文件位置:');\n logger.info(` ${chalk.gray(userConfigManager.getConfigPath())}`);\n }\n }\n } catch (error: any) {\n logger.error(`读取配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 删除配置\n */\nexport const removeConfigCommand = new Command('remove')\n .alias('rm')\n .description('删除 GitLab 配置')\n .action(async () => {\n try {\n const hasConfig = await userConfigManager.hasConfig();\n\n if (!hasConfig) {\n logger.warn('未配置 GitLab Access Token');\n return;\n }\n\n const answers = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'confirm',\n message: '确定要删除 GitLab 配置吗?',\n default: false,\n },\n ]);\n\n if (!answers.confirm) {\n logger.info('已取消');\n return;\n }\n\n await userConfigManager.removeConfig();\n logger.success('配置已删除');\n } catch (error: any) {\n logger.error(`删除配置失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 验证 Token\n */\nexport const validateTokenCommand = new Command('validate')\n .alias('test')\n .description('验证当前 Token 是否有效')\n .action(async () => {\n try {\n logger.header('验证 GitLab Token');\n logger.newLine();\n\n const config = await userConfigManager.getGitLabConfig();\n\n if (!config) {\n logger.warn('未配置 GitLab Access Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n process.exit(1);\n }\n\n logger.info('正在验证...');\n\n const gitlabAPI = new GitLabAPI(config);\n const isValid = await gitlabAPI.authenticate();\n\n if (isValid) {\n logger.success('Token 有效!');\n logger.newLine();\n logger.info(`GitLab URL: ${chalk.cyan(config.baseUrl)}`);\n } else {\n logger.error('Token 验证失败');\n logger.info('请检查 Token 是否正确或已过期');\n process.exit(1);\n }\n } catch (error: any) {\n logger.error(`验证失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * Config 命令 - 管理 GitLab 配置\n */\nexport const configCommand = new Command('config')\n .description('管理 GitLab 配置')\n .addCommand(setTokenCommand)\n .addCommand(showConfigCommand)\n .addCommand(removeConfigCommand)\n .addCommand(validateTokenCommand);\n","import { Command } from 'commander';\nimport path from 'path';\nimport chalk from 'chalk';\nimport table from 'cli-table3';\nimport { readTemplateConfig, type TemplateType } from '../lib/template-version.js';\nimport { logger } from '../lib/logger.js';\nimport { FileUtils } from '../lib/utils.js';\nimport { userConfigManager } from '../lib/user-config.js';\nimport { GitLabAPI, GitLabDiffResult } from '../lib/gitlab-api.js';\n\n/**\n * Diff 命令 - 对比本地与远程模板差异\n */\nexport const diffCommand = new Command('diff')\n .description('对比本地与远程模板差异')\n .option('-f, --frontend', '对比前端模板')\n .option('-b, --backend', '对比后端模板')\n .option('-t, --tag <tag>', '指定远程标签')\n .option('-B, --branch <branch>', '指定远程分支')\n .option('-o, --output <format>', '输出格式 (table|json|diff)', 'table')\n .action(async (options) => {\n try {\n logger.header('模板版本对比');\n logger.newLine();\n\n // 检查是否在项目目录中\n const hasConfig = await FileUtils.exists('TECH_STACK.md');\n if (!hasConfig) {\n logger.error('当前目录不是一个有效的 team-cli 项目');\n logger.info(\"请先切换到项目目录\");\n process.exit(1);\n }\n\n const projectPath = '.';\n const checkAll = !options.frontend && !options.backend;\n const checkFrontend = options.frontend || checkAll;\n const checkBackend = options.backend || checkAll;\n\n const config = await readTemplateConfig(projectPath);\n if (!config) {\n logger.error('未找到模板配置');\n process.exit(1);\n }\n\n const gitlabConfig = await userConfigManager.getGitLabConfig();\n if (!gitlabConfig) {\n logger.warn('未配置 GitLab Token');\n logger.info(\"请使用 'team-cli config set-token' 进行配置\");\n logger.info(\"将使用基本 git 命令进行对比\");\n }\n\n const results: Array<{\n type: TemplateType;\n local: any;\n remote: any;\n diff?: GitLabDiffResult;\n }> = [];\n\n // 对比前端模板\n if (checkFrontend && config.frontend) {\n const result = await compareTemplate(\n projectPath,\n 'frontend',\n config.frontend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n // 对比后端模板\n if (checkBackend && config.backend) {\n const result = await compareTemplate(\n projectPath,\n 'backend',\n config.backend,\n options.tag,\n options.branch,\n gitlabConfig || undefined\n );\n if (result) {\n results.push(result);\n }\n }\n\n if (results.length === 0) {\n logger.info('没有可对比的模板');\n return;\n }\n\n // 根据输出格式显示结果\n switch (options.output) {\n case 'json':\n outputJson(results);\n break;\n case 'diff':\n outputDiff(results);\n break;\n case 'table':\n default:\n outputTable(results);\n break;\n }\n } catch (error: any) {\n logger.error(`对比失败: ${error.message}`);\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n }\n });\n\n/**\n * 对比模板版本\n */\nasync function compareTemplate(\n projectPath: string,\n type: TemplateType,\n localConfig: any,\n remoteTag?: string,\n remoteBranch?: string,\n gitlabConfig?: { accessToken: string; baseUrl: string; timeout?: number }\n): Promise<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult } | null> {\n try {\n logger.step(`对比${type === 'frontend' ? '前端' : '后端'}模板...`);\n\n const repository = localConfig.repository;\n const localCommit = localConfig.commit;\n const localTag = localConfig.tag;\n const localBranch = localConfig.branch;\n\n let remoteCommit: string | null = null;\n let remoteTagName: string | undefined;\n let remoteBranchName: string | undefined;\n\n // 如果有 GitLab 配置,使用 API 获取远程信息\n if (gitlabConfig) {\n const gitlabAPI = new GitLabAPI(gitlabConfig);\n const projectPathEncoded = GitLabAPI.parseProjectPath(repository);\n\n if (remoteTag) {\n // 获取指定 tag 的 commit\n remoteCommit = await gitlabAPI.getTagCommit(projectPathEncoded, remoteTag);\n remoteTagName = remoteTag;\n } else if (remoteBranch) {\n // 获取指定 branch 的 commit\n remoteCommit = await gitlabAPI.getBranchCommit(projectPathEncoded, remoteBranch);\n remoteBranchName = remoteBranch;\n } else {\n // 获取最新版本\n const latest = await gitlabAPI.getLatestVersion(projectPathEncoded);\n if (latest) {\n remoteCommit = latest.commit;\n if (latest.type === 'tag') {\n remoteTagName = latest.name;\n } else {\n remoteBranchName = latest.name;\n }\n }\n }\n\n // 获取 diff 信息\n if (remoteCommit && localCommit && remoteCommit !== localCommit) {\n const from = localTag || localBranch || localCommit;\n const to = remoteTagName || remoteBranchName || remoteCommit;\n const diff = await gitlabAPI.compareVersions(projectPathEncoded, from, to);\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n diff: diff || undefined,\n };\n }\n }\n\n // 如果没有 GitLab 配置,使用 git 命令获取基本信息\n if (!remoteCommit) {\n // 使用 git ls-remote 获取远程最新 commit\n const { execa } = await import('execa');\n const ref = remoteTag || remoteBranch || 'HEAD';\n const { stdout } = await execa('git', ['ls-remote', repository, ref], {\n stdio: 'pipe',\n });\n remoteCommit = stdout.split('\\t')[0];\n remoteTagName = remoteTag;\n remoteBranchName = remoteBranch;\n }\n\n const needsUpdate = localCommit !== remoteCommit;\n\n logger.info(\n `${type === 'frontend' ? '前端' : '后端'}模板: ${needsUpdate ? chalk.yellow('有更新') : chalk.green('已是最新')}`\n );\n\n return {\n type,\n local: {\n commit: localCommit,\n tag: localTag,\n branch: localBranch,\n },\n remote: {\n commit: remoteCommit || undefined,\n tag: remoteTagName,\n branch: remoteBranchName,\n },\n };\n } catch (error) {\n logger.error(`对比${type === 'frontend' ? '前端' : '后端'}模板失败: ${error}`);\n return null;\n }\n}\n\n/**\n * 输出表格格式\n */\nfunction outputTable(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const t = new Table({\n head: [chalk.cyan('项目'), chalk.cyan('版本')],\n colWidths: [20, 50],\n });\n\n // 本地版本\n const localVersion = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || '-';\n const localInfo = `Commit: ${result.local.commit?.substring(0, 8) || '-'}${result.local.tag ? `\\nTag: ${result.local.tag}` : ''}${result.local.branch ? `\\nBranch: ${result.local.branch}` : ''}`;\n t.push(['本地', localInfo]);\n\n // 远程版本\n const remoteVersion = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || '-';\n const remoteInfo = `Commit: ${result.remote.commit?.substring(0, 8) || '-'}${result.remote.tag ? `\\nTag: ${result.remote.tag}` : ''}${result.remote.branch ? `\\nBranch: ${result.remote.branch}` : ''}`;\n t.push(['远程', remoteInfo]);\n\n console.log(t.toString());\n\n // 显示 diff 信息\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('新增提交:'));\n\n const commitsTable = new Table({\n head: [chalk.cyan('Commit'), chalk.cyan('作者'), chalk.cyan('时间'), chalk.cyan('描述')],\n colWidths: [10, 15, 20, 50],\n wordWrap: true,\n });\n\n for (const commit of result.diff.commits.slice(0, 10)) {\n commitsTable.push([\n commit.short_id,\n commit.author_name,\n new Date(commit.created_at).toLocaleDateString('zh-CN'),\n commit.title,\n ]);\n }\n\n console.log(commitsTable.toString());\n\n if (result.diff.commits.length > 10) {\n console.log(chalk.gray(`... 还有 ${result.diff.commits.length - 10} 个提交`));\n }\n\n // 文件变更统计\n const files = result.diff.diffs;\n const added = files.filter((f) => f.new_file).length;\n const deleted = files.filter((f) => f.deleted_file).length;\n const modified = files.length - added - deleted;\n\n console.log('');\n console.log(chalk.bold('文件变更:'));\n console.log(` ${chalk.green('+')} 新增: ${added}`);\n console.log(` ${chalk.red('-')} 删除: ${deleted}`);\n console.log(` ${chalk.yellow('~')} 修改: ${modified}`);\n }\n\n console.log('');\n }\n}\n\n/**\n * 输出 JSON 格式\n */\nfunction outputJson(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n console.log(JSON.stringify(results, null, 2));\n}\n\n/**\n * 输出 diff 格式\n */\nfunction outputDiff(results: Array<{ type: TemplateType; local: any; remote: any; diff?: GitLabDiffResult }>): void {\n logger.newLine();\n\n for (const result of results) {\n const typeName = result.type === 'frontend' ? '前端' : '后端';\n console.log(chalk.bold(`${typeName}模板:`));\n console.log('');\n\n const from = result.local.tag || result.local.branch || result.local.commit?.substring(0, 8) || 'unknown';\n const to = result.remote.tag || result.remote.branch || result.remote.commit?.substring(0, 8) || 'unknown';\n\n console.log(`本地版本: ${chalk.cyan(from)}`);\n console.log(`远程版本: ${chalk.cyan(to)}`);\n\n if (result.diff && result.diff.commits.length > 0) {\n console.log('');\n console.log(chalk.bold('提交历史:'));\n\n for (const commit of result.diff.commits) {\n console.log('');\n console.log(chalk.yellow(`commit ${commit.id}`));\n console.log(`Author: ${commit.author_name} <${commit.author_email}>`);\n console.log(`Date: ${new Date(commit.created_at).toLocaleString('zh-CN')}`);\n console.log('');\n console.log(` ${commit.title}`);\n if (commit.message) {\n console.log(` ${commit.message.split('\\n').join('\\n ')}`);\n }\n }\n }\n\n console.log('');\n }\n}\n\n/**\n * 简单的 Table 类(如果 cli-table3 不可用)\n */\nclass Table {\n private options: any;\n private rows: any[][] = [];\n\n constructor(options: any) {\n this.options = options;\n }\n\n push(row: any[]): void {\n this.rows.push(row);\n }\n\n toString(): string {\n if (this.rows.length === 0) return '';\n\n let result = '';\n const colWidths = this.options.colWidths || [];\n\n // 表头\n if (this.options.head) {\n result += '| ';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n const cell = this.options.head[i] || '';\n result += cell.padEnd(width) + ' | ';\n }\n result += '\\n';\n\n // 分隔线\n result += '|';\n for (let i = 0; i < this.options.head.length; i++) {\n const width = colWidths[i] || 20;\n result += '-'.repeat(width + 2) + '|';\n }\n result += '\\n';\n }\n\n // 数据行\n for (const row of this.rows) {\n result += '| ';\n for (let i = 0; i < row.length; i++) {\n const width = colWidths[i] || 20;\n const cell = String(row[i] || '');\n const displayCell = this.options.wordWrap && cell.length > width ? cell.substring(0, width - 3) + '...' : cell;\n result += displayCell.padEnd(width) + ' | ';\n }\n result += '\\n';\n }\n\n return result;\n }\n}\n","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport { logger } from './lib/logger.js';\nimport { initCommand } from './commands/init.js';\nimport { breakdownCommand } from './commands/breakdown.js';\nimport { devCommand } from './commands/dev.js';\nimport { addFeatureCommand } from './commands/add-feature.js';\nimport { splitPrdCommand } from './commands/split-prd.js';\nimport { bugfixCommand } from './commands/bugfix.js';\nimport { hotfixCommand } from './commands/bugfix.js';\nimport { lintCommand } from './commands/lint.js';\nimport { statusCommand } from './commands/status.js';\nimport { detectDepsCommand } from './commands/detect-deps.js';\nimport { syncMemoryCommand } from './commands/sync-memory.js';\nimport { checkApiCommand } from './commands/check-api.js';\nimport { logsCommand } from './commands/logs.js';\nimport { updateCommand } from './commands/update.js';\nimport { configCommand } from './commands/config.js';\nimport { diffCommand } from './commands/diff.js';\n\n/**\n * team-cli - AI-Native 团队研发脚手架\n * Node.js 版本\n */\n\nconst program = new Command();\n\n// 基本信息\nprogram\n .name('team-cli')\n .description('AI-Native 团队研发脚手架')\n .version('2.1.3');\n\n// 全局选项\nprogram.option('-v, --verbose', '详细输出模式').option('--debug', '调试模式');\n\n// 注册命令\nprogram.addCommand(initCommand);\nprogram.addCommand(splitPrdCommand);\nprogram.addCommand(breakdownCommand);\nprogram.addCommand(devCommand);\nprogram.addCommand(addFeatureCommand);\nprogram.addCommand(bugfixCommand);\nprogram.addCommand(hotfixCommand);\nprogram.addCommand(lintCommand);\nprogram.addCommand(statusCommand);\nprogram.addCommand(detectDepsCommand);\nprogram.addCommand(syncMemoryCommand);\nprogram.addCommand(checkApiCommand);\nprogram.addCommand(logsCommand);\nprogram.addCommand(updateCommand);\nprogram.addCommand(configCommand);\nprogram.addCommand(diffCommand);\n\n// 默认显示帮助\nprogram.action(() => {\n showHelp();\n});\n\n/**\n * 显示帮助信息\n */\nfunction showHelp() {\n console.log('');\n logger.header('team-cli - AI-Native 团队研发脚手架');\n console.log('');\n console.log(chalk.bold('使用方法:'));\n console.log(' team-cli init [project-name] 初始化新项目');\n console.log(' team-cli split-prd <prd-folder> 将 PRD 拆分成多个 specs');\n console.log(' team-cli breakdown [spec-file] 将 spec 拆分为 milestones 和 todos');\n console.log(' team-cli dev 开发模式,执行具体任务');\n console.log(' team-cli add-feature <name> 添加新功能');\n console.log(' team-cli bugfix 创建 Bugfix 记录');\n console.log(' team-cli hotfix 创建 Hotfix');\n console.log(' team-cli detect-deps [spec] 检测依赖关系');\n console.log(' team-cli sync-memory 同步 AI_MEMORY.md');\n console.log(' team-cli check-api API 检查(冲突/变更/Registry)');\n console.log(' team-cli status 查看项目状态');\n console.log(' team-cli lint 代码质量检查 (前端+后端)');\n console.log(' team-cli logs [date] 查看会话日志');\n console.log(' team-cli update 检查并更新模板版本');\n console.log(' team-cli config 管理 GitLab 配置');\n console.log(' team-cli diff 对比本地与远程模板差异');\n console.log(' team-cli --help 显示帮助信息');\n console.log('');\n console.log(chalk.bold('示例:'));\n console.log(' team-cli init my-project');\n console.log(' cd my-project');\n console.log(' team-cli add-feature payment-system');\n console.log(' team-cli breakdown docs/specs/xxx.md');\n console.log(' team-cli dev');\n console.log('');\n console.log(chalk.bold('开发流程:'));\n console.log(' 1. PRD → specs (split-prd)');\n console.log(' 2. spec → milestones + todos (breakdown)');\n console.log(' 3. 选择 milestone/todo → 实现 (dev)');\n console.log('');\n console.log(chalk.bold('迭代流程:'));\n console.log(' team-cli add-feature <name> # 添加新功能');\n console.log(' team-cli detect-deps [spec] # 检测依赖关系');\n console.log(' team-cli sync-memory # 同步 AI_MEMORY');\n console.log(' team-cli check-api # API 检查');\n console.log(' team-cli bugfix # 创建 bugfix');\n console.log(' team-cli hotfix # 紧急修复');\n console.log(' team-cli status # 查看项目状态');\n console.log('');\n console.log(chalk.bold('模板管理:'));\n console.log(' team-cli config set-token # 设置 GitLab Access Token');\n console.log(' team-cli config show # 显示当前配置');\n console.log(' team-cli init --tag v1.0.0 # 使用指定 tag 初始化');\n console.log(' team-cli update --tag v1.1.0 # 更新到指定版本');\n console.log(' team-cli diff # 对比模板差异');\n console.log('');\n console.log(chalk.gray('更多信息: https://github.com/yungu/team-cli'));\n console.log('');\n}\n\n/**\n * 错误处理\n */\nprocess.on('uncaughtException', (error) => {\n logger.error('未捕获的异常');\n if (process.env.DEBUG) {\n console.error(error);\n }\n process.exit(1);\n});\n\nprocess.on('unhandledRejection', (reason) => {\n logger.error('未处理的 Promise 拒绝');\n if (process.env.DEBUG) {\n console.error(reason);\n }\n process.exit(1);\n});\n\n// 解析命令行参数\nprogram.parse(process.argv);\n","#!/usr/bin/env node\n// CLI 入口文件\nimport('./index.js').catch((error) => {\n console.error('Failed to start team-cli:', error);\n process.exit(1);\n});\n"],"mappings":"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A;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6ShB,QAAM,UAAU,MAAMA,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","names":["path","StringUtils","execa","path","execa","path","path","path","path","fs","userConfigManager","GitLabAPI","StringUtils","Command","inquirer","path","Listr","Command","inquirer","path","todo","Command","inquirer","path","Listr","ctx","StringUtils","Command","path","Listr","ctx","Command","inquirer","path","Listr","execa","Command","execa","Command","path","parseSpecStatus","Command","path","inquirer","Command","path","parseSpecStatus","Command","path","inquirer","Listr","controllers","extractMethodComment","Command","path","inquirer","Command","path","execa","inquirer","fs","userConfigManager","GitLabAPI","Command","inquirer","chalk","Command","chalk","execa","Command","chalk"]}
|