mirror of
https://github.com/openai/codex.git
synced 2026-06-01 19:02:59 +00:00
feat: Add marketplace source filtering and plugin share context (#21419)
Adds marketplaceKinds to plugin/list for local, workspace-directory, and shared-with-me; omitted params keep default local plus gated global behavior, while explicit kinds are exact. Exposes shareContext on plugin summaries from local share mappings and remote workspace/shared responses, including remotePluginId and nullable creator metadata. Adds shared-with-me listing through /ps/plugins/workspace/shared, renames the workspace remote namespace to workspace-directory, and keeps direct remote read/share/install/update/delete paths gated by plugins rather than remote_plugin.
This commit is contained in:
@@ -2144,6 +2144,14 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginListMarketplaceKind": {
|
||||
"enum": [
|
||||
"local",
|
||||
"workspace-directory",
|
||||
"shared-with-me"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginListParams": {
|
||||
"properties": {
|
||||
"cwds": {
|
||||
@@ -2155,6 +2163,16 @@
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"marketplaceKinds": {
|
||||
"description": "Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus the default remote catalog when enabled by feature flag.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PluginListMarketplaceKind"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
|
||||
@@ -12353,6 +12353,14 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginListMarketplaceKind": {
|
||||
"enum": [
|
||||
"local",
|
||||
"workspace-directory",
|
||||
"shared-with-me"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
@@ -12365,6 +12373,16 @@
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"marketplaceKinds": {
|
||||
"description": "Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus the default remote catalog when enabled by feature flag.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/v2/PluginListMarketplaceKind"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginListParams",
|
||||
@@ -12481,6 +12499,29 @@
|
||||
"title": "PluginReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareContext": {
|
||||
"properties": {
|
||||
"creatorAccountUserId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"creatorName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
@@ -12845,6 +12886,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareContext": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/v2/PluginShareContext"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Remote sharing context associated with this plugin when available."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/v2/PluginSource"
|
||||
}
|
||||
|
||||
@@ -8964,6 +8964,14 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginListMarketplaceKind": {
|
||||
"enum": [
|
||||
"local",
|
||||
"workspace-directory",
|
||||
"shared-with-me"
|
||||
],
|
||||
"type": "string"
|
||||
},
|
||||
"PluginListParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
@@ -8976,6 +8984,16 @@
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"marketplaceKinds": {
|
||||
"description": "Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus the default remote catalog when enabled by feature flag.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PluginListMarketplaceKind"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginListParams",
|
||||
@@ -9092,6 +9110,29 @@
|
||||
"title": "PluginReadResponse",
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareContext": {
|
||||
"properties": {
|
||||
"creatorAccountUserId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"creatorName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareDeleteParams": {
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"properties": {
|
||||
@@ -9456,6 +9497,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareContext": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginShareContext"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Remote sharing context associated with this plugin when available."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/PluginSource"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,14 @@
|
||||
"AbsolutePathBuf": {
|
||||
"description": "A path that is guaranteed to be absolute and normalized (though it is not guaranteed to be canonicalized or exist on the filesystem).\n\nIMPORTANT: When deserializing an `AbsolutePathBuf`, a base path must be set using [AbsolutePathBufGuard::new]. If no base path is set, the deserialization will fail unless the path being deserialized is already absolute.",
|
||||
"type": "string"
|
||||
},
|
||||
"PluginListMarketplaceKind": {
|
||||
"enum": [
|
||||
"local",
|
||||
"workspace-directory",
|
||||
"shared-with-me"
|
||||
],
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
@@ -16,6 +24,16 @@
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"marketplaceKinds": {
|
||||
"description": "Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus the default remote catalog when enabled by feature flag.",
|
||||
"items": {
|
||||
"$ref": "#/definitions/PluginListMarketplaceKind"
|
||||
},
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
]
|
||||
}
|
||||
},
|
||||
"title": "PluginListParams",
|
||||
|
||||
@@ -232,6 +232,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareContext": {
|
||||
"properties": {
|
||||
"creatorAccountUserId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"creatorName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -357,6 +380,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareContext": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginShareContext"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Remote sharing context associated with this plugin when available."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/PluginSource"
|
||||
}
|
||||
|
||||
@@ -251,6 +251,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareContext": {
|
||||
"properties": {
|
||||
"creatorAccountUserId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"creatorName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginSource": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -376,6 +399,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareContext": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginShareContext"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Remote sharing context associated with this plugin when available."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/PluginSource"
|
||||
}
|
||||
|
||||
@@ -167,6 +167,29 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareContext": {
|
||||
"properties": {
|
||||
"creatorAccountUserId": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"creatorName": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"remotePluginId": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"remotePluginId"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PluginShareListItem": {
|
||||
"properties": {
|
||||
"localPluginPath": {
|
||||
@@ -317,6 +340,17 @@
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"shareContext": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/definitions/PluginShareContext"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"description": "Remote sharing context associated with this plugin when available."
|
||||
},
|
||||
"source": {
|
||||
"$ref": "#/definitions/PluginSource"
|
||||
}
|
||||
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginListMarketplaceKind.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginListMarketplaceKind.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// 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.
|
||||
|
||||
export type PluginListMarketplaceKind = "local" | "workspace-directory" | "shared-with-me";
|
||||
@@ -2,10 +2,16 @@
|
||||
|
||||
// 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";
|
||||
import type { PluginListMarketplaceKind } from "./PluginListMarketplaceKind";
|
||||
|
||||
export type PluginListParams = {
|
||||
/**
|
||||
* Optional working directories used to discover repo marketplaces. When omitted,
|
||||
* only home-scoped marketplaces and the official curated marketplace are considered.
|
||||
*/
|
||||
cwds?: Array<AbsolutePathBuf> | null, };
|
||||
cwds?: Array<AbsolutePathBuf> | null,
|
||||
/**
|
||||
* Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus
|
||||
* the default remote catalog when enabled by feature flag.
|
||||
*/
|
||||
marketplaceKinds?: Array<PluginListMarketplaceKind> | null, };
|
||||
|
||||
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareContext.ts
generated
Normal file
5
codex-rs/app-server-protocol/schema/typescript/v2/PluginShareContext.ts
generated
Normal file
@@ -0,0 +1,5 @@
|
||||
// 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.
|
||||
|
||||
export type PluginShareContext = { remotePluginId: string, creatorAccountUserId: string | null, creatorName: string | null, };
|
||||
@@ -5,9 +5,14 @@ import type { PluginAuthPolicy } from "./PluginAuthPolicy";
|
||||
import type { PluginAvailability } from "./PluginAvailability";
|
||||
import type { PluginInstallPolicy } from "./PluginInstallPolicy";
|
||||
import type { PluginInterface } from "./PluginInterface";
|
||||
import type { PluginShareContext } from "./PluginShareContext";
|
||||
import type { PluginSource } from "./PluginSource";
|
||||
|
||||
export type PluginSummary = { id: string, name: string, source: PluginSource, installed: boolean, enabled: boolean, installPolicy: PluginInstallPolicy, authPolicy: PluginAuthPolicy,
|
||||
export type PluginSummary = { id: string, name: string,
|
||||
/**
|
||||
* Remote sharing context associated with this plugin when available.
|
||||
*/
|
||||
shareContext: PluginShareContext | null, source: PluginSource, installed: boolean, enabled: boolean, installPolicy: PluginInstallPolicy, authPolicy: PluginAuthPolicy,
|
||||
/**
|
||||
* Availability state for installing and using the plugin.
|
||||
*/
|
||||
|
||||
@@ -278,11 +278,13 @@ export type { PluginInstallParams } from "./PluginInstallParams";
|
||||
export type { PluginInstallPolicy } from "./PluginInstallPolicy";
|
||||
export type { PluginInstallResponse } from "./PluginInstallResponse";
|
||||
export type { PluginInterface } from "./PluginInterface";
|
||||
export type { PluginListMarketplaceKind } from "./PluginListMarketplaceKind";
|
||||
export type { PluginListParams } from "./PluginListParams";
|
||||
export type { PluginListResponse } from "./PluginListResponse";
|
||||
export type { PluginMarketplaceEntry } from "./PluginMarketplaceEntry";
|
||||
export type { PluginReadParams } from "./PluginReadParams";
|
||||
export type { PluginReadResponse } from "./PluginReadResponse";
|
||||
export type { PluginShareContext } from "./PluginShareContext";
|
||||
export type { PluginShareDeleteParams } from "./PluginShareDeleteParams";
|
||||
export type { PluginShareDeleteResponse } from "./PluginShareDeleteResponse";
|
||||
export type { PluginShareDiscoverability } from "./PluginShareDiscoverability";
|
||||
|
||||
@@ -132,6 +132,24 @@ pub struct PluginListParams {
|
||||
/// only home-scoped marketplaces and the official curated marketplace are considered.
|
||||
#[ts(optional = nullable)]
|
||||
pub cwds: Option<Vec<AbsolutePathBuf>>,
|
||||
/// Optional marketplace kind filter. When omitted, only local marketplaces are queried, plus
|
||||
/// the default remote catalog when enabled by feature flag.
|
||||
#[ts(optional = nullable)]
|
||||
pub marketplace_kinds: Option<Vec<PluginListMarketplaceKind>>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub enum PluginListMarketplaceKind {
|
||||
#[serde(rename = "local")]
|
||||
#[ts(rename = "local")]
|
||||
Local,
|
||||
#[serde(rename = "workspace-directory")]
|
||||
#[ts(rename = "workspace-directory")]
|
||||
WorkspaceDirectory,
|
||||
#[serde(rename = "shared-with-me")]
|
||||
#[ts(rename = "shared-with-me")]
|
||||
SharedWithMe,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
@@ -501,6 +519,8 @@ pub enum PluginAvailability {
|
||||
pub struct PluginSummary {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
/// Remote sharing context associated with this plugin when available.
|
||||
pub share_context: Option<PluginShareContext>,
|
||||
pub source: PluginSource,
|
||||
pub installed: bool,
|
||||
pub enabled: bool,
|
||||
@@ -514,6 +534,15 @@ pub struct PluginSummary {
|
||||
pub keywords: Vec<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
pub struct PluginShareContext {
|
||||
pub remote_plugin_id: String,
|
||||
pub creator_account_user_id: Option<String>,
|
||||
pub creator_name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
#[ts(export_to = "v2/")]
|
||||
|
||||
@@ -2843,7 +2843,33 @@ fn plugin_list_params_ignore_removed_force_remote_sync_field() {
|
||||
"forceRemoteSync": true,
|
||||
}))
|
||||
.unwrap(),
|
||||
PluginListParams { cwds: None },
|
||||
PluginListParams {
|
||||
cwds: None,
|
||||
marketplace_kinds: None,
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn plugin_list_params_serializes_marketplace_kind_filter() {
|
||||
assert_eq!(
|
||||
serde_json::to_value(PluginListParams {
|
||||
cwds: None,
|
||||
marketplace_kinds: Some(vec![
|
||||
PluginListMarketplaceKind::Local,
|
||||
PluginListMarketplaceKind::WorkspaceDirectory,
|
||||
PluginListMarketplaceKind::SharedWithMe,
|
||||
]),
|
||||
})
|
||||
.unwrap(),
|
||||
json!({
|
||||
"cwds": null,
|
||||
"marketplaceKinds": [
|
||||
"local",
|
||||
"workspace-directory",
|
||||
"shared-with-me",
|
||||
],
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -3099,6 +3125,7 @@ fn plugin_share_list_response_serializes_share_items() {
|
||||
plugin: PluginSummary {
|
||||
id: "plugins~Plugin_00000000000000000000000000000000".to_string(),
|
||||
name: "gmail".to_string(),
|
||||
share_context: None,
|
||||
source: PluginSource::Remote,
|
||||
installed: false,
|
||||
enabled: false,
|
||||
@@ -3118,6 +3145,7 @@ fn plugin_share_list_response_serializes_share_items() {
|
||||
"plugin": {
|
||||
"id": "plugins~Plugin_00000000000000000000000000000000",
|
||||
"name": "gmail",
|
||||
"shareContext": null,
|
||||
"source": { "type": "remote" },
|
||||
"installed": false,
|
||||
"enabled": false,
|
||||
@@ -3149,6 +3177,7 @@ fn plugin_summary_defaults_missing_availability_to_available() {
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(summary.availability, PluginAvailability::Available);
|
||||
assert_eq!(summary.share_context, None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user