3 Commits

Author SHA1 Message Date
Leo 0c6fb43117 fix(t213): 診斷檔遮蔽引擎錯誤訊息裡的本機絕對路徑
engine.detail/engine.last_error 在同步引擎沒在跑時,會把 collector 開機
橫幅的完整原文帶出來(direct.go RunDirect 的「監看 %s → %s」那行),其中
含監看資料夾的絕對路徑(如 /Users/xxx/Desktop/...)。這是上一輪(第二/
三輪)已發現但標記「附帶發現、未修」的洞——首頁在同一狀態下本來就會顯示
同一句話(不動,留給另案判斷),但診斷檔現在會被匯出成檔案交給外部人看,
風險層級跟留在托盤畫面上不同,這輪把它遮掉。

新增 redactLocalPaths(),只在 buildDiagnosticsPayload() 組裝 engine 欄位時
套用:把訊息裡看起來像本機絕對路徑的片段換成「…/<路徑最後一截>」,
http(s) URL 先放行原文(避免 URL 裡的 / 被誤判成本機路徑)。只動
diagnostics_export.go 這一端,不改 describeStatus()/collectorFailure()/
direct.go 的訊息本身——那些同時是首頁托盤畫面在用的同一組憑據。

擴充 diagnostics_engine_e2e_test.go(真執行檔+真 supervisor 子行程,零
網路零帳號):監看資料夾改用真實絕對路徑,證明子行程停擺後整份匯出 JSON
找不到該路徑,同時 last_error/detail 仍讀得出「引擎沒在跑、以及為什麼」
(含監看資料夾的名字)。另加 8 個 redactLocalPaths 純函式單測。

go build/go vet/go test ./...(collector+arcrun-app+supervisor 三個
package)全綠;diagnostics_stage_manual_test.go 維持預設 SKIP,本輪未碰
網路/stage。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 16:36:20 +08:00
Leo 8baa9170da feat(t213): 診斷檔補 engine 區塊,補上考卷 Q2「還在不在跑」缺口
pending=0 以前只能證明「現在沒有排隊的」,證明不了「真的做完了」還是
「daemon 早就掛了沒人知道」——因為診斷檔完全沒有時間資訊。

local.engine 不發明第二套判斷法:直接借用首頁狀態列本來就在用的
collectorAlive()/collectorSyncing()/collectorFailure()/describeStatus(),
只是把這些憑據也寫進 JSON(alive/syncing/crash_looping/headline/detail/
last_sync/last_activity_at/seconds_since_last_sync)。last_error 只在
alive=false 或 crash_looping=true 時才附上,避免健康行程的開機橫幅
被誤讀成錯誤訊息。

新增 diagnostics_engine_e2e_test.go:真的建執行檔、真的用 supervisor
拉起子行程、真的 Stop() 停掉它,驗證同一組 progress 數字在兩種情境下
engine.alive 正確反映活/死(永久迴歸測試,零帳號零網路,快且穩定)。

stage(youlin 帳號)實測驗證見 system-dev/wiki/status.md:兩次真實匯出
(活著/停了)JSON 全文、四題考卷重跑 4/4。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 14:37:53 +08:00
Leo e5d8cee58b feat(t213): 匯出診斷檔搬進 arcrun-app 本機端(phase 2,接手 t210 落地後的 Progress/FailureBreakdown)
t210(commit 5effcb2)已把「總量進度」「失敗分類」算好並寫進 status.json(現況快照,
不隨閒置歸零)——本次直接讀那兩個欄位,不另算一套(首頁與診斷檔同一組數字)。

新增:
- collector/cmd/arcrun-app/diagnostics_export.go
  - App.ExportDiagnostics():合併本機(daemon 版本/自我更新狀態/Progress/
    FailureBreakdown/略過檔案樣本)與雲端(每帳號打新端點 GET /portal/daemon/diagnostics,
    X-Arcrun-API-Key 認證)成一份 JSON,彈系統存檔對話框存下來
  - mergeDiagnostics 抽成無 IO 純函式,方便測試
- collector/cmd/arcrun-app/diagnostics_export_test.go:5 個離線測試,涵蓋
  同首頁數字/分類名稱原樣照抄不自己判斷/失敗檔名 basename-only/略過清單省略欄位/
  帳號層 cloud 與 cloud_error 互斥
- frontend/src/main.js:「版本與更新」頁加「疑難排解」卡片+匯出按鈕

守住的規則:
- Progress/FailureBreakdown 原樣接住 status.json,不重掃 manifest
- 分類名稱字串只認 collector/progress.go 的 ClassifyFailure,本檔不判斷任何分類
- 失敗檔名 basename-only:借用既有 buildSkipped() 輸出(本來就是 basename+白話標籤)

驗證(實跑,非設計稿):go build/vet/gofmt 全乾淨;go test ./...(collector+
arcrun-app)全過;check-cis.sh/check-render.sh 視覺機械閘全過;wails build 成功
產生含 ExportDiagnostics 的 bindings;拿本機真實 config.json(2 個真帳號)+真網路
跑 buildDiagnosticsPayload():真拿到 update_check.latest=v0.18.23、真列出本機
略過檔案(basename)、兩個真帳號誠實回 cloud_error(線上新端點還沒部署,與總管
實測結果一致)。未在真實 GUI 點過按鈕(本機正跑 production Arcrun.app,避免干擾)。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 13:09:48 +08:00