feat(onboarding): 接入包 v1.6.0——蓝图机器门控双层实现

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
This commit is contained in:
lanrtop 2026-07-15 13:38:32 +09:00
parent be2f69578a
commit f04eb6e766
4 changed files with 42 additions and 1 deletions

View File

@ -0,0 +1,31 @@
#!/usr/bin/env node
// 蓝图门控pre-commit 检查未关闭的 🔵 任务卡warn onlyexit 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);

View File

@ -18,7 +18,7 @@
<!-- TODO: 列出 README / ARCHITECTURE.md / 其他关键文档及用途。 -->
<!-- ONBOARDING_MANAGED_START version="1.5.0" -->
<!-- ONBOARDING_MANAGED_START version="1.6.0" -->
## 核心开发约束
### 包管理
@ -55,6 +55,8 @@
**边界模糊时**:保守判断,按 Feature 处理,走完整确认卡。
**提交时**`feat:` 提交须在 commit message 末尾加 `Feature-Confirmed: true` trailerlefthook commit-msg 强制检查)。这是确认卡已输出的机器层存证。
> ⚠️ Session 结束汇总补录 ≠ 确认卡替代——补录仅适用于漂移检测触发后用户主动选择补录的场景,不得作为「先做再补」的通道。
## Git 工作流

View File

@ -17,8 +17,14 @@ pre-commit:
# run: pnpm --filter api typecheck # monorepo workspace
# # run: pnpm exec tsc -p api/tsconfig.json --noEmit # 独立 tsconfig
# # run: pnpm -r typecheck # 递归所有包
blueprint-gate:
run: node .claude/hooks/blueprint-gate.cjs || true
commit-msg:
commands:
conventional:
run: "head -1 .git/COMMIT_EDITMSG | grep -qE '^(feat|fix|docs|chore|refactor|ci|perf|style|test|build|revert)(\\(.+\\))?!?: .+' || exit 1"
feature-confirmed:
run: |
head -1 .git/COMMIT_EDITMSG | grep -qE '^feat' || exit 0
grep -q 'Feature-Confirmed: true' .git/COMMIT_EDITMSG || { printf '\n⚠ feat: 提交须含 Feature-Confirmed: true trailer\n 在 commit message 末尾加一行Feature-Confirmed: true\n (确认卡已与用户对齐,方可提交)\n\n' >&2; exit 1; }

View File

@ -17,6 +17,7 @@ const TMPL_AGENTS: &str = include_str!("../../resources/onboarding/AGENTS.md.tmp
const TMPL_LEFTHOOK: &str = include_str!("../../resources/onboarding/lefthook.yml.tmpl");
const TMPL_GIT_WORKFLOW: &str = include_str!("../../resources/onboarding/git-workflow.md.tmpl");
const TMPL_ENVOY: &str = include_str!("../../resources/onboarding/.claude/commands/envoy.md");
const TMPL_BLUEPRINT_GATE: &str = include_str!("../../resources/onboarding/.claude/hooks/blueprint-gate.cjs");
/// 单个模板的分发结果。
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
@ -147,6 +148,7 @@ pub fn dispatch_templates(project_path: &str) -> Vec<TemplateResult> {
dispatch_one(root, "lefthook.yml", TMPL_LEFTHOOK),
dispatch_versioned(root, "docs/ai-context/git-workflow.md", TMPL_GIT_WORKFLOW),
dispatch_one(root, ".claude/commands/envoy.md", TMPL_ENVOY),
dispatch_one(root, ".claude/hooks/blueprint-gate.cjs", TMPL_BLUEPRINT_GATE),
]
}