fix(t91+t92): 萃取狀態可見+Finder 啟動 PATH 修正——背景執行不可見的兩題同根一起解
leo 07-28 實測根因:Finder 起的 GUI app 只有最小 PATH(無 /opt/homebrew/bin) → claude 靜默找不到→整輪萃取失敗,托盤卻顯示「看守中」。leo:「我怎麼知道它有萃?」 - FindClaudeBin:LookPath 失敗後掃 4 個常見絕對路徑,找到回寫 config claude_bin - CheckExtractor 預檢+每輪寫 ~/.arcrun-rag/status.json(ok/fail 計數+失敗清單) - 托盤:引擎未就緒→「⚠ 萃取引擎未就緒:<白話原因>」;失敗>0→可點開明細;正常→「已萃 N 檔」 測試:collector+supervisor+tray 三模組 go test 全綠(總管親跑)。 (實作=子 CC;驗證+commit=總管)
This commit is contained in:
+48
-7
@@ -16,9 +16,51 @@ import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// claudeFallbackPaths 是 PATH 找不到 claude 時依序嘗試的絕對路徑清單。
|
||||
// Finder 啟動的 GUI app 只拿最小 PATH(/usr/bin:/bin 等),brew 裝的 claude 在此找不到(t92)。
|
||||
// 測試可覆蓋此變數注入暫存目錄,無需真的安裝 Claude Code。
|
||||
var claudeFallbackPaths = defaultClaudeFallbackPaths()
|
||||
|
||||
func defaultClaudeFallbackPaths() []string {
|
||||
home, _ := os.UserHomeDir()
|
||||
paths := []string{
|
||||
"/opt/homebrew/bin/claude",
|
||||
"/usr/local/bin/claude",
|
||||
}
|
||||
if home != "" {
|
||||
paths = append(paths,
|
||||
filepath.Join(home, ".local", "bin", "claude"),
|
||||
filepath.Join(home, ".claude", "local", "claude"),
|
||||
)
|
||||
}
|
||||
return paths
|
||||
}
|
||||
|
||||
// FindClaudeBin 找可執行的 claude 二進位:先試 hint(空="claude")在 PATH;
|
||||
// 找不到再依序掃 claudeFallbackPaths(解決 Finder 啟動 app PATH 不含 /opt/homebrew/bin 的問題)。
|
||||
// 回傳完整絕對路徑,或「全都找不到」的白話錯誤。
|
||||
func FindClaudeBin(hint string) (string, error) {
|
||||
if hint == "" {
|
||||
hint = "claude"
|
||||
}
|
||||
if p, err := exec.LookPath(hint); err == nil {
|
||||
return p, nil
|
||||
}
|
||||
for _, p := range claudeFallbackPaths {
|
||||
info, err := os.Stat(p)
|
||||
if err == nil && !info.IsDir() && info.Mode()&0o111 != 0 {
|
||||
return p, nil
|
||||
}
|
||||
}
|
||||
tried := append([]string{hint}, claudeFallbackPaths...)
|
||||
return "", fmt.Errorf("找不到 Claude 指令(試了 %s)——請確認 Claude Code 已安裝,或改用 Gemma 萃取路",
|
||||
strings.Join(tried, "、"))
|
||||
}
|
||||
|
||||
// cardsRelDir 是 template 規約的卡片產物區(相對監看根)。
|
||||
const cardsRelDir = "system-dev/wiki/cards"
|
||||
|
||||
@@ -55,13 +97,12 @@ func diffCards(before, after map[string]fileState) []string {
|
||||
const claudeExtractTimeout = 10 * time.Minute
|
||||
|
||||
// ExtractWithClaude 叫起用戶自己的 claude 跑 template 的 /rag-extract-file(task 3)。
|
||||
// binPath 空="claude"(PATH 尋找)。回傳本次產出的卡片相對路徑。
|
||||
// binPath 空或 PATH 找不到時,自動掃 claudeFallbackPaths(t92 Finder 啟動 PATH 不完整)。
|
||||
// 回傳本次產出的卡片相對路徑。
|
||||
func ExtractWithClaude(binPath, absRoot, relPath string) ([]string, error) {
|
||||
if binPath == "" {
|
||||
binPath = "claude"
|
||||
}
|
||||
if _, err := exec.LookPath(binPath); err != nil {
|
||||
return nil, fmt.Errorf("找不到 claude 執行檔(%s):%w——請確認已安裝 Claude Code,或改用 gemma 萃取路", binPath, err)
|
||||
resolved, err := FindClaudeBin(binPath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
before := snapshotCards(absRoot)
|
||||
|
||||
@@ -70,7 +111,7 @@ func ExtractWithClaude(binPath, absRoot, relPath string) ([]string, error) {
|
||||
// /rag-extract-file=template 既有萃取 skill;cwd=監看根(template 已代裝,skill 就在 .claude/commands/)。
|
||||
// --permission-mode acceptEdits:headless 無人按核准,寫卡會卡在權限確認(07-24 真機 e2e 實撞);
|
||||
// acceptEdits 只自動放行檔案編輯、不放行任意 Bash,範圍侷限在監看根(cwd)。
|
||||
cmd := exec.CommandContext(ctx, binPath, "-p", fmt.Sprintf("/rag-extract-file %s", relPath), "--permission-mode", "acceptEdits")
|
||||
cmd := exec.CommandContext(ctx, resolved, "-p", fmt.Sprintf("/rag-extract-file %s", relPath), "--permission-mode", "acceptEdits")
|
||||
cmd.Dir = absRoot
|
||||
out, err := cmd.CombinedOutput()
|
||||
if ctx.Err() == context.DeadlineExceeded {
|
||||
|
||||
Reference in New Issue
Block a user