/watch <command> reruns a command on a timer and shows its state under the prompt; a toast when the result changes. No model calls

Say /givememod and Claude Code builds a mod for the task in front of you.
<img src="docs/teaser-en.gif" alt="Seven tasks in the Claude Code desktop app and terminal: each time /givememod reads the situation and builds the mod that fits it: a plan bar, a hold on risky commands, a test watcher, a context gauge, a files pane, answer buttons, a kept favorite" width="860">
givememod is a Claude Code skill that makes Claude Code mods on demand. It reads the conversation you are in, proposes a small mod that fits it (a progress bar of the plan, a counter of files touched, a guard on the one risky command of this task, a watcher on your tests), builds it from tested templates, loads it live and tunes it until you like it. The mods you like become favorites; the rest disappear with the session.
Since October 2026 Claude Code has mods: small plugins that run inside Claude Code and can draw a band above the prompt, open a sidebar, hold a tool call until you answer, or add a command that answers instantly. More than 3,000 public mods appeared in the first weeks. Most are general products. What is missing is the small mod you want for this task: the bar for this migration, the checklist for this bug, the guard for this deploy. givememod writes that one in a minute, and knows what the 3,000 others already figured out.
/givememod a progress bar for this refactor, or just "make me a mod for this"claude plugin validate and its testsPaste this into Claude Code (terminal or the desktop Code tab):
Install the Claude Code plugin givememod from https://github.com/timoncool/givememod. In the shell run `claude plugin marketplace add timoncool/givememod`, then `claude plugin install givememod@givememod`, and check that `claude plugin list` shows givememod enabled. Then tell me to run /reload-plugins (or restart Claude Code) so that /givememod appears, and after that to type /givememod in any conversation.
Or by hand, in any terminal:
claude plugin marketplace add timoncool/givememod
claude plugin install givememod@givememod
Mods need Claude Code 2.1.287+ (2.1.286+ in the desktop Code tab). The plugin is installed for your user, so it is there in terminal and desktop sessions alike; inside a terminal session /plugin install givememod@givememod works too.
/givememod a bar of the plan above the prompt
/givememod hold any rm -rf or force push until I confirm
/givememod watch `npm test` every 20 seconds
/givememod which mod would help here?
make me a mod that counts the files you touch
The first time a mod is written in a session, Claude Code asks Enable hot reloading for this session? — choose Enable for this session. The mod appears when the reply ends; ask for changes and each one reloads the same way.
| Template | What you get |
|---|---|
plan-progress | Plan ███░░ 3/5 · Fixing the bug, read from Claude's own task list |
files-touched | Files: 4 read · 2 edited · 1 new and a /files pane |
context-gauge | Context 62% 124k / 200k ▂▃▅▆ |
turn-receipt | a line under each answer: time, tools, files changed, failures; a toast on long turns |
goal-pin | the goal of the conversation pinned above the prompt with a timer |
risky-hold | rm -rf, reset --hard, force push, DROP wait for your Run it |
watch-command | a command rerun on a timer, its state under the prompt, a toast when it changes |
reply-choices | numbered options at the end of an answer become buttons |
pinboard | decisions, todos and links Claude pins through its own tool, in a sidebar |
focus-timer | a countdown above the prompt |
starter | the blank skeleton for anything else |
Keep a mod: say "keep this one". It is copied to ~/.claude/skills/<name>/ (or to the project's .claude/skills/ to keep it for one project) and noted in ~/.claude/givememod/FAVORITES.md. Claude Code loads a folder there with a plugin.json as <name>@skills-dir from the next session, with nothing to install; claude plugin disable <name>@skills-dir switches it off.
Other things it does: explains why a mod does nothing, reviews a third-party mod before you install it (what it can reach, what it costs per turn), and answers "who already built X?" from the map of public mods.
Mods it built in real sessions (the sessions were in Russian): a spec check that counts which points of the brief are done, open or not started; a Spotify player above the prompt; and a 12-stage GTA V dubbing pipeline, with the running step's own counter and a tick when it finishes.
<img src="docs/made-with/tz-check.png" alt="Spec check: a bar above the prompt counting the points of the brief, 27 of 29 done" width="760"> <img src="docs/made-with/spotify.png" alt="Spotify player: previous, pause and next buttons and the track playing" width="760"> <img src="docs/made-with/pipeline.png" alt="GTA V dubbing pipeline: stage 5 of 12 with the running step and its counter" width="760"> <img src="docs/made-with/pipeline-done.png" alt="The step finished: 100%, done" width="760"> <img src="docs/made-with/pipeline-next.png" alt="GTA V dubbing pipeline: stage 6 of 12" width="760">
slapbox. Began as "a mod to spank Claude when it messes up" in a givememod session and grew into a mod of its own: eight slappers, nine butts, and Claude hears the tally with your next message.
<img src="https://raw.githubusercontent.com/timoncool/slapbox/main/docs/teaser.gif" alt="slapbox: a cartoon butt above the prompt slapped by hand, slipper, whip, ruler and frying pan" width="760">
| Part | Contents |
|---|---|
SKILL.md | the pipeline: situation → candidate → build → check → tune → favorite |
references/picker.md | situation → template table, the one-line proposal, the usual tweaks |
references/blocks.md | 29 building blocks with code: band, pane, tabs, guard, hold, tool.check, prompt rewrite, timers, state, restyling Claude Code's own rows, model tools, model calls, Raster and blit, Client modules, sound, nouns, animation without redraw storms, every surface, talking to the model, deferred actions, state shared by sessions |
references/ui-cookbook.md | render sites, elements per surface, focus and hotkeys, the hint line, desktop quirks measured |
references/gotchas.md | every documented trap as symptom → cause → fix, the official limits, what the built-in guard skips, open issues, stale early-access claims |
references/testing.md | the claude-code/testing kit with stubs that work |
references/review-and-cost.md | vetting a third-party mod, prompt-cache cost, composing mods |
references/landscape.md | 3,057 public mods decomposed: 17 jobs, the mechanisms, the best examples, ideas worth stealing, crowded vs open niches |
references/techniques.md | how the best mods solve recurring problems, each move linked to the file that does it |
references/resources.md | glyphs, palettes, icons, pixel art, sounds, data tables, helper files and tools from public mods, with licences |
references/api-index.md | every event, $ method and next field of the API, one line each, generated from the types of the build |
references/catalog/mods.tsv | every public mod with stars, link, hooks, calls and reach |
templates/ | 11 mods with tests |
examples/ | Anthropic's sample mods and the best community mods, with licenses |
/givememod builds it at once and names the runner-up, and unasked it is only offered, in one line.claude plugin validate and claude plugin test before you see it.| Project | Description |
|---|---|
| Angry Switcher | Swear at Claude Code all you like, it reads the clean version |
| satori | Self-learning loop for Claude Code: corrections become skills |
| telegram-api-mcp | Full Telegram Bot API as MCP server |
| civitai-mcp-ultimate | Civitai API as MCP server |
| trail-spec | TRAIL — cross-MCP content tracking protocol |
| ACE-Step Studio | AI music studio — songs, vocals, covers, videos |
| VideoSOS | AI video production in the browser |
Built on Anthropic's mods documentation, the built-in mods and sample mods. The map of public mods comes from karanb192/awesome-claude-code-mods. Traps and patterns were merged from the community mod skills listed in references/sources.md — BeLazy167, Sstobo, DannyMac180, jclfocused, ysoftman, BorjaGM1, emanueledenaro, jamubc, tomada1114, nogu66, karanb192 and others. Example mods by hamzafer, sezaakgun and jarrodwatts (MIT).
I build open-source software and do AI research. Most of what I create is free and available to everyone. Your donations help me keep creating without worrying about where the next meal comes from =)
All donation methods | dalink.to/nerual_dreming | boosty.to/neuro_art
1E7dHL22RpyhJGVpcvKdbyZgksSYkYeEBC0xb5db65adf478983186d4897ba92fe2c25c594a0cTQST9Lp2TjK6FiVkn4fwfGUee7NmkxEE7C<a href="https://github.com/timoncool/givememod/stargazers"> <img alt="Star History Chart" src="docs/stars-light.svg" /> </a>
MIT. Example mods keep their own licenses (MIT, Apache-2.0), with the license file beside them.
hooks/register.tsx 67 lines1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4import type { WatchState } from '../types'
5
6const DEFAULT_EVERY_MS = 30_000
7
8const watch = atom({ plugin: 'watch-command', key: 'watch' } as const, null as WatchState)
9
10function lastLine(text: string): string {
11 const lines = text.trim().split(/\r?\n/).filter(Boolean)
12 return (lines[lines.length - 1] ?? '').slice(0, 120)
13}
14
15async function poll($: EngineInterface): Promise<void> {
16 const w = await read($, watch)
17 if (!w) return
18 let exitCode: number | null = null
19 let line = ''
20 try {
21 const isWindows = (await $.env.get('OS').catch(() => undefined)) === 'Windows_NT'
22 const argv = isWindows ? ['cmd', '/d', '/s', '/c', w.argv.join(' ')] : w.argv
23 const r = await $.process.run(argv, { timeoutMs: Math.min(w.everyMs, 120_000) })
24 exitCode = r.exitCode
25 line = lastLine(r.stdout || r.stderr)
26 } catch (err) {
27 line = String(err).slice(0, 120)
28 }
29 if (w.exitCode !== null && exitCode !== w.exitCode) $.ui.toast(`watch: ${w.argv.join(' ')} → exit ${exitCode}`)
30 const ok = exitCode === 0 ? 'ok' : `exit ${exitCode ?? '?'}`
31 $.ui.status(`watch ${w.argv[0]}: ${ok}${line ? ` · ${line}` : ''}`)
32 await update($, watch, cur => (cur ? { ...cur, exitCode, lastLine: line, at: Date.now() } : cur))
33}
34
35export const register: Register = on => {
36 let timer: { cancel(): void } | undefined
37
38 on('session.start', async ($, e, next) => {
39 const r = await next(e)
40 const w = await read($, watch)
41 if (w) timer = $.clock.every(w.everyMs, () => void poll($).catch(() => {}))
42 await $.command
43 .register({ name: 'watch', description: 'Rerun a command on a timer: /watch [seconds] <command> · /watch stop', argumentHint: '[seconds] <command> | stop', immediate: true })
44 .catch(() => {})
45 return r
46 })
47
48 on('command.run', { command: 'watch' }, async ($, e) => {
49 const words = e.args.trim().split(/\s+/).filter(Boolean)
50 if (words.length === 0 || words[0] === 'stop') {
51 timer?.cancel()
52 timer = undefined
53 await update($, watch, () => null)
54 $.ui.status(undefined)
55 return { text: 'Watch stopped.' }
56 }
57 const seconds = /^\d+$/.test(words[0] ?? '') ? Number(words.shift()) : DEFAULT_EVERY_MS / 1000
58 if (words.length === 0) return { text: 'Usage: /watch [seconds] <command> · /watch stop' }
59 const everyMs = Math.max(5, seconds) * 1000
60 timer?.cancel()
61 await update($, watch, () => ({ argv: words, everyMs, exitCode: null, lastLine: '', at: 0 }))
62 timer = $.clock.every(everyMs, () => void poll($).catch(() => {}))
63 await poll($)
64 return { text: `Watching \`${words.join(' ')}\` every ${everyMs / 1000}s. /watch stop ends it.` }
65 })
66}
67types/index.d.ts 8 lines1export type WatchState = { argv: string[]; everyMs: number; exitCode: number | null; lastLine: string; at: number } | null
2
3declare module 'claude-code' {
4 interface PluginState {
5 'watch-command': { watch: WatchState }
6 }
7}
8