Skip to content

fix(tui): show loading status during hatch initialization (#74385)#75120

Closed
ottodeng wants to merge 6 commits into
openclaw:mainfrom
ottodeng:fix/tui-hatch-busy-state
Closed

fix(tui): show loading status during hatch initialization (#74385)#75120
ottodeng wants to merge 6 commits into
openclaw:mainfrom
ottodeng:fix/tui-hatch-busy-state

Conversation

@ottodeng

Copy link
Copy Markdown
Contributor

What

Surfaces a busy initializing activity status while the TUI runs its post-connect refreshAgents() + loadHistory() work, instead of showing local ready | idle for up to a minute before the first hatch auto-message can even fire.

Fixes #74385.

Why

On openclaw onboard → "Hatch in Terminal", the TUI previously transitioned to idle the moment the local runtime came up, then silently spent up to ~60s loading agents and chat history before the auto-message could start. The status line claimed the bot was idle the whole time, so users assumed the launch had hung.

clawsweeper's triage on the issue traced this to src/tui/tui.ts:1073client.onConnected sets the connection status but doesn't set any activity status while the awaited initialization work runs, even though the existing busy-state machinery at src/tui/tui.ts:597 already renders a loader for sending|waiting|streaming|running.

How

  • Promote the inline busyStates set in src/tui/tui.ts to an exported isBusyActivityStatus() helper plus a named INITIALIZATION_ACTIVITY_STATUS = "initializing" constant. The existing loader render path (renderStatus, startStatusTimer) now treats "initializing" as busy with no other changes — same spinner, same elapsed counter.
  • In client.onConnected, set activityStatus = "initializing" immediately after setConnectionStatus(...), before awaiting refreshAgents() / loadHistory().
  • When an auto-message is queued, sendMessage() flips the status into sendingwaiting as today, so the loader stays continuous from boot through the first model response. If no auto-message is configured, the post-init block restores idle once history loads — but only if the status is still initializing, so we don't clobber a state that an event handler already updated. Errors restore idle the same way before rethrowing.

Coverage

Acceptance-criteria test suites from the issue (124 tests, all green):

✓ src/tui/tui.test.ts                     (43, +3 new)
✓ src/tui/tui-event-handlers.test.ts      (44)
✓ src/tui/tui-command-handlers.test.ts    (21)
✓ src/tui/tui-session-actions.test.ts     (5)
✓ src/wizard/setup.finalize.test.ts       (11)

pnpm exec oxfmt --check clean on the files listed in the issue acceptance criteria (setup.finalize.ts, tui.ts, tui-command-handlers.ts, tui-event-handlers.ts, tui-session-actions.ts, embedded-backend.ts). pnpm exec oxlint reports 0 warnings / 0 errors on touched files.

New describe("isBusyActivityStatus", ...) block asserts:

Risk

Low. The change is additive: one extra entry in the busy set, and one extra status transition during connect. No public API surface, no config schema change, no impact on remote/headless flows. Existing send → wait → stream cycles take exactly the same path as before.

Out of scope

This PR only addresses the missing busy state during the post-connect init block. The underlying duration of loadHistory() / refreshAgents() themselves (which can still legitimately take a long time on large workspaces) is a separate concern.

…4385)

The local TUI showed `local ready | idle` while still awaiting
refreshAgents() and loadHistory() during the Terminal hatch flow,
making the bot look stuck for up to a minute before the first
hatch auto-message could even start.

Reuse the existing busy-state machinery to surface initialization
work to the user; idle is restored once history loads (or the
auto-message takes over the loader).

Fixes openclaw#74385
@clawsweeper

clawsweeper Bot commented Apr 30, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The PR adds an initializing TUI activity status during post-connect agent/history loading, routes it through the existing busy loader, adds focused TUI tests, and adds a changelog entry.

Reproducibility: yes. from source inspection: Terminal Hatch launches the local TUI, current main sets ready before awaited agent/session/history work completes, and the busy renderer excludes initialization. I did not run a live Hatch session in this read-only review.

Real behavior proof
Needs real behavior proof before merge: The PR body and comments list tests and lint only; the contributor still needs a redacted terminal screenshot, recording, copied live output, runtime log, or linked artifact showing the fixed Hatch/TUI flow, then update the PR body so ClawSweeper reruns or ask a maintainer to comment @clawsweeper re-review.

Next step before merge
Human follow-up is needed because contributor-side real behavior proof is missing and the submitted patch has a concrete startup-error regression to fix before normal review can pass.

Security
Cleared: The diff only touches TUI status logic, colocated tests, and changelog text; no dependency, workflow, secret, package, download, or code-execution surface change was found.

Review findings

  • [P2] Preserve startup error reporting — src/tui/tui.ts:1224
Review details

Best possible solution:

Land a narrow TUI initializing busy-status fix that preserves startup-failure rendering and reconnect busy states, then treat any remaining Hatch latency as a separate performance investigation.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection: Terminal Hatch launches the local TUI, current main sets ready before awaited agent/session/history work completes, and the busy renderer excludes initialization. I did not run a live Hatch session in this read-only review.

Is this the best way to solve the issue?

No, not as submitted. Reusing the existing busy-loader path is the right narrow fix, but this branch must preserve the current startup-error .catch() and add real Hatch/TUI behavior proof before merge.

Full review comments:

  • [P2] Preserve startup error reporting — src/tui/tui.ts:1224
    Current main renders startup failures in the TUI via the terminal .catch() on this initialization IIFE. This patch catches errors only to reset initializing and then rethrows without an outer catch, so failed refreshAgents(), loadHistory(), or bootstrap auto-message startup now becomes an unhandled rejection instead of visible startup failed feedback.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.86

What I checked:

  • Current main lacks initialization busy state: Current main still keeps the busy renderer limited to sending, waiting, streaming, and running; no initializing status exists in the current TUI path. (src/tui/tui.ts:779, a6aa48350b7e)
  • Current main reports ready before awaited startup work: client.onConnected sets local ready or connected before awaiting refreshAgents(), restoreRememberedSession(), and loadHistory(), then preserves visible startup failure reporting with an outer .catch(). (src/tui/tui.ts:1292, a6aa48350b7e)
  • Terminal Hatch reaches the affected local TUI path: The onboarding Terminal Hatch choice calls launchTuiCli({ local: true, deliver: false, message, timeoutMs }), matching the linked Hatch report. (src/wizard/setup.finalize.ts:488, a6aa48350b7e)
  • PR head adds intended loader status but drops the outer error handler: The PR head adds INITIALIZATION_ACTIVITY_STATUS and the busy helper, but its initialization IIFE catches errors only to reset status and rethrows at line 1224 while the IIFE call has no outer .catch(). (src/tui/tui.ts:1224, f02f570b3f69)
  • PR metadata and proof state: Live PR data shows this PR is open, unmerged, references [Bug]: Stuck and ultra slow during Hatch (terminal mode) - took a minute to come back up #74385 as a closing issue, and the body/comments list tests and lint but no after-fix real Hatch/TUI run evidence. (f02f570b3f69)
  • Feature-history routing evidence: History shows local embedded TUI and onboarding Hatch flow were introduced in 276c000, reconnect watchdog behavior changed in d4e52f4, setup TUI handoff changed in aae4b1b, and Hatch timeout handling changed in 86cc292. (276c00015c83)

Likely related people:

  • fuller-stack-dev: Introduced local embedded TUI mode and the onboarding Hatch flow that reaches the affected terminal TUI path. (role: introduced behavior; confidence: high; commits: 276c00015c83; files: src/tui/tui.ts, src/tui/tui-session-actions.ts, src/wizard/setup.finalize.ts)
  • rogerdigital: Recently changed reconnect streaming-watchdog behavior in the same TUI connection/activity-status area this PR updates. (role: recent adjacent contributor; confidence: high; commits: d4e52f454255; files: src/tui/tui.ts, src/tui/tui-event-handlers.ts, src/tui/tui-event-handlers.test.ts)
  • shakkernerd: Recently fixed setup-to-TUI terminal handoff behavior adjacent to the onboarding Hatch launch path. (role: recent hatch handoff contributor; confidence: medium; commits: aae4b1b29dd7; files: src/tui/tui-launch.ts, src/wizard/setup.finalize.ts, src/wizard/setup.finalize.test.ts)
  • joshavant: Added bounded Terminal Hatch timeout handling near this startup path, though that is separate from the missing initialization loader. (role: recent adjacent contributor; confidence: medium; commits: 86cc29274e03; files: src/wizard/setup.finalize.ts, src/tui/tui-launch.test.ts, src/tui/embedded-backend.test.ts)

Remaining risk / open question:

  • The PR head turns startup initialization failures into unhandled rejections instead of visible startup failed TUI feedback.
  • Contributor-side real behavior proof is still absent; tests and lint do not demonstrate the fixed Hatch/TUI path in a real run.

Codex review notes: model gpt-5.5, reasoning high; reviewed against a6aa48350b7e.

@ottodeng

ottodeng commented May 2, 2026

Copy link
Copy Markdown
Contributor Author

Addressed clawsweeper [P3]: added a TUI changelog entry under Unreleased Fixes referencing #74385. Pushed in latest commit.

…state

# Conflicts:
#	CHANGELOG.md
#	src/tui/tui.ts
@ottodeng

Copy link
Copy Markdown
Contributor Author

Closing as stale — merge conflict unresolved for 14+ days and no maintainer follow-up. Freeing the PR slot. (Auto-managed by hermes-eason)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Stuck and ultra slow during Hatch (terminal mode) - took a minute to come back up

1 participant