jim800121chen ad9beab0ca fix(local-tool): Restart / StopServer+StartServer 後前端 5 階段 UI 不更新
使用者在 Windows 版 local tool 按「重新啟動伺服器」或 Stop 再 Start 後,
畫面中間的 5 階段面板停留在「等待中」不更新,但實際上 server 已經
成功啟動完成。

根因:
  Restart / StartServer 路徑 → ctrl.Restart() / ctrl.Start() →
  ctrl.startInternal() → startServerV2()

  但 StartupPipeline 已經 markReady (current=7),所以 startServerV2 內
  所有 CompleteStage(2/3/4) / EmitStageDetail / IsInColdStart 檢查都
  early return 或 no-op,Go 端完全不 emit 任何 startup:progress event。
  前端 resetStartupPanel 後開始等事件,但事件根本沒來 → UI 停留在
  pending「等待中」。

  RestartStartupSequence(Retry 按鈕)有自己完整重建 pipeline 的 5 步
  邏輯,所以 Retry 路徑沒事。但 Restart / Stop+Start 走的是 ctrl.Restart
  / ctrl.Start 不走 RestartStartupSequence。

修法:

1. 抽 helper rebuildStartupPipeline() — 把 RestartStartupSequence 裡
   「重建 pipeline + emit Stage 1 completed + 啟 watcher + 前進 Stage 2」
   那 20 多行邏輯抽出來,讓 startInternal 也能呼叫。

2. startInternal 進場時偵測 pipeline 狀態:
   - cold start 路徑 (current ∈ [1..6]) → 不動
   - 已 ready (current > totalStages) 或 已 failed (current == -1)
     → 清 sentinel file + 呼叫 rebuildStartupPipeline(),記 didRebuild=true

3. startInternal 成功返回前,Stage 5 openBrowser 處理改成三分支:
   - didRebuild=true → 呼叫 runStartupStage5(Restart 路徑)
   - cold start (IsInColdStart && !didRebuild) → skip 由上層呼叫
     runStartupStage5(app.startup 冷啟動路徑或 RestartStartupSequence)
   - fallback (pipeline == nil) → 自己 openBrowser 一次

四條路徑的分流現在完整:

  (A) cold start           : app.startup → Pipeline.Start 自己前進到 2 →
                             startInternal 看 current=2 不 rebuild →
                             didRebuild=false → app.startup 呼叫 stage5
  (B) Restart / Stop+Start : ctrl.Restart/Start → startInternal 看
                             current=7 rebuild → didRebuild=true →
                             startInternal 自己呼叫 stage5
  (C) RestartStartupSequence: 自己 rebuild 前進到 2 → ctrl.Start →
                             startInternal 看 current=2 不 rebuild →
                             didRebuild=false → RestartStartupSequence
                             後續呼叫 stage5
  (D) pipeline == nil       : 走舊 fallback 自己 openBrowser

驗證:
- visiona-local 套件 go build / vet / test -race 全綠
- 關鍵 test TestRestartStartupSequence_ColdStartOpenBrowser_OnlyOnce
  仍 pass(驗證 browser 不會被 cold start 開兩次)
- macOS dmg 163MB 重 build OK

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 08:19:33 +08:00

visionA

Innovedus visionA monorepo. Currently contains:

Subprojects

local-tool/

visionA-local — local-first edge AI desktop tool, derived from edge-ai-platform. Wails + Go + Next.js, packaged as macOS dmg / Windows exe / Linux AppImage.

See local-tool/README.md for details.

License

TBD (internal use)

Description
No description provided
Readme 56 MiB
Languages
Go 42.4%
TypeScript 33.7%
JavaScript 7.5%
Python 5.3%
Makefile 3.7%
Other 7.4%