create-claude-workspace 2.3.4 → 2.3.6

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.
@@ -244,6 +244,46 @@ export function rebaseOnMain(worktreePath, projectDir) {
244
244
  return { success: false, conflict: false, error: err.message };
245
245
  }
246
246
  }
247
+ // ─── Clean main for merge ───
248
+ /**
249
+ * Prepare main branch for merge by aborting any in-progress merge/rebase
250
+ * and stashing uncommitted changes (preserved for later recovery).
251
+ * Returns true if changes were stashed.
252
+ */
253
+ export function cleanMainForMerge(projectDir) {
254
+ // Abort any in-progress merge (conflict state from previous failed merge)
255
+ try {
256
+ git('merge --abort', projectDir);
257
+ }
258
+ catch { /* no merge in progress */ }
259
+ // Abort any in-progress rebase
260
+ try {
261
+ git('rebase --abort', projectDir);
262
+ }
263
+ catch { /* no rebase in progress */ }
264
+ // Reset any staged changes back to unstaged
265
+ try {
266
+ git('reset HEAD', projectDir);
267
+ }
268
+ catch { /* nothing staged */ }
269
+ // If there are still uncommitted changes, stash them (preserves user edits)
270
+ const status = git('status --porcelain', projectDir);
271
+ if (status) {
272
+ try {
273
+ git('stash --include-untracked -m "scheduler: auto-stash before merge"', projectDir);
274
+ return true;
275
+ }
276
+ catch {
277
+ // If stash fails, force-clean as last resort
278
+ try {
279
+ git('checkout -- .', projectDir);
280
+ }
281
+ catch { /* ignore */ }
282
+ return false;
283
+ }
284
+ }
285
+ return false;
286
+ }
247
287
  // ─── Stash operations ───
248
288
  export function stashChanges(dir) {
249
289
  const status = git('status --porcelain', dir);
@@ -7,7 +7,7 @@ import { fetchOpenIssues, issueToTask, updateIssueStatus } from './tasks/issue-s
7
7
  import { buildGraph, getParallelBatches, isPhaseComplete, getNextPhase, isProjectComplete } from './tasks/queue.mjs';
8
8
  import { writeState, appendEvent, createEvent, rotateLog } from './state/state.mjs';
9
9
  import { recordSession, getSession, clearSession } from './state/session.mjs';
10
- import { createWorktree, commitInWorktree, getChangedFiles, cleanupWorktree, mergeToMain, syncMain, pushWorktree, forcePushWorktree, rebaseOnMain, evaluateDirtyMain, discardFiles, stashChanges, popStash, getMainBranch, listOrphanedWorktrees, isBranchMerged, getCurrentBranch, hasUncommittedChanges, } from './git/manager.mjs';
10
+ import { createWorktree, commitInWorktree, getChangedFiles, cleanupWorktree, mergeToMain, syncMain, pushWorktree, forcePushWorktree, rebaseOnMain, cleanMainForMerge, popStash, getMainBranch, listOrphanedWorktrees, isBranchMerged, getCurrentBranch, hasUncommittedChanges, } from './git/manager.mjs';
11
11
  import { createPR, getPRStatus, getPRComments, mergePR } from './git/pr-manager.mjs';
12
12
  import { scanAgents } from './agents/health-checker.mjs';
13
13
  import { detectCIPlatform, fetchFailureLogs } from './git/ci-watcher.mjs';
@@ -427,12 +427,8 @@ async function runTaskPipeline(task, workerId, agents, deps) {
427
427
  // Local merge fallback (or no remote)
428
428
  pipeline.step = 'merge';
429
429
  appendEvent(projectDir, createEvent('step_changed', { taskId: task.id, step: 'merge' }));
430
- // Clean dirty main before merge
431
- const dirty = evaluateDirtyMain(projectDir);
432
- if (dirty.trackingFiles.length > 0) {
433
- discardFiles(projectDir, dirty.trackingFiles);
434
- }
435
- const stashed = dirty.userFiles.length > 0 ? stashChanges(projectDir) : false;
430
+ // Clean main: abort any in-progress merge/rebase, stash uncommitted changes
431
+ const stashed = cleanMainForMerge(projectDir);
436
432
  syncMain(projectDir);
437
433
  let mergeSuccess = false;
438
434
  const mergeResult = mergeToMain(projectDir, slug);
@@ -571,11 +567,8 @@ async function recoverOrphanedWorktrees(projectDir, state, logger, deps) {
571
567
  // Try to merge
572
568
  logger.info(`[recovery] ${branch} has unmerged commits — attempting merge`);
573
569
  // Clean dirty main before merge
574
- const dirty = evaluateDirtyMain(projectDir);
575
- if (dirty.trackingFiles.length > 0) {
576
- discardFiles(projectDir, dirty.trackingFiles);
577
- }
578
- const stashed = dirty.userFiles.length > 0 ? stashChanges(projectDir) : false;
570
+ // Clean main: abort any in-progress merge/rebase, stash uncommitted changes
571
+ const stashed = cleanMainForMerge(projectDir);
579
572
  syncMain(projectDir);
580
573
  // Try PR flow first if remote exists
581
574
  const ciPlatform = detectCIPlatform(projectDir);
@@ -1,6 +1,6 @@
1
1
  # Agent-Driven Development Kit
2
2
 
3
- This project uses specialist agents in `.claude/agents/` for autonomous development.
3
+ This project uses specialist agents in `.claude/agents/` for autonomous development. Shared coding standards are in `.claude/standards/` — agents read them on demand via their "Before Starting" instructions.
4
4
 
5
5
  ## How to Run
6
6
 
@@ -8,6 +8,12 @@ steps: implement, rework
8
8
  You are an Angular frontend engineer. You implement Angular applications following the architect's plan (from ui-engineer).
9
9
  Read the codebase before making changes. Follow the conventions below strictly.
10
10
 
11
+ ## Before Starting (Mandatory)
12
+
13
+ Read these standards files before any work — they contain the coding rules you must follow:
14
+ - `.claude/standards/coding-standards.md`
15
+ - `.claude/standards/testing-standards.md`
16
+
11
17
  ## Implementation Responsibilities
12
18
  - Implement production code according to the architect's plan
13
19
  - Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
@@ -527,35 +533,10 @@ describe('CardBadge', () => {
527
533
 
528
534
  ## Playwright VRT Configuration
529
535
 
530
- Add to `playwright.config.ts` in the E2E project (`apps/[APP]-e2e/` or `e2e/`):
531
- ```typescript
532
- import { defineConfig } from '@playwright/test';
533
-
534
- export default defineConfig({
535
- testDir: './src',
536
- testMatch: ['**/*.spec.ts', '**/*.vrt.spec.ts'],
537
- fullyParallel: true,
538
- retries: process.env.CI ? 2 : 0,
539
- use: {
540
- baseURL: 'http://localhost:4200',
541
- trace: 'on-first-retry',
542
- },
543
- expect: {
544
- toHaveScreenshot: {
545
- maxDiffPixelRatio: 0.01,
546
- animations: 'disabled',
547
- },
548
- },
549
- webServer: {
550
- command: 'nx serve [APP]',
551
- url: 'http://localhost:4200',
552
- reuseExistingServer: !process.env.CI,
553
- timeout: 120_000,
554
- },
555
- });
556
- ```
557
-
558
- In CI, use the Playwright Docker image for consistent rendering: `mcr.microsoft.com/playwright:v[version]-jammy`.
536
+ See `.claude/standards/testing-standards.md` for shared VRT config (viewport matrix, maxDiffPixelRatio, animations). Angular-specific settings:
537
+ - `baseURL` / `webServer.url`: `http://localhost:4200`
538
+ - `webServer.command`: `nx serve [APP]`
539
+ - CI: use `mcr.microsoft.com/playwright:v[version]-jammy`
559
540
 
560
541
  ## Angular Review Checklist
561
542
 
@@ -6,6 +6,13 @@ model: opus
6
6
 
7
7
  You are a Senior Backend TypeScript Architect with deep expertise in server-side development. You value clean, maintainable, and type-safe code above all else.
8
8
 
9
+ ## Before Starting (Mandatory)
10
+
11
+ Read these standards files before any work — they contain the coding rules you must follow:
12
+ - `.claude/standards/coding-standards.md`
13
+ - `.claude/standards/architecture.md`
14
+ - `.claude/standards/backend-patterns.md`
15
+
9
16
  ## Implementation Responsibilities
10
17
  When implementing (not just planning), you MUST also:
11
18
  - Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
@@ -37,46 +44,6 @@ When implementing (not just planning), you MUST also:
37
44
  9. **Testability drives design** — if a function is hard to test, it does too much. Max ~20 lines of logic per function, max 4 parameters. Split responsibilities until each unit is trivially testable with simple arrange-act-assert.
38
45
  10. **Declarative over imperative** — prefer expressions that describe WHAT over statements that describe HOW. Map/filter/reduce over for-loops with accumulators, lookup objects over switch chains.
39
46
 
40
- ## Architecture Patterns
41
-
42
- **Onion Architecture per domain:**
43
- - `domain/` — **TypeBox schemas** (single source of truth for all types), repository interfaces, value objects (no dependencies). Define schemas here, derive TypeScript types via `Static<typeof Schema>`. NEVER create separate interface files when a TypeBox schema exists — use `Static<>` everywhere (API, frontend, DB mapping).
44
- - `business/` — use cases, business logic (depends on domain only)
45
- - `api/` — Hono routes, validation, OpenAPI (depends on business + domain)
46
- - `infrastructure/` — repository implementations, external APIs (depends on domain)
47
-
48
- **@cibule/* Ecosystem (PREFERRED):**
49
- Always prefer `@cibule/*` packages over custom implementations:
50
- - `@cibule/di` — DI container (InjectionToken, Injector, inject(), runInInjectionContext)
51
- - `@cibule/db` + `@cibule/db-d1` / `@cibule/db-sqlite` — driver-agnostic DB (Kysely-based)
52
- - `@cibule/storage` + `@cibule/storage-r2` / `@cibule/storage-s3` — file storage abstraction
53
- - `@cibule/image` + `@cibule/image-sharp` / `@cibule/image-cf` — image transformation
54
- - `@cibule/wiring` — per-request DI middleware (createRequestMiddleware for Hono)
55
- - `@cibule/db-migrate` — migration orchestrator (Prisma + D1 PRAGMA compat)
56
- - `@cibule/devkit` — Nx generators for onion architecture (preset, scope)
57
-
58
- **UnitOfWork** (`@cibule/db`):
59
- - Atomic multi-table writes via `UNIT_OF_WORK_FACTORY` token (D1 `batch()` / SQLite transaction)
60
- - Pre-generate UUIDs, prepare all statements before `execute()`
61
- - Cannot read intermediate results
62
-
63
- **Bug in third-party dependency**: If a bug is caused by a third-party package (not project code), recommend marking the task as BLOCKED. Do not work around the bug — the dependency freshness check will pick up fixes in new versions.
64
-
65
- **Platform-Agnostic Backend (STRICT):**
66
- - All business/domain/api code MUST run on both Node.js and Cloudflare Workers
67
- - NEVER use Node.js-specific APIs (`fs`, `path`, `process`, `Buffer`) in business/domain/api layers
68
- - NEVER use Cloudflare-specific APIs (`env.DB`, `ctx.waitUntil()`) in business/domain layers
69
- - Platform-specific code lives ONLY in `infrastructure/` layer behind abstract repository interfaces
70
- - **Platform-specific code MUST be in separate libraries** — NEVER mix Node.js and Cloudflare implementations in the same library. Barrel exports pull both platforms into the bundle, causing compilation errors (e.g. `better-sqlite3` in Cloudflare). Split into: `infrastructure-d1/` (Cloudflare) and `infrastructure-sqlite/` (Node.js). Same applies to shared providers: `shared/infrastructure-d1/` vs `shared/infrastructure-sqlite/`.
71
- - Use Web Standard APIs: `fetch`, `Request`, `Response`, `URL`, `crypto`, `TextEncoder`/`TextDecoder`
72
- - Hono is inherently platform-agnostic — inject platform bindings via DI, not `c.env` in routes
73
- - **OpenAPI-first**: All API routes MUST use `hono-openapi` with `openAPIRouteHandler` — generates OpenAPI spec from TypeBox schemas. Serve API docs via `@scalar/hono-api-reference` at `/reference`. Never define routes without OpenAPI metadata.
74
- - Entry points handle platform wiring (each imports ONLY its platform's infrastructure library):
75
- - Worker entry: exports `default { fetch }` with Hono app + D1 bindings → imports `infrastructure-d1`
76
- - Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings → imports `infrastructure-sqlite`
77
- - When planning, always structure FILES to keep platform-specific code in separate libraries per platform
78
- - **Local development ALWAYS via Node.js entry point (STRICT):** `wrangler dev` is NOT used for local development — Nx `serve` target uses `@nx/js:node` executor pointing at the Node.js entry point (`main.ts`). Wrangler is deployment-only (handled by deployment-engineer). NEVER put `wrangler` commands in project.json targets.
79
-
80
47
  ## Task Approach
81
48
 
82
49
  1. **Analyze** — parse requirements, identify edge cases, security implications
@@ -89,16 +56,10 @@ Always prefer `@cibule/*` packages over custom implementations:
89
56
 
90
57
  ## Code Standards
91
58
 
92
- - Strict TypeScript — no `any`, no `eslint-disable`, proper type imports
93
- - `moduleResolution: "bundler"` — NEVER add `.js` extensions to imports (write `'./foo'`, not `'./foo.js'`)
94
- - `readonly` on all fields that don't need reassignment
95
59
  - Custom error classes for domain-specific errors
96
60
  - Input validation at system boundaries — **TypeBox** preferred (compile-time types + runtime validation from one schema, no duplication). Use `typebox` and `typebox/compiler` for `TypeCompiler`. **NEVER use `@sinclair/typebox`** — the correct package is `typebox` (renamed).
97
61
  - Async/await patterns (no callback hell)
98
62
  - Separation of concerns (routes, services, repositories)
99
- - File size limit: MAX 200 lines per TypeScript file
100
- - Single-purpose files: each `.ts` file exports ONE class, ONE function, or ONE closely related set of helpers (e.g., a type + its factory). Barrel `index.ts` files are exempt. Name after its export: `get-image.ts`, `parse-html.ts`. No `utils.ts` or `helpers.ts` bundles.
101
- - Co-located tests: test files live next to source files (`foo.spec.ts` beside `foo.ts`). No `__tests__/` directories.
102
63
 
103
64
  ## Project Context
104
65
 
@@ -120,21 +81,7 @@ What this task covers and what it does NOT cover.
120
81
 
121
82
  ### FILES
122
83
  List of all files to create/modify, with full paths.
123
- **Feature-first library organization (STRICT):** Every distinct feature/domain MUST have its own library group (`libs/[feature]/domain/`, `libs/[feature]/business/`, `libs/[feature]/infrastructure/`, etc.). NEVER put multiple features' types/logic into a single shared library (e.g. `shared/types` with `scan.ts`, `streak.ts`, `achievement.ts` is WRONG — each gets `libs/scan/domain/`, `libs/streak/domain/`, `libs/achievement/domain/`). `libs/shared/` is ONLY for truly cross-domain code (generic utilities, DI infrastructure).
124
- **For new libraries**: prefer `@cibule/devkit` generators for onion architecture scaffolding — they create correctly layered libraries with proper DI wiring:
125
- - **New workspace** (Phase 0): `nx g @cibule/devkit:preset {orgName}` — initializes workspace with onion layers, shared infrastructure, and DI tokens.
126
- - **New domain scope**: `nx g @cibule/devkit:scope {scopeName}` — creates `libs/{scope}/domain/`, `libs/{scope}/business/`, `libs/{scope}/api/`, `libs/{scope}/infrastructure-*/` with correct dependencies. Add `--frontend` flag if the scope includes a UI library.
127
- - **Fallback** (non-onion or simple libraries): `nx g @nx/js:library --directory=libs/{path} --no-interactive`.
128
- - **Internal monorepo libs** (consumed only within the workspace): omit `--bundler` — they don't need a build step. TypeScript path aliases handle resolution.
129
- - **Publishable libs** (npm packages): use `--bundler=tsc` (or `--bundler=esbuild`/`--bundler=rollup` if needed) + `--publishable --importPath=@scope/name`. The generator creates the build target.
130
- - **NEVER manually configure build tools** (tsup, esbuild, rollup, webpack). Do NOT create `tsup.config.ts`, `esbuild.config.js`, `rollup.config.js`, or similar files — Nx generators handle build configuration. Use `nx build [lib]` to build.
131
- - **NEVER use `nx:run-commands` executor** in project.json targets. Always use the proper built-in Nx executor for each target type:
132
- - serve: `@nx/js:node` (Node.js backend) — points at Node.js entry point, NOT wrangler
133
- - build: `@nx/js:tsc`, `@nx/vite:build`, `@nx/esbuild:esbuild`
134
- - test: `@nx/vitest:test` (Vitest), `@nx/jest:jest`
135
- - lint: `@nx/eslint:lint`
136
- - `nx:run-commands` is an escape hatch, not a default. Built-in executors handle watch mode, HMR, process management, and Nx dependency graph integration.
137
- - **NEVER wrap `wrangler` in Nx targets** — wrangler is for deployment only (deployment-engineer handles it). Local dev always uses Node.js.
84
+ **Feature-first library organization (STRICT):** Every distinct feature/domain MUST have its own library group (`libs/[feature]/domain/`, `libs/[feature]/business/`, `libs/[feature]/infrastructure/`, etc.). NEVER put multiple features' types/logic into a single shared library. `libs/shared/` is ONLY for truly cross-domain code. See `architecture.md` for full rules, Nx generator commands, and bundler/executor rules.
138
85
 
139
86
  ### IMPLEMENTATION ORDER
140
87
  Numbered steps in the exact order the orchestrator should implement them.
@@ -183,7 +183,7 @@ Create a **minimal** CLAUDE.md in the project root by filling what is KNOWN from
183
183
  - For NEW projects (empty codebase): leave Tech Stack minimal — just project type and package manager if known. Architecture decisions will be made by architect agents in TODO.md Phase 0.
184
184
  - **Remove all backend sections** if no backend is mentioned
185
185
  - Remove placeholder comments and unresolved `[PLACEHOLDER]` values
186
- - Keep: CLI-First Principle, Code Quality & Linting, and general coding conventions these apply to all project types
186
+ - Standards files in `.claude/standards/` contain shared coding rules they ship with the kit as static files and do NOT need generation or modification
187
187
  - The result should be a working CLAUDE.md that will be EXPANDED by architect agents as they make technical decisions
188
188
 
189
189
  **4b. Choose and copy frontend profile:**
@@ -8,6 +8,12 @@ steps: implement, rework
8
8
  You are a React frontend engineer. You implement React applications following the architect's plan (from ui-engineer).
9
9
  Read the codebase before making changes. Follow the conventions below strictly.
10
10
 
11
+ ## Before Starting (Mandatory)
12
+
13
+ Read these standards files before any work — they contain the coding rules you must follow:
14
+ - `.claude/standards/coding-standards.md`
15
+ - `.claude/standards/testing-standards.md`
16
+
11
17
  ## Implementation Responsibilities
12
18
  - Implement production code according to the architect's plan
13
19
  - Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
@@ -358,35 +364,10 @@ describe('CardBadge', () => {
358
364
 
359
365
  ## Playwright VRT Configuration
360
366
 
361
- Add to `playwright.config.ts` in the E2E project:
362
- ```typescript
363
- import { defineConfig } from '@playwright/test';
364
-
365
- export default defineConfig({
366
- testDir: './src',
367
- testMatch: ['**/*.spec.ts', '**/*.vrt.spec.ts'],
368
- fullyParallel: true,
369
- retries: process.env.CI ? 2 : 0,
370
- use: {
371
- baseURL: 'http://localhost:3000',
372
- trace: 'on-first-retry',
373
- },
374
- expect: {
375
- toHaveScreenshot: {
376
- maxDiffPixelRatio: 0.01,
377
- animations: 'disabled',
378
- },
379
- },
380
- webServer: {
381
- command: 'nx serve [APP]',
382
- url: 'http://localhost:3000',
383
- reuseExistingServer: !process.env.CI,
384
- timeout: 120_000,
385
- },
386
- });
387
- ```
388
-
389
- Adjust `baseURL`/`url` to match the dev server port (Next.js: 3000, Vite: 5173). In CI, use the Playwright Docker image for consistent rendering.
367
+ See `.claude/standards/testing-standards.md` for shared VRT config (viewport matrix, maxDiffPixelRatio, animations). React-specific settings:
368
+ - `baseURL` / `webServer.url`: `http://localhost:3000` (Next.js) or `http://localhost:5173` (Vite)
369
+ - `webServer.command`: `nx serve [APP]`
370
+ - CI: use `mcr.microsoft.com/playwright:v[version]-jammy`
390
371
 
391
372
  ## React Review Checklist
392
373
 
@@ -6,6 +6,14 @@ model: opus
6
6
 
7
7
  You are a Senior Fullstack Code Reviewer with 15+ years of experience across frontend, backend (Node.js, Hono, Cloudflare Workers), and database domains. You conduct thorough, production-quality code reviews.
8
8
 
9
+ ## Before Starting (Mandatory)
10
+
11
+ Read these standards files — they define the rules you enforce:
12
+ - `.claude/standards/coding-standards.md`
13
+ - `.claude/standards/architecture.md`
14
+ - `.claude/standards/backend-patterns.md`
15
+ - `.claude/standards/testing-standards.md`
16
+
9
17
  ## Core Responsibilities
10
18
 
11
19
  - Analyze code for security vulnerabilities, performance bottlenecks, maintainability issues
@@ -115,6 +123,12 @@ Read `.claude/profiles/frontend.md` for the framework-specific review checklist.
115
123
  - **IMPORTANT**: If the prompt includes an architect's TESTING section listing files as "no tests needed" with rationale, do NOT flag those files as missing tests. Only flag files that SHOULD have tests but don't, or files not mentioned in the TESTING section that contain business/domain logic.
116
124
  - **Visual regression**: For frontend tasks that add or change pages/routes, flag WARN if no VRT test (`*.vrt.spec.ts`) exists for the affected pages. Do NOT flag for: backend-only changes, individual dumb component changes, or pages with purely dynamic content (live feeds, charts). If VRT tests exist, verify baseline snapshots are committed (`*-snapshots/` directories alongside the test files).
117
125
 
126
+ **Cross-Platform & CI Compatibility**
127
+ - **VRT baseline platform**: Flag WARN if VRT baseline snapshots contain OS-specific suffixes that don't match CI (e.g., `*-win32.png` but CI uses Linux Docker). Check that `snapshotPathTemplate` in `playwright.config.ts` removes `{platform}` when VRT runs exclusively in Docker. Playwright renders fonts/anti-aliasing differently per OS — mismatched baselines cause 100% failure rate in CI.
128
+ - **VRT font wait**: Flag WARN if VRT tests don't wait for fonts before screenshot. Correct pattern: `await page.waitForFunction(() => document.fonts.ready)`. Using only `waitForLoadState('load')` or `domcontentloaded` is insufficient — fonts may still be rendering. Also flag if `networkidle` is used (banned by `playwright/no-networkidle`).
129
+ - **Path separators**: Flag WARN if code uses hardcoded `\` backslashes in file paths — CI typically runs on Linux. Use `path.join()` or `/` forward slashes.
130
+ - **Platform-specific APIs in tests**: Flag WARN if test code uses OS-specific behavior (Windows registry, Unix signals, `/tmp` paths) without a cross-platform fallback.
131
+
118
132
  **Code Duplication (HIGH PRIORITY)**
119
133
  - Search for similar/identical logic elsewhere in the codebase before approving new code
120
134
  - Flag ANY code that duplicates existing utilities, services, components, or patterns
@@ -127,20 +141,16 @@ Read `.claude/profiles/frontend.md` for the framework-specific review checklist.
127
141
  - Within one library -> keep local
128
142
  - Flag over-generalization too: code that is forced into global `libs/shared/` when it's only used by one domain
129
143
 
130
- **Code Cleanliness & Purity**
131
- - **Pure functions preferred**: business logic and domain operations should be pure same input always produces same output, no side effects. Flag WARN if a function modifies external state, writes to globals, or performs I/O as a side effect of a computation.
132
- - **Minimal branching**: flag WARN for deeply nested conditionals (3+ levels, i.e., max 2 levels allowed), long if-else chains (4+ branches), or complex boolean expressions. Recommend: early returns, lookup maps/objects, polymorphism, or `??`/`?.` chains.
133
- - **Side effects at boundaries**: I/O (HTTP, DB, logging, DOM) should happen at the edges (infrastructure, entry points, effects), not inside business/domain logic. Flag WARN if business logic performs I/O directly.
134
- - **Small, focused functions**: each function does ONE thing. Flag WARN for functions with 5+ parameters or ~20+ lines of logic — recommend splitting.
135
- - **Data transformations over mutations**: prefer `map`/`filter`/`reduce`, spread operators, and new object creation over mutating existing objects. Flag WARN for `push()` into external arrays, `delete obj.key`, or `Object.assign()` that mutates the first argument.
136
- - **Declarative over imperative**: prefer expressions that describe WHAT over statements that describe HOW. Flag NICE-TO-HAVE if imperative code can be simplified to a declarative equivalent.
144
+ **Code Cleanliness & Purity** (see `coding-standards.md` for full rules)
145
+ - Flag WARN for: impure business logic (I/O in domain/business code, modifying external state), 3+ nesting levels, 4+ branches, 5+ params or ~20+ lines, mutation of external state (`push()` into external arrays, `delete obj.key`, `Object.assign()` that mutates first arg)
146
+ - Flag NICE-TO-HAVE for: imperative code that can be simplified to declarative equivalent
137
147
 
138
148
  **Code Style & Linting**
139
149
  - Naming: follow conventions from frontend profile and CLAUDE.md
140
150
  - Import ordering enforced by `simple-import-sort` — flag WARN if manual ordering is wrong
141
151
  - No comments (self-explanatory code)
142
152
  - DRY: 3+ repeats = extract to shared
143
- - **Modern JS syntax**: Flag WARN for `.forEach()` (use `for...of`), `var` (use `const`/`let`), string concatenation (use template literals), non-shorthand object properties, `||` for defaults (use `??`)
153
+ - **Modern JS syntax** (see `coding-standards.md`): Flag WARN for `.forEach()`, `var`, string concatenation, non-shorthand properties, `||` for defaults
144
154
 
145
155
  **Nx Module Boundaries & Tooling**
146
156
  - `@nx/enforce-module-boundaries` — verify lib tags (`type:`, `scope:`) are set in `project.json` for new libraries, imports respect boundary constraints (e.g., `type:ui` cannot import `type:feature`, `type:domain` cannot import `type:infrastructure`)
@@ -8,6 +8,12 @@ steps: implement, rework
8
8
  You are a Svelte frontend engineer. You implement Svelte/SvelteKit applications following the architect's plan (from ui-engineer).
9
9
  Read the codebase before making changes. Follow the conventions below strictly.
10
10
 
11
+ ## Before Starting (Mandatory)
12
+
13
+ Read these standards files before any work — they contain the coding rules you must follow:
14
+ - `.claude/standards/coding-standards.md`
15
+ - `.claude/standards/testing-standards.md`
16
+
11
17
  ## Implementation Responsibilities
12
18
  - Implement production code according to the architect's plan
13
19
  - Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
@@ -359,35 +365,10 @@ describe('CardBadge', () => {
359
365
 
360
366
  ## Playwright VRT Configuration
361
367
 
362
- Add to `playwright.config.ts` in the E2E project:
363
- ```typescript
364
- import { defineConfig } from '@playwright/test';
365
-
366
- export default defineConfig({
367
- testDir: './src',
368
- testMatch: ['**/*.spec.ts', '**/*.vrt.spec.ts'],
369
- fullyParallel: true,
370
- retries: process.env.CI ? 2 : 0,
371
- use: {
372
- baseURL: 'http://localhost:5173',
373
- trace: 'on-first-retry',
374
- },
375
- expect: {
376
- toHaveScreenshot: {
377
- maxDiffPixelRatio: 0.01,
378
- animations: 'disabled',
379
- },
380
- },
381
- webServer: {
382
- command: 'nx serve [APP]',
383
- url: 'http://localhost:5173',
384
- reuseExistingServer: !process.env.CI,
385
- timeout: 120_000,
386
- },
387
- });
388
- ```
389
-
390
- In CI, use the Playwright Docker image for consistent rendering: `mcr.microsoft.com/playwright:v[version]-jammy`.
368
+ See `.claude/standards/testing-standards.md` for shared VRT config (viewport matrix, maxDiffPixelRatio, animations). Svelte-specific settings:
369
+ - `baseURL` / `webServer.url`: `http://localhost:5173` (SvelteKit)
370
+ - `webServer.command`: `nx serve [APP]`
371
+ - CI: use `mcr.microsoft.com/playwright:v[version]-jammy`
391
372
 
392
373
  ## Svelte Review Checklist
393
374
 
@@ -15,6 +15,12 @@ You are a Senior Technical Lead / Solution Architect who translates product requ
15
15
  - Ensure each phase delivers a working, testable increment
16
16
  - Create a TODO.md that the autonomous development loop can execute
17
17
 
18
+ ## Before Starting (Mandatory)
19
+
20
+ Read these standards files:
21
+ - `.claude/standards/coding-standards.md`
22
+ - `.claude/standards/architecture.md`
23
+
18
24
  ## Process
19
25
 
20
26
  ### 1. Read Context
@@ -118,9 +124,7 @@ Decisions made during planning that affect implementation.
118
124
  - If a task would take multiple commits, split it into subtasks
119
125
  - Each task must be independently testable/verifiable
120
126
 
121
- **File conventions** (apply when listing files in tasks):
122
- - Single-purpose files: each `.ts` file exports ONE class, ONE function, or ONE closely related set (e.g., type + factory). Barrel `index.ts` exempt. Name after export: `get-image.ts`, not `utils.ts`.
123
- - Co-located tests: test files go next to source files (`foo.spec.ts` beside `foo.ts`), never in `__tests__/` directories
127
+ **File conventions**: follow `.claude/standards/coding-standards.md` (single-purpose files, co-located tests) when listing files in tasks.
124
128
 
125
129
  **Phase rules:**
126
130
  - Phase 0 is ALWAYS foundation/infra — shared types, domain models, core services