Quick reference
| Field | Value |
|---|---|
| Command | /brewcode:setup-status [<plugin>|<skill>] |
| Arguments | empty = full report; a plugin name filters to its rows; a skill name prints one row with its detection rule spelled out |
| Model | sonnet |
| Tools | Read, Bash, Glob, Grep — no Write, no Edit, no Agent |
| Covers | 11 setup skills across brewcode, brewtools and brewdoc |
| Writes | nothing, ever |
What it does
You open an unfamiliar repo and want one answer: what of the brewcode suite is already wired in here, what drifted since the last plugin update, and what was never installed. setup-status probes the project and hands back one table plus an ordered run-list.
Every probe is an existence check, a cmp against the installed plugin asset, or a one-line grep. Nothing is created, edited or deleted — that is a capability, not a policy: allowed-tools carries no Write, no Edit and no Agent, so the skill physically cannot mutate your project or spawn a subagent that could.
Staleness is decided from three signals, never mtime and never a guess: the artifact’s own version stamp (which plugin release produced it), its owner stamp — generated_by compared against the setup that should have written the path — and cmp against the plugin asset, which only corroborates the other two. A cmp source missing from the plugin cache reports version unknown (plugin asset missing), never stale.
A setup you switched off on purpose is reported disabled, not broken: the state is evaluated before missing, partial and stale, its command column offers enable, and it never enters the run-list.
Why it refuses to run the setups
There is no --run and no --fix, by design
Every setup skill is an interactive generator: it fans out subagents, analyses the repo and asks you real questions. Run two back-to-back in one session and both degrade — the context fills with the first one’s analysis, and the second one’s questions get answered against stale findings. So this skill reports and stops, and you run each setup by hand, ideally one per fresh session.
Ask it to “install everything” or “fix them all” and it refuses once, plainly, then prints the run-list instead. The flag does not exist because of the failure mode above, not because nobody got around to adding it.
When to use
| Situation | Command |
|---|---|
| New repo, no idea what is wired in | /brewcode:setup-status |
| Just updated the plugins, what drifted? | /brewcode:setup-status |
| Only care about one plugin’s rows | /brewcode:setup-status brewtools |
| One row, with its detection rule in full | /brewcode:setup-status semble-setup |
| Free text, RU or EN — answers in your language | /brewcode:setup-status что установлено |
Example
/brewcode:setup-status
4 of 11 setups are behind the installed plugin (2 stale by version, 1 legacy stamp, 1 stale by wiring).
| Skill | State | Version | Found | Command
| /brewcode:semble-setup | stale | A.B.C | rule + all five live hook files current; semble-explore.mjs (RETIRED, superseded by semble-subagent.mjs) is still on disk — wiring shows only 5 of the 6 settings.json entries the current version wants | /brewcode:semble-setup install "remove the retired hook file, re-wire all six settings entries"
| /brewtools:task-board-setup | stale (X.Y.Z -> A.B.C) | X.Y.Z -> A.B.C | board.md + tracker present, .claude/skills/task-spec/ absent | /brewtools:task-board-setup upgrade "retrofit the spec + design layer onto the deployed board, keep every task id"
| /brewtools:agent-deadline-setup | stale (X.Y.Z -> A.B.C) | X.Y.Z -> A.B.C | guard + config present, JSON trio never restamped since an older release | /brewtools:agent-deadline-setup upgrade "restamp the config trio at the current budget"
| /brewdoc:memory-sync-setup | stale (legacy stamp) | legacy -> A.B.C | emitted SKILL.md has no frontmatter version: (the current carrier); the retired <!-- memory-sync template v1.0.0 --> tail survives only as the legacy detector | /brewdoc:memory-sync-setup upgrade "migrate the pre-5.0 tail stamp to provenance frontmatter"
| /brewdoc:docsync-setup | missing | -- | nothing under .claude/docsync/ | /brewdoc:docsync-setup install
| /brewcode:teams-setup | installed | A.B.C | team.md (Version A.B.C) + trace.jsonl + trace-ops.sh, all bytes match | /brewcode:teams-setup status
| /brewtools:think-short-setup | disabled | A.B.C | 4 hooks wired, prompt renamed to think-short-prompt.md.disabled | /brewtools:think-short-setup enable
| /brewtools:manager-setup | n/a | -- | brewtools not installed | claude plugin install brewtools@claude-brewcode
Run in this order, ONE PER SESSION:
1. /brewcode:semble-setup install "..." <- stale first
2. /brewtools:task-board-setup upgrade "..."
3. /brewtools:agent-deadline-setup upgrade "..."
4. /brewdoc:memory-sync-setup upgrade "..."
5. /brewdoc:docsync-setup install <- new installs last
Each of these spawns several subagents and will ask you questions. Running two in one
session degrades both. Start a fresh session per command.
think-short-setup is disabled on purpose — enable with /brewtools:think-short-setup enable.
roster: 11/11 in sync
A.B.C stands for the installed plugin version and X.Y.Z for an artifact’s own, older stamp in the samples above — the real report always prints real numbers, never these placeholders.
The last line is separate: it is Phase 5’s roster self-check, not part of the table above — it confirms the skill’s own roster still matches every *-setup directory shipped in the installed plugins.
The Command column is ready to paste. For stale and partial it always carries a concrete fine-tune prompt naming what to refresh — a bare upgrade with no prompt is not acceptable output. Only canonical verbs appear there (status · install · upgrade · enable · disable · uninstall · purge), plus the extras two setups genuinely add after them: reindex | optimize | resume for semble-setup, and level <...> for agent-router-setup and manager-setup.
Workflow
- Resolve plugin roots
Finds the newest cached version of each of the four plugins under
~/.claude/plugins/cache/claude-brewcode/. A plugin that is not installed makes all of its rowsn/a, nevermissing. All four absent = stop and say so, rather than printing an all-missing table. - Probe artifacts
One generic block fed from the roster: an existence check per anchor and secondary path, plus
settings.jsonwiring greps and the global~/.claudetwins for the two setups that install to either scope. Textual grep counts prove a key is mentioned, not that the entry is well-formed — the report says so. - Read the disable switches
All eleven setups leave a real off-switch on disk, probed directly rather than inferred — the two mechanisms are detailed in Two rules that stop false alarms below. An absent key means OFF on the opt-in
agent-deadlineandagent-returnrows, but ON on the opt-outagent-routeranddocsyncrows — the two defaults ship side by side. - Version signals
Only for rows whose anchor exists and whose roster cell defines a signal. Read the version stamp, compare
generated_byagainst the row’s own owner, thencmpthe project copy against the plugin asset to corroborate. A missing plugin asset reportsversion unknown (plugin asset missing), neverstale. - Classify
Exactly one state per row, evaluated in this fixed order:
n/a, thendisabled, thenmissing, thenpartial, thenstale, theninstalled— whydisabledoutranksmissingis explained in Two rules that stop false alarms below. - Output
One table in roster order, then the ordered run-list:
partial(broken installs) first, thenstale, thenmissing.disabled,installedandn/arows stay out of it; a disabled row is mentioned once below the list with itsenablecommand. Answers in the language you wrote in — the prose is translated, never the paths or the commands. - Roster self-check
Lists the
*-setupdirectories actually present in the installed plugins and compares them against the roster. A setup it does not know about produces a warning above the table, never a silent edit. Match prints one line:roster: 11/11 in sync.
Technical details
A remedy must be able to clear the verdict it follows
Every earlier release verified that an artifact was stamped at install; none verified the stamp could ever move. upgrade used to refresh content and leave the version stamp untouched — status reported stale, upgrade reported success, the next status reported stale again, forever. All eleven setups now close that loop: install at an old version, bump the plugin, status reports stale, upgrade restamps it, status reports installed, and a second upgrade is a no-op with the artifact body byte-identical. A handful of findings genuinely have no clearing mode — a .template-baseline/ diff on superreview-setup, a hand-edited memory-sync reference, a hand-edited semble-first.md — and this skill reports those as a diff to port by hand, never dressed up as a command that would do nothing.
The 11 setups it covers
| Setup | Anchor artifact |
|---|---|
/brewcode:teams-setup | .claude/teams/*/team.md |
/brewcode:semble-setup | .claude/rules/semble-first.md |
/brewcode:superreview-setup | .claude/skills/superreview/SKILL.md |
/brewtools:task-board-setup | .claude/features/board.md |
/brewtools:think-short-setup | .claude/hooks/think-short-session.mjs (or the ~/.claude twin) |
/brewtools:agent-deadline-setup | .claude/hooks/agent-deadline-guard.mjs (or the twin) |
/brewtools:agent-router-setup | .claude/hooks/agent-router.mjs |
/brewtools:manager-setup | .claude/brewtools/manager/state.json |
/brewtools:agent-return-setup | .claude/hooks/agent-return-guard.mjs (or the twin) |
/brewdoc:memory-sync-setup | .claude/skills/memory-sync/SKILL.md |
/brewdoc:docsync-setup | .claude/docsync/config.json |
Recurring tools never appear in the report — they have no installed state and are correct to run repeatedly: brewcode:agents, skills, rules, convention, e2e; brewtools:text-optimize, text-human, secrets-scan, ssh, deploy, plugin-update, provider-switch; brewdoc:md-to-pdf, my-claude, publish.
States
Evaluated in this fixed order:
| # | State | Means |
|---|---|---|
| 1 | n/a | that plugin is not installed |
| 2 | disabled | installed, then switched off on purpose — a config flag flipped, or the entry file parked as <name>.disabled. Reported as inactive with its real version, never as broken and never as missing, and never queued in the run-list |
| 3 | missing | the anchor is absent in both spellings, no <name>.disabled twin either — never installed here. A shared file the project happens to contain is not evidence |
| 4 | partial | some artifacts present and some gone, a version stamp left as an unresolved {PLACEHOLDER}, a row-1/row-4 toggle caught half-parked, or generated_by naming the wrong setup |
| 5 | stale | the version stamp is behind, ahead, retired, or missing, or the bytes drifted from the plugin asset — one of the four qualifiers below. An absence signal or semble’s wiring signal fires with no stamp or byte problem at all, and prints a bare stale naming the missing artifact in the Found column instead |
| 6 | installed | the stamp equals the installed plugin version and every cmp pair matches |
stale carries one of four qualifiers when a stamp or byte signal fired. Two cases print a bare
stale with no qualifier and name the missing artifact in the Found column instead: an absence
signal (a deployed board with no task-spec skill, a complete team with no trace-ops.sh) and
semble’s wiring signal (retired[]/staleEntries when every file on disk is already byte-current).
| Qualifier | Means |
|---|---|
(X.Y.Z -> A.B.C) | the stamp is a plugin version behind (or ahead, printed the same way) |
(legacy stamp) | a retired stamp spelling is present instead of the current carrier |
(legacy, unstamped) | the artifact carries no stamp in any carrier at all |
(bytes drifted) | the version stamp is current but a cmp pair DIFFERS |
One case survives outside this vocabulary: a cmp source missing from the plugin cache reports version unknown (plugin asset missing), never stale — the cache is incomplete, not the project.
Two rules that stop false alarms
Anchor MISS is decisive, and every secondary must be exclusive. The anchor is the artifact only that setup writes. A shared file — any hand-written .claude/agents/*.md, or intent-guard.md, which both superreview-setup and teams-setup can emit — is not evidence that this setup ran, and listing one as a secondary made teams-setup report a broken partial install (and jump to the top of the run-list) in every project that merely had an agent file. So teams-setup’s secondaries are now .claude/teams/*/trace.jsonl and .claude/teams/*/trace-ops.sh, superreview-setup no longer claims intent-guard.md, and a setup with no exclusive secondary is decided by its anchor alone.
disabled is evaluated before missing, partial and stale, because all three readings are wrong on a deliberately switched-off setup. Five setups disable by parking the anchor file itself — superreview-setup disable renames SKILL.md away, so checking presence first would report missing (“never installed”) for something the user turned off on purpose. think-short-setup disable renames its prompt file away, so the roster secondary legitimately MISSes — calling that partial tells you to repair something you turned off. Inversely, semble at enabled: false or a manager wall at hard: false has every file in place and byte-identical, and reporting it installed would hide that the mechanism is inert.
All eleven setups leave a real off-switch on disk, under two mechanisms: a live config flag the reader re-checks on every invocation, or entry-file parking, where the one filename Claude Code discovers is renamed to <name>.disabled with the body left byte-identical.
| Setup | Mechanism | Off-switch | Disabled when |
|---|---|---|---|
teams-setup | entry-file parking | .claude/agents/<member>.md.disabled | every roster member of team.md is parked. intent-guard is never parked — it is shared with superreview-setup |
semble-setup | config flag | .claude/semble/state.json | .enabled is false — every file stays in place |
superreview-setup | entry-file parking | .claude/skills/superreview/SKILL.md.disabled | present, SKILL.md gone. references/ stays readable |
task-board-setup | entry-file parking | any of task-tracker.md, task-board/SKILL.md, task-spec/SKILL.md, rules/tasks.md as .disabled | every deployed one of the four is parked; .claude/features/** untouched |
think-short-setup | entry-file parking | the hooks dir (project or ~/.claude) | think-short-prompt.md.disabled present, think-short-prompt.md absent — hooks stay wired and no-op |
agent-deadline-setup | config flag | .claude/agent-deadline.json (or the ~/.claude twin) | "enabled": false or the key absent — opt-in, so a key-less config is inert |
agent-router-setup | config flag | .claude/brewtools/agent-router.json | "enabled": false. An absent key means enabled — opt-out, the hook defaults enabled: true |
manager-setup | config flag | .claude/brewtools/manager/state.json | .hard is not true — the wall is disarmed, not broken |
agent-return-setup | config flag | .claude/agent-return.json (or the ~/.claude twin) | "enabled": false or the key absent — opt-in, so a key-less config is inert |
memory-sync-setup | entry-file parking | .claude/skills/memory-sync/SKILL.md.disabled | present, SKILL.md gone. The 3 references and every self-synced hand-edit stay |
docsync-setup | config flag | .claude/docsync/config.json | "enabled": false. An absent key means enabled — opt-out, for back-compat installs written before the key existed |
Four rows read an absent key differently, and conflating them inverts a row: agent-deadline and agent-return are opt-in (cfg.enabled !== true), so no key means OFF. agent-router and docsync are opt-out (c.enabled !== false), so no key means ON.
How staleness is decided
Three signals, never mtime and never a guess. None answers another’s question — the version stamp cannot see body drift, cmp is meaningless for a generated artifact, and only generated_by catches the wrong setup writing a path that is otherwise perfectly current.
| Signal | Question | How |
|---|---|---|
| version stamp (headline) | which plugin version produced what is installed here? | frontmatter version:, a top-level JSON key, a brewcode-meta: comment after the shebang, or team.md’s | Version | header row — whichever carrier the roster names for that row |
| owner stamp | did the setup that owns this path actually write it? | generated_by compared against the row’s own <plugin>:<skill>. A mismatch is partial; a real version with no generated_by beside it is stale (legacy stamp) |
cmp vs the plugin asset (corroborating) | was this file actually re-copied after the plugin update? | byte equality on the copied files — semble’s rule + all five live hook files (never .sembleignore; those five files wire as six settings.json registrations, since semble-stats.mjs fires on both PostToolUse and PostToolUseFailure), think-short’s 4, agent-deadline’s 2, agent-router’s 1, the manager guard, docsync’s 3, two of memory-sync’s 3 references, and trace-ops.sh |
semble-setup reads a fourth, independent signal: wiring. .claude/settings.json can list a hook that no longer exists, or omit one the current version wants, while every file on disk is already byte-current — retired[], staleEntries and wiredCount/wantCount catch what a version-and-bytes check cannot see.
Per-row notes worth knowing before reading a row: memory-sync-setup’s version stamp is frontmatter version: resolved from brewdoc/.claude-plugin/plugin.json — the <!-- memory-sync template vX.Y.Z tail is a retired legacy stamp, read only as a fallback. superreview-setup reads the version out of the emitted SKILL.md frontmatter, never out of .template-baseline/, which stays at the unresolved {PLUGIN_VERSION} token by design. teams-setup and task-board-setup both carry real stamps (team.md’s \| Version \| header row, board.md’s frontmatter version:) — an earlier release forced both into an “unknown” state; that state is retired. Two absence signals still stand in for a stamp: a deployed board with no .claude/skills/task-spec/ predates the spec + design layer, and a complete team with no trace-ops.sh is a pre-standard install whose agents cannot trace — both stale, cleared by one upgrade.
The version-comparison heredoc
Every stamp read in the table above comes from one heredoc — plugin|path|expected-owner|content_version-source — twenty-one lines covering the roster’s eleven rows. The fourth field names the plugin file that supplies that SAME artifact’s own content_version, so each row is measured against its own history, never against the release-wide plugin version directly:
brewcode|.claude/teams/*/team.md|brewcode:teams-setup|skills/teams-setup/SKILL.md
brewcode|.claude/rules/semble-first.md|brewcode:semble-setup|skills/semble-setup/assets/semble-first.md.template
brewcode|.claude/skills/superreview/SKILL.md|brewcode:superreview-setup|skills/superreview-setup/SKILL.md
brewtools|.claude/features/board.md|brewtools:task-board-setup|skills/task-board-setup/SKILL.md
brewtools|.claude/hooks/think-short-session.mjs|brewtools:think-short-setup|skills/think-short-setup/assets/think-short-session.mjs
brewtools|~/.claude/hooks/think-short-session.mjs|brewtools:think-short-setup|skills/think-short-setup/assets/think-short-session.mjs
brewtools|.claude/hooks/agent-deadline-guard.mjs|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/agent-deadline-guard.mjs
brewtools|~/.claude/hooks/agent-deadline-guard.mjs|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/agent-deadline-guard.mjs
brewtools|.claude/agent-deadline.json|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/INSTALL.md
brewtools|~/.claude/agent-deadline.json|brewtools:agent-deadline-setup|skills/agent-deadline-setup/assets/INSTALL.md
brewtools|.claude/hooks/agent-router.mjs|brewtools:agent-router-setup|skills/agent-router-setup/assets/agent-router.mjs
brewtools|.claude/brewtools/agent-router.json|brewtools:agent-router-setup|skills/agent-router-setup/assets/INSTALL.md
brewtools|.claude/brewtools/manager/state.json|brewtools:manager-setup|hooks/lib/manager-state.mjs
brewtools|.claude/brewtools/manager/hardmode-guard.mjs|brewtools:manager-setup|hooks/hardmode-guard.mjs
brewtools|.claude/hooks/agent-return-guard.mjs|brewtools:agent-return-setup|skills/agent-return-setup/assets/agent-return-guard.mjs
brewtools|~/.claude/hooks/agent-return-guard.mjs|brewtools:agent-return-setup|skills/agent-return-setup/assets/agent-return-guard.mjs
brewtools|.claude/agent-return.json|brewtools:agent-return-setup|skills/agent-return-setup/assets/INSTALL.md
brewtools|~/.claude/agent-return.json|brewtools:agent-return-setup|skills/agent-return-setup/assets/INSTALL.md
brewdoc|.claude/skills/memory-sync/SKILL.md|brewdoc:memory-sync-setup|skills/memory-sync-setup/SKILL.md
brewdoc|.claude/docsync/config.json|brewdoc:docsync-setup|skills/docsync-setup/SKILL.md
brewdoc|.claude/hooks/docsync-track.mjs|brewdoc:docsync-setup|skills/docsync-setup/assets/docsync-track.mjs
Twenty-one lines over eleven rows, because several rows contribute more than one carrier: think-short-setup and agent-router-setup two each (project scope plus global, or hook plus config), agent-deadline-setup and agent-return-setup four each (guard and config, project and global scope), manager-setup two (state.json primary, the copied guard as a documented fallback). Two assertions guard the set against silent drift, both a hard exit 1 rather than a warning: TOTAL must equal 21 — a line deleted anywhere aborts the run, even in a plugin group this pass is not scanning — and SEEN must equal the group’s own WANT (brewcode 3, brewtools 15, brewdoc 3).
Reading a stamp also compares its generated_by against the line’s expected owner. A different name reports OWNER-WRONG — some other setup wrote this path — and a real version with no generated_by beside it reports OWNER-NONE, treated as stale (legacy stamp).
Fixed: no more false BEHIND on a missing cache source
An artifact’s headline stamp is measured against its OWN content_version-source — the plugin file that supplies that same artifact’s current content_version — never against the release-wide plugin version directly. When that source file is absent from the plugin cache, the skill used to fall back to comparing against the plugin version anyway, which could print a bogus regression like stale (5.6.0 -> 5.7.0) on an artifact that had not actually changed. It now reports the gap and stops: no source, no verdict, classified unknown, never stale.
Version resolution never guesses
The plugin version every stamp is measured against is resolved, never typed in by hand and never inferred loosely: the installed cache directory’s basename first (~/.claude/plugins/cache/claude-brewcode/<plugin>/*/, newest by sort -V), that root’s .claude-plugin/plugin.json .version second — the same precedence the brewcode SessionStart hook uses. When neither resolves, the skill aborts rather than guessing: feeding an unresolved value to sort -V would silently produce a confident but meaningless BEHIND/AHEAD verdict instead of an honest failure.
Two things that look like staleness and are not
| Looks like | Actually |
|---|---|
manager-setup’s guard DIFFERS | Only means the wall was not re-armed since the last brewtools update. It still works. Reported stale, with that clause attached — a different finding from hard: false, which is disabled and outranks it |
A hook under ~/.claude while the project also has one | A scope answer, not a conflict. think-short-setup and agent-deadline-setup are legitimately global |
The repo-root .sembleignore reads DIFFERS/bytes drifted | Used to be a false alarm on every healthy project — the installer appends a measured-candidates block to .sembleignore after copying it, so a correct install is never byte-equal to the template by construction. .sembleignore is now out of the cmp set; its presence and its own version stamp are still checked and still valid. unchanged reported by an installer does not mean byte-equal to the template — worth keeping in mind reading any row on this dashboard |
Edge cases
| Condition | Response |
|---|---|
No .claude/ in the project | Every row missing; the table and the install run-list print anyway |
| All four plugin roots absent | ”no brewcode plugins installed” plus the claude plugin install lines — not an all-missing table |
Running with --plugin-dir (dev mode) | No cache root to compare against. Says so; a repo checkout is not a substitute |
A cmp source path is missing from the cache | version unknown (plugin asset missing), never stale |
A *-setup on disk the roster does not know | WARNING above the table naming it, and the note that its state was not checked |
Roster as single source of truth
Every fact the skill knows lives in ONE table in its SKILL.md. Adding a future setup is one row — no script, no second list, no code change, because every probe is a generic inline block fed from that table.
brewcode overview
Full plugin overview — all skills, agents, and hooks in one place.
semble-setup
One of the eleven rows: its five hooks and rule are cmpd verbatim against the plugin assets.
superreview-setup
Another row: staleness comes from its .template-baseline/ diff, so your tailoring never counts as drift.
GitHub source
SKILL.md — the roster table, the probe blocks, and the output contract.
Updating plugins
/brewtools:plugin-update to check and update the brewcode plugin suite in one command.
See the FAQ for details.