@skip-ai/scanner 0.2.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.d.ts CHANGED
@@ -1,4 +1,11 @@
1
- export interface CliOptions {
1
+ export interface SendOptions {
2
+ file: string;
3
+ token: string;
4
+ url: string;
5
+ verbose: boolean;
6
+ noPolling: boolean;
7
+ }
8
+ export interface ScanOptions {
2
9
  token?: string;
3
10
  url: string;
4
11
  dir: string;
@@ -7,5 +14,8 @@ export interface CliOptions {
7
14
  dryRun: boolean;
8
15
  }
9
16
  export declare const DEFAULT_BASE_URL = "https://app.goskip.dev";
10
- export declare function parseCli(argv?: string[]): CliOptions;
17
+ export declare function parseCli(argv?: string[]): {
18
+ command: 'send' | 'scan';
19
+ opts: SendOptions | ScanOptions;
20
+ };
11
21
  //# sourceMappingURL=cli.d.ts.map
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD,wBAAgB,QAAQ,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,UAAU,CAuBlE"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,eAAO,MAAM,gBAAgB,2BAA2B,CAAC;AAEzD,wBAAgB,QAAQ,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG;IAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,GAAG,WAAW,CAAA;CAAE,CAgDrH"}
package/dist/cli.js CHANGED
@@ -1,21 +1,44 @@
1
1
  import { Command } from 'commander';
2
+ import { CLI_VERSION } from './reporter.js';
2
3
  export const DEFAULT_BASE_URL = 'https://app.goskip.dev';
3
4
  export function parseCli(argv = process.argv) {
4
5
  const program = new Command()
5
6
  .name('skip-scanner')
6
- .description('Scanner de código para a plataforma Skip AI Accessibility Layer')
7
- .option('-t, --token <token>', 'Token do projeto (obtido no Dashboard). Obrigatório salvo em --dry-run.')
8
- .option('-u, --url <url>', 'URL da plataforma Skip', DEFAULT_BASE_URL)
7
+ .description('Scanner CLI para a plataforma Skip AI Accessibility Layer')
8
+ .version(CLI_VERSION);
9
+ // Comando principal: send (transporta um mapa montado pelo agente)
10
+ program
11
+ .command('send', { isDefault: true })
12
+ .description('Envia um payload já montado (pelo agente/skill) para o Skip Cloud. Este é o modo recomendado.')
13
+ .requiredOption('-f, --file <path>', 'Arquivo JSON com o payload (gerado pelo agente)')
14
+ .requiredOption('-t, --token <token>', 'Token do projeto (do .skip.json ou dashboard)')
15
+ .option('-u, --url <url>', 'URL do Skip Cloud', DEFAULT_BASE_URL)
16
+ .option('--no-polling', 'Enviar sem aguardar o enriquecimento', false)
17
+ .option('-v, --verbose', 'Exibir detalhes no terminal', false)
18
+ .action(() => { });
19
+ // Comando legado: scan (extração por regex — mantido como fallback)
20
+ program
21
+ .command('scan')
22
+ .description('Modo legado: extrai rotas/componentes via regex e envia. Menos inteligente que o agente.')
23
+ .option('-t, --token <token>', 'Token do projeto. Obrigatório salvo em --dry-run.')
24
+ .option('-u, --url <url>', 'URL do Skip Cloud', DEFAULT_BASE_URL)
9
25
  .option('-d, --dir <dir>', 'Diretório raiz do projeto', process.cwd())
10
26
  .option('-i, --ignore <patterns...>', 'Padrões a ignorar além do padrão', [])
11
27
  .option('--dry-run', 'Executa o scan sem enviar para a plataforma', false)
12
28
  .option('-v, --verbose', 'Exibir detalhes do scan no terminal', false)
13
- .parse(argv);
14
- const opts = program.opts();
15
- // Token é obrigatório fora do dry-run (no dry-run nada é enviado à API).
16
- if (!opts.dryRun && !opts.token) {
17
- program.error("erro: a opção '-t, --token <token>' é obrigatória (ou use --dry-run para testar sem enviar).", { exitCode: 1 });
29
+ .action(() => { });
30
+ program.parse(argv);
31
+ const [cmd] = program.commands.filter((c) => c.name() === program.args[0] || program.args.length === 0);
32
+ const commandName = program.args[0] === 'scan' ? 'scan' : 'send';
33
+ const command = program.commands.find((c) => c.name() === commandName);
34
+ const opts = (command?.opts() ?? {});
35
+ // Validação específica do modo scan: token obrigatório fora do dry-run
36
+ if (commandName === 'scan') {
37
+ const scanOpts = opts;
38
+ if (!scanOpts.dryRun && !scanOpts.token) {
39
+ program.error("erro: a opção '-t, --token <token>' é obrigatória (ou use --dry-run para testar sem enviar).", { exitCode: 1 });
40
+ }
18
41
  }
19
- return opts;
42
+ return { command: commandName, opts };
20
43
  }
21
44
  //# sourceMappingURL=cli.js.map
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAEzD,MAAM,UAAU,QAAQ,CAAC,OAAiB,OAAO,CAAC,IAAI;IACpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;SAC1B,IAAI,CAAC,cAAc,CAAC;SACpB,WAAW,CAAC,iEAAiE,CAAC;SAC9E,MAAM,CAAC,qBAAqB,EAAE,yEAAyE,CAAC;SACxG,MAAM,CAAC,iBAAiB,EAAE,wBAAwB,EAAE,gBAAgB,CAAC;SACrE,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SACrE,MAAM,CAAC,4BAA4B,EAAE,kCAAkC,EAAE,EAAE,CAAC;SAC5E,MAAM,CAAC,WAAW,EAAE,6CAA6C,EAAE,KAAK,CAAC;SACzE,MAAM,CAAC,eAAe,EAAE,qCAAqC,EAAE,KAAK,CAAC;SACrE,KAAK,CAAC,IAAI,CAAC,CAAC;IAEf,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,EAAgB,CAAC;IAE1C,4EAA4E;IAC5E,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,CAAC;QAChC,OAAO,CAAC,KAAK,CACX,8FAA8F,EAC9F,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAmB5C,MAAM,CAAC,MAAM,gBAAgB,GAAG,wBAAwB,CAAC;AAEzD,MAAM,UAAU,QAAQ,CAAC,OAAiB,OAAO,CAAC,IAAI;IACpD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE;SAC1B,IAAI,CAAC,cAAc,CAAC;SACpB,WAAW,CAAC,2DAA2D,CAAC;SACxE,OAAO,CAAC,WAAW,CAAC,CAAC;IAExB,sEAAsE;IACtE,OAAO;SACJ,OAAO,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;SACpC,WAAW,CAAC,+FAA+F,CAAC;SAC5G,cAAc,CAAC,mBAAmB,EAAE,iDAAiD,CAAC;SACtF,cAAc,CAAC,qBAAqB,EAAE,+CAA+C,CAAC;SACtF,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,CAAC;SAChE,MAAM,CAAC,cAAc,EAAE,sCAAsC,EAAE,KAAK,CAAC;SACrE,MAAM,CAAC,eAAe,EAAE,6BAA6B,EAAE,KAAK,CAAC;SAC7D,MAAM,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEpB,oEAAoE;IACpE,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,0FAA0F,CAAC;SACvG,MAAM,CAAC,qBAAqB,EAAE,mDAAmD,CAAC;SAClF,MAAM,CAAC,iBAAiB,EAAE,mBAAmB,EAAE,gBAAgB,CAAC;SAChE,MAAM,CAAC,iBAAiB,EAAE,2BAA2B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SACrE,MAAM,CAAC,4BAA4B,EAAE,kCAAkC,EAAE,EAAE,CAAC;SAC5E,MAAM,CAAC,WAAW,EAAE,6CAA6C,EAAE,KAAK,CAAC;SACzE,MAAM,CAAC,eAAe,EAAE,qCAAqC,EAAE,KAAK,CAAC;SACrE,MAAM,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAEpB,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpB,MAAM,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC;IACxG,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,WAAW,CAAC,CAAC;IACvE,MAAM,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAA8B,CAAC;IAElE,uEAAuE;IACvE,IAAI,WAAW,KAAK,MAAM,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAmB,CAAC;QACrC,IAAI,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;YACxC,OAAO,CAAC,KAAK,CACX,8FAA8F,EAC9F,EAAE,QAAQ,EAAE,CAAC,EAAE,CAChB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;AACxC,CAAC"}
package/dist/index.js CHANGED
@@ -1,7 +1,12 @@
1
1
  #!/usr/bin/env node
2
+ import fs from 'fs';
2
3
  import path from 'path';
3
4
  import chalk from 'chalk';
4
5
  import { parseCli } from './cli.js';
6
+ import { maskObject } from './scanner/secrets.js';
7
+ import { uploadReport, pollStatus } from './uploader.js';
8
+ import { banner, spinner, printSummary, fail } from './ui.js';
9
+ // Modo legado de extração
5
10
  import { detectProject } from './detector.js';
6
11
  import { extractRoutes } from './scanner/routes.js';
7
12
  import { extractComponents } from './scanner/components.js';
@@ -9,34 +14,103 @@ import { extractApiCalls } from './scanner/api-calls.js';
9
14
  import { extractNavigation } from './scanner/navigation.js';
10
15
  import { buildBriefing } from './scanner/briefing.js';
11
16
  import { buildWidgetSnippet } from './scanner/widget-snippet.js';
17
+ import { auditWcag, summarize, WCAG_RULES_VERSION } from './scanner/wcag.js';
18
+ import { calculateScore, scoreColor } from './scanner/score.js';
19
+ /** Aplica cor do chalk conforme o score (necessário porque chalk não é indexável por string). */
20
+ function colorScore(score) {
21
+ const c = scoreColor(score);
22
+ if (c === 'green')
23
+ return chalk.bold.green(`${score}/100`);
24
+ if (c === 'yellow')
25
+ return chalk.bold.yellow(`${score}/100`);
26
+ if (c === 'magenta')
27
+ return chalk.bold.magenta(`${score}/100`);
28
+ return chalk.bold.red(`${score}/100`);
29
+ }
30
+ import { detectGuidedFlows } from './scanner/guided-flows.js';
31
+ import { appendHistory } from './scanner/history.js';
12
32
  import { buildReport, maskReportSecrets, CLI_VERSION } from './reporter.js';
13
- import { uploadReport, pollStatus } from './uploader.js';
14
- import { banner, spinner, printSummary, fail } from './ui.js';
15
33
  import { DEFAULT_IGNORE_PATTERNS } from './scanner/ignore.js';
16
- async function main() {
17
- const opts = parseCli();
18
- const rootDir = path.resolve(opts.dir);
34
+ // ============ MODO SEND (transportador puro) ============
35
+ async function sendMode(opts) {
19
36
  console.log(banner(CLI_VERSION));
37
+ console.log(chalk.dim(` Modo: send (transportador)`));
38
+ console.log(chalk.dim(` Plataforma: ${opts.url}`));
39
+ console.log(chalk.dim(` Arquivo: ${opts.file}\n`));
40
+ // 1. Ler o payload do arquivo
41
+ if (!fs.existsSync(opts.file)) {
42
+ throw new Error(`Arquivo não encontrado: ${opts.file}`);
43
+ }
44
+ const readSpinner = spinner('Lendo payload...');
45
+ let payload;
46
+ try {
47
+ payload = JSON.parse(fs.readFileSync(opts.file, 'utf-8'));
48
+ }
49
+ catch (e) {
50
+ readSpinner.fail();
51
+ throw new Error(`JSON inválido em ${opts.file}: ${e instanceof Error ? e.message : String(e)}`);
52
+ }
53
+ readSpinner.succeed('Payload carregado.');
54
+ // 2. Checagem mínima de estrutura
55
+ if (!payload.navigationMap && !payload.routes) {
56
+ throw new Error('O payload não contém navigationMap nem routes. Use o validador da skill antes de enviar: node validate-report.js <arquivo>');
57
+ }
58
+ // 3. Preencher metadados se faltarem
59
+ if (!payload.metadata) {
60
+ payload.metadata = {
61
+ framework: payload.framework ?? 'unknown',
62
+ language: payload.language ?? 'TypeScript',
63
+ packageCount: 0,
64
+ typescript: payload.language === 'TypeScript',
65
+ scannedAt: new Date().toISOString(),
66
+ cliVersion: CLI_VERSION,
67
+ };
68
+ }
69
+ // 4. Mascara secrets
70
+ const { result: masked, count: secretsFound } = maskObject(payload);
71
+ const report = { ...masked, secretsFound };
72
+ if (secretsFound > 0) {
73
+ console.log(chalk.yellow(`⚠ ${secretsFound} possível(eis) secret(s) mascarado(s) antes do envio.`));
74
+ }
75
+ if (opts.verbose) {
76
+ console.log('\n' + chalk.dim('Payload a enviar:'));
77
+ console.log(chalk.dim(JSON.stringify(report, null, 2).slice(0, 2000) + (JSON.stringify(report).length > 2000 ? '...' : '')));
78
+ }
79
+ // 5. Enviar
80
+ const uploadSpinner = spinner('Enviando para o Skip Cloud...');
81
+ const scanId = await uploadReport(report, opts.token, opts.url);
82
+ uploadSpinner.succeed(`Scan enviado! ID: ${chalk.yellow(scanId)}`);
83
+ // 6. Polling (opcional)
84
+ if (opts.noPolling) {
85
+ console.log(chalk.dim('\n--no-polling: não aguardando enriquecimento.\n'));
86
+ return;
87
+ }
88
+ const status = await pollStatus(scanId, opts.token, opts.url);
89
+ printSummary({ scanId, entitiesCount: status.entitiesCount, baseUrl: opts.url, status: status.status });
90
+ if (status.status !== 'COMPLETED')
91
+ process.exitCode = 1;
92
+ }
93
+ // ============ MODO SCAN (legado, extração por regex) ============
94
+ async function scanMode(opts) {
95
+ console.log(banner(CLI_VERSION));
96
+ console.log(chalk.dim(` Modo: scan (legado, regex)`));
97
+ const rootDir = path.resolve(opts.dir);
20
98
  console.log(chalk.dim(` Diretório: ${rootDir}`));
21
99
  console.log(chalk.dim(` Plataforma: ${opts.url}\n`));
100
+ console.log(chalk.yellow(' ⚠ Modo scan usa extração por regex (menos inteligente que o agente).\n'));
22
101
  const ignorePatterns = [...DEFAULT_IGNORE_PATTERNS, ...opts.ignore];
23
- // 1. Detectar framework
24
102
  const detectSpinner = spinner('Detectando projeto...');
25
103
  const signature = detectProject(rootDir);
26
104
  detectSpinner.succeed(`Framework detectado: ${chalk.cyan(signature.framework)} (${signature.language})`);
27
- // 2. Extrair rotas (necessárias para mapear page.tsx -> rota lógica)
28
105
  const routeSpinner = spinner('Extraindo rotas...');
29
106
  const routes = await extractRoutes(rootDir, signature.srcDir, ignorePatterns);
30
107
  routeSpinner.succeed(`${routes.length} rotas encontradas`);
31
- // 3. Extrair componentes e eventos (inventário)
32
108
  const compSpinner = spinner('Extraindo componentes e eventos...');
33
109
  const { components, events } = await extractComponents(rootDir, opts.ignore);
34
110
  compSpinner.succeed(`${components.length} componentes, ${events.length} eventos`);
35
- // 4. Extrair chamadas de API
36
111
  const apiSpinner = spinner('Extraindo chamadas de API...');
37
112
  const apiCalls = await extractApiCalls(rootDir, opts.ignore);
38
113
  apiSpinner.succeed(`${apiCalls.length} chamadas de API detectadas`);
39
- // 5. Extrair mapa de navegação (telas, botões, links, inputs) — núcleo do produto
40
114
  const navSpinner = spinner('Construindo mapa de navegação...');
41
115
  const navigationMap = await extractNavigation(rootDir, opts.ignore, {
42
116
  pagesRoutes: routes.map((r) => ({ physicalPath: r.physicalPath, logicalRoute: r.logicalRoute })),
@@ -44,69 +118,99 @@ async function main() {
44
118
  });
45
119
  const totalActions = navigationMap.screens.reduce((acc, s) => acc + s.actions.length, 0);
46
120
  navSpinner.succeed(`${navigationMap.screens.length} telas mapeadas, ${totalActions} ações, ${navigationMap.navigationGraph.length} arestas de navegação`);
47
- // 6. Gerar briefing em linguagem natural + snippet do widget
48
121
  const briefing = buildBriefing(navigationMap);
49
122
  const widgetSnippet = buildWidgetSnippet();
50
- // 7. Contagem fiel de arquivos físicos lidos
123
+ // ---- Auditoria WCAG ----
124
+ // Lê os arquivos das telas LOCALMENTE (não envia o conteúdo ao servidor).
125
+ const auditSpinner = spinner('Auditando WCAG...');
126
+ const contentsByFile = {};
127
+ for (const s of navigationMap.screens) {
128
+ const abs = path.join(rootDir, s.filePath);
129
+ try {
130
+ contentsByFile[s.filePath] = fs.readFileSync(abs, 'utf-8');
131
+ }
132
+ catch {
133
+ contentsByFile[s.filePath] = '';
134
+ }
135
+ }
136
+ const violations = auditWcag(navigationMap.screens, contentsByFile);
137
+ const summary = summarize(violations);
138
+ const { score, level, total } = calculateScore(violations);
139
+ const wcag = {
140
+ score,
141
+ level,
142
+ violations,
143
+ summary,
144
+ auditedAt: new Date().toISOString(),
145
+ rulesVersion: WCAG_RULES_VERSION,
146
+ };
147
+ auditSpinner.succeed(`WCAG: score ${colorScore(score)} (${level}), ${total} violação(ões) [${summary.critical}c/${summary.serious}s/${summary.moderate}m/${summary.minor}i]`);
148
+ // ---- Fluxos guiados ----
149
+ const guidedFlows = detectGuidedFlows(navigationMap);
150
+ // ---- Histórico (local, enviado junto pra o dashboard) ----
151
+ const historyEntry = {
152
+ scannedAt: wcag.auditedAt,
153
+ score,
154
+ violations: total,
155
+ critical: summary.critical,
156
+ serious: summary.serious,
157
+ moderate: summary.moderate,
158
+ minor: summary.minor,
159
+ };
160
+ const history = appendHistory(rootDir, historyEntry);
51
161
  const uniqueFiles = new Set([
52
162
  ...routes.map((r) => r.physicalPath),
53
163
  ...components.map((c) => c.filepath),
54
164
  ...apiCalls.map((a) => a.filepath),
55
165
  ...navigationMap.screens.map((s) => s.filePath),
56
166
  ]);
57
- const filesScanned = uniqueFiles.size;
58
- // 8. Montar payload e mascarar secrets
59
167
  const projectName = path.basename(rootDir);
60
168
  const rawReport = buildReport({
61
- signature,
62
- routes,
63
- components,
64
- events,
65
- apiCalls,
66
- navigationMap,
67
- widgetSnippet,
68
- briefing,
69
- filesScanned,
70
- projectName,
169
+ signature, routes, components, events, apiCalls,
170
+ navigationMap, widgetSnippet, briefing, wcag, guidedFlows, history,
171
+ filesScanned: uniqueFiles.size, projectName,
71
172
  });
72
173
  const { report, secretsFound } = maskReportSecrets(rawReport);
73
174
  if (secretsFound > 0) {
74
175
  console.log(chalk.yellow(`⚠ ${secretsFound} possível(eis) secret(s) mascarado(s) antes do envio.`));
75
176
  }
76
177
  if (opts.verbose) {
77
- console.log('\n' + chalk.dim('Briefing (resumo para IA):'));
178
+ console.log('\n' + chalk.dim('Briefing:'));
78
179
  console.log(chalk.dim(briefing));
79
- console.log('\n' + chalk.dim('Navigation Map:'));
80
- console.log(chalk.dim(JSON.stringify(report.navigationMap, null, 2)));
180
+ console.log('\n' + chalk.dim('Top violações WCAG:'));
181
+ for (const v of violations.slice(0, 8)) {
182
+ console.log(chalk.dim(` [${v.severity}] ${v.title} — ${v.screen} (${v.selector})`));
183
+ }
81
184
  }
82
185
  if (opts.dryRun) {
83
- console.log(chalk.bold.cyan('\n🏃 Modo dry-run: pulando envio para a plataforma.\n'));
84
- console.log(` Arquivos escaneados: ${chalk.bold(filesScanned)}`);
85
- console.log(` Telas mapeadas: ${chalk.bold(navigationMap.screens.length)}`);
86
- console.log(` Ações (botões/inputs): ${chalk.bold(totalActions)}`);
87
- console.log(` Arestas de navegação: ${chalk.bold(navigationMap.navigationGraph.length)}`);
88
- console.log(` Rotas: ${chalk.bold(routes.length)}`);
89
- console.log(` Componentes: ${chalk.bold(components.length)}`);
90
- console.log(` Eventos: ${chalk.bold(events.length)}`);
91
- console.log(` Chamadas de API: ${chalk.bold(apiCalls.length)}`);
92
- console.log(` Secrets mascarados: ${chalk.bold(secretsFound)}\n`);
186
+ console.log(chalk.bold.cyan('\n🏃 Modo dry-run: pulando envio.\n'));
187
+ console.log(` Telas mapeadas: ${chalk.bold(navigationMap.screens.length)}`);
188
+ console.log(` Ações: ${chalk.bold(totalActions)}`);
189
+ console.log(` Arestas: ${chalk.bold(navigationMap.navigationGraph.length)}`);
190
+ console.log(` Fluxos guiados: ${chalk.bold(guidedFlows.length)}`);
191
+ console.log(` Score WCAG: ${colorScore(score)} (${level})`);
192
+ console.log(` Violações WCAG: ${chalk.bold(String(total))} [${summary.critical} critical, ${summary.serious} serious, ${summary.moderate} moderate, ${summary.minor} minor]`);
193
+ console.log(` Histórico: ${chalk.bold(String(history.length))} scan(s)\n`);
93
194
  return;
94
195
  }
95
- // 9. Enviar para a plataforma
96
- const uploadSpinner = spinner('Enviando para a plataforma Skip...');
196
+ const uploadSpinner = spinner('Enviando para o Skip Cloud...');
97
197
  const scanId = await uploadReport(report, opts.token, opts.url);
98
198
  uploadSpinner.succeed(`Scan enviado! ID: ${chalk.yellow(scanId)}`);
99
- // 10. Aguardar enriquecimento com IA
100
199
  const status = await pollStatus(scanId, opts.token, opts.url);
101
- printSummary({
102
- scanId,
103
- entitiesCount: status.entitiesCount,
104
- baseUrl: opts.url,
105
- status: status.status,
106
- });
200
+ printSummary({ scanId, entitiesCount: status.entitiesCount, baseUrl: opts.url, status: status.status });
107
201
  if (status.status !== 'COMPLETED')
108
202
  process.exitCode = 1;
109
203
  }
204
+ // ============ Entry point ============
205
+ async function main() {
206
+ const { command, opts } = parseCli();
207
+ if (command === 'send') {
208
+ await sendMode(opts);
209
+ }
210
+ else {
211
+ await scanMode(opts);
212
+ }
213
+ }
110
214
  main().catch((err) => {
111
215
  const msg = err instanceof Error ? err.message : String(err);
112
216
  console.error(fail(`Erro: ${msg}\n`));
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -3,7 +3,10 @@ import type { RouteEntry } from './scanner/routes.js';
3
3
  import type { ComponentEntry, EventEntry } from './scanner/components.js';
4
4
  import type { ApiCallEntry } from './scanner/api-calls.js';
5
5
  import type { NavigationMap } from './scanner/navigation.js';
6
- export declare const CLI_VERSION = "0.2.0";
6
+ import type { WcagReport } from './scanner/wcag.js';
7
+ import type { GuidedFlow } from './scanner/guided-flows.js';
8
+ import type { HistoryEntry } from './scanner/history.js';
9
+ export declare const CLI_VERSION = "0.4.0";
7
10
  export interface ScanMetadata {
8
11
  framework: string;
9
12
  language: string;
@@ -25,6 +28,12 @@ export interface ScanReport {
25
28
  widgetSnippet: string;
26
29
  /** Resumo em linguagem natural das telas e ações (pronto para a IA ler). */
27
30
  briefing: string;
31
+ /** Auditoria WCAG: violações, score (0-100) e nível alcançável. */
32
+ wcag: WcagReport;
33
+ /** Fluxos guiados detectados (ex.: login, preenchimento de form). */
34
+ guidedFlows: GuidedFlow[];
35
+ /** Histórico de scans neste projeto (score ao longo do tempo). */
36
+ history: HistoryEntry[];
28
37
  secretsFound: number;
29
38
  metadata: ScanMetadata;
30
39
  }
@@ -37,6 +46,9 @@ export interface BuildReportInput {
37
46
  navigationMap: NavigationMap;
38
47
  widgetSnippet: string;
39
48
  briefing: string;
49
+ wcag: WcagReport;
50
+ guidedFlows: GuidedFlow[];
51
+ history: HistoryEntry[];
40
52
  filesScanned: number;
41
53
  projectName: string;
42
54
  }
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAG7D,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,mFAAmF;IACnF,aAAa,EAAE,aAAa,CAAC;IAC7B,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAwB/D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAGlG"}
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAC3D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAC5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,eAAO,MAAM,WAAW,UAAU,CAAC;AAEnC,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,mFAAmF;IACnF,aAAa,EAAE,aAAa,CAAC;IAC7B,qFAAqF;IACrF,aAAa,EAAE,MAAM,CAAC;IACtB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,IAAI,EAAE,UAAU,CAAC;IACjB,qEAAqE;IACrE,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,kEAAkE;IAClE,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,gBAAgB,CAAC;IAC5B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,cAAc,EAAE,CAAC;IAC7B,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,aAAa,EAAE,aAAa,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CA2B/D;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,UAAU,GAAG;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAGlG"}
package/dist/reporter.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { maskObject } from './scanner/secrets.js';
2
- export const CLI_VERSION = '0.2.0';
2
+ export const CLI_VERSION = '0.4.0';
3
3
  /**
4
4
  * Monta o payload final (ScanReport) enviado para a API.
5
5
  */
6
6
  export function buildReport(input) {
7
- const { signature, routes, components, events, apiCalls, navigationMap, widgetSnippet, briefing, filesScanned, projectName } = input;
7
+ const { signature, routes, components, events, apiCalls, navigationMap, widgetSnippet, briefing, wcag, guidedFlows, history, filesScanned, projectName } = input;
8
8
  const report = {
9
9
  projectName,
10
10
  filesScanned,
@@ -15,6 +15,9 @@ export function buildReport(input) {
15
15
  navigationMap,
16
16
  widgetSnippet,
17
17
  briefing,
18
+ wcag,
19
+ guidedFlows,
20
+ history,
18
21
  secretsFound: 0,
19
22
  metadata: {
20
23
  framework: signature.framework,
@@ -1 +1 @@
1
- {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAyCnC;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAErI,MAAM,MAAM,GAAe;QACzB,WAAW;QACX,YAAY;QACZ,MAAM;QACN,UAAU;QACV,MAAM;QACN,QAAQ;QACR,aAAa;QACb,aAAa;QACb,QAAQ;QACR,YAAY,EAAE,CAAC;QACf,QAAQ,EAAE;YACR,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,UAAU,EAAE,SAAS,CAAC,QAAQ,KAAK,YAAY;YAC/C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,WAAW;SACxB;KACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAC7E,CAAC"}
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAElD,MAAM,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAkDnC;;GAEG;AACH,MAAM,UAAU,WAAW,CAAC,KAAuB;IACjD,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,aAAa,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC;IAEjK,MAAM,MAAM,GAAe;QACzB,WAAW;QACX,YAAY;QACZ,MAAM;QACN,UAAU;QACV,MAAM;QACN,QAAQ;QACR,aAAa;QACb,aAAa;QACb,QAAQ;QACR,IAAI;QACJ,WAAW;QACX,OAAO;QACP,YAAY,EAAE,CAAC;QACf,QAAQ,EAAE;YACR,SAAS,EAAE,SAAS,CAAC,SAAS;YAC9B,QAAQ,EAAE,SAAS,CAAC,QAAQ;YAC5B,YAAY,EAAE,SAAS,CAAC,YAAY;YACpC,UAAU,EAAE,SAAS,CAAC,QAAQ,KAAK,YAAY;YAC/C,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,UAAU,EAAE,WAAW;SACxB;KACF,CAAC;IACF,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAAkB;IAClD,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;IAC7C,OAAO,EAAE,MAAM,EAAE,EAAE,GAAG,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC;AAC7E,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { NavigationMap } from './navigation.js';
2
+ export interface GuidedFlowStep {
3
+ screen: string;
4
+ action: string;
5
+ label: string;
6
+ /** Rota destino, se a ação navegar. */
7
+ navigatesTo?: string | null;
8
+ }
9
+ export interface GuidedFlow {
10
+ name: string;
11
+ description: string;
12
+ steps: GuidedFlowStep[];
13
+ }
14
+ /**
15
+ * Detecta fluxos guiados a partir do navigationMap.
16
+ * Um fluxo é uma sequência de ações que leva o usuário a um objetivo
17
+ * (ex.: login, preencher formulário, finalizar compra).
18
+ *
19
+ * Heurística: para cada tela que tem um <form> (ações fill + submit),
20
+ * monta um fluxo "Preencher <tela>" com as ações em ordem.
21
+ */
22
+ export declare function detectGuidedFlows(map: NavigationMap): GuidedFlow[];
23
+ //# sourceMappingURL=guided-flows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guided-flows.d.ts","sourceRoot":"","sources":["../../src/scanner/guided-flows.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAoB,MAAM,iBAAiB,CAAC;AAEvE,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,GAAG,UAAU,EAAE,CAwClE"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Detecta fluxos guiados a partir do navigationMap.
3
+ * Um fluxo é uma sequência de ações que leva o usuário a um objetivo
4
+ * (ex.: login, preencher formulário, finalizar compra).
5
+ *
6
+ * Heurística: para cada tela que tem um <form> (ações fill + submit),
7
+ * monta um fluxo "Preencher <tela>" com as ações em ordem.
8
+ */
9
+ export function detectGuidedFlows(map) {
10
+ const flows = [];
11
+ for (const screen of map.screens) {
12
+ const fills = screen.actions.filter((a) => a.kind === 'fill');
13
+ const submits = screen.actions.filter((a) => a.kind === 'submit');
14
+ const navigations = screen.actions.filter((a) => a.kind === 'navigation');
15
+ // Fluxo 1: formulário (fill + submit)
16
+ if (fills.length > 0 && submits.length > 0) {
17
+ const steps = fills
18
+ .sort(byLabel)
19
+ .map((a) => ({ screen: screen.route, action: a.kind, label: a.label }));
20
+ for (const s of submits) {
21
+ steps.push({
22
+ screen: screen.route,
23
+ action: s.kind,
24
+ label: s.label,
25
+ navigatesTo: s.targetRoute,
26
+ });
27
+ }
28
+ flows.push({
29
+ name: flowNameFor(screen.title, submits[0]?.intent),
30
+ description: `Preencher e enviar o formulário da tela ${screen.title}.`,
31
+ steps,
32
+ });
33
+ }
34
+ // Fluxo 2: navegação primária (se há uma navegação clara da tela)
35
+ if (fills.length === 0 && navigations.length === 1) {
36
+ const nav = navigations[0];
37
+ flows.push({
38
+ name: `Ir para ${navLabel(nav)}`,
39
+ description: `Navegar de ${screen.title} para ${navLabel(nav)}.`,
40
+ steps: [{ screen: screen.route, action: nav.kind, label: nav.label, navigatesTo: nav.targetRoute }],
41
+ });
42
+ }
43
+ }
44
+ return flows;
45
+ }
46
+ function byLabel(a, b) {
47
+ return a.label.localeCompare(b.label);
48
+ }
49
+ function navLabel(nav) {
50
+ return nav.targetRoute ?? nav.label;
51
+ }
52
+ function flowNameFor(screenTitle, intent) {
53
+ if (intent === 'login')
54
+ return 'Login do usuário';
55
+ if (intent === 'save')
56
+ return `Salvar em ${screenTitle}`;
57
+ if (intent === 'search')
58
+ return `Buscar em ${screenTitle}`;
59
+ return `Preencher ${screenTitle}`;
60
+ }
61
+ //# sourceMappingURL=guided-flows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guided-flows.js","sourceRoot":"","sources":["../../src/scanner/guided-flows.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ export interface HistoryEntry {
2
+ scannedAt: string;
3
+ score: number;
4
+ violations: number;
5
+ /** Contagem por severidade. */
6
+ critical: number;
7
+ serious: number;
8
+ moderate: number;
9
+ minor: number;
10
+ }
11
+ export declare const HISTORY_FILE = ".skip-history.json";
12
+ /**
13
+ * Lê o histórico local do projeto (.skip-history.json).
14
+ * Retorna [] se não existir ou for inválido.
15
+ */
16
+ export declare function readHistory(rootDir: string): HistoryEntry[];
17
+ /**
18
+ * Adiciona uma entrada ao histórico local e retorna o histórico atualizado.
19
+ * Mantém apenas as últimas MAX_ENTRIES entradas.
20
+ */
21
+ export declare function appendHistory(rootDir: string, entry: HistoryEntry): HistoryEntry[];
22
+ //# sourceMappingURL=history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../src/scanner/history.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,YAAY,uBAAuB,CAAC;AAGjD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAS3D;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,YAAY,EAAE,CAalF"}
@@ -0,0 +1,38 @@
1
+ import fs from 'fs';
2
+ import path from 'path';
3
+ export const HISTORY_FILE = '.skip-history.json';
4
+ const MAX_ENTRIES = 100;
5
+ /**
6
+ * Lê o histórico local do projeto (.skip-history.json).
7
+ * Retorna [] se não existir ou for inválido.
8
+ */
9
+ export function readHistory(rootDir) {
10
+ const file = path.join(rootDir, HISTORY_FILE);
11
+ if (!fs.existsSync(file))
12
+ return [];
13
+ try {
14
+ const data = JSON.parse(fs.readFileSync(file, 'utf-8'));
15
+ return Array.isArray(data) ? data : [];
16
+ }
17
+ catch {
18
+ return [];
19
+ }
20
+ }
21
+ /**
22
+ * Adiciona uma entrada ao histórico local e retorna o histórico atualizado.
23
+ * Mantém apenas as últimas MAX_ENTRIES entradas.
24
+ */
25
+ export function appendHistory(rootDir, entry) {
26
+ const history = readHistory(rootDir);
27
+ history.push(entry);
28
+ const trimmed = history.slice(-MAX_ENTRIES);
29
+ const file = path.join(rootDir, HISTORY_FILE);
30
+ try {
31
+ fs.writeFileSync(file, JSON.stringify(trimmed, null, 2), 'utf-8');
32
+ }
33
+ catch {
34
+ // Falha ao salvar histórico não deve quebrar o scan.
35
+ }
36
+ return trimmed;
37
+ }
38
+ //# sourceMappingURL=history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.js","sourceRoot":"","sources":["../../src/scanner/history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAaxB,MAAM,CAAC,MAAM,YAAY,GAAG,oBAAoB,CAAC;AACjD,MAAM,WAAW,GAAG,GAAG,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe,EAAE,KAAmB;IAChE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACpB,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,CAAC;IAE5C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAC;IAC9C,IAAI,CAAC;QACH,EAAE,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { Severity, WcagLevel, WcagViolation } from './wcag.js';
2
+ /** Penalização por severidade (multiplicada pela contagem). */
3
+ export declare const SEVERITY_WEIGHT: Record<Severity, number>;
4
+ export interface ScoreResult {
5
+ /** 0–100 */
6
+ score: number;
7
+ /** Nível WCAG alcançável: A, AA ou AAA. */
8
+ level: WcagLevel;
9
+ /** Total de violações consideradas. */
10
+ total: number;
11
+ }
12
+ /**
13
+ * Calcula o score de acessibilidade (0–100).
14
+ * Começa em 100 e desconta por severidade, com floor em 0.
15
+ */
16
+ export declare function calculateScore(violations: WcagViolation[]): ScoreResult;
17
+ /** Cor sugerida para o score (pra usar no dashboard/terminal). */
18
+ export declare function scoreColor(score: number): string;
19
+ //# sourceMappingURL=score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/scanner/score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAEpE,+DAA+D;AAC/D,eAAO,MAAM,eAAe,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,CAKpD,CAAC;AAEF,MAAM,WAAW,WAAW;IAC1B,YAAY;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,2CAA2C;IAC3C,KAAK,EAAE,SAAS,CAAC;IACjB,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,WAAW,CAcvE;AAsBD,kEAAkE;AAClE,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKhD"}
@@ -0,0 +1,52 @@
1
+ /** Penalização por severidade (multiplicada pela contagem). */
2
+ export const SEVERITY_WEIGHT = {
3
+ critical: 12,
4
+ serious: 6,
5
+ moderate: 3,
6
+ minor: 1,
7
+ };
8
+ /**
9
+ * Calcula o score de acessibilidade (0–100).
10
+ * Começa em 100 e desconta por severidade, com floor em 0.
11
+ */
12
+ export function calculateScore(violations) {
13
+ let penalty = 0;
14
+ let total = violations.length;
15
+ for (const v of violations) {
16
+ penalty += SEVERITY_WEIGHT[v.severity];
17
+ }
18
+ // Cada tela sem violações ameniza o desconto (evita score punitivo em projetos grandes)
19
+ const score = Math.max(0, Math.round(100 - penalty));
20
+ const level = determineLevel(violations);
21
+ return { score, level, total };
22
+ }
23
+ /**
24
+ * Determina o nível WCAG alcançável:
25
+ * - AAA: nenhuma violação
26
+ * - AA: nenhuma violação AA/AAA (pode ter A)
27
+ * - A: nenhuma violação A... na prática, se há A, fica A
28
+ *
29
+ * Observação: projetado como indicador de conformidade alcançável, não certificação.
30
+ */
31
+ function determineLevel(violations) {
32
+ if (violations.length === 0)
33
+ return 'AAA';
34
+ const hasA = violations.some((v) => v.level === 'A');
35
+ if (hasA)
36
+ return 'A';
37
+ const hasAA = violations.some((v) => v.level === 'AA');
38
+ if (hasAA)
39
+ return 'AA';
40
+ return 'AA';
41
+ }
42
+ /** Cor sugerida para o score (pra usar no dashboard/terminal). */
43
+ export function scoreColor(score) {
44
+ if (score >= 90)
45
+ return 'green';
46
+ if (score >= 70)
47
+ return 'yellow';
48
+ if (score >= 50)
49
+ return 'magenta';
50
+ return 'red';
51
+ }
52
+ //# sourceMappingURL=score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/scanner/score.ts"],"names":[],"mappings":"AAEA,+DAA+D;AAC/D,MAAM,CAAC,MAAM,eAAe,GAA6B;IACvD,QAAQ,EAAE,EAAE;IACZ,OAAO,EAAE,CAAC;IACV,QAAQ,EAAE,CAAC;IACX,KAAK,EAAE,CAAC;CACT,CAAC;AAWF;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,UAA2B;IACxD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,IAAI,KAAK,GAAG,UAAU,CAAC,MAAM,CAAC;IAE9B,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;QAC3B,OAAO,IAAI,eAAe,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACzC,CAAC;IAED,wFAAwF;IACxF,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;IAErD,MAAM,KAAK,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAEzC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,UAA2B;IACjD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAE1C,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,GAAG,CAAC,CAAC;IACrD,IAAI,IAAI;QAAE,OAAO,GAAG,CAAC;IAErB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,KAAK,IAAI,CAAC,CAAC;IACvD,IAAI,KAAK;QAAE,OAAO,IAAI,CAAC;IAEvB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,kEAAkE;AAClE,MAAM,UAAU,UAAU,CAAC,KAAa;IACtC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,OAAO,CAAC;IAChC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,QAAQ,CAAC;IACjC,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC;IAClC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,58 @@
1
+ import type { ScreenMap } from './navigation.js';
2
+ export type Severity = 'critical' | 'serious' | 'moderate' | 'minor';
3
+ export type WcagLevel = 'A' | 'AA' | 'AAA';
4
+ export interface WcagViolation {
5
+ id: string;
6
+ rule: string;
7
+ level: WcagLevel;
8
+ severity: Severity;
9
+ impact: string;
10
+ title: string;
11
+ description: string;
12
+ screen: string;
13
+ filePath: string;
14
+ selector: string;
15
+ fix: string;
16
+ wcagUrl: string;
17
+ }
18
+ export interface WcagSummary {
19
+ critical: number;
20
+ serious: number;
21
+ moderate: number;
22
+ minor: number;
23
+ }
24
+ export interface WcagReport {
25
+ score: number;
26
+ level: WcagLevel;
27
+ violations: WcagViolation[];
28
+ summary: WcagSummary;
29
+ auditedAt: string;
30
+ rulesVersion: string;
31
+ }
32
+ export declare const WCAG_RULES_VERSION = "1.0.0";
33
+ export interface AuditContext {
34
+ screen: ScreenMap;
35
+ /** Conteúdo do arquivo da tela (lido localmente; NUNCA enviado ao servidor). */
36
+ content: string;
37
+ }
38
+ export interface RuleDef {
39
+ id: string;
40
+ rule: string;
41
+ level: WcagLevel;
42
+ severity: Severity;
43
+ impact: string;
44
+ title: string;
45
+ wcagUrl: string;
46
+ defaultFix: string;
47
+ /** Extrai as violações desta regra no contexto. */
48
+ check: (ctx: AuditContext) => WcagViolation[];
49
+ }
50
+ export declare const RULES: RuleDef[];
51
+ /**
52
+ * Aplica todas as regras WCAG a um conjunto de telas.
53
+ * Os conteúdos dos arquivos são lidos localmente e NÃO são enviados ao servidor.
54
+ */
55
+ export declare function auditWcag(screens: ScreenMap[], contentsByFile: Record<string, string>): WcagViolation[];
56
+ /** Conta violações por severidade. */
57
+ export declare function summarize(violations: WcagViolation[]): WcagSummary;
58
+ //# sourceMappingURL=wcag.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wcag.d.ts","sourceRoot":"","sources":["../../src/scanner/wcag.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAIjD,MAAM,MAAM,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AACrE,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,aAAa,EAAE,CAAC;IAC5B,OAAO,EAAE,WAAW,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,kBAAkB,UAAU,CAAC;AAI1C,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,SAAS,CAAC;IAClB,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,KAAK,EAAE,CAAC,GAAG,EAAE,YAAY,KAAK,aAAa,EAAE,CAAC;CAC/C;AA6FD,eAAO,MAAM,KAAK,EAAE,OAAO,EAuP1B,CAAC;AA4CF;;;GAGG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,SAAS,EAAE,EACpB,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GACrC,aAAa,EAAE,CAwBjB;AAED,sCAAsC;AACtC,wBAAgB,SAAS,CAAC,UAAU,EAAE,aAAa,EAAE,GAAG,WAAW,CAIlE"}
@@ -0,0 +1,392 @@
1
+ export const WCAG_RULES_VERSION = '1.0.0';
2
+ function findTags(content, tagNames) {
3
+ const out = [];
4
+ const re = new RegExp(`<(${tagNames.join('|')})\\b`, 'gi');
5
+ let m;
6
+ while ((m = re.exec(content)) !== null) {
7
+ const lt = m.index;
8
+ const tag = m[1];
9
+ let i = lt + 1 + tag.length;
10
+ let brace = 0;
11
+ let quote = null;
12
+ while (i < content.length) {
13
+ const ch = content[i];
14
+ if (quote) {
15
+ if (ch === quote)
16
+ quote = null;
17
+ i++;
18
+ continue;
19
+ }
20
+ if (ch === '"' || ch === "'") {
21
+ quote = ch;
22
+ i++;
23
+ continue;
24
+ }
25
+ if (ch === '{') {
26
+ brace++;
27
+ i++;
28
+ continue;
29
+ }
30
+ if (ch === '}') {
31
+ brace--;
32
+ i++;
33
+ continue;
34
+ }
35
+ if (brace === 0 && ch === '>') {
36
+ out.push({
37
+ full: content.substring(lt, i + 1),
38
+ tag,
39
+ attrs: content.substring(lt + 1 + tag.length, i).trim(),
40
+ contentStart: i + 1,
41
+ });
42
+ break;
43
+ }
44
+ i++;
45
+ }
46
+ }
47
+ return out;
48
+ }
49
+ function attr(attrs, name) {
50
+ const m = attrs.match(new RegExp(`\\b${name}\\s*=\\s*["']([^"']*)["']`, 'i'));
51
+ return m ? m[1] : null;
52
+ }
53
+ function visibleText(content, from) {
54
+ if (from < 0)
55
+ return '';
56
+ const slice = content.substring(from, from + 120);
57
+ const m = slice.match(/^\s*([^<{]+)/);
58
+ return m ? m[1].trim() : '';
59
+ }
60
+ function buildSelectorFromTag(tag, attrs, inputName) {
61
+ const id = attr(attrs, 'id');
62
+ if (id)
63
+ return `#${id}`;
64
+ const anchor = attr(attrs, 'data-skip-anchor');
65
+ if (anchor)
66
+ return `[data-skip-anchor='${anchor}']`;
67
+ if (inputName)
68
+ return `${tag}[name='${inputName}']`;
69
+ const aria = attr(attrs, 'aria-label');
70
+ if (aria)
71
+ return `${tag}[aria-label='${aria}']`;
72
+ return tag;
73
+ }
74
+ // ---- Definição das regras WCAG ----
75
+ const VALID_ROLES = new Set([
76
+ 'alert', 'alertdialog', 'banner', 'button', 'checkbox', 'complementary',
77
+ 'contentinfo', 'dialog', 'document', 'form', 'grid', 'gridcell', 'heading',
78
+ 'img', 'link', 'list', 'listbox', 'listitem', 'main', 'menu', 'menubar',
79
+ 'menuitem', 'navigation', 'none', 'note', 'option', 'presentation', 'progressbar',
80
+ 'radio', 'radiogroup', 'region', 'row', 'rowgroup', 'rowheader', 'scrollbar',
81
+ 'search', 'separator', 'slider', 'spinbutton', 'status', 'tab', 'tablist',
82
+ 'tabpanel', 'textbox', 'timer', 'toolbar', 'tooltip', 'tree', 'treegrid', 'treeitem',
83
+ ]);
84
+ export const RULES = [
85
+ // 1.1.1 — Imagem sem alt
86
+ {
87
+ id: 'img-alt-missing',
88
+ rule: '1.1.1 Non-text Content',
89
+ level: 'A',
90
+ severity: 'critical',
91
+ impact: 'Leitores de tela não conseguem descrever a imagem para usuários cegos.',
92
+ title: 'Imagem sem texto alternativo',
93
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#non-text-content',
94
+ defaultFix: "Adicione alt='...' descrevendo a imagem, ou alt='' se for puramente decorativa.",
95
+ check: (ctx) => {
96
+ const out = [];
97
+ for (const t of findTags(ctx.content, ['img'])) {
98
+ if (!/\balt\s*=/.test(t.attrs)) {
99
+ out.push(violation(thisId(ctx, 'img-alt'), ctx, t, buildSelectorFromTag('img', t.attrs, null)));
100
+ }
101
+ }
102
+ return out;
103
+ },
104
+ },
105
+ // 4.1.2 — Button sem nome acessível
106
+ {
107
+ id: 'button-no-name',
108
+ rule: '4.1.2 Name, Role, Value',
109
+ level: 'A',
110
+ severity: 'serious',
111
+ impact: 'Usuários de leitor de tela ouvem apenas "botão" sem saber sua função.',
112
+ title: 'Botão sem nome acessível',
113
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#name-role-value',
114
+ defaultFix: "Adicione texto visível, aria-label='...' ou aria-labelledby='...'.",
115
+ check: (ctx) => {
116
+ const out = [];
117
+ for (const t of findTags(ctx.content, ['button'])) {
118
+ const aria = attr(t.attrs, 'aria-label') || attr(t.attrs, 'aria-labelledby');
119
+ const text = visibleText(ctx.content, t.contentStart);
120
+ if (!aria && !text) {
121
+ out.push(violation(thisId(ctx, 'btn-name'), ctx, t, buildSelectorFromTag('button', t.attrs, null)));
122
+ }
123
+ }
124
+ return out;
125
+ },
126
+ },
127
+ // 1.3.1 / 3.3.2 — Input sem label
128
+ {
129
+ id: 'input-no-label',
130
+ rule: '1.3.1 Info and Relationships / 3.3.2 Labels or Instructions',
131
+ level: 'A',
132
+ severity: 'serious',
133
+ impact: 'Usuários não sabem o que preencher; leitores de tela anunciam "campo de texto" sem contexto.',
134
+ title: 'Campo de formulário sem label associada',
135
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#labels-or-instructions',
136
+ defaultFix: "Associe um <label for='id'>, ou adicione aria-label='...' ou aria-labelledby='...'.",
137
+ check: (ctx) => {
138
+ const out = [];
139
+ const inputs = findTags(ctx.content, ['input', 'textarea', 'select']);
140
+ // Procura <label for="x"> no conteúdo pra ver se o input tem label
141
+ const labelFors = new Set();
142
+ const labelRe = /<label\b[^>]*\bfor\s*=\s*["']([^"']+)["']/gi;
143
+ let lm;
144
+ while ((lm = labelRe.exec(ctx.content)) !== null)
145
+ labelFors.add(lm[1]);
146
+ for (const t of inputs) {
147
+ if (t.attrs.includes('type="hidden"') || t.attrs.includes("type='hidden'"))
148
+ continue;
149
+ const id = attr(t.attrs, 'id');
150
+ const aria = attr(t.attrs, 'aria-label') || attr(t.attrs, 'aria-labelledby');
151
+ const labelled = (id && labelFors.has(id)) || aria;
152
+ if (!labelled) {
153
+ const name = attr(t.attrs, 'name');
154
+ out.push(violation(thisId(ctx, 'input-label'), ctx, t, buildSelectorFromTag(t.tag, t.attrs, name)));
155
+ }
156
+ }
157
+ return out;
158
+ },
159
+ },
160
+ // 2.4.4 — Link com href vazio
161
+ {
162
+ id: 'link-href-empty',
163
+ rule: '2.4.4 Link Purpose (In Context)',
164
+ level: 'A',
165
+ severity: 'moderate',
166
+ impact: "Links com href='#' ou vazio não levam a lugar algum, confundindo navegação.",
167
+ title: 'Link sem destino válido',
168
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#link-purpose-in-context',
169
+ defaultFix: "Use um href válido apontando para a rota correta, ou transforme em <button> se for uma ação.",
170
+ check: (ctx) => {
171
+ const out = [];
172
+ for (const t of findTags(ctx.content, ['a'])) {
173
+ const href = attr(t.attrs, 'href');
174
+ if (href === '#' || href === '' || href == null) {
175
+ out.push(violation(thisId(ctx, 'link-href'), ctx, t, buildSelectorFromTag('a', t.attrs, null)));
176
+ }
177
+ }
178
+ return out;
179
+ },
180
+ },
181
+ // 2.4.3 — tabindex positivo
182
+ {
183
+ id: 'tabindex-positive',
184
+ rule: '2.4.3 Focus Order',
185
+ level: 'A',
186
+ severity: 'moderate',
187
+ impact: 'tabindex positivo quebra a ordem natural de navegação por teclado.',
188
+ title: 'tabindex positivo quebra ordem de foco',
189
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#focus-order',
190
+ defaultFix: "Remova o tabindex positivo; use ordem natural do DOM. Use tabindex='0' se precisar tornar focável.",
191
+ check: (ctx) => {
192
+ const out = [];
193
+ const re = /<(\w+)\b([^>]*?)\btabindex\s*=\s*["']([1-9]\d*)["']/gi;
194
+ let m;
195
+ while ((m = re.exec(ctx.content)) !== null) {
196
+ out.push(violationRaw(thisId(ctx, 'tabindex'), ctx, `${m[1]}`, m[2], `${m[1]}[tabindex='${m[3]}']`));
197
+ }
198
+ return out;
199
+ },
200
+ },
201
+ // 1.3.1 — ordem de headings
202
+ {
203
+ id: 'heading-order',
204
+ rule: '1.3.1 Info and Relationships',
205
+ level: 'A',
206
+ severity: 'moderate',
207
+ impact: 'Pular níveis de heading (ex.: h1→h3) confunde a estrutura do documento para leitores de tela.',
208
+ title: 'Ordem de headings inconsistente',
209
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#info-and-relationships',
210
+ defaultFix: 'Não pule níveis: após h1 use h2, após h2 use h3, etc.',
211
+ check: (ctx) => {
212
+ const out = [];
213
+ const re = /<h([1-6])\b/gi;
214
+ let prev = 0;
215
+ let m;
216
+ while ((m = re.exec(ctx.content)) !== null) {
217
+ const lvl = parseInt(m[1], 10);
218
+ if (prev !== 0 && lvl > prev + 1) {
219
+ out.push(violationRaw(thisId(ctx, 'heading'), ctx, `h${lvl}`, '', `h${lvl}`));
220
+ }
221
+ prev = lvl;
222
+ }
223
+ return out;
224
+ },
225
+ },
226
+ // 4.1.2 — role inválida
227
+ {
228
+ id: 'aria-invalid-role',
229
+ rule: '4.1.2 Name, Role, Value',
230
+ level: 'A',
231
+ severity: 'serious',
232
+ impact: 'role inválida faz leitores de tela anunciarem o elemento incorretamente.',
233
+ title: 'atributo role inválido',
234
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#name-role-value',
235
+ defaultFix: 'Use um valor de role válido da especificação ARIA, ou remova o atributo.',
236
+ check: (ctx) => {
237
+ const out = [];
238
+ const re = /<(\w+)\b([^>]*?)\brole\s*=\s*["']([^"']+)["']/gi;
239
+ let m;
240
+ while ((m = re.exec(ctx.content)) !== null) {
241
+ if (!VALID_ROLES.has(m[3])) {
242
+ out.push(violationRaw(thisId(ctx, 'aria-role'), ctx, m[1], m[2], `${m[1]}[role='${m[3]}']`));
243
+ }
244
+ }
245
+ return out;
246
+ },
247
+ },
248
+ // 3.1.1 — html sem lang
249
+ {
250
+ id: 'lang-missing',
251
+ rule: '3.1.1 Language of Page',
252
+ level: 'A',
253
+ severity: 'serious',
254
+ impact: 'Sem lang no <html>, leitores de tela usam idioma errado pra pronunciar.',
255
+ title: 'Documento sem idioma declarado',
256
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#language-of-page',
257
+ defaultFix: "Adicione lang='pt-BR' (ou o idioma correto) na tag <html>.",
258
+ check: (ctx) => {
259
+ const htmlMatch = ctx.content.match(/<html\b([^>]*)>/i);
260
+ if (htmlMatch && !/\blang\s*=/.test(htmlMatch[1])) {
261
+ return [
262
+ violationRaw(thisId(ctx, 'lang'), ctx, 'html', htmlMatch[1], 'html'),
263
+ ];
264
+ }
265
+ return [];
266
+ },
267
+ },
268
+ // 2.4.1 — sem skip link
269
+ {
270
+ id: 'skip-link-missing',
271
+ rule: '2.4.1 Bypass Blocks',
272
+ level: 'A',
273
+ severity: 'moderate',
274
+ impact: 'Usuários de teclado precisam tabular por toda a navegação repetitiva a cada página.',
275
+ title: 'Sem link de pular para o conteúdo',
276
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#bypass-blocks',
277
+ defaultFix: "Adicione um <a href='#main' className='skip-link'>Pular para o conteúdo</a> como primeiro elemento focável.",
278
+ check: (ctx) => {
279
+ const hasSkip = /href\s*=\s*["']#(?:main|content)["']/i.test(ctx.content);
280
+ const hasMain = /id\s*=\s*["']main["']/i.test(ctx.content) || /<main\b/i.test(ctx.content);
281
+ if (!hasSkip && hasMain) {
282
+ return [violationRaw(thisId(ctx, 'skip'), ctx, 'body', '', 'body')];
283
+ }
284
+ return [];
285
+ },
286
+ },
287
+ // 1.4.3 — contraste (heurística estática)
288
+ {
289
+ id: 'low-contrast-hint',
290
+ rule: '1.4.3 Contrast (Minimum)',
291
+ level: 'AA',
292
+ severity: 'minor',
293
+ impact: 'Possível baixo contraste texto/fundo dificulta leitura para usuários com baixa visão.',
294
+ title: 'Possível baixo contraste de cor',
295
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#contrast-minimum',
296
+ defaultFix: 'Verifique a razão de contraste (mínimo 4.5:1 para texto normal). Evite classes como text-gray-300 em fundos brancos.',
297
+ check: (ctx) => {
298
+ const out = [];
299
+ const suspect = /(text-(?:gray|slate|zinc|neutral)-(?:200|300))|(text-white\/[1-4]\d)|(opacity-(?:[1-3]\d|40))/gi;
300
+ let m;
301
+ while ((m = suspect.exec(ctx.content)) !== null) {
302
+ out.push(violationRaw(thisId(ctx, 'contrast'), ctx, '*', m[0], m[0]));
303
+ }
304
+ return out;
305
+ },
306
+ },
307
+ // 3.3.2 — form sem instrução
308
+ {
309
+ id: 'form-no-instruction',
310
+ rule: '3.3.2 Labels or Instructions',
311
+ level: 'A',
312
+ severity: 'moderate',
313
+ impact: 'Formulários sem instruções aumentam chance de erro do usuário.',
314
+ title: 'Formulário sem instrução de preenchimento',
315
+ wcagUrl: 'https://www.w3.org/WAI/WCAG22/quickref/#labels-or-instructions',
316
+ defaultFix: 'Adicione uma instrução curta antes do formulário, ou aria-describedby nos campos.',
317
+ check: (ctx) => {
318
+ const forms = findTags(ctx.content, ['form']);
319
+ if (forms.length === 0)
320
+ return [];
321
+ // heurística: se há <form> mas nenhum <p>/<span> com texto de instrução antes
322
+ const hasInstruction = /(por favor|preencha|informe|digite|required|obrigat)/i.test(ctx.content);
323
+ if (!hasInstruction) {
324
+ return [violationRaw(thisId(ctx, 'form-instr'), ctx, 'form', '', 'form')];
325
+ }
326
+ return [];
327
+ },
328
+ },
329
+ ];
330
+ // ---- Helpers de construção de violação ----
331
+ function thisId(ctx, slug) {
332
+ return `${slug}-${ctx.screen.id}`;
333
+ }
334
+ function violation(id, ctx, tag, selector) {
335
+ return violationRaw(id, ctx, tag.tag, tag.attrs, selector);
336
+ }
337
+ function violationRaw(id, ctx, tag, attrs, selector) {
338
+ void tag;
339
+ void attrs;
340
+ return {
341
+ id,
342
+ rule: '',
343
+ level: 'A',
344
+ severity: 'minor',
345
+ impact: '',
346
+ title: '',
347
+ description: '',
348
+ screen: ctx.screen.route,
349
+ filePath: ctx.screen.filePath,
350
+ selector,
351
+ fix: '',
352
+ wcagUrl: '',
353
+ };
354
+ }
355
+ // ---- Orquestrador da auditoria ----
356
+ /**
357
+ * Aplica todas as regras WCAG a um conjunto de telas.
358
+ * Os conteúdos dos arquivos são lidos localmente e NÃO são enviados ao servidor.
359
+ */
360
+ export function auditWcag(screens, contentsByFile) {
361
+ const all = [];
362
+ for (const screen of screens) {
363
+ const content = contentsByFile[screen.filePath] ?? '';
364
+ const ctx = { screen, content };
365
+ for (const rule of RULES) {
366
+ const found = rule.check(ctx);
367
+ for (const v of found) {
368
+ all.push({
369
+ ...v,
370
+ id: v.id,
371
+ rule: rule.rule,
372
+ level: rule.level,
373
+ severity: rule.severity,
374
+ impact: rule.impact,
375
+ title: rule.title,
376
+ fix: rule.defaultFix,
377
+ wcagUrl: rule.wcagUrl,
378
+ description: `${rule.title} em ${screen.route} (${screen.filePath}).`,
379
+ });
380
+ }
381
+ }
382
+ }
383
+ return all;
384
+ }
385
+ /** Conta violações por severidade. */
386
+ export function summarize(violations) {
387
+ const s = { critical: 0, serious: 0, moderate: 0, minor: 0 };
388
+ for (const v of violations)
389
+ s[v.severity]++;
390
+ return s;
391
+ }
392
+ //# sourceMappingURL=wcag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wcag.js","sourceRoot":"","sources":["../../src/scanner/wcag.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skip-ai/scanner",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Scanner CLI para a plataforma Skip AI Accessibility Layer",
5
5
  "type": "module",
6
6
  "bin": {