6 Commits

Author SHA1 Message Date
00192d3d1e fix(local-tool): yt-dlp / ffmpeg 找不到 — VISIONA_BUNDLE_BIN_DIR 加到 PATH
根因:Go 1.19+ Windows 的 exec.LookPath 不再搜尋 current directory,
而 exec.Command("yt-dlp") / exec.Command("ffmpeg") 只走 LookPath。
Wails app 有設 VISIONA_BUNDLE_BIN_DIR 環境變數指向 {app}\bin\,
但 server 的 deps/checker.go 只在 startup 檢查時用它,沒把它加到 PATH。

修法:server main.go 啟動時把 VISIONA_BUNDLE_BIN_DIR prepend 到 PATH。
這一次解決三個問題:
- yt-dlp: cannot run executable found relative to current directory
- ffmpeg 攝影機列舉找不到 ffmpeg binary
- ffmpeg camera capture 也找不到

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 23:32:02 +08:00
aa324cef42 fix(local-tool): flash 模型檔案找不到 — 相對路徑未解析
根因:models.json 的 filePath 是相對路徑("data/nef/kl520/xxx.nef"),
但 server working directory 是 {app}\bin\(app.go 設 cmd.Dir = binary 目錄),
所以 server 在 {app}\bin\data\nef\ 找 .nef 檔,找不到。

實際位置:{app}\data\nef\(installer 裝的位置),對應 server 的 --data-dir
由 Wails app 傳入的 %APPDATA%\visiona-local(或 fallback 到 <exe>/../data)。

修法:
- flash.NewService 新增 dataDir 參數
- StartFlash 中把相對 filePath 用 dataDir 拼接成絕對路徑:
  "data/nef/..." → 去掉 "data/" 前綴 → dataDir + "/nef/..."
- main.go 傳 dataDir 給 flash.NewService

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 22:03:28 +08:00
44711753ae feat(local-tool): 推論功能完整搬入 — flash 模組 + workspace 推論介面
## 後端(Phase 1)
新增 flash 模組(從 edge-ai-platform 搬入):
- server/internal/flash/service.go:StartFlash + 模型相容性檢查 + 晶片 NEF 解析
- server/internal/flash/progress.go:Flash 進度追蹤器
- server/internal/api/ws/flash_ws.go:WebSocket 推送 flash 進度
- device_handler.go:新增 FlashDevice method + flashSvc 欄位
- router.go:新增 POST /api/devices/:id/flash + WS /ws/devices/:id/flash-progress
- main.go:初始化 flash.NewService 並傳入 router

推論/攝影機/MJPEG/inference WebSocket 之前 M1 已搬好,不需改動。
Python bridge (kneron_bridge.py) 與 edge-ai-platform 完全相同,不需改動。

## 前端 store + hooks(Phase 2)
- stores/flash-store.ts(新):Zustand store — startFlash / updateProgress / retryFlash / reset
- hooks/use-flash-progress.ts(新):WebSocket hook 接收 flash 進度

inference-store / camera-store / inference types / use-inference-stream / use-websocket
之前 M1 已搬好,不需改動。

## 前端 UI 元件(Phase 3)
- components/devices/flash-dialog.tsx(新):模型載入對話框 + 硬體相容性檢查
- components/devices/flash-progress.tsx(新):Flash 進度條 + 錯誤重試

camera-inference-view / camera-feed / camera-overlay / source-selector /
inference-panel / performance-metrics / classification-result / confidence-slider /
video-progress / batch-image-thumbnails 之前 M1 已搬好。

## 前端頁面整合(Phase 4)
- workspace/page.tsx:繁中硬編碼、顯示已載入模型名稱
- workspace/[deviceId]/workspace-client.tsx:加入 FlashDialog 按鈕 + 繁中硬編碼
- devices/[id]/device-detail-client.tsx:加入 FlashDialog + 「進入工作區」按鈕(模型已載入才顯示)
- device-card.tsx:已連線 + 模型已載入時顯示「工作區」快捷按鈕

## 使用者操作流程
裝置列表 → 連線 → 管理 → 載入模型 → 進入工作區 → 選攝影機/圖片/影片 → 開始推論 → 看 bounding box / FPS / latency
或:裝置列表 → 工作區(已有模型)→ 直接推論

## 不搬的東西
- cluster/* 全部不搬(已砍 cluster 功能)
- relay / tunnel 相關不搬

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 20:07:09 +08:00
4902cb5531 feat(local-tool): Kneron WinUSB driver 透過 KneronPLUS SDK libwdi 安裝
根因:
  KP_ERROR_CONNECT_FAILED (error code 28) — Kneron USB 裝置預設沒綁定
  WinUSB driver,SDK 無法開 handle。原 .iss 的 pnputil /add-driver 做法
  需要 .cat 簽章(Windows 10/11 driver signing enforcement),我們沒有。

參考 edge-ai-platform/installer/platform_windows.go 的 installKneronDriverViaSDK:
  KneronPLUS SDK 內建 libwdi wrapper — kp.core.install_driver_for_windows(pid)
  libwdi 會自動用臨時自簽憑證,不需要 .cat 檔,只需要 UAC 提權。

實作:
- server/internal/api/handlers/system_driver_windows.go(新):
  組 Python script → kp.core.install_driver_for_windows 對 KL520/KL720/KL720_LEGACY →
  PowerShell Start-Process -Verb RunAs 提權執行 → 結果寫 temp 檔讀回
- server/internal/api/handlers/system_driver_other.go(新):非 Windows stub
- system_handler.go: NewSystemHandler 新增 pythonBin 參數 + InstallDriver handler
  先判斷 runtime.GOOS==windows 才執行
- router.go: 新增 POST /system/install-driver
- main.go: 解析 pythonBin(VISIONA_PYTHON env var → cfg.PythonBin)傳入

前端:
- frontend/src/app/devices/page.tsx:Windows only 多一個「安裝 USB Driver」按鈕
  (用 navigator.userAgent 判斷平台)
- frontend/src/stores/device-store.ts:connect 失敗訊息偵測 winusb / error 28 /
  KP_ERROR_CONNECT_FAILED 特徵字串,回一條明確的繁中提示引導使用者去點按鈕

Wails app 端:
- visiona-local/app.go: 新增 InstallKneronDriver() binding 作為備用入口(目前前端沒用到,
  因為前端跑在 http://127.0.0.1 不是 wails://,但保留給未來 splash 階段觸發用)
- visiona-local/platform_{windows,darwin,linux}.go: installKneronWinUSBDriver 平台實作
  / 跨平台 stub

.iss:
- 移除 pnputil /add-driver 的 [Run] entry(它是 silent-fail 的 dead code,
  因為沒 .cat 簽章)
- 新增註解說明:driver 安裝改由 app 端呼叫 libwdi 完成

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 05:25:32 +08:00
f8533a6b04 fix(local-tool): sidebar icon + Wails Windows icon.ico + 掃裝置路徑修復
sidebar E icon:
- frontend/src/components/layout/sidebar.tsx 左上角的 "E" 方塊換成 <img> 指向
  /visiona-logo.png,從 frontend/public/visiona-logo.png serve

Wails 桌面/工作列 icon:
- 把 branding/icon.ico 複製到 visiona-local/build/windows/icon.ico
- Wails v2 Windows build 偵測到這個檔案就會直接用它當 exe embedded icon,
  不再從 appicon.png 自動 resize(解析度更好)

掃裝置根因修復:
1. server main.go:新增 resolveBridgeScript() 智慧找 kneron_bridge.py
   - 優先 <exe>/scripts/kneron_bridge.py
   - fallback <exe>/../scripts/... 對應 Windows installer 的 {app}\bin\ + {app}\scripts\ 佈局
   - fallback <exe>/../Resources/scripts/... 對應 macOS app bundle

2. server kneron/detector.go:ResolvePython 重寫
   - 最高優先:VISIONA_PYTHON 環境變數(由 Wails 殼層注入)
   - 加入 visiona-local 新路徑:%APPDATA%\visiona-local\runtime\venv、
     ~/Library/Application Support/visiona-local/runtime/venv、
     ~/.local/share/visiona-local/runtime/venv
   - 保留 edge-ai-platform 舊路徑作為 legacy fallback

3. visiona-local/app.go:spawn server 時 export VISIONA_PYTHON=<pyBin>
   讓 detector 直接用 Wails 殼層已經 resolve 好的 python interpreter,
   不再自己獨立去找造成不一致。

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 04:59:23 +08:00
c54f16fca0 Initial commit: visionA monorepo with local-tool subproject
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>
2026-04-11 22:10:38 +08:00