#!/bin/bash # validate-prd.sh # PostToolUse Hook: PRD 文档写入/编辑后自动校验章节完整性 # # 检查标准 PRD 模板的必需章节是否存在。 # 借鉴 devflow-claude validate-requirement.sh。 # REQ-20260416-0017 P1-14 # # 安装方式(可选,加到 ~/.claude/settings.json): # hooks.PostToolUse: # - matcher: "Write|Edit" # hooks: # - type: command # command: "/hooks/validate-prd.sh" # timeout: 5 # # 也可由 skill 脚本在 PRD 写完后手动调用: # bash validate-prd.sh /path/to/PRD.md set -e # ============ 1. 获取文件路径 ============ FILE_PATH="$1" # 如果没有参数,从 stdin JSON 提取(PostToolUse hook 模式) if [ -z "$FILE_PATH" ] && command -v jq >/dev/null 2>&1; then INPUT=$(cat 2>/dev/null || echo "") if [ -n "$INPUT" ]; then FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.content // empty' 2>/dev/null) fi fi # 没有文件路径,静默退出 if [ -z "$FILE_PATH" ]; then exit 0 fi # 不是 .md 文件,跳过 case "$FILE_PATH" in *.md) ;; *) exit 0 ;; esac # 文件不存在,跳过 if [ ! -f "$FILE_PATH" ]; then exit 0 fi # 不含 PRD / 需求 关键词的文件名,跳过 BASENAME=$(basename "$FILE_PATH") case "$BASENAME" in *PRD*|*prd*|*需求*|*requirement*|*REQ*) ;; *) exit 0 ;; esac # ============ 2. 检查章节 ============ # 标准 PRD 必需章节(来自 req-prd SKILL.md 的模板) REQUIRED_SECTIONS=( "## 1. 概述" "### 1.1 背景" "### 1.2 目标" "### 1.4 客户原始诉求" "## 2. 用户分析" "## 3. 功能需求" "## 4. 交互设计" "## 5. 技术要求" "## 6. 上线计划" "## 7. 风险评估" ) MISSING=() CONTENT=$(cat "$FILE_PATH") for section in "${REQUIRED_SECTIONS[@]}"; do # 模糊匹配:忽略空格差异和标点 PATTERN=$(echo "$section" | sed 's/[[:space:]]*//g') CONTENT_CLEAN=$(echo "$CONTENT" | sed 's/[[:space:]]*//g') if ! echo "$CONTENT_CLEAN" | grep -qi "$(echo "$PATTERN" | sed 's/#//g')"; then MISSING+=("$section") fi done # ============ 3. 输出 ============ if [ ${#MISSING[@]} -gt 0 ]; then echo "" echo "⚠️ PRD 章节检查:${BASENAME}" echo "" echo "缺少 ${#MISSING[@]} 个必需章节:" for m in "${MISSING[@]}"; do echo " ❌ $m" done echo "" echo "💡 请参考 req-prd skill 的 PRD 模板补充缺失章节。" echo " 章节结构不可变:不得新增、删除、合并或重命名模板中的章节。" fi exit 0