A: feat: 提交须含 Feature-Confirmed: true trailer
- lefthook.yml.tmpl commit-msg 新增 feature-confirmed 命令
- AGENTS.md.tmpl 需求对齐协议补 trailer 说明
B: pre-commit 检查未关闭 🔵 任务卡(warn only)
- 新增 .claude/hooks/blueprint-gate.cjs(CommonJS,兼容 ESM 项目)
- lefthook.yml.tmpl pre-commit 新增 blueprint-gate 命令
- onboarding.rs dispatch 新增 blueprint-gate.cjs
Feature-Confirmed: true
32 lines
1012 B
JavaScript
32 lines
1012 B
JavaScript
#!/usr/bin/env node
|
||
// 蓝图门控:pre-commit 检查未关闭的 🔵 任务卡,warn only(exit 0,不阻断提交)。
|
||
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const modulesDir = path.join(process.cwd(), '.blueprint', 'modules');
|
||
|
||
if (!fs.existsSync(modulesDir)) {
|
||
process.exit(0);
|
||
}
|
||
|
||
const unclosed = [];
|
||
for (const file of fs.readdirSync(modulesDir).filter(f => f.endsWith('.md'))) {
|
||
const content = fs.readFileSync(path.join(modulesDir, file), 'utf8');
|
||
for (const line of content.split('\n')) {
|
||
if (line.startsWith('### 🔵')) {
|
||
unclosed.push({ file, title: line.replace(/^###\s*🔵\s*/, '').trim() });
|
||
}
|
||
}
|
||
}
|
||
|
||
if (unclosed.length > 0) {
|
||
process.stderr.write('\n⚠️ 蓝图门控:发现未关闭任务卡\n');
|
||
for (const { file, title } of unclosed) {
|
||
process.stderr.write(` 🔵 ${title}(${file})\n`);
|
||
}
|
||
process.stderr.write('\n 已完成 → 改为 ✅;仍进行中 → 属预期,可忽略本提示。\n\n');
|
||
}
|
||
|
||
process.exit(0);
|