We had this annotation everywhere in app-server APIs which made it so that fields get serialized as `field?: T`, meaning if the field as `None` we would omit the field in the payload. Removing this annotation changes it so that we return `field: T | null` instead, which makes codex app-server's API more aligned with the convention of public OpenAI APIs like Responses. Separately, remove the `#[ts(optional_fields = nullable)]` annotations that were recently added which made all the TS types become `field?: T | null` which is not great since clients need to handle undefined and null. I think generally it'll be best to have optional types be either: - `field: T | null` (preferred, aligned with public OpenAI APIs) - `field?: T` where we have to, such as types generated from the MCP schema: https://github.com/modelcontextprotocol/modelcontextprotocol/blob/main/schema/2025-06-18/schema.ts (see changes to `mcp-types/`) I updated @etraut-openai's unit test to check that all generated TS types are one or the other, not both (so will error if we have a type that has `field?: T | null`). I don't think there's currently a good use case for that - but we can always revisit.
79 lines
2.2 KiB
Rust
79 lines
2.2 KiB
Rust
use std::fmt;
|
|
use std::path::PathBuf;
|
|
|
|
mod apply;
|
|
mod errors;
|
|
mod ghost_commits;
|
|
mod operations;
|
|
mod platform;
|
|
|
|
pub use apply::ApplyGitRequest;
|
|
pub use apply::ApplyGitResult;
|
|
pub use apply::apply_git_patch;
|
|
pub use apply::extract_paths_from_patch;
|
|
pub use apply::parse_git_apply_output;
|
|
pub use apply::stage_paths;
|
|
pub use errors::GitToolingError;
|
|
pub use ghost_commits::CreateGhostCommitOptions;
|
|
pub use ghost_commits::create_ghost_commit;
|
|
pub use ghost_commits::restore_ghost_commit;
|
|
pub use ghost_commits::restore_to_commit;
|
|
pub use platform::create_symlink;
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
use serde::Serialize;
|
|
use ts_rs::TS;
|
|
|
|
type CommitID = String;
|
|
|
|
/// Details of a ghost commit created from a repository state.
|
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, TS)]
|
|
pub struct GhostCommit {
|
|
id: CommitID,
|
|
parent: Option<CommitID>,
|
|
preexisting_untracked_files: Vec<PathBuf>,
|
|
preexisting_untracked_dirs: Vec<PathBuf>,
|
|
}
|
|
|
|
impl GhostCommit {
|
|
/// Create a new ghost commit wrapper from a raw commit ID and optional parent.
|
|
pub fn new(
|
|
id: CommitID,
|
|
parent: Option<CommitID>,
|
|
preexisting_untracked_files: Vec<PathBuf>,
|
|
preexisting_untracked_dirs: Vec<PathBuf>,
|
|
) -> Self {
|
|
Self {
|
|
id,
|
|
parent,
|
|
preexisting_untracked_files,
|
|
preexisting_untracked_dirs,
|
|
}
|
|
}
|
|
|
|
/// Commit ID for the snapshot.
|
|
pub fn id(&self) -> &str {
|
|
&self.id
|
|
}
|
|
|
|
/// Parent commit ID, if the repository had a `HEAD` at creation time.
|
|
pub fn parent(&self) -> Option<&str> {
|
|
self.parent.as_deref()
|
|
}
|
|
|
|
/// Untracked or ignored files that already existed when the snapshot was captured.
|
|
pub fn preexisting_untracked_files(&self) -> &[PathBuf] {
|
|
&self.preexisting_untracked_files
|
|
}
|
|
|
|
/// Untracked or ignored directories that already existed when the snapshot was captured.
|
|
pub fn preexisting_untracked_dirs(&self) -> &[PathBuf] {
|
|
&self.preexisting_untracked_dirs
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for GhostCommit {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
write!(f, "{}", self.id)
|
|
}
|
|
}
|