feat: 将 task 从 plan 文档提升为独立 SDD 阶段
This commit is contained in:
@@ -39,6 +39,7 @@ describe("loadConfig", () => {
|
||||
const config = await loadConfig(TMP_DIR);
|
||||
expect(config.stages.discuss).toBeDefined();
|
||||
expect(config.stages.plan).toBeDefined();
|
||||
expect(config.stages.task).toBeDefined();
|
||||
expect(config.stages.build).toBeDefined();
|
||||
expect(config.stages.archive).toBeDefined();
|
||||
});
|
||||
@@ -65,9 +66,7 @@ describe("loadConfig", () => {
|
||||
await mkdir(runeDir, { recursive: true });
|
||||
await writeFile(
|
||||
join(runeDir, "config.yaml"),
|
||||
`metadata:
|
||||
tracked: false
|
||||
stages:
|
||||
`stages:
|
||||
plan:
|
||||
documents:
|
||||
- name: spec
|
||||
@@ -86,6 +85,7 @@ stages:
|
||||
const config = await loadConfig(TMP_DIR);
|
||||
expect(config.stages.discuss).toBeDefined();
|
||||
expect(config.stages.plan).toBeDefined();
|
||||
expect(config.stages.task).toBeDefined();
|
||||
expect(config.stages.build).toBeDefined();
|
||||
expect(config.stages.archive).toBeDefined();
|
||||
});
|
||||
@@ -170,56 +170,6 @@ describe("validateConfig", () => {
|
||||
};
|
||||
expect(() => validateConfig(config)).not.toThrow();
|
||||
});
|
||||
|
||||
it("tracked=true 时 plan.documents 必须包含 task 文档", () => {
|
||||
const config: RuneConfig = {
|
||||
stages: {
|
||||
plan: {
|
||||
documents: [{ name: "design", prompt: "生成设计" }],
|
||||
},
|
||||
},
|
||||
metadata: { tracked: true },
|
||||
};
|
||||
expect(() => validateConfig(config)).toThrow(ConfigError);
|
||||
});
|
||||
|
||||
it("tracked=true 且 plan.documents 包含 task 时不报错", () => {
|
||||
const config: RuneConfig = {
|
||||
stages: {
|
||||
plan: {
|
||||
documents: [
|
||||
{ name: "design", prompt: "生成设计" },
|
||||
{ name: "task", prompt: "生成任务" },
|
||||
],
|
||||
},
|
||||
},
|
||||
metadata: { tracked: true },
|
||||
};
|
||||
expect(() => validateConfig(config)).not.toThrow();
|
||||
});
|
||||
|
||||
it("tracked=false 时 plan.documents 不包含 task 也不报错", () => {
|
||||
const config: RuneConfig = {
|
||||
stages: {
|
||||
plan: {
|
||||
documents: [{ name: "design", prompt: "生成设计" }],
|
||||
},
|
||||
},
|
||||
metadata: { tracked: false },
|
||||
};
|
||||
expect(() => validateConfig(config)).not.toThrow();
|
||||
});
|
||||
|
||||
it("tracked 未配置时等同于 false,不强制要求 task 文档", () => {
|
||||
const config: RuneConfig = {
|
||||
stages: {
|
||||
plan: {
|
||||
documents: [{ name: "design", prompt: "生成设计" }],
|
||||
},
|
||||
},
|
||||
};
|
||||
expect(() => validateConfig(config)).not.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe("mergeConfig 保留 metadata", () => {
|
||||
@@ -242,52 +192,28 @@ describe("mergeConfig 保留 metadata", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("无 metadata 时保留默认 metadata(tracked: true)", async () => {
|
||||
const tmpDir = join(import.meta.dir, "__tmp_config_nometa_test__");
|
||||
await mkdir(tmpDir, { recursive: true });
|
||||
try {
|
||||
const configPath = join(tmpDir, ".rune", "config.yaml");
|
||||
await mkdir(join(tmpDir, ".rune"), { recursive: true });
|
||||
await writeFile(configPath, `stages:\n discuss:\n prompt: "测试"\n`);
|
||||
const config = await loadConfig(tmpDir);
|
||||
expect(config.metadata?.tracked).toBe(true);
|
||||
} finally {
|
||||
await rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
it("默认配置包含 task 阶段", async () => {
|
||||
const config = await loadConfig(TMP_DIR);
|
||||
expect(config.stages.task).toBeDefined();
|
||||
expect(config.stages.task!.prompt).toBeTruthy();
|
||||
});
|
||||
|
||||
it("用户 metadata 与默认 metadata 深合并", async () => {
|
||||
const tmpDir = join(import.meta.dir, "__tmp_config_deep_merge__");
|
||||
await mkdir(tmpDir, { recursive: true });
|
||||
try {
|
||||
const configPath = join(tmpDir, ".rune", "config.yaml");
|
||||
await mkdir(join(tmpDir, ".rune"), { recursive: true });
|
||||
await writeFile(
|
||||
configPath,
|
||||
`metadata:\n command: "rune"\nstages:\n discuss:\n prompt: "测试"\n`,
|
||||
);
|
||||
const config = await loadConfig(tmpDir);
|
||||
expect(config.metadata?.command).toBe("rune");
|
||||
expect(config.metadata?.tracked).toBe(true);
|
||||
} finally {
|
||||
await rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
it("默认 metadata 不包含 tracked", async () => {
|
||||
const config = await loadConfig(TMP_DIR);
|
||||
expect((config.metadata as any)?.tracked).toBeUndefined();
|
||||
});
|
||||
|
||||
it("用户 metadata.tracked 显式覆盖默认值", async () => {
|
||||
const tmpDir = join(import.meta.dir, "__tmp_config_tracked_override__");
|
||||
await mkdir(tmpDir, { recursive: true });
|
||||
try {
|
||||
const configPath = join(tmpDir, ".rune", "config.yaml");
|
||||
await mkdir(join(tmpDir, ".rune"), { recursive: true });
|
||||
await writeFile(
|
||||
configPath,
|
||||
`metadata:\n tracked: false\nstages:\n discuss:\n prompt: "测试"\n`,
|
||||
);
|
||||
const config = await loadConfig(tmpDir);
|
||||
expect(config.metadata?.tracked).toBe(false);
|
||||
} finally {
|
||||
await rm(tmpDir, { recursive: true, force: true });
|
||||
}
|
||||
it("用户配置 task 阶段覆盖默认", async () => {
|
||||
const runeDir = join(TMP_DIR, ".rune");
|
||||
await mkdir(runeDir, { recursive: true });
|
||||
await writeFile(
|
||||
join(runeDir, "config.yaml"),
|
||||
`stages:
|
||||
task:
|
||||
prompt: 自定义任务提示词
|
||||
`,
|
||||
);
|
||||
const config = await loadConfig(TMP_DIR);
|
||||
expect(config.stages.task!.prompt).toBe("自定义任务提示词");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user