Files
codex/codex-rs/plugin/src/provider.rs
T
Anthony Tafoya a7e069dc3a Separate plugin catalog listing from package resolution (#46567)
## What changed

- Move catalog types and the `PluginProvider` listing interface into `codex-core-plugins`, with a concrete `PluginListQuery` carrying thread, turn, and MCP resource context.
- Remove root resolution from `PluginProvider`; keep executor package access in `ExecutorPluginProvider::resolve_bound`, which retains the filesystem used to resolve the package.
- Add shared provider result and error types, and re-export the listing API from `codex-mcp-extension`.

## Testing

Update executor and manifest tests to use `resolve_bound`, and assert that malformed manifest errors preserve the underlying `serde_json::Error` as their source.

GitOrigin-RevId: c6cd5a0269ed3b8ac9b93f306a70821e63e3671e
2026-09-19 01:49:01 +00:00

109 lines
3.3 KiB
Rust

//! Authority-bound plugin descriptors and resource locations.
use crate::manifest::PluginManifest;
use codex_utils_path_uri::PathUri;
use thiserror::Error;
/// A plugin resource paired with the environment that owns its filesystem.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum PluginResourceLocator {
Environment {
/// Environment whose filesystem owns the resource.
environment_id: String,
/// Resource URI within that filesystem.
path: PathUri,
},
}
/// Authority-bound location of a resolved plugin package.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ResolvedPluginLocation {
Environment {
/// Environment whose filesystem owns the package.
environment_id: String,
/// Package root URI within that filesystem.
root: PathUri,
},
}
/// An inert plugin descriptor whose resources retain their source authority.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ResolvedPlugin {
selected_root_id: String,
location: ResolvedPluginLocation,
manifest_path: PluginResourceLocator,
manifest: PluginManifest<PluginResourceLocator>,
}
/// Failure to construct a resolved plugin with internally consistent resources.
#[derive(Clone, Debug, Error, PartialEq, Eq)]
pub enum ResolvedPluginError {
#[error("plugin resource path `{path}` is outside package root `{root}`")]
ResourceOutsideRoot { root: PathUri, path: PathUri },
}
impl ResolvedPlugin {
/// Creates an environment-owned descriptor from a validated plugin manifest.
pub fn from_environment(
selected_root_id: String,
environment_id: String,
root: PathUri,
manifest_path: PathUri,
manifest: PluginManifest<PathUri>,
) -> Result<Self, ResolvedPluginError> {
let manifest_path = environment_resource(&environment_id, &root, manifest_path)?;
let manifest = manifest
.try_map_resources(|path| environment_resource(&environment_id, &root, path))?;
Ok(Self {
selected_root_id,
location: ResolvedPluginLocation::Environment {
environment_id,
root,
},
manifest_path,
manifest,
})
}
/// Returns the opaque ID supplied for the selected capability root.
pub fn selected_root_id(&self) -> &str {
&self.selected_root_id
}
/// Returns the authority-bound package location.
pub fn location(&self) -> &ResolvedPluginLocation {
&self.location
}
/// Returns the manifest resource used to resolve this package.
pub fn manifest_path(&self) -> &PluginResourceLocator {
&self.manifest_path
}
/// Returns package metadata whose resource fields retain their source authority.
pub fn manifest(&self) -> &PluginManifest<PluginResourceLocator> {
&self.manifest
}
}
fn environment_resource(
environment_id: &str,
root: &PathUri,
path: PathUri,
) -> Result<PluginResourceLocator, ResolvedPluginError> {
if !path.starts_with(root) {
return Err(ResolvedPluginError::ResourceOutsideRoot {
root: root.clone(),
path,
});
}
Ok(PluginResourceLocator::Environment {
environment_id: environment_id.to_string(),
path,
})
}
#[cfg(test)]
#[path = "provider_tests.rs"]
mod tests;