diff --git a/codex-rs/Cargo.lock b/codex-rs/Cargo.lock index a72c8858..ec6420a0 100644 --- a/codex-rs/Cargo.lock +++ b/codex-rs/Cargo.lock @@ -979,7 +979,6 @@ dependencies = [ "codex-mcp-server", "codex-process-hardening", "codex-protocol", - "codex-protocol-ts", "codex-responses-api-proxy", "codex-rmcp-client", "codex-stdio-to-uds", @@ -1363,16 +1362,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "codex-protocol-ts" -version = "0.0.0" -dependencies = [ - "anyhow", - "clap", - "codex-app-server-protocol", - "ts-rs", -] - [[package]] name = "codex-responses-api-proxy" version = "0.0.0" diff --git a/codex-rs/Cargo.toml b/codex-rs/Cargo.toml index d732151c..dd074e1d 100644 --- a/codex-rs/Cargo.toml +++ b/codex-rs/Cargo.toml @@ -25,7 +25,6 @@ members = [ "ollama", "process-hardening", "protocol", - "protocol-ts", "rmcp-client", "responses-api-proxy", "stdio-to-uds", @@ -75,7 +74,6 @@ codex-ollama = { path = "ollama" } codex-otel = { path = "otel" } codex-process-hardening = { path = "process-hardening" } codex-protocol = { path = "protocol" } -codex-protocol-ts = { path = "protocol-ts" } codex-responses-api-proxy = { path = "responses-api-proxy" } codex-rmcp-client = { path = "rmcp-client" } codex-stdio-to-uds = { path = "stdio-to-uds" } diff --git a/codex-rs/cli/Cargo.toml b/codex-rs/cli/Cargo.toml index 041644b3..c5a55bb2 100644 --- a/codex-rs/cli/Cargo.toml +++ b/codex-rs/cli/Cargo.toml @@ -30,7 +30,6 @@ codex-login = { workspace = true } codex-mcp-server = { workspace = true } codex-process-hardening = { workspace = true } codex-protocol = { workspace = true } -codex-protocol-ts = { workspace = true } codex-responses-api-proxy = { workspace = true } codex-rmcp-client = { workspace = true } codex-stdio-to-uds = { workspace = true } diff --git a/codex-rs/cli/src/main.rs b/codex-rs/cli/src/main.rs index 66f551a5..633f2605 100644 --- a/codex-rs/cli/src/main.rs +++ b/codex-rs/cli/src/main.rs @@ -99,9 +99,9 @@ enum Subcommand { /// Resume a previous interactive session (picker by default; use --last to continue the most recent). Resume(ResumeCommand), - /// Internal: generate TypeScript protocol bindings. - #[clap(hide = true)] + /// [experimental] Generate TypeScript bindings for the app server protocol. GenerateTs(GenerateTsCommand), + /// [EXPERIMENTAL] Browse tasks from Codex Cloud and apply changes locally. #[clap(name = "cloud", alias = "cloud-tasks")] Cloud(CloudTasksCli), @@ -528,7 +528,7 @@ async fn cli_main(codex_linux_sandbox_exe: Option) -> anyhow::Result<() .await??; } Some(Subcommand::GenerateTs(gen_cli)) => { - codex_protocol_ts::generate_ts(&gen_cli.out_dir, gen_cli.prettier.as_deref())?; + codex_app_server_protocol::generate_ts(&gen_cli.out_dir, gen_cli.prettier.as_deref())?; } Some(Subcommand::Features(FeaturesCli { sub })) => match sub { FeaturesSubcommand::List => { diff --git a/codex-rs/protocol-ts/Cargo.toml b/codex-rs/protocol-ts/Cargo.toml deleted file mode 100644 index 53f314cc..00000000 --- a/codex-rs/protocol-ts/Cargo.toml +++ /dev/null @@ -1,21 +0,0 @@ -[package] -edition = "2024" -name = "codex-protocol-ts" -version = { workspace = true } - -[lints] -workspace = true - -[lib] -name = "codex_protocol_ts" -path = "src/lib.rs" - -[[bin]] -name = "codex-protocol-ts" -path = "src/main.rs" - -[dependencies] -anyhow = { workspace = true } -clap = { workspace = true, features = ["derive"] } -codex-app-server-protocol = { workspace = true } -ts-rs = { workspace = true } diff --git a/codex-rs/protocol-ts/generate-ts b/codex-rs/protocol-ts/generate-ts deleted file mode 100755 index 8f90bced..00000000 --- a/codex-rs/protocol-ts/generate-ts +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -set -euo pipefail - -cd "$(dirname "$0")"/.. - -tmpdir=$(mktemp -d) -just codex generate-ts --prettier ../node_modules/.bin/prettier --out "$tmpdir" - -echo "wrote output to $tmpdir" diff --git a/codex-rs/protocol-ts/src/lib.rs b/codex-rs/protocol-ts/src/lib.rs deleted file mode 100644 index c3180d9b..00000000 --- a/codex-rs/protocol-ts/src/lib.rs +++ /dev/null @@ -1,135 +0,0 @@ -use anyhow::Context; -use anyhow::Result; -use anyhow::anyhow; -use codex_app_server_protocol::ClientNotification; -use codex_app_server_protocol::ClientRequest; -use codex_app_server_protocol::ServerNotification; -use codex_app_server_protocol::ServerRequest; -use codex_app_server_protocol::export_client_responses; -use codex_app_server_protocol::export_server_responses; -use std::ffi::OsStr; -use std::fs; -use std::io::Read; -use std::io::Write; -use std::path::Path; -use std::path::PathBuf; -use std::process::Command; -use ts_rs::TS; - -const HEADER: &str = "// GENERATED CODE! DO NOT MODIFY BY HAND!\n\n"; - -pub fn generate_ts(out_dir: &Path, prettier: Option<&Path>) -> Result<()> { - ensure_dir(out_dir)?; - - // Generate the TS bindings client -> server messages. - ClientRequest::export_all_to(out_dir)?; - export_client_responses(out_dir)?; - ClientNotification::export_all_to(out_dir)?; - - // Generate the TS bindings server -> client messages. - ServerRequest::export_all_to(out_dir)?; - export_server_responses(out_dir)?; - ServerNotification::export_all_to(out_dir)?; - - // Generate index.ts that re-exports all types. - generate_index_ts(out_dir)?; - - // Prepend header to each generated .ts file - let ts_files = ts_files_in(out_dir)?; - for file in &ts_files { - prepend_header_if_missing(file)?; - } - - // Format with Prettier by passing individual files (no shell globbing) - if let Some(prettier_bin) = prettier - && !ts_files.is_empty() - { - let status = Command::new(prettier_bin) - .arg("--write") - .arg("--log-level") - .arg("warn") - .args(ts_files.iter().map(|p| p.as_os_str())) - .status() - .with_context(|| format!("Failed to invoke Prettier at {}", prettier_bin.display()))?; - if !status.success() { - return Err(anyhow!("Prettier failed with status {status}")); - } - } - - Ok(()) -} - -fn ensure_dir(dir: &Path) -> Result<()> { - fs::create_dir_all(dir) - .with_context(|| format!("Failed to create output directory {}", dir.display())) -} - -fn prepend_header_if_missing(path: &Path) -> Result<()> { - let mut content = String::new(); - { - let mut f = fs::File::open(path) - .with_context(|| format!("Failed to open {} for reading", path.display()))?; - f.read_to_string(&mut content) - .with_context(|| format!("Failed to read {}", path.display()))?; - } - - if content.starts_with(HEADER) { - return Ok(()); - } - - let mut f = fs::File::create(path) - .with_context(|| format!("Failed to open {} for writing", path.display()))?; - f.write_all(HEADER.as_bytes()) - .with_context(|| format!("Failed to write header to {}", path.display()))?; - f.write_all(content.as_bytes()) - .with_context(|| format!("Failed to write content to {}", path.display()))?; - Ok(()) -} - -fn ts_files_in(dir: &Path) -> Result> { - let mut files = Vec::new(); - for entry in - fs::read_dir(dir).with_context(|| format!("Failed to read dir {}", dir.display()))? - { - let entry = entry?; - let path = entry.path(); - if path.is_file() && path.extension() == Some(OsStr::new("ts")) { - files.push(path); - } - } - files.sort(); - Ok(files) -} - -/// Generate an index.ts file that re-exports all generated types. -/// This allows consumers to import all types from a single file. -fn generate_index_ts(out_dir: &Path) -> Result { - let mut entries: Vec = Vec::new(); - let mut stems: Vec = ts_files_in(out_dir)? - .into_iter() - .filter_map(|p| { - let stem = p.file_stem()?.to_string_lossy().into_owned(); - if stem == "index" { None } else { Some(stem) } - }) - .collect(); - stems.sort(); - stems.dedup(); - - for name in stems { - entries.push(format!("export type {{ {name} }} from \"./{name}\";\n")); - } - - let mut content = - String::with_capacity(HEADER.len() + entries.iter().map(String::len).sum::()); - content.push_str(HEADER); - for line in &entries { - content.push_str(line); - } - - let index_path = out_dir.join("index.ts"); - let mut f = fs::File::create(&index_path) - .with_context(|| format!("Failed to create {}", index_path.display()))?; - f.write_all(content.as_bytes()) - .with_context(|| format!("Failed to write {}", index_path.display()))?; - Ok(index_path) -} diff --git a/codex-rs/protocol-ts/src/main.rs b/codex-rs/protocol-ts/src/main.rs deleted file mode 100644 index f477b9f5..00000000 --- a/codex-rs/protocol-ts/src/main.rs +++ /dev/null @@ -1,20 +0,0 @@ -use anyhow::Result; -use clap::Parser; -use std::path::PathBuf; - -#[derive(Parser, Debug)] -#[command(about = "Generate TypeScript bindings for the Codex protocol")] -struct Args { - /// Output directory where .ts files will be written - #[arg(short = 'o', long = "out", value_name = "DIR")] - out_dir: PathBuf, - - /// Optional path to the Prettier executable to format generated files - #[arg(short = 'p', long = "prettier", value_name = "PRETTIER_BIN")] - prettier: Option, -} - -fn main() -> Result<()> { - let args = Args::parse(); - codex_protocol_ts::generate_ts(&args.out_dir, args.prettier.as_deref()) -}