feat(plugins): add cix plugin + fix Bash grep/rg PreToolUse hook#39
Merged
Conversation
…apshot Restores the plugin tree from the (since-deleted) feat/claude-code-plugin branch onto develop, so the plugin lives alongside the rest of the cix codebase and can be developed via normal PRs to develop. Contents: - plugins/cix/ — full plugin tree (hooks, scripts, commands, skills, tests) - .claude-plugin/marketplace.json — root marketplace manifest used by `/plugin marketplace add github:dvcdsys/code-index` - .github/workflows/ci-plugin.yml — bats + shellcheck on push/PR Snapshot SHA in the local marketplace cache: 74816e7. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The PreToolUse matcher was "Grep|Glob", which only fires for the built-in Grep/Glob tools — `grep`/`rg` invoked through Bash (the common real-session path: pipelines, `| head`, `cd && grep …`) silently never triggered the nudge. Fix: - hooks.json gains a second PreToolUse entry with matcher "Bash" that points at the same script (split into two entries instead of "Grep|Glob|Bash" so each path's intent reads clearly in review). - grep-nudge.sh inspects tool_name on stdin; for Bash it also parses tool_input.command and only proceeds when the command contains a standalone grep-family token (grep/egrep/fgrep/rg/ripgrep). Non-grep Bash (ls, git status, make, go test) exits silently BEFORE the backoff counter increments, so the existing 1/2/4/8/16 cadence is preserved. - tests/manifest.bats pins the matcher list: dropping "Bash" or "Grep" from hooks.json fails CI immediately — the exact regression that produced this fix. - tests/grep-nudge.bats grows 14 cases covering grep/rg/ripgrep, pipelines, chained commands, substring rejection (grepl), and the full no-fire set (ls/git status/make/go test/Read tool). - README troubleshooting bullet documents the failure mode and the manifest test that guards against recurrence. Without jq the Bash branch is silent rather than parsing shell commands with sed — false-positive risk too high. jq is already in the CI image and listed as a dev dependency. Verification: - bats plugins/cix/tests/*.bats → 60/60 green (18 pre-existing grep-nudge + 14 new Bash cases + 5 new manifest cases + the rest of the suite unchanged). - shellcheck --severity=warning plugins/cix/scripts/*.sh → clean. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the cix plugin source onto
develop(it previously lived only on the now-deletedfeat/claude-code-pluginbranch) and fixes thePreToolUsehook so it actually fires forgrep/rginvocations via the Bash tool — the common real-session shape.Two commits for readable review:
feat(plugins): add cix plugin sources …— pure copy of the plugin tree from the local marketplace snapshot (74816e7), plus.claude-plugin/marketplace.jsonand.github/workflows/ci-plugin.yml. No behavior change.fix(plugins/cix): match Bash grep/rg in PreToolUse hook— the actual fix + tests + docs.Root cause
hooks.jsondeclared"matcher": "Grep|Glob". PreToolUse matchers match ontool_name, not ontool_input.command, soBashinvocations (which is where Claude runsgrep -rn …,rg …,cat | grep | head,cd && grep …) were silently never matched. Thegrep-nudge.shscript itself was healthy — confirmed via a manual repro: invoking the script with a fake PreToolUse payload produced the expectedadditionalContextJSON, while a realgrep -rnthrough Bash in a session emitted nothing.Fix
hooks.jsongains a second PreToolUse entry with"matcher": "Bash"pointing at the same script. Split into two entries (rather than"Grep|Glob|Bash") so each path's intent reads clearly.grep-nudge.shinspectstool_name; forBashit parsestool_input.commandand only proceeds when the command contains a standalone grep-family token (grep/egrep/fgrep/rg/ripgrep). Non-grep Bash exits silently before the backoff counter increments, so the 1/2/4/8/16 cadence is preserved.tests/manifest.batspins the matcher list: droppingBashorGrepfromhooks.jsonnow fails CI — the exact regression that produced this PR.tests/grep-nudge.batsgrows 14 cases: grep/rg/ripgrep/egrep/fgrep, pipelines, chained commands,git grep(intentionally nudges),greplsubstring rejection, and the no-fire set (ls/git status/make/go test/Read tool).Without
jqthe Bash branch is silent rather than parsing shell commands withsed— false-positive risk too high.jqis already in the CI image and listed as a dev dependency.Test plan
bats plugins/cix/tests/*.bats→ 60/60 green locally (18 pre-existing grep-nudge + 14 new Bash + 5 new manifest + 23 other hook tests unchanged)shellcheck --severity=warning plugins/cix/scripts/*.sh→ clean locallyPlugin Testsworkflow green on Linux + macOS (runs bats + shellcheck + JSON validation + symlink check)hooks.json/grep-nudge.shgrep -rn Foo .— tool result must include thecix searchnudgels -la,git status,make test— no nudge, no counter bump