eslint-plugin-code-style 2.0.0 → 2.0.2
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/README.md +5 -3
- package/dist/index.js +244 -244
- package/package.json +1 -5
- package/AGENTS.md +0 -1387
- package/CHANGELOG.md +0 -2087
- package/CLAUDE.md +0 -12
- package/docs/rules/README.md +0 -31
- package/docs/rules/arrays.md +0 -107
- package/docs/rules/arrow-functions.md +0 -115
- package/docs/rules/call-expressions.md +0 -275
- package/docs/rules/classes.md +0 -88
- package/docs/rules/comments.md +0 -42
- package/docs/rules/components.md +0 -330
- package/docs/rules/control-flow.md +0 -448
- package/docs/rules/functions.md +0 -232
- package/docs/rules/hooks.md +0 -147
- package/docs/rules/imports-exports.md +0 -383
- package/docs/rules/jsx.md +0 -518
- package/docs/rules/objects.md +0 -224
- package/docs/rules/react.md +0 -175
- package/docs/rules/spacing.md +0 -61
- package/docs/rules/strings.md +0 -92
- package/docs/rules/typescript.md +0 -482
- package/docs/rules/variables.md +0 -32
package/AGENTS.md
DELETED
|
@@ -1,1387 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
Instructions for AI coding agents working with this codebase.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
**eslint-plugin-code-style** is an ESLint plugin providing 79 custom formatting rules (70 auto-fixable, 19 configurable, 9 report-only) for React/JSX projects. It's designed for ESLint v9+ flat config system.
|
|
8
|
-
|
|
9
|
-
- **Source code:** `src/` - Modular rule files organized by category
|
|
10
|
-
- **Built output:** `dist/index.js` - Bundled + minified (generated by esbuild, gitignored)
|
|
11
|
-
- **Type definitions:** `index.d.ts` - TypeScript declarations for IDE support
|
|
12
|
-
- **Recommended configs:** `recommended-configs/` - Ready-to-use ESLint configurations
|
|
13
|
-
- **Test apps:** `_tests_/` - Sample apps for testing rules
|
|
14
|
-
|
|
15
|
-
### Available Configurations
|
|
16
|
-
|
|
17
|
-
| Config | Recommended Folder | Test Folder | Status |
|
|
18
|
-
|--------|-------------------|-------------|--------|
|
|
19
|
-
| React (JS) | `recommended-configs/react/` | `_tests_/react/` | Available |
|
|
20
|
-
| React + TS + Tailwind | `recommended-configs/react-ts-tw/` | `_tests_/react-ts-tw/` | Available |
|
|
21
|
-
| React + TypeScript | `recommended-configs/react-ts/` | `_tests_/react-ts/` | Available |
|
|
22
|
-
| React + Tailwind | `recommended-configs/react-tw/` | `_tests_/react-tw/` | Available |
|
|
23
|
-
|
|
24
|
-
### Test Projects & Rule Compatibility
|
|
25
|
-
|
|
26
|
-
**IMPORTANT:** When adding/editing rules, they must be tested in ALL applicable test projects.
|
|
27
|
-
|
|
28
|
-
Each test project in `_tests_/` corresponds to a specific tech stack. Rules should ONLY be added to projects that support them:
|
|
29
|
-
|
|
30
|
-
| Rule Category | `react/` (JS only) | `react-ts-tw/` (TS + Tailwind) | `react-ts/` (TS) | `react-tw/` (TW) |
|
|
31
|
-
|---------------|:------------------:|:------------------------------:|:-------------------:|:-------------------:|
|
|
32
|
-
| **General rules** (arrays, functions, etc.) | ✅ | ✅ | ✅ | ✅ |
|
|
33
|
-
| **JSX/React rules** | ✅ | ✅ | ✅ | ✅ |
|
|
34
|
-
| **TypeScript rules** | ❌ | ✅ | ✅ | ❌ |
|
|
35
|
-
| **Tailwind rules** | ❌ | ✅ | ❌ | ✅ |
|
|
36
|
-
|
|
37
|
-
**TypeScript-only rules** (70 rules in JS projects, 79 in TS projects):
|
|
38
|
-
- `component-props-inline-type`
|
|
39
|
-
- `enum-format`
|
|
40
|
-
- `enum-type-enforcement`
|
|
41
|
-
- `interface-format`
|
|
42
|
-
- `no-inline-type-definitions`
|
|
43
|
-
- `prop-naming-convention`
|
|
44
|
-
- `type-annotation-spacing`
|
|
45
|
-
- `type-format`
|
|
46
|
-
- `typescript-definition-location`
|
|
47
|
-
|
|
48
|
-
**Tailwind-related rules** (work in all projects but most useful with Tailwind):
|
|
49
|
-
- `classname-dynamic-at-end` - Enforce dynamic expressions at end of className
|
|
50
|
-
- `classname-multiline` - Format long className strings with one class per line
|
|
51
|
-
- `classname-no-extra-spaces` - Remove extra/leading/trailing spaces in className
|
|
52
|
-
- `classname-order` - Enforce Tailwind CSS class ordering in variables, object properties, and return statements
|
|
53
|
-
|
|
54
|
-
> **Note:** `classname-order` complements the official `tailwindcss/classnames-order` plugin:
|
|
55
|
-
> - **`tailwindcss/classnames-order`** - Handles JSX `className` attributes directly
|
|
56
|
-
> - **`classname-order`** - Handles class strings in variables, object properties, and return statements (areas the Tailwind plugin doesn't cover)
|
|
57
|
-
>
|
|
58
|
-
> Both rules should be enabled together for complete Tailwind class ordering coverage.
|
|
59
|
-
|
|
60
|
-
**When adding a new test project:**
|
|
61
|
-
1. Create folder: `_tests_/<project-name>/`
|
|
62
|
-
2. Copy structure from similar existing project
|
|
63
|
-
3. Create `eslint.config.js` with appropriate rules for that stack
|
|
64
|
-
4. Add ALL applicable rules (skip rules for unsupported tech)
|
|
65
|
-
5. Update this table in AGENTS.md
|
|
66
|
-
6. Update "Available Configurations" table above
|
|
67
|
-
|
|
68
|
-
## Build & Test Commands
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
# Build (required before testing or publishing)
|
|
72
|
-
npm run build # Bundles src/ into dist/index.js via esbuild
|
|
73
|
-
|
|
74
|
-
# Test rules against a test app (e.g., react, react-ts, react-ts-tw)
|
|
75
|
-
cd _tests_/<config-name>
|
|
76
|
-
npm install
|
|
77
|
-
npm run lint # Check for errors
|
|
78
|
-
npm run lint:fix # Auto-fix issues
|
|
79
|
-
|
|
80
|
-
# Publish (from root folder only — run build first)
|
|
81
|
-
npm run build && npm publish
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Code Structure
|
|
85
|
-
|
|
86
|
-
Rules are organized in modular source files under `src/`:
|
|
87
|
-
|
|
88
|
-
```
|
|
89
|
-
src/
|
|
90
|
-
├── index.js — Entry point, imports all rules, exports plugin object
|
|
91
|
-
├── utils/
|
|
92
|
-
│ └── tailwind.js — Tailwind CSS class utilities (shared across classname-* rules)
|
|
93
|
-
└── rules/
|
|
94
|
-
├── arrays.js — 3 rules
|
|
95
|
-
├── arrow-functions.js — 4 rules
|
|
96
|
-
├── call-expressions.js — 6 rules
|
|
97
|
-
├── classes.js — 2 rules
|
|
98
|
-
├── comments.js — 1 rule
|
|
99
|
-
├── components.js — 6 rules
|
|
100
|
-
├── control-flow.js — 8 rules
|
|
101
|
-
├── functions.js — 6 rules
|
|
102
|
-
├── hooks.js — 3 rules
|
|
103
|
-
├── imports-exports.js — 8 rules
|
|
104
|
-
├── jsx.js — 14 rules
|
|
105
|
-
├── objects.js — 5 rules
|
|
106
|
-
├── react.js — 1 rule
|
|
107
|
-
├── spacing.js — 2 rules
|
|
108
|
-
├── strings.js — 1 rule
|
|
109
|
-
├── typescript.js — 8 rules
|
|
110
|
-
└── variables.js — 1 rule
|
|
111
|
-
dist/
|
|
112
|
-
└── index.js — Bundled + minified output (generated, gitignored)
|
|
113
|
-
```
|
|
114
|
-
|
|
115
|
-
The build step (`npm run build`) uses esbuild to bundle all source files into a single minified `dist/index.js`.
|
|
116
|
-
|
|
117
|
-
## Rule Implementation Pattern
|
|
118
|
-
|
|
119
|
-
Every rule follows this exact structure:
|
|
120
|
-
|
|
121
|
-
```javascript
|
|
122
|
-
/**
|
|
123
|
-
* ───────────────────────────────────────────────────────────────
|
|
124
|
-
* Rule: Rule Name Here
|
|
125
|
-
* ───────────────────────────────────────────────────────────────
|
|
126
|
-
*
|
|
127
|
-
* Description:
|
|
128
|
-
* Brief description of what the rule does.
|
|
129
|
-
*
|
|
130
|
-
* Options:
|
|
131
|
-
* { optionName: defaultValue } - Description of option
|
|
132
|
-
*
|
|
133
|
-
* ✓ Good:
|
|
134
|
-
* // Example of correct code
|
|
135
|
-
*
|
|
136
|
-
* ✗ Bad:
|
|
137
|
-
* // Example of incorrect code
|
|
138
|
-
*/
|
|
139
|
-
const ruleName = {
|
|
140
|
-
create(context) {
|
|
141
|
-
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
142
|
-
const options = context.options[0] || {};
|
|
143
|
-
const optionName = options.optionName !== undefined ? options.optionName : defaultValue;
|
|
144
|
-
|
|
145
|
-
return {
|
|
146
|
-
NodeType(node) {
|
|
147
|
-
// Rule logic here
|
|
148
|
-
|
|
149
|
-
// Report issues with auto-fix
|
|
150
|
-
context.report({
|
|
151
|
-
fix: (fixer) => fixer.replaceText(node, "fixed code"),
|
|
152
|
-
message: "Error message describing the issue",
|
|
153
|
-
node,
|
|
154
|
-
});
|
|
155
|
-
},
|
|
156
|
-
};
|
|
157
|
-
},
|
|
158
|
-
meta: {
|
|
159
|
-
docs: { description: "Short description for documentation" },
|
|
160
|
-
fixable: "code", // Required for auto-fix rules
|
|
161
|
-
schema: [
|
|
162
|
-
{
|
|
163
|
-
additionalProperties: false,
|
|
164
|
-
properties: {
|
|
165
|
-
optionName: {
|
|
166
|
-
default: 3,
|
|
167
|
-
description: "Option description",
|
|
168
|
-
minimum: 1,
|
|
169
|
-
type: "integer",
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
type: "object",
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
type: "layout", // "layout" for formatting, "suggestion" for conventions
|
|
176
|
-
},
|
|
177
|
-
};
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
### Adding a New Rule — Complete Checklist
|
|
181
|
-
|
|
182
|
-
**IMPORTANT:** Adding a new rule requires a **MINOR version bump** (e.g., 1.5.0 → 1.6.0).
|
|
183
|
-
|
|
184
|
-
When creating a new rule, ALL of the following files must be updated:
|
|
185
|
-
|
|
186
|
-
#### 1. `src/rules/<category>.js` — Rule Implementation
|
|
187
|
-
|
|
188
|
-
- [ ] Add rule to the appropriate category file in `src/rules/`
|
|
189
|
-
- [ ] Add the variable name to the file's `export { ... }` block
|
|
190
|
-
- [ ] Add JSDoc comment block with the standard format:
|
|
191
|
-
```javascript
|
|
192
|
-
/**
|
|
193
|
-
* ───────────────────────────────────────────────────────────────
|
|
194
|
-
* Rule: Rule Name Here
|
|
195
|
-
* ───────────────────────────────────────────────────────────────
|
|
196
|
-
*
|
|
197
|
-
* Description:
|
|
198
|
-
* Brief description of what the rule does.
|
|
199
|
-
*
|
|
200
|
-
* ✓ Good:
|
|
201
|
-
* // Example of correct code
|
|
202
|
-
*
|
|
203
|
-
* ✗ Bad:
|
|
204
|
-
* // Example of incorrect code
|
|
205
|
-
*/
|
|
206
|
-
```
|
|
207
|
-
- [ ] Add `const ruleName = { create(), meta: {} }` definition
|
|
208
|
-
- [ ] Include `fixable: "code"` or `fixable: "whitespace"` in meta if auto-fixable
|
|
209
|
-
- [ ] Import rule in `src/index.js` and add to `rules` object in default export (keep **alphabetical order**)
|
|
210
|
-
- [ ] Run `npm run build` to regenerate `dist/index.js`
|
|
211
|
-
|
|
212
|
-
#### 2. `index.d.ts` — TypeScript Types
|
|
213
|
-
|
|
214
|
-
- [ ] Add rule name to `RuleNames` type union (**alphabetically sorted**):
|
|
215
|
-
```typescript
|
|
216
|
-
| "code-style/new-rule-name"
|
|
217
|
-
```
|
|
218
|
-
- [ ] Add rule to `PluginRules` interface (**alphabetically sorted**):
|
|
219
|
-
```typescript
|
|
220
|
-
"new-rule-name": Rule.RuleModule;
|
|
221
|
-
```
|
|
222
|
-
|
|
223
|
-
#### 3. `README.md` — Main Documentation
|
|
224
|
-
|
|
225
|
-
> ⚠️ **IMPORTANT:** README.md has **three separate sections** that mention rules. When adding or editing a rule, you must update ALL relevant sections:
|
|
226
|
-
> - **Rule counts** (5 locations) — must match actual rule count
|
|
227
|
-
> - **Quick Start example** (~line 184) — alphabetically sorted configuration example
|
|
228
|
-
> - **Rules Summary table** — brief description with emoji indicators
|
|
229
|
-
>
|
|
230
|
-
> Missing any section will leave documentation inconsistent. Use the `audit-docs` skill to verify all sections are in sync.
|
|
231
|
-
|
|
232
|
-
**a) Update rule counts** (see [Rule Count Locations](#rule-count-locations) for all positions):
|
|
233
|
-
- [ ] Line ~22: `*XX rules (YY auto-fixable)*`
|
|
234
|
-
- [ ] Line ~30: `**XX custom rules** (YY auto-fixable)`
|
|
235
|
-
- [ ] Line ~39: `YY of XX rules support auto-fix`
|
|
236
|
-
- [ ] Line ~272: `**XX rules total** — YY with auto-fix`
|
|
237
|
-
- [ ] Line ~409: `YY of XX rules support auto-fixing`
|
|
238
|
-
|
|
239
|
-
**b) Add rule to Quick Start example** (~line 184, alphabetically sorted):
|
|
240
|
-
```javascript
|
|
241
|
-
"code-style/new-rule-name": "error",
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
**c) Add rule to Rules Summary table** (find the appropriate category):
|
|
245
|
-
```markdown
|
|
246
|
-
| `new-rule-name` | Brief description of what it does 🔧 |
|
|
247
|
-
```
|
|
248
|
-
- Add 🔧 emoji if auto-fixable
|
|
249
|
-
- Add ⚙️ emoji if has configurable options
|
|
250
|
-
|
|
251
|
-
#### 3b. `docs/rules/<category>.md` — Detailed Rule Documentation
|
|
252
|
-
|
|
253
|
-
Add detailed rule documentation to the appropriate category file in `docs/rules/`:
|
|
254
|
-
|
|
255
|
-
```markdown
|
|
256
|
-
### `new-rule-name`
|
|
257
|
-
|
|
258
|
-
**What it does:** One-line description of the rule's purpose.
|
|
259
|
-
|
|
260
|
-
**Why use it:** Context for why this rule is helpful (optional).
|
|
261
|
-
|
|
262
|
-
\`\`\`javascript
|
|
263
|
-
// ✅ Good — description of correct pattern
|
|
264
|
-
const example = "correct code";
|
|
265
|
-
|
|
266
|
-
// ✅ Good — another correct example
|
|
267
|
-
const another = "also correct";
|
|
268
|
-
|
|
269
|
-
// ❌ Bad — description of incorrect pattern
|
|
270
|
-
const example = "incorrect code";
|
|
271
|
-
|
|
272
|
-
// ❌ Bad — another incorrect example
|
|
273
|
-
const wrong = "also wrong";
|
|
274
|
-
\`\`\`
|
|
275
|
-
|
|
276
|
-
**Options:** (only if rule has options)
|
|
277
|
-
|
|
278
|
-
| Option | Type | Default | Description |
|
|
279
|
-
|--------|------|---------|-------------|
|
|
280
|
-
| `optionName` | `string` | `"value"` | What the option does |
|
|
281
|
-
|
|
282
|
-
\`\`\`javascript
|
|
283
|
-
// Configuration example
|
|
284
|
-
"code-style/new-rule-name": ["error", { optionName: "value" }]
|
|
285
|
-
\`\`\`
|
|
286
|
-
|
|
287
|
-
---
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
#### 4. `AGENTS.md` — Agent Instructions
|
|
291
|
-
|
|
292
|
-
- [ ] Update rule counts in [Rule Count Locations](#rule-count-locations) section (Current Counts table)
|
|
293
|
-
- [ ] Update all rule count references (see table in Rule Count Locations)
|
|
294
|
-
- [ ] Add rule to its category in [Rule Categories](#rule-categories) section
|
|
295
|
-
|
|
296
|
-
#### 5. Config Files — Add Rule to Configs
|
|
297
|
-
|
|
298
|
-
Add the rule (**alphabetically sorted**) to ALL config files:
|
|
299
|
-
|
|
300
|
-
- [ ] `recommended-configs/react-ts-tw/eslint.config.js`
|
|
301
|
-
- [ ] `recommended-configs/react/eslint.config.js` (skip if TypeScript-only rule)
|
|
302
|
-
- [ ] `_tests_/react-ts-tw/eslint.config.js`
|
|
303
|
-
- [ ] `_tests_/react/eslint.config.js` (skip if TypeScript-only rule)
|
|
304
|
-
|
|
305
|
-
**TypeScript-only rules** (only add to `-ts-tw` configs):
|
|
306
|
-
- `component-props-inline-type`, `enum-format`, `interface-format`
|
|
307
|
-
- `no-inline-type-definitions`, `type-annotation-spacing`, `type-format`
|
|
308
|
-
- `typescript-definition-location`
|
|
309
|
-
|
|
310
|
-
#### 6. Config READMEs — Update Rule Counts
|
|
311
|
-
|
|
312
|
-
- [ ] `recommended-configs/react-ts-tw/README.md` (~line 396)
|
|
313
|
-
- [ ] `recommended-configs/react/README.md` (~line 286)
|
|
314
|
-
|
|
315
|
-
#### 7. Version & Tag
|
|
316
|
-
|
|
317
|
-
- [ ] Update `package.json` version (MINOR bump: x.Y.0)
|
|
318
|
-
- [ ] Commit with message: `feat: add rule-name rule`
|
|
319
|
-
- [ ] Create tag: `git tag vX.Y.0`
|
|
320
|
-
|
|
321
|
-
#### 8. Testing the Rule
|
|
322
|
-
|
|
323
|
-
**IMPORTANT:** Every new rule MUST be tested before committing.
|
|
324
|
-
|
|
325
|
-
**a) Add examples to existing test project code:**
|
|
326
|
-
|
|
327
|
-
The test projects (`_tests_/react/`, `_tests_/react-ts-tw/`, etc.) contain real code (components, hooks, utils, etc.) that should naturally exercise all rules. When adding a new rule:
|
|
328
|
-
|
|
329
|
-
- Add code examples to **existing files** in the test project that are relevant to the rule
|
|
330
|
-
- For example: if adding an array rule, add array code to existing component files
|
|
331
|
-
- The test project code should cover ALL rules through its natural structure
|
|
332
|
-
|
|
333
|
-
```
|
|
334
|
-
_tests_/react-ts-tw/src/
|
|
335
|
-
├── app.tsx # Main app - exercises component rules
|
|
336
|
-
├── components/ # Components - exercises JSX, props rules
|
|
337
|
-
│ ├── button.tsx
|
|
338
|
-
│ └── card.tsx
|
|
339
|
-
├── hooks/ # Hooks - exercises hook rules
|
|
340
|
-
├── utils/ # Utils - exercises function rules
|
|
341
|
-
├── interfaces/ # Interfaces - exercises TS rules
|
|
342
|
-
└── types/ # Types - exercises type rules
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**b) Create temporary test file for quick verification:**
|
|
346
|
-
|
|
347
|
-
For quick testing during development, create a temporary test file:
|
|
348
|
-
|
|
349
|
-
```bash
|
|
350
|
-
# Create temp test file
|
|
351
|
-
_tests_/react-ts-tw/src/test-rule-name.tsx
|
|
352
|
-
```
|
|
353
|
-
|
|
354
|
-
```javascript
|
|
355
|
-
// Temporary test file: test-rule-name.tsx
|
|
356
|
-
|
|
357
|
-
// Test case 1: Should trigger error (BAD code)
|
|
358
|
-
const badExample = /* code that violates the rule */;
|
|
359
|
-
|
|
360
|
-
// Test case 2: Should NOT trigger error (GOOD code)
|
|
361
|
-
const goodExample = /* code that follows the rule */;
|
|
362
|
-
```
|
|
363
|
-
|
|
364
|
-
**c) Run the linter to verify:**
|
|
365
|
-
|
|
366
|
-
```bash
|
|
367
|
-
cd _tests_/react-ts-tw
|
|
368
|
-
|
|
369
|
-
# Check errors are reported for bad code
|
|
370
|
-
npx eslint src/test-rule-name.tsx
|
|
371
|
-
|
|
372
|
-
# Verify auto-fix works (if rule is fixable)
|
|
373
|
-
npx eslint src/test-rule-name.tsx --fix
|
|
374
|
-
cat src/test-rule-name.tsx # Verify fixed code is correct
|
|
375
|
-
|
|
376
|
-
# Also run on entire project to ensure no regressions
|
|
377
|
-
npx eslint src/
|
|
378
|
-
```
|
|
379
|
-
|
|
380
|
-
**d) Clean up temporary test file:**
|
|
381
|
-
|
|
382
|
-
```bash
|
|
383
|
-
rm _tests_/react-ts-tw/src/test-rule-name.tsx
|
|
384
|
-
rm _tests_/react/src/test-rule-name.jsx # if created
|
|
385
|
-
```
|
|
386
|
-
|
|
387
|
-
**e) Ensure test project code covers the new rule:**
|
|
388
|
-
|
|
389
|
-
After temporary testing, make sure the actual test project code (components, hooks, etc.) includes examples that exercise the new rule. This provides ongoing regression testing.
|
|
390
|
-
|
|
391
|
-
#### 9. Verification
|
|
392
|
-
|
|
393
|
-
Run these commands to verify all rules are in sync:
|
|
394
|
-
|
|
395
|
-
```bash
|
|
396
|
-
# Count rules in each location
|
|
397
|
-
grep -rc "^const [a-zA-Z]* = {$" src/rules/
|
|
398
|
-
grep -c 'code-style/' index.d.ts
|
|
399
|
-
grep -c '"code-style/' recommended-configs/react-ts-tw/eslint.config.js
|
|
400
|
-
|
|
401
|
-
# Find rules missing from README
|
|
402
|
-
grep -oE '"[a-z-]+":' src/index.js | tr -d '":' | sort > /tmp/a.txt
|
|
403
|
-
grep -oE '\`[a-z-]+\`' README.md | tr -d '\`' | sort | uniq > /tmp/b.txt
|
|
404
|
-
comm -23 /tmp/a.txt /tmp/b.txt
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
---
|
|
408
|
-
|
|
409
|
-
### Removing a Rule — Complete Checklist
|
|
410
|
-
|
|
411
|
-
**IMPORTANT:** Removing a rule is a **BREAKING CHANGE** requiring a **MAJOR version bump** (e.g., 1.6.0 → 2.0.0).
|
|
412
|
-
|
|
413
|
-
#### 1. `src/rules/<category>.js` + `src/index.js`
|
|
414
|
-
- [ ] Remove the rule's JSDoc comment block and `const` definition from category file
|
|
415
|
-
- [ ] Remove from the file's `export { ... }` block
|
|
416
|
-
- [ ] Remove import and `rules` object entry from `src/index.js`
|
|
417
|
-
- [ ] Run `npm run build` to regenerate `dist/index.js`
|
|
418
|
-
|
|
419
|
-
#### 2. `index.d.ts`
|
|
420
|
-
- [ ] Remove from `RuleNames` type union
|
|
421
|
-
- [ ] Remove from `PluginRules` interface
|
|
422
|
-
|
|
423
|
-
#### 3. `README.md` + `docs/rules/`
|
|
424
|
-
- [ ] Update all rule counts (see [Rule Count Locations](#rule-count-locations))
|
|
425
|
-
- [ ] Remove from `rules: {}` example in Quick Start
|
|
426
|
-
- [ ] Remove from Rules Summary table
|
|
427
|
-
- [ ] Remove detailed documentation from `docs/rules/<category>.md`
|
|
428
|
-
|
|
429
|
-
#### 4. `AGENTS.md`
|
|
430
|
-
- [ ] Update all rule counts
|
|
431
|
-
- [ ] Remove from Rule Categories section
|
|
432
|
-
|
|
433
|
-
#### 5. Config Files
|
|
434
|
-
- [ ] Remove from `recommended-configs/react-ts-tw/eslint.config.js`
|
|
435
|
-
- [ ] Remove from `recommended-configs/react/eslint.config.js`
|
|
436
|
-
- [ ] Remove from `_tests_/react-ts-tw/eslint.config.js`
|
|
437
|
-
- [ ] Remove from `_tests_/react/eslint.config.js`
|
|
438
|
-
|
|
439
|
-
#### 6. Config READMEs
|
|
440
|
-
- [ ] Update `recommended-configs/react-ts-tw/README.md`
|
|
441
|
-
- [ ] Update `recommended-configs/react/README.md`
|
|
442
|
-
|
|
443
|
-
#### 7. Version & Tag
|
|
444
|
-
- [ ] Update `package.json` version (MAJOR bump: X.0.0)
|
|
445
|
-
- [ ] Commit with message: `feat!: remove rule-name rule` (note the `!` for breaking change)
|
|
446
|
-
- [ ] Create tag: `git tag vX.0.0`
|
|
447
|
-
|
|
448
|
-
---
|
|
449
|
-
|
|
450
|
-
### Editing an Existing Rule — Checklist
|
|
451
|
-
|
|
452
|
-
When modifying an existing rule, check if these need updates:
|
|
453
|
-
|
|
454
|
-
> ⚠️ **Documentation Reminder:** If the rule's behavior, examples, or options change, update README.md (Quick Start example, Rules Summary table) and the detailed docs in `docs/rules/<category>.md`. See the note in "Adding a New Rule" section for details.
|
|
455
|
-
|
|
456
|
-
#### If fixing a bug (PATCH version: x.x.+1):
|
|
457
|
-
- [ ] Fix the issue in rule's `create()` function in `src/rules/<category>.js`
|
|
458
|
-
- [ ] Test in `_tests_/` apps with `npm run lint` and `npm run lint:fix`
|
|
459
|
-
- [ ] Commit: `fix: description of what was fixed in rule-name`
|
|
460
|
-
|
|
461
|
-
#### If changing rule behavior (PATCH or MINOR depending on scope):
|
|
462
|
-
- [ ] Update rule logic in `src/rules/<category>.js`
|
|
463
|
-
- [ ] Update JSDoc in source file (Good/Bad examples if they changed)
|
|
464
|
-
- [ ] Update `README.md` rule documentation section:
|
|
465
|
-
- Update "What it does" if behavior changed
|
|
466
|
-
- Update code examples (✅ Good / ❌ Bad) to reflect new behavior
|
|
467
|
-
- [ ] Test in `_tests_/` apps with `npm run lint` and `npm run lint:fix`
|
|
468
|
-
|
|
469
|
-
#### If adding new options (MINOR version: x.+1.0):
|
|
470
|
-
- [ ] Add option to `schema` in rule's `meta` object in `src/rules/<category>.js`
|
|
471
|
-
- [ ] Add option handling in `create()` function with default value:
|
|
472
|
-
```javascript
|
|
473
|
-
const options = context.options[0] || {};
|
|
474
|
-
const newOption = options.newOption !== undefined ? options.newOption : defaultValue;
|
|
475
|
-
```
|
|
476
|
-
- [ ] Update JSDoc Options section in source file
|
|
477
|
-
- [ ] Update README.md rule documentation:
|
|
478
|
-
- Add row to Options table
|
|
479
|
-
- Add configuration example showing the new option
|
|
480
|
-
|
|
481
|
-
#### If adding auto-fix to rule that didn't have it (MINOR version: x.+1.0):
|
|
482
|
-
- [ ] Add `fixable: "code"` or `fixable: "whitespace"` to rule's `meta` object
|
|
483
|
-
- [ ] Add `fix()` function in `context.report()`:
|
|
484
|
-
```javascript
|
|
485
|
-
context.report({
|
|
486
|
-
fix: (fixer) => fixer.replaceText(node, "fixed code"),
|
|
487
|
-
message: "Error message",
|
|
488
|
-
node,
|
|
489
|
-
});
|
|
490
|
-
```
|
|
491
|
-
- [ ] Update README.md Rules Summary table: add 🔧 emoji
|
|
492
|
-
- [ ] Update rule counts: increment auto-fixable count, decrement report-only count
|
|
493
|
-
- [ ] Test auto-fix with `npm run lint:fix`
|
|
494
|
-
|
|
495
|
-
#### If changing default values (MAJOR version: +1.0.0 — breaking change):
|
|
496
|
-
- [ ] Update default value in `create()` function
|
|
497
|
-
- [ ] Update JSDoc in source file
|
|
498
|
-
- [ ] Update README.md options table (Default column)
|
|
499
|
-
- [ ] Commit with `!`: `feat!: change default value for rule-name option`
|
|
500
|
-
|
|
501
|
-
#### Testing After Any Edit
|
|
502
|
-
|
|
503
|
-
**IMPORTANT:** Always test rule changes before committing.
|
|
504
|
-
|
|
505
|
-
1. **Create a temporary test file** for quick verification:
|
|
506
|
-
```bash
|
|
507
|
-
# Create in appropriate project(s)
|
|
508
|
-
_tests_/react-ts-tw/src/test-rule-name.tsx # For TS rules
|
|
509
|
-
_tests_/react/src/test-rule-name.jsx # For general rules (test in both)
|
|
510
|
-
```
|
|
511
|
-
|
|
512
|
-
2. **Add test cases:**
|
|
513
|
-
```javascript
|
|
514
|
-
// Temporary test file
|
|
515
|
-
|
|
516
|
-
// Should trigger the rule (BAD - test this fails)
|
|
517
|
-
const badCode = /* code that should fail */;
|
|
518
|
-
|
|
519
|
-
// Should pass (GOOD - test this passes)
|
|
520
|
-
const goodCode = /* code that should pass */;
|
|
521
|
-
```
|
|
522
|
-
|
|
523
|
-
3. **Run tests:**
|
|
524
|
-
```bash
|
|
525
|
-
cd _tests_/react-ts-tw
|
|
526
|
-
npx eslint src/test-rule-name.tsx # Verify error is reported
|
|
527
|
-
npx eslint src/test-rule-name.tsx --fix # Verify auto-fix works
|
|
528
|
-
npx eslint src/ # Ensure no regressions
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
4. **Clean up temporary test file:**
|
|
532
|
-
```bash
|
|
533
|
-
rm _tests_/react-ts-tw/src/test-rule-name.tsx
|
|
534
|
-
rm _tests_/react/src/test-rule-name.jsx # if created
|
|
535
|
-
```
|
|
536
|
-
|
|
537
|
-
5. **Ensure test project code covers the change:**
|
|
538
|
-
- Update existing code in test project (components, hooks, etc.) if needed
|
|
539
|
-
- The test project should naturally exercise the edited rule behavior
|
|
540
|
-
|
|
541
|
-
#### Version Bump After Edits
|
|
542
|
-
|
|
543
|
-
**IMPORTANT:** Every commit requires a version bump and tag. After committing your changes:
|
|
544
|
-
|
|
545
|
-
1. Bump version in `package.json` (PATCH for fixes, MINOR for new features)
|
|
546
|
-
2. Update `CHANGELOG.md`:
|
|
547
|
-
- Add new version entry at the top
|
|
548
|
-
- Add comparison link at the bottom: `[X.Y.Z]: https://github.com/.../compare/vPREV...vX.Y.Z`
|
|
549
|
-
3. Commit: `chore: bump version to X.Y.Z`
|
|
550
|
-
4. Create tag: `git tag -a vX.Y.Z -m "vX.Y.Z - description"`
|
|
551
|
-
5. Push: `git push origin main --tags`
|
|
552
|
-
|
|
553
|
-
See "When to Bump Version & Create Tag" section in Git Workflow for details.
|
|
554
|
-
|
|
555
|
-
---
|
|
556
|
-
|
|
557
|
-
### Rule Documentation Format in docs/rules/
|
|
558
|
-
|
|
559
|
-
Each rule should have this format in its category file under `docs/rules/`:
|
|
560
|
-
|
|
561
|
-
```markdown
|
|
562
|
-
### `rule-name`
|
|
563
|
-
|
|
564
|
-
**What it does:** One-line description of the rule's purpose.
|
|
565
|
-
|
|
566
|
-
**Why use it:** Optional context for why this rule is helpful.
|
|
567
|
-
|
|
568
|
-
> **Note:** Any special notes or dependencies (optional).
|
|
569
|
-
|
|
570
|
-
\`\`\`javascript
|
|
571
|
-
// ✅ Good — description
|
|
572
|
-
const example = "correct code";
|
|
573
|
-
|
|
574
|
-
// ❌ Bad — description
|
|
575
|
-
const example = "incorrect code";
|
|
576
|
-
\`\`\`
|
|
577
|
-
|
|
578
|
-
**Options:** (if rule has options)
|
|
579
|
-
|
|
580
|
-
| Option | Type | Default | Description |
|
|
581
|
-
|--------|------|---------|-------------|
|
|
582
|
-
| `optionName` | `string` | `"value"` | What the option does |
|
|
583
|
-
|
|
584
|
-
\`\`\`javascript
|
|
585
|
-
// Configuration example
|
|
586
|
-
"code-style/rule-name": ["error", { optionName: "value" }]
|
|
587
|
-
\`\`\`
|
|
588
|
-
|
|
589
|
-
---
|
|
590
|
-
```
|
|
591
|
-
|
|
592
|
-
## Key Patterns & Conventions
|
|
593
|
-
|
|
594
|
-
### Source Code Access
|
|
595
|
-
```javascript
|
|
596
|
-
const sourceCode = context.sourceCode || context.getSourceCode();
|
|
597
|
-
```
|
|
598
|
-
|
|
599
|
-
### Options with Defaults
|
|
600
|
-
```javascript
|
|
601
|
-
const options = context.options[0] || {};
|
|
602
|
-
const maxItems = options.maxItems !== undefined ? options.maxItems : 3;
|
|
603
|
-
```
|
|
604
|
-
|
|
605
|
-
### Getting Tokens
|
|
606
|
-
```javascript
|
|
607
|
-
const openBracket = sourceCode.getFirstToken(node);
|
|
608
|
-
const closeBracket = sourceCode.getLastToken(node);
|
|
609
|
-
const tokenBefore = sourceCode.getTokenBefore(node);
|
|
610
|
-
const tokenAfter = sourceCode.getTokenAfter(node);
|
|
611
|
-
```
|
|
612
|
-
|
|
613
|
-
### Getting Text
|
|
614
|
-
```javascript
|
|
615
|
-
const text = sourceCode.getText(node);
|
|
616
|
-
const lines = sourceCode.lines; // Array of all lines
|
|
617
|
-
```
|
|
618
|
-
|
|
619
|
-
### Indentation Calculation
|
|
620
|
-
```javascript
|
|
621
|
-
const lineText = sourceCode.lines[node.loc.start.line - 1];
|
|
622
|
-
const baseIndent = lineText.match(/^\s*/)[0];
|
|
623
|
-
const itemIndent = baseIndent + " "; // 4 spaces
|
|
624
|
-
```
|
|
625
|
-
|
|
626
|
-
### Fixer Methods
|
|
627
|
-
```javascript
|
|
628
|
-
fixer.replaceText(node, "new text")
|
|
629
|
-
fixer.replaceTextRange([start, end], "new text")
|
|
630
|
-
fixer.insertTextBefore(node, "text")
|
|
631
|
-
fixer.insertTextAfter(node, "text")
|
|
632
|
-
fixer.remove(node)
|
|
633
|
-
fixer.removeRange([start, end])
|
|
634
|
-
```
|
|
635
|
-
|
|
636
|
-
### Common Node Type Checks
|
|
637
|
-
```javascript
|
|
638
|
-
// Check parent type
|
|
639
|
-
if (node.parent && node.parent.type === "Property") { }
|
|
640
|
-
|
|
641
|
-
// Check for specific patterns
|
|
642
|
-
if (node.type === "ArrowFunctionExpression") { }
|
|
643
|
-
if (node.type === "JSXElement") { }
|
|
644
|
-
if (node.type === "ObjectExpression") { }
|
|
645
|
-
|
|
646
|
-
// React hooks detection
|
|
647
|
-
if (/^use[A-Z]/.test(node.callee.name)) { }
|
|
648
|
-
```
|
|
649
|
-
|
|
650
|
-
### Skip Conditions (Common Patterns)
|
|
651
|
-
```javascript
|
|
652
|
-
// Skip empty structures
|
|
653
|
-
if (elements.length === 0) return;
|
|
654
|
-
|
|
655
|
-
// Skip complex elements
|
|
656
|
-
const hasComplexElement = elements.some((el) =>
|
|
657
|
-
el.type === "SpreadElement" ||
|
|
658
|
-
el.type === "ObjectExpression" ||
|
|
659
|
-
el.type === "ArrowFunctionExpression"
|
|
660
|
-
);
|
|
661
|
-
if (hasComplexElement) return;
|
|
662
|
-
|
|
663
|
-
// Skip specific parent contexts
|
|
664
|
-
if (node.parent?.type === "CallExpression") return;
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
## Rule Categories
|
|
668
|
-
|
|
669
|
-
Rules are organized in these categories (alphabetically sorted in src/index.js and README.md):
|
|
670
|
-
|
|
671
|
-
- **Array Rules** — Rules for array formatting
|
|
672
|
-
- `array-callback-destructure`, `array-items-per-line`, `array-objects-on-new-lines`
|
|
673
|
-
- **Arrow Function Rules** — Arrow function syntax and style
|
|
674
|
-
- `arrow-function-block-body`, `arrow-function-simple-jsx`, `arrow-function-simplify`, `curried-arrow-same-line`
|
|
675
|
-
- **Call Expression Rules** — Function call formatting
|
|
676
|
-
- `function-arguments-format`, `nested-call-closing-brackets`, `no-empty-lines-in-function-calls`, `opening-brackets-same-line`, `simple-call-single-line`, `single-argument-on-one-line`
|
|
677
|
-
- **Class Rules** — Class and method definition formatting
|
|
678
|
-
- `class-method-definition-format`, `class-naming-convention`
|
|
679
|
-
- **Comment Rules** — Comment formatting
|
|
680
|
-
- `comment-format`
|
|
681
|
-
- **Component Rules** — React component patterns
|
|
682
|
-
- `component-props-destructure`, `component-props-inline-type`, `folder-based-naming-convention`, `folder-structure-consistency`, `no-redundant-folder-suffix`, `svg-icon-naming-convention`
|
|
683
|
-
- **Control Flow Rules** — if/switch/block statements
|
|
684
|
-
- `block-statement-newlines`, `if-else-spacing`, `if-statement-format`, `multiline-if-conditions`, `no-empty-lines-in-switch-cases`, `ternary-condition-multiline`
|
|
685
|
-
- **Function Rules** — Function declarations and params
|
|
686
|
-
- `function-call-spacing`, `function-declaration-style`, `function-naming-convention`, `function-object-destructure`, `function-params-per-line`, `no-empty-lines-in-function-params`
|
|
687
|
-
- **Hook Rules** — React hooks formatting
|
|
688
|
-
- `hook-callback-format`, `hook-deps-per-line`
|
|
689
|
-
- **Import/Export Rules** — Import/export statements
|
|
690
|
-
- `absolute-imports-only`, `export-format`, `import-format`, `import-source-spacing`, `index-export-style`, `index-exports-only`, `inline-export-declaration`, `module-index-exports`
|
|
691
|
-
- **JSX Rules** — JSX elements and attributes
|
|
692
|
-
- `classname-dynamic-at-end`, `classname-multiline`, `classname-no-extra-spaces`, `classname-order`, `jsx-children-on-new-line`, `jsx-closing-bracket-spacing`, `jsx-element-child-new-line`, `jsx-logical-expression-simplify`, `jsx-parentheses-position`, `jsx-prop-naming-convention`, `jsx-simple-element-one-line`, `jsx-string-value-trim`, `jsx-ternary-format`, `no-empty-lines-in-jsx`
|
|
693
|
-
- **Object Rules** — Object literal formatting
|
|
694
|
-
- `no-empty-lines-in-objects`, `object-property-per-line`, `object-property-value-brace`, `object-property-value-format`, `string-property-spacing`
|
|
695
|
-
- **React Rules** — React-specific patterns
|
|
696
|
-
- `react-code-order`
|
|
697
|
-
- **Spacing Rules** — General spacing rules
|
|
698
|
-
- `assignment-value-same-line`, `member-expression-bracket-spacing`
|
|
699
|
-
- **TypeScript Rules** — TypeScript-specific rules (TS configs only)
|
|
700
|
-
- `enum-format`, `interface-format`, `no-inline-type-definitions`, `prop-naming-convention`, `type-annotation-spacing`, `type-format`, `typescript-definition-location`
|
|
701
|
-
- **Variable Rules** — Variable declarations and naming
|
|
702
|
-
- `variable-naming-convention`
|
|
703
|
-
|
|
704
|
-
## Naming Conventions
|
|
705
|
-
|
|
706
|
-
- **Rule names:** kebab-case (e.g., `array-items-per-line`)
|
|
707
|
-
- **Internal variables:** camelCase (e.g., `arrayItemsPerLine`)
|
|
708
|
-
- **Handler functions:** end with `Handler` (e.g., `checkPatternHandler`)
|
|
709
|
-
- **Options:** camelCase (e.g., `maxItems`, `minProperties`)
|
|
710
|
-
|
|
711
|
-
## Meta Types
|
|
712
|
-
|
|
713
|
-
- `type: "layout"` - Formatting/whitespace rules (most rules)
|
|
714
|
-
- `type: "suggestion"` - Code convention rules (naming conventions)
|
|
715
|
-
|
|
716
|
-
## Documentation Files
|
|
717
|
-
|
|
718
|
-
- `README.md` - Main documentation with rule overview and links
|
|
719
|
-
- `docs/rules/` - Detailed rule documentation (17 category files with examples and options)
|
|
720
|
-
- `recommended-configs/<config-name>/README.md` - Config-specific documentation (references docs/rules/ for rule details)
|
|
721
|
-
- `index.d.ts` - TypeScript types for IDE autocomplete
|
|
722
|
-
|
|
723
|
-
## Important Notes
|
|
724
|
-
|
|
725
|
-
- Most rules should be auto-fixable (`fixable: "code"` or `fixable: "whitespace"` in meta)
|
|
726
|
-
- Rules that require file creation/movement or architectural decisions may be report-only
|
|
727
|
-
- Currently: 70 auto-fixable rules, 19 configurable rules, 9 report-only rules
|
|
728
|
-
- Use 4-space indentation throughout
|
|
729
|
-
- Object properties in `context.report()` must be alphabetically sorted
|
|
730
|
-
- Keep rules self-sufficient (no dependencies on other ESLint rules)
|
|
731
|
-
- Test with relevant test app in `_tests_/` before publishing
|
|
732
|
-
|
|
733
|
-
---
|
|
734
|
-
|
|
735
|
-
## Rule Count Locations
|
|
736
|
-
|
|
737
|
-
**IMPORTANT:** When adding/removing rules, update the rule counts in ALL these locations:
|
|
738
|
-
|
|
739
|
-
### Current Counts (update these when changing rules)
|
|
740
|
-
- **Total rules:** 79
|
|
741
|
-
- **Auto-fixable:** 70
|
|
742
|
-
- **Configurable:** 19 (rules with ⚙️ that have options)
|
|
743
|
-
- **Report-only:** 9
|
|
744
|
-
|
|
745
|
-
**IMPORTANT:** All counts must be uniform across ALL files. When updating:
|
|
746
|
-
- Total rules, auto-fixable count, configurable count, and report-only count must match everywhere
|
|
747
|
-
- The auto-fixable breakdown (code vs whitespace) in this section must match actual `grep` counts
|
|
748
|
-
- Use the Quick Verification Commands below to verify counts before committing
|
|
749
|
-
|
|
750
|
-
### Files & Line Numbers to Update
|
|
751
|
-
|
|
752
|
-
| File | Line(s) | What to Update |
|
|
753
|
-
|------|---------|----------------|
|
|
754
|
-
| `README.md` | ~22 | `*79 rules (70 auto-fixable, 19 configurable)*` |
|
|
755
|
-
| `README.md` | ~30 | `**79 custom rules** (70 auto-fixable, 19 configurable)` |
|
|
756
|
-
| `README.md` | ~39 | `70 of 79 rules support auto-fix` |
|
|
757
|
-
| `README.md` | ~272 | `**79 rules total** — 70 with auto-fix, 19 configurable` |
|
|
758
|
-
| `README.md` | ~409 | `70 of 79 rules support auto-fixing` |
|
|
759
|
-
| `docs/rules/README.md` | ~3 | `**79 rules total** — 70 with auto-fix, 19 configurable` |
|
|
760
|
-
| `AGENTS.md` | ~7 | `79 custom formatting rules (70 auto-fixable, 19 configurable, 9 report-only)` |
|
|
761
|
-
| `AGENTS.md` | ~9 | `Contains all 79 rules` |
|
|
762
|
-
| `AGENTS.md` | ~36 | `(70 rules in JS projects, 79 in TS projects)` |
|
|
763
|
-
| `AGENTS.md` | ~89 | `(79 rules total)` |
|
|
764
|
-
| `AGENTS.md` | ~675 | `all 79 rules` |
|
|
765
|
-
| `AGENTS.md` | ~697 | `70 auto-fixable rules, 19 configurable rules, 9 report-only` |
|
|
766
|
-
| `AGENTS.md` | Rule Count Locations section | Current Counts table |
|
|
767
|
-
| `recommended-configs/react-ts-tw/README.md` | ~396 | `**70 auto-fixable rules** (79 total, 19 configurable, 9 report-only)` |
|
|
768
|
-
| `recommended-configs/react/README.md` | ~286 | `**70 auto-fixable rules** (79 total, 19 configurable, 9 report-only)` |
|
|
769
|
-
|
|
770
|
-
### Quick Verification Commands
|
|
771
|
-
|
|
772
|
-
```bash
|
|
773
|
-
# Count total rules
|
|
774
|
-
grep -rc "^const [a-zA-Z]* = {$" src/rules/
|
|
775
|
-
|
|
776
|
-
# Count auto-fixable (code)
|
|
777
|
-
grep -rc 'fixable: "code"' src/rules/
|
|
778
|
-
|
|
779
|
-
# Count auto-fixable (whitespace)
|
|
780
|
-
grep -rc 'fixable: "whitespace"' src/rules/
|
|
781
|
-
|
|
782
|
-
# Count configurable rules (rules with ⚙️ in README table)
|
|
783
|
-
grep "| \`" README.md | grep -c "⚙️"
|
|
784
|
-
|
|
785
|
-
# Find all rule count mentions (excluding CHANGELOG)
|
|
786
|
-
grep -rn "[0-9][0-9] rules\|[0-9][0-9] auto" --include="*.md" | grep -v CHANGELOG
|
|
787
|
-
```
|
|
788
|
-
|
|
789
|
-
---
|
|
790
|
-
|
|
791
|
-
## Git Workflow
|
|
792
|
-
|
|
793
|
-
### Commit Message Format
|
|
794
|
-
|
|
795
|
-
Follow [Conventional Commits](https://www.conventionalcommits.org/) specification:
|
|
796
|
-
|
|
797
|
-
```
|
|
798
|
-
<type>: <subject>
|
|
799
|
-
|
|
800
|
-
[optional body]
|
|
801
|
-
```
|
|
802
|
-
|
|
803
|
-
**Types:**
|
|
804
|
-
- `feat` - New feature or rule
|
|
805
|
-
- `fix` - Bug fix
|
|
806
|
-
- `docs` - Documentation only changes
|
|
807
|
-
- `refactor` - Code change that neither fixes a bug nor adds a feature
|
|
808
|
-
- `chore` - Maintenance tasks (deps, configs)
|
|
809
|
-
|
|
810
|
-
**Subject line rules:**
|
|
811
|
-
- Use lowercase (except proper nouns)
|
|
812
|
-
- No period at the end
|
|
813
|
-
- Maximum 72 characters
|
|
814
|
-
- Use imperative mood ("add" not "added")
|
|
815
|
-
|
|
816
|
-
**Examples:**
|
|
817
|
-
```
|
|
818
|
-
feat: add function-declaration-style rule
|
|
819
|
-
fix: allow relative imports in entry files
|
|
820
|
-
docs: update options descriptions
|
|
821
|
-
```
|
|
822
|
-
|
|
823
|
-
**Multi-feature commits:**
|
|
824
|
-
```
|
|
825
|
-
feat: add function-declaration-style rule and enhancements
|
|
826
|
-
|
|
827
|
-
New rule:
|
|
828
|
-
- function-declaration-style: auto-fixes to arrow expressions
|
|
829
|
-
|
|
830
|
-
Enhancements:
|
|
831
|
-
- function-naming-convention: add auto-fix
|
|
832
|
-
```
|
|
833
|
-
|
|
834
|
-
---
|
|
835
|
-
|
|
836
|
-
### Versioning (SemVer)
|
|
837
|
-
|
|
838
|
-
Format: `MAJOR.MINOR.PATCH` (e.g., `1.2.8`)
|
|
839
|
-
|
|
840
|
-
| Change Type | Version | Examples |
|
|
841
|
-
|-------------|---------|----------|
|
|
842
|
-
| **PATCH** | `x.x.+1` | Bug fixes, typo corrections, doc updates |
|
|
843
|
-
| **MINOR** | `x.+1.0` | New rules, new features, new options |
|
|
844
|
-
| **MAJOR** | `+1.0.0` | Breaking changes, removed/renamed rules |
|
|
845
|
-
|
|
846
|
-
**Decision guide:**
|
|
847
|
-
- New rule → MINOR
|
|
848
|
-
- Auto-fix to existing rule → MINOR
|
|
849
|
-
- New option → MINOR
|
|
850
|
-
- Bug fix → PATCH
|
|
851
|
-
- Doc update only → PATCH
|
|
852
|
-
- Change default values → MAJOR (breaking)
|
|
853
|
-
- Rename/remove rule → MAJOR (breaking)
|
|
854
|
-
|
|
855
|
-
---
|
|
856
|
-
|
|
857
|
-
### When to Bump Version & Create Tag
|
|
858
|
-
|
|
859
|
-
**IMPORTANT:** Every commit requires a version bump and tag. Follow this workflow:
|
|
860
|
-
|
|
861
|
-
#### Commit Workflow (Always Bump Version)
|
|
862
|
-
After every meaningful change:
|
|
863
|
-
1. Make changes and commit with appropriate message
|
|
864
|
-
2. Bump version in `package.json`
|
|
865
|
-
3. Update `CHANGELOG.md`:
|
|
866
|
-
- Add new version entry at the top
|
|
867
|
-
- Add comparison link at the bottom: `[X.Y.Z]: https://github.com/.../compare/vPREV...vX.Y.Z`
|
|
868
|
-
4. Commit version bump with descriptive message (see below)
|
|
869
|
-
5. Create annotated tag with descriptive message
|
|
870
|
-
6. Push commits and tags
|
|
871
|
-
|
|
872
|
-
#### Version Bump Commit Messages
|
|
873
|
-
|
|
874
|
-
**IMPORTANT:** Do NOT use generic messages like `chore: bump version to X.Y.Z`. Instead, use descriptive messages that summarize what changes are in this version.
|
|
875
|
-
|
|
876
|
-
**Format:** `chore: release vX.Y.Z - brief description`
|
|
877
|
-
|
|
878
|
-
**Good examples:**
|
|
879
|
-
```
|
|
880
|
-
chore: release v1.7.2 - fix double comma bug in enum/interface format
|
|
881
|
-
chore: release v1.7.1 - multiple rule fixes for destructuring and ternaries
|
|
882
|
-
chore: release v1.6.0 - add 3 new rules and enhance ternary formatting
|
|
883
|
-
```
|
|
884
|
-
|
|
885
|
-
**Bad examples:**
|
|
886
|
-
```
|
|
887
|
-
chore: bump version to 1.7.2
|
|
888
|
-
chore: version bump
|
|
889
|
-
chore: v1.7.2
|
|
890
|
-
```
|
|
891
|
-
|
|
892
|
-
This makes `git log` readable and helps understand what each version contains without checking the CHANGELOG.
|
|
893
|
-
|
|
894
|
-
#### Version Bump Rules
|
|
895
|
-
| Change Type | Version Bump | Example | GitHub Release? |
|
|
896
|
-
|-------------|--------------|---------|-----------------|
|
|
897
|
-
| Bug fix | PATCH (+0.0.1) | 1.5.2 → 1.5.3 | No |
|
|
898
|
-
| Enhancement to existing rule | PATCH (+0.0.1) | 1.5.3 → 1.5.4 | No |
|
|
899
|
-
| New rule | MINOR (+0.1.0) | 1.5.4 → 1.6.0 | **Yes** |
|
|
900
|
-
| Breaking change | MAJOR (+1.0.0) | 1.6.0 → 2.0.0 | **Yes** |
|
|
901
|
-
| Docs only | PATCH (+0.0.1) | 1.5.2 → 1.5.3 | No |
|
|
902
|
-
|
|
903
|
-
#### MINOR/MAJOR Release Format (GitHub Releases)
|
|
904
|
-
|
|
905
|
-
When bumping MINOR or MAJOR version, the CHANGELOG entry must follow this format.
|
|
906
|
-
|
|
907
|
-
**IMPORTANT:** The release should contain ALL changes since the **previous RELEASE** (MINOR/MAJOR). The Version Range starts from the first version AFTER the previous release.
|
|
908
|
-
|
|
909
|
-
Example: If releasing v1.7.0 and the previous release was v1.6.0:
|
|
910
|
-
- Version Range: **v1.6.1 → v1.7.0** (starts AFTER v1.6.0)
|
|
911
|
-
- Include changes from: v1.6.1, v1.6.2, ... v1.6.6, AND v1.7.0
|
|
912
|
-
|
|
913
|
-
```markdown
|
|
914
|
-
## [X.Y.0] - YYYY-MM-DD
|
|
915
|
-
|
|
916
|
-
**Release Title (Brief Description of Main Features)**
|
|
917
|
-
|
|
918
|
-
**Version Range:** vAfterPreviousRelease → vCurrent
|
|
919
|
-
|
|
920
|
-
### Added
|
|
921
|
-
|
|
922
|
-
**New Rules (N)**
|
|
923
|
-
- `rule-name` - Description 🔧
|
|
924
|
-
|
|
925
|
-
### Enhanced
|
|
926
|
-
|
|
927
|
-
- **`rule-name`** - What was enhanced (consolidate all enhancements since last release)
|
|
928
|
-
|
|
929
|
-
### Fixed
|
|
930
|
-
|
|
931
|
-
- **`rule-name`** - What was fixed (consolidate all fixes since last release)
|
|
932
|
-
|
|
933
|
-
### Stats
|
|
934
|
-
|
|
935
|
-
- Total Rules: XX (was YY)
|
|
936
|
-
- Auto-fixable: ZZ rules 🔧
|
|
937
|
-
- Report-only: N rules
|
|
938
|
-
|
|
939
|
-
**Full Changelog:** [vAfterPreviousRelease...vCurrent](https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/vAfterPreviousRelease...vCurrent)
|
|
940
|
-
```
|
|
941
|
-
|
|
942
|
-
**Required elements for MINOR/MAJOR releases:**
|
|
943
|
-
1. **Release title** in bold describing main changes
|
|
944
|
-
2. **Version Range** showing first version AFTER previous release → current version
|
|
945
|
-
3. **Consolidated changes** from all versions since last release
|
|
946
|
-
4. **Stats** section with rule counts
|
|
947
|
-
5. **Full Changelog** link at the end
|
|
948
|
-
|
|
949
|
-
#### Example Workflow
|
|
950
|
-
```bash
|
|
951
|
-
# 1. Make changes and commit
|
|
952
|
-
git add .
|
|
953
|
-
git commit -m "fix: handle edge case in rule-name"
|
|
954
|
-
|
|
955
|
-
# 2. Bump version in package.json (1.5.2 → 1.5.3)
|
|
956
|
-
# 3. Update CHANGELOG.md with new entry
|
|
957
|
-
|
|
958
|
-
# 4. Commit version bump with descriptive message
|
|
959
|
-
git add package.json CHANGELOG.md
|
|
960
|
-
git commit -m "chore: release v1.5.3 - fix edge case in rule-name"
|
|
961
|
-
|
|
962
|
-
# 5. Create annotated tag with descriptive message
|
|
963
|
-
git tag -a v1.5.3 -m "v1.5.3 - Fix Edge Case in rule-name
|
|
964
|
-
|
|
965
|
-
- Fixed edge case handling in rule-name
|
|
966
|
-
- Improved error messages"
|
|
967
|
-
|
|
968
|
-
# 6. Push
|
|
969
|
-
git push origin main --tags
|
|
970
|
-
```
|
|
971
|
-
|
|
972
|
-
---
|
|
973
|
-
|
|
974
|
-
### Release Steps
|
|
975
|
-
|
|
976
|
-
1. **Update version in package.json**
|
|
977
|
-
2. **Update CHANGELOG.md:**
|
|
978
|
-
- Add new version entry at the top
|
|
979
|
-
- Add comparison link at the bottom: `[X.Y.Z]: https://github.com/.../compare/vPREV...vX.Y.Z`
|
|
980
|
-
3. **Commit version bump with descriptive message:**
|
|
981
|
-
```bash
|
|
982
|
-
git commit -m "chore: release v1.2.9 - brief description of changes"
|
|
983
|
-
```
|
|
984
|
-
4. **Create annotated tag with descriptive message:**
|
|
985
|
-
```bash
|
|
986
|
-
git tag -a v1.2.9 -m "v1.2.9 - Brief Description
|
|
987
|
-
|
|
988
|
-
- Feature description 1
|
|
989
|
-
- Feature description 2"
|
|
990
|
-
```
|
|
991
|
-
5. **Push (requires explicit approval):** `git push origin main --tags`
|
|
992
|
-
6. **Publish (requires explicit approval):** `npm publish`
|
|
993
|
-
|
|
994
|
-
---
|
|
995
|
-
|
|
996
|
-
### GitHub Releases (Grouped Tags)
|
|
997
|
-
|
|
998
|
-
GitHub Releases group multiple version tags into a single release announcement. Create a release when a significant milestone is reached (new features, major enhancements).
|
|
999
|
-
|
|
1000
|
-
**When to create a GitHub Release:**
|
|
1001
|
-
- **All MINOR versions (x.Y.0)** - Every new MINOR version is a release
|
|
1002
|
-
- **All MAJOR versions (X.0.0)** - Every new MAJOR version is a release
|
|
1003
|
-
- Optionally after multiple PATCH versions accumulate significant changes
|
|
1004
|
-
|
|
1005
|
-
**Note:** All MINOR versions (e.g., v1.7.0, v1.8.0) and MAJOR versions (e.g., v2.0.0) are considered releases and must be added to the "Current releases" list. The Version Range for a release always starts from the first version AFTER the previous release (MINOR or MAJOR) up to the current version.
|
|
1006
|
-
|
|
1007
|
-
**Release format:**
|
|
1008
|
-
|
|
1009
|
-
```markdown
|
|
1010
|
-
## Release Title
|
|
1011
|
-
<Short, descriptive title summarizing the main changes>
|
|
1012
|
-
|
|
1013
|
-
## Version Range
|
|
1014
|
-
vX.X.X → vY.Y.Y
|
|
1015
|
-
|
|
1016
|
-
---
|
|
1017
|
-
|
|
1018
|
-
## What's New
|
|
1019
|
-
|
|
1020
|
-
<Brief intro paragraph mentioning key highlights and rule count change>
|
|
1021
|
-
|
|
1022
|
-
### New Rules
|
|
1023
|
-
|
|
1024
|
-
| Rule | Description |
|
|
1025
|
-
|------|-------------|
|
|
1026
|
-
| `rule-name` | What it does |
|
|
1027
|
-
|
|
1028
|
-
### Enhancements
|
|
1029
|
-
|
|
1030
|
-
| Rule | Enhancement |
|
|
1031
|
-
|------|-------------|
|
|
1032
|
-
| `rule-name` | What was improved |
|
|
1033
|
-
|
|
1034
|
-
### New Features
|
|
1035
|
-
|
|
1036
|
-
- Feature 1 description
|
|
1037
|
-
- Feature 2 description
|
|
1038
|
-
|
|
1039
|
-
### Bug Fixes
|
|
1040
|
-
|
|
1041
|
-
- Fix 1 description
|
|
1042
|
-
- Fix 2 description
|
|
1043
|
-
|
|
1044
|
-
### Documentation
|
|
1045
|
-
|
|
1046
|
-
- Doc change 1
|
|
1047
|
-
- Doc change 2
|
|
1048
|
-
|
|
1049
|
-
## Installation
|
|
1050
|
-
|
|
1051
|
-
\`\`\`bash
|
|
1052
|
-
npm install eslint-plugin-code-style@Y.Y.Y
|
|
1053
|
-
\`\`\`
|
|
1054
|
-
|
|
1055
|
-
## Stats
|
|
1056
|
-
|
|
1057
|
-
- Total Rules: X (was Y)
|
|
1058
|
-
- All rules are auto-fixable with `eslint --fix`
|
|
1059
|
-
|
|
1060
|
-
**Full Changelog**: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/vX.X.X...vY.Y.Y
|
|
1061
|
-
```
|
|
1062
|
-
|
|
1063
|
-
**Steps to create a GitHub Release:**
|
|
1064
|
-
|
|
1065
|
-
1. Go to repository → Releases → "Draft a new release"
|
|
1066
|
-
2. Choose the latest tag (e.g., `v1.3.0`)
|
|
1067
|
-
3. Set release title (short, descriptive)
|
|
1068
|
-
4. Paste the release description following the format above
|
|
1069
|
-
5. Update `CHANGELOG.md` with the same information
|
|
1070
|
-
6. Publish release
|
|
1071
|
-
|
|
1072
|
-
### CHANGELOG.md
|
|
1073
|
-
|
|
1074
|
-
This project follows the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) standard.
|
|
1075
|
-
|
|
1076
|
-
**IMPORTANT:**
|
|
1077
|
-
- The CHANGELOG must list **ALL version tags** (currently 82 tags)
|
|
1078
|
-
- Update the CHANGELOG with every new tag/release
|
|
1079
|
-
- Keep it in sync with changes as you work
|
|
1080
|
-
- **Releases must match GitHub Releases content exactly**
|
|
1081
|
-
|
|
1082
|
-
#### Two Types of Entries
|
|
1083
|
-
|
|
1084
|
-
**1. Releases** (published to GitHub Releases)
|
|
1085
|
-
- Have **Version Range** showing tags covered
|
|
1086
|
-
- Full detailed sections with sub-categories
|
|
1087
|
-
- Include **Full Changelog** link at the end
|
|
1088
|
-
- Content must match the GitHub Release description
|
|
1089
|
-
- **Current releases:** v1.15.0, v1.14.0, v1.13.0, v1.12.0, v1.11.0, v1.10.0, v1.9.0, v1.8.0, v1.7.0, v1.6.0, v1.5.0, v1.4.2, v1.3.0, v1.2.0, v1.1.0, v1.0.16, v1.0.14, v1.0.7, v1.0.6
|
|
1090
|
-
|
|
1091
|
-
**2. Tags/PATCH versions** (between releases)
|
|
1092
|
-
- Simpler entries with just the changes
|
|
1093
|
-
- **NO title** (bold description line after date)
|
|
1094
|
-
- **NO Version Range**
|
|
1095
|
-
- **NO Full Changelog link** in the entry body
|
|
1096
|
-
- **MUST add link reference** at bottom of CHANGELOG.md: `[X.Y.Z]: https://github.com/.../compare/vA.B.C...vX.Y.Z`
|
|
1097
|
-
- Just `### Fixed`, `### Enhanced`, or other section headers directly
|
|
1098
|
-
|
|
1099
|
-
#### When to Create a Release
|
|
1100
|
-
|
|
1101
|
-
Create a release when:
|
|
1102
|
-
- Adding new rules (MINOR version bump)
|
|
1103
|
-
- Significant feature additions
|
|
1104
|
-
- Major documentation overhauls
|
|
1105
|
-
- Grouping multiple related changes together
|
|
1106
|
-
|
|
1107
|
-
After creating a release:
|
|
1108
|
-
1. Create the GitHub Release with full description
|
|
1109
|
-
2. Copy the same content to CHANGELOG.md
|
|
1110
|
-
3. Add **Full Changelog** link at the end
|
|
1111
|
-
4. Ensure both match exactly
|
|
1112
|
-
|
|
1113
|
-
#### Release Format
|
|
1114
|
-
|
|
1115
|
-
```markdown
|
|
1116
|
-
## [1.4.2] - 2026-01-30
|
|
1117
|
-
|
|
1118
|
-
**New Rules, Enhanced Auto-Fix & Comprehensive Documentation**
|
|
1119
|
-
|
|
1120
|
-
**Version Range:** v1.3.1 → v1.4.2
|
|
1121
|
-
|
|
1122
|
-
### Added
|
|
1123
|
-
|
|
1124
|
-
**New Rules (3)**
|
|
1125
|
-
- `rule-name` - Description 🔧
|
|
1126
|
-
|
|
1127
|
-
**Feature Category**
|
|
1128
|
-
- Feature description
|
|
1129
|
-
|
|
1130
|
-
### Enhanced
|
|
1131
|
-
|
|
1132
|
-
- **`rule-name`** - What was improved
|
|
1133
|
-
- **`rule-name`** - Another improvement
|
|
1134
|
-
|
|
1135
|
-
### Fixed
|
|
1136
|
-
|
|
1137
|
-
- **`rule-name`** - What was fixed
|
|
1138
|
-
|
|
1139
|
-
### Documentation
|
|
1140
|
-
|
|
1141
|
-
- What docs were updated
|
|
1142
|
-
|
|
1143
|
-
### Stats
|
|
1144
|
-
|
|
1145
|
-
- Total Rules: 64 (was 61)
|
|
1146
|
-
- Auto-fixable: 58 rules 🔧
|
|
1147
|
-
- Report-only: 6 rules
|
|
1148
|
-
|
|
1149
|
-
**Full Changelog:** [v1.3.1...v1.4.2](https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.3.1...v1.4.2)
|
|
1150
|
-
```
|
|
1151
|
-
|
|
1152
|
-
#### Tag Format (PATCH versions)
|
|
1153
|
-
|
|
1154
|
-
PATCH versions (x.y.+1) have a simpler format - NO title, NO version range, NO full changelog in entry:
|
|
1155
|
-
|
|
1156
|
-
```markdown
|
|
1157
|
-
## [1.11.2] - 2026-02-04
|
|
1158
|
-
|
|
1159
|
-
### Fixed
|
|
1160
|
-
|
|
1161
|
-
- **`rule-name`** - What was fixed
|
|
1162
|
-
- **`another-rule`** - Another fix
|
|
1163
|
-
|
|
1164
|
-
---
|
|
1165
|
-
```
|
|
1166
|
-
|
|
1167
|
-
For version bumps with no changes:
|
|
1168
|
-
```markdown
|
|
1169
|
-
## [1.0.19] - 2026-01-11
|
|
1170
|
-
|
|
1171
|
-
- Version bump
|
|
1172
|
-
|
|
1173
|
-
---
|
|
1174
|
-
```
|
|
1175
|
-
|
|
1176
|
-
**IMPORTANT:** Even though PATCH entries don't have Full Changelog links in the body, you MUST still add the link reference at the bottom of CHANGELOG.md:
|
|
1177
|
-
```markdown
|
|
1178
|
-
[1.11.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.1...v1.11.2
|
|
1179
|
-
[1.11.1]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.11.0...v1.11.1
|
|
1180
|
-
```
|
|
1181
|
-
|
|
1182
|
-
#### Section Types
|
|
1183
|
-
|
|
1184
|
-
| Section | Use for |
|
|
1185
|
-
|---------|---------|
|
|
1186
|
-
| **Added** | New rules, features, configurations |
|
|
1187
|
-
| **Changed** | Breaking changes, behavior changes |
|
|
1188
|
-
| **Enhanced** | Improvements to existing functionality |
|
|
1189
|
-
| **Fixed** | Bug fixes |
|
|
1190
|
-
| **Deprecated** | Features to be removed in future |
|
|
1191
|
-
| **Removed** | Removed features |
|
|
1192
|
-
| **Security** | Security fixes |
|
|
1193
|
-
| **Documentation** | Doc-only changes |
|
|
1194
|
-
| **Stats** | Rule counts (include for releases) |
|
|
1195
|
-
|
|
1196
|
-
#### Comparison Links
|
|
1197
|
-
|
|
1198
|
-
At the bottom of CHANGELOG.md, maintain comparison links for **every version**:
|
|
1199
|
-
|
|
1200
|
-
```markdown
|
|
1201
|
-
[1.4.2]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.4.1...v1.4.2
|
|
1202
|
-
[1.4.1]: https://github.com/Mohamed-Elhawary/eslint-plugin-code-style/compare/v1.4.0...v1.4.1
|
|
1203
|
-
```
|
|
1204
|
-
|
|
1205
|
-
#### When to Update
|
|
1206
|
-
|
|
1207
|
-
Update CHANGELOG.md when creating any new tag:
|
|
1208
|
-
- [ ] Add new section at top: `## [X.Y.Z] - YYYY-MM-DD`
|
|
1209
|
-
- [ ] For releases: add **Version Range**, full detailed sections, and **Full Changelog** link
|
|
1210
|
-
- [ ] For tags: add appropriate subsections
|
|
1211
|
-
- [ ] Add comparison link at bottom
|
|
1212
|
-
- [ ] Separate each version with `---`
|
|
1213
|
-
|
|
1214
|
-
**Tip:** Update the CHANGELOG as you make changes, not just at release time
|
|
1215
|
-
|
|
1216
|
-
#### Release Checklist
|
|
1217
|
-
|
|
1218
|
-
When creating a release:
|
|
1219
|
-
- [ ] Write full release description with all sections (Added, Enhanced, Fixed, Stats, etc.)
|
|
1220
|
-
- [ ] Create GitHub Release with the description and title
|
|
1221
|
-
- [ ] Copy exact same content to CHANGELOG.md
|
|
1222
|
-
- [ ] Add **Release Title** (bold text after version header)
|
|
1223
|
-
- [ ] Add **Version Range** showing first and last tag in release
|
|
1224
|
-
- [ ] Add **Full Changelog** link at the end: `**Full Changelog:** [vX.X.X...vY.Y.Y](compare-url)`
|
|
1225
|
-
- [ ] Update the "Current releases" list in this file (AGENTS.md)
|
|
1226
|
-
- [ ] Verify content matches between GitHub Release and CHANGELOG
|
|
1227
|
-
|
|
1228
|
-
#### Verifying CHANGELOG
|
|
1229
|
-
|
|
1230
|
-
To verify all tags are in CHANGELOG:
|
|
1231
|
-
```bash
|
|
1232
|
-
# Count tags vs CHANGELOG entries
|
|
1233
|
-
echo "Tags: $(git tag | wc -l)"
|
|
1234
|
-
echo "CHANGELOG: $(grep -c '^## \[' CHANGELOG.md)"
|
|
1235
|
-
|
|
1236
|
-
# Check for missing tags
|
|
1237
|
-
git tag -l | sort -V > /tmp/tags.txt
|
|
1238
|
-
grep '^## \[' CHANGELOG.md | sed 's/.*\[\([^]]*\)\].*/v\1/' | sort -V > /tmp/changelog.txt
|
|
1239
|
-
diff /tmp/tags.txt /tmp/changelog.txt
|
|
1240
|
-
```
|
|
1241
|
-
|
|
1242
|
-
## Skills
|
|
1243
|
-
|
|
1244
|
-
This project includes reusable skills in the `.skills/` directory following the [Agent Skills](https://agentskills.io) open standard. These work with Claude Code, Cursor, VS Code, GitHub Copilot, Gemini CLI, and other compatible agents.
|
|
1245
|
-
|
|
1246
|
-
| Skill | Description |
|
|
1247
|
-
|-------|-------------|
|
|
1248
|
-
| `audit-docs` | Verify documentation accuracy across all files |
|
|
1249
|
-
| `manage-rule` | Add, edit, or remove an ESLint rule with all required file updates |
|
|
1250
|
-
| `review-config` | Review a recommended ESLint configuration |
|
|
1251
|
-
| `test-rule` | Test an ESLint rule after creating or modifying it |
|
|
1252
|
-
| `validate-types` | Verify TypeScript definitions match rules in src/index.js |
|
|
1253
|
-
|
|
1254
|
-
See `.skills/*/skill.md` for detailed instructions.
|
|
1255
|
-
|
|
1256
|
-
---
|
|
1257
|
-
|
|
1258
|
-
## Workflows
|
|
1259
|
-
|
|
1260
|
-
Reusable workflows for common tasks. Any AI agent should follow these when performing the specified task.
|
|
1261
|
-
|
|
1262
|
-
---
|
|
1263
|
-
|
|
1264
|
-
### Workflow: Test Rule
|
|
1265
|
-
|
|
1266
|
-
Test an ESLint rule to verify it works correctly.
|
|
1267
|
-
|
|
1268
|
-
**When to use:** After creating or modifying a rule.
|
|
1269
|
-
|
|
1270
|
-
**Steps:**
|
|
1271
|
-
|
|
1272
|
-
1. **Find the rule** in `src/rules/<category>.js` and understand what it checks
|
|
1273
|
-
2. **Identify test app** — Use `_tests_/react/` for JS rules or `_tests_/react-ts-tw/` for TS rules
|
|
1274
|
-
3. **Create test cases** in the test app:
|
|
1275
|
-
- Add code that should PASS (no violations)
|
|
1276
|
-
- Add code that should FAIL (triggers violations)
|
|
1277
|
-
4. **Run the linter:**
|
|
1278
|
-
```bash
|
|
1279
|
-
cd _tests_/<config-name>
|
|
1280
|
-
npm run lint # Check for violations
|
|
1281
|
-
npm run lint:fix # Verify auto-fix works
|
|
1282
|
-
```
|
|
1283
|
-
5. **Verify results:**
|
|
1284
|
-
- Valid code produces no errors
|
|
1285
|
-
- Invalid code triggers the expected error message
|
|
1286
|
-
- Auto-fix transforms code correctly
|
|
1287
|
-
|
|
1288
|
-
---
|
|
1289
|
-
|
|
1290
|
-
### Workflow: Validate Types
|
|
1291
|
-
|
|
1292
|
-
Verify TypeScript definitions match the rules in `src/index.js`.
|
|
1293
|
-
|
|
1294
|
-
**When to use:** After adding new rules or before releases.
|
|
1295
|
-
|
|
1296
|
-
**Steps:**
|
|
1297
|
-
|
|
1298
|
-
1. **Count rules in src/:**
|
|
1299
|
-
```bash
|
|
1300
|
-
grep -rc "^const .* = {$" src/rules/
|
|
1301
|
-
```
|
|
1302
|
-
Or count entries in the `rules` export object.
|
|
1303
|
-
|
|
1304
|
-
2. **Check index.d.ts:**
|
|
1305
|
-
- Verify `RuleNames` type includes all rule names (alphabetically sorted)
|
|
1306
|
-
- Verify `PluginRules` interface includes all rules
|
|
1307
|
-
|
|
1308
|
-
3. **Look for mismatches:**
|
|
1309
|
-
- Rules in `src/index.js` missing from `index.d.ts`?
|
|
1310
|
-
- Rules in `index.d.ts` that don't exist in `src/index.js`?
|
|
1311
|
-
|
|
1312
|
-
4. **Report:**
|
|
1313
|
-
- Total rules: X
|
|
1314
|
-
- Types match: Yes/No
|
|
1315
|
-
- Missing types: [list]
|
|
1316
|
-
- Extra types: [list]
|
|
1317
|
-
|
|
1318
|
-
---
|
|
1319
|
-
|
|
1320
|
-
### Workflow: Review Config
|
|
1321
|
-
|
|
1322
|
-
Review a recommended ESLint configuration for consistency.
|
|
1323
|
-
|
|
1324
|
-
**When to use:** After adding rules or modifying configs.
|
|
1325
|
-
|
|
1326
|
-
**Arguments:** `<config-name>` (e.g., `react`, `react-ts-tw`)
|
|
1327
|
-
|
|
1328
|
-
**Steps:**
|
|
1329
|
-
|
|
1330
|
-
1. **Check config file:** `recommended-configs/<config-name>/eslint.config.js`
|
|
1331
|
-
- Does it import the plugin correctly?
|
|
1332
|
-
- Are rules set to `"error"` (not `"off"`)?
|
|
1333
|
-
- Are rule options valid per the rule's schema?
|
|
1334
|
-
|
|
1335
|
-
2. **Compare with test config:** `_tests_/<config-name>/eslint.config.js`
|
|
1336
|
-
- Should have the same rules enabled
|
|
1337
|
-
- Test config may have additional test-specific settings
|
|
1338
|
-
|
|
1339
|
-
3. **Test the config:**
|
|
1340
|
-
```bash
|
|
1341
|
-
cd _tests_/<config-name>
|
|
1342
|
-
npm run lint
|
|
1343
|
-
```
|
|
1344
|
-
|
|
1345
|
-
4. **Check README:** `recommended-configs/<config-name>/README.md`
|
|
1346
|
-
- Does it list all enabled rules?
|
|
1347
|
-
- Are rule counts accurate?
|
|
1348
|
-
|
|
1349
|
-
5. **Report:**
|
|
1350
|
-
- Config valid: Yes/No
|
|
1351
|
-
- Rules enabled: X
|
|
1352
|
-
- Issues found: [list]
|
|
1353
|
-
|
|
1354
|
-
---
|
|
1355
|
-
|
|
1356
|
-
### Workflow: Audit Docs
|
|
1357
|
-
|
|
1358
|
-
Verify documentation accuracy across all files.
|
|
1359
|
-
|
|
1360
|
-
**When to use:** Before releases or after adding rules.
|
|
1361
|
-
|
|
1362
|
-
**Steps:**
|
|
1363
|
-
|
|
1364
|
-
1. **Count actual rules:**
|
|
1365
|
-
```bash
|
|
1366
|
-
grep -rc "^const .* = {$" src/rules/
|
|
1367
|
-
```
|
|
1368
|
-
|
|
1369
|
-
2. **Check rule count references:**
|
|
1370
|
-
- `AGENTS.md`: "61 custom auto-fixable formatting rules"
|
|
1371
|
-
- `README.md`: Multiple mentions of rule count
|
|
1372
|
-
- `recommended-configs/*/README.md`: Any rule count mentions
|
|
1373
|
-
|
|
1374
|
-
3. **Verify version consistency:**
|
|
1375
|
-
- `package.json` version matches latest tag
|
|
1376
|
-
- No outdated version references in docs
|
|
1377
|
-
|
|
1378
|
-
4. **Check links:**
|
|
1379
|
-
- Config paths in README exist
|
|
1380
|
-
- Test app paths exist
|
|
1381
|
-
- Internal markdown links work
|
|
1382
|
-
|
|
1383
|
-
5. **Report:**
|
|
1384
|
-
- Actual rule count: X
|
|
1385
|
-
- Documented counts match: Yes/No
|
|
1386
|
-
- Outdated references: [list]
|
|
1387
|
-
- Broken links: [list]
|