Merge origin/main into etraut/tuiappserver-mcp-regression

This commit is contained in:
Eric Traut
2026-03-28 11:31:03 -06:00
1130 changed files with 389 additions and 3923 deletions
+21 -18
View File
@@ -29,14 +29,15 @@ Accept any of the following:
4. If `diagnose_ci_failure` is present, inspect failed run logs and classify the failure.
5. If the failure is likely caused by the current branch, patch code locally, commit, and push.
6. If `process_review_comment` is present, inspect surfaced review items and decide whether to address them.
7. If a review item is actionable and correct, patch code locally, commit, and push.
8. If the failure is likely flaky/unrelated and `retry_failed_checks` is present, rerun failed jobs with `--retry-failed-now`.
9. If both actionable review feedback and `retry_failed_checks` are present, prioritize review feedback first; a new commit will retrigger CI, so avoid rerunning flaky checks on the old SHA unless you intentionally defer the review change.
10. On every loop, verify mergeability / merge-conflict status (for example via `gh pr view`) in addition to CI and review state.
11. After any push or rerun action, immediately return to step 1 and continue polling on the updated SHA/state.
12. If you had been using `--watch` before pausing to patch/commit/push, relaunch `--watch` yourself in the same turn immediately after the push (do not wait for the user to re-invoke the skill).
13. Repeat polling until the PR is green + review-clean + mergeable, `stop_pr_closed` appears, or a user-help-required blocker is reached.
14. Maintain terminal/session ownership: while babysitting is active, keep consuming watcher output in the same turn; do not leave a detached `--watch` process running and then end the turn as if monitoring were complete.
7. If a review item is actionable and correct, patch code locally, commit, push, and then mark the associated review thread/comment as resolved once the fix is on GitHub.
8. If a review item from another author is non-actionable, already addressed, or not valid, post one reply on the comment/thread explaining that decision (for example answering the question or explaining why no change is needed). If the watcher later surfaces your own reply, treat that self-authored item as already handled and do not reply again.
9. If the failure is likely flaky/unrelated and `retry_failed_checks` is present, rerun failed jobs with `--retry-failed-now`.
10. If both actionable review feedback and `retry_failed_checks` are present, prioritize review feedback first; a new commit will retrigger CI, so avoid rerunning flaky checks on the old SHA unless you intentionally defer the review change.
11. On every loop, verify mergeability / merge-conflict status (for example via `gh pr view`) in addition to CI and review state.
12. After any push or rerun action, immediately return to step 1 and continue polling on the updated SHA/state.
13. If you had been using `--watch` before pausing to patch/commit/push, relaunch `--watch` yourself in the same turn immediately after the push (do not wait for the user to re-invoke the skill).
14. Repeat polling until the PR is green + review-clean + mergeable, `stop_pr_closed` appears, or a user-help-required blocker is reached.
15. Maintain terminal/session ownership: while babysitting is active, keep consuming watcher output in the same turn; do not leave a detached `--watch` process running and then end the turn as if monitoring were complete.
## Commands
@@ -94,10 +95,11 @@ When you agree with a comment and it is actionable:
1. Patch code locally.
2. Commit with `codex: address PR review feedback (#<n>)`.
3. Push to the PR head branch.
4. Resume watching on the new SHA immediately (do not stop after reporting the push).
5. If monitoring was running in `--watch` mode, restart `--watch` immediately after the push in the same turn; do not wait for the user to ask again.
4. After the push succeeds, mark the associated GitHub review thread/comment as resolved.
5. Resume watching on the new SHA immediately (do not stop after reporting the push).
6. If monitoring was running in `--watch` mode, restart `--watch` immediately after the push in the same turn; do not wait for the user to ask again.
If you disagree or the comment is non-actionable/already addressed, record it as handled by continuing the watcher loop (the script de-duplicates surfaced items via state after surfacing them).
If you disagree or the comment is non-actionable/already addressed, reply once directly on the GitHub comment/thread so the reviewer gets an explicit answer, then continue the watcher loop. If the watcher later surfaces your own reply because the authenticated operator is treated as a trusted review author, treat that self-authored item as already handled and do not reply again.
If a code review comment/thread is already marked as resolved in GitHub, treat it as non-actionable and safely ignore it unless new unresolved follow-up feedback appears.
## Git Safety Rules
@@ -124,13 +126,14 @@ Use this loop in a live Codex session:
3. First check whether the PR is now merged or otherwise closed; if so, report that terminal state and stop polling immediately.
4. Check CI summary, new review items, and mergeability/conflict status.
5. Diagnose CI failures and classify branch-related vs flaky/unrelated.
6. Process actionable review comments before flaky reruns when both are present; if a review fix requires a commit, push it and skip rerunning failed checks on the old SHA.
7. Retry failed checks only when `retry_failed_checks` is present and you are not about to replace the current SHA with a review/CI fix commit.
8. If you pushed a commit or triggered a rerun, report the action briefly and continue polling (do not stop).
9. After a review-fix push, proactively restart continuous monitoring (`--watch`) in the same turn unless a strict stop condition has already been reached.
10. If everything is passing, mergeable, not blocked on required review approval, and there are no unaddressed review items, report success and stop.
11. If blocked on a user-help-required issue (infra outage, exhausted flaky retries, unclear reviewer request, permissions), report the blocker and stop.
12. Otherwise sleep according to the polling cadence below and repeat.
6. For each surfaced review item from another author, either reply once with an explanation if it is non-actionable or patch/commit/push and then resolve it if it is actionable. If a later snapshot surfaces your own reply, treat it as informational and continue without responding again.
7. Process actionable review comments before flaky reruns when both are present; if a review fix requires a commit, push it and skip rerunning failed checks on the old SHA.
8. Retry failed checks only when `retry_failed_checks` is present and you are not about to replace the current SHA with a review/CI fix commit.
9. If you pushed a commit, resolved a review thread, replied to a review comment, or triggered a rerun, report the action briefly and continue polling (do not stop).
10. After a review-fix push, proactively restart continuous monitoring (`--watch`) in the same turn unless a strict stop condition has already been reached.
11. If everything is passing, mergeable, not blocked on required review approval, and there are no unaddressed review items, report success and stop.
12. If blocked on a user-help-required issue (infra outage, exhausted flaky retries, unclear reviewer request, permissions), report the blocker and stop.
13. Otherwise sleep according to the polling cadence below and repeat.
When the user explicitly asks to monitor/watch/babysit a PR, prefer `--watch` so polling continues autonomously in one command. Use repeated `--once` snapshots only for debugging, local testing, or when the user explicitly asks for a one-shot check.
Do not stop to ask the user whether to continue polling; continue autonomously until a strict stop condition is met or the user explicitly interrupts.
+4 -6
View File
@@ -35,9 +35,9 @@ In the codex-rs folder where the rust code lives:
- If a file exceeds roughly 800 LoC, add new functionality in a new module instead of extending
the existing file unless there is a strong documented reason not to.
- This rule applies especially to high-touch files that already attract unrelated changes, such
as `codex-rs/tui_app_server/src/app.rs`, `codex-rs/tui_app_server/src/bottom_pane/chat_composer.rs`,
`codex-rs/tui_app_server/src/bottom_pane/footer.rs`, `codex-rs/tui_app_server/src/chatwidget.rs`,
`codex-rs/tui_app_server/src/bottom_pane/mod.rs`, and similarly central orchestration modules.
as `codex-rs/tui/src/app.rs`, `codex-rs/tui/src/bottom_pane/chat_composer.rs`,
`codex-rs/tui/src/bottom_pane/footer.rs`, `codex-rs/tui/src/chatwidget.rs`,
`codex-rs/tui/src/bottom_pane/mod.rs`, and similarly central orchestration modules.
- When extracting code from a large module, move the related tests and module/type docs toward
the new implementation so the invariants stay close to the code that owns them.
- When running Rust commands (e.g. `just fix` or `cargo test`) be patient with the command and never try to kill them using the PID. Rust lock can make the execution slow, this is expected.
@@ -66,12 +66,10 @@ Likewise, when reviewing code, do not hesitate to push back on PRs that would un
## TUI style conventions
See `codex-rs/tui_app_server/styles.md`.
See `codex-rs/tui/styles.md`.
## TUI code conventions
- When a change lands in `codex-rs/tui` and `codex-rs/tui_app_server` has a parallel implementation of the same behavior, reflect the change in `codex-rs/tui_app_server` too unless there is a documented reason not to.
- Use concise styling helpers from ratatui’s Stylize trait.
- Basic spans: use "text".into()
- Styled spans: use "text".red(), "text".green(), "text".magenta(), "text".dim(), etc.
+2 -2
View File
@@ -49,7 +49,7 @@ members = [
"sandboxing",
"stdio-to-uds",
"otel",
"tui_app_server",
"tui",
"tools",
"v8-poc",
"utils/absolute-path",
@@ -149,7 +149,7 @@ codex-state = { path = "state" }
codex-stdio-to-uds = { path = "stdio-to-uds" }
codex-terminal-detection = { path = "terminal-detection" }
codex-tools = { path = "tools" }
codex-tui = { path = "tui_app_server" }
codex-tui = { path = "tui" }
codex-v8-poc = { path = "v8-poc" }
codex-utils-absolute-path = { path = "utils/absolute-path" }
codex-utils-approval-presets = { path = "utils/approval-presets" }
+6 -6
View File
@@ -24,10 +24,10 @@ use codex_execpolicy::ExecPolicyCheckCommand;
use codex_responses_api_proxy::Args as ResponsesApiProxyArgs;
use codex_state::StateRuntime;
use codex_state::state_db_path;
use codex_tui_app_server::AppExitInfo;
use codex_tui_app_server::Cli as TuiCli;
use codex_tui_app_server::ExitReason;
use codex_tui_app_server::update_action::UpdateAction;
use codex_tui::AppExitInfo;
use codex_tui::Cli as TuiCli;
use codex_tui::ExitReason;
use codex_tui::update_action::UpdateAction;
use codex_utils_cli::CliConfigOverrides;
use owo_colors::OwoColorize;
use std::io::IsTerminal;
@@ -1228,7 +1228,7 @@ async fn run_interactive_tui(
let normalized_remote = remote
.as_deref()
.map(codex_tui_app_server::normalize_remote_addr)
.map(codex_tui::normalize_remote_addr)
.transpose()
.map_err(std::io::Error::other)?;
if remote_auth_token_env.is_some() && normalized_remote.is_none() {
@@ -1241,7 +1241,7 @@ async fn run_interactive_tui(
.map(read_remote_auth_token_from_env_var)
.transpose()
.map_err(std::io::Error::other)?;
codex_tui_app_server::run_main(
codex_tui::run_main(
interactive,
arg0_paths,
codex_core::config_loader::LoaderOverrides::default(),
+5 -5
View File
@@ -931,7 +931,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
if page.composer.flush_paste_burst_if_due() { needs_redraw = true; }
if page.composer.is_in_paste_burst() {
let _ = frame_tx
.send(Instant::now() + codex_tui_app_server::ComposerInput::recommended_flush_delay());
.send(Instant::now() + codex_tui::ComposerInput::recommended_flush_delay());
}
}
// Keep spinner pulsing only while loading.
@@ -1492,7 +1492,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
_ => {
if page.submitting {
// Ignore input while submitting
} else if let codex_tui_app_server::ComposerAction::Submitted(text) =
} else if let codex_tui::ComposerAction::Submitted(text) =
page.composer.input(key)
{
// Submit only if we have an env id
@@ -1526,7 +1526,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
if page.composer.is_in_paste_burst() {
let _ = frame_tx.send(
Instant::now()
+ codex_tui_app_server::ComposerInput::recommended_flush_delay(),
+ codex_tui::ComposerInput::recommended_flush_delay(),
);
}
// Always schedule an immediate redraw for key edits in the composer.
@@ -2136,8 +2136,8 @@ mod tests {
use codex_cloud_tasks_client::TaskId;
use codex_cloud_tasks_client::TaskStatus;
use codex_cloud_tasks_client::TaskSummary;
use codex_tui_app_server::ComposerAction;
use codex_tui_app_server::ComposerInput;
use codex_tui::ComposerAction;
use codex_tui::ComposerInput;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyModifiers;
+1 -1
View File
@@ -1,4 +1,4 @@
use codex_tui_app_server::ComposerInput;
use codex_tui::ComposerInput;
pub struct NewTaskPage {
pub composer: ComposerInput,
+1 -1
View File
@@ -23,7 +23,7 @@ use crate::app::AttemptView;
use crate::util::format_relative_time_now;
use codex_cloud_tasks_client::AttemptStatus;
use codex_cloud_tasks_client::TaskStatus;
use codex_tui_app_server::render_markdown_text;
use codex_tui::render_markdown_text;
pub fn draw(frame: &mut Frame, app: &mut App) {
let area = frame.area();
@@ -1,8 +1,8 @@
load("//:defs.bzl", "codex_rust_crate")
codex_rust_crate(
name = "tui_app_server",
crate_name = "codex_tui_app_server",
name = "tui",
crate_name = "codex_tui",
compile_data = glob(
include = ["**"],
exclude = [
@@ -6,19 +6,15 @@ license.workspace = true
autobins = false
[[bin]]
name = "codex-tui-app-server"
name = "codex-tui"
path = "src/main.rs"
[[bin]]
name = "codex-tui"
path = "src/bin/codex-tui.rs"
[[bin]]
name = "md-events-app-server"
name = "md-events"
path = "src/bin/md-events.rs"
[lib]
name = "codex_tui_app_server"
name = "codex_tui"
path = "src/lib.rs"
[features]

Some files were not shown because too many files have changed in this diff Show More