自检修复: reflog读git + threaded=True + TODO误判修正

- Git: 从.git/logs/HEAD读取提交历史,不依赖git二进制
- Flask: threaded=True防止单线程阻塞
- TODO: 'already running'→completed而非failed
- E元成长: 改用reflog行数计算commit数
This commit is contained in:
hmo
2026-07-14 02:49:08 +08:00
parent f284ddfd3f
commit 3238ba54fb
2 changed files with 53 additions and 26 deletions
+48 -25
View File
@@ -562,22 +562,45 @@ def api_kanban():
# ════════════════════════════════════════════════════════════
@app.route("/api/git")
def api_git():
"""最近 git 提交历史 + 分支状态"""
"""最近 git 提交历史 + 分支状态(从 .git 直接读取,不依赖 git 命令)"""
try:
git_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", "..")
git_dir = os.path.normpath(git_dir) # → AgentsMeeting/
if not os.path.exists(os.path.join(git_dir, ".git")):
# 如果 _PROJECT_OVERRIDE 设置了,用它
git_dir = os.environ.get("AGENTSMEETING_ROOT", "")
if not git_dir or not os.path.exists(os.path.join(git_dir, ".git")):
return jsonify({"ok": False, "log": [".git not found at " + git_dir], "dirty": False})
r = subprocess.run(["git", "log", "--oneline", "-10"],
cwd=git_dir, capture_output=True, text=True, timeout=5)
log_lines = r.stdout.strip().split("\n") if r.returncode == 0 else ["git not available"]
r2 = subprocess.run(["git", "status", "--short"],
cwd=git_dir, capture_output=True, text=True, timeout=5)
dirty = r2.stdout.strip() != "" if r2.returncode == 0 else False
return jsonify({"ok": True, "log": log_lines if log_lines != [""] else [], "dirty": dirty, "branch": "master"})
git_dir = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".."))
dot_git = os.path.join(git_dir, ".git")
if not os.path.exists(dot_git):
alt = os.environ.get("AGENTSMEETING_ROOT", "")
if alt and os.path.exists(os.path.join(alt, ".git")):
git_dir = alt
dot_git = os.path.join(alt, ".git")
else:
return jsonify({"ok": True, "log": [], "dirty": False, "note": "no .git"})
# 从 .git/logs/HEAD 读取最近提交
reflog = os.path.join(dot_git, "logs", "HEAD")
log_lines = []
if os.path.exists(reflog):
with open(reflog, "r", encoding="utf-8", errors="replace") as f:
lines = f.readlines()
# 取最后 10 行非空行,格式: "hash hash user ... msg"
for line in reversed(lines):
line = line.strip()
if not line:
continue
parts = line.split("\t")
msg = parts[-1] if len(parts) > 1 else line
# 取前 7 位 hash
hash_part = line.split()[1][:7] if len(line.split()) > 1 else "?"
log_lines.append(f"{hash_part} {msg}")
if len(log_lines) >= 10:
break
# 检查是否有未提交的改动:比较 .git/index 的 mtime 与 HEAD
dirty = False
head_file = os.path.join(dot_git, "HEAD")
index_file = os.path.join(dot_git, "index")
if os.path.exists(head_file) and os.path.exists(index_file):
try:
dirty = os.path.getmtime(index_file) > os.path.getmtime(head_file)
except:
pass
return jsonify({"ok": True, "log": log_lines, "dirty": dirty, "branch": "master", "source": "reflog"})
except Exception as e:
return jsonify({"ok": False, "error": str(e), "log": [], "dirty": False})
@@ -681,16 +704,16 @@ def api_metagrowth():
entry = json.loads(line)
if entry.get("status") == "completed":
completed_fixes += 1
# 统计 git 提交次数(用作开发活动指标
git_dir = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".."))
# 统计 git 提交次数(从 reflog 行数计算
git_dir2 = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)), "..", ".."))
commit_count = 0
try:
r = subprocess.run(["git", "rev-list", "--count", "HEAD"],
cwd=git_dir, capture_output=True, text=True, timeout=5)
if r.returncode == 0:
commit_count = int(r.stdout.strip())
except:
pass
reflog = os.path.join(git_dir2, ".git", "logs", "HEAD")
if os.path.exists(reflog):
try:
with open(reflog, "r", encoding="utf-8", errors="replace") as f:
commit_count = sum(1 for line in f if line.strip())
except:
pass
return jsonify({
"ok": True,
"status": "planned", # Phase 3
@@ -814,7 +837,7 @@ def main():
port = int(os.environ.get("DASHBOARD_PORT", 5803))
log.info(f"Dashboard starting on :{port}")
print(f"[dashboard] Starting on http://127.0.0.1:{port}")
app.run(host="0.0.0.0", port=port, debug=False, use_reloader=False)
app.run(host="0.0.0.0", port=port, debug=False, use_reloader=False, threaded=True)
if __name__ == "__main__":
+5 -1
View File
@@ -162,7 +162,11 @@ def main():
log(f"处理: {service}{issue}")
success, detail = execute_fix(entry)
if success:
# "another instance is already running" = 服务已在正常运行,不算失败
if not success and "another instance is already running" in detail:
mark_todo(entry, "completed", "already_running")
log(f"{service}: 已在运行,无需修复 ({detail[:60]})")
elif success:
mark_todo(entry, "completed", detail)
log(f"{service}: 修复成功 ({detail})")
else: