Local Plugin UI Containment Bug in Codex App
What version of the Codex App are you using (From “About Codex” dialog)?
Version 26.325.31654 (1272)
What subscription do you have?
Pro
What platform is your computer?
Darwin 24.6.0 arm64 arm
What issue are you seeing?
A local skill-bearing plugin installs cleanly and the CLI/runtime surface is
namespaced correctly, but the Codex Electron app still exposes plugin-owned
skills as directly invokable items in the picker and Skills UI. The same app
also renders local marketplace metadata differently from the curatedBuild iOS Apps plugin.
The core issue is that local plugin-owned skills are not visually contained
behind the plugin entrypoint in Electron, even though the runtime itself is
cleanly namespaced.
What is already proven clean:
- plugin-managed runtime install is proven through installed cache, enabled
config state, and fresh-session visibility
- local plugin source is a materialized directory at
~/plugins/apple-appdev-workflow
- plugin payload no longer ships
node_modules/ - CLI skill listing is namespaced and clean, for example:
apple-appdev-workflow:apple-product-surface-orchestratorapple-appdev-workflow:apple-persistence-orchestratorapple-appdev-workflow:apple-swiftdata-review
- explicit plugin-entry controls are green for both product-surface and
persistence brigades
Remaining Electron-only defects:
- plugin-owned skills still surface outside the plugin entrypoint in
picker/Skills UI
- plugin card metadata uses local marketplace
namein the Category row
instead of marketplace interface.displayName
- local plugin presentation differs from curated plugin presentation even when
plugin-level and skill-level metadata are aligned closely with
Build iOS Apps
Exact text error encountered during local marketplace metadata testing:
Failed to load plugin
invalid marketplace name: only ASCII letters, digits, '_', and '-' are allowed
Exact prompt examples used during validation:
Use [@apple-appdev-workflow](plugin://apple-appdev-workflow@LocalAppleWorkflow) to review the SwiftData model and migration approach for saved reference captures, and recommend what should change first to reduce rollout and data-loss risk.
Review the SwiftData model and migration approach for saved reference captures, and recommend what should change first to reduce rollout and data-loss risk.
Use apple-product-surface-orchestrator to review this SwiftUI app's main product surface and recommend what should change first so the navigation, empty states, and on-screen copy feel more coherent and production-ready.
Representative CLI validation commands:
python3 ./scripts/probe_plugin_managed_runtime.py --repo-root .
codex exec -C /tmp --skip-git-repo-check "List the available plugins in this session by name only."
codex exec -C /tmp --skip-git-repo-check "List the available skills in this session by name only."
Representative clean runtime conclusion:
plugin-managed runtime is proven for the target plugin through installed cache, enabled config state, and fresh-session visibility
Electron-specific text clues observed in app-side logging / Sentry scope:
Skills/list missing short_description ...
method=plugin/read
Why this appears platform-side rather than bundle-side:
- first-party
Build iOS Appsis also a real skills plugin - its installed cache includes
skills/and skill-levelagents/openai.yaml - CLI exposes those skills as namespaced runtime skills
- the local plugin runtime is also namespaced cleanly in CLI
- the exposed/duplicate behavior persists primarily in Electron UI surfaces
rather than in the runtime listing itself
What steps can reproduce the bug?
- Create or use a local plugin marketplace with a local skill-bearing plugin.
In my case:
- marketplace name:
LocalAppleWorkflow - marketplace display name:
Local Apple Workflow - plugin id:
apple-appdev-workflow
- Install the plugin from the local marketplace in the Codex Electron app.
- Confirm the runtime itself is healthy:
- run
python3 ./scripts/probe_plugin_managed_runtime.py --repo-root . - confirm the probe concludes:
plugin-managed runtime is proven for the target plugin through installed cache, enabled config state, and fresh-session visibility
- Confirm CLI runtime namespacing is clean:
- run
codex exec -C /tmp --skip-git-repo-check "List the available plugins in this session by name only." - run
codex exec -C /tmp --skip-git-repo-check "List the available skills in this session by name only." - confirm only namespaced skill entries appear for the local plugin
- Open the plugin card, picker, and Skills tab in the Electron app.
- Observe that plugin-owned skills are exposed as directly invokable UI items
outside the plugin entrypoint, and that the plugin card Category row uses the
marketplace slug-style name rather than the human-facing marketplace
interface.displayName.
What is the expected behavior?
For local skill-bearing plugins, Electron should either:
- preserve plugin containment rules consistently with curated plugins
- or document that local skill-bearing plugins are intentionally exposed as
standalone picker/Skills items
Expected metadata behavior:
- human-facing marketplace labels should use marketplace
interface.displayName
- slug-style marketplace
nameshould remain an internal identifier and not
leak into the plugin card Category row
Instead, I see:
- The local plugin runtime is clean in CLI, but Electron still exposes
plugin-owned skills as standalone invokable items in picker/Skills UI.
- The plugin card Category row uses the marketplace slug-style identifier
instead of the human-facing display name.
- Curated
Build iOS Appsis presented differently in Electron despite both
plugins being real skill-bearing plugins with runtime-visible skills/.
Representative local plugin runtime entries:
apple-appdev-workflow:apple-product-surface-orchestrator
apple-appdev-workflow:apple-persistence-orchestrator
apple-appdev-workflow:apple-swiftdata-review
Representative curated plugin cache root:
~/.codex/plugins/cache/openai-curated/build-ios-apps/...
Additional information
PII-redacted path examples:
/Users/<redacted>/.codex/plugins/cache/LocalAppleWorkflow/apple-appdev-workflow/local/skills/apple-product-surface-orchestrator/SKILL.md
/Users/<redacted>/.codex/plugins/cache/openai-curated/build-ios-apps/...
The local plugin and curated plugin both have:
skills/- plugin-level
agents/openai.yaml - skill-level
agents/openai.yaml
I did not find an explicit allow_implicit_invocation: false in the curated
plugin files I inspected, so the different Electron presentation does not look
like a simple manifest-field difference.
This issue has 4 comments on GitHub. Read the full discussion on GitHub ↗