# 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 兩個決策直接改寫這個流程:
1. **R5-5a 完全砍除 Mock 模式** → Step 2 整步消失
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)
- 標題 `
` 28 px Bold
- 簡介 `
` 15 px
- Gatekeeper 安撫段 ``(灰底卡片 `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 | ``;掃描 spinner `` |
| 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