SLOPSHOPPER

hello-mod

The smallest useful mod: a /hello command, a toast and a band above the prompt.

newbandcommandtoast
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · hello-mod
› fix the failing auth test and add an audit log call ╭───────────────────────────╮ │ hello-mod │ ⏺ Read(src/auth.ts) │ Hello #1 from hello-mod │ ⎿ Read 6 lines │ 👋 │ ⏺ Update(src/auth.ts) ╰───────────────────────────╯ ⎿ Added 2 lines, removed 1 line ⏺ Bash(bun test) ⎿ 3 pass, 1 fail ● Done. refresh now rejects expired claims and logs an audit event. ✻ Worked for 42s · done 4:20 PM › /hello ⎿ hello-mod: Hello! You said hi 1 time. ⟨Claude Code's own drawing⟩ ◆ hello-mod │ /hello pressed 1× ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Band
⟨Claude Code's own drawing⟩ ◆ hello-mod │ /hello pressed 1×
README

claude-code-mods

🧩 Claude Code Mods: Make Your Terminal Come Alive

Claude Code now has mods: plugins made of TypeScript function hooks that can draw UI right inside the terminal, react to everything Claude does, and change how it works. This repo contains four mods I use every day. There's a pixel critter that lives above your prompt, a control panel for model, effort and parallel agents, a project launcher box, and a live status bar. It also has everything you need to build your own in about 10 minutes.

Claude Code TypeScript License: MIT

⚠️ Mods are early access. The function-hooks API can change between Claude Code releases. Everything here was built and tested on Claude Code 2.1.294.


⚡ Quick Start (30 seconds)

Open Claude Code in a terminal and paste:

/plugin install pixel-buddy --marketplace Bocskay-Botond/claude-code-mods

Answer y to add the marketplace, press Enter for the user scope, and you're done. A little orange critter appears above your prompt. Start typing and watch it pull out a laptop. 🧡

Want the full setup? 👉 quick-start/


🎮 What's Included

ModWhat it doesCommands
🐾 pixel-buddyA 12×4 pixel Claude critter above the prompt. It types on a tiny laptop while you type, patrols while Claude works, celebrates when a turn finishes, plays (keepy-uppy, jump rope, butterflies, bubbles, reading) when you're idle, and falls asleep after 3 minutes./buddy /pet
🛠️ tristens-toolsA tools menu and status line: model & effort picker, Clean View (hides tool noise and shows a simple checklist), Prompt Upgrade, Agent Dock (split each request across 1–100 helper agents and watch them live), and a Roadtrip racing minigame./tools /dock /roadtrip
📁 project-boxA folder-tree card beside the status bar listing your projects by category. Click a category, then a project, to see its note and path. pixel-buddy walks over and "types the cd" for you./projects
📊 statusbarA minimal one-line status bar: working/idle, tool count, last tool, last turn duration, turns. The simplest real mod in the repo, so read this one first.—
👋 hello-modThe tutorial example: a slash command, a toast and a band in about 35 lines./hello

Install any of them the same way:

/plugin install <mod-name> --marketplace Bocskay-Botond/claude-code-mods

📂 Repository Structure

claude-code-mods/
├── .claude-plugin/
│   └── marketplace.json      # makes this repo a plugin marketplace
├── mods/
│   ├── pixel-buddy/          # 🐾 the critter
│   ├── tristens-tools/       # 🛠️ tools menu, Agent Dock, Roadtrip
│   ├── project-box/          # 📁 project launcher card
│   └── statusbar/            # 📊 one-line status bar
├── examples/
│   └── hello-mod/            # 👋 your first mod, fully commented
├── quick-start/              # ⚡ 5-minute setup
├── docs/
│   ├── installation.md       # every way to install & manage mods
│   ├── writing-your-own-mod.md
│   ├── api-cheatsheet.md     # events, $ nouns, UI elements
│   └── troubleshooting.md
├── mod-builder-prompt/       # 🤖 a prompt that makes Claude build mods for you
└── assets/                   # 🖼️ social preview (HTML source + PNG)

Every mod is the same four small files:

my-mod/
├── .claude-plugin/plugin.json   # name, version, description
├── hooks/hooks.json             # { "modules": ["./register.tsx"] }
├── hooks/register.tsx           # the code
└── types/index.d.ts             # the state your mod keeps (optional)

🎯 What You'll Learn

  • What a Claude Code mod is, and how it differs from skills, slash commands and classic shell hooks
  • How the on(event, hook) / next(e) middleware chain works
  • How to draw UI in the terminal: bands above the prompt, panes, buttons, even a pixel raster at 25 fps
  • How to keep state with atoms and have the UI redraw automatically
  • How to change Claude's behaviour: swap the model per request, add system-prompt sections, react to tool calls
  • How to test a mod with claude plugin test and ship it as a GitHub marketplace

🚦 Prerequisites

  • Claude Code 2.1.294 or newer in a terminal (claude --version)
  • A Claude subscription or API key (whatever you already use with Claude Code)
  • Git if you want to clone and hack on the mods
  • Coffee ☕ (highly recommended)

No Node, no npm install, no build step. Claude Code compiles the TypeScript itself.


🔨 Build Your Own Mod

The fastest way is to ask Claude. Inside Claude Code:

Make me a mod that shows a 🍅 pomodoro timer above the prompt and plays a toast when it ends.

Claude Code has a built-in skill for this: it writes the mod, hot-reloads it into your session and tests it. For a better result, paste the prompt from mod-builder-prompt/ first.

Prefer to do it by hand? docs/writing-your-own-mod.md walks through hello-mod line by line, and docs/api-cheatsheet.md has the events and elements you'll use most.


📁 Configure project-box

project-box shows a demo list until you give it yours. Copy the example and edit it:

# macOS / Linux
cp mods/project-box/project-box.example.json ~/.claude/project-box.json

# Windows (PowerShell)
Copy-Item mods\project-box\project-box.example.json $HOME\.claude\project-box.json

Restart Claude Code (or run /reload-plugins) and your projects show up. Colors can be any terminal color name (magenta, cyan, green, yellow, blue, red). Set "live": true for a green dot.


🐛 Troubleshooting

ProblemFix
Nothing appears after installRun /reload-plugins, or restart Claude Code. Make sure you're in a terminal: /plugin isn't available in the desktop app's Code tab.
Marketplace file not foundCheck the repo name: Bocskay-Botond/claude-code-mods
A mod silently does nothingStart with claude --debug. A failing hook is skipped and logged with the reason.
Two bands fight for spacepixel-buddy, project-box and tristens-tools are designed to stack. Turn things off with /buddy, /projects, or /plugin → disable.

More: docs/troubleshooting.md


🤝 Contributing

Built a cool mod? PRs are welcome!

  1. Fork the repo
  2. Add your mod under mods/<your-mod>/ (four files, see above)
  3. Make sure claude plugin validate mods/<your-mod> and claude plugin test mods/<your-mod> pass
  4. Add it to .claude-plugin/marketplace.json and to the table in this README
  5. Open a PR with a screenshot or GIF 📸

📄 License

MIT. Do whatever you want, just don't blame me if your critter falls asleep on the job. 😴


🙏 Acknowledgments


☕ Support

If this made your terminal a little more fun, ⭐ star the repo and share it with someone who lives in Claude Code.

Now go build a mod. Your terminal has been boring for long enough. 🚀

Source 2 files
hooks/register.tsx 38 lines
1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4// One value the band reads; update() redraws every reader.
5const count = atom({ plugin: 'hello-mod', key: 'count' } as const, 0)
6
7export const register: Register = on => {
8  // 1. Register a slash command when the session starts.
9  on('session.start', async ($, e, next) => {
10    await $.command.register({ name: 'hello', description: 'Say hello from your first mod' })
11    return next(e)
12  })
13
14  // 2. Answer it: bump the counter and pop a toast.
15  on('command.run', { command: 'hello' }, async $ => {
16    const n = await update($, count, c => c + 1)
17    $.ui.toast(`Hello #${n} from hello-mod 👋`)
18    return { text: `Hello! You said hi ${n} time${n === 1 ? '' : 's'}.` }
19  })
20
21  // 3. Draw a one-line band above the prompt.
22  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
23    if (e.props.hasSurvey) return next(e)
24    const below = await next(e)
25    const { Box, Text } = $.ui.resolve(e)
26    const n = await read($, count)
27    return (
28      <Box flexDirection="column">
29        {below}
30        <Text>
31          <Text color="magenta">◆ hello-mod</Text>
32          <Text dimColor> │ /hello pressed {n}×</Text>
33        </Text>
34      </Box>
35    )
36  })
37}
38
types/index.d.ts 8 lines
1export type Count = number
2
3declare module 'claude-code' {
4  interface PluginState {
5    'hello-mod': { count: Count }
6  }
7}
8