Leo
|
4d3a6a09a6
|
v0.18.9:collector 併進同一支執行檔——磁碟上不再攤出第二支 exe
leo 08-06 裁決:「不要兩支,寫成一支檔案」。
## 為什麼
v0.18.7-8 的「單一 exe」其實是**一支包著另一支**:collector.exe 被 go:embed
進 Arcrun.exe,執行時攤到 ~/.arcrun-rag/bin/ 再跑。
那正是防毒軟體眼中的 dropper 特徵 —— 封測者實撞
`Trojan:Win32/Sabsik.FL.A!ml`,檔案當場被隔離、自動刪除。
⚠️ 誠實界定:`!ml` 結尾=**機器學習判定**,Sabsik 是最常見的通用誤判家族,
主因是「未簽章+下載次數少」,**不是**特別指向 dropper 行為。
所以本次改動**不保證**解除誤判——真正的解是上架 MS Store(微軟簽章)。
但「執行時把第二支 PE 寫到磁碟再執行」本來就該拿掉,這是對的方向且順手變小。
## 怎麼做
- `collector/` 39 個檔 `package main` → `package collector`,`main()` → 匯出的 `Run(args) int`
- 新增 `collector/cmd/collector/`(薄殼 CLI,讓單獨跑 collector 這條路仍可用)
- App 直接 import 該套件;`main()` 第一件事就判 `--collector`,是的話走 `collector.Run` 不碰 GUI
- `supervisor` 加 `ArgPrefix`,App 把 `BinPath` 指向 `os.Executable()` 自己
- 刪掉 `bundled_collector_{windows,other}.go`(embed + 攤檔那套)
- 三支打包腳本不再編/複製第二支;版本注入同時打到兩個 package
- build-win.sh 的機械閘改成**直接問它**:`--collector --version` 回得出版本才放行
(舊閘是比大小,只能證明「有 embed」,證明不了「分派是對的」)
## 驗(真機實跑)
· `.app/Contents/MacOS/` 只有 **一個** 執行檔(原本兩個)
· 跑起來兩個行程是**同一個 exe**:
…/MacOS/arcrun-app
…/MacOS/arcrun-app --collector direct --config …
· `~/.arcrun-rag/bin` **不存在**(沒有任何東西被攤出來)
· 端到端:丟檔進看守資料夾 → collector.log `"status":"ingested","http_status":200`
· `lsappinfo` 仍是 `type="UIElement"`、`Version="0.18.9"`
· collector 39 檔測試全過;app 測試過;go vet 全綠;mac + windows 交叉編譯皆過
· 單檔 26MB → 22MB(不再夾帶第二份完整程式)
|
2026-08-06 16:00:47 +08:00 |
|
Leo
|
f4eb3c9fa1
|
Mac 四修:Dock 不再重複/結束真的會結束/全螢幕可用/視窗 70%
leo 08-06 Mac 實測回報。四個都是**只在 Mac 現形**的病。
## ① Dock 與選單列兩邊都顯示(連帶:只有 Arcrun 列在強制結束清單)
真兇:Wails 在 AppDelegate.m:44 applicationWillFinishLaunching 硬設
`setActivationPolicy:Regular`,**runtime 蓋掉 Info.plist 的 LSUIElement**
(後者只決定啟動當下的初始 policy)。而 v2.13 的 mac.ActivationPolicy 是註解掉的。
🔴 **這件事 fyne 版 604704a(07-24)已經解過且真機驗證通過**,換 Wails 時整段掉了;
wiki mistakes.md:124 也早就記著同一條。**本次是取回原版,不是重新發明**——
dock_darwin.go/dock_other.go 逐字沿用,只更新註解說明 Wails 死法相同。
## ② 托盤右鍵「結束 Arcrun」點了不會結束
leo:「唯一結束法是強制結束…因為舊版沒結束導致無法覆蓋,
**如果不知道怎麼強制結束的人就放棄了**」
真兇:Wails 的 runtime.Quit() 與「按 ×」**共用同一個 OnBeforeClose**
(frontend.go:364 `if !OnBeforeClose(ctx) { mainWindow.Quit() }`),
我們無條件回 true ⇒ mainWindow.Quit() 永遠不執行,還順手 WindowHide
⇒ 看起來像關了、其實行程還活著。
(AppDelegate.m:41 的 applicationShouldTerminate 也一律回 NSTerminateCancel,
決定權整個在這個回呼 ⇒ 回 true 就沒有任何出口。)
解:quitting 旗標區分兩者,並抽出 closeMeansHide()/beginQuit() 讓它**可機械驗證**。
## ③ Mac 全螢幕(綠色)按鈕被停用
真兇同樣在 Wails:window.go:92 `zoomable` 只在 `frontendOptions.Mac != nil` 時賦值,
我們沒設 Mac ⇒ zoomable 維持零值 false ⇒ WailsContext.m:208
`if (!zoomable && resizable) { [zoomButton setEnabled:NO]; }`。Windows 無此段。
解:`Mac: &mac.Options{}`(空的即可,DisableZoom 預設 false)。
## ④ 視窗 50% 太小
leo:「Google Drive 大約螢幕長寬的 70%,改成 50% 後顯得太小」⇒ 常數 screenFraction=0.70。
並加 appLog 留痕(螢幕多大、算出多大),以後不必請人量像素。
## 驗(本機真機實跑,非推測)
· `lsappinfo` → **type="UIElement"**、Version="0.18.8"
= 604704a 當年用的同一個驗法,通過 ⇒ Dock 無 icon、不列強制結束
· 截圖放大號誌燈 → **綠燈是彩色的(enabled)**,停用時會是灰色
· app.log 自報 → **視窗依螢幕 1470x956 設為 1029x669(70%)**
· 首頁顯示「看守中·資料夾有變動就會自動整理/已整理 1 份」=判活正常
· go test TestCloseMeansHide 通過(釘住「按×要隱藏、按結束要放行」)
· go vet 全綠;mac build + windows 交叉編譯皆 OK
· **未驗**:托盤右鍵實際點擊(osascript 缺輔助取用權限,點不到選單列)
⇒ 邏輯已單元測試+原始碼追到底,但**實際點擊歸 leo 真機**
|
2026-08-06 14:11:49 +08:00 |
|
Leo
|
b783b870e6
|
版本號改由 changelog 決定:從頭到尾沒有人打過數字,且與更新內容天生綁定
## 為什麼推翻自己幾小時前的做法
上一版用「動過 collector/ 的 commit 數」當 patch。確實不用手打,但
**每個 commit 都變成一版**(一天 5 個 commit 就跳 5 版),
每跳一版還要補一段 changelog ⇒ 把機械化變成新的手工活。leo 要的不是這個。
## 現在的機制(daemon-version.py)
單一真相源=docs-site/.../help/changelog.md:
· 要出新版 ⇒ 最上面加一段 `## 下一版(未發佈)`,底下寫白話更新內容
· 打包時腳本把它**戳成正式版號**(上一版 patch+1)並補今天日期
· 沒有「未發佈」段 ⇒ 版本=最上面那一版(重打同一版,冪等不虛增)
⇒ 版本號沒有人打過;且不可能「升了版卻沒人知道改什麼」,
也不可能「寫了內容卻忘了升版」——兩者出自同一段文字。
換線(0.18→0.19)只改 DAEMON_LINE,下一版自動從 0.19.0 起。
刪掉 daemon-version.sh 與 DAEMON_PATCH_BASE(一版的殘留)。
## 驗(實測輸出)
· `## 下一版(未發佈)` --stamp→ `## v0.18.7(2026-08-06)`(腳本自己改的)
· 沒有未發佈段時重跑 → 仍回 v0.18.7(冪等,不虛增)
· ./build-win.sh 全程通 → dist/Arcrun-win-v0.18.7.exe(27,445,248 bytes)
strings 抽內嵌版本 = v0.18.7
· ./build-dmg.sh 全程通 → dist/Arcrun-v0.18.7.dmg(10M)
掛載後 strings 抽 App 內嵌版本 = v0.18.7
Info.plist CFBundleShortVersionString = 0.18.7(以前永遠是 1.0.0)
⇒ **兩條打包線第一次在同一個版本號上對齊**——這正是 08-06 那個病
(只重打 Mac DMG、Windows 沒動、manifest 卻宣告新版)的根治。
· 未驗:Windows/Mac 真機行為;未出貨 ⇒ ◐
|
2026-08-06 13:16:14 +08:00 |
|
Leo
|
be817b3c16
|
更新內容機械化+manifest 補上「宣告版本==產物版本」的閘+前端顯示同步器版本
回應 leo 08-06 兩問與兩項新需求。
## ①「更新內容還要寫在 docs 裡,機械化要怎麼做」
答:改的是「寫在哪」,不是「誰來寫」。
- 單一真相源=docs-site/.../help/changelog.md(本來就存在,用戶語言那份)
- 新增 changelog-section.sh:抽出某版段落(供 manifest.notes 投影用)
+ --check 模式當閘
- build-win.sh/build-mac.sh 接上閘:**changelog 找不到這版段落 ⇒ 中止打包**
⇒「忘了寫更新內容」變成不可能,而不是靠誰記得
- 已寫 v0.18.8 的用戶語言版本說明(本次五修)
## ② manifest 的閘:這次的病是從兩條規則中間的縫穿過去的
verifyManifest 對 daemon 只驗 ①version 欄在不在 ②file 指的檔存不存在。
08-06 那次**兩條都過**(宣告 v0.18.5、`-v0.18.4.zip` 檔案真的存在)⇒ 全綠放行。
新增第三條:宣告版本必須等於產物真正的版本
(a) 檔名要帶宣告的版本(光這條就足以擋下 08-06 那次)
(b) .exe 再驗一層:版本字串要真的在二進位裡(檔名可改,內嵌版本改不了)
實測(用當時的真實 manifest 值重現):
· 宣告 v0.18.5 + 檔名 -v0.18.4.zip → ❌ 擋下(mac/win 各一條)
· 檔名改成 v0.18.8 但內容是 v0.18.7 那顆 → ❌ 擋下(規則 b)
## ③ 前端顯示同步器版本+下載入口
leo:「連我都沒辦法確認,所以用戶到底是否最新版他自己也不知道」
- /api/latest 新增 daemon 欄(version/notes/downloads),由 daemonOf(env) 讀釘點
manifest——與 releaseOf 同原則同真相源,不留手抄本。
下載網址走 raw + 釘點 sha,與 selfupdate.go:158 同源(不自創第二條路)。
- rag.arcrun.dev 步驟 4 補上**真的下載按鈕**(Win/Mac)+同步器版本+
「這一版改了什麼」連結。以前這裡只有文案提到下載、沒有連結也沒有版本。
取不到就顯示「(查詢中)」並退回安裝說明頁——沿用 bf06ed7 的原則,不留手抄值。
## 驗
· node --check worker.js(installer/landing)皆 OK
· changelog 閘:v0.18.6 通過;不存在的 v0.18.7 → 退出碼 1 並印出可照抄的範本
· manifest 三條規則實測如上
· 未驗:線上畫面(要出貨後才有 daemon 欄位)⇒ ◐,不是 ✅
|
2026-08-06 13:12:48 +08:00 |
|
Leo
|
a55488040d
|
Windows 交付改單一 exe+版本號不再手打(leo 08-06 回報②與「整串該機械化」)
## ② 兩個檔很迷惑 → 一個檔
leo 圖一標註:「下載還是 ZIP ⇒ 應該是 MSIX 或 EXE;解開還是 2 個檔 ⇒ 應該只有 1 個檔案」。
舊做法 zip 裡放 Arcrun.exe+arcrun-collector.exe 同層,少解一個檔就永遠不會同步,
而畫面不會說是這個原因。
修:collector 用 go:embed 收進 Arcrun.exe,第一次執行攤到 ~/.arcrun-rag/bin/
(冪等:sha256 相同不重寫;先寫暫存再 rename,避免留半截執行檔)。
build-win.sh 直接產單一 Arcrun-win-<ver>.exe,不再打 zip。
加機械閘:產出的 exe 若比 collector 還小 ⇒ 沒 embed 成功 ⇒ 中止(過去只會
默默得到一顆「裝了也不會同步」的空殼)。
不走 MSIX:未上架的 MSIX 要使用者先開「開發人員模式」,比 zip 更麻煩。
## 版本號機械化(leo:「這一整串都應該是機械化,不應該每次手工做」)
病根實測:本 repo **一個 git tag 都沒有**,而四支 build 腳本寫的是
`git describe --tags` ⇒ 永遠拿不到 v0.18.x ⇒ 只能靠打包時人工敲 VERSION=
⇒ 兩條打包線各敲各的 ⇒ manifest 宣告 0.18.5、產物其實是 0.18.4。
修:新增 daemon-version.sh 當唯一產生器,沿用 release.mjs 已在跑的原則
(「版本號由內容算出來,不是由人宣告」),不另立新制:
MINOR ← DAEMON_LINE(人決定,大改版才動)
PATCH ← 動過 collector/ 的 commit 數 − DAEMON_PATCH_BASE(機器決定)
⇒ 沒改 daemon 重跑打包不會虛增;改了才 +1;四支腳本在同一 commit 必得同號。
⇒ 不需要 git tag/Actions/輪詢(守 D20 紅線)。
校準:DAEMON_LINE=0.18、BASE=87 ⇒ 現在的樹算出 v0.18.7(上次出貨過 0.18.6)。
build-win/mac/dmg/msix 四支全部改用它。
## icon 漂移根治接上打包
build-win.sh 步驟⓪ 每次都跑 gen-icons.py 重產 icon.ico/trayicon.ico。
## 驗(實測輸出,非推測)
· ./build-win.sh 全程跑通,產出 dist/Arcrun-win-v0.18.7.exe(27,445,248 bytes)
· strings 抽內嵌版本 = v0.18.7、buildTime = 20260806-1233(機器算的,沒人敲)
· 位元組比對該 exe:
CIS trayicon 在裡面 = True
Wails「W」圖還在 = False
collector 有 embed 進去 = True(16,104,960 bytes)
· go vet 全綠(darwin + windows);mac build OK
· 未驗:Windows 真機行為(需封測者實跑)⇒ 狀態 ◐,不是 ✅
· 未做:CHANGELOG 閘、manifest「宣告版本 == 產物版本」驗證閘、前端顯示版本與下載入口
|
2026-08-06 12:35:54 +08:00 |
|
Leo
|
ee2fc2a803
|
Windows 三修:不再無限多開/首頁不再謊報「引擎沒在跑」/視窗改螢幕 50%
leo 08-06 封測回報①④+圖三標註。三個都是**只在 Windows 現形**的病。
## ④ 托盤一次開好幾個 icon
leo:「點一次開一個新的,測試者原本給我看顯示到 4 個」。
真兇:main.go 的 options.App 沒設 SingleInstanceLock(Wails v2.13 有這選項)。
每個實例還各自拉一份 collector 子行程。
macOS 由 LaunchServices 天然單實例 ⇒ Mac 上驗不出來。
修:加 SingleInstanceLock,第二次啟動叫醒既有視窗後自己退出。
## ① 根本不運行(首頁恆顯示「同步引擎沒有在跑」)
真兇:collectorAlive() 的憑據是 `pgrep -f <bin>`,**Windows 沒有 pgrep**
⇒ 恆回 false ⇒ app.go:356 一定走「同步引擎沒有在跑」,與實際狀態無關。
修:憑據換成 supervisor 自己的狀態機(親手拉起的子行程、runOnce 以 cmd.Wait 收尾)
——比掃行程表更有憑據且跨平台,順帶修掉 pgrep 會匹配到別的實例的偽陽性。
⚠️ 不是發明第三種判斷法:db17f28(08-05)已為「同步中」立下同一條路
「改讀 sup.Status().State ⇒ 接回既有機制,不發明第三種判斷法」,
當時只改了 collectorSyncing 那半邊,這裡把漏掉的 collectorAlive 補上。
順帶移除 waitCollectorGone/pkill:翻 supervisor 原始碼確認 Stop() 回來時
子行程已被 cmd.Wait 收屍完畢,補刀多餘;且那兩支指令 Windows 根本沒有。
## 視窗高度擠出畫面
leo 圖三:「視窗尺寸應該是 default 50% 螢幕長寬,高度太高快擠到外面了」。
修:OnStartup 依 ScreenGetAll 算 50% 並置中;保底值 1000x700 → 960x600
(拿不到螢幕資訊時不瞎猜,沿用保底值)。
## 驗(實測輸出)
· go vet 全綠(darwin + GOOS=windows 各一次)
· mac build OK;GOOS=windows CGO_ENABLED=1 CC=x86_64-w64-mingw32-gcc 交叉編譯 OK
· 位元組比對交叉編譯出的 .exe:
新 CIS trayicon.ico 在 exe 裡 = True
舊 Wails「W」圖在 exe 裡 = False
· 未驗:Windows 真機行為(需重打包後由封測者確認)⇒ 狀態 ◐,不是 ✅
|
2026-08-06 12:20:25 +08:00 |
|
Leo
|
051c865085
|
Windows 版 icon 換回 CIS chevron,並根治「換了 appicon 卻沒換 Windows」
leo 08-06 封測回報:托盤與視窗 icon 是「W」,不是 CIS 的 chevron。
真兇:build/windows/icon.ico 是 wails init 生成後從沒被動過的 Wails 預設圖。
換 CIS logo 那次只換了 build/appicon.png,Windows 這顆沒人碰;
tray_windows.go 又 embed 同一顆 ⇒ 視窗與托盤兩處都是 W。
macOS 走 trayicon.png(正確)⇒ 這個病在 Mac 上 100% 驗不出來。
改法不是「這次手動換一顆」,是讓它不可能再漂移:
- 新增 gen-icons.py:兩顆 .ico 一律由 appicon.png 現場產生;
--check 模式比對「committed == 重新產生的」,可當機械閘。
- tray_windows.go 改 embed build/trayicon.ico(小尺寸階梯,系統匣只吃 16/32)。
已驗:重新產生後把 256/32 都渲成 PNG 目視確認為 CIS chevron;--check 通過。
未驗:Windows 真機(需重打包後由封測者確認)⇒ 狀態 ◐,不是 ✅。
同時落帳(wiki status/mistakes):
- manifest 宣告 v0.18.5 但產物是 v0.18.4 的完整證據鏈
- 五個 Windows 真兇(檔:行)
- leo 兩問的設計定案:trigger=內容指紋(不另立、不用 tag/Actions)、
changelog 單一真相源=CHANGELOG.md 其餘全投影
- 這次穿過機械閘的那道縫:缺「宣告版本 == 產物內嵌版本」的驗證
|
2026-08-06 12:09:53 +08:00 |
|
Leo
|
9cd0adab22
|
G-6.2:讀不了的檔案不再安靜消失——首頁當場說出來
服務 J-1 / S6「我丟進去的檔案,查得到」的考題 G-6.2:
「要嘛查得到,要嘛**當場被告知這種檔案還不支援**,不准安靜地略過。」
本次只做後半句(轉檔本體另有人閘,等 leo 裁「那段 Go 住哪裡」)。
## 真實現況比記載更糟
t16 寫的「PDF 被靜默略過」已不成立(t73 的轉檔層把 pdf/docx/xlsx/csv/pptx
都接上了,實測 2 頁中文 PDF 完整抽出)。**真正還在沉默的是別的東西**:
副檔名不在 allowedExt 的檔案在 scan.go 直接 `return nil`——
不進事件、不進 manifest、不進 status、不進畫面。
使用者丟一份 .doc 進去,從頭到尾一個字都沒有。
實測基線(真檔):丟 .pdf/.md/.doc/.key/.jpg 進資料夾,
`collector scan` 只吐出 pdf 與 md 兩個事件,另外三個檔沒留下任何痕跡。
## 改了什麼
- scan.go:白名單閘不再是死巷。像文件的(.doc/.xls/.ppt/.pages/.key/
.numbers/.odt/.ods/.odp/.rtf/.epub/.wpd/.msg/.eml)逐檔留名;
其餘(圖片/影音/程式碼)只計總數——**避免 Obsidian 附件庫炸出幾百行噪音**。
- 兩個新欄位標 `json:"-"`:collector-trigger schema 是
additionalProperties:false,且 BuildSendablePayload 是淺拷貝
⇒ 有 tag 就會漏到雲端被擋。這是給本機使用者看的,不上 wire。
- direct.go → status.json → App 首頁一張卡:講檔名與格式(「舊版報告.doc
(舊版 Word)」),並告訴他不用重丟、也給替代路(另存成 PDF/.docx)。
- 刻意不進 manifest、不走 CarryForwardActivity:每輪由檔案系統重算,
不製造 t195 那種「跨輪欄位漏 carry 就靜默歸零」的債。
## 順手修掉一個會讓驗收失效的回歸
同綑的 arcrun-collector 一路自稱 `dev`:退役 fyne 版
(arcrun-tray/build-mac.sh:24,t150/t72)本來就有版本注入,
t194 換 Wails 時沒帶過來,Mac 與 Windows 兩邊都掉。
**幹活的是 collector**——它不報版本,就沒人能判斷修復有沒有到使用者手上。
## 實測
- go test ./... 135 過 0 敗(新增 10 條:scan 5+首頁文案 5)
- check-cis / check-render / check-tray 三閘全過;淺色深色都抓過畫面
- 從 **DMG 裡那支** collector 實跑:Info.plist 0.18.6、
collector 回報 v0.18.6 (build 20260806-0101)、
status.json 吐出 skipped_docs=[簡報.key, 舊版報告.doc]、other=1
⚠️ 未出貨:推 bundles repo 在 GitHub,要 leo 開 D20 閘。
DMG 已備妥 dist/Arcrun-v0.18.6.dmg。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-06 01:04:25 +08:00 |
|
Leo
|
f32e82bab5
|
清掉三個假 Arcrun:退役 fyne 版 .app 不再進版控
leo 08-05:Launchpad 搜 arc 跑出 4 個 Arcrun,「這很奇怪」。
## 實查:只有一個是真的
/Applications/Arcrun.app v0.18.5 ← 真正安裝的
collector/cmd/arcrun-app/build/bin/Arcrun.app v0.18.5 ← 建置產物(未版控)
collector/cmd/arcrun-tray/Arcrun.app v0.0.1 ← **退役 fyne 版,被 commit 進 repo**
collector/cmd/arcrun-tray/Arcrun RAG.app v0.0.1 ← 同上,更舊的名字
Spotlight 索引磁碟上任何 .app ⇒ repo 裡的產物全冒到 Launchpad。
危險在於**點到 v0.0.1 那兩個就是 t184 的病**(在非 /Applications 執行 ⇒ 更新不了),
等於我們自己的 repo 天天在給用戶擺陷阱。
## 處置
· git rm 兩個 v0.0.1 的 .app(build 產物本來就不該版控;Wails 換代後 arcrun-tray 已退役)
· 刪掉磁碟上三個非安裝版本
· .gitignore 加 collector/cmd/**/*.app
· 兩個 build 目錄放 .metadata_never_index,讓 Spotlight 不再索引產物
驗:mdfind 'Arcrun*.app' 現在只回 /Applications/Arcrun.app 一個。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-05 18:47:57 +08:00 |
|
Leo
|
6bf0daa786
|
修首頁狀態說謊+DMG 補上拖曳版面(leo 08-05 封測回報 ①②)
## ② 首頁狀態是壞的
leo:「拖新的檔案進資料夾,完成本地萃取、上傳,但自始至終 daemon 的首頁都顯示
『有變動就自動開始』『等待中』,都顯示綠燈沒動,實際上已經做完了。」
兩個獨立的真兇:
**A. 「同步中」判斷用錯依據(回歸)**
t191 早就做好機制:collector 開工印 phase:"start"、跑完印 "done",
supervisor 據此維護 StateSyncing。**換 Wails 時 App 沒接這條線**,改看 sync-now 訊號檔:
① 訊號檔只有手動按「立刻同步」才產生 ⇒ 拖檔進資料夾(自動觸發)整輪不亮燈
② 就算手動按,collector 是**先刪檔再跑**(consumeSyncNowSignal)⇒ 真正在跑時檔早沒了
⇒ 改讀 sup.Status().State == StateSyncing。**接回既有機制,不發明第三種判斷法。**
**B. 做完的證據被下一輪抹掉**
ExtractedOK/ExtractFailed 是**本輪**計數、每輪覆寫整份 status.json
⇒ 有產出那輪寫下 N,十幾秒後空轉的一輪把它蓋成 0
⇒ 「上一輪 N 份」永遠空白、四步時間軸的綠燈只靠「跑過任何一輪」判斷=與實際進度脫鉤。
⇒ 新增 last_activity_{at,ok,failed}:有產出記本輪、空轉沿用上一輪(CarryForwardActivity)。
首頁改顯示「幾點整理了幾份」,綠燈只在真的整理過東西時才亮。
## ① Mac DMG 少了「看得出要拖」的版面
leo:「要跳出虛擬隨身碟,打開一個 finder 的視窗,**顯示 Arcrun 和 Application 的捷徑**,
用戶把 App 拖進 Application」。
原本 DMG 內容是對的(Arcrun.app+Applications 捷徑),但**沒設版面**
⇒ 預設清單視圖、位置隨機,看不出「要往右拖」。
⇒ build-dmg.sh 改走 UDRW → Finder AppleScript 設大圖示/視窗大小/左右並排 → 轉 UDZO。
best-effort:無桌面工作階段時只警告不中止(版面是加分,不該讓打包掛掉)。
⚠️ 真正讓 leo 拿到 zip 的原因不在這裡——是**線上 portal 還沒出貨**(見下)。
## 驗(實測輸出)
· collector 全測綠;新增 TestCarryForwardActivity 四子測(含「空轉不該抹掉上次成果」)
· 掛載 dist/Arcrun-v0.18.5.dmg 實查:
內容剛好兩項(Arcrun.app + Applications→/Applications 捷徑)
.DS_Store 6148 bytes(版面已存進去)
Contents/MacOS/ 有 arcrun-app **和 arcrun-collector**
CFBundleShortVersionString = 0.18.5(不是 1.0.0)/LSUIElement = true/codesign -v 通過
· 三支機械閘 check-cis/check-render/check-tray 全 PASS
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-05 18:01:17 +08:00 |
|
Leo
|
1a1478260b
|
打包產物不進版控(dist/ dist-msix/)
dmg/zip/msix 都是可重現的產物,真身走 bundles repo 出貨
(github.com/youlinhsieh/arcrun-rag-bundles)。
進版控只會讓 repo 膨脹、每次重編都變動、每次都來吵未推警察。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-05 17:25:45 +08:00 |
|
Leo
|
133bfdbc84
|
修 Info.plist 版本永遠是 1.0.0+skill 補「用戶視角驗收」
leo 開 DMG 檢查時抓到:CFBundleShortVersionString = **1.0.0**(Wails 預設),
不是 v0.18.4 ⇒ 使用者在 Finder/「關於」看到的版本永遠不變
⇒ 無從判斷自己是不是新版(同「版本號是唯一驗收介面」的病)。
真因:wails.json 沒有 info.productVersion,而 wails build **沒有 CLI 旗標**可指定。
修:build-mac.sh/build-win.sh 建置前把版本寫進 wails.json 的 info,
建完用 trap 還原(不污染版控)。
驗:重打後 Info.plist = 0.18.4 ✅、wails.json 無殘留 ✅
DMG 用戶視角實測(掛載後看):
剛好兩項 Arcrun.app + Applications 捷徑 ✅(拖進去的標準畫面)
MacOS/ 內含 arcrun-app + arcrun-collector ✅(沒同綑=裝了不會同步)
LSUIElement=true ✅(不佔 Dock)|codesign -v 通過 ✅
skill 補兩段:
· 3.5「把 DMG/zip 真的打開,用使用者第一次看到的樣子檢查」(含五項判準與漏掉的後果)
· 開頭「這支 skill 自己的失效模式」——leo:「你寫完一個 skill 然後每個我要提醒你,
表示這個 skill 無效」。根因是憑印象列步驟沒走過使用者的路;
訂三條鐵律(每條要有可貼的實測輸出/使用者看得到的東西一律真的打開/
被 leo 問出來的缺口當場補進 skill)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-05 16:52:34 +08:00 |
|
Leo
|
d80e9e1357
|
t196:Windows 版重編(Wails)+MSIX 打包——在 Mac 上交叉編譯,不需 Windows 機器
leo 08-05:「Windows 版一定要重編,因為我只有 Mac,我需要人家測試,
要做到最完善不要給人家找麻煩,然後當測試者給我截圖安裝成功就要提交 ms store」
## 缺口
Windows 打包腳本全在**舊的 arcrun-tray(fyne 版)**,
新的 arcrun-app(Wails,t193/t194 整批 UI 重做)**完全沒有 Windows 產線**
⇒ Windows 封測者只能拿到 v0.15.7 的舊 fyne 版。
## 新增
· tray_windows.go — Windows 系統匣(energye/systray)
行為與 macOS 版逐項對齊:左鍵開視窗/右鍵只有「結束 Arcrun」/關窗不結束。
⚠️ 為什麼 Windows 能用 systray 而 macOS 不能(wiki 有全文):
macOS 上它在 Wails 之下根本不建托盤(setInternalLoop 只在 systray.Run() 呼叫),
改用 systray.Run() 又搶 macOS 主 loop ⇒ macOS 最後走原生 NSStatusItem。
**Windows 走 Win32 訊息迴圈,沒有主執行緒限制**,所以這裡用 systray 是對的,
不是抄 macOS 失敗的做法。
trayApp 與 ICO 都在本檔自帶(tray_darwin.go 有 //go:build darwin,Windows 看不到)。
· build-win.sh — 交叉編譯 zip(CGO_ENABLED=1 + mingw-w64,Wails Windows 要 WebView2 綁定)
**同綑 collector.exe**:daemon 本體是 collector direct,沒同綑=裝了不會同步
(t194 在 Mac 版就漏過一次)。supervise.go 的 collectorBinPath() 已處理 .exe 副檔名。
· build-msix.sh — MS Store 用的 msix(沿用 makemsix,Mac 上就打得出來)
與舊 fyne 版差別:**Wails 是兩個 exe**,兩個都要進 msix root。
Identity 三值走環境變數(要與 Partner Center 完全一致),預設佔位並印警告。
## 驗
· Windows zip:兩個檔都是正牌 PE(MZ 標頭)/Arcrun.exe 11.4MB+collector.exe 16.1MB
· 退避修復確實編進 Windows 版(不剝符號重編一份,grep 到 MarkFailed/ShouldRetry/
retrySkipReason 各 2 處;出貨版用 -s -w 剝符號故查不到,屬預期)
· MSIX:16 檔、含 AppxBlockMap;zip 回讀兩個 exe 的 sha256 與原檔**逐一相符**;
manifest Executable="Arcrun.exe"、Version=0.18.4.0
· **macOS 版不受影響**:編譯通過、三支機械閘全過
## 兩個踩到的坑(已修)
· zip 用相對路徑在 cd 後失效(zip I/O error,fallback 湊巧成功但不可靠)⇒ 改絕對路徑
· 全形括號緊接變數會被當成變數名(腳本自己的註解就警告過)⇒ 改 ${VAR}
## 殘項
· Identity 仍是 PLACEHOLDER ⇒ **這顆 msix 還不能送 Store**,等 leo 給 Partner Center 三值
· 未在真 Windows 上跑過(誠實界定:只證明編得出來,不證明跑起來對)
|
2026-08-05 15:50:57 +08:00 |
|
Leo
|
369eef07d4
|
修 check-render 誤報:server 沒收乾淨導致連跑會抓到舊頁面
實撞:同一份 build 連跑三次,一次綠兩次紅,白追一輪
(先誤判「深色模式壞了」→ 實際渲染截圖一看深色是好的)。
真因:trap 用 `kill %1`(job spec),在子 shell/連續執行時抓不到
⇒ 上一次的 http.server 佔住 8799 ⇒ 下一次抓到舊頁面。
修:改記 PID 收;並在啟動前先 lsof 清掉殘留在該 port 的 server。
順帶修 mock.js:t193 三修起 main.js 啟動會依 localStorage 覆寫成預設淺色
⇒ 光改 <html data-theme> 會被 JS 蓋掉,要在 module 之前寫 localStorage
(key=arcrun_app_theme)。
驗:連跑三次全過(原本會紅);三支閘 check-cis/check-render/check-tray 全過。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-05 15:22:48 +08:00 |
|
Leo
|
47580f4ba5
|
t195:失敗重試加指數退避+上限——一個壞檔不再拖住整個資料夾
leo 2026-08-05:「有封測者在等,一直出錯」「已經等了幾天了」
## 病(leo 實撞,log 實證)
`小果被AFTEE詐貸.pdf` 雲端 401 失敗後,**manifest 完全不記失敗**
⇒ 下輪掃描又當「新檔」⇒ **1387 輪、跨 11 小時**,每輪 3.2~3.8 秒全在撞同一面牆;
且它排在佇列前面 ⇒ **整個資料夾的同步被一個壞檔拖住**。
leo:「原先萃檔案速度也快,現在花了十幾分才萃完」——**萃取沒變慢,慢的是重試**
(log 的 `FOREACH 所有 5 項目均失敗` 證明卡早就萃好了)。
**這是獨立於 401 的架構缺陷**:401 修好了,下次換別的錯照樣卡死。
## 修
· ManifestEntry 加 FailCount / LastFailAt / NextRetry
· MarkFailed():退避階梯 1m→5m→15m→1h→6h(之後維持 6h)
· ShouldRetry():退避窗口內跳過;連續失敗 8 次暫停自動重試
force(使用者按「立刻同步」)忽略退避與上限——**人明確要求不該被機器擋住**
· MarkIngestedBy() 成功時清空失敗狀態(下次再壞從第一階重算)
· direct.go 三個失敗出口都記退避(讀檔失敗/萃取失敗/上傳失敗)
· retrySkipReason():跳過時說人話,不靜默(同 t195 燈號誠實原則)
## 🔴 真兇其實有兩層——第二層才是關鍵
只加退避欄位**沒有用**:`scan.go` 每輪都**重建** ManifestEntry,
原本只 carry IngestedHash/IngestedAt ⇒ 我寫進去的 fail_count 下一輪就被抹掉
⇒ 退避永遠停在「第 1 次失敗」=等同沒有退避。
(順帶發現 ExtractedBy(t73「誰萃的」)原本也一直悄悄丟失。)
⇒ scan.go carry 補齊四個欄位,並留註解:**日後新增跨輪欄位必須加在這裡**。
## 驗(真實跑,非只有單元測試)
單元測試 6 項全過(退避窗口/指數遞增 60/300/900/3600/21600/21600/
上限停止/force 忽略/成功清空/壞檔不連累同輪其他檔)
實跑(cypher_url 指向不存在主機製造必失敗):
第 1 輪 failed
第 2 輪 skipped「上次失敗(第 1 次),1m0s 後重試」
第 3 輪 skipped(同上)
第 4 輪 skipped(同上)
模擬退避到期 → 確實重送、fail_count=2、退避升為 300s ✅
go test ./... 全綠;go vet 通過。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-05 14:46:03 +08:00 |
|
Leo
|
d787bfc47d
|
t195:燈號不再說謊+加診斷 log(leo:「燈號是真的還是假的?」→ 是假的)
## leo 實撞
丟 PDF 進 youlinhsieh-test1 沒反應;按「立刻同步」後畫面顯示
「正在整理知識卡」,但**卡從來沒產出**。
## 燈號為什麼是假的
舊版 describeStatus 只看「sync-now 訊號檔存不存在」就顯示「同步中…」。
那只代表**排隊了**,不代表有人處理:leo 的 collector 在 11:25 跑完最後一輪,
他 11:38 按同步 ⇒ 訊號檔沒人消化 ⇒ 畫面一直說在整理,實際 13 分鐘沒跑過。
**這比沒有燈號更糟——它在說謊。**
修:燈號要有憑有據——
· collector 沒在跑 → 明說「同步引擎沒有在跑」並告訴他怎麼辦
· 有排隊 **且** 引擎活著 → 才是「同步中」
· 其餘 → 看守中
## 順手補上診斷 log(~/.arcrun-rag/app.log)
startSupervisor 以前只 Stat(config) 就靜默 return,出問題完全查不到
(我這次也是繞了很久才確定它有啟動)。現在每個 return 點都留痕。
## 🔴 但真正擋住產卡的是另一個 401(未修,需 leo 裁)
實測鏈路:掃到 PDF ✅ → /portal/daemon/extract ✅ 200 → 寫 kbdb ❌ 401
curl -X POST https://arcrun-kbdb.youlin-hsieh-dev.workers.dev/entries(無 token)→ 401
真兇:workflows/rag-ingest-card.local.yaml 打 __KBDB_BASE__/entries
**完全沒帶 Authorization**,但 kbdb 要 Bearer KBDB_INTERNAL_TOKEN。
⚠️ 與今天修的 t189 不同:那是 extract 端點入口(現已 200),這是 workflow 內部寫 kbdb。
修法命中 D36 金鑰鐵律(「只能拿 key,送出時自動拉 value」)
⇒ 應寫 {{credential.kbdb_internal_token}} 由 resolve_credentials 回填,
而非讓安裝器 sed 把 token 值塞進定義。**已停下等 leo 裁**。
## CP 對帳
「丟檔→產卡」= ❌ 斷(卡產不出來)。本次只修好「燈號誠實」與「可診斷」,
**未送達用戶**(daemon 新版尚未出貨、401 未修)。
|
2026-08-05 11:45:07 +08:00 |
|
Leo
|
5860ef72df
|
t194 四修:托盤改用原生 NSStatusItem——energye/systray 在 Wails 之下根本不建托盤
leo:右鍵仍然沒用。這次先做**最小重現**才動手,結果推翻了我前兩次的判斷。
## 真兇(實測,非推論)
systray.go:83 的 setInternalLoop(true) **只在 systray.Run() 裡呼叫**;
RunWithExternalLoop 沒有 ⇒ registerSystray() 第一行就
`if (!internalLoop) return;` ⇒ **delegate 從沒建立**
⇒ onReady 不會被呼叫、enable_on_click 不會執行、左右鍵事件根本不存在。
最小重現(scratchpad/traytest):RunWithExternalLoop + onReady 印 "READY"
⇒ **READY 從未印出**。托盤自始至終沒被建立過。
(左鍵之所以「第一次能開」是 Wails 自己開的窗,與托盤無關。)
## 正解:原生 NSStatusItem(tray_darwin.m + tray_darwin.go)
左鍵=開視窗;右鍵=暫時掛選單、performClick、再拿掉(不常駐 setMenu:,
否則按鈕 action 不會被呼叫、左鍵也會變成彈選單——與 systray 那個坑同源)。
## 過程中踩到、也寫進閘的三個坑
① dispatch_async(main_queue) **無效**:Wails 佔住主執行緒後不跑標準 run loop,
排進去的 block 永遠不執行(log 只印到 "dispatching…")⇒ 改 performSelectorOnMainThread
② NSStatusBar 需要 NSApp 已初始化:在 wails.Run() 之前呼叫 ⇒ 靜默失敗、icon 不出現
③ 🔴 **我一度對著 `go build` 產的 stub 除錯**——沒帶 Wails build tags 的執行檔
一跑就印 "Wails applications will not build without the correct build tags" 並退出,
我卻以為是「托盤沒建起來」,白繞一圈。**驗 Wails App 一定要用 wails build 的產物。**
## 實測證據(AppleScript 從 UI 層查,最貼近使用者看到的)
menu bar 數=2,status item 數=1 ← 選單列 icon 真的存在
collector 同步啟動、正常結束無孤兒
三支機械閘全過(閘也改成驗原生實作:不可 dispatch_async/必須
performSelectorOnMainThread/不可常駐 setMenu/不可再依賴 energye/systray)。
⚠️ 仍未驗:左右鍵的**實際點擊行為**要 leo 手動點。
|
2026-08-05 02:56:41 +08:00 |
|
Leo
|
a02eed539a
|
t194 三修:右鍵選單——正解是「**少寫**一段」,不是再補一段
leo 實測:右鍵仍然沒有 quit 選單。
## 真兇:我把函式庫本來就會做對的事,換成一個更脆弱的版本
讀 systray_darwin.go 的 systray_on_rclick():
func systray_on_rclick() {
if onRClick != nil { onRClick(st) } else { C.show_menu() }
}
⇒ **沒註冊 SetOnRClick 時,函式庫自己就會把選單叫出來**;
而且 C 層的 show_menu 內部已經處理好整套:
create_menu() → [statusItem.button performClick:nil] → set_menu_nil()
我卻註冊了自己的 handler、還加 `if menu != nil` 防呆
⇒ 等於用一個判斷把「本來會動的預設行為」擋掉。
修:**刪掉 SetOnRClick 註冊**。左鍵仍自訂(要開視窗),右鍵交還函式庫。
## 判準(已寫進 mistakes)
用第三方函式庫時,**先讀它的預設行為再決定要不要覆寫**。
「多註冊一個 handler」看起來是加功能,實際上常是**關掉**原本正確的行為。
## 閘也跟著改
check-tray.sh 原本驗「SetOnRClick 有註冊且順序對」——**那是在守一個錯的寫法**。
改成反向:**出現 systray.SetOnRClick 就擋下**,並說明原因。
實跑 7 項全過;App 活著 pid 14081、crash 0。
|
2026-08-05 02:27:23 +08:00 |
|
Leo
|
c400292c01
|
新增 check-tray.sh:托盤行為的機械閘(交付警察攔下後補)
leo 真機測出的四個 bug **編得過也跑得起來**,只有真的去點才會發現;
我改完只驗「build ok」就想交 ⇒ 把「點不下去的部分」用可機械檢查的前置條件守住:
① template icon:22/44 RGBA、**不透明 <50%**(否則會顯示成方塊)、顏色種類
② 呼叫順序:AddMenuItem → SetMenuNil → SetOnClick/SetOnRClick
(順序錯=滑鼠事件全失效,正是 leo 撞到的②③)
③ ShowWindow 必須有 Unminimise/Show/SetAlwaysOnTop 三者(缺一就叫不回被蓋住的窗)
④ 結束路徑:有 signal.Notify+waitCollectorGone(否則只能強制結束、留孤兒)
實跑 7 項全過。這支+check-cis+check-render 三支都要過才准交。
|
2026-08-05 01:47:58 +08:00 |
|
Leo
|
fcdb1df71d
|
t194 二修:托盤 icon/右鍵選單/重複點擊/正常結束(leo 實測四點)
leo 真機測出四個問題,每個都查到真兇後才動手:
## ① 托盤 icon 變方塊
真兇:我塞 1024x1024 的**彩色 app icon** 當 template icon。
macOS 選單列規格是 **16-22pt、純黑+alpha**(由系統依深淺色自動上色)
⇒ 彩色大圖被縮成一坨方塊是必然。
修:用 CIS 的 chevron-double.svg 渲成 44x44 純黑 template icon。
## ②③ 右鍵沒選單/第一次能開之後就不再跳
真兇(energye/systray 原始碼註解白紙黑字寫著):
「該方法主動調用後 如果托盤菜單已創建則添加進去, **之後鼠標事件失效**」
⇒ 只要用 AddMenuItem 建了選單,SetOnClick/SetOnRClick **全部失效**。
修:SetMenuNil() 移除選單讓滑鼠事件生效,右鍵時自己 ShowMenu()。
另外 ShowWindow 只呼叫 WindowShow 對「已開但被蓋住」無效
⇒ 補 Unminimise + AlwaysOnTop 閃一下搶焦點。
## ④ 只能用強制結束
真兇:Wails 的 loop 不理 SIGTERM,且 collector 是我們自己 Start 的子行程
⇒ 主程式被殺後**子行程變孤兒繼續跑**。
實測(機械驗證,非目視):
修前 kill -TERM → App 沒退、collector 孤兒還在
修後 kill -TERM → App 正常退出 ✅、collector 一起收掉 ✅、殘留 0
修:installSignalHandler 收 TERM/INT → stopSupervisor() →
waitCollectorGone(3s) 確認子行程真的不見(逾時補一刀)→ 才 os.Exit。
「關了卻還在同步」比沒關更糟。
實跑驗證:App 活著 pid 88466、自己拉起 collector、crash 0、兩支機械閘全過。
|
2026-08-05 01:41:31 +08:00 |
|
Leo
|
643acc0f74
|
t194 修:托盤必須在主執行緒建立——交付警察攔下,實跑才發現會 crash
交付警察問「leo 現在去測會不會發現你沒發現的東西」⇒ 我去真的跑一次,
**發現這版根本起不來**。我原本只驗了「打包產物有沒有那些檔案」,沒驗它會不會活著。
## 兩個 crash,都要真機跑才看得到
① `systray.Run()` 自己開 loop ⇒ 與 Wails 搶 macOS 主 loop
⇒ SIGTRAP `signal arrived during cgo execution`
② 改用 RunWithExternalLoop 但在 OnStartup/goroutine 裡呼叫 start
⇒ SIGABRT `NSWindow should only be instantiated on the main thread!`
(NSStatusItem 內部會 new NSWindow,AppKit 規定只能在主執行緒)
⚠️ 我一度想「加個 sleep 丟 goroutine」——那只是拖延,goroutine 永遠不是主執行緒。
## 正解
main() 一開始(還在主執行緒)就 RunWithExternalLoop 註冊並 trayStart(),
它**不阻塞**,接著把主執行緒交給 wails.Run();defer trayEnd() 收尾。
## 實測(跑真的 .app,非只看檔案)
App 活著 pid 59162 ✅
它拉起自己的 collector ✅(arcrun-app/.../arcrun-collector,與舊 fyne 版並存不衝突)
crash 訊號 0 ✅/log 僅 1 行 ✅
兩支機械閘仍全過。
⚠️ 未驗:托盤左右鍵的**點擊行為**要人真的去點(我點不了)。
|
2026-08-05 00:46:52 +08:00 |
|
Leo
|
549834f343
|
t194:托盤收成 Google Drive 式(點 icon 開視窗/右鍵只有結束)+同綑 collector
leo 2026-08-05:「依照 google drive,托盤裡只剩下按右鍵會結束,
其他設定都在這個頁面,點擊托盤的 icon 就立刻展開界面」
## 托盤
Wails v2 沒有內建托盤 ⇒ 用 energye/systray(Wails 相容分支,支援左鍵事件)。
- 左鍵:直接展開主視窗,**不彈選單**
- 右鍵:只有一項「結束 Arcrun」
- 設定全部留在視窗裡,托盤不再是第二套 UI
(fyne 版把設定塞下拉選單,leo 早說過「不可能統統塞在下拉選單」)
- 關窗=隱藏不結束(daemon 常駐;按 × 就停止同步不符預期)
- Dock 不出現 icon:Wails v2.13 的 mac.ActivationPolicy 還沒開放(原始碼是註解掉的)
⇒ 改走 Info.plist 的 LSUIElement,與 fyne 版同一個做法
## 🔴 順手抓到自己的大漏:這個 App 根本沒有啟動 collector
daemon 的**本體**是 `collector direct`(監看/萃卡/上傳),Wails 版我一路沒接
⇒ 照這樣出貨會是「裝了也不會同步」的空殼。
修:新增 supervise.go,**複用既有 supervisor 套件**(重起退避/狀態機/
t191 的 phase:start/done ⇒「同步中…」),不複製一份(複製=會漂移)。
go.mod 用 replace 指回 collector 主模組。
加/刪資料夾、改 AI 設定後都會 restartWatch(),設定立刻生效。
## 打包
新增 build-mac.sh:編 collector → wails build → **同綑進 .app** → ad-hoc 重簽。
沒同綑就等於沒有 daemon。
實測(v0.18.0):collector 同綑 15M ✅/LSUIElement=true ✅/版本注入 ✅/已簽 ✅
兩支機械閘全過。
⚠️ 未驗:托盤左右鍵的實際行為要真機點(我開不了視窗)。
|
2026-08-05 00:31:52 +08:00 |
|
Leo
|
5a48abb784
|
t193 四修:裁淨版 lockup+側邊欄選中態照 portal(leo 兩點)
## ① logo 比例不對+深色仍有白底+旁邊大量空白
三個症狀同一個根:**我用的是未裁淨的原始 PNG**。
portal 的註解早就寫著:原始 1840x560 **只有 32% 高度是實際字形**,上下大留白
⇒ 同 height 字看起來很小;留白處露出 paper-on-ink 自帶的 Ink 底板=白底。
portal 用的是裁淨版(986x176),但**只內嵌在它的 HTML base64 裡**,我抄不到才用了原始圖。
修:
- 從 portal 的 base64 抽出兩張裁淨版,存成 arcrun-cis/trimmed/ 供全站共用
- 兩張**都是透明底**(實測四邊留白 0)⇒ 深色模式**拿掉 Ink 底板**
- 空白是**版面**造成:側欄 232px 扣 padding 剩 184px,logo 高 24px 只有 134px ⇒ 空 50px
⇒ 側欄對齊 portal 的 216px,logo 改 width:100% 填滿可用寬度
實測(渲染後量像素):
logo 26px 高 × 151px 寬,右側剩餘空白 1px(原本 50px)
深色:側欄底(18,18,18) vs logo 上下皆(18,18,18) ⇒ 落差 0,無白底
## ② 側邊欄選中態太粗糙
leo:「參考現在 Portal 的格式⋯⋯這個比現在膠囊反紅精緻,重點是跟 portal 的形象符合」
修:逐字照 portal 的 #sidenav .nav.on ——
**不是實心膠囊**,而是 amber 字色 + 8% amber 底 + 右側 2px amber 邊。
側欄右緣也照 portal 用 2px amber 35%。
實測:選中列底(237,228,222)=amber 8%、右緣(176,74,47)=Relation、未選(242,241,237)=Canvas。
## 機械閘加三項守衛
- 不准用未裁淨的原始 lockup(字會太小)
- 選中態必須有 border-right-color: var(--amber)
- 不准再出現 border-radius:999px(膠囊,leo 已否決)
兩支閘全過;style.css 仍 0 個 hex。
|
2026-08-05 00:02:46 +08:00 |
|
Leo
|
751ee74f19
|
t193 三修:每庫一頁+狀態時間軸+預設淺色(leo 六點回饋)
## ① logo 尺寸不對導致白邊
真兇:我寫死 height:22px **沒給 width:auto** ⇒ 容器一壓就變形、露出底板邊緣。
修:照 portal 側欄同一條 clamp(22px,5vw,28px) + width:auto + max-width:100%,
並依 CIS「clear space = one chevron height」在四邊留白。
實測:logo 底板與品牌區落差 **0**(原本是明顯方塊)。
## ② 深色跟網頁不同/「它有淺色佈景?」
是——**portal 預設淺色**,深色由使用者切換並存 localStorage。
我卻硬跟系統走 ⇒ 兩邊當然不同。
修:改成與 portal 同一套(預設淺色+切換鈕+localStorage),
按鈕規格也逐字對齊 portal 的 .btn/.btn3(padding/font-size/radius/border)。
實測淺色:品牌區(253,252,251)=Paper、側欄(242,241,237)=Canvas,與 CIS 一致。
## ③ 「開啟知識庫網頁」開到錯的庫
真兇:它在首頁、寫死取 accounts[0] ⇒ 有兩個庫必然開錯。
修:移到**各庫頁的上方**,開的就是那個庫。
## ④⑤ 30 個資料夾放不下/「加入資料夾」會加到哪個帳號?
修:**每個知識庫一個獨立分頁**(側邊欄動態列出,附資料夾數)。
「加入資料夾」在庫頁裡,**作用對象就是那個庫**,不會加錯。
## ⑥ 首頁要顯示 status(看守/發現變化/萃取/上傳)
修:首頁改成**狀態時間軸**四步,進行中那步的圓點會呼吸。
誠實邊界:collector 目前回報「整輪」而非逐檔階段,
所以同步中時後三步一起標進行中,**不假裝有更細的進度**。
兩支機械閘全過(check-cis.sh 14 項/check-render.sh 深淺色皆驗)。
style.css 仍是 0 個 hex(顏色全走 var)。
|
2026-08-04 23:35:49 +08:00 |
|
Leo
|
3d13e5a54e
|
t193 二修:側邊欄版面+共用 CSS+App 內更新+兩支視覺機械閘
leo 08-04 看過 v0.17.0 後的四點,逐條回應:
## ① 「不會這裡又寫了一個新的 CSS?」——是,我又寫了一份
真兇:portal 的樣式內嵌在 HTML 裡,沒有獨立檔 ⇒ 四個站各抄一份、本來就在漂移。
解:抽出 InkStoneCo/arcrun-cis/css/arcrun-cis.css 當唯一真相源。
daemon 的 style.css 現在**一個 hex 都沒有**,顏色全走 var(--...)。
## ② 「完全模仿 gdrive,左方側邊欄,在右方替換頁面」
底部 nav bar 拿掉(leo:「幾乎沒看過這種 nav bar 在下方的」)。
改成左側邊欄四頁:首頁/同步資料夾/AI 設定/版本與更新,右側換頁。
設定不再開 popup;只有「確認移除資料夾」才用覆蓋層。
## ③ 「既然是 Web,你做的時候無法檢視?」——可以,我之前沒做
新增 check-render.sh:headless Chrome 真的渲染一次並**量像素**。
它抓到一個肉眼容易誤判的真 bug:
arcrun-lockup-h-paper-on-ink.png **自帶不透明 Ink 底板**(實測左上像素 RGBA=23,24,26,255),
設計前提是貼在純 Ink 表面;我們背景有紙張紋理 ⇒ 出現突兀方塊。
修:深色模式把品牌區做成純 Ink。實測落差 4(原本會是一個明顯方塊)。
過程中也發現自己對著**舊的 dist**除錯,浪費一輪——這支閘同時防這個。
## ④ 「檢查更新連到 docs,不正確,是直接在這裡進行」
新增「版本與更新」頁:顯示**現在版本 vs 最新版本**,
三段式全在 App 內完成——檢查/下載並安裝/重新啟動套用。
selfupdate 邏輯逐字沿用 arcrun-tray(含 t186 走 raw、t184 蓋正在跑的 .app),不重寫。
## 交貨閘(leo:「你做為檢查有嗎?沒有怎麼交貨?」)
check-cis.sh 擴充:版面檔不准出現任何 hex + 共用底層色票逐項比對。
兩支閘實跑全過。
|
2026-08-04 23:09:54 +08:00 |
|
Leo
|
bd0cead00e
|
t193:daemon UI 換 Wails——CIS 是硬要求,fyne 做不到
leo 2026-08-04 看過 v0.16.0 畫面後:
「功能都有了,但美感非常糟糕⋯⋯跟 CIS 完全無關,每個功能都開一個小小的 popup 視窗,
非常缺乏整體感,這要理解的是原始的技術選擇是否出錯?」
「我的要求是符合 CIS,在風格上跟 portal 一樣」
「CIS 已經提供規範,你做的連 Logo 都沒放上去,這跟美不美有關係嗎?
要求放進 CIS 是硬要求,你做為檢查有嗎?沒有怎麼交貨?」
## 我的兩個錯
1. **動工前沒提醒做不到**——decisions-summary.md:314 的 D-daemon-UI
是我 07-27 自己寫的調研(結論:fyne 全自繪、CSS 套不進去),寫完就沒再看。
今天動工前該查它卻直接開寫,浪費 leo 的時間與 token。
2. **沒做 CIS 檢查就交貨**——連 logo 都沒放。
## 換 Wails(WebView 殼)
前端就是 HTML/CSS ⇒ 可以直接用 portal 那份色票與 lockup。
- style.css 的色票/字體/紙張紋理**逐字取自** portal 的 :root
(matrix/arcrun:console-ui/public/portal/index.html),不自創任何顏色
- CIS lockup 官方 PNG,淺色 ink 版/深色 paper 版,切換規則同 portal
(避開 08-01 作廢的自產 SVG——字腔缺失)
- 對話框改**內嵌覆蓋層**,不再每個功能開一個小 popup
- 原生資料夾選擇器(macOS powerbox 會自動授予該資料夾存取權,
fyne 自繪 picker 拿不到;未來上 Mac App Store 是硬需求)
- 同步中的圓點會呼吸 ⇒ 看得出來在動(issue #17)
- 無帳號時是 onboarding 引導,不是空白面板
## 連線邏輯逐字沿用,不重寫
connect.go 的 normalizePortalURL/fetchConfigByLogin 取自 arcrun-tray/main.go,
含 t86 個資外洩事故的防線(不同實例=新增帳號,絕不覆蓋舊帳號的資料夾)。
今天已犯過一次「重寫別人修好的東西還修得更差」,不再犯第二次。
## 新增 check-cis.sh(交貨前必跑)
機械檢查六類:官方色票逐個到齊/**不准出現非 CIS 色**/logo 真的放進去/
不可用作廢 SVG/深色模式/字體與紙張紋理同 portal/app icon。
實跑 14 項全過。以後「沒跑過就不准交」。
⚠️ 未驗:實際畫面要 leo 開來看(我開不了視窗)。
|
2026-08-04 22:19:41 +08:00 |
|
Leo
|
cc6534dd39
|
t191/t192:daemon 主視窗(Google Drive 風格)+「同步中…」進行中狀態
解 issue #18+#17(leo 指定併做)。
## #17 進行中狀態——真兇是「工作時間對用戶隱形」
leo:「按『立刻同步』後很快就回到『看守中』,看起來好像就做完了,
這時使用者一看沒做完啊,就覺得是 bug」。
真兇:collector **只在一輪跑完後**才印 JSON ⇒ 托盤無從得知「正在跑」。
修:開工前先印 phase:"start"、跑完印 phase:"done";
supervisor 新增 StateSyncing;托盤/主視窗顯示「同步中… 正在讀檔並整理成知識卡」。
形狀相容:兩筆都有 at,舊版托盤只會多算一次 round,不會壞。
實測(真的跑一輪 --once):
第1筆 phase='start' at=21:31:26
第2筆 phase='done' at=21:31:27
## #18 主視窗(新檔 mainwindow.go)
leo:「daemon 設定項越來越多,不可能統統塞在下拉選單」
「參考 Google Drive 設定畫面:點擊 daemon 就開一個視窗,佔螢幕約 1/2」
「資料夾清單要可捲動——我每個 gitea 專案都要同步,那就是幾十個,根本塞不下」
- 920x620 視窗,關窗=隱藏(daemon 續跑)
- 上:大字狀態+副標(上次同步/已整理幾份/失敗幾份;有錯誤優先顯示)
- 中:widget.List 虛擬捲動的資料夾清單(帳號標題+其下資料夾攤平成單層)
- 下:白話動作列(加入資料夾/新增知識庫帳號/AI 設定/檢查更新)
- 每秒自動刷新 ⇒ 同步中看得到在動
- 無帳號時引導去連線(onboarding),不是丟錯誤或空面板
- **所有動作複用既有 handler**,不在視窗那邊重寫一份邏輯
托盤選單第一項加「開啟 Arcrun…」——leo 已點破兩次
「能力做出來了,入口沒出現在用戶會看的地方」(docs 沒連結/MCP 零處提及),
這次做完就讓它看得見。
測試:t192_test.go 八則(狀態文案四態/同步中要說明在做什麼/
副標優先顯示錯誤/副標不可空白/清單攤平且 accIdx 正確/60 個資料夾/無帳號空清單)全過。
collector 與 supervisor 全套綠。
⚠️ 未驗:fyne GUI 的實際外觀需真機開窗(無螢幕環境驗不到),
CIS 視覺套用待 leo 看過畫面再調。
|
2026-08-04 21:32:31 +08:00 |
|
Leo
|
8c7b50d9a9
|
t190:Gemini 金鑰刪不掉——清空輸入框現在真的會刪除
leo 08-04 實撞:「我切到 Gemini 把內容刪掉,再切回 Workers AI,儲存,
回去發現 Gemini Key 還在」。要求:「如果他不想留 Key 了,要可以刪除」。
真兇:cfg.GeminiAPIKey = key 寫在 if useGemini 裡 ⇒ 選回雲端 AI 時整段跳過,
舊金鑰原封不動(帳號層同病)⇒ 清空輸入框等於沒作用。
改成無條件以輸入框為準(清空=刪除),符合使用者心智模型:
我把欄位清空並按儲存,它就該不見。頂層與每個帳號層一併清。
測試:新增 t190_test.go 兩則——清空要真的清掉(頂層+所有帳號層)、
選 Gemini 填值時每層都要寫進去(不可被本次修改弄壞)。兩則皆過,全套綠。
|
2026-08-04 20:47:32 +08:00 |
|
Leo
|
6275daa555
|
t185/t186:三站 nav bar 補齊+自更新改走 raw(jsDelivr @main ref 解析卡死)
## t185:用戶原本根本進不去 docs
leo:「從用戶角度看,**你沒有 nav bar 用戶怎麼進去**?」
——docs 建好了但首頁零連結,只有知道網址的人找得到=同一個病
(能力做出來了,入口沒出現在用戶會看的地方)。
- rag/install 兩站各加同一條 nav(首頁/安裝/說明文件,當前頁 highlight)
- **下載步驟旁**另加 Mac/Windows 分流連結——入口要放在「用戶正在卡住的地方」,
不能只靠頁首 nav
實測(線上抓 href,非只看 200):
rag.arcrun.dev → /docs/、/docs/start/install-mac/、/docs/start/install-windows/
install.arcrun.dev → /docs/
## t186:自更新改打 raw.githubusercontent(推翻 t150 二修的判斷)
真兇不是檔案快取,是 **jsDelivr 的 ref 解析(main→commit)被快取**,
與 purge 都清不掉。08-04 三條路同時比對坐實:
@main 1.4.9/v0.15.6(卡住,x-cache MISS,MISS 仍吐舊)/@sha 與 raw 皆 1.4.10/v0.15.7
zip 能靠改帶版本號檔名繞開,**manifest.json 檔名寫死在 code 裡繞不了** ⇒ 只能換來源。
D20 合規:t150 那輪否決 raw 的理由「那是實名讀」是**誤判**——
D20 對實名的定義是「URL 帶 token@/clone private 殼」,
daemon 這個請求不帶任何憑證=**匿名讀**,D20:22 明列「✅ 放行,不計數」。
副效益:portal 下載按鈕本來就走 raw ⇒ 兩條路同源,不再有「下載頁對、檢查更新錯」。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-04 19:29:17 +08:00 |
|
Leo
|
9fcd82b517
|
v0.15.7:改名 Arcrun.app+發 DMG(拖進 Applications)+MSIX 正式身分
leo 08-04:「如果當初 mac 打包就是 dmg 用拖的,現在 oscar 那裡就解決了,
如果當初 msix 就用了,現在另一個人也是更新就可以」——遠慮該在第一版就有。
原則:**用戶好用、白癡化**。
① 改名 Arcrun RAG.app → Arcrun.app(leo:「不要 rag,要 arcrun.app」)
五處引用一起改(selfupdate.go/build-mac.sh/build-dmg.sh/t184_test.go/README)
② 新增 build-dmg.sh:DMG 內含 Arcrun.app + Applications 捷徑
=Mac 幾十年的標準做法,開起來就暗示你拖進去 ⇒ **從源頭讓 app 待在對的位置**。
坑:hdiutil 預設檔案系統會把「Arcrun RAG.app」截成「RAG.app」⇒ 加 -fs HFS+ 解。
DMG 治源頭、t184 是安全網,兩個都要(已裝在別處的人不會因改發 DMG 就自動變好)。
③ MSIX 用 .env 的正式 Partner Center 身分重打(**不是佔位值**)
回讀 AppxManifest 逐欄驗證:
Identity Name Uncle6.Arcrun
Publisher CN=DE038286-31A5-47CF-B83F-FF6B206BF591
PublisherDisplayName Uncle6
Version 0.15.7.0
仍含 PLACEHOLDER False
實測(t184 端到端,模擬 Oscar 的情境):
app 放 /tmp/oscar-test/Downloads/(不在 /Applications)→ 跑更新覆蓋
→ 該處 app 變成 v0.15.7 ✅
→ /Applications 沒有被無中生有一個副本 ✅
路徑推導三種放置位置皆正確(Downloads/Applications/Desktop)
產物 sha256:
dmg 0eb3f76b60bf6891 mac zip f264dda7391f3006
win 32fe44450ca77c62 msix 5bf7c911b8f3a817
⛔ 誠實標記:MSIX 能否實際安裝**這台 Mac 驗不到**(Add-AppxPackage 只有 Windows)。
已驗的是包結構合法(unpack 過 blockmap 雜湊)+身分欄位正確。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-04 18:12:53 +08:00 |
|
Leo
|
0021c274e8
|
t184:自更新蓋回「正在跑的那個 .app」——修 Oscar 更新完又跳回舊版
leo 08-04 實撞(Oscar 截圖):托盤顯示「🟢 新版 v0.15.6 已就緒」,
點下去重啟後**版本又是 v0.15.4**。同一套機制在 leo 機器正常。
真兇=`selfupdate.go` 寫死 `/Applications/Arcrun RAG.app`:
· leo 有把 app 放進 /Applications ⇒ 剛好蓋對他正在跑的那份 ⇒ 一直正常
· Oscar 從下載資料夾直接跑 ⇒ 蓋到一個他沒在跑的路徑
· 而且 **ditto 會自動建出該目錄並回傳成功**(實測 exit 0,非報錯)
⇒ 畫面說「更新完成」、版本卻永遠是舊的=**靜默失敗**
⇒ 不是新舊 Mac 的差別,是 **app 放置位置**的差別(leo 機器實查證實)。
修法:改用 os.Executable() 往上推 .app(runningAppBundlePath),
更新**當前真的在跑的那份**——放哪都能更新,也不再無中生有 /Applications 副本。
找不到 .app 結構時誠實回錯,不猜路徑亂蓋(蓋錯比不更新更難查)。
⚠️ 「檢查更新」這條路**保留且必須修好**——leo:「這是我解決每次都要撞
沒簽章問題的解法,不能說它無用」。本次是修它,不是繞過它。
測試:新增 t184_test.go(不得回傳寫死 /Applications/.app 推導對三種放置位置
/ditto 靜默建目錄的認知回歸);順手把 t182 的 TestAccountEngineLabel 改寫成
新判準(explicit 決定,非 config 殘留字串)。兩模組全綠。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-04 17:57:46 +08:00 |
|
Leo
|
b1898a4530
|
產物同步 v0.15.6(t182 出貨打包)
Mac/Windows 兩平台重編為 v0.15.6,含 t182 三顆修復。
實測(用**打包後的執行檔**跑,非源碼、非 mock):
① 老 config 抹除 — 丟 leo 真 config 複本(頂層+兩帳號皆 "gemma"、無 explicit)
→ 跑完三層全變 workers-ai、Gemini 金鑰保留、重讀仍是 workers-ai
② 真的走 Workers AI(**把 Gemini 金鑰整個拔掉**才算數)
→ 拔除頂層+帳號層 gemini_api_key 後丟「火星座標.md」
→ 仍 ingested、卡片四段齊全(一句話定義/要點/關鍵實體/關聯)
⇒ Gemini 路無金鑰必失敗,故此卡只可能是 Workers AI 萃的
⇒ 同時證明「新用戶不填任何金鑰就能用」= leo 要的目的達成
③ 版本號注入:mac/win tray 皆 v0.15.6
體積(jsDelivr 20MB 單檔上限內):
mac zip 16M sha256 c31803a4f56c00bc…
win zip 17M sha256 dbb7b0beb5136a70…
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-04 16:40:05 +08:00 |
|
Leo
|
133f5add46
|
t182:老 config 抹除成 Workers AI+雲端探測——leo 實測「無卡」的真因
leo 08-04 實測回報(更新 v0.15.5 後仍顯示 Gemini/丟 PDF 無卡),
查出來不是 Workers AI 不通,是**根本沒走到那條路**。三顆真 bug:
① 抹除只做一半(leo:「就要抹除改成用 Workers AI,如果保持 Gemini
它不會改掉,那就是失敗的」)
t181 只在 RunDirectOnce 改頂層記憶體值,但
- makeAccountSubConfig 會把**帳號層**舊值蓋回來(t126「帳號層優先」)
- 完全**沒寫回檔案** ⇒ 托盤是另一個行程,讀檔還是念 Gemini
leo 的 config 正是頂層+兩個帳號各留 "gemma"、無 explicit
⇒ 畫面顯示 Gemini、萃取也真的跑 Gemini。
修:遷移移到 LoadDirectConfig(每次啟動必經),逐層抹除 + 寫回檔案。
金鑰保留(Gemini 是選配不是廢除)。
② 驗證器擋掉自己的新預設
`extractor 只能是 claude / gemma` ⇒ config 一旦寫成 workers-ai,
daemon 直接載入失敗起不來。v0.15.5 已帶著這顆出貨。
③ 托盤標籤照 config 舊字串念(t178 的通則版)
t178 只把 claude 這**一個**殘留值導向 Gemini,殘留 gemma 一樣脫鉤。
改成與 direct.go 同一條判準:沒 explicit 就一律念「雲端 AI」。
+ t182 雲端探測(leo 指定設計:「會去掃一次看雲端是否裝好,沒裝好就顯示
workers AI 還沒通,一旦通了就顯示可用」):ProbeWorkersAI 逐帳號探
/portal/daemon/extract(送空 text,不燒 LLM 額度),結果寫進 status.json
由托盤「狀態:」講白話。**不做靜默退回 Gemini**——那會讓用戶永遠
不知道自己雲端沒更新。
實測證據(非 mock,打真實例):
- youlin 實例萃真卡:3.67s,產出完整知識卡(一句話定義/要點/關鍵實體/關聯)
- 連測三次:3.51s / 3.34s / 3.59s(Gemini 實測 16.87s ⇒ 快約 5 倍)
- 兩個實例都已有 /portal/daemon/extract(皆回 400=route 存在)
- 拿 leo 真 config 複本跑遷移:三層全抹成 workers-ai、金鑰留著、重讀仍是 workers-ai
測試:新增 direct_t182_test.go(抹除全層/寫回磁碟/主動選過不動/合法值/冪等);
既有三則因預設變更而失效的斷言已更新(t108 二進位不出機的契約未放寬,仍綠)。
全套綠。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
2026-08-04 16:29:56 +08:00 |
|
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 |
|