Claude Mod Manager
Ask Claude for a mod. Get one people can install.
cmod is the library, docs, and command line your Claude builds Claude Code mods with. The install, the cleanup, the saved settings, the tests, and the release are already written. Claude writes only the part that is new.
npm i -g @cmodjs/cliFree and open source under MIT. Runs on macOS and Linux.
cmod new no-force-push
Created no-force-push in no-force-push
Installed packages for no-force-push
cmod check
The layout fits a mod
Imports reach only the mod, its packages, and claude-code
claude plugin validate --strict passed
oxlint found no problems
bun test passed: 5 pass, 0 fail
no-force-push: 8 passed, 0 failed, 3 skipped
Why not from scratch
Every mod needs the same eight parts. cmod has all eight built and tested.
Claude can write each part on its own. Then each part is more code to review, to try by hand in a live session, and to fix when Claude Code changes. With cmod, each part is one line, and cmod keeps up with Claude Code so the mod does not have to.
| The part | From scratch | With cmod |
|---|---|---|
| Run an install script | Ask before it runs. Ask again when a script changes. Show progress. Undo a first install that fails. | "install": "./setup/install.sh" |
| Clean up when removed | Notice the plugin is gone, then undo the install from a saved copy of its scripts, because the mod's folder is gone too. | "uninstall": "./setup/uninstall.sh" |
| Keep settings | Save values per session, per project, and per machine. Merge the person's overrides with the team's. | state: { project: { expanded: [] } } |
| Draw in the terminal | Learn the events and props Claude Code draws with, and redraw when a value changes. | mod.ui.pane(filesPane) |
| Block a risky command | Parse the shell: pipes, && chains, sudo, xargs, and clustered short flags. | permissions({ deny: [{ command: 'git push --force' }] }) |
| Test without Claude Code | Start a session and try each case by hand. | testMod(guard).fire('tool.check', call) |
| Ship a command-line program | Build it for each platform, attach it to a release, check its SHA-256 on install, and link it onto PATH. | "program": "hello" |
| Release a version | Bundle the code so Anthropic's plugin directory can read it, pass Claude Code's validator, and tag the release. | cmod publish |
Built for the Claude that builds it
Claude reads the docs for the exact version it installed
Training data falls behind every release. So the docs ship inside @cmodjs/core, and each mod's node_modules holds the docs of the version it runs. cmod new writes a CLAUDE.md that sends Claude there before it changes anything.
cmod check gives Claude one command to run after every change. It checks the layout and the imports, runs Claude Code's own validator, type-checks, lints, and runs the tests. Each failure names its fix, so Claude keeps going until the mod passes.
- node_modules/@cmodjs/core/docs/ holds the docs of the installed @cmodjs/core. They match this version, and training data does not. Read the doc for the part you change, starting at index.md, before Claude Mod Manager (cmod) work.
cmod check
Imports reach only the mod, its packages, and claude-code
tsc 7.0.2 found type errors:
hooks/register.ts(2,29): error TS2307: Cannot find module '../node_modules/@cmodjs/core/register.js'
Fix each error, then run cmod check again.
What Claude writes
This mod stops Claude Code from force-pushing
The rule, one line in hooks/register.ts, and a test are all Claude writes. cmod reads the whole command line, so a force push inside an && chain or behind sudo is denied too, and Claude gets the reason.
The test runs in bun test, with no Claude Code session. All five cases pass.
src/mod.ts
import { permissions } from '../node_modules/@cmodjs/core/jobs/permissions.js'
import { defineMod } from '../node_modules/@cmodjs/core/mod.js'
export const noForcePush = defineMod({
name: 'no-force-push',
setup(mod) {
mod.use(
permissions({
deny: [
{ command: 'git push --force', reason: 'Force pushes rewrite shared history.' },
{ command: 'git push -f', reason: 'Force pushes rewrite shared history.' },
],
}),
)
},
})tests/mod.test.ts
test('a force push inside an && chain is denied', async () => {
expect(await check('npm test && git push --force')).toEqual(denied)
})
test('a plain push is left to Claude Code', async () => {
expect(await check('git push origin main')).toEqual({ decision: 'allow' })
})For people who install mods
A mod asks before it changes the machine, and cleans up after itself
Installing a mod takes two commands in Claude Code. Claude Code installs the cmod plugin with it.
/plugin marketplace add owner/repo
/plugin install my-mod@my-marketplace
It asks first
Before an install step runs, the mod shows its commands and asks. A changed script asks again.
It cleans up
Removing a mod runs its uninstall step at the next session start, and again if Claude Code quit partway.
Your changes stay
Starting values and Skill text changed in ~/.claude/cmods/<mod>/ survive updates and removal.
Nothing leaves the machine
The cmod plugin sends no data. Its one download is the cmod program, checked against the release's SHA256SUMS.
Get started
Start a mod in four commands
cmod link loads the mod in every new Claude Code session. The template already counts prompts and shows the count in a pane, so Claude starts from a mod that works. Start claude in the folder and describe the mod.
npm i -g @cmodjs/cli
cmod new my-mod
Created my-mod in my-mod
Installed packages for my-mod
cd my-mod
cmod link
Questions
Is cmod free?
Yes. The @cmodjs/core library, the cmod command, and the cmod plugin are open source under the MIT license.
Can Claude build a mod without cmod?
Yes. A Claude Code plugin is a hooks file, and Claude writes one well. cmod adds the parts every shared mod needs on top of it: install steps, cleanup, saved settings, tests, and releases. Claude spends the session on what the mod does.
Do people need to install cmod before my mod?
No. Each mod lists cmod as a dependency, so Claude Code installs the cmod plugin with the mod. The plugin fetches the cmod program the first time it runs.
Which systems does cmod run on?
macOS and Linux, on arm64 and x64. Every release carries a cmod build for each.
Can cmod manage plugins that are not mods?
Yes. cmod install, cmod update, and cmod remove work on any Claude Code plugin. A plugin that is not a mod installs with no consent question.
Is cmod made by Anthropic?
No. Claude Mod Manager is an independent open source project. Claude and Claude Code are Anthropic's.
Build the mod Claude Code is missing
Install the command line, start a mod, and give Claude the rest.
npm i -g @cmodjs/cli