eslint-plugin-ai-rules 0.3.0 → 0.4.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 +1 -1
- package/README.md +203 -81
- package/dist/index.cjs +129 -83
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +7 -6
- package/dist/index.d.ts +7 -6
- package/dist/index.js +129 -83
- package/dist/index.js.map +1 -1
- package/package.json +20 -11
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -94,6 +94,7 @@ npx eslint --fix .
|
|
|
94
94
|
- [Structure DSL](#structure-dsl)
|
|
95
95
|
- [Limitations](#limitations)
|
|
96
96
|
- [Rules](#rules)
|
|
97
|
+
- [Disabling or changing rules](#disabling-or-changing-rules)
|
|
97
98
|
- [What runs automatically](#what-runs-automatically)
|
|
98
99
|
- [Recommended preset](#recommended-preset)
|
|
99
100
|
- [Troubleshooting](#troubleshooting)
|
|
@@ -101,19 +102,19 @@ npx eslint --fix .
|
|
|
101
102
|
- [Migrating from 0.2.x](#migrating-from-02x)
|
|
102
103
|
- [Development](#development)
|
|
103
104
|
- [Publishing](#publishing)
|
|
104
|
-
- [
|
|
105
|
+
- [Articles](#articles)
|
|
106
|
+
- [Contributing](#contributing)
|
|
107
|
+
- [Security](#security)
|
|
105
108
|
|
|
106
109
|
## Configuration warning
|
|
107
110
|
|
|
108
|
-
If you install the plugin and use `aiRules.configs.recommended` without configuring the project structure,
|
|
111
|
+
If you install the plugin and use `aiRules.configs.recommended` without configuring the project structure, `ai-rules/project-setup` reports a warning the first time it lints a file:
|
|
109
112
|
|
|
110
113
|
```text
|
|
111
|
-
|
|
112
|
-
Configure it with aiRules.configs.projects([{ rootFolder: '.', preset: 'frontend' | 'backend' }]).
|
|
113
|
-
If this project is not a frontend/backend, use preset: 'other' to disable this warning.
|
|
114
|
+
Project structure validation is not configured. Configure it with aiRules.configs.projects([{ rootFolder: ".", preset: "frontend" | "backend" }]). If this project is not a frontend/backend, use preset: "other" to disable this warning. ai-rules/project-setup
|
|
114
115
|
```
|
|
115
116
|
|
|
116
|
-
The warning exists only to make sure the new structure rules are actually configured. It is
|
|
117
|
+
The warning exists only to make sure the new structure rules are actually configured. It is reported once per process.
|
|
117
118
|
|
|
118
119
|
It disappears when you provide a valid configuration:
|
|
119
120
|
|
|
@@ -123,7 +124,7 @@ It disappears when you provide a valid configuration:
|
|
|
123
124
|
- a custom non-empty `structure`
|
|
124
125
|
- a `relations` configuration
|
|
125
126
|
|
|
126
|
-
A project containing only `rootFolder` and an empty `structure` is still considered unconfigured and will
|
|
127
|
+
A project containing only `rootFolder` and an empty `structure` is still considered unconfigured and will report.
|
|
127
128
|
|
|
128
129
|
For CI or temporary runs, silence the warning without changing the config:
|
|
129
130
|
|
|
@@ -131,6 +132,16 @@ For CI or temporary runs, silence the warning without changing the config:
|
|
|
131
132
|
AI_RULES_SILENT=1 npx eslint .
|
|
132
133
|
```
|
|
133
134
|
|
|
135
|
+
You can also disable the rule or change its severity like any other ESLint rule:
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
{
|
|
139
|
+
rules: {
|
|
140
|
+
'ai-rules/project-setup': 'off',
|
|
141
|
+
},
|
|
142
|
+
}
|
|
143
|
+
```
|
|
144
|
+
|
|
134
145
|
The warning is still recommended as a setup check, so prefer `preset: 'other'` for projects that intentionally do not use structure validation.
|
|
135
146
|
|
|
136
147
|
## Features
|
|
@@ -167,6 +178,7 @@ interface IProjectDefinition {
|
|
|
167
178
|
preset?: 'frontend' | 'backend' | 'other'
|
|
168
179
|
structure?: IProjectStructure
|
|
169
180
|
relations?: IRelationsConfig
|
|
181
|
+
rules?: Linter.RulesRecord
|
|
170
182
|
}
|
|
171
183
|
```
|
|
172
184
|
|
|
@@ -178,6 +190,7 @@ interface IProjectDefinition {
|
|
|
178
190
|
- `preset` provides a base structure.
|
|
179
191
|
- `structure` is merged on top of the preset.
|
|
180
192
|
- `relations` enables architecture dependency policies with `eslint-plugin-boundaries`.
|
|
193
|
+
- `rules` overrides rule severities and options for that project using the standard ESLint rule format.
|
|
181
194
|
- `preset: 'other'` disables structure validation unless a custom `structure` is provided.
|
|
182
195
|
|
|
183
196
|
`aiRules.configs.projects([...])` generates one flat config per project. Each config:
|
|
@@ -186,9 +199,10 @@ interface IProjectDefinition {
|
|
|
186
199
|
- sets `settings['ai-rules'].project`;
|
|
187
200
|
- enables `ai-rules/project-structure`;
|
|
188
201
|
- adds `ignores` from `ignoredPaths`;
|
|
189
|
-
- includes the recommended rules
|
|
202
|
+
- includes the recommended rules, overridable by `rules`;
|
|
190
203
|
- disables `ai-rules/filename-pascal-case`, because file naming is handled by `project-structure`;
|
|
191
|
-
- when `relations` is present, registers `boundaries` and enables `boundaries/dependencies
|
|
204
|
+
- when `relations` is present, registers `boundaries` and enables `boundaries/dependencies`;
|
|
205
|
+
- applies `rules` last, so a project can disable or change any rule.
|
|
192
206
|
|
|
193
207
|
## Examples
|
|
194
208
|
|
|
@@ -422,7 +436,7 @@ structure: {
|
|
|
422
436
|
|
|
423
437
|
```ts
|
|
424
438
|
structure: {
|
|
425
|
-
ignoredPaths: ['dist/**', 'coverage/**', 'src/services/generated/**'],
|
|
439
|
+
ignoredPaths: ['dist/**', 'coverage/**', 'src/shared/services/generated/**'],
|
|
426
440
|
}
|
|
427
441
|
```
|
|
428
442
|
|
|
@@ -579,6 +593,8 @@ These violations are intentional and should be fixed during migration.
|
|
|
579
593
|
|
|
580
594
|
### Frontend preset relations
|
|
581
595
|
|
|
596
|
+
All global frontend layers live under `src/shared` (for example `src/shared/components`). Page-local layers remain under `src/pages/*`.
|
|
597
|
+
|
|
582
598
|
| Layer | Can import | Same layer |
|
|
583
599
|
|-------|------------|------------|
|
|
584
600
|
| components | components, hooks, contexts, services, generated, utils, helpers, constants, env | yes |
|
|
@@ -731,32 +747,36 @@ Custom relation message:
|
|
|
731
747
|
│ index.html, AGENTS.md, README.md, LICENSE
|
|
732
748
|
├── src/
|
|
733
749
|
│ ├── App.tsx, AppRoutes.tsx, main.tsx, index.css, vite-env.d.ts
|
|
734
|
-
│ ├──
|
|
735
|
-
│ ├── components/
|
|
736
|
-
│ ├──
|
|
737
|
-
│
|
|
738
|
-
│ ├──
|
|
739
|
-
│ ├── helpers/*.ts
|
|
740
|
-
│ ├── hooks/*.ts
|
|
741
|
-
│ ├── pages/*.tsx
|
|
742
|
-
│ ├── pages/<feature-kebab>/
|
|
743
|
-
│ │ ├── *.tsx, helpers.ts, schema.ts, types.ts
|
|
744
|
-
│ │ ├── components/*.tsx
|
|
745
|
-
│ │ ├── hooks/*.ts
|
|
746
|
-
│ │ ├── services/*.ts
|
|
750
|
+
│ ├── shared/
|
|
751
|
+
│ │ ├── components/
|
|
752
|
+
│ │ │ ├── *.tsx
|
|
753
|
+
│ │ │ └── ui/*.{ts,tsx}
|
|
754
|
+
│ │ ├── constants/*.ts
|
|
747
755
|
│ │ ├── contexts/*.tsx
|
|
756
|
+
│ │ ├── env/index.ts
|
|
748
757
|
│ │ ├── helpers/*.ts
|
|
749
|
-
│ │
|
|
750
|
-
│ │
|
|
751
|
-
│ │
|
|
752
|
-
│ │
|
|
753
|
-
│ │
|
|
754
|
-
│
|
|
755
|
-
│
|
|
756
|
-
│
|
|
757
|
-
│
|
|
758
|
-
│
|
|
759
|
-
│
|
|
758
|
+
│ │ ├── hooks/*.ts
|
|
759
|
+
│ │ ├── services/
|
|
760
|
+
│ │ │ ├── generated/** (ignored)
|
|
761
|
+
│ │ │ └── utils/*.ts
|
|
762
|
+
│ │ └── utils/*.ts
|
|
763
|
+
│ └── pages/
|
|
764
|
+
│ ├── *.tsx
|
|
765
|
+
│ └── <feature-kebab>/
|
|
766
|
+
│ ├── *.tsx, helpers.ts, schema.ts, types.ts
|
|
767
|
+
│ ├── components/*.tsx
|
|
768
|
+
│ ├── hooks/*.ts
|
|
769
|
+
│ ├── services/*.ts
|
|
770
|
+
│ ├── contexts/*.tsx
|
|
771
|
+
│ ├── helpers/*.ts
|
|
772
|
+
│ └── tabs/<tab-kebab>/
|
|
773
|
+
│ ├── *.tsx
|
|
774
|
+
│ └── <section-kebab>/
|
|
775
|
+
│ ├── *.tsx, *.ts
|
|
776
|
+
│ ├── components/*.tsx
|
|
777
|
+
│ └── contents/
|
|
778
|
+
│ ├── *.tsx
|
|
779
|
+
│ └── components/*.tsx
|
|
760
780
|
├── e2e/
|
|
761
781
|
│ ├── .auth/** (ignored)
|
|
762
782
|
│ ├── fixtures/*
|
|
@@ -955,12 +975,12 @@ Validates the configured hierarchy, folder names and file names.
|
|
|
955
975
|
|
|
956
976
|
### `ai-rules/project-setup`
|
|
957
977
|
|
|
958
|
-
|
|
978
|
+
Reports the configuration warning described above as a regular ESLint diagnostic.
|
|
959
979
|
|
|
960
980
|
- Type: `suggestion`
|
|
961
981
|
- Enabled as `warn` in `recommended`
|
|
962
|
-
-
|
|
963
|
-
-
|
|
982
|
+
- Reports once per process
|
|
983
|
+
- Respects the configured severity (`off`, `warn`, `error`)
|
|
964
984
|
- Suppressed by `preset: 'other'`, `frontend`, `backend` or a non-empty custom structure
|
|
965
985
|
|
|
966
986
|
### `ai-rules/filename-pascal-case`
|
|
@@ -1032,20 +1052,82 @@ The plugin also configures the `import-x` resolver with:
|
|
|
1032
1052
|
extensions: ['.ts', '.tsx', '.d.ts', '.js', '.jsx']
|
|
1033
1053
|
```
|
|
1034
1054
|
|
|
1035
|
-
|
|
1055
|
+
## Disabling or changing rules
|
|
1056
|
+
|
|
1057
|
+
Every rule is controlled through the standard ESLint `rules` object. Any entry accepts `'off'`, `'warn'`, `'error'`, or `['error', options]`.
|
|
1058
|
+
|
|
1059
|
+
### Option 1: override after the generated config
|
|
1060
|
+
|
|
1061
|
+
Flat config is evaluated in order, so a config placed after `projects()` or `recommended` wins:
|
|
1036
1062
|
|
|
1037
1063
|
```ts
|
|
1038
1064
|
export default defineConfig([
|
|
1039
|
-
...
|
|
1065
|
+
...tseslint.configs.recommended,
|
|
1066
|
+
...aiRules.configs.projects([
|
|
1067
|
+
{ rootFolder: '.', preset: 'frontend' },
|
|
1068
|
+
]),
|
|
1040
1069
|
{
|
|
1041
1070
|
rules: {
|
|
1042
|
-
'
|
|
1071
|
+
'ai-rules/sort-imports': 'off',
|
|
1072
|
+
'ai-rules/project-structure': 'warn',
|
|
1073
|
+
'ai-rules/filename-pascal-case': 'error',
|
|
1074
|
+
'@stylistic/semi': ['warn', 'always'],
|
|
1043
1075
|
'import-x/no-default-export': 'off',
|
|
1076
|
+
'boundaries/dependencies': 'off',
|
|
1077
|
+
},
|
|
1078
|
+
},
|
|
1079
|
+
])
|
|
1080
|
+
```
|
|
1081
|
+
|
|
1082
|
+
To apply an override only to part of the repository, use `files`:
|
|
1083
|
+
|
|
1084
|
+
```ts
|
|
1085
|
+
{
|
|
1086
|
+
files: ['scripts/**/*', '*.config.*'],
|
|
1087
|
+
rules: {
|
|
1088
|
+
'ai-rules/filename-pascal-case': 'off',
|
|
1089
|
+
},
|
|
1090
|
+
}
|
|
1091
|
+
```
|
|
1092
|
+
|
|
1093
|
+
### Option 2: per-project `rules`
|
|
1094
|
+
|
|
1095
|
+
When using `projects()`, pass `rules` in the project definition. These rules are applied after the recommended rules, the preset rules and the automatic structure/relations rules:
|
|
1096
|
+
|
|
1097
|
+
```ts
|
|
1098
|
+
aiRules.configs.projects([
|
|
1099
|
+
{
|
|
1100
|
+
rootFolder: 'apps/api',
|
|
1101
|
+
preset: 'backend',
|
|
1102
|
+
rules: {
|
|
1103
|
+
'ai-rules/sort-imports': 'off',
|
|
1104
|
+
'ai-rules/project-structure': 'warn',
|
|
1105
|
+
'@stylistic/semi': ['warn', 'always'],
|
|
1106
|
+
'boundaries/dependencies': 'off',
|
|
1044
1107
|
},
|
|
1045
1108
|
},
|
|
1046
1109
|
])
|
|
1047
1110
|
```
|
|
1048
1111
|
|
|
1112
|
+
Precedence inside `projects()` is:
|
|
1113
|
+
|
|
1114
|
+
1. `recommended` rules
|
|
1115
|
+
2. automatic `project-structure`, `filename-pascal-case` and `boundaries/dependencies` rules
|
|
1116
|
+
3. `preset.rules`
|
|
1117
|
+
4. project `rules`
|
|
1118
|
+
5. any flat config placed after `projects()` in the ESLint config array
|
|
1119
|
+
|
|
1120
|
+
The `rules` option uses the same shape as ESLint, including options arrays:
|
|
1121
|
+
|
|
1122
|
+
```ts
|
|
1123
|
+
rules: {
|
|
1124
|
+
'ai-rules/filename-pascal-case': [
|
|
1125
|
+
'error',
|
|
1126
|
+
{ ignore: ['\\.config\\.'], ignoreMiddleExtensions: false },
|
|
1127
|
+
],
|
|
1128
|
+
}
|
|
1129
|
+
```
|
|
1130
|
+
|
|
1049
1131
|
## What runs automatically
|
|
1050
1132
|
|
|
1051
1133
|
| You use | What is enabled |
|
|
@@ -1101,6 +1183,16 @@ Or explicitly opt out:
|
|
|
1101
1183
|
|
|
1102
1184
|
A project with only `rootFolder` and an empty `structure` still warns.
|
|
1103
1185
|
|
|
1186
|
+
If you intentionally do not want this check, disable the rule:
|
|
1187
|
+
|
|
1188
|
+
```ts
|
|
1189
|
+
{
|
|
1190
|
+
rules: {
|
|
1191
|
+
'ai-rules/project-setup': 'off',
|
|
1192
|
+
},
|
|
1193
|
+
}
|
|
1194
|
+
```
|
|
1195
|
+
|
|
1104
1196
|
For temporary runs or CI, use:
|
|
1105
1197
|
|
|
1106
1198
|
```bash
|
|
@@ -1204,34 +1296,36 @@ If you intentionally do not want structure validation:
|
|
|
1204
1296
|
## Development
|
|
1205
1297
|
|
|
1206
1298
|
```bash
|
|
1207
|
-
git clone
|
|
1299
|
+
git clone https://github.com/lvsouza/eslint-ai-guard.git
|
|
1208
1300
|
cd eslint-ai-guard
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1301
|
+
corepack enable
|
|
1302
|
+
yarn install --frozen-lockfile
|
|
1303
|
+
|
|
1304
|
+
yarn typecheck # tsc --noEmit
|
|
1305
|
+
yarn test # node:test against dist
|
|
1306
|
+
yarn test:watch # node:test in watch mode
|
|
1307
|
+
yarn lint # eslint .
|
|
1308
|
+
yarn lint --fix
|
|
1309
|
+
yarn build # tsup -> ESM + CJS + declarations
|
|
1310
|
+
yarn dev # tsup --watch
|
|
1311
|
+
yarn verify # typecheck + test + lint + pack
|
|
1312
|
+
yarn test:coverage # c8 coverage with thresholds
|
|
1313
|
+
yarn test:consumer # install packed tarball in a temp project
|
|
1314
|
+
yarn test:package # publint + arethetypeswrong
|
|
1315
|
+
yarn test:release # full validation before release
|
|
1316
|
+
npm pack --dry-run # verify published files
|
|
1223
1317
|
```
|
|
1224
1318
|
|
|
1225
|
-
`test:consumer` and `test:package` are release checks and are not part of `verify`. They may use the network.
|
|
1319
|
+
`test:consumer` and `test:package` are release checks and are not part of `verify`. They may use the network. `test:release` runs the complete validation: `verify`, coverage, consumer and package checks.
|
|
1226
1320
|
|
|
1227
1321
|
The consumer smoke test covers structure validation, relations with aliases and type-only imports, warning/suppression, ESM and CJS. It accepts `ESLINT_VERSION`:
|
|
1228
1322
|
|
|
1229
1323
|
```bash
|
|
1230
|
-
ESLINT_VERSION=9.22.0
|
|
1231
|
-
ESLINT_VERSION='^10.0.0'
|
|
1324
|
+
ESLINT_VERSION=9.22.0 yarn test:consumer
|
|
1325
|
+
ESLINT_VERSION='^10.0.0' yarn test:consumer
|
|
1232
1326
|
```
|
|
1233
1327
|
|
|
1234
|
-
|
|
1328
|
+
The full validation runs in `.github/workflows/release.yml` on version tags: `verify` on Node 20, 22 and 24, coverage and package checks on Node 24, and consumer tests on Node 20/24 with ESLint 9.22 and 10. Pull requests keep dependency review and CodeQL.
|
|
1235
1329
|
|
|
1236
1330
|
### Project structure
|
|
1237
1331
|
|
|
@@ -1254,13 +1348,9 @@ eslint-ai-guard/
|
|
|
1254
1348
|
│ │ ├── validateRelations.ts
|
|
1255
1349
|
│ │ ├── validateStructure.ts
|
|
1256
1350
|
│ │ └── presets/
|
|
1257
|
-
│ │ ├── frontend.ts
|
|
1258
|
-
│ │ ├── backend.ts
|
|
1259
|
-
│ │ ├── other.ts
|
|
1260
|
-
│ │ ├── helpers.ts
|
|
1261
|
-
│ │ └── index.ts
|
|
1262
1351
|
│ ├── utils/
|
|
1263
1352
|
│ └── rules/
|
|
1353
|
+
│ ├── constants.ts
|
|
1264
1354
|
│ ├── FilenamePascalCase.ts
|
|
1265
1355
|
│ ├── NoMultilineImports.ts
|
|
1266
1356
|
│ ├── ProjectSetup.ts
|
|
@@ -1270,11 +1360,18 @@ eslint-ai-guard/
|
|
|
1270
1360
|
├── test/
|
|
1271
1361
|
├── scripts/
|
|
1272
1362
|
│ └── TestConsumer.mjs
|
|
1363
|
+
├── docs/
|
|
1273
1364
|
├── .github/
|
|
1274
|
-
│
|
|
1275
|
-
│
|
|
1276
|
-
├──
|
|
1365
|
+
│ ├── workflows/
|
|
1366
|
+
│ │ ├── codeql.yml
|
|
1367
|
+
│ │ ├── dependency-review.yml
|
|
1368
|
+
│ │ └── release.yml
|
|
1369
|
+
│ ├── ISSUE_TEMPLATE/
|
|
1370
|
+
│ └── dependabot.yml
|
|
1277
1371
|
├── CHANGELOG.md
|
|
1372
|
+
├── CONTRIBUTING.md
|
|
1373
|
+
├── SECURITY.md
|
|
1374
|
+
├── CODE_OF_CONDUCT.md
|
|
1278
1375
|
├── eslint.config.mjs
|
|
1279
1376
|
├── tsconfig.json
|
|
1280
1377
|
├── tsup.config.ts
|
|
@@ -1284,28 +1381,53 @@ eslint-ai-guard/
|
|
|
1284
1381
|
|
|
1285
1382
|
### Adding a new rule
|
|
1286
1383
|
|
|
1287
|
-
1. Create `src/rules/MyRule.ts
|
|
1288
|
-
2.
|
|
1289
|
-
3.
|
|
1290
|
-
4.
|
|
1291
|
-
5. Add
|
|
1292
|
-
6.
|
|
1384
|
+
1. Create `src/rules/MyRule.ts` in PascalCase.
|
|
1385
|
+
2. Add the rule name to `src/rules/constants.ts`.
|
|
1386
|
+
3. Export it from `src/rules/index.ts`.
|
|
1387
|
+
4. Register it in `src/plugin.ts`.
|
|
1388
|
+
5. Add it to `src/configs/recommended.ts` if it should be enabled by default.
|
|
1389
|
+
6. Provide `meta.docs.description`, `meta.docs.url`, `meta.docs.recommended`, `meta.schema` and `meta.messages`.
|
|
1390
|
+
7. Add `meta.defaultOptions` when the rule accepts options.
|
|
1391
|
+
8. Add tests in `test/`.
|
|
1392
|
+
9. Run `yarn verify`.
|
|
1293
1393
|
|
|
1294
1394
|
## Publishing
|
|
1295
1395
|
|
|
1396
|
+
Releases are driven by a version tag. The workflow validates that the tag matches `package.json`, runs all checks, publishes to npm with provenance and creates a GitHub release.
|
|
1397
|
+
|
|
1398
|
+
1. Update `version` in `package.json`.
|
|
1399
|
+
2. Update `CHANGELOG.md`.
|
|
1400
|
+
3. Run `yarn test:release`.
|
|
1401
|
+
4. Commit and push the changes.
|
|
1402
|
+
5. Create and push a tag:
|
|
1403
|
+
|
|
1296
1404
|
```bash
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
npm run test:release
|
|
1300
|
-
npm version patch|minor|major
|
|
1301
|
-
npm publish --access public
|
|
1405
|
+
git tag v0.4.0
|
|
1406
|
+
git push origin v0.4.0
|
|
1302
1407
|
```
|
|
1303
1408
|
|
|
1304
|
-
|
|
1409
|
+
The release workflow requires the `NPM_TOKEN` repository secret. Provenance also requires `id-token: write`, which is already configured in `.github/workflows/release.yml`.
|
|
1410
|
+
|
|
1411
|
+
The workflow runs all checks before publishing. If any check fails, the publish job is skipped. Fix the problem, delete the tag and recreate it before pushing again:
|
|
1412
|
+
|
|
1413
|
+
```bash
|
|
1414
|
+
git tag -d v0.4.0
|
|
1415
|
+
git push origin :refs/tags/v0.4.0
|
|
1416
|
+
```
|
|
1417
|
+
|
|
1418
|
+
`prepack` runs `yarn build` automatically, so published packages always contain a fresh `dist`. The plugin version is injected from `package.json` during the build, so you do not need to edit `src/plugin.ts`.
|
|
1419
|
+
|
|
1420
|
+
## Contributing
|
|
1421
|
+
|
|
1422
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md) for setup, testing and rule-authoring guidelines. All participants are expected to follow the [Code of Conduct](CODE_OF_CONDUCT.md).
|
|
1423
|
+
|
|
1424
|
+
## Security
|
|
1425
|
+
|
|
1426
|
+
See [SECURITY.md](SECURITY.md) for supported versions and private vulnerability reporting.
|
|
1305
1427
|
|
|
1306
|
-
##
|
|
1428
|
+
## Articles
|
|
1307
1429
|
|
|
1308
|
-
|
|
1430
|
+
- [How I forced AI to follow the project standard with ESLint](docs/tabnews-eslint-plugin-ai-rules.md)
|
|
1309
1431
|
|
|
1310
1432
|
## License
|
|
1311
1433
|
|