fix(skill-management): PR-open hook matcher never matched MCP create_pull_request tools - #550
Conversation
…reate_pull_request tools The PostToolUse matcher "Bash|create_pull_request" contains only exact-match characters, so Claude Code evaluates it as a list of exact tool names, not a regex. No MCP tool is named bare create_pull_request (they are namespaced, e.g. mcp__github__create_pull_request), so the MCP branch of pr-skill-doctor-prompt.cjs was unreachable and the /skill-mine nudge was silently lost for MCP-created PRs. "Bash|mcp__.+__create_pull_request" contains regex metacharacters, which flips the whole matcher into (unanchored) regex mode and matches any mcp__<server>__create_pull_request tool name. Bumps skill-management to 1.0.2.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
🤖 Claude Code Review
SummarySmall, correct fix. This changes the PostToolUse hook matcher from Why the fix is correct
Version bump (1.0.1 → 1.0.2, patch) and the Non-blocking observationBecause the matcher is now unanchored regex, the No bugs, security, or data-loss concerns. Safe to merge. Files reviewed
💡 Want a fresh review? Add a comment containing |
There was a problem hiding this comment.
📋 Review verdict: APPROVE
👆 The main review comment above is the source of truth for this PR review. It is automatically updated on each review cycle, so always refer to it for the most current feedback.
This formal review submission is for the verdict only.
|
Re the non-blocking observation on anchoring ( Note on the red |
Summary
The
pr-skill-doctor-prompt.cjsPostToolUse hook is supposed to fire when a PR is opened viagh pr create/gt submit(Bash) or via a GitHub MCPcreate_pull_requesttool. The MCP path has never worked: the matcher inhooks/hooks.jsonwas"Bash|create_pull_request", and per the Claude Code hooks docs, a matcher composed only of letters, digits,_,-, spaces,,, and|is evaluated as a list of exact tool names, not a regex. Regex mode activates only when the pattern contains a character outside that set.No MCP tool is named bare
create_pull_request— they are namespaced (mcp__github__create_pull_request,mcp__plugin_uniswap-integrations_github__create_pull_request, etc.) — so the hook never fired for MCP-created PRs, the script'stoolName.endsWith('create_pull_request')branch was unreachable dead code, and the once-per-session/skill-minenudge was silently lost whenever a PR was opened through MCP.Fix
One line: matcher becomes
"Bash|mcp__.+__create_pull_request". The.+metacharacters flip the whole matcher into (unanchored) JavaScript regex mode, so it matchesBashand anymcp__<server>__create_pull_requesttool name.Edge case checked: in regex mode the unanchored
Bashalternative also matchesBashOutput, butisPrOpen()in the hook script requirestoolName === 'Bash'exactly (else theendsWithcheck), so the only cost is a no-op hook invocation — no spurious prompts.Also in this PR:
skill-managementplugin version 1.0.1 → 1.0.2 (patch, per repo semver policy) + root CLAUDE.md version table.+is load-bearing, so this doesn't regress in a future "simplification"Same fix already shipped and verified in Utility-NYC/closet-ai#57 (
plugins/closet-ai-meta/hooks/hooks.json).Test plan
RegExp.test)node scripts/validate-plugin.cjs packages/plugins/skill-managementpassesbunx nx affected --target=lint --base=origin/nextgreen;bunx markdownlint-cli20 errors