create-claude-workspace 2.2.2 → 2.3.1
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/agents/prompt-builder.mjs +15 -6
- package/dist/scheduler/agents/prompt-builder.spec.js +20 -12
- package/dist/scheduler/loop.mjs +58 -34
- package/dist/template/.claude/CLAUDE.md +10 -6
- package/dist/template/.claude/agents/angular-engineer.md +9 -3
- package/dist/template/.claude/agents/backend-ts-architect.md +6 -0
- package/dist/template/.claude/agents/react-engineer.md +9 -3
- package/dist/template/.claude/agents/senior-code-reviewer.md +4 -4
- package/dist/template/.claude/agents/svelte-engineer.md +9 -3
- package/dist/template/.claude/agents/test-engineer.md +13 -11
- package/dist/template/.claude/agents/ui-engineer.md +12 -18
- package/dist/template/.claude/agents/vue-engineer.md +9 -3
- package/package.json +1 -1
|
@@ -43,13 +43,14 @@ export function buildImplementPrompt(ctx) {
|
|
|
43
43
|
if (ctx.profileContent) {
|
|
44
44
|
lines.push(``, `## Frontend Profile`, ctx.profileContent);
|
|
45
45
|
}
|
|
46
|
-
lines.push(``, `## Instructions`, `Follow the plan exactly. Write production code.
|
|
46
|
+
lines.push(``, `## Instructions`, `Follow the plan exactly. Write production code AND unit tests.`, ``, `### Implementation`, `- Write production code according to the plan`, `- Follow project conventions from CLAUDE.md`, ``, `### Unit Tests`, `- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)`, `- Test pure logic, business rules, edge cases, error conditions`, `- Auto-detect test framework (Vitest or Jest) from project config`, `- Run tests to verify they pass`, ``, `### Verification`, `- Run build and lint — fix any failures before finishing`, `- Ensure all unit tests pass`);
|
|
47
47
|
return lines.join('\n');
|
|
48
48
|
}
|
|
49
|
-
// ───
|
|
50
|
-
export function
|
|
49
|
+
// ─── QA prompt (E2E, integration, acceptance criteria) ───
|
|
50
|
+
export function buildQAPrompt(ctx) {
|
|
51
51
|
const lines = [
|
|
52
|
-
`
|
|
52
|
+
`You are a QA engineer. Verify the implementation meets acceptance criteria and write higher-level tests.`,
|
|
53
|
+
`Unit tests were already written by the implementing developer — your focus is on integration, E2E, and acceptance.`,
|
|
53
54
|
``,
|
|
54
55
|
`## Task`,
|
|
55
56
|
`**${ctx.task.title}** (${ctx.task.type})`,
|
|
@@ -63,7 +64,7 @@ export function buildTestPrompt(ctx) {
|
|
|
63
64
|
if (ctx.testingSection) {
|
|
64
65
|
lines.push(``, `## Architect's Testing Decisions`, ctx.testingSection);
|
|
65
66
|
}
|
|
66
|
-
lines.push(``, `## Instructions`,
|
|
67
|
+
lines.push(``, `## Instructions`, ``, `### Integration Tests (*.integration.spec.ts)`, `- API endpoint tests (real HTTP calls via test server)`, `- Database operation tests (real DB, not mocks)`, `- Service collaboration tests (multiple real services)`, `- Co-locate next to source files`, ``, `### E2E Tests (if task has UI)`, `- Playwright user flow tests`, `- Test the happy path and key error scenarios`, `- Visual regression tests (toHaveScreenshot) for new pages`, ``, `### Acceptance Criteria Verification`, `- Read the task description / issue body for acceptance criteria`, `- Verify each criterion is met by the implementation`, `- If a criterion is NOT met, report it clearly`, ``, `### What NOT to do`, `- Do NOT write unit tests (developer already wrote them)`, `- Do NOT rewrite existing tests`, `- Do NOT test internal implementation details`);
|
|
67
68
|
return lines.join('\n');
|
|
68
69
|
}
|
|
69
70
|
// ─── Review prompt ───
|
|
@@ -142,8 +143,16 @@ export function buildRoutingPrompt(task, step, agents) {
|
|
|
142
143
|
`## Available Agents`,
|
|
143
144
|
agentList,
|
|
144
145
|
``,
|
|
146
|
+
`## Routing Rules`,
|
|
147
|
+
`- Planning tasks (step=plan): use architect agents (ui-engineer for frontend, backend-ts-architect for backend)`,
|
|
148
|
+
`- Implementation tasks (step=implement): use framework-specific agents (angular/react/vue/svelte-engineer) or backend-ts-architect`,
|
|
149
|
+
`- Test/QA tasks (step=test): use test-engineer (QA: E2E, integration, VRT, acceptance criteria)`,
|
|
150
|
+
`- Test infrastructure setup (VRT, Playwright config, test scaffolding): use test-engineer`,
|
|
151
|
+
`- CI/CD, deployment, pipeline config: use deployment-engineer`,
|
|
152
|
+
`- Git platform setup, secrets, labels: use devops-integrator`,
|
|
153
|
+
``,
|
|
145
154
|
`## Instructions`,
|
|
146
|
-
`Choose the most qualified agent. If no agent fits, respond with agent: null and provide a new agent definition.`,
|
|
155
|
+
`Choose the most qualified agent based on the routing rules above. If no agent fits, respond with agent: null and provide a new agent definition.`,
|
|
147
156
|
``,
|
|
148
157
|
`## Required Output Format`,
|
|
149
158
|
`Respond with JSON only:`,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { buildPlanPrompt, buildImplementPrompt,
|
|
2
|
+
import { buildPlanPrompt, buildImplementPrompt, buildQAPrompt, buildReviewPrompt, buildReworkPrompt, buildDecomposePrompt, buildRoutingPrompt, buildCIFixPrompt, buildPhaseTransitionPrompt, } from './prompt-builder.mjs';
|
|
3
3
|
// ─── Fixtures ───
|
|
4
4
|
const backendTask = {
|
|
5
5
|
id: 'p1-1',
|
|
@@ -106,9 +106,13 @@ describe('buildImplementPrompt', () => {
|
|
|
106
106
|
expect(prompt).toContain("Architect's Plan");
|
|
107
107
|
expect(prompt).toContain('Create users.ts with POST handler');
|
|
108
108
|
});
|
|
109
|
-
it('instructs to run build
|
|
109
|
+
it('instructs to run build and lint', () => {
|
|
110
110
|
const prompt = buildImplementPrompt(baseCtx);
|
|
111
|
-
expect(prompt).toContain('build
|
|
111
|
+
expect(prompt).toContain('build and lint');
|
|
112
|
+
});
|
|
113
|
+
it('instructs to write unit tests', () => {
|
|
114
|
+
const prompt = buildImplementPrompt(baseCtx);
|
|
115
|
+
expect(prompt).toContain('unit tests');
|
|
112
116
|
});
|
|
113
117
|
it('does not contain workflow instructions', () => {
|
|
114
118
|
const prompt = buildImplementPrompt(baseCtx);
|
|
@@ -117,26 +121,30 @@ describe('buildImplementPrompt', () => {
|
|
|
117
121
|
});
|
|
118
122
|
});
|
|
119
123
|
// ─── Test prompt ───
|
|
120
|
-
describe('
|
|
124
|
+
describe('buildQAPrompt', () => {
|
|
121
125
|
it('includes changed files', () => {
|
|
122
126
|
const ctx = { ...baseCtx, changedFiles: ['src/routes/users.ts', 'src/models/user.ts'] };
|
|
123
|
-
const prompt =
|
|
127
|
+
const prompt = buildQAPrompt(ctx);
|
|
124
128
|
expect(prompt).toContain('src/routes/users.ts');
|
|
125
129
|
expect(prompt).toContain('src/models/user.ts');
|
|
126
130
|
});
|
|
127
131
|
it('includes testing section from architect', () => {
|
|
128
132
|
const ctx = { ...baseCtx, testingSection: 'Skip E2E, focus on unit tests' };
|
|
129
|
-
const prompt =
|
|
133
|
+
const prompt = buildQAPrompt(ctx);
|
|
130
134
|
expect(prompt).toContain("Architect's Testing Decisions");
|
|
131
135
|
expect(prompt).toContain('Skip E2E, focus on unit tests');
|
|
132
136
|
});
|
|
133
|
-
it('mentions
|
|
134
|
-
const prompt =
|
|
135
|
-
expect(prompt).toContain('
|
|
137
|
+
it('mentions integration tests', () => {
|
|
138
|
+
const prompt = buildQAPrompt(baseCtx);
|
|
139
|
+
expect(prompt).toContain('integration.spec.ts');
|
|
140
|
+
});
|
|
141
|
+
it('mentions acceptance criteria', () => {
|
|
142
|
+
const prompt = buildQAPrompt(baseCtx);
|
|
143
|
+
expect(prompt).toContain('Acceptance Criteria');
|
|
136
144
|
});
|
|
137
|
-
it('
|
|
138
|
-
const prompt =
|
|
139
|
-
expect(prompt).toContain('
|
|
145
|
+
it('says NOT to write unit tests', () => {
|
|
146
|
+
const prompt = buildQAPrompt(baseCtx);
|
|
147
|
+
expect(prompt).toContain('NOT write unit tests');
|
|
140
148
|
});
|
|
141
149
|
});
|
|
142
150
|
// ─── Review prompt ───
|
package/dist/scheduler/loop.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import { scanAgents } from './agents/health-checker.mjs';
|
|
|
13
13
|
import { detectCIPlatform, fetchFailureLogs } from './git/ci-watcher.mjs';
|
|
14
14
|
import { createRelease } from './git/release.mjs';
|
|
15
15
|
import { processInbox, addTaskMessageToTask } from './tasks/inbox.mjs';
|
|
16
|
-
import { buildPlanPrompt, buildImplementPrompt,
|
|
16
|
+
import { buildPlanPrompt, buildImplementPrompt, buildQAPrompt, buildReviewPrompt, buildReworkPrompt, buildCIFixPrompt, buildPRCommentPrompt, } from './agents/prompt-builder.mjs';
|
|
17
17
|
const MAX_REVIEW_CYCLES = 5;
|
|
18
18
|
const MAX_BUILD_FIXES = 3;
|
|
19
19
|
const MAX_CI_FIXES = 3;
|
|
@@ -243,7 +243,7 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
243
243
|
agent: pipeline.assignedAgent ?? undefined,
|
|
244
244
|
cwd: worktreePath,
|
|
245
245
|
prompt: buildPlanPrompt({ task, worktreePath, projectDir }),
|
|
246
|
-
model: getAgentModel(pipeline.assignedAgent, agents),
|
|
246
|
+
model: getAgentModel(pipeline.assignedAgent, agents, task),
|
|
247
247
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
248
248
|
if (!planResult.success) {
|
|
249
249
|
logger.error(`[${task.id}] Planning failed: ${planResult.error}`);
|
|
@@ -256,47 +256,57 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
256
256
|
logger.info(`[${task.id}] L-task split recommended — deferring to decomposition`);
|
|
257
257
|
// TODO: implement decomposition flow
|
|
258
258
|
}
|
|
259
|
-
// STEP 2: Implement
|
|
259
|
+
// STEP 2: Implement (includes unit tests + build/lint)
|
|
260
260
|
pipeline.step = 'implement';
|
|
261
261
|
appendEvent(projectDir, createEvent('step_changed', { taskId: task.id, step: 'implement' }));
|
|
262
|
+
// Re-route to implementation agent (may differ from planning agent)
|
|
263
|
+
// e.g., ui-engineer plans → angular-engineer implements
|
|
264
|
+
const implRouting = await orchestrator.routeTask(task, 'implement', agents);
|
|
265
|
+
const implAgent = implRouting.agent ?? pipeline.assignedAgent;
|
|
262
266
|
const implResult = await spawnAgent(pool, workerId, {
|
|
263
|
-
agent:
|
|
267
|
+
agent: implAgent ?? undefined,
|
|
264
268
|
cwd: worktreePath,
|
|
265
269
|
prompt: buildImplementPrompt({
|
|
266
270
|
task, worktreePath, projectDir,
|
|
267
271
|
architectPlan: pipeline.architectPlan,
|
|
268
272
|
apiContract: pipeline.apiContract ?? undefined,
|
|
269
273
|
}),
|
|
270
|
-
model: getAgentModel(
|
|
274
|
+
model: getAgentModel(implAgent, agents, task),
|
|
271
275
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
272
276
|
if (!implResult.success) {
|
|
273
277
|
logger.error(`[${task.id}] Implementation failed: ${implResult.error}`);
|
|
274
278
|
return false;
|
|
275
279
|
}
|
|
276
|
-
// STEP 3:
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
280
|
+
// STEP 3: QA (E2E tests, integration tests, acceptance criteria verification)
|
|
281
|
+
// Only for tasks that need it — skip for pure refactoring, config changes, etc.
|
|
282
|
+
const needsQA = task.type !== 'fullstack' || !isRefactoringTask(task);
|
|
283
|
+
if (needsQA) {
|
|
284
|
+
pipeline.step = 'test';
|
|
285
|
+
appendEvent(projectDir, createEvent('step_changed', { taskId: task.id, step: 'test' }));
|
|
286
|
+
const changedFiles = getChangedFiles(worktreePath);
|
|
287
|
+
const qaRouting = await orchestrator.routeTask(task, 'test', agents);
|
|
288
|
+
const qaResult = await spawnAgent(pool, workerId, {
|
|
289
|
+
agent: qaRouting.agent ?? undefined,
|
|
290
|
+
cwd: worktreePath,
|
|
291
|
+
prompt: buildQAPrompt({
|
|
292
|
+
task, worktreePath, projectDir, changedFiles,
|
|
293
|
+
testingSection: pipeline.testingSection ?? undefined,
|
|
294
|
+
}),
|
|
295
|
+
model: getAgentModel(qaRouting.agent, agents, task),
|
|
296
|
+
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
297
|
+
if (!qaResult.success) {
|
|
298
|
+
pipeline.buildFixes++;
|
|
299
|
+
if (pipeline.buildFixes >= MAX_BUILD_FIXES) {
|
|
300
|
+
logger.error(`[${task.id}] QA failed ${MAX_BUILD_FIXES} times — skipping`);
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
const decision = await orchestrator.handleFailure(task.title, 'test', qaResult.error ?? 'QA failed', pipeline.buildFixes);
|
|
304
|
+
if (decision.action === 'skip')
|
|
305
|
+
return false;
|
|
295
306
|
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
return false;
|
|
307
|
+
}
|
|
308
|
+
else {
|
|
309
|
+
logger.info(`[${task.id}] Skipping QA step (refactoring/config task)`);
|
|
300
310
|
}
|
|
301
311
|
// STEP 4: Review
|
|
302
312
|
pipeline.step = 'review';
|
|
@@ -313,7 +323,7 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
313
323
|
changedFiles: getChangedFiles(worktreePath),
|
|
314
324
|
testingSection: pipeline.testingSection ?? undefined,
|
|
315
325
|
}),
|
|
316
|
-
model: getAgentModel(reviewRouting.agent, agents),
|
|
326
|
+
model: getAgentModel(reviewRouting.agent, agents, task),
|
|
317
327
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
318
328
|
if (reviewResult.output.includes('**PASS**') || reviewResult.output.includes('PASS')) {
|
|
319
329
|
reviewPassed = true;
|
|
@@ -335,7 +345,7 @@ async function runTaskPipeline(task, workerId, agents, deps) {
|
|
|
335
345
|
task, worktreePath, projectDir,
|
|
336
346
|
reviewFindings: pipeline.reviewFindings,
|
|
337
347
|
}),
|
|
338
|
-
model: getAgentModel(pipeline.assignedAgent, agents),
|
|
348
|
+
model: getAgentModel(pipeline.assignedAgent, agents, task),
|
|
339
349
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
340
350
|
pipeline.step = 're-review';
|
|
341
351
|
}
|
|
@@ -500,17 +510,31 @@ function taskToSlug(task) {
|
|
|
500
510
|
.slice(0, 40);
|
|
501
511
|
return `feat/${task.id}-${sanitized}`;
|
|
502
512
|
}
|
|
503
|
-
function getAgentModel(agentName, agents) {
|
|
513
|
+
function getAgentModel(agentName, agents, task) {
|
|
504
514
|
if (!agentName)
|
|
505
515
|
return undefined;
|
|
506
516
|
const agent = agents.find(a => a.name === agentName);
|
|
507
|
-
|
|
517
|
+
const agentModel = agent?.model;
|
|
518
|
+
// If agent specifies a fixed model (opus/sonnet), respect it
|
|
519
|
+
if (agentModel && agentModel !== 'auto')
|
|
520
|
+
return agentModel;
|
|
521
|
+
// Auto model selection based on task complexity
|
|
522
|
+
if (task) {
|
|
523
|
+
// L = complex → opus, S/M = straightforward → sonnet
|
|
524
|
+
return task.complexity === 'L' ? 'opus' : 'sonnet';
|
|
525
|
+
}
|
|
526
|
+
return agentModel;
|
|
508
527
|
}
|
|
509
528
|
function extractSection(output, section) {
|
|
510
529
|
const pattern = new RegExp(`### ${section}\\s*\\n([\\s\\S]*?)(?=\\n### |$)`, 'i');
|
|
511
530
|
const match = output.match(pattern);
|
|
512
531
|
return match ? match[1].trim() : null;
|
|
513
532
|
}
|
|
533
|
+
function isRefactoringTask(task) {
|
|
534
|
+
const lower = task.title.toLowerCase();
|
|
535
|
+
return lower.includes('refactor') || lower.includes('config') || lower.includes('cleanup')
|
|
536
|
+
|| lower.includes('rename') || lower.includes('migrate') || lower.includes('upgrade');
|
|
537
|
+
}
|
|
514
538
|
// ─── Orphaned worktree recovery ───
|
|
515
539
|
async function recoverOrphanedWorktrees(projectDir, state, logger, deps) {
|
|
516
540
|
const knownPaths = Object.values(state.pipelines).map(p => p.worktreePath);
|
|
@@ -673,7 +697,7 @@ async function pollAndMergePR(task, pipeline, branch, platform, projectDir, work
|
|
|
673
697
|
agent: pipeline.assignedAgent ?? undefined,
|
|
674
698
|
cwd: worktreePath,
|
|
675
699
|
prompt: buildCIFixPrompt({ task, worktreePath, projectDir }, logs),
|
|
676
|
-
model: getAgentModel(pipeline.assignedAgent, agents),
|
|
700
|
+
model: getAgentModel(pipeline.assignedAgent, agents, task),
|
|
677
701
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
678
702
|
if (fixResult.success) {
|
|
679
703
|
commitInWorktree(worktreePath, `fix: CI failure for ${task.title}`);
|
|
@@ -698,7 +722,7 @@ async function pollAndMergePR(task, pipeline, branch, platform, projectDir, work
|
|
|
698
722
|
agent: pipeline.assignedAgent ?? undefined,
|
|
699
723
|
cwd: worktreePath,
|
|
700
724
|
prompt: buildPRCommentPrompt({ task, worktreePath, projectDir }, commentText),
|
|
701
|
-
model: getAgentModel(pipeline.assignedAgent, agents),
|
|
725
|
+
model: getAgentModel(pipeline.assignedAgent, agents, task),
|
|
702
726
|
}, state, task.id, logger, onMessage, onSpawnStart, onSpawnEnd);
|
|
703
727
|
if (commentResult.success) {
|
|
704
728
|
commitInWorktree(worktreePath, `fix: address PR review comments`);
|
|
@@ -22,14 +22,18 @@ npx create-claude-workspace --update
|
|
|
22
22
|
|
|
23
23
|
| Agent | Purpose | Model |
|
|
24
24
|
|-------|---------|-------|
|
|
25
|
-
| orchestrator | Development cycle (pick task → plan → implement →
|
|
25
|
+
| orchestrator | Development cycle (pick task → plan → implement → QA → review → commit → merge) | opus |
|
|
26
26
|
| project-initializer | Full project setup pipeline (discovery → CLAUDE.md → PRODUCT.md → TODO.md) | opus |
|
|
27
27
|
| product-owner | Product strategy, features, monetization → PRODUCT.md | opus |
|
|
28
|
-
| technical-planner | Phased development plan → TODO.md | opus |
|
|
29
|
-
| ui-engineer | Frontend architecture and
|
|
28
|
+
| technical-planner | Phased development plan → TODO.md or platform issues | opus |
|
|
29
|
+
| ui-engineer | Frontend architecture and planning (does NOT implement) | opus |
|
|
30
|
+
| angular-engineer | Angular frontend implementation (follows ui-engineer's plan) | auto |
|
|
31
|
+
| react-engineer | React frontend implementation | auto |
|
|
32
|
+
| vue-engineer | Vue frontend implementation | auto |
|
|
33
|
+
| svelte-engineer | Svelte frontend implementation | auto |
|
|
30
34
|
| backend-ts-architect | Backend architecture and implementation | opus |
|
|
31
|
-
| senior-code-reviewer | Structured code review (CRITICAL
|
|
32
|
-
| test-engineer |
|
|
33
|
-
| devops-integrator | Git platform
|
|
35
|
+
| senior-code-reviewer | Structured code review (CRITICAL=blocker, WARN, NICE-TO-HAVE) | opus |
|
|
36
|
+
| test-engineer | QA: E2E tests, integration tests, acceptance criteria verification | sonnet |
|
|
37
|
+
| devops-integrator | Git platform setup (remote, CI secrets, labels, milestones) | sonnet |
|
|
34
38
|
| deployment-engineer | CI/CD pipelines, deploys, rollbacks, migrations | sonnet |
|
|
35
39
|
| it-analyst | Technical analyst, breaks features into detailed platform issues | sonnet |
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: angular-engineer
|
|
3
3
|
description: Angular frontend specialist — components, signals, RxJS, SSR, testing
|
|
4
|
-
model:
|
|
5
|
-
steps:
|
|
4
|
+
model: auto
|
|
5
|
+
steps: implement, rework
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are an Angular frontend engineer. You
|
|
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
|
+
## Implementation Responsibilities
|
|
12
|
+
- Implement production code according to the architect's plan
|
|
13
|
+
- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
|
|
14
|
+
- Run build, lint, and unit tests before finishing — fix any failures
|
|
15
|
+
- Do NOT plan architecture — follow the plan provided
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
## Framework
|
|
13
19
|
|
|
@@ -6,6 +6,12 @@ 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
|
+
## Implementation Responsibilities
|
|
10
|
+
When implementing (not just planning), you MUST also:
|
|
11
|
+
- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
|
|
12
|
+
- Test pure logic, business rules, edge cases, error conditions
|
|
13
|
+
- Run build, lint, and unit tests before finishing — fix any failures
|
|
14
|
+
|
|
9
15
|
## Core Competencies
|
|
10
16
|
|
|
11
17
|
- Advanced TypeScript patterns (generics, conditional types, mapped types, branded types)
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: react-engineer
|
|
3
3
|
description: React frontend specialist — components, hooks, SSR, Next.js, testing
|
|
4
|
-
model:
|
|
5
|
-
steps:
|
|
4
|
+
model: auto
|
|
5
|
+
steps: implement, rework
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are a React frontend engineer. You
|
|
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
|
+
## Implementation Responsibilities
|
|
12
|
+
- Implement production code according to the architect's plan
|
|
13
|
+
- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
|
|
14
|
+
- Run build, lint, and unit tests before finishing — fix any failures
|
|
15
|
+
- Do NOT plan architecture — follow the plan provided
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
## Framework
|
|
13
19
|
|
|
@@ -12,7 +12,7 @@ You are a Senior Fullstack Code Reviewer with 15+ years of experience across fro
|
|
|
12
12
|
- Evaluate architectural decisions against onion architecture and project conventions
|
|
13
13
|
- Ensure adherence to project-specific standards from CLAUDE.md
|
|
14
14
|
- Identify bugs, edge cases, error handling gaps
|
|
15
|
-
- Check frontend patterns from
|
|
15
|
+
- Check frontend patterns (detect framework from package.json and apply framework best practices)
|
|
16
16
|
|
|
17
17
|
## Review Process
|
|
18
18
|
|
|
@@ -156,13 +156,13 @@ Read `.claude/profiles/frontend.md` for the framework-specific review checklist.
|
|
|
156
156
|
ALL 4 sections MANDATORY, even if empty:
|
|
157
157
|
|
|
158
158
|
### CRITICAL
|
|
159
|
-
|
|
159
|
+
**BLOCKER — must fix before merge.** Bugs, security vulnerabilities, memory leaks, crashes, data loss. Orchestrator MUST NOT skip CRITICAL findings.
|
|
160
160
|
|
|
161
161
|
### WARN
|
|
162
|
-
Should fix. Bad practices, missing error handling, performance issues, a11y violations.
|
|
162
|
+
Should fix. Bad practices, missing error handling, performance issues, a11y violations. May be skipped after max review cycles.
|
|
163
163
|
|
|
164
164
|
### NICE-TO-HAVE
|
|
165
|
-
|
|
165
|
+
Optional improvement. Naming, refactors, extra type safety, tests. Does not block merge.
|
|
166
166
|
|
|
167
167
|
### GREEN
|
|
168
168
|
What is done well. Correct patterns, clean code, good decisions. Be specific.
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: svelte-engineer
|
|
3
3
|
description: Svelte frontend specialist — runes, SvelteKit, SSR, testing
|
|
4
|
-
model:
|
|
5
|
-
steps:
|
|
4
|
+
model: auto
|
|
5
|
+
steps: implement, rework
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are a Svelte frontend engineer. You
|
|
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
|
+
## Implementation Responsibilities
|
|
12
|
+
- Implement production code according to the architect's plan
|
|
13
|
+
- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
|
|
14
|
+
- Run build, lint, and unit tests before finishing — fix any failures
|
|
15
|
+
- Do NOT plan architecture — follow the plan provided
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
## Framework
|
|
13
19
|
|
|
@@ -1,24 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-engineer
|
|
3
|
-
description: "
|
|
3
|
+
description: "QA engineer — writes E2E tests (Playwright), integration tests, VRT (visual regression testing) setup and tests, and verifies acceptance criteria. Also handles test infrastructure setup (Playwright config, VRT scaffolding, test patterns). Unit tests are the implementing developer's responsibility.\n\n<example>\nuser: \"Write E2E tests for the checkout flow\"\nassistant: \"I'll use the test-engineer agent to create Playwright E2E tests for this flow.\"\n</example>\n\n<example>\nuser: \"Verify the auth feature meets acceptance criteria\"\nassistant: \"I'll use the test-engineer agent to verify acceptance criteria and write integration tests.\"\n</example>\n\n<example>\nuser: \"Write integration tests for the API endpoints\"\nassistant: \"I'll use the test-engineer agent to create integration tests with real HTTP calls.\"\n</example>"
|
|
4
4
|
model: sonnet
|
|
5
5
|
---
|
|
6
6
|
|
|
7
|
-
You are a
|
|
7
|
+
You are a QA Engineer specializing in integration testing, E2E testing with Playwright, and acceptance criteria verification. You verify implementations from a user/QA perspective — not implementation details. Unit tests are the developer's responsibility; you focus on higher-level testing.
|
|
8
|
+
|
|
9
|
+
You always RUN the tests after writing them and report results.
|
|
8
10
|
|
|
9
11
|
## Core Competencies
|
|
10
12
|
|
|
11
|
-
- **
|
|
12
|
-
- **Component testing**: Framework-specific component tests (
|
|
13
|
-
- **
|
|
14
|
-
- **
|
|
15
|
-
- **
|
|
16
|
-
- **Integration testing**: API endpoint tests (supertest/test server), DB operations, service collaboration, library public API contracts
|
|
17
|
-
- **E2E testing**: Playwright browser automation, user flow testing, visual verification
|
|
13
|
+
- **Integration testing**: API endpoint tests (real HTTP calls), DB operations, service collaboration
|
|
14
|
+
- **Component testing**: Framework-specific component tests (detect framework from package.json)
|
|
15
|
+
- **E2E testing**: Playwright browser automation, user flow testing, visual regression
|
|
16
|
+
- **Visual regression**: Playwright `toHaveScreenshot()`, multi-viewport matrix
|
|
17
|
+
- **Acceptance criteria verification**: Read task/issue descriptions, verify each criterion
|
|
18
18
|
|
|
19
|
-
##
|
|
19
|
+
## What You Do NOT Do
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
- **Unit tests** — the implementing developer writes these during implementation
|
|
22
|
+
- **Rewriting existing tests** — only add new higher-level tests
|
|
23
|
+
- **Testing internal implementation details** — focus on behavior and user-facing outcomes
|
|
22
24
|
|
|
23
25
|
## Test Framework Detection (MANDATORY first step)
|
|
24
26
|
|
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ui-engineer
|
|
3
|
-
description: "
|
|
3
|
+
description: "Frontend architect agent — plans component architecture, identifies reuse, outputs structured design specs. Does NOT implement code directly — implementation is delegated to framework-specific agents (angular-engineer, react-engineer, vue-engineer, svelte-engineer).\n\n<example>\nuser: \"Plan the component architecture for the dashboard\"\nassistant: \"I'll use the ui-engineer agent to design the component architecture and implementation plan.\"\n</example>\n\n<example>\nuser: \"Design the multi-step form architecture\"\nassistant: \"I'll engage the ui-engineer agent to plan the form structure, smart/dumb split, and reuse opportunities.\"\n</example>"
|
|
4
4
|
model: opus
|
|
5
|
+
steps: plan
|
|
5
6
|
---
|
|
6
7
|
|
|
7
|
-
You are
|
|
8
|
+
You are a frontend architect specializing in modern frontend development within monorepo architecture. Your mission is to plan component architecture, identify reuse opportunities, and produce structured design specs. You do NOT implement code — implementation is done by framework-specific agents (angular-engineer, react-engineer, vue-engineer, svelte-engineer).
|
|
8
9
|
|
|
9
|
-
##
|
|
10
|
+
## Your Role
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
-
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
- Theme system usage
|
|
16
|
-
- Generator commands for scaffolding
|
|
17
|
-
- Component testing approach
|
|
18
|
-
- Review checklist
|
|
19
|
-
|
|
20
|
-
If the file does not exist, detect the framework from `package.json` dependencies and apply your native knowledge of that framework's best practices.
|
|
12
|
+
- **Plan** frontend architecture (component structure, smart/dumb split, data flow)
|
|
13
|
+
- **Identify** existing code to reuse, extend, or compose
|
|
14
|
+
- **Output** structured specs that framework-specific agents follow to implement
|
|
15
|
+
- **Do NOT** write production code — only interface definitions and architecture decisions
|
|
21
16
|
|
|
22
17
|
## Your Expertise
|
|
23
18
|
|
|
@@ -76,18 +71,17 @@ Write clean, elegant code that is easy to test and reason about:
|
|
|
76
71
|
## Approach
|
|
77
72
|
|
|
78
73
|
1. **Read CLAUDE.md** for project-specific patterns, design system, and conventions
|
|
79
|
-
2. **
|
|
74
|
+
2. **Detect framework** from `package.json` dependencies (Angular, React, Vue, or Svelte)
|
|
80
75
|
3. **Check existing components** — search for similar components, shared UI pieces, and utilities that already exist. List them in your EXISTING CODE section.
|
|
81
76
|
4. **Design architecture** — plan smart vs dumb, identify reusable parts. Prefer extending/composing existing components over creating new ones.
|
|
82
77
|
5. **Identify reuse** — explicitly flag existing code to import, extend, or generalize. If a near-duplicate exists, recommend refactoring to shared instead of creating new.
|
|
83
|
-
6. **Provide structured plan** — output clear implementation steps for the
|
|
84
|
-
7. **
|
|
85
|
-
8. **Verify** — accessibility, responsive design, performance, SSR safety
|
|
78
|
+
6. **Provide structured plan** — output clear implementation steps for the framework-specific agent
|
|
79
|
+
7. **Consider** — accessibility, responsive design, performance, SSR safety
|
|
86
80
|
|
|
87
81
|
## SSR Safety
|
|
88
82
|
|
|
89
83
|
- NEVER access `window`, `document`, `navigator` directly in server-rendered code
|
|
90
|
-
- Follow framework-specific SSR patterns
|
|
84
|
+
- Follow framework-specific SSR patterns
|
|
91
85
|
|
|
92
86
|
## Design Implementation
|
|
93
87
|
|
|
@@ -1,13 +1,19 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: vue-engineer
|
|
3
3
|
description: Vue frontend specialist — Composition API, Pinia, Nuxt, SSR, testing
|
|
4
|
-
model:
|
|
5
|
-
steps:
|
|
4
|
+
model: auto
|
|
5
|
+
steps: implement, rework
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
You are a Vue frontend engineer. You
|
|
8
|
+
You are a Vue frontend engineer. You implement Vue 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
|
+
## Implementation Responsibilities
|
|
12
|
+
- Implement production code according to the architect's plan
|
|
13
|
+
- Write unit tests for all new/modified code (co-located: foo.spec.ts beside foo.ts)
|
|
14
|
+
- Run build, lint, and unit tests before finishing — fix any failures
|
|
15
|
+
- Do NOT plan architecture — follow the plan provided
|
|
16
|
+
|
|
11
17
|
|
|
12
18
|
## Framework
|
|
13
19
|
|