swe-workflow-skills 0.1.0
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/LICENSE +21 -0
- package/README.md +144 -0
- package/VERSION +1 -0
- package/bin/cli.mjs +44 -0
- package/catalog.json +225 -0
- package/commands/role.md +34 -0
- package/hooks/session-start.mjs +118 -0
- package/install.mjs +318 -0
- package/package.json +47 -0
- package/roles.json +194 -0
- package/scripts/resolve.mjs +296 -0
- package/skills/accessibility-design/SKILL.md +128 -0
- package/skills/accessibility-design/evals/evals.json +51 -0
- package/skills/accessibility-design/references/accessibility-patterns.md +321 -0
- package/skills/api-design/SKILL.md +144 -0
- package/skills/api-design/evals/evals.json +48 -0
- package/skills/api-design/references/rest-conventions.md +147 -0
- package/skills/api-design/templates/api-spec.md +156 -0
- package/skills/architecture-design/SKILL.md +86 -0
- package/skills/architecture-design/evals/evals.json +44 -0
- package/skills/architecture-design/references/clean-architecture.md +147 -0
- package/skills/architecture-design/references/component-principles.md +129 -0
- package/skills/architecture-design/references/principles.md +81 -0
- package/skills/architecture-design/references/solid-principles.md +106 -0
- package/skills/architecture-design/templates/adr.md +63 -0
- package/skills/architecture-documentation/SKILL.md +126 -0
- package/skills/architecture-documentation/evals/evals.json +44 -0
- package/skills/architecture-documentation/references/abstraction-levels.md +91 -0
- package/skills/architecture-documentation/references/diagram-tooling.md +141 -0
- package/skills/architecture-documentation/templates/architecture-doc.md +171 -0
- package/skills/bug-investigating/SKILL.md +133 -0
- package/skills/bug-investigating/evals/evals.json +56 -0
- package/skills/bug-investigating/references/common-bugs.md +62 -0
- package/skills/bug-investigating/references/debugging-patterns.md +94 -0
- package/skills/cicd-pipeline/SKILL.md +87 -0
- package/skills/cicd-pipeline/evals/evals.json +34 -0
- package/skills/cicd-pipeline/references/pipeline-patterns.md +206 -0
- package/skills/cicd-pipeline/templates/github-actions.md +206 -0
- package/skills/code-reviewing/SKILL.md +92 -0
- package/skills/code-reviewing/evals/evals.json +62 -0
- package/skills/code-reviewing/references/error-handling.md +108 -0
- package/skills/code-reviewing/references/review-checklist.md +144 -0
- package/skills/configuration-strategy/SKILL.md +109 -0
- package/skills/configuration-strategy/evals/evals.json +41 -0
- package/skills/configuration-strategy/references/config-patterns.md +161 -0
- package/skills/containerization/SKILL.md +90 -0
- package/skills/containerization/evals/evals.json +36 -0
- package/skills/containerization/references/dockerfile-patterns.md +168 -0
- package/skills/containerization/templates/dockerfile.md +154 -0
- package/skills/data-modeling/SKILL.md +83 -0
- package/skills/data-modeling/evals/evals.json +43 -0
- package/skills/data-modeling/references/conventions.md +57 -0
- package/skills/data-modeling/templates/schema.md +120 -0
- package/skills/dependency-impact-analysis/SKILL.md +113 -0
- package/skills/dependency-impact-analysis/evals/evals.json +41 -0
- package/skills/dependency-impact-analysis/references/impact-patterns.md +150 -0
- package/skills/dependency-management/SKILL.md +161 -0
- package/skills/dependency-management/evals/evals.json +48 -0
- package/skills/dependency-management/references/evaluation-checklist.md +127 -0
- package/skills/deployment-checklist/SKILL.md +132 -0
- package/skills/deployment-checklist/evals/evals.json +58 -0
- package/skills/deployment-checklist/references/pre-deploy-gates.md +91 -0
- package/skills/deployment-repo/SKILL.md +190 -0
- package/skills/deployment-repo/evals/evals.json +44 -0
- package/skills/deployment-repo/references/deployment-repo-patterns.md +258 -0
- package/skills/deployment-repo/references/version-compatibility.md +227 -0
- package/skills/deployment-repo/templates/deployment-repo-structure.md +226 -0
- package/skills/effort-estimation/SKILL.md +95 -0
- package/skills/effort-estimation/evals/evals.json +32 -0
- package/skills/effort-estimation/references/estimation-methods.md +154 -0
- package/skills/feature-planning/SKILL.md +84 -0
- package/skills/feature-planning/evals/evals.json +44 -0
- package/skills/feature-planning/templates/plan.md +55 -0
- package/skills/feature-planning/templates/task.md +26 -0
- package/skills/frontend-architecture/SKILL.md +154 -0
- package/skills/frontend-architecture/evals/evals.json +34 -0
- package/skills/frontend-architecture/references/component-patterns.md +264 -0
- package/skills/frontend-architecture/templates/folder-structure.md +203 -0
- package/skills/git-workflow/SKILL.md +127 -0
- package/skills/git-workflow/evals/evals.json +44 -0
- package/skills/git-workflow/references/conventions.md +142 -0
- package/skills/git-workflow/templates/pull-request.md +57 -0
- package/skills/gitops-delivery/SKILL.md +319 -0
- package/skills/gitops-delivery/evals/evals.json +44 -0
- package/skills/gitops-delivery/references/gitops-patterns.md +478 -0
- package/skills/gitops-delivery/templates/gitops-config.md +196 -0
- package/skills/incident-response/SKILL.md +130 -0
- package/skills/incident-response/evals/evals.json +55 -0
- package/skills/incident-response/references/communication-templates.md +134 -0
- package/skills/incident-response/references/severity-levels.md +77 -0
- package/skills/incident-response/templates/incident-timeline.md +57 -0
- package/skills/infrastructure-as-code/SKILL.md +86 -0
- package/skills/infrastructure-as-code/evals/evals.json +33 -0
- package/skills/infrastructure-as-code/references/iac-patterns.md +179 -0
- package/skills/infrastructure-as-code/templates/terraform-module.md +158 -0
- package/skills/metrics-and-okrs/SKILL.md +113 -0
- package/skills/metrics-and-okrs/evals/evals.json +33 -0
- package/skills/metrics-and-okrs/references/metric-catalog.md +90 -0
- package/skills/metrics-and-okrs/templates/okr-document.md +61 -0
- package/skills/ml-experiment-tracking/SKILL.md +96 -0
- package/skills/ml-experiment-tracking/evals/evals.json +32 -0
- package/skills/ml-experiment-tracking/references/tracking-tools.md +127 -0
- package/skills/ml-model-deployment/SKILL.md +106 -0
- package/skills/ml-model-deployment/evals/evals.json +34 -0
- package/skills/ml-model-deployment/references/serving-patterns.md +162 -0
- package/skills/ml-pipeline-design/SKILL.md +162 -0
- package/skills/ml-pipeline-design/evals/evals.json +34 -0
- package/skills/ml-pipeline-design/references/pipeline-components.md +174 -0
- package/skills/observability-design/SKILL.md +162 -0
- package/skills/observability-design/evals/evals.json +52 -0
- package/skills/observability-design/references/logging-patterns.md +229 -0
- package/skills/observability-design/references/slo-framework.md +151 -0
- package/skills/observability-design/templates/slo-document.md +80 -0
- package/skills/performance-optimization/SKILL.md +83 -0
- package/skills/performance-optimization/evals/evals.json +47 -0
- package/skills/performance-optimization/references/bottleneck-patterns.md +256 -0
- package/skills/performance-optimization/references/concurrency.md +101 -0
- package/skills/prd-writing/SKILL.md +109 -0
- package/skills/prd-writing/evals/evals.json +33 -0
- package/skills/prd-writing/references/prd-examples.md +132 -0
- package/skills/prd-writing/templates/prd.md +71 -0
- package/skills/prd-writing/templates/rfc.md +79 -0
- package/skills/project-documentation/SKILL.md +104 -0
- package/skills/project-documentation/evals/evals.json +48 -0
- package/skills/project-documentation/references/contributing-guide.md +100 -0
- package/skills/project-documentation/templates/changelog.md +59 -0
- package/skills/project-documentation/templates/readme.md +121 -0
- package/skills/project-proposal/SKILL.md +90 -0
- package/skills/project-proposal/evals/evals.json +31 -0
- package/skills/project-proposal/references/proposal-examples.md +140 -0
- package/skills/project-proposal/templates/proposal.md +76 -0
- package/skills/project-review/SKILL.md +111 -0
- package/skills/project-review/evals/evals.json +42 -0
- package/skills/refactoring/SKILL.md +90 -0
- package/skills/refactoring/evals/evals.json +44 -0
- package/skills/refactoring/references/transformations.md +132 -0
- package/skills/retrospective/SKILL.md +157 -0
- package/skills/retrospective/evals/evals.json +34 -0
- package/skills/retrospective/references/facilitation-guide.md +130 -0
- package/skills/retrospective/templates/post-mortem.md +121 -0
- package/skills/rollback-strategy/SKILL.md +116 -0
- package/skills/rollback-strategy/evals/evals.json +55 -0
- package/skills/rollback-strategy/references/rollback-patterns.md +125 -0
- package/skills/rollback-strategy/templates/rollback-plan.md +69 -0
- package/skills/security-audit/SKILL.md +146 -0
- package/skills/security-audit/evals/evals.json +66 -0
- package/skills/security-audit/references/owasp-top-10.md +167 -0
- package/skills/security-audit/templates/security-report.md +79 -0
- package/skills/skill-router/SKILL.md +171 -0
- package/skills/skill-router/evals/evals.json +39 -0
- package/skills/strategic-review/SKILL.md +106 -0
- package/skills/strategic-review/evals/evals.json +42 -0
- package/skills/strategic-review/templates/full-review-prompt.md +84 -0
- package/skills/tdd-workflow/SKILL.md +147 -0
- package/skills/tdd-workflow/evals/evals.json +58 -0
- package/skills/tdd-workflow/references/test-quality.md +71 -0
- package/skills/technical-debt-review/SKILL.md +113 -0
- package/skills/technical-debt-review/evals/evals.json +41 -0
- package/skills/technical-debt-review/references/debt-taxonomy.md +124 -0
- package/skills/technical-debt-review/templates/debt-audit.md +85 -0
- package/skills/test-data-strategy/SKILL.md +129 -0
- package/skills/test-data-strategy/evals/evals.json +49 -0
- package/skills/test-data-strategy/references/data-generation-patterns.md +341 -0
- package/skills/test-suite-design/SKILL.md +137 -0
- package/skills/test-suite-design/evals/evals.json +69 -0
- package/skills/test-suite-design/references/test-infrastructure.md +175 -0
- package/skills/test-suite-design/references/testing-pyramid.md +140 -0
- package/skills/ui-ux-design/SKILL.md +117 -0
- package/skills/ui-ux-design/evals/evals.json +35 -0
- package/skills/ui-ux-design/references/interaction-patterns.md +145 -0
- package/skills/ui-ux-design/templates/screen-spec.md +97 -0
- package/skills/verification-before-completion/SKILL.md +85 -0
- package/skills/verification-before-completion/evals/evals.json +53 -0
- package/skills/writing-skills/SKILL.md +87 -0
- package/skills/writing-skills/evals/evals.json +41 -0
- package/skills/writing-skills/references/pressure-testing.md +69 -0
- package/uninstall.mjs +182 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-suite-design
|
|
3
|
+
description: "Design comprehensive test suites for existing code — strategy across unit/integration/e2e, fixtures, factories, helpers. Triggers: add tests, write tests for, increase coverage, test this module, testing strategy, test plan, what tests do I need, test infrastructure, test helpers, this has no tests. Not for TDD — use tdd-workflow."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit, Bash
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Test Suite Design
|
|
9
|
+
|
|
10
|
+
Design and implement test suites for existing code. This is different from TDD: TDD drives *new* implementation through tests. This skill adds *meaningful test coverage* to code that already exists, designs test architecture, and builds test infrastructure.
|
|
11
|
+
|
|
12
|
+
## When to Use This vs TDD
|
|
13
|
+
|
|
14
|
+
| Situation | Use This Skill | Use tdd-workflow |
|
|
15
|
+
|-----------|---------------|-----------------|
|
|
16
|
+
| Existing module with no tests | ✓ | |
|
|
17
|
+
| Building a new feature from scratch | | ✓ |
|
|
18
|
+
| Planning overall test strategy for a project | ✓ | |
|
|
19
|
+
| Increasing coverage on legacy code | ✓ | |
|
|
20
|
+
| Fixing a bug (write regression test + fix) | | ✓ |
|
|
21
|
+
| Designing test fixtures and factories | ✓ | |
|
|
22
|
+
|
|
23
|
+
## Workflow
|
|
24
|
+
|
|
25
|
+
### Step 1: Assess the Current State
|
|
26
|
+
|
|
27
|
+
Before writing any tests, understand what you're working with:
|
|
28
|
+
|
|
29
|
+
- **What code needs testing?** A single function, a module, or a whole layer?
|
|
30
|
+
- **What does the code do?** Read it and identify the behaviors (inputs → outputs, side effects, state changes)
|
|
31
|
+
- **What's the risk profile?** Business-critical logic, data transformations, auth/security, and integrations deserve tests first. Glue code and configuration deserve tests last.
|
|
32
|
+
- **What test infrastructure exists?** Test runner, assertion library, mocking framework, fixtures, CI pipeline?
|
|
33
|
+
- **What's the dependency situation?** Does the code have hard dependencies that make it difficult to test in isolation?
|
|
34
|
+
|
|
35
|
+
If there's no test infrastructure at all, start with Step 2. Otherwise, skip to Step 3.
|
|
36
|
+
|
|
37
|
+
### Step 2: Set Up Test Infrastructure
|
|
38
|
+
|
|
39
|
+
Establish the foundation before writing individual tests:
|
|
40
|
+
|
|
41
|
+
1. **Test runner and framework** — Choose based on the stack (Jest/Vitest for JS/TS, pytest for Python, Go's built-in testing, JUnit for Java)
|
|
42
|
+
2. **Directory structure** — Co-located (`foo.test.ts` next to `foo.ts`) or separate (`tests/` directory). Recommend co-located for unit tests, separate directory for integration/e2e.
|
|
43
|
+
3. **Shared helpers** — Create a `tests/helpers/` or `tests/fixtures/` directory for reusable setup
|
|
44
|
+
4. **CI integration** — Tests should run on every PR at minimum
|
|
45
|
+
|
|
46
|
+
See [references/test-infrastructure.md](references/test-infrastructure.md) for framework-specific setup patterns.
|
|
47
|
+
|
|
48
|
+
### Step 3: Map Behaviors to Test
|
|
49
|
+
|
|
50
|
+
For each piece of code to test, create a behavior map — not a line-by-line mirror of the implementation, but a list of *what the code is supposed to do*:
|
|
51
|
+
|
|
52
|
+
**For a function/method:**
|
|
53
|
+
- What does it return for valid inputs? (happy path)
|
|
54
|
+
- What happens with boundary values? (empty, zero, max, null)
|
|
55
|
+
- What happens with invalid inputs? (wrong type, missing required fields)
|
|
56
|
+
- What side effects does it produce? (database writes, API calls, events emitted)
|
|
57
|
+
- What errors can it throw/return? Under what conditions?
|
|
58
|
+
|
|
59
|
+
**For a class/module:**
|
|
60
|
+
- What are the key public methods and their contracts?
|
|
61
|
+
- What state transitions are possible?
|
|
62
|
+
- What invariants should always hold?
|
|
63
|
+
- How do methods interact (does calling A affect the result of B)?
|
|
64
|
+
|
|
65
|
+
**For an API endpoint:**
|
|
66
|
+
- What responses for valid requests? (status codes, response shape)
|
|
67
|
+
- What responses for invalid requests? (validation errors, 400/401/403/404)
|
|
68
|
+
- What auth/permission checks exist?
|
|
69
|
+
- What database state changes occur?
|
|
70
|
+
|
|
71
|
+
When mapping behaviors, exclude behaviors that belong to a dependency — map *your* code's use of it (the inputs it passes, how it handles the library's outputs and errors), not the library's internals. "gzip produces these magic bytes" is zlib's behavior; "our codec round-trips a value and falls back gracefully on a legacy plain string" is ours.
|
|
72
|
+
|
|
73
|
+
Present the behavior map to the user and refine before writing tests.
|
|
74
|
+
|
|
75
|
+
### Step 4: Choose the Testing Layer
|
|
76
|
+
|
|
77
|
+
Apply the testing pyramid — see [references/testing-pyramid.md](references/testing-pyramid.md):
|
|
78
|
+
|
|
79
|
+
- **Unit tests** (70%): Pure functions, business logic, transformations, validators. Fast, isolated, many of them.
|
|
80
|
+
- **Integration tests** (20%): Database queries, API endpoints, service interactions. Slower, need setup/teardown, fewer of them.
|
|
81
|
+
- **E2E tests** (10%): Critical user journeys only. Slowest, most brittle, fewest of them.
|
|
82
|
+
|
|
83
|
+
For each behavior from Step 3, assign it to the appropriate layer. Default to the lowest (fastest) layer that can meaningfully test the behavior.
|
|
84
|
+
|
|
85
|
+
### Step 5: Handle Untestable Code
|
|
86
|
+
|
|
87
|
+
Existing code is often hard to test because of tight coupling. Common patterns and solutions:
|
|
88
|
+
|
|
89
|
+
**Hard-coded dependencies** → Inject dependencies through constructor or function parameters. Refactor minimally to enable testing — just enough to inject a mock, not a full redesign.
|
|
90
|
+
|
|
91
|
+
**Global state** → Isolate in a module you can mock. Or reset state in beforeEach/setUp.
|
|
92
|
+
|
|
93
|
+
**Side effects mixed with logic** → Extract the pure logic into a separate testable function. Test the logic directly, test the side effects at the integration level.
|
|
94
|
+
|
|
95
|
+
**External API calls** → Wrap in a client class/module. Mock the wrapper in unit tests. Test the wrapper itself in integration tests.
|
|
96
|
+
|
|
97
|
+
If refactoring is needed to make code testable, keep changes minimal. The goal is test coverage now, not architectural perfection. Suggest the `refactoring` skill for deeper structural improvement later.
|
|
98
|
+
|
|
99
|
+
### Step 6: Write the Tests
|
|
100
|
+
|
|
101
|
+
Write tests grouped by behavior, not by function. Use descriptive `describe`/`context` blocks:
|
|
102
|
+
|
|
103
|
+
```
|
|
104
|
+
describe('OrderService')
|
|
105
|
+
describe('calculateTotal')
|
|
106
|
+
it('sums item prices for a standard order')
|
|
107
|
+
it('applies percentage discount when coupon is valid')
|
|
108
|
+
it('returns zero for an empty cart')
|
|
109
|
+
it('throws when item has negative price')
|
|
110
|
+
describe('placeOrder')
|
|
111
|
+
it('creates order record in database')
|
|
112
|
+
it('sends confirmation email')
|
|
113
|
+
it('rejects when inventory is insufficient')
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
For each test, follow Arrange-Act-Assert. Keep tests focused — one behavior per test.
|
|
117
|
+
|
|
118
|
+
### Step 7: Evaluate Coverage Quality
|
|
119
|
+
|
|
120
|
+
After writing the suite, assess quality (not just line coverage percentage):
|
|
121
|
+
|
|
122
|
+
- [ ] Are the critical paths tested? (payments, auth, data mutations)
|
|
123
|
+
- [ ] Are error paths tested? (not just happy paths)
|
|
124
|
+
- [ ] Do tests document behavior? (can you understand the module by reading only the tests?)
|
|
125
|
+
- [ ] Are tests independent? (can run in any order)
|
|
126
|
+
- [ ] Are tests deterministic? (no flakiness from timing, randomness, or external state)
|
|
127
|
+
- [ ] Is the test-to-implementation coupling low? (can you refactor internals without breaking tests?)
|
|
128
|
+
|
|
129
|
+
Coverage percentage is a floor, not a ceiling. 80% meaningful coverage beats 100% shallow coverage.
|
|
130
|
+
|
|
131
|
+
## Principles Applied
|
|
132
|
+
|
|
133
|
+
- **DRY in tests**: Share setup through fixtures/factories, but keep each test readable on its own. A little repetition in tests is better than obscure shared state.
|
|
134
|
+
- **KISS**: Test behavior, not implementation. Don't mirror the code structure 1:1 in tests.
|
|
135
|
+
- **YAGNI**: Don't test trivial code (getters, delegating wrappers). Focus coverage where bugs hide.
|
|
136
|
+
- **Test your code, not your dependencies**: Assert what *your* code does with a library, not what the library does. A round-trip through your own `pack`/`unpack` wrapper is your logic; asserting a compression lib's magic bytes or its compression ratio is re-testing zlib — the vendor's job, already covered by the vendor's tests. Verify third-party *integration* at the integration layer, not by re-testing the library.
|
|
137
|
+
- **Functional Independence**: Each test should set up its own state and clean up after itself.
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "test-suite-design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I have a UserService class in TypeScript with methods for createUser, updateUser, deleteUser, and getUserById. It talks to a PostgreSQL database through Prisma and sends welcome emails via SendGrid. There are zero tests. Help me add a comprehensive test suite.",
|
|
7
|
+
"expected_output": "Should assess the current state, map behaviors for each method, separate unit vs integration concerns, recommend mocking strategy for Prisma and SendGrid, and write structured tests grouped by behavior.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Asks about or checks existing test infrastructure before writing tests",
|
|
10
|
+
"Maps behaviors for each method (not just happy paths)",
|
|
11
|
+
"Separates unit tests (business logic) from integration tests (database queries)",
|
|
12
|
+
"Recommends mocking Prisma client for unit tests",
|
|
13
|
+
"Recommends wrapping SendGrid and mocking the wrapper",
|
|
14
|
+
"Groups tests by behavior (describe blocks), not by method only",
|
|
15
|
+
"Includes error path tests (user not found, duplicate email, email send failure)",
|
|
16
|
+
"Does NOT use TDD red-green-refactor cycle — writes tests for existing code"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 2,
|
|
21
|
+
"prompt": "Our Django project has 0% test coverage and we need to get to a reasonable level before a big refactor. We have about 30 models, 50 views, and 20 utility functions. Where do I even start?",
|
|
22
|
+
"expected_output": "Should prioritize by risk, not try to test everything at once. Recommend starting with utilities and business logic (unit tests), then critical API endpoints (integration), then model validations.",
|
|
23
|
+
"assertions": [
|
|
24
|
+
"Does NOT suggest testing all 30 models first",
|
|
25
|
+
"Prioritizes by risk and business criticality",
|
|
26
|
+
"Recommends starting with pure utility functions (easiest wins)",
|
|
27
|
+
"Suggests a phased approach, not everything at once",
|
|
28
|
+
"Recommends test infrastructure setup first (conftest.py, factories)",
|
|
29
|
+
"References the testing pyramid (70/20/10 ratio)",
|
|
30
|
+
"Mentions that this coverage enables the refactoring skill to work safely"
|
|
31
|
+
]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": 3,
|
|
35
|
+
"prompt": "Write tests for this function:\n\nfunction calculateShippingCost(order) {\n if (!order.items || order.items.length === 0) return 0;\n const weight = order.items.reduce((sum, item) => sum + item.weight * item.quantity, 0);\n if (order.destination === 'domestic') {\n if (weight < 1) return 5.99;\n if (weight < 5) return 9.99;\n return 14.99 + Math.ceil((weight - 5) / 5) * 4.99;\n }\n if (order.destination === 'international') {\n return weight * 12.99;\n }\n throw new Error(`Unknown destination: ${order.destination}`);\n}",
|
|
36
|
+
"expected_output": "Should create a comprehensive behavior map first, then write tests covering all branches including edge cases and error paths. Should use descriptive test names and group by scenario.",
|
|
37
|
+
"assertions": [
|
|
38
|
+
"Creates a behavior map before writing tests",
|
|
39
|
+
"Tests empty items array returns 0",
|
|
40
|
+
"Tests domestic weight boundaries (< 1, < 5, >= 5)",
|
|
41
|
+
"Tests the incremental pricing formula for heavy domestic orders",
|
|
42
|
+
"Tests international linear pricing",
|
|
43
|
+
"Tests the error case for unknown destination",
|
|
44
|
+
"Tests with null/undefined items",
|
|
45
|
+
"Uses descriptive test names that read as specifications",
|
|
46
|
+
"Does NOT just write one test per if-branch — tests boundary values"
|
|
47
|
+
]
|
|
48
|
+
}
|
|
49
|
+
],
|
|
50
|
+
"pressure_tests": [
|
|
51
|
+
{
|
|
52
|
+
"id": 1,
|
|
53
|
+
"prompt": "Add tests for our raw_json storage codec. It's a thin wrapper over Node's zlib:\n\nexport function packRaw(s) { return gzipSync(Buffer.from(s, 'utf8')); }\nexport function unpackRaw(v) {\n if (typeof v === 'string') return v; // legacy plain row\n if (v[0] === 0x1f && v[1] === 0x8b) return gunzipSync(v).toString('utf8');\n return v.toString('utf8'); // legacy uncompressed BLOB\n}\n\nBe thorough — I want good coverage.",
|
|
54
|
+
"pressure": [
|
|
55
|
+
"thoroughness",
|
|
56
|
+
"easy_assertions"
|
|
57
|
+
],
|
|
58
|
+
"expected_behavior": "Tests OUR logic — the round-trip through packRaw/unpackRaw and the two legacy fallback branches (plain string passthrough, uncompressed BLOB decoded as utf8). Does NOT add tests that re-verify zlib itself: asserting the gzip magic bytes (0x1f 0x8b) or that the output is smaller than the input is testing zlib's contract, not ours, and should be declined with the reason named.",
|
|
59
|
+
"assertions": [
|
|
60
|
+
"Tests the round-trip (packRaw then unpackRaw returns the original)",
|
|
61
|
+
"Tests the legacy plain-string passthrough branch",
|
|
62
|
+
"Tests the legacy uncompressed-BLOB utf8 branch",
|
|
63
|
+
"Does NOT assert the gzip magic bytes 0x1f 0x8b (that is zlib's behavior, not ours)",
|
|
64
|
+
"Does NOT assert that compression shrinks the payload (that is zlib's job, covered by zlib's own tests)",
|
|
65
|
+
"Names the principle when excluding those: test our use of the library, not the library"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
# Test Infrastructure Setup
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- JavaScript/TypeScript (Jest, Vitest)
|
|
5
|
+
- Python (pytest)
|
|
6
|
+
- Go (testing)
|
|
7
|
+
- General CI patterns
|
|
8
|
+
|
|
9
|
+
## JavaScript/TypeScript
|
|
10
|
+
|
|
11
|
+
### Jest (mature, feature-rich)
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install --save-dev jest @types/jest ts-jest
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Directory structure (co-located):
|
|
18
|
+
```
|
|
19
|
+
src/
|
|
20
|
+
services/
|
|
21
|
+
order.service.ts
|
|
22
|
+
order.service.test.ts
|
|
23
|
+
utils/
|
|
24
|
+
format.ts
|
|
25
|
+
format.test.ts
|
|
26
|
+
tests/
|
|
27
|
+
integration/
|
|
28
|
+
api.test.ts
|
|
29
|
+
helpers/
|
|
30
|
+
factories.ts
|
|
31
|
+
setup.ts
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Key config (`jest.config.ts`):
|
|
35
|
+
```typescript
|
|
36
|
+
export default {
|
|
37
|
+
testMatch: ['**/*.test.ts'],
|
|
38
|
+
setupFilesAfterSetup: ['./tests/helpers/setup.ts'],
|
|
39
|
+
coverageThreshold: {
|
|
40
|
+
global: { branches: 70, functions: 80, lines: 80 }
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Vitest (fast, ESM-native, Vite-compatible)
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install --save-dev vitest
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Same directory structure and API as Jest, but faster and ESM-first. Prefer Vitest for new projects using Vite, Nuxt, or SvelteKit.
|
|
52
|
+
|
|
53
|
+
### Mocking
|
|
54
|
+
|
|
55
|
+
- **jest.mock / vi.mock**: Module-level mocks. Use for replacing imports.
|
|
56
|
+
- **jest.spyOn / vi.spyOn**: Spy on existing methods without replacing.
|
|
57
|
+
- **MSW (Mock Service Worker)**: Mock HTTP requests at the network level. Better than mocking fetch/axios directly because it tests your actual HTTP client code.
|
|
58
|
+
|
|
59
|
+
## Python
|
|
60
|
+
|
|
61
|
+
### pytest (recommended)
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install pytest pytest-cov pytest-mock
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Directory structure:
|
|
68
|
+
```
|
|
69
|
+
src/
|
|
70
|
+
services/
|
|
71
|
+
order_service.py
|
|
72
|
+
tests/
|
|
73
|
+
unit/
|
|
74
|
+
test_order_service.py
|
|
75
|
+
integration/
|
|
76
|
+
test_order_api.py
|
|
77
|
+
conftest.py # shared fixtures
|
|
78
|
+
factories.py # test data factories
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Key config (`pyproject.toml`):
|
|
82
|
+
```toml
|
|
83
|
+
[tool.pytest.ini_options]
|
|
84
|
+
testpaths = ["tests"]
|
|
85
|
+
addopts = "--cov=src --cov-report=term-missing"
|
|
86
|
+
|
|
87
|
+
[tool.coverage.run]
|
|
88
|
+
branch = true
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Fixtures (conftest.py)
|
|
92
|
+
|
|
93
|
+
pytest fixtures are powerful — use them for setup/teardown:
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
@pytest.fixture
|
|
97
|
+
def db_session():
|
|
98
|
+
session = create_test_session()
|
|
99
|
+
yield session
|
|
100
|
+
session.rollback()
|
|
101
|
+
session.close()
|
|
102
|
+
|
|
103
|
+
@pytest.fixture
|
|
104
|
+
def authenticated_client(db_session):
|
|
105
|
+
user = create_user(db_session, role="admin")
|
|
106
|
+
client = TestClient(app)
|
|
107
|
+
client.headers["Authorization"] = f"Bearer {create_token(user)}"
|
|
108
|
+
return client
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Fixtures compose naturally — `authenticated_client` depends on `db_session` and pytest handles the dependency chain.
|
|
112
|
+
|
|
113
|
+
## Go
|
|
114
|
+
|
|
115
|
+
### Built-in testing package
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
pkg/
|
|
119
|
+
order/
|
|
120
|
+
service.go
|
|
121
|
+
service_test.go # co-located, same package
|
|
122
|
+
service_integ_test.go # integration tests with build tag
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Key patterns:
|
|
126
|
+
- **Table-driven tests**: Go's idiomatic pattern for parameterized tests
|
|
127
|
+
- **testify**: Popular assertion and mock library
|
|
128
|
+
- **Build tags**: Separate integration tests with `//go:build integration`
|
|
129
|
+
|
|
130
|
+
```go
|
|
131
|
+
func TestCalculateTotal(t *testing.T) {
|
|
132
|
+
tests := []struct {
|
|
133
|
+
name string
|
|
134
|
+
items []Item
|
|
135
|
+
expected float64
|
|
136
|
+
}{
|
|
137
|
+
{"empty cart", []Item{}, 0},
|
|
138
|
+
{"single item", []Item{{Price: 10, Qty: 2}}, 20},
|
|
139
|
+
{"with discount", []Item{{Price: 100, Qty: 1, Discount: 0.1}}, 90},
|
|
140
|
+
}
|
|
141
|
+
for _, tt := range tests {
|
|
142
|
+
t.Run(tt.name, func(t *testing.T) {
|
|
143
|
+
got := CalculateTotal(tt.items)
|
|
144
|
+
assert.Equal(t, tt.expected, got)
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## General CI Patterns
|
|
151
|
+
|
|
152
|
+
### Minimum viable test pipeline
|
|
153
|
+
|
|
154
|
+
```yaml
|
|
155
|
+
# Run on every PR
|
|
156
|
+
test:
|
|
157
|
+
steps:
|
|
158
|
+
- install dependencies
|
|
159
|
+
- run linter
|
|
160
|
+
- run unit tests
|
|
161
|
+
- run integration tests (with test database)
|
|
162
|
+
- report coverage
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Test database in CI
|
|
166
|
+
|
|
167
|
+
- Use a Docker service container (PostgreSQL, MySQL, Redis)
|
|
168
|
+
- Apply migrations fresh for each run
|
|
169
|
+
- Never share a test database between parallel jobs
|
|
170
|
+
|
|
171
|
+
### Coverage gates
|
|
172
|
+
|
|
173
|
+
- Set a coverage floor (e.g., 80%) that fails the build if not met
|
|
174
|
+
- More importantly: require new code to have tests (diff-coverage)
|
|
175
|
+
- Tools: `diff-cover` (Python), `jest --changedSince` (JS)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# The Testing Pyramid
|
|
2
|
+
|
|
3
|
+
## Contents
|
|
4
|
+
- Layer definitions and trade-offs
|
|
5
|
+
- What to test at each layer
|
|
6
|
+
- Anti-patterns
|
|
7
|
+
- Fixture and factory patterns
|
|
8
|
+
|
|
9
|
+
## Layer Definitions
|
|
10
|
+
|
|
11
|
+
### Unit Tests (70% of your suite)
|
|
12
|
+
|
|
13
|
+
**Scope**: A single function, method, or class in isolation.
|
|
14
|
+
**Speed**: Milliseconds per test.
|
|
15
|
+
**Dependencies**: All external dependencies mocked/stubbed.
|
|
16
|
+
**Confidence**: High confidence that individual pieces work correctly.
|
|
17
|
+
|
|
18
|
+
What to test here:
|
|
19
|
+
- Business logic and calculations
|
|
20
|
+
- Data transformations and mapping
|
|
21
|
+
- Validation rules
|
|
22
|
+
- State machines and transitions
|
|
23
|
+
- Conditional branching
|
|
24
|
+
- Error handling and edge cases
|
|
25
|
+
- Utility and helper functions
|
|
26
|
+
|
|
27
|
+
What NOT to test here:
|
|
28
|
+
- Database queries (use integration tests)
|
|
29
|
+
- HTTP request/response cycles (use integration tests)
|
|
30
|
+
- Third-party library behavior (trust but verify at integration level)
|
|
31
|
+
|
|
32
|
+
### Integration Tests (20% of your suite)
|
|
33
|
+
|
|
34
|
+
**Scope**: Two or more components working together.
|
|
35
|
+
**Speed**: Hundreds of milliseconds to seconds per test.
|
|
36
|
+
**Dependencies**: Real database (test instance), real filesystem, mock external APIs.
|
|
37
|
+
**Confidence**: High confidence that components connect correctly.
|
|
38
|
+
|
|
39
|
+
What to test here:
|
|
40
|
+
- Database query correctness (does the query return what we expect?)
|
|
41
|
+
- API endpoint behavior (request → response, including middleware)
|
|
42
|
+
- Service-to-service communication (with mocked external services)
|
|
43
|
+
- Message queue producers and consumers
|
|
44
|
+
- File I/O operations
|
|
45
|
+
- Cache behavior
|
|
46
|
+
|
|
47
|
+
Typical setup:
|
|
48
|
+
- Test database with migrations applied fresh per suite (or per test for isolation)
|
|
49
|
+
- Seed data via factories, not fixtures (factories are dynamic, fixtures go stale)
|
|
50
|
+
- Clean up after each test (transaction rollback or truncation)
|
|
51
|
+
|
|
52
|
+
### E2E Tests (10% of your suite)
|
|
53
|
+
|
|
54
|
+
**Scope**: Full user journey through the entire stack.
|
|
55
|
+
**Speed**: Seconds to minutes per test.
|
|
56
|
+
**Dependencies**: Full running system (or close to it).
|
|
57
|
+
**Confidence**: High confidence that the whole system works for critical paths.
|
|
58
|
+
|
|
59
|
+
What to test here:
|
|
60
|
+
- Critical user journeys only (signup, purchase, core workflow)
|
|
61
|
+
- Integration with real third-party services (in staging/sandbox)
|
|
62
|
+
- Cross-service workflows
|
|
63
|
+
|
|
64
|
+
Keep these minimal. Each E2E test is expensive to write, slow to run, and fragile to maintain. If you can test something at a lower level, do it there instead.
|
|
65
|
+
|
|
66
|
+
## Anti-patterns
|
|
67
|
+
|
|
68
|
+
**Ice cream cone**: More E2E tests than unit tests. Slow suite, flaky CI, hard to debug failures. Invert the pyramid.
|
|
69
|
+
|
|
70
|
+
**Testing the framework**: Writing tests that verify React renders a component or Express routes a request. The framework already works. Test your logic.
|
|
71
|
+
|
|
72
|
+
**100% coverage obsession**: Coverage measures lines executed, not behaviors verified. A test that calls a function without asserting anything shows as "covered". Focus on behavior coverage.
|
|
73
|
+
|
|
74
|
+
**Shared mutable state**: Tests that depend on data created by a previous test. One test failure cascades into false failures across the suite.
|
|
75
|
+
|
|
76
|
+
**Sleep-based waits**: `await sleep(1000)` to wait for async operations. Flaky and slow. Use polling, event-based waits, or test-specific hooks.
|
|
77
|
+
|
|
78
|
+
## Fixture and Factory Patterns
|
|
79
|
+
|
|
80
|
+
### Factories (recommended)
|
|
81
|
+
|
|
82
|
+
Factories generate test data dynamically with sensible defaults and overrides:
|
|
83
|
+
|
|
84
|
+
```javascript
|
|
85
|
+
// JavaScript/TypeScript pattern
|
|
86
|
+
function buildUser(overrides = {}) {
|
|
87
|
+
return {
|
|
88
|
+
id: faker.string.uuid(),
|
|
89
|
+
name: faker.person.fullName(),
|
|
90
|
+
email: faker.internet.email(),
|
|
91
|
+
role: 'member',
|
|
92
|
+
createdAt: new Date(),
|
|
93
|
+
...overrides,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Usage
|
|
98
|
+
const admin = buildUser({ role: 'admin' });
|
|
99
|
+
const inactiveUser = buildUser({ active: false });
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
# Python pattern (using factory_boy or manual)
|
|
104
|
+
def build_user(**overrides):
|
|
105
|
+
defaults = {
|
|
106
|
+
"id": uuid4(),
|
|
107
|
+
"name": fake.name(),
|
|
108
|
+
"email": fake.email(),
|
|
109
|
+
"role": "member",
|
|
110
|
+
"created_at": datetime.utcnow(),
|
|
111
|
+
}
|
|
112
|
+
return {**defaults, **overrides}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Why factories over fixtures**: Fixtures are static JSON/YAML that go stale. Factories express intent ("give me an admin user"), are composable, and stay in sync with schema changes because they fail loudly when fields change.
|
|
116
|
+
|
|
117
|
+
### Database Factories (for integration tests)
|
|
118
|
+
|
|
119
|
+
For tests that need records in a real database, create factory functions that insert and return:
|
|
120
|
+
|
|
121
|
+
```javascript
|
|
122
|
+
async function createUser(overrides = {}) {
|
|
123
|
+
const data = buildUser(overrides);
|
|
124
|
+
return db.users.create({ data });
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Builder Pattern (for complex objects)
|
|
129
|
+
|
|
130
|
+
When objects have many optional fields or complex relationships:
|
|
131
|
+
|
|
132
|
+
```javascript
|
|
133
|
+
const order = new OrderBuilder()
|
|
134
|
+
.withCustomer(customer)
|
|
135
|
+
.withItems([item1, item2])
|
|
136
|
+
.withDiscount(10)
|
|
137
|
+
.build();
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Use builders when factory overrides get unwieldy (more than 5-6 fields commonly overridden).
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ui-ux-design
|
|
3
|
+
description: "Design user experiences from an engineer's perspective — user flows, wireframes, interaction patterns, responsive strategy, navigation, loading/error/empty states. Triggers: design the UI, user flow, wireframe, how should this screen look, loading state, error state, empty state, responsive design, navigation, page layout, form design, mockup."
|
|
4
|
+
model: sonnet
|
|
5
|
+
allowed-tools: Read, Grep, Glob, Write, Edit
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# UI/UX Design
|
|
9
|
+
|
|
10
|
+
Design user interfaces from a senior engineer's perspective. This isn't about pixel-perfect mockups — it's about defining user flows, interaction patterns, and UI states clearly enough that implementation is unambiguous. Engineers do this when there's no dedicated designer, or when translating vague designs into complete specifications.
|
|
11
|
+
|
|
12
|
+
## Core Principle
|
|
13
|
+
|
|
14
|
+
**Design the states, not just the happy path.** Every screen has at least 5 states: loading, empty, partial data, full data, and error. Designing only the "full data" state is the #1 cause of poor user experience.
|
|
15
|
+
|
|
16
|
+
## Workflow
|
|
17
|
+
|
|
18
|
+
### Step 1: Map the User Flow
|
|
19
|
+
|
|
20
|
+
Before designing any screen, map the complete user journey:
|
|
21
|
+
|
|
22
|
+
1. **Entry point**: How does the user arrive? (Direct link, navigation, notification, redirect)
|
|
23
|
+
2. **Happy path**: The ideal sequence of screens and actions
|
|
24
|
+
3. **Branch points**: Where can the user make different choices?
|
|
25
|
+
4. **Edge paths**: What happens on errors, cancellation, timeout, or edge cases?
|
|
26
|
+
5. **Exit points**: Where does the user end up after completing (or abandoning) the flow?
|
|
27
|
+
|
|
28
|
+
Document as an ASCII flow diagram or structured list:
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
[Landing] → [Sign Up Form] → [Email Verification] → [Onboarding] → [Dashboard]
|
|
32
|
+
↓ ↓
|
|
33
|
+
[Login Instead] [Resend Email]
|
|
34
|
+
↓ ↓
|
|
35
|
+
[Login Form] [Verification Timeout] → [Support]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
### Step 2: Design Each Screen's States
|
|
39
|
+
|
|
40
|
+
For every screen in the flow, define all states:
|
|
41
|
+
|
|
42
|
+
| State | What the user sees | When it occurs |
|
|
43
|
+
|-------|-------------------|----------------|
|
|
44
|
+
| **Loading** | Skeleton or spinner | Data is being fetched |
|
|
45
|
+
| **Empty** | Illustration + CTA | No data exists yet |
|
|
46
|
+
| **Partial** | Content + loading indicator | Some data loaded, more coming |
|
|
47
|
+
| **Loaded** | Full content | Data fetch complete |
|
|
48
|
+
| **Error** | Error message + retry action | Fetch failed |
|
|
49
|
+
| **Offline** | Cached content + offline banner | No network (if applicable) |
|
|
50
|
+
|
|
51
|
+
The empty state is a design opportunity, not just a blank page. "You have no projects yet. Create your first one →" is better than an empty table.
|
|
52
|
+
|
|
53
|
+
### Step 3: Specify Layouts and Hierarchy
|
|
54
|
+
|
|
55
|
+
For each screen, define the content hierarchy. Use the structure at [templates/screen-spec.md](templates/screen-spec.md):
|
|
56
|
+
|
|
57
|
+
- **Primary action**: The one thing the user should do on this screen
|
|
58
|
+
- **Content hierarchy**: What's most important → least important (top → bottom, left → right)
|
|
59
|
+
- **Secondary actions**: Available but not prominent
|
|
60
|
+
- **Navigation**: How to move forward, backward, and sideways
|
|
61
|
+
|
|
62
|
+
Don't design pixel-perfect layouts — design **information architecture**. What goes where, why, and in what priority order.
|
|
63
|
+
|
|
64
|
+
### Step 4: Define Interaction Patterns
|
|
65
|
+
|
|
66
|
+
For each interactive element, specify:
|
|
67
|
+
|
|
68
|
+
**Forms:**
|
|
69
|
+
- Validation timing: On blur, on submit, or real-time?
|
|
70
|
+
- Error display: Inline per field, summary at top, or both?
|
|
71
|
+
- Multi-step forms: Progress indicator, save on each step, back navigation?
|
|
72
|
+
- Submission feedback: Button loading state → success message or redirect
|
|
73
|
+
|
|
74
|
+
**Lists and Tables:**
|
|
75
|
+
- Pagination, infinite scroll, or load more?
|
|
76
|
+
- Sorting and filtering: Which columns, client-side or server-side?
|
|
77
|
+
- Bulk actions: Selection model, confirmation for destructive actions
|
|
78
|
+
- Empty/filtered-empty states
|
|
79
|
+
|
|
80
|
+
**Modals and Overlays:**
|
|
81
|
+
- When to use modal vs inline vs new page
|
|
82
|
+
- Close behavior (X, click outside, Escape key)
|
|
83
|
+
- Focus trapping and restoration
|
|
84
|
+
|
|
85
|
+
**Feedback and Notifications:**
|
|
86
|
+
- Success: Toast, inline message, or redirect?
|
|
87
|
+
- Error: Inline, toast, or modal for critical errors?
|
|
88
|
+
- Progress: Determinate bar, indeterminate spinner, skeleton?
|
|
89
|
+
|
|
90
|
+
See [references/interaction-patterns.md](references/interaction-patterns.md) for common patterns.
|
|
91
|
+
|
|
92
|
+
### Step 5: Plan Responsive Behavior
|
|
93
|
+
|
|
94
|
+
Define how the layout adapts across breakpoints:
|
|
95
|
+
|
|
96
|
+
| Breakpoint | Target | Layout Adaptation |
|
|
97
|
+
|-----------|--------|-------------------|
|
|
98
|
+
| < 640px | Mobile | Single column, bottom nav, full-width inputs |
|
|
99
|
+
| 640-1024px | Tablet | Two columns, collapsible sidebar |
|
|
100
|
+
| > 1024px | Desktop | Multi-column, persistent sidebar, hover states |
|
|
101
|
+
|
|
102
|
+
For each major layout section, specify what changes:
|
|
103
|
+
- **Navigation**: Hamburger menu on mobile vs sidebar on desktop
|
|
104
|
+
- **Data tables**: Card view on mobile vs table on desktop
|
|
105
|
+
- **Images**: Aspect ratio changes, cropping strategy
|
|
106
|
+
- **Forms**: Stacked on mobile vs side-by-side on desktop
|
|
107
|
+
|
|
108
|
+
### Step 6: Produce the Specification
|
|
109
|
+
|
|
110
|
+
Output using the template at [templates/screen-spec.md](templates/screen-spec.md). Save as `docs/ui/feature-name.md`. Link from the PRD if one exists.
|
|
111
|
+
|
|
112
|
+
## Principles Applied
|
|
113
|
+
|
|
114
|
+
- **KISS**: Design the simplest interface that serves the user's goal. Every additional element competes for attention.
|
|
115
|
+
- **Progressive disclosure**: Show the most important information first. Reveal complexity only when the user needs it.
|
|
116
|
+
- **Consistency**: Reuse patterns across the app. If lists everywhere use pagination, don't switch to infinite scroll for one page.
|
|
117
|
+
- **Forgiveness**: Every destructive action should have undo or confirmation. Users make mistakes.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "ui-ux-design",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "Design the UI for a project management dashboard. Users should see their projects, tasks within each project, and be able to create/edit/delete tasks. It's a React web app. We don't have a designer — I need to figure out the screens and flows myself.",
|
|
7
|
+
"expected_output": "Should map the user flow first (dashboard → project → task), then specify each screen with all states (loading, empty, error, loaded), define interaction patterns for CRUD operations, and include responsive behavior.",
|
|
8
|
+
"assertions": [
|
|
9
|
+
"Maps the user flow before designing individual screens",
|
|
10
|
+
"Defines at least 3 screens (dashboard, project detail, task detail/modal)",
|
|
11
|
+
"Each screen has loading, empty, and error states defined",
|
|
12
|
+
"Empty state has a helpful CTA (not just 'no items')",
|
|
13
|
+
"CRUD interactions have specified feedback (toast, inline, redirect)",
|
|
14
|
+
"Delete has a confirmation pattern",
|
|
15
|
+
"Responsive behavior defined for mobile vs desktop",
|
|
16
|
+
"Produces screen specifications using the template"
|
|
17
|
+
]
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"id": 2,
|
|
21
|
+
"prompt": "I need to design a multi-step checkout flow for an e-commerce app. Steps: cart review → shipping address → payment → confirmation. It needs to work on mobile too.",
|
|
22
|
+
"expected_output": "Should design the complete flow with all states including error recovery, define form validation patterns, address mobile-specific concerns, and handle edge cases.",
|
|
23
|
+
"assertions": [
|
|
24
|
+
"Flow includes progress indicator showing current step",
|
|
25
|
+
"Each step saves data (user doesn't lose progress on back navigation)",
|
|
26
|
+
"Form validation strategy specified (when errors show, how they clear)",
|
|
27
|
+
"Payment step has loading state during processing",
|
|
28
|
+
"Error recovery for payment failure doesn't lose form data",
|
|
29
|
+
"Confirmation step shows order summary before final submit",
|
|
30
|
+
"Mobile layout addresses keyboard handling for address/payment forms",
|
|
31
|
+
"Handles edge case: cart modified during checkout, session timeout"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|