feat: 优化 suggestNextStep 依赖提示,修复 finish 归档目录缺失问题,移除 es-toolkit
This commit is contained in:
3
bun.lock
3
bun.lock
@@ -6,7 +6,6 @@
|
|||||||
"name": "rune",
|
"name": "rune",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cac": "^7.0.0",
|
"cac": "^7.0.0",
|
||||||
"es-toolkit": "^1.47.0",
|
|
||||||
"yaml": "^2.7.0",
|
"yaml": "^2.7.0",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -120,8 +119,6 @@
|
|||||||
|
|
||||||
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
|
"environment": ["environment@1.1.0", "", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
|
||||||
|
|
||||||
"es-toolkit": ["es-toolkit@1.47.0", "", {}, "sha512-n1GuoD0WEQZMBk5tttoZSqwgyLx01oqa5XsBmCHwPyNe1S9jPBEmtR2pSgp2kJuWE3ciFZ6yRHmY4pM4C3OOkw=="],
|
|
||||||
|
|
||||||
"eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
|
"eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
|
||||||
|
|
||||||
"get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="],
|
"get-east-asian-width": ["get-east-asian-width@1.6.0", "", {}, "sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA=="],
|
||||||
|
|||||||
@@ -21,7 +21,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"cac": "^7.0.0",
|
"cac": "^7.0.0",
|
||||||
"es-toolkit": "^1.47.0",
|
|
||||||
"yaml": "^2.7.0"
|
"yaml": "^2.7.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
38
src/cli.ts
38
src/cli.ts
@@ -76,11 +76,26 @@ export function formatChangeStatus(change: ChangeStatus, config?: RuneConfig): s
|
|||||||
|
|
||||||
export function suggestNextStep(change: ChangeStatus, config?: RuneConfig): string {
|
export function suggestNextStep(change: ChangeStatus, config?: RuneConfig): string {
|
||||||
const prefix = getPmPrefix(config);
|
const prefix = getPmPrefix(config);
|
||||||
|
const planDocs = config?.stages.plan?.documents;
|
||||||
if (!change.planCompleted) {
|
if (!change.planCompleted) {
|
||||||
const nextDoc = change.documents.find((d) => !d.completed && d.dependMet);
|
const nextDoc = change.documents.find((d) => !d.completed && d.dependMet);
|
||||||
if (nextDoc) {
|
if (nextDoc) {
|
||||||
return `${prefix} plan ${change.name} ${nextDoc.name}`;
|
return `${prefix} plan ${change.name} ${nextDoc.name}`;
|
||||||
}
|
}
|
||||||
|
const firstMissingDep = change.documents
|
||||||
|
.filter((d) => !d.completed && !d.dependMet)
|
||||||
|
.map((d) => {
|
||||||
|
const docConfig = planDocs?.find((c) => c.name === d.name);
|
||||||
|
const missing =
|
||||||
|
docConfig?.depend?.filter(
|
||||||
|
(dep) => !change.documents.find((cd) => cd.name === dep)?.completed,
|
||||||
|
) ?? [];
|
||||||
|
return { name: d.name, missing };
|
||||||
|
})
|
||||||
|
.find((d) => d.missing.length > 0);
|
||||||
|
if (firstMissingDep) {
|
||||||
|
return `${prefix} plan ${change.name} ${firstMissingDep.missing[0]}(${firstMissingDep.name} 的前置依赖)`;
|
||||||
|
}
|
||||||
return `完成前置依赖后再规划文档`;
|
return `完成前置依赖后再规划文档`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,14 +276,13 @@ cli
|
|||||||
cli.command("task <change-name>", "任务拆解阶段").action(async (changeName: string) => {
|
cli.command("task <change-name>", "任务拆解阶段").action(async (changeName: string) => {
|
||||||
validateChangeName(changeName);
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
|
const config = await loadConfig(root);
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
const prefix = getPmPrefix();
|
|
||||||
throw new CommandError(`变更"${changeName}"不存在`, {
|
throw new CommandError(`变更"${changeName}"不存在`, {
|
||||||
hint: `请先运行 ${prefix} create ${changeName} 创建变更`,
|
hint: `请先运行 ${getPmPrefix(config)} create ${changeName} 创建变更`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const config = await loadConfig(root);
|
|
||||||
const prompt = await assembleTaskPrompt(config, root, changeName);
|
const prompt = await assembleTaskPrompt(config, root, changeName);
|
||||||
console.log(prompt);
|
console.log(prompt);
|
||||||
});
|
});
|
||||||
@@ -276,14 +290,13 @@ cli.command("task <change-name>", "任务拆解阶段").action(async (changeName
|
|||||||
cli.command("build <change-name>", "构建阶段").action(async (changeName: string) => {
|
cli.command("build <change-name>", "构建阶段").action(async (changeName: string) => {
|
||||||
validateChangeName(changeName);
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
|
const config = await loadConfig(root);
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
const prefix = getPmPrefix();
|
|
||||||
throw new CommandError(`变更"${changeName}"不存在`, {
|
throw new CommandError(`变更"${changeName}"不存在`, {
|
||||||
hint: `请先运行 ${prefix} create ${changeName} 创建变更`,
|
hint: `请先运行 ${getPmPrefix(config)} create ${changeName} 创建变更`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const config = await loadConfig(root);
|
|
||||||
const prompt = await assembleBuildPrompt(config, root, changeName);
|
const prompt = await assembleBuildPrompt(config, root, changeName);
|
||||||
console.log(prompt);
|
console.log(prompt);
|
||||||
});
|
});
|
||||||
@@ -291,14 +304,13 @@ cli.command("build <change-name>", "构建阶段").action(async (changeName: str
|
|||||||
cli.command("archive <change-name>", "归档阶段").action(async (changeName: string) => {
|
cli.command("archive <change-name>", "归档阶段").action(async (changeName: string) => {
|
||||||
validateChangeName(changeName);
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
|
const config = await loadConfig(root);
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
const prefix = getPmPrefix();
|
|
||||||
throw new CommandError(`变更"${changeName}"不存在`, {
|
throw new CommandError(`变更"${changeName}"不存在`, {
|
||||||
hint: `请先运行 ${prefix} create ${changeName} 创建变更`,
|
hint: `请先运行 ${getPmPrefix(config)} create ${changeName} 创建变更`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const config = await loadConfig(root);
|
|
||||||
const prompt = await assembleArchivePrompt(config, root, changeName);
|
const prompt = await assembleArchivePrompt(config, root, changeName);
|
||||||
console.log(prompt);
|
console.log(prompt);
|
||||||
});
|
});
|
||||||
@@ -306,15 +318,17 @@ cli.command("archive <change-name>", "归档阶段").action(async (changeName: s
|
|||||||
cli.command("finish <change-name>", "归档变更").action(async (changeName: string) => {
|
cli.command("finish <change-name>", "归档变更").action(async (changeName: string) => {
|
||||||
validateChangeName(changeName);
|
validateChangeName(changeName);
|
||||||
const root = requireProjectRoot();
|
const root = requireProjectRoot();
|
||||||
|
const config = await loadConfig(root);
|
||||||
const changeDir = getChangeDir(root, changeName);
|
const changeDir = getChangeDir(root, changeName);
|
||||||
if (!existsSync(changeDir)) {
|
if (!existsSync(changeDir)) {
|
||||||
const prefix = getPmPrefix();
|
|
||||||
throw new CommandError(`变更"${changeName}"不存在`, {
|
throw new CommandError(`变更"${changeName}"不存在`, {
|
||||||
hint: `请先运行 ${prefix} create ${changeName} 创建变更`,
|
hint: `请先运行 ${getPmPrefix(config)} create ${changeName} 创建变更`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const today = new Date().toISOString().slice(0, 10);
|
const today = new Date().toISOString().slice(0, 10);
|
||||||
const dest = join(getArchiveDir(root), `${today}-${changeName}`);
|
const archiveDir = getArchiveDir(root);
|
||||||
|
await mkdir(archiveDir, { recursive: true });
|
||||||
|
const dest = join(archiveDir, `${today}-${changeName}`);
|
||||||
if (existsSync(dest)) {
|
if (existsSync(dest)) {
|
||||||
throw new CommandError(`归档目标 "${today}-${changeName}" 已存在`, {
|
throw new CommandError(`归档目标 "${today}-${changeName}" 已存在`, {
|
||||||
hint: `同一天同一变更名只能归档一次。如需重新归档,请先删除 .rune/archive/${today}-${changeName} 目录`,
|
hint: `同一天同一变更名只能归档一次。如需重新归档,请先删除 .rune/archive/${today}-${changeName} 目录`,
|
||||||
|
|||||||
Reference in New Issue
Block a user