Leo
|
12c2d41886
|
feat(collector): daemon 產出改成規範形 wiki 卡——1 文件卡+N 原子卡落 .wiki/(InkStoneCo#44 ④)
LLM 只回 JSON 判斷,格式/落點/連結閉合/索引/manifest 全由 wikishape.go 機械組裝:
- 卡形=frontmatter(tags/gloss/created/updated)+← 上層+摘要/重點/實體(帶類型)/
關聯(內文知識關係/卡片關係/出處)——差距表 #6
- 落點 <節點>/.wiki/、檔名=H1(.wiki 隱藏目錄自身即機器標記,machinemark 例外③)——#7
- 00-INDEX 機械維護:每行五樣照抄 frontmatter;每份原稿必列——#8
- 萃取端就切 1 hub+N 原子卡(gemma 路 prompt 改 JSON 契約)——#9
- 無可萃概念標「空」+理由,上索引不產卡——#10
機械保證對著 wiki-lint.py 寫:斷連結拆殼、index 式句改寫、三元組恰三項、
雙向邊自動補反向、佔用不覆蓋、原稿永不動;同名概念跨文件先消歧(merge 歸第⑤環)。
scan/convert 白名單補 .feature/.yaml/.yml/.org/.rst(規範洞 6);
lint.go 新舊格式雙軌(workers-ai 雲端 prompt 屬 matrix/arcrun 核心,待開票);
direct.go 只送文件卡上雲(takedown 配對鍵不變)、下架收走 .wiki 產物。
實測:真資料夾+真 Gemini → 2 節點 12 卡,wiki-lint 17/17 exit 0,
原稿 sha256 前後不變;go test collector+supervisor+arcrun-app 全綠(新增 9 案)。
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
2026-08-15 21:03:45 +08:00 |
|
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
|
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
|
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
|
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
|
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 |
|