Skip to content

fix(tui): derive tab busy state from execution only - #47666

Open
opencode-agent[bot] wants to merge 3 commits into
v2from
shell-tab-idle
Open

fix(tui): derive tab busy state from execution only#47666
opencode-agent[bot] wants to merge 3 commits into
v2from
shell-tab-idle

Conversation

@opencode-agent

@opencode-agent opencode-agent Bot commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Make the tab spinner follow execution, not pending inbox contents. The production change is one line:

busy: members.some((id) => data.session.status(id) === "running"),

A completed ! shell stores its output for the next model prompt without starting execution. Other inputs can also remain queued while idle, including after an execution fails or is interrupted. Neither inbox presence nor message type reliably indicates execution. This replaces the earlier synthetic-item filter entirely.

Shell output, input delivery, execution, family membership, unread state, and question/permission indicators are unchanged.

State coverage

Regression tests use the real client event projection and tab controller:

  • Completed shell context, including mixed synthetic/user pending input, in root and child sessions.
  • User, synthetic, compaction, and move items with both steer and queue delivery: admission does not start the spinner; delivery/cancellation does not stop active execution.
  • Success, failure, and interruption with retained user input; restarting execution lights the spinner again.
  • Running children/grandchildren propagate to the root, unrelated sessions do not, and one family member completing does not hide another still running.
  • Initial active-state hydration and reconnect snapshots after missed start/completion events.
  • Optimistic submission and failed preparation do not claim execution has started.
  • User-admission pulses and question/permission indicators remain separate from execution.

Also audited the execution lifecycle: execution-owned setup, LLM streaming, foreground tool/permission/question waits, retries, compaction, and session movement remain inside the same running period. Intermediate step completion does not end it. Existing client and Core tests cover these status/lifecycle paths.

Behavior and boundaries

  • The spinner starts when execution starts, not while an input is merely being prepared or sent. The existing optimistic prompt display is unchanged; this PR does not introduce a separate submitting indicator.
  • User ! shells, detached shell jobs, and automatic title generation have separate lifecycles. They do not by themselves make model execution busy.
  • Existing connection limitations are unchanged: disconnected clients retain their last-known status until reconciliation; a failed active-state fetch can leave stale status. Family aggregation also requires loaded ancestry, so an unseen grandchild on cold connection is not addressed here. Inbox inspection was not a reliable solution to either limitation.

Checks

  • 146 focused TUI tab, client-data, and retry-UI tests passed.
  • 70 Core execution, coordinator, and session-shell tests passed.
  • bun typecheck in packages/tui passed.
  • Prettier and git diff --check passed; focused lint has no errors (two existing warnings on unchanged lines).
  • The expanded regression suite produced 16 failures against the earlier synthetic-filter implementation before this change.
  • Real isolated TUI validation at edaa6ae9ffb549cf8880cfc389bcb91e49026d38: completed !printf stays idle; a subsequent model response shows the spinner while running and clears it on completion; empty-output shells and verbose exit-7 output at 60×24 stay idle. Shell commands were real and model output was simulated.

Requested by: @rekram1-node (Aiden via Slack)

Completed user shells enqueue synthetic context without waking the model. Do not count this deferred context as active tab work; preserve busy indicators for running sessions and pending user or control items.
Inbox admission, delivery, and item type do not describe execution. Follow the existing family execution status and cover retained input, terminal outcomes, reconnect snapshots, optimistic submission, and attention states.
@opencode-agent opencode-agent Bot changed the title fix(tui): stop tab spinner after user shell completion fix(tui): derive tab busy state from execution only Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant