Skip to content

fix: pipeline progress bar eases inside each stage's slice - #111

Merged
sgardoll merged 4 commits into
milestone/stu-implement-updated-ui-uxfrom
devin/1790621766-smooth-progress
Sep 28, 2026
Merged

sgardoll merged 4 commits into
milestone/stu-implement-updated-ui-uxfrom
devin/1790621766-smooth-progress

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Summary

The generation progress bar snapped between stage boundaries — renderPipelineTrack() wrote completedStages / 3 * 100%, so the fill had exactly four positions and nothing moved while a stage was in flight.

Each stage now owns a third of the track and the fill eases inside its slice, the same shape CommitPhases uses for the deploy overlay:

  • pipelineTrackPercent() returns (activeStage - 1) * 33.3% + 33.3% * 0.95 * (1 - exp(-elapsed / 12)) while the active stage runs — approaching 95% of the slice asymptotically so a slow stage still looks alive without ever claiming it finished.
  • pipelineStageStartedAt re-arms on every updatePipelineProgressStep(); the existing 250ms pipelineElapsedTimer tick now also re-renders the track, so the fill moves continuously.
  • Real completions still land on exact boundaries via the done/3 fallback; a failed stage freezes where it eased to; refine/fix re-entry at stage 2 starts its slice consumed (skipped stage 1 reads as passed).
  • New e2e holds all three stage responses and asserts the fill strictly increases inside each slice and never crosses a boundary before the response lands.

Evidence

  • CI=1 CCC_TEST_PORT=3105 npx playwright test stu377-pipeline-progress → 30/30 passed (new spec: the track eases through each stage's slice instead of jumping)
  • npm test → 396/396 passed

Link to Devin session: https://app.devin.ai/sessions/2c1947d6c8094275a078fc26277154d5
Open in Devin Desktop: https://app.devin.ai/desktop/session/2c1947d6c8094275a078fc26277154d5?variant=devin
Requested by: @sgardoll


Devin Review

The fill jumped between stage boundaries (doneCount/3) so nothing moved
while a stage ran. Each stage now owns a third of the track and the fill
eases asymptotically toward 95% of its slice on the existing 250ms tick,
landing on the real boundary only when the stage's response arrives.
Failed stages freeze where they eased; skipped slices (refine re-entry)
start consumed.

Co-Authored-By: Stuart Gardoll <sgardoll@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

I'll fix CI failures and address comments from users with write access that start with 'Devin'.

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

This PR does not match any of the 1 configured review trigger rule.

devin-ai-integration[bot]

This comment was marked as resolved.

…their boundary

- Failed runs pin the fill's rendered width with the transition disabled,
  so the bar stops where it visibly was instead of drifting 700ms more.
- A completed active stage sits on its own boundary (activeStage/3), so
  stage-2 re-entry runs finish on 100% instead of retreating to 66.7%.
- e2e: held stages 2/3 assert upper ceilings; a new spec pins the frozen
  width across the transition window; the refine spec asserts a 100% finish.
- Timer comment now covers both elements it drives.

Co-Authored-By: Stuart Gardoll <sgardoll@gmail.com>
devin-ai-integration[bot]

This comment was marked as resolved.

…rack %

- Reading getComputedStyle after transition:none resolves the pending
  target, not the mid-flight position — capture first, then pin.
- The pin is now renderedPx/trackPx as a percentage, so a later viewport
  resize keeps the same proportion instead of a stale pixel count.
- e2e: frozen pin asserts a %-valued inline width and a fixed computed
  width across a 900ms window.

Co-Authored-By: Stuart Gardoll <sgardoll@gmail.com>
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Verified the smooth progress bar end-to-end against the real backend (not mocks). A full 3-stage generation run on the Vite dev server showed the fill easing continuously inside each stage's slice instead of jumping at boundaries.

Instrumented #pipeline-progress-fill every 100ms across the whole run:

  • Stage 1 in flight (~19s): 77 distinct widths, strictly increasing 16.1→28.5%, never past the 33% slice
  • Stage 2 in flight (~26s): 105 distinct widths, strictly increasing 33.3→61.4% — segment started exactly at 33.3333% when the architect response landed
  • Stage 3 in flight (~14s): 55 distinct widths, strictly increasing 66.8→88.1%
  • Zero decreases anywhere; fill hit exactly 100% on the final response and the results view rendered (score 100/100)
  • Elapsed counter ticked normally throughout

Stage 3 easing in flight (~75%)

More evidence

Stage 1 mid-ease (~20%)
Stage 2 mid-ease (~40%)
Results view after completion

The branch's own spec the track eases through each stage's slice instead of jumping also passes.

devin-ai-integration[bot]

This comment was marked as resolved.

Co-Authored-By: Stuart Gardoll <sgardoll@gmail.com>
@sgardoll
sgardoll merged commit 46b1349 into milestone/stu-implement-updated-ui-ux Sep 28, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant