Skip to content

feat(plugins): add cix plugin + fix Bash grep/rg PreToolUse hook#39

Merged
dvcdsys merged 2 commits into
developfrom
feat/cix-plugin
May 13, 2026
Merged

feat(plugins): add cix plugin + fix Bash grep/rg PreToolUse hook#39
dvcdsys merged 2 commits into
developfrom
feat/cix-plugin

Conversation

@dvcdsys
Copy link
Copy Markdown
Owner

@dvcdsys dvcdsys commented May 13, 2026

Summary

Brings the cix plugin source onto develop (it previously lived only on the now-deleted feat/claude-code-plugin branch) and fixes the PreToolUse hook so it actually fires for grep/rg invocations via the Bash tool — the common real-session shape.

Two commits for readable review:

  1. feat(plugins): add cix plugin sources … — pure copy of the plugin tree from the local marketplace snapshot (74816e7), plus .claude-plugin/marketplace.json and .github/workflows/ci-plugin.yml. No behavior change.
  2. fix(plugins/cix): match Bash grep/rg in PreToolUse hook — the actual fix + tests + docs.

Root cause

hooks.json declared "matcher": "Grep|Glob". PreToolUse matchers match on tool_name, not on tool_input.command, so Bash invocations (which is where Claude runs grep -rn …, rg …, cat | grep | head, cd && grep …) were silently never matched. The grep-nudge.sh script itself was healthy — confirmed via a manual repro: invoking the script with a fake PreToolUse payload produced the expected additionalContext JSON, while a real grep -rn through Bash in a session emitted nothing.

Fix

  • hooks.json gains 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.sh inspects tool_name; for Bash it parses tool_input.command and 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.bats pins the matcher list: dropping Bash or Grep from hooks.json now fails CI — the exact regression that produced this PR.
  • tests/grep-nudge.bats grows 14 cases: grep/rg/ripgrep/egrep/fgrep, pipelines, chained commands, git grep (intentionally nudges), grepl substring rejection, and the no-fire set (ls/git status/make/go test/Read tool).
  • README troubleshooting bullet documents the failure mode + the manifest guard.

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.

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 locally
  • CI Plugin Tests workflow green on Linux + macOS (runs bats + shellcheck + JSON validation + symlink check)
  • Manual repro after merge:
    • Reinstall the plugin so the cache picks up new hooks.json/grep-nudge.sh
    • In a cix-indexed project, ask Claude to run grep -rn Foo . — tool result must include the cix search nudge
    • Same session: ls -la, git status, make test — no nudge, no counter bump

dvcdsys and others added 2 commits May 13, 2026 23:31
…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>
@dvcdsys dvcdsys merged commit 7e22ba7 into develop May 13, 2026
4 checks passed
@dvcdsys dvcdsys deleted the feat/cix-plugin branch May 13, 2026 22:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant