使用者回報:Windows 乾淨環境安裝後,一打開 app 就看到「Settings modal +
shutdown-modal「正在停止伺服器…」+ 紅 banner「伺服器無法啟動」」三個應該
hidden 的 element 同時可見。
前面幾個 commit 一直往 Go 端找為什麼 ctrl.Stop 會被意外呼叫,全都沒對。
真正的 bug 是 CSS specificity:
.modal-backdrop { display: flex; ... } /* L587,specificity (0,1,0) */
.error-banner { display: flex; ... } /* L488,specificity (0,1,0) */
這兩個 class 的 `display: flex` 規則和 user agent stylesheet 內建的
`[hidden] { display: none }` specificity 相同,但因為我們的 CSS 寫在
cascade 後段勝出——結果是即使 DOM 裡元素有 `hidden` 屬性,瀏覽器依然
渲染成 `display: flex` 可見。
三個受害元素:
<div class="modal-backdrop" id="settings-modal" hidden>
<div class="modal-backdrop shutdown-modal" id="shutdown-modal" hidden>
<section class="error-banner" id="error-banner" hidden>
全部從 DOM 載入第一刻就可見,和 Go 端 ctrl.Stop 是否被呼叫無關。M7
splash 時代前端沒 modal 所以沒人踩到,M8 新加的控制台 UI(8cd5751)
引入這個 bug,但 macOS dev 測試時我只看 server 端 log + api 回應,
沒真的看 Wails 視窗長什麼樣,所以也漏抓。
修法:加全域 `[hidden] { display: none !important; }`。這是 W3C 規範
的標準寫法,保證任何帶 hidden 屬性的元素都會被隱藏,不管其他 CSS
規則怎麼寫。!important 在這情境是正確的——hidden 屬性代表「該元素
不應被顯示」是規範強制語意,不該被任何樣式覆蓋。
驗證:
- macOS dmg 重 build 163MB OK
- binary 內 strings 確認 `[hidden] { display: none !important; }` 已 embed
- 清乾淨 user dataDir 後啟動 wails app,wails.log 整條 startup 流程正常:
Stage 1 complete → Stage 2 → ctrl.Start returned successfully
- Chrome 建立 2 條 ESTABLISHED 連線到 127.0.0.1:3721
- dataDir 有完整檔案(lock / ipc-port / wails-ipc-port / sentinel / models.json / nef/)
前幾個 commit 修的東西(Stage 2 pause、waitHealthy pause、shutdown modal
safety net、Bug A killStaleServerOnPort)仍然有防禦價值,但都不是使用者
截圖症狀的 root cause。
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
visionA-local
裝起來像一般 app,離線也能跑,接上 Kneron 就推論。 把
edge-ai-platform的 Kneron AI 邊緣推論能力,打包成單機桌面應用。
這是什麼
visionA-local 是 edge-ai-platform(原本要部署到 EC2 + Docker 的 Kneron 邊緣推論平台)的單機桌面衍生版本。為「帶著筆電做 Kneron demo 的人」而生 —— 主要服務 Innovedus 內部 FAE 與外部 Kneron 開發者。
三個核心承諾:
- 🎒 零依賴:Python runtime、KneronPLUS SDK、ffmpeg、預置
.nef模型全部內嵌 - ✈️ 零網路:下載一次後完全離線可用(適合客戶現場 IT 鎖得死緊的場景)
- 🖱️ 零學習成本:雙擊安裝 → 開啟 → 插上 Kneron 裝置 30 秒內跑出第一幀推論
對標產品:Docker Desktop、Ollama。
安裝(使用者)
macOS(x86_64,beta)
- 從內部 Gitea Releases 下載
visiona-local.dmg - 雙擊開啟 dmg → 把
visionA-local.app拖到Applications/ - 第一次啟動:因為未做程式碼簽章,Gatekeeper 會警告「來自未識別開發者」
- 在 Finder 中右鍵點
visionA-local.app→ 選「開啟」(不是雙擊) - 對話框出現「仍要開啟」時點確認
- 往後直接雙擊即可
- 在 Finder 中右鍵點
- 首次啟動會花 30–60 秒解壓內嵌的 Python runtime 並離線安裝 wheels 這是預期行為,不是卡住。之後啟動只要幾秒
📁 資料目錄:
~/Library/Application Support/visiona-local/包含 log、lock、ipc-port、自上傳模型
Windows / Linux
Coming soon — build script 已經寫好,等 CI runner 齊備後就會釋出。
- Windows:Inno Setup
.exeinstaller - Linux:
.AppImage+ udev rules(需 root 裝99-kneron.rules)
系統需求
| 平台 | 最低版本 | 架構 |
|---|---|---|
| macOS | 14 Sonoma | x86_64 ¹ |
| Windows | 10 1809 | x86_64 |
| Ubuntu | 22.04 | x86_64 |
¹ Apple Silicon 理論上可透過 Rosetta 2 執行,但未經測試。
離線可用:安裝後所有核心功能(包含 Python sidecar、推論、模型管理、攝影機、影片解碼)完全不需要網路。
功能總覽
✅ 有的功能
- 裝置管理:USB 自動偵測 Kneron KL520 / KL720,10 秒內連線
- 攝影機推論:MJPEG 串流 + 即時 overlay(首次延遲 ≤ 250ms,穩定後 ≤ 150ms)
- 模型管理:8 個預置
.nef模型(分類 / 偵測 / 臉辨)+ 自上傳切換 - 核心推論引擎:image classification、object detection、face recognition
- 媒體推論:支援圖片與影片檔(本機上傳,R5 決策後不支援 URL 推論)
- 中英雙語,跟隨系統 Dark Mode
❌ 不做的事(明確排除)
為了聚焦「個人工具」,以下功能從 edge-ai-platform 全數砍掉:
- ❌ Cluster(多裝置叢集)
- ❌ Relay / Tunnel(遠端連線、反向代理)
- ❌ 韌體燒錄(firmware flash)
- ❌ 系統列 Tray 常駐
- ❌ Auto-update
- ❌ Telemetry / 崩潰回報
- ❌ License 啟用、憑證簽章
- ❌ Mac App Store / Microsoft Store / Snap Store 上架
開發者區
專案結構
local-tool/
├── .autoflow/ PRD / 設計 / 架構 / 進度文件
├── server/ Go 1.26 後端(Gin + go:embed)
├── frontend/ Next.js 16 + React 19 + shadcn
├── visiona-local/ Wails 應用殼(installer)
├── payload/ 打包暫存區
├── vendor/ 第三方依賴(make vendor-sync 下載,不進 git)
├── dist/ 最終安裝檔(.dmg / .exe / .AppImage)
├── installer/ Inno Setup / AppImage script
├── scripts/ build 與維運腳本
└── Makefile
開發流程
# 1. 下載全部第三方依賴到 vendor/
make vendor-sync
# 2. 本機 build 並產出 dmg(macOS)
make dmg
# 查看所有可用 targets
make help
主要 make targets:
| Target | 作用 |
|---|---|
vendor-sync |
下載 python-build-standalone、wheels、ffmpeg |
build-server |
編譯 Go server binary(先 build frontend + embed) |
build-frontend |
pnpm build Next.js 靜態產物 |
payload-macos |
準備 macOS payload(binary + python + wheels + ffmpeg + 模型) |
wails-macos |
Wails build + ad-hoc codesign |
dmg |
產出 dist/visiona-local.dmg |
exe |
Windows installer(需在 Windows runner 執行) |
appimage |
Linux AppImage(需在 Linux runner 執行) |
三方平台 build
| 平台 | 指令 | 執行環境 |
|---|---|---|
| macOS | make dmg |
本機(Intel Mac) |
| Windows | make exe |
Windows runner + Inno Setup 6 |
| Linux | make appimage |
Ubuntu 22.04+ runner + appimagetool |
vendor-*-windows / vendor-*-linux 可在 macOS 上跑通(只有 wails-* 和最後一步 installer 需要對應平台)。
文件位置
所有設計與架構文件在 .autoflow/:
| 類型 | 路徑 |
|---|---|
| 產品需求(PRD) | .autoflow/02-prd/PRD.md |
| 設計規格 | .autoflow/03-design/ |
| 架構設計 | .autoflow/04-architecture/design-doc.md |
| TDD | .autoflow/04-architecture/TDD.md |
| 進度 | .autoflow/progress.md |
已知限制與 TODO
- 🟡 Kneron 預置模型 re-distribution 授權:開發階段假設可用,正式發佈前需與 Kneron 官方確認
- 🟡 Windows / Linux 安裝檔:build script 就緒,等 CI runner 齊備
- 🟡 Apple Silicon 未經測試(理論上 Rosetta 2 可跑)
- 🟡 Linux Kneron USB vendor ID:
installer/linux/99-kneron.rules需最終確認 - 🟡 程式碼簽章(Developer ID / EV cert)不做,使用者需手動繞過 Gatekeeper / SmartScreen
- 🟡 無 auto-update:新版需手動從 Gitea 下載
授權
License: TBD(內部工具 / MIT / proprietary 待定,發佈前確認)
第三方元件授權
| 元件 | 授權 | 備註 |
|---|---|---|
| ffmpeg | LGPL v3(方案 B 混合:macOS 自 build decoder-only / Windows & Linux 用 BtbN n7.1 LGPL) | v2 TDD §2.2 |
| KneronPLUS SDK | Kneron 商用條款 | 再次確認 re-distribution 權利 |
| python-build-standalone | MPL 2.0 / PSFL | — |
| Python 標準函式庫 | PSFL | — |
| shadcn/ui | MIT | — |
| Next.js / React | MIT | — |
| Wails | MIT | — |
| Gin | MIT | — |
完整第三方授權清單於 .autoflow/02-prd/PRD.md §4.8。
致謝 / 起源
visionA-local 衍生自 Innovedus 內部專案 edge-ai-platform(原為部署於 EC2 + Docker 的多人共享平台)。本專案將其改造為單機桌面版本,聚焦「一個人帶一台筆電」的使用場景。
感謝 Kneron、python-build-standalone(astral-sh)、shadcn 等開源社群。