Think-Short Setup — install terse-mode hooks

sonnet status / install / upgrade / enable / disable / uninstall / purge project | global user-invoked

What it does

/brewtools:think-short-setup installs (or removes) a small set of hooks that inject a fixed brevity directive into the Claude Code session. Run the skill with a free-text intent — “make responses shorter”, “stop the preamble” — and it asks via AskUserQuestion whether to apply to the current Project or Globally. It then copies four files into the target hooks directory — three hook scripts and think-short-prompt.md (the directive body) — and registers three hook entries in the appropriate settings.json. The subagent hook injects the directive on SubagentStart via hookSpecificOutput.additionalContext.

The -setup suffix is literal: this skill installs a mechanism you then use instead of the skill. After install you never type the skill again unless you want to change or remove the wiring.

There are no profiles and no config file. The only persisted state is the copied prompt file plus an ephemeral per-session counter in the OS temp directory. Because the hooks have no enabled flag, disable renames think-short-prompt.md to think-short-prompt.md.disabled — the hooks stay wired, find no prompt and no-op. purge deletes the files and the tmp markers outright.

The same directive body is injected at every point:

Be terse. Results first, no preamble/filler/sycophancy. ASCII only.
Think short: minimal internal reasoning, no exploring aloud.
Grep before Read. Edit over Write. Parallel calls in one message.
Plan the full edit set, then execute.

Keep code simple - do not over-engineer. Before writing anything new,
check existing code and libraries for the needed functionality.
Prefer extending or abstracting a similar class over adding a new one.
After writing code, one pass: can this be simpler? If yes - simplify it.

Comment like a human, not an AI. Write comments only where they earn it:
non-obvious logic, public APIs, class/method docstrings (JavaDoc/PyDoc/etc).
Do NOT narrate self-evident code or add line-by-line noise. Keep docstrings -
just stop over-commenting. Each comment terse: ~1 line, 2 only if asked.

Two of those lines are the simplicity discipline: the model thinks short instead of exploring aloud, and after the code is written it makes one explicit pass asking whether the same thing can be done simpler.

When to use

SituationSuggested invocation
See what is wired where, change nothing/brewtools:think-short-setup status
Long automated runs where preamble accumulates across many subagent turns/brewtools:think-short-setup install project
Consistent brevity across all projects on this machine/brewtools:think-short-setup install global
Pick up a new directive text after a brewtools update/brewtools:think-short-setup upgrade
Status says injects=unknown — the installed copy is older than the --check diagnostic/brewtools:think-short-setup upgrade
Pause terseness for a few sessions without deleting anything/brewtools:think-short-setup disable
Turn it back on/brewtools:think-short-setup enable
Unwire the hooks, keep the tmp markers/brewtools:think-short-setup uninstall
Delete every file and every marker this skill ever wrote/brewtools:think-short-setup purge
Output-heavy sessions where you want periodic reinforcement, not constant injectionInstall project-scope — counter hook fires every 10 turns, not every turn

Examples

Install for the current project:

/brewtools:think-short-setup make responses shorter, install in this project

Install globally (all projects on this machine):

/brewtools:think-short-setup install global

Pause it without deleting anything:

/brewtools:think-short-setup disable

Every mode starts with the same status block, and the skill calls AskUserQuestion to confirm scope (Project vs. Global) before writing any files. With no arguments at all it defaults to status when something is installed and install when nothing is.

Workflow

  1. Status first, always

    Every mode opens with the same status block: how many of the 3 hook scripts are present per scope, how many settings.json entries reference them, whether the prompt file is enabled, disabled or none, and — via —check on the installed subagent hook — whether subagent injection actually fires (injects). Half-installed states are reported as such, never as installed.

  2. Mode read from free text

    The argument is a free-text description or one of status, install, upgrade, enable, disable, uninstall, purge — RU triggers included. Ambiguity between an install and a removal verb raises AskUserQuestion instead of a guess.

  3. Scope confirmation (AskUserQuestion)

    The skill asks: Project (writes to .claude/hooks/ + .claude/settings.json) or Global (writes to ~/.claude/hooks/ + ~/.claude/settings.json). No files are written until you answer.

  4. Hook files copied to target directory

    Four files are copied: three hook scripts (think-short-session.mjs, think-short-prompt-counter.mjs, think-short-subagent.mjs) and think-short-prompt.md (the directive body text each hook reads at runtime). For global scope, writes go via Bash (the Write tool is blocked on ~/.claude/* in all permission modes).

  5. Entries merged into settings.json

    Three hook registrations are added to the matching settings.json — one per hook file. Existing entries from other skills are preserved.

  6. Hooks active from the next session start

    Wiring changes (install, upgrade, uninstall, purge) need a new Claude Code session — plain settings.json hooks, so /reload-plugins is not involved. enable and disable take effect immediately, because the hooks re-read the prompt file on every call.

Modes

ModeEffectHook filessettings.jsonPrompt filetmp markers
statusreport only
installwire the 3 hookscopiedentries mergedcopied
upgradere-emit from the current plugin versionre-copiedentries re-mergedre-copied, disabled state keptkept
enable.disabled -> think-short-prompt.mdkeptkeptrenamed backkept
disableprompt renamed away; hooks stay wired, become no-opskeptkeptrenamed awaykept
uninstallunwiredeletedentries strippeddeletedkept
purgefull wipedeletedentries strippeddeleteddeleted

Re-install is a no-op. One target per run; “both scopes” is two runs.

Delegation

Warning

A big task handed to one agent = an agent gone for an hour. You cannot observe it, you cannot correct it, and it usually drifts off-target. Install or remove for one target is one bounded unit — 4 asset files plus one settings.json, well under 10 steps — so it is a single brewcode:hook-creator spawn. A wider request (“install here AND globally AND clean three other repos”) is split into N tasks, one per target, all spawned in a single message.

The spawn prompt carries six fields. A bare one-line task is never enough:

FieldContent
GOALthe user wants terse-mode hooks installed or removed for this target; pure file + settings wiring
ROLEown the file copy/strip and the settings.json merge — never edit hook logic or unrelated settings keys
SCOPEin — the 4 assets, the target .claude/ dir, its settings.json; global target is Bash-only (protected path)
CONTEXTthe plugin cache is already verified and every path resolved; nothing copied yet, no sibling writer
CONSUMERthe settings file is loaded by the next Claude Code session — a malformed merge breaks that session, not this one
DONEwhich hooks were installed or removed, plus the exact settings.json path touched

That CONSUMER line is the reason the agent must report the exact path: the failure surfaces one session later, so it has to be checkable now.

How it works

Three hooks are installed, each targeting a different injection point:

HookEventBehavior
think-short-session.mjsSessionStartInjects the full directive; resets the per-session prompt counter in $TMPDIR; prunes stale counters from prior sessions
think-short-prompt-counter.mjsUserPromptSubmitInjects the directive on every 10th user prompt (turns 10, 20, 30 — never turn 1, which is covered by SessionStart)
think-short-subagent.mjsSubagentStartInjects the full directive into every spawned subagent via additionalContext

The counter hook keeps injection periodic, not per-turn. Turns 2–9 run without re-injection; at turn 10 the hook fires again to reinforce brevity after context drift.

Installation targets

ScopeHook files written toSettings file updated
Project.claude/hooks/.claude/settings.json
Global~/.claude/hooks/~/.claude/settings.json (via Bash)

Global installs use the Bash tool for all file operations because ~/.claude/* is a protected path — the Write and Edit tools are blocked there in every permission mode, including bypassPermissions.

Subagent hook injection

think-short-subagent.mjs fires on SubagentStart and delivers the directive via hookSpecificOutput.additionalContext. That channel accumulates across hooks — every registered SubagentStart hook’s context is appended and delivered into the subagent’s own message list, so any number of injectors coexist with no clobbering and nothing to yield to.

Note

This replaces an earlier PreToolUse:Task|Agent design that rewrote the spawn prompt via updatedInput. That channel is single-writer/last-wins — every PreToolUse hook on the same event receives the same original input, and the runner keeps only the last hook’s updatedInput, so two hooks editing it would clobber each other. SubagentStart + additionalContext has no such conflict.

status runs node <that scope's hooks>/think-short-subagent.mjs --check "$PWD" and adds one field:

FieldValueMeaning
injectsyessubagents really receive the directive
nowired and enabled, but the prompt file is missing or empty — a broken install
n/ano subagent hook installed in that scope
unknownthe installed copy predates the --check diagnostic — run upgrade on that scope

injects measures the subagent hook only. SessionStart and the every-10th-prompt injection are separate paths.

Example status output on a machine whose global install predates the diagnostic:

project: hook_files=0/3 settings_refs=0/3 prompt=none injects=n/a
global: hook_files=3/3 settings_refs=3/3 prompt=enabled injects=unknown

The 3/3 3/3 enabled line used to be the whole report, and it read as a healthy install. injects=unknown is the part that says otherwise.

Version and ownership

install/upgrade stamp all four copied files with generated_by: "brewtools:think-short-setup". Each of the three .mjs hooks carries // brewcode-meta: version=X.Y.Z generated_by=brewtools:think-short-setup on line 2; think-short-prompt.md carries <!-- think-short brewcode-meta: version=X.Y.Z generated_by=brewtools:think-short-setup --> on line 1. /brewcode:setup-status reads these lines to tell an install running an older brewtools apart from one on the current version — upgrade is what refreshes them.

Removal

uninstall deletes all four copied files (the three hook scripts and think-short-prompt.md) and strips the corresponding three entries from settings.json, keeping the tmp markers. purge does the same and deletes the marker directory too. Neither touches entries added by other skills or plugins.

⚙️

Manager Setup

Installs a HARD wall that blocks main-session edits and forces subagent delegation. Pairs with think-short for focused, low-noise automated runs.

📋

Setup Status

Read-only dashboard across every -setup skill — installed, stale or missing, with the hand-run command for each.

📄

Brewtools overview

All brewtools skills and agents in one place.

🔗

GitHub source

Hook scripts and install/remove logic.

Updating plugins

Use /brewtools:plugin-update to check and update the brewcode plugin suite in one command. See the FAQ for details.