Files
dev/patches/upstream.json
zeekayandHanzo Dev 5d8652d06d fix(dev): review and memory run on models the provider serves
On api.hanzo.ai, automatic approval review and memory extraction and
consolidation ask for enso-auto, not OpenAI's ids. Off OpenAI, the reviewer
counts a model as served only when the catalog lists it: the bundled OpenAI
entries ride along unlisted for lookups, so codex-auto-review looked served on
every provider and a LAN engine was reviewed by a model it does not have. Now
it falls back to the model the run is on.

Co-authored-by: Hanzo Dev <[email protected]>
2026-10-09 17:06:36 -07:00

639 lines
36 KiB
JSON

[
{
"file": "tui/Cargo.toml",
"old": "[dependencies]",
"new": "[dependencies]\nhanzo-tui = { path = \"../../../../crates/hanzo-tui\" }",
"count": 1
},
{
"file": "tui/src/history_cell/session.rs",
"old": "\"OpenAI Codex\".bold()",
"new": "hanzo_tui::PRODUCT_NAME.bold()",
"count": 1
},
{
"file": "tui/src/history_cell/session.rs",
"old": "format!(\"OpenAI Codex (v{})\", self.version)",
"new": "format!(\"{} (v{})\", hanzo_tui::PRODUCT_NAME, self.version)",
"count": 1
},
{
"file": "tui/src/chatwidget.rs",
"old": "const PLACEHOLDER: &str = \"Ask Codex to do anything\";",
"new": "const PLACEHOLDER: &str = hanzo_tui::INPUT_PLACEHOLDER;",
"count": 1
},
{
"file": "tui/src/version.rs",
"old": "/// The current Codex CLI version as embedded at compile time.\npub const CODEX_CLI_VERSION: &str = env!(\"CARGO_PKG_VERSION\");",
"new": "/// The version this process runs as, which the binary sets (hanzo-version).\npub const CODEX_CLI_VERSION: &hanzo_version::Version = hanzo_version::VERSION;",
"count": 1
},
{
"file": "tui/src/style.rs",
"old": " let (top, alpha) = if is_light(terminal_bg) {\n ((0, 0, 0), 0.04)\n } else {\n ((255, 255, 255), 0.12)\n };\n blend(top, terminal_bg, alpha)",
"new": " hanzo_tui::input_background(terminal_bg, is_light(terminal_bg))",
"count": 1
},
{
"file": "tui/src/startup_draft.rs",
"old": "\"Ask Codex to do anything\".to_string()",
"new": "hanzo_tui::INPUT_PLACEHOLDER.to_string()",
"count": 1
},
{
"file": "tui/src/keymap_setup.rs",
"old": "\"Ask Codex to do anything\".to_string()",
"new": "hanzo_tui::INPUT_PLACEHOLDER.to_string()",
"count": 1
},
{
"file": "tui/src/onboarding/welcome.rs",
"old": "\"Codex\".bold()",
"new": "hanzo_tui::PRODUCT_NAME.bold()",
"count": 1
},
{
"file": "tui/src/onboarding/welcome.rs",
"old": "\", OpenAI's command-line coding agent\".into()",
"new": "\", your Hanzo coding agent\".into()",
"count": 1
},
{
"file": "tui/src/tooltips.rs",
"old": "pub(crate) fn get_tooltip(plan: Option<PlanType>, keymap: &TuiKeymap) -> Option<String> {",
"new": "pub(crate) fn get_tooltip(plan: Option<PlanType>, keymap: &TuiKeymap) -> Option<String> {\n if plan.is_none() {\n return Some(hanzo_tui::STARTUP_TIP.to_string());\n }",
"count": 1
},
{
"file": "tui/src/cli.rs",
"old": "fields that are not recognized by this version of Codex.",
"new": "fields this version of Dev does not recognize.",
"count": 1
},
{
"file": "cli/src/lib.rs",
"old": "pub(crate) mod debug_sandbox;\nmod exit_status;\npub(crate) mod login;",
"new": "#![allow(dead_code)]\npub(crate) mod debug_sandbox;\nmod exit_status;\npub(crate) mod login;\n// Upstream declares these in its binary, which puts them out of reach of\n// any other front end. They are self-contained; publishing them from the\n// library is the whole of the change.\n#[cfg(any(target_os = \"macos\", target_os = \"windows\"))]\npub mod app_cmd;\npub mod cloud_config;\n#[cfg(any(target_os = \"macos\", target_os = \"windows\"))]\npub mod desktop_app;\npub mod doctor;\npub mod marketplace_cmd;\npub mod mcp_cmd;\npub mod mcp_login;\npub mod migrate_rollouts;\npub mod plugin_cmd;\npub mod remote_control_cmd;",
"count": 1
},
{
"file": "cli/src/doctor/output.rs",
"old": "bold(\"Codex Doctor\", options)",
"new": "bold(\"Hanzo Dev Doctor\", options)",
"count": 1
},
{
"file": "cli/src/cloud_config.rs",
"old": "pub(crate) async fn load_config(",
"new": "pub async fn load_config(",
"count": 1
},
{
"file": "Cargo.toml",
"old": "version = \"0.0.0\"",
"new": "version = \"0.7.0-dev.1\"",
"count": 1
},
{
"file": "exec/src/event_processor_with_human_output.rs",
"old": "const VERSION: &str = env!(\"CARGO_PKG_VERSION\");\n eprintln!(\"OpenAI Codex v{VERSION}\\n--------\");",
"new": "eprintln!(\"Hanzo Dev v{}\\n--------\", hanzo_version::get());",
"count": 1
},
{
"file": "sandboxing/src/bwrap.rs",
"old": "\"Codex's Linux sandbox uses bubblewrap",
"new": "\"The Linux sandbox uses bubblewrap",
"count": 2
},
{
"file": "utils/cli/src/config_override.rs",
"old": "`~/.codex/config.toml`",
"new": "`$DEV_HOME/config.toml`",
"count": 1
},
{
"file": "exec/src/cli.rs",
"old": "fields that are not recognized by this version of Codex.",
"new": "fields this version of Dev does not recognize.",
"count": 1
},
{
"file": "exec/src/cli.rs",
"old": "Allow running Codex outside a Git repository.",
"new": "Allow running Dev outside a Git repository.",
"count": 1
},
{
"file": "exec/src/cli.rs",
"old": "(OpenAI provider only)",
"new": "(supported providers only)",
"count": 1
},
{
"file": "exec/src/event_processor_with_human_output.rs",
"old": "\"codex\".style(self.italic)",
"new": "\"dev\".style(self.italic)",
"count": 2
},
{
"file": "exec/src/cli.rs",
"old": "override_usage = \"codex exec [OPTIONS] [PROMPT]\\n codex exec [OPTIONS] <COMMAND> [ARGS]\"",
"new": "override_usage = \"dev exec [OPTIONS] [PROMPT]\\n dev exec [OPTIONS] <COMMAND> [ARGS]\"",
"count": 1
},
{
"file": "cloud-tasks/src/cli.rs",
"old": "Codex Cloud task",
"new": "Hanzo task",
"count": 8
},
{
"file": "cloud-tasks/src/cli.rs",
"old": "Codex Cloud",
"new": "Hanzo Tasks",
"count": 2
},
{
"file": "cli/src/lib.rs",
"old": "Layer $CODEX_HOME/<name>.config.toml on top of the base user config",
"new": "Layer $DEV_HOME/<name>.config.toml on top of the base user config",
"count": 3
},
{
"file": "cli/src/main.rs",
"old": "Layer $CODEX_HOME/<name>.config.toml on top of the base user config",
"new": "Layer $DEV_HOME/<name>.config.toml on top of the base user config",
"count": 1
},
{
"file": "utils/cli/src/shared_options.rs",
"old": "Layer $CODEX_HOME/<name>.config.toml on top of the base user config",
"new": "Layer $DEV_HOME/<name>.config.toml on top of the base user config",
"count": 1
},
{
"file": "exec/src/cli.rs",
"old": "Do not load `$CODEX_HOME/config.toml`; auth still uses `CODEX_HOME`",
"new": "Do not load `$DEV_HOME/config.toml`; auth still uses `DEV_HOME`",
"count": 1
},
{
"file": "cli/src/doctor.rs",
"old": "Fix the reported config error, then rerun codex doctor.",
"new": "Fix the reported config error, then rerun dev doctor.",
"count": 1
},
{
"file": "cli/src/doctor/output.rs",
"old": "Run codex doctor without --summary for detailed diagnostics.",
"new": "Run dev doctor without --summary for detailed diagnostics.",
"count": 3
},
{
"file": "cli/src/doctor.rs",
"old": "CODEX_HOME was resolved without config",
"new": "DEV_HOME was resolved without config",
"count": 1
},
{
"file": "cli/src/doctor.rs",
"old": "CODEX_HOME could not be resolved",
"new": "DEV_HOME could not be resolved",
"count": 1
},
{
"file": "cli/src/doctor.rs",
"old": "CODEX_HOME: {}",
"new": "DEV_HOME: {}",
"count": 2
},
{
"file": "cli/src/doctor.rs",
"old": "path_readiness(&mut details, \"CODEX_HOME\"",
"new": "path_readiness(&mut details, \"DEV_HOME\"",
"count": 1
},
{
"file": "cli/src/doctor.rs",
"old": " codex_version: String,\n checks: Vec<DoctorCheck>,",
"new": " #[serde(rename = \"devVersion\")]\n codex_version: String,\n checks: Vec<DoctorCheck>,",
"count": 1
},
{
"file": "cli/src/doctor.rs",
"old": " codex_version: String,\n checks: BTreeMap<String, JsonDoctorCheck>,",
"new": " #[serde(rename = \"devVersion\")]\n codex_version: String,\n checks: BTreeMap<String, JsonDoctorCheck>,",
"count": 1
},
{
"file": "cli/src/lib.rs",
"old": "JSON value from `codex/sandbox-state-meta` to apply directly",
"new": "JSON value from the MCP sandbox state capability to apply directly",
"count": 1
},
{
"file": "core/Cargo.toml",
"old": "[dependencies]",
"new": "[dependencies]\nhanzo-loop = { path = \"../../../../crates/hanzo-loop\" }",
"count": 1
},
{
"file": "core/src/session/turn.rs",
"old": " Ok(Arc::new(build_tool_router(\n",
"new": " // Hanzo: the thread's controller shortlists this step's MCP tools.\n if let Some(handle) = sess\n .services\n .thread_extension_data\n .get::<hanzo_loop::Handle>()\n {\n let cards = all_mcp_tools\n .iter()\n .map(|tool| hanzo_loop::Card {\n name: tool.canonical_tool_name().to_string(),\n description: tool.tool.description.as_deref().unwrap_or_default().to_string(),\n })\n .collect();\n if let Some(shortlist) = handle.tools(&turn_context.sub_id, cards).await {\n step_store.insert(shortlist);\n }\n }\n Ok(Arc::new(build_tool_router(\n",
"count": 1
},
{
"file": "core/src/tools/spec_plan.rs",
"old": " apply_mcp_tool_exposure_policy(\n turn_context,\n model_info,\n mcp,\n &registered_mcp_tools,\n &mut registry,\n );\n",
"new": " apply_mcp_tool_exposure_policy(\n turn_context,\n model_info,\n mcp,\n &registered_mcp_tools,\n &mut registry,\n );\n // Hanzo: MCP tools off the controller's shortlist leave direct view; tool search\n // still finds them when the model supports it.\n if let Some(shortlist) = step_store.get::<hanzo_loop::Shortlist>() {\n let search = model_info.supports_search_tool;\n for tool in registry.entries_mut() {\n let name = tool.runtime.tool_name();\n if !registered_mcp_tools.contains(&name) || shortlist.keeps(&name.to_string()) {\n continue;\n }\n tool.exposure = match (tool.exposure, search) {\n (ToolExposure::Direct, true) => ToolExposure::Deferred,\n (ToolExposure::DirectModelOnly, true) => ToolExposure::DeferredModelOnly,\n (exposure, _) if exposure.is_direct() => ToolExposure::Hidden,\n (exposure, _) => exposure,\n };\n }\n }\n",
"count": 1
},
{
"file": "core/src/tools/orchestrator.rs",
"old": " let requirement = tool.exec_approval_requirement(req).unwrap_or_else(|| {\n default_exec_approval_requirement(approval_policy, &file_system_sandbox_policy)\n });\n",
"new": " let requirement = tool.exec_approval_requirement(req).unwrap_or_else(|| {\n default_exec_approval_requirement(approval_policy, &file_system_sandbox_policy)\n });\n // Hanzo: the thread's controller joins the policy on allow < ask < deny; it never\n // loosens it.\n let requirement = match tool_ctx\n .session\n .services\n .thread_extension_data\n .get::<hanzo_loop::Handle>()\n {\n None => requirement,\n Some(handle) => {\n let policy = match &requirement {\n ExecApprovalRequirement::Skip { .. } => hanzo_loop::Verdict::Allow,\n ExecApprovalRequirement::NeedsApproval { .. } => hanzo_loop::Verdict::Ask,\n ExecApprovalRequirement::Forbidden { .. } => hanzo_loop::Verdict::Deny,\n };\n let action = tool\n .approval_action(req, &tool_ctx.call_id)\n .ok()\n .and_then(|action| serde_json::to_value(action).ok())\n .unwrap_or_default();\n let turn = &tool_ctx.step_context.turn.sub_id;\n match handle.command(turn, &tool_ctx.call_id, policy, action).await {\n verdict if verdict == policy => requirement,\n hanzo_loop::Verdict::Deny => ExecApprovalRequirement::Forbidden {\n reason: \"Kai refused this command.\".to_string(),\n },\n _ => ExecApprovalRequirement::NeedsApproval {\n reason: Some(\"Kai asks before this command runs.\".to_string()),\n proposed_execpolicy_amendment: None,\n },\n }\n }\n };\n",
"count": 1
},
{
"file": "core/src/session/turn.rs",
"old": " let user_input = turn_user_input(&input);\n",
"new": " let user_input = turn_user_input(&input);\n // Hanzo: the thread's controller adds routing hints to the turn's request metadata.\n if let Some(handle) = sess\n .services\n .thread_extension_data\n .get::<hanzo_loop::Handle>()\n {\n let request = hanzo_loop::Request {\n text: user_input\n .iter()\n .filter_map(|item| match item {\n UserInput::Text { text, .. } => Some(text.as_str()),\n _ => None,\n })\n .collect::<Vec<_>>()\n .join(\"\\n\"),\n images: user_input\n .iter()\n .any(|item| matches!(item, UserInput::Image { .. } | UserInput::LocalImage { .. })),\n };\n let hints = handle.route(&turn_context.sub_id, request).await;\n if !hints.is_empty() {\n let mut metadata = turn_context.config.responses_api_metadata.clone();\n metadata.extend(hints);\n turn_context\n .turn_metadata_state\n .set_responses_api_metadata(metadata);\n }\n }\n",
"count": 1
},
{
"file": "app-server/Cargo.toml",
"old": "[dependencies]",
"new": "[dependencies]\nhanzo-kai = { path = \"../../../../crates/hanzo-kai\" }",
"count": 1
},
{
"file": "app-server/src/extensions.rs",
"old": " codex_guardian_v2::install(&mut builder, auth_manager.clone(), thread_manager);",
"new": " // Hanzo: Kai decides in the loop; it runs only for a profile with a kai.toml.\n hanzo_kai::install(&mut builder, thread_manager.clone());\n codex_guardian_v2::install(&mut builder, auth_manager.clone(), thread_manager);",
"count": 1
},
{
"file": "core-plugins/src/remote_legacy.rs",
"old": " let base_url = config.chatgpt_base_url.trim_end_matches('/');\n let mut url = Url::parse(&format!(\"{base_url}/plugins/featured\"))",
"new": " // Featured plugins are served to a ChatGPT sign-in only; any other caller is\n // refused, so it is not asked.\n let Some(auth) = auth.filter(|auth| auth.uses_codex_backend()) else {\n return Ok(Vec::new());\n };\n let base_url = config.chatgpt_base_url.trim_end_matches('/');\n let mut url = Url::parse(&format!(\"{base_url}/plugins/featured\"))",
"count": 1
},
{
"file": "core-plugins/src/remote_legacy.rs",
"old": " if let Some(auth) = auth.filter(|auth| auth.uses_codex_backend()) {\n request =\n request.headers(codex_model_provider::auth_provider_from_auth(auth).to_auth_headers());\n }\n",
"new": " request = request.headers(codex_model_provider::auth_provider_from_auth(auth).to_auth_headers());\n",
"count": 1
},
{
"file": "core/src/tools/handlers/mod.rs",
"old": " if justification.is_some() && sandbox_permissions.is_none() {\n return Err(FunctionCallError::RespondToModel(\n \"`justification` requires an explicit `sandbox_permissions`; use `sandbox_permissions: \\\"require_escalated\\\"` for unsandboxed execution, or omit `justification`.\".to_string(),\n ));\n }\n\n Ok(sandbox_permissions.unwrap_or_default())",
"new": " // A justification explains an escalation. With none asked for there is\n // nothing for it to explain, so the call runs at the default permissions\n // rather than failing.\n let _ = justification;\n Ok(sandbox_permissions.unwrap_or_default())",
"count": 1
},
{
"file": "models-manager/Cargo.toml",
"old": "[dependencies]",
"new": "[dependencies]\nhanzo-config = { path = \"../../../../crates/hanzo-config\" }",
"count": 1
},
{
"file": "models-manager/src/model_info.rs",
"old": " warn!(\"Unknown model {slug} is used. This will use fallback model metadata.\");\n ModelInfo {\n slug: slug.to_string(),\n display_name: slug.to_string(),",
"new": " let known = hanzo_config::catalog::find(slug);\n if known.is_none() {\n warn!(\"Unknown model {slug} is used. This will use fallback model metadata.\");\n }\n let window = known.map_or(272_000, |model| model.window);\n ModelInfo {\n slug: slug.to_string(),\n display_name: known.map_or_else(|| slug.to_string(), |model| model.name.to_string()),",
"count": 1
},
{
"file": "models-manager/src/model_info.rs",
"old": " context_window: Some(272_000),\n max_context_window: Some(272_000),",
"new": " context_window: Some(window),\n max_context_window: Some(window),",
"count": 1
},
{
"file": "models-manager/src/model_info.rs",
"old": " input_modalities: default_input_modalities(),\n used_fallback_model_metadata: true, // this is the fallback model metadata",
"new": " input_modalities: match known {\n Some(model) if !model.vision => vec![codex_protocol::openai_models::InputModality::Text],\n _ => default_input_modalities(),\n },\n used_fallback_model_metadata: known.is_none(),",
"count": 1
},
{
"file": "tui/src/bottom_pane/chat_composer/sparkle.rs",
"old": " pub(crate) fn is_sparkle_model(model: &str) -> bool {\n model\n .split(|ch: char| !ch.is_alphanumeric() && ch != '_')\n .any(|part| part.eq_ignore_ascii_case(\"astra\"))\n }\n",
"new": " pub(crate) fn is_sparkle_model(_model: &str) -> bool {\n // Hanzo: the input stays plain; no starfield for any model.\n false\n }\n",
"count": 1
},
{
"file": "tui/src/slash_command.rs",
"old": " Logout,\n",
"new": " Logout,\n Login,\n Auth,\n",
"count": 1
},
{
"file": "tui/src/slash_command.rs",
"old": " SlashCommand::Logout => \"log out of Codex\",",
"new": " SlashCommand::Logout => \"sign out of Hanzo\",\n SlashCommand::Login => \"sign in to Hanzo\",\n SlashCommand::Auth => \"show who is signed in\",",
"count": 1
},
{
"file": "tui/src/slash_command.rs",
"old": " | SlashCommand::Logout\n | SlashCommand::MemoryDrop",
"new": " | SlashCommand::Logout\n | SlashCommand::Login\n | SlashCommand::MemoryDrop",
"count": 1
},
{
"file": "tui/src/slash_command.rs",
"old": " | SlashCommand::Status\n | SlashCommand::Daemon\n | SlashCommand::Warnings\n | SlashCommand::Pwd\n | SlashCommand::Usage\n | SlashCommand::DebugConfig",
"new": " | SlashCommand::Status\n | SlashCommand::Auth\n | SlashCommand::Daemon\n | SlashCommand::Warnings\n | SlashCommand::Pwd\n | SlashCommand::Usage\n | SlashCommand::DebugConfig",
"count": 1
},
{
"file": "tui/src/slash_command.rs",
"old": " pub fn supports_inline_args(self) -> bool {\n matches!(\n self,\n SlashCommand::Review",
"new": " pub fn supports_inline_args(self) -> bool {\n matches!(\n self,\n SlashCommand::Model\n | SlashCommand::Review",
"count": 1
},
{
"file": "tui/src/chatwidget/slash_dispatch.rs",
"old": " SlashCommand::Logout => {\n self.app_event_tx.send(AppEvent::Logout);\n }\n",
"new": " SlashCommand::Logout => {\n self.app_event_tx.send(AppEvent::Logout);\n }\n SlashCommand::Login => {\n // Hanzo: sign in through the Hanzo CLI, with its output shown here.\n let tx = self.app_event_tx.clone();\n hanzo_tui::account::login(move |line| {\n tx.send(AppEvent::InsertHistoryCell(Box::new(\n crate::history_cell::new_info_event(line, /*hint*/ None),\n )));\n });\n }\n SlashCommand::Auth => {\n hanzo_tui::account::show(|line| self.add_info_message(line, /*hint*/ None));\n }\n",
"count": 1
},
{
"file": "tui/src/chatwidget/slash_dispatch.rs",
"old": " SlashCommand::Rename if !trimmed.is_empty() => {",
"new": " SlashCommand::Model if !trimmed.is_empty() => {\n // Hanzo: `/model <name>` switches this session directly.\n let offered: Vec<String> = self\n .model_catalog\n .try_list_models()\n .unwrap_or_default()\n .into_iter()\n .map(|preset| preset.model)\n .collect();\n match hanzo_tui::model::pick(trimmed, &offered) {\n hanzo_tui::model::Pick::One(model) => {\n self.add_info_message(format!(\"Model set to {model}.\"), /*hint*/ None);\n self.app_event_tx.send(AppEvent::SelectSessionModel {\n model,\n effort: None,\n });\n }\n hanzo_tui::model::Pick::Many(names) => self.add_error_message(format!(\n \"`{trimmed}` fits {}. Name one of them.\",\n names.join(\", \")\n )),\n hanzo_tui::model::Pick::None => self.add_error_message(format!(\n \"No model matches `{trimmed}`. Use /model to see the list.\"\n )),\n }\n }\n SlashCommand::Rename if !trimmed.is_empty() => {",
"count": 1
},
{
"file": "tui/src/chatwidget/slash_dispatch.rs",
"old": " | SlashCommand::Logout\n | SlashCommand::Mention",
"new": " | SlashCommand::Logout\n | SlashCommand::Login\n | SlashCommand::Auth\n | SlashCommand::Mention",
"count": 1
},
{
"file": "tui/src/chatwidget/slash_dispatch.rs",
"old": " SlashCommand::Status => {\n if self.should_prefetch_rate_limits() {",
"new": " SlashCommand::Status => {\n // Hanzo: who the session runs as, ahead of the card.\n hanzo_tui::account::show(|line| self.add_info_message(line, /*hint*/ None));\n if self.should_prefetch_rate_limits() {",
"count": 1
},
{
"file": "tui/src/app/event_dispatch.rs",
"old": " AppEvent::Logout => match app_server.logout_account().await {",
"new": " AppEvent::Logout => match {\n // Hanzo: the sign-in lives in the Hanzo CLI; sign out of it first.\n hanzo_tui::account::logout(|line| self.chat_widget.add_info_message(line, /*hint*/ None));\n app_server.logout_account().await\n } {",
"count": 1
},
{
"file": "tui/src/app/managed_worktree_creation.rs",
"old": "The local Codex service cannot check background terminals. Run `codex app-server daemon update`, then restart Codex.",
"new": "The local Dev service cannot check background terminals. Update Dev, then restart it.",
"count": 1
},
{
"file": "app-server/src/request_processors/account_processor/bedrock_setup.rs",
"old": "`codex logout`",
"new": "`dev logout`",
"count": 1
},
{
"file": "tui/src/app/startup.rs",
"old": "See the Codex keymap documentation",
"new": "See the Dev keymap documentation",
"count": 1
},
{
"file": "tui/src/onboarding/trust_directory.rs",
"old": "Trust this folder? Codex can read",
"new": "Trust this folder? Dev can read",
"count": 1
},
{
"file": "app-server/src/request_processors/account_processor/bedrock_setup.rs",
"old": "Codex-managed Bedrock credentials",
"new": "Dev-managed Bedrock credentials",
"count": 1
},
{
"file": "login/src/device_code_auth.rs",
"old": "Welcome to Codex [v",
"new": "Welcome to Hanzo Dev [v",
"count": 1
},
{
"file": "login/src/device_code_auth.rs",
"old": "OpenAI's command-line coding agent",
"new": "your Hanzo coding agent",
"count": 1
},
{
"file": "login/src/device_code_auth.rs",
"old": "started this login in Codex.",
"new": "started this login in Dev.",
"count": 1
},
{
"file": "config/src/tui_keymap.rs",
"old": "See the Codex keymap documentation",
"new": "See the Dev keymap documentation",
"count": 2
},
{
"file": "sandboxing/src/seatbelt.rs",
"old": "then restart Codex or its executor",
"new": "then restart Dev or its executor",
"count": 1
},
{
"file": "models-manager/models.json",
"old": "Codex",
"new": "Dev",
"count": 24
},
{
"file": "tui/assets/tooltips.txt",
"old": "Codex",
"new": "Dev",
"count": 4
},
{
"file": "memories/write/templates/memories/consolidation.md",
"old": "Codex",
"new": "Dev",
"count": 3
},
{
"file": "prompts/templates/realtime/backend_prompt.md",
"old": "Codex",
"new": "Dev",
"count": 1
},
{
"file": "prompts/templates/guardian/classifier_instructions.md",
"old": "Codex",
"new": "Dev",
"count": 1
},
{
"file": "models-manager/src/lib.rs",
"old": "pub fn bundled_models_response()\n-> std::result::Result<codex_protocol::openai_models::ModelsResponse, serde_json::Error> {\n serde_json::from_str(include_str!(\"../models.json\"))\n}",
"new": "pub fn bundled_models_response()\n-> std::result::Result<codex_protocol::openai_models::ModelsResponse, serde_json::Error> {\n use codex_protocol::openai_models::ModelVisibility;\n let mut response: codex_protocol::openai_models::ModelsResponse =\n serde_json::from_str(include_str!(\"../models.json\"))?;\n // Hanzo: the Hanzo catalog leads the picker, with the default first. The bundled\n // OpenAI models stay known, for lookups, but unlisted.\n for model in &mut response.models {\n model.visibility = ModelVisibility::Hide;\n }\n let default = hanzo_config::DEFAULT_MODEL;\n let served = hanzo_config::catalog::MODELS\n .iter()\n .map(|model| model.slug)\n .filter(|slug| !slug.contains('/') && *slug != default);\n let mut models: Vec<_> = std::iter::once(default)\n .chain(served)\n .enumerate()\n .map(|(index, slug)| {\n let mut info = model_info::model_info_from_slug(slug);\n info.visibility = ModelVisibility::List;\n info.priority = index as i32;\n info\n })\n .collect();\n models.append(&mut response.models);\n response.models = models;\n Ok(response)\n}",
"count": 1
},
{
"file": "tui/src/updates.rs",
"old": " if !config.check_for_update_on_startup || is_source_build_version(CODEX_CLI_VERSION) {",
"new": " if !hanzo_tui::UPDATE_CHECK\n || !config.check_for_update_on_startup\n || is_source_build_version(CODEX_CLI_VERSION)\n {",
"count": 2
},
{
"file": "tui/src/startup_orchestration.rs",
"old": " if cli.no_daemon && explicit_remote_endpoint.is_some() {\n return Err(std::io::Error::other(\n \"--no-daemon cannot be used with --remote.\",\n ));\n }\n",
"new": " if !hanzo_tui::BACKGROUND_SERVER && explicit_remote_endpoint.is_none() {\n cli.no_daemon = true;\n }\n if cli.no_daemon && explicit_remote_endpoint.is_some() {\n return Err(std::io::Error::other(\n \"--no-daemon cannot be used with --remote.\",\n ));\n }\n",
"count": 1
},
{
"file": "protocol/src/permissions.rs",
"old": "const PROTECTED_METADATA_CODEX_PATH_NAME: &str = \".codex\";",
"new": "/// The directory a project keeps Hanzo's settings in; Dev's own are under `dev/` in it,\n/// the same layout as `~/.hanzo/dev`. Another product's directory is not Dev's to read.\npub const PROJECT_DIR: &str = \".hanzo\";\nconst PROTECTED_METADATA_CODEX_PATH_NAME: &str = PROJECT_DIR;",
"count": 1
},
{
"file": "protocol/src/permissions.rs",
"old": "append_default_read_only_project_root_subpath_if_no_explicit_rule(&mut entries, \".codex\");",
"new": "append_default_read_only_project_root_subpath_if_no_explicit_rule(&mut entries, PROJECT_DIR);",
"count": 1
},
{
"file": "config/src/loader/mod.rs",
"old": "let dot_codex_abs = dir.join(\".codex\");",
"new": "let dot_codex_abs = dir.join(codex_protocol::permissions::PROJECT_DIR).join(\"dev\");",
"count": 1
},
{
"file": "config/src/loader/mod.rs",
"old": "Some(repo_root.join(relative_dir).join(\".codex\"))",
"new": "Some(\n repo_root\n .join(relative_dir)\n .join(codex_protocol::permissions::PROJECT_DIR)\n .join(\"dev\"),\n )",
"count": 1
},
{
"file": "config/src/loader/mod.rs",
"old": "const SYSTEM_CONFIG_TOML_FILE_UNIX: &str = \"/etc/codex/config.toml\";",
"new": "const SYSTEM_CONFIG_TOML_FILE_UNIX: &str = \"/etc/hanzo/dev/config.toml\";",
"count": 1
},
{
"file": "config/src/loader/mod.rs",
"old": "AbsolutePathBuf::from_absolute_path(Path::new(\"/etc/codex/requirements.toml\"))",
"new": "AbsolutePathBuf::from_absolute_path(Path::new(\"/etc/hanzo/dev/requirements.toml\"))",
"count": 1
},
{
"file": "config/src/loader/layer_io.rs",
"old": "const CODEX_MANAGED_CONFIG_SYSTEM_PATH: &str = \"/etc/codex/managed_config.toml\";",
"new": "const CODEX_MANAGED_CONFIG_SYSTEM_PATH: &str = \"/etc/hanzo/dev/managed_config.toml\";",
"count": 1
},
{
"file": "config/src/loader/mod.rs",
"old": "program_data.join(\"OpenAI\").join(\"Codex\")",
"new": "program_data.join(\"Hanzo\").join(\"Dev\")",
"count": 1
},
{
"file": "config/src/loader/macos.rs",
"old": "const MANAGED_PREFERENCES_APPLICATION_ID: &str = \"com.openai.codex\";",
"new": "const MANAGED_PREFERENCES_APPLICATION_ID: &str = \"ai.hanzo.dev\";",
"count": 1
},
{
"file": "models-manager/src/lib.rs",
"old": " format!(\n \"{}.{}.{}\",\n env!(\"CARGO_PKG_VERSION_MAJOR\"),\n env!(\"CARGO_PKG_VERSION_MINOR\"),\n env!(\"CARGO_PKG_VERSION_PATCH\")\n )",
"new": " let version = hanzo_version::get();\n version.split(['-', '+']).next().unwrap_or(version).to_string()",
"count": 1
},
{
"file": "rmcp-client/src/utils.rs",
"old": "pub(crate) const MCP_USER_AGENT: &str = concat!(\"codex-mcp-client/\", env!(\"CARGO_PKG_VERSION\"));",
"new": "pub(crate) static MCP_USER_AGENT: std::sync::LazyLock<String> =\n std::sync::LazyLock::new(|| format!(\"codex-mcp-client/{}\", hanzo_version::get()));",
"count": 1
},
{
"file": "rmcp-client/src/utils.rs",
"old": "HeaderValue::from_static(MCP_USER_AGENT)",
"new": "HeaderValue::from_static(&MCP_USER_AGENT)",
"count": 1
},
{
"file": "rmcp-client/src/oauth_http_client.rs",
"old": "HeaderValue::from_static(MCP_USER_AGENT)",
"new": "HeaderValue::from_static(&MCP_USER_AGENT)",
"count": 2
},
{
"file": "rmcp-client/src/oauth_http_client_security_tests.rs",
"old": " } else {\n MCP_USER_AGENT\n },",
"new": " } else {\n MCP_USER_AGENT.as_str()\n },",
"count": 1
},
{
"file": "rmcp-client/src/oauth_http_client_security_tests.rs",
"old": ".and(header(\"user-agent\", MCP_USER_AGENT))",
"new": ".and(header(\"user-agent\", MCP_USER_AGENT.as_str()))",
"count": 1
},
{
"file": "rmcp-client/src/oauth_client_registration_tests.rs",
"old": ".and(header(\"user-agent\", MCP_USER_AGENT))",
"new": ".and(header(\"user-agent\", MCP_USER_AGENT.as_str()))",
"count": 1
},
{
"file": "cli/src/doctor/updates.rs",
"old": "concat!(\"codex-doctor/\", env!(\"CARGO_PKG_VERSION\"))",
"new": "format!(\"codex-doctor/{}\", hanzo_version::get())",
"count": 1
},
{
"file": "tui/src/tui.rs",
"old": " set_modes()?;\n\n set_panic_hook();",
"new": " set_modes()?;\n if hanzo_tui::MONOCHROME {\n crossterm::style::force_color_output(false);\n }\n\n set_panic_hook();",
"count": 1
},
{
"file": "tui/src/insert_history.rs",
"old": " if next_fg != fg || next_bg != bg {",
"new": " // A disabled color writes an empty SGR, which would also drop the span's weight.\n if (next_fg != fg || next_bg != bg) && !crossterm::style::Colored::ansi_color_disabled_memoized() {",
"count": 1
},
{
"file": "tui/src/chatwidget/rendering.rs",
"old": " options.separate_status_line = options.command_popup_placement\n != crate::bottom_pane::CommandPopupPlacement::AboveComposer;",
"new": " options.separate_status_line = hanzo_tui::SEPARATE_STATUS_LINE\n && options.command_popup_placement\n != crate::bottom_pane::CommandPopupPlacement::AboveComposer;",
"count": 1
},
{
"file": "tui/src/startup_draft_layout.rs",
"old": " separate_status_line: true,",
"new": " separate_status_line: hanzo_tui::SEPARATE_STATUS_LINE,",
"count": 1
},
{
"file": "model-provider/Cargo.toml",
"old": "[dependencies]",
"new": "[dependencies]\nhanzo-config = { path = \"../../../../crates/hanzo-config\" }",
"count": 1
},
{
"file": "model-provider/src/provider.rs",
"old": " fn approval_review_preferred_model(&self) -> &'static str {\n if self\n .auth_manager\n .as_ref()\n .and_then(|auth_manager| auth_manager.auth_cached())\n .is_some_and(|auth| auth.is_api_key_auth())\n {\n API_KEY_APPROVAL_REVIEW_PREFERRED_MODEL\n } else {\n DEFAULT_APPROVAL_REVIEW_PREFERRED_MODEL\n }\n }\n",
"new": " fn approval_review_preferred_model(&self) -> &'static str {\n // Hanzo: api.hanzo.ai serves none of OpenAI's own ids; Enso routes the review.\n if hanzo_config::is_hanzo(self.info.base_url.as_deref()) {\n return hanzo_config::DEFAULT_MODEL;\n }\n if self\n .auth_manager\n .as_ref()\n .and_then(|auth_manager| auth_manager.auth_cached())\n .is_some_and(|auth| auth.is_api_key_auth())\n {\n API_KEY_APPROVAL_REVIEW_PREFERRED_MODEL\n } else {\n DEFAULT_APPROVAL_REVIEW_PREFERRED_MODEL\n }\n }\n\n fn memory_extraction_preferred_model(&self) -> &'static str {\n if hanzo_config::is_hanzo(self.info.base_url.as_deref()) {\n return hanzo_config::DEFAULT_MODEL;\n }\n DEFAULT_MEMORY_EXTRACTION_PREFERRED_MODEL\n }\n\n fn memory_consolidation_preferred_model(&self) -> &'static str {\n if hanzo_config::is_hanzo(self.info.base_url.as_deref()) {\n return hanzo_config::DEFAULT_MODEL;\n }\n DEFAULT_MEMORY_CONSOLIDATION_PREFERRED_MODEL\n }\n",
"count": 1
},
{
"file": "core/src/guardian/reviewer_config.rs",
"old": " let available_models = session\n .services\n .models_manager\n .list_models(\n codex_models_manager::manager::RefreshStrategy::Offline,\n turn.config.http_client_factory(),\n )\n .await;\n let default_review_model_id = turn.provider.approval_review_preferred_model();\n",
"new": " let mut available_models = session\n .services\n .models_manager\n .list_models(\n codex_models_manager::manager::RefreshStrategy::Offline,\n turn.config.http_client_factory(),\n )\n .await;\n // Hanzo: off OpenAI a provider serves the models its catalog lists. The bundled\n // OpenAI entries ride along unlisted, for lookups, and no other provider serves them.\n if !turn.provider.info().is_openai() {\n available_models.retain(|preset| preset.show_in_picker);\n }\n let default_review_model_id = turn.provider.approval_review_preferred_model();\n",
"count": 1
}
]