diff --git a/.github/workflows/nori-release.yml b/.github/workflows/nori-release.yml index 1c9e72c07..73c592aab 100644 --- a/.github/workflows/nori-release.yml +++ b/.github/workflows/nori-release.yml @@ -357,7 +357,7 @@ jobs: - name: Build release binaries working-directory: codex-rs run: | - cargo build --release --target ${{ matrix.target }} -p codex-cli + cargo build --release --target ${{ matrix.target }} -p nori-cli # List built artifacts ls -la target/${{ matrix.target }}/release/ diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 3d2d01a1e..5cb2b6b84 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -126,7 +126,7 @@ jobs: run: | mkdir -p target/mock-acp-out # build mock-acp-agent to a known location for E2E tests cargo +nightly build -p mock-acp-agent --profile ci-test --target ${{ matrix.target }} --artifact-dir target/mock-acp-out -Z unstable-options - cargo build -p codex-cli --profile ci-test --target ${{ matrix.target }} + cargo build -p nori-cli --profile ci-test --target ${{ matrix.target }} cargo build -p codex-exec --profile ci-test --target ${{ matrix.target }} # separately needed because some tests call `CargoRun('codex-exec')` - name: cargo test nori env: @@ -134,8 +134,8 @@ jobs: run: | cargo test --profile ci-test --target ${{ matrix.target }} --package tui-pty-e2e cargo test --profile ci-test --target ${{ matrix.target }} --package codex-acp - cargo test --profile ci-test --target ${{ matrix.target }} --package codex-tui - cargo test --profile ci-test --target ${{ matrix.target }} --package codex-cli + cargo test --profile ci-test --target ${{ matrix.target }} --package nori-tui + cargo test --profile ci-test --target ${{ matrix.target }} --package nori-cli cargo test --profile ci-test --target ${{ matrix.target }} --package codex-protocol - name: cargo clippy run: cargo clippy --target ${{ matrix.target }} --all-features -- -D warnings diff --git a/AGENTS.md b/AGENTS.md index 566478f17..e90cbb9a3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -21,7 +21,7 @@ In the codex-rs folder where the rust code lives: Run `just fmt` (in `codex-rs` directory) automatically after making Rust code changes; do not ask for approval to run it. Before finalizing a change to `codex-rs`, run `just fix -p ` (in `codex-rs` directory) to fix any linter issues in the code. Prefer scoping with `-p` to avoid slow workspace‑wide Clippy builds; only run `just fix` without `-p` if you changed shared crates. Additionally, run the tests: -1. Run the test for the specific project that was changed. For example, if changes were made in `codex-rs/tui`, run `cargo test -p codex-tui`. +1. Run the test for the specific project that was changed. For example, if changes were made in `codex-rs/tui`, run `cargo test -p nori-tui`. 2. Once those pass, if any changes were made in common, core, or protocol, run the complete test suite with `cargo test --all-features`. When running interactively, ask the user before running `just fix` to finalize. `just fmt` does not require approval. project-specific or individual tests can be run without asking the user, but do ask the user before running the complete test suite. 3. If any changes were made in tui, cli, or acp, run the E2E test suite with `cargo test -p tui-pty-e2e`. @@ -65,13 +65,13 @@ See `codex-rs/tui/styles.md`. This repo uses snapshot tests (via `insta`), especially in `codex-rs/tui`, to validate rendered output. When UI or text output changes intentionally, update the snapshots as follows: - Run tests to generate any updated snapshots: - - `cargo test -p codex-tui` -- Check what’s pending: - - `cargo insta pending-snapshots -p codex-tui` + - `cargo test -p nori-tui` +- Check what's pending: + - `cargo insta pending-snapshots -p nori-tui` - Review changes by reading the generated `*.snap.new` files directly in the repo, or preview a specific file: - - `cargo insta show -p codex-tui path/to/file.snap.new` + - `cargo insta show -p nori-tui path/to/file.snap.new` - Only if you intend to accept all new snapshots in this crate, run: - - `cargo insta accept -p codex-tui` + - `cargo insta accept -p nori-tui` If you don’t have the tool: diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index 947d83d4b..3c737656c 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -1081,47 +1081,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "codex-cli" -version = "0.0.0" -dependencies = [ - "anyhow", - "assert_cmd", - "assert_matches", - "clap", - "clap_complete", - "codex-acp", - "codex-app-server", - "codex-app-server-protocol", - "codex-arg0", - "codex-chatgpt", - "codex-cloud-tasks", - "codex-common", - "codex-core", - "codex-exec", - "codex-execpolicy", - "codex-login", - "codex-mcp-server", - "codex-process-hardening", - "codex-protocol", - "codex-rmcp-client", - "codex-stdio-to-uds", - "codex-tui", - "codex-windows-sandbox", - "ctor 0.5.0", - "libc", - "owo-colors", - "predicates", - "pretty_assertions", - "regex-lite", - "serde_json", - "supports-color", - "tempfile", - "tokio", - "toml", - "tracing", -] - [[package]] name = "codex-client" version = "0.0.0" @@ -1152,8 +1111,8 @@ dependencies = [ "codex-common", "codex-core", "codex-login", - "codex-tui", "crossterm", + "nori-tui", "ratatui", "reqwest", "serde", @@ -1571,76 +1530,6 @@ dependencies = [ "uds_windows", ] -[[package]] -name = "codex-tui" -version = "0.0.0" -dependencies = [ - "anyhow", - "arboard", - "assert_matches", - "async-stream", - "base64", - "chrono", - "clap", - "codex-acp", - "codex-ansi-escape", - "codex-app-server-protocol", - "codex-arg0", - "codex-backend-client", - "codex-common", - "codex-core", - "codex-feedback", - "codex-file-search", - "codex-login", - "codex-protocol", - "codex-utils-pty", - "codex-windows-sandbox", - "color-eyre", - "crossterm", - "derive_more 2.0.1", - "diffy", - "dirs", - "dunce", - "image", - "insta", - "itertools 0.14.0", - "lazy_static", - "libc", - "mcp-types", - "nori-installed", - "opentelemetry-appender-tracing", - "pathdiff", - "pretty_assertions", - "pulldown-cmark", - "rand 0.9.2", - "ratatui", - "ratatui-macros", - "regex-lite", - "reqwest", - "serde", - "serde_json", - "serial_test", - "shlex", - "strum 0.27.2", - "strum_macros 0.27.2", - "supports-color", - "tempfile", - "textwrap 0.16.2", - "tokio", - "tokio-stream", - "toml", - "tracing", - "tracing-appender", - "tracing-subscriber", - "tree-sitter-bash", - "tree-sitter-highlight", - "unicode-segmentation", - "unicode-width 0.2.1", - "url", - "vt100 0.16.2", - "which", -] - [[package]] name = "codex-utils-cache" version = "0.0.0" @@ -4057,6 +3946,47 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nori-cli" +version = "0.0.0" +dependencies = [ + "anyhow", + "assert_cmd", + "assert_matches", + "clap", + "clap_complete", + "codex-acp", + "codex-app-server", + "codex-app-server-protocol", + "codex-arg0", + "codex-chatgpt", + "codex-cloud-tasks", + "codex-common", + "codex-core", + "codex-exec", + "codex-execpolicy", + "codex-login", + "codex-mcp-server", + "codex-process-hardening", + "codex-protocol", + "codex-rmcp-client", + "codex-stdio-to-uds", + "codex-windows-sandbox", + "ctor 0.5.0", + "libc", + "nori-tui", + "owo-colors", + "predicates", + "pretty_assertions", + "regex-lite", + "serde_json", + "supports-color", + "tempfile", + "tokio", + "toml", + "tracing", +] + [[package]] name = "nori-installed" version = "0.0.0" @@ -4076,6 +4006,76 @@ dependencies = [ "windows-sys 0.59.0", ] +[[package]] +name = "nori-tui" +version = "0.0.0" +dependencies = [ + "anyhow", + "arboard", + "assert_matches", + "async-stream", + "base64", + "chrono", + "clap", + "codex-acp", + "codex-ansi-escape", + "codex-app-server-protocol", + "codex-arg0", + "codex-backend-client", + "codex-common", + "codex-core", + "codex-feedback", + "codex-file-search", + "codex-login", + "codex-protocol", + "codex-utils-pty", + "codex-windows-sandbox", + "color-eyre", + "crossterm", + "derive_more 2.0.1", + "diffy", + "dirs", + "dunce", + "image", + "insta", + "itertools 0.14.0", + "lazy_static", + "libc", + "mcp-types", + "nori-installed", + "opentelemetry-appender-tracing", + "pathdiff", + "pretty_assertions", + "pulldown-cmark", + "rand 0.9.2", + "ratatui", + "ratatui-macros", + "regex-lite", + "reqwest", + "serde", + "serde_json", + "serial_test", + "shlex", + "strum 0.27.2", + "strum_macros 0.27.2", + "supports-color", + "tempfile", + "textwrap 0.16.2", + "tokio", + "tokio-stream", + "toml", + "tracing", + "tracing-appender", + "tracing-subscriber", + "tree-sitter-bash", + "tree-sitter-highlight", + "unicode-segmentation", + "unicode-width 0.2.1", + "url", + "vt100 0.16.2", + "which", +] + [[package]] name = "normalize-line-endings" version = "0.3.0" diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index 9b629da66..324244693 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -87,7 +87,7 @@ codex-process-hardening = { path = "process-hardening" } codex-protocol = { path = "protocol" } codex-rmcp-client = { path = "rmcp-client" } codex-stdio-to-uds = { path = "stdio-to-uds" } -codex-tui = { path = "tui" } +nori-tui = { path = "tui" } codex-utils-cache = { path = "utils/cache" } codex-utils-image = { path = "utils/image" } codex-utils-json-to-toml = { path = "utils/json-to-toml" } diff --git a/codex-rs/acp/src/tracing_setup.rs b/codex-rs/acp/src/tracing_setup.rs index feac1a3d4..7bbdf7f4d 100644 --- a/codex-rs/acp/src/tracing_setup.rs +++ b/codex-rs/acp/src/tracing_setup.rs @@ -16,14 +16,14 @@ use tracing_subscriber::util::SubscriberInitExt; /// Returns the default log level based on build configuration. /// /// - Debug builds: `debug` level (captures debug, info, warn, error) -/// - Release builds: `warn,codex_tui=info,acp=info` (warn default, info for TUI/ACP) +/// - Release builds: `warn,nori_tui=info,acp=info` (warn default, info for TUI/ACP) /// /// Note: This can be overridden by setting the RUST_LOG environment variable. fn default_log_level() -> &'static str { if cfg!(debug_assertions) { "debug" } else { - "warn,codex_tui=info,acp=info" + "warn,nori_tui=info,acp=info" } } @@ -177,7 +177,7 @@ mod tests { /// Test that default_log_level returns the correct value based on build type. /// /// - Debug builds: "debug" (all debug and above) - /// - Release builds: "warn,codex_tui=info,acp=info" (warn default, but info for TUI/ACP) + /// - Release builds: "warn,nori_tui=info,acp=info" (warn default, but info for TUI/ACP) #[test] fn test_default_log_level_returns_expected_value() { let level = default_log_level(); @@ -193,8 +193,8 @@ mod tests { #[cfg(not(debug_assertions))] { assert_eq!( - level, "warn,codex_tui=info,acp=info", - "Release builds should default to 'warn,codex_tui=info,acp=info'" + level, "warn,nori_tui=info,acp=info", + "Release builds should default to 'warn,nori_tui=info,acp=info'" ); } } diff --git a/codex-rs/backend-client/src/client.rs b/codex-rs/backend-client/src/client.rs index 0fb627ef0..d6983e451 100644 --- a/codex-rs/backend-client/src/client.rs +++ b/codex-rs/backend-client/src/client.rs @@ -110,7 +110,7 @@ impl Client { if let Some(ua) = &self.user_agent { h.insert(USER_AGENT, ua.clone()); } else { - h.insert(USER_AGENT, HeaderValue::from_static("codex-cli")); + h.insert(USER_AGENT, HeaderValue::from_static("nori-cli")); } if let Some(token) = &self.bearer_token { let value = format!("Bearer {token}"); diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index a64f17ea0..61d876090 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "codex-cli" +name = "nori-cli" version.workspace = true edition.workspace = true license.workspace = true @@ -9,7 +9,7 @@ name = "nori" path = "src/main.rs" [lib] -name = "codex_cli" +name = "nori_cli" path = "src/lib.rs" [lints] @@ -34,7 +34,7 @@ full = [ # Codex-only features (exec, resume, features subcommands) - propagate to TUI # Disabled by default for Nori builds; enabled by 'full' for upstream compatibility -codex-features = ["codex-tui/codex-features"] +codex-features = ["nori-tui/codex-features"] # App server functionality app-server = ["dep:codex-app-server"] @@ -43,20 +43,20 @@ app-server = ["dep:codex-app-server"] cloud-tasks = ["dep:codex-cloud-tasks"] # Login/logout commands - propagate to TUI -login = ["dep:codex-login", "codex-tui/login"] +login = ["dep:codex-login", "nori-tui/login"] # Feedback feature - propagate to TUI (legacy OpenAI Sentry feedback) # Future Nori feedback: https://github.com/tilework-tech/nori-cli/issues -feedback = ["codex-tui/feedback"] +feedback = ["nori-tui/feedback"] # Backend client feature - propagate to TUI -backend-client = ["codex-tui/backend-client"] +backend-client = ["nori-tui/backend-client"] # Upstream updates feature - propagate to TUI -upstream-updates = ["codex-tui/upstream-updates"] +upstream-updates = ["nori-tui/upstream-updates"] # OSS providers (Ollama, LM Studio) - propagate to TUI and codex-common -oss-providers = ["codex-tui/oss-providers", "codex-common/oss-providers"] +oss-providers = ["nori-tui/oss-providers", "codex-common/oss-providers"] # MCP server functionality mcp-server = ["dep:codex-mcp-server", "dep:codex-rmcp-client"] @@ -84,7 +84,7 @@ codex-process-hardening = { workspace = true } codex-protocol = { workspace = true } codex-rmcp-client = { workspace = true, optional = true } codex-stdio-to-uds = { workspace = true } -codex-tui = { workspace = true } +nori-tui = { workspace = true } ctor = { workspace = true } libc = { workspace = true } owo-colors = { workspace = true } diff --git a/codex-rs/cli/docs.md b/codex-rs/cli/docs.md index 0e90f9f55..434ced7a6 100644 --- a/codex-rs/cli/docs.md +++ b/codex-rs/cli/docs.md @@ -4,13 +4,13 @@ Path: @/codex-rs/cli ### Overview -The `codex-cli` crate is the main multitool binary that provides the `nori` command. It serves as the central dispatcher routing to different modes: interactive TUI, headless exec, MCP server, app server, login management, and sandbox debugging tools. The crate handles CLI argument parsing, subcommand routing, and cross-cutting concerns like feature toggles. +The `nori-cli` crate is the main multitool binary that provides the `nori` command. It serves as the central dispatcher routing to different modes: interactive TUI, headless exec, MCP server, app server, login management, and sandbox debugging tools. The crate handles CLI argument parsing, subcommand routing, and cross-cutting concerns like feature toggles. ### How it fits into the larger codebase This crate is the primary entry point that ties together all other crates: -- **Always included:** `codex-tui`, `codex-acp`, `codex-core` (minimal build) +- **Always included:** `nori-tui`, `codex-acp`, `codex-core` (minimal build) - **Optional via features:** `codex-exec`, `codex-mcp-server`, `codex-app-server`, `codex-cloud-tasks`, `codex-login`, `codex-chatgpt` - **Uses** `codex-arg0` for arg0-based dispatch (Linux sandbox embedding) @@ -22,7 +22,7 @@ This crate is the primary entry point that ties together all other crates: ```rust match subcommand { - None => codex_tui::run_main(...), // Interactive + None => nori_tui::run_main(...), // Interactive Some(Subcommand::Exec(cli)) => codex_exec::run_main(...), Some(Subcommand::McpServer) => codex_mcp_server::run_main(...), Some(Subcommand::Login(cli)) => run_login_*(...), @@ -97,32 +97,32 @@ The CLI uses Cargo features to enable optional functionality. By default (`defau | `full` | All features | Complete legacy binary | | `app-server` | `codex-app-server` | `app-server` subcommand | | `cloud-tasks` | `codex-cloud-tasks` | `cloud` subcommand | -| `login` | `codex-login`, `codex-tui/login` | `login`/`logout` subcommands + TUI login | -| `feedback` | `codex-tui/feedback` | Sentry feedback in TUI | -| `backend-client` | `codex-tui/backend-client` | Cloud tasks backend client | -| `upstream-updates` | `codex-tui/upstream-updates` | OpenAI update mechanism (vs Nori's) | +| `login` | `codex-login`, `nori-tui/login` | `login`/`logout` subcommands + TUI login | +| `feedback` | `nori-tui/feedback` | Sentry feedback in TUI | +| `backend-client` | `nori-tui/backend-client` | Cloud tasks backend client | +| `upstream-updates` | `nori-tui/upstream-updates` | OpenAI update mechanism (vs Nori's) | | `mcp-server` | `codex-mcp-server`, `codex-rmcp-client` | `mcp`, `mcp-server` subcommands | | `chatgpt` | `codex-chatgpt` | `apply` subcommand | -| `oss-providers` | `codex-tui/oss-providers`, `codex-common/oss-providers` | Ollama/LM Studio local model support | -| `codex-features` | `codex-tui/codex-features` | `exec`, `resume`, `features` subcommands + power-user CLI flags + TUI `/undo`, `/compact`, `/review` | +| `oss-providers` | `nori-tui/oss-providers`, `codex-common/oss-providers` | Ollama/LM Studio local model support | +| `codex-features` | `nori-tui/codex-features` | `exec`, `resume`, `features` subcommands + power-user CLI flags + TUI `/undo`, `/compact`, `/review` | **Feature Propagation to TUI:** Several CLI features propagate to the TUI crate for coordinated behavior: -- `login` -> `codex-tui/login`: Enables login screens and `/login` command in TUI -- `feedback` -> `codex-tui/feedback`: Enables Sentry feedback and `/feedback` command -- `backend-client` -> `codex-tui/backend-client`: Enables cloud tasks backend -- `upstream-updates` -> `codex-tui/upstream-updates`: Uses OpenAI update system instead of Nori's -- `oss-providers` -> `codex-tui/oss-providers` -> `codex-common/oss-providers`: Enables Ollama/LM Studio local model support -- `codex-features` -> `codex-tui/codex-features`: Enables `/undo`, `/compact`, `/review` commands in TUI + power-user CLI flags +- `login` -> `nori-tui/login`: Enables login screens and `/login` command in TUI +- `feedback` -> `nori-tui/feedback`: Enables Sentry feedback and `/feedback` command +- `backend-client` -> `nori-tui/backend-client`: Enables cloud tasks backend +- `upstream-updates` -> `nori-tui/upstream-updates`: Uses OpenAI update system instead of Nori's +- `oss-providers` -> `nori-tui/oss-providers` -> `codex-common/oss-providers`: Enables Ollama/LM Studio local model support +- `codex-features` -> `nori-tui/codex-features`: Enables `/undo`, `/compact`, `/review` commands in TUI + power-user CLI flags Without these features, the TUI uses Nori-specific alternatives (e.g., GitHub Discussions for feedback, GitHub releases for updates). For OSS providers, the `codex-common` crate provides stub implementations that return `None` or errors when the feature is disabled. Build examples: ```bash -cargo build -p codex-cli # Minimal (TUI + ACP only, no power-user flags) -cargo build -p codex-cli --features full # All functionality (OpenAI-compatible) -cargo build -p codex-cli --features login,mcp-server # Selective +cargo build -p nori-cli # Minimal (TUI + ACP only, no power-user flags) +cargo build -p nori-cli --features full # All functionality (OpenAI-compatible) +cargo build -p nori-cli --features login,mcp-server # Selective ``` Feature-gated code uses `#[cfg(feature = "...")]` on imports, enum variants, match arms, and struct definitions in `main.rs`. Integration tests that require specific features use `required-features` in `Cargo.toml` (e.g., MCP tests require `mcp-server`). diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 66d05db50..0956324b8 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -6,31 +6,31 @@ use codex_arg0::arg0_dispatch_or_else; use codex_chatgpt::apply_command::ApplyCommand; #[cfg(feature = "chatgpt")] use codex_chatgpt::apply_command::run_apply_command; -use codex_cli::LandlockCommand; -use codex_cli::SeatbeltCommand; -use codex_cli::WindowsCommand; -#[cfg(feature = "login")] -use codex_cli::login::read_api_key_from_stdin; -#[cfg(feature = "login")] -use codex_cli::login::run_login_status; -#[cfg(feature = "login")] -use codex_cli::login::run_login_with_api_key; -#[cfg(feature = "login")] -use codex_cli::login::run_login_with_chatgpt; -#[cfg(feature = "login")] -use codex_cli::login::run_login_with_device_code; -#[cfg(feature = "login")] -use codex_cli::login::run_logout; #[cfg(feature = "cloud-tasks")] use codex_cloud_tasks::Cli as CloudTasksCli; use codex_common::CliConfigOverrides; #[cfg(feature = "codex-features")] use codex_exec::Cli as ExecCli; use codex_execpolicy::ExecPolicyCheckCommand; +use nori_cli::LandlockCommand; +use nori_cli::SeatbeltCommand; +use nori_cli::WindowsCommand; +#[cfg(feature = "login")] +use nori_cli::login::read_api_key_from_stdin; +#[cfg(feature = "login")] +use nori_cli::login::run_login_status; +#[cfg(feature = "login")] +use nori_cli::login::run_login_with_api_key; +#[cfg(feature = "login")] +use nori_cli::login::run_login_with_chatgpt; +#[cfg(feature = "login")] +use nori_cli::login::run_login_with_device_code; +#[cfg(feature = "login")] +use nori_cli::login::run_logout; -use codex_tui::AppExitInfo; -use codex_tui::Cli as TuiCli; -use codex_tui::update_action::UpdateAction; +use nori_tui::AppExitInfo; +use nori_tui::Cli as TuiCli; +use nori_tui::update_action::UpdateAction; use owo_colors::OwoColorize; use std::path::PathBuf; use supports_color::Stream; @@ -498,7 +498,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() &mut interactive.config_overrides, root_config_overrides.clone(), ); - let exit_info = codex_tui::run_main(interactive, codex_linux_sandbox_exe).await?; + let exit_info = nori_tui::run_main(interactive, codex_linux_sandbox_exe).await?; handle_app_exit(exit_info)?; } #[cfg(feature = "codex-features")] @@ -549,7 +549,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() all, config_overrides, ); - let exit_info = codex_tui::run_main(interactive, codex_linux_sandbox_exe).await?; + let exit_info = nori_tui::run_main(interactive, codex_linux_sandbox_exe).await?; handle_app_exit(exit_info)?; } #[cfg(feature = "login")] @@ -606,7 +606,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() &mut seatbelt_cli.config_overrides, root_config_overrides.clone(), ); - codex_cli::debug_sandbox::run_command_under_seatbelt( + nori_cli::debug_sandbox::run_command_under_seatbelt( seatbelt_cli, codex_linux_sandbox_exe, ) @@ -617,7 +617,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() &mut landlock_cli.config_overrides, root_config_overrides.clone(), ); - codex_cli::debug_sandbox::run_command_under_landlock( + nori_cli::debug_sandbox::run_command_under_landlock( landlock_cli, codex_linux_sandbox_exe, ) @@ -628,7 +628,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() &mut windows_cli.config_overrides, root_config_overrides.clone(), ); - codex_cli::debug_sandbox::run_command_under_windows( + nori_cli::debug_sandbox::run_command_under_windows( windows_cli, codex_linux_sandbox_exe, ) diff --git a/codex-rs/cloud-tasks/Cargo.toml b/codex-rs/cloud-tasks/Cargo.toml index c9edf5b4a..9d4b7a9db 100644 --- a/codex-rs/cloud-tasks/Cargo.toml +++ b/codex-rs/cloud-tasks/Cargo.toml @@ -23,7 +23,7 @@ codex-cloud-tasks-client = { path = "../cloud-tasks-client", features = [ codex-common = { path = "../common", features = ["cli"] } codex-core = { path = "../core" } codex-login = { path = "../login" } -codex-tui = { path = "../tui" } +nori-tui = { path = "../tui" } crossterm = { workspace = true, features = ["event-stream"] } ratatui = { workspace = true } reqwest = { workspace = true, features = ["json"] } diff --git a/codex-rs/cloud-tasks/src/lib.rs b/codex-rs/cloud-tasks/src/lib.rs index 6fc721404..98c1ccbe3 100644 --- a/codex-rs/cloud-tasks/src/lib.rs +++ b/codex-rs/cloud-tasks/src/lib.rs @@ -509,7 +509,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option) -> an if let Some(page) = app.new_task.as_mut() { 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::ComposerInput::recommended_flush_delay()); + let _ = frame_tx.send(Instant::now() + nori_tui::ComposerInput::recommended_flush_delay()); } } // Keep spinner pulsing only while loading. @@ -1070,7 +1070,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option) -> an _ => { if page.submitting { // Ignore input while submitting - } else if let codex_tui::ComposerAction::Submitted(text) = page.composer.input(key) { + } else if let nori_tui::ComposerAction::Submitted(text) = page.composer.input(key) { // Submit only if we have an env id if let Some(env) = page.env_id.clone() { append_error_log(format!( @@ -1110,7 +1110,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option) -> an needs_redraw = true; // If paste‑burst is active, schedule a micro‑flush frame. if page.composer.is_in_paste_burst() { - let _ = frame_tx.send(Instant::now() + codex_tui::ComposerInput::recommended_flush_delay()); + let _ = frame_tx.send(Instant::now() + nori_tui::ComposerInput::recommended_flush_delay()); } // Always schedule an immediate redraw for key edits in the composer. let _ = frame_tx.send(Instant::now()); @@ -1712,11 +1712,11 @@ fn pretty_lines_from_error(raw: &str) -> Vec { #[cfg(test)] mod tests { - use codex_tui::ComposerAction; - use codex_tui::ComposerInput; use crossterm::event::KeyCode; use crossterm::event::KeyEvent; use crossterm::event::KeyModifiers; + use nori_tui::ComposerAction; + use nori_tui::ComposerInput; use ratatui::buffer::Buffer; use ratatui::layout::Rect; diff --git a/codex-rs/cloud-tasks/src/new_task.rs b/codex-rs/cloud-tasks/src/new_task.rs index 162fd3bb3..e76d4bd65 100644 --- a/codex-rs/cloud-tasks/src/new_task.rs +++ b/codex-rs/cloud-tasks/src/new_task.rs @@ -1,4 +1,4 @@ -use codex_tui::ComposerInput; +use nori_tui::ComposerInput; pub struct NewTaskPage { pub composer: ComposerInput, diff --git a/codex-rs/cloud-tasks/src/ui.rs b/codex-rs/cloud-tasks/src/ui.rs index e3a97aeb3..375732925 100644 --- a/codex-rs/cloud-tasks/src/ui.rs +++ b/codex-rs/cloud-tasks/src/ui.rs @@ -24,7 +24,7 @@ use chrono::Local; use chrono::Utc; use codex_cloud_tasks_client::AttemptStatus; use codex_cloud_tasks_client::TaskStatus; -use codex_tui::render_markdown_text; +use nori_tui::render_markdown_text; pub fn draw(frame: &mut Frame, app: &mut App) { let area = frame.area(); diff --git a/codex-rs/cloud-tasks/src/util.rs b/codex-rs/cloud-tasks/src/util.rs index 1c690b26c..f79d8bdaa 100644 --- a/codex-rs/cloud-tasks/src/util.rs +++ b/codex-rs/cloud-tasks/src/util.rs @@ -83,7 +83,7 @@ pub async fn build_chatgpt_headers() -> HeaderMap { let mut headers = HeaderMap::new(); headers.insert( USER_AGENT, - HeaderValue::from_str(&ua).unwrap_or(HeaderValue::from_static("codex-cli")), + HeaderValue::from_str(&ua).unwrap_or(HeaderValue::from_static("nori-cli")), ); if let Some(am) = load_auth_manager().await && let Some(auth) = am.auth() diff --git a/codex-rs/protocol/README.md b/codex-rs/protocol/README.md index 7120d9f3b..36d04ed1e 100644 --- a/codex-rs/protocol/README.md +++ b/codex-rs/protocol/README.md @@ -1,6 +1,6 @@ # codex-protocol -This crate defines the "types" for the protocol used by Codex CLI, which includes both "internal types" for communication between `codex-core` and `codex-tui`, as well as "external types" used with `codex app-server`. +This crate defines the "types" for the protocol used by Codex CLI, which includes both "internal types" for communication between `codex-core` and `nori-tui`, as well as "external types" used with `codex app-server`. This crate should have minimal dependencies. diff --git a/codex-rs/rmcp-client/src/oauth.rs b/codex-rs/rmcp-client/src/oauth.rs index f8eafaf23..f70360eac 100644 --- a/codex-rs/rmcp-client/src/oauth.rs +++ b/codex-rs/rmcp-client/src/oauth.rs @@ -49,7 +49,7 @@ use tokio::sync::Mutex; use crate::find_codex_home::find_codex_home; -const KEYRING_SERVICE: &str = "Codex MCP Credentials"; +const KEYRING_SERVICE: &str = "Nori MCP Credentials"; const REFRESH_SKEW_MILLIS: u64 = 30_000; #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] diff --git a/codex-rs/tui-pty-e2e/src/lib.rs b/codex-rs/tui-pty-e2e/src/lib.rs index 8e7f93ba6..8a8e5387b 100644 --- a/codex-rs/tui-pty-e2e/src/lib.rs +++ b/codex-rs/tui-pty-e2e/src/lib.rs @@ -352,7 +352,7 @@ name = "Mock ACP provider for tests" // Enable debug logging for codex_acp to capture timing information cmd.env( "RUST_LOG", - "codex_core=info,codex_tui=info,codex_rmcp_client=info,codex_acp=debug", + "codex_core=info,nori_tui=info,codex_rmcp_client=info,codex_acp=debug", ); let _child = pair.slave.spawn_command(cmd)?; diff --git a/codex-rs/tui/Cargo.toml b/codex-rs/tui/Cargo.toml index 183cdfe1a..0c7b5146e 100644 --- a/codex-rs/tui/Cargo.toml +++ b/codex-rs/tui/Cargo.toml @@ -1,15 +1,15 @@ [package] -name = "codex-tui" +name = "nori-tui" version.workspace = true edition.workspace = true license.workspace = true [[bin]] -name = "codex-tui" +name = "nori-tui" path = "src/main.rs" [lib] -name = "codex_tui" +name = "nori_tui" path = "src/lib.rs" [features] diff --git a/codex-rs/tui/docs.md b/codex-rs/tui/docs.md index b539cfc64..56cb582c6 100644 --- a/codex-rs/tui/docs.md +++ b/codex-rs/tui/docs.md @@ -4,7 +4,7 @@ Path: @/codex-rs/tui ### Overview -The `codex-tui` crate provides the interactive terminal user interface for Codex, built with the Ratatui framework. It handles the fullscreen TUI experience including chat display, input composition, onboarding flows, session management, and real-time streaming of model responses with markdown rendering. +The `nori-tui` crate provides the interactive terminal user interface for Codex, built with the Ratatui framework. It handles the fullscreen TUI experience including chat display, input composition, onboarding flows, session management, and real-time streaming of model responses with markdown rendering. ### How it fits into the larger codebase @@ -16,7 +16,7 @@ TUI is one of the primary entry points, invoked when running `nori` without a su - **Uses** `codex-protocol` types for events and messages - **Optionally integrates** `codex-feedback`, `codex-login`, `codex-backend-client` via feature flags -The `cli/` crate's `main.rs` dispatches to `codex_tui::run_main()` for interactive mode. Feature flags propagate from CLI to TUI for coordinated modular builds. +The `cli/` crate's `main.rs` dispatches to `nori_tui::run_main()` for interactive mode. Feature flags propagate from CLI to TUI for coordinated modular builds. ### Core Implementation diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap new file mode 100644 index 000000000..adb764b6c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__backspace_after_pastes.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› [Pasted Content 1002 chars][Pasted Content 1004 chars] " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__empty.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__empty.snap new file mode 100644 index 000000000..3bdd7260f --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__empty.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" " +" ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap new file mode 100644 index 000000000..49ffb0d4c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_interrupt.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" ctrl + c again to interrupt " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap new file mode 100644 index 000000000..7ecc5bba7 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_quit.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" ctrl + c again to quit " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap new file mode 100644 index 000000000..9cad17b86 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_ctrl_c_then_esc_hint.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" esc esc to edit previous message " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap new file mode 100644 index 000000000..9cad17b86 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_esc_hint_from_overlay.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" esc esc to edit previous message " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_shortcut_overlay.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_shortcut_overlay.snap new file mode 100644 index 000000000..3b6782d06 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__footer_mode_shortcut_overlay.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› Ask Codex to do anything " +" " +" " +" " +" " +" " +" " +" / for commands shift + enter for newline " +" @ for file paths ctrl + v to paste images " +" esc again to edit previous message ctrl + c to exit " +" ctrl + t to view transcript " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__large.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__large.snap new file mode 100644 index 000000000..4237a17ae --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__large.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› [Pasted Content 1005 chars] " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap new file mode 100644 index 000000000..3edfc2ce2 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__multiple_pastes.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› [Pasted Content 1003 chars][Pasted Content 1007 chars] another short paste " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__slash_popup_mo.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__slash_popup_mo.snap new file mode 100644 index 000000000..661e82e3a --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__slash_popup_mo.snap @@ -0,0 +1,9 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› /mo " +" " +" /model choose what model and reasoning effort to use " +" /mention mention a file " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__small.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__small.snap new file mode 100644 index 000000000..402740b8f --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__chat_composer__tests__small.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/bottom_pane/chat_composer.rs +expression: terminal.backend() +--- +" " +"› short " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap new file mode 100644 index 000000000..31a1b743b --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_idle.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ctrl + c again to quit " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap new file mode 100644 index 000000000..9979372a1 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_ctrl_c_quit_running.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ctrl + c again to interrupt " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap new file mode 100644 index 000000000..b2333b025 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_esc_hint_idle.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" esc esc to edit previous message " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap new file mode 100644 index 000000000..21a8f4ebd --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_default.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_shift_and_esc.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_shift_and_esc.snap new file mode 100644 index 000000000..264515a6c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_shortcuts_shift_and_esc.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" / for commands shift + enter for newline " +" @ for file paths ctrl + v to paste images " +" esc again to edit previous message ctrl + c to exit " +" ctrl + t to view transcript " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_full_nori_info.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_full_nori_info.snap new file mode 100644 index 000000000..36ee7e573 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_full_nori_info.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ⎇ feature/test · Skillset: clifford · Skillsets v19.1.1 · +10 -3 · ? for short" diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_no_nori.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_no_nori.snap new file mode 100644 index 000000000..21a8f4ebd --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_no_nori.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_only_git.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_only_git.snap new file mode 100644 index 000000000..230da49a1 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_only_git.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ⎇ main · +5 -2 · ? for shortcuts " diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_worktree_orange.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_worktree_orange.snap new file mode 100644 index 000000000..d8dc02cc7 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__footer__tests__footer_with_worktree_orange.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/bottom_pane/footer.rs +expression: terminal.backend() +--- +" ⎇ feature/worktree-branch · Skillset: clifford · Skillsets v19.1.1 · +5 -2 · ?" diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_model_picker_width_80.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_model_picker_width_80.snap new file mode 100644 index 000000000..be81978c8 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_model_picker_width_80.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/list_selection_view.rs +expression: "render_lines_with_width(&view, 80)" +--- + + Select Model and Effort + +› 1. gpt-5.1-codex (current) Optimized for Codex. Balance of reasoning + quality and coding ability. + 2. gpt-5.1-codex-mini Optimized for Codex. Cheaper, faster, but less + capable. + 3. gpt-4.1-codex Legacy model. Use when you need compatibility + with older automations. diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_narrow_width_preserves_rows.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_narrow_width_preserves_rows.snap new file mode 100644 index 000000000..3ce6a3c45 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_narrow_width_preserves_rows.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/bottom_pane/list_selection_view.rs +expression: "render_lines_with_width(&view, 24)" +--- + + Debug + +› 1. Item 1 + xxxxxxxxx + x + 2. Item 2 + xxxxxxxxx + x + 3. Item 3 + xxxxxxxxx + x diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_with_subtitle.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_with_subtitle.snap new file mode 100644 index 000000000..382542174 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_with_subtitle.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/bottom_pane/list_selection_view.rs +expression: render_lines(&view) +--- + + Select Approval Mode + Switch between Codex approval presets + +› 1. Read Only (current) Codex can read files + 2. Full Access Codex can edit files + + ↑/k ↓/j to navigate, enter to confirm, esc to diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_without_subtitle.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_without_subtitle.snap new file mode 100644 index 000000000..74073a47f --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__list_selection_view__tests__list_selection_spacing_without_subtitle.snap @@ -0,0 +1,11 @@ +--- +source: tui/src/bottom_pane/list_selection_view.rs +expression: render_lines(&view) +--- + + Select Approval Mode + +› 1. Read Only (current) Codex can read files + 2. Full Access Codex can edit files + + ↑/k ↓/j to navigate, enter to confirm, esc to diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_many_line_message.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_many_line_message.snap new file mode 100644 index 000000000..d2afbf7db --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_many_line_message.snap @@ -0,0 +1,27 @@ +--- +source: tui/src/bottom_pane/queued_user_messages.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 40, height: 5 }, + content: [ + " ↳ This is ", + " a message ", + " with many ", + " … ", + " ⌥ + ↑ edit ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 11, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 4, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 13, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 4, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 13, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 5, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 14, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + ] +} diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_more_than_three_messages.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_more_than_three_messages.snap new file mode 100644 index 000000000..9d7527d16 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_more_than_three_messages.snap @@ -0,0 +1,30 @@ +--- +source: tui/src/bottom_pane/queued_user_messages.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 40, height: 5 }, + content: [ + " ↳ Hello, world! ", + " ↳ This is another message ", + " ↳ This is a third message ", + " ↳ This is a fourth message ", + " ⌥ + ↑ edit ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 17, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 27, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 27, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 28, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 14, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + ] +} diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_one_message.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_one_message.snap new file mode 100644 index 000000000..d47fa9786 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_one_message.snap @@ -0,0 +1,18 @@ +--- +source: tui/src/bottom_pane/queued_user_messages.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 40, height: 2 }, + content: [ + " ↳ Hello, world! ", + " ⌥ + ↑ edit ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 17, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 14, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + ] +} diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_two_messages.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_two_messages.snap new file mode 100644 index 000000000..1f020fec6 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_two_messages.snap @@ -0,0 +1,22 @@ +--- +source: tui/src/bottom_pane/queued_user_messages.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 40, height: 3 }, + content: [ + " ↳ Hello, world! ", + " ↳ This is another message ", + " ⌥ + ↑ edit ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 17, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 27, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 14, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + ] +} diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_wrapped_message.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_wrapped_message.snap new file mode 100644 index 000000000..4f2917a6c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__queued_user_messages__tests__render_wrapped_message.snap @@ -0,0 +1,25 @@ +--- +source: tui/src/bottom_pane/queued_user_messages.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 40, height: 4 }, + content: [ + " ↳ This is a longer message that should", + " be wrapped ", + " ↳ This is another message ", + " ⌥ + ↑ edit ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 0, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 4, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 14, y: 1, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 4, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: DIM | ITALIC, + x: 27, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 14, y: 3, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + ] +} diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__queued_messages_visible_when_status_hidden_snapshot.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__queued_messages_visible_when_status_hidden_snapshot.snap new file mode 100644 index 000000000..d9d61aefd --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__queued_messages_visible_when_status_hidden_snapshot.snap @@ -0,0 +1,11 @@ +--- +source: tui/src/bottom_pane/mod.rs +expression: "render_snapshot(&pane, area)" +--- + ↳ Queued follow-up question + ⌥ + ↑ edit + + +› Ask Codex to do anything + + ? for shortcuts diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap new file mode 100644 index 000000000..e55f9a58c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_composer_fill_height_without_bottom_padding.snap @@ -0,0 +1,10 @@ +--- +source: tui/src/bottom_pane/mod.rs +expression: "render_snapshot(&pane, area)" +--- +• Working (0s • esc to interru + + +› Ask Codex to do anything + + ? for shortcuts diff --git a/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_queued_messages_snapshot.snap b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_queued_messages_snapshot.snap new file mode 100644 index 000000000..9463539f8 --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/nori_tui__bottom_pane__tests__status_and_queued_messages_snapshot.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/bottom_pane/mod.rs +expression: "render_snapshot(&pane, area)" +--- +• Working (0s • esc to interrupt) + ↳ Queued follow-up question + ⌥ + ↑ edit + + +› Ask Codex to do anything + + ? for shortcuts diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_markdown_list_response.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_markdown_list_response.snap new file mode 100644 index 000000000..4b06d70a0 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_markdown_list_response.snap @@ -0,0 +1,20 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• Here are the key considerations for your ACP integration: + + 1. Protocol Compliance + - Use JSON-RPC 2.0 message format + - Handle bidirectional communication + - Support session management + 2. Event Handling + - Subscribe to session/update notifications + - Process agent_message_chunk for streaming + - Handle agent_reasoning_chunk for thinking + 3. Error Recovery + - Implement reconnection logic + - Buffer partial messages + - Log protocol violations + + Would you like me to elaborate on any of these points? diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_multi_turn_conversation.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_multi_turn_conversation.snap new file mode 100644 index 000000000..2df6514e7 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_multi_turn_conversation.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: combined +--- +• I can help you refactor that function. First, let me analyze the current + implementation. +─ Worked for 0s ──────────────────────────────────────────────────────────────── + +• Here's the refactored version: + + fn process(data: &str) -> Result { + data.parse() + } diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_reasoning_then_answer.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_reasoning_then_answer.snap new file mode 100644 index 000000000..e2d6dd9ea --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_reasoning_then_answer.snap @@ -0,0 +1,20 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• The user wants to sort a list. I should consider: + + - Time complexity requirements + - Whether stability matters + - Memory constraints +─ Worked for 0s ──────────────────────────────────────────────────────────────── +• Based on your requirements, here's a quicksort implementation: + + def quicksort(arr): + if len(arr) <= 1: + return arr + pivot = arr[len(arr) // 2] + left = [x for x in arr if x < pivot] + middle = [x for x in arr if x == pivot] + right = [x for x in arr if x > pivot] + return quicksort(left) + middle + quicksort(right) diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_stream_error.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_stream_error.snap new file mode 100644 index 000000000..64aef27b3 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_stream_error.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: combined +--- +• Let me help you with that... diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_streaming_text_response.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_streaming_text_response.snap new file mode 100644 index 000000000..8776b4783 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__acp_streaming_text_response.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• I'll help you implement that feature. + + Here's the code: + + fn calculate_sum(numbers: &[i32]) -> i32 { + numbers.iter().sum() + } + + This function takes a slice of integers and returns their sum using iterator + methods. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__apply_patch_manual_flow_history_approved.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__apply_patch_manual_flow_history_approved.snap new file mode 100644 index 000000000..e139b5108 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__apply_patch_manual_flow_history_approved.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: lines_to_single_string(&approved_lines) +--- +• Added foo.txt (+1 -0) + 1 +hello diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec.snap new file mode 100644 index 000000000..ff7ae1034 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend().vt100().screen().contents() +--- + Would you like to run the following command? + + Reason: this is a test reason such as one that would be produced by the + model + + $ echo hello world + +› 1. Yes, proceed (y) + 2. Yes, and don't ask again for this command (a) + 3. No, and tell the agent what to do differently (esc) + + Press enter to confirm or esc to cancel diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec_no_reason.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec_no_reason.snap new file mode 100644 index 000000000..1c16dc8df --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_exec_no_reason.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend().vt100().screen().contents() +--- + Would you like to run the following command? + + $ echo hello world + +› 1. Yes, proceed (y) + 2. Yes, and don't ask again for this command (a) + 3. No, and tell the agent what to do differently (esc) + + Press enter to confirm or esc to cancel diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_patch.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_patch.snap new file mode 100644 index 000000000..c07a661e9 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approval_modal_patch.snap @@ -0,0 +1,17 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend().vt100().screen().contents() +--- + Would you like to make the following edits? + + Reason: The model wants to apply changes + + README.md (+2 -0) + + 1 +hello + 2 +world + +› 1. Yes, proceed (y) + 2. No, and tell the agent what to do differently (esc) + + Press enter to confirm or esc to cancel diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approvals_selection_popup.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approvals_selection_popup.snap new file mode 100644 index 000000000..7866a0dd3 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__approvals_selection_popup.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Select Approval Mode + +› 1. Read Only (current) Requires approval to edit files and run commands. + 2. Agent Read and edit files, and run commands. + 3. Agent (full access) Codex can edit files outside this workspace and run + commands with network access. Exercise caution when + using. + + ↑/k ↓/j to navigate, enter to confirm, esc to go back diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_model_picker_open.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_model_picker_open.snap new file mode 100644 index 000000000..278f18c33 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_model_picker_open.snap @@ -0,0 +1,34 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " +" Select Model and Effort " +" Access legacy models by running codex -m or in your config.toml " +" " +" 1. Mock ACP Agent Mock agent for testing purposes. " +" 2. Gemini 2.0 Flash Thinking Google's experimental thinking model. " +" 3. Claude Anthropic's Claude via Agent Context Protocol. " +"› 4. gpt-5.1-codex (current) Optimized for codex. " +" 5. gpt-5.1-codex-mini Optimized for codex. Cheaper, faster, but less capable. " +" 6. gpt-5.1 Broad world knowledge with strong general reasoning. " +" " +" Press enter to select reasoning effort, or esc to dismiss. " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_typing_hello.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_typing_hello.snap new file mode 100644 index 000000000..f26524b6e --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__blackbox_typing_hello.snap @@ -0,0 +1,34 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " +"› hello " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h1.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h1.snap new file mode 100644 index 000000000..1e73a237e --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h1.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h2.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h2.snap new file mode 100644 index 000000000..7a04b0ef1 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h2.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h3.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h3.snap new file mode 100644 index 000000000..4487d0652 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_idle_h3.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h1.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h1.snap new file mode 100644 index 000000000..1e73a237e --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h1.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h2.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h2.snap new file mode 100644 index 000000000..7a04b0ef1 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h2.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h3.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h3.snap new file mode 100644 index 000000000..4487d0652 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chat_small_running_h3.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " +" " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap new file mode 100644 index 000000000..b83bf8a91 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_exec_and_status_layout_vt100_snapshot.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• I’m going to search the repo for where “Change Approved” is rendered to update + that view. + +• Explored + └ Search Change Approved + Read diff_render.rs + +• Investigating rendering code (0s • esc to interrupt) + + +› Summarize recent commits diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_markdown_code_blocks_vt100_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_markdown_code_blocks_vt100_snapshot.snap new file mode 100644 index 000000000..aeae13094 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_markdown_code_blocks_vt100_snapshot.snap @@ -0,0 +1,18 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• -- Indented code block (4 spaces) + SELECT * + FROM "users" + WHERE "email" LIKE '%@example.com'; + + ```sh + printf 'fenced within fenced\n' + ``` + + { + // comment allowed in jsonc + "path": "C:\\Program Files\\App", + "regex": "^foo.*(bar)?$" + } diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_tall.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_tall.snap new file mode 100644 index 000000000..c61f035e1 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__chatwidget_tall.snap @@ -0,0 +1,27 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: term.backend().vt100().screen().contents() +--- +• Working (0s • esc to interrupt) + ↳ Hello, world! 0 + ↳ Hello, world! 1 + ↳ Hello, world! 2 + ↳ Hello, world! 3 + ↳ Hello, world! 4 + ↳ Hello, world! 5 + ↳ Hello, world! 6 + ↳ Hello, world! 7 + ↳ Hello, world! 8 + ↳ Hello, world! 9 + ↳ Hello, world! 10 + ↳ Hello, world! 11 + ↳ Hello, world! 12 + ↳ Hello, world! 13 + ↳ Hello, world! 14 + ↳ Hello, world! 15 + ↳ Hello, world! 16 + + +› Ask Codex to do anything + + ? for shortcuts diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__deltas_then_same_final_message_are_rendered_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__deltas_then_same_final_message_are_rendered_snapshot.snap new file mode 100644 index 000000000..606208718 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__deltas_then_same_final_message_are_rendered_snapshot.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: combined +--- +• Here is the result. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__disabled_slash_command_while_task_running_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__disabled_slash_command_while_task_running_snapshot.snap new file mode 100644 index 000000000..e8f08a437 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__disabled_slash_command_while_task_running_snapshot.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: blob +--- +■ '/model' is disabled while a task is in progress. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_long.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_long.snap new file mode 100644 index 000000000..44ed1f401 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_long.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: lines_to_single_string(&aborted_long) +--- +✗ You canceled the request to run echo + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa... diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_multiline.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_multiline.snap new file mode 100644 index 000000000..5aee3b284 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_aborted_multiline.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: lines_to_single_string(&aborted_multi) +--- +✗ You canceled the request to run echo line1 ... diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_approved_short.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_approved_short.snap new file mode 100644 index 000000000..46249593a --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_history_decision_approved_short.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: lines_to_single_string(&decision) +--- +✔ You approved Nori to runecho hello world this time diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_modal_exec.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_modal_exec.snap new file mode 100644 index 000000000..4d39ea51e --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exec_approval_modal_exec.snap @@ -0,0 +1,39 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: "format!(\"{buf:?}\")" +--- +Buffer { + area: Rect { x: 0, y: 0, width: 80, height: 14 }, + content: [ + " ", + " ", + " Would you like to run the following command? ", + " ", + " Reason: this is a test reason such as one that would be produced by the ", + " model ", + " ", + " $ echo hello world ", + " ", + "› 1. Yes, proceed (y) ", + " 2. Yes, and don't ask again for this command (a) ", + " 3. No, and tell the agent what to do differently (esc) ", + " ", + " Press enter to confirm or esc to cancel ", + ], + styles: [ + x: 0, y: 0, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 2, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: BOLD, + x: 46, y: 2, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 10, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: ITALIC, + x: 73, y: 4, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 2, y: 5, fg: Reset, bg: Reset, underline: Reset, modifier: ITALIC, + x: 7, y: 5, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 0, y: 9, fg: Cyan, bg: Reset, underline: Reset, modifier: BOLD, + x: 21, y: 9, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 48, y: 10, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 49, y: 10, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 52, y: 11, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + x: 55, y: 11, fg: Reset, bg: Reset, underline: Reset, modifier: NONE, + x: 2, y: 13, fg: Reset, bg: Reset, underline: Reset, modifier: DIM, + ] +} diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step1_start_ls.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step1_start_ls.snap new file mode 100644 index 000000000..a69fccd30 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step1_start_ls.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: active_blob(&chat) +--- +• Exploring + └ List ls -la diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step2_finish_ls.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step2_finish_ls.snap new file mode 100644 index 000000000..e7155b845 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step2_finish_ls.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: active_blob(&chat) +--- +• Explored + └ List ls -la diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step3_start_cat_foo.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step3_start_cat_foo.snap new file mode 100644 index 000000000..6ff2edef8 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step3_start_cat_foo.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: active_blob(&chat) +--- +• Exploring + └ List ls -la + Read foo.txt diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step4_finish_cat_foo.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step4_finish_cat_foo.snap new file mode 100644 index 000000000..de15e7ca2 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step4_finish_cat_foo.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: active_blob(&chat) +--- +• Explored + └ List ls -la + Read foo.txt diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step5_finish_sed_range.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step5_finish_sed_range.snap new file mode 100644 index 000000000..de15e7ca2 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__exploring_step5_finish_sed_range.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: active_blob(&chat) +--- +• Explored + └ List ls -la + Read foo.txt diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__final_reasoning_then_message_without_deltas_are_rendered.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__final_reasoning_then_message_without_deltas_are_rendered.snap new file mode 100644 index 000000000..606208718 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__final_reasoning_then_message_without_deltas_are_rendered.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: combined +--- +• Here is the result. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__full_access_confirmation_popup.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__full_access_confirmation_popup.snap new file mode 100644 index 000000000..a4c631c5e --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__full_access_confirmation_popup.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Enable full access? + When Nori runs with full access, it can edit any file on your computer and + run commands with network, without your approval.Exercise caution when + enabling full access. This significantly increases the risk of data loss, + leaks, or unexpected behavior. + +› 1. Yes, continue anyway Apply full access for this session + 2. Yes, and don't ask again Enable full access and remember this choice + 3. Cancel Go back without enabling full access + + ↑/k ↓/j to navigate, enter to confirm, esc to go back diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupt_exec_marks_failed.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupt_exec_marks_failed.snap new file mode 100644 index 000000000..59eff20ac --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupt_exec_marks_failed.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: exec_blob +--- +• Ran sleep 1 + └ (no output) diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupted_turn_error_message.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupted_turn_error_message.snap new file mode 100644 index 000000000..60715e581 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__interrupted_turn_error_message.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: last +--- +■ Conversation interrupted - tell the model what to do differently. Something went wrong? Hit `/feedback` to report the issue. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__local_image_attachment_history_snapshot.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__local_image_attachment_history_snapshot.snap new file mode 100644 index 000000000..cf4c6943f --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__local_image_attachment_history_snapshot.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: combined +--- +• Viewed Image + └ example.png diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup.snap new file mode 100644 index 000000000..ef0ae828d --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Select Reasoning Level for gpt-5.1-codex-max + + 1. Low Fast responses with lighter reasoning + 2. Medium (default) Balances speed and reasoning depth for everyday tasks +› 3. High (current) Maximizes reasoning depth for complex problems + 4. Extra high Extra high reasoning depth for complex problems + + ↑/k ↓/j to navigate, enter to confirm, esc to go back diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup_extra_high_warning.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup_extra_high_warning.snap new file mode 100644 index 000000000..e332efcc5 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_reasoning_selection_popup_extra_high_warning.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Select Reasoning Level for gpt-5.1-codex-max + + 1. Low Fast responses with lighter reasoning + 2. Medium (default) Balances speed and reasoning depth for everyday + tasks + 3. High Maximizes reasoning depth for complex problems +› 4. Extra high (current) Extra high reasoning depth for complex problems + ⚠ Extra high reasoning effort can quickly consume + Plus plan rate limits. + + ↑/k ↓/j to navigate, enter to confirm, esc to go back diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_selection_popup.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_selection_popup.snap new file mode 100644 index 000000000..eac8252b2 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__model_selection_popup.snap @@ -0,0 +1,17 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Select Model and Effort + Access legacy models by running codex -m or in your config.toml + +› 1. Mock ACP Agent Mock agent for testing purposes. + 2. Gemini 2.0 Flash Thinking Google's experimental thinking model. + 3. Claude Anthropic's Claude via Agent Context Protocol. + 4. gpt-5.1-codex Optimized for codex. + 5. gpt-5.1-codex-mini Optimized for codex. Cheaper, faster, but + less capable. + 6. gpt-5.1 Broad world knowledge with strong general + reasoning. + + Press enter to select reasoning effort, or esc to dismiss. diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__rate_limit_switch_prompt_popup.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__rate_limit_switch_prompt_popup.snap new file mode 100644 index 000000000..fd1bd9309 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__rate_limit_switch_prompt_popup.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: popup +--- + Approaching rate limits + Switch to gpt-5.1-codex-mini for lower credit usage? + +› 1. Switch to gpt-5.1-codex-mini Optimized for codex. Cheaper, + faster, but less capable. + 2. Keep current model + 3. Keep current model (never show again) Hide future rate limit reminders + about switching models. + + ↑/k ↓/j to navigate, enter to confirm, esc to go back diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_active.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_active.snap new file mode 100644 index 000000000..293698267 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_active.snap @@ -0,0 +1,11 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +"• Analyzing (0s • esc to interrupt) " +" " +" " +"› Ask Codex to do anything " +" " +" ? for shortcuts " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_and_approval_modal.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_and_approval_modal.snap new file mode 100644 index 000000000..74ccbd706 --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__status_widget_and_approval_modal.snap @@ -0,0 +1,18 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: terminal.backend() +--- +" " +" " +" Would you like to run the following command? " +" " +" Reason: this is a test reason such as one that would be produced by the " +" model " +" " +" $ echo 'hello world' " +" " +"› 1. Yes, proceed (y) " +" 2. Yes, and don't ask again for this command (a) " +" 3. No, and tell the agent what to do differently (esc) " +" " +" Press enter to confirm or esc to cancel " diff --git a/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__user_shell_ls_output.snap b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__user_shell_ls_output.snap new file mode 100644 index 000000000..c67cd637d --- /dev/null +++ b/codex-rs/tui/src/chatwidget/snapshots/nori_tui__chatwidget__tests__user_shell_ls_output.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/chatwidget/tests.rs +expression: blob +--- +• You ran ls + └ file1 + file2 diff --git a/codex-rs/tui/src/clipboard_paste.rs b/codex-rs/tui/src/clipboard_paste.rs index 2a669f5c4..e69fa1bd7 100644 --- a/codex-rs/tui/src/clipboard_paste.rs +++ b/codex-rs/tui/src/clipboard_paste.rs @@ -122,7 +122,7 @@ pub fn paste_image_to_temp_png() -> Result<(PathBuf, PastedImageInfo), PasteImag let (png, info) = paste_image_as_png()?; // Create a unique temporary file with a .png suffix to avoid collisions. let tmp = Builder::new() - .prefix("codex-clipboard-") + .prefix("nori-clipboard-") .suffix(".png") .tempfile() .map_err(|e| PasteImageError::IoError(e.to_string()))?; diff --git a/codex-rs/tui/src/lib.rs b/codex-rs/tui/src/lib.rs index f3c02ce3f..f256a2830 100644 --- a/codex-rs/tui/src/lib.rs +++ b/codex-rs/tui/src/lib.rs @@ -369,7 +369,7 @@ pub async fn run_main( log_file_opts.mode(0o600); } - let log_file = log_file_opts.open(log_dir.join("codex-tui.log"))?; + let log_file = log_file_opts.open(log_dir.join("nori-tui.log"))?; // Wrap file in non‑blocking writer. let (non_blocking, _guard) = non_blocking(log_file); @@ -377,7 +377,7 @@ pub async fn run_main( // use RUST_LOG env var, default to info for codex crates. let env_filter = || { EnvFilter::try_from_default_env().unwrap_or_else(|_| { - EnvFilter::new("codex_core=info,codex_tui=info,codex_rmcp_client=info") + EnvFilter::new("codex_core=info,nori_tui=info,codex_rmcp_client=info") }) }; diff --git a/codex-rs/tui/src/main.rs b/codex-rs/tui/src/main.rs index 42ef3090d..1aa95211f 100644 --- a/codex-rs/tui/src/main.rs +++ b/codex-rs/tui/src/main.rs @@ -1,8 +1,8 @@ use clap::Parser; use codex_arg0::arg0_dispatch_or_else; use codex_common::CliConfigOverrides; -use codex_tui::Cli; -use codex_tui::run_main; +use nori_tui::Cli; +use nori_tui::run_main; #[derive(Parser, Debug)] struct TopCli { diff --git a/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_git_repo.snap b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_git_repo.snap new file mode 100644 index 000000000..6bd256d63 --- /dev/null +++ b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_git_repo.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/nori/onboarding/trust_directory.rs +expression: output +--- +> You are running Nori in /workspace/project + + Since this folder is version controlled, you may wish to allow Nori + to work in this folder without asking for approval. + +› 1. Yes, allow Nori to work in this folder without asking for + approval + 2. No, ask me to approve edits and commands + + Press enter to continue diff --git a/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_non_git_repo.snap b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_non_git_repo.snap new file mode 100644 index 000000000..21a87f8a9 --- /dev/null +++ b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__trust_directory__tests__nori_trust_non_git_repo.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/nori/onboarding/trust_directory.rs +expression: output +--- +> You are running Nori in /workspace/project + + Since this folder is not version controlled, we recommend requiring + approval of all edits and commands. + + 1. Allow Nori to work in this folder without asking for approval +› 2. Require approval of edits and commands + + Press enter to continue diff --git a/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__welcome__tests__nori_welcome_snapshot.snap b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__welcome__tests__nori_welcome_snapshot.snap new file mode 100644 index 000000000..4bcee18d6 --- /dev/null +++ b/codex-rs/tui/src/nori/onboarding/snapshots/nori_tui__nori__onboarding__welcome__tests__nori_welcome_snapshot.snap @@ -0,0 +1,17 @@ +--- +source: tui/src/nori/onboarding/welcome.rs +expression: output +--- + _ _ ___ ____ ___ + | \ | |/ _ \| _ \|_ _| + | \| | | | | |_) || | + | |\ | |_| | _ < | | + |_| \_|\___/|_| \_\___| + + + Welcome to Nori, your AI coding assistant + + Let's get you set up... + + + Press Enter to continue diff --git a/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_empty_session_snapshot.snap b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_empty_session_snapshot.snap new file mode 100644 index 000000000..022494f41 --- /dev/null +++ b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_empty_session_snapshot.snap @@ -0,0 +1,18 @@ +--- +source: tui/src/nori/exit_message.rs +expression: rendered +--- +╭───────────────────────────────────────────────╮ +│ Goodbye! Thanks for using Nori. │ +│ │ +│ Session: sess_empty │ +│ │ +│ Messages User: 0 Assistant: 0 Total: 0 │ +│ Tool Calls (none) │ +│ │ +│ Skills Used │ +│ (none) │ +│ │ +│ Subagents Used │ +│ (none) │ +╰───────────────────────────────────────────────╯ diff --git a/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_snapshot.snap b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_snapshot.snap new file mode 100644 index 000000000..66fad72e6 --- /dev/null +++ b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__exit_message__tests__exit_message_snapshot.snap @@ -0,0 +1,19 @@ +--- +source: tui/src/nori/exit_message.rs +expression: rendered +--- +╭────────────────────────────────────────────────╮ +│ Goodbye! Thanks for using Nori. │ +│ │ +│ Session: sess_abc123def456 │ +│ │ +│ Messages User: 5 Assistant: 8 Total: 13 │ +│ Tool Calls Bash: 12 Edit: 7 Read: 25 │ +│ │ +│ Skills Used │ +│ commit │ +│ review-pr │ +│ │ +│ Subagents Used │ +│ nori-codebase-locator │ +╰────────────────────────────────────────────────╯ diff --git a/codex-rs/tui/src/nori/snapshots/nori_tui__nori__session_header__tests__nori_header_snapshot.snap b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__session_header__tests__nori_header_snapshot.snap new file mode 100644 index 000000000..b73af296d --- /dev/null +++ b/codex-rs/tui/src/nori/snapshots/nori_tui__nori__session_header__tests__nori_header_snapshot.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/nori/session_header.rs +expression: rendered +--- +╭──────────────────────────────────────────╮ +│ Nori CLI v0.1.0 │ +│ │ +│ directory: /home/user/project │ +│ agent: claude-sonnet │ +│ skillset: senior-swe │ +│ │ +│ Instruction Files │ +│ /home/user/project/AGENTS.md │ +│ /home/user/project/.claude/settings.md │ +╰──────────────────────────────────────────╯ diff --git a/codex-rs/tui/src/onboarding/snapshots/nori_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap b/codex-rs/tui/src/onboarding/snapshots/nori_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap new file mode 100644 index 000000000..71cbc3d6e --- /dev/null +++ b/codex-rs/tui/src/onboarding/snapshots/nori_tui__onboarding__trust_directory__tests__renders_snapshot_for_git_repo.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/onboarding/trust_directory.rs +expression: terminal.backend() +--- +> You are running Codex in /workspace/project + + Since this folder is version controlled, you may wish to allow Codex + to work in this folder without asking for approval. + +› 1. Yes, allow Codex to work in this folder without asking for + approval + 2. No, ask me to approve edits and commands + + Press enter to continue diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_add_block.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_add_block.snap new file mode 100644 index 000000000..cd5aaf5fa --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_add_block.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Added new_file.txt (+2 -0) " +" 1 +alpha " +" 2 +beta " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_delete_block.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_delete_block.snap new file mode 100644 index 000000000..edfdb2c05 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_delete_block.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Deleted tmp_delete_example.txt (+0 -3) " +" 1 -first " +" 2 -second " +" 3 -third " +" " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_multiple_files_block.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_multiple_files_block.snap new file mode 100644 index 000000000..62fc671d1 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_multiple_files_block.snap @@ -0,0 +1,18 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Edited 2 files (+2 -1) " +" └ a.txt (+1 -1) " +" 1 -one " +" 1 +one changed " +" " +" └ b.txt (+1 -0) " +" 1 +new " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block.snap new file mode 100644 index 000000000..8cc31efdd --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Edited example.txt (+1 -1) " +" 1 line one " +" 2 -line two " +" 2 +line two changed " +" 3 line three " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_line_numbers_three_digits_text.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_line_numbers_three_digits_text.snap new file mode 100644 index 000000000..56058ee70 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_line_numbers_three_digits_text.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/diff_render.rs +expression: text +--- +• Edited hundreds.txt (+1 -1) + 97 line 97 + 98 line 98 + 99 line 99 + 100 -line 100 + 100 +line 100 changed + 101 line 101 + 102 line 102 + 103 line 103 diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_relativizes_path.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_relativizes_path.snap new file mode 100644 index 000000000..a50f7700c --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_relativizes_path.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Edited abs_old.rs → abs_new.rs (+1 -1) " +" 1 -X " +" 1 +X changed " +" 2 Y " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines.snap new file mode 100644 index 000000000..72b9528e5 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Edited long_example.txt (+1 -1) " +" 1 line 1 " +" 2 -short " +" 2 +short this_is_a_very_long_modified_line_that_should_wrap_across_m " +" ultiple_terminal_columns_and_continue_even_further_beyond_eighty_ " +" columns_to_force_multiple_wraps " +" 3 line 3 " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines_text.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines_text.snap new file mode 100644 index 000000000..17c92c1b5 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_block_wraps_long_lines_text.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/diff_render.rs +expression: text +--- +• Edited wrap_demo.txt (+2 -2) + 1 1 + 2 -2 + 2 +added long line which + wraps and_if_there_i + s_a_long_token_it_wil + l_be_broken + 3 3 + 4 -4 + 4 +4 context line which + also wraps across diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_with_rename_block.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_with_rename_block.snap new file mode 100644 index 000000000..29b321011 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__apply_update_with_rename_block.snap @@ -0,0 +1,16 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"• Edited old_name.rs → new_name.rs (+1 -1) " +" 1 A " +" 2 -B " +" 2 +B changed " +" 3 C " +" " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__wrap_behavior_insert.snap b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__wrap_behavior_insert.snap new file mode 100644 index 000000000..7532977ce --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__diff_render__tests__wrap_behavior_insert.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/diff_render.rs +expression: terminal.backend() +--- +"1 +this is a very long line that should wrap across multiple terminal columns an " +" d continue " +" " +" " +" " +" " +" " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__active_mcp_tool_call_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__active_mcp_tool_call_snapshot.snap new file mode 100644 index 000000000..2077da659 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__active_mcp_tool_call_snapshot.snap @@ -0,0 +1,5 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Calling search.find_docs({"query":"ratatui styling","limit":3}) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesced_reads_dedupe_names.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesced_reads_dedupe_names.snap new file mode 100644 index 000000000..2044d41a1 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesced_reads_dedupe_names.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Explored + └ Read auth.rs, shimmer.rs diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_reads_across_multiple_calls.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_reads_across_multiple_calls.snap new file mode 100644 index 000000000..fcfa31eed --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_reads_across_multiple_calls.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Explored + └ Search shimmer_spans + Read shimmer.rs, status_indicator_widget.rs diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_sequential_reads_within_one_call.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_sequential_reads_within_one_call.snap new file mode 100644 index 000000000..533a489ee --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__coalesces_sequential_reads_within_one_call.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Explored + └ Search shimmer_spans + Read shimmer.rs + Read status_indicator_widget.rs diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_error_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_error_snapshot.snap new file mode 100644 index 000000000..bb0b826bb --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_error_snapshot.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Called search.find_docs({"query":"ratatui styling","limit":3}) + └ Error: network timeout diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_inline_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_inline_snapshot.snap new file mode 100644 index 000000000..0ee965d82 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_inline_snapshot.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Called metrics.summary({"metric":"trace.latency","window":"15m"}) + └ Latency summary: p50=120ms, p95=480ms. + No anomalies detected. diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_snapshot.snap new file mode 100644 index 000000000..62cc89b2f --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_multiple_outputs_snapshot.snap @@ -0,0 +1,10 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Called + └ search.find_docs({"query":"ratatui + styling","limit":3}) + Found styling guidance in styles.md and + additional notes in CONTRIBUTING.md. + link: file:///docs/styles.md diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_success_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_success_snapshot.snap new file mode 100644 index 000000000..cd5eb9dc0 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_success_snapshot.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Called search.find_docs({"query":"ratatui styling","limit":3}) + └ Found styling guidance in styles.md diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_wrapped_outputs_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_wrapped_outputs_snapshot.snap new file mode 100644 index 000000000..ed2e0c236 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__completed_mcp_tool_call_wrapped_outputs_snapshot.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Called + └ metrics.get_nearby_metric({"query":" + very_long_query_that_needs_wrapp + ing_to_display_properly_in_the_h + istory","limit":1}) + Line one of the response, which is + quite long and needs wrapping. + Line two continues the response with + more detail. diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__mcp_tools_output_masks_sensitive_values.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__mcp_tools_output_masks_sensitive_values.snap new file mode 100644 index 000000000..329cd232d --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__mcp_tools_output_masks_sensitive_values.snap @@ -0,0 +1,26 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +/mcp + +🔌 MCP Tools + + • docs + • Status: enabled + • Auth: Unsupported + • Command: docs-server + • Env: TOKEN=*****, APP_TOKEN=***** + • Tools: list + • Resources: (none) + • Resource templates: (none) + + • http + • Status: enabled + • Auth: Unsupported + • URL: https://example.com/mcp + • HTTP headers: Authorization=***** + • Env HTTP headers: X-API-Key=API_KEY_ENV + • Tools: ping + • Resources: (none) + • Resource templates: (none) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_both_lines_wrap_with_correct_prefixes.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_both_lines_wrap_with_correct_prefixes.snap new file mode 100644 index 000000000..b5d4fac16 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_both_lines_wrap_with_correct_prefixes.snap @@ -0,0 +1,9 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran first_token_is_long_en + │ ough_to_wrap + │ second_token_is_also_lon + │ … +1 lines + └ (no output) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_without_wrap_uses_branch_then_eight_spaces.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_without_wrap_uses_branch_then_eight_spaces.snap new file mode 100644 index 000000000..10d87ad9d --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_without_wrap_uses_branch_then_eight_spaces.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran echo one + │ echo two + └ (no output) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_wraps_with_extra_indent_on_subsequent_lines.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_wraps_with_extra_indent_on_subsequent_lines.snap new file mode 100644 index 000000000..e8458cfdc --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__multiline_command_wraps_with_extra_indent_on_subsequent_lines.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran set -o pipefail + │ cargo test + │ --all-features --quiet + └ (no output) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_with_note_and_wrapping_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_with_note_and_wrapping_snapshot.snap new file mode 100644 index 000000000..27649a11d --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_with_note_and_wrapping_snapshot.snap @@ -0,0 +1,20 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Updated Plan + └ I’ll update Grafana call + error handling by adding + retries and clearer + messages when the backend is + unreachable. + ✔ Investigate existing error + paths and logging around + HTTP timeouts + □ Harden Grafana client + error handling with retry/ + backoff and user‑friendly + messages + □ Add tests for transient + failure scenarios and + surfacing to the UI diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_without_note_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_without_note_snapshot.snap new file mode 100644 index 000000000..e3ac8844f --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__plan_update_without_note_snapshot.snap @@ -0,0 +1,7 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Updated Plan + └ □ Define error taxonomy + □ Implement mapping to user messages diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__ran_cell_multiline_with_stderr_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__ran_cell_multiline_with_stderr_snapshot.snap new file mode 100644 index 000000000..0c7b5ee84 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__ran_cell_multiline_with_stderr_snapshot.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran echo + │ this_is_a_very_long_si + │ ngle_token_that_will_w + │ … +2 lines + └ error: first line on + stderr + error: second line on + stderr diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_compact_when_fits.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_compact_when_fits.snap new file mode 100644 index 000000000..23827df92 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_compact_when_fits.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran echo ok + └ (no output) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_wraps_with_four_space_continuation.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_wraps_with_four_space_continuation.snap new file mode 100644 index 000000000..244fd1d7e --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__single_line_command_wraps_with_four_space_continuation.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran a_very_long_token_ + │ without_spaces_to_ + │ force_wrapping + └ (no output) diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__stderr_tail_more_than_five_lines_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__stderr_tail_more_than_five_lines_snapshot.snap new file mode 100644 index 000000000..ae7ee1518 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__stderr_tail_more_than_five_lines_snapshot.snap @@ -0,0 +1,10 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +• Ran seq 1 10 1>&2 && false + └ 1 + 2 + … +6 lines + 9 + 10 diff --git a/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__user_history_cell_wraps_and_prefixes_each_line_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__user_history_cell_wraps_and_prefixes_each_line_snapshot.snap new file mode 100644 index 000000000..9870dddb0 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__history_cell__tests__user_history_cell_wraps_and_prefixes_each_line_snapshot.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/history_cell.rs +expression: rendered +--- +› one two + three + four five + six seven diff --git a/codex-rs/tui/src/snapshots/nori_tui__markdown_render__markdown_render_tests__markdown_render_complex_snapshot.snap b/codex-rs/tui/src/snapshots/nori_tui__markdown_render__markdown_render_tests__markdown_render_complex_snapshot.snap new file mode 100644 index 000000000..cc752dd66 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__markdown_render__markdown_render_tests__markdown_render_complex_snapshot.snap @@ -0,0 +1,62 @@ +--- +source: tui/src/markdown_render_tests.rs +expression: rendered +--- +# H1: Markdown Streaming Test + +Intro paragraph with bold text, italic text, and inline code x=1. +Combined bold-italic both and escaped asterisks *literal*. +Auto-link: https://example.com (https://example.com) and reference link [ref][r1]. +Link with title: hover me (https://example.com) and mailto mailto:test@example.com (mailto:test@example.com). +Image: alt text + +> Blockquote level 1 +> +> > Blockquote level 2 with inline code + +- Unordered list item 1 + - Nested bullet with italics inner +- Unordered list item 2 with strikethrough + +1. Ordered item one +2. Ordered item two with sublist: + 1. Alt-numbered subitem + +- [ ] Task: unchecked +- [x] Task: checked with link home (https://example.org) + +——— + +Table below (alignment test): +| Left | Center | Right | +|:-----|:------:|------:| +| a | b | c | +Inline HTML: sup and sub. +HTML block: +
inline block
+Escapes: \_underscores\_, backslash \\, ticks ``code with `backtick` inside``. +Emoji shortcodes: :sparkles: :tada: (if supported). +Hard break test (line ends with two spaces) +Next line should be close to previous. +Footnote reference here[^1] and another[^longnote]. +Horizontal rule with asterisks: +*** +Fenced code block (JSON): +```json +{ "a": 1, "b": [true, false] } +``` +Fenced code with tildes and triple backticks inside: +~~~markdown +To close ``` you need tildes. +~~~ +Indented code block: + for i in range(3): print(i) +Definition-like list: +Term +: Definition with `code`. +Character entities: & < > " ' +[^1]: This is the first footnote. +[^longnote]: A longer footnote with a link to [Rust](https://www.rust-lang.org/). +Escaped pipe in text: a \| b \| c. +URL with parentheses: [link](https://example.com/path_(with)_parens). +[r1]: https://example.com/ref "Reference link title" diff --git a/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt.snap b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt.snap new file mode 100644 index 000000000..5b3136803 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt.snap @@ -0,0 +1,19 @@ +--- +source: tui/src/model_migration.rs +expression: terminal.backend() +--- +> Codex just got an upgrade. Introducing gpt-5.1-codex-max + + Codex is now powered by gpt-5.1-codex-max, our latest + frontier agentic coding model. It is smarter and faster + than its predecessors and capable of long-running + project-scale work. + + Learn more at www.openai.com/index/gpt-5-1-codex-max. + + Choose how you'd like Codex to proceed. + +› 1. Try new model + 2. Use existing model + + Use ↑/↓ to move, press enter to confirm diff --git a/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex.snap b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex.snap new file mode 100644 index 000000000..5a0ccd9b5 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/model_migration.rs +expression: terminal.backend() +--- +> Introducing our gpt-5.1 models + + We've upgraded our family of models supported in Codex to + gpt-5.1, gpt-5.1-codex and gpt-5.1-codex-mini. + + You can continue using legacy models by specifying them + directly with the -m option or in your config.toml. + + Learn more at www.openai.com/index/gpt-5-1. + + Press enter to continue diff --git a/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex_mini.snap b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex_mini.snap new file mode 100644 index 000000000..5a0ccd9b5 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_codex_mini.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/model_migration.rs +expression: terminal.backend() +--- +> Introducing our gpt-5.1 models + + We've upgraded our family of models supported in Codex to + gpt-5.1, gpt-5.1-codex and gpt-5.1-codex-mini. + + You can continue using legacy models by specifying them + directly with the -m option or in your config.toml. + + Learn more at www.openai.com/index/gpt-5-1. + + Press enter to continue diff --git a/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_family.snap b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_family.snap new file mode 100644 index 000000000..5a0ccd9b5 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__model_migration__tests__model_migration_prompt_gpt5_family.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/model_migration.rs +expression: terminal.backend() +--- +> Introducing our gpt-5.1 models + + We've upgraded our family of models supported in Codex to + gpt-5.1, gpt-5.1-codex and gpt-5.1-codex-mini. + + You can continue using legacy models by specifying them + directly with the -m option or in your config.toml. + + Learn more at www.openai.com/index/gpt-5-1. + + Press enter to continue diff --git a/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_snapshot_basic.snap b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_snapshot_basic.snap new file mode 100644 index 000000000..bc7818aff --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_snapshot_basic.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/pager_overlay.rs +expression: term.backend() +--- +"/ S T A T I C / / / / / / / / / / / / / " +"one " +"two " +"three " +"~ " +"~ " +"───────────────────────────────── 100% ─" +" ↑/↓ to scroll pgup/pgdn to page hom" +" q to quit " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_wraps_long_lines.snap b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_wraps_long_lines.snap new file mode 100644 index 000000000..8bbcc488c --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__static_overlay_wraps_long_lines.snap @@ -0,0 +1,12 @@ +--- +source: tui/src/pager_overlay.rs +expression: term.backend() +--- +"/ S T A T I C / / / / / " +"a very long line that " +"should wrap when " +"rendered within a narrow" +"─────────────────── 0% ─" +" ↑/↓ to scroll pgup/pg" +" q to quit " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_apply_patch_scroll_vt100.snap b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_apply_patch_scroll_vt100.snap new file mode 100644 index 000000000..1f086e81e --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_apply_patch_scroll_vt100.snap @@ -0,0 +1,15 @@ +--- +source: tui/src/pager_overlay.rs +expression: snapshot +--- +/ T R A N S C R I P T / / / / / / / / / / / / / / / / / / / / / / / / / / / / / +• Added foo.txt (+2 -0) + 1 +hello + 2 +world + +• Added foo.txt (+2 -0) + 1 +hello + 2 +world +─────────────────────────────────────────────────────────────────────────── 0% ─ + ↑/↓ to scroll pgup/pgdn to page home/end to jump + q to quit esc to edit prev diff --git a/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_snapshot_basic.snap b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_snapshot_basic.snap new file mode 100644 index 000000000..61fcf7d2e --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__pager_overlay__tests__transcript_overlay_snapshot_basic.snap @@ -0,0 +1,14 @@ +--- +source: tui/src/pager_overlay.rs +expression: term.backend() +--- +"/ T R A N S C R I P T / / / / / / / / / " +"alpha " +" " +"beta " +" " +"gamma " +"───────────────────────────────── 100% ─" +" ↑/↓ to scroll pgup/pgdn to page hom" +" q to quit esc to edit prev " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__resume_picker__tests__resume_picker_table.snap b/codex-rs/tui/src/snapshots/nori_tui__resume_picker__tests__resume_picker_table.snap new file mode 100644 index 000000000..c02904321 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__resume_picker__tests__resume_picker_table.snap @@ -0,0 +1,8 @@ +--- +source: tui/src/resume_picker.rs +expression: snapshot +--- + Updated Branch CWD Conversation + 42 seconds ago - - Fix resume picker timestamps +> 35 minutes ago - - Investigate lazy pagination cap + 2 hours ago - - Explain the codebase diff --git a/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_truncated.snap b/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_truncated.snap new file mode 100644 index 000000000..ba179808b --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_truncated.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/status_indicator_widget.rs +expression: terminal.backend() +--- +"• Working (0s • esc " +" " diff --git a/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_with_working_header.snap b/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_with_working_header.snap new file mode 100644 index 000000000..2b80830f8 --- /dev/null +++ b/codex-rs/tui/src/snapshots/nori_tui__status_indicator_widget__tests__renders_with_working_header.snap @@ -0,0 +1,6 @@ +--- +source: tui/src/status_indicator_widget.rs +expression: terminal.backend() +--- +"• Working (0s • esc to interrupt) " +" " diff --git a/codex-rs/tui/tests/suite/vt100_history.rs b/codex-rs/tui/tests/suite/vt100_history.rs index 6df9dedf1..52e13f76c 100644 --- a/codex-rs/tui/tests/suite/vt100_history.rs +++ b/codex-rs/tui/tests/suite/vt100_history.rs @@ -23,20 +23,20 @@ macro_rules! assert_contains { } struct TestScenario { - term: codex_tui::custom_terminal::Terminal, + term: nori_tui::custom_terminal::Terminal, } impl TestScenario { fn new(width: u16, height: u16, viewport: Rect) -> Self { let backend = VT100Backend::new(width, height); - let mut term = codex_tui::custom_terminal::Terminal::with_options(backend) + let mut term = nori_tui::custom_terminal::Terminal::with_options(backend) .expect("failed to construct terminal"); term.set_viewport_area(viewport); Self { term } } fn run_insert(&mut self, lines: Vec>) { - codex_tui::insert_history::insert_history_lines(&mut self.term, lines) + nori_tui::insert_history::insert_history_lines(&mut self.term, lines) .expect("Failed to insert history lines in test"); } } diff --git a/codex-rs/tui/tests/suite/vt100_live_commit.rs b/codex-rs/tui/tests/suite/vt100_live_commit.rs index 2be9658b2..e53dcf089 100644 --- a/codex-rs/tui/tests/suite/vt100_live_commit.rs +++ b/codex-rs/tui/tests/suite/vt100_live_commit.rs @@ -7,7 +7,7 @@ use ratatui::text::Line; #[test] fn live_001_commit_on_overflow() { let backend = VT100Backend::new(20, 6); - let mut term = match codex_tui::custom_terminal::Terminal::with_options(backend) { + let mut term = match nori_tui::custom_terminal::Terminal::with_options(backend) { Ok(t) => t, Err(e) => panic!("failed to construct terminal: {e}"), }; @@ -15,7 +15,7 @@ fn live_001_commit_on_overflow() { term.set_viewport_area(area); // Build 5 explicit rows at width 20. - let mut rb = codex_tui::live_wrap::RowBuilder::new(20); + let mut rb = nori_tui::live_wrap::RowBuilder::new(20); rb.push_fragment("one\n"); rb.push_fragment("two\n"); rb.push_fragment("three\n"); @@ -26,7 +26,7 @@ fn live_001_commit_on_overflow() { let commit_rows = rb.drain_commit_ready(3); let lines: Vec> = commit_rows.into_iter().map(|r| r.text.into()).collect(); - codex_tui::insert_history::insert_history_lines(&mut term, lines) + nori_tui::insert_history::insert_history_lines(&mut term, lines) .expect("Failed to insert history lines in test"); let screen = term.backend().vt100().screen(); diff --git a/codex-rs/windows-sandbox-rs/sandbox_smoketests.py b/codex-rs/windows-sandbox-rs/sandbox_smoketests.py index 0fc049d4e..c9e3112a2 100644 --- a/codex-rs/windows-sandbox-rs/sandbox_smoketests.py +++ b/codex-rs/windows-sandbox-rs/sandbox_smoketests.py @@ -39,9 +39,9 @@ def _resolve_codex_cmd() -> List[str]: raise FileNotFoundError( "Codex CLI not found. Build it first, e.g.\n" - " cargo build -p codex-cli --release\n" + " cargo build -p nori-cli --release\n" "or for debug:\n" - " cargo build -p codex-cli\n" + " cargo build -p nori-cli\n" ) CODEX_CMD = _resolve_codex_cmd()