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
259 changes: 259 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-25147.json

Large diffs are not rendered by default.

121 changes: 121 additions & 0 deletions artifacts/github/bundles/openai-codex-pr-26701.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
{
"analysis_mode": "pr_first",
"commits": [
{
"author": "canvrno-oai",
"committed_at": "2026-06-03T18:10:15Z",
"message": "init",
"sha": "52f9ec871bedbd53a0c0741d0b7bc47e3dae3da9",
"url": "https://github.com/openai/codex/commit/52f9ec871bedbd53a0c0741d0b7bc47e3dae3da9"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-03T22:09:21Z",
"message": "cleanup",
"sha": "4d32a96c7580b022e5d906bcbb2eb283b80338f7",
"url": "https://github.com/openai/codex/commit/4d32a96c7580b022e5d906bcbb2eb283b80338f7"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-03T23:18:35Z",
"message": "Adjustment for admin-disabled plugins in /plugin menu",
"sha": "ddd48cab1b5d617e8a01737c0665f4025b351421",
"url": "https://github.com/openai/codex/commit/ddd48cab1b5d617e8a01737c0665f4025b351421"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-04T00:23:54Z",
"message": "fix",
"sha": "44448048dcad4a75a1d7056f23cc87691438268c",
"url": "https://github.com/openai/codex/commit/44448048dcad4a75a1d7056f23cc87691438268c"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-06T00:41:49Z",
"message": "tui: update remote plugin detail fixtures",
"sha": "ccf0f0d9892fd9b253401466d6dee7a1886ac407",
"url": "https://github.com/openai/codex/commit/ccf0f0d9892fd9b253401466d6dee7a1886ac407"
},
{
"author": "canvrno-oai",
"committed_at": "2026-06-09T20:54:23Z",
"message": "Merge branch 'main' into canvrno/plugin_sharing_tui_stack_pr1_remote_identity",
"sha": "9da50461f3d23990d484b3ba29b5cb293269d23f",
"url": "https://github.com/openai/codex/commit/9da50461f3d23990d484b3ba29b5cb293269d23f"
}
],
"default_branch": "main",
"docs_refs": [],
"examples_refs": [],
"extracted_flags": [
"TUI",
"OPENAI_CURATED_MARKETPLACE_NAME",
"NONE"
],
"files": [
{
"additions": 1,
"deletions": 0,
"patch_excerpt": "@@ -11,6 +11,7 @@ use crate::app_event::ExitMode;\n use crate::app_event::FeedbackCategory;\n use crate::app_event::HistoryLookupResponse;\n use crate::app_event::PermissionProfileSelection;\n+use crate::app_event::PluginLocation;\n use crate::app_event::RateLimitRefreshOrigin;\n use crate::app_event::RealtimeAudioDeviceKind;\n #[cfg(target_os = \"windows\")]",
"path": "codex-rs/tui/src/app.rs",
"status": "modified"
},
{
"additions": 28,
"deletions": 7,
"patch_excerpt": "@@ -241,22 +241,22 @@ impl App {\n &mut self,\n app_server: &AppServerSession,\n cwd: PathBuf,\n- marketplace_path: AbsolutePathBuf,\n+ location: PluginLocation,\n plugin_name: String,\n plugin_display_name: String,\n ) {\n let request_handle = app_server.request_handle();\n let app_event_tx = self.app_event_tx.clone();\n tokio::spawn(async move {\n let cwd_for_event = cwd.clone();\n- let marketplace_path_for_event = marketplace_path.clone();\n+ let location_for_event = location.clone();\n let plugin_name_for_event = plugin_name.clone();\n- let result = fetch_plugin_install(request_handle, marketplace_path, plugin_name)\n+ let result = fetch_plugin_install(request_handle, location, plugin_name)\n .await\n .map_err(|err| format!...",
"path": "codex-rs/tui/src/app/background_requests.rs",
"status": "modified"
},
{
"additions": 8,
"deletions": 6,
"patch_excerpt": "@@ -573,14 +573,14 @@ impl App {\n }\n AppEvent::FetchPluginInstall {\n cwd,\n- marketplace_path,\n+ location,\n plugin_name,\n plugin_display_name,\n } => {\n self.fetch_plugin_install(\n app_server,\n cwd,\n- marketplace_path,\n+ location,\n plugin_name,\n plugin_display_name,\n );\n@@ -601,7 +601,7 @@ impl App {\n }\n AppEvent::PluginInstallLoaded {\n cwd,\n- marketplace_path,\n+ location,\n plugin_name,\n plugin_display_name,\n result,\n@@ -612,7 +612,7 @@ impl App {\n }\n let should_refresh_plugin_detail...",
"path": "codex-rs/tui/src/app/event_dispatch.rs",
"status": "modified"
},
{
"additions": 17,
"deletions": 2,
"patch_excerpt": "@@ -109,6 +109,21 @@ pub(crate) struct ConnectorsSnapshot {\n pub(crate) connectors: Vec<AppInfo>,\n }\n \n+#[derive(Debug, Clone, PartialEq, Eq)]\n+pub(crate) enum PluginLocation {\n+ Local { marketplace_path: AbsolutePathBuf },\n+ Remote { marketplace_name: String },\n+}\n+\n+impl PluginLocation {\n+ pub(crate) fn into_request_params(self) -> (Option<AbsolutePathBuf>, Option<String>) {\n+ match self {\n+ PluginLocation::Local { marketplace_path } => (Some(marketplace_path), None),\n+ PluginLocation::Remote { marketplace_name } => (None, Some(marketplace_name)),\n+ }\n+ }\n+}\n+\n /// Distinguishes why a rate-limit refresh was requested so the completion\n /// handler can route the result correctly.\n ///\n@@ -493,15 +508,15 @@ pub(crate) enum AppEvent {\n /// Install a specific plugin from a marketplace.\n FetchPluginInstall {\n cwd: PathBuf,\n...",
"path": "codex-rs/tui/src/app_event.rs",
"status": "modified"
},
{
"additions": 146,
"deletions": 59,
"patch_excerpt": "@@ -5,6 +5,7 @@ use std::time::Instant;\n \n use super::ChatWidget;\n use crate::app_event::AppEvent;\n+use crate::app_event::PluginLocation;\n use crate::bottom_pane::ColumnWidthMode;\n use crate::bottom_pane::SelectionAction;\n use crate::bottom_pane::SelectionItem;\n@@ -25,17 +26,18 @@ use crate::tui::FrameRequester;\n use codex_app_server_protocol::MarketplaceAddResponse;\n use codex_app_server_protocol::MarketplaceRemoveResponse;\n use codex_app_server_protocol::MarketplaceUpgradeResponse;\n+use codex_app_server_protocol::PluginAvailability;\n use codex_app_server_protocol::PluginDetail;\n use codex_app_server_protocol::PluginInstallPolicy;\n use codex_app_server_protocol::PluginInstallResponse;\n use codex_app_server_protocol::PluginListResponse;\n use codex_app_server_protocol::PluginMarketplaceEntry;\n use codex_app_server_protocol::PluginReadResponse;\n+use codex_app_server_protocol::PluginSource;...",
"path": "codex-rs/tui/src/chatwidget/plugins.rs",
"status": "modified"
},
{
"additions": 28,
"deletions": 0,
"patch_excerpt": "@@ -1337,6 +1337,34 @@ pub(super) fn plugins_test_summary(\n }\n }\n \n+pub(super) fn plugins_test_remote_summary(\n+ remote_plugin_id: &str,\n+ name: &str,\n+ display_name: Option<&str>,\n+ description: Option<&str>,\n+ installed: bool,\n+) -> PluginSummary {\n+ PluginSummary {\n+ id: remote_plugin_id.to_string(),\n+ remote_plugin_id: Some(remote_plugin_id.to_string()),\n+ local_version: None,\n+ name: name.to_string(),\n+ share_context: None,\n+ source: PluginSource::Remote,\n+ installed,\n+ enabled: true,\n+ install_policy: PluginInstallPolicy::Available,\n+ auth_policy: PluginAuthPolicy::OnInstall,\n+ availability: PluginAvailability::Available,\n+ interface: Some(plugins_test_interface(\n+ display_name,\n+ description,\n+ /*long_description*/ None,\n+ )),\n+ k...",
"path": "codex-rs/tui/src/chatwidget/tests/helpers.rs",
"status": "modified"
},
{
"additions": 345,
"deletions": 0,
"patch_excerpt": "@@ -6,6 +6,7 @@ use codex_app_server_protocol::HookErrorInfo;\n use codex_app_server_protocol::HooksListEntry;\n use codex_app_server_protocol::HooksListResponse;\n use codex_app_server_protocol::MarketplaceRemoveResponse;\n+use codex_app_server_protocol::PluginAvailability;\n use codex_features::Stage;\n use pretty_assertions::assert_eq;\n \n@@ -714,6 +715,350 @@ async fn plugin_detail_popup_hides_disclosure_for_installed_plugins() {\n );\n }\n \n+#[tokio::test]\n+async fn plugins_popup_remote_row_opens_remote_detail() {\n+ let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;\n+ chat.set_feature_enabled(Feature::Plugins, /*enabled*/ true);\n+\n+ let popup = render_loaded_plugins_popup(\n+ &mut chat,\n+ plugins_test_response(vec![PluginMarketplaceEntry {\n+ name: \"workspace-directory\".to_string(),\n+ path: None,\n+ ...",
"path": "codex-rs/tui/src/chatwidget/tests/popups_and_settings.rs",
"status": "modified"
}
],
"linked_issues": [],
"notes": [
"Built from GitHub pull-request, commits, files, and repo endpoints."
],
"primary_pr": {
"body": "This starts the shared-plugin TUI stack by teaching the existing plugin popup flows to address plugins from either a local marketplace path or a remote marketplace name. The visible surface stays intentionally narrow so later catalog work can build on stable remote request identity without adding share-management UI.\r\n\r\n- Adds remote-capable detail/install/uninstall request routing for plugin popup actions.\r\n- Uses remote plugin IDs for remote install and uninstall while preserving local plugin IDs and paths.\r\n- Keeps remote detail views available when a marketplace has no filesystem path.\r\n- Blocks admin-disabled plugin installs and toggle affordances in the existing flows.",
"labels": [],
"merged_at": "2026-06-09T23:34:39Z",
"number": 26701,
"state": "merged",
"title": "TUI Plugin Sharing 1 - add remote plugin identity",
"url": "https://github.com/openai/codex/pull/26701"
},
"repo": "openai/codex",
"schema": "github_change_bundle/v1"
}
Loading