@mocoto/mahoraga 0.14.9 → 0.15.1

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 (49) hide show
  1. package/README.md +263 -30
  2. package/dist/analysts/js-ts/registrar.js +1 -1
  3. package/dist/analysts/react/analysts/analyst-react-hooks.js +30 -15
  4. package/dist/analysts/react/analysts/analyst-react.js +4 -2
  5. package/dist/analysts/react/detectors/detector-react-best-practices.js +7 -4
  6. package/dist/caretakers/caretaker-imports.js +0 -9
  7. package/dist/cli/commands/command-github-actions.js +0 -27
  8. package/dist/core/messages/en/cli/cli-command-github-actions-messages.js +0 -5
  9. package/dist/core/messages/en/github/index.js +0 -1
  10. package/dist/core/messages/ja/cli/cli-command-github-actions-messages.js +0 -5
  11. package/dist/core/messages/ja/github/index.js +0 -1
  12. package/dist/core/messages/pt/cli/cli-command-github-actions-messages.js +0 -5
  13. package/dist/core/messages/pt/github/index.js +0 -1
  14. package/dist/core/messages/zh/cli/cli-command-github-actions-messages.js +0 -5
  15. package/dist/core/messages/zh/github/index.js +0 -1
  16. package/dist/core/registry/file-registry.js +1 -1
  17. package/dist/node.loader.js +0 -2
  18. package/dist/shared/formatters/formatters/commons.js +36 -10
  19. package/dist/shared/formatters/formatters/shell.js +6 -3
  20. package/dist/types/analysts/index.js +1 -1
  21. package/docs/.obsidian/app.json +7 -0
  22. package/docs/.obsidian/appearance.json +8 -0
  23. package/docs/.obsidian/community-plugins.json +28 -0
  24. package/docs/.obsidian/core-plugins-migration.json +18 -0
  25. package/docs/.obsidian/core-plugins.json +73 -0
  26. package/docs/.obsidian/graph.json +22 -0
  27. package/docs/.obsidian/workspace.json +196 -0
  28. package/docs/01-arquitetura/ADR-001-estrutura-testes.md +31 -0
  29. package/docs/01-arquitetura/_index.md +152 -0
  30. package/docs/02-componentes/_index.md +294 -0
  31. package/docs/02-componentes/supressao-inline.md +88 -0
  32. package/docs/03-guias/_index.md +173 -0
  33. package/docs/03-guias/contribuindo.md +71 -0
  34. package/docs/03-guias/testes.md +133 -0
  35. package/docs/04-glossario/_index.md +29 -0
  36. package/docs/04-glossario/termos.md +247 -0
  37. package/docs/05-referencias/_index.md +87 -0
  38. package/docs/_home.md +140 -0
  39. package/docs/partials/AVISO-PROVENIENCIA.md +3 -0
  40. package/docs/templates/ADR.md +24 -0
  41. package/docs/templates/componente.md +34 -0
  42. package/docs/templates/guia.md +28 -0
  43. package/package.json +31 -32
  44. package/dist/app/github.js +0 -14
  45. package/dist/app/index.js +0 -1
  46. package/dist/core/messages/en/github/github-app-messages.js +0 -9
  47. package/dist/core/messages/ja/github/github-app-messages.js +0 -9
  48. package/dist/core/messages/pt/github/github-app-messages.js +0 -9
  49. package/dist/core/messages/zh/github/github-app-messages.js +0 -9
@@ -1,4 +1,3 @@
1
- export * from './github-app-messages.js';
2
1
  export * from './github-push-report-messages.js';
3
2
  export * from './github-repo-downloader-messages.js';
4
3
  export * from './github-webhook-messages.js';
@@ -3,7 +3,6 @@ export const CliComandoGithubActionsMensagens = {
3
3
  descricaoScan: 'Analisa workflows do GitHub Actions',
4
4
  descricaoReport: 'Gera relatório de análise de workflows',
5
5
  descricaoGate: 'Gate de qualidade para CI/CD - falha se score abaixo do threshold',
6
- descricaoApp: 'Inicia o servidor para atuar como GitHub App',
7
6
  optPath: 'Caminho para o repositório',
8
7
  optWorkflow: 'Analisar workflow específico',
9
8
  optFix: 'Aplica correções automaticamente quando possível',
@@ -35,8 +34,4 @@ export const CliComandoGithubActionsMensagens = {
35
34
  gatePassou: (score, threshold) => `[OK] Gate passou! Score: ${score}/100 (threshold: ${threshold})`,
36
35
  gateFalhou: (score, threshold) => `[ERRO] Gate falhou! Score: ${score}/100 (threshold: ${threshold})`,
37
36
  gateFalhaMotivo: (motivo) => ` - ${motivo}`,
38
- appSetupRequired: 'Para iniciar o GitHub App, você precisa configurar as variáveis de ambiente:',
39
- appSetupEnvList: ' - GITHUB_APP_ID\n - GITHUB_PRIVATE_KEY\n - GITHUB_WEBHOOK_SECRET',
40
- appDicaEnv: '\nDica: Crie um arquivo .env na raiz com essas variáveis.',
41
- erroIniciarServidor: (msg) => `Erro ao iniciar servidor: ${msg}`,
42
37
  };
@@ -1,4 +1,3 @@
1
- export * from './github-app-messages.js';
2
1
  export * from './github-push-report-messages.js';
3
2
  export * from './github-repo-downloader-messages.js';
4
3
  export * from './github-webhook-messages.js';
@@ -3,7 +3,6 @@ export const CliComandoGithubActionsMensagens = {
3
3
  descricaoScan: '分析 GitHub Actions 工作流',
4
4
  descricaoReport: '生成工作流分析报告',
5
5
  descricaoGate: 'CI/CD 质量门 - 分数低于阈值则失败',
6
- descricaoApp: '启动服务器以作为 GitHub App 运行',
7
6
  optPath: '仓库路径',
8
7
  optWorkflow: '分析特定工作流',
9
8
  optFix: '自动应用修复(如可能)',
@@ -35,8 +34,4 @@ export const CliComandoGithubActionsMensagens = {
35
34
  gatePassou: (score, threshold) => `[OK] 质量门通过! 分数: ${score}/100 (阈值: ${threshold})`,
36
35
  gateFalhou: (score, threshold) => `[错误] 质量门失败! 分数: ${score}/100 (阈值: ${threshold})`,
37
36
  gateFalhaMotivo: (motivo) => ` - ${motivo}`,
38
- appSetupRequired: '要启动 GitHub App,您需要配置以下环境变量:',
39
- appSetupEnvList: ' - GITHUB_APP_ID\n - GITHUB_PRIVATE_KEY\n - GITHUB_WEBHOOK_SECRET',
40
- appDicaEnv: '\n提示: 在根目录创建一个 .env 文件并设置这些变量。',
41
- erroIniciarServidor: (msg) => `启动服务器错误: ${msg}`,
42
37
  };
@@ -1,4 +1,3 @@
1
- export * from './github-app-messages.js';
2
1
  export * from './github-push-report-messages.js';
3
2
  export * from './github-repo-downloader-messages.js';
4
3
  export * from './github-webhook-messages.js';
@@ -1,7 +1,7 @@
1
1
  import { promises as fs } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { messages } from '../messages/index.js';
4
- import { MIGRACAO_MAPA, MAHORAGA_ARQUIVOS, MAHORAGA_DIRS } from './paths.js';
4
+ import { MAHORAGA_ARQUIVOS, MAHORAGA_DIRS, MIGRACAO_MAPA } from './paths.js';
5
5
  async function fileExists(fileCaminho) {
6
6
  try {
7
7
  await fs.stat(fileCaminho);
@@ -109,8 +109,6 @@ const aliases = {
109
109
  "@analysts/xml/corrections": "./src/analysts/xml/corrections/index",
110
110
  "@analysts/xml/detectors": "./src/analysts/xml/detectors/index",
111
111
  "@analysts/xml/scorers": "./src/analysts/xml/scorers/index",
112
- "@app": "./src/app/index",
113
- "@app/github": "./src/app/github",
114
112
  "@caretakers": "./src/caretakers/index",
115
113
  "@cli": "./src/cli/index",
116
114
  "@cli/commands": "./src/cli/commands/index",
@@ -1,3 +1,20 @@
1
+ import { extrairSupressoes, isRegraSuprimida } from '../../helpers/index.js';
2
+ const REGRAS_SUPRESSAO_FORMATADOR = ['pontuacao-repetida', 'espacamento-incorreto', 'formatador', 'analista-formatador', '*'];
3
+ export function extrairLinhasProtegidasFormatador(src) {
4
+ const supressoes = extrairSupressoes(src);
5
+ const lines = src.split('\n');
6
+ const protegidas = new Set();
7
+ for (let indice = 0; indice < lines.length; indice++) {
8
+ const lineNo = indice + 1;
9
+ for (const regra of REGRAS_SUPRESSAO_FORMATADOR) {
10
+ if (isRegraSuprimida(regra, lineNo, supressoes)) {
11
+ protegidas.add(lineNo);
12
+ break;
13
+ }
14
+ }
15
+ }
16
+ return protegidas;
17
+ }
1
18
  export function normalizarFimDeLinha(code) {
2
19
  return code.replace(/\r\n?/g, '\n');
3
20
  }
@@ -88,7 +105,7 @@ export function corrigirEspacamentoBasicoCodigo(code) {
88
105
  count
89
106
  };
90
107
  }
91
- const REPEATABLE_TO_SINGLE = new Set([',', '.', '!', '?', ';']);
108
+ const REPEATABLE_TO_SINGLE = new Set([',', '.', '!', '?']);
92
109
  const REPEATABLE_KEEP_UP_TO_3 = new Set(['.', '!', '?']);
93
110
  const MULTI_PUNCT_RE = /([,\.!?:;_\-])\1+/g;
94
111
  const SPACE_BEFORE_PUNCT_RE = /\s+([,.:;!?])/g;
@@ -214,11 +231,14 @@ function shouldSkipLineForPunctuation(line, lineIndex, lines) {
214
231
  }
215
232
  return false;
216
233
  }
217
- function collapseRepeatedPunct(code) {
234
+ function collapseRepeatedPunct(code, protectedLines) {
218
235
  const lines = code.split('\n');
219
236
  let totalCount = 0;
220
237
  let changed = false;
221
238
  const out = lines.map((line, idx) => {
239
+ if (protectedLines?.has(idx + 1)) {
240
+ return line;
241
+ }
222
242
  if (shouldSkipLineForPunctuation(line, idx, lines)) {
223
243
  return line;
224
244
  }
@@ -280,12 +300,15 @@ function fixDotPunct(match, offset, fullLine) {
280
300
  }
281
301
  return '. ';
282
302
  }
283
- function fixSpacingAroundPunct(code) {
303
+ function fixSpacingAroundPunct(code, protectedLines) {
284
304
  const { text: protected_code, placeholders } = protectSequences(code);
285
305
  const lines = protected_code.split('\n');
286
306
  let totalChanges = 0;
287
307
  let changed = false;
288
308
  const out = lines.map((line, idx) => {
309
+ if (protectedLines?.has(idx + 1)) {
310
+ return line;
311
+ }
289
312
  if (shouldSkipLineForPunctuation(line, idx, lines)) {
290
313
  return line;
291
314
  }
@@ -329,11 +352,14 @@ const RELATIONAL_OPS = [{
329
352
  pattern: /->/g,
330
353
  replacement: '→'
331
354
  }];
332
- function normalizeRelationalOperators(code) {
355
+ function normalizeRelationalOperators(code, protectedLines) {
333
356
  const lines = code.split('\n');
334
357
  let totalCount = 0;
335
358
  let changed = false;
336
359
  const out = lines.map((line, idx) => {
360
+ if (protectedLines?.has(idx + 1)) {
361
+ return line;
362
+ }
337
363
  if (shouldSkipLineForPunctuation(line, idx, lines)) {
338
364
  return line;
339
365
  }
@@ -377,24 +403,24 @@ function restoreHtmlComments(code, placeholders) {
377
403
  function skipJsonYamlResult(code) {
378
404
  return { text: code, changed: false, stats: { pontuacaoRepetida: 0, espacamentoIncorreto: 0, operadoresRelacionais: 0 } };
379
405
  }
380
- export function corrigirPontuacaoECodigo(code) {
406
+ export function corrigirPontuacaoECodigo(code, protectedLines) {
381
407
  if (isJsonOrYaml(code)) {
382
408
  return skipJsonYamlResult(code);
383
409
  }
384
410
  const { text: semHtml, placeholders } = extractHtmlComments(code);
385
- const { text: collapsed, count: pontuacaoRepetida } = collapseRepeatedPunct(semHtml);
386
- const { text: spaced, count: espacamentoIncorreto } = fixSpacingAroundPunct(collapsed);
387
- const { text: normalized, count: operadoresRelacionais } = normalizeRelationalOperators(spaced);
411
+ const { text: collapsed, count: pontuacaoRepetida } = collapseRepeatedPunct(semHtml, protectedLines);
412
+ const { text: spaced, count: espacamentoIncorreto } = fixSpacingAroundPunct(collapsed, protectedLines);
413
+ const { text: normalized, count: operadoresRelacionais } = normalizeRelationalOperators(spaced, protectedLines);
388
414
  const restored = restoreHtmlComments(normalized, placeholders);
389
415
  const changed = pontuacaoRepetida > 0 || espacamentoIncorreto > 0 || operadoresRelacionais > 0;
390
416
  return { text: restored, changed, stats: { pontuacaoRepetida, espacamentoIncorreto, operadoresRelacionais } };
391
417
  }
392
- export function corrigirPontuacaoECodigoConservador(code) {
418
+ export function corrigirPontuacaoECodigoConservador(code, protectedLines) {
393
419
  if (isJsonOrYaml(code)) {
394
420
  return skipJsonYamlResult(code);
395
421
  }
396
422
  const { text: semHtml, placeholders } = extractHtmlComments(code);
397
- const { text: collapsed, count: pontuacaoRepetida } = collapseRepeatedPunct(semHtml);
423
+ const { text: collapsed, count: pontuacaoRepetida } = collapseRepeatedPunct(semHtml, protectedLines);
398
424
  const { text: spaced, count: espacamentoIncorreto } = corrigirEspacamentoBasicoCodigo(collapsed);
399
425
  const restored = restoreHtmlComments(spaced, placeholders);
400
426
  const changed = pontuacaoRepetida > 0 || espacamentoIncorreto > 0;
@@ -136,13 +136,15 @@ function isIndexInQuotes(line, index) {
136
136
  continue;
137
137
  }
138
138
  if (inSingle) {
139
- if (ch === "'")
139
+ if (ch === "'") {
140
140
  inSingle = false;
141
+ }
141
142
  continue;
142
143
  }
143
144
  if (inDouble) {
144
- if (ch === '"')
145
+ if (ch === '"') {
145
146
  inDouble = false;
147
+ }
146
148
  continue;
147
149
  }
148
150
  if (ch === "'") {
@@ -157,8 +159,9 @@ function isIndexInQuotes(line, index) {
157
159
  return inSingle || inDouble;
158
160
  }
159
161
  function isRealShellPipe(line, index) {
160
- if (isIndexInQuotes(line, index))
162
+ if (isIndexInQuotes(line, index)) {
161
163
  return false;
164
+ }
162
165
  const before = line.slice(0, index);
163
166
  return true;
164
167
  }
@@ -5,6 +5,7 @@ export * from './strategists.js';
5
5
  export * from './azure-pipelines.js';
6
6
  export {} from './circleci.js';
7
7
  export * from './corrections.js';
8
+ export * from './css-in-js.js';
8
9
  export * from './dynamic-modules.js';
9
10
  export * from './github-actions-plugins.js';
10
11
  export {} from './github-actions-reports.js';
@@ -14,5 +15,4 @@ export {} from './jenkins.js';
14
15
  export * from './metrics.js';
15
16
  export * from './plugins.js';
16
17
  export * from './scoring.js';
17
- export * from './css-in-js.js';
18
18
  export * from './svg-plugins.js';
@@ -0,0 +1,7 @@
1
+ {
2
+ "enabled": true,
3
+ "alwaysUpdateLinks": true,
4
+ "promptDelete": false,
5
+ "newFileLocation": "current",
6
+ "attachmentFolderPath": "./"
7
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "theme": "system",
3
+ "accentColor": "#6b5bff",
4
+ "cssTheme": "",
5
+ "baseFontSize": 15,
6
+ "showViewHeader": false,
7
+ "nativeMenus": false
8
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "enabled": [
3
+ "obsidian-dataview",
4
+ "templater-obsidian",
5
+ "obsidian-git"
6
+ ],
7
+ "plugins": {
8
+ "obsidian-dataview": {
9
+ "enableDataviewJs": false,
10
+ "renderNullAs": "\\-",
11
+ "taskLinkLocation": "end",
12
+ "taskLinkText": "🔗"
13
+ },
14
+ "templater-obsidian": {
15
+ "templatesFolder": "templates",
16
+ "dateFormat": "YYYY-MM-DD",
17
+ "timeFormat": "HH:mm"
18
+ },
19
+ "obsidian-git": {
20
+ "autoCommitMessage": "docs: auto-sync {{date}}",
21
+ "autoPullInterval": 30,
22
+ "autoPushInterval": 30,
23
+ "autoBackupAfterFileChange": true,
24
+ "gitRemote": "origin",
25
+ "syncMethod": "rebase"
26
+ }
27
+ }
28
+ }
@@ -0,0 +1,18 @@
1
+ {
2
+ "mermaid": true,
3
+ "tagPane": true,
4
+ "graphView": true,
5
+ "pagePreview": true,
6
+ "backlink": true,
7
+ "outgoingLink": true,
8
+ "outline": true,
9
+ "starred": false,
10
+ "switcher": true,
11
+ "commandPalette": true,
12
+ "markdownImporter": false,
13
+ "wordCount": true,
14
+ "fileExplorer": true,
15
+ "search": true,
16
+ "bookmarks": true,
17
+ "properties": true
18
+ }
@@ -0,0 +1,73 @@
1
+ {
2
+ "core-plugin-list": [
3
+ "backlink",
4
+ "bookmarks",
5
+ "command-palette",
6
+ "daily-notes",
7
+ "file-explorer",
8
+ "file-recovery",
9
+ "global-search",
10
+ "graph-view",
11
+ "outgoing-link",
12
+ "outline",
13
+ "page-preview",
14
+ "properties",
15
+ "random-note",
16
+ "slash-command",
17
+ "switcher",
18
+ "tag-pane",
19
+ "templates",
20
+ "word-count"
21
+ ],
22
+ "enabled": [
23
+ "backlink",
24
+ "bookmarks",
25
+ "command-palette",
26
+ "daily-notes",
27
+ "file-explorer",
28
+ "file-recovery",
29
+ "global-search",
30
+ "graph-view",
31
+ "outgoing-link",
32
+ "outline",
33
+ "page-preview",
34
+ "properties",
35
+ "random-note",
36
+ "slash-command",
37
+ "switcher",
38
+ "tag-pane",
39
+ "templates",
40
+ "word-count"
41
+ ],
42
+ "file-explorer": true,
43
+ "global-search": true,
44
+ "switcher": true,
45
+ "graph": true,
46
+ "backlink": true,
47
+ "canvas": true,
48
+ "outgoing-link": true,
49
+ "tag-pane": true,
50
+ "footnotes": false,
51
+ "properties": true,
52
+ "page-preview": true,
53
+ "daily-notes": true,
54
+ "templates": true,
55
+ "note-composer": true,
56
+ "command-palette": true,
57
+ "slash-command": false,
58
+ "editor-status": true,
59
+ "bookmarks": true,
60
+ "markdown-importer": false,
61
+ "zk-prefixer": false,
62
+ "random-note": false,
63
+ "outline": true,
64
+ "word-count": true,
65
+ "slides": false,
66
+ "audio-recorder": false,
67
+ "workspaces": false,
68
+ "file-recovery": true,
69
+ "publish": false,
70
+ "sync": true,
71
+ "bases": true,
72
+ "webviewer": false
73
+ }
@@ -0,0 +1,22 @@
1
+ {
2
+ "collapse-filter": true,
3
+ "search": "",
4
+ "showTags": false,
5
+ "showAttachments": false,
6
+ "hideUnresolved": false,
7
+ "showOrphans": true,
8
+ "collapse-color-groups": true,
9
+ "colorGroups": [],
10
+ "collapse-display": true,
11
+ "showArrow": false,
12
+ "textFadeMultiplier": 0,
13
+ "nodeSizeMultiplier": 1,
14
+ "lineSizeMultiplier": 1,
15
+ "collapse-forces": true,
16
+ "centerStrength": 0.518713248970312,
17
+ "repelStrength": 10,
18
+ "linkStrength": 1,
19
+ "linkDistance": 250,
20
+ "scale": 1,
21
+ "close": true
22
+ }
@@ -0,0 +1,196 @@
1
+ {
2
+ "main": {
3
+ "id": "38cd0250b80f3c65",
4
+ "type": "split",
5
+ "children": [
6
+ {
7
+ "id": "2dae1c0919723f46",
8
+ "type": "tabs",
9
+ "children": [
10
+ {
11
+ "id": "d13e1d2e479b3201",
12
+ "type": "leaf",
13
+ "state": {
14
+ "type": "markdown",
15
+ "state": {
16
+ "file": "02-componentes/_index.md",
17
+ "mode": "source",
18
+ "source": false
19
+ },
20
+ "icon": "lucide-file",
21
+ "title": "_index"
22
+ }
23
+ }
24
+ ]
25
+ }
26
+ ],
27
+ "direction": "vertical"
28
+ },
29
+ "left": {
30
+ "id": "57192ac9415d99df",
31
+ "type": "split",
32
+ "children": [
33
+ {
34
+ "id": "93e26a2b823d31a6",
35
+ "type": "tabs",
36
+ "children": [
37
+ {
38
+ "id": "eec9025824b684fa",
39
+ "type": "leaf",
40
+ "state": {
41
+ "type": "file-explorer",
42
+ "state": {
43
+ "sortOrder": "alphabetical",
44
+ "autoReveal": false
45
+ },
46
+ "icon": "lucide-folder-closed",
47
+ "title": "Explorador de arquivos"
48
+ }
49
+ },
50
+ {
51
+ "id": "12c861fc6eed8790",
52
+ "type": "leaf",
53
+ "state": {
54
+ "type": "search",
55
+ "state": {
56
+ "query": "",
57
+ "matchingCase": false,
58
+ "explainSearch": false,
59
+ "collapseAll": false,
60
+ "extraContext": false,
61
+ "sortOrder": "alphabetical"
62
+ },
63
+ "icon": "lucide-search",
64
+ "title": "Procurar"
65
+ }
66
+ },
67
+ {
68
+ "id": "741d819feaded626",
69
+ "type": "leaf",
70
+ "state": {
71
+ "type": "bookmarks",
72
+ "state": {},
73
+ "icon": "lucide-bookmark",
74
+ "title": "Marcadores"
75
+ }
76
+ }
77
+ ]
78
+ }
79
+ ],
80
+ "direction": "horizontal",
81
+ "width": 300
82
+ },
83
+ "right": {
84
+ "id": "a4b627412871651f",
85
+ "type": "split",
86
+ "children": [
87
+ {
88
+ "id": "e19dd6dbffcc1cd6",
89
+ "type": "tabs",
90
+ "children": [
91
+ {
92
+ "id": "5009486718136ab8",
93
+ "type": "leaf",
94
+ "state": {
95
+ "type": "backlink",
96
+ "state": {
97
+ "collapseAll": false,
98
+ "extraContext": false,
99
+ "sortOrder": "alphabetical",
100
+ "showSearch": false,
101
+ "searchQuery": "",
102
+ "backlinkCollapsed": false,
103
+ "unlinkedCollapsed": true
104
+ },
105
+ "icon": "links-coming-in",
106
+ "title": "Links inversos"
107
+ }
108
+ },
109
+ {
110
+ "id": "2bbe7040a4c87fa6",
111
+ "type": "leaf",
112
+ "state": {
113
+ "type": "outgoing-link",
114
+ "state": {
115
+ "linksCollapsed": false,
116
+ "unlinkedCollapsed": true
117
+ },
118
+ "icon": "links-going-out",
119
+ "title": "Links de saída"
120
+ }
121
+ },
122
+ {
123
+ "id": "4ea52f6f13c06874",
124
+ "type": "leaf",
125
+ "state": {
126
+ "type": "tag",
127
+ "state": {
128
+ "sortOrder": "frequency",
129
+ "useHierarchy": true,
130
+ "showSearch": false,
131
+ "searchQuery": ""
132
+ },
133
+ "icon": "lucide-tags",
134
+ "title": "Etiquetas"
135
+ }
136
+ },
137
+ {
138
+ "id": "6d51f37d307431c8",
139
+ "type": "leaf",
140
+ "state": {
141
+ "type": "all-properties",
142
+ "state": {
143
+ "sortOrder": "frequency",
144
+ "showSearch": false,
145
+ "searchQuery": ""
146
+ },
147
+ "icon": "lucide-archive",
148
+ "title": "Todas as propriedades"
149
+ }
150
+ },
151
+ {
152
+ "id": "844a6214db033948",
153
+ "type": "leaf",
154
+ "state": {
155
+ "type": "outline",
156
+ "state": {
157
+ "followCursor": false,
158
+ "showSearch": false,
159
+ "searchQuery": ""
160
+ },
161
+ "icon": "lucide-list",
162
+ "title": "Sumário"
163
+ }
164
+ }
165
+ ]
166
+ }
167
+ ],
168
+ "direction": "horizontal",
169
+ "width": 300,
170
+ "collapsed": true
171
+ },
172
+ "left-ribbon": {
173
+ "hiddenItems": {
174
+ "switcher:Abrir a troca rápida": false,
175
+ "graph:Abrir visualização em gráfico": false,
176
+ "canvas:Criar novo canvas": false,
177
+ "daily-notes:Abrir a nota de hoje": false,
178
+ "templates:Inserir modelo": false,
179
+ "command-palette:Abrir paleta de comandos": false,
180
+ "bases:Criar nova base": false
181
+ }
182
+ },
183
+ "active": "d13e1d2e479b3201",
184
+ "lastOpenFiles": [
185
+ "templates/guia.md",
186
+ "templates/componente.md",
187
+ "templates/ADR.md",
188
+ "04-glossario/termos.md",
189
+ "03-guias/testes.md",
190
+ "03-guias/contribuindo.md",
191
+ "02-componentes/_index.md",
192
+ "01-arquitetura/ADR-001-estrutura-testes.md",
193
+ "01-arquitetura/_index.md",
194
+ "_home.md"
195
+ ]
196
+ }
@@ -0,0 +1,31 @@
1
+ ---
2
+ Proveniência e Autoria: Este documento integra o projeto @mocoto/mahoraga (licença MIT-0).
3
+ tags: [adr, testes]
4
+ status: aceito
5
+ created: 2026-07-24
6
+ ---
7
+
8
+ # ADR-001: Estrutura de Testes com Vitest
9
+
10
+ ## Contexto
11
+
12
+ O projeto precisava de uma estrutura de testes que suportasse mocking de módulos ES, coverage por diretório, e integração com TypeScript sem transpilação extra.
13
+
14
+ ## Decisão
15
+
16
+ - **Framework:** Vitest v4 com v8 coverage
17
+ - **Mocks globais:** `vi.hoisted()` + `vi.mock()` no topo dos testes
18
+ - **Alias:** `@` → `src/types/index.ts` resolvido via `vitest.config.ts`
19
+ - **Organização:** `tests/` espelha `src/` em estrutura de diretórios
20
+ - **Comandos CLI:** `parseAsync([], { from: 'user' })` sem argv posicionais (Commander v15)
21
+
22
+ ## Consequências
23
+
24
+ - Testes rodam em ~30s (full suite) e ~6s (parciais)
25
+ - 222 test files, 3116 testes
26
+ - Coverage total: ~47% (target: 56%+)
27
+
28
+ ## Alternativas Consideradas
29
+
30
+ - **Jest**: maior ecossistema, mas mais lento e sem ESM nativo
31
+ - **Mocha**: flexível, mas sem built-in coverage e mocking