Phase 2: Rust Workspace Transformation (Part 1)

- Renamed directory: codex-backend-openapi-models -> llmx-backend-openapi-models
- Updated all Cargo.toml files:
  - Package names: codex-* -> llmx-*
  - Library names: codex_* -> llmx_*
  - Workspace dependencies updated
- Renamed Rust source files:
  - codex*.rs -> llmx*.rs (all modules)
  - codex_conversation -> llmx_conversation
  - codex_delegate -> llmx_delegate
  - codex_message_processor -> llmx_message_processor
  - codex_tool_* -> llmx_tool_*
- Updated all Rust imports:
  - use codex_* -> use llmx_*
  - mod codex* -> mod llmx*
- Updated environment variables in code:
  - CODEX_HOME -> LLMX_HOME
  - .codex -> .llmx paths
- Updated protocol crate lib name for proper linking

Note: Some compilation errors remain (type inference issues) but all
renaming is complete. Will fix compilation in next phase.

🤖 Generated with Claude Code
This commit is contained in:
Sebastian Krüger
2025-11-11 14:29:57 +01:00
parent f237fe560d
commit cb8d941adf
346 changed files with 3256 additions and 3199 deletions

View File

@@ -40,9 +40,9 @@ pub struct ApplyModalState {
}
use crate::scrollable_diff::ScrollableDiff;
use codex_cloud_tasks_client::CloudBackend;
use codex_cloud_tasks_client::TaskId;
use codex_cloud_tasks_client::TaskSummary;
use llmx_cloud_tasks_client::CloudBackend;
use llmx_cloud_tasks_client::TaskId;
use llmx_cloud_tasks_client::TaskSummary;
#[derive(Default)]
pub struct App {
pub tasks: Vec<TaskSummary>,
@@ -148,7 +148,7 @@ pub struct DiffOverlay {
#[derive(Clone, Debug, Default)]
pub struct AttemptView {
pub turn_id: Option<String>,
pub status: codex_cloud_tasks_client::AttemptStatus,
pub status: llmx_cloud_tasks_client::AttemptStatus,
pub attempt_placement: Option<i64>,
pub diff_lines: Vec<String>,
pub text_lines: Vec<String>,
@@ -316,7 +316,7 @@ pub enum AppEvent {
turn_id: Option<String>,
sibling_turn_ids: Vec<String>,
attempt_placement: Option<i64>,
attempt_status: codex_cloud_tasks_client::AttemptStatus,
attempt_status: llmx_cloud_tasks_client::AttemptStatus,
},
DetailsFailed {
id: TaskId,
@@ -325,10 +325,10 @@ pub enum AppEvent {
},
AttemptsLoaded {
id: TaskId,
attempts: Vec<codex_cloud_tasks_client::TurnAttempt>,
attempts: Vec<llmx_cloud_tasks_client::TurnAttempt>,
},
/// Background completion of new task submission
NewTaskSubmitted(Result<codex_cloud_tasks_client::CreatedTask, String>),
NewTaskSubmitted(Result<llmx_cloud_tasks_client::CreatedTask, String>),
/// Background completion of apply preflight when opening modal or on demand
ApplyPreflightFinished {
id: TaskId,
@@ -341,7 +341,7 @@ pub enum AppEvent {
/// Background completion of apply action (actual patch application)
ApplyFinished {
id: TaskId,
result: std::result::Result<codex_cloud_tasks_client::ApplyOutcome, String>,
result: std::result::Result<llmx_cloud_tasks_client::ApplyOutcome, String>,
},
}
@@ -357,11 +357,11 @@ mod tests {
}
#[async_trait::async_trait]
impl codex_cloud_tasks_client::CloudBackend for FakeBackend {
impl llmx_cloud_tasks_client::CloudBackend for FakeBackend {
async fn list_tasks(
&self,
env: Option<&str>,
) -> codex_cloud_tasks_client::Result<Vec<TaskSummary>> {
) -> llmx_cloud_tasks_client::Result<Vec<TaskSummary>> {
let key = env.map(str::to_string);
let titles = self
.by_env
@@ -373,11 +373,11 @@ mod tests {
out.push(TaskSummary {
id: TaskId(format!("T-{i}")),
title: t.to_string(),
status: codex_cloud_tasks_client::TaskStatus::Ready,
status: llmx_cloud_tasks_client::TaskStatus::Ready,
updated_at: Utc::now(),
environment_id: env.map(str::to_string),
environment_label: None,
summary: codex_cloud_tasks_client::DiffSummary::default(),
summary: llmx_cloud_tasks_client::DiffSummary::default(),
is_review: false,
attempt_total: Some(1),
});
@@ -388,8 +388,8 @@ mod tests {
async fn get_task_diff(
&self,
_id: TaskId,
) -> codex_cloud_tasks_client::Result<Option<String>> {
Err(codex_cloud_tasks_client::CloudTaskError::Unimplemented(
) -> llmx_cloud_tasks_client::Result<Option<String>> {
Err(llmx_cloud_tasks_client::CloudTaskError::Unimplemented(
"not used in test",
))
}
@@ -397,20 +397,20 @@ mod tests {
async fn get_task_messages(
&self,
_id: TaskId,
) -> codex_cloud_tasks_client::Result<Vec<String>> {
) -> llmx_cloud_tasks_client::Result<Vec<String>> {
Ok(vec![])
}
async fn get_task_text(
&self,
_id: TaskId,
) -> codex_cloud_tasks_client::Result<codex_cloud_tasks_client::TaskText> {
Ok(codex_cloud_tasks_client::TaskText {
) -> llmx_cloud_tasks_client::Result<llmx_cloud_tasks_client::TaskText> {
Ok(llmx_cloud_tasks_client::TaskText {
prompt: Some("Example prompt".to_string()),
messages: Vec::new(),
turn_id: Some("fake-turn".to_string()),
sibling_turn_ids: Vec::new(),
attempt_placement: Some(0),
attempt_status: codex_cloud_tasks_client::AttemptStatus::Completed,
attempt_status: llmx_cloud_tasks_client::AttemptStatus::Completed,
})
}
@@ -418,7 +418,7 @@ mod tests {
&self,
_task: TaskId,
_turn_id: String,
) -> codex_cloud_tasks_client::Result<Vec<codex_cloud_tasks_client::TurnAttempt>> {
) -> llmx_cloud_tasks_client::Result<Vec<llmx_cloud_tasks_client::TurnAttempt>> {
Ok(Vec::new())
}
@@ -426,8 +426,8 @@ mod tests {
&self,
_id: TaskId,
_diff_override: Option<String>,
) -> codex_cloud_tasks_client::Result<codex_cloud_tasks_client::ApplyOutcome> {
Err(codex_cloud_tasks_client::CloudTaskError::Unimplemented(
) -> llmx_cloud_tasks_client::Result<llmx_cloud_tasks_client::ApplyOutcome> {
Err(llmx_cloud_tasks_client::CloudTaskError::Unimplemented(
"not used in test",
))
}
@@ -436,8 +436,8 @@ mod tests {
&self,
_id: TaskId,
_diff_override: Option<String>,
) -> codex_cloud_tasks_client::Result<codex_cloud_tasks_client::ApplyOutcome> {
Err(codex_cloud_tasks_client::CloudTaskError::Unimplemented(
) -> llmx_cloud_tasks_client::Result<llmx_cloud_tasks_client::ApplyOutcome> {
Err(llmx_cloud_tasks_client::CloudTaskError::Unimplemented(
"not used in test",
))
}
@@ -449,8 +449,8 @@ mod tests {
_git_ref: &str,
_qa_mode: bool,
_best_of_n: usize,
) -> codex_cloud_tasks_client::Result<codex_cloud_tasks_client::CreatedTask> {
Err(codex_cloud_tasks_client::CloudTaskError::Unimplemented(
) -> llmx_cloud_tasks_client::Result<llmx_cloud_tasks_client::CreatedTask> {
Err(llmx_cloud_tasks_client::CloudTaskError::Unimplemented(
"not used in test",
))
}

View File

@@ -1,6 +1,6 @@
use clap::Args;
use clap::Parser;
use codex_common::CliConfigOverrides;
use llmx_common::CliConfigOverrides;
#[derive(Parser, Debug, Default)]
#[command(version)]

View File

@@ -8,7 +8,7 @@ pub mod util;
pub use cli::Cli;
use anyhow::anyhow;
use codex_login::AuthManager;
use llmx_login::AuthManager;
use std::io::IsTerminal;
use std::io::Read;
use std::path::PathBuf;
@@ -22,12 +22,12 @@ use util::append_error_log;
use util::set_user_agent_suffix;
struct ApplyJob {
task_id: codex_cloud_tasks_client::TaskId,
task_id: llmx_cloud_tasks_client::TaskId,
diff_override: Option<String>,
}
struct BackendContext {
backend: Arc<dyn codex_cloud_tasks_client::CloudBackend>,
backend: Arc<dyn llmx_cloud_tasks_client::CloudBackend>,
base_url: String,
}
@@ -43,13 +43,13 @@ async fn init_backend(user_agent_suffix: &str) -> anyhow::Result<BackendContext>
if use_mock {
return Ok(BackendContext {
backend: Arc::new(codex_cloud_tasks_client::MockClient),
backend: Arc::new(llmx_cloud_tasks_client::MockClient),
base_url,
});
}
let ua = codex_core::default_client::get_codex_user_agent();
let mut http = codex_cloud_tasks_client::HttpClient::new(base_url.clone())?.with_user_agent(ua);
let ua = llmx_core::default_client::get_codex_user_agent();
let mut http = llmx_cloud_tasks_client::HttpClient::new(base_url.clone())?.with_user_agent(ua);
let style = if base_url.contains("/backend-api") {
"wham"
} else {
@@ -106,7 +106,7 @@ async fn run_exec_command(args: crate::cli::ExecCommand) -> anyhow::Result<()> {
let ctx = init_backend("codex_cloud_tasks_exec").await?;
let prompt = resolve_query_input(query)?;
let env_id = resolve_environment_id(&ctx, &environment).await?;
let created = codex_cloud_tasks_client::CloudBackend::create_task(
let created = llmx_cloud_tasks_client::CloudBackend::create_task(
&*ctx.backend,
&env_id,
&prompt,
@@ -192,17 +192,17 @@ fn resolve_query_input(query_arg: Option<String>) -> anyhow::Result<String> {
}
}
fn level_from_status(status: codex_cloud_tasks_client::ApplyStatus) -> app::ApplyResultLevel {
fn level_from_status(status: llmx_cloud_tasks_client::ApplyStatus) -> app::ApplyResultLevel {
match status {
codex_cloud_tasks_client::ApplyStatus::Success => app::ApplyResultLevel::Success,
codex_cloud_tasks_client::ApplyStatus::Partial => app::ApplyResultLevel::Partial,
codex_cloud_tasks_client::ApplyStatus::Error => app::ApplyResultLevel::Error,
llmx_cloud_tasks_client::ApplyStatus::Success => app::ApplyResultLevel::Success,
llmx_cloud_tasks_client::ApplyStatus::Partial => app::ApplyResultLevel::Partial,
llmx_cloud_tasks_client::ApplyStatus::Error => app::ApplyResultLevel::Error,
}
}
fn spawn_preflight(
app: &mut app::App,
backend: &Arc<dyn codex_cloud_tasks_client::CloudBackend>,
backend: &Arc<dyn llmx_cloud_tasks_client::CloudBackend>,
tx: &UnboundedSender<app::AppEvent>,
frame_tx: &UnboundedSender<Instant>,
title: String,
@@ -227,7 +227,7 @@ fn spawn_preflight(
task_id,
diff_override,
} = job;
let result = codex_cloud_tasks_client::CloudBackend::apply_task_preflight(
let result = llmx_cloud_tasks_client::CloudBackend::apply_task_preflight(
&*backend,
task_id.clone(),
diff_override,
@@ -264,7 +264,7 @@ fn spawn_preflight(
fn spawn_apply(
app: &mut app::App,
backend: &Arc<dyn codex_cloud_tasks_client::CloudBackend>,
backend: &Arc<dyn llmx_cloud_tasks_client::CloudBackend>,
tx: &UnboundedSender<app::AppEvent>,
frame_tx: &UnboundedSender<Instant>,
job: ApplyJob,
@@ -288,7 +288,7 @@ fn spawn_apply(
task_id,
diff_override,
} = job;
let result = codex_cloud_tasks_client::CloudBackend::apply_task(
let result = llmx_cloud_tasks_client::CloudBackend::apply_task(
&*backend,
task_id.clone(),
diff_override,
@@ -384,7 +384,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
append_error_log(format!(
"startup: wham_force_internal={} ua={}",
force_internal,
codex_core::default_client::get_codex_user_agent()
llmx_core::default_client::get_codex_user_agent()
));
// Non-blocking initial load so the in-box spinner can animate
app.status = "Loading tasks…".to_string();
@@ -509,7 +509,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> 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() + llmx_tui::ComposerInput::recommended_flush_delay());
}
}
// Keep spinner pulsing only while loading.
@@ -742,7 +742,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
let tx = tx.clone();
let task_id = id.clone();
tokio::spawn(async move {
match codex_cloud_tasks_client::CloudBackend::list_sibling_attempts(
match llmx_cloud_tasks_client::CloudBackend::list_sibling_attempts(
&*backend,
task_id.clone(),
turn_id,
@@ -871,7 +871,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
match result {
Ok(outcome) => {
app.status = outcome.message.clone();
if matches!(outcome.status, codex_cloud_tasks_client::ApplyStatus::Success) {
if matches!(outcome.status, llmx_cloud_tasks_client::ApplyStatus::Success) {
app.apply_modal = None;
app.diff_overlay = None;
// Refresh tasks after successful apply
@@ -1070,7 +1070,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
_ => {
if page.submitting {
// Ignore input while submitting
} else if let codex_tui::ComposerAction::Submitted(text) = page.composer.input(key) {
} else if let llmx_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!(
@@ -1085,9 +1085,9 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
let best_of_n = page.best_of_n;
tokio::spawn(async move {
let git_ref = if let Ok(cwd) = std::env::current_dir() {
if let Some(branch) = codex_core::git_info::default_branch_name(&cwd).await {
if let Some(branch) = llmx_core::git_info::default_branch_name(&cwd).await {
branch
} else if let Some(branch) = codex_core::git_info::current_branch_name(&cwd).await {
} else if let Some(branch) = llmx_core::git_info::current_branch_name(&cwd).await {
branch
} else {
"main".to_string()
@@ -1096,7 +1096,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
"main".to_string()
};
let result = codex_cloud_tasks_client::CloudBackend::create_task(&*backend, &env, &text, &git_ref, false, best_of_n).await;
let result = llmx_cloud_tasks_client::CloudBackend::create_task(&*backend, &env, &text, &git_ref, false, best_of_n).await;
let evt = match result {
Ok(ok) => app::AppEvent::NewTaskSubmitted(Ok(ok)),
Err(e) => app::AppEvent::NewTaskSubmitted(Err(format!("{e}"))),
@@ -1110,7 +1110,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
needs_redraw = true;
// If pasteburst is active, schedule a microflush 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() + llmx_tui::ComposerInput::recommended_flush_delay());
}
// Always schedule an immediate redraw for key edits in the composer.
let _ = frame_tx.send(Instant::now());
@@ -1449,12 +1449,12 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
let diff_id = id.clone();
let diff_title = title.clone();
tokio::spawn(async move {
match codex_cloud_tasks_client::CloudBackend::get_task_diff(&*backend, diff_id.clone()).await {
match llmx_cloud_tasks_client::CloudBackend::get_task_diff(&*backend, diff_id.clone()).await {
Ok(Some(diff)) => {
let _ = tx.send(app::AppEvent::DetailsDiffLoaded { id: diff_id, title: diff_title, diff });
}
Ok(None) => {
match codex_cloud_tasks_client::CloudBackend::get_task_text(&*backend, diff_id.clone()).await {
match llmx_cloud_tasks_client::CloudBackend::get_task_text(&*backend, diff_id.clone()).await {
Ok(text) => {
let evt = app::AppEvent::DetailsMessagesLoaded {
id: diff_id,
@@ -1475,7 +1475,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
}
Err(e) => {
append_error_log(format!("get_task_diff failed for {}: {e}", diff_id.0));
match codex_cloud_tasks_client::CloudBackend::get_task_text(&*backend, diff_id.clone()).await {
match llmx_cloud_tasks_client::CloudBackend::get_task_text(&*backend, diff_id.clone()).await {
Ok(text) => {
let evt = app::AppEvent::DetailsMessagesLoaded {
id: diff_id,
@@ -1504,7 +1504,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
let msg_id = id;
let msg_title = title;
tokio::spawn(async move {
if let Ok(text) = codex_cloud_tasks_client::CloudBackend::get_task_text(&*backend, msg_id.clone()).await {
if let Ok(text) = llmx_cloud_tasks_client::CloudBackend::get_task_text(&*backend, msg_id.clone()).await {
let evt = app::AppEvent::DetailsMessagesLoaded {
id: msg_id,
title: msg_title,
@@ -1531,7 +1531,7 @@ pub async fn run_main(cli: Cli, _codex_linux_sandbox_exe: Option<PathBuf>) -> an
}
if let Some(task) = app.tasks.get(app.selected).cloned() {
match codex_cloud_tasks_client::CloudBackend::get_task_diff(&*backend, task.id.clone()).await {
match llmx_cloud_tasks_client::CloudBackend::get_task_diff(&*backend, task.id.clone()).await {
Ok(Some(diff)) => {
let diff_override = Some(diff.clone());
let task_id = task.id.clone();
@@ -1712,8 +1712,8 @@ fn pretty_lines_from_error(raw: &str) -> Vec<String> {
#[cfg(test)]
mod tests {
use codex_tui::ComposerAction;
use codex_tui::ComposerInput;
use llmx_tui::ComposerAction;
use llmx_tui::ComposerInput;
use crossterm::event::KeyCode;
use crossterm::event::KeyEvent;
use crossterm::event::KeyModifiers;

View File

@@ -1,4 +1,4 @@
use codex_tui::ComposerInput;
use llmx_tui::ComposerInput;
pub struct NewTaskPage {
pub composer: ComposerInput,

View File

@@ -22,9 +22,9 @@ use crate::app::App;
use crate::app::AttemptView;
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 llmx_cloud_tasks_client::AttemptStatus;
use llmx_cloud_tasks_client::TaskStatus;
use llmx_tui::render_markdown_text;
pub fn draw(frame: &mut Frame, app: &mut App) {
let area = frame.area();
@@ -783,7 +783,7 @@ fn style_diff_line(raw: &str) -> Line<'static> {
Line::from(vec![Span::raw(raw.to_string())])
}
fn render_task_item(_app: &App, t: &codex_cloud_tasks_client::TaskSummary) -> ListItem<'static> {
fn render_task_item(_app: &App, t: &llmx_cloud_tasks_client::TaskSummary) -> ListItem<'static> {
let status = match t.status {
TaskStatus::Ready => "READY".green(),
TaskStatus::Pending => "PENDING".magenta(),

View File

@@ -2,12 +2,12 @@ use base64::Engine as _;
use chrono::Utc;
use reqwest::header::HeaderMap;
use codex_core::config::Config;
use codex_core::config::ConfigOverrides;
use codex_login::AuthManager;
use llmx_core::config::Config;
use llmx_core::config::ConfigOverrides;
use llmx_login::AuthManager;
pub fn set_user_agent_suffix(suffix: &str) {
if let Ok(mut guard) = codex_core::default_client::USER_AGENT_SUFFIX.lock() {
if let Ok(mut guard) = llmx_core::default_client::USER_AGENT_SUFFIX.lock() {
guard.replace(suffix.to_string());
}
}
@@ -79,7 +79,7 @@ pub async fn build_chatgpt_headers() -> HeaderMap {
use reqwest::header::USER_AGENT;
set_user_agent_suffix("codex_cloud_tasks_tui");
let ua = codex_core::default_client::get_codex_user_agent();
let ua = llmx_core::default_client::get_codex_user_agent();
let mut headers = HeaderMap::new();
headers.insert(
USER_AGENT,