@mocoto/mahoraga 0.14.1 → 0.14.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (268) hide show
  1. package/dist/analysts/architects/analyst-structure.js +1 -1
  2. package/dist/analysts/architects/archetypes-custom.js +8 -13
  3. package/dist/analysts/architects/detector-archetypes.js +39 -35
  4. package/dist/analysts/architects/orchestrator-archetypes.js +3 -3
  5. package/dist/analysts/architects/signals-project-advanced.js +2 -2
  6. package/dist/analysts/architects/signals-project.js +1 -1
  7. package/dist/analysts/azure-pipelines/analysts/analyst-azure.js +20 -21
  8. package/dist/analysts/azure-pipelines/detectors/detector-azure-structure.js +0 -3
  9. package/dist/analysts/circleci/analysts/analyst-circleci.js +22 -24
  10. package/dist/analysts/circleci/detectors/detector-circleci-structure.js +4 -7
  11. package/dist/analysts/converters/convert-registry.js +1 -1
  12. package/dist/analysts/converters/index.js +1 -1
  13. package/dist/analysts/corrections/auto-fix-engine.js +1 -1
  14. package/dist/analysts/corrections/corrector-structure.js +8 -7
  15. package/dist/analysts/corrections/map-reversion.js +2 -2
  16. package/dist/analysts/corrections/reorganize-barrels.js +3 -3
  17. package/dist/analysts/corrections/rewrite-testes-aliases.js +23 -22
  18. package/dist/analysts/corrections/type-safety/type-analyzer.js +3 -3
  19. package/dist/analysts/corrections/type-safety/type-validator.js +2 -2
  20. package/dist/analysts/corrections/type-safety/usage-analyzer.js +3 -3
  21. package/dist/analysts/css/analysts/analyst-css.js +27 -28
  22. package/dist/analysts/css-in-js/detectors/detector-css-in-js-best-practices.js +8 -15
  23. package/dist/analysts/detectors/detector-architecture.js +2 -2
  24. package/dist/analysts/detectors/detector-bugs-ml.js +8 -8
  25. package/dist/analysts/detectors/detector-code-fragile.js +11 -10
  26. package/dist/analysts/detectors/detector-dependencies.js +5 -5
  27. package/dist/analysts/detectors/detector-duplications.js +5 -8
  28. package/dist/analysts/detectors/detector-monorepo.js +10 -9
  29. package/dist/analysts/detectors/detector-performance.js +2 -1
  30. package/dist/analysts/detectors/detector-recommendation-architecture.js +1 -1
  31. package/dist/analysts/detectors/detector-security.js +1 -1
  32. package/dist/analysts/detectors/detector-structure.js +3 -3
  33. package/dist/analysts/github-actions/analysts/analyst-github-actions.js +5 -8
  34. package/dist/analysts/github-actions/detectors/detector-workflow-accessibility.js +1 -9
  35. package/dist/analysts/github-actions/detectors/detector-workflow-structure.js +1 -4
  36. package/dist/analysts/github-actions/detectors/detector-workflow-trigger-unsafe.js +6 -5
  37. package/dist/analysts/gitlab-ci/analysts/analyst-gitlab-ci.js +2 -2
  38. package/dist/analysts/gitlab-ci/detectors/detector-gitlab-ci-structure.js +0 -3
  39. package/dist/analysts/go/analysts/analyst-best-practices.js +2 -2
  40. package/dist/analysts/go/analysts/analyst-concurrency.js +1 -1
  41. package/dist/analysts/go/analysts/analyst-security.js +1 -1
  42. package/dist/analysts/go/detectors/detector-conventions.js +1 -1
  43. package/dist/analysts/html/analysts/analyst-html.js +10 -12
  44. package/dist/analysts/html/detectors/detector-html.js +3 -3
  45. package/dist/analysts/js-ts/analysts/analyst-commands-cli.js +22 -22
  46. package/dist/analysts/js-ts/analysts/analyst-functions-long.js +5 -5
  47. package/dist/analysts/js-ts/analysts/analyst-patterns-usage.js +6 -2
  48. package/dist/analysts/js-ts/detectors/detector-anti-patterns-async.js +81 -9
  49. package/dist/analysts/js-ts/detectors/detector-constructions-syntactic.js +35 -6
  50. package/dist/analysts/js-ts/detectors/detector-context-smart.js +6 -6
  51. package/dist/analysts/js-ts/detectors/detector-leaks-memory.js +1 -1
  52. package/dist/analysts/js-ts/detectors/detector-types-unsafe.js +33 -2
  53. package/dist/analysts/php/analysts/analyst-php.js +3 -3
  54. package/dist/analysts/php/detectors/detector-php-best-practices.js +5 -5
  55. package/dist/analysts/php/detectors/detector-php-security.js +5 -5
  56. package/dist/analysts/php/scorers/scorer-php.js +2 -2
  57. package/dist/analysts/plugins/detector-documentation.js +5 -6
  58. package/dist/analysts/plugins/detector-markdown.js +7 -7
  59. package/dist/analysts/python/analysts/analyst-python.js +2 -5
  60. package/dist/analysts/react/analysts/analyst-react-hooks.js +63 -8
  61. package/dist/analysts/react/analysts/analyst-react.js +45 -1
  62. package/dist/analysts/react/corrections/correction-react.js +40 -0
  63. package/dist/analysts/react/detectors/detector-react-best-practices.js +4 -4
  64. package/dist/analysts/react/scorers/scorer-react.js +36 -1
  65. package/dist/analysts/rust/analysts/analyst-best-practices.js +42 -3
  66. package/dist/analysts/rust/analysts/analyst-memory.js +2 -2
  67. package/dist/analysts/rust/analysts/analyst-rust.js +52 -5
  68. package/dist/analysts/rust/analysts/analyst-security.js +29 -1
  69. package/dist/analysts/scorers/scorer.js +5 -5
  70. package/dist/analysts/shell/analysts/analyst-shell.js +81 -5
  71. package/dist/analysts/shell/corrections/correction-shell.js +34 -1
  72. package/dist/analysts/shell/detectors/detector-shell-security.js +88 -0
  73. package/dist/analysts/shell/scorers/scorer-shell.js +58 -1
  74. package/dist/analysts/strategists/operator-structure.js +5 -7
  75. package/dist/analysts/strategists/suggestions-contextuais.js +5 -2
  76. package/dist/analysts/svg/analysts/analyst-svg.js +1 -0
  77. package/dist/analysts/tailwind/analysts/analyst-tailwind.js +79 -55
  78. package/dist/analysts/tailwind/corrections/correction-tailwind.js +116 -9
  79. package/dist/analysts/tailwind/detectors/detector-tailwind-best-practices.js +122 -7
  80. package/dist/analysts/tailwind/scorers/scorer-tailwind.js +62 -10
  81. package/dist/analysts/xml/analysts/analyst-xml.js +2 -2
  82. package/dist/app/index.js +1 -0
  83. package/dist/bin/cli-bootstrap.js +6 -4
  84. package/dist/bin/index.js +6 -4
  85. package/dist/caretakers/scoring.js +1 -0
  86. package/dist/cli/commands/command-analysts.js +1 -1
  87. package/dist/cli/commands/command-azure.js +1 -1
  88. package/dist/cli/commands/command-circleci.js +1 -1
  89. package/dist/cli/commands/command-compliance.js +1 -1
  90. package/dist/cli/commands/command-diagnose.js +10 -13
  91. package/dist/cli/commands/command-fix-types.js +9 -32
  92. package/dist/cli/commands/command-formatters.js +2 -2
  93. package/dist/cli/commands/command-gitlab-ci.js +1 -1
  94. package/dist/cli/commands/command-guardian.js +1 -1
  95. package/dist/cli/commands/command-imports.js +6 -6
  96. package/dist/cli/commands/command-jenkins.js +1 -1
  97. package/dist/cli/commands/command-licenses.js +1 -1
  98. package/dist/cli/commands/command-marketplace.js +3 -3
  99. package/dist/cli/commands/command-names.js +3 -8
  100. package/dist/cli/commands/command-perf.js +7 -9
  101. package/dist/cli/commands/command-plugins.js +4 -4
  102. package/dist/cli/diagnostic/auto-fix.js +2 -2
  103. package/dist/cli/diagnostic/exporters/json-exporter.js +1 -1
  104. package/dist/cli/diagnostic/exporters/sharded-exporter.js +0 -3
  105. package/dist/cli/diagnostic/exporters/svg-optimization-exporter.js +1 -1
  106. package/dist/cli/diagnostic/handlers/archetype-handler.js +3 -6
  107. package/dist/cli/diagnostic/handlers/auto-fix-handler.js +4 -4
  108. package/dist/cli/diagnostic/handlers/guardian-handler.js +1 -1
  109. package/dist/cli/diagnostic/processing-diagnostic.js +31 -35
  110. package/dist/cli/diagnostic/processing-helpers.js +2 -2
  111. package/dist/cli/handlers/fix-types-exporter.js +1 -4
  112. package/dist/cli/helpers/display-frame.js +5 -5
  113. package/dist/core/config/auto/auto-fix-config.js +0 -6
  114. package/dist/core/config/chalk-safe.js +2 -2
  115. package/dist/core/config/config.js +6 -8
  116. package/dist/core/config/conventions.js +1 -1
  117. package/dist/core/config/security.js +2 -2
  118. package/dist/core/execution/analysis-cache.js +5 -8
  119. package/dist/core/execution/executor.js +8 -19
  120. package/dist/core/execution/inquisitor.js +24 -21
  121. package/dist/core/execution/results.js +1 -0
  122. package/dist/core/execution/scanner.js +3 -3
  123. package/dist/core/messages/en/analysts/analyst-github-actions-messages.js +1 -1
  124. package/dist/core/messages/en/analysts/analyst-patterns-usage-messages.js +1 -0
  125. package/dist/core/messages/en/analysts/analyst-shell-messages.js +15 -0
  126. package/dist/core/messages/en/analysts/detector-constructions-syntactic-messages.js +6 -0
  127. package/dist/core/messages/en/analysts/detector-js-ts-messages.js +27 -0
  128. package/dist/core/messages/en/analysts/detector-react-messages.js +8 -0
  129. package/dist/core/messages/en/analysts/detector-shell-messages.js +17 -0
  130. package/dist/core/messages/en/analysts/detector-tailwind-messages.js +3 -3
  131. package/dist/core/messages/en/core/plugin-messages.js +31 -3
  132. package/dist/core/messages/en/log/log.js +4 -4
  133. package/dist/core/messages/en/ui/filter-config.js +1 -5
  134. package/dist/core/messages/i18n-system.js +3 -3
  135. package/dist/core/messages/index.js +3 -3
  136. package/dist/core/messages/ja/analysts/analyst-github-actions-messages.js +1 -1
  137. package/dist/core/messages/ja/analysts/analyst-patterns-usage-messages.js +1 -0
  138. package/dist/core/messages/ja/analysts/analyst-shell-messages.js +15 -0
  139. package/dist/core/messages/ja/analysts/detector-constructions-syntactic-messages.js +6 -0
  140. package/dist/core/messages/ja/analysts/detector-js-ts-messages.js +27 -0
  141. package/dist/core/messages/ja/analysts/detector-react-messages.js +8 -0
  142. package/dist/core/messages/ja/analysts/detector-shell-messages.js +17 -0
  143. package/dist/core/messages/ja/analysts/detector-tailwind-messages.js +3 -3
  144. package/dist/core/messages/ja/core/plugin-messages.js +31 -3
  145. package/dist/core/messages/ja/log/log.js +4 -4
  146. package/dist/core/messages/ja/ui/filter-config.js +1 -1
  147. package/dist/core/messages/pt/analysts/analyst-github-actions-messages.js +1 -1
  148. package/dist/core/messages/pt/analysts/analyst-patterns-usage-messages.js +1 -0
  149. package/dist/core/messages/pt/analysts/analyst-shell-messages.js +15 -0
  150. package/dist/core/messages/pt/analysts/detector-constructions-syntactic-messages.js +6 -0
  151. package/dist/core/messages/pt/analysts/detector-js-ts-messages.js +27 -0
  152. package/dist/core/messages/pt/analysts/detector-react-messages.js +8 -0
  153. package/dist/core/messages/pt/analysts/detector-shell-messages.js +17 -0
  154. package/dist/core/messages/pt/analysts/detector-tailwind-messages.js +3 -3
  155. package/dist/core/messages/pt/core/plugin-messages.js +31 -3
  156. package/dist/core/messages/pt/log/log-engine.js +6 -6
  157. package/dist/core/messages/pt/log/log.js +3 -3
  158. package/dist/core/messages/pt/ui/filter-config.js +1 -1
  159. package/dist/core/messages/shared/icons.js +3 -3
  160. package/dist/core/messages/zh/analysts/analyst-github-actions-messages.js +1 -1
  161. package/dist/core/messages/zh/analysts/analyst-patterns-usage-messages.js +1 -0
  162. package/dist/core/messages/zh/analysts/analyst-shell-messages.js +15 -0
  163. package/dist/core/messages/zh/analysts/detector-constructions-syntactic-messages.js +6 -0
  164. package/dist/core/messages/zh/analysts/detector-js-ts-messages.js +27 -0
  165. package/dist/core/messages/zh/analysts/detector-react-messages.js +8 -0
  166. package/dist/core/messages/zh/analysts/detector-shell-messages.js +17 -0
  167. package/dist/core/messages/zh/analysts/detector-tailwind-messages.js +3 -3
  168. package/dist/core/messages/zh/core/plugin-messages.js +31 -3
  169. package/dist/core/messages/zh/log/log.js +3 -3
  170. package/dist/core/messages/zh/ui/filter-config.js +1 -5
  171. package/dist/core/parsing/filters.js +3 -3
  172. package/dist/core/parsing/langs/json.js +1 -1
  173. package/dist/core/parsing/langs/python.js +1 -1
  174. package/dist/core/parsing/langs/typescript.js +1 -1
  175. package/dist/core/parsing/parser.js +2 -2
  176. package/dist/core/registry/file-registry.js +3 -2
  177. package/dist/core/registry/paths.js +3 -3
  178. package/dist/core/reporting/default-reporter.js +2 -2
  179. package/dist/core/schema/version.js +6 -6
  180. package/dist/core/workers/worker-executor.js +3 -3
  181. package/dist/core/workers/worker-pool.js +0 -0
  182. package/dist/guardian/baseline.js +1 -1
  183. package/dist/guardian/gpg.js +3 -1
  184. package/dist/guardian/integrity.js +2 -7
  185. package/dist/guardian/records.js +6 -1
  186. package/dist/guardian/result.js +1 -1
  187. package/dist/guardian/sentinel.js +6 -1
  188. package/dist/guardian/watcher-hidden.js +5 -1
  189. package/dist/licenses/fs-utils.js +4 -1
  190. package/dist/licenses/generate-notices.js +1 -1
  191. package/dist/licenses/header-options.js +0 -1
  192. package/dist/licenses/index.js +1 -0
  193. package/dist/licenses/normalizer.js +10 -9
  194. package/dist/node.loader.js +224 -4
  195. package/dist/reports/analise-async-patterns.js +1 -1
  196. package/dist/reports/filter-smart.js +2 -5
  197. package/dist/reports/generator-report.js +4 -4
  198. package/dist/reports/report-archetypes.js +10 -10
  199. package/dist/reports/report-caretaker-health.js +2 -1
  200. package/dist/sdk/analyzer.js +1 -1
  201. package/dist/shared/data-processing/fragment-report.js +10 -10
  202. package/dist/shared/data-processing/json.js +1 -1
  203. package/dist/shared/data-processing/occurrences.js +3 -2
  204. package/dist/shared/formatters/code-min-formatter.js +1 -1
  205. package/dist/shared/formatters/engines/prettier.js +1 -1
  206. package/dist/shared/formatters/engines/stylelint.js +6 -9
  207. package/dist/shared/formatters/formatter.js +8 -8
  208. package/dist/shared/formatters/formatters/code.js +3 -3
  209. package/dist/shared/formatters/formatters/css.js +2 -10
  210. package/dist/shared/formatters/formatters/dotfiles.js +1 -1
  211. package/dist/shared/formatters/formatters/html.js +1 -5
  212. package/dist/shared/formatters/formatters/json.js +0 -3
  213. package/dist/shared/formatters/formatters/markdown.js +18 -23
  214. package/dist/shared/formatters/formatters/properties.js +2 -2
  215. package/dist/shared/formatters/formatters/shell.js +1 -4
  216. package/dist/shared/formatters/formatters/sql.js +0 -3
  217. package/dist/shared/formatters/formatters/xml.js +5 -7
  218. package/dist/shared/formatters/formatters/yaml.js +2 -7
  219. package/dist/shared/formatters/index.js +1 -1
  220. package/dist/shared/helpers/framework-detector.js +1 -1
  221. package/dist/shared/helpers/json.js +1 -1
  222. package/dist/shared/helpers/magic-constants-whitelist.js +1 -1
  223. package/dist/shared/helpers/masking.js +17 -17
  224. package/dist/shared/helpers/reader-report.js +0 -12
  225. package/dist/shared/helpers/structural-hash.js +3 -2
  226. package/dist/shared/helpers/structure.js +1 -1
  227. package/dist/shared/marketplace/registry.js +1 -1
  228. package/dist/shared/marketplace/remote.js +4 -4
  229. package/dist/shared/persistence/persistence.js +0 -1
  230. package/dist/shared/plugins/core-plugin.js +3 -1
  231. package/dist/shared/plugins/registry.js +3 -2
  232. package/dist/types/caretakers/imports-barrel.js +1 -0
  233. package/dist/types/caretakers/index.js +4 -0
  234. package/dist/types/caretakers/map-reversion.js +1 -0
  235. package/dist/types/caretakers/pruning.js +1 -0
  236. package/dist/types/caretakers/scoring.js +1 -0
  237. package/dist/types/common/analysts.js +1 -1
  238. package/dist/types/core/config/filters.js +1 -0
  239. package/dist/types/core/config/index.js +2 -0
  240. package/dist/types/core/execution/ambiente.js +1 -0
  241. package/dist/types/core/execution/linguagens.js +1 -0
  242. package/dist/types/core/execution/parse-errors.js +1 -0
  243. package/dist/types/core/execution/results.js +1 -0
  244. package/dist/types/core/execution/structure-json.js +1 -0
  245. package/dist/types/core/index.js +1 -0
  246. package/dist/types/core/messages/index.js +1 -0
  247. package/dist/types/core/messages/log.js +1 -0
  248. package/dist/types/core/parsing/babel-narrow.js +1 -0
  249. package/dist/types/core/parsing/index.js +1 -0
  250. package/dist/types/core/runtime.js +1 -0
  251. package/dist/types/guardian/index.js +2 -0
  252. package/dist/types/guardian/integrity.js +7 -0
  253. package/dist/types/guardian/snapshot.js +1 -0
  254. package/dist/types/index.js +4 -4
  255. package/dist/types/licenses/index.js +2 -0
  256. package/dist/types/processing/display.js +16 -13
  257. package/dist/types/processing/filters.js +3 -7
  258. package/dist/types/reports/compliance.js +1 -0
  259. package/dist/types/reports/streaming.js +1 -0
  260. package/dist/types/scripts/index.js +1 -0
  261. package/dist/types/scripts/migrar-aliases.js +1 -0
  262. package/dist/types/sdk/index.js +1 -0
  263. package/dist/types/shared/index.js +2 -0
  264. package/dist/types/vulnerabilities/index.js +2 -0
  265. package/dist/vulnerabilities/npm-audit.js +0 -1
  266. package/dist/vulnerabilities/scanner.js +2 -1
  267. package/dist/vulnerabilities/vulnerabilities.js +0 -1
  268. package/package.json +11 -12
@@ -1,6 +1,27 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  import { splitLines } from '../../../shared/helpers/index.js';
3
3
  import { criarOcorrencia } from '../../../types/index.js';
4
+ const V3_DEPRECATED_UTILITIES_MAP = {
5
+ 'shadow-sm': 'shadow-xs',
6
+ 'drop-shadow-sm': 'drop-shadow-xs',
7
+ 'blur-sm': 'blur-xs',
8
+ 'backdrop-blur-sm': 'backdrop-blur-xs',
9
+ 'rounded-sm': 'rounded-xs',
10
+ 'outline-none': 'outline-hidden',
11
+ 'flex-shrink': 'shrink',
12
+ 'flex-grow': 'grow',
13
+ 'overflow-ellipsis': 'text-ellipsis',
14
+ 'decoration-slice': 'box-decoration-slice',
15
+ 'decoration-clone': 'box-decoration-clone',
16
+ };
17
+ const V3_SUFFIX_UTILITIES_MAP = {
18
+ 'shadow': 'shadow-sm',
19
+ 'drop-shadow': 'drop-shadow-sm',
20
+ 'blur': 'blur-sm',
21
+ 'backdrop-blur': 'backdrop-blur-sm',
22
+ 'rounded': 'rounded-sm',
23
+ 'ring': 'ring-3',
24
+ };
4
25
  const TAILWIND_UTILITIES = new Set([
5
26
  'bg-', 'text-', 'm-', 'mt-', 'mr-', 'mb-', 'ml-', 'mx-', 'my-',
6
27
  'p-', 'pt-', 'pr-', 'pb-', 'pl-', 'px-', 'py-',
@@ -11,13 +32,16 @@ const TAILWIND_UTILITIES = new Set([
11
32
  'transition', 'duration-', 'ease-', 'animate-',
12
33
  'z-', 'overflow-', 'cursor-', 'select-', 'blur-',
13
34
  'top-', 'left-', 'right-', 'bottom-', 'inset-',
35
+ 'field-sizing-', 'text-shadow-', 'inset-shadow-', 'zoom-', 'perspective-',
36
+ 'outline-', 'drop-shadow-', 'backdrop-blur-',
14
37
  ]);
15
38
  const TAILWIND_COLORS = [
16
39
  'slate', 'gray', 'zinc', 'neutral', 'stone', 'red', 'orange', 'amber',
17
40
  'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue',
18
41
  'indigo', 'violet', 'purple', 'fuchsia', 'pink', 'rose',
42
+ 'mauve', 'olive', 'mist', 'taupe',
19
43
  ];
20
- function _isTailwindColor(value) {
44
+ function isTailwindColor(value) {
21
45
  return TAILWIND_COLORS.some(c => value.includes(c));
22
46
  }
23
47
  function getPropertyKey(token) {
@@ -45,12 +69,27 @@ function getPropertyKey(token) {
45
69
  if (/^opacity/.test(token)) {
46
70
  return 'opacity';
47
71
  }
72
+ if (/^field-sizing/.test(token)) {
73
+ return 'field-sizing';
74
+ }
75
+ if (/^text-shadow/.test(token)) {
76
+ return 'text-shadow';
77
+ }
78
+ if (/^inset-shadow/.test(token)) {
79
+ return 'inset-shadow';
80
+ }
81
+ if (/^zoom/.test(token)) {
82
+ return 'zoom';
83
+ }
84
+ if (/^perspective/.test(token)) {
85
+ return 'perspective';
86
+ }
48
87
  return null;
49
88
  }
50
89
  export const detectorTailwindBestPractices = {
51
90
  nome: 'detector-tailwind-best-practices',
52
91
  categoria: 'estilo',
53
- descricao: 'Detecta más práticas em Tailwind CSS',
92
+ descricao: 'Detecta más práticas em Tailwind CSS v4',
54
93
  test: (relPath) => /\.(jsx|tsx|js|ts|html|astro)$/i.test(relPath),
55
94
  aplicar: (src, relPath) => {
56
95
  if (!src) {
@@ -62,10 +101,86 @@ export const detectorTailwindBestPractices = {
62
101
  let inlineStyleCount = 0;
63
102
  linhas.forEach((linha, index) => {
64
103
  const numeroLinha = index + 1;
65
- if (/\bclass(Name)?\s*=\s*["'][^"']*["']/.test(linha)) {
104
+ if (/@tailwind\s+(base|components|utilities)/.test(linha)) {
105
+ ocorrencias.push(criarOcorrencia({
106
+ tipo: 'tailwind-v3-directive',
107
+ nivel: 'aviso',
108
+ mensagem: 'Diretiva @tailwind detectada (v3) - use @import "tailwindcss"',
109
+ relPath,
110
+ linha: numeroLinha,
111
+ sugestao: 'Substitua @tailwind base/components/utilities por @import "tailwindcss"'
112
+ }));
113
+ }
114
+ if (/@layer\s+utilities\s*\{/.test(linha)) {
115
+ ocorrencias.push(criarOcorrencia({
116
+ tipo: 'tailwind-v3-layer-utilities',
117
+ nivel: 'info',
118
+ mensagem: '@layer utilities detectado (v3) - use @utility (v4)',
119
+ relPath,
120
+ linha: numeroLinha,
121
+ sugestao: 'Use @utility nome-da-utilidade { ... } ao invés de @layer utilities { ... }'
122
+ }));
123
+ }
124
+ if (/\btheme\(/.test(linha)) {
125
+ ocorrencias.push(criarOcorrencia({
126
+ tipo: 'tailwind-theme-function',
127
+ nivel: 'info',
128
+ mensagem: 'theme() detectado (deprecated v3) - use CSS variables',
129
+ relPath,
130
+ linha: numeroLinha,
131
+ sugestao: 'Substitua theme(colors.red.500) por var(--color-red-500)'
132
+ }));
133
+ }
134
+ if (/\bclass(Name)?\s*=\s*["'][^"']*![\w-]/.test(linha)) {
135
+ ocorrencias.push(criarOcorrencia({
136
+ tipo: 'tailwind-important-prefix',
137
+ nivel: 'info',
138
+ mensagem: '!important como prefixo (v3) - mova ! para o final da classe',
139
+ relPath,
140
+ linha: numeroLinha,
141
+ sugestao: 'Use "flex!" ao invés de "!flex"'
142
+ }));
143
+ }
144
+ if (/\bclass(Name)?\s*=\s*["'][^"']*\[--[^\]]+\]/.test(linha)) {
145
+ ocorrencias.push(criarOcorrencia({
146
+ tipo: 'tailwind-arbitrary-var-syntax',
147
+ nivel: 'info',
148
+ mensagem: 'Variável em colchetes (v3) - use parênteses (v4)',
149
+ relPath,
150
+ linha: numeroLinha,
151
+ sugestao: 'Use bg-(--brand-color) ao invés de bg-[--brand-color]'
152
+ }));
153
+ }
154
+ if (/\bclass(Name)?\s*=\s*["']([^"']*)["']/.test(linha)) {
66
155
  const classMatch = linha.match(/\bclass(Name)?\s*=\s*["']([^"']*)["']/);
67
156
  if (classMatch) {
68
157
  const classes = classMatch[2].split(/\s+/).filter(Boolean);
158
+ for (const cls of classes) {
159
+ const v4Equivalent = V3_DEPRECATED_UTILITIES_MAP[cls];
160
+ if (v4Equivalent) {
161
+ ocorrencias.push(criarOcorrencia({
162
+ tipo: 'tailwind-v3-deprecated-utility',
163
+ nivel: 'aviso',
164
+ mensagem: `Classe obsoleta do v3: "${cls}" → use "${v4Equivalent}"`,
165
+ relPath,
166
+ linha: numeroLinha,
167
+ sugestao: `Substitua ${cls} por ${v4Equivalent}`
168
+ }));
169
+ }
170
+ const baseClass = cls.split(':').pop() ?? cls;
171
+ if (baseClass && V3_SUFFIX_UTILITIES_MAP[baseClass]) {
172
+ const variante = cls.endsWith(baseClass) ? '' : cls.slice(0, -baseClass.length);
173
+ const v4Suffix = V3_SUFFIX_UTILITIES_MAP[baseClass];
174
+ ocorrencias.push(criarOcorrencia({
175
+ tipo: 'tailwind-v3-deprecated-utility',
176
+ nivel: 'aviso',
177
+ mensagem: `Classe renomeada no v4: "${cls}" → use "${variante}${v4Suffix}"`,
178
+ relPath,
179
+ linha: numeroLinha,
180
+ sugestao: `Substitua ${cls} por ${variante}${v4Suffix} (ex: shadow → shadow-sm)`
181
+ }));
182
+ }
183
+ }
69
184
  const seen = new Map();
70
185
  classes.forEach(token => {
71
186
  const base = token.split(':').pop() ?? token;
@@ -139,7 +254,7 @@ export const detectorTailwindBestPractices = {
139
254
  }
140
255
  const hardcodedValues = classes.filter(c => {
141
256
  const val = c.split('-').pop() ?? '';
142
- return /^\d+$/.test(val) && !TAILWIND_COLORS.some(col => c.includes(col)) && val.length > 2;
257
+ return /^\d+$/.test(val) && !isTailwindColor(c) && val.length > 2;
143
258
  });
144
259
  if (hardcodedValues.length > 0 && !hardcodedValues.some(v => /^[0-9]+\/[0-9]+$/.test(v))) {
145
260
  ocorrencias.push(criarOcorrencia({
@@ -148,7 +263,7 @@ export const detectorTailwindBestPractices = {
148
263
  mensagem: 'Valor hardcoded detectado - use tokens de design do Tailwind',
149
264
  relPath,
150
265
  linha: numeroLinha,
151
- sugestao: 'Extraia cores, espaçamentos e tamanhos para o tailwind.config.js'
266
+ sugestao: 'Extraia cores, espaçamentos e tamanhos para @theme no CSS (v4)'
152
267
  }));
153
268
  }
154
269
  }
@@ -166,7 +281,7 @@ export const detectorTailwindBestPractices = {
166
281
  mensagem: `Valor arbitrário detectado: ${val}`,
167
282
  relPath,
168
283
  linha: numeroLinha,
169
- sugestao: 'Considere adicionar ao tailwind.config.js'
284
+ sugestao: 'Considere adicionar ao @theme no CSS (v4)'
170
285
  }));
171
286
  }
172
287
  }
@@ -204,7 +319,7 @@ export const detectorTailwindBestPractices = {
204
319
  mensagem: 'Uso excessivo de valores arbitrários - pode indicar falta de tokens de design',
205
320
  relPath,
206
321
  linha: 1,
207
- sugestao: 'Defina tokens personalizados em tailwind.config.js ao invés de valores arbitrários'
322
+ sugestao: 'Defina tokens personalizados via @theme no CSS ao invés de valores arbitrários'
208
323
  }));
209
324
  }
210
325
  return ocorrencias;
@@ -1,17 +1,36 @@
1
1
  // SPDX-License-Identifier: MIT
2
2
  import { splitLines } from '../../../shared/helpers/index.js';
3
+ const V3_DEPRECATED_MAP = {
4
+ 'shadow-sm': 'shadow-xs',
5
+ 'drop-shadow-sm': 'drop-shadow-xs',
6
+ 'blur-sm': 'blur-xs',
7
+ 'rounded-sm': 'rounded-xs',
8
+ 'outline-none': 'outline-hidden',
9
+ 'flex-shrink': 'shrink',
10
+ 'flex-grow': 'grow',
11
+ 'overflow-ellipsis': 'text-ellipsis',
12
+ 'decoration-slice': 'box-decoration-slice',
13
+ 'decoration-clone': 'box-decoration-clone',
14
+ };
3
15
  export function pontuarTailwind(src, _relPath) {
4
16
  let score = 0;
5
17
  const maxScore = 100;
6
18
  const issues = [];
7
19
  const strengths = [];
8
- const _linhas = splitLines(src);
9
20
  const srcCompleto = src;
10
21
  const classMatches = srcCompleto.match(/\bclass(Name)?\s*=\s*["']([^"']*)["']/g) ?? [];
11
22
  const allClasses = classMatches.map(metrica => {
12
23
  const match = metrica.match(/["']([^"']*)["']/);
13
24
  return match ? match[1].split(/\s+/).filter(Boolean) : [];
14
25
  }).flat();
26
+ const v3Deprecated = allClasses.filter(c => V3_DEPRECATED_MAP[c] !== undefined);
27
+ if (v3Deprecated.length === 0) {
28
+ score += 5;
29
+ strengths.push('Sem classes obsoletas do v3');
30
+ }
31
+ else {
32
+ issues.push(`${v3Deprecated.length} classe(s) obsoleta(s) do v3 detectadas: ${v3Deprecated.map(c => `${c}→${V3_DEPRECATED_MAP[c]}`).join(', ')}`);
33
+ }
15
34
  const duplicates = allClasses.filter((elem, indice) => allClasses.indexOf(elem) !== indice);
16
35
  if (duplicates.length === 0) {
17
36
  score += 10;
@@ -55,7 +74,7 @@ export function pontuarTailwind(src, _relPath) {
55
74
  }
56
75
  else {
57
76
  score += 2;
58
- issues.push(`${arbitraryValues.length} valores arbitrários - considere tailwind.config.js`);
77
+ issues.push(`${arbitraryValues.length} valores arbitrários - considere @theme no CSS`);
59
78
  }
60
79
  const importantCount = (srcCompleto.match(/class(Name)?=.*!/g) ?? []).length;
61
80
  if (importantCount === 0) {
@@ -123,15 +142,48 @@ export function pontuarTailwind(src, _relPath) {
123
142
  else {
124
143
  issues.push(`Média de ${avgClasses.toFixed(1)} classes por elemento - considere extrair componentes`);
125
144
  }
126
- const customCssPatterns = (srcCompleto.match(/@apply|@layer|@tailwind/g) ?? []).length;
127
- if (customCssPatterns > 0) {
145
+ const hasThemeDirective = /@theme\b/.test(srcCompleto);
146
+ const hasConfigRef = /\btailwind\.config|\b@config\b/.test(srcCompleto);
147
+ if (hasThemeDirective) {
128
148
  score += 5;
129
- strengths.push('Uso de @apply para estilos customizados');
149
+ strengths.push('Uso de @theme para design tokens (v4)');
130
150
  }
131
- const designTokensInConfig = /\btailwind\.config/.test(srcCompleto);
132
- if (designTokensInConfig) {
133
- score += 5;
134
- strengths.push('Design tokens configurados');
151
+ else if (hasConfigRef) {
152
+ score += 2;
153
+ issues.push('Use @theme no CSS ao invés de tailwind.config.js (v4)');
154
+ }
155
+ else {
156
+ score += 3;
157
+ }
158
+ const hasImportTailwindcss = /@import\s+["']tailwindcss["']/.test(srcCompleto);
159
+ const hasTailwindDirective = /@tailwind\s+(base|components|utilities)/.test(srcCompleto);
160
+ if (hasImportTailwindcss) {
161
+ score += 3;
162
+ strengths.push('Importa Tailwind via @import "tailwindcss" (v4)');
163
+ }
164
+ else if (hasTailwindDirective) {
165
+ issues.push('Use @import "tailwindcss" ao invés de @tailwind (v4)');
166
+ }
167
+ const hasUtilityDirective = /@utility\b/.test(srcCompleto);
168
+ const hasLayerUtilities = /@layer\s+utilities/.test(srcCompleto);
169
+ if (hasUtilityDirective) {
170
+ score += 4;
171
+ strengths.push('Uso de @utility para custom utilities (v4)');
172
+ }
173
+ else if (hasLayerUtilities) {
174
+ issues.push('Use @utility ao invés de @layer utilities (v4)');
175
+ }
176
+ const v3ImportantPrefix = (srcCompleto.match(/class(Name)?\s*=\s*["'][^"']*![\w-]/g) ?? []).length;
177
+ if (v3ImportantPrefix > 0) {
178
+ issues.push(`${v3ImportantPrefix} uso(s) de ! como prefixo (v3) - mova ! para o final (ex: flex! no lugar de !flex)`);
179
+ }
180
+ const v3VariableArbitrary = (srcCompleto.match(/\[--[^\]]+\]/g) ?? []).length;
181
+ if (v3VariableArbitrary > 0) {
182
+ issues.push(`${v3VariableArbitrary} variável(is) em colchetes - use bg-(--var) ao invés de bg-[--var] (v4)`);
183
+ }
184
+ const themeFunction = (srcCompleto.match(/\btheme\(/g) ?? []).length;
185
+ if (themeFunction > 0) {
186
+ issues.push(`${themeFunction} uso(s) de theme() - prefira CSS variables (var(--color-*)) (v4)`);
135
187
  }
136
188
  return {
137
189
  score: Math.min(score, maxScore),
@@ -144,6 +196,6 @@ export function pontuarTailwind(src, _relPath) {
144
196
  export const pontuadorTailwind = {
145
197
  nome: 'pontuador-tailwind',
146
198
  categoria: 'estilo',
147
- descricao: 'Pontua qualidade de Tailwind CSS',
199
+ descricao: 'Pontua qualidade de Tailwind CSS v4',
148
200
  pontuar: pontuarTailwind
149
201
  };
@@ -147,7 +147,7 @@ function collectXmlIssues(src, relPath) {
147
147
  }
148
148
  // DOCTYPE + ENTITY (XXE)
149
149
  for (const metrica of scan.matchAll(/<!DOCTYPE\b[\s\S]*?(?:\]\s*>|>)/gi)) {
150
- const chunk = metrica[0] ?? '';
150
+ const chunk = metrica[0];
151
151
  const hasExternalId = /\b(SYSTEM|PUBLIC)\b/i.test(chunk);
152
152
  const line = lineOf(metrica.index);
153
153
  ocorrencias.push(warn(messages.XmlMensagens.doctypeDetectado, relPath, line));
@@ -156,7 +156,7 @@ function collectXmlIssues(src, relPath) {
156
156
  }
157
157
  }
158
158
  for (const metrica of scan.matchAll(/<!ENTITY\b[\s\S]*?>/gi)) {
159
- const chunk = metrica[0] ?? '';
159
+ const chunk = metrica[0];
160
160
  const hasExternal = /\b(SYSTEM|PUBLIC)\b/i.test(chunk);
161
161
  const isParamEntity = /<!ENTITY\s+%/i.test(chunk);
162
162
  const line = lineOf(metrica.index);
@@ -0,0 +1 @@
1
+ export * from './github.js';
@@ -35,9 +35,11 @@ async function registrarLoader() {
35
35
  const loaderCaminho = resolvePath(distRaiz, 'node.loader.js');
36
36
  const loaderUrl = pathToFileURL(loaderCaminho).toString();
37
37
  // Tenta registrar o loader via API experimental da v20+
38
- const { register } = await import('node:module');
39
- if (typeof register === 'function') {
40
- register(loaderUrl, pathToFileURL('./'));
38
+ const moduleImport = await import('node:module');
39
+ const registerHooks = moduleImport.registerHooks;
40
+ if (typeof registerHooks === 'function') {
41
+ const hooks = await import(loaderUrl);
42
+ registerHooks(hooks);
41
43
  }
42
44
  }
43
45
  catch (err) {
@@ -170,7 +172,7 @@ export async function mainCli() {
170
172
  log.debug(CliBinMensagens.erroInicializarFormatadores.replace('{erro}', err instanceof Error ? err.message : String(err)));
171
173
  }
172
174
  // 4. Registro de Comandos
173
- registrarComandos(program, ocorrencia => aplicarFlagsGlobais(ocorrencia));
175
+ registrarComandos(program, ocorrencia => void aplicarFlagsGlobais(ocorrencia));
174
176
  program.addCommand(comandoPerf());
175
177
  // 5. Flags de histórico
176
178
  const argv = process.argv.slice(2);
package/dist/bin/index.js CHANGED
@@ -35,9 +35,11 @@ async function registrarLoader() {
35
35
  const loaderCaminho = resolvePath(distRaiz, 'node.loader.js');
36
36
  const loaderUrl = pathToFileURL(loaderCaminho).toString();
37
37
  // Tenta registrar o loader via API experimental da v20+
38
- const { register } = await import('node:module');
39
- if (typeof register === 'function') {
40
- register(loaderUrl, pathToFileURL('./'));
38
+ const moduleImport = await import('node:module');
39
+ const registerHooks = moduleImport.registerHooks;
40
+ if (typeof registerHooks === 'function') {
41
+ const hooks = await import(loaderUrl);
42
+ registerHooks(hooks);
41
43
  }
42
44
  }
43
45
  catch (err) {
@@ -170,7 +172,7 @@ export async function mainCli() {
170
172
  log.debug(CliBinMensagens.erroInicializarFormatadores.replace('{erro}', err instanceof Error ? err.message : String(err)));
171
173
  }
172
174
  // 4. Registro de Comandos
173
- registrarComandos(program, ocorrencia => aplicarFlagsGlobais(ocorrencia));
175
+ registrarComandos(program, ocorrencia => void aplicarFlagsGlobais(ocorrencia));
174
176
  program.addCommand(comandoPerf());
175
177
  // 5. Flags de histórico
176
178
  const argv = process.argv.slice(2);
@@ -1 +1,2 @@
1
+ // Tipos mínimos para o zelador de pontuação
1
2
  export {};
@@ -56,7 +56,7 @@ export function comandoAnalistas() {
56
56
  geradoEm: new Date().toISOString(),
57
57
  total: lista.length,
58
58
  analistas: lista,
59
- configLimites: config.ANALISE_LIMITES ?? {}
59
+ configLimites: config.ANALISE_LIMITES
60
60
  });
61
61
  log.sucesso(messages.CliComandoAnalistasMensagens.jsonExportado(destino));
62
62
  return;
@@ -73,7 +73,7 @@ export function comandoAzure() {
73
73
  console.log('');
74
74
  ocorrencias.forEach((ocorrencia) => {
75
75
  const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
76
- log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem ?? ''));
76
+ log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
77
77
  if (ocorrencia.sugestao) {
78
78
  log.info(msgs.sugestao(ocorrencia.sugestao));
79
79
  }
@@ -69,7 +69,7 @@ export function comandoCircleCI() {
69
69
  console.log('');
70
70
  ocorrencias.forEach(ocorrencia => {
71
71
  const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
72
- log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem ?? ''));
72
+ log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
73
73
  if (ocorrencia.sugestao) {
74
74
  log.info(msgs.sugestao(ocorrencia.sugestao));
75
75
  }
@@ -28,7 +28,7 @@ export function comandoCompliance() {
28
28
  }
29
29
  const { processarDiagnostico } = await import('../diagnostic/index.js');
30
30
  const resultado = await processarDiagnostico({ json: true });
31
- const ocorrencias = resultado.resultadoFinal.ocorrencias ?? [];
31
+ const ocorrencias = resultado.resultadoFinal.ocorrencias;
32
32
  const relatorio = gerarRelatorioCompliance(framework, ocorrencias, {
33
33
  nomeProjeto: process.cwd().split('/').pop() ?? 'projeto',
34
34
  duracao: resultado.resultadoFinal.metricas.tempoTotal ?? 0,
@@ -44,10 +44,6 @@ async function mostrarSugestoesVerbose(opts, command, logNivel) {
44
44
  const activeFlags = [];
45
45
  const details = [];
46
46
  const parentOpts = obterOptsParent(command);
47
- if (json) {
48
- activeFlags.push('--json');
49
- details.push(messages.CliComandoDiagnosticarMensagens.detalheSaidaEstruturada);
50
- }
51
47
  if (Boolean(opts['guardianCheck'])) {
52
48
  activeFlags.push('--guardian-check');
53
49
  details.push(messages.CliComandoDiagnosticarMensagens.detalheGuardian);
@@ -81,28 +77,29 @@ async function mostrarSugestoesVerbose(opts, command, logNivel) {
81
77
  activeFlags.push('--auto-fix-conservative');
82
78
  details.push(messages.CliComandoDiagnosticarMensagens.detalheAutoFixConservative);
83
79
  }
84
- const includes = opts['include'] || [];
85
- const excludes = opts['exclude'] || [];
80
+ const includes = opts['include'];
81
+ const excludes = opts['exclude'];
86
82
  if (includes.length) {
87
83
  details.push(messages.CliComandoDiagnosticarMensagens.detalheIncludePatterns(includes.length, includes.join(', ')));
88
84
  }
89
85
  if (excludes.length) {
90
86
  details.push(messages.CliComandoDiagnosticarMensagens.detalheExcludePatterns(excludes.length, excludes.join(', ')));
91
87
  }
92
- const parentExport = (parentOpts && Object.prototype.hasOwnProperty.call(parentOpts, 'export') && Boolean(parentOpts['export']));
93
- const parentExportFull = (parentOpts && Object.prototype.hasOwnProperty.call(parentOpts, 'exportFull') && Boolean(parentOpts['exportFull']));
88
+ const parentExport = (Object.prototype.hasOwnProperty.call(parentOpts, 'export') && Boolean(parentOpts['export']));
89
+ const parentExportFull = (Object.prototype.hasOwnProperty.call(parentOpts, 'exportFull') && Boolean(parentOpts['exportFull']));
94
90
  const localExport = Boolean(opts['export']);
95
91
  const localExportFull = Boolean(opts['exportFull']);
96
92
  if (parentExport || localExport) {
97
93
  activeFlags.push('--export');
98
- const relDir = config && (config['REPORTS_DIR'] ?? 'reports');
99
- details.push(messages.CliComandoDiagnosticarMensagens.detalheExport(String(relDir)));
94
+ const relDirValue = config?.['REPORTS_DIR'];
95
+ const relDir = typeof relDirValue === 'string' ? relDirValue : 'reports';
96
+ details.push(messages.CliComandoDiagnosticarMensagens.detalheExport(relDir));
100
97
  }
101
98
  if (parentExportFull || localExportFull) {
102
99
  activeFlags.push('--export-full');
103
100
  details.push(messages.CliComandoDiagnosticarMensagens.detalheExportFull);
104
101
  }
105
- const resolvedParentLogNivel = parentOpts && Object.prototype.hasOwnProperty.call(parentOpts, 'logLevel') ? String(parentOpts['logLevel']) : undefined;
102
+ const resolvedParentLogNivel = Object.prototype.hasOwnProperty.call(parentOpts, 'logLevel') ? String(parentOpts['logLevel']) : undefined;
106
103
  const effectiveLogNivel = logNivel || (resolvedParentLogNivel ?? 'info');
107
104
  details.push(messages.CliComandoDiagnosticarMensagens.detalheLogLevel(effectiveLogNivel));
108
105
  details.push(messages.CliComandoDiagnosticarMensagens.dicaPrefiraLogLevelDebug);
@@ -151,7 +148,7 @@ export function comandoDiagnosticar(aplicarFlagsGlobais) {
151
148
  cmd.allowUnknownOption(true);
152
149
  cmd.allowExcessArguments(true);
153
150
  for (const opt of optionsDiagnosticar) {
154
- if ('parser' in opt && opt.parser) {
151
+ if ('parser' in opt) {
155
152
  cmd.option(opt.flags, opt.desc, opt.parser, opt.defaultValue);
156
153
  }
157
154
  else if ('defaultValue' in opt) {
@@ -162,7 +159,7 @@ export function comandoDiagnosticar(aplicarFlagsGlobais) {
162
159
  }
163
160
  }
164
161
  cmd.action(async (opts, command) => {
165
- await aplicarFlagsCombinadas(command, opts, aplicarFlagsGlobais);
162
+ aplicarFlagsCombinadas(command, opts, aplicarFlagsGlobais);
166
163
  if (process.env.SUKUNA_TEST_FAST === '1') {
167
164
  if (opts.json) {
168
165
  console.log(JSON.stringify({
@@ -8,7 +8,7 @@ import { PROJETO_RAIZ } from '../../core/registry/index.js';
8
8
  import { exportarRelatoriosFixTypes } from '../handlers/index.js';
9
9
  import { ExitCode, expandIncludePatterns, processPatternList, sair } from '../helpers/index.js';
10
10
  import { asTecnicas, extrairMensagemErro } from '../../types/index.js';
11
- const { CliComandoFixTypesMensagens, DICAS, formatarTipoInseguro, gerarResumoCategoria, ICONES_FIX_TYPES: ICONES, log, MENSAGENS_AUTOFIX, MENSAGENS_CLI_CORRECAO_TIPOS, MENSAGENS_ERRO_FIX_TYPES: MENSAGENS_ERRO, MENSAGENS_INICIO_FIX_TYPES: MENSAGENS_INICIO, MENSAGENS_PROGRESSO_FIX_TYPES: MENSAGENS_PROGRESSO, MENSAGENS_RESUMO, MENSAGENS_SUCESSO_FIX_TYPES: MENSAGENS_SUCESSO, TEMPLATE_RESUMO_FINAL, TEXTOS_CATEGORIZACAO_CORRECAO_TIPOS, } = getMessages();
11
+ const { CliComandoFixTypesMensagens, DICAS, formatarTipoInseguro, gerarResumoCategoria, log, MENSAGENS_AUTOFIX, MENSAGENS_CLI_CORRECAO_TIPOS, MENSAGENS_ERRO_FIX_TYPES: MENSAGENS_ERRO, MENSAGENS_INICIO_FIX_TYPES: MENSAGENS_INICIO, MENSAGENS_PROGRESSO_FIX_TYPES: MENSAGENS_PROGRESSO, MENSAGENS_RESUMO, MENSAGENS_SUCESSO_FIX_TYPES: MENSAGENS_SUCESSO, TEXTOS_CATEGORIZACAO_CORRECAO_TIPOS, } = getMessages();
12
12
  function mostrarErroDev(err) {
13
13
  if (!config.DEV_MODE) {
14
14
  return;
@@ -24,8 +24,8 @@ async function carregarInquisicao() {
24
24
  const modInq = await import('../../core/execution/index.js');
25
25
  const modReg = await import('../../analysts/registry/index.js');
26
26
  registroAnalistasCache = modReg.registroAnalistas;
27
- const analistaTiposInseguros = registroAnalistasCache.find((arquivo) => {
28
- return typeof arquivo === 'object' && arquivo !== null && arquivo.nome === 'detector-tipos-inseguros';
27
+ const analistaTiposInseguros = registroAnalistasCache?.find((arquivo) => {
28
+ return typeof arquivo === 'object' && arquivo.nome === 'detector-tipos-inseguros';
29
29
  });
30
30
  return {
31
31
  iniciarInquisicao: modInq.iniciarInquisicao,
@@ -210,12 +210,12 @@ async function aplicarCorrecoesAutomaticas(ocorrenciasCategorizadas, verbose) {
210
210
  const porArquivo = {};
211
211
  for (const item of ocorrenciasCategorizadas) {
212
212
  const arquivo = item.ocorrencia.relPath || 'desconhecido';
213
- if (!porArquivo[arquivo]) {
213
+ if (!(arquivo in porArquivo)) {
214
214
  porArquivo[arquivo] = [];
215
215
  }
216
216
  porArquivo[arquivo].push(item);
217
217
  }
218
- const resultado = await aplicarCorrecoesEmLote(porArquivo, {
218
+ const resultado = aplicarCorrecoesEmLote(porArquivo, {
219
219
  dryRun: false,
220
220
  minConfianca: 85,
221
221
  verbose,
@@ -273,17 +273,6 @@ function mostrarExemplosDryRun(tiposInseguros, verbose, minConfidence) {
273
273
  log.info(DICAS.usarInterativo);
274
274
  log.info(DICAS.ajustarConfianca(minConfidence));
275
275
  }
276
- function mostrarMensagemDryRun() {
277
- console.log();
278
- log.aviso(MENSAGENS_CLI_CORRECAO_TIPOS.dryRunAviso(ICONES.inicio));
279
- log.info(MENSAGENS_CLI_CORRECAO_TIPOS.linhaEmBranco);
280
- log.info(TEMPLATE_RESUMO_FINAL.titulo);
281
- for (const passo of TEMPLATE_RESUMO_FINAL.passos) {
282
- log.info(MENSAGENS_CLI_CORRECAO_TIPOS.templatePasso(passo));
283
- }
284
- log.info(MENSAGENS_CLI_CORRECAO_TIPOS.linhaEmBranco);
285
- log.info(MENSAGENS_AUTOFIX.dicas.removerDryRun);
286
- }
287
276
  export function criarComandoFixTypes() {
288
277
  const cmd = new Command('fix-types');
289
278
  cmd.description(CliComandoFixTypesMensagens.descricao).option('--dry-run', 'Mostra o que seria corrigido sem aplicar mudanças', false).option('--target <path>', 'Diretório ou arquivo específico para analisar', 'src').option('--confidence <number>', 'Nível mínimo de confiança para aplicar correções (0-100)', '85').option('--verbose', 'Mostra detalhes de cada correção', false).option('--interactive', 'Modo interativo: confirma cada correção', false).option('--export', 'Exporta relatórios JSON e Markdown para pasta relatorios/', false).option('--include <padrao>', 'Glob pattern a INCLUIR (pode repetir a flag ou usar vírgulas / espaços para múltiplos)', (val, prev) => {
@@ -342,7 +331,7 @@ async function executarFixTypes(options) {
342
331
  sair(ExitCode.Failure);
343
332
  return;
344
333
  }
345
- const ocorrencias = resultado.ocorrencias || [];
334
+ const ocorrencias = resultado.ocorrencias;
346
335
  const tiposInseguros = ocorrencias.filter((ocorrencia) => ocorrencia.tipo && ['tipo-inseguro-any', 'tipo-inseguro-any-assertion', 'tipo-inseguro-any-cast', 'tipo-inseguro-unknown'].includes(ocorrencia.tipo));
347
336
  if (tiposInseguros.length === 0) {
348
337
  log.sucesso(MENSAGENS_SUCESSO.nenhumTipoInseguro);
@@ -351,7 +340,7 @@ async function executarFixTypes(options) {
351
340
  log.aviso(MENSAGENS_RESUMO.encontrados(tiposInseguros.length));
352
341
  const porTipo = tiposInseguros.reduce((acc, ocorrencia) => {
353
342
  const tipo = ocorrencia.tipo ?? 'desconhecido';
354
- if (!acc[tipo]) {
343
+ if (!(tipo in acc)) {
355
344
  acc[tipo] = [];
356
345
  }
357
346
  acc[tipo].push(ocorrencia);
@@ -367,15 +356,9 @@ async function executarFixTypes(options) {
367
356
  return;
368
357
  }
369
358
  log.fase(MENSAGENS_CLI_CORRECAO_TIPOS.aplicandoCorrecoesAuto);
370
- const { fixAnyToProperTipo, fixUnknownToSpecificTipo } = await import('../../analysts/corrections/quick-fixes/index.js');
371
- if (!fixAnyToProperTipo || !fixUnknownToSpecificTipo) {
372
- log.erro(MENSAGENS_ERRO.modulosNaoEncontrados);
373
- sair(ExitCode.Failure);
374
- return;
375
- }
376
359
  const porArquivo = tiposInseguros.reduce((acc, ocorrencia) => {
377
360
  const arquivo = ocorrencia.relPath || 'desconhecido';
378
- if (!acc[arquivo]) {
361
+ if (!(arquivo in acc)) {
379
362
  acc[arquivo] = [];
380
363
  }
381
364
  acc[arquivo].push(ocorrencia);
@@ -395,9 +378,6 @@ async function executarFixTypes(options) {
395
378
  if (casosAltaPrioridade.length > 0) {
396
379
  await aplicarCorrecoesAutomaticas(ocorrenciasCategorizadas, verbose);
397
380
  }
398
- else if (isDryRun) {
399
- mostrarMensagemDryRun();
400
- }
401
381
  else {
402
382
  console.log();
403
383
  log.info(MENSAGENS_SUCESSO.nenhumAltaConfianca);
@@ -423,10 +403,7 @@ async function executarFixTypes(options) {
423
403
  verbose
424
404
  });
425
405
  }
426
- const temAny = porTipo['tipo-inseguro-any'].length > 0;
427
- if (temAny && !isDryRun) {
428
- sair(ExitCode.Failure);
429
- }
406
+ sair(ExitCode.Failure);
430
407
  }
431
408
  async function salvarAnaliseDetalhada(ocorrenciasCategorizadas, stats, mediaConfianca, verbose) {
432
409
  if (!verbose) {
@@ -48,11 +48,11 @@ export function comandoFormatters() {
48
48
  return;
49
49
  }
50
50
  const mod = await import(caminhoResolvido);
51
- if (!mod.default || typeof mod.default.gerar !== 'function') {
51
+ if (typeof mod.default.gerar !== 'function') {
52
52
  log.erro(FormattersMensagens.moduloInvalido(caminho));
53
53
  return;
54
54
  }
55
- const formatter = { nome, ...mod.default };
55
+ const formatter = { nome, ...mod.default, descricao: mod.default.descricao ?? '' };
56
56
  registrarFormatter(formatter);
57
57
  log.sucesso(FormattersMensagens.formatadorRegistrado(nome));
58
58
  }
@@ -69,7 +69,7 @@ export function comandoGitlabCI() {
69
69
  console.log('');
70
70
  ocorrencias.forEach(ocorrencia => {
71
71
  const prefix = ocorrencia.nivel === 'erro' ? '[RED]' : ocorrencia.nivel === 'aviso' ? '[YELLOW]' : '[BLUE]';
72
- log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem ?? ''));
72
+ log.info(msgs.ocorrencia(prefix, ocorrencia.tipo ?? '', ocorrencia.linha ?? 0, ocorrencia.mensagem));
73
73
  if (ocorrencia.sugestao) {
74
74
  log.info(msgs.sugestao(ocorrencia.sugestao));
75
75
  }
@@ -167,7 +167,7 @@ export function comandoGuardian(aplicarFlagsGlobais) {
167
167
  }
168
168
  }
169
169
  catch (err) {
170
- logGuardian.erroGuardian(err.message ?? String(err));
170
+ logGuardian.erroGuardian(err.message);
171
171
  mostrarErroDev(err);
172
172
  if (opts.json) {
173
173
  console.log(JSON.stringify({ status: 'erro', mensagem: extrairMensagemErro(err) }));