PLUGIN brewcode / Agents

Setup Upgrader

inherit internal unattended

View agent file on GitHub (opens in a new tab)

Internal agent

You never start it: /brewcode:setup-status upgrade spawns it, one stale setup per spawn.

Quick reference

FieldValue
Agentbrewcode:setup-upgrader
InvocationSpawned by /brewcode:setup-status upgrade, or by a yes to its Upgrade N setups now? offer; no direct or automatic use
Modelinherit: the spawn sets it, per quick and long setup
ToolsRead, Write, Edit, Bash, Agent
WritesThe OWNED path prefixes of the brief; no git write. Project rows: the row’s project prefixes plus .claude/settings.json and .claude/settings.local.json. Global rows (agent-deadline, agent-return with scope=global): the global prefixes, the global settings.json included
Turn limitmaxTurns: 80, an anti-loop stop
OutputAt most 12 lines, then one RESULT line

What it does

After a plugin update, installed setups such as semble, docsync or agent-deadline can sit behind the plugin version. /brewcode:setup-status upgrade hands each stale setup to a fresh Setup Upgrader, one agent per setup, one after another, so no setup answers against another’s findings. Which setups qualify is on setup-status.

The agent reads the setup owner’s skill file and runs only that skill’s upgrade section with the --unattended flag. Nothing is asked: every confirmation gate takes its decline branch and counts as pending for you. A setup that needs a decision (not installed, parked, a file you edited) is skipped with nothing written.

The agent writes only inside the OWNED paths, makes no git write and never uses --force. It ends with one RESULT line. setup-status treats that line as a claim and re-probes the setup itself: the re-probe is the verdict.

Example

Run the command in a project whose setups are behind the installed plugins; the report it prints is on setup-status:

/brewcode:setup-status upgrade

The agent’s last line, one per result status:

RESULT ok brewtools:agent-deadline-setup scope=project cv=6.5.0->6.9.6 pending=0 note="upgraded, 20 min budget kept"
RESULT partial brewtools:task-board-setup cv=6.5.6->6.5.6 pending=2 note="2 PATCH edits declined: TRACKER.md, rules/tasks.md"
RESULT skipped brewcode:superreview-setup cv=?->? pending=0 note="parked"
RESULT failed brewcode:semble-setup cv=?->? pending=0 note="unfilled-token CLAUDE_SKILL_DIR"

How it works

  1. Check the brief

    Seven values must be filled: ID, SKILL, CLAUDE_SKILL_DIR, CLAUDE_PLUGIN_ROOT, CLAUDE_PROJECT_DIR, ARGUMENTS, OWNED. A missing one returns failed with unfilled-token <NAME> and writes nothing; only ID is rebuilt from the owner.

  2. Read the owner

    Reads the owner’s SKILL.md whole and finds its upgrade section. The section must carry the unattended block; without it the result is skipped with no-unattended-block.

  3. Fill the path tokens

    Owner skills cannot be loaded through the Skill tool, so Read returns raw text and the agent fills each load-time token from the brief itself. Runtime shell variables and runbook files stay untouched.

  4. Run the section

    Strips the unattended flag, takes the decline branch of every gate, skips on a precondition the section names. Each **EXECUTE** fence runs as written, one per Bash call; a STOP if ❌ hit ends the run with failed.

  5. Delegate only where the owner does

    Spawns a helper only for steps the section names, one foreground spawn per step, never to verify its own work.

  6. Check and return

    Runs the checks the section names, reads the setup’s content_version after the run, then returns the short summary and the RESULT line.

Return contract and RESULT line

At most 12 lines, then exactly one final line: the RESULT line. Nothing follows it and no other line starts with RESULT. The 12 lines give the verdict first, each path written, each pending gate as the command you run, and a failure as the failing command or path:line plus its first error line. No file bodies, fence output, diffs, logs or preamble, and no report or checkpoint file. A return without the line counts as failed.

RESULT <ok|partial|skipped|failed> <id> cv=<before>-><after> pending=<n> note="<one line>"
FieldValue
statusok: the section ran to its end, nothing pending. partial: it ran, some gates were declined. skipped: a precondition stopped it before any write. failed: a command, check or write failed, or the section did not finish
<id>The brief’s ID, verbatim: <plugin>:<skill>, then scope=project or scope=global, or team=<name>, when the row has one
cvThe setup’s content_version before the first write and after the last; ? = unknown
pendingDeclined gates and items left for you
noteOne line, no double quote: the skip reason, the migration or the failing check

What setup-status does with each status is under Outcome of one setup.

The brief setup-status sends

setup-status sends the six labeled fields (GOAL, ROLE, SCOPE, CONTEXT, CONSUMER, DONE). The agent reads these values from them by bare name; a value that is missing, empty or still a placeholder counts as unfilled.

ValueFieldHolds
IDSCOPEThe id of the RESULT line, e.g. brewtools:agent-deadline-setup scope=project
SKILLSCOPEAbsolute path of the owner’s SKILL.md
CLAUDE_SKILL_DIRSCOPEThe directory holding that SKILL.md
CLAUDE_PLUGIN_ROOTSCOPEThe owner’s plugin root: brewtools’ or brewdoc’s on their rows, never brewcode’s
CLAUDE_PROJECT_DIRSCOPEAbsolute project root
ARGUMENTSSCOPEupgrade, the row’s scope or team name when it has one, and the unattended flag
OWNEDROLEPath prefixes this row may change. Project row: its prefixes joined to the project root, plus .claude/settings.json and .claude/settings.local.json. Global row: its global prefixes joined to the global config directory, the global settings.json included, nothing else
Limits and delegation
NeverInstead / consequence
A git write: add, commit, push, stash, reset, checkout, restore, revert, clean, tag, merge, rebase, worktreeRead-only git is fine: status, diff, log, rev-parse, ls-files, hash-object
--force on any commandThe agent never passes it
Scratch anywhere but one private mktemp -d: no /tmp/*.log, no file in the project or config directoryThe directory is never deleted through a variable path
A write outside OWNED, by Write, Edit or BashThe scope check passes a project row’s OWNED paths plus both project settings files, and a global row’s two project settings files alone (its global paths lie outside the project), reports any other changed path as OUTSIDE and stops the whole run. Untracked runtime files that hooks and Claude Code write (logs, telemetry, state, plans, reports) are skipped by the check itself; the agent never writes one
Another mode (install included), another owner’s section, or a fix the section does not prescribeOnly the owner’s upgrade section runs; a setup that is not installed is skipped
Shell the permission checker cannot parse: sh -c or bash -c on a dynamic string, eval, source <(...), rm -rf on a variable pathLonger logic goes into a script in the scratch directory, run as bash /abs/path.sh
Running past the budgetA section not finished near turn 60 stops at the next clean boundary with failed and turn budget; an abort without a RESULT line stops the whole run

Delegation: brewcode:hook-creator for agent-deadline, agent-router and agent-return, and task-board-setup’s own analysis agent. The agent forwards the section’s own brief plus four lines: no git commit, push, stash or reset; no questions; scratch only in a private mktemp -d; write only under: the brief’s OWNED value, pasted literally. If a section spawns while Agent is missing from the agent’s tools (spawn-depth limit), the result is skipped with no-agent-tool.

The checks around the agent (HEAD, stash and scope), the spawn-depth rule and the permission-prompt note belong to setup-status: see How the upgrade stays safe and What the upgrade leaves to you.

setup-status

The dashboard and the upgrade run that spawns this agent.

Brewcode overview

All brewcode skills and agents in one place.

Hook Creator

The agent that does the file work for the hook-based setups.

GitHub source

Agent definition, return contract and limits in full.

Update: /brewtools:plugin-update, /reload-plugins, then /brewcode:setup-status upgrade - FAQ