ci: validate referenced component paths in plugin manifests - #244
ci: validate referenced component paths in plugin manifests#244rootkiller6788 wants to merge 1 commit into
Conversation
validate-plugins.mjs only checks plugin.json against the JSON schema and that the marketplace name matches. A typo'd component path (skills/agents/ commands/rules/hooks/mcpServers/logo) passes schema validation and CI but silently fails to load in Cursor. Add an existence check for every path declared in plugin.json, resolved relative to the plugin directory, with inline hooks/mcpServers objects and absolute-URL logos skipped. Also add scripts/** to the validate-plugins workflow paths filter so a PR that only changes the validator itself triggers the job that runs it.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 2 potential issues.
Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.
Reviewed by Cursor Bugbot for commit 7b25915. Configure here.
| // a typo in the base directory is still caught. | ||
| function checkReferencedPath(pluginName, pluginDir, field, declared) { | ||
| if (typeof declared !== "string" || declared.trim().length === 0) return; | ||
| if (isAbsoluteUrl(declared)) return; |
There was a problem hiding this comment.
URL skip not logo-only
Medium Severity · Logic Bug
checkReferencedPath returns early for any http(s): or data: value on every component field. The schema only allows absolute URLs for logo; for skills, agents, commands, rules, hooks, and mcpServers those strings are local paths. Remote-looking values therefore skip the existence check and can pass CI while Cursor still fails to load them.
Additional Locations (1)
Reviewed by Cursor Bugbot for commit 7b25915. Configure here.
| // Cursor. Glob patterns are checked against their static directory prefix so | ||
| // a typo in the base directory is still caught. | ||
| function checkReferencedPath(pluginName, pluginDir, field, declared) { | ||
| if (typeof declared !== "string" || declared.trim().length === 0) return; |
There was a problem hiding this comment.
Empty paths skip checks
Low Severity · Logic Bug
When a declared component path is empty or only whitespace, checkReferencedPath returns without calling fail. An explicit empty skills/hooks/similar value therefore passes validation even though it is not a usable relative path and will not load in Cursor.
Reviewed by Cursor Bugbot for commit 7b25915. Configure here.


What
scripts/validate-plugins.mjsonly checks plugin.json against the JSON schema and that the marketplace name matches the manifest name. A typo'd component path — e.g."skills": "./skils/"or a renamedhooks/hooks.json— passes schema validation and CI but silently fails to load in Cursor. This PR adds an existence check for every path declared inplugin.json:skills,agents,commands,rules,hooks,mcpServers,logo./prefix stripped)hooks/mcpServersobjects and absolute-URLlogovalues are skipped, matching the schema's allowed shapesskills/*) are validated against their static directory prefix so a typo in the base directory is still caught..) or are absolute are rejectedAlso adds
scripts/**to thevalidate-plugins.ymlpathsfilter, so a PR that only changes the validator itself now triggers the job that runs it (previously a broken validator could merge without CI ever executing it).Why
All 32 current marketplace plugins pass the new check (verified locally). The check only guards future PRs — which is the point of a merge gate: a contributor adding a new plugin or tweaking an existing manifest can't merge a path that Cursor will silently ignore.
Verification
node scripts/validate-plugins.mjsexits 0 on the current repo.skills->./skils/) produces a clear error and non-zero exit:ERROR: Plugin "teaching": skills path "./skils/" does not exist (resolved to teaching\skils).hooksobject (skipped), absolute-URLlogo(skipped), glob with valid/invalid prefix, and../path traversal (rejected).Note
Low Risk
CI-only validator and workflow path filter; no runtime, auth, or marketplace data changes.
Overview
Plugin validation now checks that component paths in
plugin.jsonactually exist under the plugin directory, so typos (e.g.skils/or a renamed hooks file) fail CI instead of silently failing to load in Cursor.Checks cover
skills,agents,commands,rules,hooks,mcpServers, andlogo. Inline objects and absolute-URL logos are skipped. Globs are validated on their static directory prefix; absolute paths and..escapes are rejected.Also includes
scripts/**in the validate-plugins workflow path filter so validator-only PRs still run the job.Reviewed by Cursor Bugbot for commit 7b25915. Bugbot is set up for automated code reviews on this repo. Configure here.