feat: plan skill 引导 AI 先通过 rune status 获取文档列表

This commit is contained in:
2026-06-09 12:34:26 +08:00
parent da826e2029
commit 5705e59285
3 changed files with 35 additions and 3 deletions

View File

@@ -55,6 +55,12 @@ function generateSkill(stage: string, hasChangeName: boolean): string {
const nameHint = hasChangeName const nameHint = hasChangeName
? `将 <变更名> 替换为实际的变更名称。\n` ? `将 <变更名> 替换为实际的变更名称。\n`
: ""; : "";
let extraGuide = "";
if (stage === "plan") {
extraGuide = `\n规划阶段应先运行 \`rune status <变更名>\` 获取当前有哪些文档需要编写,再按依赖顺序逐个生成。\n`;
}
const descriptionMap: Record<string, string> = { const descriptionMap: Record<string, string> = {
discuss: "Use when 需要进入 SDD 讨论阶段,自由讨论需求和架构方案", discuss: "Use when 需要进入 SDD 讨论阶段,自由讨论需求和架构方案",
plan: "Use when 需要进入 SDD 规划阶段,生成设计文档和任务清单", plan: "Use when 需要进入 SDD 规划阶段,生成设计文档和任务清单",
@@ -75,7 +81,7 @@ description: ${descriptionMap[stage] ?? `Use when 需要执行 SDD ${stage} 阶
${cmd} ${cmd}
\`\`\` \`\`\`
${nameHint}将命令输出作为工作指引,执行当前阶段的工作。 ${nameHint}${extraGuide}将命令输出作为工作指引,执行当前阶段的工作。
`; `;
} }

View File

@@ -18,7 +18,11 @@ export const defaultConfig: RuneConfig = {
documents: [ documents: [
{ {
name: "design", name: "design",
prompt: `根据之前的讨论内容,生成一份设计文档 prompt: `先获取当前规划状态
建议执行: rune status <变更名>
请根据之前的讨论内容和状态输出,生成一份设计文档。
要求: 要求:
- 清晰描述背景和目标 - 清晰描述背景和目标
@@ -43,7 +47,11 @@ export const defaultConfig: RuneConfig = {
{ {
name: "task", name: "task",
depend: ["design"], depend: ["design"],
prompt: `根据设计文档,生成一份任务列表 prompt: `先获取当前规划状态
建议执行: rune status <变更名>
请根据设计文档,生成一份任务列表。
要求: 要求:
- 将设计拆分为可独立执行的小任务 - 将设计拆分为可独立执行的小任务

View File

@@ -75,6 +75,24 @@ describe("injectOpenCode", () => {
} }
}); });
it("plan skill 包含运行 status 的引导", async () => {
await injectOpenCode(TMP_DIR);
const content = await readFile(
join(TMP_DIR, ".opencode", "skills", "rune-plan", "SKILL.md"),
"utf-8",
);
expect(content).toContain("rune status");
});
it("discuss skill 不包含 status 引导", async () => {
await injectOpenCode(TMP_DIR);
const content = await readFile(
join(TMP_DIR, ".opencode", "skills", "rune-discuss", "SKILL.md"),
"utf-8",
);
expect(content).not.toContain("rune status");
});
it("重复注入时不覆盖已存在的文件", async () => { it("重复注入时不覆盖已存在的文件", async () => {
await injectOpenCode(TMP_DIR); await injectOpenCode(TMP_DIR);
const originalContent = await readFile( const originalContent = await readFile(