@runecraft/grimoire 1.0.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 +21 -0
- package/catalog.json +9 -0
- package/dist/grimoire.js +1758 -0
- package/package.json +54 -0
- package/references/definition-of-done.md +67 -0
- package/references/testing-patterns.md +260 -0
- package/skills/code-review-and-quality/README.md +13 -0
- package/skills/code-review-and-quality/SKILL.md +389 -0
- package/skills/code-simplification/README.md +13 -0
- package/skills/code-simplification/SKILL.md +338 -0
- package/skills/debugging-and-error-recovery/README.md +13 -0
- package/skills/debugging-and-error-recovery/SKILL.md +343 -0
- package/skills/debugging-and-error-recovery/scripts/__pycache__/triage_state.cpython-314.pyc +0 -0
- package/skills/debugging-and-error-recovery/scripts/triage_state.py +206 -0
- package/skills/deprecation-and-migration/README.md +13 -0
- package/skills/deprecation-and-migration/SKILL.md +248 -0
- package/skills/deprecation-and-migration/scripts/__pycache__/migration_tracker.cpython-314.pyc +0 -0
- package/skills/deprecation-and-migration/scripts/migration_tracker.py +237 -0
- package/skills/doubt-driven-development/README.md +13 -0
- package/skills/doubt-driven-development/SKILL.md +251 -0
- package/skills/git-commit-learning/.skill-meta.json +14 -0
- package/skills/git-commit-learning/README.md +205 -0
- package/skills/git-commit-learning/SKILL.md +435 -0
- package/skills/git-commit-learning/references/commit-patterns.md +595 -0
- package/skills/git-worktree/README.md +13 -0
- package/skills/git-worktree/SKILL.md +220 -0
- package/skills/idea-refine/README.md +13 -0
- package/skills/idea-refine/SKILL.md +186 -0
- package/skills/interview-me/README.md +13 -0
- package/skills/interview-me/SKILL.md +233 -0
- package/skills/linkedin-audit/SKILL.md +98 -0
- package/skills/linkedin-audit/references/dashboard-spec.md +43 -0
- package/skills/memory-management/README.md +13 -0
- package/skills/memory-management/SKILL.md +198 -0
- package/skills/security-and-hardening/README.md +13 -0
- package/skills/security-and-hardening/SKILL.md +472 -0
- package/skills/shipping-and-launch/README.md +13 -0
- package/skills/shipping-and-launch/SKILL.md +317 -0
- package/skills/skill-forge/README.md +153 -0
- package/skills/skill-forge/SKILL.md +291 -0
- package/skills/skill-forge/assets/SKILL.template.md +73 -0
- package/skills/skill-forge/references/authoring-patterns.md +249 -0
- package/skills/skill-forge/references/description-optimization.md +171 -0
- package/skills/skill-forge/references/output-evaluation.md +276 -0
- package/skills/skill-forge/references/scripts-guide.md +232 -0
- package/skills/skill-forge/references/spec.md +175 -0
- package/skills/skill-forge/scripts/validate.py +536 -0
- package/skills/spec-driven/.skill-meta.json +14 -0
- package/skills/spec-driven/README.md +335 -0
- package/skills/spec-driven/SKILL.md +174 -0
- package/skills/spec-driven/references/code-analysis.md +98 -0
- package/skills/spec-driven/references/coding-principles.md +56 -0
- package/skills/spec-driven/references/context-limits.md +31 -0
- package/skills/spec-driven/references/design.md +199 -0
- package/skills/spec-driven/references/discuss.md +136 -0
- package/skills/spec-driven/references/implement.md +425 -0
- package/skills/spec-driven/references/lessons.md +113 -0
- package/skills/spec-driven/references/memory.md +126 -0
- package/skills/spec-driven/references/specify.md +210 -0
- package/skills/spec-driven/references/sub-agents.md +96 -0
- package/skills/spec-driven/references/tasks.md +484 -0
- package/skills/spec-driven/references/validate.md +350 -0
- package/skills/spec-driven/scripts/__pycache__/lessons.cpython-314.pyc +0 -0
- package/skills/spec-driven/scripts/lessons.py +370 -0
- package/skills/spec-loop/README.md +36 -0
- package/skills/spec-loop/SKILL.md +61 -0
- package/skills/test-driven-development/README.md +13 -0
- package/skills/test-driven-development/SKILL.md +388 -0
- package/skills/typescript-patterns/README.md +13 -0
- package/skills/typescript-patterns/SKILL.md +346 -0
- package/skills/using-agent-skills/README.md +13 -0
- package/skills/using-agent-skills/SKILL.md +187 -0
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@runecraft/grimoire",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Interactive catalog and installer for agent skills",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"engines": {
|
|
8
|
+
"node": ">=20.12.0"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"bin": {
|
|
14
|
+
"grimoire": "dist/grimoire.js"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"skills/",
|
|
18
|
+
"references/",
|
|
19
|
+
"dist/",
|
|
20
|
+
"catalog.json"
|
|
21
|
+
],
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "rm -rf dist && bun build src/index.ts --target=node --format=esm --outfile dist/grimoire.js && chmod +x dist/grimoire.js",
|
|
24
|
+
"dev": "bun run src/index.ts",
|
|
25
|
+
"lint": "bun run typecheck",
|
|
26
|
+
"test": "bun test",
|
|
27
|
+
"typecheck": "tsc --noEmit",
|
|
28
|
+
"prepack": "bun run build",
|
|
29
|
+
"prepublishOnly": "bun run build"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"grimoire",
|
|
33
|
+
"agent",
|
|
34
|
+
"skills",
|
|
35
|
+
"prompts",
|
|
36
|
+
"ai",
|
|
37
|
+
"coding-agent",
|
|
38
|
+
"claude",
|
|
39
|
+
"codex",
|
|
40
|
+
"opencode",
|
|
41
|
+
"copilot",
|
|
42
|
+
"installer",
|
|
43
|
+
"cli"
|
|
44
|
+
],
|
|
45
|
+
"dependencies": {
|
|
46
|
+
"@clack/prompts": "^1.7.0",
|
|
47
|
+
"picocolors": "^1.1.1"
|
|
48
|
+
},
|
|
49
|
+
"devDependencies": {
|
|
50
|
+
"@types/bun": "^1.3.14",
|
|
51
|
+
"@types/node": "^26.2.0",
|
|
52
|
+
"typescript": "^7.0.2"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Definition of Done
|
|
2
|
+
|
|
3
|
+
A standing, project-wide bar that every change must clear before it counts as done. Unlike acceptance criteria, which vary per task and answer "did we build the right thing?", the Definition of Done is the same every time and answers "is this finished to our standard?". Use it as the final gate in `spec-driven` and `shipping-and-launch`.
|
|
4
|
+
|
|
5
|
+
## Definition of Done vs. Acceptance Criteria
|
|
6
|
+
|
|
7
|
+
| | Acceptance Criteria | Definition of Done |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| Scope | Specific to one task or spec | Applies to every increment |
|
|
10
|
+
| Changes | Different for each item | Fixed and reused |
|
|
11
|
+
| Answers | "Did we build *this thing*?" | "Is it *ready*?" |
|
|
12
|
+
| Owner | Defined when planning the task | Defined once for the project |
|
|
13
|
+
| Example | "User can reset password via email link" | "Tests pass, no regressions, docs updated" |
|
|
14
|
+
|
|
15
|
+
The two are complementary. A task is done only when **its** acceptance criteria are met **and** the standing Definition of Done is satisfied. Skipping either leaves work that looks finished but is not.
|
|
16
|
+
|
|
17
|
+
## The Standing Checklist
|
|
18
|
+
|
|
19
|
+
Apply this to every change before declaring it done.
|
|
20
|
+
|
|
21
|
+
### Correctness
|
|
22
|
+
- [ ] All acceptance criteria for the task are met
|
|
23
|
+
- [ ] Code runs and behaves as intended, verified at runtime, not just compiled or typechecked
|
|
24
|
+
- [ ] New behavior is covered by tests that fail without the change and pass with it
|
|
25
|
+
- [ ] Existing tests still pass; no regressions introduced
|
|
26
|
+
- [ ] Edge cases and error paths are handled, not just the happy path
|
|
27
|
+
|
|
28
|
+
### Quality
|
|
29
|
+
- [ ] Code reveals intent through naming and structure; no comments needed to explain *what* it does
|
|
30
|
+
- [ ] No duplicated business logic
|
|
31
|
+
- [ ] No dead code, debug output, or commented-out blocks left behind
|
|
32
|
+
- [ ] Changes are scoped to the task; no unrelated refactors snuck in
|
|
33
|
+
- [ ] Linting and formatting pass
|
|
34
|
+
|
|
35
|
+
The depth behind these items lives in `code-review-and-quality` (the five-axis review) and `code-simplification` (reducing complexity without changing behavior).
|
|
36
|
+
|
|
37
|
+
### Integration
|
|
38
|
+
- [ ] Change works with the rest of the system, not just in isolation
|
|
39
|
+
- [ ] Database migrations, config changes, and feature flags are accounted for
|
|
40
|
+
- [ ] Backward compatibility considered for any public interface or API change
|
|
41
|
+
|
|
42
|
+
### Documentation
|
|
43
|
+
- [ ] Public interfaces, APIs, and user-facing behavior are documented
|
|
44
|
+
- [ ] Architectural decisions worth preserving are recorded
|
|
45
|
+
- [ ] Documentation describes the current state in timeless language, not the change history
|
|
46
|
+
|
|
47
|
+
### Ship-readiness
|
|
48
|
+
- [ ] Security implications reviewed for any untrusted input, auth, or data handling (see `security-and-hardening`)
|
|
49
|
+
- [ ] Observability in place for new critical paths (logs, metrics, traces)
|
|
50
|
+
- [ ] Rollback path exists for anything risky (see `shipping-and-launch`)
|
|
51
|
+
- [ ] The human has reviewed and approved before merge or deploy
|
|
52
|
+
|
|
53
|
+
## How to Apply
|
|
54
|
+
|
|
55
|
+
- **Per task**: confirm the Correctness and Quality sections before checking the task off.
|
|
56
|
+
- **Per feature**: confirm Integration and Documentation before considering the feature complete.
|
|
57
|
+
- **Per release**: the full checklist is the floor; `shipping-and-launch` adds the deploy-specific gates on top.
|
|
58
|
+
|
|
59
|
+
Tailor the list to the project once, then reuse it unchanged. A Definition of Done that is renegotiated every sprint is not a Definition of Done.
|
|
60
|
+
|
|
61
|
+
## Red Flags
|
|
62
|
+
|
|
63
|
+
- "It's done, I just haven't run it yet": unverified work is not done.
|
|
64
|
+
- "Tests pass" used as a synonym for done while docs, regressions, or runtime verification are skipped.
|
|
65
|
+
- A different bar applied depending on deadline pressure.
|
|
66
|
+
- Acceptance criteria treated as the whole bar, with no standing quality floor.
|
|
67
|
+
- "Done" declared before human review on changes that need it.
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
# Testing Patterns Reference
|
|
2
|
+
|
|
3
|
+
Quick reference for common testing patterns across the stack. Use alongside the `test-driven-development` skill.
|
|
4
|
+
|
|
5
|
+
## Test Pyramid (80/15/5)
|
|
6
|
+
|
|
7
|
+
Target distribution for a healthy suite:
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
/\
|
|
11
|
+
/ \ E2E ~5% (slow, brittle, high signal)
|
|
12
|
+
/----\
|
|
13
|
+
/ \ Integration ~15% (contract-level, balanced)
|
|
14
|
+
/--------\
|
|
15
|
+
/ \ Unit ~80% (fast, focused, cheap)
|
|
16
|
+
/------------\
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
- **80% unit** — pure functions, single behavior, milliseconds
|
|
20
|
+
- **15% integration** — module boundaries, contracts between collaborators
|
|
21
|
+
- **5% E2E** — critical user journeys only; every E2E test is expensive
|
|
22
|
+
|
|
23
|
+
## Beyonce Rule
|
|
24
|
+
|
|
25
|
+
> "If you liked it then you should've put a test on it."
|
|
26
|
+
|
|
27
|
+
Every shipped behavior needs a regression test. "We'll add tests later" is a known failure mode — the gap is rarely closed, and the next change touches untested code. New behavior without a test is unfinished work, not done work.
|
|
28
|
+
|
|
29
|
+
## Table of Contents
|
|
30
|
+
|
|
31
|
+
- [Test Structure (Arrange-Act-Assert)](#test-structure-arrange-act-assert)
|
|
32
|
+
- [Test Naming Conventions](#test-naming-conventions)
|
|
33
|
+
- [Common Assertions](#common-assertions)
|
|
34
|
+
- [Mocking Patterns](#mocking-patterns)
|
|
35
|
+
- [React/Component Testing](#reactcomponent-testing)
|
|
36
|
+
- [API / Integration Testing](#api--integration-testing)
|
|
37
|
+
- [E2E Testing (Playwright)](#e2e-testing-playwright)
|
|
38
|
+
- [Test Anti-Patterns](#test-anti-patterns)
|
|
39
|
+
|
|
40
|
+
## Test Structure (Arrange-Act-Assert)
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
it('describes expected behavior', () => {
|
|
44
|
+
// Arrange: Set up test data and preconditions
|
|
45
|
+
const input = { title: 'Test Task', priority: 'high' };
|
|
46
|
+
|
|
47
|
+
// Act: Perform the action being tested
|
|
48
|
+
const result = createTask(input);
|
|
49
|
+
|
|
50
|
+
// Assert: Verify the outcome
|
|
51
|
+
expect(result.title).toBe('Test Task');
|
|
52
|
+
expect(result.priority).toBe('high');
|
|
53
|
+
expect(result.status).toBe('pending');
|
|
54
|
+
});
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Test Naming Conventions
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
// Pattern: [unit] [expected behavior] [condition]
|
|
61
|
+
describe('TaskService.createTask', () => {
|
|
62
|
+
it('creates a task with default pending status', () => {});
|
|
63
|
+
it('throws ValidationError when title is empty', () => {});
|
|
64
|
+
it('trims whitespace from title', () => {});
|
|
65
|
+
it('generates a unique ID for each task', () => {});
|
|
66
|
+
});
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Common Assertions
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
// Equality
|
|
73
|
+
expect(result).toBe(expected); // Strict equality (===)
|
|
74
|
+
expect(result).toEqual(expected); // Deep equality (objects/arrays)
|
|
75
|
+
expect(result).toStrictEqual(expected); // Deep equality + type matching
|
|
76
|
+
|
|
77
|
+
// Truthiness
|
|
78
|
+
expect(result).toBeTruthy();
|
|
79
|
+
expect(result).toBeFalsy();
|
|
80
|
+
expect(result).toBeNull();
|
|
81
|
+
expect(result).toBeDefined();
|
|
82
|
+
expect(result).toBeUndefined();
|
|
83
|
+
|
|
84
|
+
// Numbers
|
|
85
|
+
expect(result).toBeGreaterThan(5);
|
|
86
|
+
expect(result).toBeLessThanOrEqual(10);
|
|
87
|
+
expect(result).toBeCloseTo(0.3, 5); // Floating point
|
|
88
|
+
|
|
89
|
+
// Strings
|
|
90
|
+
expect(result).toMatch(/pattern/);
|
|
91
|
+
expect(result).toContain('substring');
|
|
92
|
+
|
|
93
|
+
// Arrays / Objects
|
|
94
|
+
expect(array).toContain(item);
|
|
95
|
+
expect(array).toHaveLength(3);
|
|
96
|
+
expect(object).toHaveProperty('key', 'value');
|
|
97
|
+
|
|
98
|
+
// Errors
|
|
99
|
+
expect(() => fn()).toThrow();
|
|
100
|
+
expect(() => fn()).toThrow(ValidationError);
|
|
101
|
+
expect(() => fn()).toThrow('specific message');
|
|
102
|
+
|
|
103
|
+
// Async
|
|
104
|
+
await expect(asyncFn()).resolves.toBe(value);
|
|
105
|
+
await expect(asyncFn()).rejects.toThrow(Error);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Mocking Patterns
|
|
109
|
+
|
|
110
|
+
### Mock Functions
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
const mockFn = jest.fn();
|
|
114
|
+
mockFn.mockReturnValue(42);
|
|
115
|
+
mockFn.mockResolvedValue({ data: 'test' });
|
|
116
|
+
mockFn.mockImplementation((x) => x * 2);
|
|
117
|
+
|
|
118
|
+
expect(mockFn).toHaveBeenCalled();
|
|
119
|
+
expect(mockFn).toHaveBeenCalledWith('arg1', 'arg2');
|
|
120
|
+
expect(mockFn).toHaveBeenCalledTimes(3);
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Mock Modules
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// Mock an entire module
|
|
127
|
+
jest.mock('./database', () => ({
|
|
128
|
+
query: jest.fn().mockResolvedValue([{ id: 1, title: 'Test' }]),
|
|
129
|
+
}));
|
|
130
|
+
|
|
131
|
+
// Mock specific exports
|
|
132
|
+
jest.mock('./utils', () => ({
|
|
133
|
+
...jest.requireActual('./utils'),
|
|
134
|
+
generateId: jest.fn().mockReturnValue('test-id'),
|
|
135
|
+
}));
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### Mock at Boundaries Only
|
|
139
|
+
|
|
140
|
+
```
|
|
141
|
+
Mock these: Don't mock these:
|
|
142
|
+
├── Database calls ├── Internal utility functions
|
|
143
|
+
├── HTTP requests ├── Business logic
|
|
144
|
+
├── File system operations ├── Data transformations
|
|
145
|
+
├── External API calls ├── Validation functions
|
|
146
|
+
└── Time/Date (when needed) └── Pure functions
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## React/Component Testing
|
|
150
|
+
|
|
151
|
+
```tsx
|
|
152
|
+
import { render, screen, fireEvent, waitFor } from '@testing-library/react';
|
|
153
|
+
|
|
154
|
+
describe('TaskForm', () => {
|
|
155
|
+
it('submits the form with entered data', async () => {
|
|
156
|
+
const onSubmit = jest.fn();
|
|
157
|
+
render(<TaskForm onSubmit={onSubmit} />);
|
|
158
|
+
|
|
159
|
+
// Find elements by accessible role/label (not test IDs)
|
|
160
|
+
await screen.findByRole('textbox', { name: /title/i });
|
|
161
|
+
fireEvent.change(screen.getByRole('textbox', { name: /title/i }), {
|
|
162
|
+
target: { value: 'New Task' },
|
|
163
|
+
});
|
|
164
|
+
fireEvent.click(screen.getByRole('button', { name: /create/i }));
|
|
165
|
+
|
|
166
|
+
await waitFor(() => {
|
|
167
|
+
expect(onSubmit).toHaveBeenCalledWith({ title: 'New Task' });
|
|
168
|
+
});
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
it('shows validation error for empty title', async () => {
|
|
172
|
+
render(<TaskForm onSubmit={jest.fn()} />);
|
|
173
|
+
|
|
174
|
+
fireEvent.click(screen.getByRole('button', { name: /create/i }));
|
|
175
|
+
|
|
176
|
+
expect(await screen.findByText(/title is required/i)).toBeInTheDocument();
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
## API / Integration Testing
|
|
182
|
+
|
|
183
|
+
```typescript
|
|
184
|
+
import request from 'supertest';
|
|
185
|
+
import { app } from '../src/app';
|
|
186
|
+
|
|
187
|
+
describe('POST /api/tasks', () => {
|
|
188
|
+
it('creates a task and returns 201', async () => {
|
|
189
|
+
const response = await request(app)
|
|
190
|
+
.post('/api/tasks')
|
|
191
|
+
.send({ title: 'Test Task' })
|
|
192
|
+
.set('Authorization', `Bearer ${testToken}`)
|
|
193
|
+
.expect(201);
|
|
194
|
+
|
|
195
|
+
expect(response.body).toMatchObject({
|
|
196
|
+
id: expect.any(String),
|
|
197
|
+
title: 'Test Task',
|
|
198
|
+
status: 'pending',
|
|
199
|
+
});
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it('returns 422 for invalid input', async () => {
|
|
203
|
+
const response = await request(app)
|
|
204
|
+
.post('/api/tasks')
|
|
205
|
+
.send({ title: '' })
|
|
206
|
+
.set('Authorization', `Bearer ${testToken}`)
|
|
207
|
+
.expect(422);
|
|
208
|
+
|
|
209
|
+
expect(response.body.error.code).toBe('VALIDATION_ERROR');
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
it('returns 401 without authentication', async () => {
|
|
213
|
+
await request(app)
|
|
214
|
+
.post('/api/tasks')
|
|
215
|
+
.send({ title: 'Test' })
|
|
216
|
+
.expect(401);
|
|
217
|
+
});
|
|
218
|
+
});
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
## E2E Testing (Playwright)
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
import { test, expect } from '@playwright/test';
|
|
225
|
+
|
|
226
|
+
test('user can create and complete a task', async ({ page }) => {
|
|
227
|
+
// Navigate and authenticate
|
|
228
|
+
await page.goto('/');
|
|
229
|
+
await page.fill('[name="email"]', 'test@example.com');
|
|
230
|
+
await page.fill('[name="password"]', 'testpass123');
|
|
231
|
+
await page.click('button:has-text("Log in")');
|
|
232
|
+
|
|
233
|
+
// Create a task
|
|
234
|
+
await page.click('button:has-text("New Task")');
|
|
235
|
+
await page.fill('[name="title"]', 'Buy groceries');
|
|
236
|
+
await page.click('button:has-text("Create")');
|
|
237
|
+
|
|
238
|
+
// Verify task appears
|
|
239
|
+
await expect(page.locator('text=Buy groceries')).toBeVisible();
|
|
240
|
+
|
|
241
|
+
// Complete the task
|
|
242
|
+
await page.click('[aria-label="Complete Buy groceries"]');
|
|
243
|
+
await expect(page.locator('text=Buy groceries')).toHaveCSS(
|
|
244
|
+
'text-decoration-line', 'line-through'
|
|
245
|
+
);
|
|
246
|
+
});
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## Test Anti-Patterns
|
|
250
|
+
|
|
251
|
+
| Anti-Pattern | Problem | Better Approach |
|
|
252
|
+
|---|---|---|
|
|
253
|
+
| Testing implementation details | Breaks on refactor | Test inputs/outputs |
|
|
254
|
+
| Snapshot everything | No one reviews snapshot diffs | Assert specific values |
|
|
255
|
+
| Shared mutable state | Tests pollute each other | Setup/teardown per test |
|
|
256
|
+
| Testing third-party code | Wastes time, not your bug | Mock the boundary |
|
|
257
|
+
| Skipping tests to pass CI | Hides real bugs | Fix or delete the test |
|
|
258
|
+
| Using `test.skip` permanently | Dead code | Remove or fix it |
|
|
259
|
+
| Overly broad assertions | Doesn't catch regressions | Be specific |
|
|
260
|
+
| No async error handling | Swallowed errors, false passes | Always `await` async tests |
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# code-review-and-quality
|
|
2
|
+
|
|
3
|
+
Multi-axis code review (correctness, readability, architecture, security, performance) with severity labels (Blocker, Required, Optional, Nit, FYI).
|
|
4
|
+
|
|
5
|
+
| Field | Value |
|
|
6
|
+
|-------|-------|
|
|
7
|
+
| Version | 1.0.0 |
|
|
8
|
+
| Trigger | `/review`, "code review", "PR review", "merge gate", "five-axis review" |
|
|
9
|
+
| PT trigger | `/revisar`, "revisão de código", "revisão de PR" |
|
|
10
|
+
|
|
11
|
+
**Do not use for** in-flight decisions on non-trivial work (that's `/harden`), single-line typo fixes, or when the user explicitly skips review.
|
|
12
|
+
|
|
13
|
+
See [SKILL.md](SKILL.md) for the full process.
|