Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8557,6 +8557,21 @@
},
"type": "object"
},
"MarketplaceLoadErrorInfo": {
"properties": {
"marketplacePath": {
"$ref": "#/definitions/v2/AbsolutePathBuf"
},
"message": {
"type": "string"
}
},
"required": [
"marketplacePath",
"message"
],
"type": "object"
},
"McpAuthStatus": {
"enum": [
"unsupported",
Expand Down Expand Up @@ -9515,6 +9530,13 @@
},
"type": "array"
},
"marketplaceLoadErrors": {
"default": [],
"items": {
"$ref": "#/definitions/v2/MarketplaceLoadErrorInfo"
},
"type": "array"
},
"marketplaces": {
"items": {
"$ref": "#/definitions/v2/PluginMarketplaceEntry"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5305,6 +5305,21 @@
},
"type": "object"
},
"MarketplaceLoadErrorInfo": {
"properties": {
"marketplacePath": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"message": {
"type": "string"
}
},
"required": [
"marketplacePath",
"message"
],
"type": "object"
},
"McpAuthStatus": {
"enum": [
"unsupported",
Expand Down Expand Up @@ -6263,6 +6278,13 @@
},
"type": "array"
},
"marketplaceLoadErrors": {
"default": [],
"items": {
"$ref": "#/definitions/MarketplaceLoadErrorInfo"
},
"type": "array"
},
"marketplaces": {
"items": {
"$ref": "#/definitions/PluginMarketplaceEntry"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,21 @@
},
"type": "object"
},
"MarketplaceLoadErrorInfo": {
"properties": {
"marketplacePath": {
"$ref": "#/definitions/AbsolutePathBuf"
},
"message": {
"type": "string"
}
},
"required": [
"marketplacePath",
"message"
],
"type": "object"
},
"PluginAuthPolicy": {
"enum": [
"ON_INSTALL",
Expand Down Expand Up @@ -246,6 +261,13 @@
},
"type": "array"
},
"marketplaceLoadErrors": {
"default": [],
"items": {
"$ref": "#/definitions/MarketplaceLoadErrorInfo"
},
"type": "array"
},
"marketplaces": {
"items": {
"$ref": "#/definitions/PluginMarketplaceEntry"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!

// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { AbsolutePathBuf } from "../AbsolutePathBuf";

export type MarketplaceLoadErrorInfo = { marketplacePath: AbsolutePathBuf, message: string, };
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// GENERATED CODE! DO NOT MODIFY BY HAND!

// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually.
import type { MarketplaceLoadErrorInfo } from "./MarketplaceLoadErrorInfo";
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Generate MarketplaceLoadErrorInfo TS schema file

PluginListResponse.ts now imports ./MarketplaceLoadErrorInfo, but this commit does not add schema/typescript/v2/MarketplaceLoadErrorInfo.ts (and index.ts also re-exports it). Any TypeScript consumer that compiles or bundles these generated schema types will fail module resolution (Cannot find module './MarketplaceLoadErrorInfo').

Useful? React with 👍 / 👎.

import type { PluginMarketplaceEntry } from "./PluginMarketplaceEntry";

export type PluginListResponse = { marketplaces: Array<PluginMarketplaceEntry>, remoteSyncError: string | null, featuredPluginIds: Array<string>, };
export type PluginListResponse = { marketplaces: Array<PluginMarketplaceEntry>, marketplaceLoadErrors: Array<MarketplaceLoadErrorInfo>, remoteSyncError: string | null, featuredPluginIds: Array<string>, };
1 change: 1 addition & 0 deletions codex-rs/app-server-protocol/schema/typescript/v2/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export type { LoginAccountParams } from "./LoginAccountParams";
export type { LoginAccountResponse } from "./LoginAccountResponse";
export type { LogoutAccountResponse } from "./LogoutAccountResponse";
export type { MarketplaceInterface } from "./MarketplaceInterface";
export type { MarketplaceLoadErrorInfo } from "./MarketplaceLoadErrorInfo";
export type { McpAuthStatus } from "./McpAuthStatus";
export type { McpElicitationArrayType } from "./McpElicitationArrayType";
export type { McpElicitationBooleanSchema } from "./McpElicitationBooleanSchema";
Expand Down
10 changes: 10 additions & 0 deletions codex-rs/app-server-protocol/src/protocol/v2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3146,11 +3146,21 @@ pub struct PluginListParams {
#[ts(export_to = "v2/")]
pub struct PluginListResponse {
pub marketplaces: Vec<PluginMarketplaceEntry>,
#[serde(default)]
pub marketplace_load_errors: Vec<MarketplaceLoadErrorInfo>,
pub remote_sync_error: Option<String>,
#[serde(default)]
pub featured_plugin_ids: Vec<String>,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
pub struct MarketplaceLoadErrorInfo {
pub marketplace_path: AbsolutePathBuf,
pub message: String,
}

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
#[serde(rename_all = "camelCase")]
#[ts(export_to = "v2/")]
Expand Down
2 changes: 1 addition & 1 deletion codex-rs/app-server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Example with notification opt-out:
- `experimentalFeature/list` — list feature flags with stage metadata (`beta`, `underDevelopment`, `stable`, etc.), enabled/default-enabled state, and cursor pagination. For non-beta flags, `displayName`/`description`/`announcement` are `null`.
- `collaborationMode/list` — list available collaboration mode presets (experimental, no pagination). This response omits built-in developer instructions; clients should either pass `settings.developer_instructions: null` when setting a mode to use Codex's built-in instructions, or provide their own instructions explicitly.
- `skills/list` — list skills for one or more `cwd` values (optional `forceReload`).
- `plugin/list` — list discovered plugin marketplaces and plugin state, including effective marketplace install/auth policy metadata and best-effort `featuredPluginIds` for the official curated marketplace. `interface.category` uses the marketplace category when present; otherwise it falls back to the plugin manifest category. Pass `forceRemoteSync: true` to refresh curated plugin state before listing (**under development; do not call from production clients yet**).
- `plugin/list` — list discovered plugin marketplaces and plugin state, including effective marketplace install/auth policy metadata, fail-open `marketplaceLoadErrors` entries for marketplace files that could not be parsed or loaded, and best-effort `featuredPluginIds` for the official curated marketplace. `interface.category` uses the marketplace category when present; otherwise it falls back to the plugin manifest category. Pass `forceRemoteSync: true` to refresh curated plugin state before listing (**under development; do not call from production clients yet**).
- `plugin/read` — read one plugin by `marketplacePath` plus `pluginName`, returning marketplace info, a list-style `summary`, manifest descriptions/interface metadata, and bundled skills/apps/MCP server names. Returned plugin skills include their current `enabled` state after local config filtering. Plugin app summaries also include `needsAuth` when the server can determine connector accessibility (**under development; do not call from production clients yet**).
- `skills/changed` — notification emitted when watched local skill files change.
- `app/list` — list available apps.
Expand Down
28 changes: 22 additions & 6 deletions codex-rs/app-server/src/codex_message_processor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5524,11 +5524,18 @@ impl CodexMessageProcessor {

let config_for_marketplace_listing = config.clone();
let plugins_manager_for_marketplace_listing = plugins_manager.clone();
let data = match tokio::task::spawn_blocking(move || {
let marketplaces = plugins_manager_for_marketplace_listing
let (data, marketplace_load_errors) = match tokio::task::spawn_blocking(move || {
let outcome = plugins_manager_for_marketplace_listing
.list_marketplaces_for_config(&config_for_marketplace_listing, &roots)?;
Ok::<Vec<PluginMarketplaceEntry>, MarketplaceError>(
marketplaces
Ok::<
(
Vec<PluginMarketplaceEntry>,
Vec<codex_app_server_protocol::MarketplaceLoadErrorInfo>,
),
MarketplaceError,
>((
outcome
.marketplaces
.into_iter()
.map(|marketplace| PluginMarketplaceEntry {
name: marketplace.name,
Expand All @@ -5552,11 +5559,19 @@ impl CodexMessageProcessor {
.collect(),
})
.collect(),
)
outcome
.errors
.into_iter()
.map(|err| codex_app_server_protocol::MarketplaceLoadErrorInfo {
marketplace_path: err.path,
message: err.message,
})
.collect(),
))
})
.await
{
Ok(Ok(data)) => data,
Ok(Ok(outcome)) => outcome,
Ok(Err(err)) => {
self.send_marketplace_error(request_id, err, "list marketplace plugins")
.await;
Expand Down Expand Up @@ -5598,6 +5613,7 @@ impl CodexMessageProcessor {
request_id,
PluginListResponse {
marketplaces: data,
marketplace_load_errors,
remote_sync_error,
featured_plugin_ids,
},
Expand Down
Loading
Loading