#!/usr/bin/env python3 """daemon-selfcheck.py — 桌面小幫手(daemon)本機狀態自檢,唯讀。 為什麼有這支(leo 2026-08-19): 「現在本機的資料夾跟雲端已經不相連了。」 這句話有好幾種可能的形狀,而它們的處置完全不同: ① 帳號指的那台實例被重裝過(網址沒變、鑰匙換了) ← arcrun-rag#103 ② 監看資料夾在本機被搬走/改名/刪掉 ③ 資料夾是空的,雲端因此「什麼都沒有」 ← arcrun-rag#106 ④ 真的連不上網路 這支不猜,只把**分得出這四種**的事實印出來。 🔴 唯讀:不寫任何檔、不連網、不印任何金鑰(api_key/gemini_api_key 一律過濾)。 用法: python3 scripts/daemon-selfcheck.py # 看 ~/.arcrun-rag/ python3 scripts/daemon-selfcheck.py /some/home # 指定家目錄(測試用) """ import json,glob,os,sys H=os.path.expanduser(sys.argv[1] if len(sys.argv)>1 else "~") D=os.path.join(H,".arcrun-rag") SECRET={"api_key","gemini_api_key","password","token"} def acc(a): return {k:v for k,v in a.items() if k not in SECRET and not isinstance(v,(dict,list))} print("狀態目錄:",D, "存在" if os.path.isdir(D) else "❌ 不存在") try: c=json.load(open(os.path.join(D,"config.json"))) except Exception as e: print("config.json 讀不到:",e); c={} accs=c.get("accounts") or ([{k:c.get(k) for k in ("cypher_url","namespace","email","instance_name")}] if c.get("cypher_url") else []) print("\n帳號 %d 個:"%len(accs)) for a in accs: print(" -",acc(a)) print("\n監看資料夾:") for f in (c.get("watch_folders") or ([c["watch_folder"]] if c.get("watch_folder") else [])): print(" -",f, "(本機存在)" if os.path.isdir(os.path.expanduser(f)) else "(❌ 本機找不到)") for a in accs: for f in (a.get("watch_folders") or []): print(" -",f,"[帳號 %s]"%a.get("instance_name",""), "(本機存在)" if os.path.isdir(os.path.expanduser(f)) else "(❌ 本機找不到)") print("\n機器身分:") try: print(" ",json.load(open(os.path.join(D,"machine.json")))) except Exception as e: print(" machine.json 沒有或讀不到:",e,"(⇒ 這台還沒鑄過機器 ID,或 daemon 還沒跑過 0.18.33)") print("\nmanifest 的最後錯誤(每份只印一種):") for p in sorted(glob.glob(os.path.join(D,"manifest*.json"))): try: m=json.load(open(p)) except Exception as e: print(" ",os.path.basename(p),"讀不到",e); continue errs={} for k,v in (m.get("entries") or {}).items(): e=(v or {}).get("last_error") or "" if e: errs[e]=errs.get(e,0)+1 print(" ",os.path.basename(p),"root=",m.get("root"),"檔數=",len(m.get("entries") or {})) if not errs: print(" (無錯誤)") for e,n in sorted(errs.items(),key=lambda x:-x[1])[:3]: print(" x%d %s"%(n,e[:160]))