opus mcp human-invoked

Quick reference

FieldValue
Command/brewcode:semble-setup [status|install|upgrade|enable|disable|uninstall|purge|reindex|optimize|resume]
Argumentsa mode keyword, or free text in RU/EN
No-arg defaultalways status — see the exception note below
Modelopus
ToolsRead, Bash, AskUserQuestion
MCP serversemble_code, registered at user scope, pin semble[mcp]==0.5.4

The one skill that never defaults to install

Every other -setup skill treats a bare invocation as status when installed and install when not. semble-setup breaks that rule on purpose: install runs brew install uv, a machine-level mutation outside the project. A bare /brewcode:semble-setup must never be able to trigger it, so empty input always resolves to read-only status. To install, type the verb.

What it does

semble-setup is the lifecycle router for semble_code — a semantic code-search MCP server that gives Claude two tools: mcp__semble_code__search (find code by intent) and mcp__semble_code__find_related (neighbors of a known location). The skill never edits code itself; it installs the prerequisite, registers the MCP server, wires a project rule and hooks, and migrates project agents so they can call the tools.

It always prints the current state before changing anything. Every mutation goes through a script under scripts/ — the skill only decides which one to run and reports the result.

Semble has no Homebrew formula of its own. The skill installs uv via brew (a machine-level step gated by an explicit confirmation) and then runs the pinned uvx --from 'semble[mcp]==0.5.4' semble --content <SEMBLE_CONTENT_ARGS> — never a floating version. See Corpus below for the actual token list.

When to use

SituationCommand
First time on a project, nothing wired yet/brewcode:semble-setup install
Just reloaded Claude Code after install/brewcode:semble-setup resume
Check current state, no changes/brewcode:semble-setup (empty input)
Something looks off, want a diagnostic/brewcode:semble-setup optimize
A newer semble[mcp] pin is approved/brewcode:semble-setup upgrade
Turn search off without deleting anything/brewcode:semble-setup disable
One repo’s index looks stale/brewcode:semble-setup reindex
Free-text works too, RU or EN/brewcode:semble-setup переиндексируй
Remove the wiring, keep or drop pieces/brewcode:semble-setup uninstall
Wipe everything, including the cache/brewcode:semble-setup purge

Example

/brewcode:semble-setup install

install probes uv, asks once before the machine-level brew install uv, registers the MCP server, then wires everything that does not need a live server — the rule, .sembleignore, the CLAUDE.md block, the five hooks, permissions and agent migration — before stopping at the reload checkpoint:

# Semble install

## Detection
project: /abs/project/root
prompt: "install"
mode: install  (reason: matched keyword "install")
scope: user

## Before
cli:      uv absent | uvx absent | semble pin 0.5.4 (uvx-ephemeral) | claude 2.1.226
mcp:      absent @ user  [unknown]
cache:    /Users/me/Library/Caches/semble-code | repo — | 0 B | absent | docs root reserved: no
guidance: rule absent | CLAUDE.md absent | hooks 0/6 wired | permissions no
agents:   4 total | 2 inherit | 0 patched | 2 need patch | 0 conflict | 0 skipped
state:    phase=absent enabled=null completed=[]

## Actions
changed:   brew install uv, semble_code registered @ user, docs cache root reserved, rule installed, .sembleignore installed, CLAUDE.md block installed, 5 hooks wired, permissions merged, 2 agents patched
unchanged: none
skipped:   none
failed:    none

## Verification
commands: bash scripts/semble-install.sh all --yes --json; bash scripts/semble-cache.sh reserve-docs --json; bash scripts/semble-mcp.sh add --scope user --yes --json; bash scripts/semble-guidance.sh install --part all --json; bash scripts/semble-agents.sh apply --scope project --yes --json
smoke:    skipped (MCP not yet live in this session)
corpus:   code docs config | repo <hash8> | unknown
uncovered: .json/.json5/.csv/.tsv/.psv (no content type reaches them), .mdx/.txt (absent from _EXTENSION_TO_LANGUAGE) -> use rg

## Current Status
reload required — semble_code registered, wiring complete, session has not restarted

## Next Step
Reload Claude Code (new session), then run: /brewcode:semble-setup resume
Checkpoint: /abs/project/root/.claude/semble/state.json

The /6 in guidance: counts settings registrations, not hook files - five files wire six rows, so 5 hooks wired under Actions and hooks 0/6 wired under Before both describe the same install correctly.

After a fresh session, resume re-checks status, runs the smoke query (the one step that actually needed a live server), and re-applies the same wiring idempotently so any drift self-repairs:

/brewcode:semble-setup resume
## Actions
changed:   phase -> verifying, smoke query ok, phase -> ready
unchanged: rule, .sembleignore, CLAUDE.md block, 5 hooks, permissions, 2 agents (already wired by install)
skipped:   none
failed:    none

## Verification
commands: bash scripts/semble-state.sh phase verifying --json; bash scripts/semble-project.sh smoke --json; bash scripts/semble-guidance.sh install --part all --json; bash scripts/semble-agents.sh apply --scope project --yes --json; bash scripts/semble-state.sh phase ready --json
smoke:    how sessions are persisted -> 5 results, top = src/store/session.ts:41-58 score 0.83
corpus:   code docs config | repo <hash8> | unknown
uncovered: .json/.json5/.csv/.tsv/.psv (no content type reaches them), .mdx/.txt (absent from _EXTENSION_TO_LANGUAGE) -> use rg

## Current Status
ready — MCP verified, wiring confirmed, agents migrated

## Next Step
none

Subsequent searches are sub-second and require the absolute repo path:

{"query": "how sessions are persisted", "repo": "/abs/project/root", "top_k": 5}
{"results": [
  {"file_path": "src/store/session.ts", "start_line": 41, "end_line": 58, "score": 0.83}
]}

Workflow

  1. Status first, every mode

    Runs semble-status.sh —section all —json — read-only, writes nothing under the project, the cache root or ~/.claude/settings.json. Prints the pre-mutation Before snapshot.

  2. Resolve the mode

    Applies the 5-step routing algorithm to $ARGUMENTS: empty input is always status, never a mutation; a pending reload routes straight to resume; otherwise the highest count of matched keywords wins. States the resolved mode and the reason before acting.

  3. Install — prerequisite gate

    semble-install.sh <check|uv|coreutils|semble|all>all runs check -> uv -> coreutils -> semble. Probes without —yes first. uv is a hard gate: missing, it asks one AskUserQuestion before running brew install uv — a machine-level mutation outside the project, never silent. coreutils is a soft, optional offer for the same question — see Technical details below.

  4. Install — register and wire

    Reserves the separate docs cache root, registers semble_code at user scope, then wires everything that does not need a live MCP server — the semble-first rule, .sembleignore, the CLAUDE.md block, the five hooks, permissions and project agent migration — before writing a reload checkpoint and stopping. Only the smoke query and phase -> ready wait for the new session.

  5. Resume — verify and self-repair

    Re-checks status; if the MCP state is not correct, falls back into install instead of verifying. Otherwise runs the smoke query (up to 600s on a cold embedding-model download) and an idempotent re-run of the same rule/hooks/permissions/agent wiring — self-repairing any drift, not repeating work install already did — then closes the state at phase: ready.

  6. Other modes — one delegation each

    enable/disable flip a flag, deleting nothing. reindex and purge run dry first (exit 4), show the exact paths, then require one confirmation before the destructive pass. optimize only reads. upgrade compares the recorded pin against 0.5.4 and no-ops if identical.

  7. Report

    Re-runs status after the last write and prints six fixed sections: Detection, Before, Actions, Verification, Current Status, Next Step — including every command actually run and an uncovered: line on every invocation.

Technical details

Modes

ModeEffectMutates
statusfull report: prereqs, MCP, cache, guidance, agents, coverage, state — the default on empty inputno
installinstall uv, register semble_code at user scope, wire the rule, .sembleignore, CLAUDE.md, hooks, permissions and agent migration, checkpoint for reloadyes
upgradecompare the recorded pin against 0.5.4, re-register if different, then unconditionally re-sync the rule, .sembleignore, hooks and permissions — the only path that moves the artifact version stampyes
enableturn back on: verify, warm, phase -> readyyes
disableenabled=false — hooks go silent, nothing deletedyes
uninstallfour flavours: integration / mcp / cli / purgeyes
purgeeverything, including the code cache root — typed confirmation requiredyes
reindexextra: stage a rebuild in a private cache root, verify it with a warm query, delete the live index only after the staged build proves itself, then swap the staged copy inyes
optimizeextra: read-only audit fan-out with concrete recommendations — reads current cache size, staleness and entry count via semble-cache.sh info --json (figures vary by machine/repo, no fixed number published)no
resumeextra: after reload — smoke query, then an idempotent self-repair re-run of the same wiring, phase -> readyyes
warmfree-text intent (“warm”, “прогрей”) — pre-builds the index, deletes nothingyes (cache write only)

The first seven rows are the canonical vocabulary shared by every -setup skill. reindex, optimize and resume are semble-specific extras with no equivalent elsewhere. The retired verbs setup, update and remove are gone; free-text intent in RU or EN still routes to the right mode.

Prerequisites

PackageRequired?If declined or impossible
uv / uvx (brew install uv)required — install asks first, stops on declinemanual fallback curl -LsSf https://astral.sh/uv/install.sh | sh is printed, never run
coreutils (brew install coreutils -> gtimeout)optional — offered only when no timeout/gtimeout binary exists and brew doesnothing breaks: sc_timeout keeps its pure-bash watchdog, every shell-out stays bounded either way

semble-install.sh takes one of check \| uv \| coreutils \| semble \| allall runs them in that order and is what install calls.

What install installs

SurfaceLocation
MCP server~/.claude.json .mcpServers.semble_code, user scope — -s user is mandatory, the CLI default is local. Every mutation is rollback-safe: a failed add/repair restores the file it was about to overwrite instead of leaving it half-written
Commanduvx --from 'semble[mcp]==0.5.4' semble --content <SEMBLE_CONTENT_ARGS> (Corpus below has the actual token list)
Code cache rootabsolute SEMBLE_CACHE_LOCATION: macOS ~/Library/Caches/semble-code / Linux ${XDG_CACHE_HOME:-~/.cache}/semble-code
Docs cache rootsame path with a semble-docs leaf — created empty, reserved, never registered
State<repo>/.claude/semble/state.json — project root resolved by the canonical recipe: CLAUDE_PROJECT_DIR -> git rev-parse --show-toplevel -> an upward walk for .git/.claude -> PWD
Rule<repo>/.claude/rules/semble-first.md
Ignore file<repo>/.sembleignore — keeps generated/vendored trees out of the corpus; managed like the rule (user edits reported, never clobbered) and gets an appended, commented-out block of measured candidates (duplicate trees, disproportionately heavy directories) — nothing is excluded until the user uncomments a line
CLAUDE.mda marked <!-- BEGIN brewcode:semble --> block
Hooksfive files in .claude/hooks/semble-session.mjs (SessionStart), semble-prefetch.mjs (UserPromptSubmit), semble-stats.mjs (PostToolUse + PostToolUseFailure, stats matcher), semble-reminder.mjs (PreToolUse Bash|Grep), semble-subagent.mjs (SubagentStart, no matcher key — matches every agent type) — six settings.json registrations total, each "timeout": 5 (seconds). Status reports hooks <n>/6 wired — never 6 files. semble-explore.mjs is retired for good, replaced by semble-subagent.mjs: install/upgrade deletes the file and replaces its settings row, never leaves both. See Retirement of the advisory pair and Reminder mechanic below
Agentsproject .claude/agents/**/*.md get the two tool names added to tools:; global agents are never touched. apply records, per file, exactly which tool names it added; --revert strips only those recorded names and leaves any user-authored tool name in the same list untouched — a file with no record declines to revert rather than guessing

CLAUDE.md conflict scan

install reconciles the root CLAUDE.md (--part claudemd) right after it installs the <!-- BEGIN brewcode:semble --> block. It scans the rest of the file (the skill’s own marked block is never a candidate) for lines that assert a competing search doctrine, against a two-tier pattern set:

TierMatchResult
DENYexplicit contradiction - grep/glob called a no-op/removed/unavailable, semble/semantic search called broken/unreliable/disabled, or “never/dont use semble”line removed
FIRSTcompeting claim - “search via <tool>”, “always use <tool> for all/any/every/code”, “<tool>-first”, “<tool> before semble”, or “all searches through <tool>line removed, unless KEEP-exempt
KEEP (exempt)scopes the tool to exact/literal/identifier/regex/path/filename/exhaustive/enumeration/verify/count - the skill’s own correct guidancenever touched, not even reported
neithermentions a search tool without matching DENY or FIRSTleft untouched, reported skipped for manual review

The KEEP exemption applies only to the FIRST tier — a DENY match is always removed regardless of scoping words in the same line.

The scan reads the root CLAUDE.md only and never walks into a nested one, and a search-titled heading that a removal leaves empty is removed along with it.

Finding a contradiction: backs up the whole file (sc_backup), strips the offending lines, reports changed with the exact line numbers and text removed. SEMBLE_DRY_RUN=1 prints what it would remove without touching the file. No contradiction found: reports unchanged.

Built on a hypothesis the data refuted

The motivating idea was that a contradicting CLAUDE.md line suppresses conversion to semble. A controlled A/B tested it directly: sessions with the contradiction present converted 5/14 = 36%, sessions with it removed converted 4/18 = 22% — the “clean” arm was nominally worse (Fisher exact two-sided p = 0.45, n = 32). Removing false statements about the toolchain is still correct on its own merits, but it is not shown to change tool choice — treat this as documentation hygiene, not a conversion fix.

Retirement of the advisory pair

The old rationale for retiring the advisory pair — “0/18 and 0/11 conversion, delivery independently confirmed” — was wrong on the first number:

ClaimFact
Delivery channel was brokenNever was. On CC 2.1.226 PreToolUse and SubagentStart both accept additionalContext in the zod union and reach the model over the same unfiltered path
0/18 conversionMeasured nothing. The reminder hook fired zero times across those 18 sessions: its own gate (the then-current isExactIntent, biased to silence — any doubt returned true) suppressed 74 of 113 evaluations, 37 were disabled, 2 throttled. Lifetime rate was 14 nudges / 2718 evaluations = 0.52%. The denominator 18 counted trial sessions, not deliveries
0/11 conversionReal — but of one agent type (Explore, the one semble-explore.mjs was pinned to via agent_type === 'Explore') and of text that undercut itself with “this is a reminder, not a block”. The replacement, semble-subagent.mjs, carries no matcher key at all — which is what matches every agent type — and was verified live on Explore, Plan and general-purpose

Reminder mechanic

The 600-second throttle is gone. semble-reminder.mjs fires on every Nth eligible search call — N = 1 by default (was 5), configurable via reminderEvery in .claude/semble/state.json. The counter lives in .claude/semble/reminder.json, written atomically, reset on corruption; the old .claude/semble/.reminder-ts marker is retired for good.

The counter is project-global, not per-session

It still survives across sessions — but at the new default N = 1 it cannot suppress anything, every eligible call fires. The counter only matters once a user raises reminderEvery above 1; at that point “every Nth search” is a property of the project, not the session, and a fresh session inherits whatever phase is left over.

The injected text shrank alongside the cadence change — semble: wrong tool. mcp__semble_code__search repo="<cwd>" first. (exact/-l stays rg), and (first call builds the index; exact/-l stays rg) while the index is not ready (phase !== 'ready') — 36 tokens (cl100k_base, 42 cold), down from 65, by dropping the params the semble-first rule and the subagent brief already carry. The four-word grep clause is deliberate insurance: the gate is a heuristic, so a bare “wrong tool” would push the model off rg on the calls the gate misjudges.

The gate itself moved from “let most things through” to high-specificity — it now suppresses far more than the 5.2.3 gate did:

SuppressorDetail
Single-word patternone token = an identifier lookup, rg is right
Short patternunder 8 characters
Enumeration/literal flags-l/-c/-o/--files, -F/-w
Filename toolsany find/bfs invocation
Path-shapedpattern containing /
Filename-shaped tokenchecked per token, not just the whole pattern
Regex metacharactersany of ^ $ * + ? ( ) [ ] { } or a backslash/pipe
ALL-CAPSa shout/banner string
Enumeration words”every”, “all”, “how many”, “list the”
Piped binarya binary reading another command’s output, e.g. strings x piped into grep y
Aggregator pipepipes into wc/sort/uniq/cut/awk
semble mentionedthe command already names the tool
Code-literal punctuation# : = < > backtick ~ @ % suppress unconditionally
Identifier shapessnake_case, intra-word hyphen, camelCase suppress ONLY when no token is a plain lowercase word — rateLimit config and max_retries setting still fire

Replayed on the same historical stream of 2543 recorded search calls, three gates side by side:

GateEligibleFired
Old (pre-5.2.3)23032
5.2.31024204
Current1414

Measured delivery and cost

CC 2.1.226, real headless sessions, joined on tool_use_id between the hook’s own telemetry record and the hook_additional_context transcript attachment.

Subagent delivery: proven, not merely inferred

A subagent caught its own injection in-band and reported it back — joined by tool_use_id, telemetry tagged agent:"sub". Subagent transcripts on disk store only SubagentStart attachments (92 across 852 files, zero PreToolUse) — that is a storage gap in what gets written to <session-id>/subagents/agent-<id>.jsonl, not a delivery gap. Any earlier claim that PreToolUse injection inside a subagent is unobservable is now known wrong.

FindingNumber
SubagentStart delivery8/8 with the registration installed, 0/6 with it removed (negative control); 36/36 over 6 agent types in a 525-transcript corpus
Gate precision (hand-labelled, 80 real commands)of the 40 the 5.2.3 gate fired on but the current gate suppresses: 37 exact/exhaustive (rg is right), 1 behavioural, 2 ambiguous — ~95% of the old gate’s injections were wrong advice
False negatives in the stricter gate0 of the 40 commands both gates suppress were behavioural
Reminder fire rate, 7 sessions, TypeScript fixture0 nudges / 59 Bash calls
Reminder injection cost36 tokens, 42 cold (was 65) — PreToolUse context is not deduplicated, every injection paid in full

Conversion after a nudge is undefined (0/0) — with zero fires there is nothing to report. The 59 is every Bash tool call in the runs, not 59 searches the gate judged: the matcher is Bash|Grep, so a gate row is written per Bash call whatever it contains. 13 held no search binary (cd, ls -R, cat -n, sed -n, wc), 13 were find, 33 were rg/grep on a single-token identifier, and zero were the multi-word behaviour phrase the gate fires on. “0 fires” is arithmetically true and is evidence neither of a broken hook nor of a valuable one. The rule of three puts the 95% upper bound on the fire rate over that traffic mix at 5.1%; closing it would take roughly 680 comparable calls (~80 sessions).

Two published figures are withdrawn

“Control conversion without a nudge was 8/59” is withdrawn. It is unreproducible: re-derived with the scoring script’s own rule — a semble call within the next 3 tool uses after a non-fired gate — the value is 0/32 in one arm and 0/27 in the other. The 8 was the count of mcp__semble_code__search calls in one arm, over a denominator it never shared. No corrected control figure replaces it, because no arm of the design lacked a semble instruction.

“90.6% of search traffic is subagent traffic (3084 sub / 321 main)” is withdrawn. It came from agentOf() in semble-stats.mjs, which mislabels the main thread of an --agent session as sub — a fresh 7-session run tagged all 126 stats records sub, including known main-thread calls. Historical telemetry cannot be corrected retroactively and there is no adjusted percentage to print.

SubagentStart is proven to deliver, not to route

The registration’s text reached 8 of 8 subagents when installed and 0 of 6 when removed — a clean negative control that the registration is what puts the text into a subagent’s context, corroborated 36/36 across a 525-transcript corpus over 6 agent types. It is not proven to change tool choice: every spawn prompt in both arms already carried a literal start with ONE mcp__semble_code__search instruction, so first-tool semble was 14/14 with and without the hook. The brief’s causal effect on tool choice is untested. Treat the PreToolUse reminder as low-cost insurance against a bad rg call already in flight; it has no measured adoption effect either.

Parent and subagent contexts are disjoint: the SubagentStart context is visible only inside the subagent and is written only to <session-id>/subagents/agent-<id>.jsonl, never to the parent transcript.

semble-status.sh reports conversion per source (session / reminder / subagent / prefetch), not one pooled denominator — pooling let 126 SessionStart firings drown every other channel. Each slot carries its own measure (injected-path-opened for prefetch, semble-call-after for the rest); a channel that never fired prints 0/0 rather than vanishing — 0/0 is “never delivered”, 0/N is “delivered and ignored”, and only the second is evidence about the advice.

Skipped is not failed, and a partial verdict is honest

A skipped operation exits RC 3 with "status":"skipped" in its JSON — distinct from a real failure (RC 1). SEMBLE_NO_NETWORK=1, SEMBLE_DRY_RUN=1 or a missing uvx skip the smoke query, warm, enable and reindex’s staged rebuild the same way: nothing broke, nothing was proven. resume/enable leave phase at verifying rather than ready on a skipped warm, and status reports the gap as partial - warm and smoke not recorded in state.completed, naming exactly the missing member(s) of the pair.

The verdict logic itself follows one rule: a guidance section that errored always downgrades the overall verdict from ready to partial, whatever the cause — a missing unit, a crashed probe, a malformed file all count the same, because each leaves the rule, hooks and permissions exactly as unproven. A null measurement never downgrades anything — null means the section was not requested (--section mcp), and an absent measurement is not a defect. cache and agents stay lenient by design since each witnesses one optional fact.

Version tracking

status compares the version stamped into the installed artifacts against the plugin running on this machine, folded into the same guidance: line:

guidance: rule managed | CLAUDE.md present | hooks 6/6 wired | permissions yes | version X.Y.Z (plugin A.B.C - run /brewcode:semble-setup upgrade)

The stamp lives in the frontmatter of .claude/rules/semble-first.md (version:) and on line 2 of each hook file (// brewcode-meta: version=X.Y.Z generated_by=brewcode:semble-setup). When the two disagree, the overall verdict drops from ready to partial and Next Step becomes Run /brewcode:semble-setup upgrade. Stamping never fabricates a value it cannot resolve — the resolver refuses to write rather than bake in a fake version.

upgrade’s idempotence was tightened alongside it: a run with nothing to change now reports unchanged, not changed — the .sembleignore half snapshots itself before and after so a template re-sync followed by the candidates re-append collapses to a net-zero result instead of a false positive on every run. And because the MCP server is registered at user scope, a second project on the same machine used to short-circuit on “already registered” and never receive its own state.json; every project now gets one, regardless of what an earlier project already wrote.

Note

unchanged from install/upgrade is never a promise of byte-identity with the plugin template — a stale metadata stamp on otherwise identical prose re-syncs and reports itself as re-synced ... (metadata only), and a managed .sembleignore legitimately differs from the shipped template the moment install appends its measured-candidates block. Read Actions, not just the verdict, before assuming nothing moved.

Reload boundary

A newly registered MCP server is not usable until a new Claude Code session. install writes the checkpoint and stops there — it never claims success it cannot verify. /brewcode:semble-setup resume continues at the smoke query in the new session.

Tool contract

Both mcp__semble_code__search and mcp__semble_code__find_related require an absolute repo argument — it is never inferred. Results carry file_path, start_line, end_line, score and optional content — there is no line field. Defaults: top_k=5, max_snippet_lines=10.

Corpus and coverage

Note

Corpus is the --content set named by SEMBLE_CONTENT_ARGS (currently code docs config) — docs is mandatory: markdown lives in semble’s doc-language bucket, so a code config corpus indexes zero .md files. .html/.htm are indexed, in the docs bucket. .json/.json5/.csv/.tsv/.psv are excluded from every content type, unreachable even with --content all; .mdx/.txt are absent from semble’s extension table entirely. rg stays the tool for those, and for exact identifiers, regexes, and exhaustive enumeration.

Honest limits

FactConsequence
No watcher, no daemonThe index is built inside a tool call and cached; staleness is re-checked per call. Nothing runs in the background.
Every shell-out is time-bounded, with or without coreutilssc_timeout uses timeout/gtimeout when a binary is present and a pure-bash watchdog when none is — the report’s timeout.bounded is always true. coreutils only upgrades which binary enforces the bound; it is never required and never a reason a run can fail.
Cold cache = slow first queryThe embedding model download can take up to 600s and fails offline with a cold HuggingFace cache.
Docs corpus is reserved, not registeredThe per-repo cache key does not encode content type — mixing code and docs in one cache dir would collide and invalidate on every call, so the docs root exists empty and untouched.
semble clear index wipes everything under the cache rootThere is no per-repo rebuild CLI; reindex rebuilds into a private staging root first and only deletes the live <code root>/<64-hex> directory once the staged build has answered a real query — a failed or skipped staged warm leaves the live index untouched. If the final swap (mv staged -> live) itself fails, the staged index is kept on disk and its path is printed for manual recovery, never silently discarded.
Windows is unsupportedThe skill refuses every mutation on a non-macOS/Linux platform.

Removal flavours

FlavourRule / hooksMCPAgent frontmatterCacheuv tool
integrationremovedkeptsemble entries removedkeptkept
mcpkeptremovedkeptkeptkept
clikeptkeptkeptkeptuninstalled
purgeremovedremovedremovedcode root removedtyped confirmation
🚀

brewcode overview

Full plugin overview — all skills, agents, and hooks in one place.

🤖

agents skill

Manages the project agent roster — the install step patches those same agents’ tools: allowlists; resume re-applies it idempotently.

📋

setup-status

Read-only dashboard: it cmps the five semble hooks and the rule against the plugin assets to decide installed vs stale.

🔗

GitHub source

SKILL.md, scripts, and the reference files behind every mode.

Updating plugins

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