專案進度 — visionA-local
目的:全新專案(從 edge-ai-platform 衍生的 local 版本)
當前階段:第二階段 — M7 Windows 實機 build + splash regression 修復
當前狀態:Windows 端待驗證重 build 後 UI
最後更新:2026-04-12
🎉 M1 達成總結
dist/visiona-local.dmg (70MB) 可雙擊安裝
- 全新環境下能 mount → 拖到任意位置 → 雙擊執行
- Mock 模式 server 子程序自動啟動(Bundle 內
Resources/bin/visiona-local-server)
- API endpoints 全部 200:health、info、devices、models
- 乾淨退出(SIGTERM → 5s → SIGKILL)
- 資料目錄:
~/Library/Application Support/visiona-local/(lock + ipc-port + logs + custom-models)
- 第三輪 P0 bugs 修復:(1) APFS case-insensitive 自我毀滅、(2)
--python flag 不存在、(3) Resources/bin/ 路徑漏 bin/ 子目錄
M1 收尾(C 已完成)
- ✅
GET / 404 修復:Makefile 加 build-embed target,把 frontend/out → server/web/out 同步,再 build server binary。dmg 71MB 含完整主 UI(21KB 首頁 + Next.js chunks)
M2-M6 任務清單(使用者選 Y:全包,macOS 為主)
M2 — i18n + Settings 分頁調整
| # |
任務 |
狀態 |
| M2-1 |
i18n 中英雙語切換 |
✅ |
| M2-2 |
Settings 4 分頁重構 |
✅ |
| M2-3 |
清 cluster.* i18n keys |
✅ |
| M2-4 |
sidebar Workspace 接 i18n |
✅ |
| M2-5 |
rebuild dmg + smoke test |
✅(71MB, root+settings 200, server 從 bundle Resources 起) |
M3 — Python runtime 策略 A 內嵌 + KneronPLUS wheel
| # |
任務 |
狀態 |
| M3-1 |
vendor-python (PBS 3.12.9, 15MB) |
✅ |
| M3-2 |
vendor-wheels (9 wheels, 71MB) |
✅ |
| M3-3 |
ensureBundledPython() 實作 |
✅ |
| M3-4 |
payload-macos stage python + wheels |
✅ |
| M3-5 |
dylib codesign |
✅ 不需要(Gatekeeper 沒擋) |
| M3-6 |
rebuild dmg + smoke test |
✅ 157MB, venv + 9 wheels + import kp 全通過 |
M6 — ffmpeg + yt-dlp 內嵌(完整離線)
| # |
任務 |
狀態 |
| M6-1 |
vendor-ffmpeg |
✅(77MB GPL build, 由 VISIONA_ALLOW_GPL_FFMPEG flag 放行) |
| M6-2 |
vendor-ytdlp |
✅(35MB, yt-dlp 2026.03.17) |
| M6-3 |
payload-macos stage ffmpeg + yt-dlp |
✅ |
| M6-4 |
server internal/deps/ env var 偵測 |
✅(VISIONA_BUNDLE_BIN_DIR) |
| M6-5 |
rebuild dmg |
✅ 220MB |
🔴 P1 release blocker:ffmpeg 授權
- macOS 上現成的 ffmpeg static binary 全部都是 GPL build(含 --enable-gpl --enable-libx264)
- 使用者決定 B:暫定使用 GPL build,發佈前由法務 review
- 必須在 PRD 第三方授權頁明確標
ffmpeg: GPL build (under legal review)
- 替代方案保留:自 build LGPL(需 build pipeline)/ online download / 砍 ffmpeg 功能
M4 / M5 — Windows / Linux(無法在這台 Mac 驗證,僅寫 script)
| # |
任務 |
狀態 |
| M4-1 |
Inno Setup .iss script |
✅ installer/windows/visiona-local.iss |
| M4-2 |
Makefile wails-windows / exe target |
✅ uname 守門 |
| M4-3 |
payload-windows |
✅ 在 macOS 上跑通 vendor 部分(378MB) |
| M5-1 |
build-appimage.sh |
✅ installer/linux/build-appimage.sh |
| M5-2 |
Makefile wails-linux / appimage |
✅ uname 守門 |
| M5-3 |
payload-linux + udev rule |
✅ installer/linux/99-kneron.rules + install-udev.sh,在 macOS 上跑通 vendor(317MB) |
lifecycle 補件(M1+ TODO 移入 M2-M6 末尾)
| # |
任務 |
狀態 |
| L-1 |
watchServer() 每 10s health check |
✅ 連續 3 次失敗 emit server:dead event |
| L-2 |
Fatal 原生對話框 |
✅ macOS osascript / Win PS / Linux zenity-kdialog-stderr |
| L-3 |
Wails /ipc/raise endpoint |
✅ 隨機 port + wails-ipc-port 檔案 |
| L-4 |
stale process 清理 |
✅ macOS/Linux lsof+ps;Windows 留 TODO |
M7 — Windows 實機 build + splash regression 修復(2026-04-12)
M7-A:Windows 一鍵 build 工具鏈(使用者在 Windows 機器上實機跑 bootstrap)
新增 local-tool/scripts/bootstrap-linux.sh + bootstrap-windows.ps1,目標是使用者 clone repo 後一行指令完成依賴安裝 + vendor 下載 + payload 打包 + wails build + installer 產出。
| # |
任務 |
狀態 |
| M7-A1 |
統一專案目錄名為 local-tool(連字號),清掉所有 local_tool 殘留 |
✅ |
| M7-A2 |
bootstrap-linux.sh(apt + go 1.22.5 + node 20 + pnpm + wails) |
✅ 未在 Ubuntu 實機驗證 |
| M7-A3 |
bootstrap-windows.ps1(winget 安裝 git/go/node/python/msys2/inno setup + build) |
✅ Windows 實機驗證通過 |
Windows build 踩坑紀錄(每個都修好並 push):
- PowerShell 5.1 不支援
&& → 改用陣列 + -join ' && '
- 中文亂碼 → ps1 加 UTF-8 BOM
pip3: command not found → Makefile 偵測 pip/pip3/python -m pip + bootstrap MSYS2_PATH_TYPE=inherit 讓 bash 繼承 Windows PATH
unzip: command not found → Makefile 改用 Python zipfile 解壓,移除 unzip 依賴
server.exe 沒 build → 新增 build-server-windows cross-build target
- Microsoft Store
python3 stub → Makefile 偵測時排除 *WindowsApps* 路徑,bootstrap 主動找真實 Python 並以 VISIONA_PYTHON 環境變數傳入
/tmp/ffmpeg-win.zip 路徑問題 → Windows 版 python.exe 不懂 MSYS2 的 /tmp,改用相對路徑 vendor/ffmpeg/windows/ffmpeg-win.zip
- Inno Setup
ISCC.exe 找不到 → winget 裝到 user-scope %LOCALAPPDATA%\Programs\Inno Setup 6\,非傳統 Program Files (x86)。Find-Iscc 多層偵測 + 新增 ISCC 環境變數 override + user-scope 固定路徑 + 登錄檔 fallback
ChineseTraditional.isl 不存在 → Inno Setup 6.3+ 官方移除繁體中文語系,改用 #ifdef WITH_TRAD_CHINESE 條件宏,預設只用英文 installer UI(不影響 app 本身 i18n)
make exe 成功但 dist 空 → PS → bash quoting 問題,改寫 tmp .visiona-build.sh 檔再執行;另外拆出 exe-only target 讓使用者刪掉 dist 能快速重跑 iscc 不重 build wails
- Makefile
exe recipe 診斷輸出 → 印 cwd / iscc exit code / dist 內容,避免靜默失敗
成果:E:\visionA\local-tool\dist\visiona-local-0.1.0-windows-x64.exe 成功產出,iscc 正常 compile 通過。
M7-B:🔴 splash regression 修復(P0)
根因:visiona-local/frontend/ 是 M1 階段從 edge-ai-platform 複製過來的 installer wizard HTML/JS/CSS,整組沒清理。main.go 的 //go:embed all:frontend 直接把這堆 wizard 當 Wails 主視窗內容,使用者開 app 看到的是 Edge AI Platform Installer 而不是 Next.js 主 UI。
影響範圍:macOS dmg 也有同樣 bug,只是 M1 驗收時是用瀏覽器連 http://localhost:3721/ 驗證 server 回應,沒真的打開 Wails 視窗看 UI,所以 regression 一路混過 M1-M6 直到 Windows 實機驗證才被發現。
修法(commit 570e040,刪 1248 行 / 新增 79 行):
visiona-local/frontend/index.html → 極簡 splash(logo + spinner + status)
visiona-local/frontend/app.js → ES module,輪詢 GetServerStatus() binding,拿到 running=true + url 後 window.location.replace(url + '/') 跳到 Next.js 主 UI
visiona-local/frontend/style.css → 深色 splash 樣式
Next.js 主 UI 完全不使用 Wails JS binding(純 HTTP API),從 wails:// 跳到 http://127.0.0.1:<port>/ 後功能完整可用。
| # |
任務 |
狀態 |
| M7-B1 |
清掉 frontend/ 的 edge-ai-platform wizard 殘留 |
✅ |
| M7-B2 |
改寫為 splash + redirect |
✅ |
| M7-B3 |
Windows 實機重 build + 測試 splash → Next.js UI 跳轉 |
⏳ 待使用者驗證 |
| M7-B4 |
macOS 重 build 驗證同樣修復有效 |
⏳ 待排程 |
專案概述
visionA-local 是 /Users/jimchen/Innovedus/edge-ai-platform 的 local 版本,目標是把原本要 deploy 到 EC2/staging Docker 環境的網頁工具,改造成可在本地單機執行的桌面應用,並打包成 GUI 安裝檔,支援 macOS / Windows / Ubuntu 三平台。
任務等級:L 級(完整流程)
進度表
| 階段 |
狀態 |
完成時間 |
備註 |
| 需求討論(三方聯合) |
✅ 已完成 |
2026-04-11 |
四輪討論 + 交叉審閱完成 |
| PRD |
✅ 已完成 |
2026-04-11 |
v1.2 定稿 |
| 設計規格 |
✅ 已完成 |
2026-04-11 |
第四輪修訂定稿 |
| 系統架構 / TDD |
✅ 已完成 |
2026-04-11 |
第四輪修訂 + Plan B 補件 |
| 開發(增量式) |
🔄 進行中 |
- |
M1-M6 macOS ✅;M7 Windows build 完成,splash 修復待 Windows 驗證 |
| Review |
⏳ 待開始 |
- |
- |
| 測試 |
⏳ 待開始 |
- |
- |
| 打包 / 安裝檔 |
🔄 進行中 |
- |
macOS dmg ✅;Windows exe 成功產出(UI 待驗證);Linux AppImage 待 Linux 機器驗證 |
| 交付 |
⏳ 待開始 |
- |
- |
當前待辦
M1 開發進度(第二階段)
| # |
任務 |
狀態 |
| M1-1 |
repo 骨架初始化 |
✅ 完成(Review 通過) |
| M1-2 |
複製 server core(跳過 cluster/tunnel/flash/update) |
✅ 完成(Review 通過) |
| M1-3 |
改寫 main.go / config.go / router.go |
✅ 完成(Review 通過) |
| M1-4 |
複製 frontend |
✅ 完成 |
| M1-5 |
build Go server binary |
✅ 完成(Review 通過) |
| M1-6 |
複製 server/data 預置模型 |
✅ 已於 M1-2 併入(8 個 .nef, 73MB) |
| M1-7 |
清理前端 cluster/relay/tunnel UI |
✅ 完成(Review 通過) |
| M1-8 |
pnpm build 通過 |
✅ 已於 M1-7 併入驗收 |
| M1-9 |
複製 installer shell 改名 visiona-local |
✅ 完成(Review 通過) |
| M1-10 |
改寫 installer + Python 雙策略空殼 |
✅ 完成(Review 通過) |
| M1-11 |
payload 打包 |
✅ 完成(103MB,含 server binary + 8 nef) |
| M1-12 |
wails build + ad-hoc sign + dmgbuild |
✅ 完成(.dmg 70MB 產出) |
| M1-13 |
全新 mac 端到端驗證 |
✅ 完成(5 核心承諾全達成;2 P0 + 1 路徑 bug 已修復) |
第二輪產出(進行中)
- Architect:
/Users/jimchen/visionA/local-tool/.autoflow/04-architecture/
design-doc.md(索引)
TDD.md(索引)
architecture-overview.md
dependency-bundling.md
packaging.md
build-pipeline.md
tray-and-lifecycle.md
i18n.md
risks-and-mitigations.md
api-endpoints.md
code-reuse-plan.md
removed-code.md
重要決策紀錄
來源與策略
- 參考原專案:
/Users/jimchen/Innovedus/edge-ai-platform
- 程式碼策略:重新建立 local-tool,可從 edge-ai-platform 自由取用任何程式碼(不做 fork、不做 submodule)
- 產品名稱:visionA-local
- Bundle ID(暫定):
com.innovedus.visiona-local
產品定位
- 單機桌面應用,不需要 proxy / nginx / relay / tunnel
- Web UI 跑在 localhost(沿用原本 3721 埠或視情況調整)
- 必須能打包成 GUI 安裝檔,支援 macOS / Windows / Ubuntu
- 目標是「裝起來像一般 app」的體驗(類似 Docker Desktop / Ollama)
功能取捨(全照建議)
| 功能 |
決定 |
| 裝置管理(USB 連 Kneron) |
✅ 保留 |
| 攝影機串流(MJPEG + FFmpeg) |
✅ 保留 |
| 模型管理(上傳/切換 .nef) |
✅ 保留 |
| 推論引擎(分類/偵測/臉辨) |
✅ 保留 |
| Mock 模式 |
✅ 保留 |
| Tray(系統列常駐) |
❌ 砍(2026-04-11 改變:Q7 選關閉=結束後 tray 價值降低) |
| Cluster(多裝置叢集) |
❌ 砍 |
| Relay / Tunnel(遠端連線) |
❌ 砍 |
技術決策
- GUI 框架:Wails(沿用 edge-ai-platform 的
installer/)
- 依賴打包:一鍵安裝所有依賴 — Python runtime + KneronPLUS SDK + ffmpeg + 預置模型 .nef 全部包進安裝檔,使用者不需要事先裝任何東西
- 前端清理:清掉 relay 模式切換、cluster 管理等 UI
原專案技術堆疊(沿用)
- 前端:Next.js 16 + React 19 + TypeScript + shadcn/Radix + Tailwind + Zustand
- 後端:Go 1.26 + Gin + go:embed
- 硬體:Python KneronPLUS SDK
- 儲存:本地 JSON + 記憶體(無 DB)
第四輪使用者決策(2026-04-11,三方交叉審閱後)
| # |
問題 |
決定 |
| R4-1 |
Kneron 授權 |
繼續內嵌(不主動問 Kneron,B4 延續,發佈前 gate 維持) |
| R4-2 |
MJPEG 延遲指標 |
首次 ≤250ms / 穩定後 ≤150ms |
| R4-3 |
WCAG 2.2 AA |
不做(改為「盡力而為」,明確 scope 外) |
| R4-4 |
安裝時間 / RAM 指標 |
放寬:安裝上限 5 分鐘、Mock idle RAM ≤600MB |
| R4-5 |
資料目錄命名 |
全小寫 visiona-local(符合 Bundle ID + Linux 慣例) |
| R4-6 |
快捷鍵 |
⌘R → ⌘Shift+R;⌘Shift+W 取消(⌘4 已涵蓋) |
| R4-7 |
首次推論時間 AC |
拆為 首次 30s / 回訪 15s 兩級 |
| R4-8 |
OS 通知策略 |
裝置連/斷 → App 內 toast;Server 崩潰 → shell out 原生通知 |
第三輪使用者決策(2026-04-11,三方第二輪文件後)
| # |
問題 |
決定 |
| Q-A |
Tray 角色衝突(Q7 選關閉=結束後 tray 價值變低) |
A3 砍掉 tray,省跨平台圖資產與 Wails tray 踩坑。從「保留功能」改為「不做」 |
| Q-B |
Kneron 預置模型 re-distribution 授權 |
B4:先假設可重新散布,開發時繼續內嵌,發佈前必須再確認(風險標記) |
| Q-C |
M1 範圍 |
C2 不接受「M1 先不清前端」:M1 就要把前端 cluster/relay UI 清乾淨,一次到位 |
| Q-D |
vendor/ 目錄管理 |
D2 不進 git,用 make vendor-sync 下載 |
| Q-E1 |
macOS 資料目錄 |
用 ~/Library/Application Support/visionA-local/(OS 慣例) |
| Q-E2 |
Workspace 提升為 sidebar 一級 |
OK |
| Q-E3 |
Settings「外觀」分頁取消,語言併入「一般」 |
OK |
第二輪使用者決策(2026-04-11)
| # |
問題 |
決定 |
| Q1 |
Python runtime 策略 |
A(完全離線內嵌 python-build-standalone),同時保留 B(偵測系統 Python)作為 fallback 選項 |
| Q2 |
程式碼簽章 |
C 都不買(內部工具接受警告) |
| Q3 |
最低 OS 版本 |
都最新兩版(macOS 14/15、Windows 10/11、Ubuntu 22.04/24.04) |
| Q4 |
ARM 支援 |
三平台都只做 x86_64,之後有需求再加(使用者是 Intel Mac) |
| Q5 |
預置模型 |
全部打包(~73MB) |
| Q6 |
Auto-update |
先不做 |
| Q7 |
視窗關閉行為 |
B 傳統式(關閉 = 結束程式) |
| Q8 |
預設執行模式 |
直接真實硬體模式(不預設 Mock) |
| Q9 |
韌體燒錄 flash |
B 砍掉 |
| Q10 |
yt-dlp / media/url |
A 保留(要打包 yt-dlp) |
| Q11 |
Bundle ID |
com.innovedus.visiona-local 確認 |
| Q12 |
Telemetry / 崩潰回報 |
預設不做 |
| Q13 |
多語系 |
中英雙語 |
| Q14 |
Logo / 品牌 |
先沿用 edge-ai-platform,之後有需要再換 |
| Q15 |
深色模式 |
跟隨系統 |
M1-10 留下的 M2/M1+ TODO(不阻斷 M1)
ensureBundledPython() 實作(解壓 python-build-standalone、建 venv、離線 pip install wheels)— M2
- Wails
/ipc/raise endpoint(真正的 single-instance focus)— M1+
watchServer() 健康偵測 goroutine(每 10s health check)— M1+
isOurStaleServer / killByPort(stale process 清理)— M1+
- Fatal 錯誤的原生對話框(目前只 emit event)— M1+
未解決問題
- Kneron 預置模型 re-distribution 授權(B4 決策):開發階段先假設可用,發佈前必須跟 Kneron 官方確認。若不允許需改為首次啟動線上下載,會破壞「完全離線」承諾。
- ffmpeg GPL 授權 release blocker(M6):macOS 上的 ffmpeg static build 全是 GPL,暫定用
VISIONA_ALLOW_GPL_FFMPEG=1 放行,發佈前需法務 review 或改走自 build LGPL / 線上下載 / 砍 ffmpeg 三條路。
- 內部 Gitea Releases / GitHub Releases 基礎設施:發佈策略假設有此通路,待確認。
- CI runner 三平台是否齊備:macOS / Windows / Linux runner 狀況待確認。
- M1 驗收流程漏看 Wails 視窗內容:M1-13 當初是用瀏覽器連
http://localhost:3721/ 驗證 server 回應,沒真的開 Wails window 看 UI,導致 edge-ai-platform installer wizard 殘留一路混過 M1-M6 到 Windows 實機驗證才發現。後續 M 任務的驗收 checklist 必須強制「開 app window 確認主 UI 是 Next.js 而非 splash / wizard / 白畫面」。
第一輪三方分析產出(已完成)
- PM:
/Users/jimchen/visionA/local-tool/.autoflow/01-requirements/pm-analysis-round1.md
- Design:
/Users/jimchen/visionA/local-tool/.autoflow/03-design/design-analysis-round1.md
- Architect:
/Users/jimchen/visionA/local-tool/.autoflow/04-architecture/architect-analysis-round1.md