Commit Graph

63 Commits

Author SHA1 Message Date
Leo cea6108924 產物同步 v0.15.5(隨 t181 出貨重建)
.app/mac zip/collector 執行檔重建為 v0.15.5,與已出貨的 bundles
(1fc8029、release 1.4.7、mac sha a38c64bc…)一致。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 16:02:17 +08:00
Leo 1a8906c0b7 t181 daemon 端:萃取預設走 Workers AI(免金鑰)+托盤可切換 AI 來源
【leo 08-04 列為最優先】「daemon 的 AI 改用 workers AI」
——「這是我的用戶**最大障礙**,造成首輪測試用戶的**好評或惡評**」。

【新增】collector/extract_workersai.go:打自己雲端實例的 /portal/daemon/extract,
那端用 env.AI binding ⇒ **完全不需要任何金鑰**。與 gemma 路架構完全對稱
(leo 的判斷:「不論用 Claude/Gemini/Workers AI…應該是同一件事」——是,
只有「送到哪」不同,讀檔/轉檔/淨化/落卡全共用)。
舊實例回 404 時講人話:「你的知識庫還是舊版 ⇒ 請到 portal 按『立即更新』」。

【預設改為一律 Workers AI】leo 特別交代:
  「default 用 Workers AI,你要用 Gemini 要**特別去選取**,**不管你現在是否有填金鑰**」
  「只要更新版本,就已經 default workers AI 了,除非去一個地方切換」
  「不然我會有很多質疑,**花在解釋為什麼 Gemini 不管用上**」
⇒ 判準是新欄位 ExtractorExplicit(使用者主動選過),**不是「有沒有金鑰」**。
  舊 config 沒這欄=false ⇒ 更新版本後自動走 Workers AI;金鑰留著不動,改選 Gemini 立刻可用。

【托盤=唯一切換處】「AI 設定…」改成引擎選擇:雲端 AI(預設)/Gemini(選配)。
選 Gemini 才顯示金鑰欄,並附「Billing Tier: Unavailable ⇒ 換 Google 帳號」的排難提示
(今天 oscar 撞的那題)。Gemini 不推廣(leo:「特定人告訴他怎麼做就好」),文案只說明不慫恿。

【標籤】leo:「用 workers AI 就**不顯示**,用 Gemini 會顯示 Gemini」
⇒ 預設路徑不佔版面;只有主動選了別的才標出來(延續 t178「標籤必須與實際行為一致」)。

【測試】新增 TestT181DefaultsToWorkersAI 六則,含最關鍵的
**「有金鑰但沒主動選 ⇒ 仍走 workers-ai」**;既有測試補 ExtractorExplicit 以隔離變因
(它們測的是萃取管線,不是預設邏輯)。兩模組全綠。

⚠️ 未送達:要打包 v0.15.5 並部署雲端端點才會到用戶手上。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 15:00:48 +08:00
Leo 1a3e974941 t178:托盤標籤與錯誤訊息對齊實際行為(leo 封測者實撞)
【leo 08-04】封測者是台大資工碩士,仍搞不清楚 ⇒「一般人就完蛋了」。
他的托盤顯示「oscar · Claude」但他根本沒有 Claude,
同時錯誤說「Gemini 金鑰是空的」——**兩個訊息互相矛盾**。

① 標籤與行為脫鉤(accountEngineLabel)
   direct.go 早就把 claude 正規化成 gemma(t176:地端先只支援 Gemini),
   但標籤照 config 舊字串念 ⇒ 顯示 Claude、實際走 gemma。
   舊值來源=雲端舊版下發後留在 config.json 的殘留(t176 擋了新寫入、沒洗舊值)。
   修:claude 也顯示「· Gemini」,與萃取實際走的路一致。

② 錯誤訊息沒說設定在哪
   舊:「請在設定裡輸入 Gemini API Key」——用戶找不到入口。
   新:「點托盤選單的『AI 設定…』貼上金鑰(免費申請:aistudio.google.com/apikey)」
   ——錯誤訊息本身就要能當 onboarding。

測試:TestAccountEngineLabel 兩則斷言翻轉成新規格(claude→仍顯示 Gemini),
並註明「若變回 · Claude 代表標籤又和萃取實際走的路脫鉤」;兩模組全綠。

⚠️ 未送達:daemon 執行檔要打包 v0.15.5 出貨才會到用戶手上。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 11:33:13 +08:00
Leo ae0a94b172 產物同步 v0.15.4(隨 t177 出貨重建)
.app/mac zip/collector 執行檔重建為 v0.15.4,與已出貨的 bundles
(24d4418、daemon v0.15.4、mac sha 776ace79…)一致。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 10:20:09 +08:00
Leo 1e139a2e7e t177 更正:取回 08-02 的原版修法,撤掉我重寫的次級版本
【leo 08-04 質問】「這不是先前改過為什麼又出現?你去查看 wiki,是不是你沒看 wiki 就改?」
——**是。查證屬實,而且比沒查更糟。**

【事實】08-02 commit `dde7a5b` 已完整修過這個 bug(t170 daemon 側),
但它**只在 `fix/cis-round3-landing-favicon` 分支**,`feat/daemon` 不含它。
我在 feat/daemon 上看到沒修過的舊 code,就當新 bug 從頭修了一遍。

【而且我修得比原版差】
  08-02 原版:isSemverLike 辨格式 → compareSemver **逐段整數比較**
              (能擋 "1.10.0" < "1.9.0" 這個經典坑)+ minCloudRelease 最低版本常數
  我今天版:  只判「是不是 semver」,是就放行 ⇒ 無法表達「semver 世代的最低相容版本」
⇒ 本 commit **取回 08-02 原版**(git checkout dde7a5b -- ...),
   刪掉我另建的重複測試檔 cloudversion_test.go,改用原版在 main_test.go 的 8 則。

【測試】兩模組全綠;8 則逐項通過,含「semver 1.10.0 比 1.9.0 新(防字串比較)」
——那則正是我的版本表達不出來的。

【病根】hook 給的是 wiki grep 命中行,而那幾行**不含「已修過」的線索**
(關鍵字 compareSemver/isSemverLike 不在搜尋詞裡)。我把「hook 沒提」當成「沒人修過」,
且跳過了 `git log --all -S` 這個五秒就能做的機械檢查。
⇒ 已在頂層 InkStoneCo 補 hook:改檔時一併列出**該檔在所有分支的近期 commit**。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 09:51:48 +08:00
Leo e516e0dbce t177 修「知識庫需要更新」永遠消不掉:semver 打爆字串比較(兩份都修)
【leo 08-04 實撞】「刷新完兩個雲端,為什麼還要我去更新?」
實測坐實**更新其實成功了**:youlin 實例 /health = 1.4.6、daemon 已 v0.15.3,
但托盤兩個帳號都掛「⚠ 知識庫需要更新(點我)」。

【真兇】版本號 08-02 由 `2026-07-31+8e83589` 改成 semver(`1.4.6`)後,
判斷式仍是 `date < "2026-07-28"` ——**字串比較**:
    "1.4.6"      < "2026-07-28" → true   ⚠️ 最新版被判過舊
    "2026-07-31" < "2026-07-28" → false  舊格式才會對
⇒ **任何 semver 都恆判過舊,更新幾次都消不掉。** 這是 wiki 事故 D,08-02 立案未修。

【修法】照事故 D 定案③「兩種格式都要認」:
semver(X.Y.Z 純數字三段)⇒ 視為新契約、不判過舊;
舊日期格式 ⇒ 維持日期比較,讓尚未更新的老實例仍被正確提示(不為修 A 而漏報 B)。

⚠️ **這 bug 有兩份**(tasks.md:2592 早就寫明),兩份都修:
  collector/cloud_version.go  的 cloudVersionStale
  cmd/arcrun-tray/main.go     的 trayCloudVersionStale

【為什麼會出貨】collector 那份**一直有測試**、tray 那份**完全沒有**
⇒ 沒有任何閘擋得住。本 commit 補上 cmd/arcrun-tray/cloudversion_test.go。

【測試證明有效,非裝飾】暫時把 semver 分支拿掉重跑 → 三個 case 立刻紅
(含「leo 08-04 實撞的那一版」);裝回去即綠。
兩模組全測試綠(collector/supervisor/tray)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-04 09:38:19 +08:00
Leo 9a7aaf3fce 產物同步 v0.15.3(隨 t176 出貨重建)
collector/cmd/arcrun-tray 的 .app/mac zip/collector 執行檔重建為 v0.15.3,
與已出貨的 bundles(release 1.4.5、daemon v0.15.3、sha a1c890f2…)一致。

註:這批二進位早已在版控裡(前人決定),本次只更新內容不改版控策略。
⚠️ build-mac.sh 只產 .app 不產 zip——zip 要自己 ditto 打,
否則沿用舊 zip 會出貨到「改之前」的執行檔(t174 同款病,本次實際撞到)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 23:06:18 +08:00
Leo f903a3f53f t176 daemon:LLM 設定移回地端+托盤單一實例(leo 08-03 架構翻案)
leo 回報 Windows daemon 三症狀,查完 ①③ 同根,根在「雲端控制地端」這個設計。

【①③ 真兇】雲端 extractor_config 是**全租戶共用一把 KV**
(arcrun:portal.ts:43 portalTenant = worker 層級變數,不分用戶),
任一處設了 claude → 所有人的 daemon 都收到 claude。沒裝 Claude Code 的機器
FindClaudeBin 失敗 → 每檔萃取 failed、一張卡都沒建;想去 portal 改回 gemini,
checkbox 卻恆 disabled(claude_available 恆 false,因 daemon 從未實作
report-capabilities 回報 → daemon_caps KV 永遠空)⇒ 用戶自己解不開。
awindhon 實證:雲端同步成功、Gemini key 有效、零張卡,config.json extractor="claude"。

【leo 裁示】「地端要用什麼模型就在 daemon 上輸入 API Key 設置,而不是雲端設置後
控制地端」「地端先限制 Gemini API Key 配合客戶要求」「雲端就是 Workers AI」。

本次(daemon 端):
- addOrUpdateAccount 不再接受雲端下發的 extractor/gemini_api_key/llm_model,
  只收連線欄位。t126「每帳號一份萃取設定」照舊保留——t126 修的是「存在哪一層」,
  本次改的是「值從哪來」,兩者正交。
- 托盤新增「AI 設定…」:使用者自己填 Gemini API Key,寫本地 config 後立即生效。
- 萃取一律走 gemini:殘留的 extractor:"claude" 正規化為 gemma;claude 路退役。
  ⚠️ 這不是「自動偵測有無 claude」(leo 07-27 已否決的 B 案),是整條路先不支援。
- 清掉隨之死亡的 claude_bin 回寫(死代碼=錯誤的環境信號)。
- 托盤單一實例(症狀②):pidfile + 跨平台 processAlive。
  mac 之前不多開是借 macOS Launch Services 的巧合,Windows 沒有該層 ⇒ 每點一次多一個 icon。
  Unix 用 signal 0(EPERM 也算活著,測試抓到的實際 bug)/Windows 用 OpenProcess+ExitCode。

測試:collector 全綠、tray 全綠。5 個原本用 claude stub 的測試改走**真實 gemma 路**
(httptest 替身注入 gemmaBaseURL),不是改斷言充綠;t126②③ 兩案翻轉成
「雲端下發一律被忽略」的回歸守衛;新增 4 案 single-instance。

未送達:本 commit 只到 code,尚未打包出貨;雲端側(刪 portal AI 設定區塊、
extractor 下發、admin/extractor)未動,待部署授權。CP rag-beta 步驟仍為 ◐。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 17:48:10 +08:00
Leo 7ecd740f82 品牌 icon 落地:托盤/app/msix/landing favicon 用 leo 的 CIS
用戶從 rag.arcrun.dev → install.arcrun.dev → 自己的 portal → 托盤,
四個地方應該看到同一個 icon。此前最不一致的就是托盤(Fyne 內建的通用
「儲存」圖示,main.go:1016 留著 TODO)。

素材真身=InkStoneCo/arcrun-cis/(leo 用 Claude Design 做的 CIS)。

托盤(trayicon.go,新檔)
- macOS:template 單色(純黑+alpha),系統依選單列深淺自動反色。
  ⚠️ fyne v2.5.3 只有 *theme.ThemedResource 才會走 systray.SetTemplateIcon
  (driver_desktop.go:169);傳一般 StaticResource 會走 SetIcon=不反色。
- Windows:完整墨底 icon(template 是 mac 專有)。
- 兩份都用 go:embed 內嵌,不讀外部路徑——打包後工作目錄不是原始碼目錄。
- 選單列用雙 chevron 而非完整方形字符:CIS 規定 26px 以下降級成 chevron,
  方塊裡的字符只佔高度 ~28%,22pt 下只剩 ~4px 會糊掉。

app 圖示
- icon.png 換成 CIS 1024 原生;icns 重產含 16→1024 全套 Retina 階梯。

msix(Store)
- 圖示改成預先產好、隨 repo 版控的 assets/store/(含 gen-store-assets.py 可重跑)。
- 修掉一個實際的變形 bug:舊版 `sips -z 150 310 icon.png` 會把方形 icon
  **橫向拉扁**成寬磚(實測產出的字符明顯變形),違反 CIS「never skew or stretch」。
  寬磚改用橫式 lockup 等比置中於墨底。
- 補 71x71/310x310/targetsize-16/24/32/48/256,manifest 一併宣告;
  BackgroundColor 從 transparent 改成品牌 Ink #17181A。

landing favicon(rag.arcrun.dev)
- LOGO_SVG 從琥珀金圓圈暫代圖換成 CIS 正式 mark(單色,CIS:彩色 chevron
  在產品裡代表「這條關係是活的」,用在 logo 會是謊話)。
- 修掉名實不符:`/favicon.ico` 過去回的是 SVG 位元組卻標 image/svg+xml
  (線上實測 200 但 type=image/svg+xml),老瀏覽器與抓圖服務畫不出來。
  現在 .ico 回真 ICO(16/32/48 三尺寸)、apple-touch-icon.png 回真 PNG(180)。
- 三個頁面(首頁/privacy/support)補上 icon link 宣告(此前完全沒有)。

⚠️ installer 這次沒動:`install.arcrun.dev` 的真身是
`installer/oauth-prototype/worker.js`(不在本分支,見 wiki decisions-summary
「installer 有兩個 worker,改錯=白做」),另立一筆處理。

實測證據
- mac .app 執行檔內 grep 到 tray-template.png 位元組(sha f6af940d,位移 14001472);
  Windows exe 內 grep 到 tray-windows.png(sha 59f4f1ac);各自平台只嵌自己那份
  (另一份被 linker 消掉=runtime.GOOS 編譯期常數,正確)。
- msix 重打包過 makemsix unpack 回讀驗證,包內 11 張圖示齊全。
- 已部署 arcrun-landing(版本 b79d19df)。繞快取實測 rag.arcrun.dev:
  favicon.ico→image/x-icon 1573B(3 icons,sha 151e645b=與本機產出同一顆)、
  apple-touch-icon.png→image/png 180x180、首頁 head 三個 link 宣告都在。
  ⚠️ 舊版 max-age=86400 的邊緣快取未 purge(無 zone token),24h 內自然過期。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-31 20:43:55 +08:00
Leo 0c93475ab9 t150 二修:繞開 jsDelivr @main 的 7 天快取(否則更新機制形同虛設)
實測(07-29):jsDelivr 對 @main 回 cache-control max-age=604800=**7 天**
⇒ 用戶小幫手連續七天看不到新版;下載 zip 同理會抓到舊檔 ⇒ sha256 不符 ⇒ 更新永遠失敗。
修:manifest 與 zip 下載都帶 ?t=<unix> 繞快取(實測即取得最新)。
不用 raw.githubusercontent——那是實名讀 GitHub,受 D20 頻率閘管制。
另修副作用:檔名要用去掉查詢字串的網址算,否則存成 ...zip?t=1785... 怪檔名。
2026-07-29 22:47:46 +08:00
Leo 8dd15fbe43 t150: 小幫手自我更新(背景備妥+重啟完成)+版本一致性
leo 07-29 三句話定調:
「小白不會動不動就刪除再裝新的」
「如果它都掛着,那準備好就告訴他重啓更新」
「**我要他下載多幾次他就放棄了,所以抓到一個客戶後不能讓他有機會離開**」

① 版本一致性(leo:「我的和下載下來的會是同一個嗎?」)
   真因:build-mac.sh L22/build-windows.sh L46 **只有 tray 注入版本,collector 沒有**
   ⇒ 托盤顯示 tray 的版本,實際幹活的 collector 無版本可查、可能不同版。
   修:collector 加 version/buildTime 變數與 --version 旗標;兩個 build 腳本都改為
   兩支注入同一個 LDFLAGS_VER(各 2 處)。
   驗:collector --version → v0.15.0 (build 20260729-2238);tray 內含同一組值。

② 自我更新(leo 選 1+3:完全自動,但要有提醒與手動檢查)
   - 背景每日檢查 manifest 的 daemon 版本(單一 CDN 靜態檔,非 GitHub API,不違反不輪詢紅線)
   - 有新版**默默下載並驗 sha256**,備妥後選單變「🟢 新版已就緒 — 點此重新啟動完成更新」
   - daemon 常駐不重啟 ⇒ 不偷換正在跑的自己;使用者按一下才 ditto 覆蓋並重啟
   - 另有「檢查更新…」讓人隨時手動按(不必等每日排程)
   - 驗章不符或解壓失敗=保留舊版不動(壞掉的 .app 比舊版更糟)
   ⇒ **封測者完全不必再下載任何東西**

驗:go build/go vet 過;三個版本比較測試通過(dev 不提示/同版不提示/新版要提示);
未剝離符號版確認 5 個更新函式在 build 範圍內
(註:打包版被 -s -w 剝符號,用 grep/strings 驗會誤判為「功能沒進去」)。
2026-07-29 22:40:58 +08:00
Leo 6a3942024a t149: Folders() 收 accounts[].watch_folders——修多帳號用戶「按同步沒反應」
leo 07-29 實測揪出:按「立刻同步」毫無反應,log 顯示 "folders": null、results: []。
真因:Folders() 只讀頂層 watch_folder/watch_folders,**完全沒讀 Accounts[].WatchFolders**。
多帳號設定(新制)一律寫在 accounts[] 裡 ⇒ 掃描清單空 ⇒ 什麼都不做。
**每個多帳號用戶都會中**,不是 leo 特有。

驗:go build 過;純 accounts[] 設定 dry-run → folders = [/tmp/aaa /tmp/bbb](先前 null)。
註:AccountConfig 只有複數 WatchFolders(無單數欄位),初版寫錯已修正。
2026-07-29 21:00:00 +08:00
Leo 71e91aefbd chore(landing): SITE_BUNDLE_VERSION → 2026-07-29+bc507f7 2026-07-29 15:51:50 +08:00
Leo be5d6e3237 fix(t126): 萃取引擎/金鑰改每帳號一份——多帳號不再互相覆蓋
leo:「2 個 CF 帳號一個填 gemma4 一個填 Mistral,daemon 會用誰的?別人也加就會有一樣的疑問」
實證:金鑰只有機器層一份 ⇒ 後連的覆蓋前一個。
修:AccountConfig 加 Extractor/GeminiAPIKey/LLMModel;帳號層優先、空值繼承機器層;
既有 config 遷移(頂層金鑰複製到各帳號,冪等);連線只寫該帳號不覆蓋機器層;
托盤帳號標題顯示「· Gemini」/「· Claude」(一眼看出誰用誰)。
三模組 go test 全綠(總管親跑)。(實作=子 CC;驗證+commit=總管)
2026-07-29 14:36:44 +08:00
Leo 4b60190bad fix(t113): 拿掉「暫停看守」——leo:想不出什麼場景要暫停
同 t101 語意收斂:列入=同步、不要=刪除,沒有暫停態。tray go test 綠。
(實作=子 CC;驗證+commit=總管)
2026-07-28 21:17:39 +08:00
Leo 668eb5f0b8 fix(t110 二修): 結束項加回——「fyne 自動附 Quit」是錯誤前提(leo 真機:兩個都沒了)
教訓:runtime 生成的 UI 元素驗收只能看真選單,grep binary 驗不到;
子 CC 的框架行為研究要求實證不採信註解。tray go test 綠。
2026-07-28 21:00:10 +08:00
Leo 921628098e fix(t110): 移除自訂「結束 Arcrun RAG」——fyne systray 自動附 Quit 造成重複
leo 實測:選單同時有兩個結束項。fyne v2.5.3 內建 Quit 無公開 API 可改文案/抑制,
選移除自訂項(sup.Stop() 經 SetOnStopped 保障不變,Windows 同理)。tray go test 綠。
(實作=子 CC;驗證+commit=總管)
2026-07-28 18:43:37 +08:00
Leo 1738acaca7 fix(t108 🔴🔴): 逐帳號同步遺失萃取設定→原文直送——三層修+契約保險絲
事故(leo 機 07-28 17:3x 總管現場抓到):t104 config 重寫吃掉機器層 extractor/key、
per-account DirectConfig 不繼承 ⇒ extractor 空 ⇒ 6 筆走 rag_ingest_direct 原文出機。
修:①config 讀改寫全程保留既有欄位(帶測試)②帳號層無值垂直繼承機器層
extractor/claude_bin/gemini_api_key/llm_model/CardIngestWF/RemovedWF(帶 fake server 測試:
必須收到 rag_ingest_card 非 direct)③契約保險絲:extractor 空時非 .md/.txt 禁直送、
標 failed「萃取器未設定,已跳過(不直送原文)」——同類 bug 永不再成外洩。
三模組 go test 全綠(總管親跑)。(實作=子 CC;驗證+commit=總管)
2026-07-28 17:59:42 +08:00
Leo bf1f0d9991 feat(t104): 多帳號同時看守——切換概念消滅
leo 架構依據:「它只是一個門,幾個帳號通過它同步並沒有影響」+
「我不是 Google Drive……不提供暫存空間,daemon 工作輕巧,多帳號只是頁簽問題」
(D-daemon-not-Drive)。
Accounts[] 每帳號獨立連線+資料夾;舊 config 冪等遷移 accounts[0];
逐帳號同步一敗不擋全;status.json 分帳;托盤每帳號一分組;
「連上知識庫」→「+新增帳號…」(append 非替換);t86 切換清空退役;
t101 刪除作用於正確帳號。+873/-149、collector 5+tray 5 新測試,
兩模組 go test 全綠(總管親跑)。
(實作=子 CC;驗證+commit=總管)
2026-07-28 16:45:14 +08:00
Leo f8450815d3 feat(t103): daemon 偵測雲端過舊+托盤更新入口——連動閉環
每輪 GET /health 取 bundle_version(5s timeout 失敗靜默);空或日期<minCloudBuilt
→ 托盤「⚠ 知識庫需要更新(點我)」開 install.arcrun.dev;結果進 status.json。
兩模組 go test 全綠(總管親跑)。leo:「daemon 和雲端是連動的」——自此用戶只看托盤。
(實作=子 CC;驗證+commit=總管)
2026-07-28 16:15:12 +08:00
Leo ef74c69023 feat(t101): 托盤刪除語意取代看守語意——leo 實測裁定
「沒有看守這件事,只要列入就是看守,不想同步就刪掉」:
子選單「停止看守這個資料夾」→「刪除這個知識庫」(按下從列表剔除、冪等);
「+ 建立新資料夾並看守…」整項刪除。tray go test 綠(總管親跑)。
(實作=子 CC;驗證+commit=總管。此案原被誤擱置害 v0.13 漏裝=mistakes c947e5a)
2026-07-28 16:06:08 +08:00
Leo 77aa4c5195 feat(t98): 托盤「立刻同步」——訊號檔法零 IPC,跨平台
leo:「無法知道到底同步了沒,可以在 daemon 上加一個立刻同步?」
tray 點擊寫 ~/.arcrun-rag/sync-now+短暫顯示「同步中…」;collector 主迴圈 1 秒輪詢
訊號檔、有就立刻跑一輪刪檔,無則照 PollSec 排程;完成後 status.json 更新自然刷新托盤。
測試:collector+supervisor+tray 三模組全綠(總管親跑)。
(實作=子 CC;驗證+commit=總管)
2026-07-28 15:06:08 +08:00
Leo 903ca60154 feat: 本地轉檔層補 .pptx——CP B1 最後一個 Office 格式
同 docx 路數:zip 開 OOXML、slide 按數字序、每頁「## 投影片 N」+文字+(備註);
空/純圖回 ErrNoText 明示不靜默。測試 4 案(中文/多頁排序/備註/空簡報)。
過程紅測一輪:NFKC 套整份 Markdown 把自家全形標籤「(備註)」轉半形——
改為只正規化 XML 抽出片段、結構標記正規化後組裝。collector go test 全綠(總管親跑)。
(實作=子 CC;驗證+commit=總管)
2026-07-28 13:40:36 +08:00
Leo 9df8d037ca fix(t86b): manifest 分實例——換知識庫後同資料夾不再被舊帳跳過
根因:manifestPathFor 雜湊只含資料夾路徑,換實例讀到舊帳本
→ 全部檔案被視為已同步 → 新知識庫靜默拿不到資料(leo 機實證:刪 manifest 才通)。
- instanceHostOf:CypherURL 的 host 作為實例鍵
- manifestPathFor:sha256(host+"\n"+absRoot),單根多根統一公式
- migrateManifestIfNeeded:新名不在、舊名在 → rename 過戶(一次性、冪等)
- 換回舊實例帳本仍在=不重傳(每實例一本帳,設計目標)
已知殘窗(記 tasks.md):升級後第一次掃描前就換實例,舊帳會被過戶給新實例
(舊格式無實例資訊,無從分辨);常態下升級後首掃已把帳過戶給舊實例,窗口極窄。
測試:新增 6 條(分實例/穩定/單根遷移/多根遷移/冪等)+三模組全綠(總管親跑)。
(實作=子 CC;驗證+commit=總管)
2026-07-28 12:59:07 +08:00
Leo 02833588e5 build: v0.12.0 Mac zip 重包(含 t89/t86/t77lite/t91/92)+mistakes:zip 假綠一課 2026-07-28 12:43:01 +08:00
Leo 6c9d74d588 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=總管)
2026-07-28 12:41:41 +08:00
Leo 5e122b47ec feat(t77-lite): Windows 合併成單一 exe——go:embed 把 collector 吃進 tray
leo 07-28:「Windows 解開有 2 個 exe,被瀏覽器擋住,如果只有 1 個,
我還可以把 exe 改成 e_e 讓朋友改回來,但現在這樣完全不行」。
做法:build-windows.sh 先編 collector.exe 到 tray 目錄供 //go:embed,
tray 啟動時 ensureEmbeddedCollector() sha256 比對後解壓到 ~/.arcrun-rag/bin/,
失敗 fallback 同層(舊版相容);Mac 走 build-tag no-op 完全不動。
驗收(總管親跑):PE32+ GUI exe/zip 僅 1 檔 16.9MB<20MB jsDelivr 上限/
collector 特徵字串在 exe 肚裡(grep=1)/Mac go build+test 全綠/tray 測試綠。
(實作=子 CC;build+驗收+commit=總管)
2026-07-28 12:15:13 +08:00
Leo 0deef3dbd9 fix(t86 🔴): 換知識庫實例時清空看守資料夾——堵個資外洩
leo 07-28 實測坐實:youlin 時代的資料夾被原封同步進 geek6688 新實例
(「假如我把個人的同步到官方去就很危險,個資外泄」)。
修:instanceChanged(old,new) 比 host;連線精靈成功後若換了實例→清空
WatchFolders/WatchFolder,成功對話框改為說明「因為換了知識庫,為避免把舊資料夾
誤傳到新知識庫,請重新用『+新增知識資料夾…』選擇」;同實例改密碼行為照舊。
測試(main_test.go):host 異同判定含大小寫/尾斜線/scheme 差異。tray go test 綠。
(實作=子 CC;審查+commit=總管。⚠️ manifest 沿用=t86b 另案未含)
2026-07-28 12:03:20 +08:00
Leo fb63d9f0c4 fix(t89 🔴🔴): 純中文資料夾名不再靜默併進 kb 庫——slug 空改生路徑穩定雜湊鍵
leo 07-28 實測:「官方總圖」被顯示成「知識庫」=slug 後為空退到 kb;
兩個純中文資料夾會塌縮同庫(靜默混庫,B5 分庫隔離形同虛設)。
修:libraryFor 第三優先從退 c.Library/kb 改為 lib_+sha256(絕對路徑)前6hex——
路徑穩定故鍵穩定、不同路徑必不同鍵;後端庫名鍵限 A-Za-z0-9_- 相容。
測試(t52_library_test.go):純中文→lib_雜湊非kb/兩中文夾不同鍵/同夾重跑鍵穩定/
ASCII 行為不變/明列對映仍最優先。collector go test 全綠(總管親跑)。
(實作=子 CC headless;審查+commit=總管)
2026-07-28 12:03:20 +08:00
Leo 59cf9825d1 fix(t75 ④⑤): 連線精靈不再清空輸入+Windows 不再每幾秒閃 console 視窗
leo 同事真機實測撞到的兩個最嚴重問題。

④ 連線失敗會清空使用者輸入(leo:「很糟糕」)
   真兇:失敗後呼叫 showConnectWizard(),註解寫著「不要把他丟回空白畫面」
   **但行為與註解相反**——它重建整個對話框,urlEntry 是全新的,
   而 cfg.CypherURL 因連線失敗根本沒寫入 ⇒ 欄位就是空的 ⇒ 使用者整段重打。
   修:改 showConnectWizardWith(prevURL, prevEmail) 帶回上次輸入,
   讓他只改錯的那個字。密碼不帶回(打錯時重打較安全,也少留記憶體)。

⑤ daemon 開著時每幾秒閃一個方框(約半螢幕)
   真兇:arcrun-collector.exe 是 console 型執行檔,supervisor 每輪 exec 起它,
   **Windows 預設會為 console 程式配可見視窗** ⇒ 每輪閃一次。
   Mac/Linux 無此概念故開發期完全沒想到。
   修:新增 hidewindow_windows.go(HideWindow + CREATE_NO_WINDOW)
   +hidewindow_other.go(no-op),編譯期分平台不寫 runtime.GOOS 判斷。
   註:-H windowsgui 是連結期選項(管自己有沒有視窗),與此(管起別人時給不給視窗)
   是兩件事,兩者都要做才乾淨。

驗證:Mac 與 Windows 交叉編譯皆 exit=0 且產物生成;collector 全測試綠。
⚠️ 未真機驗——⑤ 的效果必須在真 Windows 上確認方框消失。
2026-07-28 00:42:12 +08:00
Leo 1b58cd1a35 fix(t72): build-windows.sh 補版本注入(Mac 有、Windows 漏了)+tray go.mod tidy
實測抓到:Windows 版編出來 v0.10.0 命中 0——版本注入只加在 build-mac.sh,
Windows 那支漏了(我今天改的那份在 detached worktree,沒進分支)。

v0.10.0 兩平台實測:
  Mac  zip 15.92MB|托盤 21.15MB(strip)|collector 14.46MB(含 PDFium)
  Win  zip 16.86MB|tray 22.40MB|collector 15.15MB
  兩者皆 < jsDelivr 20MB
  指紋全中:v0.10.0/版本列/結束 Arcrun RAG/PDF 打不開(轉檔層)

順帶修:tray go.mod 需 tidy 才編得過(合併後又被覆蓋,撞了兩次)。
2026-07-27 21:17:50 +08:00
Leo a0a7215d24 Merge branch 'fix/mac-build-strip-t72' into feat/daemon 2026-07-27 21:12:55 +08:00
Leo 55ed2c86a7 feat(t73): PDF 抽取器接上 PDFium-via-wazero——leo 裁定的引擎,實測通過
 決定性實測:Chrome headless 列印的中文 PDF 完整抽出
   「船舶維修合約書/第一條 維修費用為新台幣 350,000 元整/2026 年 8 月 15 日」
   ——這正是 pdf-extraction-options.md §3 實測「純 Go 套件會整段亂碼」的那種檔,
   也是客戶最常丟的(瀏覽器列印)。選 PDFium 的理由至此坐實。

用戶不必裝任何東西(回答 leo「我的用戶可能不會自己裝 Python 環境」):
pdfium.wasm 由 wazero(純 Go WASM runtime)在本行程跑,embed 進執行檔。
實測 CGO_ENABLED=0 GOOS=windows 交叉編譯一行成功 → PE32+ executable x86-64,
證實「無 CGo」承諾為真,不加重 t72 負擔。

體積實測(有實際呼叫路徑,避開今天記過的 dead-code 陷阱):
  mac 14.53MB / windows 15.15MB(strip 後)
  leo 定調「全運作在客戶電腦上,肥一點喘一點也沒事」

設計決定:
- lazy init(sync.Once)——多數資料夾可能一個 PDF 都沒有,不該白付 WASM 啟動的記憶體
- pdfMu 互斥——pool 單 worker,別依賴「scan 是循序」這個假設
- 單頁失敗不放棄整份,但留「(第 N 頁讀取失敗)」痕跡
- 抽不出字 → ErrNoText(掃描件;PDFium 不做 OCR),絕不靜默送空內容

測試 4/4:Chrome PDF 中文正確/無文字回 ErrNoText/壞檔報錯可辨識
(『可能損壞或有密碼保護』)/連續多檔不爆(daemon 長駐會遇到)。
2026-07-27 21:07:11 +08:00
Leo a50cc37949 feat(t73): manifest 記錄 extracted_by——換萃取器時才分辨得出哪些卡是舊的
leo 07-27 三問查證後補的缺口。查證結果(已用測試釘死,下次不必再讀碼推論):
① 已萃過它知道嗎 → 知道。ingested_hash vs content_hash,相同就跳過;
   只有 2xx 成功才回寫(direct.go:405),失敗下輪自動重試不漏檔。
② gemma 會重萃 claude 萃過的嗎 → 不會重萃(hash 相同),但原本**分辨不出誰萃的**
   =換萃取器後兩種品質的卡混在同一知識庫,想重萃也不知該重萃哪些。← 這次補的
③ 誰負責萃 → cfg.Extractor 一個資料夾一個設定(direct.go:346),無自動判斷。

做法(純記錄不改行為、可逆,故自裁):
- ManifestEntry 加 ExtractedBy(omitempty)
- 另開 MarkIngestedBy 而非改 MarkIngested 簽名——後者有多處呼叫(direct 兩處+
  trigger.go MarkIngestedEvents+測試),改簽名會擴散破壞

測試 7/7:萃過不重萃/改了要重萃/失敗下輪重試/記得誰萃的/
舊簽名仍可用/舊 manifest 讀得進來且空值不污染 JSON/有值真的存進檔案。

未做(屬品味題待 leo 裁):B 自動偵測有無 claude 優先用用戶訂閱、C ChatGPT 路。
2026-07-27 20:58:30 +08:00
Leo 12c8098b5f feat(t73): Excel/CSV 抽取器——企業用很多(leo)
leo 兩句定調:
①「要思考 Excel 和 csv 的問題,因為企業用很多」
②「企業的 excel 通常不會是 1 萬行,人工做不出這麼多,但你可以轉結構資料丟進去」
→ 修正我先前「CSV 會變數字牆、先不加」的判斷——那是拿機器產生的百萬列當前提。
   實測 60列x6欄 ≈ 2,200 token,對 LLM 完全不是問題。

統一中間格式=Markdown(leo 提 n8n 對照後定調):
n8n 一切轉 JSON 是對的,因為它下游是程式(.欄位 取值);
我們下游是 LLM ⇒ Markdown 表格更好。實測同一份表格
JSON 6,872 字元 vs Markdown 3,341=JSON 多花 2.1 倍 token(每列重複寫欄位名)。

測試 8/8,用 openpyxl 產的真 Excel 檔(非自捏 XML):
   測試抓到兩個真 bug(讀原始碼看不出來):
     ① rels 的 Target 是絕對路徑 /xl/... 我卻又補 xl/ 前綴 → 變 xl/xl/...
     ② r:id 帶 namespace,寫 xml:"id,attr" 抓不到,要用完整 namespace URI
     修好後分頁名從 ## sheet1 變成 ## 維修紀錄(企業分頁名本身就是語意)
  CSV:去 BOM(Excel 另存必帶)/引號內逗號不拆欄/| 跳脫/欄數不齊不整份失敗
  XLSX:多工作表全讀(只取第一頁會漏)/sharedStrings 索引/壞檔報錯

防呆:超過 500 列截斷並明說截斷了(不靜默丟資料);單格超 500 字截斷。
2026-07-27 20:50:45 +08:00
Leo 09bf454402 feat(t73): 轉檔層接進主流程——docx 真的走得通(零件完成≠功能完成)
ExtractWithGemma 讀檔後改走 ConvertToText,LLM 只會收到文字永不收二進位。
刻意不吞錯:ErrNoText(掃描件/空檔) 與 ErrUnsupported(未支援格式) 都往上拋,
因為靜默略過正是 leo 撞到的病。

接線測試 5/5(驗用戶真的會走的那條路,非只測零件):
  scan 收得到 .docx/收 .md/不收 .png
   docx 一路走到 Gemini API 才因假 key 失敗 = 決定性證據:
     轉檔確實發生在送模型之前(非宣稱)
  抽不出文字 → 明確失敗且 errors.Is(ErrNoText) 可判定,不靜默送空卡
  未支援格式 → ErrUnsupported,與 ErrNoText 可區分(給用戶的說法不同)
  .md 迴歸保護:不因接了轉檔層而壞掉

順帶修:變數名與既有 text(LLM 回應) 衝突 → 改 srcText(輸入原稿),IDE 診斷抓到。
全 collector 測試綠。
2026-07-27 20:44:29 +08:00
Leo 66d4fef045 feat(t73/t16): 本地轉檔層骨架+docx 抽取器(leo 定的『收集端 Markitdown』)
leo 07-27 定的形狀:「本地任何檔案都透過一個機制把它轉成模型可讀,再把模型可讀
內容發給它」「能不能讀 PDF 根本不是 Arcrun 的工作」。

convert.go=調度層(工頭):認副檔名→派抽取器→統一吐純文字。
加新格式只要在 extractors 註冊一行,不動架構。
convert_docx.go=第一個抽取器,純標準庫 archive/zip+encoding/xml。

三個設計決定(都有理由,非隨手):
① ErrNoText 獨立錯誤——掃描件 PDF 抽不出字時絕不能靜默略過(leo 撞過的病),
   要能轉成使用者看得懂的訊息;與 ErrUnsupported 分開因為說法不同。
② NFKC 正規化——PDF 抽中文會出康熙部首變體,長得一樣但碼位不同=用戶搜不到
   自己的檔案。廉價保險,對其他來源同樣有效。
③ 只取 word/document.xml——頁首頁尾多是雜訊(頁碼/公司名),知識萃取不要。

測試 10/10 + 真 Word 檔實測:
  textutil 產生的 real.docx → 抽出「船舶維修合約/350,000/2026 年 8 月 15 日」全對
  同段落多 run 相連(Word 常把一句話切成多個 w:r)
  壞檔(舊版 .doc 改名)報錯且不歸類成 ErrNoText
  NFKC 康熙部首摺回正常字
註:全形「,」會被 NFKC 轉半形「,」=正常行為,對搜尋無害(反而統一)。

下一步:接 PDFium-via-wazero(+10.43MB)。未接進 extract_gemma 主流程。
2026-07-27 20:36:02 +08:00
Leo 90b6de66bc feat(t72): daemon 加版本編號(leo 07-27:沒版本號=只能靠 shasum 對帳)
病根:在此之前無法從畫面看出裝的是哪一版。07-27 花大半天對帳
「leo 手上/鏡像上/剛編的」是否同一顆,只能 shasum 比對 binary;
使用者更做不到這件事,回報問題時我們也不知道他跑的是哪版(t63 三層落差)。

做法:
- main.go 加 version/buildTime 變數,build 時 -ldflags -X 注入,未注入顯示 dev
- 托盤選單「結束」正上方加停用態版本列(回報問題時眼睛已在那一區)
- build-mac.sh / build-windows.sh 同一套:VERSION 環境變數 > git describe > dev

實測(兩平台各實跑一次 VERSION=v0.9.0):
  Mac  托盤 21.1MB/zip 12.43MB/v0.9.0 命中 3/版本列 1/結束 1/連上知識庫 1
  Win  zip 13.27MB/PE32+ GUI/v0.9.0 命中 3/版本列 1/結束 1/連上知識庫 1
  兩包皆 < jsDelivr 20MB 上限

未驗:選單版本列的實際顯示(Mac 需 leo 點選單、Windows 需真機)。
2026-07-27 19:46:19 +08:00
Leo 1c48d58789 fix(t72/t63): build-mac.sh 加 -s -w——Mac 版掉進 jsDelivr 20MB 內,免拆檔
真兇:fyne package 內部自己 go build,吃不到 -ldflags,產出含符號表+DWARF 的胖執行檔。
解:②b 用 -s -w 重編托盤覆蓋回 bundle;collector 也一併 strip。

實測(從乾淨狀態重跑 build-mac.sh):
  托盤   28.6MB → 21.1MB
  整包zip 21.1MB → 12.43MB  ← 遠低於 jsDelivr 20MB 上限
  功能指紋 結束 Arcrun RAG=1 / 連上知識庫=1(未掉功能)
  codesign -v 通過

影響:此前 Mac 版超 20MB,jsDelivr 直接回 File size exceeded,只能走 raw;
現在可走 CDN,且**免除原本要拆檔(tray/collector 分開)的工程**。
Windows 版 13MB 本來就在限內,不受影響。

未驗:真機執行行為(托盤 icon/選資料夾)——strip 不影響邏輯但仍需真機確認。
2026-07-27 19:31:30 +08:00
Leo 26dd6960c2 feat(t72): Windows 交叉編譯腳本——Mac 上就編得出 Windows 托盤(推翻「要真機」假設)
任務板一直寫「fyne GUI 沙箱編不了 CGo+GL → 歸屬真機」,本機實測推翻一半:
裝 mingw-w64 後 Mac 直接交叉編譯成功,不需 Windows 機器/Docker/fyne-cross。

  CGO_ENABLED=1 GOOS=windows CC=x86_64-w64-mingw32-gcc \
    go build -ldflags "-H windowsgui -s -w"
  → PE32+ executable (GUI) x86-64, for MS Windows

正確說法是「編得出來、但驗不了」——編譯是 Mac 的事,跑起來對不對才是真機的事。

另兩條路實測皆失敗(訊息留在文件):
- CGO_ENABLED=0 → go-gl/gl 無 non-cgo 實作
- CGO_ENABLED=1 無交叉編譯器 → 退回 host clang 報 -mthreads 不支援

體積(解掉 t72 的 zip 疑慮):tray 加 -s -w 40.8MB→23.5MB、collector 6.5MB,
zip 合計 13.9MB=在 jsDelivr 20MB 上限內,Windows 版不會踩到 Mac 版那個坑。

腳本已實跑通過。 未驗=托盤 icon/選資料夾對話框/SmartScreen 實際行為(要真 Windows)。
詳 system-dev/docs/3-specs/rag-wave1/windows-build-and-os-split.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-27 18:34:59 +08:00
Leo fedb765742 feat(t52): per-folder 庫章——DirectConfig.libraries 對映+libraryFor()(資料夾名 slug/中文退後備/明列優先,go test 綠);兩支 ingest workflow 的 post_block metadata 補 library(真兇:blocks 沒蓋章=兩資料夾全歸 general);托盤連線時回報庫自動登記 2026-07-26 01:53:44 +08:00
Leo 3675f38e59 fix(daemon/t55): 托盤補「結束 Arcrun RAG」——leo 07-26 實撞沒有出口(關窗只隱藏、LSUIElement 無 Dock 右鍵、只剩強制結束);結束前先 sup.Stop() 不留孤兒 collector 2026-07-26 01:12:57 +08:00
Leo 3174340c4c feat(daemon/t54): 連線精靈——首次啟動輸入知識庫網址+帳密,自動換取設定並開始看守(不再需要下載 config.json 丟隱藏資料夾);portal→cypher 子域自動換算、三種輸入格式實測可用;選單加「連上知識庫…」供換帳號 2026-07-26 00:16:58 +08:00
Claude e548c57efa fix(t39): daemon 端展開 config 的 ~/ 路徑
安裝器成功頁下載的 config.json 把 manifest 寫成 ~/.arcrun-rag/manifest.json——那是給人
看的寫法,Go 不展開波浪號,os.ReadFile 會去找一個字面上叫 "~" 的資料夾。

修在 daemon 端而非前端:用戶自己手打 config、或把設定搬到另一台機器時 ~/ 都該會動,
而前端也拿不到用戶家目錄。manifest 與 watch_folder(s) 全展開;只認 ~/ 與單獨的 ~,
~user 形式不猜(Go 無法解析他人家目錄);拿不到家目錄就原樣返回讓錯誤誠實浮現。

測試 +2(config 展開含 CJK 路徑與絕對路徑不動、expandHome 六種邊界),collector 全套綠。
2026-07-25 08:18:21 +00:00
Leo 125377b899 feat(daemon-beta t26): 托盤選單顯連線身分(暱稱>email>未設定),CF 全程隱形
- directConfig/DirectConfig 加 Email、InstanceName(選配)欄,兩結構同形
- rebuildTray 選單頂加 disabled「連線中:<暱稱||email||未設定>」列;
  有 cypher_url 再加一行縮短 host(fyne MenuItem 無 tooltip,取捨見註解)
- connectionStatusLabel/shortCypherHost 抽純函式,3+3 案 table test
- go vet + go test 全綠(collector 43 通、tray 10 通);tray go build 過
2026-07-24 17:59:01 +08:00
Leo b9d880413d feat(daemon-beta t14/t15/t17): supervisor log 檔+removed 清本地卡+托盤建新資料夾
- t14 supervisor:子行程 stdout(tee)/stderr 全落 ~/.arcrun-rag/collector.log,
  >5MB 改名 .old 重開(兩代輪替);落 log 失敗一律吞掉不擋看守。新增 2 測試
  (輸出進檔+輪替觸發)。
- t15 direct removed(extractor 模式):雲端 takedown 2xx 後同步刪本地
  system-dev/wiki/cards/<頁名>.md(存在才刪;刪失敗只記 warning 不擋)。
  新增 2 測試(刪原檔→本地卡被清/卡已不在照常下架)。
- t17 arcrun-tray:tray 選單+設定視窗加「建立新資料夾並看守…」——
  widget.Entry 輸入名稱→ ~/ 底下 mkdir(已存在沿用;擋路徑分隔與 ..)→
  addWatchFolder+saveConfig+重啟看守+rebuildTray。

collector: go vet ✓、go test -count=1 ./... 43/43 綠;arcrun-tray: go build ✓(產物已刪)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 15:06:21 +08:00
Leo 6e5009ff35 fix(daemon-beta t6): ingest path 改帶原檔路徑——修 takedown 0 命中孤兒 bug(第五枚真機坑);mistakes 補成對操作同鍵教訓 2026-07-24 13:21:26 +08:00
Leo 387ce3d1a4 feat(daemon-beta t7/t8): Dock 隱藏真機驗證通過(lsappinfo type=UIElement)——runtime Accessory policy(cgo)+appID+ad-hoc 重簽;mistakes 記四枚真機坑;暫用 icon(等 leo logo) 2026-07-24 12:56:40 +08:00
Leo 5017d0381e feat(daemon-beta t7): 托盤多資料夾選單(每根一列:點開 Finder/子選單停止看守/動態重建)+build-mac.sh(fyne package+LSUIElement=true 隱 Dock——leo 07-24 裁決);編譯通過,真機驗歸 leo 2026-07-24 12:32:44 +08:00
Leo c0bf83def4 fix(daemon-beta t3): headless claude -p 寫卡卡權限確認——帶 --permission-mode acceptEdits(真機 e2e 第二枚實撞) 2026-07-24 12:28:47 +08:00