diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index bd516ffa..21fc539a 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -895,6 +895,15 @@ own marketplace/store/loader code. Remaining plugin-shaped imports are narrower telemetry and skill-namespace compatibility residues, not the old marketplace runtime. +Plugin telemetry has now been cut from `codex-analytics`. Analytics no longer +tracks plugin used/installed/uninstalled/enabled/disabled events, keeps plugin +dedupe state, or depends on `codex-plugin`; the unreferenced `codex-plugin` +crate is deleted from the vendored workspace. Verified with +`cargo check -p codex-analytics` and +`cargo test -p codex-analytics --tests --no-run`. Remaining `.codex-plugin` +hits are stale tests and the narrower `codex-utils-plugins` skill-namespace +utility, not live marketplace machinery. + The Phase 6 freshness slice is landed. It exposes read-only `thread/epiphany/freshness` from live retrieval summaries plus graph frontier/churn state and, for loaded threads, watcher-backed invalidation diff --git a/state/ledgers.msgpack b/state/ledgers.msgpack index 327e75c4..ee4843cd 100644 Binary files a/state/ledgers.msgpack and b/state/ledgers.msgpack differ diff --git a/state/map.yaml b/state/map.yaml index 9a0044d0..f3db8a79 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -317,8 +317,11 @@ current_status: `codex-chatgpt` product crate was deleted from the vendored workspace; only ChatGPT auth originator strings remain where they serve the subscription compatibility spine. The orphaned `codex-core-plugins` crate was also - deleted from the workspace; remaining plugin references are narrower - telemetry/skill-namespace residues, not a plugin marketplace runtime. MCP - remains JSON-RPC at the edge; user-declared MCP servers are the only runtime - MCP authority. + deleted from the workspace. Analytics no longer knows plugin lifecycle/use + events, keeps plugin dedupe state, or depends on `codex-plugin`; the + unreferenced `codex-plugin` crate was deleted from the workspace. Remaining + `.codex-plugin` references are stale tests or the narrower + `codex-utils-plugins` skill-namespace utility, not a plugin marketplace + runtime. MCP remains JSON-RPC at the edge; user-declared MCP servers are the + only runtime MCP authority. next_action: Continue starving coordinator/runtime execution and operator surfaces off app-server JSON-RPC and out of `codex_message_processor.rs`; keep the vestigial Codex organ narrowed to subscription auth/model transport. diff --git a/vendor/codex/codex-rs/Cargo.lock b/vendor/codex/codex-rs/Cargo.lock index 315fc47b..9f09ec18 100644 --- a/vendor/codex/codex-rs/Cargo.lock +++ b/vendor/codex/codex-rs/Cargo.lock @@ -1813,7 +1813,6 @@ dependencies = [ "codex-app-server-protocol", "codex-git-utils", "codex-login", - "codex-plugin", "codex-protocol", "codex-utils-absolute-path", "os_info", @@ -3031,15 +3030,6 @@ dependencies = [ "tracing-subscriber", ] -[[package]] -name = "codex-plugin" -version = "0.0.0" -dependencies = [ - "codex-utils-absolute-path", - "codex-utils-plugins", - "thiserror 2.0.18", -] - [[package]] name = "codex-process-hardening" version = "0.0.0" diff --git a/vendor/codex/codex-rs/Cargo.toml b/vendor/codex/codex-rs/Cargo.toml index e433e7d3..89978b86 100644 --- a/vendor/codex/codex-rs/Cargo.toml +++ b/vendor/codex/codex-rs/Cargo.toml @@ -94,7 +94,6 @@ members = [ "thread-store", "uds", "codex-experimental-api-macros", - "plugin", "model-provider", ] resolver = "2" @@ -157,7 +156,6 @@ codex-models-manager = { path = "models-manager" } codex-network-proxy = { path = "network-proxy" } codex-ollama = { path = "ollama" } codex-otel = { path = "otel" } -codex-plugin = { path = "plugin" } codex-model-provider = { path = "model-provider" } codex-process-hardening = { path = "process-hardening" } codex-protocol = { path = "protocol" } diff --git a/vendor/codex/codex-rs/analytics/Cargo.toml b/vendor/codex/codex-rs/analytics/Cargo.toml index f706814d..ecdb40b7 100644 --- a/vendor/codex/codex-rs/analytics/Cargo.toml +++ b/vendor/codex/codex-rs/analytics/Cargo.toml @@ -16,7 +16,6 @@ workspace = true codex-app-server-protocol = { workspace = true } codex-git-utils = { workspace = true } codex-login = { workspace = true } -codex-plugin = { workspace = true } codex-protocol = { workspace = true } os_info = { workspace = true } serde = { workspace = true, features = ["derive"] } diff --git a/vendor/codex/codex-rs/analytics/src/analytics_client_tests.rs b/vendor/codex/codex-rs/analytics/src/analytics_client_tests.rs index f65c9262..2992d53b 100644 --- a/vendor/codex/codex-rs/analytics/src/analytics_client_tests.rs +++ b/vendor/codex/codex-rs/analytics/src/analytics_client_tests.rs @@ -5,8 +5,6 @@ use crate::events::CodexAppServerClientMetadata; use crate::events::CodexAppUsedEventRequest; use crate::events::CodexCompactionEventRequest; use crate::events::CodexHookRunEventRequest; -use crate::events::CodexPluginEventRequest; -use crate::events::CodexPluginUsedEventRequest; use crate::events::CodexRuntimeMetadata; use crate::events::CodexTurnEventRequest; use crate::events::GuardianApprovalRequestSource; @@ -20,8 +18,6 @@ use crate::events::ThreadInitializedEventParams; use crate::events::TrackEventRequest; use crate::events::codex_app_metadata; use crate::events::codex_hook_run_metadata; -use crate::events::codex_plugin_metadata; -use crate::events::codex_plugin_used_metadata; use crate::events::subagent_thread_started_event_request; use crate::facts::AnalyticsFact; use crate::facts::AnalyticsJsonRpcError; @@ -40,9 +36,6 @@ use crate::facts::HookRunFact; use crate::facts::HookRunInput; use crate::facts::InputError; use crate::facts::InvocationType; -use crate::facts::PluginState; -use crate::facts::PluginStateChangedInput; -use crate::facts::PluginUsedInput; use crate::facts::SkillInvocation; use crate::facts::SkillInvokedInput; use crate::facts::SubAgentThreadStartedInput; @@ -85,10 +78,6 @@ use codex_app_server_protocol::TurnSteerResponse; use codex_app_server_protocol::UserInput; use codex_login::default_client::DEFAULT_ORIGINATOR; use codex_login::default_client::originator; -use codex_plugin::AppConnectorId; -use codex_plugin::PluginCapabilitySummary; -use codex_plugin::PluginId; -use codex_plugin::PluginTelemetryMetadata; use codex_protocol::approvals::NetworkApprovalProtocol; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::ModeKind; @@ -771,7 +760,6 @@ fn app_used_dedupe_is_keyed_by_turn_and_connector() { let queue = AnalyticsEventsQueue { sender, app_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), - plugin_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), }; let app = AppInvocation { connector_id: Some("calendar".to_string()), @@ -1378,66 +1366,6 @@ async fn subagent_thread_started_publishes_without_initialize() { assert_eq!(payload[0]["event_params"]["subagent_source"], "review"); } -#[test] -fn plugin_used_event_serializes_expected_shape() { - let tracking = TrackEventsContext { - model_slug: "gpt-5".to_string(), - thread_id: "thread-3".to_string(), - turn_id: "turn-3".to_string(), - }; - let event = TrackEventRequest::PluginUsed(CodexPluginUsedEventRequest { - event_type: "codex_plugin_used", - event_params: codex_plugin_used_metadata(&tracking, sample_plugin_metadata()), - }); - - let payload = serde_json::to_value(&event).expect("serialize plugin used event"); - - assert_eq!( - payload, - json!({ - "event_type": "codex_plugin_used", - "event_params": { - "plugin_id": "sample@test", - "plugin_name": "sample", - "marketplace_name": "test", - "has_skills": true, - "mcp_server_count": 2, - "connector_ids": ["calendar", "drive"], - "product_client_id": originator().value, - "thread_id": "thread-3", - "turn_id": "turn-3", - "model_slug": "gpt-5" - } - }) - ); -} - -#[test] -fn plugin_management_event_serializes_expected_shape() { - let event = TrackEventRequest::PluginInstalled(CodexPluginEventRequest { - event_type: "codex_plugin_installed", - event_params: codex_plugin_metadata(sample_plugin_metadata()), - }); - - let payload = serde_json::to_value(&event).expect("serialize plugin installed event"); - - assert_eq!( - payload, - json!({ - "event_type": "codex_plugin_installed", - "event_params": { - "plugin_id": "sample@test", - "plugin_name": "sample", - "marketplace_name": "test", - "has_skills": true, - "mcp_server_count": 2, - "connector_ids": ["calendar", "drive"], - "product_client_id": originator().value - } - }) - ); -} - #[test] fn hook_run_event_serializes_expected_shape() { let tracking = TrackEventsContext { @@ -1541,32 +1469,6 @@ fn hook_run_metadata_maps_stopped_status() { assert_eq!(stopped["status"], "stopped"); } -#[test] -fn plugin_used_dedupe_is_keyed_by_turn_and_plugin() { - let (sender, _receiver) = mpsc::channel(1); - let queue = AnalyticsEventsQueue { - sender, - app_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), - plugin_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), - }; - let plugin = sample_plugin_metadata(); - - let turn_1 = TrackEventsContext { - model_slug: "gpt-5".to_string(), - thread_id: "thread-1".to_string(), - turn_id: "turn-1".to_string(), - }; - let turn_2 = TrackEventsContext { - model_slug: "gpt-5".to_string(), - thread_id: "thread-1".to_string(), - turn_id: "turn-2".to_string(), - }; - - assert_eq!(queue.should_enqueue_plugin_used(&turn_1, &plugin), true); - assert_eq!(queue.should_enqueue_plugin_used(&turn_1, &plugin), false); - assert_eq!(queue.should_enqueue_plugin_used(&turn_2, &plugin), true); -} - #[tokio::test] async fn reducer_ingests_skill_invoked_fact() { let mut reducer = AnalyticsReducer::default(); @@ -1650,7 +1552,7 @@ async fn reducer_ingests_hook_run_fact() { } #[tokio::test] -async fn reducer_ingests_app_and_plugin_facts() { +async fn reducer_ingests_app_facts() { let mut reducer = AnalyticsReducer::default(); let mut events = Vec::new(); let tracking = TrackEventsContext { @@ -1685,56 +1587,10 @@ async fn reducer_ingests_app_and_plugin_facts() { &mut events, ) .await; - reducer - .ingest( - AnalyticsFact::Custom(CustomAnalyticsFact::PluginUsed(PluginUsedInput { - tracking, - plugin: sample_plugin_metadata(), - })), - &mut events, - ) - .await; - let payload = serde_json::to_value(&events).expect("serialize events"); - assert_eq!(payload.as_array().expect("events array").len(), 3); + assert_eq!(payload.as_array().expect("events array").len(), 2); assert_eq!(payload[0]["event_type"], "codex_app_mentioned"); assert_eq!(payload[1]["event_type"], "codex_app_used"); - assert_eq!(payload[2]["event_type"], "codex_plugin_used"); -} - -#[tokio::test] -async fn reducer_ingests_plugin_state_changed_fact() { - let mut reducer = AnalyticsReducer::default(); - let mut events = Vec::new(); - - reducer - .ingest( - AnalyticsFact::Custom(CustomAnalyticsFact::PluginStateChanged( - PluginStateChangedInput { - plugin: sample_plugin_metadata(), - state: PluginState::Disabled, - }, - )), - &mut events, - ) - .await; - - let payload = serde_json::to_value(&events).expect("serialize events"); - assert_eq!( - payload, - json!([{ - "event_type": "codex_plugin_disabled", - "event_params": { - "plugin_id": "sample@test", - "plugin_name": "sample", - "marketplace_name": "test", - "has_skills": true, - "mcp_server_count": 2, - "connector_ids": ["calendar", "drive"], - "product_client_id": originator().value - } - }]) - ); } #[test] @@ -2405,20 +2261,3 @@ async fn turn_completed_without_started_notification_emits_null_started_at() { ); assert_eq!(payload["event_params"]["total_tokens"], json!(null)); } - -fn sample_plugin_metadata() -> PluginTelemetryMetadata { - PluginTelemetryMetadata { - plugin_id: PluginId::parse("sample@test").expect("valid plugin id"), - capability_summary: Some(PluginCapabilitySummary { - config_name: "sample@test".to_string(), - display_name: "sample".to_string(), - description: None, - has_skills: true, - mcp_server_names: vec!["mcp-1".to_string(), "mcp-2".to_string()], - app_connector_ids: vec![ - AppConnectorId("calendar".to_string()), - AppConnectorId("drive".to_string()), - ], - }), - } -} diff --git a/vendor/codex/codex-rs/analytics/src/client.rs b/vendor/codex/codex-rs/analytics/src/client.rs index a3a20231..6881984f 100644 --- a/vendor/codex/codex-rs/analytics/src/client.rs +++ b/vendor/codex/codex-rs/analytics/src/client.rs @@ -12,8 +12,6 @@ use crate::facts::AppUsedInput; use crate::facts::CustomAnalyticsFact; use crate::facts::HookRunFact; use crate::facts::HookRunInput; -use crate::facts::PluginState; -use crate::facts::PluginStateChangedInput; use crate::facts::SkillInvocation; use crate::facts::SkillInvokedInput; use crate::facts::SubAgentThreadStartedInput; @@ -29,7 +27,6 @@ use codex_app_server_protocol::RequestId; use codex_app_server_protocol::ServerNotification; use codex_login::AuthManager; use codex_login::default_client::create_client; -use codex_plugin::PluginTelemetryMetadata; use std::collections::HashSet; use std::sync::Arc; use std::sync::Mutex; @@ -44,7 +41,6 @@ const ANALYTICS_EVENT_DEDUPE_MAX_KEYS: usize = 4096; pub(crate) struct AnalyticsEventsQueue { pub(crate) sender: mpsc::Sender, pub(crate) app_used_emitted_keys: Arc>>, - pub(crate) plugin_used_emitted_keys: Arc>>, } #[derive(Clone)] @@ -67,7 +63,6 @@ impl AnalyticsEventsQueue { Self { sender, app_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), - plugin_used_emitted_keys: Arc::new(Mutex::new(HashSet::new())), } } @@ -95,21 +90,6 @@ impl AnalyticsEventsQueue { } emitted.insert((tracking.turn_id.clone(), connector_id.clone())) } - - pub(crate) fn should_enqueue_plugin_used( - &self, - tracking: &TrackEventsContext, - plugin: &PluginTelemetryMetadata, - ) -> bool { - let mut emitted = self - .plugin_used_emitted_keys - .lock() - .unwrap_or_else(std::sync::PoisonError::into_inner); - if emitted.len() >= ANALYTICS_EVENT_DEDUPE_MAX_KEYS { - emitted.clear(); - } - emitted.insert((tracking.turn_id.clone(), plugin.plugin_id.as_key())) - } } impl AnalyticsEventsClient { @@ -204,15 +184,6 @@ impl AnalyticsEventsClient { ))); } - pub fn track_plugin_used(&self, tracking: TrackEventsContext, plugin: PluginTelemetryMetadata) { - if !self.queue.should_enqueue_plugin_used(&tracking, &plugin) { - return; - } - self.record_fact(AnalyticsFact::Custom(CustomAnalyticsFact::PluginUsed( - crate::facts::PluginUsedInput { tracking, plugin }, - ))); - } - pub fn track_compaction(&self, event: crate::facts::CodexCompactionEvent) { self.record_fact(AnalyticsFact::Custom(CustomAnalyticsFact::Compaction( Box::new(event), @@ -231,42 +202,6 @@ impl AnalyticsEventsClient { ))); } - pub fn track_plugin_installed(&self, plugin: PluginTelemetryMetadata) { - self.record_fact(AnalyticsFact::Custom( - CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput { - plugin, - state: PluginState::Installed, - }), - )); - } - - pub fn track_plugin_uninstalled(&self, plugin: PluginTelemetryMetadata) { - self.record_fact(AnalyticsFact::Custom( - CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput { - plugin, - state: PluginState::Uninstalled, - }), - )); - } - - pub fn track_plugin_enabled(&self, plugin: PluginTelemetryMetadata) { - self.record_fact(AnalyticsFact::Custom( - CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput { - plugin, - state: PluginState::Enabled, - }), - )); - } - - pub fn track_plugin_disabled(&self, plugin: PluginTelemetryMetadata) { - self.record_fact(AnalyticsFact::Custom( - CustomAnalyticsFact::PluginStateChanged(PluginStateChangedInput { - plugin, - state: PluginState::Disabled, - }), - )); - } - pub(crate) fn record_fact(&self, input: AnalyticsFact) { if self.analytics_enabled == Some(false) { return; diff --git a/vendor/codex/codex-rs/analytics/src/events.rs b/vendor/codex/codex-rs/analytics/src/events.rs index 73f2886f..2ec16cdf 100644 --- a/vendor/codex/codex-rs/analytics/src/events.rs +++ b/vendor/codex/codex-rs/analytics/src/events.rs @@ -10,7 +10,6 @@ use crate::facts::CompactionStrategy; use crate::facts::CompactionTrigger; use crate::facts::HookRunFact; use crate::facts::InvocationType; -use crate::facts::PluginState; use crate::facts::SubAgentThreadStartedInput; use crate::facts::ThreadInitializationMode; use crate::facts::TrackEventsContext; @@ -21,7 +20,6 @@ use crate::facts::TurnSubmissionType; use crate::now_unix_seconds; use codex_app_server_protocol::CodexErrorInfo; use codex_login::default_client::originator; -use codex_plugin::PluginTelemetryMetadata; use codex_protocol::approvals::NetworkApprovalProtocol; use codex_protocol::models::PermissionProfile; use codex_protocol::models::SandboxPermissions; @@ -61,11 +59,6 @@ pub(crate) enum TrackEventRequest { Compaction(Box), TurnEvent(Box), TurnSteer(CodexTurnSteerEventRequest), - PluginUsed(CodexPluginUsedEventRequest), - PluginInstalled(CodexPluginEventRequest), - PluginUninstalled(CodexPluginEventRequest), - PluginEnabled(CodexPluginEventRequest), - PluginDisabled(CodexPluginEventRequest), } #[derive(Serialize)] @@ -530,47 +523,6 @@ pub(crate) struct CodexTurnSteerEventRequest { pub(crate) event_params: CodexTurnSteerEventParams, } -#[derive(Serialize)] -pub(crate) struct CodexPluginMetadata { - pub(crate) plugin_id: Option, - pub(crate) plugin_name: Option, - pub(crate) marketplace_name: Option, - pub(crate) has_skills: Option, - pub(crate) mcp_server_count: Option, - pub(crate) connector_ids: Option>, - pub(crate) product_client_id: Option, -} - -#[derive(Serialize)] -pub(crate) struct CodexPluginUsedMetadata { - #[serde(flatten)] - pub(crate) plugin: CodexPluginMetadata, - pub(crate) thread_id: Option, - pub(crate) turn_id: Option, - pub(crate) model_slug: Option, -} - -#[derive(Serialize)] -pub(crate) struct CodexPluginEventRequest { - pub(crate) event_type: &'static str, - pub(crate) event_params: CodexPluginMetadata, -} - -#[derive(Serialize)] -pub(crate) struct CodexPluginUsedEventRequest { - pub(crate) event_type: &'static str, - pub(crate) event_params: CodexPluginUsedMetadata, -} - -pub(crate) fn plugin_state_event_type(state: PluginState) -> &'static str { - match state { - PluginState::Installed => "codex_plugin_installed", - PluginState::Uninstalled => "codex_plugin_uninstalled", - PluginState::Enabled => "codex_plugin_enabled", - PluginState::Disabled => "codex_plugin_disabled", - } -} - pub(crate) fn codex_app_metadata( tracking: &TrackEventsContext, app: AppInvocation, @@ -586,29 +538,6 @@ pub(crate) fn codex_app_metadata( } } -pub(crate) fn codex_plugin_metadata(plugin: PluginTelemetryMetadata) -> CodexPluginMetadata { - let capability_summary = plugin.capability_summary; - CodexPluginMetadata { - plugin_id: Some(plugin.plugin_id.as_key()), - plugin_name: Some(plugin.plugin_id.plugin_name), - marketplace_name: Some(plugin.plugin_id.marketplace_name), - has_skills: capability_summary - .as_ref() - .map(|summary| summary.has_skills), - mcp_server_count: capability_summary - .as_ref() - .map(|summary| summary.mcp_server_names.len()), - connector_ids: capability_summary.map(|summary| { - summary - .app_connector_ids - .into_iter() - .map(|connector_id| connector_id.0) - .collect() - }), - product_client_id: Some(originator().value), - } -} - pub(crate) fn codex_compaction_event_params( input: CodexCompactionEvent, app_server_client: CodexAppServerClientMetadata, @@ -640,18 +569,6 @@ pub(crate) fn codex_compaction_event_params( } } -pub(crate) fn codex_plugin_used_metadata( - tracking: &TrackEventsContext, - plugin: PluginTelemetryMetadata, -) -> CodexPluginUsedMetadata { - CodexPluginUsedMetadata { - plugin: codex_plugin_metadata(plugin), - thread_id: Some(tracking.thread_id.clone()), - turn_id: Some(tracking.turn_id.clone()), - model_slug: Some(tracking.model_slug.clone()), - } -} - pub(crate) fn codex_hook_run_metadata( tracking: &TrackEventsContext, hook: HookRunFact, diff --git a/vendor/codex/codex-rs/analytics/src/facts.rs b/vendor/codex/codex-rs/analytics/src/facts.rs index 1d371acb..fe2a6e9a 100644 --- a/vendor/codex/codex-rs/analytics/src/facts.rs +++ b/vendor/codex/codex-rs/analytics/src/facts.rs @@ -7,7 +7,6 @@ use codex_app_server_protocol::InitializeParams; use codex_app_server_protocol::JSONRPCErrorError; use codex_app_server_protocol::RequestId; use codex_app_server_protocol::ServerNotification; -use codex_plugin::PluginTelemetryMetadata; use codex_protocol::config_types::ApprovalsReviewer; use codex_protocol::config_types::ModeKind; use codex_protocol::config_types::Personality; @@ -302,8 +301,6 @@ pub(crate) enum CustomAnalyticsFact { AppMentioned(AppMentionedInput), AppUsed(AppUsedInput), HookRun(HookRunInput), - PluginUsed(PluginUsedInput), - PluginStateChanged(PluginStateChangedInput), } pub(crate) struct SkillInvokedInput { @@ -331,21 +328,3 @@ pub struct HookRunFact { pub hook_source: HookSource, pub status: HookRunStatus, } - -pub(crate) struct PluginUsedInput { - pub tracking: TrackEventsContext, - pub plugin: PluginTelemetryMetadata, -} - -pub(crate) struct PluginStateChangedInput { - pub plugin: PluginTelemetryMetadata, - pub state: PluginState, -} - -#[derive(Clone, Copy)] -pub(crate) enum PluginState { - Installed, - Uninstalled, - Enabled, - Disabled, -} diff --git a/vendor/codex/codex-rs/analytics/src/reducer.rs b/vendor/codex/codex-rs/analytics/src/reducer.rs index a6ce3fc8..b4e13c58 100644 --- a/vendor/codex/codex-rs/analytics/src/reducer.rs +++ b/vendor/codex/codex-rs/analytics/src/reducer.rs @@ -4,8 +4,6 @@ use crate::events::CodexAppServerClientMetadata; use crate::events::CodexAppUsedEventRequest; use crate::events::CodexCompactionEventRequest; use crate::events::CodexHookRunEventRequest; -use crate::events::CodexPluginEventRequest; -use crate::events::CodexPluginUsedEventRequest; use crate::events::CodexRuntimeMetadata; use crate::events::CodexTurnEventParams; use crate::events::CodexTurnEventRequest; @@ -22,9 +20,6 @@ use crate::events::TrackEventRequest; use crate::events::codex_app_metadata; use crate::events::codex_compaction_event_params; use crate::events::codex_hook_run_metadata; -use crate::events::codex_plugin_metadata; -use crate::events::codex_plugin_used_metadata; -use crate::events::plugin_state_event_type; use crate::events::subagent_parent_thread_id; use crate::events::subagent_source_name; use crate::events::subagent_thread_started_event_request; @@ -35,9 +30,6 @@ use crate::facts::AppUsedInput; use crate::facts::CodexCompactionEvent; use crate::facts::CustomAnalyticsFact; use crate::facts::HookRunInput; -use crate::facts::PluginState; -use crate::facts::PluginStateChangedInput; -use crate::facts::PluginUsedInput; use crate::facts::SkillInvokedInput; use crate::facts::SubAgentThreadStartedInput; use crate::facts::ThreadInitializationMode; @@ -223,12 +215,6 @@ impl AnalyticsReducer { CustomAnalyticsFact::HookRun(input) => { self.ingest_hook_run(input, out); } - CustomAnalyticsFact::PluginUsed(input) => { - self.ingest_plugin_used(input, out); - } - CustomAnalyticsFact::PluginStateChanged(input) => { - self.ingest_plugin_state_changed(input, out); - } }, } } @@ -456,32 +442,6 @@ impl AnalyticsReducer { })); } - fn ingest_plugin_used(&mut self, input: PluginUsedInput, out: &mut Vec) { - let PluginUsedInput { tracking, plugin } = input; - out.push(TrackEventRequest::PluginUsed(CodexPluginUsedEventRequest { - event_type: "codex_plugin_used", - event_params: codex_plugin_used_metadata(&tracking, plugin), - })); - } - - fn ingest_plugin_state_changed( - &mut self, - input: PluginStateChangedInput, - out: &mut Vec, - ) { - let PluginStateChangedInput { plugin, state } = input; - let event = CodexPluginEventRequest { - event_type: plugin_state_event_type(state), - event_params: codex_plugin_metadata(plugin), - }; - out.push(match state { - PluginState::Installed => TrackEventRequest::PluginInstalled(event), - PluginState::Uninstalled => TrackEventRequest::PluginUninstalled(event), - PluginState::Enabled => TrackEventRequest::PluginEnabled(event), - PluginState::Disabled => TrackEventRequest::PluginDisabled(event), - }); - } - fn ingest_response( &mut self, connection_id: u64, diff --git a/vendor/codex/codex-rs/plugin/BUILD.bazel b/vendor/codex/codex-rs/plugin/BUILD.bazel deleted file mode 100644 index 292606ff..00000000 --- a/vendor/codex/codex-rs/plugin/BUILD.bazel +++ /dev/null @@ -1,15 +0,0 @@ -load("//:defs.bzl", "codex_rust_crate") - -codex_rust_crate( - name = "plugin", - crate_name = "codex_plugin", - compile_data = glob( - include = ["**"], - exclude = [ - "**/* *", - "BUILD.bazel", - "Cargo.toml", - ], - allow_empty = True, - ), -) diff --git a/vendor/codex/codex-rs/plugin/Cargo.toml b/vendor/codex/codex-rs/plugin/Cargo.toml deleted file mode 100644 index b72d7468..00000000 --- a/vendor/codex/codex-rs/plugin/Cargo.toml +++ /dev/null @@ -1,18 +0,0 @@ -[package] -edition.workspace = true -license.workspace = true -name = "codex-plugin" -version.workspace = true - -[lib] -doctest = false -name = "codex_plugin" -path = "src/lib.rs" - -[lints] -workspace = true - -[dependencies] -codex-utils-absolute-path = { workspace = true } -codex-utils-plugins = { workspace = true } -thiserror = { workspace = true } diff --git a/vendor/codex/codex-rs/plugin/src/lib.rs b/vendor/codex/codex-rs/plugin/src/lib.rs deleted file mode 100644 index b984b9d2..00000000 --- a/vendor/codex/codex-rs/plugin/src/lib.rs +++ /dev/null @@ -1,54 +0,0 @@ -//! Shared plugin identifiers and telemetry-facing summaries. - -pub use codex_utils_plugins::mention_syntax; -pub use codex_utils_plugins::plugin_namespace_for_skill_path; - -mod load_outcome; -mod plugin_id; - -pub use load_outcome::EffectiveSkillRoots; -pub use load_outcome::LoadedPlugin; -pub use load_outcome::PluginLoadOutcome; -pub use load_outcome::prompt_safe_plugin_description; -pub use plugin_id::PluginId; -pub use plugin_id::PluginIdError; -pub use plugin_id::validate_plugin_segment; - -#[derive(Debug, Clone, PartialEq, Eq, Hash)] -pub struct AppConnectorId(pub String); - -#[derive(Debug, Clone, Default, PartialEq, Eq)] -pub struct PluginCapabilitySummary { - pub config_name: String, - pub display_name: String, - pub description: Option, - pub has_skills: bool, - pub mcp_server_names: Vec, - pub app_connector_ids: Vec, -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct PluginTelemetryMetadata { - pub plugin_id: PluginId, - pub capability_summary: Option, -} - -impl PluginTelemetryMetadata { - pub fn from_plugin_id(plugin_id: &PluginId) -> Self { - Self { - plugin_id: plugin_id.clone(), - capability_summary: None, - } - } -} - -impl PluginCapabilitySummary { - pub fn telemetry_metadata(&self) -> Option { - PluginId::parse(&self.config_name) - .ok() - .map(|plugin_id| PluginTelemetryMetadata { - plugin_id, - capability_summary: Some(self.clone()), - }) - } -} diff --git a/vendor/codex/codex-rs/plugin/src/load_outcome.rs b/vendor/codex/codex-rs/plugin/src/load_outcome.rs deleted file mode 100644 index 062886be..00000000 --- a/vendor/codex/codex-rs/plugin/src/load_outcome.rs +++ /dev/null @@ -1,162 +0,0 @@ -use std::collections::HashMap; -use std::collections::HashSet; - -use codex_utils_absolute_path::AbsolutePathBuf; - -use crate::AppConnectorId; -use crate::PluginCapabilitySummary; - -const MAX_CAPABILITY_SUMMARY_DESCRIPTION_LEN: usize = 1024; - -/// A plugin that was loaded from disk, including merged MCP server definitions. -#[derive(Debug, Clone, PartialEq)] -pub struct LoadedPlugin { - pub config_name: String, - pub manifest_name: Option, - pub manifest_description: Option, - pub root: AbsolutePathBuf, - pub enabled: bool, - pub skill_roots: Vec, - pub disabled_skill_paths: HashSet, - pub has_enabled_skills: bool, - pub mcp_servers: HashMap, - pub apps: Vec, - pub error: Option, -} - -impl LoadedPlugin { - pub fn is_active(&self) -> bool { - self.enabled && self.error.is_none() - } -} - -fn plugin_capability_summary_from_loaded( - plugin: &LoadedPlugin, -) -> Option { - if !plugin.is_active() { - return None; - } - - let mut mcp_server_names: Vec = plugin.mcp_servers.keys().cloned().collect(); - mcp_server_names.sort_unstable(); - - let summary = PluginCapabilitySummary { - config_name: plugin.config_name.clone(), - display_name: plugin - .manifest_name - .clone() - .unwrap_or_else(|| plugin.config_name.clone()), - description: prompt_safe_plugin_description(plugin.manifest_description.as_deref()), - has_skills: plugin.has_enabled_skills, - mcp_server_names, - app_connector_ids: plugin.apps.clone(), - }; - - (summary.has_skills - || !summary.mcp_server_names.is_empty() - || !summary.app_connector_ids.is_empty()) - .then_some(summary) -} - -/// Normalizes plugin descriptions for inclusion in model-facing capability summaries. -pub fn prompt_safe_plugin_description(description: Option<&str>) -> Option { - let description = description? - .split_whitespace() - .collect::>() - .join(" "); - if description.is_empty() { - return None; - } - - Some( - description - .chars() - .take(MAX_CAPABILITY_SUMMARY_DESCRIPTION_LEN) - .collect(), - ) -} - -/// Outcome of loading configured plugins (skills roots, MCP, apps, errors). -#[derive(Debug, Clone, PartialEq)] -pub struct PluginLoadOutcome { - plugins: Vec>, - capability_summaries: Vec, -} - -impl Default for PluginLoadOutcome { - fn default() -> Self { - Self::from_plugins(Vec::new()) - } -} - -impl PluginLoadOutcome { - pub fn from_plugins(plugins: Vec>) -> Self { - let capability_summaries = plugins - .iter() - .filter_map(plugin_capability_summary_from_loaded) - .collect::>(); - Self { - plugins, - capability_summaries, - } - } - - pub fn effective_skill_roots(&self) -> Vec { - let mut skill_roots: Vec = self - .plugins - .iter() - .filter(|plugin| plugin.is_active()) - .flat_map(|plugin| plugin.skill_roots.iter().cloned()) - .collect(); - skill_roots.sort_unstable(); - skill_roots.dedup(); - skill_roots - } - - pub fn effective_mcp_servers(&self) -> HashMap { - let mut mcp_servers = HashMap::new(); - for plugin in self.plugins.iter().filter(|plugin| plugin.is_active()) { - for (name, config) in &plugin.mcp_servers { - mcp_servers - .entry(name.clone()) - .or_insert_with(|| config.clone()); - } - } - mcp_servers - } - - pub fn effective_apps(&self) -> Vec { - let mut apps = Vec::new(); - let mut seen_connector_ids = HashSet::new(); - - for plugin in self.plugins.iter().filter(|plugin| plugin.is_active()) { - for connector_id in &plugin.apps { - if seen_connector_ids.insert(connector_id.clone()) { - apps.push(connector_id.clone()); - } - } - } - - apps - } - - pub fn capability_summaries(&self) -> &[PluginCapabilitySummary] { - &self.capability_summaries - } - - pub fn plugins(&self) -> &[LoadedPlugin] { - &self.plugins - } -} - -/// Implemented by [`PluginLoadOutcome`] so callers (e.g. skills) can depend on `codex-plugin` -/// without naming the MCP config type parameter. -pub trait EffectiveSkillRoots { - fn effective_skill_roots(&self) -> Vec; -} - -impl EffectiveSkillRoots for PluginLoadOutcome { - fn effective_skill_roots(&self) -> Vec { - PluginLoadOutcome::effective_skill_roots(self) - } -} diff --git a/vendor/codex/codex-rs/plugin/src/plugin_id.rs b/vendor/codex/codex-rs/plugin/src/plugin_id.rs deleted file mode 100644 index 07511632..00000000 --- a/vendor/codex/codex-rs/plugin/src/plugin_id.rs +++ /dev/null @@ -1,64 +0,0 @@ -//! Stable plugin identifier parsing and validation shared with the plugin cache. - -#[derive(Debug, thiserror::Error)] -pub enum PluginIdError { - #[error("{0}")] - Invalid(String), -} - -#[derive(Debug, Clone, PartialEq, Eq)] -pub struct PluginId { - pub plugin_name: String, - pub marketplace_name: String, -} - -impl PluginId { - pub fn new(plugin_name: String, marketplace_name: String) -> Result { - validate_plugin_segment(&plugin_name, "plugin name").map_err(PluginIdError::Invalid)?; - validate_plugin_segment(&marketplace_name, "marketplace name") - .map_err(PluginIdError::Invalid)?; - Ok(Self { - plugin_name, - marketplace_name, - }) - } - - pub fn parse(plugin_key: &str) -> Result { - let Some((plugin_name, marketplace_name)) = plugin_key.rsplit_once('@') else { - return Err(PluginIdError::Invalid(format!( - "invalid plugin key `{plugin_key}`; expected @" - ))); - }; - if plugin_name.is_empty() || marketplace_name.is_empty() { - return Err(PluginIdError::Invalid(format!( - "invalid plugin key `{plugin_key}`; expected @" - ))); - } - - Self::new(plugin_name.to_string(), marketplace_name.to_string()).map_err(|err| match err { - PluginIdError::Invalid(message) => { - PluginIdError::Invalid(format!("{message} in `{plugin_key}`")) - } - }) - } - - pub fn as_key(&self) -> String { - format!("{}@{}", self.plugin_name, self.marketplace_name) - } -} - -/// Validates a single path segment used in plugin IDs and cache layout. -pub fn validate_plugin_segment(segment: &str, kind: &str) -> Result<(), String> { - if segment.is_empty() { - return Err(format!("invalid {kind}: must not be empty")); - } - if !segment - .chars() - .all(|ch| ch.is_ascii_alphanumeric() || ch == '-' || ch == '_') - { - return Err(format!( - "invalid {kind}: only ASCII letters, digits, `_`, and `-` are allowed" - )); - } - Ok(()) -} diff --git a/vendor/codex/codex-rs/plugin/src/plugin_namespace.rs b/vendor/codex/codex-rs/plugin/src/plugin_namespace.rs deleted file mode 100644 index 6688ae04..00000000 --- a/vendor/codex/codex-rs/plugin/src/plugin_namespace.rs +++ /dev/null @@ -1,70 +0,0 @@ -//! Resolve plugin namespace from skill file paths by walking ancestors for `plugin.json`. - -use std::fs; -use std::path::Path; - -/// Relative path from a plugin root to its manifest file. -pub const PLUGIN_MANIFEST_PATH: &str = ".codex-plugin/plugin.json"; - -#[derive(serde::Deserialize)] -#[serde(rename_all = "camelCase")] -struct RawPluginManifestName { - #[serde(default)] - name: String, -} - -fn plugin_manifest_name(plugin_root: &Path) -> Option { - let manifest_path = plugin_root.join(PLUGIN_MANIFEST_PATH); - if !manifest_path.is_file() { - return None; - } - let contents = fs::read_to_string(&manifest_path).ok()?; - let RawPluginManifestName { name: raw_name } = serde_json::from_str(&contents).ok()?; - Some( - plugin_root - .file_name() - .and_then(|entry| entry.to_str()) - .filter(|_| raw_name.trim().is_empty()) - .unwrap_or(raw_name.as_str()) - .to_string(), - ) -} - -/// Returns the plugin manifest `name` for the nearest ancestor of `path` that contains a valid -/// plugin manifest (same `name` rules as full manifest loading in codex-core). -pub fn plugin_namespace_for_skill_path(path: &Path) -> Option { - for ancestor in path.ancestors() { - if let Some(name) = plugin_manifest_name(ancestor) { - return Some(name); - } - } - None -} - -#[cfg(test)] -mod tests { - use super::plugin_namespace_for_skill_path; - use std::fs; - use tempfile::tempdir; - - #[test] - fn uses_manifest_name() { - let tmp = tempdir().expect("tempdir"); - let plugin_root = tmp.path().join("plugins/sample"); - let skill_path = plugin_root.join("skills/search/SKILL.md"); - - fs::create_dir_all(skill_path.parent().expect("parent")).expect("mkdir"); - fs::create_dir_all(plugin_root.join(".codex-plugin")).expect("mkdir manifest"); - fs::write( - plugin_root.join(".codex-plugin/plugin.json"), - r#"{"name":"sample"}"#, - ) - .expect("write manifest"); - fs::write(&skill_path, "---\ndescription: search\n---\n").expect("write skill"); - - assert_eq!( - plugin_namespace_for_skill_path(&skill_path), - Some("sample".to_string()) - ); - } -}