Claude Code Mods: Secrets Filter, Blocking rm -rf, a CI Status Line, and Code Review GA
Guides11 min readOctober 19, 2026

Claude Code Mods: Secrets Filter, Blocking rm -rf, a CI Status Line, and Code Review GA

A hands-on guide to Claude Code Mods: I built one plugin with a secrets filter, a blocker for dangerous commands, and a CI status line — all via the official API. Plus: Code Review hits GA with Quick, Standard and Deep modes.

Yuval Avidani

Yuval Avidani

Author

Claude Code Mods (their official name is Claude Code Mods) are small functions in TypeScript or JavaScript that run inside Claude Code itself, and can see, change, or stop any prompt, any tool call, and any pixel in the interface. Anthropic launched them on October 1, 2026, and two weeks later, on October 15, they also shipped Code Review to general availability — the service where several agents review every Pull Request on GitHub. Together, these two features close the loop: the mod protects us while the agent works on our machine, and Code Review protects us once the code reaches a PR.

In this guide we're going to build one thing, start to finish: a plugin called team-guard for the team's repo, with three mods. A secrets filter that redacts API keys before they reach the model, a blocker that stops rm -rf and asks us first, and a status line that shows the CI state of our PR. And at the end, we'll send the PR off for Claude to review.

What's a mod anyway, and why is it different from everything that came before

Let's break it down. Until now, Claude Code gave us four ways to customize it: Skills (instruction files the model reads), MCP servers (external processes that give it tools), Settings Hooks (a script that runs on a specific event, like before running a tool), and a status line. All of them work "from the outside": you run a script, add text, or add a tool.

A mod is a plugin whose code runs inside the Claude Code process itself, for anyone who wants to change the behavior and the interface of the tool itself. Think of it like the difference between a sign you hang on the kitchen door and a chef standing inside next to the stove. The sign can only ask. The chef sees every dish before it goes out, can fix it, and can also send it back.

Technically speaking, a mod is a collection of event handlers (functions triggered when an event happens). Claude Code fires an event at every point where it's about to act: tool.call when the agent is about to run a tool, prompt.submit when we've sent a prompt, ui.render when it's about to draw part of the interface. Each handler receives three things: $, the mods API, e, the event itself, and next, the function that passes the event along. What our function does with next determines everything: calling it as-is means "observe," calling it with a modified copy means "rewrite," and not calling it at all means "answer instead of Claude Code."

Here's the comparison, based on the comparison table in the official docs:

In short: if a Settings Hook or a Skill already does the job, there's no reason to write a mod. A mod is worth it when you want to draw something in the interface, add a command that runs immediately without Claude's queue, or rewrite an event on the fly.

The catch: code that runs inside us, with no sandbox

Before we write a single line, I need to say the most important thing in this guide. Mods don't run in a sandbox (an isolated environment). A mod runs with our own permissions: it can read and write any file, run programs, send network requests, and read environment variables — including API keys. The docs say this explicitly, and add that even if we've turned on sandboxing, it isolates Claude's Bash commands, not a process a mod launches.

And there's more. A mod can approve a tool call before we're even asked, rewrite a prompt, and use our subscription to call the model. The one thing a mod can't change is the permission request window itself.

So what do we do? Four simple habits:

  • Check before you install. The command claude plugin validate ./some-mod prints, without running anything, the hooks: line (which events the mod listens to) and the calls: line (which capabilities it uses). If a "color theme" mod is calling $.http.fetch and $.env.get — something's off.
  • Only install from sources you trust, exactly like with any other code.
  • Debug issues with claude --safe-mode, which turns off every installed mod for one session.
  • In an organization, let the admins control it. On a machine with managed settings, or for a user signed in with a Team or Enterprise plan, a built-in mod called sec-default loads before any user mod. It stops a user mod from approving a call that a deny rule blocks, and it protects the managed hooks, the system prompt, and the settings the organization has set. An admin can also turn on the allowManagedModsOnly option, and then only organization mods run.

It's also important to understand the limit of this protection: a deny rule on Read(.env) blocks Claude's Read tool, but not a mod's own call to $.fs.read. The real protection is simply not loading a mod you don't trust.

Let's build: three mods in one plugin

Turns out you don't need Node.js, a bundler, or a build step. Claude Code loads .js and .ts files directly. Every mod needs three files: plugin.json (the plugin's ID card), hooks/hooks.json (which points to the code), and the code file itself. Minimum version: Claude Code v2.1.287.

Now for the heart of it. All the code below is built on the patterns from the official mods docs, with two things we wrote ourselves: the regex patterns for detecting secrets, and the summarize function that counts CI checks:

Let's walk through the three pieces.

1. The secrets filter. The hook on prompt.submit gets the text we typed in e.text. If we find something that looks like an AWS key, a GitHub token, or an Anthropic API key, we pass along a copy with [REDACTED] in its place instead. The model simply never sees the original. The second hook handles tool output: it waits for the result with await next(e), and if there's something that looks like a secret in it, it returns { deny }. According to the docs, this hides the result from Claude, and it reads our explanation instead. Note that this hides the entire output, not just the secret. To redact only the secret, you need to build the result in the exact shape each tool expects, and that shape lives in the type files Claude Code writes to the .claude-plugin/types/ folder.

2. The rm -rf blocker. This is almost one-to-one the example from the docs. The hook on tool.call is filtered to Bash only. If the command matches a dangerous pattern, it stops the call and opens a question with $.ui.ask. The cool part is that the tool call literally waits until we answer. Picked "Run it"? The call proceeds, and the normal permission check still runs afterward. Any other answer, or a claude -p session with nobody to ask, returns deny. We also added a .catch, so that if the check itself crashes, the command doesn't run. This is called fail closed: when something breaks, the default is to block. And to be fair, I'll say it plainly: a regex won't catch every spelling (like git push -f). This is a safety net, not a wall.

3. The CI status line. On session.start we start a timer with $.clock.every, which every 60 seconds runs gh pr checks --json name,bucket via $.process.run, and displays a summary below the prompt line with $.ui.status. The bucket field from the GitHub CLI already sorts every check into pass, fail, pending, skipping, or cancel. Want a real panel on the side of the screen with tabs and buttons? That's $.ui.open plus another hook on ui.render with { component: 'Pane' }, exactly like the hello-tabs example in the docs.

Bottom line: three files, about 70 lines, and we've got an agent that won't see secrets we accidentally pasted, won't delete a folder without asking, and will tell us when CI is red.

From our machine to the PR: Code Review goes live

The mod protects the local session. But what happens once the code is already in a PR? That's where Code Review comes in, which reached general availability on October 15 for organizations on Team and Enterprise plans.

It works in four stages, on Anthropic's own infrastructure: several agents read the diff and the surrounding code in parallel, a verification stage filters out false positives, findings get a severity rating, and then everything gets posted to the PR as comments on the relevant lines, with a summary and a check run called Claude Code Review. It never approves and never blocks a merge. The decision stays with us.

The big new thing in GA is three depth levels per repo: Quick (a light pass, fastest and cheapest), Standard (the default), and Deep (the most thorough, slowest, and priciest). According to Anthropic, most reviews now finish within 6 to 10 minutes, compared to about 20 minutes during the preview period. Anyone with write access can request a review by commenting @claude review on the PR, and you tune the review's style with a REVIEW.md file, which is always read from the base branch and never from the PR's own changes. That way, no PR can "talk" the reviewer into going easy on it. No organizational plan? The /code-review command inside Claude Code works on every plan.

To understand why this matters, it's worth peeking at how Anthropic works internally. In an engineering post from October 13, they say that in May 2026 they were merging around 2,500 code changes a day on average, and by September that was already more than 30,000 a day. Git simply couldn't keep up with the pace, so a team of seven people spent five months building a new version control system called Scion, alongside a code review interface called Antique.

And in a post published on October 15 ("How the Claude Code team does code review," which hit 478 points on Hacker News), the Claude Code team describes a seven-layer process, on code that's about 90% written by Claude: self-verification and a second agent before the PR, an AI review on every PR, a security review that can block, mandatory CI, human approval based on risk level (zero people for a low-risk change, one for medium, two for high), a merge queue, and fast rollback.

The share of PRs that made it through in a single review round rose from 65% to 78%, and PRs that needed five rounds or more dropped from 8.9% to 1.5%. And also: the number of PRs merged more than doubled between June and September, while the revert rate dropped by more than 40%.

My take: what this is, and what it isn't

In my view, mods are the step that turns Claude Code from a tool into a platform. Until now, we adapted ourselves to the tool. Now the tool adapts itself to the team: to our rules, our CI, our specific fears. And the connection with Code Review is exactly Anthropic's own model, in miniature: layers. No single layer is perfect on its own, but together they catch most of what matters.

Now the limitations, no sugarcoating. Mods aren't sandboxed, and a malicious mod is malicious code with access to everything we have. The API is new and changes between versions, and the docs themselves tell you to trust the type files generated for your version more than any docs page. A regex-based blocker is a reminder, not enforcement, and real protection for main requires branch protection on GitHub. And Code Review is paid, available only for Team and Enterprise, and not available for organizations with Zero Data Retention. Anthropic also states plainly that a review with no findings doesn't mean the code is bug-free.

So — which mod are you going to write for your team first?

Want to go further with this?

I break down the whole Claude Code world, from hooks and plugins to agents working in parallel, in depth in the Claude Code Mastery course (in English, at yuv.ai).

If you want to start from the basics in Hebrew, with Claude Desktop, MCP, Skills, agents and automations, you'll find it at Practical AI with Claude.

I post demos, including the mods from this guide in action, on YouTube and LinkedIn. You can also follow me on X, Instagram, and TikTok, and you'll find my code on GitHub.

Comments