A side agent reads each long reply and surfaces what you should not miss (costs, risks, actions needed).

Eight mods for Claude Code (terminal and the desktop app's Code tab). Requires Claude Code 2.1.287 or newer.
| Mod | What it does | Commands |
|---|---|---|
| savvy-progress | Progress bar above the prompt; an Agents side panel with a pixel crab per subagent showing model, effort, task progress, context, tokens and estimated cost | /savvy, /crab-style <keyword> <color> <hat> |
| tool-skins | Themed icons and colors for tool calls (Tokyo Night, Nord, Dracula, Gruvbox, Solarized, Catppuccin, Rose Pine) | /skin <theme> |
| you-should-know | After a long reply, a Haiku side agent flags costs, risks and actions you might miss | /ysk on, /ysk off, /ysk focus <text> |
| file-tree | A panel showing which files Claude is reading or editing; turns green once committed | /files |
| cache-tax | Warns before a prompt reloads a cold prompt cache, with a token and cost estimate | /keepwarm, /cachetax ttl <minutes> |
| blast-radius | Stops rm -r, Remove-Item -Recurse, git clean -f, git reset --hard and similar, lists the files at stake, and waits for Proceed or Cancel | automatic |
| reflect | Spots corrections in your prompts and offers to save them as rules in CLAUDE.md | /reflect <rule> |
| terminal-browser | A text-mode browser pane; Claude can open pages there too | /browse <url or path> |
Cost figures are estimates at API list prices. you-should-know and reflect make small Haiku calls, which count toward your usage.
At a Claude Code prompt in a terminal:
/plugin install savvy-progress --marketplace Isaacg1000/isaac-mods
Answer y to add the marketplace, then pick the user scope. Repeat with each mod name you want.
Or from a shell, all at once:
claude plugin marketplace add Isaacg1000/isaac-mods
claude plugin install savvy-progress@isaac-mods --scope user
claude plugin install tool-skins@isaac-mods --scope user
claude plugin install you-should-know@isaac-mods --scope user
claude plugin install file-tree@isaac-mods --scope user
claude plugin install cache-tax@isaac-mods --scope user
claude plugin install blast-radius@isaac-mods --scope user
claude plugin install reflect@isaac-mods --scope user
claude plugin install terminal-browser@isaac-mods --scope user
Each mod lives in plugins/<name>/: hooks/register.tsx is the hooks module, types/index.d.ts its state contract. Check and test one with:
claude plugin validate plugins/<name>
claude plugin test plugins/<name>
When this folder is added as a local marketplace (claude plugin marketplace add <this folder>), edits are picked up with /reload-plugins.
hooks/register.tsx 128 lines1import { atom, read, update } from 'claude-code'
2import type { Register } from 'claude-code'
3
4import type { Flags } from '../types'
5
6const flags = atom({ plugin: 'you-should-know', key: 'flags' } as const, null as Flags | null)
7const isChecking = atom({ plugin: 'you-should-know', key: 'isChecking' } as const, false)
8const focus = atom({ plugin: 'you-should-know', key: 'focus' } as const, '')
9const isEnabled = atom({ plugin: 'you-should-know', key: 'isEnabled' } as const, true)
10
11// Replies shorter than this are easy to read in full; skip the side agent.
12const MIN_CHARS = 600
13
14const SYSTEM = `You are a second reader watching an AI assistant's reply to its user. The user often skims long replies.
15Flag ONLY things the user would regret missing, such as:
16- money or usage costs, paid API calls, pricing
17- irreversible, destructive or risky actions taken or proposed
18- security or privacy concerns, secrets, credentials
19- decisions or actions the user must take themselves
20- failures, skipped steps, unverified claims, caveats buried in the text
21Reply with at most 3 lines, each starting with "- " and under 22 words, most important first.
22If nothing qualifies, reply with exactly NONE.`
23
24export const register: Register = on => {
25 let lastPrompt = ''
26
27 on('session.start', async ($, e, next) => {
28 await $.command.register({
29 name: 'ysk',
30 description: 'You Should Know: /ysk on | off | focus <what to watch for> | show',
31 argumentHint: 'on | off | focus <text> | show',
32 })
33 const saved = (await $.store.get('settings')) as { focus?: string; isEnabled?: boolean } | undefined
34 if (saved?.focus) await update($, focus, () => saved.focus ?? '')
35 if (saved?.isEnabled === false) await update($, isEnabled, () => false)
36 return next(e)
37 })
38
39 on('command.run', { command: 'ysk' }, async ($, e) => {
40 const [verb = '', ...rest] = e.args.trim().split(/\s+/)
41 if (verb === 'on' || verb === 'off') {
42 await update($, isEnabled, () => verb === 'on')
43 } else if (verb === 'focus') {
44 await update($, focus, () => rest.join(' '))
45 } else if (verb === 'show') {
46 const f = await read($, flags)
47 return { text: f ? f.items.join('\n') : 'Nothing flagged yet.' }
48 } else {
49 const f = await read($, focus)
50 const enabled = await read($, isEnabled)
51 return { text: `You Should Know is ${enabled ? 'on' : 'off'}. Extra focus: ${f || '(none)'}.\nUsage: /ysk on | off | focus <text> | show` }
52 }
53 await $.store.set('settings', { focus: await read($, focus), isEnabled: await read($, isEnabled) })
54 return { text: verb === 'focus' ? `Now also watching for: ${rest.join(' ') || '(defaults only)'}` : `You Should Know ${verb}.` }
55 })
56
57 on('turn.start', async ($, e, next) => {
58 lastPrompt = e.text
59 await update($, flags, () => null)
60 return next(e)
61 })
62
63 on('turn.complete', async ($, e, next) => {
64 const result = await next(e)
65 if (e.agentId || e.isAborted || e.answer.length < MIN_CHARS || !(await read($, isEnabled))) return result
66
67 const answer = e.answer
68 const turnId = e.turnId
69 const prompt = lastPrompt
70 // Run after this dispatch so the turn is never held up by the side agent.
71 $.clock.after(0, () => {
72 void (async () => {
73 await update($, isChecking, () => true)
74 try {
75 const extra = await read($, focus)
76 const reply = await $.model.complete({
77 model: 'haiku',
78 system: extra ? `${SYSTEM}\nThe user especially cares about: ${extra}` : SYSTEM,
79 prompt: `The user asked:\n${prompt.slice(0, 2000)}\n\nThe assistant replied:\n${answer.slice(0, 24000)}`,
80 maxTokens: 300,
81 timeoutMs: 45000,
82 })
83 if (!reply.isAnswered) return
84 const items = reply.text
85 .split('\n')
86 .map(l => l.trim())
87 .filter(l => l.startsWith('- '))
88 .map(l => l.slice(2))
89 .slice(0, 3)
90 if (items.length === 0 || /^NONE\b/.test(reply.text.trim())) return
91 await update($, flags, () => ({ turnId, items }))
92 $.ui.toast(`You should know: ${items[0]}`, { timeoutMs: 6000 })
93 } finally {
94 await update($, isChecking, () => false)
95 }
96 })()
97 })
98 return result
99 })
100
101 on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
102 const f = await read($, flags)
103 const checking = await read($, isChecking)
104 if (e.props.hasSurvey || e.props.isWorking || (!f && !checking)) return next(e)
105 const { Box, Text, Button } = $.ui.resolve(e)
106 if (!f) {
107 return (
108 <Box>
109 <Text dimColor>💡 skimming the reply for anything you should know…</Text>
110 </Box>
111 )
112 }
113 return (
114 <Box flexDirection="column" borderStyle="round" borderColor="warning" paddingX={1}>
115 <Box flexDirection="row" justifyContent="space-between">
116 <Text bold color="warning">
117 💡 You should know
118 </Text>
119 <Button key="dismiss" label="Dismiss" role="dismiss" plain onPress={() => update($, flags, () => null)} />
120 </Box>
121 {f.items.map(item => (
122 <Text wrap="wrap">• {item}</Text>
123 ))}
124 </Box>
125 )
126 })
127}
128types/index.d.ts 13 lines1export type Flags = { turnId: string; items: string[] }
2
3declare module 'claude-code' {
4 interface PluginState {
5 'you-should-know': {
6 flags: Flags | null
7 isChecking: boolean
8 focus: string
9 isEnabled: boolean
10 }
11 }
12}
13