Files
codex/prs/bolinfest/study/PR-1677-study.md
2025-09-02 15:17:45 -07:00

2.9 KiB
Raw Blame History

DOs

  • Return Named Structs: Replace multi-value tuple returns with small, public structs.
// Before
pub async fn spawn(config: Config, ctrl_c: Arc<Notify>) -> CodexResult<(Codex, String, Uuid)>;

// After
pub struct CodexSpawnOk {
    pub codex: Codex,
    pub init_id: String,
    pub session_id: Uuid,
}
pub async fn spawn(config: Config, ctrl_c: Arc<Notify>) -> CodexResult<CodexSpawnOk>;
  • Export New Types: Re-export structs from the crate root to stabilize the public API.
// codex-rs/core/src/lib.rs
pub use codex::CodexSpawnOk;
  • Use Clear “Ok” Naming: Name Ok-payload types with an Ok suffix when returned inside Result<T, E>.
pub struct CodexSpawnOk { /* ... */ } // Good: represents the Ok variant payload
  • Destructure With ..: Pull only the fields you need and ignore the rest succinctly.
let CodexSpawnOk { codex, .. } = Codex::spawn(config, ctrl_c.clone()).await?;
  • Prefer init_codex(): For high-level callers, use the wrapper that validates the first event and returns a cohesive conversation handle.
use codex_core::codex_wrapper::{init_codex, CodexConversation};

let CodexConversation {
    codex,
    session_configured,
    ctrl_c,
    session_id,
} = init_codex(config).await?;
  • Forward the Initial Event: Surface the validated SessionConfigured event to UIs/clients immediately.
// MCP server example
outgoing.send_event_as_notification(&session_configured).await;

// TUI example
app_event_tx.send(AppEvent::CodexEvent(session_configured.clone()));
  • Inline Format Variables: Use {var} directly in format! and logging macros.
info!("resume_path: {resume_path:?}");
info!("Codex initialized with event: {session_configured:?}");

DONTs

  • Dont Return Tuples: Avoid ambiguous, brittle tuple returns for multi-value results.
// Avoid
pub async fn spawn(...) -> CodexResult<(Codex, String, Uuid)>;
  • Dont Use “Result” In Type Names: If a type is the Ok payload (not a Result itself), dont name it ...Result.
// Avoid
pub struct CodexSpawnResult { /* ... */ }
  • Dont Revalidate First Event After init_codex(): It already checks that the first event is EventMsg::SessionConfigured.
// Avoid re-checking
match &session_configured.msg {
    EventMsg::SessionConfigured { .. } => { /* redundant */ }
    _ => unreachable!(),
}
  • Dont Bind Unused Fields: Skip needless variables; use .. in struct patterns.
// Avoid
let CodexSpawnOk { codex, init_id, session_id } = Codex::spawn(config, ctrl_c).await?;
// Prefer
let CodexSpawnOk { codex, .. } = Codex::spawn(config, ctrl_c).await?;
  • Dont Drop The Initial Event: Ensure the captured session_configured is forwarded; dont silently ignore it.
// Avoid: never sending the initial event to the client/UI
// Correct: always send `session_configured` as shown in the DOs above.