playwright
Drives a real browser so the agent can open pages, click, fill forms and read what actually rendered.
Claude Code
$ claude # or moai cc — run Claude Code inside the project
Codex
$ claude # or moai cc — run Claude Code inside the project
Cursor
$ claude # or moai cc — run Claude Code inside the project
Gemini CLI
$ claude # or moai cc — run Claude Code inside the project
GitHub Copilot
$ claude # or moai cc — run Claude Code inside the project
OpenCode
$ claude # or moai cc — run Claude Code inside the project
Windsurf
$ claude # or moai cc — run Claude Code inside the project
Security report
Not enough data
Known flaws
Not published
Signed build
Not published
Maintained
Nov 12, 2026
Last push
Licence
Apache-2.0
Runs as
Local process
On your machine
Deprecated
Not published
Signals from public registries, not an audit. Checked Nov 12, 2026.
moai-adk README

A verification-driven agent orchestration harness — the structure that makes Claude Code's code trustworthy
English · 한국어 · 日本語 · 中文
Official Documentation · Book: Practical Agentic Coding with Claude Code · Discord
"The model is a stochastic worker moving token by token. It cannot remember, turn to turn, what it used this turn and how much, whether the result is good, or how far the last session got. A harness enforces all three from the outside."
What's New in v3.2 — Factory Mode
A session spends one context window. A long SPEC fills it, and every later task carries everything before it. The plan is long finished yet stays in the window through the whole review, and the review stays through the whole write-up. The usual escape, /clear, throws away the context along with the baggage.
Factory Mode splits the work across one leader session and several numbered lane sessions. The leader watches the queue and hands cards to free lanes. A card does not change sessions at each stage; it goes whole into one lane, and that lane carries it through plan → run → sync in order, inside its own session. Each stage is spawned as an Agent() subagent, and the lane itself only orchestrates. Nothing is uncapped: each session's limit is still there. What changes is that one card's history accumulates only in the lane that owns it. The same budget therefore goes much further, and a lane empties its context after each card before taking the next.
Getting started
moai cc -f # leader — opens the factory
moai cc -l # a lane, each in its own terminal — joins as the next free number
moai cc -l # lane-1, lane-2 … in order
moai glm -l # a lane on the GLM backend
-f (long form --factory) opens the leader, and -l joins the running factory as a lane. Neither takes an argument. The operator never picks a lane number; it is assigned automatically. Lanes are launched by hand, one fresh terminal each, because a session cannot launch another session.
A launch carries one entry token, so -f together with -l is an error. A value after either token (moai cc -f <value>, moai cc -l lane-2) is refused with a one-line error that names the correct form. The -k entry of the former multi-session board mode is removed.
Which backend to run
The backend is chosen per lane: moai cc -l is a Claude lane, moai glm -l a GLM lane. The leader's seat is not for passing verdicts but for watching the queue and carrying cards, so GLM (moai glm -f), which is cheap to leave waiting, suits it. When one account starts hitting 429s, spreading lanes across accounts works. This mix is only one example — putting every session on a single backend is fine too.
Many cards at once across N lanes
Grow the run one lane at a time by running -l once more. The number is assigned automatically, so passing --name/-n alongside is an error. A number is skipped only while a live session holds it — a dead lane's claim no longer blocks its number, but automatic assignment always takes the highest live number + 1, so it never backfills a gap in the middle. Lane ownership is recorded in ~/.moai/db/<project-key>/factory/factory.db. When the base directory is a temporary directory (and no absolute MOAI_HOME override is set), it is recorded under the project-local <base>/.moai/db/<project-key>/factory/ instead — the same exception the backlog queue makes. The old .moai/state/factory/workers.json is imported once and kept only as rollback evidence.
Find the database paths with moai paths instead of guessing them. Opening a guessed path such as ~/.moai/db/todo.db with sqlite3 creates an empty file, so never do it. If you must read directly, read only a snapshot copy of .db, .db-wal, and .db-shm together; otherwise prefer the CLI, such as moai todo list --json and moai factory status.
A lane runs at most 10 Agent() subagents at once, and write-capable spawns are isolated in their own worktrees. Don't light up the lanes all at once: bring up the first lane, confirm it is actually producing output, then start the rest. A card is never split across lanes.
A factory run records the process identity of the session that owns it. A run whose leader has died is retired automatically when the next lane joins, so the join does not stall on AMBIGUOUS_FACTORY. The reverse is covered too: when a lane joins and the run record is missing or retired while a live leader session exists, the join verifies that leader (pid plus process start fingerprint; the target is picked with the long form --leader <name>, default leader), restores the run record, and joins as usual — with more than one verified leader it fails closed, naming every candidate. --leader is a selector that composes with -l only; it is not a short form of any entry token. moai factory runs lists every run with its owner's liveness, and moai factory runs --retire <run-id> retires one named run by hand. It refuses if the owner is not actually dead, and it also refuses when the run still holds cards that are not done, failed, or abandoned: it lists those cards together with the exits you can use instead (join with moai cc -l --factory-run <run-id>, adopt with moai cc -f --factory-run <run-id>, or end each card with moai factory decide <card> --choice abandon --run <run-id>). Joining and adopting work only while the run is active, and abandoning a card cannot be undone. There is no force flag. Pointing it at a run that is already retired reports the result without a second write and lists the cards still stranded there. For an active run that still holds such cards, moai factory relaunch --from-run also leaves the run active and reports left active (N in-progress cards); an already-retired run is left untouched (not active (retired), left untouched).
After a run dies or is replaced, a lane session keeps pointing at the old run baked into its environment. Reattach it to a live run with moai factory relaunch. The command re-executes the provider's own lane-join line (moai cc -l, moai glm -l), and its options are --provider, --lane, --run, --from-run <run-id> and --dry-run. Because -l takes no argument, a --lane you pass is not carried onto the join line: the command says so on stderr, and the lane joins as the next free number. --from-run retires that run first, but only when it is active and its owner is dead, and --dry-run prints the launch line and changes nothing. It is a one-shot command, separate from the --clear-policy relaunch loop that walks cards inside one run. The stale-run notice now shows this command filled in, instead of prose.
Details: Factory Mode
Cards start in the queue. backlog has no owning session by design, so work enters the queue only when you put it there:
/moai gtd "fix the stale rename hint" # append a card
/moai gtd # list the queue
/moai gtd is the canonical task-management surface. /moai todo remains a compatibility name backed by the same SQLite queue, card IDs, order, and archive/restore behavior. moai gtd capture|clarify|organize|reflect|engage carries an item through Capture → Clarify → Organize → Reflect → Engage before approved work enters the unchanged backlog → plan → run → sync → done development flow. SQLite operation receipts and authoritative readback prevent a retry after a crash from silently duplicating publication, pick, or dispatch.
Two rules keep the factory honest. The leader advances a card only on evidence it read from the card's progress.md — never on a lane's reply, because a reply is a claim and inter-session delivery is not guaranteed. And when a card finishes, the lane asks for a /clear, since /clear is user-typed and cannot be sent as an instruction (--clear-policy changes this).
Words the factory uses
The recurring vocabulary of the factory docs, gathered in one place. The leader is the session that watches the queue and carries cards; a lane is the pair of a session and its worktree that carries one card through to the end.
| Word | One-line definition |
|---|---|
| Card | One unit of work. Enters through /moai gtd and is called by a short id |
| Backlog | The entry queue. It has no owning session, so only a person can put cards in |
| Leader | The coordinating session. Advances cards on evidence it read and never writes code itself |
| Lane | A session + worktree pair that carries one card to the end. One parallel work stream, numbered lane-1, lane-2 … automatically |
| Run id | The short identifier of one factory run. When several runs are alive, --factory-run <run-id> picks which one to join |
| Worktree | An isolated checkout just for the card. Its directory is the card id, its branch a WT-<slug> describing the work |
| Dispatch | The instruction the leader sends a lane — a pointer to the work, not a copy of it |
Cards differ in shape, and so do the stages a lane runs. When a card leaves the queue the leader sorts it into one of three classes and names it in the dispatch.
| Class | Shape | Shortcut |
|---|---|---|
| A — direct close | One file, one line, no design judgement, CI catches the regression | One lane takes it all the way to the PR (plan skipped) |
| B — defect, cause unknown | Clearly broken, cause not yet established | run → sync (no plan, no SPEC) |
| C — design change | Contains a decision, or spans subsystems | All three stages |
Class A is admitted on checked evidence, not assertion — a card that cannot cite a diff measured to one file and green CI on the head that will merge is not Class A. Class B skips only plan; the sync gate's review still runs, and the cause-establishing evidence (reproduction command and its output) is left in the card's progress record.
Watching the factory
moai web serves a local console. The Factory screen shows the factory lanes alongside the SPEC pipeline, plus Overview, Specs, Monitor, Settings, and Todo screens.

Full guide: Factory Mode · manager-lead Leader Coordinator · /moai todo
Agentic development harness for Claude Code — SPEC-driven plan/run/sync, TRUST 5 quality gates, model+effort routing, and Claude×GLM multi-LLM cost control. Single Go binary, 16 languages, zero deps.
More MCP servers from other plugins.
paperclip
MCPShips with paperclip: Open-source orchestration for teams of AI agents. If OpenClaw is an employee, Paperclip is the company.…
t
MCPShips with oh-my-claudecode: For Codex users: Check out oh-my-codex — the same orchestration experience for OpenAI Codex CLI.…
Questions about playwright.
- Which coding agents can use playwright?
- playwright works in any agent that reads an MCP config file: Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf. Each agent reads it from its own file; this page names the file for each one.

