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.
- package/dist/scheduler/git/manager.mjs +40 -0
- package/dist/scheduler/loop.mjs +5 -12
- package/dist/template/.claude/CLAUDE.md +1 -1
- package/dist/template/.claude/agents/angular-engineer.md +10 -29
- package/dist/template/.claude/agents/backend-ts-architect.md +8 -61
- package/dist/template/.claude/agents/project-initializer.md +1 -1
- package/dist/template/.claude/agents/react-engineer.md +10 -29
- package/dist/template/.claude/agents/senior-code-reviewer.md +18 -8
- package/dist/template/.claude/agents/svelte-engineer.md +10 -29
- package/dist/template/.claude/agents/technical-planner.md +7 -3
- package/dist/template/.claude/agents/test-engineer.md +97 -33
- package/dist/template/.claude/agents/ui-engineer.md +6 -22
- package/dist/template/.claude/agents/vue-engineer.md +10 -29
- package/dist/template/.claude/standards/architecture.md +108 -0
- package/dist/template/.claude/standards/backend-patterns.md +82 -0
- package/dist/template/.claude/standards/coding-standards.md +64 -0
- package/dist/template/.claude/standards/testing-standards.md +94 -0
- package/dist/template/.claude/templates/claude-md.md +6 -292
- package/package.json +1 -1
|
@@ -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);
|
package/dist/scheduler/loop.mjs
CHANGED
|
@@ -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,
|
|
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
|
|
431
|
-
const
|
|
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
|
-
|
|
575
|
-
|
|
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
|
-
|
|
531
|
-
|
|
532
|
-
|
|
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
|
|
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
|
-
-
|
|
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
|
-
|
|
362
|
-
|
|
363
|
-
|
|
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
|
-
-
|
|
132
|
-
-
|
|
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
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
|
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
|