A clean mod without any license.

One mod to manage your Claude Code mods: switch, configure and profile them in one window. It ships with my best-of selection of fifteen mods, and takes any others you add.
Claude Code mods are small hook modules that change how Claude Code behaves and looks: a guard that stops rm -rf before it runs, a meter that shows when the prompt cache goes cold, a watcher that follows your CI after every push. There are a lot of good ones scattered over GitHub. The Mod Box collects them, makes them work together, and gives you one place to switch them, configure them and add more.
<!-- screenshot: the Mods tab -->
Highlights
/mod-box): every mod as a card with a switch, its options, commands and token cost; profiles; sources; health..env files before they reach a file or commit, Screen Mask hides them (and e-mails, IPs, names) on screen while you share it, Package Guard holds installs of made-up, brand-new or typosquatted packages, CI Watch follows every push and pull request to the end.mod-box-add skill. Profiles are rules, so new mods land in the right ones; foreign code stays off until you trust it.Most of the mods are adapted copies of other people's mods, credited below with what was changed. The rest were written for this box.
Needs Claude Code 2.1.287 or newer. In a terminal Claude Code session:
/plugin install mod-box --marketplace LupusMalusDeviant/mod-box
Answer y to add the marketplace, then pick a scope. Or from a shell:
claude plugin marketplace add LupusMalusDeviant/mod-box
claude plugin install mod-box@mod-box
Then open the window with /mod-box. A mod installed at user scope also runs in the desktop app's Code tab.
Update with claude plugin update mod-box@mod-box and a restart of Claude. Remove with claude plugin uninstall mod-box@mod-box.
Working on the box itself: have Claude Code load it straight from your clone. In ~/.claude/settings.json, under env, set CLAUDE_CODE_PLUGIN_DIRS to the folder and CLAUDE_CODE_PLUGIN_DIR_WATCH to 1, then restart Claude once. After that, every saved change reloads the box by itself. The tools in tools/ need Node.js 26. See CONTRIBUTING.md.
The own mods and the forks with real changes are also available one by one, without the box: claude-mods (Cache Meter, Subagent Saver, Read Guard, Secret Guard, Screen Mask, Package Guard, CI Watch, Sign Guard, Handoff Note, Desktop Pet, and Blast Radius as a marked fork). For the other mods, use their originals; they are linked under Credits.
claude plugin validate proves that a plugin loads, not that it is harmless.~/.claude/settings.json only where you ask it to: switches and options (in pluginConfigs, where the desktop app does not list plugin rows in /config) and the auto-compact window when you set it.gh. Mods that call a model (Next Steps, Catch Me Up, the handoff note, keep-warm) say so and show their token use./mod-box opens the window. /mod-box profiles, sources and diag open it on a given tab. The window speaks English by default, or German with the language setting.
owner/repo or a URL). The Import button fetches a mod with function hooks, rewrites it for the box and validates it. The imported mod starts switched off, and if validation fails, the box stays as it was. Updates of the originals checks the copied mods against their upstream repos (see below).gh signed in, Git Bash, the signing script);If Claude Code runs with --debug-file ~/.claude/mod-box/debug.log, this tab also shows the box's last error lines from that log.
Some hosts, the desktop app among them, don't list a plugin's options in /config. There the window builds the rows itself and writes changes to pluginConfigs in ~/.claude/settings.json, which is where Claude Code keeps them.
The same window runs in terminal Claude Code, as a side pane next to the conversation.
<table> <tr><td><img src="docs/images/cli-mods.png" alt="Mods tab in the terminal" width="400"></td><td><img src="docs/images/cli-profiles.png" alt="Profiles tab in the terminal" width="400"></td></tr> <tr><td><img src="docs/images/cli-sources.png" alt="Sources tab in the terminal" width="400"></td><td><img src="docs/images/cli-health.png" alt="Health tab in the terminal" width="400"></td></tr> <tr><td colspan="2" align="center"><img src="docs/images/cli-filetree.png" alt="Filetree side pane in the terminal" width="400"></td></tr> </table>
| Switch | Mod | Default | What it does | Costs tokens? |
|---|---|---|---|---|
blastRadius | Blast Radius | on | Holds risky shell commands (rm -rf, git reset --hard, git clean, force push, migrations) and shows what they would hit. | no |
packageGuard | Package Guard | on | Before an install or npx/uvx run (npm, pnpm, yarn, bun, pip, uv, poetry, pipx, cargo) asks the public registry; holds the command when the package does not exist, is under 14 days old, was removed as malware, or looks like a well-known package and is young or thin. Mode block or warn; allow in the band or with /pkg-allow. Sends only the package name to the registry. | no |
secretGuard | Secret Guard | on | Stops before an API key, token, private key or non-ignored .env file gets into a file, git add or a commit. Mode block or warn; exceptions via /secret-allow. | no |
screenMask | Screen Mask | off | For screen sharing and recordings: hides API keys, tokens, e-mail and IP addresses, your login name in paths and names you list, in the display only. Claude still reads the original; nothing leaves the machine. /mask switches it; the band shows when it is on. | no |
ciWatch | CI Watch | on | Follows the GitHub Actions runs after each git push (via gh) to the end. For an open pull request it watches every check and says whether the PR is ready to merge. When a run turns red, it shows the failed step's log and/or puts an analysis request into the prompt; it can also play a sound. /ci shows the state. A system notification when a run ends (default: red only), since Claude Code notifies only at the end of a turn. In the desktop app, a new PR's checks are left to the app's own CI bar. | no |
signGuard | Sign Guard | off | Spots Windows builds and signs the new .exe, .msi and .msix files with your own script (<script> -Exe <file>). Mode ask or auto. | no |
savvyProgress | Savvy Progress | on | Progress bar and agents panel (/agents-info). | no |
filetree | Filetree | on | File tree side pane (/filetree) that lights up as Claude reads and writes. Right-click a file or folder (or press o) for Open with: the default app, the editors, IDEs and browsers found on this machine (by file type), preview, show in folder, copy path; Shift+right-click copies the path. With the Codebase Map on, a Features tab lists its features (live marks, uses / used by, files that jump to the tree) and the blueprint actions. | no |
replayTheater | Replay Theater | on | Steps through the last turn's edits (/replay). | no |
nextSteps | Next Steps | off | Suggests 2–3 next prompts. Claude Code has one built-in suggestion (Tab); this offers two or three. | a Haiku call per answer |
cacheMeter | Cache Meter (with Cache Tax) | on | Shows the time left on the warm cache, the hit rate, the context as weather with its trend over the last 12 turns (growth per turn, turns until full) and the plan limits, with compact and keep-warm buttons. It also stops a send to a cold cache once and names its cost, and the cost of compacting first instead. Auto-compact at sets Claude Code's autoCompactWindow: on 1M-context models Claude otherwise compacts only at about 967k tokens. | only keep-warm requests, when on |
readGuard | Read Guard | on | Holds a whole-file Read (no offset/limit) above the limit (default 50 KB), of a lockfile, minified code or a source map, and the same via cat, type or Get-Content; tells Claude the size, a token estimate and a better way (Grep, offset/limit). A second try at the same file goes through, and so does a Read with allow_large (Claude Code 2.1.296+). Claude Code itself stops a Read only at about 25,000 tokens. | no |
subagentSaver | Subagent Saver | on | Search subagents (Explore) that got no model of their own run on Sonnet (or Haiku) instead of inheriting the main model. An explicit model, forks, teammates and plugin agents stay untouched; the band shows how many were routed. | no |
handoff | Handoff Note | on | /handoff writes .claude/handoff.local.md, and a new session offers to continue from it. | one request over the warm cache |
pet | Desktop Pet | off | Windows only: a little companion on the desktop, always on top, that says in a speech bubble what Claude is doing (file read or changed, command running, what a guard held) and sums up each turn. A cardboard box or one of twelve figures (cat, dog, fox, bunny, hamster, owl, penguin, frog, axolotl, dragon, robot, ghost), cat, dog and bunny in nine coats, or a random one per session. Claude's questions and Next Steps' suggestions show as buttons in the bubble: a click answers or sends them, and whichever answers first, the pet or Claude Code's dialog, counts. An answer that ends with a question shows that question, with two or three short replies from Haiku as buttons. A click on the pet brings back the last answer in short, with its buttons while they still apply, and a name tag under it says which project it stands for. A bubble with a question or buttons that nobody answers shrinks to one line after the bubble time (or at once with its –); a click on that line or the pet opens it again. Permission requests are shown; with permission requests: answer the bubble also offers Allow once and Deny for 90 seconds (never "always", no rule is added), otherwise approving stays in Claude Code's dialog. It watches the prompt cache: a few minutes before it goes cold it says so, with a button that keeps it warm for an hour (Cache Meter on). Optionally one pet per active session, side by side, each with its own figure: when a session's cache goes cold its pet goes to sleep, and the next message brings it back. With type answers in the pet on (off by default), a hotkey (Ctrl+Alt+Space), the pet's menu or Write your own answer in the bubble opens a small input box: the text goes to Claude as the next prompt, as the answer to its open question, or in place of a suggestion, and the focus goes back to the game. Drag it anywhere; right-click for quiet time or Figur to pick another figure and coat. Built once with the C# compiler that ships with Windows into %LOCALAPPDATA%\mod-box\pet, signed with the Sign Guard script when one is set. | only with summary haiku |
ccSplitDiffView | Split Diff | off | Draws the result of Edit and Write as a side-by-side diff with line numbers; only the drawing changes. | no |
humanInTheLoop | Human in the Loop | off | Claude hands you tasks only a person can do (a secret to put in place, an account it cannot reach, a decision); they stay in the band and in /my-tasks until you answer or mark them done. | no |
promptRail | Prompt Rail | off | A rail of this session's prompts above the input (terminal) or beside the transcript; hover to read one, click to jump to it (/prompt-rail). | no |
visibleCompact | Visible Compact | on | Before/after view of /compact (/show-last-compact). | no |
catchMeUp | Catch Me Up | off | Live summary of the session (/catch-me-up), kept up after turns with tools. Claude Code's built-in recap (/recap) is one short note when you come back; this pane stays open. | Haiku calls after turns |
codebaseMap | Codebase Map | off | Feature map from docs/blueprints with live highlighting of the features Claude edits, a freshness band and a CLAUDE.md pointer; mapper instructions with machine-checked edges load only when you ask for blueprint work (/codebase-map). In the prompt, @ and part of a feature name offers its blueprint to attach, and an @file gets one line on the feature it belongs to. | only blueprint runs you ask for; about 500 tokens per session for the CLAUDE.md pointer |
| Command | Mod | What it does | ||||||
|---|---|---|---|---|---|---|---|---|
| `/mod-box [profiles | sources | diag]` | Mod Box | opens the window, optionally on a tab | ||||
/pkg-allow [name] | Package Guard | allows a held package for this session | ||||||
/secret-allow | Secret Guard | the exception list: last finds, project and global entries | ||||||
| `/mask [on\ | off]` | Screen Mask | hide secrets and names on screen, or show them again | |||||
/ci · `/ci pr <nr | url> · /ci stop` | CI Watch | state of the watched runs · watch a pull request · stop watching | |||||
/agents-info | Savvy Progress | agents panel | ||||||
/filetree | Filetree | opens the file tree | ||||||
/my-tasks | Human in the Loop | your open tasks from Claude | ||||||
| `/prompt-rail [vertical\ | horizontal\ | off\ | next\ | prev\ | <nr>\ | find <words>]` | Prompt Rail | switch the rail, jump to a prompt |
/replay | Replay Theater | steps through the last turn's edits | ||||||
| `/keepwarm <6h | 90m | always | off | status> · /cache-tax` | Cache Meter | keeps the cache warm · cache costs of this session | ||
/pet [stop] | Desktop Pet | shows the pet, or sends it off | ||||||
/pet <figure> [coat] | Desktop Pet | picks a figure, e.g. /pet cat calico, /pet random; with one pet per session for this session only | ||||||
/handoff | Handoff Note | writes the handoff note | ||||||
/show-last-compact | Visible Compact | before/after of the last /compact | ||||||
/catch-me-up | Catch Me Up | live summary pane | ||||||
| `/codebase-map [create\ | update [feature]\ | check\ | publish [feature]]` | Codebase Map | opens the feature map; with an argument, prepares the blueprint prompt (for one feature, if named) |
The window lists them too: next to each mod's name, and in full under ⚙.
CI Watch, Sign Guard, Cache Meter and Handoff Note hand their displays to the box, which draws them all in one band above the prompt:
Each mod in box.json carries attributes: group (guards, display, context, watchers), tokens (none, optional, always), default, and compat (see below). A profile is a rule over them: Default takes each mod's default, Lean takes tokens: none | optional, Guards only takes group: guards, Everything on takes all. So a new mod lands in the right profiles as soon as it is classified.
The window remembers the profile you applied last (Default until you apply one). At the next session start it gives every mod that is new since then the switch that profile wants, and marks it new. If you have changed switches by hand since, the header says (changed); new mods still follow the profile.
Foreign code waits for trust. A mod imported from another repo starts switched off, and profiles leave it off until you trust it: Trust under its ⚙, or switch it on by hand once. Imported mods show 🔒 until then, 📦 after.
What a mod may do. The build reads each mod's source for the calls it makes, and the window shows the result next to its name: 👁 reads files or the transcript, ✎ writes files, the transcript or the prompt, ▶ runs programs, 🌐 goes online, 🔧 changes settings. Under ⚙ the same in words, with the programs by name. It is a reading of the code, not a sandbox, but it means a new mod cannot surprise you with what it touches.
Each mod declares where it works: the surfaces (terminal, desktop app, VS Code, mobile), the operating systems, and the programs it needs (git, gh signed in, Node.js, Git Bash, PowerShell, a signing script). The window compares that with the session you are in (surface, OS, and the environment check under Health) and puts a ⚠ with the reason next to a mod that would not, or not fully, run here. ⚙ shows the full list.
The Sources tab also searches the community mod catalogue of awesome-claude-code-mods (mods.aidojo.si, CC0): several thousand public mods, each with what Claude's validator says it may read, write, run or send. The box fetches the list once a day (node tools/box.mjs modcat --query <words>); Import takes a hit through the same checks as a git link.
The box ships the skill mod-box-add. Ask Claude something like "add the mod from owner/repo to the Mod Box", and it:
tools/box.mjs import, or installs it natively with tools/box.mjs native install;tools/box.mjs analyze <id> gives a first guess to start from);All instructions the box gives Claude (the skill, the prompts of the mods) are English. Only the language Claude answers in follows the setting.
Not every plugin can live inside the box. Before anything changes, the box reads the plugin (nothing of it runs) and gives one of these verdicts, shown in the Sources tab:
$.store keys get the mod's prefix.${CLAUDE_PLUGIN_ROOT} stay plugins of their own. The box installs them through Claude Code (claude plugin install), shows their parts and token cost, switches, configures, updates (with a diff) and removes them, all in the same window. Plugins without a marketplace go through the box's local marketplace. A plugin you installed yourself comes under the box with Adopt.Mods that ship with Claude Code itself (@builtin, such as You should know, a side agent that points out what you might miss) show up in the same card under Built into Claude Code, with a switch where Claude Code allows one. These switches apply to all projects.
The setting Import strategy chooses between automatic (integrate where nothing is lost, otherwise native) and always native. Trust and profiles work the same way for both kinds: a natively managed plugin is installed switched off, profiles skip it until you trust it, and once trusted it follows the profile rules by its group and token use.
The full matrix of what is handled how, before and after, the platform limits and the real plugins it was tested with are in docs/capabilities.md.
box.json is the single source: mods, switches, options (English, with _de translations), groups, state prefixes and profiles.node tools/box.mjs build generates hooks/register.ts, the type contracts, the userConfig in .claude-plugin/plugin.json and the window's catalog. Don't edit those by hand.tools/box.mjs also has export <id>... --out <folder> (the standalone plugins of claude-mods), catalog, inspect, import, reimport, analyze <id|dir>, remove, validate, updates [<id>], diff <id>, update <id>, native <action> (list, details, options, set, install, adopt, trust, untrust, enable, disable, update, uninstall, profile) and release (bhooks/register.ts 11 lines1// Fixture nolicense: a tiny function-hook module.
2import type { Register } from 'claude-code'
3
4export const register: Register = (on, options) => {
5 on('session.start', async ($, e, next) => {
6 await $.command.register({ name: 'fx-nolicense', description: 'fx-nolicense (fixture)' })
7 return next(e)
8 })
9 on('command.run', { command: 'fx-nolicense' }, async () => ({ text: 'ok' }))
10}
11