@shivaedev/quality 0.4.0 → 0.5.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.
Files changed (387) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +119 -29
  3. package/biome/declarations.json +17 -0
  4. package/biome/plugins/ambient-runtime.grit +18 -0
  5. package/biome/plugins/effect-fn-spans.grit +7 -0
  6. package/biome/preset.json +602 -0
  7. package/dist/baseline/compare.d.ts +8 -9
  8. package/dist/baseline/compare.d.ts.map +1 -1
  9. package/dist/baseline/compare.js +4 -4
  10. package/dist/baseline/compare.js.map +1 -1
  11. package/dist/baseline/format.d.ts +4 -4
  12. package/dist/baseline/format.d.ts.map +1 -1
  13. package/dist/baseline/format.js +3 -2
  14. package/dist/baseline/format.js.map +1 -1
  15. package/dist/baseline/guard.d.ts +3 -3
  16. package/dist/baseline/guard.d.ts.map +1 -1
  17. package/dist/baseline/guard.js +6 -5
  18. package/dist/baseline/guard.js.map +1 -1
  19. package/dist/baseline/legacy.d.ts +3 -3
  20. package/dist/baseline/legacy.d.ts.map +1 -1
  21. package/dist/baseline/legacy.js.map +1 -1
  22. package/dist/baseline/rewrite.d.ts +1 -1
  23. package/dist/baseline/rewrite.d.ts.map +1 -1
  24. package/dist/baseline/rewrite.js.map +1 -1
  25. package/dist/baseline/update.d.ts +8 -9
  26. package/dist/baseline/update.d.ts.map +1 -1
  27. package/dist/baseline/update.js +10 -9
  28. package/dist/baseline/update.js.map +1 -1
  29. package/dist/biome/report.d.ts +33 -0
  30. package/dist/biome/report.d.ts.map +1 -0
  31. package/dist/biome/report.js +25 -0
  32. package/dist/biome/report.js.map +1 -0
  33. package/dist/biome/run.d.ts +7 -0
  34. package/dist/biome/run.d.ts.map +1 -0
  35. package/dist/biome/run.js +16 -0
  36. package/dist/biome/run.js.map +1 -0
  37. package/dist/cli/args.d.ts +6 -3
  38. package/dist/cli/args.d.ts.map +1 -1
  39. package/dist/cli/args.js +9 -4
  40. package/dist/cli/args.js.map +1 -1
  41. package/dist/cli/baseline.d.ts +1 -1
  42. package/dist/cli/baseline.d.ts.map +1 -1
  43. package/dist/cli/baseline.js +3 -3
  44. package/dist/cli/baseline.js.map +1 -1
  45. package/dist/cli/check.js.map +1 -1
  46. package/dist/cli/fix.d.ts +4 -0
  47. package/dist/cli/fix.d.ts.map +1 -0
  48. package/dist/cli/fix.js +19 -0
  49. package/dist/cli/fix.js.map +1 -0
  50. package/dist/cli/lint.js +1 -1
  51. package/dist/cli/lint.js.map +1 -1
  52. package/dist/cli/run-main.d.ts.map +1 -1
  53. package/dist/cli/run-main.js +7 -3
  54. package/dist/cli/run-main.js.map +1 -1
  55. package/dist/cli.js +3 -0
  56. package/dist/cli.js.map +1 -1
  57. package/dist/config/decode.d.ts +4 -4
  58. package/dist/config/decode.js +12 -12
  59. package/dist/config/decode.js.map +1 -1
  60. package/dist/config/load.d.ts +3 -3
  61. package/dist/config/load.d.ts.map +1 -1
  62. package/dist/config/load.js +1 -1
  63. package/dist/config/load.js.map +1 -1
  64. package/dist/config/resolve.d.ts +3 -5
  65. package/dist/config/resolve.d.ts.map +1 -1
  66. package/dist/config/resolve.js +11 -5
  67. package/dist/config/resolve.js.map +1 -1
  68. package/dist/config.d.ts +9 -9
  69. package/dist/config.d.ts.map +1 -1
  70. package/dist/config.js.map +1 -1
  71. package/dist/decoded.d.ts +1 -1
  72. package/dist/decoded.d.ts.map +1 -1
  73. package/dist/engine/baseline-file.d.ts +1 -1
  74. package/dist/engine/baseline-file.d.ts.map +1 -1
  75. package/dist/engine/evaluate.d.ts +8 -9
  76. package/dist/engine/evaluate.d.ts.map +1 -1
  77. package/dist/engine/evaluate.js +4 -4
  78. package/dist/engine/evaluate.js.map +1 -1
  79. package/dist/engine/run-rules.d.ts +4 -3
  80. package/dist/engine/run-rules.d.ts.map +1 -1
  81. package/dist/engine/run-rules.js +3 -3
  82. package/dist/engine/run-rules.js.map +1 -1
  83. package/dist/engine/session.d.ts +3 -3
  84. package/dist/engine/session.d.ts.map +1 -1
  85. package/dist/engine/violation.d.ts +11 -3
  86. package/dist/engine/violation.d.ts.map +1 -1
  87. package/dist/engine/violation.js +6 -2
  88. package/dist/engine/violation.js.map +1 -1
  89. package/dist/exceptions/registry.d.ts +7 -8
  90. package/dist/exceptions/registry.d.ts.map +1 -1
  91. package/dist/exceptions/registry.js +6 -6
  92. package/dist/exceptions/registry.js.map +1 -1
  93. package/dist/git/base.d.ts +1 -1
  94. package/dist/git/base.d.ts.map +1 -1
  95. package/dist/git/base.js.map +1 -1
  96. package/dist/git/command.d.ts +3 -3
  97. package/dist/git/command.d.ts.map +1 -1
  98. package/dist/git/command.js.map +1 -1
  99. package/dist/git/history.d.ts +1 -1
  100. package/dist/git/history.d.ts.map +1 -1
  101. package/dist/git/history.js +1 -1
  102. package/dist/git/history.js.map +1 -1
  103. package/dist/imports/ambient.d.ts +7 -0
  104. package/dist/imports/ambient.d.ts.map +1 -0
  105. package/dist/imports/ambient.js +44 -0
  106. package/dist/imports/ambient.js.map +1 -0
  107. package/dist/imports/components.d.ts +2 -0
  108. package/dist/imports/components.d.ts.map +1 -0
  109. package/dist/imports/components.js +63 -0
  110. package/dist/imports/components.js.map +1 -0
  111. package/dist/imports/extract.d.ts +10 -0
  112. package/dist/imports/extract.d.ts.map +1 -0
  113. package/dist/imports/extract.js +100 -0
  114. package/dist/imports/extract.js.map +1 -0
  115. package/dist/imports/fences/dsl.d.ts +18 -0
  116. package/dist/imports/fences/dsl.d.ts.map +1 -0
  117. package/dist/imports/fences/dsl.js +14 -0
  118. package/dist/imports/fences/dsl.js.map +1 -0
  119. package/dist/imports/fences/evaluate.d.ts +12 -0
  120. package/dist/imports/fences/evaluate.d.ts.map +1 -0
  121. package/dist/imports/fences/evaluate.js +55 -0
  122. package/dist/imports/fences/evaluate.js.map +1 -0
  123. package/dist/imports/fences/match.d.ts +17 -0
  124. package/dist/imports/fences/match.d.ts.map +1 -0
  125. package/dist/imports/fences/match.js +106 -0
  126. package/dist/imports/fences/match.js.map +1 -0
  127. package/dist/imports/fences/model.d.ts +60 -0
  128. package/dist/imports/fences/model.d.ts.map +1 -0
  129. package/dist/imports/fences/model.js +2 -0
  130. package/dist/imports/fences/model.js.map +1 -0
  131. package/dist/imports/fences/policy.d.ts +5 -0
  132. package/dist/imports/fences/policy.d.ts.map +1 -0
  133. package/dist/imports/fences/policy.js +59 -0
  134. package/dist/imports/fences/policy.js.map +1 -0
  135. package/dist/imports/fences/reach.d.ts +12 -0
  136. package/dist/imports/fences/reach.d.ts.map +1 -0
  137. package/dist/imports/fences/reach.js +39 -0
  138. package/dist/imports/fences/reach.js.map +1 -0
  139. package/dist/imports/fences/selectors.d.ts +11 -0
  140. package/dist/imports/fences/selectors.d.ts.map +1 -0
  141. package/dist/imports/fences/selectors.js +27 -0
  142. package/dist/imports/fences/selectors.js.map +1 -0
  143. package/dist/imports/fences/vocabulary.d.ts +9 -0
  144. package/dist/imports/fences/vocabulary.d.ts.map +1 -0
  145. package/dist/imports/fences/vocabulary.js +40 -0
  146. package/dist/imports/fences/vocabulary.js.map +1 -0
  147. package/dist/imports/generated.d.ts +6 -0
  148. package/dist/imports/generated.d.ts.map +1 -0
  149. package/dist/imports/generated.js +78 -0
  150. package/dist/imports/generated.js.map +1 -0
  151. package/dist/imports/glob.d.ts +2 -0
  152. package/dist/imports/glob.d.ts.map +1 -0
  153. package/dist/imports/glob.js +125 -0
  154. package/dist/imports/glob.js.map +1 -0
  155. package/dist/imports/graph.d.ts +23 -0
  156. package/dist/imports/graph.d.ts.map +1 -0
  157. package/dist/imports/graph.js +56 -0
  158. package/dist/imports/graph.js.map +1 -0
  159. package/dist/imports/paths.d.ts +2 -0
  160. package/dist/imports/paths.d.ts.map +1 -0
  161. package/dist/imports/paths.js +24 -0
  162. package/dist/imports/paths.js.map +1 -0
  163. package/dist/imports/pnpm-workspace.d.ts +2 -0
  164. package/dist/imports/pnpm-workspace.d.ts.map +1 -0
  165. package/dist/imports/pnpm-workspace.js +122 -0
  166. package/dist/imports/pnpm-workspace.js.map +1 -0
  167. package/dist/imports/projects.d.ts +10 -0
  168. package/dist/imports/projects.d.ts.map +1 -0
  169. package/dist/imports/projects.js +83 -0
  170. package/dist/imports/projects.js.map +1 -0
  171. package/dist/imports/resolve.d.ts +16 -0
  172. package/dist/imports/resolve.d.ts.map +1 -0
  173. package/dist/imports/resolve.js +88 -0
  174. package/dist/imports/resolve.js.map +1 -0
  175. package/dist/imports/workspace.d.ts +10 -0
  176. package/dist/imports/workspace.d.ts.map +1 -0
  177. package/dist/imports/workspace.js +55 -0
  178. package/dist/imports/workspace.js.map +1 -0
  179. package/dist/index.d.ts +3 -0
  180. package/dist/index.d.ts.map +1 -1
  181. package/dist/index.js +2 -0
  182. package/dist/index.js.map +1 -1
  183. package/dist/inventory/collect.d.ts +6 -6
  184. package/dist/inventory/collect.d.ts.map +1 -1
  185. package/dist/inventory/collect.js.map +1 -1
  186. package/dist/manifests/sorted.d.ts +14 -0
  187. package/dist/manifests/sorted.d.ts.map +1 -0
  188. package/dist/manifests/sorted.js +39 -0
  189. package/dist/manifests/sorted.js.map +1 -0
  190. package/dist/report/guard.d.ts +1 -1
  191. package/dist/report/guard.d.ts.map +1 -1
  192. package/dist/report/guard.js +1 -1
  193. package/dist/report/guard.js.map +1 -1
  194. package/dist/report/render.d.ts +2 -2
  195. package/dist/report/render.d.ts.map +1 -1
  196. package/dist/report/render.js.map +1 -1
  197. package/dist/report/stale.d.ts +2 -2
  198. package/dist/report/stale.d.ts.map +1 -1
  199. package/dist/report/stale.js.map +1 -1
  200. package/dist/rule.d.ts +12 -11
  201. package/dist/rule.d.ts.map +1 -1
  202. package/dist/rule.js.map +1 -1
  203. package/dist/rules/biome.d.ts +4 -0
  204. package/dist/rules/biome.d.ts.map +1 -0
  205. package/dist/rules/biome.js +40 -0
  206. package/dist/rules/biome.js.map +1 -0
  207. package/dist/rules/built-in.d.ts +8 -10
  208. package/dist/rules/built-in.d.ts.map +1 -1
  209. package/dist/rules/built-in.js +12 -0
  210. package/dist/rules/built-in.js.map +1 -1
  211. package/dist/rules/comments/kinds.d.ts +1 -2
  212. package/dist/rules/comments/kinds.d.ts.map +1 -1
  213. package/dist/rules/comments/kinds.js +7 -16
  214. package/dist/rules/comments/kinds.js.map +1 -1
  215. package/dist/rules/comments/max-per-file.d.ts +1 -1
  216. package/dist/rules/comments/max-per-file.js +11 -11
  217. package/dist/rules/comments/max-per-file.js.map +1 -1
  218. package/dist/rules/comments/no-banner.js +2 -2
  219. package/dist/rules/comments/no-banner.js.map +1 -1
  220. package/dist/rules/comments/no-environment-pragma.d.ts +2 -0
  221. package/dist/rules/comments/no-environment-pragma.d.ts.map +1 -0
  222. package/dist/rules/comments/no-environment-pragma.js +8 -0
  223. package/dist/rules/comments/no-environment-pragma.js.map +1 -0
  224. package/dist/rules/comments/no-jsdoc.js +3 -3
  225. package/dist/rules/comments/no-jsdoc.js.map +1 -1
  226. package/dist/rules/comments/no-line-reference.js +2 -2
  227. package/dist/rules/comments/no-line-reference.js.map +1 -1
  228. package/dist/rules/comments/no-pr-reference.js +6 -6
  229. package/dist/rules/comments/no-pr-reference.js.map +1 -1
  230. package/dist/rules/comments/no-todo.js +2 -2
  231. package/dist/rules/comments/no-todo.js.map +1 -1
  232. package/dist/rules/comments/pattern-rule.d.ts +2 -2
  233. package/dist/rules/comments/pattern-rule.d.ts.map +1 -1
  234. package/dist/rules/comments/pattern-rule.js +2 -2
  235. package/dist/rules/comments/pattern-rule.js.map +1 -1
  236. package/dist/rules/comments/scan.d.ts +6 -6
  237. package/dist/rules/comments/scan.d.ts.map +1 -1
  238. package/dist/rules/comments/scan.js +2 -2
  239. package/dist/rules/comments/scan.js.map +1 -1
  240. package/dist/rules/imports/cycles.d.ts +2 -0
  241. package/dist/rules/imports/cycles.d.ts.map +1 -0
  242. package/dist/rules/imports/cycles.js +38 -0
  243. package/dist/rules/imports/cycles.js.map +1 -0
  244. package/dist/rules/imports/fences.d.ts +5 -0
  245. package/dist/rules/imports/fences.d.ts.map +1 -0
  246. package/dist/rules/imports/fences.js +24 -0
  247. package/dist/rules/imports/fences.js.map +1 -0
  248. package/dist/rules/imports/resolvable.d.ts +4 -0
  249. package/dist/rules/imports/resolvable.d.ts.map +1 -0
  250. package/dist/rules/imports/resolvable.js +22 -0
  251. package/dist/rules/imports/resolvable.js.map +1 -0
  252. package/dist/rules/manifests-sorted.d.ts +2 -0
  253. package/dist/rules/manifests-sorted.d.ts.map +1 -0
  254. package/dist/rules/manifests-sorted.js +22 -0
  255. package/dist/rules/manifests-sorted.js.map +1 -0
  256. package/dist/rules/max-lines.js +4 -4
  257. package/dist/rules/max-lines.js.map +1 -1
  258. package/dist/rules/suppressions/biome/configs.d.ts +6 -6
  259. package/dist/rules/suppressions/biome/configs.d.ts.map +1 -1
  260. package/dist/rules/suppressions/biome/configs.js +2 -2
  261. package/dist/rules/suppressions/biome/configs.js.map +1 -1
  262. package/dist/rules/suppressions/biome/declarations.d.ts +4 -4
  263. package/dist/rules/suppressions/biome/declarations.d.ts.map +1 -1
  264. package/dist/rules/suppressions/biome/declarations.js +3 -3
  265. package/dist/rules/suppressions/biome/declarations.js.map +1 -1
  266. package/dist/rules/suppressions/biome/json.d.ts +2 -2
  267. package/dist/rules/suppressions/biome/json.d.ts.map +1 -1
  268. package/dist/rules/suppressions/biome/json.js +1 -1
  269. package/dist/rules/suppressions/biome/json.js.map +1 -1
  270. package/dist/rules/suppressions/biome/resolve.js +3 -3
  271. package/dist/rules/suppressions/biome/resolve.js.map +1 -1
  272. package/dist/rules/suppressions/biome/weakenings.d.ts +4 -4
  273. package/dist/rules/suppressions/biome/weakenings.d.ts.map +1 -1
  274. package/dist/rules/suppressions/biome/weakenings.js.map +1 -1
  275. package/dist/rules/suppressions/biome-overrides.d.ts +1 -1
  276. package/dist/rules/suppressions/biome-overrides.js +4 -4
  277. package/dist/rules/suppressions/biome-overrides.js.map +1 -1
  278. package/dist/rules/suppressions/directives.d.ts +1 -1
  279. package/dist/rules/suppressions/directives.d.ts.map +1 -1
  280. package/dist/rules/suppressions/directives.js +11 -11
  281. package/dist/rules/suppressions/directives.js.map +1 -1
  282. package/dist/rules/suppressions/no-double-cast.js +2 -2
  283. package/dist/rules/suppressions/no-double-cast.js.map +1 -1
  284. package/dist/rules/suppressions/no-inline.d.ts +1 -7
  285. package/dist/rules/suppressions/no-inline.d.ts.map +1 -1
  286. package/dist/rules/suppressions/no-inline.js +7 -30
  287. package/dist/rules/suppressions/no-inline.js.map +1 -1
  288. package/dist/rules/suppressions/stylesheet-comments.d.ts +1 -1
  289. package/dist/rules/suppressions/stylesheet-comments.d.ts.map +1 -1
  290. package/dist/rules/suppressions/stylesheet-comments.js +3 -3
  291. package/dist/rules/suppressions/stylesheet-comments.js.map +1 -1
  292. package/dist/rules/syntax.js +4 -4
  293. package/dist/rules/syntax.js.map +1 -1
  294. package/dist/standard-schema.d.ts +1 -1
  295. package/dist/standard-schema.d.ts.map +1 -1
  296. package/dist/vitest.d.ts +3 -0
  297. package/dist/vitest.d.ts.map +1 -0
  298. package/dist/vitest.js +20 -0
  299. package/dist/vitest.js.map +1 -0
  300. package/package.json +46 -31
  301. package/src/baseline/compare.ts +10 -15
  302. package/src/baseline/format.ts +8 -6
  303. package/src/baseline/guard.ts +11 -10
  304. package/src/baseline/legacy.ts +3 -3
  305. package/src/baseline/rewrite.ts +1 -1
  306. package/src/baseline/update.ts +21 -21
  307. package/src/biome/report.ts +35 -0
  308. package/src/biome/run.ts +23 -0
  309. package/src/cli/args.ts +14 -8
  310. package/src/cli/baseline.ts +5 -6
  311. package/src/cli/check.ts +1 -1
  312. package/src/cli/fix.ts +19 -0
  313. package/src/cli/lint.ts +1 -1
  314. package/src/cli/run-main.ts +8 -3
  315. package/src/cli.ts +3 -0
  316. package/src/config/decode.ts +12 -12
  317. package/src/config/load.ts +4 -4
  318. package/src/config/resolve.ts +15 -11
  319. package/src/config.ts +9 -9
  320. package/src/decoded.ts +1 -1
  321. package/src/engine/baseline-file.ts +1 -1
  322. package/src/engine/evaluate.ts +14 -16
  323. package/src/engine/run-rules.ts +8 -7
  324. package/src/engine/session.ts +3 -3
  325. package/src/engine/violation.ts +18 -4
  326. package/src/exceptions/registry.ts +10 -16
  327. package/src/git/base.ts +2 -2
  328. package/src/git/command.ts +3 -3
  329. package/src/git/history.ts +2 -2
  330. package/src/imports/ambient.ts +54 -0
  331. package/src/imports/components.ts +80 -0
  332. package/src/imports/extract.ts +129 -0
  333. package/src/imports/fences/dsl.ts +33 -0
  334. package/src/imports/fences/evaluate.ts +75 -0
  335. package/src/imports/fences/match.ts +148 -0
  336. package/src/imports/fences/model.ts +42 -0
  337. package/src/imports/fences/policy.ts +70 -0
  338. package/src/imports/fences/reach.ts +62 -0
  339. package/src/imports/fences/selectors.ts +37 -0
  340. package/src/imports/fences/vocabulary.ts +51 -0
  341. package/src/imports/generated.ts +95 -0
  342. package/src/imports/glob.ts +142 -0
  343. package/src/imports/graph.ts +81 -0
  344. package/src/imports/paths.ts +28 -0
  345. package/src/imports/pnpm-workspace.ts +134 -0
  346. package/src/imports/projects.ts +106 -0
  347. package/src/imports/resolve.ts +115 -0
  348. package/src/imports/workspace.ts +76 -0
  349. package/src/index.ts +3 -0
  350. package/src/inventory/collect.ts +6 -6
  351. package/src/manifests/sorted.ts +46 -0
  352. package/src/report/guard.ts +2 -2
  353. package/src/report/render.ts +9 -9
  354. package/src/report/stale.ts +3 -3
  355. package/src/rule.ts +13 -12
  356. package/src/rules/biome.ts +47 -0
  357. package/src/rules/built-in.ts +12 -0
  358. package/src/rules/comments/kinds.ts +11 -21
  359. package/src/rules/comments/max-per-file.ts +13 -13
  360. package/src/rules/comments/no-banner.ts +2 -2
  361. package/src/rules/comments/no-environment-pragma.ts +9 -0
  362. package/src/rules/comments/no-jsdoc.ts +3 -3
  363. package/src/rules/comments/no-line-reference.ts +2 -2
  364. package/src/rules/comments/no-pr-reference.ts +6 -6
  365. package/src/rules/comments/no-todo.ts +2 -2
  366. package/src/rules/comments/pattern-rule.ts +6 -6
  367. package/src/rules/comments/scan.ts +13 -13
  368. package/src/rules/imports/cycles.ts +44 -0
  369. package/src/rules/imports/fences.ts +27 -0
  370. package/src/rules/imports/resolvable.ts +23 -0
  371. package/src/rules/manifests-sorted.ts +23 -0
  372. package/src/rules/max-lines.ts +6 -6
  373. package/src/rules/suppressions/biome/configs.ts +12 -12
  374. package/src/rules/suppressions/biome/declarations.ts +7 -7
  375. package/src/rules/suppressions/biome/json.ts +3 -3
  376. package/src/rules/suppressions/biome/resolve.ts +3 -3
  377. package/src/rules/suppressions/biome/weakenings.ts +18 -19
  378. package/src/rules/suppressions/biome-overrides.ts +7 -7
  379. package/src/rules/suppressions/directives.ts +12 -12
  380. package/src/rules/suppressions/no-double-cast.ts +4 -4
  381. package/src/rules/suppressions/no-inline.ts +13 -37
  382. package/src/rules/suppressions/stylesheet-comments.ts +4 -4
  383. package/src/rules/syntax.ts +4 -4
  384. package/src/standard-schema.ts +1 -1
  385. package/src/vitest.ts +22 -0
  386. package/tsconfig/base.json +21 -21
  387. package/tsconfig/package.json +2 -2
package/CHANGELOG.md CHANGED
@@ -1,5 +1,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.5.0 - 2026-10-04
4
+
5
+ ### Added
6
+
7
+ - Add the Biome preset `@shivaedev/quality/biome`. It sets the formatting (tabs, a line width of 150, double quotes), every rule Biome recommends at `error`, a list of stricter rules such as `noUnsafeTypeAssertion`, `useBlockStatements`, `noEqualsToNull`, `useConsistentArrayType` with `readonly T[]`, `noFloatingPromises` and `useExhaustiveSwitchCases`, sorted keys in JSON and object literals, and the GritQL plugins that ban ambient time, randomness, `console` and `process.env` and check `Effect.fn` span names. Its `declarations.json` declares the rules it turns off.
8
+ - Add the `biome` rule. It runs Biome, now a dependency pinned to 2.5.14, and reports each finding as `biome/<category>`, so Biome's findings take part in the baseline. `adopt: ["biome"]` adopts all of them. It also asks for a root Biome config that extends the preset. Like every rule it is an error by default, so a repository that upgrades extends the preset and adopts `biome` into its baseline.
9
+ - Add `quality fix`, which sorts every `package.json` and applies Biome's safe fixes, assist actions and formatting.
10
+ - Add the `manifests/sorted` rule. It reports every `package.json` in the repository whose keys are not in the order of sort-package-json, now a dependency pinned to 4.0.0, and every `package.json` that is not valid JSON.
11
+ - Add `@shivaedev/quality/vitest`. Its `testProjects()` sets up Vitest projects by file name: `unit` runs `*.test.ts` files in Node, `dom` runs `*.dom.test.ts` and `*.dom.test.tsx` files in happy-dom, and `slow` runs `*.slow.test.ts` files only when `--project slow` asks for it. Type tests (`*.typecheck.test.ts`) never run. `vitest` is an optional peer dependency.
12
+ - Add `comments/no-environment-pragma`, which reports a test environment set by a Vitest or Jest environment pragma. A DOM test is named `*.dom.test.ts` instead.
13
+ - Add `imports/cycles` and `imports/resolvable`, which read the import graph of the sources with the TypeScript compiler. `imports/cycles` reports each group of modules that import each other at run time, ignoring type-only imports, and takes no registry exceptions. `imports/resolvable` reports an import that resolves to nothing; its `generated` option names the folders where a relative import of a missing file is generated output. Like every rule they are errors by default, so a repository that upgrades baselines what they find. A run whose sources hold no module fails instead of passing on an empty graph.
14
+ - Add `imports/fences` and the `fence()` builder for declaring import fences in the config without patterns: `fence(name).because(reason).from(target)` with `mayNotImport`, `mayNotReach` or `mayImportOnly(...).of(...)`, demonstrated by an illegal and a legal example that the rule checks against the policy. Targets are `packages`, `folders`, `files`, `modules`, `scopes`, `anyOf`, `workspace` and `anything`, each with `.except`, and every name must exist.
15
+
16
+ ### Changed
17
+
18
+ - `suppressions/no-inline` allows `@ts-expect-error` in type tests by their file name, `*.typecheck.test.ts` or `typecheck.test.ts`, and takes no options. The `declared` option is gone, so a config that sets it fails to load until it is removed.
19
+ - The `allow` lists of `comments/no-jsdoc` and `comments/max-per-file` are empty by default, so a tool pragma counts as a comment until the config allows its tag.
20
+
21
+ ### Fixed
22
+
23
+ - Write all of a long report before exiting when the output is a pipe, instead of cutting it off.
24
+
3
25
  ## 0.4.0 - 2026-10-03
4
26
 
5
27
  ### Added
package/README.md CHANGED
@@ -61,15 +61,16 @@ The config is typed: an unknown rule id, a misspelled option or an option of the
61
61
 
62
62
  ### Comments
63
63
 
64
- A comment says why, never what the code already says or what it used to be. Six rules hold every comment to that:
64
+ A comment says why, never what the code already says or what it used to be. Seven rules hold every comment to that:
65
65
 
66
66
  | Rule | Reports | Options |
67
67
  | --- | --- | --- |
68
- | `comments/no-jsdoc` | Every `/** */` block, except a tool pragma | `allow` |
68
+ | `comments/no-jsdoc` | Every `/** */` block, except a tool pragma the config allows | `allow` |
69
69
  | `comments/no-line-reference` | A line number: `file.ts:42`, `file.ts#L42`, `line 42` | none |
70
70
  | `comments/no-pr-reference` | A pull request or issue: `#123`, `PR 123`, `MR 123`, `pull request 123`, `merge request 123`, `issue 123`, `ticket 123`, `/pull/123`, `/pulls/123`, `/issues/123`, `/merge_requests/123`, `GH-123` | none |
71
71
  | `comments/no-banner` | A banner, divider or region: a line that starts or ends with three or more of `- = * # ~ _ + / \ ─ ━ ═ ┄ ┈`, `#region`, `#endregion` | none |
72
72
  | `comments/no-todo` | `TODO`, `FIXME`, `XXX` and `@todo` | none |
73
+ | `comments/no-environment-pragma` | A test environment set by a `@vitest-environment` or `@jest-environment` pragma (and its `-options`); name the file `*.dom.test.ts` instead, see [Vitest projects](#vitest-projects) | none |
73
74
  | `comments/max-per-file` | A file with more than `max` comments, 2 by default | `max`, `allow` |
74
75
 
75
76
  The rules find comments with the TypeScript parser, so text inside strings, template literals, regular expressions and JSX never counts as a comment. They read the TypeScript and JavaScript modules among the sources and skip declaration files and the directives listed below. Each finding names the line its comment starts on.
@@ -80,14 +81,14 @@ The default is no comments at all: a comment states only what the code cannot sh
80
81
 
81
82
  - A block comment counts once, however many lines it spans.
82
83
  - Line comments that each stand alone on adjacent lines form one run and count once. A blank line, code, a directive, or a comment after code on the same line starts a new one.
83
- - Tool pragmas and directives are not counted: compiler and linter directives (`@ts-…`, triple-slash directives such as `/// <reference …>`, `biome-ignore…`, `eslint-disable…`, `eslint-enable…`, `oxlint-…`, `stylelint-…`, `deno-lint-ignore…`, `tslint:disable…`, `prettier-ignore`, Flow's `$FlowFixMe`, `$FlowIgnore`, `$FlowExpectedError`, `$FlowIssue` and `@noflow`), bundler annotations (`#__PURE__`, `@__PURE__`, `#__NO_SIDE_EFFECTS__`, `@__NO_SIDE_EFFECTS__`) and coverage hints (`c8 ignore`, `v8 ignore`, `istanbul ignore`). The suppression rules below report the directives that silence a check.
84
+ - Allowed tool pragmas and directives are not counted: compiler and linter directives (`@ts-…`, triple-slash directives such as `/// <reference …>`, `biome-ignore…`, `eslint-disable…`, `eslint-enable…`, `oxlint-…`, `stylelint-…`, `deno-lint-ignore…`, `tslint:disable…`, `prettier-ignore`, Flow's `$FlowFixMe`, `$FlowIgnore`, `$FlowExpectedError`, `$FlowIssue` and `@noflow`), bundler annotations (`#__PURE__`, `@__PURE__`, `#__NO_SIDE_EFFECTS__`, `@__NO_SIDE_EFFECTS__`) and coverage hints (`c8 ignore`, `v8 ignore`, `istanbul ignore`). The suppression rules below report the directives that silence a check.
84
85
 
85
86
  A file over the limit counts one violation for each comment above it: 5 comments against a limit of 2 count 3. A finding names the first comment over the limit.
86
87
 
87
- A tool pragma is a comment whose every line starts with an allowed tag, such as `/** @vitest-environment happy-dom */`. `allow` lists the tags and defaults to `@vitest-environment`, `@vitest-environment-options`, `@jest-environment`, `@jsx`, `@jsxFrag`, `@jsxImportSource` and `@jsxRuntime`. A list given replaces the default, and `comments/no-jsdoc` and `comments/max-per-file` each take their own, so give both the same list:
88
+ A tool pragma is a comment whose every line starts with an allowed tag, such as `/** @jsxImportSource preact */`. `allow` lists the tags and is empty by default, so a pragma counts as a comment until the config allows its tag. Settings that a pragma would repeat in each file belong in the tool's config. `comments/no-jsdoc` and `comments/max-per-file` each take their own list, so give both the same one:
88
89
 
89
90
  ```ts
90
- const pragmas = ["@vitest-environment", "@license"];
91
+ const pragmas = ["@jsxImportSource", "@license"];
91
92
 
92
93
  export default defineConfig({
93
94
  rules: {
@@ -105,7 +106,7 @@ A check that is silenced at one site hides the problem instead of fixing it. Thr
105
106
 
106
107
  | Rule | Reports | Options |
107
108
  | --- | --- | --- |
108
- | `suppressions/no-inline` | Every comment directive that silences a linter, the compiler or a formatter, except a declared `@ts-expect-error` | `declared` |
109
+ | `suppressions/no-inline` | Every comment directive that silences a linter, the compiler or a formatter, except `@ts-expect-error` in a type test | none |
109
110
  | `suppressions/no-double-cast` | A cast through `unknown`, `any` or `never`: `x as unknown as T`, `x as any as T`, `x as never as T`, `<T><unknown>x` | none |
110
111
  | `suppressions/biome-overrides` | A Biome setting that turns a check off or down, or keeps files out of it, without a declaration, and a declaration that matches no setting | `declared` |
111
112
 
@@ -119,29 +120,9 @@ A check that is silenced at one site hides the problem instead of fixing it. Thr
119
120
 
120
121
  Coverage hints (`c8 ignore`, `v8 ignore`, `istanbul ignore`) are allowed: they leave code out of a coverage measure and silence no linter or compiler. The rule reads the TypeScript and JavaScript modules among the sources, declaration files included, and every `.css`, `.scss` and `.less` file among the checked files, whatever `extensions` says. Each finding names the line its comment starts on and has the directive as its subject.
121
122
 
122
- #### Declared type tests
123
+ #### Type tests
123
124
 
124
- A type test proves that an API rejects what its types forbid, and TypeScript asserts a compile error only through `@ts-expect-error`, which fails as soon as the error it expects goes away. So `@ts-expect-error`, and no other directive, may be declared for a set of files:
125
-
126
- ```ts
127
- export default defineConfig({
128
- rules: {
129
- "suppressions/no-inline": {
130
- options: {
131
- declared: [
132
- {
133
- directive: "@ts-expect-error",
134
- includes: ["*.typecheck.ts"],
135
- reason: "Type tests assert the compile errors the public types must raise.",
136
- },
137
- ],
138
- },
139
- },
140
- },
141
- });
142
- ```
143
-
144
- `includes` takes `.gitignore` patterns, like `exclude`. `@ts-ignore`, `@ts-nocheck` and every linter and formatter directive stay reported in those files. A declaration that matches no `@ts-expect-error` is reported against `quality.config.ts` until it is removed. A test that must pass a rejected value at run time, to prove the runtime refuses it too, calls the API through `Reflect.apply` instead of a directive.
125
+ A type test proves that an API rejects what its types forbid, and TypeScript asserts a compile error only through `@ts-expect-error`, which fails as soon as the error it expects goes away. So `@ts-expect-error`, and no other directive, is allowed in a type test: a file named `*.typecheck.test.ts` or `typecheck.test.ts` (or `.tsx`). The compiler checks these files; [Vitest projects](#vitest-projects) never run them. `@ts-ignore`, `@ts-nocheck` and every linter and formatter directive stay reported in them. A test that must pass a rejected value at run time, to prove the runtime refuses it too, calls the API through `Reflect.apply` instead of a directive.
145
126
 
146
127
  `suppressions/no-double-cast` finds casts with the TypeScript parser, through parentheses and in either assertion syntax. A single cast is left to the linter, and `as const` is not a cast.
147
128
 
@@ -214,6 +195,69 @@ A package that ships a preset declares the weakenings the preset makes in a `dec
214
195
 
215
196
  A weakening the preset makes without such a declaration is reported at the line of the repository's `extends` entry, and the repository's own declaration covers it. A weakening the repository adds beyond the preset needs its own declaration, and a repository declaration that repeats one the preset ships is reported until it is removed. A preset entry that cannot be resolved or read, or whose `declarations.json` is invalid, is reported at the `extends` entry as well.
216
197
 
198
+ ### Imports
199
+
200
+ Three rules read the import graph of the TypeScript and JavaScript modules among the sources. They build it once per run with the TypeScript compiler, without a bundler or another dependency.
201
+
202
+ | Rule | Reports | Options |
203
+ | --- | --- | --- |
204
+ | `imports/cycles` | Modules that import each other at run time | none |
205
+ | `imports/resolvable` | An import that resolves to nothing | `generated` |
206
+ | `imports/fences` | An import that crosses a fence the config declares | `fences` |
207
+
208
+ Each import resolves the way the compiler resolves it, with the options of the nearest `tsconfig.json` and the projects it references, under bundler resolution: `paths`, `package.json` `imports` and `exports` and the `source` condition hold, so a workspace package resolves to its source. The graph reads static and dynamic imports, `export ... from`, `require()`, `require.resolve()`, `import.meta.resolve()` of a bare specifier (a relative one is URL arithmetic that never checks the path), `import()` types, `/// <reference types>`, `/// <reference path>` and JSDoc `@import` tags.
209
+
210
+ - An import of a stylesheet, an image or JSON resolves to the file, and only when the file exists, whatever declaration describes it. A Node builtin resolves.
211
+ - A runtime import must resolve to code: a declaration file (`.d.ts`, `.d.mts`, `.d.cts`, or an asset declaration such as `.d.css.ts`) satisfies only `import type` and `export type`, however the import reaches it, so a package that has only its `@types` package installed, or an `exports` entry that points at a declaration, is reported.
212
+ - A bare import resolves when a declaration file of the importer's tsconfig project declares the module in a script (`declare module "virtual:*"`). A relative import always needs a real file, `declare module "*"` and patterns with more than one `*` never count, and a `declare module` inside a module is an augmentation, which declares nothing new.
213
+ - A relative import of a missing file resolves only inside a folder that `generated` names, such as a client a generator writes before the tests run. Each folder must be ignored by git, or at least every file an import names in it must be, hold no file git tracks but a `.gitkeep` or `.keep` placeholder, lie outside `node_modules` and hold a file that an import names. The import stays an edge to its path, so fences apply to it before the file exists.
214
+ - A module that resolves into `node_modules` or outside the root is external, and its package is the one it resolves into, whatever alias the import uses. A `@types` package counts as the package it describes: `@types/hast` is `hast`, `@types/scope__name` is `@scope/name`.
215
+
216
+ ```ts
217
+ "imports/resolvable": { options: { generated: ["packages/db/test/generated"] } },
218
+ ```
219
+
220
+ `imports/cycles` reports each group of modules that import each other at run time once, at the alphabetically first of them, with one loop through the group. Its count is the number of modules in the group. `import type`, `export type`, type references and imports in declaration files are left out; `import { type X }` stays a runtime import. Dynamic `import()` and `require()` count; `require.resolve()` does not. It takes no registry exceptions. Each finding of `imports/resolvable` has the import as its subject.
221
+
222
+ The gate fails closed: when the sources hold no module at all, the imports rules stop the run instead of passing on an empty graph. Point `sources` at the code, or turn the rules off.
223
+
224
+ #### Fences
225
+
226
+ A fence is one prohibition, stated in the config without patterns:
227
+
228
+ ```ts
229
+ import { defineConfig, external, fence, folders, packages } from "@shivaedev/quality";
230
+
231
+ const fences = [
232
+ fence("ui-never-imports-server")
233
+ .because("The UI ships to browsers.")
234
+ .from(folders("packages/ui/src"))
235
+ .mayNotImport(packages("server"))
236
+ .demonstratedBy({
237
+ illegal: ["packages/ui/src/index.ts", "packages/server/src/index.ts"],
238
+ legal: ["packages/ui/src/index.ts", external("effect")],
239
+ }),
240
+ ];
241
+
242
+ export default defineConfig({ rules: { "imports/fences": { options: { fences } } } });
243
+ ```
244
+
245
+ A fence has a name, a reason, the modules it holds (`from`) and one prohibition:
246
+
247
+ - `mayNotImport(target)`: no module it holds imports the target.
248
+ - `mayNotReach(target)`: nothing a module it holds imports, directly or through other modules of the repository, is the target. The finding names the path.
249
+ - `mayImportOnly(...subjects).of(unit)`: the modules it holds import only the named modules or folders directly in a package's `src` folder (or the package folder) or in a folder.
250
+
251
+ Targets are `packages(...)` (workspace packages by name, with or without their scope; a workspace package is a named `package.json` that `pnpm-workspace.yaml` or the root `package.json` `workspaces` includes, with `*`, `**`, `?`, `{a,b}` and `[...]` in its patterns, none of which match a folder whose name starts with `.` unless the pattern spells the dot, and a `packages` list or pattern the gate cannot read stops the run, and it holds every file below it that no deeper workspace package holds), `folders(...)`, `files(...)`, `modules(...)` (external packages by package name, and Node builtins), `scopes(...)` (every external package of a scope), `anyOf(...)`, `workspace` (every workspace package) and `anything`. Each takes `.except(...)`.
252
+
253
+ The config does not compile without `demonstratedBy`, and the rule checks the examples against the policy: each is a chain of imports from a file of the repository, which may end in `external(name)`. The illegal example must cross this fence and no other; the legal example must cross none. Every name a fence uses must exist: a package, a folder that holds checked files, a checked file, a subject of the unit. Two fences may not share a name, and each needs a reason. A policy that breaks any of this stops the run. Fences count type imports too.
254
+
255
+ A finding has its fence's name as its subject, so a registry entry with that subject excuses one file from one fence.
256
+
257
+ ### Manifests
258
+
259
+ `manifests/sorted` keeps every `package.json` in the repository in the key order of [sort-package-json](https://github.com/keithamus/sort-package-json), a dependency of this package. It walks the whole repository, not only the sources, and skips files ignored by git and `node_modules`. A manifest that is not valid JSON is reported too. `quality fix` sorts the manifests, and the rule takes no registry exceptions.
260
+
217
261
  ### Local rules
218
262
 
219
263
  ```ts
@@ -314,6 +358,7 @@ An entry covers a rule's violations in one file, for good, and must say why. Wit
314
358
 
315
359
  ```text
316
360
  quality lint [--config <file>] [--warnings summary|all]
361
+ quality fix [--config <file>]
317
362
  quality baseline write [--config <file>] [--rule <id>]...
318
363
  quality baseline prune [--config <file>] [--against <ref>]
319
364
  quality baseline tighten [--config <file>] [--staged]
@@ -329,6 +374,51 @@ quality baseline migrate [--config <file>] [--from <file>]
329
374
  | 1 | Failed: an uncovered error-level violation, a baselined file that got worse, a stale registry entry, a baseline entry for a rule that is off or unknown, or a baseline that grew against the merge base. |
330
375
  | 2 | Could not run: no or invalid config, an invalid baseline or registry, a baseline left in the earlier format, a missing source, a rule that threw, git history the check cannot read, or a usage error. |
331
376
 
377
+ ## Biome preset
378
+
379
+ `@shivaedev/quality/biome` is one Biome setup for every repository. Biome is a dependency of this package, pinned to an exact version, and `quality` runs it, so a repository needs no Biome install of its own. The root `biome.json` extends the preset and adds only what is the repository's own:
380
+
381
+ ```json
382
+ {
383
+ "$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
384
+ "extends": ["@shivaedev/quality/biome"]
385
+ }
386
+ ```
387
+
388
+ The preset sets:
389
+
390
+ - **Formatting:** tabs, a line width of 150, double quotes, semicolons, trailing commas and operators at the start of a wrapped line.
391
+ - **Lint:** every rule Biome recommends, at `error`, and a list of stricter rules on top, among them `noUnsafeTypeAssertion`, `useBlockStatements`, `noEqualsToNull`, `useNumericSeparators`, `useUnicodeRegex`, `useLiteralKeys`, `readonly T[]` arrays, `noFloatingPromises`, `noMisusedPromises`, `useExhaustiveSwitchCases`, `useExhaustiveDependencies`, `it` for every test, function declarations over function expressions, interfaces for object types, a cognitive complexity limit of 15, no nested ternaries, no barrel files and no `export *`.
392
+ - **Assist:** organized imports and sorted keys, attributes, enum members, interface members and properties. Keys are sorted in JSON and in object literals alike; `package.json` is left out, because `manifests/sorted` gives it the order npm users expect.
393
+ - **Plugins:** GritQL rules that ban ambient time, randomness, `console` and `process.env` for Effect's services, and that ask `Effect.fn` for a literal span name shaped `Owner.operation`. They load from `./node_modules/@shivaedev/quality/biome/plugins`, so the package must be installed at the repository root.
394
+ - Files ignored by git are skipped.
395
+
396
+ The preset turns off `noUnusedVariables` and `noUnusedFunctionParameters`, because the tsconfig presets report them through TypeScript, and allows default exports in `*.config.*` files, which tools load through the default export. It declares these weakenings in its `declarations.json`, so `suppressions/biome-overrides` takes them as declared. Every other weakening a repository adds is an override it declares with a reason.
397
+
398
+ The `biome` rule runs `biome check` with the repository's config and reports each finding as `biome/<category>`, such as `biome/lint/style/useBlockStatements`, `biome/assist/source/useSortedKeys`, `biome/format` or `biome/plugin`, so Biome's findings go through the baseline like any other rule's. `adopt: ["biome"]` and `quality baseline write --rule biome` take in every Biome category at once. A finding below `error`, such as a rule a repository declared at `warn`, is not reported. The rule also asks for a root `biome.json` or `biome.jsonc` that extends the preset, and it takes no registry exceptions. A Biome config that Biome cannot load stops the run with Biome's message.
399
+
400
+ `quality fix` sorts every `package.json`, then applies Biome's safe fixes, assist actions and formatting. An editor that runs Biome on save uses the same version when it resolves Biome from the root `node_modules`, so a repository that wants that installs `@biomejs/biome` at the version this package pins.
401
+
402
+ ## Vitest projects
403
+
404
+ `@shivaedev/quality/vitest` sets up the tests of a package by file name, so no test file sets its environment with a pragma. It needs `vitest`, and `happy-dom` for DOM tests.
405
+
406
+ ```ts
407
+ // vitest.config.ts
408
+ import { testProjects } from "@shivaedev/quality/vitest";
409
+ import { defineConfig } from "vitest/config";
410
+
411
+ export default defineConfig({ test: testProjects() });
412
+ ```
413
+
414
+ | Project | Files | Environment | Runs |
415
+ | --- | --- | --- | --- |
416
+ | `unit` | `*.test.ts` and the other test files | Node | By default |
417
+ | `dom` | `*.dom.test.ts`, `*.dom.test.tsx` | happy-dom | By default |
418
+ | `slow` | `*.slow.test.ts`, `*.slow.test.tsx` | Node | Only with `vitest run --project slow` |
419
+
420
+ Type tests (`*.typecheck.test.ts` and `typecheck.test.ts`) are in no project: the compiler checks them. A test that is too slow for every run goes into the slow project instead of being skipped.
421
+
332
422
  ## tsconfig presets
333
423
 
334
424
  Two presets hold one strict, current TypeScript setup for every repository. They target TypeScript 7.
@@ -372,4 +462,4 @@ A package that type-checks its tests with one config and builds `src` with anoth
372
462
 
373
463
  ## Validation
374
464
 
375
- `pnpm ready` checks formatting, TypeScript 7, the rules, config, discovery, registry, baseline and report behavior, the command line against seeded repositories and git histories, an installed tarball consumer that type-checks a config and runs the `quality` bin through a baseline cycle, and installed consumers that extend each tsconfig preset, type-check a fixture with an expected error for each check the base turns on, and run the package preset's build output.
465
+ `pnpm ready` checks formatting, TypeScript 7, the rules, the import graph against seeded repositories and the fence policy against its examples, config, discovery, registry, baseline and report behavior, the command line against seeded repositories and git histories, the Biome preset against every rule Biome recommends and against its declarations, the `biome` and `manifests/sorted` rules and `quality fix` against seeded repositories, the Vitest projects against a seeded repository that Vitest runs, an installed tarball consumer that type-checks a config and runs the `quality` bin through a baseline that takes in the preset's lint and plugin findings, and installed consumers that extend each tsconfig preset, type-check a fixture with an expected error for each check the base turns on, and run the package preset's build output.
@@ -0,0 +1,17 @@
1
+ [
2
+ {
3
+ "includes": ["**"],
4
+ "reason": "TypeScript reports unused variables through noUnusedLocals in the shared tsconfig, so Biome would report each one twice.",
5
+ "rule": "lint/correctness/noUnusedVariables"
6
+ },
7
+ {
8
+ "includes": ["**"],
9
+ "reason": "TypeScript reports unused parameters through noUnusedParameters in the shared tsconfig, so Biome would report each one twice.",
10
+ "rule": "lint/correctness/noUnusedFunctionParameters"
11
+ },
12
+ {
13
+ "includes": ["**/*.config.*"],
14
+ "reason": "Tools load their config files through the default export.",
15
+ "rule": "lint/style/noDefaultExport"
16
+ }
17
+ ]
@@ -0,0 +1,18 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ or {
5
+ or {
6
+ `Date.now()` as $match,
7
+ `new Date()` as $match
8
+ } where { register_diagnostic(span=$match, message="Ambient time is banned. Read time through Effect's Clock service.") },
9
+ `Math.random()` as $match where { register_diagnostic(span=$match, message="Ambient randomness is banned. Use Effect's Random service.") },
10
+ or {
11
+ `console.$method($...)` as $match,
12
+ `console[$method]($...)` as $match
13
+ } where { register_diagnostic(span=$match, message="console.* is banned. Log through Effect's logger.") },
14
+ or {
15
+ JsStaticMemberExpression() as $match where { $match <: `process.env` },
16
+ JsComputedMemberExpression() as $match where { $match <: `process["env"]` }
17
+ } where { register_diagnostic(span=$match, message="process.env is banned. Read configuration through Effect's Config service.") }
18
+ }
@@ -0,0 +1,7 @@
1
+ engine biome(1.0)
2
+ language js(typescript, jsx)
3
+
4
+ `Effect.fn($name)` as $match where {
5
+ ! $name <: r"^[\"'][A-Z][A-Za-z0-9]*\.[a-z][A-Za-z0-9]*[\"']$",
6
+ register_diagnostic(span=$match, message="Effect.fn takes a literal span name shaped PascalCaseOwner.lowerCamelCaseOperation, such as \"Transact.invalidateOnCommit\".")
7
+ }