log-cross-module.sh
3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#!/usr/bin/env bash
# PostToolUse hook: 检测 Edit/Write 是否触及"当前模块以外"的模块路径,若是则在当前模块的跨模块日志中留痕(软规则 S2)。
# 注:原设计基于"已勾 [x] 模块"触发,但 docs/08 § 二 的 checkbox 永远保持 `- [ ]`(完成由 MR merged state 判定);
# 新判定按"非当前模块"触发——CC 在当前模块开发期间改动其他模块(无论是否已 merged)都应留痕。
set -euo pipefail
input="$(cat)"
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty')"
case "$tool_name" in Edit|Write) ;; *) exit 0 ;; esac
file_path="$(printf '%s' "$input" | jq -r '.tool_input.file_path // empty')"
[ -n "$file_path" ] || exit 0
project_dir="${CLAUDE_PROJECT_DIR:-$(pwd)}"
docs08="$project_dir/docs/08-模块任务管理.md"
[ -f "$docs08" ] || exit 0
# 跳过 docs/08 自身的改动(元数据文件编辑不是代码跨模块改动,不触发 S2)
case "$file_path" in *"/docs/08-模块任务管理.md") exit 0 ;; esac
# 当前模块 = 当前 git 分支名去掉 `module-` 前缀。
# erp-module-start 步骤 3 保证模块循环期间处于 module-<id> 分支;
# 非 module-* 分支(如 main、feature/*、docs/*)不在模块循环内,不触发 S2 留痕。
current_branch="$(cd "$project_dir" 2>/dev/null && git branch --show-current 2>/dev/null || echo '')"
case "$current_branch" in
module-*) current_module="${current_branch#module-}" ;;
*) exit 0 ;;
esac
[ -n "$current_module" ] || exit 0
# 遍历所有 `- module_X` 行(docs/08 § 二 的所有模块,纯 bullet 无 checkbox),
# 提取 module_id 和其下的"路径:"行。
# docs/08 § 二 的模块块结构:
# - module_0 <name>
# - 依赖: ...
# - 路径: backend/module/xxx/, frontend/pages/xxx/
# - MR: !N 或 —
hit_module=""
# 用 awk 逐模块解析:每碰到 `- module_` 记录 module_id($2),然后在其下找第一个 `- 路径:` 行
# current_module 已在上文计算,在外层循环被排除 → 只会命中"非当前模块"的路径
while IFS=$'\t' read -r mod paths; do
[ "$mod" = "$current_module" ] && continue
IFS=',' read -ra scope_arr <<< "$paths"
for s in "${scope_arr[@]}"; do
s="$(echo "$s" | sed 's/^[[:space:]]*//; s/[[:space:]]*$//; s:/$::')"
[ -z "$s" ] && continue
case "$file_path" in *"$s"*) hit_module="$mod"; break 2;; esac
done
done < <(awk '
/^- module_/ {
# `- module_xxx <name>` awk 默认分词:$1=-、$2=module_xxx、$3=<name>
mod=$2
next
}
mod && /^[[:space:]]*- 路径:/ {
sub(/^[[:space:]]*- 路径:[[:space:]]*/,"")
print mod "\t" $0
mod=""
}
/^- module_/ && mod { mod="" }
' "$docs08")
[ -n "$hit_module" ] || exit 0
log_dir="$project_dir/docs/superpowers/module-reports"
mkdir -p "$log_dir"
log_file="$log_dir/${current_module}-cross-module.md"
if [ ! -f "$log_file" ]; then
{
echo "# 跨模块改动日志 — ${current_module}"
echo ""
echo "| 时间戳 | 目标模块 | 文件 | 改动摘要 | 原因 | 影响评估 |"
echo "|---|---|---|---|---|---|"
} > "$log_file"
fi
ts="$(date -u +%FT%TZ)"
rel_path="${file_path#$project_dir/}"
echo "| ${ts} | ${hit_module} | ${rel_path} | ${tool_name} | TBD(CC 补) | TBD(CC 补) |" >> "$log_file"
jq -n --arg m "$hit_module" --arg f "$log_file" --arg p "$rel_path" \
'{hookSpecificOutput:{hookEventName:"PostToolUse",additionalContext:("跨模块改动检测:\($p) 属于模块 [\($m)](非当前模块)。存根已写入 \($f),含 TBD(CC 补) 占位。请由 CC 调用 erp-cross-module-log skill 自主推断并补填原因与影响评估(软规则 S2,CC 自主维护,非人工填写)。")}}'