use codex_cli_sdk::config::ApprovalPolicy;
use codex_cli_sdk::permissions::{ApprovalCallback, ApprovalContext, ApprovalDecision};
use codex_cli_sdk::{Codex, CodexConfig, ThreadOptions};
use std::sync::Arc;
#[tokio::main]
async fn main() -> codex_cli_sdk::Result<()> {
let codex = Codex::new(CodexConfig::default())?;
let options = ThreadOptions::builder()
.approval(ApprovalPolicy::OnRequest)
.build();
let callback: ApprovalCallback = Arc::new(|ctx: ApprovalContext| {
Box::pin(async move {
let cmd = &ctx.request.command;
println!("\n[approval] {cmd}");
if cmd.starts_with("cat ")
|| cmd.starts_with("ls ")
|| cmd.starts_with("find ")
|| cmd.starts_with("grep ")
{
println!(" -> Approved (read-only)");
ApprovalDecision::Approved.into()
} else if cmd.starts_with("cargo ") || cmd.starts_with("rustfmt ") {
println!(" -> Approved for session (build tool)");
ApprovalDecision::ApprovedForSession.into()
} else if cmd.starts_with("rm ") || cmd.starts_with("sudo ") {
println!(" -> Denied (destructive)");
ApprovalDecision::Denied.into()
} else {
println!(" -> Approved");
ApprovalDecision::Approved.into()
}
})
});
let mut thread = codex.start_thread(options).with_approval_callback(callback);
let turn = thread
.run(
"Set up a new Rust project called my-app",
Default::default(),
)
.await?;
println!("\nResponse:\n{}", turn.final_response);
Ok(())
}