This commit is contained in:
zlwu committed 2026-05-20 09:28:36 +08:00
1 parent e6072457fd
commit be4fab78e1
578 files changed
+174415 -214

No files matched your search

+15
View File
@@ -0,0 +1,15 @@
#!/bin/bash
# Post-commit hook: 增量更新知识图谱(仅当 backend/app/ 或 web-admin/src/ 有变化时)
# 安装: cp scripts/post-commit-graph.sh .git/hooks/post-commit
CHANGED=$(git diff-tree --no-commit-id --name-only -r HEAD)
if echo "$CHANGED" | grep -q "^backend/app/"; then
echo "[graphify] 检测到后端代码变更,更新图谱..."
"$(dirname "$0")/../../scripts/update-graph.sh" backend 2>/dev/null &
fi
if echo "$CHANGED" | grep -q "^web-admin/src/"; then
echo "[graphify] 检测到前端代码变更,更新图谱..."
"$(dirname "$0")/../../scripts/update-graph.sh" frontend 2>/dev/null &
fi
+201
View File
@@ -0,0 +1,201 @@
#!/bin/bash
# update-graph.sh — 增量更新知识图谱
# 用法:
# ./scripts/update-graph.sh # 更新前后端
# ./scripts/update-graph.sh backend # 只更新后端
# ./scripts/update-graph.sh frontend # 只更新前端
#
# 由 AI Agent 在完成代码修改后自动调用,或手动执行。
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
PYTHON=""
# 检测 graphify 使用的 Python 解释器
detect_python() {
local graphify_out="$1/graphify-out/.graphify_python"
if [ -f "$graphify_out" ]; then
PYTHON="$(cat "$graphify_out")"
else
PYTHON="python3"
fi
}
# 检查 graphify 是否安装
check_graphify() {
if ! "$PYTHON" -c "import graphify" 2>/dev/null; then
echo "[graphify] 未安装,正在安装..."
"$PYTHON" -m pip install graphifyy -q 2>/dev/null || "$PYTHON" -m pip install graphifyy -q --break-system-packages 2>&1 | tail -3
fi
}
# 增量更新单个项目的图谱
update_graph() {
local name="$1"
local src_dir="$2"
local label="$3"
echo ""
echo "=== 更新 ${label} 知识图谱 (${src_dir}) ==="
detect_python "$ROOT_DIR/$name"
check_graphify
cd "$ROOT_DIR/$name"
local detect_json="graphify-out/.graphify_detect.json"
local manifest_json="graphify-out/manifest.json"
if [ ! -f "$manifest_json" ]; then
echo "[graphify] 未找到 manifest.json,跳过增量更新(首次需运行完整构建)"
return 0
fi
# 运行增量检测
"$PYTHON" -c "
import sys, json
from graphify.detect import detect_incremental, save_manifest
from pathlib import Path
result = detect_incremental(Path('${src_dir}'))
new_total = result.get('new_total', 0)
Path('graphify-out/.graphify_incremental.json').write_text(json.dumps(result))
print(f'{new_total} file(s) changed since last run.')
if new_total == 0:
print('SKIP: Nothing to update.')
sys.exit(0)
"
# 如果没有变化,跳过
local changed=$?
if [ $changed -ne 0 ]; then
return 0
fi
# 检查是否只是代码变更
"$PYTHON" -c "
import json
from pathlib import Path
result = json.loads(Path('graphify-out/.graphify_incremental.json').read_text())
code_exts = {'.py','.ts','.js','.vue','.go','.rs','.java','.cpp','.c','.rb','.swift','.kt','.cs','.scala','.php','.cc','.cxx','.hpp','.h','.kts'}
new_files = result.get('new_files', {})
all_changed = [f for files in new_files.values() for f in files]
code_only = all(Path(f).suffix.lower() in code_exts for f in all_changed) if all_changed else True
print('code_only:', code_only)
" 2>/dev/null
# AST 提取
"$PYTHON" -c "
import sys, json
from graphify.extract import collect_files, extract
from graphify.build import build_from_json
from graphify.cluster import cluster, score_all
from graphify.analyze import god_nodes, surprising_connections, suggest_questions
from graphify.report import generate
from graphify.export import to_json, to_html
from pathlib import Path
extraction = json.loads(Path('graphify-out/.graphify_extract.json').read_text()) if Path('graphify-out/.graphify_extract.json').exists() else None
if extraction is None:
print('ERROR: No existing extraction found. Run full build first.')
sys.exit(1)
# Re-extract AST for all code files (fast, deterministic)
from graphify.detect import detect
detection = detect(Path('${src_dir}'))
Path('graphify-out/.graphify_detect.json').write_text(json.dumps(detection))
code_files = []
for f in detection.get('files', {}).get('code', []):
code_files.extend(collect_files(Path(f)) if Path(f).is_dir() else [Path(f)])
if code_files:
result = extract(code_files)
Path('graphify-out/.graphify_extract.json').write_text(json.dumps(result, indent=2))
print(f'AST: {len(result[\"nodes\"])} nodes, {len(result[\"edges\"])} edges')
else:
print('No code files found.')
sys.exit(1)
# Build graph
G = build_from_json(result)
communities = cluster(G)
cohesion = score_all(G, communities)
tokens = {'input': 0, 'output': 0}
gods = god_nodes(G)
surprises = surprising_connections(G, communities)
# Try to load existing labels
labels = {}
labels_path = Path('graphify-out/.graphify_labels.json')
if labels_path.exists():
labels_raw = json.loads(labels_path.read_text())
labels = {int(k): v for k, v in labels_raw.items()}
else:
labels = {cid: f'Community {cid}' for cid in communities}
questions = suggest_questions(G, communities, labels)
# Generate outputs
report = generate(G, communities, cohesion, labels, gods, surprises, detection, tokens, '${src_dir}', suggested_questions=questions)
Path('graphify-out/GRAPH_REPORT.md').write_text(report)
to_json(G, communities, 'graphify-out/graph.json')
# Save analysis for labels
analysis = {
'communities': {str(k): v for k, v in communities.items()},
'cohesion': {str(k): v for k, v in cohesion.items()},
'gods': gods,
'surprises': surprises,
}
Path('graphify-out/.graphify_analysis.json').write_text(json.dumps(analysis, indent=2))
Path('graphify-out/.graphify_labels.json').write_text(json.dumps({str(k): v for k, v in labels.items()}))
# Generate HTML
to_html(G, communities, 'graphify-out/graph.html', community_labels=labels or None)
# Save manifest
from graphify.detect import save_manifest
save_manifest(detection['files'])
print(f'Graph updated: {G.number_of_nodes()} nodes, {G.number_of_edges()} edges, {len(communities)} communities')
print(f'Report: graphify-out/GRAPH_REPORT.md')
" || {
echo "[graphify] 增量更新失败"
return 1
}
# Cleanup temp files
rm -f graphify-out/.graphify_detect.json graphify-out/.graphify_extract.json graphify-out/.graphify_ast.json graphify-out/.graphify_incremental.json graphify-out/.graphify_analysis.json graphify-out/.graphify_labels.json
cd "$ROOT_DIR"
echo "[graphify] ${label} 图谱更新完成 ✓"
}
# ---- Main ----
TARGET="${1:-all}"
echo "╔══════════════════════════════════════╗"
echo "║ zkxw 知识图谱增量更新工具 ║"
echo "╚══════════════════════════════════════╝"
case "$TARGET" in
backend)
update_graph "backend" "app" "后端"
;;
frontend)
update_graph "web-admin" "src" "前端"
;;
all|"")
update_graph "backend" "app" "后端"
update_graph "web-admin" "src" "前端"
;;
*)
echo "用法: $0 [backend|frontend|all]"
exit 1
;;
esac
echo ""
echo "✅ 知识图谱更新完毕。HTML 可视化: */graphify-out/graph.html"