From e1a204b2d333a28ddf4c3381165368194a75f881 Mon Sep 17 00:00:00 2001 From: Yvette Carlisle Date: Mon, 8 Jun 2026 10:13:49 +0800 Subject: [PATCH] {"schema":"decodex/commit/1","summary":"Persist 2026-06-07 Radar archive contract","authority":"manual"} --- .../index/2026-06-07-pre-2026-05-17.json | 53 +++++++ .../openai-codex-pr-22414.analysis.json | 26 ---- .../openai-codex-pr-22425.analysis.json | 23 --- .../github/bundles/openai-codex-pr-22414.json | 142 ------------------ .../github/bundles/openai-codex-pr-22425.json | 93 ------------ 5 files changed, 53 insertions(+), 284 deletions(-) create mode 100644 artifacts/archive/index/2026-06-07-pre-2026-05-17.json delete mode 100644 artifacts/github/analysis/openai-codex-pr-22414.analysis.json delete mode 100644 artifacts/github/analysis/openai-codex-pr-22425.analysis.json delete mode 100644 artifacts/github/bundles/openai-codex-pr-22414.json delete mode 100644 artifacts/github/bundles/openai-codex-pr-22425.json diff --git a/artifacts/archive/index/2026-06-07-pre-2026-05-17.json b/artifacts/archive/index/2026-06-07-pre-2026-05-17.json new file mode 100644 index 000000000..ddf528a36 --- /dev/null +++ b/artifacts/archive/index/2026-06-07-pre-2026-05-17.json @@ -0,0 +1,53 @@ +{ + "archive_asset": { + "name": "decodex-radar-archive-2026-06-07-pre-2026-05-17.tar.zst", + "sha256": "2fe97a74e1ab03543013abd429305f0b3cc268f33e44b3ff3c527883983d762c", + "size_bytes": 7015 + }, + "archive_id": "2026-06-07-pre-2026-05-17", + "checksum_asset": { + "name": "SHA256SUMS", + "sha256": "809edb57502f5eb0b8a782f04932bf8aedbe12e4be48b0864e9a290e4ba1ce2e" + }, + "created_at": "2026-06-07T03:34:15Z", + "cutoff_evidence_before": "2026-05-17T03:33:29Z", + "files": [ + { + "evidence_date": "2026-05-13T04:17:20Z", + "evidence_source": "site/src/content/signals/openai-codex-pr-22414.json.published_at", + "kind": "analysis", + "path": "artifacts/github/analysis/openai-codex-pr-22414.analysis.json", + "sha256": "c6f13a69c921bc85b714df8e447ee467cd847fe911979e1126f36f4a9ace150a", + "size_bytes": 2587 + }, + { + "evidence_date": "2026-05-13T04:11:19Z", + "evidence_source": "site/src/content/signals/openai-codex-pr-22425.json.published_at", + "kind": "analysis", + "path": "artifacts/github/analysis/openai-codex-pr-22425.analysis.json", + "sha256": "4f90ff018b487d9cb9c173718102f530637f070fbd49a5fea24c1d3841cd5482", + "size_bytes": 2062 + }, + { + "evidence_date": "2026-05-13T04:17:20Z", + "evidence_source": "primary_pr.merged_at", + "kind": "bundle", + "path": "artifacts/github/bundles/openai-codex-pr-22414.json", + "sha256": "5c54d39a56cbb4b8a5af3bd7c737c59340d56877478ca999efc636798285edc5", + "size_bytes": 12693 + }, + { + "evidence_date": "2026-05-13T04:11:19Z", + "evidence_source": "primary_pr.merged_at", + "kind": "bundle", + "path": "artifacts/github/bundles/openai-codex-pr-22425.json", + "sha256": "9d5736b2b0c39c37f78d03e19fb93b42cfa2fe1187f0e2e499a9359674668add", + "size_bytes": 8656 + } + ], + "release_tag": "radar-archive-2026-06-07-pre-2026-05-17", + "release_url": "https://github.com/hack-ink/decodex/releases/tag/radar-archive-2026-06-07-pre-2026-05-17", + "retention_days": 21, + "schema": "radar_archive_manifest/v1", + "source_commit": "b63295eb9860acb7d2107e548492faeca9ac5f08" +} diff --git a/artifacts/github/analysis/openai-codex-pr-22414.analysis.json b/artifacts/github/analysis/openai-codex-pr-22414.analysis.json deleted file mode 100644 index 31a826249..000000000 --- a/artifacts/github/analysis/openai-codex-pr-22414.analysis.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "caveats": [ - "This is upstream merged code evidence; availability still depends on the Codex build or prerelease channel that includes PR #22414.", - "The PR keeps remote auth-token transport restricted to `wss://` and loopback `ws://` endpoints, so UDS support should not be framed as broad remote-auth relaxation." - ], - "confidence": "confirmed", - "config_flags": [ - "--remote" - ], - "expected_effect": "The remote Codex client connects to the app-server over the Unix socket while reusing the same JSON-RPC protocol; the TUI can also prefer the local daemon socket and fall back to its embedded app-server if the daemon is absent or unresponsive.", - "how_to_try": "On a Codex build that includes PR #22414, point the remote client at a Unix socket endpoint with `codex --remote unix://PATH`, or use `unix://` for the default daemon socket path when the daemon is configured for UDS.", - "impact": "medium", - "kind": "capability", - "proof_points": [ - "The PR body says `codex --remote` now accepts `ws://host:port`, `wss://host:port`, `unix://`, and `unix://PATH`.", - "`codex-rs/app-server-client/src/remote.rs` adds endpoint parsing and transport handling for WebSocket and Unix socket app-server endpoints.", - "`codex-rs/app-server-client/src/lib.rs` reuses the existing JSON-RPC client protocol over either a WebSocket stream or a Unix socket stream.", - "`codex-rs/tui/src/lib.rs` adds a fast startup probe for the default daemon socket and falls back to the embedded app-server when the daemon is missing or unresponsive.", - "The PR records focused coverage for UDS remote round trips, WebSocket auth headers, auth-token transport policy, remote address parsing, and missing-daemon fallback." - ], - "slug": "remote-codex-can-use-unix-sockets", - "summary": "Merged PR #22414 adds Unix domain socket endpoints to `codex --remote`. The remote app-server client can now use `unix://` or `unix://PATH` in addition to WebSocket URLs, while the TUI probes the default daemon socket before falling back to an embedded app-server.", - "title": "Remote Codex can use Unix socket endpoints", - "watch_state": "Track when this lands in a public prerelease, because Decodex Control Plane and app-server integrations may be able to prefer local UDS transport over loopback WebSocket wiring.", - "why_it_matters": "This is directly useful for Decodex Control Plane work built on the Codex app-server: local Unix sockets can reduce exposed loopback surface area and make daemon-style local integrations cleaner without changing the JSON-RPC protocol shape." -} diff --git a/artifacts/github/analysis/openai-codex-pr-22425.analysis.json b/artifacts/github/analysis/openai-codex-pr-22425.analysis.json deleted file mode 100644 index b804d7b8d..000000000 --- a/artifacts/github/analysis/openai-codex-pr-22425.analysis.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "caveats": [ - "This is a plugin/app-server payload behavior change, not evidence of a broader plugin UI redesign.", - "The bundle has no docs or examples refs, so the public framing should stay tied to PR and test evidence." - ], - "confidence": "confirmed", - "config_flags": [], - "expected_effect": null, - "how_to_try": null, - "impact": "low", - "kind": "behavior_change", - "proof_points": [ - "The PR body states that `shared-with-me` remains the request kind while private plugins return under `workspace-shared-with-me-private` and UNLISTED installed workspace plugins return under `workspace-shared-with-me-unlisted`.", - "`codex-rs/core-plugins/src/remote.rs` replaces the old shared-with-me marketplace constant with separate private and unlisted workspace-shared marketplace names.", - "`codex-rs/core-plugins/src/remote/remote_installed_plugin_sync.rs` initializes installed-plugin tracking for both new workspace-shared buckets.", - "App-server and core plugin tests update `plugin/list`, `plugin/read`, `plugin/share`, and share-list expectations from `shared-with-me` IDs to `workspace-shared-with-me-private`, with list coverage for the unlisted bucket." - ], - "slug": "split-shared-workspace-plugins-by-discoverability", - "summary": "Merged PR #22425 keeps `shared-with-me` as the `plugin/list` request kind, but changes the returned workspace-shared plugin buckets: private shares now use `workspace-shared-with-me-private`, and installed unlisted workspace plugins can use `workspace-shared-with-me-unlisted`.", - "title": "Shared workspace plugins are split by discoverability", - "watch_state": "Watch whether downstream plugin clients or cached IDs still assume all shared workspace plugins live under `shared-with-me`.", - "why_it_matters": "App-server and plugin clients get less ambiguous marketplace identities for workspace-shared plugins. That makes it easier to distinguish private shares from unlisted workspace installs without treating every shared workspace plugin as one generic `shared-with-me` bucket." -} diff --git a/artifacts/github/bundles/openai-codex-pr-22414.json b/artifacts/github/bundles/openai-codex-pr-22414.json deleted file mode 100644 index a7f62c0db..000000000 --- a/artifacts/github/bundles/openai-codex-pr-22414.json +++ /dev/null @@ -1,142 +0,0 @@ -{ - "analysis_mode": "pr_first", - "commits": [ - { - "author": "etraut-openai", - "committed_at": "2026-05-13T02:38:21Z", - "message": "Support UDS and websocket remotes", - "sha": "f31f1b6804de3bf47b89d55886e573e0f314ef6e", - "url": "https://github.com/openai/codex/commit/f31f1b6804de3bf47b89d55886e573e0f314ef6e" - } - ], - "default_branch": "main", - "docs_refs": [], - "examples_refs": [], - "extracted_flags": [ - "UDS", - "--remote", - "TUI", - "JSON", - "TCP", - "PATH", - "--remote-auth-token-env", - "DEFAULT_IN_PROCESS_CHANNEL_CAPACITY", - "JSONRPCM", - "JSONRPCR", - "URL", - "CONNECT_TIMEOUT", - "INITIALIZE_TIMEOUT", - "REMOTE_APP_SERVER_MAX_WEBSOCKET_MESSAGE_SIZE", - "HTTP", - "URI", - "UDS_WEBSOCKET_HANDSHAKE_URL", - "AUTHORIZATION", - "ADDR", - "AUTO_CONNECT_DAEMON_CONNECT_TIMEOUT", - "CODEX_HOME", - "CARGO_PKG_VERSION", - "NUX" - ], - "files": [ - { - "additions": 2, - "deletions": 0, - "patch_excerpt": "@@ -1970,6 +1970,8 @@ dependencies = [\n \"codex-exec-server\",\n \"codex-feedback\",\n \"codex-protocol\",\n+ \"codex-uds\",\n+ \"codex-utils-absolute-path\",\n \"codex-utils-rustls-provider\",\n \"futures\",\n \"pretty_assertions\",", - "path": "codex-rs/Cargo.lock", - "status": "modified" - }, - { - "additions": 2, - "deletions": 0, - "patch_excerpt": "@@ -21,6 +21,8 @@ codex-core = { workspace = true }\n codex-exec-server = { workspace = true }\n codex-feedback = { workspace = true }\n codex-protocol = { workspace = true }\n+codex-uds = { workspace = true }\n+codex-utils-absolute-path = { workspace = true }\n codex-utils-rustls-provider = { workspace = true }\n futures = { workspace = true }\n serde = { workspace = true }", - "path": "codex-rs/app-server-client/Cargo.toml", - "status": "modified" - }, - { - "additions": 101, - "deletions": 22, - "patch_excerpt": "@@ -25,6 +25,7 @@ use std::io::Result as IoResult;\n use std::sync::Arc;\n use std::time::Duration;\n \n+pub use codex_app_server::app_server_control_socket_path;\n pub use codex_app_server::in_process::DEFAULT_IN_PROCESS_CHANNEL_CAPACITY;\n pub use codex_app_server::in_process::InProcessServerEvent;\n use codex_app_server::in_process::InProcessStartArgs;\n@@ -61,6 +62,7 @@ use tracing::warn;\n \n pub use crate::remote::RemoteAppServerClient;\n pub use crate::remote::RemoteAppServerConnectArgs;\n+pub use crate::remote::RemoteAppServerEndpoint;\n \n /// Transitional access to core-only embedded app-server types.\n ///\n@@ -952,6 +954,8 @@ mod tests {\n use codex_app_server_protocol::ToolRequestUserInputQuestion;\n use codex_core::config::ConfigBuilder;\n use codex_core::init_state_db;\n+ use codex_uds::UnixListener;\n+ use codex_utils_absolute_path::AbsolutePathBuf;\n use futures::SinkExt...", - "path": "codex-rs/app-server-client/src/lib.rs", - "status": "modified" - }, - { - "additions": 226, - "deletions": 99, - "patch_excerpt": "@@ -1,11 +1,13 @@\n /*\n-This module implements the websocket-backed app-server client transport.\n+This module implements the remote app-server client transport.\n \n It owns the remote connection lifecycle, including the initialize/initialized\n handshake, JSON-RPC request/response routing, server-request resolution, and\n-notification streaming. The rest of the crate uses the same `AppServerEvent`\n-surface for both in-process and remote transports, so callers such as the TUI\n-can switch between them without changing their higher-level session logic.\n+notification streaming. Remote connections always carry WebSocket frames, over\n+either TCP WebSocket URLs or local Unix sockets. The rest of the crate uses the\n+same `AppServerEvent` surface for both in-process and remote transports, so\n+callers such as the TUI can switch between them without changing their\n+higher-level session logic.\n */\n \n us...", - "path": "codex-rs/app-server-client/src/remote.rs", - "status": "modified" - }, - { - "additions": 33, - "deletions": 26, - "patch_excerpt": "@@ -722,9 +722,9 @@ struct FeatureToggles {\n \n #[derive(Debug, Default, Parser, Clone)]\n struct InteractiveRemoteOptions {\n- /// Connect the TUI to a remote app server websocket endpoint.\n+ /// Connect the TUI to a remote app server endpoint.\n ///\n- /// Accepted forms: `ws://host:port` or `wss://host:port`.\n+ /// Accepted forms: `ws://host:port`, `wss://host:port`, `unix://`, or `unix://PATH`.\n #[arg(long = \"remote\", value_name = \"ADDR\")]\n remote: Option,\n \n@@ -1709,27 +1709,39 @@ async fn run_interactive_tui(\n }\n }\n \n- let normalized_remote = remote\n+ let mut remote_endpoint = remote\n .as_deref()\n- .map(codex_tui::normalize_remote_addr)\n+ .map(codex_tui::resolve_remote_addr)\n .transpose()\n .map_err(std::io::Error::other)?;\n- if remote_auth_token_env.is_some() && normalized_remote.is_none() {\n- ...", - "path": "codex-rs/cli/src/main.rs", - "status": "modified" - }, - { - "additions": 4, - "deletions": 6, - "patch_excerpt": "@@ -80,6 +80,7 @@ use crate::workspace_command::AppServerWorkspaceCommandRunner;\n use crate::workspace_command::WorkspaceCommandRunner;\n use codex_ansi_escape::ansi_escape_line;\n use codex_app_server_client::AppServerRequestHandle;\n+use codex_app_server_client::RemoteAppServerEndpoint;\n use codex_app_server_client::TypedRequestError;\n use codex_app_server_protocol::AddCreditsNudgeCreditType;\n use codex_app_server_protocol::AskForApproval;\n@@ -498,8 +499,7 @@ pub(crate) struct App {\n pub(crate) feedback: codex_feedback::CodexFeedback,\n feedback_audience: FeedbackAudience,\n environment_manager: Arc,\n- remote_app_server_url: Option,\n- remote_app_server_auth_token: Option,\n+ remote_app_server_endpoint: Option,\n /// Set when the user confirms an update; propagated on exit.\n pub(crate) pending_update_acti...", - "path": "codex-rs/tui/src/app.rs", - "status": "modified" - }, - { - "additions": 2, - "deletions": 5, - "patch_excerpt": "@@ -57,11 +57,8 @@ impl App {\n AppEvent::OpenResumePicker => {\n let picker_app_server = match crate::start_app_server_for_picker(\n &self.config,\n- &match self.remote_app_server_url.clone() {\n- Some(websocket_url) => crate::AppServerTarget::Remote {\n- websocket_url,\n- auth_token: self.remote_app_server_auth_token.clone(),\n- },\n+ &match self.remote_app_server_endpoint.clone() {\n+ Some(endpoint) => crate::AppServerTarget::Remote { endpoint },\n None => crate::AppServerTarget::Embedded,\n },\n self.state_db.clone(),", - "path": "codex-rs/tui/src/app/event_dispatch.rs", - "status": "modified" - }, - { - "additions": 1, - "deletions": 1, - "patch_excerpt": "@@ -633,7 +633,7 @@ impl App {\n }\n \n let current_cwd = self.config.cwd.to_path_buf();\n- let resume_cwd = if self.remote_app_server_url.is_some() {\n+ let resume_cwd = if self.remote_app_server_endpoint.is_some() {\n current_cwd.clone()\n } else {\n match crate::session_resume::resolve_cwd_for_resume_or_fork(", - "path": "codex-rs/tui/src/app/session_lifecycle.rs", - "status": "modified" - }, - { - "additions": 1, - "deletions": 2, - "patch_excerpt": "@@ -44,8 +44,7 @@ pub(super) async fn make_test_app() -> App {\n feedback: codex_feedback::CodexFeedback::new(),\n feedback_audience: FeedbackAudience::External,\n environment_manager: Arc::new(EnvironmentManager::default_for_tests()),\n- remote_app_server_url: None,\n- remote_app_server_auth_token: None,\n+ remote_app_server_endpoint: None,\n pending_update_action: None,\n pending_shutdown_exit_thread_id: None,\n windows_sandbox: WindowsSandboxState::default(),", - "path": "codex-rs/tui/src/app/test_support.rs", - "status": "modified" - }, - { - "additions": 2, - "deletions": 4, - "patch_excerpt": "@@ -3992,8 +3992,7 @@ async fn make_test_app() -> App {\n feedback: codex_feedback::CodexFeedback::new(),\n feedback_audience: FeedbackAudience::External,\n environment_manager: Arc::new(EnvironmentManager::default_for_tests()),\n- remote_app_server_url: None,\n- remote_app_server_auth_token: None,\n+ remote_app_server_endpoint: None,\n pending_update_action: None,\n pending_shutdown_exit_thread_id: None,\n windows_sandbox: WindowsSandboxState::default(),\n@@ -4055,8 +4054,7 @@ async fn make_test_app_with_channels() -> (\n feedback: codex_feedback::CodexFeedback::new(),\n feedback_audience: FeedbackAudience::External,\n environment_manager: Arc::new(EnvironmentManager::default_for_tests()),\n- remote_app_server_url: None,\n- remote_app_server_auth_token: None,\n+ remo...", - "path": "codex-rs/tui/src/app/tests.rs", - "status": "modified" - }, - { - "additions": 185, - "deletions": 122, - "patch_excerpt": "@@ -25,6 +25,7 @@ use codex_app_server_client::InProcessAppServerClient;\n use codex_app_server_client::InProcessClientStartArgs;\n use codex_app_server_client::RemoteAppServerClient;\n use codex_app_server_client::RemoteAppServerConnectArgs;\n+pub use codex_app_server_client::RemoteAppServerEndpoint;\n use codex_app_server_protocol::Account as AppServerAccount;\n use codex_app_server_protocol::AskForApproval;\n use codex_app_server_protocol::AuthMode as AppServerAuthMode;\n@@ -272,6 +273,10 @@ pub use public_widgets::composer_input::ComposerAction;\n pub use public_widgets::composer_input::ComposerInput;\n // (tests access modules directly within the crate)\n \n+#[cfg(unix)]\n+const AUTO_CONNECT_DAEMON_CONNECT_TIMEOUT: std::time::Duration =\n+ std::time::Duration::from_millis(50);\n+\n #[allow(clippy::too_many_arguments)]\n async fn start_embedded_app_server(\n arg0_paths: Arg0DispatchPaths,\n@@ -3...", - "path": "codex-rs/tui/src/lib.rs", - "status": "modified" - }, - { - "additions": 1, - "deletions": 2, - "patch_excerpt": "@@ -57,8 +57,7 @@ fn main() -> anyhow::Result<()> {\n inner,\n arg0_paths,\n LoaderOverrides::default(),\n- /*remote*/ None,\n- /*remote_auth_token*/ None,\n+ /*explicit_remote_endpoint*/ None,\n )\n .await?;\n match exit_info.exit_reason {", - "path": "codex-rs/tui/src/main.rs", - "status": "modified" - } - ], - "linked_issues": [], - "notes": [ - "Built from GitHub pull-request, commits, files, and repo endpoints.", - "Discovered via continuous upstream commit sync: https://github.com/openai/codex/commit/ad572709aba1cdaac5ffe181f9cb64dbe07ba239" - ], - "primary_pr": { - "body": "## Why\r\n\r\nAdded support for UDS connections in `codex --remote`.\r\n\r\nTUI also now connects to local app-server using UDS by default if it is running and set to listen to UDS connection. \r\n\r\n## What Changed\r\n\r\n- Introduced `RemoteAppServerEndpoint` with `WebSocket` and `UnixSocket` variants.\r\n- Reused the existing JSON-RPC-over-WebSocket protocol over either a TCP WebSocket stream or a UDS stream.\r\n- Updated `codex --remote` to accept `ws://host:port`, `wss://host:port`, `unix://`, and `unix://PATH`.\r\n- Kept `--remote-auth-token-env` restricted to `wss://` and loopback `ws://` remotes.\r\n- Added a fast TUI startup probe for the default daemon socket, falling back to the embedded app server when the daemon is absent or unresponsive.\r\n\r\n## Verification\r\n\r\n- Manually verified that the updated remote flow works.\r\n- Added coverage for UDS remote round trips, WebSocket auth headers, auth-token transport policy, remote address parsing, and missing-daemon fallback.\r\n- Ran focused remote test coverage locally.\r\n", - "labels": [], - "merged_at": "2026-05-13T04:17:20Z", - "number": 22414, - "state": "merged", - "title": "Add support for UDS in `codex --remote`", - "url": "https://github.com/openai/codex/pull/22414" - }, - "repo": "openai/codex", - "schema": "github_change_bundle/v1" -} diff --git a/artifacts/github/bundles/openai-codex-pr-22425.json b/artifacts/github/bundles/openai-codex-pr-22425.json deleted file mode 100644 index 94219fab5..000000000 --- a/artifacts/github/bundles/openai-codex-pr-22425.json +++ /dev/null @@ -1,93 +0,0 @@ -{ - "analysis_mode": "pr_first", - "commits": [ - { - "author": "xl-openai", - "committed_at": "2026-05-13T03:24:01Z", - "message": "feat: Split shared workspace plugins by discoverability", - "sha": "4456c20bd0c8d4fa61e5714dccdf5e65e197b5e8", - "url": "https://github.com/openai/codex/commit/4456c20bd0c8d4fa61e5714dccdf5e65e197b5e8" - } - ], - "default_branch": "main", - "docs_refs": [], - "examples_refs": [], - "extracted_flags": [ - "UNLISTED", - "PRIVATE", - "WORKSPACE", - "REMOTE_GLOBAL_MARKETPLACE_NAME", - "REMOTE_WORKSPACE_MARKETPLACE_NAME", - "REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME", - "REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME", - "REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME", - "REMOTE_GLOBAL_MARKETPLACE_DISPLAY_NAME", - "REMOTE_WORKSPACE_MARKETPLACE_DISPLAY_NAME", - "REMOTE_SHARED_WITH_ME_MARKETPLACE_DISPLAY_NAME", - "REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_DISPLAY_NAME", - "REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_DISPLAY_NAME", - "REMOTE_PLUGIN_CATALOG_TIMEOUT", - "REMOTE_PLUGIN_LIST_PAGE_LIMIT", - "PLUGINS_CACHE_DIR" - ], - "files": [ - { - "additions": 69, - "deletions": 11, - "patch_excerpt": "@@ -1824,13 +1824,27 @@ async fn plugin_list_fetches_shared_with_me_kind() -> Result<()> {\n ))?;\n shared_plugin_body[\"plugins\"][0][\"share_principals\"] = serde_json::Value::Null;\n let shared_plugin_body = serde_json::to_string(&shared_plugin_body)?;\n- let workspace_installed_body = workspace_remote_plugin_page_body(\n- \"plugins~Plugin_22222222222222222222222222222222\",\n- \"shared-linear\",\n- \"Shared Linear\",\n- \"PRIVATE\",\n- /*enabled*/ Some(true),\n- );\n+ let mut workspace_installed_body: serde_json::Value =\n+ serde_json::from_str(&workspace_remote_plugin_page_body(\n+ \"plugins~Plugin_22222222222222222222222222222222\",\n+ \"shared-linear\",\n+ \"Shared Linear\",\n+ \"PRIVATE\",\n+ /*enabled*/ Some(true),\n+ ))?;\n+ let unlisted_installed_body: serde_json::Value =\n+ serd...", - "path": "codex-rs/app-server/tests/suite/v2/plugin_list.rs", - "status": "modified" - }, - { - "additions": 9, - "deletions": 3, - "patch_excerpt": "@@ -303,7 +303,7 @@ async fn plugin_read_returns_share_context_for_shared_remote_plugin() -> Result<\n let request_id = mcp\n .send_plugin_read_request(PluginReadParams {\n marketplace_path: None,\n- remote_marketplace_name: Some(\"shared-with-me\".to_string()),\n+ remote_marketplace_name: Some(\"workspace-shared-with-me-private\".to_string()),\n plugin_name: \"plugins~Plugin_11111111111111111111111111111111\".to_string(),\n })\n .await?;\n@@ -315,8 +315,14 @@ async fn plugin_read_returns_share_context_for_shared_remote_plugin() -> Result<\n .await??;\n let response: PluginReadResponse = to_response(response)?;\n \n- assert_eq!(response.plugin.marketplace_name, \"shared-with-me\");\n- assert_eq!(response.plugin.summary.id, \"shared-linear@shared-with-me\");\n+ assert_eq!(\n+ response.plugin.marketplace_name,\n+ ...", - "path": "codex-rs/app-server/tests/suite/v2/plugin_read.rs", - "status": "modified" - }, - { - "additions": 3, - "deletions": 3, - "patch_excerpt": "@@ -162,7 +162,7 @@ async fn plugin_share_save_uploads_local_plugin() -> Result<()> {\n PluginShareListResponse {\n data: vec![PluginShareListItem {\n plugin: PluginSummary {\n- id: \"demo-plugin@shared-with-me\".to_string(),\n+ id: \"demo-plugin@workspace-shared-with-me-private\".to_string(),\n remote_plugin_id: Some(\"plugins_123\".to_string()),\n local_version: None,\n name: \"demo-plugin\".to_string(),\n@@ -566,7 +566,7 @@ async fn plugin_share_list_returns_created_workspace_plugins() -> Result<()> {\n PluginShareListResponse {\n data: vec![PluginShareListItem {\n plugin: PluginSummary {\n- id: \"demo-plugin@shared-with-me\".to_string(),\n+ id: \"demo-plugin@workspace-shared-with-me-private\".to_string(),...", - "path": "codex-rs/app-server/tests/suite/v2/plugin_share.rs", - "status": "modified" - }, - { - "additions": 68, - "deletions": 23, - "patch_excerpt": "@@ -47,10 +47,15 @@ pub use share::update_remote_plugin_share_targets;\n \n pub const REMOTE_GLOBAL_MARKETPLACE_NAME: &str = \"chatgpt-global\";\n pub const REMOTE_WORKSPACE_MARKETPLACE_NAME: &str = \"workspace-directory\";\n-pub const REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME: &str = \"shared-with-me\";\n+pub const REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME: &str =\n+ \"workspace-shared-with-me-private\";\n+pub const REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME: &str =\n+ \"workspace-shared-with-me-unlisted\";\n pub const REMOTE_GLOBAL_MARKETPLACE_DISPLAY_NAME: &str = \"ChatGPT Plugins\";\n pub const REMOTE_WORKSPACE_MARKETPLACE_DISPLAY_NAME: &str = \"Workspace Directory\";\n-pub const REMOTE_SHARED_WITH_ME_MARKETPLACE_DISPLAY_NAME: &str = \"Shared with me\";\n+pub const REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_DISPLAY_NAME: &str = \"Shared with me\";\n+pub const REMOTE_WORKSP...", - "path": "codex-rs/core-plugins/src/remote.rs", - "status": "modified" - }, - { - "additions": 26, - "deletions": 9, - "patch_excerpt": "@@ -1,6 +1,7 @@\n use super::REMOTE_GLOBAL_MARKETPLACE_NAME;\n-use super::REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME;\n use super::REMOTE_WORKSPACE_MARKETPLACE_NAME;\n+use super::REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME;\n+use super::REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME;\n use super::RemotePluginCatalogError;\n use super::RemotePluginScope;\n use super::RemotePluginServiceConfig;\n@@ -153,7 +154,11 @@ pub async fn sync_remote_installed_plugin_bundles_once(\n BTreeSet::new(),\n ),\n (\n- REMOTE_SHARED_WITH_ME_MARKETPLACE_NAME.to_string(),\n+ REMOTE_WORKSPACE_SHARED_WITH_ME_PRIVATE_MARKETPLACE_NAME.to_string(),\n+ BTreeSet::new(),\n+ ),\n+ (\n+ REMOTE_WORKSPACE_SHARED_WITH_ME_UNLISTED_MARKETPLACE_NAME.to_string(),\n BTreeSet::new(),\n ...", - "path": "codex-rs/core-plugins/src/remote/remote_installed_plugin_sync.rs", - "status": "modified" - }, - { - "additions": 2, - "deletions": 2, - "patch_excerpt": "@@ -586,7 +586,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {\n vec![\n RemotePluginShareSummary {\n summary: RemotePluginSummary {\n- id: \"demo-plugin@shared-with-me\".to_string(),\n+ id: \"demo-plugin@workspace-shared-with-me-private\".to_string(),\n remote_plugin_id: \"plugins_123\".to_string(),\n name: \"demo-plugin\".to_string(),\n share_context: Some(RemotePluginShareContext {\n@@ -625,7 +625,7 @@ async fn list_remote_plugin_shares_fetches_created_workspace_plugins() {\n },\n RemotePluginShareSummary {\n summary: RemotePluginSummary {\n- id: \"demo-plugin@shared-with-me\".to_string(),\n+ id: \"demo-plugin@workspace-shared-with-me-private\".to_string(),\n ...", - "path": "codex-rs/core-plugins/src/remote/share/tests.rs", - "status": "modified" - } - ], - "linked_issues": [], - "notes": [ - "Built from GitHub pull-request, commits, files, and repo endpoints.", - "Discovered via continuous upstream commit sync: https://github.com/openai/codex/commit/7bf95b39aa3c649605f643a24a76b16bc45de917" - ], - "primary_pr": { - "body": " - Keep shared-with-me as the plugin/list request kind, but return private plugins under workspace-shared-with-me-private.\r\n - Add workspace-shared-with-me-unlisted for installed workspace plugins with UNLISTED discoverability,", - "labels": [], - "merged_at": "2026-05-13T04:11:19Z", - "number": 22425, - "state": "merged", - "title": "feat: Split shared workspace plugins by discoverability", - "url": "https://github.com/openai/codex/pull/22425" - }, - "repo": "openai/codex", - "schema": "github_change_bundle/v1" -}