refactor: discuss 和 plan 阶段改用 PromptBuilder 组装提示词

This commit is contained in:
2026-06-11 16:39:14 +08:00
parent 803533a7e0
commit 7951d9a82b
3 changed files with 23 additions and 21 deletions

View File

@@ -6,6 +6,7 @@ import { CommandError } from "../cli/errors.ts";
import { getChangeDir } from "./config.ts";
import { parseTasks, validateTaskFormat, TaskFormatError } from "./task-parser.ts";
import { applyCommandPrefix, getPmPrefix } from "./pm.ts";
import { PromptBuilder } from "./prompt-builder";
export function assembleDiscussPrompt(config: RuneConfig): string {
const discuss = config.stages.discuss;
@@ -13,7 +14,10 @@ export function assembleDiscussPrompt(config: RuneConfig): string {
throw new CommandError("讨论阶段未配置", {
hint: "请在 .rune/config.yaml 中配置 stages.discuss",
});
return applyCommandPrefix(discuss.prompt, config);
const raw = new PromptBuilder().head("# 讨论阶段").prompt(discuss.prompt).build();
return applyCommandPrefix(raw, config);
}
export async function assemblePlanPrompt(
@@ -36,39 +40,35 @@ export async function assemblePlanPrompt(
}
const changeDir = getChangeDir(projectRoot, changeName);
const parts: string[] = [];
const builder = new PromptBuilder();
parts.push(`# 规划阶段:${changeName}`);
parts.push("");
parts.push(`## 文档:${doc.name}.md`);
parts.push(doc.prompt);
builder.head(`# 规划阶段:${changeName}\n\n## 文档:${doc.name}.md`);
builder.prompt(doc.prompt);
const docPath = join(changeDir, `${doc.name}.md`);
if (existsSync(docPath)) {
parts.push(`\n文档已存在,请先读取 ${docPath} 查看已有内容,在此基础上修订。`);
builder.context(`文档已存在,请先读取 ${docPath} 查看已有内容,在此基础上修订。`);
}
if (doc.template) {
parts.push(`\n### 格式模板:\n${doc.template}`);
builder.context(`### 格式模板:\n${doc.template}`);
}
if (doc.depend && doc.depend.length > 0) {
parts.push("\n---\n");
parts.push("## 依赖说明\n");
parts.push("本文档依赖以下前置文档:");
for (const dep of doc.depend) {
const depLines = doc.depend.map((dep) => {
const depPath = join(changeDir, `${dep}.md`);
const depCompleted = existsSync(depPath);
const status = depCompleted ? "已完成" : "未完成";
parts.push(`- ${dep}.md${status}`);
}
parts.push("\n请先阅读已完成的前置文档确保内容一致。");
return `- ${dep}.md${status}`;
});
builder.context(
`## 依赖说明\n\n本文档依赖以下前置文档\n${depLines.join("\n")}\n\n请先阅读已完成的前置文档,确保内容一致。`,
);
}
parts.push(`\n请将文档写入目录:${changeDir}`);
return applyCommandPrefix(parts.join("\n"), config);
builder.guide(`请将文档写入目录:${changeDir}`);
return applyCommandPrefix(builder.build(), config);
}
export async function assembleTaskPrompt(

View File

@@ -35,7 +35,8 @@ describe("assembleDiscussPrompt", () => {
stages: { discuss: { prompt: "自定义讨论" } },
};
const prompt = assembleDiscussPrompt(config);
expect(prompt).toBe("自定义讨论");
expect(prompt).toContain("自定义讨论");
expect(prompt).toContain("# 讨论阶段");
});
});

View File

@@ -118,7 +118,8 @@ describe("完整 SDD 流程", () => {
const config = await loadConfig(TMP_DIR);
const discussPrompt = assembleDiscussPrompt(config);
expect(discussPrompt).toBe("自定义讨论");
expect(discussPrompt).toContain("自定义讨论");
expect(discussPrompt).toContain("# 讨论阶段");
await mkdir(getChangeDir(TMP_DIR, "test"), { recursive: true });
const planPrompt = await assemblePlanPrompt(config, TMP_DIR, "test", "spec");