@al76/tools-and-spec-workflow-mcp
Version:
MCP server for spec-driven development workflow with real-time web dashboard
94 lines (92 loc) • 3.56 kB
JavaScript
import { promises as fs } from 'fs';
import { join } from 'path';
import { PathUtils } from '../core/path-utils.js';
export const createSpecDocTool = {
name: 'create-spec-doc',
description: `按照工作流序列创建或更新规范文档。
# 说明
在每个阶段加载模板并生成内容后调用。一次创建一个文档:首先是需求,然后是设计,最后是任务。永远不要在没有用户审批的情况下创建多个文档。始终遵循 get-template-context 的模板结构。`,
inputSchema: {
type: 'object',
properties: {
projectPath: {
type: 'string',
description: '项目根目录的绝对路径'
},
specName: {
type: 'string',
pattern: '^[a-z][a-z0-9-]*$',
description: 'kebab-case 格式的功能名称(例如,user-authentication)'
},
document: {
type: 'string',
enum: ['requirements', 'design', 'tasks'],
description: '要创建/更新的规范文档:requirements、design 或 tasks'
},
content: {
type: 'string',
description: '规范文档的完整 markdown 内容'
}
},
required: ['projectPath', 'specName', 'document', 'content']
}
};
export async function createSpecDocHandler(args, context) {
const { projectPath, specName, document, content } = args;
try {
const specDir = PathUtils.getSpecPath(projectPath, specName);
await fs.mkdir(specDir, { recursive: true });
// Check workflow order - prevent creating documents out of sequence
const requirementsPath = join(specDir, 'requirements.md');
const designPath = join(specDir, 'design.md');
// Enforce workflow order
if (document === 'design') {
try {
await fs.access(requirementsPath);
}
catch {
return {
success: false,
message: `工作流违规:在 requirements.md 存在之前无法创建 design.md!
首先创建 requirements.md,获取用户审查,然后创建 design.md。`
};
}
}
if (document === 'tasks') {
try {
await fs.access(designPath);
}
catch {
return {
success: false,
message: `工作流违规:在 design.md 存在之前无法创建 tasks.md!
首先创建 design.md,获取用户审查,然后创建 tasks.md。`
};
}
}
// Create/update the document
const filename = `${document}.md`;
const filePath = join(specDir, filename);
await fs.writeFile(filePath, content, 'utf-8');
// Return concise, directive message
return {
success: true,
message: `已创建 ${filename} 位于: ${PathUtils.toUnixPath(filePath)}
阻塞:必须通过仪表板或 VS Code 扩展请求审批。
不接受口头审批。
在系统显示已批准状态之前不要继续。`,
data: {
specName,
document,
filePath: PathUtils.toUnixPath(filePath)
}
};
}
catch (error) {
return {
success: false,
message: `失败: ${error.message}`
};
}
}
//# sourceMappingURL=create-spec-doc.js.map