#!/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\` 智能提交"