@chris1807/claude-kit 2.3.9 → 2.3.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/package.json +1 -1
- package/templates/commands/autopilot.md +3 -2
- package/templates/commands/implement.md +15 -1
- package/templates/commands/qa.md +37 -7
- package/templates/commands/repro.md +2 -2
- package/templates/commands/rework.md +15 -1
- package/templates/infrastructure/CLAUDE-WORKFLOW.md +6 -1
package/README.md
CHANGED
|
@@ -520,6 +520,8 @@ Claude will:
|
|
|
520
520
|
|
|
521
521
|
Say `/implement AB#1234 work in place` to skip the worktree and work in the current folder, as before.
|
|
522
522
|
|
|
523
|
+
Add `--opus`, `--sonnet`, or `--haiku` to run every subagent on one model instead of the default Sonnet split: `/implement AB#1234 --opus`. `/rework` and `/autopilot` take the same flag. The main loop stays on your session model, so switch with `/model opus` first if you want the whole run on Opus.
|
|
524
|
+
|
|
523
525
|
The PR merges into `main`. **That merge deploys nothing** — `main` is the compare branch. The work reaches Dev when `main` is promoted:
|
|
524
526
|
|
|
525
527
|
```
|
|
@@ -698,7 +700,7 @@ Claude reviews for:
|
|
|
698
700
|
| `/promote` | `/promote main dev` | PR to promote all code to the next branch in the chain (`main → dev → test → staging → prod`) → ask who verifies → advance + assign on a green pipeline |
|
|
699
701
|
| `/rollback` | `/rollback AB#1234 prod` | Revert specific commits on an environment via PR |
|
|
700
702
|
| `/track` | `/track release 24` | Check status of a release, pipeline, work item, or environment; flags work items whose state lags their environment |
|
|
701
|
-
| `/qa` | `/qa AB#1234 [env] [--as=<user>]` | Verify the item is fully deployed with a green pipeline → open the app in a real browser → sign in (app login form, or Microsoft — you sign in once in the browser window) and optionally impersonate a user → full regression of the screens the story touched → pass/fail comment on the work item (never a state change). Environments: `local
|
|
703
|
+
| `/qa` | `/qa AB#1234 [env] [--as=<user>]` | Verify the item is fully deployed with a green pipeline → open the app in a real browser → sign in (app login form, or Microsoft — you sign in once in the browser window) and optionally impersonate a user → full regression of the screens the story touched → pass/fail comment on the work item (never a state change). Environments: `local` (starts the API and client if they aren't running), `dev`, `test`, `staging` |
|
|
702
704
|
| `/repro` | `/repro AB#1234 [env] [--as=<user>] [--verify]` | Follow a bug's repro steps in a real browser. Before a fix: confirm it reproduces (with intermittency counts) and list the code to read. After the fix is deployed: prove it's gone, checked against a control run on a build without the fix. Mode is picked from where the fix commits are; posts a result comment (never a state change) |
|
|
703
705
|
| `/plan-backlog` | `/plan-backlog [project]` | Sweep backlog for Dev Ready stories with points and no tasks → propose one child task with hours per story |
|
|
704
706
|
| `/plan-sprint` | `/plan-sprint [project] [--next]` | Sweep the current sprint (or the next one with `--next`) for stories/bugs with no child tasks → propose one child task with hours per item |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chris1807/claude-kit",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.11",
|
|
4
4
|
"description": "Claude Code starter kit for Azure DevOps teams — agents, hooks, MCP servers, slash commands, and end-to-end work item → PR → release → deploy workflow automation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -17,7 +17,7 @@ What stays fixed:
|
|
|
17
17
|
|
|
18
18
|
## Arguments
|
|
19
19
|
|
|
20
|
-
`$ARGUMENTS` is the work item id, as `1234` or `AB#1234`. It can be followed by `work in place` or `no worktree`, the same opt-out `/implement` takes. Strip
|
|
20
|
+
`$ARGUMENTS` is the work item id, as `1234` or `AB#1234`. It can be followed by `work in place` or `no worktree`, the same opt-out `/implement` takes, and by `--opus`, `--sonnet`, or `--haiku` to pin every subagent to one model (implement.md's **Model override**). Strip both before reading the id. With a flag, the `reviewer` agent in **Independent Checks** runs on the pinned tier too, and the model note goes in the opening block instead of a Step 2 summary.
|
|
21
21
|
|
|
22
22
|
## Before Step 0: Load `/implement`
|
|
23
23
|
|
|
@@ -26,7 +26,7 @@ Autopilot executes `/implement`'s steps, so read them first: `.claude/commands/i
|
|
|
26
26
|
Run implement.md from Step 0 through Step 11, or F1 through F8 for a Feature. **This file wins every conflict with implement.md.** Three overrides apply throughout:
|
|
27
27
|
|
|
28
28
|
1. **Gates resolve without asking.** Where implement.md says to wait, ask, or prompt, or offers a `(yes / no / …)` choice, apply that gate's row in the Gate Table. For a prompt the table doesn't list, take the answer implement.md suggests (its "suggested", "recommended", or "press enter to accept" value). If it suggests none, take the option that changes the least and is easiest to undo. Log the decision either way.
|
|
29
|
-
2. **Ultracode is off, always.** Autopilot never calls the `Workflow` tool, whatever the size of the change, and skips every Ultracode callout in implement.md. An unattended run multiplies cost the most, so it runs lean. implement.md's **Model Tiers** still apply: implementers run on Sonnet, and the main loop takes a piece over when one gets stuck.
|
|
29
|
+
2. **Ultracode is off, always.** Autopilot never calls the `Workflow` tool, whatever the size of the change, and skips every Ultracode callout in implement.md. An unattended run multiplies cost the most, so it runs lean. implement.md's **Model Tiers** still apply: implementers run on Sonnet (or the tier a `--opus` / `--sonnet` / `--haiku` flag pins), and the main loop takes a piece over when one gets stuck.
|
|
30
30
|
3. **The run ends one of three ways:** a PR ready for review, a draft PR with open items (**Unfinished Work**), or a **Hard Stop**. There is no other outcome.
|
|
31
31
|
|
|
32
32
|
Open with this block, then start Step 0 without waiting:
|
|
@@ -37,6 +37,7 @@ Running /implement end to end with no approval gates. Every decision is logged a
|
|
|
37
37
|
I stop only on a hard stop; the PR is where you review.
|
|
38
38
|
Claude Code's own permission prompts can still appear. Edits in the ticket's worktree (../{repo}-AB{id})
|
|
39
39
|
prompt once unless you've added it with /add-dir or are in auto mode.
|
|
40
|
+
{only with a model flag: Subagents pinned to {tier}. This session runs on {session model}, so planning and fixes stay there.}
|
|
40
41
|
```
|
|
41
42
|
|
|
42
43
|
## Gate Table
|
|
@@ -29,6 +29,20 @@ Most of a run's tokens go to subagents re-reading their context on every turn, n
|
|
|
29
29
|
|
|
30
30
|
**Escalation keeps quality up.** The plan the implementer follows was written by the main loop, and the code is reviewed afterward. If an implementer reports it is blocked, or the same build or test failure survives two of its attempts, stop delegating that piece: the main loop fixes it directly. Don't relaunch a Sonnet agent on a problem it has already failed twice.
|
|
31
31
|
|
|
32
|
+
### Model override (`--opus`, `--sonnet`, `--haiku`)
|
|
33
|
+
|
|
34
|
+
The user can pin one model for the whole run: `/implement 1234 --opus`. Match the flag case-insensitively (`--Opus` works), strip it before reading the id, and remember the tier. Without a flag, the table above applies.
|
|
35
|
+
|
|
36
|
+
With a flag, **every subagent the run launches uses that tier**, and the table's Sonnet and session-model rows no longer split the work:
|
|
37
|
+
|
|
38
|
+
- Every `Workflow` `agent()` call gets `model: '{tier}'`, the Architect Review included.
|
|
39
|
+
- Every `Agent` call gets `model: "{tier}"`, including `backend`, `frontend`, and `reviewer`. The parameter overrides the agent's frontmatter.
|
|
40
|
+
- Anywhere else this file says to run something on Sonnet, read it as the pinned tier.
|
|
41
|
+
|
|
42
|
+
**The main loop can't switch itself.** It stays on the session model, and a command can't change that. If the session isn't already on the pinned tier, say so in the Step 2 summary: `Subagents pinned to {tier}. This session runs on {session model}, so planning and fixes stay there. Run /model {tier} first to put the whole run on {tier}.` Then carry on; don't stop to wait for it.
|
|
43
|
+
|
|
44
|
+
The escalation rule still holds: an implementer that is blocked or fails the same way twice hands that piece to the main loop. Under `--opus` that's still worth doing, since the main loop has the full plan and context and a relaunched agent doesn't.
|
|
45
|
+
|
|
32
46
|
## Step 0: Set Up the Ticket's Workspace
|
|
33
47
|
|
|
34
48
|
Developers run several Claude Code sessions against the same repo at once, one per ticket. If every session `git checkout`s in the folder it started in, they clobber each other's working tree. So each ticket gets its own **git worktree** in a sibling folder, `../{repo}-AB{id}` (e.g. `../CSIPay-AB5373`), and every later step runs there. The folder the session started in is never checked out, committed to, or edited.
|
|
@@ -145,7 +159,7 @@ Read the work item from Azure DevOps via MCP. Extract:
|
|
|
145
159
|
- **System.Title** — determines branch suffix
|
|
146
160
|
- **Acceptance criteria / description** — needed for implementation
|
|
147
161
|
|
|
148
|
-
Handle `$ARGUMENTS` as either `1234` or `AB#1234` — strip the `AB#` prefix when calling the MCP API.
|
|
162
|
+
Handle `$ARGUMENTS` as either `1234` or `AB#1234` — strip the `AB#` prefix when calling the MCP API. Strip a `--opus` / `--sonnet` / `--haiku` flag too, and apply it per **Model override**.
|
|
149
163
|
|
|
150
164
|
**If `System.WorkItemType` is `Feature`, switch to the [Feature Workflow](#feature-workflow-ordered-story-waves) at the bottom of this document.** Steps 2–10 below describe the single-work-item flow; the Feature Workflow reuses them per child User Story.
|
|
151
165
|
|
package/templates/commands/qa.md
CHANGED
|
@@ -221,18 +221,46 @@ No commits at all → `No commits found referencing this work item — nothing t
|
|
|
221
221
|
|
|
222
222
|
### For `local`
|
|
223
223
|
|
|
224
|
-
No commit or pipeline gate — you are testing the working tree. Instead,
|
|
224
|
+
No commit or pipeline gate — you are testing the working tree. Instead, make sure the app is running there, and **start whatever isn't**. Nobody should have to open two terminals before `/qa` will run.
|
|
225
|
+
|
|
226
|
+
**Which tree.** Serve the current directory, unless `git worktree list` shows the item's branch (`*AB#<id>-*`) checked out in a sibling worktree. Then serve that worktree instead, and say so. Check whether the chosen tree contains the item's commits (`git log --grep="AB#<id>"` on its `HEAD`). If not, warn but continue. The user may be mid-implementation, which is a legitimate reason to run `/qa local`.
|
|
227
|
+
|
|
228
|
+
**1. Probe.** Probe the local App URL, and the API URL if the row has one. Any HTTP status means the server is up, even a 404 or 401. Only `000` (refused or timed out) means it is down:
|
|
229
|
+
|
|
230
|
+
```bash
|
|
231
|
+
curl -sk -o /dev/null -w '%{http_code}' --max-time 3 "{url}"
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
If everything answers, proceed and record `already running` for each server. You can't tell which tree a server you didn't start is serving, so say once: `Reusing the servers already running — make sure they're serving {tree}.`
|
|
235
|
+
|
|
236
|
+
**2. Find the start command** for each server that is down. Use the `**Local start:**` block in `## Environment URLs` if the project has one. Otherwise infer it:
|
|
237
|
+
|
|
238
|
+
- **API** → `Glob("**/Properties/launchSettings.json")`, skipping `bin/`, `obj/`, and test projects. Pick the profile whose `applicationUrl` contains the API URL's port. The command is `dotnet run --project {csproj} --launch-profile {profile}`.
|
|
239
|
+
- **Client** → `Glob("**/package.json")`, skipping `node_modules`. Pick the package whose `scripts` has `dev` (else `start`) and whose dev-server port matches the App URL's port. The port comes from `vite.config.*`, the script itself, or the framework default. Use the package manager named by its lockfile.
|
|
240
|
+
|
|
241
|
+
If there is exactly one candidate, use it, and after the run suggest saving it as a `**Local start:**` block. If there are none, or more than one, ask the user and list the candidates. Never guess between two APIs.
|
|
242
|
+
|
|
243
|
+
**Check where the client sends API calls**, whether you started it or not. Grep the client's dev-mode env file (`.env.development`, `.env.local`) for the single base-URL key, and echo **only that value**. If it is an absolute URL other than the local API URL, warn: `The local client calls {value}, not the local API — backend changes in this tree won't be exercised.` Then continue.
|
|
244
|
+
|
|
245
|
+
**3. Start it in the background**, from the chosen tree, with Bash `run_in_background`. Never start it in the foreground: a dev server doesn't exit, so the call hangs until it times out. Start the API first, because the client usually proxies to it. If the client folder has no `node_modules` (a fresh worktree never does), install first: `npm ci` when there's a lockfile, `npm install` otherwise. Use the equivalent command for pnpm or yarn.
|
|
246
|
+
|
|
247
|
+
**4. Wait until it answers.** Wait with `Monitor`, using an until-loop on the step 1 probe. Never use a foreground `sleep`. Allow 3 minutes for the API, because a first `dotnet run` builds, and 90 seconds for the client. Watch the background task too. If it exits before the URL answers, the start failed, so stop:
|
|
225
248
|
|
|
226
249
|
```
|
|
227
|
-
|
|
250
|
+
Couldn't start the {API | client} for /qa local.
|
|
251
|
+
|
|
252
|
+
{command} (in {dir})
|
|
253
|
+
{exited with code {n} | didn't answer on {url} within {timeout}}
|
|
228
254
|
|
|
229
|
-
|
|
230
|
-
{
|
|
255
|
+
Last lines of its output:
|
|
256
|
+
{up to 20 lines}
|
|
231
257
|
|
|
232
|
-
|
|
258
|
+
Fix it and re-run /qa AB#{id} local, or start it yourself — /qa reuses a running server.
|
|
233
259
|
```
|
|
234
260
|
|
|
235
|
-
|
|
261
|
+
Omit any output line that carries a connection string, key, or token, because dev servers sometimes log their configuration. `address already in use` means something else holds the port. `lsof -iTCP:{port} -sTCP:LISTEN` names it. Say what it is and stop. **Never kill a process you didn't start.**
|
|
262
|
+
|
|
263
|
+
**5. Leave them running.** Servers started by `/qa` stay up for the rest of the session, so a re-run or `/repro … local` reuses them. Record each one's background task id for the report. Stop them (`TaskStop`) only when the user asks. They end with the session anyway.
|
|
236
264
|
|
|
237
265
|
## Step 6: Scope the Affected Screens, Then Get Approval
|
|
238
266
|
|
|
@@ -267,6 +295,7 @@ Target: {environment} — {app-url}
|
|
|
267
295
|
Role: {role} ({USERNAME_VAR} | you'll sign in yourself in the browser window | Microsoft, unattended from {USERNAME_VAR})
|
|
268
296
|
Impersonating: {persona} ({role}) | {search term} — ad-hoc user, READ-ONLY run | none
|
|
269
297
|
Build: {n} of {n} commits on `{branch}`, {pipeline} run {id} green
|
|
298
|
+
| local working tree {dir} — API {started by /qa | already running}, client {started by /qa | already running}
|
|
270
299
|
Baseline for attributing failures: {baseline-env} — {baseline-url}
|
|
271
300
|
|
|
272
301
|
Screens the story touched:
|
|
@@ -326,7 +355,8 @@ Only filter 1's output can drive a `FAIL` verdict. A run that finds nothing but
|
|
|
326
355
|
```
|
|
327
356
|
QA — AB#{id}: {title}
|
|
328
357
|
{type} · {state} · {environment} — {app-url}
|
|
329
|
-
Build: {pipeline} run {id} · succeeded · commit {sha7}
|
|
358
|
+
Build: {pipeline} run {id} · succeeded · commit {sha7} | local working tree {dir} · commit {sha7}
|
|
359
|
+
Local servers: API {started by /qa (task {id}) | already running}, client {…} — the ones /qa started are still running; say "stop servers" to stop them
|
|
330
360
|
Signed in as: {role} ({from USERNAME_VAR | signed in by you | Microsoft, from USERNAME_VAR}) — value not shown
|
|
331
361
|
Impersonating: {persona | search term} as {role} | none
|
|
332
362
|
Screens tested: {n} · {route list}
|
|
@@ -58,7 +58,7 @@ Find the fix's commits the way `/qa` Step 5a does: linked PRs → `lastMergeComm
|
|
|
58
58
|
| some | not all | **reproduce** — the fix exists but isn't fully on {environment}, so this run confirms the bug on the old build |
|
|
59
59
|
| some | all | **verify-fix** |
|
|
60
60
|
|
|
61
|
-
For `local`, also count it as verify-fix when the current branch matches `*AB#<id>-*` and the working tree has uncommitted changes — that is a fix in progress.
|
|
61
|
+
For `local`, also count it as verify-fix when the current branch matches `*AB#<id>-*` and the working tree has uncommitted changes — that is a fix in progress. A server that `/qa`'s local step starts already serves this tree. If it reuses one that was already running, remind the user that it must be serving this working tree.
|
|
62
62
|
|
|
63
63
|
**Overrides.** `--reproduce` always wins. `--verify` on a target that lacks some fix commits is refused: verifying a fix that isn't deployed only tests the old build.
|
|
64
64
|
|
|
@@ -70,7 +70,7 @@ Run /repro AB#{id} {environment} to confirm the bug on this build, or verify whe
|
|
|
70
70
|
fix is: {environments whose branch has every commit, or "nowhere yet"}.
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
**Verify-fix on `dev` / `test` / `staging`** → also run `/qa` **Step 5b**. The pipeline that deployed the fix must be green. Being merged is not being deployed. **`local`, either mode** → run `/qa` Step 5's `local`
|
|
73
|
+
**Verify-fix on `dev` / `test` / `staging`** → also run `/qa` **Step 5b**. The pipeline that deployed the fix must be green. Being merged is not being deployed. **`local`, either mode** → run `/qa` Step 5's `local` section. It starts the API and client if they aren't already running. Reproduce mode on a deployed environment needs no pipeline gate, because it tests whatever is there.
|
|
74
74
|
|
|
75
75
|
**Pick the control** — verify-fix only. The control is what tells *fixed* apart from *these steps never triggered it*. Take the first one of these that applies:
|
|
76
76
|
|
|
@@ -32,9 +32,23 @@ Most of a run's tokens go to subagents re-reading their context on every turn, n
|
|
|
32
32
|
|
|
33
33
|
**Escalation keeps quality up.** The plan the implementer follows was written by the main loop, and the code is reviewed afterward. If an implementer reports it is blocked, or the same build or test failure survives two of its attempts, stop delegating that piece: the main loop fixes it directly. Don't relaunch a Sonnet agent on a problem it has already failed twice.
|
|
34
34
|
|
|
35
|
+
### Model override (`--opus`, `--sonnet`, `--haiku`)
|
|
36
|
+
|
|
37
|
+
The user can pin one model for the whole run: `/rework 1234 --opus`. Match the flag case-insensitively (`--Opus` works), strip it before reading the id, and remember the tier. Without a flag, the table above applies.
|
|
38
|
+
|
|
39
|
+
With a flag, **every subagent the run launches uses that tier**, and the table's Sonnet and session-model rows no longer split the work:
|
|
40
|
+
|
|
41
|
+
- Every `Workflow` `agent()` call gets `model: '{tier}'`, the Architect Review included.
|
|
42
|
+
- Every `Agent` call gets `model: "{tier}"`, including `backend`, `frontend`, and `reviewer`. The parameter overrides the agent's frontmatter.
|
|
43
|
+
- Anywhere else this file says to run something on Sonnet, read it as the pinned tier.
|
|
44
|
+
|
|
45
|
+
**The main loop can't switch itself.** It stays on the session model, and a command can't change that. If the session isn't already on the pinned tier, say so in the Step 3 summary: `Subagents pinned to {tier}. This session runs on {session model}, so planning and fixes stay there. Run /model {tier} first to put the whole run on {tier}.` Then carry on; don't stop to wait for it.
|
|
46
|
+
|
|
47
|
+
The escalation rule still holds: an implementer that is blocked or fails the same way twice hands that piece to the main loop. Under `--opus` that's still worth doing, since the main loop has the full plan and context and a relaunched agent doesn't.
|
|
48
|
+
|
|
35
49
|
## Step 1: Find the Latest Pull Request
|
|
36
50
|
|
|
37
|
-
Handle `$ARGUMENTS` as either `1234` or `AB#1234` — strip the `AB#` prefix when calling the MCP API. If it also says "work in place" or "no worktree", strip that and remember it for Step 0.
|
|
51
|
+
Handle `$ARGUMENTS` as either `1234` or `AB#1234` — strip the `AB#` prefix when calling the MCP API. If it also says "work in place" or "no worktree", strip that and remember it for Step 0. Strip a `--opus` / `--sonnet` / `--haiku` flag too, and apply it per **Model override**.
|
|
38
52
|
|
|
39
53
|
Find the most recent PR linked to this work item:
|
|
40
54
|
|
|
@@ -53,7 +53,7 @@ Short, single-query operations (`/track`, `/explain`, `/close-orphan-tasks`) do
|
|
|
53
53
|
|
|
54
54
|
**`/autopilot` never uses it.** An unattended run is where fan-out costs the most, so it runs lean: the Architect Review runs in the main loop, and one Sonnet `reviewer` agent stands in for the user's review.
|
|
55
55
|
|
|
56
|
-
**Model tiers.** In `/implement`, `/rework`, and `/autopilot`, the main loop (your session model) plans, synthesizes, and fixes review findings. Implementers (`backend`, `frontend`) and every Workflow analyst run on Sonnet, except the Architect Review, which stays on the session model. If a Sonnet implementer is blocked or fails the same way twice, the main loop takes that piece over.
|
|
56
|
+
**Model tiers.** In `/implement`, `/rework`, and `/autopilot`, the main loop (your session model) plans, synthesizes, and fixes review findings. Implementers (`backend`, `frontend`) and every Workflow analyst run on Sonnet, except the Architect Review, which stays on the session model. If a Sonnet implementer is blocked or fails the same way twice, the main loop takes that piece over. Add `--opus`, `--sonnet`, or `--haiku` to pin every subagent to one model for the run (`/implement AB#1234 --opus`). The main loop stays on the session model, so run `/model opus` first to put the whole run on Opus.
|
|
57
57
|
|
|
58
58
|
**`/plan-backlog`, `/plan-sprint`, and `/quote-backlog` use it opt-in** — only when ultracode is on.
|
|
59
59
|
|
|
@@ -482,6 +482,10 @@ Add this to your project's `CLAUDE.md` — **above the `## Claude Kit Workflow`
|
|
|
482
482
|
| test | Test | https://test.myapp.example.com | https://test.api.myapp.example.com |
|
|
483
483
|
| staging | Staging | https://staging.myapp.example.com | https://staging.api.myapp.example.com |
|
|
484
484
|
|
|
485
|
+
**Local start:** (optional — paths from the repo root)
|
|
486
|
+
- API: `dotnet run --project src/API/API.csproj --launch-profile https`
|
|
487
|
+
- Client: `npm run dev` in `Client/`
|
|
488
|
+
|
|
485
489
|
**Sign-in:** `form` at `/login` — app-issued JWT, no SSO. Signed-in landing: `/dashboard`.
|
|
486
490
|
|
|
487
491
|
**Test accounts** — each developer sets the values on their own machine; never write a password here.
|
|
@@ -506,6 +510,7 @@ Add this to your project's `CLAUDE.md` — **above the `## Claude Kit Workflow`
|
|
|
506
510
|
- **There is no `prod` row, deliberately.** `/qa` and `/repro` refuse production: an unattended run signs in and clicks through live member data.
|
|
507
511
|
- **Include the rows below the one you test.** The row immediately below the target serves the pre-change build. That is how `/qa` tells a regression this story caused from a bug that was already there, and how `/repro` runs its *control*: it proves the steps still trigger the bug on a build without the fix, so a clean run on the fixed build means **fixed**, not *never triggered*.
|
|
508
512
|
- **App URL is required; API URL is optional** — it is used to attribute a failing network call to the backend rather than the screen.
|
|
513
|
+
- **`Local start:`** is optional. On `local`, `/qa` and `/repro` probe the local row's URLs and start any server that doesn't answer. They run it in the background from the working tree under test, wait for it to come up, and leave it running for the rest of the session. A server that is already running is reused, never restarted. Without this block, the commands are inferred: the API from the `Properties/launchSettings.json` profile whose `applicationUrl` has the API port, and the client from the `package.json` with a `dev` (else `start`) script on the App URL's port. Add the block when inference picks the wrong project or finds more than one.
|
|
509
514
|
- **`Sign-in:`** starts with the method, then optional prose: the login route, the landing page, and an element that only exists once you're signed in.
|
|
510
515
|
- `` `form` `` — the app's own login form, with no MFA. If the developer has set the role's credential variables, the `qa` agent fills the form in itself. If not, the developer signs in by hand in the browser window — see Test accounts below.
|
|
511
516
|
- `` `microsoft` `` — Entra ID / MSAL redirect. Name the app's sign-in button and the signed-in marker. **By default the person running the command signs in by hand**, once, in the Chromium window Playwright opens. MFA is fine, and no credential enters any transcript. Playwright MCP keeps a persistent browser profile, so later runs reuse that session until it expires. For a fully unattended run, give the role's row credential variables **and** state on the `Sign-in:` line that the account is a cloud-only, **MFA-exempt** QA account. The agent then types them into the Microsoft page itself.
|