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 CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 eslint-plugin-ai-rules
3
+ Copyright (c) 2026 Lucas Souza
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
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
- - [Legacy](#legacy)
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, the plugin prints a warning the first time it lints a file:
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
- [eslint-plugin-ai-rules] Project structure validation is not configured.
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 printed once per process.
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 warn.
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
- │ ├── components/*.tsx
735
- │ ├── components/ui/*.{ts,tsx}
736
- │ ├── constants/*.ts
737
- │ ├── contexts/*.tsx
738
- │ ├── env/index.ts
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
- │ │ └── tabs/<tab-kebab>/
750
- │ │ ├── *.tsx
751
- │ │ └── <section-kebab>/
752
- │ │ ├── *.tsx, *.ts
753
- │ │ ├── components/*.tsx
754
- │ │ └── contents/
755
- │ │ ├── *.tsx
756
- │ │ └── components/*.tsx
757
- │ ├── services/generated/** (ignored)
758
- │ ├── services/utils/*.ts
759
- │ └── utils/*.ts
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
- Prints the configuration warning described above.
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
- - Does not report lint messages
963
- - Warns once per process
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
- Override any bundled rule after the preset:
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
- ...aiRules.configs.projects([{ rootFolder: '.', preset: 'frontend' }]),
1065
+ ...tseslint.configs.recommended,
1066
+ ...aiRules.configs.projects([
1067
+ { rootFolder: '.', preset: 'frontend' },
1068
+ ]),
1040
1069
  {
1041
1070
  rules: {
1042
- '@stylistic/semi': ['error', 'always'],
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 <repo>
1299
+ git clone https://github.com/lvsouza/eslint-ai-guard.git
1208
1300
  cd eslint-ai-guard
1209
- npm install
1210
-
1211
- npm run typecheck # tsc --noEmit
1212
- npm test # node:test against dist
1213
- npm run lint # eslint .
1214
- npm run lint -- --fix
1215
- npm run build # tsup -> ESM + CJS + declarations
1216
- npm run dev # tsup --watch
1217
- npm run verify # typecheck + test + lint + pack
1218
- npm run test:coverage # c8 coverage with thresholds
1219
- npm run test:consumer # install packed tarball in a temp project
1220
- npm run test:package # publint + arethetypeswrong
1221
- npm run test:release # consumer + package checks
1222
- npm pack --dry-run # verify published files
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 npm run test:consumer
1231
- ESLINT_VERSION='^10.0.0' npm run test:consumer
1324
+ ESLINT_VERSION=9.22.0 yarn test:consumer
1325
+ ESLINT_VERSION='^10.0.0' yarn test:consumer
1232
1326
  ```
1233
1327
 
1234
- CI runs `verify`, coverage and consumer checks on Node 20, 22 and 24.
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
- │ └── workflows/
1275
- │ └── ci.yml
1276
- ├── eslint/
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. Export it from `src/rules/index.ts`.
1289
- 3. Register it in `src/plugin.ts`.
1290
- 4. Add it to `src/configs/recommended.ts` if it should be enabled by default.
1291
- 5. Add tests in `test/`.
1292
- 6. Run `npm run verify`.
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
- npm run verify
1298
- npm run test:coverage
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
- `prepublishOnly` runs `verify` and refuses to publish with any uncommitted, staged or untracked changes.
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
- ## Legacy
1428
+ ## Articles
1307
1429
 
1308
- `eslint/` keeps the three original rule implementations before packaging. Source of truth is `src/rules/`.
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