Starter mod: blocks edits to .env files. Copy me with scripts/new-mod.sh.

<img src="assets/banner.png" alt="claude-mods: open-source mods that reshape your Claude Code sessions" width="100%">
<a href="LICENSE"><img alt="License: MIT" src="https://img.shields.io/badge/license-MIT-d97757?style=flat-square"></a> <a href="https://github.com/ibrahimkobeissy/claude-mods/actions/workflows/validate.yml"><img alt="Validate" src="https://img.shields.io/github/actions/workflow/status/ibrahimkobeissy/claude-mods/validate.yml?branch=main&style=flat-square&label=validate"></a> <a href="https://github.com/ibrahimkobeissy/claude-mods/stargazers"><img alt="Stars" src="https://img.shields.io/github/stars/ibrahimkobeissy/claude-mods?style=flat-square&color=d97757"></a> <a href="CONTRIBUTING.md"><img alt="PRs welcome" src="https://img.shields.io/badge/PRs-welcome-28c840?style=flat-square"></a> <img alt="Claude Code plugin marketplace" src="https://img.shields.io/badge/Claude%20Code-marketplace-1a1714?style=flat-square">
<b>Panes, status lines, toasts, tool guards and slash commands</b><br> dropped into Claude Code with one command and hot-reloaded while you work.
<a href="#-quick-start">Quick start</a> · <a href="#-mods">Mods</a> · <a href="#-build-your-own">Build your own</a> · <a href="CONTRIBUTING.md">Contribute</a>
A mod is a Claude Code plugin built from function hooks: a small TypeScript module that hooks the engine's events and changes what Claude Code does or draws.
export const register: Register = on => {
on('tool.call', { tool: 'Edit' }, ($, e, next) =>
/\.env$/.test(e.file_path) ? { deny: 'not touching .env' } : next(e),
)
}
With one, you can:
| 🪟 Panes & bands | Live side panels and rows above the prompt, drawn in JSX |
| 📊 Status & toasts | Put your own text on the status line or pop a notification |
| 🛡️ Tool guards | Block, rewrite or react to any tool call before or after it runs |
| ⌨️ Slash commands | Register /your-command and answer it from code |
| 🧠 Prompt shaping | Rewrite prompts or add sections to the system prompt |
| 🔊 Timers, files, sounds | Run work on a clock, touch files, play audio |
Inside Claude Code, add this repo as a marketplace:
/plugin marketplace add ibrahimkobeissy/claude-mods
Then install any mod from it:
/plugin install <mod-name>@claude-mods
Or from your shell:
claude plugin marketplace add ibrahimkobeissy/claude-mods
claude plugin install <mod-name>@claude-mods
Update later with claude plugin update <mod-name>@claude-mods, then /reload-plugins in a running session.
Get updates automatically: auto-update is off by default for community marketplaces, and only you can turn it on. Run /plugin, open Marketplaces → claude-mods and choose Enable auto-update. Or add "autoUpdate": true to the claude-mods entry under extraKnownMarketplaces in ~/.claude/settings.json:
"extraKnownMarketplaces": {
"claude-mods": {
"source": { "source": "github", "repo": "ibrahimkobeissy/claude-mods" },
"autoUpdate": true
}
}
Claude Code then updates the marketplace and your installed mods on startup.
| Mod | What it does | Install |
|---|---|---|
📡 session-radar | A live sidebar for long sessions: limits and forecast, context, agents, background shells, progress | /plugin install session-radar@claude-mods |
🔔 waiting-bell | Rings, notifies and flashes a banner whenever Claude is waiting for you; repeats every 5 min until you answer | /plugin install waiting-bell@claude-mods |
Have an idea? Suggest a mod →
<!-- Add a row per mod, in alphabetical order:
mod-name | One line on what it does | /plugin install mod-name@claude-mods |
|---|
Every mod lives in its own folder under mods/ and is three small files:
mods/my-mod/
├── .claude-plugin/plugin.json # name, version, description
└── hooks/
├── hooks.json # { "modules": ["./register.ts"] }
├── register.ts # export const register: Register = (on, options) => { ... }
└── register.test.ts # tests (any *.test.ts), run by `claude plugin test`
1. Scaffold from the starter in template/:
scripts/new-mod.sh my-mod "One line on what it does"
2. Try it live — load the folder into a session and every save hot-reloads it:
claude --plugin-dir mods/my-mod
3. Check it — validates the marketplace and runs every mod's tests:
scripts/validate.sh # everything
scripts/validate.sh mods/my-mod
[!TIP] Ask Claude Code itself to "make a mod that…". Its built-in
plugin-authoringskill knows the full hooks API, writes the mod, and loads it into your session with hot reload.
.claude-plugin/marketplace.json # the catalog `/plugin marketplace add` reads
mods/ # one folder per published mod
template/ # starter mod copied by scripts/new-mod.sh
scripts/ # new-mod.sh, validate.sh
assets/ # banner and social preview (SVG sources + PNGs)
New mods, fixes and ideas are all welcome. Read CONTRIBUTING.md for the checklist a mod needs before it's merged, and please follow the Code of Conduct.
Mods run inside your Claude Code session with the same reach as any plugin. Read a mod's source before you install it, and report anything unsafe as described in SECURITY.md.
MIT © Ibrahim Kobeissy
<sub>claude-mods is a community project and is not affiliated with or endorsed by Anthropic. Claude and Claude Code are trademarks of Anthropic, PBC.</sub>
hooks/register.ts 12 lines1import type { Register } from 'claude-code'
2
3const PROTECTED = /(^|\/)\.env(\.|$)/
4
5export const register: Register = on => {
6 on('tool.call', { tool: 'Edit' }, ($, e, next) =>
7 PROTECTED.test(e.file_path)
8 ? { deny: `${$.plugin.name}: ${e.file_path} is protected.` }
9 : next(e),
10 )
11}
12