visionA/docs/autoflow/03-design/visiona-agent-spec.md
jim800121chen fb7da5d180 chore(autoflow): migrate .autoflow/ 共享層文件至 docs/autoflow/
依 autoflow-agent workspace v2 設計把 PRD / 設計 / 架構 / 交付類
共享文件從個人層 .autoflow/(ignored)搬到 docs/autoflow/(進 git),
讓團隊可共享產品與架構文件,個人層只留 progress / review / testing 等
per-branch 筆記。

- 02-prd/        21 個檔(PRD、features、market-analysis 等)
- 03-design/     18 個檔(design-spec、wireframes、flows 等)
- 04-architecture/ 31 個檔(TDD、design-doc、ADR×14、API 規格等)
- 07-delivery/   3 個檔(project-summary、phase-0.6-handover、stage-deployment-setup)

合計 73 檔。原檔已從 .autoflow/ 移除(migration 工具執行 git mv,
但因 .autoflow/ 在 .gitignore 中、git 將此操作視為新增、無 rename history)。
2026-05-04 16:55:55 +08:00

722 lines
37 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# visionA Agent — UI 設計規格
| 項目 | 內容 |
|------|------|
| 專案代號 | visionA Agent`visiona-agent` |
| 文件版本 | v0.1 |
| 最後更新 | 2026-04-22 |
| 狀態 | Design Agent 產出M 級任務,不走三方聯合討論) |
| 定位 | visionA 雲端版的 local agent / tunnel bridge |
| 技術堆疊 | Wails v2 + React + TypeScript + Tailwind 4 + shadcn/ui與 visionA-frontend 完全相同)|
| Bundle ID | `com.innovedus.visiona-agent`(獨立於 local-tool 的 `com.innovedus.visiona-local`|
> **本規格從 visionA-frontend 的 Design System 延伸**。Design Tokens、元件、字型、Dark Mode 全部沿用,確保同一使用者在雲端 Web 與桌面 Agent 之間切換「能一眼認出是同家人」。
---
## 1. 設計概述
### 1.1 產品定位
visionA Agent 是**純橋樑**:它只做一件事 — 讓使用者桌機上的 Kneron 裝置「出現在雲端」。所有裝置管理、模型管理、推論操作都在 visionA 雲端 Web UI。Agent 本身**沒有**裝置面板、沒有攝影機預覽、沒有推論視窗。
它是一個「**開了就忘掉它**」的工具使用者配對完之後Agent 只要維持連線、不出問題就好。
### 1.2 與 visionA-frontend 的對應關係
| 使用者流程 | visionA-frontendWeb| visionA Agent桌面 |
|-----------|---------------------|--------------------|
| 取得 Pairing Token | `/devices/pair` Step 1 | — |
| 下載並啟動 Agent | `/devices/pair` Step 2指引| **Agent 安裝後首次啟動** |
| 輸入 Token 配對 | — | **配對頁** |
| 確認連線建立 | `/devices/pair` Step 3 | **狀態頁**(雙端同時顯示)|
| 後續使用裝置 | `/devices``/workspace/*` | 持續維持連線,無需互動 |
**設計職責切分**Web 負責「拿到 token」+「看到裝置」Agent 負責「用 token 連上」+「顯示連線狀態」。
### 1.3 設計原則
1. **極簡優先** — 一個 utility 不是一個 product。不做 onboarding tour、不做裝飾性插圖、不做動畫秀。
2. **誠實呈現狀態** — online / offline / reconnecting / error 必須清楚區分,不只靠顏色(搭配 icon + 文字)。
3. **與雲端視覺一致** — Design Tokens 100% 沿用,使用者看到會立刻聯想「這是 visionA 那家」。
4. **跨平台** — 不做任何倚賴特定 OS 的互動(不做 traffic light 自訂、不做 system tray、不做 Win11 Mica
5. **鍵盤友善** — 所有操作 Tab 可達,符合 WCAG 2.1 AA。
6. **Dark Mode 跟隨 OS** — 不提供手動切換,不需要多餘開關。
### 1.4 範圍內 vs 範圍外
| 範圍內 | 範圍外 |
|--------|--------|
| 連線狀態頁、配對頁、設定頁 | 裝置管理 / 模型管理 / 推論操作 UI |
| 全域 Header + Tab 導航 | System Tray / Menu Bar 圖示 |
| 開機自啟、Log 匯出、Relay URL 設定 | Onboarding Tour / Tutorial |
| 繁中 + English跟 OS 語言,無 UI switcher | i18n 切換 UI、多語言 admin |
| Dark Mode 跟隨系統 | 手動 Dark Mode toggle |
---
## 2. Design Tokens沿用 visionA-frontend
完整沿用 `.autoflow/03-design/design-tokens.md`。實作時 **直接複製 visionA-frontend 的 `globals.css`**,不動一行。
### 2.1 Agent 會用到的 token 清單
| 用途 | Token / class |
|------|---------------|
| 視窗背景 | `--background``bg-background` |
| 主要文字 | `--foreground``text-foreground` |
| 次要文字 | `--muted-foreground``text-muted-foreground` |
| 卡片 / 區塊 | `--card` + `border` + `shadow-sm` + `rounded-xl` |
| 主按鈕 | `--primary` + `--primary-foreground` |
| 次要按鈕 | `--secondary` / outline variant |
| 危險按鈕(重置 / 斷線)| `--destructive` |
| Input 邊框 | `--input`focus `--ring/50` |
| Tab bar 背景 | `--sidebar`(沿用) |
| Focus ring | `--ring``ring-[3px]`|
### 2.2 連線狀態色(沿用雲端版既有約定)
`flow-offline-handling.md` 第 2 節的狀態模型對齊:
| 狀態 | 顏色light / dark| IconLucide|
|------|---------------------|---------------|
| online | `bg-green-500` | `CheckCircle2` |
| offline | `bg-gray-400` + `dark:bg-gray-600` | `PowerOff` |
| reconnecting | `bg-yellow-400` + `animate-pulse` | `RefreshCw`(旋轉) |
| notPaired | `bg-gray-400` | `Unlink` |
| error | `bg-red-500` | `AlertTriangle` |
**無障礙**:每個狀態**必須同時有**「圓點顏色 + Icon + 文字標籤」,不只靠顏色。
### 2.3 字型
- UI 文字:`font-sans`Geist Sans沿用
- Token 顯示、Log、Relay URL`font-mono`Geist Mono
---
## 3. 全域元件 — Header / Tab 導航
### 3.1 版型
```
┌──────────────────────────────────────────────────────────────────┐
│ [Logo] visionA Agent 狀態 · 配對 · 設定 🟢 在線 │ ← h-14
├──────────────────────────────────────────────────────────────────┤
│ │
│ [ 當前分頁內容 ] │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 3.2 規格
- **高度**`h-14`56px與 visionA-frontend Header 一致
- **背景**`bg-sidebar` + `border-b border-sidebar-border`
- **左側**Logo + 產品名「visionA Agent」`text-sm font-semibold`
- **中央(或左側緊接)**:三個 Tab
- 「狀態」Status— 預設
- 「配對」Pair
- 「設定」Settings
- 使用 shadcn `Tabs` 風格active tab `bg-primary text-primary-foreground rounded-md`,其餘 `hover:bg-accent`
- **右上角**`ConnectionStatusBadge`(小型 `RemoteDeviceBadge` 的簡化版)
- 圓點 + 文字(例:`🟢 在線` / `⚪ 離線` / `🟡 重連中` / `🔗 未配對`
- 點擊可切回「狀態」tab
### 3.3 互動
- Tab 切換:`Ctrl/Cmd+1/2/3` 鍵盤快捷鍵
- Badge 永遠即時反映連線狀態(從 backend event 推送)
- **沒有**雲端版的 `PrototypeBanner`、**沒有** Sidebar視窗太小、功能太少
### 3.4 視窗規格Wails 設定)
| 項目 | 值 | 說明 |
|------|---|------|
| 初始大小 | **720 × 560** | 比 800×600 稍收斂,足夠不壅擠 |
| 最小大小 | 640 × 480 | 強制最小,避免壞掉 |
| 最大大小 | 不限 | 使用者想放大就放大(但內容有 `max-w-2xl` 收斂) |
| Title | `visionA Agent` | OS title bar |
| Resizable | Yes | 使用者可調整 |
| 關閉行為 | **退出 process** | 不隱藏到 tray已決策 |
| Icon | visionA 品牌 logo3 平台各別規格) | — |
---
## 4. 頁面 1 — 連線狀態頁(首頁 / 預設 Tab
### 4.1 版型(已配對 + 在線)
```
┌──────────────────────────────────────────────────────────────────┐
│ │
│ ╭────────────────────╮ │
│ │ ✓ 已連線 │ │
│ │ 🟢 │ │
│ ╰────────────────────╯ │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 帳號 jim@innovedus.com │ │
│ │ Relay wss://relay.visionA.cloud │ │
│ │ 連線開始 2026-04-22 14:30已連線 2 小時 15 分) │ │
│ │ Session vAs_a1b2c3d4 ··· e7f8 │ │
│ │ │ │
│ │ [ 斷開連線 ] [ 重新配對 ] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 最近連線紀錄 [ 查看完整 Log ] │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ 14:30 ✓ 已連線 │ │
│ │ 14:29 ⟳ 連線中... │ │
│ │ 14:28 ▲ 程式啟動 │ │
│ │ ...(最多 10 筆) │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 4.2 主要元件
#### (A) StatusHero — 大狀態指示器
- **大小**:直徑 80px 的圓,置中
- **內容**
- 頂層:狀態 IconLucide`h-8 w-8`
- 底層:圓點 + 狀態文字(`text-xl font-semibold`
- **狀態變體**(對應 2.2 狀態色):
- online綠圓 + `CheckCircle2` + 「已連線」
- offline灰圓 + `PowerOff` + 「離線」
- reconnecting黃圓 pulse + `RefreshCw` 旋轉 + 「重新連線中...」+ 次行 `text-xs text-muted-foreground`「第 {n}/5 次嘗試」
- notPaired灰圓 + `Unlink` + 「尚未配對」+ 次行按鈕「立即配對 →」切到配對頁
- error紅圓 + `AlertTriangle` + 「連線錯誤」+ 次行 `text-xs text-red-600`「{errorMessage}」
#### (B) InfoCard — 連線資訊卡
- shadcn `Card``p-6 space-y-3`
- **欄位**(每行 `grid grid-cols-[120px_1fr]`,左欄 `text-muted-foreground text-sm`,右欄 `text-sm font-mono`
| 欄位 | 內容 | 未配對 / 離線時 |
|------|------|---------------|
| 帳號 | `jim@innovedus.com` | `—`(未配對)/ 快取顯示(離線) |
| Relay | `wss://relay.visionA.cloud` | 顯示當前設定值 |
| 連線開始 | `2026-04-22 14:30已連線 2 小時 15 分)` | 未配對 `—`;離線顯示上次連線時間 + 「已離線 {duration}」|
| Session | `vAs_a1b2c3d4 ··· e7f8`(遮蔽中段)| 未配對 `—`;離線保留顯示(以 `text-muted-foreground` 淡化) |
- **Session Token 遮蔽規則**:顯示 `前綴(vAs_) + 前 8 hex + " ··· " + 後 4 hex`(共約 20 字元可見)。完整 token 永遠不顯示、不可複製、不寫進 log。
#### (C) 主要按鈕
於 InfoCard 下方,排成一列:
| 狀態 | 主按鈕 | 次按鈕 |
|------|--------|--------|
| online | `[ 斷開連線 ]``variant=outline`| `[ 重新配對 ]`ghost 配 `AlertDialog` |
| offline | `[ 立即重試 ]``variant=default`| `[ 重新配對 ]` |
| reconnecting | `[ 取消並手動重連 ]`outline重連中停用自動策略一次| `[ 重新配對 ]` |
| notPaired | `[ 前往配對 → ]`default切 tab| — |
| error | `[ 重試 ]`default+ `[ 查看 log ]`ghost| `[ 重新配對 ]` |
- 「斷開連線」→ `AlertDialog`「確定要斷開嗎斷開後遠端將無法使用此裝置。Session Token 不會被撤銷,下次可直接重連。」
- 「重新配對」→ `AlertDialog`「確定要重新配對?目前的 Session 會立即失效,需重新取得 Pairing Token。」確認後切配對頁並清除本地 Session Token。
#### (D) RecentLog — 最近連線紀錄
- shadcn `Card`,標題 + 右上角「查看完整 Log」連結切到設定頁 → Log 區塊)
- 每筆紀錄:`時間(HH:mm) · Icon · 事件文字`
- `✓ 已連線` / `⟳ 連線中...(嘗試 {n}/5` / `✗ 連線失敗:{reason}` / `▲ 程式啟動` / `◼ 程式關閉` / `⚙ 設定已更新`
- 最多顯示 10 筆,`text-xs font-mono`,超過出現「查看完整 Log」連結
- **只顯示使用者應該看得懂的事件**debug 級別的細節進 log 檔不上 UI
### 4.3 空狀態(尚未配對)
未配對時StatusHero 顯示 notPaired 狀態InfoCard 欄位皆為 `—`RecentLog 顯示:
```
┌─────────────────────────────────┐
│ 🔗 │
│ │
│ 尚未配對裝置 │
│ │
│ 去雲端 Web 產生 Pairing Token
│ 在「配對」分頁貼上即可開始 │
│ │
│ [ 前往配對 → ] │
└─────────────────────────────────┘
```
### 4.4 錯誤狀態
- 連線錯誤StatusHero 顯示 errorInfoCard 最下方紅色 banner`bg-red-50 dark:bg-red-950/30 border-red-300`)顯示 `errorMessage`「Pairing Token 已撤銷請重新配對」「Relay URL 不可達」)
- 錯誤分類(對應 `flow-offline-handling.md` 第 1 節的 A/B/C 失效點):
- **本機斷網**A「你的網路似乎離線了請檢查 Wi-Fi / 有線連線」
- **雲端不可達**B「無法連上 visionA 雲端服務,正在重試...」
- **認證失敗**「Session Token 已失效,請重新配對」
- **未知錯誤**:「連線錯誤,請[查看 log]{連結}」
### 4.5 互動行為
| 操作 | 行為 |
|------|------|
| 進入頁面 | 自動從 backend 取當前狀態(透過 Wails runtime event |
| 狀態變化 | backend 推送事件 → 前端即時更新 StatusHero + Badge + InfoCard |
| 點「斷開連線」| AlertDialog 確認 → call backend `Disconnect()` → 狀態變 offline |
| 點「重新連線」| call backend `Reconnect()` → 狀態變 reconnecting |
| 點「查看完整 Log」| 切到設定頁,自動 scroll 到 Log 區塊 |
| 視窗 resize | 內容以 `max-w-2xl mx-auto` 置中,大螢幕不會過寬 |
### 4.6 驗收條件
- [ ] 五種狀態online / offline / reconnecting / notPaired / error視覺各異且符合 2.2 色表
- [ ] Session Token 永遠只顯示遮蔽版
- [ ] 離線時「連線開始」欄位顯示「已離線 {duration}」並使用 `text-muted-foreground`
- [ ] 「斷開連線」「重新配對」都有 `AlertDialog` 確認
- [ ] 最近 Log 最多 10 筆,時間格式 `HH:mm`
- [ ] Dark Mode 下所有顏色對比達 4.5:1
- [ ] 完整鍵盤導航Tab / Enter / Space / Esc
---
## 5. 頁面 2 — 配對頁
### 5.1 版型
```
┌──────────────────────────────────────────────────────────────────┐
│ │
│ 配對到 visionA 雲端 │
│ 貼上 Pairing Token讓你的裝置出現在雲端 Web │
│ │
│ ┌────────────────────────────────────────────────────────────┐ │
│ │ Pairing Token │ │
│ │ ┌────────────────────────────────────────────────────────┐│ │
│ │ │ vAc_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8 ││ │
│ │ └────────────────────────────────────────────────────────┘│ │
│ │ ✓ 格式正確36 字元) │ │
│ │ │ │
│ │ 還沒有 token[ 到雲端網頁產生 ↗ ] │ │
│ │ │ │
│ │ [ 取消 ] [ 配對 ] │ │
│ └────────────────────────────────────────────────────────────┘ │
│ │
│ 💡 Token 15 分鐘內有效一次性使用。Agent 會自動換取長期 Session│ │
│ 你不需要記住或重複貼上。 │ │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 5.2 元件規格
#### (A) 標題區
- `h1`:「配對到 visionA 雲端」(`text-2xl font-semibold`
- `description`:「貼上 Pairing Token讓你的裝置出現在雲端 Web」`text-sm text-muted-foreground`
#### (B) Token 輸入卡
- shadcn `Card``p-6 space-y-4``max-w-xl mx-auto`
- `Label`「Pairing Token」
- shadcn `Input`
- `font-mono text-sm`(等寬)
- `placeholder="貼上 vAc_... 格式的 token"`
- 自動 `spellcheck={false}``autocapitalize="none"``autocomplete="off"`
- **貼上時自動清除所有空格與換行**(雲端網頁顯示可能有空格分隔,如 `vAc_a1b2c3d4 e5f6a7b8 ...`
- **焦點**進入自動全選(方便覆蓋貼上)
- **即時格式驗證**(在 input 下方顯示 hint line
- 空:`text-muted-foreground`「請貼上 token」
- 格式不對:`text-red-600`「格式不正確 — token 應為 `vAc_` 開頭 + 32 字元 hex」+ `AlertCircle` icon
- 格式正確:`text-green-600`「✓ 格式正確36 字元)」+ `CheckCircle2` icon
- 邊框狀態:預設 `border-input` / 錯誤 `border-destructive` + `ring-destructive/20` / 正確 `border-green-500`
#### (C) 輔助連結
- 「還沒有 token[ 到雲端網頁產生 ↗ ]」
- 點擊 → `wails.BrowserOpenURL("https://visionA.cloud/devices/pair")`
- **Phase 0 雛形**URL 寫死 placeholder正式上線再改為環境變數驅動
#### (D) 按鈕列(右對齊)
- 「取消」(`variant=ghost`)→ 切回狀態頁
- 「配對」(`variant=default`):格式不正確時 disabled
- 配對中:按鈕變「`⟳ 正在配對...`」(`aria-busy=true`),其餘 input / cancel disabled
#### (E) 底部提示
`Alert` 元件(`variant=default``bg-blue-50 dark:bg-blue-950/30 border-blue-300`
> 💡 Token 15 分鐘內有效一次性使用。Agent 會自動換取長期 Session你不需要記住或重複貼上。
### 5.3 配對流程狀態
| 階段 | UI |
|------|---|
| 閒置 | 如 5.1 所示,按鈕依格式驗證 enable / disable |
| 驗證中(貼上後)| 即時驗證格式100ms debounce無 loading純 client-side 正規表達式) |
| 配對中 | 按鈕變 spinner「正在連線到雲端...」,其餘 disabled。backend 呼叫 WS `/tunnel/connect?token=vAc_...` |
| 成功 | Toast `✓ 配對成功` → 0.5s 後自動切回「狀態」tab → StatusHero 顯示 online |
| 失敗 | 停留在本頁Input 下方紅色 `Alert` 顯示錯誤訊息(見 5.4),按鈕恢復為「重試」+「取消」|
### 5.4 錯誤訊息對照
| 後端錯誤代碼 | 顯示訊息 | 建議動作 |
|-------------|---------|---------|
| `token_expired` | 「此 Token 已過期15 分鐘有效)」 | 「回雲端網頁重新產生 →」 |
| `token_used` | 「此 Token 已被其他裝置使用」 | 「回雲端網頁重新產生 →」 |
| `token_invalid` | 「Token 無效或格式錯誤」 | 「請檢查是否複製完整」 |
| `token_revoked` | 「此 Token 已被撤銷」 | 「回雲端網頁重新產生 →」 |
| `network_error` | 「無法連上雲端服務,請檢查網路」 | 「重試」 |
| `relay_unreachable` | 「Relay `{url}` 無法連線,請確認設定」 | 「前往設定 →」|
| `unknown` | 「配對失敗,請查看 log」 | 「查看 log」 |
### 5.5 互動行為
| 操作 | 行為 |
|------|------|
| Focus Input | 全選現有內容 |
| 貼上 token | trim + 去空白 + 去換行;立即格式驗證 |
| 輸入中 | 100ms debounce 後顯示驗證結果 |
| Enter 鍵 | 若格式正確則觸發「配對」;否則無動作 |
| Esc 鍵 | 觸發「取消」(切回狀態頁,清空 input |
| 配對成功 | Toast + auto navigate不留在本頁 |
| 配對失敗 | Input 保留原值(方便使用者修改),顯示錯誤,按鈕變「重試」|
### 5.6 i18n key
```
pair.title → 配對到 visionA 雲端
pair.description → 貼上 Pairing Token讓你的裝置出現在雲端 Web
pair.tokenLabel → Pairing Token
pair.tokenPlaceholder → 貼上 vAc_... 格式的 token
pair.hint.empty → 請貼上 token
pair.hint.invalid → 格式不正確 — token 應為 vAc_ 開頭 + 32 字元 hex
pair.hint.valid → 格式正確36 字元)
pair.noToken → 還沒有 token
pair.openCloud → 到雲端網頁產生
pair.cancel → 取消
pair.submit → 配對
pair.submitting → 正在配對...
pair.bottomHint → Token 15 分鐘內有效一次性使用。Agent 會自動換取長期 Session你不需要記住或重複貼上。
pair.toast.success → 配對成功
pair.error.expired → 此 Token 已過期15 分鐘有效)
pair.error.used → 此 Token 已被其他裝置使用
pair.error.invalid → Token 無效或格式錯誤
pair.error.revoked → 此 Token 已被撤銷
pair.error.network → 無法連上雲端服務,請檢查網路
pair.error.relayUnreachable → Relay {url} 無法連線,請確認設定
pair.error.unknown → 配對失敗,請查看 log
pair.error.regenerate → 回雲端網頁重新產生
pair.error.goSettings → 前往設定
pair.error.viewLog → 查看 log
pair.error.retry → 重試
```
### 5.7 驗收條件
- [ ] 貼上含空格 / 換行的 token 自動清乾淨
- [ ] 格式驗證正規表達式:`/^vAc_[a-f0-9]{32}$/i`(大小寫不敏感)
- [ ] 格式不正確時按鈕 disabled
- [ ] 配對中所有 input + 按鈕 disabled僅保留「取消」
- [ ] 成功後切回狀態頁,並更新全域狀態
- [ ] 所有錯誤訊息都能明確告訴使用者「下一步該做什麼」
- [ ] 支援完整鍵盤操作Enter 送出、Esc 取消)
---
## 6. 頁面 3 — 設定頁
### 6.1 版型
```
┌──────────────────────────────────────────────────────────────────┐
│ 設定 │
│ │
│ ── 連線 ───────────────────────────────────────────────────── │
│ Relay URL [ wss://relay.visionA.cloud ] [ 測試連線 ]│
│ 當前設定將於下次連線時生效 │
│ │
│ ── 行為 ───────────────────────────────────────────────────── │
│ ☐ 開機自動啟動 visionA Agent │
│ │
│ 重連策略 ◉ 自動重試(指數退避,最多 5 次) │
│ ○ 手動重連 │
│ │
│ ── Log ───────────────────────────────────────────────────── │
│ Log 等級 [ Info ▼ ]Debug / Info / Warn / Error
│ Log 位置 ~/Library/Application Support/visionA Agent/logs/ │
│ [ 開啟資料夾 ] [ 匯出 Log... ] │
│ │
│ ── 關於 ───────────────────────────────────────────────────── │
│ 版本 visionA Agent 0.1.0 │
│ [ 檢查更新 ] [ 開啟文件 ↗ ] [ GitHub ↗ ] │
│ │
│ 危險區域 [ 重置所有設定 ] │
│ │
└──────────────────────────────────────────────────────────────────┘
```
### 6.2 區塊規格
容器:`max-w-2xl mx-auto p-6 space-y-8`。每個區塊:`space-y-3`,區塊間用 `Separator`
#### 6.2.1 連線
- **Relay URL**
- `Label` + `Input``font-mono text-sm`+ `Button "測試連線"``variant=outline size=sm`
- 預設值:`wss://relay.visionA.cloud`
- 驗證:必須以 `wss://``ws://` 開頭
- 變更不會立即套用;下方 `text-xs text-muted-foreground` 顯示「當前設定將於下次連線時生效」
- 若與當前連線值不同:顯示橙色 badge `未套用`
- **測試連線**按鈕:
- 點擊後嘗試 WebSocket handshake不帶 token只測 reachability
- Loadingspinner
- 成功:`Toast ✓ Relay 可達({latency}ms`
- 失敗:`Toast ✗ 無法連上 {url}{reason}`
#### 6.2.2 行為
- **開機自動啟動**
- shadcn `Checkbox` + `Label`
- 預設**關閉**(已決策)
- 勾選後立即套用backend 寫入對應 OS 啟動項macOS Login Items / Windows Registry Run / Linux `.desktop` autostart
- 變更時 toast「✓ 已啟用開機自啟動」/ 「已關閉開機自啟動」
- **重連策略**
- shadcn `RadioGroup`
- `自動重試` — 預設指數退避1s → 2s → 4s → 8s → 16s最多 5 次失敗後停止並轉為手動
- `手動重連` — 連線中斷後不自動重試,使用者需在狀態頁點「立即重試」
#### 6.2.3 Log
- **Log 等級**shadcn `Select`,選項 `Debug / Info / Warn / Error`,預設 `Info`
- 變更立即生效
- **Log 位置**:唯讀顯示 OS 對應路徑(`font-mono text-xs`
- macOS`~/Library/Application Support/visionA Agent/logs/`
- Windows`%APPDATA%\visionA Agent\logs\`
- Linux`~/.config/visionA-agent/logs/`
- 「開啟資料夾」按鈕call backend 開檔案總管到該路徑
- **匯出 Log**按鈕:
- 點擊 → OS save dialogWails runtime `SaveFileDialog`
- 預設檔名:`visionA-agent-log-YYYYMMDD-HHmmss.zip`
- 內容:壓縮最近 7 天的 log 檔
- 匯出中:按鈕 loading完成 toast「✓ 已匯出到 {path}」
#### 6.2.4 關於
- **版本**`visionA Agent {version}`(從 `runtime.Environment` 取)
- **檢查更新**按鈕:
- Phase 0 stubcall backend `CheckForUpdates()`,雛形直接回 `up-to-date`
- Toast`✓ 已是最新版本` / `有新版本可用v0.2.0 [ 開啟下載頁 ]`
- **開啟文件**`BrowserOpenURL("https://docs.visionA.cloud/agent")`
- **GitHub**`BrowserOpenURL("https://github.com/innovedus/visionA-agent")`
#### 6.2.5 危險區域
- 小標:`危險區域``text-sm font-medium text-destructive`
- **重置所有設定**按鈕:
- `variant=destructive size=sm`
- 點擊 → shadcn `AlertDialog`
- 標題:「確定要重置所有設定嗎?」
- 內文「這將清除Relay URL、開機自啟、Log 等級、**以及已配對的 Session Token**。你將需要重新配對才能使用。此操作無法復原。」
- 按鈕:`取消` / `確定重置`destructive
- 確認後backend 清除 config + session token → toast「已重置所有設定」→ 切到配對頁顯示 notPaired
### 6.3 i18n key
```
settings.title → 設定
settings.connection → 連線
settings.relayUrl → Relay URL
settings.relayUrl.hint → 當前設定將於下次連線時生效
settings.relayUrl.unapplied → 未套用
settings.testConnection → 測試連線
settings.testConnection.success → Relay 可達({latency}ms
settings.testConnection.failed → 無法連上 {url}{reason}
settings.behavior → 行為
settings.autoStart → 開機自動啟動 visionA Agent
settings.autoStart.enabled → 已啟用開機自啟動
settings.autoStart.disabled → 已關閉開機自啟動
settings.reconnectStrategy → 重連策略
settings.reconnectStrategy.auto → 自動重試(指數退避,最多 5 次)
settings.reconnectStrategy.manual → 手動重連
settings.log → Log
settings.logLevel → Log 等級
settings.logLocation → Log 位置
settings.openFolder → 開啟資料夾
settings.exportLog → 匯出 Log...
settings.exportLog.success → 已匯出到 {path}
settings.about → 關於
settings.version → 版本
settings.checkUpdate → 檢查更新
settings.checkUpdate.upToDate → 已是最新版本
settings.checkUpdate.available → 有新版本可用:{version}
settings.openDocs → 開啟文件
settings.github → GitHub
settings.dangerZone → 危險區域
settings.reset → 重置所有設定
settings.reset.confirm.title → 確定要重置所有設定嗎?
settings.reset.confirm.description → 這將清除Relay URL、開機自啟、Log 等級、以及已配對的 Session Token。你將需要重新配對才能使用。此操作無法復原。
settings.reset.confirm.cancel → 取消
settings.reset.confirm.ok → 確定重置
settings.reset.done → 已重置所有設定
```
### 6.4 驗收條件
- [ ] Relay URL 驗證 `ws(s)://` 前綴
- [ ] 變更 Relay URL 不立即套用顯示「未套用」badge
- [ ] 「測試連線」真正發 WS handshake不是假 loading
- [ ] 開機自啟 checkbox 在三平台都能正確寫入 OS 啟動項
- [ ] Log 位置顯示 OS 對應路徑,可開啟資料夾
- [ ] 匯出 Log 檔名格式正確、可正常解壓
- [ ] 重置設定會清 Session Token 並切回配對頁
---
## 7. 跨平台適配
### 7.1 macOS
| 項目 | 處理 |
|------|------|
| 視窗 chrome | **Wails 預設**(標準紅黃綠按鈕),不自訂 traffic light 位置 |
| 選單列 | Wails 預設 MenuApp / Edit / Window / Help不加自訂項 |
| 檔案對話框 | `runtime.SaveFileDialog` / `OpenDirectoryDialog` |
| 啟動項 | `~/Library/LaunchAgents/com.innovedus.visiona-agent.plist` |
| Log 路徑 | `~/Library/Application Support/visionA Agent/logs/` |
| 打包 | DMG參考 local-tool 已有的 `create-dmg` 流程)|
### 7.2 Windows
| 項目 | 處理 |
|------|------|
| 視窗 chrome | 標準 title barWindows 11 Mica 可選但**不強制** |
| 檔案對話框 | `runtime.SaveFileDialog`Wails 內建用 Win32 API |
| 啟動項 | Registry `HKCU\Software\Microsoft\Windows\CurrentVersion\Run` |
| Log 路徑 | `%APPDATA%\visionA Agent\logs\` |
| 打包 | NSIS installer`.exe`|
### 7.3 Linux
| 項目 | 處理 |
|------|------|
| 視窗 chrome | 依 DEGNOME / KDE / XFCE走預設 |
| 檔案對話框 | GTK / QtWails 依系統偵測) |
| 啟動項 | `~/.config/autostart/visiona-agent.desktop` |
| Log 路徑 | `~/.config/visionA-agent/logs/`XDG 規範)|
| 打包 | AppImage |
### 7.4 共通原則
- **不用** hover-only 操作(觸控筆電也要能用 — 所有資訊 hover 才顯示的 tooltip都必須 focus 也顯示)
- **不用** OS 特殊動畫 API避免 Linux 裝了 compositor 死機)
- **不用** 特殊字型(全跟 GeistWails 會 bundle
- **檔案路徑**顯示時一律 `font-mono text-xs`,避免字型不同導致錯位
---
## 8. Dark Mode
- 跟隨 OSmacOS `appearance` / Windows `apps use dark theme` / Linux `color-scheme` media query
- 實作方式:沿用 visionA-frontend 的 `ThemeSync` 元件react hook + `matchMedia`
- **不提供**手動切換 UI
- 所有顏色用 CSS 變數Design Tokens自動跟 `.dark` class 切換
- 圖示Lucide SVG`currentColor`,自動跟文字色
- **logo 圖片**需要 light / dark 兩版logo-light.svg / logo-dark.svg
---
## 9. 無障礙基準WCAG 2.1 AA
- **色彩對比**:一般文字 ≥ 4.5:1大文字 ≥ 3:1UI 元件 ≥ 3:1
- **不只靠顏色**:所有狀態搭配 icon + 文字
- **鍵盤導航**
- Tab 依視覺順序移動
- `Ctrl/Cmd+1/2/3` 切 Tab
- `Enter` 送出表單
- `Esc` 關閉 Dialog / 取消操作
- Focus ring 永遠可見(`ring-[3px] ring-ring`
- **ARIA**
- Tab 用 `role="tab"` / `role="tabpanel"` / `aria-selected`
- StatusHero 用 `role="status" aria-live="polite"`
- Toast 用 Sonner 預設 `aria-live="assertive"`
- AlertDialog 用 shadcn 內建焦點陷阱
- **螢幕閱讀器**
- Session Token 遮蔽版:`aria-label="Session token, ending in e7f8"`(不念完整字串)
- 圖示裝飾:`aria-hidden="true"`
- **Reduce motion**:支援 `prefers-reduced-motion`,停用 pulse / spinner 旋轉
---
## 10. i18n 字典 keys 預估
| 分類 | keys 數 |
|------|--------|
| 全域nav / header / common| ~15 |
| 狀態頁status| ~25 |
| 配對頁pair| ~30 |
| 設定頁settings| ~40 |
| 錯誤訊息errors| ~15 |
| Toast | ~10 |
| **總計** | **~135 keys** |
兩語言(繁中 + English共約 270 條翻譯。文件位置建議:
```
visiona-agent/frontend/src/lib/i18n/
├── zh-TW.ts
└── en.ts
```
偵測優先序OS locale → 預設 `en`(若非 `zh-*` 均 fallback en
---
## 11. 需使用者裁決的設計決定
以下三點為設計過程中稍有不確定、建議使用者快速裁決的點(不影響動工,可先照 Design 建議實作):
| # | 問題 | Design 建議 | 備選 |
|---|------|-----------|------|
| 1 | 視窗大小是否允許使用者記住上次大小? | **記住**Wails 預設行為) | 每次固定 720×560 |
| 2 | 配對成功後的轉場 | **0.5 秒後自動切回狀態頁**(有 toast 確認) | 停留原地,顯示大 ✓ 後讓使用者手動點繼續 |
| 3 | 「檢查更新」按鈕在 Phase 0 雛形的行為 | **stub直接回 up-to-date** | 直接隱藏按鈕Phase 1 再開 |
---
## 12. 交付檔案
| 檔案 | 狀態 |
|------|------|
| `.autoflow/03-design/visiona-agent-spec.md`(本檔)| ✅ 完成 |
**不產出**
- wireframe 子檔(本檔內已含 ASCII wireframe小規模 utility 無需再拆)
- 高保真 prototype雛形階段無必要
- 獨立 design-tokens完全沿用 visionA-frontend 既有檔案)
---
## 13. 給 Architect / Frontend Agent 的提醒
### 13.1 給 Architect
- Agent 與 remote-proxy 的通訊契約WS upgrade、session token 持久化、reconnect 指數退避)請對齊 `04-architecture/security.md` 的 Pairing / Session 兩階段協定
- 前端Wails runtime 呼叫 Go backend建議定義清楚的 API`Connect(token) / Disconnect() / Reconnect() / GetStatus() / TestRelay(url) / ExportLog() / ResetAll()`
- 狀態同步backend 用 Wails `EventsEmit("connection:status", payload)` 推送,前端 `EventsOn` 監聽
### 13.2 給 Frontend未來撰寫 Agent 前端的工程師)
- **直接複製** `visionA-frontend/src/app/globals.css` 到 Agent 專案,**不動一行**
- **直接複製** shadcn 基礎元件Button / Card / Dialog / Input / Tabs / Checkbox / RadioGroup / Select / AlertDialog / Alert / Sonner
- **不引入** Next.jsAgent 是純 SPA用 Vite + React Router或不用 router三個 tab 用 state 切換)
- i18n 沿用 visionA-frontend 的 `src/lib/i18n` 模式(自訂 hook + TS 字典)
- 所有 backend 呼叫走 Wails runtime bindings不碰 HTTP
- Dark Mode sync沿用 `ThemeSync` 元件
---
**本規格結束。共 3 頁面 + 1 全域導航 + 3 平台適配 + 135 i18n keys符合「極簡 utility」定位。**