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:
parent
be2f69578a
commit
f04eb6e766
@ -0,0 +1,31 @@
|
|||||||
|
#!/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);
|
||||||
@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
<!-- TODO: 列出 README / ARCHITECTURE.md / 其他关键文档及用途。 -->
|
<!-- TODO: 列出 README / ARCHITECTURE.md / 其他关键文档及用途。 -->
|
||||||
|
|
||||||
<!-- ONBOARDING_MANAGED_START version="1.5.0" -->
|
<!-- ONBOARDING_MANAGED_START version="1.6.0" -->
|
||||||
## 核心开发约束
|
## 核心开发约束
|
||||||
|
|
||||||
### 包管理
|
### 包管理
|
||||||
@ -55,6 +55,8 @@
|
|||||||
|
|
||||||
**边界模糊时**:保守判断,按 Feature 处理,走完整确认卡。
|
**边界模糊时**:保守判断,按 Feature 处理,走完整确认卡。
|
||||||
|
|
||||||
|
**提交时**:`feat:` 提交须在 commit message 末尾加 `Feature-Confirmed: true` trailer(lefthook commit-msg 强制检查)。这是确认卡已输出的机器层存证。
|
||||||
|
|
||||||
> ⚠️ Session 结束汇总补录 ≠ 确认卡替代——补录仅适用于漂移检测触发后用户主动选择补录的场景,不得作为「先做再补」的通道。
|
> ⚠️ Session 结束汇总补录 ≠ 确认卡替代——补录仅适用于漂移检测触发后用户主动选择补录的场景,不得作为「先做再补」的通道。
|
||||||
|
|
||||||
## Git 工作流
|
## Git 工作流
|
||||||
|
|||||||
@ -17,8 +17,14 @@ pre-commit:
|
|||||||
# run: pnpm --filter api typecheck # monorepo workspace
|
# run: pnpm --filter api typecheck # monorepo workspace
|
||||||
# # run: pnpm exec tsc -p api/tsconfig.json --noEmit # 独立 tsconfig
|
# # run: pnpm exec tsc -p api/tsconfig.json --noEmit # 独立 tsconfig
|
||||||
# # run: pnpm -r typecheck # 递归所有包
|
# # run: pnpm -r typecheck # 递归所有包
|
||||||
|
blueprint-gate:
|
||||||
|
run: node .claude/hooks/blueprint-gate.cjs || true
|
||||||
|
|
||||||
commit-msg:
|
commit-msg:
|
||||||
commands:
|
commands:
|
||||||
conventional:
|
conventional:
|
||||||
run: "head -1 .git/COMMIT_EDITMSG | grep -qE '^(feat|fix|docs|chore|refactor|ci|perf|style|test|build|revert)(\\(.+\\))?!?: .+' || exit 1"
|
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; }
|
||||||
|
|||||||
@ -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_LEFTHOOK: &str = include_str!("../../resources/onboarding/lefthook.yml.tmpl");
|
||||||
const TMPL_GIT_WORKFLOW: &str = include_str!("../../resources/onboarding/git-workflow.md.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_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)]
|
#[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_one(root, "lefthook.yml", TMPL_LEFTHOOK),
|
||||||
dispatch_versioned(root, "docs/ai-context/git-workflow.md", TMPL_GIT_WORKFLOW),
|
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/commands/envoy.md", TMPL_ENVOY),
|
||||||
|
dispatch_one(root, ".claude/hooks/blueprint-gate.cjs", TMPL_BLUEPRINT_GATE),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user