Skip to content

Decouple plugin manifest path resolution - #29620

Merged
jif-oai merged 9 commits into
mainfrom
jif/uri-native-plugin-manifests
Jun 23, 2026
Merged

Decouple plugin manifest path resolution#29620
jif-oai merged 9 commits into
mainfrom
jif/uri-native-plugin-manifests

Conversation

@jif-oai

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

Copy link
Copy Markdown
Contributor

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.
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. path-uri: add lexical containment #29614 — add lexical PathUri containment.
  2. This PR — share URI-native manifest path resolution.
  3. Make selected plugin roots URI-native #28918 — 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.

@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: 01b4840b95

ℹ️ 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/core-plugins/src/manifest.rs Outdated
Base automatically changed from jif/path-uri-lexical-containment to main June 23, 2026 13:59
@jif-oai
jif-oai requested a review from a team as a code owner June 23, 2026 13:59
Comment thread codex-rs/core-plugins/src/manifest.rs Outdated
@jif-oai
jif-oai enabled auto-merge (squash) June 23, 2026 20:33
@jif-oai
jif-oai merged commit f650088 into main Jun 23, 2026
31 checks passed
@jif-oai
jif-oai deleted the jif/uri-native-plugin-manifests branch June 23, 2026 20:34
@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.

2 participants