local-tool/: visionA-local desktop app
- M1: Wails shell + Go server + Next.js UI + Mock mode (macOS dmg ready)
- M2: i18n (zh-TW/en) + Settings 4-tab refactor
- M3: Embedded Python 3.12 runtime (python-build-standalone) + KneronPLUS wheels
- M4: Windows Inno Setup script (build on Windows runner)
- M5: Linux AppImage script + udev rule (build on Linux runner)
- M6: ffmpeg (GPL, pending legal review) + yt-dlp bundled
- Lifecycle: watchServer health check, fatal native dialog,
Wails IPC raise endpoint, stale process cleanup
.autoflow/: full PRD / Design Spec / Architecture / Testing docs
(4 rounds tri-party discussion + cross review)
.github/workflows/: macOS / Windows / Linux build CI
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
13 KiB
Architect Round 1 — 技術可行性分析與重大決策
目的:visionA-local 第一輪技術評估。不寫完整 TDD,只列架構方向、關鍵風險、待決問題。 作者:Architect Agent | 日期:2026-04-10
1. 整體架構方案
採用「Wails 殼 + Go Server 子程序 + Python sidecar」三層結構,而非 single binary。理由:
原 edge-ai-platform 已經跑通 installer/(Wails)把 edge-ai-server(Go binary,內含 go:embed 的 Next.js)作為「payload」解壓到使用者目錄後啟動。這個拆分是對的,不該改成單一 binary:
- Go server 本身要長時間持續跑(serve HTTP、WebSocket、管理 USB 裝置),Wails 前端則是 UI 殼;把兩者綁在同一個行程會讓 UI 當掉時連服務也一起掛。
- Python KneronPLUS SDK 必須由獨立
python3interpreter 執行,無法塞進 Go binary,註定要用 sidecar(os/exec叫scripts/kneron_bridge.py),Go server 仍是中介。 - Wails 本來就適合做「啟動器 + 控制台」,現有
installer/app.go已有 894 行成熟程式碼、含系統資訊偵測、進度回報、裝置偵測、瀏覽器開啟等——幾乎可以直接改名沿用。
建議架構:
visionA-local.app (Wails 二進位)
├─ 內嵌 payload(go:embed installer/payload/...)
│ ├─ edge-ai-server ← Go binary(含 embedded Next.js)
│ ├─ data/ ← models.json + 預置 .nef (~73MB)
│ └─ scripts/
│ ├─ kneron_bridge.py
│ ├─ requirements.txt
│ ├─ KneronPLUS-*.whl ← 每平台一份 wheel
│ └─ (ffmpeg binary — 新增)
├─ 首次執行 → 解壓到 ~/.visiona-local/
├─ 建立 venv + pip install requirements + KneronPLUS wheel
└─ 啟動 edge-ai-server 子行程 → 開啟內嵌 WebView 指向 http://127.0.0.1:3721
Wails 殼同時扮演:首次安裝精靈、Tray/常駐、啟動/停止 server、查看 log。第二次執行直接 detect 到已安裝、跳過解壓。
2. 依賴內嵌策略(關鍵)
2.1 Python Runtime
結論:不要內嵌 Python runtime,改為「偵測 + 自動安裝系統 Python」。
| 平台 | 策略 |
|---|---|
| macOS | 首選:使用者系統已有的 python3(macOS 12+ 幾乎都有)。無則呼叫 Homebrew 安裝(現有程式碼已有 brew install python@3.12 流程) |
| Windows | 首選:winget install Python.Python.3.12。備援:從 python.org 下載 embedded zip |
| Ubuntu | apt-get install python3 python3-venv python3-pip(需 sudo polkit 提權) |
不採用 python-build-standalone / PyInstaller 的原因:
- KneronPLUS wheel 綁定
pyusb+ 原生 libusb,用 embedded Python 時 site-packages 的 C extension 常踩到 ABI 問題 - 每平台都內嵌完整 Python 會讓安裝檔大約 +40MB,且升級 Python 需要重發整包
- 現有
installer/app.go的setupPythonVenv()邏輯已在 macOS/Windows/Linux 跑通,包含 linux 缺ensurepip的 fallback
代價: 使用者需要能連網做一次 pip install。如需完全離線,第二階段可改為 bundle wheels + pip install --no-index --find-links(requirements.txt 只有 numpy / opencv-python-headless / pyusb 三個,加上 KneronPLUS 共 ~80MB wheels)。建議採「離線 wheel」路線——完全符合「一鍵安裝不需連網」的要求。
2.2 KneronPLUS SDK
結論:每平台打包對應的 wheel,透過 pip install 解壓到 venv。原 installer/wheels/ 已有三平台的 wheel(共 3.9MB)。
| 平台 | wheel 狀態 | 原生函式庫 | 注意事項 |
|---|---|---|---|
| macOS | KneronPLUS-2.0.0-*.whl(含 .dylib) |
kp/lib/*.dylib | 需要 ad-hoc codesign(已有程式碼)否則 Gatekeeper 擋 |
| Linux | KneronPLUS-2.0.0 / 3.1.2-*.whl(含 .so) |
kp/lib/*.so | 需要 libusb-1.0(apt-get install libusb-1.0-0)+ udev rule 讓非 root 使用者能存取 USB |
| Windows | KneronPLUS-3.1.2-*.whl(含 .dll) |
kp/lib/*.dll + libusb-1.0.dll | 需要安裝 WinUSB driver(已有 installer/drivers/kneron_winusb.inf)— 這一步可能需要使用者手動同意 UAC |
USB driver 是風險點: Windows 必須裝 WinUSB driver 才能讓 libusb 存取裝置,現有程式碼透過 pnputil 或類似方式自動安裝,會彈 UAC。Linux 需要寫入 /etc/udev/rules.d/99-kneron.rules 也要 sudo。macOS 完全不需要 driver(IOUSB 直接用)。這點要在 PRD 裡寫成「首次啟動需管理員權限」。
2.3 ffmpeg
結論:內嵌靜態 binary,不要走 brew/winget。
| 平台 | 來源 | 大小 | 授權 |
|---|---|---|---|
| macOS (Intel + ARM) | evermeet.cx 的 static build,或 BtbN GitHub Release | ~40MB | LGPL build(不要用 GPL 版,避免產品須開源) |
| Windows | gyan.dev 或 BtbN 的 essentials_build | ~50MB | LGPL |
| Linux | johnvansickle.com 或 BtbN static build | ~50MB | LGPL |
做法: 在 installer/payload/ffmpeg/{platform}/ffmpeg 放靜態檔,解壓後 Go server 用絕對路徑呼叫,不依賴 PATH。原 stepInstallFfmpeg() 是 fallback 去系統 PATH 找,新版應改為一律用內嵌版確保可重現。
必須使用 LGPL build 而非 GPL build——否則整個產品就被 GPL 感染。授權聲明要寫在 About 頁。
2.4 預置模型 .nef
結論:放在 payload 中一起解壓到 ~/.visiona-local/data/nef/,不塞進 Go binary。
現狀 nef 總量 73MB。理由:
- go:embed 會把 73MB 直接吃進 Go binary,link 時記憶體吃緊、IDE debug 變慢
- 解壓後使用者可手動管理、刪除、增加自訂模型(符合既有
custom-models流程) - 沿用現有
stepExtractData的做法
3. 打包輸出格式
| 平台 | 格式 | 簽章 |
|---|---|---|
| macOS | .app 內包 Universal Binary(arm64 + amd64 用 lipo 合併)→ 再包成 .dmg |
強烈建議做 Developer ID + notarization;否則使用者第一次開啟要右鍵 → 開啟。Wails 支援 wails build -platform darwin/universal。Notarization 需要 Apple Developer 帳號($99/年) |
| Windows | .exe(NSIS / Inno Setup 都可,推薦 Inno Setup,UI 較現代) |
Authenticode 簽章否則 SmartScreen 會狂擋新下載。EV 憑證 $300-500/年 |
| Ubuntu | .AppImage(首選)+ .deb(次選) |
無強制簽章 |
為何選 AppImage: 單檔、不需安裝、不需 sudo、攜帶性最高,最符合「像一般 app」的體驗。.deb 需要 apt install、需要 sudo、只能跑 Debian 系;AppImage 跨所有 glibc ≥2.28 發行版。.snap / Flatpak 需要發到 store,發行流程重。
Universal Binary 是否做? 建議做。現在 M1/M2 使用者已經是主流,若只發 Intel 版,M 系 Mac 要走 Rosetta,效能不穩(KneronPLUS dylib 如果是 x86_64-only 更糟)。需先確認 KneronPLUS macOS wheel 是否支援 arm64——這是風險點 R3。
4. 預估安裝檔大小(壓縮後)
| 平台 | Wails shell | Go server | Next.js embed | Python wheels | ffmpeg | NEF 模型 | WinUSB driver | 合計 |
|---|---|---|---|---|---|---|---|---|
| macOS (Universal) | ~12MB | ~25MB (x2 架構 ~50MB) | ~5MB | ~40MB | ~35MB | ~73MB | - | ~215MB |
| Windows | ~10MB | ~20MB | ~5MB | ~40MB | ~45MB | ~73MB | ~1MB | ~195MB |
| Ubuntu (AppImage) | ~12MB | ~20MB | ~5MB | ~40MB | ~45MB | ~73MB | - | ~195MB |
以上為壓縮後大小。主要體積來自 ffmpeg + Python wheels + 預置模型。若要瘦身:可將 .nef 改為首次啟動時線上下載(-73MB),但違反「完全離線一鍵安裝」原則。建議接受 ~200MB。
5. 既有程式碼取用策略
| 目錄/檔案 | 策略 | 說明 |
|---|---|---|
installer/ |
直接複製改名 | 改為 visiona-local/,app.go 刪除 relay/dashboard 欄位,其餘流程沿用 |
installer/wheels/ |
直接複製 | 三平台 KneronPLUS wheel |
installer/drivers/ |
直接複製 | WinUSB driver 檔案 |
server/main.go |
改寫 | 刪除 cluster / tunnel / relay-token / gitea-url 相關參數與初始化 |
server/internal/api/ |
改寫 | 刪除 cluster、tunnel handler 與 route |
server/internal/camera device model inference flash config deps |
直接複製 | 核心業務邏輯全保留 |
server/internal/cluster |
❌ 刪除 | |
server/internal/tunnel |
❌ 刪除 | |
server/cmd/relay-server |
❌ 刪除 | |
server/tray/ |
直接複製 | 保留 macOS tray + Windows --gui web controller |
server/scripts/ |
直接複製 | kneron_bridge.py + firmware update |
server/data/ |
直接複製 | models.json + 預置 nef |
server/web/ + frontend/ |
改寫 | 移除 relay 模式切換、cluster 管理 UI |
docker/ scripts/deploy-* |
❌ 刪除 | 不需要部署腳本 |
tools/ |
視情況 | 多數是開發腳本 |
6. 要砍掉的程式碼清單(具體路徑)
server/internal/cluster/ ← 整包刪
server/internal/tunnel/ ← 整包刪
server/cmd/relay-server/ ← 整包刪
server/pkg/hwid/ ← relay token 用的,可刪
docker/ ← 整包刪
scripts/deploy-aws.sh
scripts/deploy-ec2.sh
frontend/app/.../cluster/ ← 前端 cluster 頁面(待 Design Agent 確認)
frontend/app/.../relay/ ← 前端 relay 模式切換 UI
server/main.go 需移除的 import 與初始化:
internal/cluster,internal/tunnel,pkg/hwidcfg.RelayURL / RelayToken / GiteaURL相關 flagtunnelClient.Start()、clusterMgr、relayWebURL()等config.go中的RelayURL / RelayToken / TrayMode(tray 保留)GUIMode、GiteaURL砍掉
7. 重大技術風險(Top 5)
| # | 風險 | 可能性 | 影響 | 緩解 |
|---|---|---|---|---|
| R1 | KneronPLUS Linux wheel 只有特定 glibc/ABI,無法在所有 Ubuntu 跑 | 高 | 高 | 先實測 Ubuntu 22.04/24.04 x64,若不過則限定支援版本;訴求 AppImage 內帶 libusb |
| R2 | Windows WinUSB driver 安裝需要 UAC,使用者拒絕就裝不起來 | 中 | 高 | 首次啟動明確說明;提供「手動安裝 driver」的後援流程 |
| R3 | KneronPLUS macOS wheel 可能只有 x86_64(M 系 Mac 要走 Rosetta,dylib 會抗議) | 中 | 高 | 第二輪前必須驗證:lipo -info 檢查 .dylib 架構;若只有 x86_64,Universal Binary 就沒意義 |
| R4 | 離線 wheel 安裝在沒有 pip 的 Python 環境會炸(macOS 系統 Python 有 pip,但 Ubuntu 沒有 python3-venv 是常態) |
中 | 中 | 已有 installPython3Venv() fallback,但需要 sudo;考慮改為引導使用者手動裝 |
| R5 | 預置 .nef 模型授權可能限制重新發布 | 低 | 中 | 請 PM 確認 Kneron 預置模型的 re-distribution license |
8. 需要 PM / Design 回答的問題
給 PM:
- 目標使用者是「開發者 / ML 工程師」還是「一般使用者」?影響 UI 的技術密度(要不要顯示 log、要不要 advanced mode)
- 是否必須支援完全離線一鍵安裝?還是可以在首次啟動時連網下載 wheels?影響 R4 緩解方案
- 預置模型清單要保留哪些?現狀 KL520/KL720 各有 5-6 個,73MB;可否精簡到 30MB?
- 是否支援多裝置連接(一台電腦插兩顆 Kneron dongle)?影響裝置列表 UI
- 要不要保留韌體更新功能(
update_kl720_firmware.py)?
給 Design:
- Wails 殼的 UI 要走「安裝精靈風格」還是「Dashboard 風格」?原 installer 是精靈式,但 local 版應該常駐後是 Dashboard
- 需要 Dark Mode 嗎?
- 首次安裝流程的進度條樣式(現有是 0-100% 橫條,可否保留?)
- 系統列(Tray)菜單要放哪些項目?至少:開啟儀表板 / 啟動/停止 / 結束
9. 需要使用者確認的問題
- Apple 簽章與 notarization:是否有 Apple Developer 帳號?沒有就只能 ad-hoc sign(使用者第一次要右鍵打開)
- Windows Authenticode:是否願意採購 EV 簽章憑證(~$300/年)?沒有就會被 SmartScreen 警告,但仍可使用
- 最低 OS 版本:建議 macOS 12+、Windows 10 (1809)+、Ubuntu 22.04+,可接受?
- ARM Linux(Raspberry Pi 之類):暫不支援?(KneronPLUS 的 arm64 Linux 支援度不明)
- Bundle ID:
com.innovedus.visiona-local可以用嗎?(progress.md 已記錄但標記待確認) - 離線 vs 線上安裝:追求完全離線(~200MB 安裝檔)還是接受首次連網(~120MB 安裝檔)?
- 預置模型:是否需要精簡清單?
- 應用程式名稱顯示:visionA-local 還是 VisionA Local?品牌字風格?
下一步: 等待 PM / Design / 使用者對上述問題的回覆。回覆後進入第二輪——產出完整 Design Doc 與 TDD,拆分為模組化檔案(04-architecture/design-doc.md 索引 + api/、database.md、infra.md 等子檔)。