Repository navigation
feat: per-step agents, subagents, teams, skills and MCP tools - #88
Merged
Merged
Conversation
…arding Sessions load the machine's and the repo's MCP servers, but a -p session cannot ask, so every MCP call was refused outside plan mode. MCP allow rules in claude.mcp_tools now reach every tool set, judges included. Entries must be mcp__ rules without commas, since the list reaches the CLI comma-joined. The operator skill lists the MCP tools its session has and writes the ones the engineer picks. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…dits Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e agents Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orts Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
runPhase passes --agents, --agent, --setting-sources, --add-dir and --forward-subagent-text when set (after the tool lists, before --settings). checkInit judges the session's first init event that lists agents or skills; a problem ends the session at once as a "setup" failure. A stop or a cancel still wins; setup is not an outage and is not retried. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each attempt reads its step's setup fresh (StepContext.models now carries agents, as it does models). An empty setup passes nothing new, so argv and prompt stay byte-identical. Otherwise the session gets the setup's tools and mcp_tools, its agent and every subagent and team member inline from main's snapshot (--agents, --agent), --setting-sources project plus the user's apiKeyHelper and env for sources: repo, main's snapshot as --add-dir for a worktree step with skills, --forward-subagent-text with subagents or teams, and an init check. A named agent that is not found fails the step with reason setup before a session starts. The setup is traced as agent_setup on the phase row; prompts carry setupLines in place of the skills line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ts refused
A setup changes how a session runs only when the step's agent settings
give it something; a stage's skills alone are the prompt's first line, as
before (no snapshot, --add-dir or init check). {{commands}} also lists the
Bash rules from the step's setup tools. A built-in agent as a step's (or
all's) agent is a config error: its fixed tools have no StructuredOutput.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…mpt unchanged Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riters out of the snapshot A writing session that loads skills gets main's snapshot as an added dir, and --add-dir also lets it edit there; later phases of the same step read their agent files from that snapshot, so a revise session could rewrite the reviewer the next review round runs as. - A loop step's repository agent files are read from the step's commit of main (git cat-file), never a checkout. Personal and plugin files are still read from disk; chat still reads the main checkout. - A session given the snapshot as an added dir also gets Edit, Write and NotebookEdit denied under it (`//<path>/**`), returned by setupSession as `deny` and added to the loop's own deny list. - setupSession's run options are typed to what the setup sets (SetupRunOptions), and chat spreads them before its own fields, so its allow and deny lists, folder and environment always stand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ain's snapshot cannot be made The agent check ran before the lock, so a second start made and removed a snapshot under the running loop's .loopstra/snapshots/, and an unresolvable main_branch threw a stack trace. It now runs once the lock is taken (the lock is let go when it refuses), and a failure making or reading the snapshot is a refusal that names main_branch. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It sat inside `claude:` at two spaces, so uncommenting it gave claude.agents, an unknown key. It is now its own paragraph at column 0 after `stages:`, and a test pins that it is the template's top-level placeholder and loads once uncommented. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
checkAgentSetup repeated build's missing agent for fix, reconcile and revise (which run as build's) and agents.all's for every step. The agent a step runs as is now checked where it is set: once under "all" for agents.all's, and not again for the steps that continue the build. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A non-empty agents or skills list without a single string (a shape Loopstra does not know) was taken as "present and empty", so every named agent or skill looked missing. It now counts as absent, like an event without the list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…order mark Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…le the plugin A plugin that is installed but not enabled is not looked in, so its agents and skills read as missing. With sources: all, the text for a `plugin:name` now says to enable the plugin in Claude Code (a repo-only setup never loads plugins, so it does not). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…art check under the lock Records that --settings still applies under --setting-sources project (checked live on CLI 2.1.311: a PreToolUse hook passed in --settings ran), so the test-protection hook holds with sources: repo. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… (lint) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ter regex Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…line text Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rding Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GET /api/agents shows each step's own, inherited and stage agent setup, the teams, the library with who uses each item, and the setup check's problems. GET /api/agents/source clones a git repository or folder into a temporary folder, lists its agents and skills, and removes the folder. POST /api/agents/files turns copy, fetch, new, edit and remove into an agent-files request with bases read from the checkout, refusing early what the loop would refuse (in use, already there, stale, links, uncommitted files). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A remove, and a copy, fetch or new that replaces, now names the version of the agent file or SKILL.md the page read; a stale one is refused, and the request's base takes the page's version (an edit's too) rather than reading the file again. Files added new are based as absent. Both settings views share one readConfig; only agents named as Loopstra names them are editable; AgentField is exported for the page. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Under the models: the agent setup problems (fails first), where steps find agents and skills, each step's six fields with their effective value and where it comes from, the teams, and the library (in the repo, on this machine, from plugins) with add, edit, remove, adding from a git repository or folder, and a new agent. Every write goes through the page's one pending change, with Cancel, as the models do. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The tools and MCP tools inputs showed example rules as placeholders on every row, which read as configured values. An empty field now shows what the step gets beside it (the inherited value and where from, or none); only the All steps row keeps a neutral "comma-separated" hint. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…other name or edit it Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ing needs Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…nce, where it is set A name a step gets only through agents.all is checked and reported once under all, a stage's skills once under stage <name>, and what a step sets itself under that step: setup --check, start and the console no longer repeat one line per step. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… step gets, problems show names as code Adding from a git repository or folder asks "Replace it?" before it replaces the repo's items. A list picker's summary is the step's effective list with inherited names marked. The problems callout shows backticked names as code, as a status. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With --forward-subagent-text a subagent's events carry the id of the Agent/Task call that started it. toItems now marks each of their rows with that id (parent) and turns the subagent's first event, its prompt, into a delegated row rather than a person's message. The page nests those rows under the call: a collapsible "Handing off to <agent>: <description>" block holding the prompt (closed), the subagent's words and calls, then the call's result. Rows whose call is not on the page stay where they are and say they come from a subagent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e chat context names a subagent's prompt The transcript's one grid column was as wide as its widest row, so a subagent's summary or prompt line widened every row past a phone's width. It is now as wide as the box, and long targets ellipsize. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s todos out of the session's, label its lines for chat Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…README How it works now opens with a diagram of the statuses and gates, and has a table of every step, a gate diagram and table, the build and review loops, and where sessions read and write. A new Agents for each step section holds what the Configuration bullet said, with diagrams of how a step's setup is built and how subagents and teams are used, and a table of the flags each setting becomes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CodeQL (js/file-system-race): a skill file was checked with lstat and then read again by its path, so a file swapped for a link in between would be followed. Each file is now opened once without following links or waiting on a pipe, and whether it is a plain file, its size, whether it is binary and its text all come from that open. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- --agents and --settings go to the CLI as owner-only files in a temporary folder per session, removed when it ends: the user's env and apiKeyHelper no longer show in the process list, and a large agent setup no longer passes the limit on an argument's length. Checked live on 2.1.311. - The git rule check sees wildcards (Bash(git c*), Bash(g* push *)) and git after env, command, sudo and the like or VAR=value. - A read-only step refuses every match-all Bash rule (Bash(:*), Bash(**)) and MultiEdit. - A subagent's todo list is a row in its block instead of being dropped. - The agent_setup event records each team's members, and the session's facts show them with their models. - Only a step that names skills makes the snapshot of main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lets each loop step (and chat's orchestrator and write-intent) choose its agent, subagents, teams of subagents, skills, tools and MCP tools. Setup, the console and the operator skill can all edit these settings. With no
agentsblock, sessions start exactly as before, and tests pin that. Includesfeat/mcp-tools(mcp_toolsin every tool set, with MCP tools chosen during onboarding) and a merge of #87.Spec:
docs/superpowers/specs/2026-10-26-agent-setup-design.md. Plans 1–4 are indocs/superpowers/plans/, and the decisions are indocs/decisions.md.Runtime
New top-level
agentsblock, withallplus one entry per step:agent,subagentsandteams(named groups runparallelor bypick);skills,toolsandmcp_tools;sources: repo, which loads only what the repo declares.claude.mcp_toolsmoved toagents.all.mcp_tools.Enforced rules:
Repo agent definitions are read from main's commit, so a change can't rewrite the agent that judges it. Writers given
--add-dirget deny rules for that snapshot.When a session starts, its
initis checked against the setup. A missing agent or skill stops the step with asetupfailure that says what's missing.loopstra startrefuses while a step names an agent that doesn't exist.Setup
loopstra setup agentssets each step's agents, subagents, teams, skills and tools. It adds skills and agents from this machine, a plugin, a git repository or folder, or a short form:.gitis never copied.Console
Settings has an Agents section that edits the same values and shows where each one comes from (step,
allor default). It can also copy, fetch, create, edit and remove agent and skill files.The console never writes the repo. The loop applies each
agent-filesrequest and commits it. A change is refused if:Request text can't carry control characters, so it can't forge a trailer.
The session page shows what a step ran as. Each subagent's work is nested under the call that started it, and a subagent's prompt is never shown as a person's message.
Verified with the real CLI (2.1.311)
--agentswith--agentkeeps structured output only when the agent's tools includeStructuredOutput.--disallowedToolsalso binds subagents.--setting-sources projectkeeps--settingshooks.parent_tool_use_id.Live runs: an intake ran as an inline agent, and a change went to
donewith build running as a custom agent. The fix sessions kept the build's session.Known and not addressed here
A build session can still influence later sessions of the same step through its change's
.claude/skills,.claude/settings.json,CLAUDE.mdor Bash. This predates the PR. Agent definitions are protected; closing the rest needs a tighter setup for judges.Verification
bun run checkpasses: typecheck, lint and deadcode are clean, and 1836 tests pass. Each task was reviewed, and each of the four parts had a final review and a re-review after its fixes. Browser checks covered phone and desktop widths, light and dark.🤖 Generated with Claude Code