依 R5 五輪決策把 visionA-local 從「Wails 內嵌 Next.js」重構為「Wails
本機伺服器控制台 + 瀏覽器 Web UI」模式(類比 Docker Desktop / Ollama)。
程式碼變動
- M8-1 砍 yt-dlp 全套(後端 resolver / URL handler / 前端 URL tab /
Makefile vendor / installer / bootstrap / CI workflow,-555 行)
- M8-2 砍 Mock 模式全套(driver/mock、mock_camera、Settings runtimeMode、
VISIONA_MOCK 環境變數,-528 行)
- M8-3 ffmpeg 從 GPL 切換到 LGPL 混合方案:Windows/Linux 用 BtbN 現成
LGPL binary,macOS 自 build minimal decoder-only 進 git
(vendor/ffmpeg/macos/ffmpeg 5.7MB + ffprobe 5.6MB,比 GPL 版省 85% 空間)
- M8-4 Wails Server Controller:state machine、log ring buffer 2000 行、
preferences.json atomic write、boot-id、Gin SkipPaths、shutdown 7+1 秒、
notify_*.go 三平台 OS 通知、watchServer 改 Error state 不 os.Exit
- M8-4b 啟動階段管線 R5-E:6 階段進度 event、20s soft / 60s hard timeout、
stage 5/6 skip 規則、sentinel file、RestartStartupSequence 5 步驟
- M8-5 Wails 控制台 vanilla HTML/JS/CSS(9 檔 ~2012 行)取代 M7-B splash:
state 視覺、log panel、startup progress panel、Stage 6 manual CTA
pulse、shutdown modal、Settings、Dark Mode、i18n 中英雙語
- M8-6 上傳影片副檔名擴充(mp4/avi/mov/mpeg/mpg)
- M8-7 Web UI Server Offline Overlay(role=alertdialog + focus trap +
wsEverConnected 容錯 + Page Visibility)
- M8-8 CORS middleware(127.0.0.1/localhost only + suffix attack 防護)+
ws/origin.go 獨立 WebSocket CheckOrigin 避 package cycle
- MAJ-4 server:shutdown-imminent WebSocket broadcast 機制
(/ws/system endpoint + notifyShutdownImminent helper)
- M8-9 Boot-ID + 瀏覽器 tab 自動重連(sessionStorage loop guard)
品質
- ~105+ 新 unit test + race detector (-count=2) 全綠
- 10 個 milestone 全部通過 Reviewer 審查
- 三方 v2 + v2.1 文件(PRD / Design Spec / TDD)+ 交叉互審紀錄
收錄在 .autoflow/
交付前待處理(M8-10)
- 重跑 make payload-macos 把舊 GPL 77MB binary 換成新 LGPL
- 三平台 end-to-end build 驗證
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
20 KiB
v2.4 — First-Run 流程重定義
本章對應 R5-4(首次啟動自動開瀏覽器)+ R5-5a(Mock 模式完全砍除)。 取代 v1
spec/04-first-run.md的「歡迎 → 模式選擇 → 硬體偵測」三步流程。 上層索引:../design-spec-v2.md
1. 背景與變更點
v1 First-Run 流程:
雙擊 app → Wails splash → Next.js 主 UI 打開 First-Run wizard
Step 1: 歡迎 / 產品介紹
Step 2: 模式選擇(真實硬體 / Mock)
Step 3: 硬體偵測
→ Dashboard
R5 兩個決策直接改寫這個流程:
- R5-5a 完全砍除 Mock 模式 → Step 2 整步消失
- R5-4 首次啟動自動開瀏覽器 → 雙擊 app 看到的是 Wails 控制台,First-Run wizard 跑在瀏覽器裡(不是 Wails 裡)
結果:First-Run wizard 從三步變成兩步,且入口從「Wails splash」變成「瀏覽器」。
2. 新的 First-Run 流程圖
┌──────────────────────────────────────────────────────────────────┐
│ 新 First-Run 完整流程 │
└──────────────────────────────────────────────────────────────────┘
使用者雙擊 visionA-local.app
│
▼
┌────────────────────────────┐
│ Wails Server Control │
│ Panel 開啟 │
│ 狀態: Starting... │
└────────────┬───────────────┘
│ 內部自動 startServer()
▼
┌────────────────────────────┐
│ Server ready │
│ 狀態: Running │
└────────────┬───────────────┘
│ [Settings.autoOpenBrowser === true]
│ (預設 ON,首次啟動一定 ON)
▼
┌────────────────────────────┐
│ 控制台呼叫 OS open │
│ http://127.0.0.1:3721/ │
└────────────┬───────────────┘
│
▼
┌────────────────────────────────────────────────────────────┐
│ 瀏覽器打開 → Next.js 啟動 │
│ 檢查 localStorage.firstRunCompleted │
│ │
│ ├── false → 導向 /onboarding │
│ └── true → 導向 / (Dashboard) │
└────────────────────────────────────────────────────────────┘
│ firstRunCompleted === false
▼
┌────────────────────────────────────────────────────────────┐
│ First-Run Wizard │
│ │
│ Step 1: 歡迎 ─────────────────────────┐ │
│ ┌──────────────────────────────────┐ │ │
│ │ 歡迎使用 visionA-local │ │ │
│ │ │ │ │
│ │ 這是一個本機 Edge AI 推論工具 │ │ │
│ │ 你可以用它在自己的電腦上跑模型 │ │ │
│ │ │ │ │
│ │ [Gatekeeper 警告說明] │ │ │
│ │ │ │ │
│ │ [ 下一步 ] │ │ │
│ │ [ 略過 ] │ │ │
│ └──────────────────────────────────┘ │ │
│ ▼ │
│ Step 2: 硬體偵測 ────────────────── │
│ ┌──────────────────────────────────┐ │
│ │ 正在掃描 Kneron 裝置... │ │
│ │ │ │
│ │ ┌─ 偵測結果 ────────────────┐ │ │
│ │ │ 情境 A: 找到 1+ 裝置 │ │ │
│ │ │ ✓ Kneron KL520 x1 │ │ │
│ │ │ [ 進入 Dashboard ] │ │ │
│ │ │ │ │ │
│ │ │ 情境 B: 未找到裝置 │ │ │
│ │ │ ⚠ 未偵測到 Kneron 裝置 │ │ │
│ │ │ 請插入 Kneron 裝置後 │ │ │
│ │ │ 重新整理,或略過直接進入 │ │ │
│ │ │ Dashboard(可隨時重掃) │ │ │
│ │ │ [ 重新掃描 ] [ 略過 ] │ │ │
│ │ └─────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
│ │ │
│ ▼ │
│ firstRunCompleted = true │
│ │ │
│ ▼ │
│ Dashboard │
└────────────────────────────────────────────────────────────┘
3. Step-by-Step 規格
3.1 Step 1 — 歡迎
目的:介紹產品、安撫 Gatekeeper 警告焦慮、讓使用者按一個按鈕就進入下一步。
結構:
┌──────────────────────────────────────────────────┐
│ │
│ [LOGO] │
│ │
│ 歡迎使用 visionA-local │
│ │
│ 這是一個本機 Edge AI 推論工具, │
│ 你可以在自己的電腦上跑模型,完全離線。 │
│ │
│ ──────────────────────────────────── │
│ │
│ 🔒 你可能剛才看到系統安全性警告? │
│ │
│ 因為這是內部工具,未購買 Apple/Microsoft │
│ 憑證簽章。你看到的警告是正常的, │
│ 我們已經驗證此版本的完整性。 │
│ │
│ [ 下一步 ] [ 略過 Onboarding ] │
│ │
└──────────────────────────────────────────────────┘
元件:
- Logo(80×80)
- 標題
<h1>28 px Bold - 簡介
<p>15 px - Gatekeeper 安撫段
<section>(灰底卡片color.muted/40) [ 下一步 ]Button primary lg[ 略過 Onboarding ]Button ghost sm(右下角)
「略過」行為:直接設 firstRunCompleted = true 並跳 Dashboard,不經過 Step 2。
3.2 Step 2 — 硬體偵測
目的:掃描 Kneron 裝置,讓使用者知道硬體 ready 與否,但 不強迫 插裝置。
結構(含三種子狀態):
3.2.1 Scanning 子狀態(進入 Step 2 的首個瞬間)
┌──────────────────────────────────────────────────┐
│ │
│ [LOGO] │
│ │
│ 硬體偵測 │
│ │
│ ⟳ 正在掃描 Kneron 裝置... │
│ │
│ (平均 2-5 秒) │
│ │
└──────────────────────────────────────────────────┘
3.2.2 Found 子狀態(找到 ≥ 1 個裝置)
┌──────────────────────────────────────────────────┐
│ │
│ ✓ 偵測到 Kneron 裝置 │
│ │
│ ┌────────────────────────────┐ │
│ │ Kneron KL520 · USB 001 │ │
│ │ 韌體 v2.1.0 │ │
│ └────────────────────────────┘ │
│ │
│ 偵測到 1 個裝置,已就緒 │
│ │
│ [ 進入 Dashboard ] [ 重新掃描 ] │
│ │
└──────────────────────────────────────────────────┘
3.2.3 Not Found 子狀態(R5-5a 新行為:沒找到就空白)
┌──────────────────────────────────────────────────┐
│ │
│ ⚠ 未偵測到 Kneron 裝置 │
│ │
│ ┌────────────────────────────────────┐ │
│ │ 可能的原因: │ │
│ │ • 裝置尚未插入 USB │ │
│ │ • 驅動程式未安裝 │ │
│ │ • 裝置被其他程式占用 │ │
│ └────────────────────────────────────┘ │
│ │
│ 你可以現在插入裝置後「重新掃描」, │
│ 或略過直接進入 Dashboard,稍後 │
│ 從 Devices 頁面再掃描。 │
│ │
│ [ 重新掃描 ] [ 略過並進入 Dashboard ] │
│ │
└──────────────────────────────────────────────────┘
R5-5a 的關鍵決策:沒插硬體不會停在這個畫面逼使用者插,使用者可以按「略過並進入 Dashboard」,Dashboard / Devices 頁面自己會顯示「無裝置」空狀態。
3.3 Step 2 的「進入 Dashboard」規則
| 情境 | 按鈕 | 行為 |
|---|---|---|
| Found | [ 進入 Dashboard ] primary |
firstRunCompleted = true → Dashboard |
| Not Found | [ 略過並進入 Dashboard ] secondary |
同上 |
Found,但使用者按 [ 重新掃描 ] |
— | 重跑掃描,回到 Scanning 子狀態 |
Not Found,使用者插入裝置後按 [ 重新掃描 ] |
— | 重跑掃描,成功的話進入 Found 子狀態 |
4. 「沒有 Mock 的替代心智模型」
R5-5a 砍掉 Mock 後,使用者如果沒插硬體就什麼都看不到推論結果。這對「想先玩玩看」的新手是個空狀態問題。
設計回應:
- Dashboard 空狀態:顯示「插入 Kneron 裝置開始推論」的友善引導,而不是冷冰冰的「無資料」
- Devices 頁面空狀態:顯示「如何取得 Kneron 裝置」的連結 + 「重新掃描」按鈕
- Workspace 入口:如果沒有裝置,sidebar 的 Workspace 項目 disabled 並 tooltip
請先在 Devices 頁面連接裝置
這些空狀態細節沿用 v1 spec/08-states.md,但把原本寫「或切換到 Mock 模式試用」的句子全部刪除。
5. i18n key 變動
5.1 新增 key(zh-TW / en)
| Key | zh-TW | en |
|---|---|---|
firstRun.step1.title |
歡迎使用 visionA-local | Welcome to visionA-local |
firstRun.step1.description |
這是一個本機 Edge AI 推論工具,你可以在自己的電腦上跑模型,完全離線。 | A local edge AI inference tool. Run models on your own computer, fully offline. |
firstRun.step1.gatekeeperTitle |
你可能剛才看到系統安全性警告? | Did you see a system security warning? |
firstRun.step1.gatekeeperDescription |
因為這是內部工具,未購買 Apple/Microsoft 憑證簽章。你看到的警告是正常的,我們已經驗證此版本的完整性。 | This is an internal tool without Apple/Microsoft code signing certificates. The warning is expected, and this version has been verified for integrity. |
firstRun.step1.next |
下一步 | Next |
firstRun.step1.skip |
略過 Onboarding | Skip onboarding |
firstRun.step2.title |
硬體偵測 | Hardware detection |
firstRun.step2.scanning |
正在掃描 Kneron 裝置... | Scanning for Kneron devices... |
firstRun.step2.found |
偵測到 Kneron 裝置 | Kneron device detected |
firstRun.step2.foundSummary |
偵測到 {count} 個裝置,已就緒 | {count} device(s) detected and ready |
firstRun.step2.notFound |
未偵測到 Kneron 裝置 | No Kneron device detected |
firstRun.step2.notFoundReasons |
可能的原因:• 裝置尚未插入 USB • 驅動程式未安裝 • 裝置被其他程式占用 | Possible reasons: • Device not plugged in • Driver not installed • Device occupied by another app |
firstRun.step2.notFoundHelp |
你可以現在插入裝置後「重新掃描」,或略過直接進入 Dashboard,稍後從 Devices 頁面再掃描。 | Plug in a device and rescan, or skip to the Dashboard and scan later from Devices. |
firstRun.step2.rescan |
重新掃描 | Rescan |
firstRun.step2.enterDashboard |
進入 Dashboard | Enter Dashboard |
firstRun.step2.skipToDashboard |
略過並進入 Dashboard | Skip to Dashboard |
5.2 刪除 key(原 Step 2「模式選擇」的 key 全砍)
所有 firstRun.mode.* / firstRun.step2.*(若原 step2 = 模式選擇)相關 key 全部刪除。這包含但不限於:
| Key | 理由 |
|---|---|
firstRun.mode.title |
模式選擇整步消失 |
firstRun.mode.real.title |
同上 |
firstRun.mode.real.description |
同上 |
firstRun.mode.mock.title |
同上 |
firstRun.mode.mock.description |
同上 |
firstRun.mode.recommend |
同上 |
firstRun.mode.switchLater |
同上 |
(實際 key 名以現有 i18n 檔為準,grep firstRun.mode 全刪)
5.3 重編號注意
v1 的 firstRun.step2.*(模式選擇)被砍,v1 的 firstRun.step3.*(硬體偵測)在 v2 變成 firstRun.step2.*。需要 rename:firstRun.step3.* → firstRun.step2.*,或者乾脆用意義化命名:firstRun.welcome.*、firstRun.hardware.*。建議後者,後續維護更清楚。
6. 無障礙考量
| 項目 | 設計 |
|---|---|
| 步驟指示 | Header 顯示 Step 1 of 2 / Step 2 of 2,對 screen reader friendly |
| Keyboard | Tab 循序、Enter 觸發 primary button、Esc 不關閉(防止誤按) |
| Focus 初始 | 每步的 primary button 預設聚焦 |
| ARIA | <section role="region" aria-labelledby="step-title">;掃描 spinner <span role="status" aria-live="polite"> |
| Reduced motion | 關閉步驟間 slide transition |
7. 與 v1 差異對照
| 面向 | v1(三步) | v2(兩步) |
|---|---|---|
| 入口 | Wails splash → 跳 Next.js | Wails 控制台 → 自動開瀏覽器 → Next.js |
| 步驟數 | 3(歡迎 / 模式選擇 / 硬體偵測) | 2(歡迎 / 硬體偵測) |
| 模式選擇 | 有(真實硬體 / Mock) | 無(R5-5a 砍 Mock) |
| 硬體未偵測到的引導 | 「或切換到 Mock 模式試用」 | 「略過並進入 Dashboard,稍後重掃」 |
| 略過按鈕位置 | 每步右上 | Step 1 右下、Step 2 主按鈕之一 |
| 完成標記 | localStorage.firstRunCompleted |
同(不變) |
8. 邊界情境
| 情境 | 處理 |
|---|---|
| 使用者在 Step 1 關閉瀏覽器 tab | firstRunCompleted 不變,下次打開還是從 Step 1 開始 |
| 使用者在 Step 2 Scanning 中關閉 | 同上 |
| 使用者在 Step 2 按「略過」 | firstRunCompleted = true,下次打開直達 Dashboard |
| 使用者清 localStorage 後重開 | 重新跑 First-Run(這是 feature 不是 bug) |
| 首次自動開瀏覽器失敗(xdg-open 在極簡 Linux) | 瀏覽器沒開 → 使用者會看到控制台「Running · Browser opened」但瀏覽器沒動 → 使用者手動點 [Open in Browser] → 瀏覽器打開 → 進 First-Run |
| 使用者在 Wails 控制台 Settings 關了 auto-open,下次雙擊 | 進 Step 1 的前提需要使用者手動點 Open in Browser。控制台開著等使用者動作 |
9. 給 PM 的提醒
- PRD 原本定義 First-Run 是 3 步,
02-prd/子檔需要更新 - Persona 流程描述 v1 寫「使用者被引導到模式選擇」,要改
- 「Mock 模式是 MVP 功能」若曾寫進 PRD,須移到「非目標 / removed features」
feature-inventory.md若列出 Mock 模式為 feature,需標記為 removed
下一步:
- 給 PM Agent 更新 PRD 對應段落(Orchestrator 自行更新或轉交 PM)
- 給 Frontend Agent 按本 spec 實作 onboarding 頁面
- 給 Testing Agent 設計 E2E:雙擊 app → 看控制台 → 自動開瀏覽器 → 跑 First-Run → 進 Dashboard 的完整 flow