Skip to content

Stop native chat jumping when Codex starts a foreground command - #26503

Merged
brennanb2025 merged 3 commits into
mainfrom
brennanb2025/command-strip-flash
Oct 8, 2026
Merged

brennanb2025 merged 3 commits into
mainfrom
brennanb2025/command-strip-flash

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

The chat jumps when Codex starts a quick command because a “1 shell command” bar appears above the composer, then disappears when that command finishes. Foreground commands now stay in their tool rows; the bar appears only for commands that are still running after their launching turn ends.

What Changed

  • Record each command immediately on the machine running the agent, marked as foreground until its own turn ends. The chat still reports that work is running, while the command stays out of the background bar.
  • Treat commands still running when their own turn ends as background work, and keep them visible during later turns. Completion, thread close, and session teardown still remove them.
  • When a newer client reads an older server's background list, identify foreground commands using existing tool rows and command creation times, including a list arriving before its tool row. Other providers and child-agent rosters retain their behavior.

Why

Commit 153d3fd3fafe9a5b85f2dc490cd6dfff3aacfc76 (#22553) classified every command as background immediately. The verified flash window is command start → background record and roster publication → command completion removes the row. There is no foreground filter or debounce in that path. The activity line can retain a completed tool, so its longer lifetime does not establish that the process still runs.

The common pattern places foreground calls in the transcript and separately projects background work. Intended difference: Orca still records every process immediately because waiting until turn completion previously made the chat briefly report done while work was running. Filtering the background list preserves that status guarantee. A renderer delay would mask the state error; hiding every command during an active turn would also hide existing background work.

Linked Issue

Requested fix for the October 8 native-chat recording; no linked issue.

Visual Proof

Before, from the reported recording (row 3, tile 2 shows the transient bar):

evidence-frames-14s-8fps.png

After, from the hidden real Orca app using an absolute-path Codex app-server stand-in. This is a deterministic provider sequence, not an authenticated Codex turn. The fresh profile had hooks and automatic chat resumption disabled, every agent command redirected, and Electron's actual home directory verified before opening the chat.

The sequence starts with Send and covers both quick command starts and completions. A separate observer sampled 87 rendered frames over 985 ms: zero background-strip mounts and unchanged composer coordinates. The app produced 29 compositor frames; the contact sheet samples every third frame plus the last. Labels are frame indices, not playback timestamps.

command-strip-after-full.png

A command that survives its source turn appears above the composer after that turn completes:

survivor-01-after-source-turn.png

It stays visible during the next running turn. The simultaneous host snapshot identifies that later turn and the same surviving command:

survivor-02-during-next-turn.png

The strip clears when the command completes. The later UI capture is also after the next turn ended; the host regression checks removal at the command-completion publication itself.

Testing

  • Hidden-app Playwright validation completed: two quick commands do not mount the strip; a survivor appears after its own turn, stays during the next turn, and clears on completion.
  • Added the failing host-channel regression before the fix; it inspects every roster publication across two quick commands, then verifies a surviving command during the next turn. Registered the SQLite-backed test in the Node project after CI caught the missing registration. Updated the existing 448-command retention fixture to send the same turn-end events as production, while preserving its output and memory-budget assertions.
  • 220 tests passed across 19 explicit files, covering host publication, old-host ordering, command retention, parent status, child ownership, approvals, and close behavior.
  • Node, renderer, and CLI typechecks passed through the machine queue.
  • All 22 pre-push static checks passed on the final staged change.

Local automated verification: macOS. No authenticated Codex turn, original provider event trace, or live Windows/Linux/SSH UI run is claimed.

Review

Self-reviewed which turn launched each command, background-list consumers, memory limits, cleanup, accurate running status, and compatibility between different client/server versions. A fresh independent review was requested from the coordinator and has not arrived.

Agent skill upstream boundary

  • Not applicable; no upstream skill-installer material copied or translated.

Notes

No protocol messages or fields changed. Classification runs on the machine executing the agent and uses its existing foreground/background phase. The same rule applies to local worktrees, folder workspaces, Windows Subsystem for Linux, and remote SSH hosts.

Temporary compatibility limitation: very old servers send only a task list without command creation times. If an earlier command's tool row is also outside the loaded conversation page, the newer client conservatively hides that command until the active turn ends. This compatibility arm can be removed when hosts that publish foreground commands age out; no follow-up ticket exists yet.

Checklist

  • Focused on the reported command-strip jump.
  • Explained the user-facing change, cause, mechanism, and alternatives.
  • Before recording and after frame sequence attached, plus a full-app survivor screenshot from a later running turn.
  • Self-reviewed correctness and bounded resource use.
  • Considered cross-platform, folder, SSH, and mixed-version behavior.
  • Targeted tests, queued typechecks, and static checks passed. CI completed on the final head: every unit shard, both package jobs, static analysis/typechecks, and the headless-server Ubuntu qualification passed. Conditional skips are not counted as passes.

@brennanb2025

brennanb2025 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor Author

The chat jumped because every Codex command was immediately listed as background work; a quick command could add the strip above the composer for one frame before completion removed it. Commit 153d3fd introduced that classification.

Foreground commands now remain in their transcript tool rows. The execution host keeps every process immediately so the chat reports that work is running, treats survivors as background work when their own turn ends, and includes only background commands in the strip; existing background work stays visible during later turns. New clients also filter current primary commands received from older hosts using existing tool rows or command creation times. No wire fields, delays, or new notices were added.

Verified: a failing host-publication regression before the fix; 220 local tests across 19 explicit files; queued node, renderer and CLI typechecks; all 22 pre-push checks; and Playwright on the hidden real app using a Codex stand-in. The pinned-home 87-frame DOM trace has no strip mounts or composer movement during both quick commands (29 full-app compositor frames), and a screenshot plus backing state show the survivor during the next running turn. Before/after frames are embedded in the PR body.

Deferred: a very old server can temporarily hide an earlier command during an active turn if its tool row is outside the loaded conversation page and the server provides no command creation times. No authenticated Codex run, original provider event trace, live Windows/Linux/SSH UI run, or independent reviewer result is claimed. The later post-completion UI frame is also after the next turn ended; the host regression verifies removal at the command-completion publication.

CI before readiness on head 3cb6b7e8512093a523054ad4d259b10ed5f5a678: all 18 executed checks passed, including all ten unit shards, Linux and Windows packaging, relay integration, static analysis/typechecks, repository guards and test-assignment validation, plus the supplementary verification and test-file checks. Eighteen conditional checks were skipped and are not counted as passes.

CI caught two omissions belonging to this PR: the new SQLite-backed regression was not registered in the Node project, and the existing 448-command retention fixture never sent turn-end events to the tracker. Both are corrected; the retention fixture preserves its output and memory-budget assertions and now verifies raw retention before each thread's promotion. The earlier Windows persistence stall failure is unrelated to the command change: the writer code was unchanged, and the repeated Windows job passed. Product source is unchanged from the pinned-home UI proof.

Readiness-triggered checks also finished successfully: headless-server persistence on Ubuntu passed, and the readiness guard reused the completed core checks. The final GitHub readback has no pending or failed checks, the PR is ready and open, and auto-merge is disabled. No merge was performed.

@brennanb2025
brennanb2025 marked this pull request as ready for review October 8, 2026 10:55
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: c77afa5b-bf13-4403-a2e2-881fe3c276b7
📥 Commits

Reviewing files that changed from the base of the PR and between b1cd858 and 3cb6b7e.

📒 Files selected for processing (18)
  • config/scripts/vitest-sqlite-runtime-files.mjs
  • src/main/codex/codex-background-command-tracker.test.ts
  • src/main/codex/codex-background-command-tracker.ts
  • src/main/codex/codex-background-task-tracker.test.ts
  • src/main/codex/codex-background-task-tracker.ts
  • src/main/codex/codex-child-work-evidence.test.ts
  • src/main/codex/codex-child-work-evidence.ts
  • src/main/codex/codex-default-mode-subagents.test.ts
  • src/main/codex/codex-persistent-command-retention.test.ts
  • src/main/runtime/structured-child-records-switch.test.ts
  • src/main/runtime/structured-foreground-command-strip.test.ts
  • src/renderer/src/components/native-chat/use-structured-agent-session-transport-state.ts
  • src/shared/agent-status-child-work-view.test.ts
  • src/shared/agent-status-child-work-view.ts
  • src/shared/structured-session-background-tasks-view.test.ts
  • src/shared/structured-session-background-tasks-view.ts
  • src/shared/structured-session-foreground-commands.test.ts
  • src/shared/structured-session-foreground-commands.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


📝 Walkthrough

Walkthrough

Codex command records now track their turn and whether they have been backgrounded. Commands become backgrounded when their turn ends, and child-work evidence reflects that status. The session derives foreground command IDs from roster and journal data, then filters those commands from background-task and child-work views. Tests cover command lifecycle, roster publication, and view filtering.

Priority: ➖ Normal

Merge Risk: ⚪ Minimal · up to 3cb6b

Foreground commands stay out of the background strip during their turn, while surviving commands become visible afterward. No identified issue currently blocks merging.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 18 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly states the primary user-facing change: preventing native chat jumping when Codex starts a foreground command.
Description check ✅ Passed The description is detailed and covers the user impact, implementation, rationale, visual proof, testing, compatibility, and checklist. It states that no linked issue exists, although the template req…
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
  • Autopilot · 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

Comment @coderabbitai help to get the list of available commands.

@brennanb2025
brennanb2025 merged commit a062abf into main Oct 8, 2026
61 checks passed
@brennanb2025
brennanb2025 deleted the brennanb2025/command-strip-flash branch October 11, 2026 21:46
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