sourceverity 1.0.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 (192) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/bin/sourceverity.js +12 -0
  4. package/dist/analysis/controlFlow.d.ts +10 -0
  5. package/dist/analysis/controlFlow.d.ts.map +1 -0
  6. package/dist/analysis/controlFlow.js +278 -0
  7. package/dist/analysis/controlFlow.js.map +1 -0
  8. package/dist/analysis/frameworks.d.ts +11 -0
  9. package/dist/analysis/frameworks.d.ts.map +1 -0
  10. package/dist/analysis/frameworks.js +189 -0
  11. package/dist/analysis/frameworks.js.map +1 -0
  12. package/dist/analysis/functions.d.ts +27 -0
  13. package/dist/analysis/functions.d.ts.map +1 -0
  14. package/dist/analysis/functions.js +628 -0
  15. package/dist/analysis/functions.js.map +1 -0
  16. package/dist/analysis/promiseFlow.d.ts +44 -0
  17. package/dist/analysis/promiseFlow.d.ts.map +1 -0
  18. package/dist/analysis/promiseFlow.js +261 -0
  19. package/dist/analysis/promiseFlow.js.map +1 -0
  20. package/dist/analysis/values.d.ts +24 -0
  21. package/dist/analysis/values.d.ts.map +1 -0
  22. package/dist/analysis/values.js +189 -0
  23. package/dist/analysis/values.js.map +1 -0
  24. package/dist/baseline/manager.d.ts +20 -0
  25. package/dist/baseline/manager.d.ts.map +1 -0
  26. package/dist/baseline/manager.js +77 -0
  27. package/dist/baseline/manager.js.map +1 -0
  28. package/dist/baseline/types.d.ts +20 -0
  29. package/dist/baseline/types.d.ts.map +1 -0
  30. package/dist/baseline/types.js +2 -0
  31. package/dist/baseline/types.js.map +1 -0
  32. package/dist/cli/args.d.ts +26 -0
  33. package/dist/cli/args.d.ts.map +1 -0
  34. package/dist/cli/args.js +126 -0
  35. package/dist/cli/args.js.map +1 -0
  36. package/dist/cli/exitCodes.d.ts +8 -0
  37. package/dist/cli/exitCodes.d.ts.map +1 -0
  38. package/dist/cli/exitCodes.js +7 -0
  39. package/dist/cli/exitCodes.js.map +1 -0
  40. package/dist/cli/help.d.ts +5 -0
  41. package/dist/cli/help.d.ts.map +1 -0
  42. package/dist/cli/help.js +46 -0
  43. package/dist/cli/help.js.map +1 -0
  44. package/dist/cli/main.d.ts +7 -0
  45. package/dist/cli/main.d.ts.map +1 -0
  46. package/dist/cli/main.js +156 -0
  47. package/dist/cli/main.js.map +1 -0
  48. package/dist/core/fingerprint.d.ts +18 -0
  49. package/dist/core/fingerprint.d.ts.map +1 -0
  50. package/dist/core/fingerprint.js +26 -0
  51. package/dist/core/fingerprint.js.map +1 -0
  52. package/dist/core/paths.d.ts +10 -0
  53. package/dist/core/paths.d.ts.map +1 -0
  54. package/dist/core/paths.js +30 -0
  55. package/dist/core/paths.js.map +1 -0
  56. package/dist/core/suppressions.d.ts +24 -0
  57. package/dist/core/suppressions.d.ts.map +1 -0
  58. package/dist/core/suppressions.js +100 -0
  59. package/dist/core/suppressions.js.map +1 -0
  60. package/dist/core/terminal.d.ts +18 -0
  61. package/dist/core/terminal.d.ts.map +1 -0
  62. package/dist/core/terminal.js +39 -0
  63. package/dist/core/terminal.js.map +1 -0
  64. package/dist/core/types.d.ts +119 -0
  65. package/dist/core/types.d.ts.map +1 -0
  66. package/dist/core/types.js +2 -0
  67. package/dist/core/types.js.map +1 -0
  68. package/dist/engine/context.d.ts +16 -0
  69. package/dist/engine/context.d.ts.map +1 -0
  70. package/dist/engine/context.js +57 -0
  71. package/dist/engine/context.js.map +1 -0
  72. package/dist/engine/registry.d.ts +26 -0
  73. package/dist/engine/registry.d.ts.map +1 -0
  74. package/dist/engine/registry.js +38 -0
  75. package/dist/engine/registry.js.map +1 -0
  76. package/dist/engine/runner.d.ts +14 -0
  77. package/dist/engine/runner.d.ts.map +1 -0
  78. package/dist/engine/runner.js +166 -0
  79. package/dist/engine/runner.js.map +1 -0
  80. package/dist/engine/symbols.d.ts +46 -0
  81. package/dist/engine/symbols.d.ts.map +1 -0
  82. package/dist/engine/symbols.js +278 -0
  83. package/dist/engine/symbols.js.map +1 -0
  84. package/dist/index.d.ts +20 -0
  85. package/dist/index.d.ts.map +1 -0
  86. package/dist/index.js +32 -0
  87. package/dist/index.js.map +1 -0
  88. package/dist/reporters/agent.d.ts +45 -0
  89. package/dist/reporters/agent.d.ts.map +1 -0
  90. package/dist/reporters/agent.js +40 -0
  91. package/dist/reporters/agent.js.map +1 -0
  92. package/dist/reporters/json.d.ts +6 -0
  93. package/dist/reporters/json.d.ts.map +1 -0
  94. package/dist/reporters/json.js +7 -0
  95. package/dist/reporters/json.js.map +1 -0
  96. package/dist/reporters/sarif.d.ts +6 -0
  97. package/dist/reporters/sarif.d.ts.map +1 -0
  98. package/dist/reporters/sarif.js +60 -0
  99. package/dist/reporters/sarif.js.map +1 -0
  100. package/dist/reporters/terminal.d.ts +10 -0
  101. package/dist/reporters/terminal.d.ts.map +1 -0
  102. package/dist/reporters/terminal.js +105 -0
  103. package/dist/reporters/terminal.js.map +1 -0
  104. package/dist/repository/detector.d.ts +6 -0
  105. package/dist/repository/detector.d.ts.map +1 -0
  106. package/dist/repository/detector.js +231 -0
  107. package/dist/repository/detector.js.map +1 -0
  108. package/dist/repository/fileFilter.d.ts +10 -0
  109. package/dist/repository/fileFilter.d.ts.map +1 -0
  110. package/dist/repository/fileFilter.js +78 -0
  111. package/dist/repository/fileFilter.js.map +1 -0
  112. package/dist/repository/git.d.ts +7 -0
  113. package/dist/repository/git.d.ts.map +1 -0
  114. package/dist/repository/git.js +53 -0
  115. package/dist/repository/git.js.map +1 -0
  116. package/dist/repository/tsLoader.d.ts +15 -0
  117. package/dist/repository/tsLoader.d.ts.map +1 -0
  118. package/dist/repository/tsLoader.js +27 -0
  119. package/dist/repository/tsLoader.js.map +1 -0
  120. package/dist/repository/types.d.ts +38 -0
  121. package/dist/repository/types.d.ts.map +1 -0
  122. package/dist/repository/types.js +2 -0
  123. package/dist/repository/types.js.map +1 -0
  124. package/dist/rules/async/asyncForeach.d.ts +3 -0
  125. package/dist/rules/async/asyncForeach.d.ts.map +1 -0
  126. package/dist/rules/async/asyncForeach.js +76 -0
  127. package/dist/rules/async/asyncForeach.js.map +1 -0
  128. package/dist/rules/async/floatingPromise.d.ts +3 -0
  129. package/dist/rules/async/floatingPromise.d.ts.map +1 -0
  130. package/dist/rules/async/floatingPromise.js +359 -0
  131. package/dist/rules/async/floatingPromise.js.map +1 -0
  132. package/dist/rules/browser/eventListenerCleanup.d.ts +3 -0
  133. package/dist/rules/browser/eventListenerCleanup.d.ts.map +1 -0
  134. package/dist/rules/browser/eventListenerCleanup.js +378 -0
  135. package/dist/rules/browser/eventListenerCleanup.js.map +1 -0
  136. package/dist/rules/browser/observerCleanup.d.ts +3 -0
  137. package/dist/rules/browser/observerCleanup.d.ts.map +1 -0
  138. package/dist/rules/browser/observerCleanup.js +184 -0
  139. package/dist/rules/browser/observerCleanup.js.map +1 -0
  140. package/dist/rules/browser/timerCleanup.d.ts +3 -0
  141. package/dist/rules/browser/timerCleanup.d.ts.map +1 -0
  142. package/dist/rules/browser/timerCleanup.js +115 -0
  143. package/dist/rules/browser/timerCleanup.js.map +1 -0
  144. package/dist/rules/index.d.ts +19 -0
  145. package/dist/rules/index.d.ts.map +1 -0
  146. package/dist/rules/index.js +41 -0
  147. package/dist/rules/index.js.map +1 -0
  148. package/dist/rules/network/fetchStatusUnchecked.d.ts +3 -0
  149. package/dist/rules/network/fetchStatusUnchecked.d.ts.map +1 -0
  150. package/dist/rules/network/fetchStatusUnchecked.js +96 -0
  151. package/dist/rules/network/fetchStatusUnchecked.js.map +1 -0
  152. package/dist/rules/react/asyncEffectCallback.d.ts +3 -0
  153. package/dist/rules/react/asyncEffectCallback.d.ts.map +1 -0
  154. package/dist/rules/react/asyncEffectCallback.js +62 -0
  155. package/dist/rules/react/asyncEffectCallback.js.map +1 -0
  156. package/dist/rules/react/derivedStateEffect.d.ts +3 -0
  157. package/dist/rules/react/derivedStateEffect.d.ts.map +1 -0
  158. package/dist/rules/react/derivedStateEffect.js +172 -0
  159. package/dist/rules/react/derivedStateEffect.js.map +1 -0
  160. package/dist/rules/react/missingEffectCleanup.d.ts +3 -0
  161. package/dist/rules/react/missingEffectCleanup.d.ts.map +1 -0
  162. package/dist/rules/react/missingEffectCleanup.js +86 -0
  163. package/dist/rules/react/missingEffectCleanup.js.map +1 -0
  164. package/dist/rules/typescript/nonNullAssertionRisk.d.ts +3 -0
  165. package/dist/rules/typescript/nonNullAssertionRisk.d.ts.map +1 -0
  166. package/dist/rules/typescript/nonNullAssertionRisk.js +65 -0
  167. package/dist/rules/typescript/nonNullAssertionRisk.js.map +1 -0
  168. package/dist/rules/typescript/uncheckedIndexAccess.d.ts +3 -0
  169. package/dist/rules/typescript/uncheckedIndexAccess.d.ts.map +1 -0
  170. package/dist/rules/typescript/uncheckedIndexAccess.js +79 -0
  171. package/dist/rules/typescript/uncheckedIndexAccess.js.map +1 -0
  172. package/dist/rules/typescript/unsafeUnvalidatedAssertion.d.ts +3 -0
  173. package/dist/rules/typescript/unsafeUnvalidatedAssertion.d.ts.map +1 -0
  174. package/dist/rules/typescript/unsafeUnvalidatedAssertion.js +94 -0
  175. package/dist/rules/typescript/unsafeUnvalidatedAssertion.js.map +1 -0
  176. package/dist/strictness/evaluator.d.ts +28 -0
  177. package/dist/strictness/evaluator.d.ts.map +1 -0
  178. package/dist/strictness/evaluator.js +141 -0
  179. package/dist/strictness/evaluator.js.map +1 -0
  180. package/dist/strictness/matrix.d.ts +8 -0
  181. package/dist/strictness/matrix.d.ts.map +1 -0
  182. package/dist/strictness/matrix.js +63 -0
  183. package/dist/strictness/matrix.js.map +1 -0
  184. package/dist/typescript/programManager.d.ts +18 -0
  185. package/dist/typescript/programManager.d.ts.map +1 -0
  186. package/dist/typescript/programManager.js +46 -0
  187. package/dist/typescript/programManager.js.map +1 -0
  188. package/dist/typescript/projectResolver.d.ts +17 -0
  189. package/dist/typescript/projectResolver.d.ts.map +1 -0
  190. package/dist/typescript/projectResolver.js +75 -0
  191. package/dist/typescript/projectResolver.js.map +1 -0
  192. package/package.json +56 -0
@@ -0,0 +1,77 @@
1
+ import fs from "node:fs/promises";
2
+ import path from "node:path";
3
+ import { normalizePath } from "../core/paths.js";
4
+ export const DEFAULT_BASELINE_FILENAME = ".sourceverity-baseline.json";
5
+ /**
6
+ * Creates a BaselineFile structure from a list of audit findings.
7
+ */
8
+ export function createBaseline(findings, repoRoot) {
9
+ const entriesMap = new Map();
10
+ for (const f of findings) {
11
+ if (!entriesMap.has(f.fingerprint)) {
12
+ entriesMap.set(f.fingerprint, {
13
+ fingerprint: f.fingerprint,
14
+ ruleId: f.ruleId,
15
+ file: normalizePath(f.file, repoRoot),
16
+ message: f.message,
17
+ });
18
+ }
19
+ }
20
+ const entries = Array.from(entriesMap.values()).sort((a, b) => a.fingerprint.localeCompare(b.fingerprint));
21
+ return {
22
+ version: 1,
23
+ generatedAt: new Date().toISOString(),
24
+ repositoryRoot: normalizePath(repoRoot),
25
+ entries,
26
+ };
27
+ }
28
+ /**
29
+ * Atomically writes a baseline file to disk.
30
+ */
31
+ export async function saveBaseline(baseline, filePath) {
32
+ const resolvedPath = path.resolve(filePath);
33
+ const dir = path.dirname(resolvedPath);
34
+ await fs.mkdir(dir, { recursive: true });
35
+ const tempPath = `${resolvedPath}.${Date.now()}.tmp`;
36
+ const serialized = JSON.stringify(baseline, null, 2);
37
+ await fs.writeFile(tempPath, serialized, "utf-8");
38
+ await fs.rename(tempPath, resolvedPath);
39
+ }
40
+ /**
41
+ * Loads and validates a baseline file from disk. Returns null if missing or malformed.
42
+ */
43
+ export async function loadBaseline(filePath) {
44
+ try {
45
+ const raw = await fs.readFile(path.resolve(filePath), "utf-8");
46
+ // sourceverity-disable-next-line typescript/unsafe-unvalidated-assertion -- validated by version and entries checks below
47
+ const parsed = JSON.parse(raw);
48
+ if (parsed && parsed.version === 1 && Array.isArray(parsed.entries)) {
49
+ return parsed;
50
+ }
51
+ return null;
52
+ }
53
+ catch {
54
+ return null;
55
+ }
56
+ }
57
+ /**
58
+ * Compares current audit findings against a baseline to determine new and resolved findings.
59
+ */
60
+ export function compareWithBaseline(currentFindings, baseline) {
61
+ const baselineFingerprints = new Set(baseline.entries.map((e) => e.fingerprint));
62
+ const currentFingerprints = new Set(currentFindings.map((f) => f.fingerprint));
63
+ const newFindings = currentFindings.filter((f) => !baselineFingerprints.has(f.fingerprint));
64
+ let resolvedCount = 0;
65
+ for (const fp of baselineFingerprints) {
66
+ if (!currentFingerprints.has(fp)) {
67
+ resolvedCount++;
68
+ }
69
+ }
70
+ return {
71
+ newFindings,
72
+ baselineCount: baseline.entries.length,
73
+ resolvedCount,
74
+ newCount: newFindings.length,
75
+ };
76
+ }
77
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/baseline/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { Finding } from "../core/types.ts";
2
+ export interface BaselineEntry {
3
+ readonly fingerprint: string;
4
+ readonly ruleId: string;
5
+ readonly file: string;
6
+ readonly message: string;
7
+ }
8
+ export interface BaselineFile {
9
+ readonly version: 1;
10
+ readonly generatedAt: string;
11
+ readonly repositoryRoot: string;
12
+ readonly entries: readonly BaselineEntry[];
13
+ }
14
+ export interface BaselineDelta {
15
+ readonly newFindings: readonly Finding[];
16
+ readonly baselineCount: number;
17
+ readonly resolvedCount: number;
18
+ readonly newCount: number;
19
+ }
20
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/baseline/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAEhD,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,QAAQ,CAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,WAAW,EAAE,SAAS,OAAO,EAAE,CAAC;IACzC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/baseline/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,26 @@
1
+ export type CliCommand = "scan" | "strictness" | "rules" | "explain" | "baseline" | "help" | "version";
2
+ export type OutputFormat = "pretty" | "json" | "agent" | "sarif";
3
+ export type MinConfidence = "high" | "medium" | "low";
4
+ export type FailOnSeverity = "error" | "warning" | "never";
5
+ export interface CliOptions {
6
+ readonly command: CliCommand;
7
+ readonly targetDir: string;
8
+ readonly format: OutputFormat;
9
+ readonly minConfidence: MinConfidence;
10
+ readonly failOn: FailOnSeverity;
11
+ readonly configPath?: string | undefined;
12
+ readonly baselinePath?: string | undefined;
13
+ readonly updateBaseline: boolean;
14
+ readonly changedOnly: boolean;
15
+ readonly verbose: boolean;
16
+ readonly quiet: boolean;
17
+ readonly color?: boolean | undefined;
18
+ readonly ruleArg?: string | undefined;
19
+ readonly baselineSubcommand?: "create" | "check" | undefined;
20
+ }
21
+ /**
22
+ * Parses raw command-line arguments into structured CliOptions.
23
+ * Throws an Error with a descriptive message on invalid input.
24
+ */
25
+ export declare function parseCliArgs(argv: readonly string[]): CliOptions;
26
+ //# sourceMappingURL=args.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.d.ts","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,YAAY,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,SAAS,CAAC;AAEvG,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAEjE,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;AAEtD,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,CAAC;AAE3D,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAC;IAChC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAC1B,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;CAC9D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,UAAU,CAiHhE"}
@@ -0,0 +1,126 @@
1
+ import { parseArgs } from "node:util";
2
+ /**
3
+ * Parses raw command-line arguments into structured CliOptions.
4
+ * Throws an Error with a descriptive message on invalid input.
5
+ */
6
+ export function parseCliArgs(argv) {
7
+ const optionsConfig = {
8
+ help: { type: "boolean", short: "h" },
9
+ version: { type: "boolean", short: "v" },
10
+ format: { type: "string", short: "f" },
11
+ "min-confidence": { type: "string" },
12
+ "fail-on": { type: "string" },
13
+ config: { type: "string", short: "c" },
14
+ baseline: { type: "string", short: "b" },
15
+ "update-baseline": { type: "boolean", short: "u" },
16
+ changed: { type: "boolean" },
17
+ verbose: { type: "boolean" },
18
+ quiet: { type: "boolean", short: "q" },
19
+ color: { type: "boolean" },
20
+ "no-color": { type: "boolean" },
21
+ };
22
+ const parsed = parseArgs({
23
+ args: [...argv],
24
+ options: optionsConfig,
25
+ allowPositionals: true,
26
+ strict: true,
27
+ });
28
+ if (parsed.values.help) {
29
+ return createDefaultOptions("help");
30
+ }
31
+ if (parsed.values.version) {
32
+ return createDefaultOptions("version");
33
+ }
34
+ const positionals = parsed.positionals;
35
+ let command = "scan";
36
+ let targetDir = ".";
37
+ let ruleArg;
38
+ let baselineSubcommand;
39
+ const first = positionals[0];
40
+ if (first) {
41
+ if (first === "scan" ||
42
+ first === "strictness" ||
43
+ first === "rules" ||
44
+ first === "explain" ||
45
+ first === "baseline" ||
46
+ first === "help" ||
47
+ first === "version") {
48
+ command = first;
49
+ if (command === "explain") {
50
+ ruleArg = positionals[1];
51
+ if (!ruleArg) {
52
+ throw new Error("Missing rule identifier for 'explain' command. Usage: sourceverity explain <rule-id>");
53
+ }
54
+ }
55
+ else if (command === "baseline") {
56
+ const sub = positionals[1];
57
+ if (sub === "create" || sub === "check") {
58
+ baselineSubcommand = sub;
59
+ targetDir = positionals[2] ?? ".";
60
+ }
61
+ else if (sub) {
62
+ targetDir = sub;
63
+ }
64
+ }
65
+ else {
66
+ targetDir = positionals[1] ?? ".";
67
+ }
68
+ }
69
+ else {
70
+ // First positional is targetDir for default 'scan' command
71
+ targetDir = first;
72
+ }
73
+ }
74
+ // Format validation
75
+ const rawFormat = parsed.values.format ?? "pretty";
76
+ if (rawFormat !== "pretty" && rawFormat !== "json" && rawFormat !== "agent" && rawFormat !== "sarif") {
77
+ throw new Error(`Invalid --format '${rawFormat}'. Valid options: pretty, json, agent, sarif`);
78
+ }
79
+ // Min confidence validation
80
+ const rawConfidence = parsed.values["min-confidence"] ?? "medium";
81
+ if (rawConfidence !== "high" && rawConfidence !== "medium" && rawConfidence !== "low") {
82
+ throw new Error(`Invalid --min-confidence '${rawConfidence}'. Valid options: high, medium, low`);
83
+ }
84
+ // Fail on validation
85
+ const rawFailOn = parsed.values["fail-on"] ?? "error";
86
+ if (rawFailOn !== "error" && rawFailOn !== "warning" && rawFailOn !== "never") {
87
+ throw new Error(`Invalid --fail-on '${rawFailOn}'. Valid options: error, warning, never`);
88
+ }
89
+ let colorOption;
90
+ if (parsed.values["no-color"]) {
91
+ colorOption = false;
92
+ }
93
+ else if (parsed.values.color !== undefined) {
94
+ colorOption = parsed.values.color;
95
+ }
96
+ return {
97
+ command,
98
+ targetDir,
99
+ format: rawFormat,
100
+ minConfidence: rawConfidence,
101
+ failOn: rawFailOn,
102
+ configPath: parsed.values.config,
103
+ baselinePath: parsed.values.baseline,
104
+ updateBaseline: Boolean(parsed.values["update-baseline"]),
105
+ changedOnly: Boolean(parsed.values.changed),
106
+ verbose: Boolean(parsed.values.verbose),
107
+ quiet: Boolean(parsed.values.quiet),
108
+ color: colorOption,
109
+ ruleArg,
110
+ baselineSubcommand,
111
+ };
112
+ }
113
+ function createDefaultOptions(command) {
114
+ return {
115
+ command,
116
+ targetDir: ".",
117
+ format: "pretty",
118
+ minConfidence: "medium",
119
+ failOn: "error",
120
+ updateBaseline: false,
121
+ changedOnly: false,
122
+ verbose: false,
123
+ quiet: false,
124
+ };
125
+ }
126
+ //# sourceMappingURL=args.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"args.js","sourceRoot":"","sources":["../../src/cli/args.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export declare const EXIT_CODES: {
2
+ readonly SUCCESS: 0;
3
+ readonly POLICY_VIOLATION: 1;
4
+ readonly USER_ERROR: 2;
5
+ readonly INTERNAL_ERROR: 3;
6
+ };
7
+ export type ExitCode = (typeof EXIT_CODES)[keyof typeof EXIT_CODES];
8
+ //# sourceMappingURL=exitCodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exitCodes.d.ts","sourceRoot":"","sources":["../../src/cli/exitCodes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,UAAU;;;;;CAKb,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,UAAU,CAAC,CAAC,MAAM,OAAO,UAAU,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ export const EXIT_CODES = {
2
+ SUCCESS: 0,
3
+ POLICY_VIOLATION: 1,
4
+ USER_ERROR: 2,
5
+ INTERNAL_ERROR: 3,
6
+ };
7
+ //# sourceMappingURL=exitCodes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"exitCodes.js","sourceRoot":"","sources":["../../src/cli/exitCodes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,UAAU,GAAG;IACxB,OAAO,EAAE,CAAC;IACV,gBAAgB,EAAE,CAAC;IACnB,UAAU,EAAE,CAAC;IACb,cAAc,EAAE,CAAC;CACT,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Formats help text for the SourceVerity CLI.
3
+ */
4
+ export declare function getHelpText(): string;
5
+ //# sourceMappingURL=help.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.d.ts","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAyCpC"}
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Formats help text for the SourceVerity CLI.
3
+ */
4
+ export function getHelpText() {
5
+ return `SourceVerity - Repository-aware frontend correctness and quality auditor
6
+
7
+ USAGE:
8
+ sourceverity scan [path] [options]
9
+ sourceverity strictness [path] [options]
10
+ sourceverity rules
11
+ sourceverity explain <rule-id>
12
+ sourceverity baseline create [path]
13
+ sourceverity baseline check [path]
14
+
15
+ COMMANDS:
16
+ scan [path] Audit frontend repository for correctness problems (default)
17
+ strictness [path] Analyze TypeScript configuration safety and migration impact
18
+ rules List all available audit rules
19
+ explain <rule-id> Show documentation and examples for a specific rule
20
+ baseline create Generate or update .sourceverity-baseline.json
21
+ baseline check Scan repository and report only new findings against baseline
22
+ help Show this help message
23
+ version Show SourceVerity version
24
+
25
+ OPTIONS:
26
+ -f, --format <type> Output format: pretty (default), json, agent, sarif
27
+ --min-confidence <lvl> Minimum finding confidence to report: medium (default), high, low
28
+ --fail-on <severity> Exit with status 1 on: error (default), warning, never
29
+ -b, --baseline <path> Path to baseline file (default: .sourceverity-baseline.json)
30
+ -u, --update-baseline Update baseline file with current findings
31
+ --changed Analyze only git-changed files in the repository
32
+ -c, --config <path> Path to custom sourceverity.json configuration
33
+ --color / --no-color Force enable or disable ANSI color output
34
+ -q, --quiet Suppress informational messages and progress
35
+ --verbose Show extended diagnostic and framework metadata
36
+ -h, --help Show help
37
+ -v, --version Show version
38
+
39
+ EXIT CODES:
40
+ 0 Scan passed or findings within configured thresholds
41
+ 1 Findings violated configured failure policy (--fail-on)
42
+ 2 Configuration, arguments, or repository input error
43
+ 3 Internal analysis or execution error
44
+ `;
45
+ }
46
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/cli/help.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,WAAW;IACzB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCR,CAAC;AACF,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { type ExitCode } from "./exitCodes.js";
2
+ import "../rules/index.js";
3
+ /**
4
+ * Main CLI execution entry point.
5
+ */
6
+ export declare function runCli(argv: readonly string[]): Promise<ExitCode>;
7
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAEA,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAoB3D,OAAO,mBAAmB,CAAC;AAE3B;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAwJvE"}
@@ -0,0 +1,156 @@
1
+ import path from "node:path";
2
+ import { parseCliArgs } from "./args.js";
3
+ import { EXIT_CODES } from "./exitCodes.js";
4
+ import { getHelpText } from "./help.js";
5
+ import { runAudit } from "../engine/runner.js";
6
+ import { globalRuleRegistry } from "../engine/registry.js";
7
+ import { discoverRepository } from "../repository/detector.js";
8
+ import { loadRepositoryTypeScript } from "../repository/tsLoader.js";
9
+ import { getChangedFiles } from "../repository/git.js";
10
+ import { evaluateStrictnessGap, renderStrictnessReport } from "../strictness/evaluator.js";
11
+ import { createBaseline, saveBaseline, loadBaseline, compareWithBaseline, DEFAULT_BASELINE_FILENAME, } from "../baseline/manager.js";
12
+ import { renderTerminalReport } from "../reporters/terminal.js";
13
+ import { renderJsonReport } from "../reporters/json.js";
14
+ import { renderAgentReport } from "../reporters/agent.js";
15
+ import { renderSarifReport } from "../reporters/sarif.js";
16
+ import { createStyler } from "../core/terminal.js";
17
+ import "../rules/index.js";
18
+ /**
19
+ * Main CLI execution entry point.
20
+ */
21
+ export async function runCli(argv) {
22
+ let options;
23
+ try {
24
+ options = parseCliArgs(argv);
25
+ }
26
+ catch (err) {
27
+ const msg = err instanceof Error ? err.message : String(err);
28
+ process.stderr.write(`sourceverity: ${msg}\n\n${getHelpText()}\n`);
29
+ return EXIT_CODES.USER_ERROR;
30
+ }
31
+ const styler = createStyler(options.color !== undefined ? { color: options.color } : undefined);
32
+ // 1. Help command
33
+ if (options.command === "help") {
34
+ process.stdout.write(getHelpText() + "\n");
35
+ return EXIT_CODES.SUCCESS;
36
+ }
37
+ // 2. Version command
38
+ if (options.command === "version") {
39
+ process.stdout.write("1.0.0\n");
40
+ return EXIT_CODES.SUCCESS;
41
+ }
42
+ // 3. Rules listing command
43
+ if (options.command === "rules") {
44
+ const rules = globalRuleRegistry.getAll();
45
+ process.stdout.write(styler.bold("SourceVerity Rules\n\n"));
46
+ for (const r of rules) {
47
+ const paddedId = r.meta.id.padEnd(45, " ");
48
+ const sev = r.meta.defaultSeverity.padEnd(8, " ");
49
+ process.stdout.write(` ${styler.bold(paddedId)} ${sev} ${styler.dim(r.meta.description)}\n`);
50
+ }
51
+ process.stdout.write(`\nTotal rules: ${rules.length}\n`);
52
+ return EXIT_CODES.SUCCESS;
53
+ }
54
+ // 4. Explain rule command
55
+ if (options.command === "explain") {
56
+ const ruleId = options.ruleArg;
57
+ const rule = ruleId ? globalRuleRegistry.get(ruleId) : undefined;
58
+ if (!rule) {
59
+ process.stderr.write(`sourceverity: unknown rule '${ruleId}'. Run 'sourceverity rules' to list all rules.\n`);
60
+ return EXIT_CODES.USER_ERROR;
61
+ }
62
+ process.stdout.write(styler.bold(`${rule.meta.id}\n\n`));
63
+ process.stdout.write(`${rule.meta.description}\n\n`);
64
+ process.stdout.write(`Category: ${rule.meta.category}\n`);
65
+ process.stdout.write(`Default Severity: ${rule.meta.defaultSeverity}\n`);
66
+ process.stdout.write(`Confidence: ${rule.meta.defaultConfidence}\n`);
67
+ process.stdout.write(`Type Information: ${rule.meta.requiresTypeInformation ? "required" : "syntax only"}\n`);
68
+ return EXIT_CODES.SUCCESS;
69
+ }
70
+ // 5. Strictness gap analysis command
71
+ if (options.command === "strictness") {
72
+ const targetDir = path.resolve(options.targetDir);
73
+ const repo = await discoverRepository(targetDir);
74
+ const tsInst = loadRepositoryTypeScript(targetDir);
75
+ if (!tsInst) {
76
+ process.stderr.write(`sourceverity: strictness analysis requires a local TypeScript installation in '${targetDir}'.\n`);
77
+ return EXIT_CODES.USER_ERROR;
78
+ }
79
+ const report = evaluateStrictnessGap(repo, tsInst);
80
+ process.stdout.write(renderStrictnessReport(report, options.color !== undefined ? { color: options.color } : undefined));
81
+ return EXIT_CODES.SUCCESS;
82
+ }
83
+ // 6. Baseline generation subcommand
84
+ if (options.command === "baseline" && options.baselineSubcommand === "create") {
85
+ const targetDir = path.resolve(options.targetDir);
86
+ const auditResult = await runAudit({ targetDir, minConfidence: options.minConfidence });
87
+ const baselineFile = options.baselinePath ?? path.join(targetDir, DEFAULT_BASELINE_FILENAME);
88
+ const baseline = createBaseline(auditResult.findings, targetDir);
89
+ await saveBaseline(baseline, baselineFile);
90
+ process.stdout.write(`Generated baseline with ${baseline.entries.length} findings at '${baselineFile}'.\n`);
91
+ return EXIT_CODES.SUCCESS;
92
+ }
93
+ // 7. Audit scan command (default)
94
+ let changedFiles;
95
+ if (options.changedOnly) {
96
+ const foundChanged = await getChangedFiles(options.targetDir);
97
+ if (foundChanged === null) {
98
+ process.stderr.write(`sourceverity: --changed requested but '${options.targetDir}' is not a git repository.\n`);
99
+ return EXIT_CODES.USER_ERROR;
100
+ }
101
+ changedFiles = foundChanged;
102
+ }
103
+ const result = await runAudit({
104
+ targetDir: options.targetDir,
105
+ minConfidence: options.minConfidence,
106
+ changedFiles,
107
+ });
108
+ // Handle baseline comparison if baseline path is provided or checking baseline
109
+ let effectiveResult = result;
110
+ if (options.baselinePath || options.command === "baseline") {
111
+ const baselineFile = options.baselinePath ?? path.join(path.resolve(options.targetDir), DEFAULT_BASELINE_FILENAME);
112
+ const loadedBaseline = await loadBaseline(baselineFile);
113
+ if (loadedBaseline) {
114
+ const delta = compareWithBaseline(result.findings, loadedBaseline);
115
+ effectiveResult = {
116
+ ...result,
117
+ findings: delta.newFindings,
118
+ };
119
+ if (!options.quiet && options.format === "pretty") {
120
+ process.stdout.write(`Baseline check against '${baselineFile}': ${delta.baselineCount} baseline, ${delta.newCount} new, ${delta.resolvedCount} resolved.\n\n`);
121
+ }
122
+ }
123
+ }
124
+ if (options.updateBaseline) {
125
+ const baselineFile = options.baselinePath ?? path.join(path.resolve(options.targetDir), DEFAULT_BASELINE_FILENAME);
126
+ const updatedBaseline = createBaseline(result.findings, options.targetDir);
127
+ await saveBaseline(updatedBaseline, baselineFile);
128
+ }
129
+ // Output formatting
130
+ if (options.format === "pretty") {
131
+ process.stdout.write(renderTerminalReport(effectiveResult, { color: options.color, verbose: options.verbose }));
132
+ }
133
+ else if (options.format === "json") {
134
+ process.stdout.write(renderJsonReport(effectiveResult) + "\n");
135
+ }
136
+ else if (options.format === "agent") {
137
+ process.stdout.write(renderAgentReport(effectiveResult) + "\n");
138
+ }
139
+ else if (options.format === "sarif") {
140
+ process.stdout.write(renderSarifReport(effectiveResult) + "\n");
141
+ }
142
+ // Policy exit code evaluation
143
+ if (options.failOn === "never") {
144
+ return EXIT_CODES.SUCCESS;
145
+ }
146
+ const hasErrors = effectiveResult.findings.some((f) => f.severity === "error");
147
+ const hasWarnings = effectiveResult.findings.some((f) => f.severity === "warning");
148
+ if (options.failOn === "error" && hasErrors) {
149
+ return EXIT_CODES.POLICY_VIOLATION;
150
+ }
151
+ if (options.failOn === "warning" && (hasErrors || hasWarnings)) {
152
+ return EXIT_CODES.POLICY_VIOLATION;
153
+ }
154
+ return EXIT_CODES.SUCCESS;
155
+ }
156
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ export interface FingerprintInput {
2
+ readonly ruleId: string;
3
+ readonly filePath: string;
4
+ readonly enclosingScope?: string;
5
+ readonly nodeKind?: string | number;
6
+ readonly symbolName?: string;
7
+ readonly snippet?: string;
8
+ readonly extraKey?: string;
9
+ }
10
+ /**
11
+ * Computes a deterministic, semantic-first finding fingerprint.
12
+ *
13
+ * Uses SHA-256 digest truncated to 16 hex characters prefixed with "sv_".
14
+ * Deliberately excludes volatile source line/column numbers to maintain
15
+ * baseline identity when unrelated code edits occur above the finding.
16
+ */
17
+ export declare function computeFingerprint(input: FingerprintInput): string;
18
+ //# sourceMappingURL=fingerprint.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.d.ts","sourceRoot":"","sources":["../../src/core/fingerprint.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACpC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAkBlE"}
@@ -0,0 +1,26 @@
1
+ import { createHash } from "node:crypto";
2
+ /**
3
+ * Computes a deterministic, semantic-first finding fingerprint.
4
+ *
5
+ * Uses SHA-256 digest truncated to 16 hex characters prefixed with "sv_".
6
+ * Deliberately excludes volatile source line/column numbers to maintain
7
+ * baseline identity when unrelated code edits occur above the finding.
8
+ */
9
+ export function computeFingerprint(input) {
10
+ const normalizedPath = input.filePath.replace(/\\/g, "/");
11
+ const normalizedSnippet = (input.snippet ?? "")
12
+ .replace(/\s+/g, " ")
13
+ .trim();
14
+ const payload = [
15
+ input.ruleId,
16
+ normalizedPath,
17
+ input.enclosingScope ?? "global",
18
+ String(input.nodeKind ?? ""),
19
+ input.symbolName ?? "",
20
+ normalizedSnippet,
21
+ input.extraKey ?? "",
22
+ ].join("::");
23
+ const hash = createHash("sha256").update(payload, "utf-8").digest("hex").slice(0, 16);
24
+ return `sv_${hash}`;
25
+ }
26
+ //# sourceMappingURL=fingerprint.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../src/core/fingerprint.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAYzC;;;;;;GAMG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAuB;IACxD,MAAM,cAAc,GAAG,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;IAC1D,MAAM,iBAAiB,GAAG,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC;SAC5C,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC;SACpB,IAAI,EAAE,CAAC;IAEV,MAAM,OAAO,GAAG;QACd,KAAK,CAAC,MAAM;QACZ,cAAc;QACd,KAAK,CAAC,cAAc,IAAI,QAAQ;QAChC,MAAM,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC5B,KAAK,CAAC,UAAU,IAAI,EAAE;QACtB,iBAAiB;QACjB,KAAK,CAAC,QAAQ,IAAI,EAAE;KACrB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACtF,OAAO,MAAM,IAAI,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Normalizes any file system path into a standardized POSIX relative path.
3
+ * Ensures consistent output across Windows and POSIX systems.
4
+ */
5
+ export declare function normalizePath(filePath: string, relativeTo?: string): string;
6
+ /**
7
+ * Determines whether a file path has an accepted TypeScript or JavaScript extension.
8
+ */
9
+ export declare function isSourceFile(filePath: string): boolean;
10
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/core/paths.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAsB3E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtD"}