From 0869014c3fe07391190ee4c514da536d3d9fc447 Mon Sep 17 00:00:00 2001 From: lanyuanxiaoyao Date: Tue, 9 Jun 2026 11:42:27 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20build=20=E5=91=BD=E4=BB=A4=E5=9C=A8=20pl?= =?UTF-8?q?an=20=E6=9C=AA=E5=AE=8C=E6=88=90=E6=97=B6=E7=BB=99=E5=87=BA?= =?UTF-8?q?=E5=8F=8B=E5=A5=BD=E6=8F=90=E7=A4=BA=E8=80=8C=E9=9D=9E=E6=9C=AA?= =?UTF-8?q?=E9=A2=84=E6=9C=9F=E9=94=99=E8=AF=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/assembler.ts | 11 +++++++++-- tests/core/assembler.test.ts | 13 +++++++++---- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/core/assembler.ts b/src/core/assembler.ts index 2d3fbab..6a5647b 100644 --- a/src/core/assembler.ts +++ b/src/core/assembler.ts @@ -2,6 +2,7 @@ import { existsSync } from "node:fs"; import { readFile } from "node:fs/promises"; import { join } from "node:path"; import type { RuneConfig } from "../types.ts"; +import { CommandError } from "../cli/errors.ts"; import { getChangeDir } from "./config.ts"; import { parseTasks } from "./task-parser.ts"; @@ -69,7 +70,11 @@ export async function assembleBuildPrompt( changeName: string, ): Promise { const build = config.stages.build; - if (!build) throw new Error("build 阶段未配置"); + if (!build) { + throw new CommandError("构建阶段未配置", { + hint: "请在 .rune/config.yaml 中配置 stages.build", + }); + } const changeDir = getChangeDir(projectRoot, changeName); const taskPath = join(changeDir, "task.md"); @@ -78,7 +83,9 @@ export async function assembleBuildPrompt( try { taskContent = await readFile(taskPath, "utf-8"); } catch { - throw new Error(`task.md not found in ${changeDir}`); + throw new CommandError(`变更 "${changeName}" 尚未完成规划,task.md 不存在`, { + hint: `请先完成规划阶段:rune plan ${changeName} 生成所有规划文档`, + }); } const tasks = parseTasks(taskContent); diff --git a/tests/core/assembler.test.ts b/tests/core/assembler.test.ts index 77fda23..45d5604 100644 --- a/tests/core/assembler.test.ts +++ b/tests/core/assembler.test.ts @@ -184,10 +184,15 @@ describe("assembleBuildPrompt", () => { expect(prompt).toContain("归档"); }); - it("task.md 不存在时抛出错误", async () => { - await expect( - assembleBuildPrompt(defaultConfig, TMP_DIR, "nonexistent"), - ).rejects.toThrow("task.md not found"); + it("task.md 不存在时抛出 CommandError 并附带提示", async () => { + try { + await assembleBuildPrompt(defaultConfig, TMP_DIR, "nonexistent"); + expect.unreachable(); + } catch (e: any) { + expect(e.message).toContain("尚未完成规划"); + expect(e.message).toContain("nonexistent"); + expect(e.hint).toContain("rune plan"); + } }); });