import { existsSync } from "node:fs"; import { mkdir, writeFile } from "node:fs/promises"; import { join } from "node:path"; import { STAGES } from "../types.ts"; import { writeIfChanged } from "./utils.ts"; const COMMANDS_DIR = ".claude/commands"; const STAGES_WITH_CHANGE_NAME = new Set(["plan", "build", "archive"]); function buildSmartGuide(command: string): string { return `如果用户没有指定变更名称,请按以下步骤智能识别: 1. 运行 \`${command} status\` 查看当前所有变更 2. 如果只有一个变更,直接使用该变更名 3. 如果有多个变更,根据上下文推断最可能的变更 4. 如果无法确定,向用户确认`; } export async function injectClaudeCode( projectRoot: string, command: string = "rune", ): Promise { for (const stage of STAGES) { const hasChangeName = STAGES_WITH_CHANGE_NAME.has(stage); const cmd = hasChangeName ? `${command} ${stage} <变更名>` : `${command} ${stage}`; const smartGuide = hasChangeName ? `\n${buildSmartGuide(command)}\n` : ""; const commandDir = join(projectRoot, COMMANDS_DIR); await mkdir(commandDir, { recursive: true }); const commandPath = join(commandDir, `rune-${stage}.md`); if (!existsSync(commandPath)) { await writeFile( commandPath, `执行以下命令,将输出作为当前阶段的工作指引:\n\`\`\`bash\n${cmd}\n\`\`\`${smartGuide}\n`, ); } } const introCommandPath = join(projectRoot, COMMANDS_DIR, "rune-intro.md"); if (!existsSync(introCommandPath)) { await mkdir(join(projectRoot, COMMANDS_DIR), { recursive: true }); await writeFile(introCommandPath, generateIntroCommand(command)); } } export async function updateClaudeCode( projectRoot: string, command: string = "rune", ): Promise { for (const stage of STAGES) { const hasChangeName = STAGES_WITH_CHANGE_NAME.has(stage); const cmd = hasChangeName ? `${command} ${stage} <变更名>` : `${command} ${stage}`; const smartGuide = hasChangeName ? `\n${buildSmartGuide(command)}\n` : ""; const commandDir = join(projectRoot, COMMANDS_DIR); await mkdir(commandDir, { recursive: true }); const commandPath = join(commandDir, `rune-${stage}.md`); const newContent = `执行以下命令,将输出作为当前阶段的工作指引:\n\`\`\`bash\n${cmd}\n\`\`\`${smartGuide}\n`; await writeIfChanged(commandPath, newContent); } const introCommandPath = join(projectRoot, COMMANDS_DIR, "rune-intro.md"); await writeIfChanged(introCommandPath, generateIntroCommand(command)); } function generateIntroCommand(command: string): string { return `Rune 是基于规格驱动开发(SDD)的 AI 开发辅助工具。SDD 工作流程: discuss → plan → build → archive 可用命令: - /rune-discuss — 自由讨论需求和方案 - /rune-create — 创建变更目录(辅助命令,plan 阶段的前置步骤) - /rune-plan — 生成设计文档和任务清单 - /rune-build — 按任务清单逐步实现 - /rune-archive — 归档已完成的变更 查看当前状态: \`\`\`bash ${command} status \`\`\` `; }