Part 1: Software factory
You set up a software factory: a crew of Claude Code sessions that plans with you, builds, reviews and merges, with Tares keeping the plan and your answers. Then you give it a small test job and watch it go from plan to pull requests merged on main.
Time: about 30 minutes. In our run: 2 minutes to start the crew, 7 minutes to plan, 12 minutes from hand-over to the last merge.
This is the local guide: Tares runs on your laptop. The cloud guide, for a Tares workspace we host, is added here before the workshop.
Before you start
- Do the setup: Everyone, then Part 1.
- Claude Code is signed in on a plan that allows background sessions. The crew runs on your own subscription: in our run on a Max plan it used about 5% of the 5-hour limit.
gh auth statusshows you are signed in.- No Anthropic API key is needed: the crew runs on Claude Code, not on Tares agents.
What you build
The factory. A crew of Claude Code sessions running in the background on your own Claude Code plan:
- the orchestrator, which picks up planned projects and starts builders;
- a builder, which works the tickets in your repo, one pull request each;
- the reviewer, which reviews every pull request before it is merged.
Tares holds what they share: the spec, the tickets, the reviews and your answers. The factory works on any repo; nothing in it is specific to tonight.
Its test job. To see the whole loop run once, you give it a deliberately small job. The starter is a link shortener with three endpoints:
POST /linkstakes a long URL and gives back a short code, for exampleaB3_x9.GET /{code}redirects to the long URL.GET /linkslists every link.
It does not count anything: you cannot tell how often a short link was opened. The test job is a
click counter. Every redirect counts as one click, and a new endpoint
GET /links/{code}/stats shows the count for one link.
Steps
Make your own copy of the starter
Clone it too. Pick any name:
gh repo create my-link-shortener --private --template glassflow/factory-workshop-starter
gh repo clone my-link-shortener
cd my-link-shortenerYou can also open github.com/glassflow/factory-workshop-starter and click Use this template. GitHub runs CI on your copy by itself; it should pass.
See what the app does today
Start it in your repo folder:
uv sync
uv run uvicorn app.main:app --reloadIn another terminal, make a short link and keep its code in CODE:
CODE=$(curl -s -X POST localhost:8000/links -H 'content-type: application/json' -d '{"url":"https://glassflow.ai"}' | jq -r .code)
echo $CODEYou should see a 6-character code. Open it:
curl -i localhost:8000/$CODEYou should see HTTP/1.1 307 Temporary Redirect and location: https://glassflow.ai/. Now try the
stats endpoint the crew will build:
curl localhost:8000/links/$CODE/statsYou should see {"detail":"Not Found"}: it does not exist yet. Leave the app running; you use it
again in step 13.
Start Tares
In a new terminal:
tares upThe console opens at http://127.0.0.1:8787 . Leave it running.
- By default Tares listens on port 8787 and keeps its data in ~/.tares.
- Already have a Tares on 8787, or want a clean one? Pick another port and folder:
tares up --port 8797 --data-dir ~/tares-workshop. Then add--taresd http://127.0.0.1:8797to the command in step 4, and runexport TARESD_URL=http://127.0.0.1:8797in every terminal you use fortares factorycommands. Read 8797 wherever this guide says 8787.
Start the MCP endpoint the crew talks to
In another terminal:
tares mcp --transport streamable-httpIt listens on port 8788. Leave it running.
Check everything
Back in your repo folder:
tares factory doctorYou should see ok on every line except two: “Claude Code has not trusted the crew home” (FIX)
and “no crew yet” (warn). Starting the crew in step 7 clears both.
Give Tares access to GitHub
So it can follow your pull requests, CI and reviews by itself.
-
Copy the token
ghalready holds:gh auth token -
In the console at http://127.0.0.1:8787 , open Settings, then GitHub, and click Add a personal token.
-
Name:
github. Token: paste whatgh auth tokenprinted. Save.
Without this the crew still works, but it checks GitHub itself and Tares does not show the pull request state.
Start the crew
tares factory crew up- It asks to open Claude Code in the crew’s folder: pick 1. Yes, open it. In Claude Code pick
Yes, I trust this folder, then type
/exit. - Then it asks five questions, one per tab. Pick:
- Merging: The crew, once its reviewer approves and tests pass
- Releasing: No, it stops when work is merged to main
- Codex check: No (pick Yes only if you have the Codex CLI signed in)
- Builders: 1 (not the recommended 2: one builder is enough for this feature and saves your plan’s limits)
- Grants: Nothing more
- On Your answers, pick Save and start the crew.
You should see “started crew-orchestrator”, “started crew-reviewer” and “started the watch”. About 2 minutes. The crew now waits for work: the orchestrator hands projects to builders, and the reviewer reviews every pull request.
Plan the feature
In your repo folder:
tares factory spec "add a click counter: count each redirect and show it at GET /links/{code}/stats"Claude Code opens in a new spec session; trust the folder if asked. It reads the repo, then asks one question at a time, each with a suggested answer. In our run it asked four:
- The goal and the project name. Accept the suggestion.
- What the stats endpoint returns, for example the code, the URL, the click count and the time
of the last click. Accept the suggestion, and add:
keep it small: two tickets at most, one milestone. - Who builds it. Pick the tares-factory crew.
- Where the tickets live: Linear or Tares. Pick Tares.
It then writes the plan to Tares: a spec, one milestone with its checks, and two tickets. About 7 minutes. Short on time? Use the ready-made spec instead.
Hand the plan to the crew
The spec session ends with “Hand this to the orchestrator now?”. Say yes.
- The spec session tells the orchestrator there is a new project, with your repo.
- The orchestrator starts a builder: a new Claude Code session that works in your repo, one ticket at a time.
- From here the crew owns the project. Type
/exitto close the spec session; you do not need it again.
Watch it build
You can follow it in three places.
-
The Tares console. Open http://127.0.0.1:8787/crew .
- The crew shows the orchestrator and the reviewer.
- Under Projects is your project and its builder. Click it.
- The project page has four columns, Spec, Build, Review and Done, with each ticket and its pull request.
-
GitHub. Your repo gets one pull request per ticket. The builder opens it, the reviewer reviews it, CI runs, and the builder merges it. In our run the first ticket merged 7 minutes after the hand-over and the second 5 minutes later.
-
The crew’s own sessions. Open the orchestrator in your terminal:
tares factory crew attach orchestratorTo see the builder at work, run
tares factory crew statusto find its name (it ends in-build-m1), thentares factory crew attach <that name>. Only watch the builder; it needs no input from you. To leave any session and keep the crew running, press ← (Claude Code shows its list of sessions), then Esc.
Say it is done
When both tickets are merged, the project page shows “1 question waiting for you”: “Is it done?”.
Answer it in the orchestrator’s session (tares factory crew attach orchestrator): type A. Then
press ← and Esc to leave it.
Look at what Tares kept
Open the project in http://127.0.0.1:8787/crew : the spec, the milestone and its checks, both tickets in Done with their pull requests, and the reviewer’s verdict on each.
Try the feature
In your repo folder, get the merged code and run the tests:
git pull
uv run pytestYou should see every test pass, including the new click tests. The app from step 2 reloads by
itself after git pull, and it starts with no links, so make a new one and open it twice:
CODE=$(curl -s -X POST localhost:8000/links -H 'content-type: application/json' -d '{"url":"https://glassflow.ai"}' | jq -r .code)
curl -s -o /dev/null localhost:8000/$CODE
curl -s -o /dev/null localhost:8000/$CODE
curl -s localhost:8000/links/$CODE/statsYou should see your code, the URL and "clicks": 2. If the app is no longer running, start it again
with uv run uvicorn app.main:app --reload.
Finished early? Plan the README’s next idea the same way, from step 8: expiry (expires_at on
create, expired codes return 410) or tags (GET /links?tag=). The crew is still up and picks it up.
When you are done, stop the crew as in Clean up.
Ready-made spec: skip the interview
Save the spec to a file in your home folder, then, in your repo folder, hand it to
tares factory spec. The spec session asks nothing and hands it to the crew by itself, so steps 8
and 9 happen in one go. In our run it took 4 minutes instead of 7, and both tickets were merged 14
minutes after the command. Type /exit when it says it has handed the project over.
cat > ~/click-counter-spec.txt <<'EOF'
Add a click counter. Goal: count every successful redirect of a short link and expose the count at GET /links/{code}/stats. Every GET /{code} that returns 307 counts as one click; a 404 for an unknown code never counts. Each link keeps clicks (int, starts at 0) and last_clicked_at (UTC datetime, null until the first click). GET /links/{code}/stats returns 200 {"code", "url", "clicks", "last_clicked_at"} for a known code and 404 {"detail": "unknown code"} for an unknown one; fetching stats is not a click. GET /links and POST /links keep their current response shapes. Counts stay in memory like the links; no persistence, no per-day breakdown, no new dependencies. The README documents the new endpoint. Plan: one milestone, exactly two tickets: T1 record a click on every successful redirect (store and redirect handler, with tests); T2 add GET /links/{code}/stats with tests and the README line, after T1 is merged. The tares-factory crew builds it, one PR per ticket into main, merged after the reviewer passes it and CI is green; nothing to deploy. Tickets live in Tares only. Everything above is decided: ask only what is still open, then hand it to the crew.
EOF
tares factory spec "$(cat ~/click-counter-spec.txt)"You can also download the spec as a file.
What just happened
tares factory specturned one line into a plan on Tares: a spec, one milestone with checks, and two tickets, each with a working doc. A second model attacked the plan before it was written.- The orchestrator picked the project up and started a builder in your repo. The builder worked the tickets in order, one pull request each.
- The reviewer reviewed every pull request against a fixed bar. Once it passed and CI was green, the builder merged it.
- Tares kept the plan, the checks, the reviews and your answers. After the hand-over you answered one question, at the end.
If something is off
- Doctor says FIX on more than the two lines in step 5. Do what the line says. “no Tares
answers”:
tares upis not running. “no MCP server answers”:tares mcp --transport streamable-httpis not running. - Stations say skills are missing. A
taresplugin from a marketplace is taking over:claude plugin uninstall tares@tares, thentares factory crew downandtares factory crew up. - Nothing moves for a while. Run
tares factory crew status: each station says what it is doing. If the orchestrator is waiting for you,tares factory crew attach orchestrator. To stop everything at once:tares factory crew halt "why", thentares factory crew resume. - You hit your plan’s limit. Use the ready-made spec, keep Builders at 1, and switch to the cloud version if it keeps happening.
- The interview proposes more than two tickets. Say
two tickets at most, one milestone.
Clean up
-
Stop the crew:
tares factory crew downThis stops the orchestrator, the reviewer, any builder and the watch. Tares keeps the project, tickets and answers.
tares factory crew upbrings the crew back. -
Stop Tares, the MCP endpoint and the app with Ctrl+C in their terminals.
-
Your repo keeps the merged feature. Delete it on GitHub if you do not want it.