Skip to content

feat(cli): show each deployment's steps live while it runs - #416

Open
PiquelChips wants to merge 2 commits into
feat/timeline-2-apifrom
feat/timeline-3-cli
Open

PiquelChips wants to merge 2 commits into
feat/timeline-2-apifrom
feat/timeline-3-cli

Conversation

@PiquelChips

@PiquelChips PiquelChips commented Nov 10, 2026 •

Copy link
Copy Markdown
Member

While piquelctl waits for a deployment, it shows one spinner line with the operation's current phase. You can't tell what already ran, what is left, or how long it will take, and in CI you get a line per phase change and nothing else.

Every command that waits for a deployment (deploy, apply/save/create that deploy, promote, restore, preview create/deploy, operation, env wait, preview wait) now follows the operation's timeline stream from #412 and draws its steps live:

⠹ Deploying 019a6f3e-…  ▕████████░░░░▏ 6/9  48.2 s  ~30.0 s left
  ✓ Fetch manifest  412 ms
  ✓ Build api       38.2 s  (usual 25.0 s)
  ⠹ Update api      3.2 s
  ○ Wait for api    ~30.0 s
  ○ Update web
  • Done steps show how long they took, plus "(usual …)" only when that is far off the usual. Steps left show ~usual. Failed steps show their diagnostic summary, and retrying steps show which retry they're waiting for.
  • The row redraws every 100 ms from the latest timeline. Running times and the time left are computed locally, so nothing is fetched per frame.
  • At the end it prints how long the deployment took and, after a clean run, how long its steps usually take, then the final tree.
  • Without a terminal, each step prints one line when it starts or changes. With --json, each change is a {"step":{…}} event on stderr. Results on stdout are unchanged. Ctrl-C still only stops watching.
  • piqueld-client gains operation_timeline and operation_timeline_stream, with a small SSE reader. Streams have no per-request deadline; --wait-timeout bounds the wait, as for every other wait since fix(cli): keep waiting through daemon restarts and retried failures #418.
  • Waiting follows fix(cli): keep waiting through daemon restarts and retried failures #418's rules through its Wait: once the daemon answered, a dropped stream, a restart or a busy daemon is retried with backoff, a failed attempt the daemon retries keeps the wait going, and --wait-timeout bounds it all. 45 s without a keep-alive counts as a drop, and a 503 refusing the stream switches to polling the timeline. Wait reports through the tree, so there is never a spinner as well.
  • Phase::label() in piqueld-core names each step for people, so the dashboard can use the same labels.

Proved on a real dev instance: piquelctl held one timeline stream through a 79 s silent job step (counted with strace), and reruns print only the new run's steps; plus CLI and transport tests.

Reviewed with review-loop: 3 rounds with 3× Claude Opus 5.5 (GPT 6.1 Sol was out of credits; a Sol pass is still owed). Verdict: approved

Note

Written by Claude Opus 5.5 in Claude Code and reviewed by Claude Opus 5.5 (via T3 Code)

@coderabbitai

coderabbitai Bot commented Nov 10, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 59 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c485d6e4-113b-4954-9b70-907fa5b3d86e
Commits

Reviewing files that changed from the base of the PR and between eaabac1 and 7e27229.

Files selected for processing: 13

  • apps/piquelctl/src/commands.rs
  • apps/piquelctl/src/environments.rs
  • apps/piquelctl/src/output/mod.rs
  • apps/piquelctl/src/output/progress.rs
  • apps/piquelctl/src/output/timeline.rs
  • apps/piquelctl/tests/cli.rs
  • crates/piqueld-client/src/client.rs
  • crates/piqueld-client/src/lib.rs
  • crates/piqueld-client/src/operations.rs
  • crates/piqueld-client/src/sse.rs
  • crates/piqueld-client/tests/transports.rs
  • crates/piqueld-core/src/timeline.rs
  • docs/user/reference/cli.md
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

Share

@PiquelChips
PiquelChips force-pushed the feat/timeline-3-cli branch 3 times, most recently from c43dd52 to 7910342 Compare November 10, 2026 20:02
@PiquelChips
PiquelChips marked this pull request as ready for review November 10, 2026 20:33
@PiquelChips
PiquelChips added this pull request to stack #449 November 12, 2026 13:48
Commands that wait for a deployment showed one spinner line with the
operation's current phase, so nobody could tell what was done, what was
left, or how long it would take.

They now follow the operation's timeline stream and draw a tree of its
steps: those done with how long they took (and how long they usually take,
when that differs noticeably), the one running, and those left with their
usual duration, under a header with a bar of steps done and the time left.
The row redraws every 100 ms from the latest timeline, computing running
times locally. Without a terminal, each step prints a line when it starts
or changes; with `--json`, a `step` event. Each wait ends with how long the
deployment took and, after a clean run, how long its steps usually take.

piqueld-client gains `operation_timeline` and `operation_timeline_stream`,
a small server-sent events reader, and streams without a request deadline.
The follower reads through the CLI's `Wait`, which stays the one place
that bounds waits by `--wait-timeout`, backs off, rides out failures once
the daemon answered, and keeps a wait going through a failure the daemon
retries: piquelctl reopens a stream that fails or ends, treats 45 s without
a keep-alive as a drop, and polls the timeline when the daemon refuses the
stream for having too many open. `Wait` reports through a small `Progress`
trait, so a deployment wait shows what it rides out under its steps instead
of in a second spinner. `Phase::label` names each step for people, for the
dashboard to share.
The CLI treated 45 seconds without a timeline change as a dropped stream,
because keep-alives never reached it: a long build or a quiet rollout made
it reopen the stream every 45 seconds, rebuilding the whole timeline on the
daemon each time. The client's timeline stream now reports keep-alives, so
silence means no bytes at all.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

1 participant