clikit-plugin 0.2.44 → 0.2.46
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/AGENTS.md +69 -3
- package/README.md +128 -92
- package/command/commit.md +1 -1
- package/command/create.md +65 -8
- package/command/debug.md +1 -1
- package/command/design.md +183 -43
- package/command/handoff.md +1 -1
- package/command/import-plan.md +2 -2
- package/command/init.md +1 -1
- package/command/issue.md +3 -4
- package/command/pr.md +1 -1
- package/command/research.md +5 -7
- package/command/resume.md +1 -1
- package/command/ship.md +29 -32
- package/command/start.md +38 -27
- package/command/{status-beads.md → status.md} +2 -3
- package/command/verify.md +132 -48
- package/dist/.tsbuildinfo +1 -1
- package/dist/agents/index.d.ts +0 -0
- package/dist/agents/index.d.ts.map +0 -0
- package/dist/beads-context.test.d.ts +2 -0
- package/dist/beads-context.test.d.ts.map +1 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.d.ts.map +0 -0
- package/dist/cli.js +5 -0
- package/dist/cli.test.d.ts +0 -0
- package/dist/cli.test.d.ts.map +0 -0
- package/dist/clikit.schema.json +32 -11
- package/dist/clilog.test.d.ts +0 -0
- package/dist/clilog.test.d.ts.map +0 -0
- package/dist/commands/index.d.ts +0 -0
- package/dist/commands/index.d.ts.map +0 -0
- package/dist/config.d.ts +15 -7
- package/dist/config.d.ts.map +1 -1
- package/dist/config.test.d.ts +0 -0
- package/dist/config.test.d.ts.map +0 -0
- package/dist/hooks/beads-context.d.ts +2 -0
- package/dist/hooks/beads-context.d.ts.map +1 -1
- package/dist/hooks/empty-message-sanitizer.d.ts +0 -0
- package/dist/hooks/empty-message-sanitizer.d.ts.map +0 -0
- package/dist/hooks/error-logger.d.ts +0 -0
- package/dist/hooks/error-logger.d.ts.map +0 -0
- package/dist/hooks/git-guard.d.ts +0 -0
- package/dist/hooks/git-guard.d.ts.map +0 -0
- package/dist/hooks/index.d.ts +0 -2
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/memory-digest.d.ts +1 -0
- package/dist/hooks/memory-digest.d.ts.map +1 -1
- package/dist/hooks/security-check.d.ts +0 -0
- package/dist/hooks/security-check.d.ts.map +0 -0
- package/dist/hooks/subagent-question-blocker.d.ts +0 -0
- package/dist/hooks/subagent-question-blocker.d.ts.map +0 -0
- package/dist/hooks/todo-beads-sync.d.ts +1 -0
- package/dist/hooks/todo-beads-sync.d.ts.map +1 -1
- package/dist/hooks/todo-enforcer.d.ts +1 -1
- package/dist/hooks/todo-enforcer.d.ts.map +1 -1
- package/dist/hooks/truncator.d.ts +0 -0
- package/dist/hooks/truncator.d.ts.map +0 -0
- package/dist/index.d.ts +0 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +250 -576
- package/dist/skills/index.d.ts +0 -0
- package/dist/skills/index.d.ts.map +0 -0
- package/dist/tools/cass-memory.d.ts +0 -0
- package/dist/tools/cass-memory.d.ts.map +0 -0
- package/dist/tools/context-summary.d.ts +0 -0
- package/dist/tools/context-summary.d.ts.map +0 -0
- package/dist/tools/index.d.ts +0 -3
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/memory-db.d.ts +0 -0
- package/dist/tools/memory-db.d.ts.map +0 -0
- package/dist/tools/memory.d.ts +0 -0
- package/dist/tools/memory.d.ts.map +0 -0
- package/dist/tools/observation.d.ts +0 -0
- package/dist/tools/observation.d.ts.map +0 -0
- package/dist/types.d.ts +0 -0
- package/dist/types.d.ts.map +0 -0
- package/memory/_digest.md +1 -1
- package/memory/_templates/handoff.md +0 -0
- package/memory/_templates/plan.md +35 -0
- package/memory/_templates/prd.md +0 -0
- package/memory/_templates/research.md +0 -0
- package/memory/_templates/review.md +0 -0
- package/memory/_templates/spec.md +12 -0
- package/memory/beads/.gitkeep +0 -0
- package/memory/handoffs/.gitkeep +0 -0
- package/memory/memory.db +0 -0
- package/memory/plans/.gitkeep +0 -0
- package/memory/prds/.gitkeep +0 -0
- package/memory/research/.gitkeep +0 -0
- package/memory/reviews/.gitkeep +0 -0
- package/memory/specs/.gitkeep +0 -0
- package/package.json +4 -4
- package/skill/beads/SKILL.md +42 -43
- package/skill/beads/mcp.json +26 -0
- package/skill/beads/references/api-reference.md +64 -0
- package/skill/chrome-devtools/SKILL.md +22 -23
- package/skill/chrome-devtools/mcp.json +17 -0
- package/skill/chrome-devtools/references/tool-reference.md +63 -0
- package/skill/condition-based-waiting/SKILL.md +28 -66
- package/skill/deep-research/SKILL.md +34 -103
- package/skill/deep-research/mcp.json +21 -0
- package/skill/deep-research/references/lsp-ops.md +44 -0
- package/skill/defense-in-depth/SKILL.md +29 -69
- package/skill/executing-plans/SKILL.md +25 -34
- package/skill/finishing-a-development-branch/SKILL.md +28 -89
- package/skill/playwright/SKILL.md +27 -22
- package/skill/playwright/mcp.json +20 -0
- package/skill/playwright/references/tool-reference.md +64 -0
- package/skill/receiving-code-review/SKILL.md +16 -27
- package/skill/requesting-code-review/SKILL.md +22 -26
- package/skill/ritual-workflow/SKILL.md +22 -82
- package/skill/root-cause-tracing/SKILL.md +30 -54
- package/skill/session-management/SKILL.md +21 -40
- package/skill/source-code-research/SKILL.md +33 -102
- package/skill/source-code-research/mcp.json +13 -0
- package/skill/source-code-research/references/quick-ref.md +65 -0
- package/skill/systematic-debugging/SKILL.md +28 -41
- package/skill/systematic-debugging/references/patterns.md +71 -0
- package/skill/test-driven-development/SKILL.md +16 -40
- package/skill/testing-anti-patterns/SKILL.md +36 -64
- package/skill/testing-anti-patterns/references/decision-matrix.md +55 -0
- package/skill/using-git-worktrees/SKILL.md +27 -103
- package/skill/vercel-react-best-practices/SKILL.md +50 -139
- package/skill/vercel-react-best-practices/references/patterns.md +70 -0
- package/skill/verification-before-completion/SKILL.md +19 -37
- package/skill/writing-plans/SKILL.md +20 -32
- package/skill/writing-skills/SKILL.md +52 -41
- package/skill/writing-skills/references/skill-anatomy.md +210 -0
- package/src/agents/AGENTS.md +48 -18
- package/src/agents/build.md +342 -93
- package/src/agents/explore.md +77 -60
- package/src/agents/index.ts +0 -0
- package/src/agents/oracle.md +153 -63
- package/src/agents/plan.md +275 -110
- package/src/agents/research.md +72 -52
- package/src/agents/review.md +182 -61
- package/src/agents/vision.md +7 -5
- package/command/plan.md +0 -152
- package/command/review-codebase.md +0 -228
- package/command/review.md +0 -135
- package/command/vision.md +0 -210
- package/dist/hooks/swarm-enforcer.d.ts +0 -31
- package/dist/hooks/swarm-enforcer.d.ts.map +0 -1
- package/dist/tools/beads-memory-sync.d.ts +0 -17
- package/dist/tools/beads-memory-sync.d.ts.map +0 -1
- package/dist/tools/quick-research.d.ts +0 -16
- package/dist/tools/quick-research.d.ts.map +0 -1
- package/dist/tools/swarm.d.ts +0 -57
- package/dist/tools/swarm.d.ts.map +0 -1
- package/skill/accessibility-audit/SKILL.md +0 -115
- package/skill/beads-bridge/SKILL.md +0 -45
- package/skill/brainstorming/SKILL.md +0 -41
- package/skill/cass-village/SKILL.md +0 -217
- package/skill/cloudflare/SKILL.md +0 -96
- package/skill/design-system-audit/SKILL.md +0 -136
- package/skill/development-lifecycle/SKILL.md +0 -58
- package/skill/dispatching-parallel-agents/SKILL.md +0 -94
- package/skill/figma/SKILL.md +0 -34
- package/skill/frontend-aesthetics/SKILL.md +0 -63
- package/skill/gemini-large-context/SKILL.md +0 -80
- package/skill/mockup-to-code/SKILL.md +0 -98
- package/skill/mqdh/SKILL.md +0 -54
- package/skill/notebooklm/SKILL.md +0 -71
- package/skill/playwriter/SKILL.md +0 -56
- package/skill/polar/SKILL.md +0 -39
- package/skill/resend/SKILL.md +0 -85
- package/skill/sharing-skills/SKILL.md +0 -50
- package/skill/subagent-driven-development/SKILL.md +0 -69
- package/skill/supabase/SKILL.md +0 -80
- package/skill/supabase-postgres-best-practices/SKILL.md +0 -168
- package/skill/swarm-coordination/SKILL.md +0 -54
- package/skill/testing-skills-with-subagents/SKILL.md +0 -102
- package/skill/ui-ux-research/SKILL.md +0 -93
- package/skill/v0/SKILL.md +0 -67
- package/skill/v1-run/SKILL.md +0 -85
- package/skill/visual-analysis/SKILL.md +0 -113
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcpServers": {
|
|
3
|
+
"context7": {
|
|
4
|
+
"type": "remote",
|
|
5
|
+
"url": "https://mcp.context7.com/mcp",
|
|
6
|
+
"description": "Fetch library docs and source when npm package internals are unclear",
|
|
7
|
+
"tools": [
|
|
8
|
+
"resolve-library-id",
|
|
9
|
+
"get-library-docs"
|
|
10
|
+
]
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# Source Code Research — Quick Reference
|
|
2
|
+
|
|
3
|
+
## Locate Package Source
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# Entry point
|
|
7
|
+
node -e "console.log(require.resolve('<pkg>'))"
|
|
8
|
+
|
|
9
|
+
# package.json fields
|
|
10
|
+
node -e "const p=require('<pkg>/package.json'); console.log(p.main, p.types, p.source, p.exports)"
|
|
11
|
+
|
|
12
|
+
# Source directory
|
|
13
|
+
ls node_modules/<pkg>/src/ 2>/dev/null || ls node_modules/<pkg>/lib/
|
|
14
|
+
|
|
15
|
+
# Has TypeScript source?
|
|
16
|
+
ls node_modules/<pkg>/src/*.ts 2>/dev/null | head -5
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Read Tests (Best Behavior Docs)
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
ls node_modules/<pkg>/test/
|
|
23
|
+
ls node_modules/<pkg>/__tests__/
|
|
24
|
+
ls node_modules/<pkg>/spec/
|
|
25
|
+
|
|
26
|
+
# Read one
|
|
27
|
+
cat node_modules/<pkg>/test/core.test.js | head -100
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Trace a Specific Behavior
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
# Find where a method/function is defined
|
|
34
|
+
grep -r "functionName" node_modules/<pkg>/src/ -l
|
|
35
|
+
grep -n "functionName" node_modules/<pkg>/src/core.ts
|
|
36
|
+
|
|
37
|
+
# Find error messages (understand throw conditions)
|
|
38
|
+
grep -n "throw\|Error(" node_modules/<pkg>/src/core.ts
|
|
39
|
+
|
|
40
|
+
# Find defaults
|
|
41
|
+
grep -n "default\|DEFAULT\|\|\s*{}" node_modules/<pkg>/src/options.ts
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Context7 MCP Alternative
|
|
45
|
+
|
|
46
|
+
When local source is unclear, use Context7 MCP:
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
resolve-library-id(libraryName="<pkg>", query="<what you need to understand>")
|
|
50
|
+
→ get library ID
|
|
51
|
+
get-library-docs(libraryId="<id>", query="<specific question>")
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Output Template
|
|
55
|
+
|
|
56
|
+
```markdown
|
|
57
|
+
## [pkg] — [function/behavior]
|
|
58
|
+
|
|
59
|
+
- **Location**: src/core.ts:142
|
|
60
|
+
- **Behavior**: [what it actually does]
|
|
61
|
+
- **Defaults**: [default values if any]
|
|
62
|
+
- **Throws when**: [conditions]
|
|
63
|
+
- **Returns**: [shape of return value]
|
|
64
|
+
- **Gotcha**: [surprising behavior]
|
|
65
|
+
```
|
|
@@ -1,58 +1,45 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: systematic-debugging
|
|
3
|
-
description: Use when encountering a bug. Enforces evidence-based 4-phase
|
|
3
|
+
description: Use when encountering a bug. Enforces evidence-based 4-phase process: Reproduce → Isolate → Identify → Verify. No guessing.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Systematic Debugging
|
|
6
|
+
# Systematic Debugging
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## 4 Phases
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
- Create a minimal reproduction case
|
|
14
|
-
- Document exact steps to trigger
|
|
15
|
-
- Verify it's reproducible (not intermittent)
|
|
16
|
-
|
|
17
|
-
### Phase 2: Isolate
|
|
18
|
-
- Binary search: Comment out half the code
|
|
19
|
-
- Which half contains the bug?
|
|
20
|
-
- Repeat until isolated to smallest possible unit
|
|
10
|
+
```
|
|
11
|
+
REPRODUCE → ISOLATE → IDENTIFY → VERIFY
|
|
12
|
+
```
|
|
21
13
|
|
|
22
|
-
|
|
23
|
-
- Read the isolated code carefully
|
|
24
|
-
- Trace variable values
|
|
25
|
-
- Add instrumentation (console.log, debugger)
|
|
26
|
-
- Understand WHY it fails, not just WHERE
|
|
14
|
+
**Reproduce** — Minimal repro case. Document exact trigger. Confirm it's not intermittent.
|
|
27
15
|
|
|
28
|
-
|
|
29
|
-
- Fix the root cause
|
|
30
|
-
- Run tests to confirm fix
|
|
31
|
-
- Check for similar issues elsewhere
|
|
32
|
-
- Add regression test
|
|
16
|
+
**Isolate** — Binary search: comment out half the code. Which half has the bug? Repeat until smallest unit.
|
|
33
17
|
|
|
34
|
-
|
|
18
|
+
**Identify** — Read isolated code. Trace variable values. Understand *why* it fails, not just *where*.
|
|
35
19
|
|
|
36
|
-
|
|
37
|
-
|------|-----|
|
|
38
|
-
| No random changes | Masks symptoms, doesn't fix cause |
|
|
39
|
-
| After 3+ failed fixes | Question architectural assumptions |
|
|
40
|
-
| Always reproduce first | Can't fix what you can't trigger |
|
|
41
|
-
| Add regression test | Prevent recurrence |
|
|
20
|
+
**Verify** — Fix root cause. Run tests. Check for similar issues. Add regression test.
|
|
42
21
|
|
|
43
22
|
## Instrumentation
|
|
44
23
|
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
console.error('
|
|
48
|
-
|
|
49
|
-
// Variable dump
|
|
50
|
-
console.error('Context:', JSON.stringify({ var1, var2 }, null, 2));
|
|
24
|
+
```js
|
|
25
|
+
console.error('[DBG]', JSON.stringify({ var1, var2 }, null, 2));
|
|
26
|
+
console.error('[STACK]', new Error().stack);
|
|
51
27
|
```
|
|
52
28
|
|
|
29
|
+
## Rules
|
|
30
|
+
|
|
31
|
+
| Situation | Action |
|
|
32
|
+
|-----------|--------|
|
|
33
|
+
| 3+ failed fixes | Question architectural assumptions |
|
|
34
|
+
| Error appears at A | Trace backward — cause is at B, fix B |
|
|
35
|
+
| No repro steps | Don't touch code yet |
|
|
36
|
+
|
|
53
37
|
## Red Flags
|
|
54
38
|
|
|
55
|
-
- Changing code without
|
|
56
|
-
-
|
|
57
|
-
-
|
|
58
|
-
|
|
39
|
+
- Changing code without a hypothesis
|
|
40
|
+
- Fixing where error appears, not where it originates
|
|
41
|
+
- No regression test after fix
|
|
42
|
+
|
|
43
|
+
## References
|
|
44
|
+
|
|
45
|
+
- [Debugging patterns](references/patterns.md) — binary search template, instrumentation helpers, async bug patterns, hypothesis template
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Debugging Patterns
|
|
2
|
+
|
|
3
|
+
## Binary Search (Isolate Phase)
|
|
4
|
+
|
|
5
|
+
```js
|
|
6
|
+
// 1. Comment out second half of suspect function
|
|
7
|
+
// 2. Does bug disappear? → bug was in that half
|
|
8
|
+
// 3. Restore, comment out first half
|
|
9
|
+
// 4. Repeat until isolated to single expression
|
|
10
|
+
|
|
11
|
+
function process(input) {
|
|
12
|
+
const a = step1(input); // ← comment from here down
|
|
13
|
+
const b = step2(a);
|
|
14
|
+
const c = step3(b); // ← to here
|
|
15
|
+
return c;
|
|
16
|
+
}
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Instrumentation Templates
|
|
20
|
+
|
|
21
|
+
```js
|
|
22
|
+
// Entry/exit trace
|
|
23
|
+
function traced(name, fn) {
|
|
24
|
+
return function(...args) {
|
|
25
|
+
console.error(`[ENTER] ${name}`, JSON.stringify(args));
|
|
26
|
+
const result = fn.apply(this, args);
|
|
27
|
+
console.error(`[EXIT] ${name}`, JSON.stringify(result));
|
|
28
|
+
return result;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// State snapshot at a point
|
|
33
|
+
function snapshot(label, state) {
|
|
34
|
+
console.error(`[SNAP] ${label}`, JSON.stringify(state, null, 2));
|
|
35
|
+
console.error(`[STACK]`, new Error().stack.split('\n').slice(1,5).join('\n'));
|
|
36
|
+
}
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Test Polluter Isolation
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# Run individual test — passes?
|
|
43
|
+
npx jest path/to/test.spec.ts
|
|
44
|
+
|
|
45
|
+
# Run full suite — fails?
|
|
46
|
+
npx jest
|
|
47
|
+
|
|
48
|
+
# Binary search: run subsets
|
|
49
|
+
npx jest --testPathPattern="a|b|c" # first half
|
|
50
|
+
npx jest --testPathPattern="d|e|f" # second half
|
|
51
|
+
# isolate to single file, then single test
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Async Bug Patterns
|
|
55
|
+
|
|
56
|
+
| Symptom | Likely Cause |
|
|
57
|
+
|---------|-------------|
|
|
58
|
+
| Passes locally, fails CI | Race condition — missing await or setTimeout |
|
|
59
|
+
| Intermittent failure | Shared mutable state between tests |
|
|
60
|
+
| Works in isolation, fails in batch | Test polluter — global state mutation |
|
|
61
|
+
| Wrong value but no error | Stale closure or captured reference |
|
|
62
|
+
|
|
63
|
+
## Hypothesis Template
|
|
64
|
+
|
|
65
|
+
Before changing anything, write:
|
|
66
|
+
```
|
|
67
|
+
Hypothesis: [specific cause]
|
|
68
|
+
Evidence: [what I observed]
|
|
69
|
+
Test: [how I will verify or falsify]
|
|
70
|
+
Expected: [what should happen if hypothesis is correct]
|
|
71
|
+
```
|
|
@@ -1,53 +1,29 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: test-driven-development
|
|
3
|
-
description: Use when implementing any feature. Enforces strict RED-GREEN-REFACTOR cycle.
|
|
3
|
+
description: Use when implementing any feature. Enforces strict RED-GREEN-REFACTOR cycle. No code before a failing test exists.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Test-Driven Development
|
|
6
|
+
# Test-Driven Development
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
## RED-GREEN-REFACTOR
|
|
11
|
-
|
|
12
|
-
### Phase 1: RED
|
|
13
|
-
1. Write a failing test
|
|
14
|
-
2. Run the test — it MUST fail
|
|
15
|
-
3. If it passes, the test is wrong — delete and rewrite
|
|
16
|
-
|
|
17
|
-
### Phase 2: GREEN
|
|
18
|
-
1. Write the MINIMUM code to make the test pass
|
|
19
|
-
2. Run the test — it MUST pass
|
|
20
|
-
3. If it fails, fix the code (not the test)
|
|
21
|
-
|
|
22
|
-
### Phase 3: REFACTOR
|
|
23
|
-
1. Clean up code while keeping tests green
|
|
24
|
-
2. Run tests after each change
|
|
25
|
-
3. Commit when satisfied
|
|
26
|
-
|
|
27
|
-
## Rules
|
|
28
|
-
|
|
29
|
-
| Rule | Enforcement |
|
|
30
|
-
|------|-------------|
|
|
31
|
-
| Write code before test? | DELETE the code. Don't keep as reference. |
|
|
32
|
-
| Test passes unexpectedly? | DELETE the test. It's testing nothing. |
|
|
33
|
-
| Skip RED phase? | Not allowed. Always start with failing test. |
|
|
34
|
-
| "Just this once"? | No. No exceptions. |
|
|
35
|
-
|
|
36
|
-
## Workflow
|
|
8
|
+
## Cycle
|
|
37
9
|
|
|
38
10
|
```
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
4. GREEN → Write minimal code
|
|
43
|
-
5. Run → Watch it pass
|
|
44
|
-
6. REFACTOR → Clean up
|
|
45
|
-
7. Commit
|
|
11
|
+
RED → write failing test → run → must fail
|
|
12
|
+
GREEN → write minimum code → run → must pass
|
|
13
|
+
REFACTOR → clean up, keep green → commit
|
|
46
14
|
```
|
|
47
15
|
|
|
16
|
+
## Hard Rules
|
|
17
|
+
|
|
18
|
+
| Situation | Action |
|
|
19
|
+
|-----------|--------|
|
|
20
|
+
| Code written before test | DELETE the code. Start over. |
|
|
21
|
+
| Test passes on first run | DELETE the test. It's testing nothing. |
|
|
22
|
+
| Tempted to skip RED | Not allowed. Always see it fail first. |
|
|
23
|
+
|
|
48
24
|
## Red Flags
|
|
49
25
|
|
|
50
|
-
-
|
|
26
|
+
- Implementation exists before test
|
|
51
27
|
- Keeping "reference code" while writing test
|
|
52
28
|
- Skipping "watch it fail" step
|
|
53
|
-
- Test
|
|
29
|
+
- Test body mirrors the implementation
|
|
@@ -1,100 +1,72 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: testing-anti-patterns
|
|
3
|
-
description: Prevents testing mock behavior instead of real code, test-only
|
|
3
|
+
description: Prevents testing mock behavior instead of real code, test-only production methods, and mocking without understanding boundaries.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Testing Anti-Patterns
|
|
6
|
+
# Testing Anti-Patterns
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Anti-Pattern 1 — Testing the Mock
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
```javascript
|
|
13
|
-
// BAD: Test verifies mock was called
|
|
14
|
-
const mock = jest.fn();
|
|
15
|
-
service.doThing(mock);
|
|
10
|
+
```js
|
|
11
|
+
// BAD: proves nothing about service.doThing
|
|
16
12
|
expect(mock).toHaveBeenCalled();
|
|
17
13
|
|
|
18
|
-
//
|
|
19
|
-
// It only proves you called the mock
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
```javascript
|
|
23
|
-
// GOOD: Test verifies actual behavior
|
|
24
|
-
const result = service.doThing(realDependency);
|
|
14
|
+
// GOOD: verify actual behavior
|
|
25
15
|
expect(result.status).toBe('success');
|
|
26
16
|
expect(sideEffectHappened).toBe(true);
|
|
27
17
|
```
|
|
28
18
|
|
|
29
|
-
## Anti-Pattern
|
|
19
|
+
## Anti-Pattern 2 — Test-Only Production Methods
|
|
30
20
|
|
|
31
|
-
```
|
|
32
|
-
// BAD
|
|
21
|
+
```js
|
|
22
|
+
// BAD
|
|
33
23
|
class UserService {
|
|
34
|
-
|
|
35
|
-
_validateEmailForTesting(email) { ... } // NEVER DO THIS
|
|
24
|
+
_validateEmailForTesting(email) { ... } // NEVER
|
|
36
25
|
}
|
|
37
26
|
|
|
38
|
-
//
|
|
39
|
-
// Refactoring becomes impossible
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
```javascript
|
|
43
|
-
// GOOD: Test through public API
|
|
44
|
-
// If you need to test validation, test it through the method that uses it
|
|
27
|
+
// GOOD: test through the public API
|
|
45
28
|
const result = userService.register(email);
|
|
46
29
|
expect(result.isValid).toBe(true);
|
|
47
30
|
```
|
|
48
31
|
|
|
49
|
-
## Anti-Pattern
|
|
32
|
+
## Anti-Pattern 3 — Over-Mocking
|
|
50
33
|
|
|
51
|
-
```
|
|
52
|
-
// BAD:
|
|
34
|
+
```js
|
|
35
|
+
// BAD: mocking everything means testing nothing
|
|
53
36
|
jest.mock('./database');
|
|
54
37
|
jest.mock('./logger');
|
|
55
38
|
jest.mock('./config');
|
|
56
|
-
jest.mock('./everything');
|
|
57
39
|
|
|
58
|
-
//
|
|
59
|
-
//
|
|
40
|
+
// GOOD: mock only external boundaries
|
|
41
|
+
// Mock: network calls, filesystem, external services, time/date
|
|
42
|
+
// Keep real: domain logic, internal utilities, business rules
|
|
60
43
|
```
|
|
61
44
|
|
|
62
|
-
|
|
63
|
-
// GOOD: Mock only external boundaries
|
|
64
|
-
// Keep real implementations for:
|
|
65
|
-
// - Domain logic
|
|
66
|
-
// - Internal utilities
|
|
67
|
-
// - Business rules
|
|
68
|
-
|
|
69
|
-
// Mock only:
|
|
70
|
-
// - Network calls
|
|
71
|
-
// - File system
|
|
72
|
-
// - External services
|
|
73
|
-
// - Time/date
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Decision Matrix
|
|
45
|
+
## Mock Decision
|
|
77
46
|
|
|
78
|
-
|
|
|
79
|
-
|
|
80
|
-
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
|
|
|
84
|
-
|
|
|
47
|
+
| Dependency | Mock? |
|
|
48
|
+
|------------|-------|
|
|
49
|
+
| Network / external API | Yes |
|
|
50
|
+
| File system | Yes |
|
|
51
|
+
| Time / date | Yes |
|
|
52
|
+
| Logger | No — use real |
|
|
53
|
+
| Domain logic | No |
|
|
54
|
+
| Your own services | No |
|
|
85
55
|
|
|
86
56
|
## Rules
|
|
87
57
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
5. **Test names describe behavior** - `shouldRejectInvalidEmail` not `testEmail`
|
|
58
|
+
- Test behavior, not implementation
|
|
59
|
+
- No test-only code in production classes
|
|
60
|
+
- Mock at external boundaries only
|
|
61
|
+
- Test names describe behavior: `rejectsInvalidEmail` not `testEmail`
|
|
93
62
|
|
|
94
63
|
## Red Flags
|
|
95
64
|
|
|
96
|
-
-
|
|
65
|
+
- More mock setup than assertions in test file
|
|
97
66
|
- Private methods exposed for testing
|
|
98
67
|
- Tests break on harmless refactors
|
|
99
|
-
- `toHaveBeenCalled` without
|
|
100
|
-
|
|
68
|
+
- `toHaveBeenCalled` without asserting the result
|
|
69
|
+
|
|
70
|
+
## References
|
|
71
|
+
|
|
72
|
+
- [Decision matrix](references/decision-matrix.md) — full mock decision table, naming conventions, AAA structure, smell → fix guide
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Testing Anti-Patterns — Decision Reference
|
|
2
|
+
|
|
3
|
+
## Mock Decision Matrix (expanded)
|
|
4
|
+
|
|
5
|
+
| Dependency | Mock in unit? | Mock in integration? | Reason |
|
|
6
|
+
|------------|:---:|:---:|--------|
|
|
7
|
+
| External HTTP API | ✅ | ❌ | External boundary |
|
|
8
|
+
| Database (real) | ✅ | ❌ | External boundary |
|
|
9
|
+
| File system | ✅ | context | Depends on test scope |
|
|
10
|
+
| Time / Date | ✅ | ✅ | Non-deterministic |
|
|
11
|
+
| Logger | ❌ | ❌ | No behavior, use real |
|
|
12
|
+
| Your own service class | ❌ | ❌ | You own it — test it |
|
|
13
|
+
| Domain logic | ❌ | ❌ | Core behavior |
|
|
14
|
+
| Config (env vars) | ❌ | ❌ | Use test env values |
|
|
15
|
+
| In-memory store | ❌ | ❌ | Fast, no reason to mock |
|
|
16
|
+
|
|
17
|
+
## Naming Convention
|
|
18
|
+
|
|
19
|
+
```js
|
|
20
|
+
// Bad — describes mechanics
|
|
21
|
+
test('testEmail')
|
|
22
|
+
test('checkValidation')
|
|
23
|
+
|
|
24
|
+
// Good — describes behavior
|
|
25
|
+
test('rejects email missing @ symbol')
|
|
26
|
+
test('returns 400 when name exceeds 255 chars')
|
|
27
|
+
test('does not create user when email already exists')
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Test Structure (Arrange-Act-Assert)
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
test('returns error when stock is zero', () => {
|
|
34
|
+
// Arrange
|
|
35
|
+
const product = { id: 1, stock: 0 };
|
|
36
|
+
|
|
37
|
+
// Act
|
|
38
|
+
const result = checkout(product, quantity=1);
|
|
39
|
+
|
|
40
|
+
// Assert
|
|
41
|
+
expect(result.error).toBe('OUT_OF_STOCK');
|
|
42
|
+
expect(result.charged).toBe(false);
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Smell → Fix Reference
|
|
47
|
+
|
|
48
|
+
| Smell | Fix |
|
|
49
|
+
|-------|-----|
|
|
50
|
+
| 10+ lines of mock setup | Extract to fixture or factory |
|
|
51
|
+
| `beforeEach` with global mocks | Move to test-local setup |
|
|
52
|
+
| Testing private via `_method` | Test via public API |
|
|
53
|
+
| `toHaveBeenCalledWith` only | Add assertion on the real result |
|
|
54
|
+
| Mock chain 3 levels deep | Mock the boundary, not each call |
|
|
55
|
+
| Same test body repeated 5× | Parameterize with `test.each` |
|
|
@@ -1,129 +1,53 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: using-git-worktrees
|
|
3
|
-
description: Use when starting isolated development work. Creates isolated workspace on new branch
|
|
3
|
+
description: Use when starting isolated development work. Creates isolated workspace on new branch via bd worktree, prevents dirty-state conflicts.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
# Using Git Worktrees
|
|
6
|
+
# Using Git Worktrees
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
## Pre-conditions (verify before creating)
|
|
9
9
|
|
|
10
|
-
## When to Use
|
|
11
|
-
|
|
12
|
-
- Starting new feature branch
|
|
13
|
-
- Parallel development work
|
|
14
|
-
- Isolated experimentation
|
|
15
|
-
- Hotfix development
|
|
16
|
-
|
|
17
|
-
## Directory Selection Priority
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
1. .worktrees/ (preferred hidden directory)
|
|
21
|
-
2. worktrees/ (visible alternative)
|
|
22
|
-
3. Check CLAUDE.md (project preference)
|
|
23
|
-
4. Ask user (if unclear)
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Workflow
|
|
27
|
-
|
|
28
|
-
### 1. Verify Pre-conditions
|
|
29
10
|
```bash
|
|
30
|
-
#
|
|
31
|
-
git
|
|
32
|
-
|
|
33
|
-
# Check for uncommitted changes
|
|
34
|
-
git status --porcelain
|
|
35
|
-
|
|
36
|
-
# Check .gitignore exists
|
|
37
|
-
test -f .gitignore && echo "exists"
|
|
11
|
+
git rev-parse --is-inside-work-tree # must be inside a repo
|
|
12
|
+
git status --porcelain # must be clean — no uncommitted changes
|
|
38
13
|
```
|
|
39
14
|
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
# Choose directory
|
|
43
|
-
WORKTREE_DIR=".worktrees"
|
|
15
|
+
## Create Worktree
|
|
44
16
|
|
|
45
|
-
# Create branch and worktree
|
|
46
|
-
git worktree add -b <branch-name> ${WORKTREE_DIR}/<branch-name>
|
|
47
|
-
```
|
|
48
|
-
|
|
49
|
-
### 3. Verify Setup
|
|
50
17
|
```bash
|
|
51
|
-
#
|
|
52
|
-
|
|
18
|
+
# Preferred: use bd (shares .beads/ database automatically)
|
|
19
|
+
bd worktree create <issue-id>-<desc> --branch <type>/<issue-id>-<desc>
|
|
53
20
|
|
|
54
|
-
#
|
|
55
|
-
|
|
21
|
+
# Fallback: raw git
|
|
22
|
+
git worktree add -b <branch> .worktrees/<branch>
|
|
56
23
|
```
|
|
57
24
|
|
|
58
|
-
|
|
59
|
-
```bash
|
|
60
|
-
# Enter worktree
|
|
61
|
-
cd ${WORKTREE_DIR}/<branch-name>
|
|
62
|
-
|
|
63
|
-
# Install dependencies
|
|
64
|
-
npm install # or appropriate package manager
|
|
25
|
+
## Branch Naming
|
|
65
26
|
|
|
66
|
-
# Run baseline tests
|
|
67
|
-
npm test
|
|
68
27
|
```
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
```
|
|
73
|
-
project-root/
|
|
74
|
-
├── .git/
|
|
75
|
-
├── .worktrees/
|
|
76
|
-
│ ├── feature-a/
|
|
77
|
-
│ ├── feature-b/
|
|
78
|
-
│ └── hotfix-123/
|
|
79
|
-
├── src/
|
|
80
|
-
└── ...
|
|
28
|
+
feature/<id>-<desc> fix/<id>-<desc> hotfix/<id>-<desc>
|
|
29
|
+
refactor/<id>-<desc> experiment/<id>-<desc>
|
|
81
30
|
```
|
|
82
31
|
|
|
83
|
-
##
|
|
32
|
+
## After Creating
|
|
84
33
|
|
|
34
|
+
```bash
|
|
35
|
+
cd .worktrees/<branch>
|
|
36
|
+
npm install # install deps
|
|
37
|
+
npm test # run baseline — must pass before any changes
|
|
85
38
|
```
|
|
86
|
-
feature/[description] # New features
|
|
87
|
-
fix/[description] # Bug fixes
|
|
88
|
-
hotfix/[description] # Urgent fixes
|
|
89
|
-
refactor/[description] # Code improvements
|
|
90
|
-
experiment/[description] # Exploration
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Commands Reference
|
|
94
|
-
|
|
95
|
-
| Command | Purpose |
|
|
96
|
-
|---------|---------|
|
|
97
|
-
| `git worktree add -b branch path` | Create new worktree with branch |
|
|
98
|
-
| `git worktree list` | List all worktrees |
|
|
99
|
-
| `git worktree remove path` | Remove worktree |
|
|
100
|
-
| `git worktree prune` | Clean up stale entries |
|
|
101
|
-
|
|
102
|
-
## Safety Checks
|
|
103
|
-
|
|
104
|
-
- [ ] Git repository confirmed
|
|
105
|
-
- [ ] No uncommitted changes
|
|
106
|
-
- [ ] .gitignore present
|
|
107
|
-
- [ ] Baseline tests pass
|
|
108
|
-
- [ ] Branch name follows convention
|
|
109
|
-
|
|
110
|
-
## Anti-Patterns
|
|
111
|
-
|
|
112
|
-
- Creating worktree with dirty state
|
|
113
|
-
- Not verifying .gitignore
|
|
114
|
-
- Skipping baseline tests
|
|
115
|
-
- Using unclear branch names
|
|
116
39
|
|
|
117
40
|
## Cleanup
|
|
118
41
|
|
|
119
|
-
When done with worktree:
|
|
120
42
|
```bash
|
|
121
|
-
#
|
|
122
|
-
git worktree
|
|
43
|
+
bd worktree remove <name> # preferred (cleans .beads redirect)
|
|
44
|
+
git worktree prune # clean stale refs
|
|
45
|
+
git branch -d <branch> # only after confirmed merge
|
|
46
|
+
```
|
|
123
47
|
|
|
124
|
-
|
|
125
|
-
git branch -d <branch-name>
|
|
48
|
+
## Red Flags
|
|
126
49
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
50
|
+
- Creating worktree with uncommitted changes
|
|
51
|
+
- Skipping baseline test run
|
|
52
|
+
- Using raw `git worktree add` without `bd` (loses beads database link)
|
|
53
|
+
- Unclear branch names
|