MOD brewcode mods
On this page
Prompt placeholders
Claude Code 2.1.301+ Works on Team orgs brewmod-placeholders++m ++a ++r ++rr +++ do nothing?
Since brewtools v6.8.0 the prompt-injection codewords ++m, ++a, ++r, ++rr and +++ live in the brewmod-placeholders mod, not in brewtools. The mod is easier to use and lets you add your own placeholders. Install it (Claude Code 2.1.301+: run claude update first), then run /reload-plugins:
claude plugin marketplace add https://github.com/kochetkov-ma/claude-brewcode && claude plugin install brewmod-placeholders@claude-brewcodeStart here: Quick start.
Prompt shortcuts for Claude Code: type ++r to attach a saved instruction block, read its text before you send, add your own with /placeholders.

Real Claude Code 2.1.301 screens, sped up where the title bar shows ⏩. ++, ↑, ⇥ insert ++r; ⏎ sends; /placeholders global add ++db: … saves your own.
View README on GitHub (opens in a new tab)
Install
Requires Claude Code 2.1.301+: run claude update first.
Install prompt- if Claude refuses, paste this into the chat
Execute these commands in this Claude Code session, one by one, show full output for each, do not skip any, do not summarize:
1. claude plugin marketplace add https://github.com/kochetkov-ma/claude-brewcode
2. claude plugin install brewmod-placeholders@claude-brewcode
After all commands succeed, run `/reload-plugins`. If `/reload-plugins` is unavailable, tell me to type `exit` and run `claude` again. Run the commands now.Then run /reload-plugins. Works on Team organizations.
Update, dev mode, requirements
Update prompt- if Claude refuses, paste this into the chat
Execute these commands in this Claude Code session, one by one, show full output for each, do not skip any, do not summarize:
1. claude plugin marketplace update claude-brewcode
2. claude plugin update brewmod-placeholders@claude-brewcode
After all commands succeed, run `/reload-plugins`. If `/reload-plugins` is unavailable, tell me to type `exit` and run `claude` again. Run the commands now.Update Claude Code first: claude update (2.1.301+). Dev mode, no install: claude --plugin-dir ./brewmod-placeholders. Needs node on the PATH (the bundled command hook runs as plain Node). Mods use the hooks module API, which is early access.
Quick start
| Want | Do |
|---|---|
| Add a block | ++r check the diff, then Enter. The block is sent as hidden context; your prompt stays as typed |
| Read a token’s text while typing | Put the caret on it (arrows, Home, End). The band shows up to 15 rows of its text, cut row and plan note included; move the caret off to return to the compact band (details) |
| Print the whole text | /placeholders show ++r, or ++r? alone and Enter twice (how). /placeholders list prints all. Full help: /placeholders help, or /placeholders plus a question in your own words |
| Make your own | /placeholders add ++ship: …. With no scope word the one dialog also asks Where (Global recommended, or Project); start with global or project to skip that question |
What Claude receives
you type ++r check the diff
Claude reads ++r check the diff <- your prompt, unchanged
+ hidden context (not shown in the transcript, not even with ctrl+o):
User typed `++r` — Two-phase review discipline is active for this turn:
[REVIEW DISCIPLINE: DOUBLE-CHECK]
Every significant change: multi-agent review ... (11 lines in all)
| Token | Normal mode | Plan mode |
|---|---|---|
++m | Manager mode is active: [ROLE: MANAGER], delegate, never code (29 lines) | Manager + Plan Mode is active: the same text + [ADDON: PLAN MODE]: stay read-only; the plan opens with the role and the full task graph (48 lines) |
++a | Architecture-first: delegate the design to expert agents before implementing | same text: ++a has no plan part |
++r | [REVIEW DISCIPLINE: DOUBLE-CHECK]: review, reproduce, fix confirmed findings only (11 lines) | same text: ++r has no plan part |
++rr | Anti-regression review: regression, project standard and functional correctness axes | same text: ++rr has no plan part |
+++ | Anti-drift cron is active: [ADDON: ANTI-DRIFT CRON], asks Claude to create one unique session cron for the current task now (9 lines) | plan the task anti-drift cron: the same text + [ADDON: ANTI-DRIFT CRON PLAN]: create no cron now, plan it as an execution step (13 lines) |
++rr + ++r | only ++rr is sent (one review per message) | same |
Every placeholder is sent in every mode. A placeholder with a plan part sends that part as an addition in plan mode only. Line counts are lines of the sent text, header line included: the numbers the band uses.
++r text as sent
User typed `++r` — Two-phase review discipline is active for this turn:
[REVIEW DISCIPLINE: DOUBLE-CHECK]
Every significant change: multi-agent review (matching reviewer expert, else
general-purpose), simplification pass first.
1) Review - finding = defect with path:line + evidence (failing command/input).
2) Double-check - reproduce each finding.
3) Fix - confirmed findings only.
Big review -> split by area, never one long pass. Brief each: goal + area +
acceptance, what's covered (don't re-litigate), who consumes the verdict;
return verdict first, then findings. ++m text as sent, normal and plan mode
User typed `++m` — Manager mode is active for this turn:
[ROLE: MANAGER]
Manage; never code/build/test/hand-debug: the main context is for orchestration.
Protocol: 1) TaskList; graph exists -> reuse it, else TaskCreate the full graph
before any work. 2) addBlockedBy/addBlocks only for real data-handoffs, else
parallel. 3) TaskUpdate owner, then launch. 4) Validate reports, integrate;
completed only when truly done; failure -> follow-up task + re-delegate. 5) all
code written -> final task: simplify, strip over-engineering.
No Task tools (CLAUDE_CODE_ENABLE_TODO_TOOLS=1 unset) -> same numbered graph
in the plan or .claude/features/<task>.md.
Sizing: one subagent = 1 deliverable, ~<=5 files, ~<=10 steps, ~<=20 min;
larger -> split. An hour-long agent = drift nobody can observe.
Scan all agents: best-matching expert per task, else general-purpose.
Spawn brief: six labeled fields. A subagent starts with an empty context, so a bare one-line task is never enough.
GOAL: task + why it exists - without the why it cannot rank the work.
ROLE: what it owns, must not touch - else two agents edit one file.
SCOPE: paths/commands in bounds and out - else the task widens.
CONTEXT: done, by whom, in parallel; only what this agent needs - else work is redone or overwritten.
CONSUMER: who or what uses the result next + the shape it must fit - else a correct result fails the next step.
DONE: acceptance, what counts as a finding, return (verdict first; evidence: command, result, unchecked; bounded; long output to a file it can write, path returned) - else it stops early or returns a dump.
Code/test briefs add: follow the closest well-built repo counterpart's
principles - additive to conventions/rules/docs, never instead.
Finish the whole job; decide without routine questions.Plan mode: the first line becomes User typed `++m` — Manager + Plan Mode is active for this turn:; the normal text stays, then a blank line and this addition:
[ADDON: PLAN MODE]
Stay read-only: no code, board/task-state writes, installation or
configuration. Read-only expert exploration is allowed.
Include in the plan (English, token economy):
- PREAMBLE: [ROLE: MANAGER] + the 5-step protocol restated verbatim as the
plan's opening section - this addon expires, so the plan carries the role
into implementation, no hook needed.
- STEP 0, stated literally: "Re-assume the MANAGER role. Call TaskList; if no
graph exists, create the ENTIRE TaskGraph now - TaskCreate for every node, or
the numbered checklist if task tools are absent - then delegate." On exit
this comes first: not code, not one task.
- The full TaskGraph: every task decomposed (subject, acceptance, owner
agent, bounded scope+acceptance per spawn), dependencies marked, parallel
branches explicit, critical path named.
Deliver the embedded role + graph, not implementation code. +++ text as sent, normal and plan mode
User typed `+++` — Anti-drift cron is active for this turn:
# [ADDON: ANTI-DRIFT CRON]
Now: announce and create one unique session cron for the current task, hourly unless the user's interval differs, using available native scheduling tools. Record its task-specific prompt, schedule ID, timezone, tick count and stop rule. If scheduling is unavailable, report the gap without claiming a schedule exists.
Each tick rereads the goal, task-specific methodology and anti-drift rules; collects active agent updates; reconciles task statuses, dependencies and remaining work; updates the task graph, keeping all unfinished entries and only the latest 10 completed entries, with older completion evidence preserved outside the active graph. It checks delivered work against the end goal, corrects drift, and names remaining acceptance criteria, problems, blockers and user questions.
Then it emits an extremely compact report: `HH:MM TZ · tick N · elapsed`; `🟢 completed`; `🔵 active / remaining / next`; `🔴 problems / blockers / questions`; `⚪ anti-drift verdict`. Omit empty rows; use only these circles. On task completion or cancellation, stop the cron and verify its removal.Plan mode: the first line becomes User typed `+++` in Plan mode — plan the task anti-drift cron:; the normal text stays, then a blank line and this addition:
# [ADDON: ANTI-DRIFT CRON PLAN]
Stay read-only in Plan mode: create no cron now. Plan it as an execution step instead: on exit, announce and create one unique session cron per top-level task, with its task-specific prompt, interval and stop rule recorded in that task's methodology. Your own placeholder can have a plan part too: see Examples.
Keys on macOS
| Hint on screen | Mac key | Glyph | Does |
|---|---|---|---|
tab | Tab | ⇥ | Inserts the selected typeahead name |
enter | Return | ⏎ | Sends the prompt. On ++r? alone it runs the query instead (how) |
esc | Esc | ⎋ | Closes the typeahead, back to typing |
↑ ↓ ← → | arrow keys | ↑↓←→ | Move in the typeahead (↑↓) or onto a token to read its text (←→) |
shift+tab | Shift + Tab | ⇧⇥ | Default mode (⏸ manual mode on): twice, accept edits then plan; or type /plan. The band does not change at the press, entering or leaving plan mode: it shows the mode of your last completed prompt, so plan mode adds: appears only after a prompt has run in plan mode. The next prompt is still sent with the new mode’s text. The effort toast comes from the other mod, brewmod-plan-effort |
ctrl+o | Control + O | ⌃O | Transcript view: your prompt and the answer only. The injected text is NOT there; use the band or /placeholders show |
Read the full text

Real Claude Code 2.1.301 screens. Caret on ++m; ? and ⏎ fill the show command, nothing is sent; ⏎ again prints the whole text.
| Where you look | It shows | How |
|---|---|---|
| The band above the prompt | Up to 15 rows of what Claude receives, cut row and plan note included | Put the caret on the token (arrows, Home, End); move it off to close |
The chat, /placeholders show ++m | The whole text, printed locally; nothing is sent to Claude | Type it, or type ++m? alone and press Enter twice (below) |
The chat, /placeholders list | Every placeholder with its text, normal and plan mode | Type it |
What ? does. A ? right after a token, with nothing else in the message, is a query, not text. The first Enter fills /placeholders show ++m in the box and sends nothing to Claude. Claude Code prefixes the notice: Prompt dropped by a hook: ++m? = /placeholders show ++m · not sent to Claude · press Enter to print it. That is the expected result: nothing was sent. The second Enter prints the text in the chat. In a longer message (check ++r?), ++r? is ordinary text: the ++r block is sent and the ? stays.
While the name menu is open (typing ++r offers ++rr), it caps the band, and a ? right after the token closes it. If the whole text then fits in 15 rows, the cut row ends with · type ? after ++r to see all. ++m never shows that hint: its 29 lines do not fit in 15 rows. Otherwise the band looks the same with or without the ?: the caret already shows the text.
Band with the caret on ++m (default mode, 120x40). Colours come from your Claude Code theme; the not sent now row is in the plan-mode colour.
++m · Claude receives these lines now:
User typed `++m` — Manager mode is active ...
... 12 more text rows (13 in all) ...
... 16 more lines · whole text: /placeholders show ++m or ++m? alone [Enter]
not sent now · plan mode adds 18 lines
close: move the caret off ++m · send as typed: ++/
| Looks like | Means | In the band above |
|---|---|---|
| Bold, placeholder blue (the theme’s suggestion colour) | A placeholder name; an unknown one is bold yellow (the theme’s warning colour) | ++m, ++zz |
| Bold, theme text colour (white on a dark theme, black on a light one) | Text Claude receives with this message | the User typed ... rows |
Bold, plan-mode colour (Claude Code’s planMode theme colour: teal on a dark theme, a darker teal on a light one) | The plan-mode addition Claude receives only in plan mode | the [ADDON: PLAN MODE] rows in plan mode |
| Plain, plan-mode colour | Marks that name plan mode | plan mode adds:, not sent now · plan mode adds 18 lines, plan +, · plan mode after placeholders 2 |
| Underlined, theme text colour | An action: what to type or do | /placeholders show ++m, ++m?, move the caret off ++m, ++/ |
| Plain, theme text colour | A key to press | [Enter] |
| Grey (dim) | Labels and notes; never sent. Text that is not sent (a skipped token, an escaped message) is grey too | close:, more:, ... 16 more lines, placeholders 2 |
The text under the head holds up to 15 rows, the cut row and the plan note included; the head and foot rows (and an also: row) come on top. The text rows are wrapped to the terminal width, so how many fit changes with it. K more lines counts the lines of the sent text left out (its header line and blank line included): ++m is 29 lines, 13 text rows shown at 120x40 (13 + the cut row + the plan note = 15). plan mode adds N lines counts the lines of the plan part; an empty plan part counts as none, so it gets no plan + tag and no note. In plan mode the band shows the plan header, the normal rows, a plan mode adds: row in the plan-mode colour and then [ADDON: PLAN MODE] with its rows in bold plan-mode colour. Outside plan mode a name with a plan part ends with the note not sent now · plan mode adds N lines in the plan-mode colour; +++ shows its own text there, sent and bold, with the note not sent now · plan mode adds 3 lines.
Hint rows, as drawn. A custom prefix replaces ++ in all of them.
| Row | Text |
|---|---|
| Cut row | ... 16 more lines · whole text: /placeholders show ++m or ++m? alone [Enter] |
| Cut row, narrow terminal or a build without the mod tools | ... 16 more lines · whole text: /placeholders show ++m |
Cut row, name menu open and ? would show it all | ... 5 more lines · type ? after ++r to see all |
| Foot with the caret on a token | close: move the caret off ++m · send as typed: ++/ |
| Foot with the caret on an unknown token | names: /placeholders list |
| Foot of the compact band | more: put the caret on ++r · send as typed: ++/ · help: /placeholders help |
| Foot of an escaped message | turn back on: delete ++/ |
| Other tokens while the caret is on one | also: ++a ++rr |
The or ++m? alone [Enter] part is the query from What ? does: [Enter] fills the show command. It appears only when the whole row fits the width. A narrower terminal shrinks the row in steps: first or ++m? alone [Enter] goes, then whole text:, then the count (... 16 more lines · ). The show command is never cut while it fits on its own. /placeholders and /placeholders help name the ++r? hand-off.
Examples
| Do | You type | What happens |
|---|---|---|
| Add | /placeholders add ++db: always use the staging DB | Claude drafts it and asks once: Save ++db as drafted? with Save as drafted (Recommended) or Change it (the question never names a layer; scope words count only outside the placeholder’s own text); with no scope word, the same dialog also asks Where to save ++db? with Global (Recommended) or Project; starting with global or project skips it. Reply: saved ++db (global): ~/.claude/placeholders/db.md |
| Add with a plan part | /placeholders add ++ship: run the tests; in plan mode also list the release steps | The same dialog adds Add this plan-mode part to ++ship? (Add it (Recommended) or No plan part). Saved as ship.md (run the tests) and ship.plan.md (also list the release steps, plan: add). A plan-mode part with no normal text to join is refused, so it is never sent in every mode: ++ship has no text yet: send text too (an inline normal text: a plan-mode part needs a normal text that is not inline) |
| Change | /placeholders make ++r shorter | Claude starts from the current text; the change stays in its layer (a plugin default -> asks where) |
| Remove | /placeholders remove ++db | Asks once: Remove it (Recommended) or Keep it; if the name is in both layers, it also asks where. Removing your override of a built-in brings the built-in back; plugin defaults are never removed (++r is built in and cannot be removed). Reply: removed ++db (global): ~/.claude/placeholders/db.md · ++db is no longer defined. When another layer keeps only a plan part for the name, the reply ends · its plan-mode part is now sent in every mode |
| Remove a plan part | /placeholders remove the plan part of ++ship | Asks Remove the plan-mode part of ++ship (global)?, then deletes ship.plan.md; ++ship keeps its normal text |
| Remove the normal text only | /placeholders remove the normal text of ++ship | Refused while ship.plan.md would be left alone, since that part would then be sent in every mode; nothing is deleted: removing only the normal text of ++ship would leave its plan-mode part alone, and that part would then be sent in every mode · remove both parts (part all), or change the normal text instead. If another layer still holds the normal text, only the file in the chosen layer goes |
| Show | /placeholders show ++r ++m, or ++r? alone + Enter | Prints the exact text with no Claude turn: outside plan mode normal: then plan mode adds:; in plan mode one block normal + plan mode part: as sent. An inline placeholder that does not expand shows stays as typed; an empty body silences the token, in plan mode too. For ++r? see Read the full text |
| List | /placeholders list | Prints every placeholder with its text as sent, normal and plan mode, with no Claude turn |
| Escape | ++/ what does ++r do? | Sent exactly as typed: no block, ++/ stays in the text |
| Scope | /placeholders project add ++lint: run npm run lint first | Reply: saved ++lint (project): .claude/placeholders/lint.md; the project copy wins over global |
Commands
| Command | What it does |
|---|---|
/placeholders (also status) | One row per name with layer and tags (plan + for a plan part with text, inline), plus hints for reading texts (caret, /placeholders show), escape and scope |
/placeholders show ++<name> ..., list, help | Print the exact text sent (list = all, normal and plan), or the full help, with no Claude turn |
/placeholders <anything else> | Claude answers, or drafts, asks once and saves; any language. A first word global or project picks the layer; without it your words decide, else one question (Global first) |
The status view explains the plan + tag, and /placeholders help describes the two file kinds, in these lines (default prefix):
`plan +`: its `<name>.plan.md` adds text in Plan mode; `<name>.md` is sent in every mode
Plan mode: `<name>.md` is sent in every mode; an optional `<name>.plan.md` (`plan: add`) adds its text in Plan mode (`++m`, `+++`), marked `plan +`. One review per message: `++rr` wins over `++r`.
Files: `<name>.md` = optional front matter (description, insert: context|inline, order, group, priority, header) + the text; `<name>.plan.md` = its Plan mode addition. Edit by hand any time; the next prompt reads it.
Prompt box
| State | What you see |
|---|---|
| Highlight, typeahead | Terminal UI only. A known token is underlined; after the prefix, matching names appear, Tab inserts one. After Tab or Enter on a name row, a history recall (arrow keys) or an undo, the band shows at once; the underline in the box appears with the next key (an engine limit). The one option, prefix (default ++, 2-8 punctuation characters), is set in /config |
| Compact band | Header placeholders 3 in grey ( · plan mode is appended in the plan-mode colour in plan mode), then one row per token: ++r <description> (name in bold blue, description grey), with · Claude receives these lines now: and the text under it when the text is drawn. Rows past the space fold into ... K more placeholders. Foot (actions underlined): more: put the caret on ++r · send as typed: ++/ · help: /placeholders help. plan +, in the plan-mode colour, marks a name with a plan part that has text; a skipped token says why, for example (not sent: ++rr wins) |
| Caret on a token | The band shown in Read the full text. A name with a plan part that has text ends with not sent now · plan mode adds N lines in the plan-mode colour; other tokens sit on one also: ++m ++a row |
| Rows from other mods | Rows another mod draws above the prompt, for example the plan-mode row of brewmod-plan-effort (same plan-mode colour), stay visible above the band; the band fits into the rows that are left, in the default and the fullscreen view alike, whichever of the two mods loads first: head, text, cut row and foot all stay on screen |
| Escaped | ++/ in the message: header ++/ placeholders off: this message is sent exactly as typed and every token (not sent: ++/ in this message) (markers and names bold blue, reasons grey), foot turn back on: delete ++/ |
| Unknown | An unknown ++zz shows bold yellow with unknown placeholder grey; while the caret is on it the foot reads names: /placeholders list, otherwise the compact foot. On submit a toast names it and the prompt is sent unchanged |
Your own files
| File | Means |
|---|---|
<name>.md in ~/.claude/placeholders/ (global) or .claude/placeholders/ (project, wins) | The text, sent in every mode; the file name is the token name; front matter is optional |
<name>.plan.md (front matter plan: add), optional | Added after <name>.md in plan mode only. Example: ship.md = run the tests, ship.plan.md = also list the release steps |
Old files keep working, with one status line each (/placeholders status and a toast):
| Old file | What happens now | Status line |
|---|---|---|
<name>.md with when: plan, when: not-plan or any value but always | Sent in every mode | <layer>/<name>.md: when: plan is gone; sent in every mode |
<name>.plan.md without plan: add | Its text is added in plan mode | <layer>/<name>.plan.md: no plan: add; its text is added in plan mode |
A brewtools planmode / cron-plan override | Its text is added in plan mode; it no longer replaces the normal text, so a full-text file repeats the role: trim it | <dir>/planmode.md: brewtools file: its text is added in plan mode; to clear this, move it to placeholders/m.plan.md with plan: add (<dir> = the real brewtools prompts directory of that file; <name> = the placeholder it extends) |
<name>.md with a plan: key | The key is ignored | <layer>/<name>.md: plan: is for <name>.plan.md; ignored |
<name>.plan.md with no <name>.md in any layer | Sent in every mode | <layer>/<name>.plan.md: no <name>.md; sent in every mode |
Two files that resolve to the same placeholder name and part (through a front matter name:) do not both count: the first one is sent, and the status line of the other reads <layer>/<file>.md: shadowed by <layer>/<file>.md; not sent.
Layers, highest wins file by file: project > its brewtools override > global > its brewtools override > plugin defaults. Keys and verification tables: definition files, verified.
With brewtools
brewtools 6.8.0+ ships no codeword hook, so this mod is the only provider of ++m, ++a, ++r, ++rr and +++. brewtools 6.7.x also injects them, so each block appears twice: use 6.8.0+. Override files under .claude/brewtools/manager/prompts/ and <config>/manager/prompts/ are read through the legacy key, whatever the brewtools version. To silence a token, give your override an empty body (it stays silent in plan mode too). The brewtools-side notes live in Codewords.
Definition files and layers
One Markdown file per placeholder. The file name is the placeholder name. Front matter is optional, and a file inherits unset keys from the placeholder it overrides (plan is the exception: it is per file and never inherited).
| Key | Values | Default | Effect |
|---|---|---|---|
name | 1-32 letters, digits or _, or ASCII punctuation | file name | Token name, case-insensitive |
description | text | none | Shown in the typeahead and band |
insert | context, inline | context | context adds hidden context and keeps the token. inline replaces the token |
plan | add | none | Marks <name>.plan.md as an addition: its body is appended to the normal text of the same name in plan mode. A .plan.md without it is still added, with a warning; on a <name>.md the key is ignored, with a warning |
order | integer | 100 | Blocks join from the lowest order up |
group | text | none | Placeholders in one group exclude each other; the loser shows not sent: ++rr wins |
priority | integer | 0 | In a group, the highest wins |
header | text | none | First line of the block. {token} becomes the prefix plus the lower-case name. A plan part without a header keeps the normal header |
legacy | text | none | Name of the brewtools override file it reads |
- Body. With fenced blocks, only the fenced text counts. Otherwise the trimmed text after the front matter.
- Empty body. Suppresses the token. Keys are inherited from the layer below, the body is not.
- Plan part.
<name>.plan.mdis the plan part of<name>, with or without front matter. In plan mode its body follows the normal text after a blank line, under the plan part’s header when it has one. An empty plan part adds nothing: noplan +tag and noplan mode addsnote. A plan part with no<name>.mdin any layer is sent in every mode, with a warning. - Cap. Blocks are sorted by
order, joined with a---line and cut at 9000 characters (...[truncated]).
A plan part that adds to a normal text:
~/.claude/placeholders/ship.md
---
description: "Run the tests; in plan mode also list the release steps"
---
run the tests
~/.claude/placeholders/ship.plan.md
---
description: "Run the tests; in plan mode also list the release steps"
plan: add
---
also list the release steps++ship sends run the tests in normal modes. In plan mode it sends run the tests, a blank line, then also list the release steps. Without plan: add the text is still added, and the status view warns.
The highest layer wins, file by file:
| Layer | Location |
|---|---|
| Project | <launch dir>/.claude/placeholders/<name>.md |
| Project, brewtools override | <launch dir>/.claude/brewtools/manager/prompts/<legacy>.md |
| Global | <config>/placeholders/<name>.md |
| Global, brewtools override | <config>/manager/prompts/<legacy>.md |
| Plugin | placeholders/ inside the mod |
<config> is CLAUDE_CONFIG_DIR, or ~/.claude. Project layers come from the launch directory, not the git root.
Technical details
Team organizations. Claude Code’s builtin security layer bypasses a mod’s classic.* hooks there. A bundled command hook, hooks/inject.mjs, adds the blocks instead. Verified on a Team-org and a Max profile. Enterprise was not run.
- Load. Unreadable or invalid definition files are skipped, with a toast and a line in the status view.
- Match. A name must stand alone:
++rris not++r.++/or++\anywhere in a message turns every placeholder off for that message. - Inject. The module expands only inline placeholders and names unknown tokens in a toast. The command hook builds the context blocks, adds plan parts when the permission mode is plan and skips subagent deliveries.
- Show.
/placeholders show,listandhelpare answered by the module with no Claude turn;++r?alone in a prompt hands off toshowthe same way. The text shown is a port of the hook’s assembly, checked against it byte by byte. - Mod tools. Free-text
/placeholdersrequests hand off to Claude withlist_placeholders,save_placeholder,remove_placeholderandplaceholders_help. Saving refuses symlinks; removing never touches plugin defaults or legacy brewtools files. Each save or remove asks once through one dialog; no permission prompt follows. - Plan mode. The hook records the permission mode in
.state/mode-<session_id>.jsonin the plugin root. There is no live plan-mode signal for the band: it learns plan mode from your first prompt in it. - Fail open. Any error returns an empty result, so a fault never blocks a prompt.
- Plugin files deleted (for example a plugin update during a running session). The band reads
plugin files removed (updated?) · run /reload-pluginsand one toast per session says the same. Tokens are not marked unknown and inline placeholders keep expanding, but context blocks cannot be added until/reload-plugins.
Verified
Live runs drive the terminal UI in tmux (default and fullscreen, 80x24 to 200x60) or use claude -p, one turn per case, brewtools disabled. Injections are the hook_additional_context rows of the session transcript.
| Check | Result |
|---|---|
node tests/inject-parity.mjs: frozen texts, layers, state file, fail-open | 316 checks pass: 101 golden, 98 sent.ts golden, 37 layer, 26 differential, 25 plan-part, 14 escape, 10 state, 3 jobs cap, 2 fail-open |
Unit tests (claude plugin test) | brewmod-placeholders 443 pass, 0 fail, 17 files; brewmod-plan-effort 71 pass, 0 fail, 1 file. tsc and claude plugin validate --strict of both mods, check-defaults and the mode test all exit 0 |
Full pre-release live check, run before the review fixes (build fingerprint 8d91c3c7, Claude Code 2.1.301), installed load order with brewmod-plan-effort loaded, terminal UI in default and fullscreen mode, 80x24 to 200x60: band colours and hint rows, caret focus, band right after Tab or Enter on a typeahead row, history recall and undo, ++r? query and its fill, compact band, cut rows, plan-mode ++m, +++ in every mode, Shift+Tab, ++/ escape, inline, unknown token, status, help, list, show, add and remove with global first word | 225 of 225 cases PASS: 217 terminal UI cases and 8 claude -p cases |
Live subset after the review fixes (build fingerprint 6c4dfa44, Claude Code 2.1.301), terminal UI, no claude -p cases: ++m in default mode (88x40), +++ in default mode (120x40) and plan-mode ++m (120x40), each in the default and the fullscreen view; /placeholders status, plan tags and show m; the caret and whole-text line of status (default and fullscreen, 120x40) | 11 of 11 PASS. The 225 above is the full run before the fixes |
Same check, the claude -p received-context e2e cases, mod tools denied so the answer comes from the received context: ++r, ++/ ++r, plan-mode ++m, plan-mode ++m with an empty global m.md, +++ in default mode, +++ in plan mode, an inline placeholder (7 cases plus the check that the tools are denied) | PASS, counted apart from the terminal UI cases: Claude quotes the r block, receives no block when escaped, quotes [ADDON: PLAN MODE], receives nothing for the empty m.md, quotes the [ADDON: ANTI-DRIFT CRON] text without the plan addon in default mode and with [ADDON: ANTI-DRIFT CRON PLAN] in plan mode, and gets the inline body in place of the token |
| Both mods together (brewmod-placeholders and brewmod-plan-effort), default and fullscreen, 80x24 and 120x40 | PASS in the installed load order (inside the 225 cases) and, with brewmod-plan-effort loading first, on the colour, hint-row and +++ subset: the plan-effort row plan mode · effort xhigh for this mode · change: /plan-effort <level> stays above the placeholders band, and the band keeps its head, text, cut row and foot. In that subset 12 cases first failed on wrong expectations in the test cases (the hooks were unchanged); after the correction the 12 pass, 12 of 12 |
Band colours, 22 colour cases (dark theme and theme: "light"): caret on ++m in default and plan mode, compact band, escaped message, unknown token | 22 of 22 PASS. Checked on the terminal’s colour codes: token names bold blue, sent rows bold in the text colour, plan-mode rows (plan mode adds:, not sent now · plan mode adds N lines, plan +, · plan mode) in the plan-mode colour 38;5;73 on a dark theme (on the light theme the not sent now note was captured in 38;5;30), the sent plan addition bold in that colour, actions underlined, labels grey, [Enter] plain. A terminal may split a coloured run per word, so a row can carry the colour code once per word |
/placeholders dialogs (S4), terminal UI, Haiku, part of the 225 | Add (global and project), add with a plan part (ship.md + ship.plan.md), remove, remove the plan part, remove from the project layer when the name is in both layers (the global ++two is served now), refusal to remove built-in ++r; each asks once and writes without a permission prompt |
Team-org and Max profiles, --plugin-dir and marketplace copies, Sonnet: ++r (2.1.300 run) | 1 block, 571 characters |
Custom prefix @@, Max, Sonnet: @@r ++r (2.1.300 run) | Only the @@r block |
| Latency, p50 (2.1.300 run): typing per keystroke (mod minus control, drafts of 0 / 4,000 / 19,700 chars) and band repaint after a token keystroke | Typing -2.6 / +6.6 / +2.1 ms, token keystrokes +2.4 / +6.6 / +5.6 ms, noise as large as the deltas. Repaint 19 to 21 ms at p50, 44 to 61 ms at p99 |
Not covered live: the light theme as a rendered image (it is checked through its colour codes and computed contrast), the 9000-character cap, the ... K more placeholders row, fullscreen hover and click, the desktop app, VS Code, subagents and other models. Unit tests cover prefix, layers and cap.
Known limits
The band shows at once after Tab or Enter on a typeahead row, a history recall and an undo; the underline in the prompt box appears with the next key (engine limit). Drafts over 20,000 characters get no highlight or band, but expansion on submit still works.
Related
brewcode mods
Plan-mode effort
Project page
GitHub source
Update: /brewtools:plugin-update - FAQ