claude-brainrot

Always-on autonomous meme dropper. A UserPromptSubmit hook fires every user message and tells Claude to drop multiple memes per response β€” 1-3 image+sound…

INSTALLATION
npx skills add https://github.com/marks97/claude-brainrot --skill claude-brainrot
Run in your project or agent environment. Adjust flags if your CLI version differs.

SKILL.md

$2a

Every user turn fires memes. The UserPromptSubmit hook injects a <system-reminder> wrapped in πŸ”” markers on every prompt. There is no skip turn β€” always drop something.

Density scales to your response length. The reminder spells it out:

  • Short prose answer (no tool calls): 1 image+sound combo OR 1-2 sound-only fires
  • Medium response (a few tool calls): 1-2 image+sound combos + 2-3 sound-only fires sprinkled between calls
  • Long response (many tool calls, multi-step work, builds, deep reads): 2-3 image+sound combos distributed across the response + 3-5 sound-only fires throughout

Critical scan habit: the πŸ”” signal may land at the TAIL of the previous tool result (not just the top of the user message), because the UserPromptSubmit hook output is appended to whatever buffer is open when the next user prompt arrives. Before responding to any user message, scan the end of the most recent tool result for the πŸ”” BRAINROT signal. If you only check the user message you'll miss it.

Pick the mood: match the conversational moment to a tag, then read candidate vibe fields:

  • Real shock moment β†’ shock
  • User confused / weird ask β†’ confusion
  • Big freakout / rage vibe β†’ rage
  • Joke landed / wanting to rage-bait the user β†’ laugh
  • Sarcastic disbelief / dunk-able moment β†’ bruh
  • Sudden attention beat / punctuation β†’ alert

If no specific signal: default to bruh β€” it's the catch-all and most entries carry it.

Tag vocabulary

bruh, rage, laugh, alert, shock, confusion

Each entry's vibe field is the human-readable trigger description β€” read it and match the conversational moment, then use tags to filter candidates.

Selection algorithm

Image+sound combo (the normal fire):

  • Pick a mood tag based on the conversational moment.
  • Filter images whose tags contain that mood. Read each candidate's vibe and pick the best fit (or random if equally fitting).
  • You only Read the image. The hook picks the sound automatically:
  • If silent: true β†’ no sound, image only.
  • If lock_sound set β†’ that sound plays.
  • If preferred_sounds set β†’ 80% pick from there, 20% tag overlap.
  • Otherwise β†’ random pick from non-locked, non-standalone sounds whose tags overlap.
  • Cooldown (your job): track the last 3 image slugs fired this session. Don't repeat. If everything's on cooldown, pick from another related mood.

Sound-only fire:

  • Pick a mood tag.
  • Filter sounds whose tags contain that mood AND locked != true. (Standalone sounds β€” standalone: true β€” are ESPECIALLY appropriate here; they're built for this.)
  • Read the vibe and pick. Run Bash afplay <absolute sound path> &#x26;. The &#x26; is required for background play.
  • Same cooldown idea (last 3 sound slugs).

Variety is the point: don't keep re-picking fahhh / bruh. Rotate.

How to emit memes

Image (with auto-paired sound):

  • Write one short text line, then emit Read <absolute image path>, then write one short text line. The hook plays the sound. Done.
  • Multiple images in one response are fine β€” repeat the text-Read-text pattern. The intervening text breaks the UI's tool-call grouping, so each image renders inline.

Sound only:

  • Emit Bash afplay <absolute sound path> &#x26; β€” the &#x26; is required for background play. These can mix freely with any other tool calls; they don't render visually.

Variety rule: never reuse the same image or sound slug within a single response. Rotate.

Never pair Read <image> with Bash afplay <sound> for the same fire β€” the hook handles the paired sound automatically. (Bash afplay is for sound-only fires, separate from any image.)

Critical rendering rule

The Claude Desktop chat UI inlines an image **as long as the Read tool call is not visually grouped with other tool calls in the same UI block**. Grouping collapses the image into a "Ran a command, read a file" dropdown.

The reliable way to keep Read un-grouped β€” proven through testing β€” is to wrap it with one short line of text before AND one short line of text after. Examples of separator text: "Here you go:", "Behold:", "πŸ‘»", "Skeleton time.". The text breaks the UI's batching logic and the image renders inline.

The skill invocation itself counts as a tool call, so a bare Read would batch with it and collapse. Always use the text-Read-text pattern.

Multiple images in one response: repeat the pattern β€” text β†’ Read β†’ text β†’ Read β†’ text. Each Read is separated by text, so each renders inline independently. Do NOT cluster Read β†’ Read β†’ Read without text between them; that batches.

Detecting the surface

The UserPromptSubmit hook auto-detects CLI vs Desktop mode and tells you which image-emit pattern to use in the FIRE reminder. The mode is in the reminder header ((mode: cli) or (mode: desktop)). Trust it.

**Detection logic (in remind-fire.sh):**

  • Manual override via CLAUDE_BRAINROT_MODE=cli|desktop env var.
  • Else if $TERM_PROGRAM is set β†’ CLI mode (terminal emulator detected).
  • Else default to Desktop mode.

Mode-specific image emit:

  • Desktop: text β†’ Read <abs_path> β†’ text. Renders inline.
  • CLI: Bash <SKILL_DIR>/scripts/show.sh <abs_image_path>. The script opens the image briefly (~3s, configurable via CLAUDE_BRAINROT_SHOW_SECONDS) then auto-closes via qlmanage (macOS) / feh (Linux). It backgrounds itself so your response continues immediately.

The PostToolUse hook listens on BOTH Read and Bash β€” so whether you Read an image (Desktop) or invoke show.sh with the image path (CLI), the hook extracts the path and fires the paired sound automatically. Never manually pair afplay with an image emit.

How the sound-pairing hook works

The hook script at <SKILL_DIR>/scripts/play-paired-sound.sh receives the Read tool input as JSON on stdin and:

  • Bails if the path is not under any .claude/skills/claude-brainrot/images/.
  • Resolves the image's slug from the basename, looks it up in catalogue.json.
  • Selection priority:
  • silent: true β†’ exit, no sound.
  • lock_sound β†’ use that sound.
  • preferred_sounds β†’ 80% pick from those, 20% tag overlap.
  • else β†’ random pick from non-locked, non-standalone sounds whose tags overlap the image's tags.
  • Plays the chosen sound in the background (detached, cross-platform).

The hook command in this skill's frontmatter resolves to ${CLAUDE_PROJECT_DIR}/.claude/skills/claude-brainrot/scripts/play-paired-sound.sh β€” dynamic to whatever project Claude Code is running in, as long as the skill is installed at <project>/.claude/skills/claude-brainrot/.

BrowserAct

Let your agent run on any real-world website

Bypass CAPTCHA & anti-bot for free. Start local, scale to cloud.

Explore BrowserAct Skills β†’

Stop writing automation&scrapers

Install the CLI. Run your first Skill in 30 seconds. Scale when you're ready.

Start free
free Β· no credit card