Skip to content

Commit d948265

Browse files
authored
Merge pull request #5040 from cardstack/docs-sf-local-testing
Add local-testing guide for the software factory
2 parents 300beb1 + 6f07688 commit d948265

1 file changed

Lines changed: 209 additions & 0 deletions

File tree

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
# Testing the Software Factory Locally
2+
3+
This guide walks through running the software factory on your own
4+
machine, two ways:
5+
6+
1. **Scripted** — the Node orchestrator (`pnpm factory:go`), which
7+
drives the loop itself using Claude's and opencode's SDKs.
8+
2. **Umbrella skill** — an interactive Claude Code session that runs
9+
the whole loop by following `docs/runbook.md`; there is no
10+
orchestrator process, the agent drives every step.
11+
12+
Pick whichever you want to exercise — the prerequisites are shared.
13+
14+
## Prerequisites
15+
16+
### 1. Download the latest Boxel CLI
17+
18+
The factory and the interactive flow both shell out to the published
19+
`@cardstack/boxel-cli`. Install (or upgrade) it globally:
20+
21+
```bash
22+
pnpm i -g @cardstack/boxel-cli@latest
23+
boxel --version
24+
```
25+
26+
`boxel --help` should list `lint`, `parse`, `test`, `realm`, and
27+
`profile` among the subcommands. If any are missing, you're on an old
28+
build — re-run the install above.
29+
30+
### 2. Make sure a Boxel profile is selected
31+
32+
Auth comes from the **active** Boxel profile. List your profiles and
33+
confirm one is marked active:
34+
35+
```bash
36+
boxel profile list
37+
```
38+
39+
If none is active (or the active one points at the wrong realm
40+
server), add or switch to the right one:
41+
42+
```bash
43+
# First time — interactive wizard (environment + credentials)
44+
boxel profile add
45+
46+
# Already have profiles — switch the active one
47+
boxel profile switch <profile-id>
48+
```
49+
50+
Concrete example:
51+
52+
```bash
53+
boxel profile switch localhost
54+
```
55+
56+
### 3. Check out the boxel repo and navigate to the software factory
57+
58+
```bash
59+
git clone https://github.com/cardstack/boxel.git
60+
cd boxel/packages/software-factory
61+
```
62+
63+
If you already have the repo, just:
64+
65+
```bash
66+
cd <path-to>/boxel/packages/software-factory
67+
```
68+
69+
The realm server at the URL you target must be reachable. If you're
70+
publishing to **staging or prod**, it's already running — you just
71+
need a profile whose credentials point at it (see step 2). If you're
72+
working **locally**, start it yourself with `mise run dev-all` from
73+
the monorepo root (starts realm server, host app, icons server,
74+
Postgres, Synapse).
75+
76+
---
77+
78+
## Section 1 — Running the scripted software factory
79+
80+
This is the Node orchestrator. It owns the loop: it picks the next
81+
unblocked issue, hands it to the agent (Claude's Agent SDK by default,
82+
opencode for the OpenRouter backend), runs the validation pipeline,
83+
and repeats. You run one command and watch it go.
84+
85+
**Generic command:**
86+
87+
```bash
88+
pnpm factory:go \
89+
--brief-url <BRIEF_URL> \
90+
--target-realm <TARGET_REALM_URL> \
91+
--enable-boxel-ui-discovery \
92+
--debug
93+
```
94+
95+
- `--brief-url` — the source brief card describing what to build.
96+
- `--target-realm` — the realm the factory creates and writes to
97+
(trailing slash, URL form).
98+
- `--enable-boxel-ui-discovery` — let the agent discover and reuse
99+
existing boxel-ui components.
100+
- `--debug` — verbose logs: LLM prompts, tool calls + results, and
101+
QUnit `console.log` output as tests run.
102+
103+
> **Testing discovery?** `--enable-boxel-ui-discovery` is not on
104+
> `main` yet — it lives on the
105+
> `cs-10527-component-specs-for-searchable-reusable-ui-components`
106+
> branch (CS-10527). Check that branch out before running with the
107+
> flag, otherwise `factory:go` rejects it as an unknown argument:
108+
>
109+
> ```bash
110+
> git checkout cs-10527-component-specs-for-searchable-reusable-ui-components
111+
> ```
112+
113+
**Concrete example (local):**
114+
115+
```bash
116+
pnpm factory:go \
117+
--brief-url https://localhost:4201/software-factory/Wiki/sticky-note \
118+
--target-realm https://localhost:4201/user/sticky-note/ \
119+
--enable-boxel-ui-discovery \
120+
--debug
121+
```
122+
123+
**Concrete example (staging):**
124+
125+
Switch to a staging profile first (`boxel profile switch <staging-id>`),
126+
then point both URLs at `realms-staging.stack.cards`:
127+
128+
```bash
129+
pnpm factory:go \
130+
--brief-url https://realms-staging.stack.cards/software-factory/Wiki/sticky-note \
131+
--target-realm https://realms-staging.stack.cards/<your-username>/sticky-note/ \
132+
--enable-boxel-ui-discovery \
133+
--debug
134+
```
135+
136+
A successful run logs the seed issue, then each outer cycle as the
137+
agent bootstraps the project and works through the implementation
138+
issues, finishing with `outcome=all_issues_done`. See the README's
139+
["What to expect on the command line"](../README.md) section for the
140+
full log shape and the resulting target-realm artifact tree.
141+
142+
**See the result:** open the Boxel host app and navigate to the
143+
target realm to browse the generated Project, Issues, card
144+
definitions, instances, and Spec.
145+
146+
- Local: `https://localhost:4200/user/sticky-note/`
147+
- Staging: `https://boxel-host-staging.stack.cards/<your-username>/sticky-note/`
148+
149+
---
150+
151+
## Section 2 — Running the factory using the umbrella skill (`runbook.md`)
152+
153+
Here there is **no** orchestrator process. You open an interactive
154+
Claude Code session from `packages/software-factory/` (so the
155+
`.claude/skills` symlink is discovered) and give it one instruction;
156+
the agent follows `docs/runbook.md` end-to-end — bootstrap, per-issue
157+
implementation, validators, and project completion — in a single loop.
158+
159+
Open the agent and paste the instruction.
160+
161+
**Generic prompt:**
162+
163+
```
164+
Run the software factory per docs/runbook.md.
165+
Brief: <BRIEF_URL>
166+
Target realm: <TARGET_REALM_URL>
167+
```
168+
169+
**Concrete example (local):**
170+
171+
```
172+
Run the software factory per docs/runbook.md.
173+
Brief: https://localhost:4201/software-factory/Wiki/sticky-note
174+
Target realm: https://localhost:4201/user/sticky-note/
175+
```
176+
177+
**Concrete example (staging):**
178+
179+
With a staging profile selected, point both URLs at
180+
`realms-staging.stack.cards`:
181+
182+
```
183+
Run the software factory per docs/runbook.md.
184+
Brief: https://realms-staging.stack.cards/software-factory/Wiki/sticky-note
185+
Target realm: https://realms-staging.stack.cards/<your-username>/sticky-note/
186+
```
187+
188+
> Always include "per docs/runbook.md". Without it, the agent falls
189+
> back to the SDK-orchestrator path described in this package's
190+
> `CLAUDE.md` instead of driving the loop itself.
191+
192+
**See the result:** when the run finishes, open the Boxel host app
193+
and navigate to the target realm to browse the generated Project,
194+
Issues, card definitions, instances, and Spec.
195+
196+
- Local: `https://localhost:4200/user/sticky-note/`
197+
- Staging: `https://boxel-host-staging.stack.cards/<your-username>/sticky-note/`
198+
199+
This is an example of what you should be seeing when you visit the newly created realm:
200+
201+
<img width="1889" height="1176" alt="image" src="https://github.com/user-attachments/assets/0ab22084-94a8-421b-831a-e6f54ec083bb" />
202+
203+
If you click on Issue Board, you will see that the software factory marked all the tickets as "Done":
204+
205+
<img width="1457" height="957" alt="image" src="https://github.com/user-attachments/assets/92fbbafa-3478-43aa-a93b-48bde4d9ea65" />
206+
207+
208+
For the full breakdown of every step the agent performs, what it
209+
invokes, and the expected output, see [docs/runbook.md](./runbook.md).

0 commit comments

Comments
 (0)