@skilly-hand/skilly-hand 0.7.0 → 0.8.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/CHANGELOG.md +32 -0
- package/README.md +7 -5
- package/catalog/README.md +3 -0
- package/catalog/catalog-index.json +3 -0
- package/catalog/skills/frontend-design/SKILL.md +237 -0
- package/catalog/skills/frontend-design/agents/component-designer.md +95 -0
- package/catalog/skills/frontend-design/agents/stack-detector.md +154 -0
- package/catalog/skills/frontend-design/assets/stack-scan-checklist.md +58 -0
- package/catalog/skills/frontend-design/manifest.json +27 -0
- package/catalog/skills/life-guard/SKILL.md +180 -0
- package/catalog/skills/life-guard/assets/committee-member-template.md +44 -0
- package/catalog/skills/life-guard/assets/safety-guard-template.md +47 -0
- package/catalog/skills/life-guard/manifest.json +33 -0
- package/catalog/skills/test-driven-development/SKILL.md +159 -0
- package/catalog/skills/test-driven-development/assets/tdd-cycle.md +487 -0
- package/catalog/skills/test-driven-development/manifest.json +25 -0
- package/package.json +1 -1
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "frontend-design",
|
|
3
|
+
"title": "Frontend Design",
|
|
4
|
+
"description": "Project-aware frontend design skill that detects the existing tech stack, UI libraries, CSS variables, and design tokens before proposing any UI work.",
|
|
5
|
+
"portable": true,
|
|
6
|
+
"tags": ["frontend", "design", "workflow", "ui"],
|
|
7
|
+
"detectors": ["always"],
|
|
8
|
+
"detectionTriggers": ["manual"],
|
|
9
|
+
"installsFor": ["all"],
|
|
10
|
+
"agentSupport": ["codex", "claude", "cursor", "gemini", "copilot"],
|
|
11
|
+
"skillMetadata": {
|
|
12
|
+
"author": "skilly-hand",
|
|
13
|
+
"last-edit": "2026-04-04",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"version": "1.0.0",
|
|
16
|
+
"changelog": "Initial frontend-design skill; enforces stack-detection-first workflow before any UI component generation; affects catalog skill coverage for frontend and design workflows",
|
|
17
|
+
"auto-invoke": "Designing or generating UI components, pages, or layouts in a web or mobile project",
|
|
18
|
+
"allowed-tools": ["Read", "Grep", "Glob", "Bash", "Edit", "Write"]
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
{ "path": "SKILL.md", "kind": "instruction" },
|
|
22
|
+
{ "path": "agents/stack-detector.md", "kind": "asset" },
|
|
23
|
+
{ "path": "agents/component-designer.md", "kind": "asset" },
|
|
24
|
+
{ "path": "assets/stack-scan-checklist.md", "kind": "asset" }
|
|
25
|
+
],
|
|
26
|
+
"dependencies": []
|
|
27
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: life-guard
|
|
3
|
+
description: >
|
|
4
|
+
Review code, decisions, and artifacts through a multi-perspective committee and a domain expert safety guard, then synthesize a structured verdict.
|
|
5
|
+
Trigger: Reviewing code, decisions, pull requests, APIs, architecture, or any artifact that benefits from adversarial multi-perspective evaluation.
|
|
6
|
+
metadata:
|
|
7
|
+
author: skilly-hand
|
|
8
|
+
last-edit: 2026-04-04
|
|
9
|
+
license: Apache-2.0
|
|
10
|
+
version: "1.0.0"
|
|
11
|
+
changelog: "Added multi-perspective review skill with committee + safety guard synthesis; enables adversarial evaluation without permanent agent files; affects catalog skill coverage for review and quality workflows"
|
|
12
|
+
auto-invoke: "Reviewing code, decisions, or artifacts where adversarial multi-perspective evaluation adds value"
|
|
13
|
+
allowed-tools: Read, Grep, Glob, Bash, Task, SubAgent
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
# Life-Guard Guide
|
|
17
|
+
|
|
18
|
+
## When to Use
|
|
19
|
+
|
|
20
|
+
Use this skill when:
|
|
21
|
+
|
|
22
|
+
- A code change, architecture decision, or artifact carries meaningful risk.
|
|
23
|
+
- A single reviewer perspective is likely to miss domain-specific edge cases.
|
|
24
|
+
- You need a structured verdict, not an opinion.
|
|
25
|
+
- Pull requests, API designs, security decisions, or data models require adversarial scrutiny.
|
|
26
|
+
|
|
27
|
+
Do not use this skill for:
|
|
28
|
+
|
|
29
|
+
- Trivial single-file edits with no systemic impact.
|
|
30
|
+
- Tasks already covered by a domain-specific automated linter or test suite.
|
|
31
|
+
- Reviews where committee overhead exceeds the risk of getting it wrong.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Core Workflow
|
|
36
|
+
|
|
37
|
+
1. Identify the target (code, decision, artifact) and its domain.
|
|
38
|
+
2. Determine committee size: 3 members for routine reviews, 5 for high-risk or cross-domain targets.
|
|
39
|
+
3. Spawn N committee members using `assets/committee-member-template.md`. Assign each a distinct evaluation lens. Run them independently — no member sees another's output.
|
|
40
|
+
4. Determine the expert domain for the safety guard.
|
|
41
|
+
5. Spawn 1 safety guard using `assets/safety-guard-template.md`. It evaluates the target from an authoritative expert position.
|
|
42
|
+
6. Run the committee and safety guard in parallel.
|
|
43
|
+
7. Collect all outputs.
|
|
44
|
+
8. Synthesize a structured verdict following the Synthesis Rules.
|
|
45
|
+
9. Emit the final verdict with confidence tier, top findings, and recommended action.
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## Committee Protocol
|
|
50
|
+
|
|
51
|
+
### Size
|
|
52
|
+
|
|
53
|
+
| Target Risk | Committee Size |
|
|
54
|
+
| ----------- | -------------- |
|
|
55
|
+
| Routine (single concern) | 3 members |
|
|
56
|
+
| High-risk or cross-domain | 5 members |
|
|
57
|
+
|
|
58
|
+
### Lens Assignment
|
|
59
|
+
|
|
60
|
+
Assign lenses based on what is being reviewed. Examples:
|
|
61
|
+
|
|
62
|
+
| Domain | Possible Lenses |
|
|
63
|
+
| ------ | --------------- |
|
|
64
|
+
| Code change | Security, Performance, Maintainability, Testability, UX impact |
|
|
65
|
+
| Architecture decision | Scalability, Operational risk, Developer experience, Cost, Data integrity |
|
|
66
|
+
| API design | Consumer ergonomics, Contract stability, Security, Versioning, Documentation |
|
|
67
|
+
| Data model | Normalization, Query performance, Migration safety, Privacy, Extensibility |
|
|
68
|
+
|
|
69
|
+
Never assign the same lens to two committee members. Each member evaluates independently — no member sees another's prompt or output during evaluation.
|
|
70
|
+
|
|
71
|
+
### Independence Rules
|
|
72
|
+
|
|
73
|
+
- Spawn committee members in parallel.
|
|
74
|
+
- Pass only the target artifact and the member's assigned lens as context.
|
|
75
|
+
- Do not share intermediate findings between members before synthesis.
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Safety Guard Protocol
|
|
80
|
+
|
|
81
|
+
### Domain Resolution
|
|
82
|
+
|
|
83
|
+
Determine the expert domain from the target:
|
|
84
|
+
|
|
85
|
+
```text
|
|
86
|
+
Target is code? -> Domain is the language + ecosystem (e.g., "TypeScript + Node.js security")
|
|
87
|
+
Target is architecture? -> Domain is the system archetype (e.g., "distributed systems reliability")
|
|
88
|
+
Target is a decision? -> Domain is the function it affects (e.g., "data privacy compliance")
|
|
89
|
+
Target is an API? -> Domain is the protocol + consumer context (e.g., "REST API design for web clients")
|
|
90
|
+
Target is unclear? -> Ask before spawning
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Specialization
|
|
94
|
+
|
|
95
|
+
The safety guard:
|
|
96
|
+
|
|
97
|
+
- Operates as an authoritative expert, not a peer reviewer.
|
|
98
|
+
- Evaluates the target for correctness, safety, and conformance to domain standards.
|
|
99
|
+
- Raises blockers, not suggestions. If the safety guard finds a structural flaw, it is a hard finding.
|
|
100
|
+
- Runs in parallel with the committee, not after it.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Synthesis Rules
|
|
105
|
+
|
|
106
|
+
### Confidence Tiers
|
|
107
|
+
|
|
108
|
+
| Tier | Condition | Recommended Action |
|
|
109
|
+
| ---- | --------- | ------------------ |
|
|
110
|
+
| HIGH | Safety guard passes + committee majority agrees | Approve with noted caveats |
|
|
111
|
+
| MEDIUM | Safety guard passes + committee is split | Approve after addressing split findings |
|
|
112
|
+
| LOW | Safety guard raises a blocker OR committee majority flags risk | Block — require remediation before approval |
|
|
113
|
+
| VETO | Safety guard raises a structural flaw | Hard block — do not proceed |
|
|
114
|
+
|
|
115
|
+
### Contradiction Handling
|
|
116
|
+
|
|
117
|
+
- Safety guard findings override committee findings on correctness and safety.
|
|
118
|
+
- When committee members contradict each other, count lenses: majority rules unless a minority finding is a security or data-integrity concern.
|
|
119
|
+
- A single security or data-integrity finding from any voice is sufficient for LOW or VETO tier.
|
|
120
|
+
|
|
121
|
+
### Verdict Structure
|
|
122
|
+
|
|
123
|
+
Emit exactly this structure:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
CONFIDENCE: {HIGH | MEDIUM | LOW | VETO}
|
|
127
|
+
|
|
128
|
+
SUMMARY:
|
|
129
|
+
{1–2 sentences on the overall state of the target}
|
|
130
|
+
|
|
131
|
+
TOP FINDINGS:
|
|
132
|
+
1. [{Voice}] {Finding} — {Severity: Info | Warning | Blocker}
|
|
133
|
+
2. [{Voice}] {Finding} — {Severity: Info | Warning | Blocker}
|
|
134
|
+
...
|
|
135
|
+
|
|
136
|
+
RECOMMENDED ACTION:
|
|
137
|
+
{Approve | Approve with caveats | Block — remediate before resubmit | Hard block}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
---
|
|
141
|
+
|
|
142
|
+
## Decision Tree
|
|
143
|
+
|
|
144
|
+
```text
|
|
145
|
+
Is there a safety guard blocker?
|
|
146
|
+
YES -> VETO — hard block regardless of committee output
|
|
147
|
+
|
|
148
|
+
Does the safety guard pass?
|
|
149
|
+
YES -> evaluate committee output
|
|
150
|
+
|
|
151
|
+
Do 3+ of 5 committee members (or 2+ of 3) flag a risk?
|
|
152
|
+
YES -> LOW — block and require remediation
|
|
153
|
+
NO -> continue
|
|
154
|
+
|
|
155
|
+
Does any committee member flag a security or data-integrity risk?
|
|
156
|
+
YES -> LOW at minimum — escalate to safety guard if not already covered
|
|
157
|
+
|
|
158
|
+
Does committee majority agree the target is sound?
|
|
159
|
+
YES and safety guard passes -> HIGH or MEDIUM depending on split
|
|
160
|
+
NO -> LOW
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Commands
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# Reference committee member template when constructing agent prompts
|
|
169
|
+
cat .skilly-hand/catalog/life-guard/assets/committee-member-template.md
|
|
170
|
+
|
|
171
|
+
# Reference safety guard template when constructing agent prompts
|
|
172
|
+
cat .skilly-hand/catalog/life-guard/assets/safety-guard-template.md
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Resources
|
|
178
|
+
|
|
179
|
+
- Committee member prompt template: [assets/committee-member-template.md](assets/committee-member-template.md)
|
|
180
|
+
- Safety guard prompt template: [assets/safety-guard-template.md](assets/safety-guard-template.md)
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Committee Member: {{LENS}}
|
|
2
|
+
|
|
3
|
+
## Role
|
|
4
|
+
|
|
5
|
+
You are an ephemeral code and decision reviewer. Your evaluation lens is **{{LENS}}**.
|
|
6
|
+
You are one of {{COMMITTEE_SIZE}} independent reviewers. You do not know what the others are evaluating or what they will find.
|
|
7
|
+
|
|
8
|
+
## Target
|
|
9
|
+
|
|
10
|
+
{{TARGET_ARTIFACT}}
|
|
11
|
+
|
|
12
|
+
## Evaluation Instructions
|
|
13
|
+
|
|
14
|
+
Evaluate the target exclusively through the **{{LENS}}** lens.
|
|
15
|
+
|
|
16
|
+
1. State the lens clearly at the top of your output.
|
|
17
|
+
2. Identify findings. For each finding:
|
|
18
|
+
- Describe the issue precisely.
|
|
19
|
+
- Cite the specific location (file, line, section, or decision point) where applicable.
|
|
20
|
+
- Assign severity: `Info`, `Warning`, or `Blocker`.
|
|
21
|
+
3. If the target is sound from your lens perspective, state that explicitly — do not invent findings.
|
|
22
|
+
4. Do not comment on concerns outside your assigned lens.
|
|
23
|
+
5. Do not suggest what other reviewers should look for.
|
|
24
|
+
|
|
25
|
+
## Output Format
|
|
26
|
+
|
|
27
|
+
```text
|
|
28
|
+
LENS: {{LENS}}
|
|
29
|
+
|
|
30
|
+
FINDINGS:
|
|
31
|
+
1. {Location} — {Description} — {Severity}
|
|
32
|
+
2. {Location} — {Description} — {Severity}
|
|
33
|
+
...
|
|
34
|
+
|
|
35
|
+
OVERALL ASSESSMENT FROM THIS LENS:
|
|
36
|
+
{Pass | Caution | Block} — {1 sentence rationale}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Constraints
|
|
40
|
+
|
|
41
|
+
- MUST evaluate only from the assigned lens.
|
|
42
|
+
- MUST NOT reference other committee members.
|
|
43
|
+
- MUST NOT speculate about the orchestrator's final verdict.
|
|
44
|
+
- MUST cite evidence from the target for every finding rated Warning or higher.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# Safety Guard: {{DOMAIN}}
|
|
2
|
+
|
|
3
|
+
## Role
|
|
4
|
+
|
|
5
|
+
You are an authoritative domain expert, not a peer reviewer. Your domain is **{{DOMAIN}}**.
|
|
6
|
+
You are the single safety guard for this review. Your findings carry elevated weight in the final verdict.
|
|
7
|
+
|
|
8
|
+
## Target
|
|
9
|
+
|
|
10
|
+
{{TARGET_ARTIFACT}}
|
|
11
|
+
|
|
12
|
+
## Evaluation Instructions
|
|
13
|
+
|
|
14
|
+
Evaluate the target for correctness, safety, and conformance to **{{DOMAIN}}** standards.
|
|
15
|
+
|
|
16
|
+
1. State the domain clearly at the top of your output.
|
|
17
|
+
2. Identify blockers first. A blocker is any finding that, if unaddressed, makes the target unsafe, incorrect, or non-conformant.
|
|
18
|
+
3. After blockers, identify warnings — issues that should be addressed but do not hard-stop the review.
|
|
19
|
+
4. If the target conforms fully, state that explicitly with rationale.
|
|
20
|
+
5. Do not hedge on blockers. If something is structurally wrong, call it a blocker.
|
|
21
|
+
|
|
22
|
+
## Output Format
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
DOMAIN: {{DOMAIN}}
|
|
26
|
+
|
|
27
|
+
BLOCKERS:
|
|
28
|
+
1. {Location} — {Description} — Blocker
|
|
29
|
+
...
|
|
30
|
+
(none if no blockers found)
|
|
31
|
+
|
|
32
|
+
WARNINGS:
|
|
33
|
+
1. {Location} — {Description} — Warning
|
|
34
|
+
...
|
|
35
|
+
(none if no warnings found)
|
|
36
|
+
|
|
37
|
+
CONFORMANCE VERDICT:
|
|
38
|
+
{Pass | Conditional Pass | Fail} — {1–2 sentence rationale}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
## Constraints
|
|
42
|
+
|
|
43
|
+
- MUST assess correctness and safety against {{DOMAIN}} standards specifically.
|
|
44
|
+
- MUST NOT soften blockers into warnings.
|
|
45
|
+
- MUST cite the relevant standard, rule, or principle for every Blocker finding.
|
|
46
|
+
- MUST NOT defer to committee output — this assessment is independent.
|
|
47
|
+
- A structural flaw triggers VETO at synthesis regardless of committee consensus.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "life-guard",
|
|
3
|
+
"title": "Life-Guard",
|
|
4
|
+
"description": "Review code, decisions, and artifacts through a multi-perspective committee and a domain expert safety guard, then synthesize a structured verdict.",
|
|
5
|
+
"portable": true,
|
|
6
|
+
"tags": ["core", "workflow", "review", "quality"],
|
|
7
|
+
"detectors": ["always"],
|
|
8
|
+
"detectionTriggers": ["manual"],
|
|
9
|
+
"installsFor": ["all"],
|
|
10
|
+
"agentSupport": ["codex", "claude", "cursor", "gemini", "copilot"],
|
|
11
|
+
"skillMetadata": {
|
|
12
|
+
"author": "skilly-hand",
|
|
13
|
+
"last-edit": "2026-04-04",
|
|
14
|
+
"license": "Apache-2.0",
|
|
15
|
+
"version": "1.0.0",
|
|
16
|
+
"changelog": "Added multi-perspective review skill with committee + safety guard synthesis; enables adversarial evaluation without permanent agent files; affects catalog skill coverage for review and quality workflows",
|
|
17
|
+
"auto-invoke": "Reviewing code, decisions, or artifacts where adversarial multi-perspective evaluation adds value",
|
|
18
|
+
"allowed-tools": [
|
|
19
|
+
"Read",
|
|
20
|
+
"Grep",
|
|
21
|
+
"Glob",
|
|
22
|
+
"Bash",
|
|
23
|
+
"Task",
|
|
24
|
+
"SubAgent"
|
|
25
|
+
]
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
{ "path": "SKILL.md", "kind": "instruction" },
|
|
29
|
+
{ "path": "assets/committee-member-template.md", "kind": "asset" },
|
|
30
|
+
{ "path": "assets/safety-guard-template.md", "kind": "asset" }
|
|
31
|
+
],
|
|
32
|
+
"dependencies": []
|
|
33
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Test-Driven Development Guide
|
|
2
|
+
|
|
3
|
+
## When to Use
|
|
4
|
+
|
|
5
|
+
Use this skill when:
|
|
6
|
+
|
|
7
|
+
- Implementing a new feature, service, component, or function from scratch.
|
|
8
|
+
- Adding behavior to existing code where the expected outcome can be defined upfront.
|
|
9
|
+
- Debugging a regression by writing a failing test that reproduces the bug first.
|
|
10
|
+
- Reviewing or pair-programming on code where test-first discipline is required.
|
|
11
|
+
|
|
12
|
+
Do not use this skill for:
|
|
13
|
+
|
|
14
|
+
- Exploratory prototyping where requirements are entirely undefined.
|
|
15
|
+
- Snapshot or visual regression tests driven by existing UI.
|
|
16
|
+
- Infrastructure or environment setup with no testable behavior.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Critical Patterns
|
|
21
|
+
|
|
22
|
+
### Pattern 1: RED First, Always
|
|
23
|
+
|
|
24
|
+
Write a failing test before writing any implementation code. This proves:
|
|
25
|
+
|
|
26
|
+
- The test is meaningful (not passing by accident).
|
|
27
|
+
- The feature is actually needed.
|
|
28
|
+
- You understand the requirements before touching implementation.
|
|
29
|
+
|
|
30
|
+
Never write implementation code without a failing test that demands it.
|
|
31
|
+
|
|
32
|
+
### Pattern 2: Minimum Code to GREEN
|
|
33
|
+
|
|
34
|
+
Write the **smallest possible code** to make the test pass:
|
|
35
|
+
|
|
36
|
+
- No extra features beyond what the test requires.
|
|
37
|
+
- No premature optimization or defensive handling.
|
|
38
|
+
- No "while I'm here, let me add…" additions.
|
|
39
|
+
|
|
40
|
+
The goal is to satisfy the test, nothing more.
|
|
41
|
+
|
|
42
|
+
### Pattern 3: REFACTOR With Tests GREEN
|
|
43
|
+
|
|
44
|
+
Only improve code structure **after** all tests pass:
|
|
45
|
+
|
|
46
|
+
- Extract constants, improve naming, simplify logic.
|
|
47
|
+
- Tests must stay green throughout every refactoring step.
|
|
48
|
+
- If a refactor breaks a test, revert — the refactor was wrong.
|
|
49
|
+
|
|
50
|
+
### Pattern 4: One Scenario Per Test
|
|
51
|
+
|
|
52
|
+
Each test must validate exactly one behavior:
|
|
53
|
+
|
|
54
|
+
- Use explicit GIVEN / WHEN / THEN structure in test bodies.
|
|
55
|
+
- A test name should complete the sentence: *"it should ___"*.
|
|
56
|
+
- If a test asserts two behaviors, split it into two tests.
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Decision Tree
|
|
61
|
+
|
|
62
|
+
```text
|
|
63
|
+
Starting a new feature or function? -> Write failing test first (RED)
|
|
64
|
+
Test is failing as expected? -> Write minimum code to pass (GREEN)
|
|
65
|
+
Test is passing? -> Improve code structure without changing behavior (REFACTOR)
|
|
66
|
+
Refactor broke a test? -> Revert — refactor introduced a behavior change
|
|
67
|
+
Test is already passing before writing code? -> Test is not meaningful; redesign it
|
|
68
|
+
Fixing a bug? -> Write failing test that reproduces the bug first
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Code Examples
|
|
74
|
+
|
|
75
|
+
### Example 1: GIVEN / WHEN / THEN Structure
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
it('should return the sum of two numbers', () => {
|
|
79
|
+
// GIVEN: Two positive integers
|
|
80
|
+
const a = 3;
|
|
81
|
+
const b = 4;
|
|
82
|
+
|
|
83
|
+
// WHEN: Sum is computed
|
|
84
|
+
const result = add(a, b);
|
|
85
|
+
|
|
86
|
+
// THEN: Result equals their sum
|
|
87
|
+
expect(result).toBe(7);
|
|
88
|
+
});
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Example 2: RED — Write Failing Test First
|
|
92
|
+
|
|
93
|
+
```typescript
|
|
94
|
+
// calculator.test.ts
|
|
95
|
+
import { divide } from './calculator';
|
|
96
|
+
|
|
97
|
+
it('should throw when dividing by zero', () => {
|
|
98
|
+
// GIVEN / WHEN / THEN
|
|
99
|
+
expect(() => divide(10, 0)).toThrow('Cannot divide by zero');
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Run the test — it **must** fail before writing any implementation.
|
|
104
|
+
|
|
105
|
+
### Example 3: GREEN — Write Minimum Implementation
|
|
106
|
+
|
|
107
|
+
```typescript
|
|
108
|
+
// calculator.ts
|
|
109
|
+
export function divide(a: number, b: number): number {
|
|
110
|
+
if (b === 0) throw new Error('Cannot divide by zero');
|
|
111
|
+
return a / b;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Run the test — it should now pass. No additional logic yet.
|
|
116
|
+
|
|
117
|
+
### Example 4: REFACTOR — Improve Without Changing Behavior
|
|
118
|
+
|
|
119
|
+
```typescript
|
|
120
|
+
// calculator.ts (refactored)
|
|
121
|
+
const DIVIDE_BY_ZERO_MESSAGE = 'Cannot divide by zero';
|
|
122
|
+
|
|
123
|
+
export function divide(numerator: number, denominator: number): number {
|
|
124
|
+
if (denominator === 0) throw new Error(DIVIDE_BY_ZERO_MESSAGE);
|
|
125
|
+
return numerator / denominator;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Run the test — it must still pass after renaming and extracting the constant.
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## Commands
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Run a single test file
|
|
137
|
+
npm test -- {test-file}
|
|
138
|
+
|
|
139
|
+
# Run all tests
|
|
140
|
+
npm test
|
|
141
|
+
|
|
142
|
+
# Run tests in watch mode
|
|
143
|
+
npm test -- --watch
|
|
144
|
+
|
|
145
|
+
# Type check without emitting
|
|
146
|
+
npx tsc --noEmit
|
|
147
|
+
|
|
148
|
+
# Lint check
|
|
149
|
+
npm run lint
|
|
150
|
+
|
|
151
|
+
# Full verify (tests + lint + type check + build)
|
|
152
|
+
npm test && npm run lint && npx tsc --noEmit && npm run build
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
## Resources
|
|
158
|
+
|
|
159
|
+
- Full cycle examples with Angular: [assets/tdd-cycle.md](assets/tdd-cycle.md)
|