legion-audit 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/LICENSE +21 -0
  3. package/README.md +84 -0
  4. package/dist/args.d.ts +18 -0
  5. package/dist/args.d.ts.map +1 -0
  6. package/dist/args.js +97 -0
  7. package/dist/args.js.map +1 -0
  8. package/dist/audit.d.ts +4 -0
  9. package/dist/audit.d.ts.map +1 -0
  10. package/dist/audit.js +81 -0
  11. package/dist/audit.js.map +1 -0
  12. package/dist/checks/directives.d.ts +8 -0
  13. package/dist/checks/directives.d.ts.map +1 -0
  14. package/dist/checks/directives.js +108 -0
  15. package/dist/checks/directives.js.map +1 -0
  16. package/dist/checks/gates.d.ts +16 -0
  17. package/dist/checks/gates.d.ts.map +1 -0
  18. package/dist/checks/gates.js +153 -0
  19. package/dist/checks/gates.js.map +1 -0
  20. package/dist/checks/git.d.ts +4 -0
  21. package/dist/checks/git.d.ts.map +1 -0
  22. package/dist/checks/git.js +36 -0
  23. package/dist/checks/git.js.map +1 -0
  24. package/dist/checks/lint.d.ts +10 -0
  25. package/dist/checks/lint.d.ts.map +1 -0
  26. package/dist/checks/lint.js +157 -0
  27. package/dist/checks/lint.js.map +1 -0
  28. package/dist/checks/lockfile.d.ts +3 -0
  29. package/dist/checks/lockfile.d.ts.map +1 -0
  30. package/dist/checks/lockfile.js +21 -0
  31. package/dist/checks/lockfile.js.map +1 -0
  32. package/dist/checks/test-coverage.d.ts +4 -0
  33. package/dist/checks/test-coverage.d.ts.map +1 -0
  34. package/dist/checks/test-coverage.js +62 -0
  35. package/dist/checks/test-coverage.js.map +1 -0
  36. package/dist/cli.d.ts +3 -0
  37. package/dist/cli.d.ts.map +1 -0
  38. package/dist/cli.js +100 -0
  39. package/dist/cli.js.map +1 -0
  40. package/dist/exec.d.ts +15 -0
  41. package/dist/exec.d.ts.map +1 -0
  42. package/dist/exec.js +43 -0
  43. package/dist/exec.js.map +1 -0
  44. package/dist/files.d.ts +7 -0
  45. package/dist/files.d.ts.map +1 -0
  46. package/dist/files.js +87 -0
  47. package/dist/files.js.map +1 -0
  48. package/dist/index.d.ts +14 -0
  49. package/dist/index.d.ts.map +1 -0
  50. package/dist/index.js +12 -0
  51. package/dist/index.js.map +1 -0
  52. package/dist/report/baseline.d.ts +3 -0
  53. package/dist/report/baseline.d.ts.map +1 -0
  54. package/dist/report/baseline.js +54 -0
  55. package/dist/report/baseline.js.map +1 -0
  56. package/dist/report/markdown.d.ts +3 -0
  57. package/dist/report/markdown.d.ts.map +1 -0
  58. package/dist/report/markdown.js +122 -0
  59. package/dist/report/markdown.js.map +1 -0
  60. package/dist/report/score.d.ts +18 -0
  61. package/dist/report/score.d.ts.map +1 -0
  62. package/dist/report/score.js +40 -0
  63. package/dist/report/score.js.map +1 -0
  64. package/dist/types.d.ts +99 -0
  65. package/dist/types.d.ts.map +1 -0
  66. package/dist/types.js +2 -0
  67. package/dist/types.js.map +1 -0
  68. package/package.json +57 -0
@@ -0,0 +1,14 @@
1
+ export { runAudit, DEFAULT_OPTIONS } from './audit.js';
2
+ export { scanDirectives, parseDirectivesInSource, isFileWideDisable, } from './checks/directives.js';
3
+ export { parseOxlintJson, parseEslintJson, countByRule, summarizeFindings, detectLinter, } from './checks/lint.js';
4
+ export { summarizeTestOutput, countTypeErrors } from './checks/gates.js';
5
+ export { summarizePrHygiene } from './checks/git.js';
6
+ export { classify } from './checks/test-coverage.js';
7
+ export { lockfileCheck } from './checks/lockfile.js';
8
+ export { computeScore, SCORE_WEIGHTS } from './report/score.js';
9
+ export { findRegressions } from './report/baseline.js';
10
+ export { renderMarkdown } from './report/markdown.js';
11
+ export { parseArgs, HELP } from './args.js';
12
+ export type { CliArgs, FailOn } from './args.js';
13
+ export type * from './types.js';
14
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC5C,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,mBAAmB,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,12 @@
1
+ export { runAudit, DEFAULT_OPTIONS } from './audit.js';
2
+ export { scanDirectives, parseDirectivesInSource, isFileWideDisable, } from './checks/directives.js';
3
+ export { parseOxlintJson, parseEslintJson, countByRule, summarizeFindings, detectLinter, } from './checks/lint.js';
4
+ export { summarizeTestOutput, countTypeErrors } from './checks/gates.js';
5
+ export { summarizePrHygiene } from './checks/git.js';
6
+ export { classify } from './checks/test-coverage.js';
7
+ export { lockfileCheck } from './checks/lockfile.js';
8
+ export { computeScore, SCORE_WEIGHTS } from './report/score.js';
9
+ export { findRegressions } from './report/baseline.js';
10
+ export { renderMarkdown } from './report/markdown.js';
11
+ export { parseArgs, HELP } from './args.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EACL,cAAc,EACd,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,eAAe,EACf,eAAe,EACf,WAAW,EACX,iBAAiB,EACjB,YAAY,GACb,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AuditResult, Regression } from '../types.js';
2
+ export declare const findRegressions: (before: AuditResult, after: AuditResult) => Regression[];
3
+ //# sourceMappingURL=baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.d.ts","sourceRoot":"","sources":["../../src/report/baseline.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ3D,eAAO,MAAM,eAAe,GAC1B,QAAQ,WAAW,EACnB,OAAO,WAAW,KACjB,UAAU,EAkDZ,CAAC"}
@@ -0,0 +1,54 @@
1
+ const gateStatus = (result, name) => result.gates.find((gate) => gate.name === name)?.status ?? 'skipped';
2
+ const legionErrors = (result) => result.lint.legion.filter((finding) => finding.severity === 'error').length;
3
+ export const findRegressions = (before, after) => {
4
+ const regressions = [];
5
+ for (const gate of after.gates) {
6
+ const previous = gateStatus(before, gate.name);
7
+ if (previous === 'pass' && gate.status === 'fail') {
8
+ regressions.push({
9
+ area: `gate: ${gate.name}`,
10
+ before: previous,
11
+ after: gate.status,
12
+ });
13
+ }
14
+ }
15
+ const beforeLegion = legionErrors(before);
16
+ const afterLegion = legionErrors(after);
17
+ if (afterLegion > beforeLegion) {
18
+ regressions.push({
19
+ area: 'legion rule errors',
20
+ before: String(beforeLegion),
21
+ after: String(afterLegion),
22
+ });
23
+ }
24
+ if (after.lint.errors > before.lint.errors) {
25
+ regressions.push({
26
+ area: 'lint errors',
27
+ before: String(before.lint.errors),
28
+ after: String(after.lint.errors),
29
+ });
30
+ }
31
+ if (after.directives.fileWide.length > before.directives.fileWide.length) {
32
+ regressions.push({
33
+ area: 'file-wide disables',
34
+ before: String(before.directives.fileWide.length),
35
+ after: String(after.directives.fileWide.length),
36
+ });
37
+ }
38
+ if (after.testCoverage.missing.length > before.testCoverage.missing.length) {
39
+ regressions.push({
40
+ area: 'files without tests',
41
+ before: String(before.testCoverage.missing.length),
42
+ after: String(after.testCoverage.missing.length),
43
+ });
44
+ }
45
+ if (after.score < before.score) {
46
+ regressions.push({
47
+ area: 'score',
48
+ before: String(before.score),
49
+ after: String(after.score),
50
+ });
51
+ }
52
+ return regressions;
53
+ };
54
+ //# sourceMappingURL=baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"baseline.js","sourceRoot":"","sources":["../../src/report/baseline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { AuditResult, Regression } from '../types.js';
2
+ export declare const renderMarkdown: (result: AuditResult, regressions: Regression[] | null) => string;
3
+ //# sourceMappingURL=markdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAuB,UAAU,EAAE,MAAM,aAAa,CAAC;AAgIhF,eAAO,MAAM,cAAc,GACzB,QAAQ,WAAW,EACnB,aAAa,UAAU,EAAE,GAAG,IAAI,KAC/B,MA6BF,CAAC"}
@@ -0,0 +1,122 @@
1
+ const ICONS = {
2
+ pass: 'pass',
3
+ fail: 'FAIL',
4
+ skipped: 'skipped',
5
+ };
6
+ const MAX_LISTED = 25;
7
+ const table = (header, rows) => {
8
+ const line = (cells) => `| ${cells.join(' | ')} |`;
9
+ const divider = `|${header.map(() => '---').join('|')}|`;
10
+ return [line(header), divider, ...rows.map(line)].join('\n');
11
+ };
12
+ const percent = (ratio) => `${Math.round(ratio * 100)}%`;
13
+ const listFindings = (findings) => {
14
+ const shown = findings.slice(0, MAX_LISTED);
15
+ const lines = shown.map((finding) => `- \`${finding.file}:${finding.line}\` ${finding.rule}: ${finding.message}`);
16
+ if (findings.length > MAX_LISTED) {
17
+ lines.push(`- ... and ${findings.length - MAX_LISTED} more`);
18
+ }
19
+ return lines.join('\n');
20
+ };
21
+ const gatesSection = (result) => {
22
+ const rows = result.gates.map((gate) => [
23
+ gate.name,
24
+ ICONS[gate.status],
25
+ gate.summary,
26
+ ]);
27
+ return table(['Gate', 'Result', 'Detail'], rows);
28
+ };
29
+ const lockfileLine = (result) => {
30
+ if (result.lockfile.found.length === 0) {
31
+ return `${ICONS[result.lockfile.status]}: no lockfile found`;
32
+ }
33
+ return `${ICONS[result.lockfile.status]}: ${result.lockfile.found.join(', ')}`;
34
+ };
35
+ const rulesSection = (result) => {
36
+ const legion = result.lint.rules.filter((rule) => rule.rule.startsWith('legion/'));
37
+ if (legion.length === 0)
38
+ return 'No `legion/*` findings (or the plugin is not installed in this repo).';
39
+ const rows = legion.map((rule) => [
40
+ rule.rule,
41
+ String(rule.errors),
42
+ String(rule.warnings),
43
+ ]);
44
+ return table(['Rule', 'Errors', 'Warnings'], rows);
45
+ };
46
+ const bypassSection = (result) => {
47
+ const { directives } = result;
48
+ const disables = directives.all.filter((hit) => hit.kind === 'disable');
49
+ const parts = [];
50
+ parts.push(`${disables.length} disable directive(s), ${directives.nosonar.length} NOSONAR marker(s), ${directives.fileWide.length} file-wide disable(s).`);
51
+ const byRule = Object.entries(directives.byRule).sort((a, b) => b[1] - a[1]);
52
+ if (byRule.length > 0) {
53
+ parts.push(table(['Bypassed rule', 'Count'], byRule.map(([rule, count]) => [rule, String(count)])));
54
+ }
55
+ if (directives.fileWide.length > 0) {
56
+ parts.push('File-wide disables (hard fail):');
57
+ parts.push(directives.fileWide
58
+ .map((hit) => `- \`${hit.file}:${hit.line}\``)
59
+ .join('\n'));
60
+ }
61
+ const explained = disables.filter((hit) => hit.description.length > 0).length;
62
+ if (disables.length > 0) {
63
+ parts.push(`${explained}/${disables.length} directives carry a reason.`);
64
+ }
65
+ return parts.join('\n\n');
66
+ };
67
+ const prSection = (result) => {
68
+ const { prHygiene } = result;
69
+ if (prHygiene.status === 'skipped')
70
+ return 'Not a git repository.';
71
+ const lines = [
72
+ `${prHygiene.withPr} of the last ${prHygiene.inspected} commits carry a PR number (${percent(prHygiene.ratio)}).`,
73
+ ];
74
+ if (prHygiene.lastPrCommit)
75
+ lines.push(`Most recent PR-tagged commit: \`${prHygiene.lastPrCommit}\`.`);
76
+ return lines.join('\n');
77
+ };
78
+ const coverageSection = (result) => {
79
+ const { testCoverage } = result;
80
+ const total = testCoverage.components + testCoverage.hooks;
81
+ const lines = [
82
+ `${testCoverage.components} component(s) and ${testCoverage.hooks} hook(s) found; ${testCoverage.missing.length} of ${total} have no test file.`,
83
+ ];
84
+ if (testCoverage.missing.length > 0) {
85
+ const shown = testCoverage.missing.slice(0, MAX_LISTED);
86
+ lines.push(shown.map((entry) => `- \`${entry.file}\` (${entry.kind})`).join('\n'));
87
+ if (testCoverage.missing.length > MAX_LISTED) {
88
+ lines.push(`- ... and ${testCoverage.missing.length - MAX_LISTED} more`);
89
+ }
90
+ }
91
+ return lines.join('\n');
92
+ };
93
+ const regressionSection = (regressions) => {
94
+ if (regressions.length === 0)
95
+ return 'No regressions against the baseline.';
96
+ return table(['Area', 'Baseline', 'Now'], regressions.map((entry) => [entry.area, entry.before, entry.after]));
97
+ };
98
+ export const renderMarkdown = (result, regressions) => {
99
+ const sections = [
100
+ `# Legion audit`,
101
+ `Generated ${result.generatedAt} for \`${result.root}\` (${result.packageManager}). Score: **${result.score}/100**.`,
102
+ `## Gates`,
103
+ gatesSection(result),
104
+ `## Legion rules`,
105
+ rulesSection(result),
106
+ ];
107
+ if (result.lint.componentCap.length > 0) {
108
+ sections.push(`## Components over the line cap`, listFindings(result.lint.componentCap));
109
+ }
110
+ if (result.lint.legion.length > 0) {
111
+ sections.push(`## Legion findings`, listFindings(result.lint.legion));
112
+ }
113
+ sections.push(`## Lint bypasses`, bypassSection(result));
114
+ sections.push(`## PR hygiene`, prSection(result));
115
+ sections.push(`## Tests by file`, coverageSection(result));
116
+ sections.push(`## Lockfile`, lockfileLine(result));
117
+ if (regressions !== null)
118
+ sections.push(`## Baseline`, regressionSection(regressions));
119
+ sections.push(`## Score formula`, 'Start at 100. Minus 2 per `legion/*` error (cap 40), 0.5 per lint warning (cap 10), 15 for a failed typecheck, 15 for a failed lint, 20 for failed tests, 5 for unformatted files, up to 10 scaled by the share of commits without a PR number, 1 per component or hook without a test (cap 15), 5 per file-wide disable (cap 15). The number is for comparing runs of the same repo, not for comparing repos.');
120
+ return `${sections.join('\n\n')}\n`;
121
+ };
122
+ //# sourceMappingURL=markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/report/markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { AuditResult } from '../types.js';
2
+ export declare const SCORE_WEIGHTS: {
3
+ readonly legionError: 2;
4
+ readonly legionErrorCap: 40;
5
+ readonly warning: 0.5;
6
+ readonly warningCap: 10;
7
+ readonly typecheckFail: 15;
8
+ readonly lintFail: 15;
9
+ readonly testsFail: 20;
10
+ readonly formatFail: 5;
11
+ readonly prHygieneMax: 10;
12
+ readonly missingTest: 1;
13
+ readonly missingTestCap: 15;
14
+ readonly fileWideDisable: 5;
15
+ readonly fileWideDisableCap: 15;
16
+ };
17
+ export declare const computeScore: (result: Omit<AuditResult, "score" | "schema" | "generatedAt">) => number;
18
+ //# sourceMappingURL=score.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.d.ts","sourceRoot":"","sources":["../../src/report/score.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE/C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;CAchB,CAAC;AAeX,eAAO,MAAM,YAAY,GACvB,QAAQ,IAAI,CAAC,WAAW,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,CAAC,KAC5D,MA0BF,CAAC"}
@@ -0,0 +1,40 @@
1
+ export const SCORE_WEIGHTS = {
2
+ legionError: 2,
3
+ legionErrorCap: 40,
4
+ warning: 0.5,
5
+ warningCap: 10,
6
+ typecheckFail: 15,
7
+ lintFail: 15,
8
+ testsFail: 20,
9
+ formatFail: 5,
10
+ prHygieneMax: 10,
11
+ missingTest: 1,
12
+ missingTestCap: 15,
13
+ fileWideDisable: 5,
14
+ fileWideDisableCap: 15,
15
+ };
16
+ const clamp = (value, min, max) => Math.min(max, Math.max(min, value));
17
+ const gatePenalty = (result, name, penalty) => {
18
+ const gate = result.gates.find((entry) => entry.name === name);
19
+ if (gate?.status === 'fail')
20
+ return penalty;
21
+ return 0;
22
+ };
23
+ export const computeScore = (result) => {
24
+ const w = SCORE_WEIGHTS;
25
+ let score = 100;
26
+ const legionErrors = result.lint.legion.filter((finding) => finding.severity === 'error').length;
27
+ score -= clamp(legionErrors * w.legionError, 0, w.legionErrorCap);
28
+ score -= clamp(result.lint.warnings * w.warning, 0, w.warningCap);
29
+ score -= gatePenalty(result, 'typecheck', w.typecheckFail);
30
+ score -= gatePenalty(result, 'lint', w.lintFail);
31
+ score -= gatePenalty(result, 'tests', w.testsFail);
32
+ score -= gatePenalty(result, 'format', w.formatFail);
33
+ if (result.prHygiene.status !== 'skipped') {
34
+ score -= (1 - result.prHygiene.ratio) * w.prHygieneMax;
35
+ }
36
+ score -= clamp(result.testCoverage.missing.length * w.missingTest, 0, w.missingTestCap);
37
+ score -= clamp(result.directives.fileWide.length * w.fileWideDisable, 0, w.fileWideDisableCap);
38
+ return Math.round(clamp(score, 0, 100));
39
+ };
40
+ //# sourceMappingURL=score.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"score.js","sourceRoot":"","sources":["../../src/report/score.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,aAAa,GAAG;IAC3B,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,EAAE;IAClB,OAAO,EAAE,GAAG;IACZ,UAAU,EAAE,EAAE;IACd,aAAa,EAAE,EAAE;IACjB,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,CAAC;IACb,YAAY,EAAE,EAAE;IAChB,WAAW,EAAE,CAAC;IACd,cAAc,EAAE,EAAE;IAClB,eAAe,EAAE,CAAC;IAClB,kBAAkB,EAAE,EAAE;CACd,CAAC;AAEX,MAAM,KAAK,GAAG,CAAC,KAAa,EAAE,GAAW,EAAE,GAAW,EAAU,EAAE,CAChE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAEtC,MAAM,WAAW,GAAG,CAClB,MAAkC,EAClC,IAAY,EACZ,OAAe,EACP,EAAE;IACV,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC;IAC/D,IAAI,IAAI,EAAE,MAAM,KAAK,MAAM;QAAE,OAAO,OAAO,CAAC;IAC5C,OAAO,CAAC,CAAC;AACX,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,CAC1B,MAA6D,EACrD,EAAE;IACV,MAAM,CAAC,GAAG,aAAa,CAAC;IACxB,IAAI,KAAK,GAAG,GAAG,CAAC;IAChB,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAC5C,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAC1C,CAAC,MAAM,CAAC;IACT,KAAK,IAAI,KAAK,CAAC,YAAY,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,CAAC;IAClE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAClE,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,WAAW,EAAE,CAAC,CAAC,aAAa,CAAC,CAAC;IAC3D,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjD,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;IACnD,KAAK,IAAI,WAAW,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IACrD,IAAI,MAAM,CAAC,SAAS,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QAC1C,KAAK,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,YAAY,CAAC;IACzD,CAAC;IACD,KAAK,IAAI,KAAK,CACZ,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,EAClD,CAAC,EACD,CAAC,CAAC,cAAc,CACjB,CAAC;IACF,KAAK,IAAI,KAAK,CACZ,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,eAAe,EACrD,CAAC,EACD,CAAC,CAAC,kBAAkB,CACrB,CAAC;IACF,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC,CAAC"}
@@ -0,0 +1,99 @@
1
+ export type GateStatus = 'pass' | 'fail' | 'skipped';
2
+ export interface GateResult {
3
+ name: string;
4
+ status: GateStatus;
5
+ summary: string;
6
+ command?: string;
7
+ exitCode?: number;
8
+ }
9
+ export interface RuleCount {
10
+ rule: string;
11
+ errors: number;
12
+ warnings: number;
13
+ }
14
+ export interface Finding {
15
+ rule: string;
16
+ file: string;
17
+ line: number;
18
+ message: string;
19
+ severity: 'error' | 'warning';
20
+ }
21
+ export interface LintResult {
22
+ linter: 'oxlint' | 'eslint' | 'none';
23
+ status: GateStatus;
24
+ errors: number;
25
+ warnings: number;
26
+ rules: RuleCount[];
27
+ legion: Finding[];
28
+ componentCap: Finding[];
29
+ }
30
+ export interface DirectiveHit {
31
+ file: string;
32
+ line: number;
33
+ tool: 'eslint' | 'oxlint';
34
+ kind: 'disable' | 'enable';
35
+ scope: 'file' | 'next-line' | 'line';
36
+ rules: string[];
37
+ description: string;
38
+ }
39
+ export interface NosonarHit {
40
+ file: string;
41
+ line: number;
42
+ }
43
+ export interface DirectivesResult {
44
+ fileWide: DirectiveHit[];
45
+ all: DirectiveHit[];
46
+ nosonar: NosonarHit[];
47
+ byRule: Record<string, number>;
48
+ }
49
+ export interface PrHygiene {
50
+ status: GateStatus;
51
+ inspected: number;
52
+ withPr: number;
53
+ ratio: number;
54
+ lastPrCommit: string | null;
55
+ }
56
+ export interface MissingTest {
57
+ file: string;
58
+ kind: 'component' | 'hook';
59
+ }
60
+ export interface TestCoverage {
61
+ components: number;
62
+ hooks: number;
63
+ missing: MissingTest[];
64
+ }
65
+ export interface LockfileResult {
66
+ status: GateStatus;
67
+ found: string[];
68
+ packageManager: PackageManager;
69
+ }
70
+ export type PackageManager = 'yarn' | 'npm' | 'pnpm' | 'bun' | 'unknown';
71
+ export interface AuditResult {
72
+ schema: 1;
73
+ generatedAt: string;
74
+ root: string;
75
+ packageManager: PackageManager;
76
+ score: number;
77
+ gates: GateResult[];
78
+ lint: LintResult;
79
+ directives: DirectivesResult;
80
+ prHygiene: PrHygiene;
81
+ testCoverage: TestCoverage;
82
+ lockfile: LockfileResult;
83
+ }
84
+ export interface AuditOptions {
85
+ root: string;
86
+ depsAudit: boolean;
87
+ runTests: boolean;
88
+ runTypecheck: boolean;
89
+ runFormat: boolean;
90
+ quiet: boolean;
91
+ commitsToInspect: number;
92
+ ignore: string[];
93
+ }
94
+ export interface Regression {
95
+ area: string;
96
+ before: string;
97
+ after: string;
98
+ }
99
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;IACrC,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,YAAY,EAAE,OAAO,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC1B,IAAI,EAAE,SAAS,GAAG,QAAQ,CAAC;IAC3B,KAAK,EAAE,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;IACrC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,GAAG,EAAE,YAAY,EAAE,CAAC;IACpB,OAAO,EAAE,UAAU,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,cAAc,EAAE,cAAc,CAAC;CAChC;AAED,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;AAEzE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,CAAC,CAAC;IACV,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,cAAc,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;IACjB,UAAU,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,YAAY,CAAC;IAC3B,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,OAAO,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;IACnB,KAAK,EAAE,OAAO,CAAC;IACf,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "legion-audit",
3
+ "version": "0.1.0",
4
+ "description": "Read-only repo scorecard against LEGION-STANDARDS: gates (typecheck, lint, tests, format), per-rule counts, lint bypasses, file-wide disables, PR hygiene, test coverage by file, lockfile sanity. Markdown and JSON output with baseline diffing for CI.",
5
+ "license": "MIT",
6
+ "author": "Veracium LLC",
7
+ "homepage": "https://github.com/Kprince1101/legion-toolkit/tree/main/packages/audit#readme",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Kprince1101/legion-toolkit.git",
11
+ "directory": "packages/audit"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/Kprince1101/legion-toolkit/issues"
15
+ },
16
+ "keywords": [
17
+ "audit",
18
+ "lint",
19
+ "code-quality",
20
+ "scorecard",
21
+ "ci",
22
+ "legion"
23
+ ],
24
+ "type": "module",
25
+ "main": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "bin": "./dist/cli.js",
28
+ "exports": {
29
+ ".": {
30
+ "types": "./dist/index.d.ts",
31
+ "default": "./dist/index.js"
32
+ },
33
+ "./cli": "./dist/cli.js",
34
+ "./package.json": "./package.json"
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "!dist/**/*.test.*",
39
+ "!dist/**/__tests__",
40
+ "LICENSE",
41
+ "README.md"
42
+ ],
43
+ "sideEffects": false,
44
+ "publishConfig": {
45
+ "access": "public",
46
+ "registry": "https://registry.npmjs.org/"
47
+ },
48
+ "scripts": {
49
+ "build": "node ../../scripts/copy-license.ts && tsc -p tsconfig.build.json && node -e \"require('node:fs').chmodSync('dist/cli.js', 0o755)\"",
50
+ "clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true}); require('node:fs').rmSync('LICENSE',{force:true})\"",
51
+ "typecheck": "tsc -p tsconfig.json --noEmit",
52
+ "prepublishOnly": "node ../../scripts/require-ci.ts"
53
+ },
54
+ "engines": {
55
+ "node": ">=22"
56
+ }
57
+ }