76 lines
3.4 KiB
TypeScript
76 lines
3.4 KiB
TypeScript
import type { GuardrailSet, GuardrailsInput, GuardrailsResult } from '../types.js';
|
||
import { resolveProject } from '../core/workspace.js';
|
||
import { createPageTestCase } from './testing.js';
|
||
import { buildVerificationPlan } from './verification.js';
|
||
export function buildGuardrails(input: GuardrailsInput): GuardrailsResult {
|
||
const project = resolveProject(input.project);
|
||
const taskType = input.taskType || input.changeType || 'general';
|
||
const paths = input.paths || [];
|
||
const guardrails: GuardrailSet = {
|
||
beforeEdit: [
|
||
'先读最近的 AGENTS.md,再读 TASKS.md 和 SKILLS.md。',
|
||
'先检查目标仓库状态,识别用户已有改动,不覆盖、不回滚无关文件。',
|
||
'先快速扫现有代码风格和目录结构,再决定改动方式。',
|
||
'搜索优先用 rg,路径和接口名尽量保持可 grep。',
|
||
],
|
||
duringEdit: [
|
||
'改动范围收敛到本次需求相关文件。',
|
||
'复杂度高的地方加简短注释,避免空泛解释。',
|
||
'后端真实环境配置不写入提交内容;前端 env 只允许客户端公开变量。',
|
||
'前端实现遵循现有 antdv-next/Vben 约定,不引入无关抽象。',
|
||
],
|
||
doNot: [
|
||
'不要执行 git reset --hard、git checkout -- 等破坏性回滚。',
|
||
'不要在用户未要求时自动 push。',
|
||
'不要把真实密钥、数据库密码、生产 env 写进可提交文件。',
|
||
'不要为了验证长期保留 Node/Vite/浏览器进程。',
|
||
],
|
||
verification: buildVerificationPlan({
|
||
changeType: taskType,
|
||
includePageTest: input.includePageTest || taskType === 'page',
|
||
project: input.project,
|
||
}),
|
||
};
|
||
|
||
if (['api', 'backend'].includes(taskType)) {
|
||
guardrails.beforeEdit.push('接口改动先确认 DTO、Controller、Service、返回结构和鉴权链路。');
|
||
guardrails.duringEdit.push('接口成功返回统一保持 code=200/msg/data,错误返回 err 字段。');
|
||
guardrails.verification.notes.push('接口改完必须本地真实调用一次对应接口。');
|
||
}
|
||
|
||
guardrails.verification.notes.push(
|
||
'改动后的 review 是硬步骤,优先用 kt_global_code_review 或 pnpm run global-review。',
|
||
);
|
||
|
||
if (taskType === 'page' || input.includePageTest) {
|
||
guardrails.beforeEdit.push('页面级测试先写用例,再打开可视化浏览器执行。');
|
||
guardrails.verification.pageTestCase = createPageTestCase({
|
||
project: input.project,
|
||
title: input.userRequest || `${project.label} 页面级测试`,
|
||
});
|
||
}
|
||
|
||
if (taskType === 'database') {
|
||
guardrails.beforeEdit.push('数据库同步或修复前先确认源库、目标库、备份库和回滚点。');
|
||
guardrails.doNot.push('不要在未确认目标库前执行覆盖、drop、truncate。');
|
||
}
|
||
|
||
if (taskType === 'deploy') {
|
||
guardrails.duringEdit.push('部署配置保留真正能提升运行稳定性的内容,删掉噪音配置。');
|
||
guardrails.doNot.push('不要在未要求时触发真实部署或改动远程服务。');
|
||
}
|
||
|
||
if (taskType === 'mcp') {
|
||
guardrails.duringEdit.push('MCP 工具描述要明确边界,默认输出建议和检查清单,不做高风险副作用。');
|
||
guardrails.verification.notes.push('MCP 变更至少跑 self-test 和真实 SDK Client smoke test。');
|
||
}
|
||
|
||
return {
|
||
guardrails,
|
||
paths,
|
||
project,
|
||
taskType,
|
||
userRequest: input.userRequest || '',
|
||
};
|
||
}
|