@nielspeter/eess-ts 0.2.1 → 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 (467) hide show
  1. package/README.md +61 -35
  2. package/dist/builders/call-rule-builder.d.ts +66 -26
  3. package/dist/builders/call-rule-builder.d.ts.map +1 -1
  4. package/dist/builders/call-rule-builder.js +75 -32
  5. package/dist/builders/call-rule-builder.js.map +1 -1
  6. package/dist/builders/class-rule-builder.d.ts +125 -26
  7. package/dist/builders/class-rule-builder.d.ts.map +1 -1
  8. package/dist/builders/class-rule-builder.js +141 -55
  9. package/dist/builders/class-rule-builder.js.map +1 -1
  10. package/dist/builders/correspondence-builder.d.ts +287 -0
  11. package/dist/builders/correspondence-builder.d.ts.map +1 -0
  12. package/dist/builders/correspondence-builder.js +385 -0
  13. package/dist/builders/correspondence-builder.js.map +1 -0
  14. package/dist/builders/correspondence-findings.d.ts +104 -0
  15. package/dist/builders/correspondence-findings.d.ts.map +1 -0
  16. package/dist/builders/correspondence-findings.js +301 -0
  17. package/dist/builders/correspondence-findings.js.map +1 -0
  18. package/dist/builders/cross-layer-builder.d.ts +99 -16
  19. package/dist/builders/cross-layer-builder.d.ts.map +1 -1
  20. package/dist/builders/cross-layer-builder.js +182 -35
  21. package/dist/builders/cross-layer-builder.js.map +1 -1
  22. package/dist/builders/function-rule-builder.d.ts +144 -25
  23. package/dist/builders/function-rule-builder.d.ts.map +1 -1
  24. package/dist/builders/function-rule-builder.js +177 -39
  25. package/dist/builders/function-rule-builder.js.map +1 -1
  26. package/dist/builders/jsx-rule-builder.d.ts +70 -14
  27. package/dist/builders/jsx-rule-builder.d.ts.map +1 -1
  28. package/dist/builders/jsx-rule-builder.js +73 -14
  29. package/dist/builders/jsx-rule-builder.js.map +1 -1
  30. package/dist/builders/module-rule-builder.d.ts +2 -2
  31. package/dist/builders/module-rule-builder.d.ts.map +1 -1
  32. package/dist/builders/module-rule-builder.js +16 -19
  33. package/dist/builders/module-rule-builder.js.map +1 -1
  34. package/dist/builders/scoped-function-rule-builder.d.ts +11 -0
  35. package/dist/builders/scoped-function-rule-builder.d.ts.map +1 -1
  36. package/dist/builders/scoped-function-rule-builder.js +12 -0
  37. package/dist/builders/scoped-function-rule-builder.js.map +1 -1
  38. package/dist/builders/slice-discovery-message.d.ts +36 -0
  39. package/dist/builders/slice-discovery-message.d.ts.map +1 -0
  40. package/dist/builders/slice-discovery-message.js +181 -0
  41. package/dist/builders/slice-discovery-message.js.map +1 -0
  42. package/dist/builders/slice-rule-builder.d.ts +151 -12
  43. package/dist/builders/slice-rule-builder.d.ts.map +1 -1
  44. package/dist/builders/slice-rule-builder.js +243 -35
  45. package/dist/builders/slice-rule-builder.js.map +1 -1
  46. package/dist/builders/type-rule-builder.d.ts +95 -24
  47. package/dist/builders/type-rule-builder.d.ts.map +1 -1
  48. package/dist/builders/type-rule-builder.js +109 -42
  49. package/dist/builders/type-rule-builder.js.map +1 -1
  50. package/dist/{helpers → builders}/within.d.ts +2 -2
  51. package/dist/builders/within.d.ts.map +1 -0
  52. package/dist/{helpers → builders}/within.js +1 -1
  53. package/dist/builders/within.js.map +1 -0
  54. package/dist/cli/commands/baseline.d.ts +8 -3
  55. package/dist/cli/commands/baseline.d.ts.map +1 -1
  56. package/dist/cli/commands/baseline.js +111 -7
  57. package/dist/cli/commands/baseline.js.map +1 -1
  58. package/dist/cli/commands/check.d.ts +7 -2
  59. package/dist/cli/commands/check.d.ts.map +1 -1
  60. package/dist/cli/commands/check.js +385 -47
  61. package/dist/cli/commands/check.js.map +1 -1
  62. package/dist/cli/commands/doctor.d.ts +29 -0
  63. package/dist/cli/commands/doctor.d.ts.map +1 -0
  64. package/dist/cli/commands/doctor.js +224 -0
  65. package/dist/cli/commands/doctor.js.map +1 -0
  66. package/dist/cli/commands/explain.d.ts +2 -1
  67. package/dist/cli/commands/explain.d.ts.map +1 -1
  68. package/dist/cli/commands/explain.js +19 -10
  69. package/dist/cli/commands/explain.js.map +1 -1
  70. package/dist/cli/commands/init.d.ts +9 -3
  71. package/dist/cli/commands/init.d.ts.map +1 -1
  72. package/dist/cli/commands/init.js +162 -137
  73. package/dist/cli/commands/init.js.map +1 -1
  74. package/dist/cli/import-rule-module.d.ts +29 -0
  75. package/dist/cli/import-rule-module.d.ts.map +1 -0
  76. package/dist/cli/import-rule-module.js +47 -0
  77. package/dist/cli/import-rule-module.js.map +1 -0
  78. package/dist/cli/index.d.ts +2 -2
  79. package/dist/cli/index.d.ts.map +1 -1
  80. package/dist/cli/index.js +101 -43
  81. package/dist/cli/index.js.map +1 -1
  82. package/dist/cli/load-rules.d.ts +6 -11
  83. package/dist/cli/load-rules.d.ts.map +1 -1
  84. package/dist/cli/load-rules.js +25 -32
  85. package/dist/cli/load-rules.js.map +1 -1
  86. package/dist/cli/resolve-config.d.ts +0 -8
  87. package/dist/cli/resolve-config.d.ts.map +1 -1
  88. package/dist/cli/resolve-config.js +25 -55
  89. package/dist/cli/resolve-config.js.map +1 -1
  90. package/dist/cli/rule-file-findings.d.ts +178 -0
  91. package/dist/cli/rule-file-findings.d.ts.map +1 -0
  92. package/dist/cli/rule-file-findings.js +351 -0
  93. package/dist/cli/rule-file-findings.js.map +1 -0
  94. package/dist/cli/watch.d.ts +17 -34
  95. package/dist/cli/watch.d.ts.map +1 -1
  96. package/dist/cli/watch.js +14 -129
  97. package/dist/cli/watch.js.map +1 -1
  98. package/dist/conditions/body-analysis-function.d.ts.map +1 -1
  99. package/dist/conditions/body-analysis-function.js +16 -7
  100. package/dist/conditions/body-analysis-function.js.map +1 -1
  101. package/dist/conditions/body-analysis-module.d.ts.map +1 -1
  102. package/dist/conditions/body-analysis-module.js +14 -9
  103. package/dist/conditions/body-analysis-module.js.map +1 -1
  104. package/dist/conditions/body-analysis.d.ts.map +1 -1
  105. package/dist/conditions/body-analysis.js +16 -7
  106. package/dist/conditions/body-analysis.js.map +1 -1
  107. package/dist/conditions/call.d.ts.map +1 -1
  108. package/dist/conditions/call.js +41 -19
  109. package/dist/conditions/call.js.map +1 -1
  110. package/dist/conditions/catch-analysis.d.ts +2 -1
  111. package/dist/conditions/catch-analysis.d.ts.map +1 -1
  112. package/dist/conditions/catch-analysis.js.map +1 -1
  113. package/dist/conditions/cross-layer.d.ts +2 -10
  114. package/dist/conditions/cross-layer.d.ts.map +1 -1
  115. package/dist/conditions/cross-layer.js +227 -23
  116. package/dist/conditions/cross-layer.js.map +1 -1
  117. package/dist/conditions/dependency.d.ts +35 -6
  118. package/dist/conditions/dependency.d.ts.map +1 -1
  119. package/dist/conditions/dependency.js +299 -45
  120. package/dist/conditions/dependency.js.map +1 -1
  121. package/dist/conditions/exports.d.ts.map +1 -1
  122. package/dist/conditions/exports.js +41 -37
  123. package/dist/conditions/exports.js.map +1 -1
  124. package/dist/conditions/function.d.ts.map +1 -1
  125. package/dist/conditions/function.js +19 -5
  126. package/dist/conditions/function.js.map +1 -1
  127. package/dist/conditions/helpers.d.ts +2 -1
  128. package/dist/conditions/helpers.d.ts.map +1 -1
  129. package/dist/conditions/helpers.js +4 -1
  130. package/dist/conditions/helpers.js.map +1 -1
  131. package/dist/conditions/jsx.d.ts.map +1 -1
  132. package/dist/conditions/jsx.js +7 -2
  133. package/dist/conditions/jsx.js.map +1 -1
  134. package/dist/conditions/match-identity.d.ts +43 -0
  135. package/dist/conditions/match-identity.d.ts.map +1 -0
  136. package/dist/conditions/match-identity.js +43 -0
  137. package/dist/conditions/match-identity.js.map +1 -0
  138. package/dist/conditions/members.d.ts.map +1 -1
  139. package/dist/conditions/members.js +20 -6
  140. package/dist/conditions/members.js.map +1 -1
  141. package/dist/conditions/reverse-dependency.d.ts +18 -5
  142. package/dist/conditions/reverse-dependency.d.ts.map +1 -1
  143. package/dist/conditions/reverse-dependency.js +155 -93
  144. package/dist/conditions/reverse-dependency.js.map +1 -1
  145. package/dist/conditions/slice.d.ts +86 -2
  146. package/dist/conditions/slice.d.ts.map +1 -1
  147. package/dist/conditions/slice.js +234 -53
  148. package/dist/conditions/slice.js.map +1 -1
  149. package/dist/conditions/structural.d.ts.map +1 -1
  150. package/dist/conditions/structural.js +16 -4
  151. package/dist/conditions/structural.js.map +1 -1
  152. package/dist/core/check-all.d.ts +19 -0
  153. package/dist/core/check-all.d.ts.map +1 -0
  154. package/dist/core/check-all.js +150 -0
  155. package/dist/core/check-all.js.map +1 -0
  156. package/dist/core/combinators.d.ts +48 -0
  157. package/dist/core/combinators.d.ts.map +1 -0
  158. package/dist/core/combinators.js +49 -0
  159. package/dist/core/combinators.js.map +1 -0
  160. package/dist/core/descendant-cache.d.ts +36 -0
  161. package/dist/core/descendant-cache.d.ts.map +1 -0
  162. package/dist/core/descendant-cache.js +117 -0
  163. package/dist/core/descendant-cache.js.map +1 -0
  164. package/dist/core/diagnose.d.ts +234 -0
  165. package/dist/core/diagnose.d.ts.map +1 -0
  166. package/dist/core/diagnose.js +390 -0
  167. package/dist/core/diagnose.js.map +1 -0
  168. package/dist/core/disk-set.d.ts +48 -0
  169. package/dist/core/disk-set.d.ts.map +1 -0
  170. package/dist/core/disk-set.js +218 -0
  171. package/dist/core/disk-set.js.map +1 -0
  172. package/dist/core/element-cache.d.ts +75 -0
  173. package/dist/core/element-cache.d.ts.map +1 -0
  174. package/dist/core/element-cache.js +32 -0
  175. package/dist/core/element-cache.js.map +1 -0
  176. package/dist/core/empty-project-advice.d.ts +75 -0
  177. package/dist/core/empty-project-advice.d.ts.map +1 -0
  178. package/dist/core/empty-project-advice.js +61 -0
  179. package/dist/core/empty-project-advice.js.map +1 -0
  180. package/dist/core/exclusion-comments.d.ts +19 -0
  181. package/dist/core/exclusion-comments.d.ts.map +1 -0
  182. package/dist/core/exclusion-comments.js +7 -0
  183. package/dist/core/exclusion-comments.js.map +1 -0
  184. package/dist/core/execute-rule.d.ts +158 -0
  185. package/dist/core/execute-rule.d.ts.map +1 -0
  186. package/dist/core/execute-rule.js +666 -0
  187. package/dist/core/execute-rule.js.map +1 -0
  188. package/dist/core/glob-diagnosis.d.ts +78 -0
  189. package/dist/core/glob-diagnosis.d.ts.map +1 -0
  190. package/dist/core/glob-diagnosis.js +134 -0
  191. package/dist/core/glob-diagnosis.js.map +1 -0
  192. package/dist/core/glob-evaluator.d.ts +48 -0
  193. package/dist/core/glob-evaluator.d.ts.map +1 -0
  194. package/dist/core/glob-evaluator.js +89 -0
  195. package/dist/core/glob-evaluator.js.map +1 -0
  196. package/dist/core/import-candidates.d.ts +60 -0
  197. package/dist/core/import-candidates.d.ts.map +1 -0
  198. package/dist/core/import-candidates.js +93 -0
  199. package/dist/core/import-candidates.js.map +1 -0
  200. package/dist/core/import-options.d.ts +55 -2
  201. package/dist/core/import-options.d.ts.map +1 -1
  202. package/dist/core/import-options.js +64 -0
  203. package/dist/core/import-options.js.map +1 -1
  204. package/dist/core/invalidate-on-modify.d.ts +20 -0
  205. package/dist/core/invalidate-on-modify.d.ts.map +1 -0
  206. package/dist/core/invalidate-on-modify.js +26 -0
  207. package/dist/core/invalidate-on-modify.js.map +1 -0
  208. package/dist/core/line-index.d.ts +3 -0
  209. package/dist/core/line-index.d.ts.map +1 -0
  210. package/dist/core/line-index.js +227 -0
  211. package/dist/core/line-index.js.map +1 -0
  212. package/dist/core/metric-violation.d.ts +86 -0
  213. package/dist/core/metric-violation.d.ts.map +1 -0
  214. package/dist/core/metric-violation.js +132 -0
  215. package/dist/core/metric-violation.js.map +1 -0
  216. package/dist/core/module-edges.d.ts +361 -0
  217. package/dist/core/module-edges.d.ts.map +1 -0
  218. package/dist/core/module-edges.js +593 -0
  219. package/dist/core/module-edges.js.map +1 -0
  220. package/dist/core/object-literal-functions.d.ts +42 -0
  221. package/dist/core/object-literal-functions.d.ts.map +1 -0
  222. package/dist/core/object-literal-functions.js +75 -0
  223. package/dist/core/object-literal-functions.js.map +1 -0
  224. package/dist/core/orphan-exclusions.d.ts +44 -0
  225. package/dist/core/orphan-exclusions.d.ts.map +1 -0
  226. package/dist/core/orphan-exclusions.js +224 -0
  227. package/dist/core/orphan-exclusions.js.map +1 -0
  228. package/dist/core/pair-condition.d.ts +32 -3
  229. package/dist/core/pair-condition.d.ts.map +1 -1
  230. package/dist/core/path-universe.d.ts +22 -0
  231. package/dist/core/path-universe.d.ts.map +1 -0
  232. package/dist/core/path-universe.js +45 -0
  233. package/dist/core/path-universe.js.map +1 -0
  234. package/dist/core/per-root-compiler-options.d.ts +20 -0
  235. package/dist/core/per-root-compiler-options.d.ts.map +1 -0
  236. package/dist/core/per-root-compiler-options.js +57 -0
  237. package/dist/core/per-root-compiler-options.js.map +1 -0
  238. package/dist/core/project-relative.d.ts +98 -0
  239. package/dist/core/project-relative.d.ts.map +1 -0
  240. package/dist/core/project-relative.js +185 -0
  241. package/dist/core/project-relative.js.map +1 -0
  242. package/dist/core/project.d.ts +7 -1
  243. package/dist/core/project.d.ts.map +1 -1
  244. package/dist/core/project.js +29 -4
  245. package/dist/core/project.js.map +1 -1
  246. package/dist/core/rule-builder.d.ts +303 -0
  247. package/dist/core/rule-builder.d.ts.map +1 -0
  248. package/dist/core/rule-builder.js +463 -0
  249. package/dist/core/rule-builder.js.map +1 -0
  250. package/dist/core/rule-declaration.d.ts +32 -0
  251. package/dist/core/rule-declaration.d.ts.map +1 -0
  252. package/dist/core/rule-declaration.js +88 -0
  253. package/dist/core/rule-declaration.js.map +1 -0
  254. package/dist/core/terminal-builder.d.ts +629 -0
  255. package/dist/core/terminal-builder.d.ts.map +1 -0
  256. package/dist/core/terminal-builder.js +807 -0
  257. package/dist/core/terminal-builder.js.map +1 -0
  258. package/dist/core/terminal-execution.d.ts +39 -0
  259. package/dist/core/terminal-execution.d.ts.map +1 -0
  260. package/dist/core/terminal-execution.js +103 -0
  261. package/dist/core/terminal-execution.js.map +1 -0
  262. package/dist/core/ts-comment-mask.d.ts +2 -0
  263. package/dist/core/ts-comment-mask.d.ts.map +1 -0
  264. package/dist/core/ts-comment-mask.js +102 -0
  265. package/dist/core/ts-comment-mask.js.map +1 -0
  266. package/dist/core/vacuity-diagnosis.d.ts +103 -0
  267. package/dist/core/vacuity-diagnosis.d.ts.map +1 -0
  268. package/dist/core/vacuity-diagnosis.js +415 -0
  269. package/dist/core/vacuity-diagnosis.js.map +1 -0
  270. package/dist/core/violation.d.ts +16 -11
  271. package/dist/core/violation.d.ts.map +1 -1
  272. package/dist/core/violation.js +33 -13
  273. package/dist/core/violation.js.map +1 -1
  274. package/dist/graphql/graphql-rule-builder.d.ts +95 -0
  275. package/dist/graphql/graphql-rule-builder.d.ts.map +1 -0
  276. package/dist/graphql/graphql-rule-builder.js +127 -0
  277. package/dist/graphql/graphql-rule-builder.js.map +1 -0
  278. package/dist/graphql/index.d.ts +1 -0
  279. package/dist/graphql/index.d.ts.map +1 -1
  280. package/dist/graphql/index.js +2 -1
  281. package/dist/graphql/index.js.map +1 -1
  282. package/dist/graphql/resolver-rule-builder.d.ts +44 -23
  283. package/dist/graphql/resolver-rule-builder.d.ts.map +1 -1
  284. package/dist/graphql/resolver-rule-builder.js +80 -72
  285. package/dist/graphql/resolver-rule-builder.js.map +1 -1
  286. package/dist/graphql/schema-loader.d.ts +21 -0
  287. package/dist/graphql/schema-loader.d.ts.map +1 -1
  288. package/dist/graphql/schema-loader.js +82 -12
  289. package/dist/graphql/schema-loader.js.map +1 -1
  290. package/dist/graphql/schema-predicates.d.ts.map +1 -1
  291. package/dist/graphql/schema-predicates.js +17 -12
  292. package/dist/graphql/schema-predicates.js.map +1 -1
  293. package/dist/graphql/schema-rule-builder.d.ts +15 -24
  294. package/dist/graphql/schema-rule-builder.d.ts.map +1 -1
  295. package/dist/graphql/schema-rule-builder.js +39 -77
  296. package/dist/graphql/schema-rule-builder.js.map +1 -1
  297. package/dist/helpers/baseline-diagnostics.d.ts +45 -0
  298. package/dist/helpers/baseline-diagnostics.d.ts.map +1 -0
  299. package/dist/helpers/baseline-diagnostics.js +168 -0
  300. package/dist/helpers/baseline-diagnostics.js.map +1 -0
  301. package/dist/helpers/baseline-generator.d.ts +28 -0
  302. package/dist/helpers/baseline-generator.d.ts.map +1 -0
  303. package/dist/helpers/baseline-generator.js +27 -0
  304. package/dist/helpers/baseline-generator.js.map +1 -0
  305. package/dist/helpers/baseline.d.ts +336 -0
  306. package/dist/helpers/baseline.d.ts.map +1 -0
  307. package/dist/helpers/baseline.js +664 -0
  308. package/dist/helpers/baseline.js.map +1 -0
  309. package/dist/helpers/body-traversal.d.ts +27 -2
  310. package/dist/helpers/body-traversal.d.ts.map +1 -1
  311. package/dist/helpers/body-traversal.js +135 -16
  312. package/dist/helpers/body-traversal.js.map +1 -1
  313. package/dist/helpers/callback-extractor.d.ts.map +1 -1
  314. package/dist/helpers/callback-extractor.js +53 -84
  315. package/dist/helpers/callback-extractor.js.map +1 -1
  316. package/dist/helpers/complexity.d.ts +13 -5
  317. package/dist/helpers/complexity.d.ts.map +1 -1
  318. package/dist/helpers/complexity.js +15 -6
  319. package/dist/helpers/complexity.js.map +1 -1
  320. package/dist/helpers/diff-aware.d.ts +16 -0
  321. package/dist/helpers/diff-aware.d.ts.map +1 -0
  322. package/dist/helpers/diff-aware.js +16 -0
  323. package/dist/helpers/diff-aware.js.map +1 -0
  324. package/dist/helpers/matchers.d.ts +68 -7
  325. package/dist/helpers/matchers.d.ts.map +1 -1
  326. package/dist/helpers/matchers.js +164 -86
  327. package/dist/helpers/matchers.js.map +1 -1
  328. package/dist/helpers/slice-graph.d.ts +100 -8
  329. package/dist/helpers/slice-graph.d.ts.map +1 -1
  330. package/dist/helpers/slice-graph.js +126 -34
  331. package/dist/helpers/slice-graph.js.map +1 -1
  332. package/dist/helpers/tarjan.d.ts +0 -14
  333. package/dist/helpers/tarjan.d.ts.map +1 -1
  334. package/dist/helpers/tarjan.js +29 -16
  335. package/dist/helpers/tarjan.js.map +1 -1
  336. package/dist/index.d.ts +55 -19
  337. package/dist/index.d.ts.map +1 -1
  338. package/dist/index.js +67 -15
  339. package/dist/index.js.map +1 -1
  340. package/dist/models/arch-call.d.ts +3 -2
  341. package/dist/models/arch-call.d.ts.map +1 -1
  342. package/dist/models/arch-call.js.map +1 -1
  343. package/dist/models/arch-function.d.ts +54 -8
  344. package/dist/models/arch-function.d.ts.map +1 -1
  345. package/dist/models/arch-function.js +145 -8
  346. package/dist/models/arch-function.js.map +1 -1
  347. package/dist/models/arch-jsx-element.d.ts.map +1 -1
  348. package/dist/models/arch-jsx-element.js +18 -19
  349. package/dist/models/arch-jsx-element.js.map +1 -1
  350. package/dist/models/slice.d.ts +33 -9
  351. package/dist/models/slice.d.ts.map +1 -1
  352. package/dist/models/slice.js +129 -19
  353. package/dist/models/slice.js.map +1 -1
  354. package/dist/predicates/call.d.ts.map +1 -1
  355. package/dist/predicates/call.js +5 -0
  356. package/dist/predicates/call.js.map +1 -1
  357. package/dist/predicates/identity.d.ts +21 -0
  358. package/dist/predicates/identity.d.ts.map +1 -1
  359. package/dist/predicates/identity.js +75 -3
  360. package/dist/predicates/identity.js.map +1 -1
  361. package/dist/predicates/index.d.ts +1 -1
  362. package/dist/predicates/index.d.ts.map +1 -1
  363. package/dist/predicates/index.js +1 -1
  364. package/dist/predicates/index.js.map +1 -1
  365. package/dist/predicates/jsx.d.ts.map +1 -1
  366. package/dist/predicates/jsx.js +2 -1
  367. package/dist/predicates/jsx.js.map +1 -1
  368. package/dist/predicates/metrics.d.ts +4 -2
  369. package/dist/predicates/metrics.d.ts.map +1 -1
  370. package/dist/predicates/metrics.js +4 -2
  371. package/dist/predicates/metrics.js.map +1 -1
  372. package/dist/predicates/module.d.ts +4 -12
  373. package/dist/predicates/module.d.ts.map +1 -1
  374. package/dist/predicates/module.js +57 -37
  375. package/dist/predicates/module.js.map +1 -1
  376. package/dist/presets/agent-guardrails.d.ts +49 -16
  377. package/dist/presets/agent-guardrails.d.ts.map +1 -1
  378. package/dist/presets/agent-guardrails.js +308 -19
  379. package/dist/presets/agent-guardrails.js.map +1 -1
  380. package/dist/presets/boundaries.d.ts +46 -3
  381. package/dist/presets/boundaries.d.ts.map +1 -1
  382. package/dist/presets/boundaries.js +132 -23
  383. package/dist/presets/boundaries.js.map +1 -1
  384. package/dist/presets/data-layer.d.ts +23 -3
  385. package/dist/presets/data-layer.d.ts.map +1 -1
  386. package/dist/presets/data-layer.js +58 -16
  387. package/dist/presets/data-layer.js.map +1 -1
  388. package/dist/presets/index.d.ts +10 -5
  389. package/dist/presets/index.d.ts.map +1 -1
  390. package/dist/presets/index.js +19 -3
  391. package/dist/presets/index.js.map +1 -1
  392. package/dist/presets/layered.d.ts +47 -3
  393. package/dist/presets/layered.d.ts.map +1 -1
  394. package/dist/presets/layered.js +66 -29
  395. package/dist/presets/layered.js.map +1 -1
  396. package/dist/presets/recommended.d.ts +81 -10
  397. package/dist/presets/recommended.d.ts.map +1 -1
  398. package/dist/presets/recommended.js +25 -23
  399. package/dist/presets/recommended.js.map +1 -1
  400. package/dist/presets/shared.d.ts +267 -2
  401. package/dist/presets/shared.d.ts.map +1 -1
  402. package/dist/presets/shared.js +367 -4
  403. package/dist/presets/shared.js.map +1 -1
  404. package/dist/rules/code-quality.d.ts.map +1 -1
  405. package/dist/rules/code-quality.js +15 -6
  406. package/dist/rules/code-quality.js.map +1 -1
  407. package/dist/rules/hygiene.d.ts +1 -1
  408. package/dist/rules/hygiene.js +1 -1
  409. package/dist/rules/metrics-function.d.ts +2 -1
  410. package/dist/rules/metrics-function.d.ts.map +1 -1
  411. package/dist/rules/metrics-function.js +63 -39
  412. package/dist/rules/metrics-function.js.map +1 -1
  413. package/dist/rules/metrics.d.ts +2 -1
  414. package/dist/rules/metrics.d.ts.map +1 -1
  415. package/dist/rules/metrics.js +80 -47
  416. package/dist/rules/metrics.js.map +1 -1
  417. package/dist/smells/clusters.d.ts +78 -0
  418. package/dist/smells/clusters.d.ts.map +1 -0
  419. package/dist/smells/clusters.js +124 -0
  420. package/dist/smells/clusters.js.map +1 -0
  421. package/dist/smells/duplicate-bodies.d.ts +92 -5
  422. package/dist/smells/duplicate-bodies.d.ts.map +1 -1
  423. package/dist/smells/duplicate-bodies.js +203 -73
  424. package/dist/smells/duplicate-bodies.js.map +1 -1
  425. package/dist/smells/duplicate-report.d.ts +90 -0
  426. package/dist/smells/duplicate-report.d.ts.map +1 -0
  427. package/dist/smells/duplicate-report.js +344 -0
  428. package/dist/smells/duplicate-report.js.map +1 -0
  429. package/dist/smells/fingerprint.d.ts +20 -1
  430. package/dist/smells/fingerprint.d.ts.map +1 -1
  431. package/dist/smells/fingerprint.js +27 -3
  432. package/dist/smells/fingerprint.js.map +1 -1
  433. package/dist/smells/inconsistent-siblings.d.ts +128 -7
  434. package/dist/smells/inconsistent-siblings.d.ts.map +1 -1
  435. package/dist/smells/inconsistent-siblings.js +288 -86
  436. package/dist/smells/inconsistent-siblings.js.map +1 -1
  437. package/dist/smells/sibling-files.d.ts +47 -0
  438. package/dist/smells/sibling-files.d.ts.map +1 -0
  439. package/dist/smells/sibling-files.js +104 -0
  440. package/dist/smells/sibling-files.js.map +1 -0
  441. package/dist/smells/similar-pairs.d.ts +28 -0
  442. package/dist/smells/similar-pairs.d.ts.map +1 -0
  443. package/dist/smells/similar-pairs.js +134 -0
  444. package/dist/smells/similar-pairs.js.map +1 -0
  445. package/dist/smells/smell-builder.d.ts +57 -12
  446. package/dist/smells/smell-builder.d.ts.map +1 -1
  447. package/dist/smells/smell-builder.js +112 -14
  448. package/dist/smells/smell-builder.js.map +1 -1
  449. package/dist/smells/variation.d.ts +47 -0
  450. package/dist/smells/variation.d.ts.map +1 -0
  451. package/dist/smells/variation.js +90 -0
  452. package/dist/smells/variation.js.map +1 -0
  453. package/dist/tsconfig/index.d.ts +19 -0
  454. package/dist/tsconfig/index.d.ts.map +1 -0
  455. package/dist/tsconfig/index.js +20 -0
  456. package/dist/tsconfig/index.js.map +1 -0
  457. package/dist/tsconfig/tsconfig-builder.d.ts +42 -9
  458. package/dist/tsconfig/tsconfig-builder.d.ts.map +1 -1
  459. package/dist/tsconfig/tsconfig-builder.js +65 -16
  460. package/dist/tsconfig/tsconfig-builder.js.map +1 -1
  461. package/package.json +4 -2
  462. package/dist/core/module-dependencies.d.ts +0 -28
  463. package/dist/core/module-dependencies.d.ts.map +0 -1
  464. package/dist/core/module-dependencies.js +0 -35
  465. package/dist/core/module-dependencies.js.map +0 -1
  466. package/dist/helpers/within.d.ts.map +0 -1
  467. package/dist/helpers/within.js.map +0 -1
@@ -0,0 +1,629 @@
1
+ import type { ArchViolation } from '@nielspeter/eess';
2
+ import type { GlobNode } from '@nielspeter/eess';
3
+ import type { ArchProject } from './project.js';
4
+ import type { CheckOptions } from '@nielspeter/eess';
5
+ import type { RuleMetadata } from '@nielspeter/eess';
6
+ import type { RuleDescription } from '@nielspeter/eess';
7
+ import type { SilentExclusion } from '@nielspeter/eess';
8
+ /**
9
+ * What a family returns from `collectViolations()` — plan 0098.
10
+ *
11
+ * Part of the extension surface [ts-archunit ADR-010](https://github.com/nielspeter/ts-archunit/blob/main/adr/010-the-extension-surface-is-a-contract.md)
12
+ * rule 1 names as contract, so changing this shape is a breaking change.
13
+ */
14
+ /**
15
+ * The receipt — re-exported from the kernel, not redeclared.
16
+ *
17
+ * This was a second `CollectResult` interface, forked alongside the rest of the
18
+ * engine (plan 0188 tracks the duplication; bugs 0156, 0163 and 0227 are what it
19
+ * costs). It carried `{ violations, examined }` where the kernel's now carries
20
+ * its evidence on the array itself, and two shapes for one concept is how
21
+ * `declaredEmpty` would reach the kernel's terminal and never the flagship
22
+ * dialect's — plan 0235's D4 exactly: "D4's declaration goes on both terminals'
23
+ * receipts, or the flagship dialect's presets arrive undeclared."
24
+ *
25
+ * Unified here rather than waiting for 0188, because this plan cannot ship a
26
+ * declaration that reaches four dialects and not the fifth.
27
+ */
28
+ import type { CollectResult } from '@nielspeter/eess';
29
+ export type { CollectResult };
30
+ /**
31
+ * The declaration half of every rule builder: what the author states.
32
+ *
33
+ * Owns `because`, `rule`, `excluding`, `describeRule`, `asSeverity`, the two
34
+ * emptiness assertions and the filter state — everything a chain accumulates
35
+ * BEFORE anything runs. {@link TerminalBuilder} extends this with the terminals
36
+ * and the execution behind them; a builder subclasses that one and inherits both
37
+ * halves, so the split is in this file rather than in their contracts.
38
+ *
39
+ * `RuleBuilder<T>` extends this too, as of plan 0069. It used not to, and the
40
+ * old docstring said so plainly: "RuleBuilder does NOT extend this because it
41
+ * predates it." The cost was not the duplicated methods, it was that every
42
+ * safety feature added to one root silently did not reach the builders on the
43
+ * other — which is what bug 0013 cost. Anything that must hold for all thirteen
44
+ * builders now has exactly one place to live.
45
+ */
46
+ declare abstract class RuleDeclaration {
47
+ protected _reason?: string;
48
+ protected _metadata?: RuleMetadata;
49
+ protected _severity?: 'error' | 'warn';
50
+ /**
51
+ * Plan 0090 — the debt half of a `warn`. `undefined` means an ADVISORY
52
+ * warning: permanent, no ceiling, exactly today's `.asSeverity('warn')`.
53
+ * Set means DEFERRED: a violation whose `subjectOf()` is in this list stays
54
+ * `warn`; anything not in it escalates to `error` in `violations()` — a new
55
+ * finding this list did not accept. See `asSeverity()`'s own doc comment.
56
+ */
57
+ protected _acceptedWarnings?: readonly string[];
58
+ protected _exclusions: (string | RegExp)[];
59
+ protected _silentIndices: Set<number>;
60
+ /**
61
+ * The declared-empty grammar — plan 0097, and [ts-archunit ADR-010](https://github.com/nielspeter/ts-archunit/blob/main/adr/010-the-extension-surface-is-a-contract.md)
62
+ * rule 3(a).
63
+ *
64
+ * These lived on `RuleBuilder<T>`, so the smell family — the one bug 0066 is
65
+ * filed against — could not reach them: that bug listed "is `.expectEmpty()`
66
+ * reachable on a smell builder at all?" under Not measured, and the answer was
67
+ * no. ADR-010 part 3 requires every family's grammar to expose a declaration
68
+ * path, so they belong on the root every family shares.
69
+ *
70
+ * Booleans rather than registry membership, deliberately. `shallowClone` in
71
+ * `copy()` carries an own property for free on every chain step, where a
72
+ * `WeakSet` keyed on the builder would be lost at the first `copy()` — and the
73
+ * threat model differs from the one that forced the cardinality registry,
74
+ * which guards user-CONSTRUCTIBLE condition objects. These sit behind a
75
+ * sanctioned method on a class whose only other audience is ADR-010's
76
+ * contract.
77
+ */
78
+ protected _requireNonEmpty: boolean;
79
+ protected _expectEmpty: boolean;
80
+ /**
81
+ * Assert that the predicate chain matches at least one subject. If the
82
+ * filtered subject set is empty, the rule FAILS with a config-level
83
+ * meta-finding instead of passing vacuously — the "0 === 0" false-green
84
+ * ADR-008 forbids. Opt-in: legitimately-empty selections (e.g. "no
85
+ * repositories yet") stay green without it. Built on the materialized
86
+ * subject set (plan 0064); the finding bypasses diff/baseline (plan 0067).
87
+ */
88
+ expectNonEmpty(): this;
89
+ /**
90
+ * Assert that this selector matches **nothing**, and fail the day it matches
91
+ * something.
92
+ *
93
+ * Plan 0074 (R3b). Since an empty selection is now a failure by default, a
94
+ * rule whose selection is legitimately empty needs a way to say so — and
95
+ * 0069's appendix rejected `.allowEmpty()` for being "one word, silent
96
+ * forever, typo or not, and nothing revisits it". This is the shape that
97
+ * survived review, and the difference is that it is an **assertion**:
98
+ *
99
+ * ```ts
100
+ * classes(p).that().haveDecorator('Deprecated')
101
+ * .expectEmpty() // nothing is deprecated yet
102
+ * .should().beExported()
103
+ *
104
+ * // the day someone deprecates a class:
105
+ * // FAIL: .expectEmpty() asserted 0 subjects, found 1
106
+ * ```
107
+ *
108
+ * An agent that reaches for this to silence a real typo gets a different
109
+ * failure the moment the typo is fixed, and until then the intent is stated
110
+ * in the rule where a reader sees it — rather than in a baseline, or nowhere.
111
+ *
112
+ * Symmetric with {@link expectNonEmpty} for the rule builders. A family may **refuse** the zero-arg form where a whole-rule notion of empty has no meaning — `CrossProjectBuilder` throws, because it declares per side — so a consumer walking `TerminalBuilder[]` must not call it unguarded. Exactly symmetric, and the two together mean
113
+ * the empty/non-empty question is always answerable from the rule text.
114
+ * Declaring both is a contradiction and throws here rather than silently
115
+ * picking one.
116
+ */
117
+ expectEmpty(): this;
118
+ /**
119
+ * True when this rule's emptiness is DECLARED — plan 0097, consumed by 0098.
120
+ *
121
+ * The base answer is the whole-rule flag. It is `protected` and overridable
122
+ * because a family whose declaration is not whole-rule must be able to say so:
123
+ * `CrossProjectBuilder` declares per SIDE and refuses the zero-arg form
124
+ * entirely, so `_expectEmpty` is unreachable there and this default would
125
+ * answer `false` for a rule whose every side the author declared — reporting a
126
+ * finding that tells them to declare what they declared, which is ADR-008
127
+ * rule 2's loop.
128
+ *
129
+ * PUBLIC, and forced rather than chosen — the same reason `assertsSomething()`
130
+ * is: `DiagnosableRule` is a structural interface, and a protected member
131
+ * cannot satisfy it. Plan 0096's preview is the first reader, and a preview
132
+ * that ignored the declaration would report a finding on a rule the gate will
133
+ * accept — over-reporting against the very thing it previews, which is the
134
+ * rule 5 violation inside the migration that plan warns about.
135
+ *
136
+ * It exists now, ahead of the floor that reads it, for a reason worth stating:
137
+ * a private version of this lived on `CrossProjectBuilder` and was deleted
138
+ * as dead code, correctly — but the deletion also removed the only expression
139
+ * of the concept, so the override 0098 needs would have gone missing SILENTLY
140
+ * rather than as the compile error a narrowed-visibility clash would have
141
+ * produced. Declaring it here makes the coupling loud again.
142
+ */
143
+ declaresEmpty(): boolean;
144
+ /**
145
+ * How THIS family spells the declaration, for a remedy that names a real call.
146
+ *
147
+ * The sibling of `assertionAdvice()`, and it exists for the same reason: a
148
+ * remedy is only verified to remediate if following it works, and the generic
149
+ * `.expectEmpty()` is a `TypeError` on `CrossProjectBuilder`, which declares
150
+ * per side. Advice that names the one form the reader cannot call is ADR-008
151
+ * rule 2's failure with extra confidence.
152
+ *
153
+ * Overriding `expectEmpty()` and not this leaves a remedy that throws, so the
154
+ * classification census in `evidence-at-every-seam.test.ts` requires both
155
+ * together rather than trusting the next author to remember.
156
+ */
157
+ emptyDeclarationAdvice(): string;
158
+ /**
159
+ * Attach a human-readable rationale to the rule.
160
+ * Included in violation messages when `.check()` throws.
161
+ */
162
+ because(reason: string): this;
163
+ /**
164
+ * Attach rich metadata to the rule.
165
+ * Provides educational context in violation output: why, how to fix, docs link.
166
+ *
167
+ * If `metadata.because` is set, it also sets the reason (same as `.because()`).
168
+ */
169
+ rule(metadata: RuleMetadata): this;
170
+ /**
171
+ * Exclude specific violations from reporting by matching against
172
+ * the violation's `element`, `file`, or `message` fields.
173
+ *
174
+ * Matched violations are silently suppressed. Use for permanent,
175
+ * intentional exceptions — not for temporary violations (use baseline for those).
176
+ *
177
+ * Patterns are matched against all three fields. Prefer anchored regexes
178
+ * or full string matches over short substrings, especially for `message`
179
+ * matching, to avoid accidentally suppressing unrelated violations whose
180
+ * messages happen to contain the same text.
181
+ *
182
+ * Emits a warning if an exclusion matches zero violations — so renamed
183
+ * or deleted exceptions don't silently stay in the rule.
184
+ *
185
+ * A configuration meta-finding — one that reports the rule enforces
186
+ * nothing — is never excludable, and an exclusion that would have matched
187
+ * one is reported as refused rather than as stale.
188
+ *
189
+ * For narrowing a rule's scope at the predicate phase (so the rule never
190
+ * evaluates the excluded element), use `satisfy(not(<predicate>))` instead.
191
+ * See the "Excluding a file from a rule's scope" recipe in docs/recipes.md.
192
+ *
193
+ * @example
194
+ * // Exclude by element name (fully qualified)
195
+ * .excluding('Asset.getImageUrl')
196
+ *
197
+ * @example
198
+ * // Exclude by file path (regex anchored to suffix)
199
+ * .excluding(/repositories\/index\.ts$/)
200
+ *
201
+ * @example
202
+ * // Multiple exclusions, mixed forms
203
+ * .excluding('Asset.getImageUrl', /\/legacy\//, /generated/)
204
+ */
205
+ excluding(...patterns: (string | RegExp | SilentExclusion)[]): this;
206
+ /**
207
+ * Return a structured description of this rule without executing it.
208
+ * Used by the `explain` CLI subcommand.
209
+ */
210
+ describeRule(): RuleDescription;
211
+ /**
212
+ * Set the severity this rule reports at WITHOUT executing it (non-terminal).
213
+ * Returns `this` so the builder can be collected into a rule array and run by
214
+ * the CLI pipeline; its `.violations()` stamp each result with this severity.
215
+ * Distinct from the terminal `.severity()` below, which executes immediately.
216
+ *
217
+ * `'warn'` alone is an ADVISORY warning — permanent, unchanged from every
218
+ * release before plan 0090, for a finding ADR-009 rule 1 says the reader must
219
+ * judge. `'warn'` with `accepted` is a DEFERRED warning — debt, with a
220
+ * ceiling: any violation whose `subjectOf()` is not in `accepted` escalates to
221
+ * `error`. The overloads make `accepted` a compile error on a literal
222
+ * `'error'`, where it would mean nothing — every violation already fails
223
+ * there. The third overload (no `options`) is for a caller dispatching on a
224
+ * runtime-computed `'error' | 'warn'` — several presets do — which cannot
225
+ * satisfy either literal overload; it still cannot pair a dynamic level with
226
+ * `accepted` in the same call, which is not a real use case today.
227
+ */
228
+ asSeverity(level: 'error'): this;
229
+ asSeverity(level: 'warn', options?: {
230
+ accepted?: readonly string[];
231
+ }): this;
232
+ asSeverity(level: 'error' | 'warn'): this;
233
+ /**
234
+ * Whether this rule asserts anything about what it selects (plan 0070).
235
+ *
236
+ * `false` means the rule can never fail, and as of 0.23.0
237
+ * `collectWithAssertionGuard()` turns that into an unsuppressable
238
+ * configuration finding on every terminal; `diagnose()` / `doctor` report it
239
+ * without running the rule. 0.22.0 shipped this hook with nothing at runtime
240
+ * reading it, because the gate drafted for that release wrote through a
241
+ * bespoke stderr channel that bypassed the formatter, the JSON payload, the
242
+ * annotation path and the exit code — a review found a defect at each of those
243
+ * seams, so the channel was withdrawn and the hook shipped on its own. The
244
+ * finding form reaches all four surfaces by construction, which is what the
245
+ * withdrawal bought.
246
+ *
247
+ * Concrete with a `true` default rather than abstract: both roots are public
248
+ * exports, so an abstract member is a compile break for an external subclass
249
+ * (the `globs()` argument). The default makes a new builder EXEMPT by
250
+ * default — the opposite polarity from `globs()`'s empty default, which only
251
+ * makes a builder invisible. The classification test in
252
+ * `tests/core/assertion-gate.test.ts` is what forces the decision for every
253
+ * exported builder.
254
+ *
255
+ * Public, not protected — `diagnose()` duck-types it through
256
+ * `DiagnosableRule`, and a protected member cannot satisfy a structural
257
+ * interface. Same forcing as `assertsSomething` on `RuleBuilder`, which was
258
+ * already shipped public.
259
+ */
260
+ assertsSomething(): boolean;
261
+ /**
262
+ * The remedy for this builder's assertion-less state, as one string.
263
+ *
264
+ * The "one string, one place" channel: `diagnose()`'s advice and the
265
+ * finding's message and `suggestion` all read this method, so the diagnostic
266
+ * a consumer runs before upgrading and the failure they get after cannot
267
+ * disagree — plan 0070 round 2 measured an earlier design shipping two
268
+ * diverging texts for one state.
269
+ *
270
+ * Public for the same `DiagnosableRule` duck-typing reason as
271
+ * `assertsSomething` — plan 0070 drafted this `protected`, and a protected
272
+ * member cannot satisfy the structural interface `diagnose()` consumes.
273
+ */
274
+ assertionAdvice(): string;
275
+ /**
276
+ * Every glob declaration this rule makes, as independent trees.
277
+ *
278
+ * One entry per independent declaration, because each one dies on its own:
279
+ * a rule whose selector is satisfiable and whose discovery glob is not has
280
+ * exactly one fault, and reporting them as one tree would lose that.
281
+ *
282
+ * Concrete with an empty default rather than abstract. Making it abstract
283
+ * would enumerate every builder at compile time — genuinely attractive, and
284
+ * how the census refactor did it — but `RuleBuilder` and `TerminalBuilder`
285
+ * are both public exports, so an abstract member is a compile break for
286
+ * anyone who has subclassed them. R2a is the release people install in order
287
+ * to MEASURE before R3 flips anything; it cannot be the one that fails to
288
+ * compile. The vacuity that `abstract` would have caught is caught instead
289
+ * by a test that reflects over both entry points and fails a `return []`
290
+ * stub, which the compiler could not have done anyway.
291
+ */
292
+ globs(): readonly GlobNode[];
293
+ /**
294
+ * The project this rule was built against, when it has one.
295
+ *
296
+ * Concrete returning `undefined` rather than abstract, for the reason
297
+ * `globs()` above records: both roots are public exports, so an abstract
298
+ * member is a compile break for an external subclass. `RuleBuilder`
299
+ * overrides it with the non-optional form.
300
+ *
301
+ * The glob gate needs it, and a builder that cannot name its project simply
302
+ * has its globs left unchecked — the same fallback `diagnose()` takes, and
303
+ * the honest one: satisfiability is meaningless without a path universe to
304
+ * take it against.
305
+ */
306
+ getProject(): ArchProject | undefined;
307
+ /**
308
+ * Selector globs that can never match — plan 0074 (R3b), the flip.
309
+ *
310
+ * 0069's decision table, not reopened here: a **selector** glob that is
311
+ * unsatisfiable means the rule can never have subjects, so it certifies
312
+ * nothing and passing is a lie. `discovery` already fails (0067-D, and the
313
+ * slice builders own their own message). `condition` and `exclusion` are
314
+ * **never** faults — a condition glob matching nothing is indistinguishable
315
+ * from an armed tripwire that has not fired, and plan 0072 got that wrong
316
+ * twice before it stayed written down.
317
+ *
318
+ * Negative polarity is excluded by `isDeadGlobTree` itself: `not(dead)`
319
+ * over-selects rather than under-selecting, so it cannot be dead.
320
+ *
321
+ * This is the same computation `diagnose()` performs — deliberately, and
322
+ * from the same functions, so the pre-flight and the gate can never disagree
323
+ * about what is dead. `doctor` told adopters what R3b would fail on; if the
324
+ * two used separate logic that promise would be worth nothing.
325
+ */
326
+ /**
327
+ * Whether any condition on this rule declares emptiness as its passing state.
328
+ *
329
+ * Concrete `false` default for the reason `globs()` records — an abstract
330
+ * member breaks external subclasses. `RuleBuilder` overrides it by reading
331
+ * its own conditions; the builders that take their condition as a
332
+ * constructor argument have no cardinality condition to declare.
333
+ *
334
+ * **PUBLIC since plan 0098**, for the same structural reason as
335
+ * `assertsSomething()` and `declaresEmpty()`: `diagnose()` reads it through a
336
+ * structural interface and a protected member cannot satisfy one. It became a
337
+ * reader the moment the rule-builder family started reporting evidence —
338
+ * `.should().notExist()` examines zero subjects *because that is what it
339
+ * asserts*, and previewing it as a fault tells the author their working rule
340
+ * is broken. Caught by this repo's own 53-rule suite, on the one rule in it
341
+ * that ends in `.notExist()`.
342
+ *
343
+ * Deliberately NOT folded into `declaresEmpty()`, though both suppress the
344
+ * same finding. They are different facts and plan 0099 needs them apart: its
345
+ * expiry branch reads the declaration flag alone, because `.notExist()` over a
346
+ * selection that has grown is the condition doing its job, never a declaration
347
+ * that has expired.
348
+ */
349
+ assertsCardinality(): boolean;
350
+ /**
351
+ * The narrowing THIS family applied, when it can name it — plan 0099.
352
+ *
353
+ * ADR-010 part 4 wants the zero-examined remedy to name the **actual excluder,
354
+ * including internal defaults**, because "fix your filters" to a user who wrote
355
+ * none sends an agent looking for filters that do not exist.
356
+ *
357
+ * The root cannot know this: only the family holds its own thresholds. Review
358
+ * measured the cost of leaving it out — `agentGuardrails({ src: '**\/lib/**',
359
+ * noCopyPaste: true })` over two one-line functions, a **correctly configured**
360
+ * rule pointing at real code, hard-failed with "widen it until it matches
361
+ * something" while the true cause was `minLines(5)`, a default the author never
362
+ * wrote and which that preset exposes no knob for.
363
+ *
364
+ * Returns `undefined` when a family has nothing specific to say, and the caller
365
+ * falls back to naming the possibility rather than asserting a cause it cannot
366
+ * verify.
367
+ */
368
+ protected narrowingHint(): string | undefined;
369
+ /**
370
+ * What this family counts in `examined` — plan 0099.
371
+ *
372
+ * `CollectResult.examined` is unit-typed per family (subjects, bodies, pairs,
373
+ * keys), so a message that prints a FILE count and then says the rule examined
374
+ * "0 of them" commits a category error. Measured on this repo: a rule whose
375
+ * glob matched essentially all 616 files and whose NAME predicate matched none
376
+ * printed "loaded 616 files, and this rule examined 0 of them" — sending the
377
+ * reader to widen a glob that was already maximal.
378
+ */
379
+ protected examinedUnitNoun(): string;
380
+ /**
381
+ * An independent copy of this builder.
382
+ *
383
+ * **A held selection is immutable** (bug 0016). Every method that adds to a
384
+ * builder returns a copy instead of mutating `this`, so
385
+ *
386
+ * ```ts
387
+ * const repositories = classes(p).that().extend('BaseRepository')
388
+ * repositories.that().haveNameEndingWith('Legacy').should().notExist().check()
389
+ * repositories.should().beExported().check() // still ALL repositories
390
+ * ```
391
+ *
392
+ * works. Before this, narrowing a held selection edited it in place: the
393
+ * second rule silently inherited `Legacy` and reported on a subset — or on
394
+ * nothing, and then passed. Same for `.excluding()`, which leaked a
395
+ * suppression into every later rule off the same selection, and `.rule()`,
396
+ * which leaked the id that `// eess-exclude <id>` comments are matched
397
+ * against (`execute-rule.ts` gates the whole comment scan on `metadata.id`)
398
+ * and that a preset's severity `overrides` are keyed on — so a later rule
399
+ * inherited a suppression channel it never opted into.
400
+ *
401
+ * Not baselines: `hashViolation` keys on the rule *description*, never on
402
+ * `metadata.id`. An earlier version of this docstring said baselines and a
403
+ * `--rule` filter were keyed on the id. Neither is true, and `--rule` does
404
+ * not exist — the only occurrences of it in the repo were three copies of
405
+ * this sentence. ADR-009 rule 2: a failure may not assert a cause it cannot
406
+ * verify, and that includes naming a flag the CLI does not have.
407
+ *
408
+ * Cost is one object per chain link, against a ts-morph walk. Irrelevant.
409
+ */
410
+ protected copy(): this;
411
+ /**
412
+ * Give this builder independent copies of another's filter state.
413
+ *
414
+ * `copy()` shallow-copies every field, so without this a copy would share
415
+ * its parent's exclusion array by reference and `.excluding()` on one would
416
+ * silently mutate the other. The copy lives here rather than inline in
417
+ * `copy()` because the knowledge of what needs duplicating belongs with the
418
+ * fields — the same reason every other state-holding class overrides
419
+ * `copy()` instead of `copy()` knowing about their fields.
420
+ */
421
+ protected adoptFilterState(source: RuleDeclaration): void;
422
+ }
423
+ /**
424
+ * The terminals — `check()`, `warn()`, `violations()` — and the execution behind
425
+ * them.
426
+ *
427
+ * Split from {@link RuleDeclaration} because a builder does two jobs: it collects
428
+ * a declaration, and it runs it. Both halves were one class of 372 code lines,
429
+ * and the gate that measures class size was right about it.
430
+ *
431
+ * A subclass still extends `TerminalBuilder` and inherits both halves, so the ten
432
+ * builders that do are untouched — the split is in this file, not in their
433
+ * contracts.
434
+ */
435
+ export declare abstract class TerminalBuilder extends RuleDeclaration {
436
+ /**
437
+ * Subclasses implement this to collect and evaluate violations, **and to say
438
+ * how many units they examined while doing it** — plan 0098.
439
+ *
440
+ * Called lazily during `.check()` / `.warn()`.
441
+ *
442
+ * ## Why the return type carries the evidence
443
+ *
444
+ * Plan 0096 gave five families an `examinedUnits()` accessor and `diagnose()`
445
+ * reads it — but it is **optional**, and four waves of vacuity guards have each
446
+ * closed their own enumeration only for the next family to land outside it
447
+ * ([ADR-010](../../../../adr/010-a-pass-is-constructed-from-evidence.md)'s Context
448
+ * table). A guard is something you can forget to add. A required return type is
449
+ * not: a new family cannot compile without stating its number.
450
+ *
451
+ * Nothing acts on `examined` in this release — plan 0099 adds the floor that
452
+ * fails a rule which produced nothing from nothing. This plan ships the seam
453
+ * alone so that the break to
454
+ * [ts-archunit ADR-010](https://github.com/nielspeter/ts-archunit/blob/main/adr/010-the-extension-surface-is-a-contract.md)'s contract
455
+ * lands in a commit whose only job is the break.
456
+ *
457
+ * ## What the compiler cannot force, and what does
458
+ *
459
+ * The type forces the field to **exist**; it cannot force it to mean anything,
460
+ * and every implementer could satisfy it with `examined: 0`. That is a real
461
+ * hole and it is half-closed:
462
+ *
463
+ * - **The numbers are guarded.** Every family exposes `examinedUnits()` and
464
+ * `tests/core/evidence-at-every-seam.test.ts` requires each to show its count
465
+ * **responding to input** — zero on a narrowed selection, non-zero on a wide
466
+ * one, over a corpus that loaded files either way. A constant fails one half
467
+ * of that pair whichever constant it is; measured, six sabotage rows caught.
468
+ * - **The WIRING is not, and cannot be, in this release.** `examined` is
469
+ * produced here and discarded by the one consumer, so nothing observes it:
470
+ * rewriting any family's `collectViolations()` to `examined: 0` while leaving
471
+ * `examinedUnits()` correct leaves the entire suite green — measured, for the
472
+ * smell family and for `RuleBuilder`. An ADR-009 rule 5 equivalence, recorded
473
+ * rather than guarded by an instrument invented for it.
474
+ *
475
+ * **That equivalence expires in plan 0099**, which reads `examined` at the
476
+ * floor. The commit that gives a claim its first reader is the commit that must
477
+ * retire it — this repo has already had one recorded equivalence outlive its
478
+ * truth by exactly one commit (`CrossProjectBuilder.declaresEmpty`), and a
479
+ * sabotage row for the wiring belongs in 0099's matrix on day one.
480
+ */
481
+ protected abstract collectViolations(): CollectResult;
482
+ /**
483
+ * Does this builder diagnose its own empty discovery?
484
+ *
485
+ * `false` — the gate reports a dead `discovery` glob, which is the fix for
486
+ * [ts-archunit bug 0040](https://github.com/nielspeter/ts-archunit/blob/main/bugs/fixed/0040-a-crosslayer-rule-reports-nothing-when-its-layer-resolves-nothing.md)'s
487
+ * silence half: two of three cross-layer conditions reported **nothing** when a
488
+ * layer resolved to no files.
489
+ *
490
+ * `true` — the builder owns it, and the gate stays out. Two builders override,
491
+ * and for different reasons, which is the thing to understand before adding a
492
+ * third:
493
+ *
494
+ * - `SliceRuleBuilder` returns a constant `true`, because its discovery
495
+ * semantics are **not** per-tree and cannot be expressed by a position filter
496
+ * (below). Nothing about that varies by condition.
497
+ * - `PairFinalBuilder` **asks its condition**, via the registry in
498
+ * `owns-empty-discovery.ts` (plan 0081). There, ownership does vary by
499
+ * condition, and a blanket `true` once suppressed the gate for the one
500
+ * condition that did not self-report — which is why this used to say
501
+ * "`SliceRuleBuilder` is the one that does" and was wrong.
502
+ *
503
+ * A hand-maintained roster of which builders override is the defect class plan
504
+ * 0081 was filed to remove, so this names the two shapes rather than the two
505
+ * classes:
506
+ *
507
+ * | builder | one dead tree among live ones |
508
+ * | --- | --- |
509
+ * | `crossLayer` | a **fault** — that layer's pairs are unchecked |
510
+ * | slice `assignedFrom` | **legitimate** — a slice with no files yet is a real shape |
511
+ *
512
+ * `slice-rule-builder.ts` records that second guard being withdrawn before
513
+ * release for firing on real projects: "a layer not created yet, and the
514
+ * `strict-boundaries` scaffold itself". Slice already handles the all-empty case
515
+ * with a better message than the gate's, so it owns both halves.
516
+ *
517
+ * Declared, never named from the outside. A list of exceptions in the gate is
518
+ * an unchecked claim about who owns what — which is exactly the comment this
519
+ * plan was filed to correct.
520
+ */
521
+ protected ownsDiscoveryDiagnosis(): boolean;
522
+ /**
523
+ * Execute the rule with the given severity.
524
+ * `.severity('error')` is equivalent to `.check()`.
525
+ * `.severity('warn')` is equivalent to `.warn()`.
526
+ */
527
+ severity(level: 'error' | 'warn'): void;
528
+ /**
529
+ * A rule that asserts nothing about what it selects cannot fail, so it is
530
+ * reported as a configuration finding (bug 0019, plan 0070).
531
+ *
532
+ * **Gate-first**, ahead of `collectViolations()`, for three measured reasons:
533
+ * an assertion-less rule cannot produce a legitimate finding, so running it
534
+ * buys nothing but a full AST walk; `CrossProjectBuilder.collectViolations`
535
+ * throws before returning, so a gate placed after it would never run for that
536
+ * builder and its `RangeError` would escape the CLI's `ArchRuleError`-only
537
+ * catch, dropping every remaining rule file; and the alternative ordering —
538
+ * let an existing `bypassFilters` finding win — only functions for rules that
539
+ * opted into `.expectNonEmpty()`, which is the opt-in this whole plan exists
540
+ * because nobody uses.
541
+ *
542
+ * The consequence, accepted: a rule with a dead glob AND no condition reports
543
+ * the missing assertion only. That is the right root cause — no selector
544
+ * makes an assertion-less rule capable of failing — and the selector fault
545
+ * resurfaces on the next run, once there is something to assert.
546
+ *
547
+ * `bypassFilters` makes it a configuration finding: `error` severity
548
+ * regardless of `.asSeverity('warn')`, refused by `.excluding()`, and skipped
549
+ * by diff and baseline. See `severityFor` and ADR-009 rule 1.
550
+ */
551
+ private collectWithAssertionGuard;
552
+ /** This rule, reduced to what `terminal-execution.ts` needs to run it. */
553
+ private asRun;
554
+ /**
555
+ * What `applyFilters` needs, in one place.
556
+ *
557
+ * `violations()`, `check()` and `warn()` each rebuilt this object literally —
558
+ * three copies of the same four fields, which is three places to forget one.
559
+ */
560
+ private filterContext;
561
+ /** This rule's own account of itself, for `vacuity-diagnosis.ts`. */
562
+ private facts;
563
+ /**
564
+ * Execute the rule and return violations after exclusion filtering.
565
+ * Does not throw — use for programmatic access (presets, aggregation).
566
+ */
567
+ violations(): CollectResult;
568
+ /**
569
+ * Plan 0090's escalation, per violation. A DEFERRED warning (`_acceptedWarnings`
570
+ * set) stays `warn` only for a violation whose `subjectOf()` is in the accepted
571
+ * list; anything else — a genuinely new finding — escalates to `error`, which is
572
+ * the whole point: an accepted list that never fails on something new is
573
+ * indistinguishable from an advisory warning, and bug 0084 is what that costs.
574
+ * An ADVISORY warning (`_acceptedWarnings` `undefined`) is unaffected — `sev`
575
+ * passes through unchanged, exactly today's behaviour.
576
+ */
577
+ private fallbackSeverityFor;
578
+ /**
579
+ * Execute the rule and throw `ArchRuleError` if any violations are found.
580
+ * This is the primary terminal method — use in test assertions.
581
+ *
582
+ * @param options - Optional baseline, diff filtering, and output format
583
+ */
584
+ check(options?: CheckOptions): void;
585
+ /**
586
+ * Execute the rule and log violations to stderr. Does not throw.
587
+ * Use for rules that should warn but not fail CI.
588
+ *
589
+ * @param options - Optional baseline, diff filtering, and output format
590
+ */
591
+ warn(options?: CheckOptions): void;
592
+ /**
593
+ * The advice for a DEFERRED warning whose accepted list no longer covers
594
+ * everything it currently finds — plan 0090.
595
+ *
596
+ * PUBLIC and zero-arg, following `inertAdvice()`/`zeroSubjectsAdvice()`'s
597
+ * precedent exactly: read structurally by `diagnose()`, so `doctor`'s preview
598
+ * and `checkAll()`/CLI `check`'s eventual failure carry the same evidence by
599
+ * construction. Returns `''` for an advisory warning (`_acceptedWarnings`
600
+ * `undefined`), for a rule at `'error'` severity, and for a deferred warning
601
+ * whose current findings are all still within `accepted` — a working, healthy
602
+ * deferral is not a problem `doctor` should report, only a breached one is.
603
+ *
604
+ * Calls `this.violations()` rather than re-deriving "is this accepted" a
605
+ * second time: that already applies the exact escalation this reports on, so
606
+ * the two can never disagree about which violations breached the list.
607
+ *
608
+ * Also checks `hasIdentityCollision()` separately, on its own
609
+ * `collectWithAssertionGuard()` pass — not to decide WHETHER to report (that
610
+ * is already folded into `.violations()`'s own escalation, which forces the
611
+ * whole batch to `error` when unsafe), but to choose the RIGHT message: a
612
+ * collision means `accepted` cannot be trusted at all here, which is a
613
+ * different, more urgent fact than "this specific finding is new".
614
+ */
615
+ deferredWarningAdvice(): string;
616
+ /**
617
+ * The advice for a rule that examined zero units — plan 0099.
618
+ *
619
+ * PUBLIC and zero-arg, following `assertionAdvice()`'s precedent exactly: it is
620
+ * read structurally by `diagnose()` so `doctor` and the gate carry the same
621
+ * string **by construction**. Plan 0070 added that seam after the two were
622
+ * measured diverging; review measured this pair diverging the same way, with
623
+ * `diagnose()` still closing "A later release makes this state fail at check
624
+ * time" in the release that makes it fail.
625
+ */
626
+ zeroSubjectsAdvice(): string;
627
+ protected zeroSubjectsViolation(project: ArchProject | undefined): ArchViolation;
628
+ }
629
+ //# sourceMappingURL=terminal-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-builder.d.ts","sourceRoot":"","sources":["../../src/core/terminal-builder.ts"],"names":[],"mappings":"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"}