Three repositories, one workflow
You hand a ticket to one command. It reads the issue, explores the code, writes a plan for you to approve, implements it test-first, has two or three AI models review the result, commits, opens the pull request and reports back. Three repositories make that possible, and each does a completely different job. This page explains which does what, and how they fit together.
Think about how a crew works. There is a process that knows what order the work happens in, there is the craft knowledge of how things are built in this particular shop, and there are the actual tools and eyes on the job. These three repositories are exactly those three things.
multi-agent-pipeline
The part that knows the order and refuses to skip steps. It drives a ticket all the way to a merged pull request: analyse, plan, build, review, commit, report. It knows what needs your approval, what is a hard stop, and where to loop back and try again.
multi-agent-plugins
The answer to how we build things here, one answer per stack: iOS, Android, frontend, backend and shared. Folder shape, naming, which layer may know what, how tests are written. The pipeline consults this knowledge while it builds instead of carrying it inside itself.
multi-agent-toolkit-mcp
The server that lets the AI actually launch the app, tap a button, take a screenshot, run a build and audit a package. Without it the AI can only read code. With it, it can look at the result of its own work.
They change at different rates, and each is useful on its own. The process can stay still for months. A stack's conventions change whenever that stack evolves. The toolkit grows when a new device capability appears. If they were one repository, every small convention change would force a release of the whole pipeline. The toolkit in particular stands alone: it gives any AI editor control of a simulator, whether or not the pipeline is involved.
The three repositories at the top. The three command-line tools that run them in the middle. At the bottom, the systems a run talks to and the durable trace it leaves behind.
Eight phases in order. Two of the arrows go backwards and one is a shortcut the fast modes take. Those three arrows are the reason this is worth drawing rather than listing.
There are not nine unrelated modes to memorise. There are three independent switches, and the nine names are just the useful combinations of them.
depth
Depth is a question, not a flag. Phase 0 asks Full or Short: Short drops analysis and planning and starts writing immediately, with a stronger model doing the writing. Pick it when you already know what changes.
local
By default the work happens in a separate checkout of the same repository, so your own working copy is never touched and two tasks can run side by side. A local mode works directly in the checkout you are sitting in, which is simpler when you want to watch it happen.
autopilot
Interactively it stops for the plan, the commit and the pull request. On autopilot it resolves those to sensible defaults and writes down what it chose. It still stops for review findings, for a build that will not go green, and for the reporting step.
Two of those switches are commands; the third is not. Worktree and questions are chosen by which entry you type. Depth is asked once, at Phase 0 Step 7.5, and recommended from the task type - which is why there is no fast-and-unattended entry: autopilot may not ask, and an unwatched run is the worst place to drop analysis and planning. And ship is the odd one out: it skips the writing entirely and runs the tail of the pipeline over work you already did by hand.
You choose how much ceremony a task gets. The full pipeline asks about everything. Autopilot resolves the defaults itself. The fast modes skip analysis and planning, go straight to building, and use a stronger model while doing it.
| Mode | Phases | Worktree | Asks you | Dev model |
|---|---|---|---|---|
/multi-agent | 0 1 2 3 4 5 6 7 | yes | at every step | Sonnet |
:autopilot | 0 1 2 3 4 6 7 | yes | only at reporting | Sonnet |
:local | 0 1 2 3 4 6 7 | no | at every step | Sonnet |
:local-autopilot | 0 1 2 3 4 6 7 | no | only at reporting | Sonnet |
Step 7.5 → Short | 0 3 4 5 6 7 | yes | at every step | Opus |
:analysis | 0 1 2 4 6 7 | no | at every step | Fable |
:resume-local | 0 4 5 6 7 | no | at every step | none, the branch diff is the input |
A check that cannot fail is worse than no check, because the green tick gets read as coverage. So every gate declares which side of the line it is on, and several deliberately stay closed when the evidence is missing.
| Gate | Phase | Kind | What it prevents |
|---|---|---|---|
| Init exit gate | 0 | stops | A run entering analysis with no task type or design access on record |
| Design access | 0 | stops | UI derived from a text description instead of the design |
| Analysis validator | 1 | stops | A malformed analysis reaching the planner |
| Reuse discovery | 1 | stops | A second copy of something that already exists |
| Plan validator and approval | 2 | stops | An unexecutable or unapproved plan reaching the build |
| Autopilot safety classifier | 2 | pauses | Unattended execution of a plan that deletes or migrates data |
| Build queue lock | 3 | serializes | Two builds racing on the same output |
| Build, lint, tests, secrets | 4 | stops | Spending review budget on a change that does not compile |
| Evidence gate | 4, 6 | stops | A claim that the build passed with no log that shows it |
| Test integrity | 4 | raises blockers | Tests weakened or deleted until the suite turns green |
| Visual conformance | 4 | stops | A component drifting away from its design |
| Diff risk score | 4 | advisory | Nothing. It routes attention, it is not a gate. |
| Secret and attribution hooks | 6 | stops | Committing a token, crediting a bot, force-pushing a protected branch |
Each specialist is defined once and states a tier, not a model name. Every CLI maps that tier onto a model it can actually reach, so one definition works in three places.
| Specialist | Phase | Tier | What it does |
|---|---|---|---|
code-reviewer | 4 | fable | Member of the review panel |
ios-architect | 2, 4 | fable | iOS structural judgement |
android-architect | 4 | fable | Android structural judgement |
backend-architect | 4 | fable | API and service judgement |
security-auditor | 4, 5 | opus | Security and store compliance |
dev-critic | 3.5 | sonnet | Critiques the code before review sees it |
explorer | 1 | sonnet | Scans the codebase in parallel |
task-clarifier | 0 | haiku | Scores how ambiguous the request is |
How you build a screen in an iOS project has nothing to do with how you add an endpoint in a backend. The pipeline does not carry those answers inside itself. It asks that stack's plugin.
| Plugin | Version | Skills | Covers |
|---|---|---|---|
ai-ios-toolkit | 0.7.3 | 147 | iOS and SwiftUI: architecture, code style, file placement, navigation, forms, previews, Figma to component, Code Connect, build and test |
ai-backend-toolkit | 0.1.5 | 33 | Service side: creating and evolving endpoints, auth, data, validation, security, the OpenAPI spec |
ai-android-toolkit | 0.1.4 | 30 | Android and Compose: architecture, state, navigation, testing, Gradle |
ai-frontend-toolkit | 0.1.4 | 25 | React and Next.js: components, state, routing, styling, accessibility |
ai-common-toolkit | 0.2.6 | 11 | Stack-agnostic: accessibility audit, plain-language editing, backlog, decision council |
index
One entry point that decides which skill should answer a given request.
reference
Knowledge to read, not steps to run: layers, naming, file placement, which unit may know what.
workflow
Create a screen, evolve a component, fix a bug, branch and open a PR. Imperative and ordered.
tools
Figma data, Code Connect mappings, component documentation, resource registries.
knowledge
Framework and API depth. Never hand-written here: it is generated from the pipeline, and the next build overwrites it.
A model being able to read code does not mean it knows whether what it wrote works. This server closes that gap: it can launch the app, tap it, take a screenshot, run a build, and audit the package before submission. All 84 tools over a standard MCP connection.
| Family | Count | What it does | Who uses it |
|---|---|---|---|
ios_* | 38 | Drives the simulator: screenshots, taps, typing, permissions, locale, location, push, appearance; plus a build wrapper and result drill-down | Phase 5 device checks, design check, store readiness |
android_* | 30 | The same surface for the emulator: install, navigate, permissions, dark mode, font scale, logcat, APK audit | The same consumers, Android side |
web_* | 8 | Headless browser: go, click, type, evaluate, wait, read text, screenshot | Frontend work and verification |
design_* | 6 | Opens the app in mock mode, enumerates every state, compares it to the Figma variant pixel by pixel | The design check command |
agent_run_steps | 1 | Runs an array of steps in a single round trip, for login and form flows | Multi-step manual test paths |
The server runs independently of the pipeline. It connects to any MCP client, because it is a plain stdio MCP server. Some pipeline skills declare a minimum version, so when the server moves it has to ship: the sync step has its own gates, from a syntax check to package completeness to the advertised tool count matching the real one.
The same tree installs into three places, in three different shapes, because the three hosts disagree about how skills are discovered and how much of a prompt survives.
Codex collects the name and description of every skill it finds into one block, and silently drops the overflow. It does not warn. This was measured, not assumed.
The same scripts have to run on macOS, Linux and Windows. That is a contract, not an aspiration: at the end of every sync each shell script is syntax-checked and scanned for patterns that are not portable.
| Platform | How it is detected | What changes |
|---|---|---|
| macOS | $OSTYPE is darwin* | BSD file timestamps; secrets in the Keychain |
| Linux | $OSTYPE is linux* | GNU file timestamps; secrets in libsecret |
| Windows (Git Bash) | $OSTYPE is msys or cygwin | The home directory resolves under /c/Users/; secrets in Credential Manager |
| Windows (WSL) | /proc/version mentions Microsoft | The Linux toolchain, inside WSL |
A task rarely arrives self-contained. Six typed fetchers pull in the surrounding evidence, and six channels write the result where people are already looking. Neither has an address or a secret hard-coded: addresses come from preferences and secrets from a keychain mapping.
| Source | What it brings in | If it fails |
|---|---|---|
| Confluence | Feature specification pages | The run continues |
| Swagger / OpenAPI | Endpoint contracts | The run continues |
| Crashlytics | The stack trace behind a reported crash | The run continues |
| Graylog | Service logs for a transaction id | The run continues, but not silently |
| Fortify | Security scan findings | A critical finding stops review |
| Figma | Design truth: screenshots, tokens, component mapping | If all three tiers fail, the run stops |
| Channel | What it writes | The rule it respects |
|---|---|---|
| Pull request | A description with fixed sections: summary, changes, architecture, verification, dependencies, related | A Bitbucket update must not clear the existing reviewers |
| Jira | One comment: summary, test scenarios, source references | It writes once, no matter how many PRs opened |
| Confluence | A page under a parent you choose | Design frames upload as attachments, never hotlinked |
| Wiki | A component page, per-platform sub-pages, screenshots, a status board | It only opens for component work |
| GitHub issue | A comment plus a progress-flag update in the issue body | The issue is never closed, and comment and flags are both or neither |
| PR review | One inline comment per finding, anchored to a line, plus a review state | One big lumped comment is forbidden |
Most of what follows exists because the opposite behaviour shipped once and cost something.
And passing means a log that shows it. A self-assertion does not count as a build.
Auto-close keywords are forbidden in commits, PR titles and bodies. Closing is a human decision.
The cleanup step has a safe skip path and never force-removes.
If a variant, spacing or string is missing, the run stops and asks for the analysis to be regenerated. Substituting something close has cost rebuild rounds.
Not in commits, not in PR bodies, not in code comments. The author is always the user's identity.
If a question is submitted blank it is asked again, never resolved to a default.
Every number describing how many commands exist is computed from the tree, and a gate requires the prose to agree.
The runner fails a suite that exits successfully having checked nothing. Three suites were doing exactly that.
On top of those sit 137 smoke suites, a separate parity gate per host, an install fingerprint that catches structural drift, and a registry where a command name may only disappear through a recorded rename.