fix(plugin-dev): align userConfig docs and hook validator with v2.1.207 shell-injection fix - #76576
Conversation
….1.207
Claude Code v2.1.207 rejects ${user_config.*} in shell-form plugin hook,
monitor, and MCP headersHelper commands (shell-injection fix), and no
longer reads pluginConfigs from project settings. The plugin-dev toolkit
did not document userConfig at all and the hook schema validator treated
real plugin hooks.json files (wrapper format, optional matcher) as
invalid.
- Document userConfig schema, storage scopes, and safe migration paths
- Teach exec-form / CLAUDE_PLUGIN_OPTION_* patterns for hooks and headersHelper
- Fix validate-hook-schema.sh: unwrap plugin format, optional matcher,
flag shell-form ${user_config.*}, fix set -e counter arithmetic
- Align plugin-validator security checks with the same rules
Addresses anthropics#76567 and anthropics#76568 for the in-repo author toolkit.
Ready for reviewThis aligns the in-repo plugin author toolkit with Claude Code v2.1.207 shell-injection hardening:
Minimal & correct: docs + validator only — no runtime product binary changes. Happy to iterate on wording or test fixtures. — 传康Kk (@1837620622) |
Second-pass validation (maintainer-ready)Post-landing checklist re-run on
Factual alignment for the new Happy to take wording nits on the migration table if a docs owner wants different emphasis between exec-form — 传康Kk (@1837620622) |
|
Friendly review ping 🙏 Aligns the in-repo plugin-dev toolkit with Claude Code v2.1.207 shell-injection rules ( |
Summary
Claude Code v2.1.207 rejected
${user_config.*}in shell-form plugin hook / monitor / MCPheadersHelpercommands (shell-injection fix) and stopped readingpluginConfigsfrom project-level.claude/settings.json. The hosted plugins reference still shows the old unsafe monitor example (see #76567 / #76568).This PR updates the in-repo plugin author toolkit (
plugin-dev) that Claude and authors actually use when scaffolding plugins—so generated plugins do not ship configs that fail after upgrade.What was wrong in this repo
userConfigwas undocumented inplugin-structure/manifest-reference, so authors had no safe pattern for enable-time options.validate-hook-schema.shrejected real bundled plugins:hooks/hooks.jsonfiles use{"description", "hooks": {...}}; the validator treatedhooks/descriptionas unknown events.matcheris optional (official hooks docs + every bundled plugin omit it in places); the validator required it.${user_config.*}, so authors could not catch a v2.1.207 break before shipping.((error_count++))underset -e, which aborts on the first error (post-increment of0is falsy).Changes
manifest-reference.mduserConfigschema, storage scopes (user /--settings/ managed only), safe vs rejected substitution rulesplugin-structure/SKILL.mduserConfigsection with v2.1.207 caveatshook-development/SKILL.md$CLAUDE_PLUGIN_OPTION_<KEY>, shell-form ban tablemcp-integration/.../authentication.mdheadersHelpermigration: pass options viaenv, not the helper command stringvalidate-hook-schema.sh${user_config.*}; safe countersplugin-validator.mdEvidence
Aligned with
CHANGELOG.md2.1.207:Hosted docs still show the unsafe monitor example (
poll-deploy.sh ${user_config.api_endpoint}) on https://code.claude.com/docs/en/plugins-reference — this PR does not modify that site (not present in this repository). Updating the author toolkit closes the gap for plugin authors usingplugin-devtoday.Verification
Related issues
user_configdocumentation still advertises unsafe shell-form interpolation #76567 (unsafe shell-form${user_config.*}docs)pluginConfigsare ignored #76568 (pluginConfigsproject scope ignored)Test plan
hooks/hooks.json${user_config.*}returns exit 1 with fix instructions