[codex] Add marketplace/remove app-server RPC (#17751)

## Summary

Add a new app-server `marketplace/remove` RPC on top of the shared
marketplace-remove implementation.

This change:
- adds `MarketplaceRemoveParams` / `MarketplaceRemoveResponse` to the
app-server protocol
- wires the new request through `codex_message_processor`
- reuses the shared core marketplace-remove flow from the stacked
refactor PR
- updates generated schema files and adds focused app-server coverage

## Validation

- `just write-app-server-schema`
- `just fmt`
- heavy compile/test coverage deferred to GitHub CI per request
This commit is contained in:
xli-oai
2026-04-19 23:22:49 -07:00
committed by GitHub
parent b44d2851cf
commit 1dc3535e17
16 changed files with 425 additions and 1 deletions
@@ -344,6 +344,10 @@ client_request_definitions! {
params: v2::MarketplaceAddParams,
response: v2::MarketplaceAddResponse,
},
MarketplaceRemove => "marketplace/remove" {
params: v2::MarketplaceRemoveParams,
response: v2::MarketplaceRemoveResponse,
},
PluginList => "plugin/list" {
params: v2::PluginListParams,
response: v2::PluginListResponse,
@@ -3481,6 +3481,21 @@ pub struct MarketplaceAddResponse {
pub already_added: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct MarketplaceRemoveParams {
pub marketplace_name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct MarketplaceRemoveResponse {
pub marketplace_name: String,
pub installed_root: Option<AbsolutePathBuf>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
@@ -8890,6 +8905,40 @@ mod tests {
);
}
#[test]
fn marketplace_remove_response_serializes_nullable_installed_root() {
let installed_root = if cfg!(windows) {
r"C:\marketplaces\debug"
} else {
"/tmp/marketplaces/debug"
};
let installed_root = AbsolutePathBuf::try_from(PathBuf::from(installed_root)).unwrap();
let installed_root_json = installed_root.as_path().display().to_string();
assert_eq!(
serde_json::to_value(MarketplaceRemoveResponse {
marketplace_name: "debug".to_string(),
installed_root: Some(installed_root),
})
.unwrap(),
json!({
"marketplaceName": "debug",
"installedRoot": installed_root_json,
}),
);
assert_eq!(
serde_json::to_value(MarketplaceRemoveResponse {
marketplace_name: "debug".to_string(),
installed_root: None,
})
.unwrap(),
json!({
"marketplaceName": "debug",
"installedRoot": null,
}),
);
}
#[test]
fn codex_error_info_serializes_http_status_code_in_camel_case() {
let value = CodexErrorInfo::ResponseTooManyFailedAttempts {