c2638668e3
leo 2026-08-20:「同一個 plugin 你用,薄殼也用,保證兩邊同步」
「我要你幫雲端做薄殼,永遠都有問題,你要做的就是這組設定
你自己可以 dogfooding」
搬進來:41 支 hook(51 條註冊)/7 支 command/2 支 skill/23 支腳本。
不搬 .env、wiki、docs——那些是知識不是環境。
51 條 hook 路徑全部從 $CLAUDE_PROJECT_DIR/.claude/hooks/ 改成 ${CLAUDE_PLUGIN_ROOT}/hooks/,
零漏網。那正是薄殼一直壞掉的根:雲端 cwd 不是真身,寫死路徑就斷。
尚未驗證:Claude Code 能不能從私有 Gitea repo 裝 marketplace(要憑證)。
下一步就是在本機實際裝一次,通了才動雲端 bootstrap.sh。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
51 lines
2.8 KiB
Python
Executable File
51 lines
2.8 KiB
Python
Executable File
#!/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]))
|