agent-toggle — disable / enable agents

sonnet session

Caution

Claude Code has no native per-agent disable. When too many agents are installed, the LLM’s routing gets confused — it picks reviewer when you wanted developer, or triggers ssh-admin on unrelated tasks. Upstream: #47747, #22345.

Tip

The fix: rename the agent file. agent-toggle renames <name>.md_<name>.md in the plugin cache. The agent vanishes from auto-selection. Reverse to bring it back. State persists across plugin updates. For skills (recipes), see /brewtools:skill-toggle.

Quick reference

CommandAction
disable plugin:nameRename <name>.md_<name>.md, record in state
enable plugin:nameRename _<name>.md<name>.md, remove from state
statusMerged table of all disabled agents (global + project)
listAll agents across all plugins, marked disabled/enabled
reapplyRe-apply renames from state (use after a plugin update)
pruneDrop stale state entries for uninstalled plugins

Target format: plugin:name — e.g. brewcode:reviewer, brewtools:ssh-admin. Omitting the plugin prefix triggers a clarification prompt.

When to use

  • An agent triggers too aggressively and hijacks tasks meant for another agent
  • You need to hide an agent only for a specific project — use --scope=project
  • You want to exclude a subagent from a plugin without uninstalling the whole plugin
  • After a plugin update agents “came back” — reapply restores the desired state

Examples

Disable an agent globally:

/brewtools:agent-toggle disable brewcode:reviewer

Disable for the current project only:

/brewtools:agent-toggle disable brewcode:tester --scope=project

Re-enable an agent:

/brewtools:agent-toggle enable brewtools:ssh-admin

Natural language also works:

disable the brewcode reviewer agent for this project

Check all disabled agents:

/brewtools:agent-toggle status

Expected output after disable:

| Plugin   | Name     | Kind  | Scope  | Action  | Result   |
|----------|----------|-------|--------|---------|----------|
| brewcode | reviewer | agent | global | disable | disabled |

> Run /reload-plugins for the change to take effect.

Interactive mode

Tip

Run with no args/brewtools:agent-toggle — and a guided flow walks you through it. Explicit commands still skip the flow.

Four phases:

  1. Pick an op

    One question, four options: status, disable, enable, or list. Pre-selected: disable.

  2. Scan the catalog

    All agents printed as one space-separated line of plugin:name tokens. Use Ctrl+F / Cmd+F to search your terminal scrollback — no pagination, no multi-line clutter.

  3. Resolve the target

    Exact plugin:name or unique shortname runs immediately — no confirmation. Fuzzy phrase (“hide a noisy agent”) or ambiguous name triggers a single confirmation.

  4. See the result

    Every run ends with a status table: what’s disabled right now, plus a count of enabled agents. No guessing what state you’re in.

Note

Explicit commands skip the flow. disable brewcode:reviewer runs directly — no questions asked. The interactive path only triggers when your intent is ambiguous.

How it works

  1. P0 — Parse intent

    Parses $ARGUMENTS or the user’s NL prompt into a structured form: op / scope / targets[]. Default scope is global. Override with —scope=project or the phrase “for this project”. If a target has no plugin prefix (e.g. just tester), the skill asks which plugin via AskUserQuestion.

  2. P1 — Validate target

    Uses enumeratePlugins + resolveTarget to confirm the plugin is installed and the agent file exists in visible or hidden form. Stops with an error if neither path is found.

  3. P2 — Mutate state

    Atomically writes or removes a {&#123;kind:"agent"&#125;} entry in toggle-state.json (global or project-scoped). Uses a tmp-file + rename pattern via writeStateAtomic.

  4. P3 — Apply rename

    Calls disableTarget(visible, hidden) or enableTarget(visible, hidden) from _shared/toggle/apply.mjs. Possible statuses: disabled, enabled, already_disabled, already_enabled, missing.

  5. P4 — Notify

    Renders a result table and reminds the user to run /reload-plugins.

State files

Both agent-toggle and skill-toggle share the same toggle-state.json. The kind field in each entry distinguishes agents ("kind":"agent") from skills ("kind":"skill").

ScopePath
Global (default)&#126;/.claude/plugins/data/brewtools-claude-brewcode/toggle-state.json
Project<cwd>/.claude/brewtools/toggle-state.json

Project scope overrides global by key — the same agent can be enabled globally but disabled in one specific project.

State schema

{
  "disabled": {
    "brewcode:reviewer": {
      "kind": "agent",
      "plugin": "brewcode",
      "name": "reviewer",
      "disabled_at": "2026-04-16T10:00:00.000Z",
      "last_applied_version": "3.5.2"
    }
  }
}

Shared helpers live in _shared/toggle/: cache.mjs (path resolution), state.mjs (read/write), apply.mjs (rename).

Surviving plugin updates

Note

The reapply-disables SessionStart hook fires on every session start. When a new plugin version is detected in the cache, it automatically re-applies all entries from toggle-state.json. Drift cases (plugin not installed, file missing) are reported in additionalContext with codes plugin_not_installed / file_missing — no silent failures.

Reload required

Warning

After any disable or enable, run /reload-plugins or start a new session. Claude Code reads the agent list only at plugin load time — the change does not take effect until then.

⚙️

Skill Toggle

The symmetric operation for skills (recipes) — same mechanism, same state file, "kind":"skill".

📄

Brewtools overview

All brewtools skills and agents in one place.

🔗

GitHub source

Source code and shared toggle helpers in _shared/toggle/.

Updating plugins

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