@simplysm/sd-claude 13.0.60 → 13.0.61
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/claude/agents/sd-api-reviewer.md +7 -6
- package/claude/agents/sd-code-simplifier.md +0 -3
- package/claude/agents/sd-security-reviewer.md +14 -3
- package/claude/refs/sd-angular.md +127 -0
- package/claude/refs/sd-orm-v12.md +81 -0
- package/claude/refs/sd-orm.md +7 -1
- package/claude/refs/sd-solid.md +8 -0
- package/claude/rules/sd-refs-linker.md +41 -9
- package/claude/skills/sd-api-name-review/SKILL.md +6 -6
- package/claude/skills/sd-brainstorm/SKILL.md +4 -0
- package/claude/skills/sd-check/SKILL.md +10 -10
- package/claude/skills/sd-check/baseline-analysis.md +24 -3
- package/claude/skills/sd-check/test-scenarios.md +34 -1
- package/claude/skills/sd-commit/SKILL.md +11 -5
- package/claude/skills/sd-debug/SKILL.md +26 -17
- package/claude/skills/sd-debug/condition-based-waiting.md +17 -12
- package/claude/skills/sd-debug/defense-in-depth.md +14 -8
- package/claude/skills/sd-debug/root-cause-tracing.md +18 -4
- package/claude/skills/sd-debug/test-baseline-pressure.md +10 -8
- package/claude/skills/sd-discuss/SKILL.md +17 -13
- package/claude/skills/sd-eml-analyze/SKILL.md +8 -7
- package/claude/skills/sd-explore/SKILL.md +2 -0
- package/claude/skills/sd-plan/SKILL.md +9 -3
- package/claude/skills/sd-plan-dev/SKILL.md +7 -2
- package/claude/skills/sd-plan-dev/code-quality-reviewer-prompt.md +2 -0
- package/claude/skills/sd-plan-dev/final-review-prompt.md +2 -2
- package/claude/skills/sd-readme/SKILL.md +22 -16
- package/claude/skills/sd-review/SKILL.md +22 -21
- package/claude/skills/sd-skill/SKILL.md +94 -35
- package/claude/skills/sd-skill/anthropic-best-practices.md +174 -148
- package/claude/skills/sd-skill/examples/CLAUDE_MD_TESTING.md +11 -0
- package/claude/skills/sd-skill/persuasion-principles.md +39 -6
- package/claude/skills/sd-skill/testing-skills-with-subagents.md +46 -26
- package/claude/skills/sd-tdd/SKILL.md +54 -36
- package/claude/skills/sd-tdd/testing-anti-patterns.md +40 -22
- package/claude/skills/sd-use/SKILL.md +22 -22
- package/claude/skills/sd-worktree/SKILL.md +1 -0
- package/claude/skills/sd-worktree/sd-worktree.mjs +1 -1
- package/package.json +1 -1
- package/claude/skills/sd-check/run-checks.mjs +0 -54
|
@@ -18,12 +18,14 @@ Write the test first. Watch it fail. Write minimal code to pass.
|
|
|
18
18
|
## When to Use
|
|
19
19
|
|
|
20
20
|
**Always:**
|
|
21
|
+
|
|
21
22
|
- New features
|
|
22
23
|
- Bug fixes
|
|
23
24
|
- Refactoring
|
|
24
25
|
- Behavior changes
|
|
25
26
|
|
|
26
27
|
**Exceptions (ask your human partner):**
|
|
28
|
+
|
|
27
29
|
- Throwaway prototypes
|
|
28
30
|
- Generated code
|
|
29
31
|
- Configuration files
|
|
@@ -39,6 +41,7 @@ NO PRODUCTION CODE WITHOUT A FAILING TEST FIRST
|
|
|
39
41
|
Write code before the test? Delete it. Start over.
|
|
40
42
|
|
|
41
43
|
**No exceptions:**
|
|
44
|
+
|
|
42
45
|
- Don't keep it as "reference"
|
|
43
46
|
- Don't "adapt" it while writing tests
|
|
44
47
|
- Don't look at it
|
|
@@ -84,12 +87,13 @@ test('retries failed operations 3 times', async () => {
|
|
|
84
87
|
return 'success';
|
|
85
88
|
};
|
|
86
89
|
|
|
87
|
-
|
|
90
|
+
const result = await retryOperation(operation);
|
|
88
91
|
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
expect(result).toBe('success');
|
|
93
|
+
expect(attempts).toBe(3);
|
|
91
94
|
});
|
|
92
|
-
|
|
95
|
+
|
|
96
|
+
````
|
|
93
97
|
Clear name, tests real behavior, one thing
|
|
94
98
|
</Good>
|
|
95
99
|
|
|
@@ -103,11 +107,13 @@ test('retry works', async () => {
|
|
|
103
107
|
await retryOperation(mock);
|
|
104
108
|
expect(mock).toHaveBeenCalledTimes(3);
|
|
105
109
|
});
|
|
106
|
-
|
|
110
|
+
````
|
|
111
|
+
|
|
107
112
|
Vague name, tests mock not code
|
|
108
113
|
</Bad>
|
|
109
114
|
|
|
110
115
|
**Requirements:**
|
|
116
|
+
|
|
111
117
|
- One behavior
|
|
112
118
|
- Clear name
|
|
113
119
|
- Real code (no mocks unless unavoidable)
|
|
@@ -117,10 +123,11 @@ Vague name, tests mock not code
|
|
|
117
123
|
**MANDATORY. Never skip.**
|
|
118
124
|
|
|
119
125
|
```bash
|
|
120
|
-
|
|
126
|
+
npx vitest path/to/test.spec.ts --run
|
|
121
127
|
```
|
|
122
128
|
|
|
123
129
|
Confirm:
|
|
130
|
+
|
|
124
131
|
- Test fails (not errors)
|
|
125
132
|
- Failure message is expected
|
|
126
133
|
- Fails because feature missing (not typos)
|
|
@@ -172,10 +179,11 @@ Don't add features, refactor other code, or "improve" beyond the test.
|
|
|
172
179
|
**MANDATORY.**
|
|
173
180
|
|
|
174
181
|
```bash
|
|
175
|
-
|
|
182
|
+
npx vitest path/to/test.spec.ts --run
|
|
176
183
|
```
|
|
177
184
|
|
|
178
185
|
Confirm:
|
|
186
|
+
|
|
179
187
|
- Test passes
|
|
180
188
|
- Other tests still pass
|
|
181
189
|
- Output pristine (no errors, warnings)
|
|
@@ -187,6 +195,7 @@ Confirm:
|
|
|
187
195
|
### REFACTOR - Clean Up
|
|
188
196
|
|
|
189
197
|
After green only:
|
|
198
|
+
|
|
190
199
|
- Remove duplication
|
|
191
200
|
- Improve names
|
|
192
201
|
- Extract helpers
|
|
@@ -199,17 +208,18 @@ Next failing test for next feature.
|
|
|
199
208
|
|
|
200
209
|
## Good Tests
|
|
201
210
|
|
|
202
|
-
| Quality
|
|
203
|
-
|
|
204
|
-
| **Minimal**
|
|
205
|
-
| **Clear**
|
|
206
|
-
| **Shows intent** | Demonstrates desired API
|
|
211
|
+
| Quality | Good | Bad |
|
|
212
|
+
| ---------------- | ----------------------------------- | --------------------------------------------------- |
|
|
213
|
+
| **Minimal** | One thing. "and" in name? Split it. | `test('validates email and domain and whitespace')` |
|
|
214
|
+
| **Clear** | Name describes behavior | `test('test1')` |
|
|
215
|
+
| **Shows intent** | Demonstrates desired API | Obscures what code should do |
|
|
207
216
|
|
|
208
217
|
## Why Order Matters
|
|
209
218
|
|
|
210
219
|
**"I'll write tests after to verify it works"**
|
|
211
220
|
|
|
212
221
|
Tests written after code pass immediately. Passing immediately proves nothing:
|
|
222
|
+
|
|
213
223
|
- Might test wrong thing
|
|
214
224
|
- Might test implementation, not behavior
|
|
215
225
|
- Might miss edge cases you forgot
|
|
@@ -220,6 +230,7 @@ Test-first forces you to see the test fail, proving it actually tests something.
|
|
|
220
230
|
**"I already manually tested all the edge cases"**
|
|
221
231
|
|
|
222
232
|
Manual testing is ad-hoc. You think you tested everything but:
|
|
233
|
+
|
|
223
234
|
- No record of what you tested
|
|
224
235
|
- Can't re-run when code changes
|
|
225
236
|
- Easy to forget cases under pressure
|
|
@@ -230,6 +241,7 @@ Automated tests are systematic. They run the same way every time.
|
|
|
230
241
|
**"Deleting X hours of work is wasteful"**
|
|
231
242
|
|
|
232
243
|
Sunk cost fallacy. The time is already gone. Your choice now:
|
|
244
|
+
|
|
233
245
|
- Delete and rewrite with TDD (X more hours, high confidence)
|
|
234
246
|
- Keep it and add tests after (30 min, low confidence, likely bugs)
|
|
235
247
|
|
|
@@ -238,6 +250,7 @@ The "waste" is keeping code you can't trust. Working code without real tests is
|
|
|
238
250
|
**"TDD is dogmatic, being pragmatic means adapting"**
|
|
239
251
|
|
|
240
252
|
TDD IS pragmatic:
|
|
253
|
+
|
|
241
254
|
- Finds bugs before commit (faster than debugging after)
|
|
242
255
|
- Prevents regressions (tests catch breaks immediately)
|
|
243
256
|
- Documents behavior (tests show how to use code)
|
|
@@ -257,19 +270,19 @@ Tests-first force edge case discovery before implementing. Tests-after verify yo
|
|
|
257
270
|
|
|
258
271
|
## Common Rationalizations
|
|
259
272
|
|
|
260
|
-
| Excuse
|
|
261
|
-
|
|
262
|
-
| "Too simple to test"
|
|
263
|
-
| "I'll test after"
|
|
264
|
-
| "Tests after achieve same goals"
|
|
265
|
-
| "Already manually tested"
|
|
266
|
-
| "Deleting X hours is wasteful"
|
|
267
|
-
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete.
|
|
268
|
-
| "Need to explore first"
|
|
269
|
-
| "Test hard = design unclear"
|
|
270
|
-
| "TDD will slow me down"
|
|
271
|
-
| "Manual test faster"
|
|
272
|
-
| "Existing code has no tests"
|
|
273
|
+
| Excuse | Reality |
|
|
274
|
+
| -------------------------------------- | ----------------------------------------------------------------------- |
|
|
275
|
+
| "Too simple to test" | Simple code breaks. Test takes 30 seconds. |
|
|
276
|
+
| "I'll test after" | Tests passing immediately prove nothing. |
|
|
277
|
+
| "Tests after achieve same goals" | Tests-after = "what does this do?" Tests-first = "what should this do?" |
|
|
278
|
+
| "Already manually tested" | Ad-hoc ≠ systematic. No record, can't re-run. |
|
|
279
|
+
| "Deleting X hours is wasteful" | Sunk cost fallacy. Keeping unverified code is technical debt. |
|
|
280
|
+
| "Keep as reference, write tests first" | You'll adapt it. That's testing after. Delete means delete. |
|
|
281
|
+
| "Need to explore first" | Fine. Throw away exploration, start with TDD. |
|
|
282
|
+
| "Test hard = design unclear" | Listen to test. Hard to test = hard to use. |
|
|
283
|
+
| "TDD will slow me down" | TDD faster than debugging. Pragmatic = test-first. |
|
|
284
|
+
| "Manual test faster" | Manual doesn't prove edge cases. You'll re-test every change. |
|
|
285
|
+
| "Existing code has no tests" | You're improving it. Add tests for existing code. |
|
|
273
286
|
|
|
274
287
|
## Red Flags - STOP and Start Over
|
|
275
288
|
|
|
@@ -294,32 +307,36 @@ Tests-first force edge case discovery before implementing. Tests-after verify yo
|
|
|
294
307
|
**Bug:** Empty email accepted
|
|
295
308
|
|
|
296
309
|
**RED**
|
|
310
|
+
|
|
297
311
|
```typescript
|
|
298
|
-
test(
|
|
299
|
-
const result = await submitForm({ email:
|
|
300
|
-
expect(result.error).toBe(
|
|
312
|
+
test("rejects empty email", async () => {
|
|
313
|
+
const result = await submitForm({ email: "" });
|
|
314
|
+
expect(result.error).toBe("Email required");
|
|
301
315
|
});
|
|
302
316
|
```
|
|
303
317
|
|
|
304
318
|
**Verify RED**
|
|
319
|
+
|
|
305
320
|
```bash
|
|
306
|
-
$
|
|
321
|
+
$ npx vitest path/to/test.spec.ts --run
|
|
307
322
|
FAIL: expected 'Email required', got undefined
|
|
308
323
|
```
|
|
309
324
|
|
|
310
325
|
**GREEN**
|
|
326
|
+
|
|
311
327
|
```typescript
|
|
312
328
|
function submitForm(data: FormData) {
|
|
313
329
|
if (!data.email?.trim()) {
|
|
314
|
-
return { error:
|
|
330
|
+
return { error: "Email required" };
|
|
315
331
|
}
|
|
316
332
|
// ...
|
|
317
333
|
}
|
|
318
334
|
```
|
|
319
335
|
|
|
320
336
|
**Verify GREEN**
|
|
337
|
+
|
|
321
338
|
```bash
|
|
322
|
-
$
|
|
339
|
+
$ npx vitest path/to/test.spec.ts --run
|
|
323
340
|
PASS
|
|
324
341
|
```
|
|
325
342
|
|
|
@@ -343,12 +360,12 @@ Can't check all boxes? You skipped TDD. Start over.
|
|
|
343
360
|
|
|
344
361
|
## When Stuck
|
|
345
362
|
|
|
346
|
-
| Problem
|
|
347
|
-
|
|
363
|
+
| Problem | Solution |
|
|
364
|
+
| ---------------------- | -------------------------------------------------------------------- |
|
|
348
365
|
| Don't know how to test | Write wished-for API. Write assertion first. Ask your human partner. |
|
|
349
|
-
| Test too complicated
|
|
350
|
-
| Must mock everything
|
|
351
|
-
| Test setup huge
|
|
366
|
+
| Test too complicated | Design too complicated. Simplify interface. |
|
|
367
|
+
| Must mock everything | Code too coupled. Use dependency injection. |
|
|
368
|
+
| Test setup huge | Extract helpers. Still complex? Simplify design. |
|
|
352
369
|
|
|
353
370
|
## Debugging Integration
|
|
354
371
|
|
|
@@ -359,6 +376,7 @@ Never fix bugs without a test.
|
|
|
359
376
|
## Testing Anti-Patterns
|
|
360
377
|
|
|
361
378
|
When adding mocks or test utilities, read testing-anti-patterns.md to avoid common pitfalls:
|
|
379
|
+
|
|
362
380
|
- Testing mock behavior instead of real behavior
|
|
363
381
|
- Adding test-only methods to production classes
|
|
364
382
|
- Mocking without understanding dependencies
|
|
@@ -21,6 +21,7 @@ Tests must verify real behavior, not mock behavior. Mocks are a means to isolate
|
|
|
21
21
|
## Anti-Pattern 1: Testing Mock Behavior
|
|
22
22
|
|
|
23
23
|
**The violation:**
|
|
24
|
+
|
|
24
25
|
```typescript
|
|
25
26
|
// ❌ BAD: Testing that the mock exists
|
|
26
27
|
test('renders sidebar', () => {
|
|
@@ -30,6 +31,7 @@ test('renders sidebar', () => {
|
|
|
30
31
|
```
|
|
31
32
|
|
|
32
33
|
**Why this is wrong:**
|
|
34
|
+
|
|
33
35
|
- You're verifying the mock works, not that the component works
|
|
34
36
|
- Test passes when mock is present, fails when it's not
|
|
35
37
|
- Tells you nothing about real behavior
|
|
@@ -37,6 +39,7 @@ test('renders sidebar', () => {
|
|
|
37
39
|
**your human partner's correction:** "Are we testing the behavior of a mock?"
|
|
38
40
|
|
|
39
41
|
**The fix:**
|
|
42
|
+
|
|
40
43
|
```typescript
|
|
41
44
|
// ✅ GOOD: Test real component or don't mock it
|
|
42
45
|
test('renders sidebar', () => {
|
|
@@ -63,10 +66,12 @@ BEFORE asserting on any mock element:
|
|
|
63
66
|
## Anti-Pattern 2: Test-Only Methods in Production
|
|
64
67
|
|
|
65
68
|
**The violation:**
|
|
69
|
+
|
|
66
70
|
```typescript
|
|
67
71
|
// ❌ BAD: destroy() only used in tests
|
|
68
72
|
class Session {
|
|
69
|
-
async destroy() {
|
|
73
|
+
async destroy() {
|
|
74
|
+
// Looks like production API!
|
|
70
75
|
await this._workspaceManager?.destroyWorkspace(this.id);
|
|
71
76
|
// ... cleanup
|
|
72
77
|
}
|
|
@@ -77,12 +82,14 @@ afterEach(() => session.destroy());
|
|
|
77
82
|
```
|
|
78
83
|
|
|
79
84
|
**Why this is wrong:**
|
|
85
|
+
|
|
80
86
|
- Production class polluted with test-only code
|
|
81
87
|
- Dangerous if accidentally called in production
|
|
82
88
|
- Violates YAGNI and separation of concerns
|
|
83
89
|
- Confuses object lifecycle with entity lifecycle
|
|
84
90
|
|
|
85
91
|
**The fix:**
|
|
92
|
+
|
|
86
93
|
```typescript
|
|
87
94
|
// ✅ GOOD: Test utilities handle test cleanup
|
|
88
95
|
// Session has no destroy() - it's stateless in production
|
|
@@ -118,33 +125,36 @@ BEFORE adding any method to production class:
|
|
|
118
125
|
## Anti-Pattern 3: Mocking Without Understanding
|
|
119
126
|
|
|
120
127
|
**The violation:**
|
|
128
|
+
|
|
121
129
|
```typescript
|
|
122
130
|
// ❌ BAD: Mock breaks test logic
|
|
123
|
-
test(
|
|
131
|
+
test("detects duplicate server", () => {
|
|
124
132
|
// Mock prevents config write that test depends on!
|
|
125
|
-
vi.mock(
|
|
126
|
-
discoverAndCacheTools: vi.fn().mockResolvedValue(undefined)
|
|
133
|
+
vi.mock("ToolCatalog", () => ({
|
|
134
|
+
discoverAndCacheTools: vi.fn().mockResolvedValue(undefined),
|
|
127
135
|
}));
|
|
128
136
|
|
|
129
137
|
await addServer(config);
|
|
130
|
-
await addServer(config);
|
|
138
|
+
await addServer(config); // Should throw - but won't!
|
|
131
139
|
});
|
|
132
140
|
```
|
|
133
141
|
|
|
134
142
|
**Why this is wrong:**
|
|
143
|
+
|
|
135
144
|
- Mocked method had side effect test depended on (writing config)
|
|
136
145
|
- Over-mocking to "be safe" breaks actual behavior
|
|
137
146
|
- Test passes for wrong reason or fails mysteriously
|
|
138
147
|
|
|
139
148
|
**The fix:**
|
|
149
|
+
|
|
140
150
|
```typescript
|
|
141
151
|
// ✅ GOOD: Mock at correct level
|
|
142
|
-
test(
|
|
152
|
+
test("detects duplicate server", () => {
|
|
143
153
|
// Mock the slow part, preserve behavior test needs
|
|
144
|
-
vi.mock(
|
|
154
|
+
vi.mock("MCPServerManager"); // Just mock slow server startup
|
|
145
155
|
|
|
146
|
-
await addServer(config);
|
|
147
|
-
await addServer(config);
|
|
156
|
+
await addServer(config); // Config written
|
|
157
|
+
await addServer(config); // Duplicate detected ✓
|
|
148
158
|
});
|
|
149
159
|
```
|
|
150
160
|
|
|
@@ -177,11 +187,12 @@ BEFORE mocking any method:
|
|
|
177
187
|
## Anti-Pattern 4: Incomplete Mocks
|
|
178
188
|
|
|
179
189
|
**The violation:**
|
|
190
|
+
|
|
180
191
|
```typescript
|
|
181
192
|
// ❌ BAD: Partial mock - only fields you think you need
|
|
182
193
|
const mockResponse = {
|
|
183
|
-
status:
|
|
184
|
-
data: { userId:
|
|
194
|
+
status: "success",
|
|
195
|
+
data: { userId: "123", name: "Alice" },
|
|
185
196
|
// Missing: metadata that downstream code uses
|
|
186
197
|
};
|
|
187
198
|
|
|
@@ -189,6 +200,7 @@ const mockResponse = {
|
|
|
189
200
|
```
|
|
190
201
|
|
|
191
202
|
**Why this is wrong:**
|
|
203
|
+
|
|
192
204
|
- **Partial mocks hide structural assumptions** - You only mocked fields you know about
|
|
193
205
|
- **Downstream code may depend on fields you didn't include** - Silent failures
|
|
194
206
|
- **Tests pass but integration fails** - Mock incomplete, real API complete
|
|
@@ -197,12 +209,13 @@ const mockResponse = {
|
|
|
197
209
|
**The Iron Rule:** Mock the COMPLETE data structure as it exists in reality, not just fields your immediate test uses.
|
|
198
210
|
|
|
199
211
|
**The fix:**
|
|
212
|
+
|
|
200
213
|
```typescript
|
|
201
214
|
// ✅ GOOD: Mirror real API completeness
|
|
202
215
|
const mockResponse = {
|
|
203
|
-
status:
|
|
204
|
-
data: { userId:
|
|
205
|
-
metadata: { requestId:
|
|
216
|
+
status: "success",
|
|
217
|
+
data: { userId: "123", name: "Alice" },
|
|
218
|
+
metadata: { requestId: "req-789", timestamp: 1234567890 },
|
|
206
219
|
// All fields real API returns
|
|
207
220
|
};
|
|
208
221
|
```
|
|
@@ -228,6 +241,7 @@ BEFORE creating mock responses:
|
|
|
228
241
|
## Anti-Pattern 5: Integration Tests as Afterthought
|
|
229
242
|
|
|
230
243
|
**The violation:**
|
|
244
|
+
|
|
231
245
|
```
|
|
232
246
|
✅ Implementation complete
|
|
233
247
|
❌ No tests written
|
|
@@ -235,11 +249,13 @@ BEFORE creating mock responses:
|
|
|
235
249
|
```
|
|
236
250
|
|
|
237
251
|
**Why this is wrong:**
|
|
252
|
+
|
|
238
253
|
- Testing is part of implementation, not optional follow-up
|
|
239
254
|
- TDD would have caught this
|
|
240
255
|
- Can't claim complete without tests
|
|
241
256
|
|
|
242
257
|
**The fix:**
|
|
258
|
+
|
|
243
259
|
```
|
|
244
260
|
TDD cycle:
|
|
245
261
|
1. Write failing test
|
|
@@ -251,6 +267,7 @@ TDD cycle:
|
|
|
251
267
|
## When Mocks Become Too Complex
|
|
252
268
|
|
|
253
269
|
**Warning signs:**
|
|
270
|
+
|
|
254
271
|
- Mock setup longer than test logic
|
|
255
272
|
- Mocking everything to make test pass
|
|
256
273
|
- Mocks missing methods real components have
|
|
@@ -263,6 +280,7 @@ TDD cycle:
|
|
|
263
280
|
## TDD Prevents These Anti-Patterns
|
|
264
281
|
|
|
265
282
|
**Why TDD helps:**
|
|
283
|
+
|
|
266
284
|
1. **Write test first** → Forces you to think about what you're actually testing
|
|
267
285
|
2. **Watch it fail** → Confirms test tests real behavior, not mocks
|
|
268
286
|
3. **Minimal implementation** → No test-only methods creep in
|
|
@@ -272,14 +290,14 @@ TDD cycle:
|
|
|
272
290
|
|
|
273
291
|
## Quick Reference
|
|
274
292
|
|
|
275
|
-
| Anti-Pattern
|
|
276
|
-
|
|
277
|
-
| Assert on mock elements
|
|
278
|
-
| Test-only methods in production | Move to test utilities
|
|
279
|
-
| Mock without understanding
|
|
280
|
-
| Incomplete mocks
|
|
281
|
-
| Tests as afterthought
|
|
282
|
-
| Over-complex mocks
|
|
293
|
+
| Anti-Pattern | Fix |
|
|
294
|
+
| ------------------------------- | --------------------------------------------- |
|
|
295
|
+
| Assert on mock elements | Test real component or unmock it |
|
|
296
|
+
| Test-only methods in production | Move to test utilities |
|
|
297
|
+
| Mock without understanding | Understand dependencies first, mock minimally |
|
|
298
|
+
| Incomplete mocks | Mirror real API completely |
|
|
299
|
+
| Tests as afterthought | TDD - tests first |
|
|
300
|
+
| Over-complex mocks | Consider integration tests |
|
|
283
301
|
|
|
284
302
|
## Red Flags
|
|
285
303
|
|
|
@@ -6,7 +6,7 @@ model: haiku
|
|
|
6
6
|
|
|
7
7
|
# sd-use - Auto Skill/Agent Router
|
|
8
8
|
|
|
9
|
-
Analyze user request from ARGUMENTS, select the best matching sd
|
|
9
|
+
Analyze user request from ARGUMENTS, select the best matching sd-\* skill or agent, explain why, then execute it.
|
|
10
10
|
|
|
11
11
|
## Execution Flow
|
|
12
12
|
|
|
@@ -19,30 +19,30 @@ Analyze user request from ARGUMENTS, select the best matching sd-* skill or agen
|
|
|
19
19
|
|
|
20
20
|
### Skills (execute via `Skill` tool)
|
|
21
21
|
|
|
22
|
-
| Skill
|
|
23
|
-
|
|
24
|
-
| `sd-brainstorm`
|
|
25
|
-
| `sd-debug`
|
|
26
|
-
| `sd-tdd`
|
|
27
|
-
| `sd-plan`
|
|
28
|
-
| `sd-plan-dev`
|
|
29
|
-
| `sd-explore`
|
|
30
|
-
| `sd-review`
|
|
31
|
-
| `sd-check`
|
|
32
|
-
| `sd-commit`
|
|
33
|
-
| `sd-readme`
|
|
34
|
-
| `sd-discuss`
|
|
35
|
-
| `sd-api-name-review` | Review public API naming consistency
|
|
36
|
-
| `sd-worktree`
|
|
37
|
-
| `sd-skill`
|
|
22
|
+
| Skill | When to select |
|
|
23
|
+
| -------------------- | ------------------------------------------------------------------------------------ |
|
|
24
|
+
| `sd-brainstorm` | New feature, component, or behavior change — **creative work before implementation** |
|
|
25
|
+
| `sd-debug` | Bug, test failure, unexpected behavior — **systematic root cause investigation** |
|
|
26
|
+
| `sd-tdd` | Implementing a feature or fixing a bug — **before writing code** |
|
|
27
|
+
| `sd-plan` | Multi-step task with spec/requirements — **planning before code** |
|
|
28
|
+
| `sd-plan-dev` | Already have a plan — **executing implementation plan** |
|
|
29
|
+
| `sd-explore` | Deep codebase analysis — tracing execution paths, architecture, dependencies |
|
|
30
|
+
| `sd-review` | Comprehensive code review of a package or path |
|
|
31
|
+
| `sd-check` | Verify code — typecheck, lint, tests |
|
|
32
|
+
| `sd-commit` | Create a git commit |
|
|
33
|
+
| `sd-readme` | Update a package README.md |
|
|
34
|
+
| `sd-discuss` | Evaluate code design decisions against industry standards and project conventions |
|
|
35
|
+
| `sd-api-name-review` | Review public API naming consistency |
|
|
36
|
+
| `sd-worktree` | Start new work in branch isolation |
|
|
37
|
+
| `sd-skill` | Create or edit skills |
|
|
38
38
|
|
|
39
39
|
### Agents (execute via `Task` tool with matching `subagent_type`)
|
|
40
40
|
|
|
41
|
-
| Agent
|
|
42
|
-
|
|
43
|
-
| `sd-code-reviewer`
|
|
44
|
-
| `sd-code-simplifier` | Simplify, clean up, improve code readability
|
|
45
|
-
| `sd-api-reviewer`
|
|
41
|
+
| Agent | When to select |
|
|
42
|
+
| -------------------- | ----------------------------------------------------------------- |
|
|
43
|
+
| `sd-code-reviewer` | Focused review for bugs, security vulnerabilities, quality issues |
|
|
44
|
+
| `sd-code-simplifier` | Simplify, clean up, improve code readability |
|
|
45
|
+
| `sd-api-reviewer` | Review library public API for DX quality |
|
|
46
46
|
|
|
47
47
|
## Selection Rules
|
|
48
48
|
|
|
@@ -15,6 +15,7 @@ Create, merge, and clean up git worktrees under `.worktrees/`. Uses the current
|
|
|
15
15
|
## Target Worktree Resolution
|
|
16
16
|
|
|
17
17
|
For all commands, the target worktree name is resolved in this order:
|
|
18
|
+
|
|
18
19
|
1. Explicitly provided in args → use as-is
|
|
19
20
|
2. Current cd is inside `.worktrees/<name>/` → use that `<name>` (auto-detected)
|
|
20
21
|
3. Neither applies → ask the user
|
|
@@ -47,7 +47,7 @@ switch (cmd) {
|
|
|
47
47
|
console.log(`Creating worktree: .worktrees/${name} (from ${branch})`);
|
|
48
48
|
run(`git worktree add "${worktreePath}" -b "${name}"`);
|
|
49
49
|
console.log("Installing dependencies...");
|
|
50
|
-
run("
|
|
50
|
+
run("npm install", { cwd: worktreePath });
|
|
51
51
|
console.log(`\nReady: ${worktreePath}`);
|
|
52
52
|
break;
|
|
53
53
|
}
|
package/package.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import { readFileSync, existsSync } from "fs";
|
|
2
|
-
import { resolve } from "path";
|
|
3
|
-
import { spawn } from "child_process";
|
|
4
|
-
|
|
5
|
-
const root = resolve(import.meta.dirname, "../../..");
|
|
6
|
-
|
|
7
|
-
// ══════════════════════════════════════════
|
|
8
|
-
// Phase 1: Environment Pre-check
|
|
9
|
-
// ══════════════════════════════════════════
|
|
10
|
-
|
|
11
|
-
const errors = [];
|
|
12
|
-
|
|
13
|
-
const pkgPath = resolve(root, "package.json");
|
|
14
|
-
if (!existsSync(pkgPath)) {
|
|
15
|
-
errors.push("package.json not found");
|
|
16
|
-
} else {
|
|
17
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
|
18
|
-
const major = parseInt(pkg.version?.split(".")[0], 10);
|
|
19
|
-
if (Number.isNaN(major) || major < 13) {
|
|
20
|
-
errors.push(`This skill requires simplysm v13+. Current: ${pkg.version}`);
|
|
21
|
-
}
|
|
22
|
-
if (!pkg.scripts?.check) {
|
|
23
|
-
errors.push("'check' script not defined in package.json");
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
for (const f of ["pnpm-workspace.yaml", "pnpm-lock.yaml"]) {
|
|
28
|
-
if (!existsSync(resolve(root, f))) {
|
|
29
|
-
errors.push(`${f} not found`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
if (!existsSync(resolve(root, "vitest.config.ts"))) {
|
|
34
|
-
errors.push("vitest.config.ts not found");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
if (errors.length > 0) {
|
|
38
|
-
console.log("ENV-CHECK FAIL");
|
|
39
|
-
for (const e of errors) console.log(`- ${e}`);
|
|
40
|
-
process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
console.log("ENV-CHECK OK");
|
|
44
|
-
|
|
45
|
-
// ══════════════════════════════════════════
|
|
46
|
-
// Phase 2: Delegate to pnpm check
|
|
47
|
-
// ══════════════════════════════════════════
|
|
48
|
-
|
|
49
|
-
const args = ["check", ...process.argv.slice(2)];
|
|
50
|
-
const child = spawn("pnpm", args, { cwd: root, shell: true, stdio: "inherit" });
|
|
51
|
-
|
|
52
|
-
child.on("close", (code) => {
|
|
53
|
-
process.exit(code ?? 1);
|
|
54
|
-
});
|