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 || '', }; }