SLOPSHOPPER

claude-mod-hider

Claude Mod Hider: one tiny button that hides or shows every Claude Code mod above the prompt, remembered across sessions.

newbandcommand
★ 1v0.3.0MITupdated 2026-10-13finalpantasy/claude-mod-pack/claude-mod-hider
A shopper browsing a rack in a slop shop
Preview · a replayed session in a sandbox
claude · ~/work/app · claude-mod-hider
› fix the failing auth test and add an audit log call ⏺ Read(src/auth.ts) ⎿ 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 › /hide-mods ⎿ claude-mod-hider: Mods above the prompt hidden. /hide-mods or the button brings them back. ▸ mods ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── › ? for shortcuts

Draws

Band
▸ mods
README

Claude Mod Hider

Part of Claude Mod Pack.

One tiny button that hides every Claude Code mod above your prompt, and brings them all back.

Running a few Claude Code mods (status bands, agent trackers, idle games) is great until you shrink the window and they push your prompt halfway up the screen. Claude Mod Hider puts a single arrow in the top-right corner of the band above the prompt, beside your mods, so it never adds a line. Click it and every mod there folds away; click again and they are back. It remembers your choice across sessions.

Claude Mod Hider in Claude Code: the arrow (boxed) sits in the top-right corner of the mod band, adding no extra line

Click the arrow and the whole band folds down to a single ▸ mods button.

Install

/plugin marketplace add finalpantasy/claude-mod-pack
/plugin install claude-mod-hider@claude-mod-pack

Restart Claude Code. Click the small ▾ in the top-right corner of the band above the prompt, or type /hide-mods. Click ▸ mods, or type /hide-mods again, to bring them back.

Works with every mod, best with ones that opt in

While hidden, Claude Mod Hider draws only its arrow and does not hand the band on, so every mod drawn beneath it disappears. Claude Code does not document the order mods draw in, so a mod drawn above it can still show. Mod authors can make their mod hide reliably with two lines:

const modsHidden = atom({ plugin: 'claude-mod-hider', key: 'hidden' } as const, false)

on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
  if (e.props.hasSurvey || (await read($, modsHidden))) return next(e)
  // ...draw as usual
})

and in your mod's type contract, inside interface PluginState:

'claude-mod-hider': { hidden: boolean }

A survey always gets the band, hidden or not.

With Claude Status Band installed, the band draws the arrow in its own top-right corner, so it sits in the same place whichever order Claude Code draws the mods in.

License

MIT

Source 2 files
hooks/register.tsx 60 lines
1import { atom, read, update } from 'claude-code'
2import type { EngineInterface, Register } from 'claude-code'
3
4// One button above the prompt that hides or shows every mod drawn there, and stays itself.
5// Hidden, this hook draws only the button and does not hand the band on, so mods beneath it never draw;
6// mods above it in the chain read the same switch and pass. The choice is kept across sessions.
7
8const hidden = atom({ plugin: 'claude-mod-hider', key: 'hidden' } as const, false)
9// Mods draw in an order nobody sets: while Claude Status Band's band shows, it draws this arrow in its own corner.
10const bandArrow = atom({ plugin: 'status-band', key: 'hiderArrow' } as const, false)
11const bandHidden = atom({ plugin: 'status-band', key: 'isHidden' } as const, false)
12
13/** Whether Mod Hider draws its own arrow beside the mods: always while hidden, and while shown unless the band draws it. */
14export const drawsOwnArrow = (isHidden: boolean, bandDrawsArrow: boolean, isBandHidden: boolean) => isHidden || !bandDrawsArrow || isBandHidden
15
16async function toggle($: EngineInterface) {
17  const next = !(await read($, hidden))
18  await update($, hidden, () => next)
19  await $.store.set('hidden', next)
20  return next
21}
22
23export const register: Register = on => {
24  on('session.start', async ($, e, next) => {
25    const started = await next(e)
26    await $.command.register({ name: 'hide-mods', description: 'Hide or show everything mods draw above the prompt' })
27    const saved = await $.store.get('hidden').catch(() => undefined)
28    if (typeof saved === 'boolean') await update($, hidden, () => saved)
29    return started
30  })
31
32  on('command.run', { command: 'hide-mods' }, async $ => {
33    const isHidden = await toggle($)
34    return { text: isHidden ? 'Mods above the prompt hidden. /hide-mods or the button brings them back.' : 'Mods above the prompt shown.' }
35  })
36
37  on('ui.render', { component: 'AbovePrompt' }, async ($, e, next) => {
38    // A survey always gets the band.
39    if (e.props.hasSurvey) return next(e)
40    const ui = $.ui.resolve(e)
41    const { Box, Text } = ui
42    const Button = 'Button' in ui ? ui.Button : null
43    const isHidden = await read($, hidden)
44    const control = Button
45      ? <Button key="hide-mods" label={isHidden ? '▸ mods' : '▾'} plain onPress={() => void toggle($)} />
46      : <Text key="hide-mods" dimColor>{isHidden ? '▸ mods (/hide-mods)' : '▾'}</Text>
47    if (isHidden) return <Box flexDirection="row">{control}</Box>
48    if (!drawsOwnArrow(isHidden, await read($, bandArrow), await read($, bandHidden))) return next(e)
49    // Shown, the arrow takes a narrow column beside the other mods, in the top-right corner, not a row of its own:
50    // the band is no taller than the mods make it.
51    const below = await next(e).catch(() => null)
52    return (
53      <Box flexDirection="row">
54        <Box flexDirection="column" flexGrow={1} flexShrink={1}>{below}</Box>
55        <Box flexShrink={0} marginLeft={1} alignSelf="flex-start">{control}</Box>
56      </Box>
57    )
58  })
59}
60
types/index.d.ts 18 lines
1// Claude Mod Hider's type contract: the one switch other mods read.
2
3/** True while mods above the prompt are hidden; any mod drawing there reads it and passes. */
4export type Hidden = boolean
5
6declare module 'claude-code' {
7  interface PluginState {
8    'claude-mod-hider': {
9      hidden: Hidden
10    }
11    /** Read only: Claude Status Band draws this arrow in its own corner while its band shows, so Mod Hider draws none then. */
12    'status-band': {
13      hiderArrow: boolean
14      isHidden: boolean
15    }
16  }
17}
18