/imps:imps decomposes a task (or a batch of GitHub issues) into model-routed agents
("imps") — parallel when the work splits into independent units, solo when it's genuinely
one — dispatches them as staged background subagents, and integrates results through
deterministic gates and an adversarial persona-review panel.
The orchestrating session is deliberately minimal: it holds only the operator-facing
work (plan approval, the push/PR gate, conflict decisions, learnings) while everything
else — dispatch, imp monitoring, merges, diffs, gate logs, persona traffic,
finalize — is real control flow inside a Workflow script
(scripts/imps-run.workflow.js), not a subagent. The command syncs the bundled script
into ~/.claude/workflows/ and invokes it fresh on every run (plugins can't ship a
runnable Workflow directly); the script's own opening step reads the run's state file
and resumes from wherever it left off, so long runs never grind the main context down —
the harness tracks the script's internal agent() dispatches separately from the calling
session's transcript, the same isolation property the old subagent-based design achieved
by hand.
| Requirement | Needed for |
|---|---|
gh CLI (authenticated) |
Issue-driven mode (issue reads, PR creates, CI checks). |
GitHub MCP (mcp__github__*) |
PR/issue reads in /imps:prs; improves issue-driven mode. |
Bundled agent types (🦇, 😈, 👺) |
Registered automatically once installed (agents/*.md). If registration fails for any reason, agent() calls inside the Workflow script fall back the same way any Agent-tool call does. |
The Workflow tool |
Hard dependency for the free-text run — no fallback. /imps:imps syncs scripts/imps-run.workflow.js into ~/.claude/workflows/ and invokes it; if Workflow is unavailable in the session, the command stops and says so rather than falling back to an inline protocol. |
Optional:
| Requirement | Needed for |
|---|---|
CLAUDE_CDP_URL env var |
Browser panel via CDP (default ws://localhost:3000). Point at a headless-Chrome container, local or LAN. |
| Claude-in-Chrome MCP | Browser panel fallback if no CDP endpoint is reachable. |
~/.claude/scripts/persona-post.sh + dedicated GitHub Apps (mm-solution-architect, mm-grumpy-engineer, mm-sre, mm-business-analyst, mm-ux-designer) installed on the target repo, with their credentials in 1Password |
Independent, per-persona review identity for the persona panel (see The persona panel). Absent or failing → that persona's verdict goes to findings_inline instead of posting — it never falls back to the orchestrator's own identity. |
claude plugin install imps@seankojiOr via the marketplace:
claude plugin marketplace add seankoji/claude-plugins
claude plugin install imps@seankojiFour entry modes, auto-detected from the argument:
| Invocation | Mode | What it does |
|---|---|---|
/imps:imps <free-text task> |
Free-text | Refine → plan (opus plan mode) → decompose → hand to the Workflow script (staged dispatch → merge → gates → persona panel → endstate PR) |
/imps:imps 42 43 51 |
Issue-driven | Scout issues → rolling dispatch in isolated worktrees → holding branch → gates → persona panel → operator handoff |
/imps:imps https://github.com/<owner>/<repo>/discussions/284 |
Discussion-seed | Fetch the discussion via GraphQL, seed it as the free-text task, run the normal free-text flow, and always post a summary comment back to the discussion at the end |
/imps:imps path/to/checklist.md |
Checklist-file | Run each Verify:/Done when: item as a read-only audit, then offer remediation dispatch |
/imps:impswith a task description (or empty — it will ask)./imps:impsrefines the brief viaprompt-builder, asks five discovery questions, then enters plan mode (opus) to decompose and writeGOAL.md(to~/.claude/imps/runs/<slug>.md, not the repo — see Runtime state).- The Head Imp (opus) adversarially reviews the plan; findings are addressed before dispatch.
- After plan approval,
/imps:impssyncs and invokes the Workflow script, then returns control —Workflowruns in the background, and you're notified when it reaches a result. The script does the git preflight, dispatches the task DAG as stagedagent()calls, and tracks progress in the run state file, so progress iscat ~/.claude/imps/runs/<slug>.json(the imps run inside the script's own tracked execution, invisible to the main session's transcript the same way the old subagent design was). - When the imps finish, the script flows straight into integration: merges code branches, drives the Head Imp diff review, runs gates, then returns an
awaiting_authorizationresult. After you approve the push, the script (re-invoked fresh with your decision persisted to the state file) opens the endstate PR (the default for runs that change code — decline the push to skip it), runs the persona panel on that PR, applies fixes, and finalizes the run (PR ready, Discussion comment, run stats, monitor state). The main session only relays your decisions, then makes the one/imps:prscall to activate the PR monitor.
/imps:imps 42 43 51— all tokens are issue numbers.- Scouts (haiku) fan out in parallel per issue; results seed the implementation queue.
- Implementation agents run in isolated worktrees up to
PARALLEL_CAP=6concurrent; file-overlapping issues serialize naturally. - After all issues merge into the holding branch,
/imps:impsruns full gates, opens the integration PR, and runs the persona panel. - Operator handoff —
/imps:impsdoes NOT merge the integration PR.
/imps:imps https://github.com/<owner>/<repo>/discussions/284(or the barediscussion 284inside that repo)./imps:impsfetches the discussion's title, body, and comments viagh api graphql(Discussions have no REST endpoint) and uses that content as the task description, skipping the "what's the task?" prompt.- Everything from there follows the free-text mode walkthrough above (discovery → plan → dispatch → integration).
- Regardless of what the discovery answers say about output artifacts, the Workflow script always posts one summary comment back to the source discussion once the run finalizes (or a short abort notice if the run is aborted) — this is not optional and does not require a PR to exist.
Pass a single .md token that resolves to a file with - [ ] checklist items, each having Verify: and Done when: sub-lines. /imps:imps fans out read-only verification imps and emits a pass/fail audit report, then offers to dispatch remediation.
Issue-driven mode is also directly invokable as /imps:issue-mode — useful for an upstream
audit or handoff tool that wants to skip /imps:imps's mode detection. It accepts either bare
issue numbers (/imps:issue-mode 42 43 51) or a structured JSON input:
{ "issues": [42, 43, 51, 60], "holdingBranch": "audit/2026-06-12" }issues(required) — the issue numbers to work (capped atISSUE_CAP=200).holdingBranch(optional) — the branch to integrate onto; defaults toswarm/<YYYY-MM-DD>cut fresh from the repo's default branch. If the branch and its tracking issue already exist, the run resumes from the first incomplete phase.
Self-rescheduling via ScheduleWakeup — do NOT wrap it with /loop.
/imps:prs— proactive PR monitor. After/imps:impspushes and creates the endstate PR, activate this to automatically address review comments, fix CI failures, and resolve merge conflicts. Stops when the PR is merged, closed, or 48 h old.
The upstream counterpart to a remediation run: a read-only whole-repo health audit that
produces a /imps:imps checklist-file plan, so the audit and the fix are one continuous
loop (/imps:imp-agency → /clear → /imps:imps <plan>).
The main session does one thing in its own context — resolve the project profile and show
it to the user as a gate — then hands the whole audit to a single imp-agency subagent
(unlike the free-text run, this path is unchanged: a single-segment subagent, not a
Workflow script — see What it does). Inside it, one finder per applicable
dimension (purpose, docs, ci, tests, security, performance, ux, stack,
ops, dx) fans out as nested background imp agents (the Workflow tool is not
available to subagents), every P0/P1 finding is adversarially refuted, a completeness
critic catches the suspiciously-clean dimension, and the survivors are synthesized into
the checklist plan.
Effectiveness before craftsmanship. The purpose finder audits fitness for purpose —
does each component earn its existence against the repo's reason-for-being (confirmed by
you at the profile gate)? It may verdict delete; delete verdicts face a 2-of-3
refuter panel, supersede fix findings on the same component, and land in an
operator-decision section of the plan — imps never auto-delete. If you wouldn't accept
"delete this component" as a finding, --focus away from purpose. The orchestrator gets back only the plan's ## Context block and the item split —
finder returns, refuter traffic, and critic output never touch its context.
Model routing follows reasoning shape. The wrangler shell (dispatch/monitor/merge) is
sonnet; the parts with real analysis are upgraded: the deep-judgment finders (purpose,
stack, security, performance, tests) and every adversarial refuter run on opus,
synthesis is an opus sub-call (it writes the most-read output), and the
cross-dimension completeness critic runs on fable — the widest-decision-space call —
falling back to opus where Fable isn't available. The evidence-gathering finders (docs,
ci, ux, ops, dx) stay on sonnet: a stronger model doesn't find more stale docs or
missing lint gates.
/imps:imp-agency [--focus docs,tests,security] [--out /abs/path/plan.md]
--focus(optional) — restrict to a subset of the dimension keys; default is all applicable.--out(optional) — where to write the plan (absolute, whitespace-free, outside the repo — the audit is read-only there). Default:~/.claude/audits/<repo>-<date>.md.
Every checklist item is a claim about the fixed end-state with a read-only Verify: command
that fails now and passes once fixed — so /imps:imps <plan> re-verifies each, reports
the failures, and offers to dispatch remediation. Read-only throughout: the only write is the
plan file outside the repo.
Five reviewer briefs, each argued from a distinct, deliberately-conflicting lens.
Bundled at ${CLAUDE_PLUGIN_ROOT}/personas/ — no manual setup needed.
| Slug | Name | Lens | Type | Model |
|---|---|---|---|---|
solution-architect |
Bramble | Boundaries, contracts, coupling — "should this exist, in this shape?" | code | opus |
grumpy-engineer |
Grudge | Edge cases, error paths, lazy shortcuts — "is this line correct?" | code | opus |
sre |
Klaxon | Failure modes, ops, idempotency, resource limits — "what does the operator see at 3am?" | code | opus |
business-analyst |
Ledger | Diff satisfies each issue's acceptance criteria — "did we build the right thing?" | code | opus |
ux-designer |
Glint | Hierarchy, affordance, consistency, mobile — "what does the user actually see?" | browser | sonnet |
Each persona ends its review with a parseable verdict line:
VERDICT: APPROVE | CHANGES_REQUESTED @ <sha>
CHANGES_REQUESTED requires at least one [blocker] or [major] finding. Minors and
nits are recorded but never block. By default each persona posts as a real GitHub PR
review under its own dedicated GitHub App identity (mm-solution-architect,
mm-grumpy-engineer, mm-sre, mm-business-analyst, mm-ux-designer) via
~/.claude/scripts/persona-post.sh — never the orchestrator's own gh/GitHub-MCP
access, so each review is attributed to and traceable as a genuinely separate GitHub
actor, not the session that authored the diff. This is independent attribution, not
an unforgeable gate: the orchestrator still holds the credentials persona-post.sh
uses to mint every App's token, so it isn't a control the authoring session is
structurally unable to satisfy — it fixes the previous self-approval-under-one's-own-
name problem, not every trust concern a branch-protection rule might assume. If that
script is absent, fails, or its post can't be verified on the PR for a given persona
(Apps not installed on this repo, 1Password locked, no op access, etc.), that persona's
verdict fails closed: it goes into findings_inline for the operator to read or post
by hand, never under the orchestrator's own identity — the rest of the panel is
unaffected.
Pushing/opening the endstate PR and authorizing personas to post live GitHub reviews are
two separate operator decisions, not one — the Push & PR? question (asked once the
Workflow script returns awaiting_authorization) offers a findings only (no persona posts) option precisely for runs where this session's own Head-Imp-driven amendments
make an independent review under a bot identity misleading. The posting-identity
protocol itself lives in references/persona-posting.md, shared by this panel and
/imps:issue-mode's — not duplicated between them.
| Asset | Location |
|---|---|
| Persona briefs (5) | ${CLAUDE_PLUGIN_ROOT}/personas/<slug>.md |
| Persona posting-identity protocol (shared) | ${CLAUDE_PLUGIN_ROOT}/references/persona-posting.md |
🦇 agent type |
${CLAUDE_PLUGIN_ROOT}/agents/imp.md |
😈 agent type |
${CLAUDE_PLUGIN_ROOT}/agents/head-imp.md |
👺 agent type (audit orchestrator) |
${CLAUDE_PLUGIN_ROOT}/agents/imp-agency.md |
| Free-text run's Workflow script | ${CLAUDE_PLUGIN_ROOT}/scripts/imps-run.workflow.js — synced to ~/.claude/workflows/imps-run.js on every invocation |
| Checklist-file mode workflow | ${CLAUDE_PLUGIN_ROOT}/references/checklist-mode.md |
| Discussion-seed mode workflow | ${CLAUDE_PLUGIN_ROOT}/references/discussion-mode.md |
| Summon banner (cosmetic) | ${CLAUDE_PLUGIN_ROOT}/scripts/imps-intro.py |
| Dispatch banner (cosmetic) | ${CLAUDE_PLUGIN_ROOT}/scripts/dispatch-banner.py |
| Final banner (cosmetic) | ${CLAUDE_PLUGIN_ROOT}/scripts/final-banner.py |
| Structured audit-log appender | ${CLAUDE_PLUGIN_ROOT}/scripts/audit-log.sh |
| opencode execute-tier dispatcher | ${CLAUDE_PLUGIN_ROOT}/scripts/opencode-dispatch.sh — hand-invocable; see ${CLAUDE_PLUGIN_ROOT}/references/opencode-harness.md |
| OS sandbox wrapper (macOS) | ${CLAUDE_PLUGIN_ROOT}/scripts/sandbox-wrap.sh |
| Sandbox containment assertions | ${CLAUDE_PLUGIN_ROOT}/scripts/sandbox-smoke.sh |
--worktree linked-worktree-shape assertions |
${CLAUDE_PLUGIN_ROOT}/tests/worktree-shape.sh |
No manual setup needed for any of these — the plugin installs them at
${CLAUDE_PLUGIN_ROOT} and the commands resolve them at runtime. The bundled
😈 agent type resolves whenever anything invokes it via the Agent tool
(Agent(subagent_type: "imps:😈", ...)).
Written to ~/.claude/imps/ on first run — not bundled:
| Path | Purpose |
|---|---|
~/.claude/imps/runs/<slug>.json |
Per-project run state — resume spine, owned by the Workflow script after handover; it heartbeats last_heartbeat + tasks_done while imps run, so cat this file for live progress. Every invocation of the script is fresh (never resumeFromRunId) — this file, plus git ground truth, is the entire resume mechanism |
~/.claude/imps/runs/<slug>.md |
Per-run GOAL.md spine (/compact-durable) — lives here, not in the repo, so writing it never needs project-directory permission |
~/.claude/imps/runs/<slug>.prs.json |
Per-PR monitor state for /imps:prs |
~/.claude/imps/learnings.md |
Self-tuning ## Active rules (≤10 bullets) + per-run notes |
~/.claude/audit.jsonl |
One structured JSON line per completed run — shared across plugins in this marketplace (schema in the root AGENTS.md) |
The learnings.md ## Active rules section is read at startup on every run and applied
to model routing, task boundaries, and dependency detection. /imps:imps appends a new run
entry after each completed run; confirmed learnings are promoted into Active rules. The
Workflow script also appends a structured audit.jsonl entry at finalize — best-effort,
skipped with a warning (not a failure) if jq is missing.
The persona panel includes a browser half when the diff touches a renderable UI surface. Transport is resolved in order:
- CDP endpoint — set
CLAUDE_CDP_URL(e.g.ws://localhost:3000orws://<lan-host>:3000for a remote rig). Connect viachromium.connectOverCDP— neverconnect()(hangs); never passhttp://(returns 426). - Chrome MCP fallback — if no CDP endpoint is reachable, the panel uses
mcp__claude-in-chrome__*tools (requires the Claude-in-Chrome extension). - No browser — neither available → panel runs code-only; skip is noted in the report.
Repos with no UI surface skip the browser half entirely.
MIT