plugin-creator validator rejects valid hook manifests and optional metadata
Problem
The bundled plugin-creator validator diverges from the current plugin
ingestion contract and official plugin documentation.
It currently:
- requires
authorandinterface, although manifest fields other than
name, version, and description are optional;
- rejects
hooks, although plugin manifests support a path, path array,
inline hooks object, or array of inline objects;
- validates only the default
skills/location instead of resolving declared
skill destinations from the plugin root.
As a result, a valid manifest such as the following fails validation:
{
"name": "synthetic-plugin",
"version": "1.0.0",
"description": "Synthetic reproduction.",
"skills": "./custom/skills/",
"hooks": "./custom/hooks/hooks.json"
}
Documentation alignment
The expected behavior follows:
- https://developers.openai.com/codex/plugins/build#plugin-structure
- https://developers.openai.com/codex/plugins/build#manifest-fields
- https://developers.openai.com/codex/plugins/build#path-rules
- https://developers.openai.com/codex/plugins/build#bundled-mcp-servers-and-lifecycle-hooks
The current Rust ingestion code also supports the four documented hook forms,
optional interface metadata, declared skill paths, and optional default
discovery.
Proposed correction
- make
authorandinterfaceoptional while retaining their validation when
present;
- validate all four documented
hooksforms without executing handlers; - resolve declared skill and hook paths relative to the plugin root;
- reject absolute paths, traversal, symlink escapes, missing destinations, and
invalid hook companions;
- keep absent default
skills/andhooks/hooks.jsonoptional.
Synthetic coverage
A focused unittest module covers:
- the official minimal manifest;
- declared skill destinations;
- all four hook forms;
- optional defaults;
- invalid hook JSON and shapes;
- absolute paths, traversal, and symlink escapes;
- optional rich metadata;
- compatibility with existing scaffold output;
- confinement to synthetic temporary plugin state with network access blocked.
Validation completed successfully:
python3 -m unittest codex-rs/skills/src/assets/samples/plugin-creator/scripts/test_validate_plugin.py
— 11 tests passed;
python3 codex-rs/skills/src/assets/samples/skill-creator/scripts/quick_validate.py codex-rs/skills/src/assets/samples/plugin-creator
— Skill is valid!;
git diff --check— passed.
No skill was installed and no personal config, cache, trust, authentication,
marketplace, or real plugin state was read or modified.
A focused implementation is available if the maintainers consider the issue
appropriate and invite a pull request.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗