Skip to content

Add startup progress indicators#71720

Merged
fabianwilliams merged 5 commits into
openclaw:mainfrom
SebTardif:copilot/cli-startup-progress
Apr 25, 2026
Merged

Add startup progress indicators#71720
fabianwilliams merged 5 commits into
openclaw:mainfrom
SebTardif:copilot/cli-startup-progress

Conversation

@SebTardif

@SebTardif SebTardif commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Show an indeterminate spinner during slow CLI bootstrap and while Crestodian loads its overview, with immediate feedback (no hardcoded 2s delay threshold).

The startup progress now stops before command execution and before the interactive TUI session begins, so nested progress is not suppressed.

Validation:

  • pnpm install --frozen-lockfile --ignore-scripts
  • pnpm exec vitest run src/cli/run-main.exit.test.ts src/crestodian/crestodian.test.ts

Copilot AI review requested due to automatic review settings April 25, 2026 19:15
@chatgpt-codex-connector

Copy link
Copy Markdown
Contributor

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Repo admins can enable using credits for code reviews in their settings.

@greptile-apps

greptile-apps Bot commented Apr 25, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds startup progress spinners for the CLI bootstrap phase and the Crestodian startup/overview-loading flows, and adds onReady signalling so the outer spinner can be dismissed before the interactive TUI starts.

  • Overview spinner always suppressed (crestodian.ts line 54): In the --message path, the "Starting Crestodian…" spinner from run-main.ts keeps activeProgress > 0 when withProgress("Loading Crestodian overview…") is called, so createCliProgress returns noopReporter unconditionally — the new overview spinner never renders from the CLI.

Confidence Score: 4/5

Mostly safe, but the newly introduced "Loading Crestodian overview…" spinner is silently dead in the primary CLI code path.

One P1 finding: the withProgress call for overview loading in crestodian.ts is always suppressed by the outer "Starting Crestodian…" spinner from run-main.ts, meaning the feature introduced in this PR for the message path never actually works. No P0 issues; functional correctness is unaffected (the command still runs), but a key UX feature regresses.

src/crestodian/crestodian.ts — the interaction between the outer progress in run-main.ts and the new withProgress call at line 54.

Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/crestodian/crestodian.ts
Line: 54-62

Comment:
**"Loading Crestodian overview…" spinner always suppressed**

When `runCrestodian` is called from `run-main.ts` with a `--message` argument, `createCliProgress` in `run-main.ts` has already incremented `activeProgress` to 1 for the "Starting Crestodian…" spinner before `runCrestodian` is entered. `createCliProgress` returns `noopReporter` when `activeProgress > 0`, so this `withProgress` call is silently suppressed for every CLI invocation via the message path — the overview spinner never appears.

`onReady` (which decrements `activeProgress` by calling `progress.done()`) is only invoked on line 81 in the TUI path, not here, so `activeProgress` is still 1 when this `withProgress` call is made. The fix is to call `opts.onReady?.()` before `loadCrestodianOverview()` so the outer spinner is stopped first, or restructure `run-main.ts` to not hold an active progress across all of `runCrestodian`.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: scripts/install.sh
Line: 449-474

Comment:
**`showed_progress` check is unreachable dead code**

`showed_progress` is set to `true` in every branch that continues past the `if/else` block: the spinner failure path sets it before falling through, and the `else` path sets it unconditionally before running the command. The `if [[ "$showed_progress" == "false" ]]` guard further down can never be entered; the `ui_info` call it wraps is dead code. The `showed_progress` variable and its guard can be removed.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (2): Last reviewed commit: "Show progress for installer download pha..." | Re-trigger Greptile

Comment thread src/cli/run-main.ts Outdated
Comment thread src/crestodian/crestodian.ts Outdated
Comment thread src/crestodian/crestodian.test.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds startup progress indicators during CLI bootstrap and Crestodian startup/overview loading, using the shared CLI progress helper to avoid polluting JSON and non-TTY output.

Changes:

  • Wrap Crestodian overview load and interactive startup in withProgress.
  • Wrap the main CLI bootstrap path in withProgress.
  • Mock and assert withProgress usage in Crestodian unit tests.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 4 comments.

File Description
src/crestodian/crestodian.ts Adds progress wrappers around overview loading and interactive startup.
src/crestodian/crestodian.test.ts Mocks withProgress and asserts progress labels are requested.
src/cli/run-main.ts Adds a bootstrap progress wrapper around routing/import/registration/parse flow.

Comment thread src/cli/run-main.ts Outdated
Comment on lines +268 to +274
await withProgress(
{
label: "Loading OpenClaw CLI…",
indeterminate: true,
delayMs: 120,
fallback: "none",
},

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fallback: "none" disables the spinner/line fallback in TTY mode (only OSC progress may show, if supported). That conflicts with the PR goal of showing a startup spinner; consider omitting fallback (default spinner) or setting fallback: "spinner" and/or enabled based on --json to keep JSON output quiet without disabling the indicator entirely.

Copilot uses AI. Check for mistakes.
Comment thread src/cli/run-main.ts Outdated
Comment on lines +365 to +371
try {
await program.parseAsync(parseArgv);
} catch (error) {
if (!(error instanceof CommanderError)) {
throw error;
}
process.exitCode = error.exitCode;

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

withProgress(...) currently wraps program.parseAsync(parseArgv), which executes the selected command. Because createCliProgress uses a global activeProgress guard, this outer progress scope will suppress any nested progress spinners used by commands for the entire runtime (and can leave the “Loading OpenClaw CLI…” state active during real work). Suggestion: limit the withProgress scope to just the slow bootstrap/import/registration steps, then call program.parseAsync after the progress has been finalized.

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +59
{
label: "Loading Crestodian overview…",
indeterminate: true,
delayMs: 120,
fallback: "none",
},

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fallback: "none" disables the spinner/line fallback in TTY mode (only OSC progress may show). If the intention is to show a visible startup indicator, consider using the default fallback (omit fallback) or explicitly fallback: "spinner" so the overview load actually displays a spinner in typical terminals.

Copilot uses AI. Check for mistakes.
Comment thread src/crestodian/crestodian.ts Outdated
Comment on lines +78 to +88
const runInteractiveTui =
opts.runInteractiveTui ?? (await import("./tui-backend.js")).runCrestodianTui;
await runInteractiveTui(opts, runtime);
await withProgress(
{
label: "Starting Crestodian…",
indeterminate: true,
delayMs: 120,
fallback: "none",
},
async () => await runInteractiveTui(opts, runtime),
);

Copilot AI Apr 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The progress wrapper for the interactive path starts after the dynamic import("./tui-backend.js"), so it won’t cover the slow module-load portion. Also, wrapping runInteractiveTui(opts, runtime) keeps the progress scope active for the entire TUI session (until the user exits), which can interfere with terminal UI and suppress any nested withProgress usage due to the global activeProgress guard. Consider scoping progress to just the startup phase (e.g., the dynamic import + initial overview load) and finishing it before entering the long-running runTui loop.

Copilot uses AI. Check for mistakes.
@SebTardif
SebTardif marked this pull request as draft April 25, 2026 19:39
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Apr 25, 2026
@SebTardif

Copy link
Copy Markdown
Contributor Author

Added follow-up coverage for the fresh-install path (curl ... | bash):\n\n- install.sh now prints immediate startup feedback before any gum bootstrap network work.\n- quiet steps now always emit a visible step label when spinner mode is unavailable (for example, shell-function-backed steps).\n- NodeSource setup-script downloads now run as explicit quiet steps, so users see progress text instead of apparent hangs.\n\nThis keeps long operations from appearing stalled in the installer flow.

@SebTardif
SebTardif marked this pull request as ready for review April 25, 2026 21:15

@fabianwilliams fabianwilliams left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worthwhile UX win — the silent multi-second startup gap is real, and createCliProgress with indeterminate spinner + done() cleanup is the right shape. onReady callback to stop the spinner from inside Crestodian keeps the lifecycle explicit. install.sh changes (adding ui_info ahead of NodeSource downloads, wrapping the bootstrap step) are also a good move — the gum bootstrap itself was the silent part. LGTM.

@fabianwilliams
fabianwilliams merged commit ea4da7d into openclaw:main Apr 25, 2026
91 of 92 checks passed
Comment on lines +54 to +62
const overview = await withProgress(
{
label: "Loading Crestodian overview…",
indeterminate: true,
delayMs: 0,
fallback: "none",
},
async () => await loadCrestodianOverview(),
);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 "Loading Crestodian overview…" spinner always suppressed

When runCrestodian is called from run-main.ts with a --message argument, createCliProgress in run-main.ts has already incremented activeProgress to 1 for the "Starting Crestodian…" spinner before runCrestodian is entered. createCliProgress returns noopReporter when activeProgress > 0, so this withProgress call is silently suppressed for every CLI invocation via the message path — the overview spinner never appears.

onReady (which decrements activeProgress by calling progress.done()) is only invoked on line 81 in the TUI path, not here, so activeProgress is still 1 when this withProgress call is made. The fix is to call opts.onReady?.() before loadCrestodianOverview() so the outer spinner is stopped first, or restructure run-main.ts to not hold an active progress across all of runCrestodian.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/crestodian/crestodian.ts
Line: 54-62

Comment:
**"Loading Crestodian overview…" spinner always suppressed**

When `runCrestodian` is called from `run-main.ts` with a `--message` argument, `createCliProgress` in `run-main.ts` has already incremented `activeProgress` to 1 for the "Starting Crestodian…" spinner before `runCrestodian` is entered. `createCliProgress` returns `noopReporter` when `activeProgress > 0`, so this `withProgress` call is silently suppressed for every CLI invocation via the message path — the overview spinner never appears.

`onReady` (which decrements `activeProgress` by calling `progress.done()`) is only invoked on line 81 in the TUI path, not here, so `activeProgress` is still 1 when this `withProgress` call is made. The fix is to call `opts.onReady?.()` before `loadCrestodianOverview()` so the outer spinner is stopped first, or restructure `run-main.ts` to not hold an active progress across all of `runCrestodian`.

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8803b2ed73

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread src/cli/run-main.ts
label: "Loading OpenClaw CLI…",
indeterminate: true,
delayMs: 0,
fallback: "none",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enable spinner fallback for CLI bootstrap progress

The new bootstrap progress reporter is created with fallback: "none", which means createCliProgress will not render a spinner or line unless OSC progress is available. In TTY environments where supportsOscProgress(...) returns false, users now see no startup indicator during slow CLI initialization, so the new feedback path is effectively disabled for that terminal class.

Useful? React with 👍 / 👎.

label: "Loading Crestodian overview…",
indeterminate: true,
delayMs: 0,
fallback: "none",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use visible fallback for Crestodian overview progress

The overview-loading progress in runCrestodian also sets fallback: "none", so on TTYs without OSC progress support there is no visible indicator while loadCrestodianOverview() runs. That creates a silent wait in the exact one-shot flow this change is trying to make more responsive.

Useful? React with 👍 / 👎.

ayesha-aziz123 pushed a commit to ayesha-aziz123/openclaw that referenced this pull request Apr 26, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
ogt-redknie pushed a commit to ogt-redknie/OPENX that referenced this pull request May 2, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 9, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
globalcaos pushed a commit to globalcaos/tinkerclaw that referenced this pull request May 13, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
github-actions Bot pushed a commit to Desicool/openclaw that referenced this pull request May 24, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
jameslcowan pushed a commit to jameslcowan/openclaw that referenced this pull request Jun 2, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
sablehead pushed a commit to sablehead/openclaw that referenced this pull request Jun 10, 2026
* Add startup progress indicators

* Narrow startup progress scope

* Revert startup spinner delay to immediate feedback

* Improve install.sh progress feedback for quiet steps

* Show progress for installer download phases
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes scripts Repository scripts size: M

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants