Skip to content

Make selected plugin roots URI-native - #28918

Merged
jif-oai merged 16 commits into
mainfrom
jif/uri-native-selected-plugins
Jun 23, 2026
Merged

Make selected plugin roots URI-native#28918
jif-oai merged 16 commits into
mainfrom
jif/uri-native-selected-plugins

Conversation

@jif-oai

@jif-oai jif-oai commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

Why

Selected capability roots belong to the executor filesystem, not the app-server host. Converting their path strings into the host's native Path breaks whenever the two machines use different path conventions, such as a Windows executor behind a Unix app-server.

This PR establishes PathUri as the selected-plugin boundary so the executor remains authoritative for its paths.

What changed

  • Require selectedCapabilityRoots[].location.path to be a canonical file: URI and deserialize it directly as PathUri; native path strings are rejected.
  • Update the app-server schema, generated TypeScript, examples, and request coverage for the URI contract.
  • Keep selected roots, resolved plugin locations, manifest paths, and manifest resources as PathUri.
  • Inspect and read plugin roots and manifests only through the selected environment's ExecutorFileSystem.
  • Parse executor manifests with the shared URI-native parser from Decouple plugin manifest path resolution #29620 instead of projecting them onto the host filesystem.
  • Enforce resource containment lexically and preserve the root URI's POSIX or Windows path convention.
  • Cover foreign Windows plugin roots and URI-native manifest resources.
thread/start
  selectedCapabilityRoots[].location.path = "file:///C:/plugins/demo"
                              | PathUri
                              v
                    ExecutorFileSystem
                              |
                              +--> plugin.json
                              +--> manifest resources

This PR stops at the shared selected-plugin representation. The next two PRs remove the remaining host-path projections in the skill and MCP consumers.

Stack

  1. path-uri: add lexical containment #29614 — add lexical PathUri containment.
  2. Decouple plugin manifest path resolution #29620 — share URI-native manifest path resolution.
  3. This PR — keep selected plugin roots and resources URI-native.
  4. Load executor skills without host path conversion #29626 — load executor skills without host path conversion.
  5. Keep executor plugin MCP paths URI-native #29628 — resolve executor MCP working directories without host path conversion.

@jif-oai
jif-oai requested a review from a team as a code owner June 18, 2026 13:59

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cd6444fcfb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread codex-rs/ext/mcp/src/executor_plugin/provider.rs
Comment thread codex-rs/ext/skills/src/provider/executor.rs
Comment thread codex-rs/plugin/Cargo.toml
Comment thread codex-rs/config/src/mcp_types.rs Outdated
Comment thread codex-rs/protocol/src/capabilities.rs Outdated
Comment thread codex-rs/core-plugins/src/manifest.rs Outdated
Comment thread codex-rs/app-server/README.md Outdated
@jif-oai
jif-oai force-pushed the jif/uri-native-selected-plugins branch from de5920d to 25a3f8d Compare June 23, 2026 12:24
@jif-oai
jif-oai changed the base branch from main to jif/uri-native-plugin-manifests June 23, 2026 12:24
Comment thread codex-rs/protocol/src/capabilities.rs
jif-oai added a commit that referenced this pull request Jun 23, 2026
## Why

Plugin manifests use the same schema whether the package lives on the
host or in an executor. Only the path representation differs: host
callers need native `Path` inputs and `AbsolutePathBuf` outputs, while
executor callers need `PathUri` throughout.

Maintaining separate parsing or resolver implementations would duplicate
the manifest rules and allow them to drift. This PR instead makes
URI-native resolution the single parsing path and keeps host conversion
at the boundary.

## What changed

- Make `parse_plugin_manifest_uri` the shared manifest parser and
resolve every path-bearing field as `PathUri`.
- Keep the existing host entrypoint as a thin adapter: convert its
native root and manifest path to `PathUri`, run the shared parser, then
map resources back to `AbsolutePathBuf`.
- Expose `PluginManifest::try_map_resources` so callers can convert the
generic resource type without duplicating manifest construction.
- Resolve relative manifest paths using the root URI's convention:
backslashes are separators for Windows roots and ordinary filename
characters for POSIX roots.
- Apply lexical containment after URI resolution, rejecting absolute
paths and parent traversal outside the plugin root.
- Make encoded backslashes fail containment only for Windows URIs;
encoded `/` remains unsafe for every convention.
- Use a host-native synthetic root for marketplace fallback manifests so
the host adapter also works on Windows.

```text
host Path --------> PathUri --\
                              +--> one manifest parser --> PluginManifest<PathUri>
executor PathUri -------------/

host result: PluginManifest<PathUri> --> PluginManifest<AbsolutePathBuf>
```

Existing host manifest behavior is preserved; #28918 is the first
executor consumer.

## Verification

- `just test -p codex-utils-path-uri`
- `just test -p codex-plugin`
- `just test -p codex-core-plugins`

## Stack

1. #29614 — add lexical `PathUri` containment.
2. **This PR** — share URI-native manifest path resolution.
3. #28918 — keep selected plugin roots and resources URI-native.
4. #29626 — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
Base automatically changed from jif/uri-native-plugin-manifests to main June 23, 2026 20:34
@jif-oai
jif-oai merged commit 2e69966 into main Jun 23, 2026
30 of 31 checks passed
@jif-oai
jif-oai deleted the jif/uri-native-selected-plugins branch June 23, 2026 21:51
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 23, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants