diff --git a/apps/desktop/src/components/desktop-install-overlay.tsx b/apps/desktop/src/components/desktop-install-overlay.tsx index 0213a93b7d2..0341dc5675f 100644 --- a/apps/desktop/src/components/desktop-install-overlay.tsx +++ b/apps/desktop/src/components/desktop-install-overlay.tsx @@ -407,7 +407,11 @@ export function DesktopInstallOverlay({ enabled = true }: DesktopInstallOverlayP const totalCount = stages.length const failed = Boolean(state.error) - const progressPct = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0 + // Count the running stage as half-done so the bar advances *during* a long + // stage instead of sitting frozen at the last completed step while its logs + // stream (e.g. "0 of 2" pinned at 0% for the whole first stage). + const progressUnits = completedCount + (!failed && currentStage ? 0.5 : 0) + const progressPct = totalCount > 0 ? Math.round((progressUnits / totalCount) * 100) : 0 const currentStartedAt = currentStage ? state.stages[currentStage]?.startedAt : null const currentElapsed = typeof currentStartedAt === 'number' ? formatElapsed(now - currentStartedAt) : '' diff --git a/apps/desktop/src/store/updates.ts b/apps/desktop/src/store/updates.ts index 6b6aae9bea1..3297b6e9a90 100644 --- a/apps/desktop/src/store/updates.ts +++ b/apps/desktop/src/store/updates.ts @@ -531,7 +531,9 @@ function ingestProgress(payload: DesktopUpdateProgress): void { applying: !terminal, stage: payload.stage, message: payload.message, - percent: payload.percent, + // Streamed log lines carry percent: null; keep the last milestone percent + // (10/60/…) instead of resetting the bar to indeterminate on every line. + percent: payload.percent ?? current.percent, error: payload.error, // 'manual' carries the command to run in its message field. command: payload.stage === 'manual' ? payload.message : current.command,