# ADR-007:visionA Agent 採 fork local-tool 獨立演進(非改造 local-tool) ## 狀態 Accepted — 2026-04-22 ## 背景 (Context) visionA 雲端版需要在使用者桌機上跑一個「local agent」,使得雲端 Web UI 可以透過 tunnel 操作桌機上的 Kneron 裝置。 這個 local agent 本質上是: - **完整的 local-tool server**(KneronPLUS / camera / inference / device / model / Python runtime / ffmpeg 等邏輯完全一樣) - **加上** tunnel client(反向連 remote-proxy) - **加上** 3 頁極簡 UI(狀態 / 配對 / 設定) - **減去** local-tool 原本的裝置 / 模型 / 推論操作 UI(這些交給雲端 web) 關鍵選擇: 1. **改造 local-tool**:讓 local-tool 本身支援「雲端模式」開關,同一份程式碼兩用。 2. **fork local-tool → visionA Agent**:複製一份出來,獨立演進。 使用者在 `progress.md` 明確提出 4 大原則之一:「**local-tool 不要動,可以複製出來**」。這個 ADR 把這個原則落地並說明技術細節。 ## 決策 (Decision) **採方案 2:fork local-tool 建立新專案 `/Users/jimchen/visionA/local-agent/`,2026-04-22 fork 一次後獨立演進。** ### 實作細節 - **整包複製**:`server/internal/*`、`server/pkg/*`、`vendor/`、`scripts/`、Makefile 結構、wails 配置都從 local-tool 整包搬 - **新增**:`cmd/visiona-agent/`(Wails app shell)、`internal/tunnel/`、`internal/pairing/`、`internal/tokenstore/`、`internal/agentconfig/`、`internal/autostart/`、`internal/connstate/`、`internal/logexport/`、`internal/httpserver/` - **刪除 / 取代**:local-tool frontend(Next.js 多頁 UI)整包刪除,改為極簡 Vite + React + shadcn SPA(3 頁) - **改造**:`wails.json`、Bundle ID、App name(`visionA Agent`、`com.innovedus.visiona-agent`)、`go.mod` 改 `module visiona-agent` ### Sync 策略 2026-04-22 fork 一次後**不主動 sync local-tool 的改動**。若 local-tool 有重大修復,走**手動 cherry-pick**(人工 diff 檢視 → apply)。這個決策在 `progress.md` visionA Agent 決策表中明列。 ## 考慮過的替代方案 | 方案 | 優點 | 缺點 | 排除原因 | |------|------|------|---------| | **改造 local-tool 支援雲端模式**(build tag / feature flag) | 程式碼唯一來源、維護成本低 | 兩套 UI 分支讓 local-tool 複雜化;使用者測試需覆蓋兩種模式;違反使用者「不動 local-tool」原則 | **使用者原則** + 複雜度風險 | | **做成 monorepo 兩個 app 共用 server 模組** | 代碼復用、一次修多處生效 | Go module 設定複雜、一處改動可能破兩個 app、測試矩陣加大 | 雛形階段不值得,收益不確定 | | **純 headless CLI agent**(不用 Wails) | 最輕量 | 使用者體驗差(無配對 UI、只能 CLI 貼 token)、無法 Log 檢視 / 設定 | UX 差 | | **抽象出獨立的 "agent-core" library** | 優雅 | 需要設計 API、進一步增加結構複雜度、現階段只有一個 consumer | 過度設計 | ## 後果 (Consequences) ### 正面影響 - **完全符合使用者「不動 local-tool」原則**:local-tool 後續任何改動都不會直接影響 visionA Agent - **獨立演進自由**:visionA Agent 可以按照雲端整合需求自由改 handler、加欄位、刪 UI,不擔心破壞 local-tool 使用者 - **共同起跑點清楚**:2026-04-22 的 fork 時間戳記是明確的 baseline;未來要追 local-tool 新功能時,知道從哪個 commit 開始 diff - **打包獨立**:兩個產品各自有 installer,Bundle ID 不衝突,使用者可以同時裝兩個 ### 負面影響(接受的取捨) - **維護成本加倍**:local-tool 若修了 Kneron driver bug,需要手動 cherry-pick 到 visionA Agent - **程式碼重複**:整個 `server/` 目錄存兩份;未來長出差異的機率高 - **Installer 體積重複**:同樣的 Python / wheels / ffmpeg bundle 各自打包一份(但反正用戶只裝一個) ### 風險 - **Cherry-pick 遺漏**:修復本 bug 卻忘了同步另一邊 → 建立明確的 review checklist(當 local-tool 修 Kneron 相關或 security 相關 bug 時,必須評估是否 cherry-pick 到 agent) - **長出的差異難以回頭合併**:隨時間兩邊結構差異加大,未來若想合併可能已不現實 — 接受這個結果,本 ADR 即假設**不會合併** - **使用者同一台電腦裝兩個可能衝突**:port / config dir 需要明確隔離(bundle ID、app name、data dir 全部不同已處理) ## 合規性 - [x] 使用者核心原則:「local-tool 不要動」— 由 fork 策略保證 - [x] 與 Design spec 對齊:Bundle ID `com.innovedus.visiona-agent` 獨立 - [ ] Cherry-pick SOP 文件:TODO(Phase 1 前補) ## 相關文件 - `progress.md` visionA 產品線 4 大核心原則 - `.autoflow/04-architecture/visiona-agent-tdd.md` §2-§3 - ADR-008(tunnel client 複用策略) - ADR-009(token 儲存策略)