feat: 融合 devflow-claude P0 批机制 (REQ-20260416-0017)

P0-1: SessionStart Hook — hooks/session-context.sh
  从分支名解析 REQ-ID,调 MCP API 查询需求详情注入 system-reminder

P0-2: PreToolUse Hook — hooks/pre-tool-confirm.sh
  拦截生产推送、force push、docker prod 容器操作、git reset --hard 等

P0-3: Release Draft 闸门设计文档 — docs/design/release-draft-gate.md
  完整架构 + 渐进式落地路径(拆 7 个子任务延后)
  附最小可用脚本 hooks/release-draft.sh 创建 Gitea draft release

P0-4: Memory 隔离规则 — 写入 req-prd / req-design / req-workflow
  禁止 auto-memory 污染模板产出物(章节结构、字段定义、文档结构)

P0-5: CLAUDE.md 架构检查 + 架构片段库
  dev-coding skill 执行前检查架构关键词
  新增 templates/claude-md-snippets/ 含 Go+Gin / React+AntD / Vue+Element /
  MCP+TS / generic 五套骨架

P0-6: /commit 分支保护自动化 — 新 skill dev-commit-plugin
  保护分支自动建功能分支 + Conventional Commits + REQ-XXX 自动关联

安装:
  bash hooks/install.sh

后续:
  P0-3 完整实现拆 7 个子任务(P0-3.1 ~ P0-3.7)
  建议先部署 hooks 跑 1-2 周观察,再推进 Release 机制落地
This commit is contained in:
2026-04-16 21:02:29 +09:30
parent bfe3815626
commit 23ea8fdca5
18 changed files with 1433 additions and 0 deletions

130
hooks/session-context.sh Executable file
View File

@@ -0,0 +1,130 @@
#!/bin/bash
# session-context.sh
# SessionStart Hook: 会话启动时自动注入需求上下文
#
# 从当前 Git 分支名解析 REQ-ID调用 ai-proj MCP API 查询需求详情,
# 把标题 / 状态 / delivery_stage / reviewer / 进行中需求数注入 system-reminder。
#
# 安装方式:
# 在 ~/.claude/settings.json 的 hooks.SessionStart 配置:
# {
# "command": "/Users/donglinlai/coding/qiudl/ai-proj-helper/hooks/session-context.sh",
# "timeout": 10
# }
#
# 参考devflow-claude 同名脚本 + ai-proj MCP 适配
# REQ-20260416-0017 P0-1
set -e
# 仅在 git 仓库内执行
if ! git rev-parse --git-dir >/dev/null 2>&1; then
exit 0
fi
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null)
if [ -z "$REPO_ROOT" ]; then
exit 0
fi
cd "$REPO_ROOT"
# ============ 1. 当前分支 → REQ ID ============
BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null || echo "")
REQ_ID=""
if [ -n "$BRANCH" ]; then
# 匹配 feat/REQ-20260416-0017-xxx / fix/REQ-20260416-0017 / feature/req-20260416-0017
REQ_ID=$(echo "$BRANCH" | grep -oiE 'REQ-[0-9]{8}-[0-9]{4}' | head -1 | tr '[:lower:]' '[:upper:]')
fi
# ============ 2. 无 REQ 时仅输出分支信息(静默退出条件) ============
if [ -z "$REQ_ID" ]; then
# 只要不在 main/develop 上就提示一下
case "$BRANCH" in
main|master|develop|"") exit 0 ;;
esac
echo "# 会话上下文"
echo ""
echo "- 当前分支: \`${BRANCH}\`(未检测到 REQ ID"
exit 0
fi
# ============ 3. 查询 MCP API ============
# MCP API 通过 localhost:8080 直连ai-proj 本地后端)或 ai-proj-prod
# 这里优先读项目根的 .ai-proj-env 决定环境
API_BASE="${AI_PROJ_API_BASE:-}"
API_TOKEN="${AI_PROJ_MCP_KEY:-}"
if [ -f "$REPO_ROOT/.ai-proj-env" ]; then
# shellcheck disable=SC1091
source "$REPO_ROOT/.ai-proj-env"
fi
if [ -z "$API_BASE" ]; then
# 默认走本地 dev
API_BASE="http://localhost:8080"
fi
# 查询需求
RESP=""
if command -v curl >/dev/null 2>&1; then
if [ -n "$API_TOKEN" ]; then
RESP=$(curl -s --max-time 3 -H "X-MCP-API-Key: $API_TOKEN" \
"${API_BASE}/api/v1/mcp/requirements/by-display-id/${REQ_ID}" 2>/dev/null || echo "")
else
RESP=$(curl -s --max-time 3 \
"${API_BASE}/api/v1/mcp/requirements/by-display-id/${REQ_ID}" 2>/dev/null || echo "")
fi
fi
# ============ 4. 解析并输出 ============
echo "# 需求上下文SessionStart Hook"
echo ""
echo "- 分支: \`${BRANCH}\`"
echo "- 需求: **${REQ_ID}**"
if [ -n "$RESP" ] && command -v python3 >/dev/null 2>&1; then
# 尝试用 python 解析
PARSED=$(python3 -c "
import sys, json
try:
d = json.loads('''$RESP''')
data = d.get('data', {})
if not data:
sys.exit(0)
title = data.get('title', '?')
status = data.get('status', '?')
stage = data.get('delivery_stage', '?')
priority = data.get('priority', '?')
project = data.get('project_name', '?')
print(f'title={title}')
print(f'status={status}')
print(f'stage={stage}')
print(f'priority={priority}')
print(f'project={project}')
except Exception:
pass
" 2>/dev/null)
if [ -n "$PARSED" ]; then
TITLE=$(echo "$PARSED" | grep '^title=' | sed 's/^title=//')
STATUS=$(echo "$PARSED" | grep '^status=' | sed 's/^status=//')
STAGE=$(echo "$PARSED" | grep '^stage=' | sed 's/^stage=//')
PRIORITY=$(echo "$PARSED" | grep '^priority=' | sed 's/^priority=//')
PROJECT=$(echo "$PARSED" | grep '^project=' | sed 's/^project=//')
[ -n "$TITLE" ] && echo "- 标题: ${TITLE}"
[ -n "$PROJECT" ] && echo "- 项目: ${PROJECT}"
[ -n "$STATUS" ] && echo "- 状态: ${STATUS}"
[ -n "$STAGE" ] && echo "- 交付阶段: ${STAGE}"
[ -n "$PRIORITY" ] && echo "- 优先级: ${PRIORITY}"
else
echo "- 📡 MCP API 响应为空或未授权API_BASE=${API_BASE}"
fi
else
echo "- ⚠️ 无法连接 MCP API${API_BASE}),仅显示分支信息"
fi
echo ""
echo "💡 相关命令:\`/req get ${REQ_ID}\` 查看详情 · \`/commit\` 智能提交"