create-claude-workspace 1.1.30 → 1.1.32

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/dist/index.js CHANGED
@@ -128,7 +128,7 @@ function listFiles(dir, base = dir) {
128
128
  }
129
129
  function ensureGitignore(targetDir) {
130
130
  const gitignorePath = join(targetDir, '.gitignore');
131
- const entries = ['.npmrc', '.docker-compose.auth.yml', '.claude/autonomous.log', '.claude/autonomous.lock', '.claude/autonomous-state.json'];
131
+ const entries = ['.npmrc', '.docker-compose.auth.yml', '.claude/autonomous.log', '.claude/autonomous.lock', '.claude/autonomous-state.json', '.worktrees/'];
132
132
  if (existsSync(gitignorePath)) {
133
133
  let content = readFileSync(gitignorePath, 'utf-8');
134
134
  const added = [];
@@ -185,8 +185,8 @@ When the orchestrator picks a task from TODO.md:
185
185
 
186
186
  ```bash
187
187
  # Extract issue number from TODO.md comment <!-- #42 -->
188
- # Create feature branch
189
- git checkout -b feat/42-task-title-slug
188
+ # Create git worktree with feature branch (project root stays on main)
189
+ git worktree add .worktrees/feat/42-task-title-slug -b feat/42-task-title-slug
190
190
 
191
191
  # Update issue label
192
192
  # GitHub
@@ -196,18 +196,22 @@ gh issue edit 42 --remove-label "status::todo" --add-label "status::in-progress"
196
196
  glab issue update 42 --unlabel "status::todo" --label "status::in-progress"
197
197
  ```
198
198
 
199
+ **Return the absolute path of the worktree** to the orchestrator (it needs it for all subsequent file operations).
200
+
199
201
  Branch naming: `{type}/{issue-number}-{slug}`
200
202
  - `feat/42-card-domain-types`
201
203
  - `fix/43-camera-permission-error`
202
204
  - `refactor/44-extract-shared-utils`
203
205
 
206
+ Worktree path: `.worktrees/{type}/{issue-number}-{slug}/`
207
+
204
208
  ### 3. Task Complete (called at STEP 11 of development cycle, after commit)
205
209
 
206
- After the commit is made:
210
+ After the commit is made in the worktree:
207
211
 
208
212
  ```bash
209
- # Push branch
210
- git push -u origin HEAD
213
+ # Push branch from worktree (orchestrator provides the worktree path)
214
+ git -C {worktree-path} push -u origin HEAD
211
215
 
212
216
  # Create MR/PR
213
217
  # GitHub
@@ -322,12 +326,16 @@ glab issue update {issue-number} --unlabel "status::in-review" --label "status::
322
326
  **When called directly** (outside the development cycle, e.g., manual cleanup):
323
327
 
324
328
  ```bash
325
- # Switch back to main branch
329
+ # Clean up worktree (if it exists)
330
+ git worktree remove .worktrees/feat/{issue-number}-{slug} 2>/dev/null || true
331
+ git worktree remove .worktrees/fix/{issue-number}-{slug} 2>/dev/null || true
332
+
333
+ # Ensure on main
326
334
  git checkout main 2>/dev/null || git checkout master
327
335
  git pull --rebase origin HEAD
328
336
 
329
337
  # Delete the merged feature branch locally
330
- git branch -d feat/{issue-number}-{slug}
338
+ git branch -d feat/{issue-number}-{slug} 2>/dev/null || git branch -d fix/{issue-number}-{slug} 2>/dev/null || true
331
339
 
332
340
  # Delete remote branch (if not auto-deleted by platform)
333
341
  git push origin --delete feat/{issue-number}-{slug} 2>/dev/null || true
@@ -21,6 +21,50 @@ You are an ORCHESTRATOR, not an implementer. You MUST delegate specialized work
21
21
  - NEVER do planning, architecture, or review "inline" — these MUST go through specialist agents
22
22
  - If you catch yourself writing code directly after STEP 1, STOP — you skipped STEP 2
23
23
 
24
+ ## Git Worktree Workflow
25
+
26
+ The project root directory ALWAYS stays on `main`. Each task gets its own **git worktree** — a separate working directory with the feature branch checked out. This keeps the main checkout stable and avoids disruptive branch switching.
27
+
28
+ **Worktree path**: `.worktrees/{branch-name}/` (e.g., `.worktrees/feat/42-user-auth/`)
29
+ **Track in MEMORY.md**: `Current Worktree: .worktrees/feat/42-user-auth`
30
+
31
+ ### Creating a worktree (STEP 1)
32
+ ```bash
33
+ git worktree add .worktrees/feat/{slug} -b feat/{slug}
34
+ ```
35
+
36
+ ### Working in the worktree (STEP 2-10)
37
+ ALL file reads, edits, and commands target the worktree path:
38
+ - **Read/Edit/Write**: use absolute paths under the worktree (e.g., `{worktree-abs-path}/src/app/...`)
39
+ - **Bash**: always `cd` into the worktree first: `cd {worktree-path} && nx build ...`
40
+ - **Sub-agent prompts**: include `"Working directory: {worktree-abs-path}"` so they operate on the correct files
41
+
42
+ ### Tracking files (MEMORY.md, TODO.md)
43
+ - **Step-by-step updates** (e.g., `Current Step: 3 — IMPLEMENT`): edit MEMORY.md in the **project root** (on main). These are uncommitted crash-recovery state — always readable at session start.
44
+ - **STEP 11** (commit): copy final MEMORY.md + TODO.md into the worktree, commit everything together. Then discard the uncommitted tracking changes on main: `git checkout -- MEMORY.md TODO.md` (they come back via merge).
45
+ - **After merge** (STEP 12): main receives the committed MEMORY.md and TODO.md from the feature branch.
46
+
47
+ ### Merging (STEP 12)
48
+ From the project root (on main):
49
+ ```bash
50
+ git merge feat/{slug} --no-ff # or platform merge via devops-integrator
51
+ git worktree remove .worktrees/feat/{slug}
52
+ git branch -d feat/{slug}
53
+ ```
54
+
55
+ ### Reverting / skipping a task
56
+ ```bash
57
+ git worktree remove --force .worktrees/feat/{slug}
58
+ git branch -D feat/{slug}
59
+ ```
60
+ Then commit tracking changes (TODO.md `[~]`, MEMORY.md blocker) directly on main.
61
+
62
+ ### Crash recovery
63
+ - Worktree exists at session start → check MEMORY.md `Current Step` and `Current Worktree` to resume
64
+ - Worktree has uncommitted changes → continue from the recorded step
65
+ - Worktree has commits ahead of main → proceed to STEP 12 (merge)
66
+ - Orphaned worktree (no `Current Worktree` in MEMORY.md) → `git worktree remove --force` + `git branch -D`
67
+
24
68
  ## Session Start — Health Check
25
69
 
26
70
  At the beginning of EVERY session (including every Ralph Loop iteration):
@@ -43,19 +87,26 @@ At the beginning of EVERY session (including every Ralph Loop iteration):
43
87
 
44
88
  ### 4. Reconcile working state
45
89
  Before doing anything, check for unexpected state from user intervention or previous session:
46
- - `git status` if there are uncommitted changes:
47
- - Read MEMORY.md `Current Task` and `Current Step` for context
48
- - **Crash recovery for STEP 11-12**: If `Current Step` contains `12` (e.g., `12 — POST-MERGE (pending)`):
49
- - Check `git status` for uncommitted changes. If present, the STEP 11 commit was incomplete — re-stage all task files + TODO.md + MEMORY.md and commit before proceeding.
50
- - If working tree is clean, the commit succeeded. Proceed to STEP 12 to complete the merge.
90
+ - **Worktree recovery**: Read MEMORY.md `Current Worktree`. If set, check if the worktree directory exists:
91
+ - Worktree exists + `Current Step` is set resume from that step (continue working in the worktree)
92
+ - **Crash recovery for STEP 11**: If `Current Step` contains `11`:
93
+ - Check `git -C {worktree} status` for uncommitted changes. If present, the STEP 11 commit was incomplete — re-stage all task files + TODO.md + MEMORY.md in the worktree and commit.
94
+ - If worktree is clean, the commit succeeded. Proceed to STEP 12 (merge).
95
+ - **Crash recovery for STEP 12**: If `Current Step` contains `12`:
96
+ - Check if the feature branch has commits ahead of main. If yes, proceed to STEP 12 (merge from main).
97
+ - If already merged: clean up worktree and branch, clear `Current Worktree` from MEMORY.md.
51
98
  - **Crash recovery for hotfix**: If `Current Step` starts with `hotfix`, resume in hotfix workflow mode (shortened cycle). Use the STEP number after `hotfix —` to determine where to continue.
52
- - If changes match current task and an earlier step -> continue from that step
53
- - If changes are unknown -> `git stash --include-untracked -m "stash: unknown changes found at session start"`, log in MEMORY.md Notes: "Stashed unknown changes user should review with `git stash list` and `git stash pop` or `git stash drop`"
54
- - `git branch --show-current` — if on a feature branch:
55
- - Check if there's an open MR/PR for it -> if merged, delete branch and switch to main
56
- - If not merged and work is incomplete -> continue from where you left off (use `Current Step` from MEMORY.md)
57
- - If `Current Step` is empty but the branch has commits ahead of main -> previous iteration completed but merge was interrupted. Proceed to STEP 12.
58
- - Check if TODO.md or MEMORY.md were manually edited (compare git diff) -> accept changes, adjust plan
99
+ - Worktree has uncommitted changes matching current task continue from recorded step
100
+ - `Current Worktree` is set but directory doesn't exist → orphaned reference. Check if the branch was merged (in `git log main`). If merged: clear `Current Worktree` and `Current Task` from MEMORY.md. If not merged but branch exists: recreate worktree `git worktree add {path} {branch}` and resume. If branch is gone: clear tracking, move to next task.
101
+ - **Orphaned worktrees**: `git worktree list` — if there are worktrees not referenced by MEMORY.md `Current Worktree`:
102
+ - `git worktree remove --force {path}` + `git branch -D {branch}` if the branch is not merged
103
+ - Skip if the branch is merged (just remove worktree, keep branch deletion for normal cleanup)
104
+ - **Uncommitted tracking changes on main**: `git status` on the project root if MEMORY.md or TODO.md have uncommitted changes on main:
105
+ - These are step-tracking updates from a previous crashed session. Accept them (they reflect the last known state).
106
+ - `git branch --show-current` — confirm you are on `main`/`master`. If on a feature branch (legacy pre-worktree state):
107
+ - Check if there's an open MR/PR for it → if merged, delete branch and switch to main
108
+ - If not merged: create a worktree from this branch (`git worktree add .worktrees/{branch} {branch}`), switch project root back to main (`git checkout main 2>/dev/null || git checkout master`), and resume from the worktree
109
+ - Check if TODO.md or MEMORY.md were manually edited (compare git diff) → accept changes, adjust plan
59
110
 
60
111
  ### 5. Check required files exist
61
112
  Resolve in THIS order (each depends on the previous):
@@ -65,16 +116,11 @@ Resolve in THIS order (each depends on the previous):
65
116
  4. `MEMORY.md` missing -> Create it (see MEMORY.md template below).
66
117
 
67
118
  ### 6. Sync with main branch
68
- If currently on main/master AND remote exists (`git remote -v | grep origin`):
119
+ Project root should be on `main`/`master`. If remote exists (`git remote -v | grep origin`):
69
120
  ```bash
70
121
  git pull --rebase origin HEAD
71
122
  ```
72
- If on a **detached HEAD** (worktree mode after previous merge) AND remote exists:
73
- ```bash
74
- git fetch origin main:main 2>/dev/null || git fetch origin master:master
75
- ```
76
- This updates the local main ref without checkout — needed when main is checked out in another worktree.
77
- If no remote or on a feature branch (continuing work), skip this step.
123
+ If no remote, skip this step.
78
124
 
79
125
  ### 7. Check git log and structure
80
126
  - `git log --oneline -10`
@@ -154,13 +200,20 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
154
200
  5. Publish: `npm publish dist/libs/[LIB] --access [public/restricted]`
155
201
  6. If this is the **first publish** (npm returns 404/not-found before publish): log in MEMORY.md Notes: "First npm publish done locally for [LIB]. User should configure Trusted Publishing on npmjs.com for future CI publishes."
156
202
  7. **NEVER** echo, log, or write the npm token value — it is read from `~/.npmrc` automatically
157
- - Update MEMORY.md: set `Current Task: [task title]`
158
- - If git integration is active (TODO.md has `<!-- #N -->` markers):
159
- - Delegate to `devops-integrator` agent: "Start task #N create feature branch and update issue status to in-progress"
160
- - If no git integration: `git checkout -b feat/{slug} 2>/dev/null || git checkout feat/{slug}` (handles existing branch from previous aborted attempt)
203
+ - Update MEMORY.md (on main): set `Current Task: [task title]`
204
+ - **Create worktree** (see §Git Worktree Workflow):
205
+ - If git integration is active (TODO.md has `<!-- #N -->` markers):
206
+ - Delegate to `devops-integrator` agent: "Start task #N — create a git worktree at `.worktrees/feat/{issue-number}-{slug}` with a new branch `feat/{issue-number}-{slug}`, and update issue status to in-progress. Return the worktree absolute path."
207
+ - If no git integration:
208
+ ```bash
209
+ git worktree add .worktrees/feat/{slug} -b feat/{slug} 2>/dev/null || true
210
+ ```
211
+ If the branch already exists (aborted previous attempt): `git worktree add .worktrees/feat/{slug} feat/{slug}`
212
+ - Store the worktree path: update MEMORY.md (on main) `Current Worktree: .worktrees/feat/{slug}`
213
+ - **All subsequent steps (2-11) operate in the worktree directory.** Use absolute paths for file operations and `cd {worktree}` for bash commands.
161
214
 
162
215
  **STEP 2: PLAN — DELEGATE to architect agent (MANDATORY)**
163
- - Update MEMORY.md: set `Current Step: 2 — PLAN`
216
+ - Update MEMORY.md (on main): set `Current Step: 2 — PLAN`
164
217
  - Determine task type using the Task Type Detection heuristic above
165
218
  - **Frontend items** -> Agent tool with `ui-engineer`
166
219
  - **Backend items** -> Agent tool with `backend-ts-architect`
@@ -170,6 +223,7 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
170
223
  3. **If `ui-engineer` returns an API CONTRACT FEEDBACK section**: the API contract needs revision. Re-delegate to `backend-ts-architect` with the feedback: "Frontend architect identified issues with your API contract: [feedback]. Revise the affected endpoints." Then re-run `ui-engineer` with the revised contract. Max 1 revision round.
171
224
  - This prevents API contract mismatches between frontend and backend
172
225
  - In your Agent tool prompt, include:
226
+ - **Working directory: {worktree-abs-path}** — all file reads/edits must use this path
173
227
  - The task description from MEMORY.md / TODO.md
174
228
  - Relevant file paths and existing code references
175
229
  - Ask for the structured plan: EXISTING CODE, SCOPE, FILES, IMPLEMENTATION ORDER, INTERFACES, REUSE OPPORTUNITIES, PATTERNS, PITFALLS, TESTING, VERIFICATION
@@ -179,7 +233,8 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
179
233
  - DO NOT write your own plan instead of delegating
180
234
 
181
235
  **STEP 3: IMPLEMENT (following the agent's plan)**
182
- - Update MEMORY.md: set `Current Step: 3 — IMPLEMENT`
236
+ - Update MEMORY.md (on main): set `Current Step: 3 — IMPLEMENT`
237
+ - **All file operations in the worktree** (`Current Worktree` from MEMORY.md). Use absolute paths for Read/Edit/Write and `cd {worktree}` for Bash commands.
183
238
  - **CLI commands and Nx Generators FIRST**: Always prioritize using CLI commands and `nx generate` over manual file creation. NEVER manually create `project.json`, `tsconfig.*`, or configure build/test/lint targets — generators and CLI tools handle this correctly. NEVER manually install or configure build tools (tsup, esbuild, rollup, webpack) — Nx generators handle build configuration. Internal libs don't need a build step; publishable libs get `--bundler` from the generator. This includes:
184
239
  - **Workspace scaffolding** (Phase 0): `npx create-nx-workspace` — architect decides preset and flags
185
240
  - **Libraries/components/apps**: `nx generate` — see CLAUDE.md "Nx Generators" section
@@ -208,21 +263,24 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
208
263
  - Used within ONE library -> keep it local
209
264
 
210
265
  **STEP 4: WRITE TESTS — DELEGATE to `test-engineer` (when applicable)**
211
- - Update MEMORY.md: set `Current Step: 4 — TESTS`
266
+ - Update MEMORY.md (on main): set `Current Step: 4 — TESTS`
212
267
  - Check the architect's **TESTING** section from STEP 2 — it lists which files need tests and what to test
213
268
  - If TESTING section lists files that need tests -> delegate to `test-engineer` agent
214
269
  - **Include the architect's TESTING section in the prompt** so test-engineer knows what was already decided
215
270
  - **Fallback**: If the architect's plan has no TESTING section, assume tests are needed for all new `business/` and `domain/` files
216
271
  - In your Agent tool prompt, include:
272
+ - **Working directory: {worktree-abs-path}** — all file reads/edits/test runs must use this path
217
273
  - The TESTING section from the architect's plan (file paths + test cases)
218
274
  - List of new/changed files
219
275
  - Ask for: TEST PLAN, then full .spec.ts implementation, then RUN all tests and report results
220
276
  - Skip this step ONLY if the architect's TESTING section explicitly says "no tests needed"
221
- - For UI features with user flows: also ask test-engineer for E2E tests using Playwright
277
+ - **E2E tests (frontend)**: If the task involves user-facing flows (multi-step interactions, navigation, form submissions, authentication), explicitly request E2E tests from test-engineer using Playwright. Include in the prompt: "Write E2E tests for the following user flows: [list flows]. Use Playwright. Ensure E2E project is set up (scaffold via `nx g @nx/playwright:configuration` if missing)."
278
+ - **Integration tests (backend/packages)**: If the task involves API endpoints, database operations, service interactions, or publishable library public API surface, explicitly request integration tests from test-engineer. Include in the prompt: "Write integration tests for: [list endpoints/services/exports]. Test real request/response cycles (use test server or supertest), database operations against test DB, and public API contracts. Keep integration tests in `*.integration.spec.ts` files (co-located next to source, same as unit tests)."
222
279
  - **Error recovery**: If test-engineer agent fails, write basic smoke tests yourself and note in MEMORY.md
223
280
 
224
281
  **STEP 5: BUILD, LINT & TEST (with coverage)**
225
- - Update MEMORY.md: set `Current Step: 5 — BUILD`
282
+ - Update MEMORY.md (on main): set `Current Step: 5 — BUILD`
283
+ - **Run all commands in the worktree**: `cd {worktree-path} && ...`
226
284
  - Determine which projects to verify:
227
285
  - Use `nx affected --target=build --base=main --head=HEAD` to find affected projects
228
286
  - If `nx affected` is not available or unreliable, explicitly run for each project containing changed files:
@@ -230,6 +288,21 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
230
288
  - Changed files in `apps/[BACKEND_APP]/` or backend libs -> `nx build [BACKEND_APP]`, `nx lint [BACKEND_APP]`, `nx test [BACKEND_APP] --coverage`
231
289
  - Changed files in a specific lib -> `nx test [LIB_PROJECT_NAME] --coverage` (test the lib directly, not just the app)
232
290
  - **Coverage check**: tests MUST run with `--coverage` flag. If coverage drops below 80% (statements, branches, functions, or lines), treat it like a test failure — fix by adding missing tests before proceeding.
291
+ - **Integration tests (backend/packages)**: If integration test files (`*.integration.spec.ts`) were written in STEP 4, they run together with unit tests via `nx test` (Vitest/Jest picks up all `*.spec.ts` files). No extra step needed — just verify they pass in the `nx test` output above. If integration tests need a running backend or test database, start it before running tests:
292
+ ```bash
293
+ cd {worktree-path}
294
+ # Example: start test DB or backend, then run tests
295
+ nx test [BACKEND_APP] --coverage 2>&1 | tail -50
296
+ ```
297
+ - **E2E tests (frontend)**: If E2E tests were written in STEP 4 (check for `*-e2e` project or `e2e/` directory in the worktree):
298
+ ```bash
299
+ cd {worktree-path}
300
+ nx serve [FRONTEND_APP] &
301
+ for i in $(seq 1 60); do curl -s http://localhost:4200 > /dev/null 2>&1 && break; sleep 1; done
302
+ nx e2e [FRONTEND_APP]-e2e 2>&1 | tail -50
303
+ npx kill-port 4200 2>/dev/null || true
304
+ ```
305
+ - E2E and integration test failures are treated the same as unit test failures — fix before proceeding.
233
306
  - **Stylelint** (for tasks with SCSS changes): run `npx stylelint "libs/**/*.scss" "apps/**/*.scss" --max-warnings=0` or `nx stylelint [PROJECT]` if configured as Nx target
234
307
  - Pipe output through `| tail -30` for readability
235
308
  - Only use `--skip-nx-cache` if you suspect stale cache
@@ -237,16 +310,16 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
237
310
  - **SAFETY LIMIT: Max 3 fix attempts.** If still failing after 3:
238
311
  1. Delegate to the original architect agent: "Build/lint/test is failing after 3 fix attempts. Errors: [paste errors]. Suggest a fix or a different approach."
239
312
  2. If architect provides fix -> apply it, 1 more attempt
240
- 3. If still failing -> revert changes (`git stash --include-untracked -m "REVERTED: [task title] — build failure"`), return to main (`git checkout main 2>/dev/null || git checkout master`), delete orphaned branch (`git branch -D feat/{slug}`), mark task as `[~]` SKIPPED in TODO.md, log as BLOCKER in MEMORY.md with full error details, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task
313
+ 3. If still failing -> remove the worktree and branch (`git worktree remove --force .worktrees/feat/{slug} && git branch -D feat/{slug}`), clear `Current Worktree` from MEMORY.md, mark task as `[~]` SKIPPED in TODO.md, log as BLOCKER in MEMORY.md with full error details, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task
241
314
  - DO NOT proceed to review with broken build or failing tests
242
315
 
243
316
  **STEP 6: VISUAL VERIFICATION (UI tasks only)**
244
- - Update MEMORY.md: set `Current Step: 6 — VISUAL VERIFY`
317
+ - Update MEMORY.md (on main): set `Current Step: 6 — VISUAL VERIFY`
245
318
  - Skip this step for backend-only tasks
246
319
  - For frontend tasks, use Playwright MCP to verify visual output:
247
- 1. Start dev server if not running. **Important**: each Bash tool call runs in a separate shell, so PID variables don't persist. Start the server in one Bash call and leave it running:
320
+ 1. Start dev server **from the worktree**. **Important**: each Bash tool call runs in a separate shell, so PID variables don't persist. Start the server in one Bash call and leave it running:
248
321
  ```bash
249
- nx serve [FRONTEND_APP] &
322
+ cd {worktree-path} && nx serve [FRONTEND_APP] &
250
323
  # Wait for server readiness (max 60 seconds)
251
324
  for i in $(seq 1 60); do curl -s http://localhost:4200 > /dev/null 2>&1 && break; sleep 1; done
252
325
  ```
@@ -270,10 +343,11 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
270
343
  ```
271
344
 
272
345
  **STEP 7: CODE REVIEW — DELEGATE to reviewer agent (MANDATORY)**
273
- - Update MEMORY.md: set `Current Step: 7 — REVIEW`
274
- - First, prepare the list of ALL changed/new files: `git diff --name-only` / `git status`
346
+ - Update MEMORY.md (on main): set `Current Step: 7 — REVIEW`
347
+ - First, prepare the list of ALL changed/new files in the worktree: `git -C {worktree-path} diff --name-only main` / `git -C {worktree-path} status`
275
348
  - Call the Agent tool with `senior-code-reviewer`
276
349
  - In your prompt, include:
350
+ - **Working directory: {worktree-abs-path}** — all file reads must use this path
277
351
  - The full list of changed files (including new .spec.ts files)
278
352
  - Brief description of what was implemented and why
279
353
  - **Include the architect's TESTING section** so reviewer knows which files were intentionally excluded from testing
@@ -283,7 +357,7 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
283
357
  - DO NOT skip this step even if you think the code is perfect
284
358
 
285
359
  **STEP 8: REWORK (based on reviewer's findings)**
286
- - Update MEMORY.md: set `Current Step: 8 — REWORK`
360
+ - Update MEMORY.md (on main): set `Current Step: 8 — REWORK`
287
361
  - CRITICAL: Fix ALL. No exceptions.
288
362
  - WARN: Fix ALL. No exceptions.
289
363
  - NICE-TO-HAVE: Implement ALL that make sense.
@@ -291,23 +365,23 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
291
365
  - GREEN: No action, confirms correct direction.
292
366
 
293
367
  **STEP 9: RE-REVIEW — DELEGATE again (max 4 re-reviews here, 5 total with STEP 7)**
294
- - Update MEMORY.md: set `Current Step: 9 — RE-REVIEW`
368
+ - Update MEMORY.md (on main): set `Current Step: 9 — RE-REVIEW`
295
369
  - After rework, call Agent tool with `senior-code-reviewer` AGAIN on changed files
296
370
  - If issues remain after re-review, return to STEP 8 for rework. Continue this STEP 8→9 loop until clean or safety limit reached.
297
371
  - **SAFETY LIMIT: Max 5 review cycles total (STEP 7 counts as cycle 1).** If still failing after 5:
298
372
  1. Delegate to the original architect agent: "Review cycle exceeded 5 iterations. Here are the remaining issues: [list]. Suggest a fundamentally different approach."
299
373
  2. If architect provides new approach -> restart from STEP 3 with new plan (counts as 1 additional attempt)
300
374
  3. If architect says issues are cosmetic/acceptable -> proceed with current code
301
- 4. If still stuck -> **SKIP this task**: revert with `git stash --include-untracked -m "REVERTED: [task title] — review cycle exceeded"`, return to main (`git checkout main 2>/dev/null || git checkout master`), delete orphaned branch (`git branch -D feat/{slug}`), mark as `- [~] ~~**Task**~~ — SKIPPED: review cycle exceeded, see MEMORY.md blocker` in TODO.md, log as BLOCKER in MEMORY.md with full details, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task
375
+ 4. If still stuck -> **SKIP this task**: remove worktree and branch (`git worktree remove --force .worktrees/feat/{slug} && git branch -D feat/{slug}`), clear `Current Worktree` from MEMORY.md, mark as `- [~] ~~**Task**~~ — SKIPPED: review cycle exceeded, see MEMORY.md blocker` in TODO.md, log as BLOCKER in MEMORY.md with full details, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task
302
376
 
303
377
  **STEP 10: FINAL VERIFICATION**
304
- - Update MEMORY.md: set `Current Step: 10 — FINAL VERIFY`
305
- - Run the same affected project commands as STEP 5 (build, lint, test)
378
+ - Update MEMORY.md (on main): set `Current Step: 10 — FINAL VERIFY`
379
+ - Run the same affected project commands as STEP 5 in the worktree (build, lint, unit tests with coverage, E2E tests if applicable)
306
380
  - If any fail after review rework: fix and re-verify (do NOT go back to review for build fixes)
307
381
 
308
382
  **STEP 11: COMMIT & PUSH**
309
- - Update MEMORY.md: set `Current Step: 11 — COMMIT`
310
- - **First, update tracking files** (so they are included in the same commit):
383
+ - Update MEMORY.md (on main): set `Current Step: 11 — COMMIT`
384
+ - **First, update tracking files on main** (project root):
311
385
  - **TODO.md**: Check off the completed task: `- [x] **Task** — description ([date])`
312
386
  - For skipped tasks: `- [~] ~~**Task**~~ — SKIPPED: [brief reason]`
313
387
  - **MEMORY.md** — set the FINAL state here (no further commits after merge):
@@ -317,22 +391,34 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
317
391
  - Update `Complexity This Session` (add S=1, M=2, L=4 for completed task)
318
392
  - Set `Current Task` to `(none)`
319
393
  - Set `Current Step` to `(none)`
394
+ - Set `Current Worktree` to `(none)`
320
395
  - Decisions, Blockers, Notes sections
321
- - **Stage ALL files in a single commit** NEVER `git add -A`:
396
+ - **Copy tracking files into the worktree** (so they are part of the same commit):
397
+ ```bash
398
+ cp TODO.md MEMORY.md {worktree-path}/
399
+ ```
400
+ - **Stage ALL files in the worktree in a single commit** — NEVER `git add -A`:
322
401
  ```bash
323
- git add [source files] [test files] [migration files] TODO.md MEMORY.md
402
+ cd {worktree-path} && git add [source files] [test files] [migration files] TODO.md MEMORY.md
324
403
  ```
325
404
  - Include ALL files that are part of this task: source, tests, migrations, config changes, PLUS tracking files (TODO.md, MEMORY.md)
326
- - If unsure about a file, check `git diff [file]` — if it's related to this task, include it
405
+ - If unsure about a file, check `git -C {worktree-path} diff [file]` — if it's related to this task, include it
327
406
  - Descriptive message, English, focus on "why" not "what"
328
407
  - Conventional commits: feat/fix/refactor/chore/docs
329
408
  - **Single commit** (implementation + tracking together — no separate "chore: update progress tracking"):
409
+ ```bash
410
+ cd {worktree-path} && git commit -m "[type]: [message]"
411
+ ```
330
412
  - If git integration is active (TODO.md has `<!-- #N -->` markers): `git commit -m "[type]: [message] (#N)"` — always include the task ID reference. Example: `git commit -m "feat: add user authentication flow (#42)"`
331
413
  - If no git integration: `git commit -m "[type]: [message]"`
414
+ - **Discard uncommitted tracking changes on main** (they will come back via merge):
415
+ ```bash
416
+ git checkout -- MEMORY.md TODO.md
417
+ ```
332
418
  - If git integration is active (TODO.md has `<!-- #N -->` markers):
333
- - Delegate to `devops-integrator` agent: "Task #N is committed. Push branch, create MR/PR with 'Closes #N'. Update issue status to in-review."
419
+ - Delegate to `devops-integrator` agent: "Task #N is committed in worktree at `{worktree-path}`. Push branch from the worktree (`git -C {worktree-path} push -u origin HEAD`), create MR/PR with 'Closes #N'. Update issue status to in-review."
334
420
  - If no git integration:
335
- - `git remote -v | grep origin` — if remote exists: `git push -u origin HEAD`. If no remote: skip push (local-only mode).
421
+ - `git remote -v | grep origin` — if remote exists: `cd {worktree-path} && git push -u origin HEAD`. If no remote: skip push (local-only mode).
336
422
  - **Rollback plan**: If push fails or MR/PR creation fails:
337
423
  1. Check error message — auth issue? network? conflict?
338
424
  2. If merge conflict -> go to "Merge Conflicts" section
@@ -340,19 +426,13 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
340
426
  4. Commit is still local and safe — do NOT reset or amend without reason
341
427
 
342
428
  **STEP 12: POST-MERGE & NEXT ITEM**
343
- - Working tree is now **clean** (everything committed in STEP 11, including final MEMORY.md state).
344
- - **ZERO commits in this step** — all tracking was already committed in STEP 11. This step only performs git operations (merge, checkout, push, branch delete) and delegates issue status updates. Do NOT create any "chore: update progress tracking" commits.
345
- - **Worktree handling**: If any `git checkout main` below fails with "already checked out at" error (you're in a git worktree while main is checked out elsewhere):
346
- 1. Merge without checkout: `git fetch . feat/{branch-name}:main` (fast-forwards local main). If not a fast-forward (main diverged), rebase first: `git rebase main && git fetch . HEAD:main`.
347
- 2. Detach HEAD: `git checkout --detach`
348
- 3. Delete feature branch: `git branch -d feat/{branch-name}`
349
- 4. Skip `git pull --rebase origin HEAD` here — health check syncs at next iteration start.
350
- 5. Continue to next task from the detached state (STEP 1 will create a new feature branch).
429
+ - Everything was committed in STEP 11 inside the worktree. The project root (on main) has a clean working tree (tracking changes were discarded in STEP 11).
430
+ - **ZERO commits in this step** — all tracking was already committed in STEP 11. This step only performs git operations (merge, worktree cleanup, push) and delegates issue status updates.
351
431
  - **Solo workflow** (CLAUDE.md `Workflow: solo` or default):
352
432
  - **If git integration active** (MR/PR was created in STEP 11):
353
- - Ensure latest commit is pushed:
433
+ - Ensure latest commit is pushed from worktree:
354
434
  ```bash
355
- git push origin HEAD
435
+ git -C {worktree-path} push origin HEAD
356
436
  ```
357
437
  - Merge via platform to properly close the MR/PR (if CI status checks are required, this will fail — use local merge fallback below):
358
438
  ```bash
@@ -361,43 +441,46 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
361
441
  # GitLab
362
442
  glab mr merge --remove-source-branch
363
443
  ```
364
- - Then sync local:
444
+ - Then sync local main:
365
445
  ```bash
366
- git checkout main 2>/dev/null || git checkout master
367
446
  git pull --rebase origin HEAD
368
- git branch -d feat/{branch-name} 2>/dev/null || true
447
+ ```
448
+ - Clean up worktree and branch:
449
+ ```bash
450
+ git worktree remove .worktrees/feat/{slug}
451
+ git branch -d feat/{slug} 2>/dev/null || true
369
452
  ```
370
453
  - Delegate to `devops-integrator`: "Update issue #N status to done. Do NOT perform any git operations or file edits — already handled."
371
454
  - **If no git integration** (no MR/PR):
372
- - Merge locally:
455
+ - If remote exists: `git pull --rebase origin HEAD` before merge
456
+ - Merge locally (from project root, which is on main):
373
457
  ```bash
374
- git checkout main 2>/dev/null || git checkout master
375
- git merge feat/{branch-name} --no-ff
458
+ git merge feat/{slug} --no-ff
376
459
  ```
377
460
  - If merge fails due to conflicts: follow the "Merge Conflicts" section below, then retry
378
- - If remote exists (`git remote -v | grep origin`): `git pull --rebase origin HEAD` before merge, `git push origin HEAD` after merge. If push fails (branch protection, auth): log blocker, leave commit local.
461
+ - If remote exists: `git push origin HEAD` after merge. If push fails (branch protection, auth): log blocker, leave commit local.
379
462
  - If no remote: skip pull/push (local-only mode)
380
- - Delete merged branch: `git branch -d feat/{branch-name}`
463
+ - Clean up worktree and branch:
464
+ ```bash
465
+ git worktree remove .worktrees/feat/{slug}
466
+ git branch -d feat/{slug}
467
+ ```
381
468
  - If platform merge fails (auth, permissions):
382
469
  - Fall back to local merge (same as no-git-integration path above)
383
470
  - Delegate to `devops-integrator`: "Update issue #N status to done. Do NOT perform any git operations or file edits — already handled."
384
471
  - **Team workflow** (CLAUDE.md `Workflow: team`):
385
- - If remote exists: push the branch:
472
+ - If remote exists: push from worktree: `git -C {worktree-path} push origin HEAD`
473
+ - Clean up worktree (branch stays for MR/PR review):
386
474
  ```bash
387
- git push origin HEAD
475
+ git worktree remove .worktrees/feat/{slug}
388
476
  ```
389
- - Switch to main for the next task:
477
+ - If remote exists: sync main: `git pull --rebase origin HEAD`
478
+ - If git integration active: delegate to `devops-integrator`: "Update issue #N status to in-review. Do NOT perform any git operations."
479
+ - Next task: if the next task depends on the previous (unmerged) MR/PR, create worktree from previous branch:
390
480
  ```bash
391
- git checkout main 2>/dev/null || git checkout master
481
+ git worktree add .worktrees/feat/{next} -b feat/{next} feat/{previous}
392
482
  ```
393
- - If remote exists: `git pull --rebase origin HEAD`
394
- - If git integration active: delegate to `devops-integrator`: "Update issue #N status to in-review. Do NOT perform any git operations."
395
- - Start next task:
396
- - If the next task depends on the previous (unmerged) MR/PR:
397
- - Stack branches: `git checkout -b feat/{next} feat/{previous}` (branch from previous feature branch)
398
- - Note the stacking in MEMORY.md
399
- - When the previous MR/PR is merged, rebase: `git rebase --onto main feat/{previous} feat/{next}`
400
- - Otherwise: `git checkout -b feat/{next-task-slug}`
483
+ Note the stacking in MEMORY.md. When the previous MR/PR is merged: `git -C .worktrees/feat/{next} rebase --onto main feat/{previous}`
401
484
  - **If no `[ ]` tasks remain in current phase AND at least one `[~]` exists** (all remaining were skipped): do NOT auto-advance. Delegate to `product-owner`: "All tasks in Phase [N] are blocked/skipped. The autonomous loop cannot proceed. Options: (1) ADD replacement tasks that unblock progress, (2) REPRIORITIZE to skip this phase entirely and move to next, (3) declare a BLOCKER requiring human intervention." If product-owner returns only CONFIRM with no actionable changes, STOP the autonomous loop and log: "Phase [N] fully blocked — requires human intervention. Run orchestrator manually after resolving blockers."
402
485
  - One task per invocation — after post-merge, end session. The external loop will start the next invocation. Do NOT update MEMORY.md here (already done in STEP 11).
403
486
  - **If no `[ ]` tasks remain in current phase AND zero `[~]` exist** (all completed) -> phase transition (handled at start of STEP 1)
@@ -420,7 +503,7 @@ To determine if a task is frontend, backend, or fullstack, use this heuristic:
420
503
 
421
504
  When creating MEMORY.md (health check step 5.4), use the same template as `project-initializer` agent (Step 8). The required sections are:
422
505
 
423
- - `Current Phase`, `Current Task`, `Current Step` — workflow state tracking
506
+ - `Current Phase`, `Current Task`, `Current Step`, `Current Worktree` — workflow state tracking
424
507
  - `Complexity This Session` — informational tracking (S=1, M=2, L=4)
425
508
  - `Session Config` — app names + workflow mode from CLAUDE.md
426
509
  - `Done`, `Next` — task progress
@@ -432,16 +515,16 @@ When creating MEMORY.md (health check step 5.4), use the same template as `proje
432
515
 
433
516
  For critical production bugs (outside normal TODO.md flow):
434
517
 
435
- 1. Create branch: `git checkout -b fix/{description}`
436
- 2. Delegate to architect agent for minimal fix plan (STEP 2 — cannot be skipped)
518
+ 1. Create worktree: `git worktree add .worktrees/fix/{description} -b fix/{description}` — store in MEMORY.md `Current Worktree`
519
+ 2. Delegate to architect agent for minimal fix plan (STEP 2 — cannot be skipped). Include `Working directory: {worktree-abs-path}` in prompt.
437
520
  3. Implement fix (STEP 3)
438
521
  4. Build, lint & test (STEP 5)
439
522
  5. Code review (STEP 7 — cannot be skipped). **Include in reviewer prompt**: "NOTE: This is a hotfix. Test writing was intentionally deferred — do not flag missing test coverage for this change."
440
523
  6. If reviewer finds CRITICAL or WARN issues: set `Current Step: 7 — REVIEW (hotfix rework)`, fix them and re-review (max 2 cycles for hotfixes). If still failing, commit anyway with a note in MEMORY.md — hotfix urgency takes priority.
441
- 7. Commit & push (STEP 11) — include in the SAME commit:
442
- - MEMORY.md: add note under "Notes": `Hotfix: [description] ([date])`, set `Current Task` to `(none)`, `Current Step` to `(none)`
524
+ 7. Commit & push from worktree (STEP 11) — include in the SAME commit:
525
+ - Copy MEMORY.md into worktree. MEMORY.md: add note under "Notes": `Hotfix: [description] ([date])`, set `Current Task` to `(none)`, `Current Step` to `(none)`, `Current Worktree` to `(none)`
443
526
  - Do NOT update TODO.md checkboxes unless the fix corresponds to an existing task
444
- 8. Post-merge: follow STEP 12 logic (solo: merge to main, team: MR/PR). No additional commits.
527
+ 8. Post-merge: follow STEP 12 logic (merge to main from project root, clean up worktree + branch). No additional commits.
445
528
  9. **Patch release**: if git integration active, delegate to `devops-integrator`: "Hotfix merged. Create a patch release with changelog."
446
529
 
447
530
  **Skipped steps:** STEP 4 (tests — unless the bug reveals missing test coverage), STEP 6 (visual verification).
@@ -452,19 +535,20 @@ For critical production bugs (outside normal TODO.md flow):
452
535
 
453
536
  If a merge conflict occurs:
454
537
 
455
- **During feature branch development** (STEP 3-10):
456
- 1. `git fetch origin main && git rebase origin/main`
538
+ **During feature branch development** (STEP 3-10, in worktree):
539
+ 1. `cd {worktree-path} && git fetch origin main && git rebase origin/main`
457
540
  2. Resolve conflicts manually — prefer keeping both changes when possible
458
- 3. Re-run STEP 5 (build, lint & test) after resolution
541
+ 3. Re-run STEP 5 (build, lint & test) in the worktree after resolution
459
542
  4. If conflict changes are significant (not just trivial merge): re-run STEP 7 (code review) on affected files
460
- 5. If rebase is too complex: `git merge origin/main` instead (creates merge commit but is safer)
543
+ 5. If rebase is too complex: `cd {worktree-path} && git merge origin/main` instead (creates merge commit but is safer)
461
544
  6. Log the conflict resolution in MEMORY.md Notes
462
545
 
463
- **During `git merge feat/branch` on main** (STEP 12 solo/no-git path):
546
+ **During `git merge feat/branch` on main** (STEP 12, from project root):
464
547
  1. Resolve the conflict in the merge commit (do NOT rebase here — you are on main)
465
548
  2. `git add [resolved files]` (only resolved files — do NOT use `git add .`), then `git merge --continue`
466
- 3. Re-run STEP 5 to verify the merged result
549
+ 3. Verify the merged result: build, lint, test from project root
467
550
  4. Push: `git push origin HEAD`
551
+ 5. Then clean up: `git worktree remove .worktrees/feat/{slug} && git branch -d feat/{slug}`
468
552
 
469
553
  ## Tech Debt & Refactoring
470
554
 
@@ -484,7 +568,7 @@ NEVER stay stuck. Escalation order:
484
568
  **A: RESEARCH** — Explore codebase, WebSearch for docs
485
569
  **B: ARCHITECT** — Delegate to `backend-ts-architect` or `ui-engineer` with problem description
486
570
  **C: DECIDE** — Pick best approach, log to MEMORY.md
487
- **D: SKIP (last resort)** — Only if blocker is objectively unresolvable. Revert changes (`git stash --include-untracked -m "REVERTED: [task title]"`), return to main (`git checkout main 2>/dev/null || git checkout master`), delete orphaned branch (`git branch -D feat/{slug}`). Then log everything in MEMORY.md Blockers section, mark task as `[~]` SKIPPED in TODO.md with reason, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task.
571
+ **D: SKIP (last resort)** — Only if blocker is objectively unresolvable. Remove worktree and branch (`git worktree remove --force .worktrees/feat/{slug} && git branch -D feat/{slug}`). Clear `Current Worktree` from MEMORY.md. Log everything in MEMORY.md Blockers section, mark task as `[~]` SKIPPED in TODO.md with reason, commit tracking on main (`git add TODO.md MEMORY.md && git commit -m "chore: skip [task title] — [brief reason]"`, push only if remote exists), move to next task.
488
572
 
489
573
  ## End-of-Iteration Output
490
574
 
@@ -253,6 +253,9 @@ Phase 0: Foundation
253
253
  ## Current Step
254
254
  (none)
255
255
 
256
+ ## Current Worktree
257
+ (none)
258
+
256
259
  ## Iterations This Session
257
260
  0
258
261
 
@@ -4,7 +4,7 @@ description: "Use this agent to write, run, and diagnose tests for recently impl
4
4
  model: sonnet
5
5
  ---
6
6
 
7
- You are a Senior Test Engineer specializing in TypeScript testing with Vitest and E2E testing with Playwright. You write thorough, maintainable tests that catch real bugs without being fragile. You always RUN the tests after writing them and report results.
7
+ You are a Senior Test Engineer specializing in TypeScript testing with Vitest, integration testing, and E2E testing with Playwright. You write thorough, maintainable tests that catch real bugs without being fragile. You always RUN the tests after writing them and report results.
8
8
 
9
9
  ## Core Competencies
10
10
 
@@ -13,6 +13,7 @@ You are a Senior Test Engineer specializing in TypeScript testing with Vitest an
13
13
  - **Service testing**: DI mocking, HTTP interceptor testing, IndexedDB mocking
14
14
  - **Business logic testing**: Pure function tests, edge cases, boundary conditions
15
15
  - **Domain model testing**: Validation, invariants, value object equality
16
+ - **Integration testing**: API endpoint tests (supertest/test server), DB operations, service collaboration, library public API contracts
16
17
  - **E2E testing**: Playwright browser automation, user flow testing, visual verification
17
18
 
18
19
  ## Frontend Profile
@@ -217,12 +218,97 @@ test.describe('Checkout Flow', () => {
217
218
  - Each test should be independent — no shared state between tests
218
219
  - Keep E2E tests focused on critical paths — don't duplicate unit test coverage
219
220
 
221
+ ## Integration Testing (Backend / Packages)
222
+
223
+ When called for **integration test writing**, create tests that verify components working together:
224
+
225
+ ### When to write integration tests
226
+ - API endpoints: real HTTP request/response cycles (use test server, supertest, or framework test utilities)
227
+ - Database operations: queries, migrations, transactions against a test database (SQLite in-memory or test D1)
228
+ - Service interactions: multiple services collaborating (DI container with real implementations, not mocks)
229
+ - Publishable library public API: test the exported surface as a consumer would use it (import from package entry point)
230
+ - Middleware chains: auth → validation → handler → response
231
+
232
+ ### Integration test file naming
233
+ - Use `*.integration.spec.ts` suffix — co-located next to source files (same rule as unit tests, NOT in a separate directory)
234
+ - Example: `create-user.handler.ts` → `create-user.handler.integration.spec.ts`
235
+
236
+ ### Integration test template (API endpoint)
237
+
238
+ ```typescript
239
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
240
+ // or import from test framework detected in project
241
+
242
+ describe('POST /api/users (integration)', () => {
243
+ let app: AppType; // framework-specific app instance
244
+
245
+ beforeAll(async () => {
246
+ // Start test server with real DI container, test DB
247
+ app = await createTestApp({ database: 'test' });
248
+ });
249
+
250
+ afterAll(async () => {
251
+ await app.close();
252
+ });
253
+
254
+ it('creates a user and returns 201', async () => {
255
+ const res = await app.request('/api/users', {
256
+ method: 'POST',
257
+ headers: { 'Content-Type': 'application/json' },
258
+ body: JSON.stringify({ name: 'Test User', email: 'test@example.com' }),
259
+ });
260
+
261
+ expect(res.status).toBe(201);
262
+ const body = await res.json();
263
+ expect(body).toMatchObject({ name: 'Test User', email: 'test@example.com' });
264
+ expect(body.id).toBeDefined();
265
+ });
266
+
267
+ it('returns 400 for invalid input', async () => {
268
+ const res = await app.request('/api/users', {
269
+ method: 'POST',
270
+ headers: { 'Content-Type': 'application/json' },
271
+ body: JSON.stringify({ name: '' }),
272
+ });
273
+
274
+ expect(res.status).toBe(400);
275
+ });
276
+ });
277
+ ```
278
+
279
+ ### Integration test template (publishable library)
280
+
281
+ ```typescript
282
+ import { describe, it, expect } from 'vitest';
283
+ // Import from the package entry point, NOT from internal paths
284
+ import { createWidget, WidgetConfig } from '@my-scope/my-lib';
285
+
286
+ describe('my-lib public API (integration)', () => {
287
+ it('creates a widget with default config', () => {
288
+ const widget = createWidget({ type: 'basic' });
289
+ expect(widget).toBeDefined();
290
+ expect(widget.type).toBe('basic');
291
+ });
292
+
293
+ it('validates config and throws on invalid input', () => {
294
+ expect(() => createWidget({} as WidgetConfig)).toThrow();
295
+ });
296
+ });
297
+ ```
298
+
299
+ ### Integration test principles
300
+ - Use **real implementations** (not mocks) for the components under test — mock only external boundaries (network, filesystem, third-party APIs)
301
+ - Each test should set up and tear down its own state (test DB, test server)
302
+ - Keep integration tests focused — test the contract/behavior, not internals
303
+ - Integration tests are slower than unit tests — that's expected. Don't optimize for speed at the cost of coverage.
304
+
220
305
  ## Running Tests (MANDATORY)
221
306
 
222
307
  After writing ALL test files, you MUST run them and report results:
223
308
 
224
309
  ```bash
225
- # Unit tests (auto-detects Vitest or Jest based on project config)
310
+ # Unit + integration tests (auto-detects Vitest or Jest based on project config)
311
+ # Integration tests (*.integration.spec.ts) are picked up automatically alongside unit tests
226
312
  nx test [PROJECT] 2>&1 | tail -50
227
313
 
228
314
  # E2E tests (if written) — requires dev server running
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.30",
3
+ "version": "1.1.32",
4
4
  "description": "Scaffold a project with Claude Code agents for autonomous AI-driven development",
5
5
  "type": "module",
6
6
  "bin": {