@quantakrypto/core 0.3.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.
Files changed (166) hide show
  1. package/dist/agent-types.d.ts +48 -0
  2. package/dist/agent-types.d.ts.map +1 -0
  3. package/dist/agent-types.js +2 -0
  4. package/dist/agent-types.js.map +1 -0
  5. package/dist/cache.d.ts +27 -0
  6. package/dist/cache.d.ts.map +1 -0
  7. package/dist/cache.js +93 -0
  8. package/dist/cache.js.map +1 -0
  9. package/dist/cbom.d.ts.map +1 -1
  10. package/dist/cbom.js +26 -1
  11. package/dist/cbom.js.map +1 -1
  12. package/dist/changed.d.ts.map +1 -1
  13. package/dist/changed.js +14 -2
  14. package/dist/changed.js.map +1 -1
  15. package/dist/codemods/config-toggle.d.ts +3 -0
  16. package/dist/codemods/config-toggle.d.ts.map +1 -0
  17. package/dist/codemods/config-toggle.js +26 -0
  18. package/dist/codemods/config-toggle.js.map +1 -0
  19. package/dist/codemods/registry.d.ts +26 -0
  20. package/dist/codemods/registry.d.ts.map +1 -0
  21. package/dist/codemods/registry.js +8 -0
  22. package/dist/codemods/registry.js.map +1 -0
  23. package/dist/comments.d.ts +45 -0
  24. package/dist/comments.d.ts.map +1 -0
  25. package/dist/comments.js +164 -0
  26. package/dist/comments.js.map +1 -0
  27. package/dist/config.d.ts +1 -1
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +7 -0
  30. package/dist/config.js.map +1 -1
  31. package/dist/dependencies.d.ts +31 -13
  32. package/dist/dependencies.d.ts.map +1 -1
  33. package/dist/dependencies.js +460 -40
  34. package/dist/dependencies.js.map +1 -1
  35. package/dist/detect-utils.d.ts +44 -1
  36. package/dist/detect-utils.d.ts.map +1 -1
  37. package/dist/detect-utils.js +113 -17
  38. package/dist/detect-utils.js.map +1 -1
  39. package/dist/detectors/c.d.ts +20 -0
  40. package/dist/detectors/c.d.ts.map +1 -0
  41. package/dist/detectors/c.js +104 -0
  42. package/dist/detectors/c.js.map +1 -0
  43. package/dist/detectors/csharp.d.ts +15 -0
  44. package/dist/detectors/csharp.d.ts.map +1 -0
  45. package/dist/detectors/csharp.js +76 -0
  46. package/dist/detectors/csharp.js.map +1 -0
  47. package/dist/detectors/go.d.ts +25 -0
  48. package/dist/detectors/go.d.ts.map +1 -0
  49. package/dist/detectors/go.js +132 -0
  50. package/dist/detectors/go.js.map +1 -0
  51. package/dist/detectors/java.d.ts +25 -0
  52. package/dist/detectors/java.d.ts.map +1 -0
  53. package/dist/detectors/java.js +200 -0
  54. package/dist/detectors/java.js.map +1 -0
  55. package/dist/detectors/python.d.ts +26 -0
  56. package/dist/detectors/python.d.ts.map +1 -0
  57. package/dist/detectors/python.js +171 -0
  58. package/dist/detectors/python.js.map +1 -0
  59. package/dist/detectors/ruby.d.ts +15 -0
  60. package/dist/detectors/ruby.d.ts.map +1 -0
  61. package/dist/detectors/ruby.js +75 -0
  62. package/dist/detectors/ruby.js.map +1 -0
  63. package/dist/detectors/rust.d.ts +13 -0
  64. package/dist/detectors/rust.d.ts.map +1 -0
  65. package/dist/detectors/rust.js +94 -0
  66. package/dist/detectors/rust.js.map +1 -0
  67. package/dist/detectors/source.d.ts.map +1 -1
  68. package/dist/detectors/source.js +70 -22
  69. package/dist/detectors/source.js.map +1 -1
  70. package/dist/index.d.ts +18 -1
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +15 -1
  73. package/dist/index.js.map +1 -1
  74. package/dist/parallel.d.ts +4 -0
  75. package/dist/parallel.d.ts.map +1 -1
  76. package/dist/parallel.js +59 -8
  77. package/dist/parallel.js.map +1 -1
  78. package/dist/patch-policy.d.ts +22 -0
  79. package/dist/patch-policy.d.ts.map +1 -0
  80. package/dist/patch-policy.js +21 -0
  81. package/dist/patch-policy.js.map +1 -0
  82. package/dist/redact.d.ts +19 -0
  83. package/dist/redact.d.ts.map +1 -0
  84. package/dist/redact.js +77 -0
  85. package/dist/redact.js.map +1 -0
  86. package/dist/registry.d.ts +13 -3
  87. package/dist/registry.d.ts.map +1 -1
  88. package/dist/registry.js +31 -4
  89. package/dist/registry.js.map +1 -1
  90. package/dist/remediate-pipeline.d.ts +41 -0
  91. package/dist/remediate-pipeline.d.ts.map +1 -0
  92. package/dist/remediate-pipeline.js +38 -0
  93. package/dist/remediate-pipeline.js.map +1 -0
  94. package/dist/remediate-request.d.ts +21 -0
  95. package/dist/remediate-request.d.ts.map +1 -0
  96. package/dist/remediate-request.js +28 -0
  97. package/dist/remediate-request.js.map +1 -0
  98. package/dist/remediation.d.ts +10 -0
  99. package/dist/remediation.d.ts.map +1 -1
  100. package/dist/remediation.js +21 -8
  101. package/dist/remediation.js.map +1 -1
  102. package/dist/report.d.ts.map +1 -1
  103. package/dist/report.js +16 -1
  104. package/dist/report.js.map +1 -1
  105. package/dist/scan-worker.js +6 -2
  106. package/dist/scan-worker.js.map +1 -1
  107. package/dist/scan.d.ts +5 -4
  108. package/dist/scan.d.ts.map +1 -1
  109. package/dist/scan.js +52 -29
  110. package/dist/scan.js.map +1 -1
  111. package/dist/triage.d.ts +27 -0
  112. package/dist/triage.d.ts.map +1 -0
  113. package/dist/triage.js +33 -0
  114. package/dist/triage.js.map +1 -0
  115. package/dist/types.d.ts +53 -3
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/verify.d.ts +30 -0
  118. package/dist/verify.d.ts.map +1 -0
  119. package/dist/verify.js +65 -0
  120. package/dist/verify.js.map +1 -0
  121. package/dist/version.d.ts +1 -1
  122. package/dist/version.js +1 -1
  123. package/dist/walk.d.ts +7 -0
  124. package/dist/walk.d.ts.map +1 -1
  125. package/dist/walk.js +85 -11
  126. package/dist/walk.js.map +1 -1
  127. package/dist/worktree.d.ts +6 -0
  128. package/dist/worktree.d.ts.map +1 -0
  129. package/dist/worktree.js +43 -0
  130. package/dist/worktree.js.map +1 -0
  131. package/package.json +1 -1
  132. package/src/agent-types.ts +52 -0
  133. package/src/cache.ts +120 -0
  134. package/src/cbom.ts +27 -1
  135. package/src/changed.ts +13 -4
  136. package/src/codemods/config-toggle.ts +35 -0
  137. package/src/codemods/registry.ts +31 -0
  138. package/src/comments.ts +180 -0
  139. package/src/config.ts +8 -0
  140. package/src/dependencies.ts +483 -51
  141. package/src/detect-utils.ts +123 -15
  142. package/src/detectors/c.ts +132 -0
  143. package/src/detectors/csharp.ts +98 -0
  144. package/src/detectors/go.ts +167 -0
  145. package/src/detectors/java.ts +235 -0
  146. package/src/detectors/python.ts +212 -0
  147. package/src/detectors/ruby.ts +97 -0
  148. package/src/detectors/rust.ts +112 -0
  149. package/src/detectors/source.ts +69 -21
  150. package/src/index.ts +45 -1
  151. package/src/parallel.ts +63 -6
  152. package/src/patch-policy.ts +42 -0
  153. package/src/redact.ts +92 -0
  154. package/src/registry.ts +32 -4
  155. package/src/remediate-pipeline.ts +81 -0
  156. package/src/remediate-request.ts +52 -0
  157. package/src/remediation.ts +27 -11
  158. package/src/report.ts +27 -1
  159. package/src/scan-worker.ts +6 -2
  160. package/src/scan.ts +62 -31
  161. package/src/triage.ts +58 -0
  162. package/src/types.ts +66 -3
  163. package/src/verify.ts +82 -0
  164. package/src/version.ts +1 -1
  165. package/src/walk.ts +81 -12
  166. package/src/worktree.ts +45 -0
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Shared types for the agent (BYOK) plane. These live in `@quantakrypto/core`
3
+ * (offline) so both the deterministic MCP tools and the networked
4
+ * `@quantakrypto/agent` package speak the same shapes without the offline side
5
+ * ever importing the network client.
6
+ */
7
+ import type { Severity, TriageAnnotation } from "./types.js";
8
+ /** How much source context a redacted request carries. */
9
+ export type ContextLevel = "metadata" | "snippet" | "function" | "file";
10
+ /** A finding's context, redacted to a {@link ContextLevel} and secret-stripped. */
11
+ export interface RedactedContext {
12
+ level: ContextLevel;
13
+ meta: {
14
+ ruleId: string;
15
+ algorithm?: string;
16
+ severity: Severity;
17
+ hndl: boolean;
18
+ file: string;
19
+ line: number;
20
+ message: string;
21
+ };
22
+ /** Redacted source, or null at `metadata` level / for a `sensitive` finding. */
23
+ code: string | null;
24
+ /** True when key material was stripped from the context. */
25
+ redactedSecret: boolean;
26
+ }
27
+ /** An LLM triage verdict for a single finding (never suppresses it). The
28
+ * exposure/priority/rationale body is the {@link TriageAnnotation} that gets
29
+ * attached to the finding; `fingerprint` links it back to that finding. */
30
+ export interface TriageVerdict extends TriageAnnotation {
31
+ fingerprint: string;
32
+ }
33
+ /** A concrete proposed edit: the full new content for a single file. */
34
+ export interface Patch {
35
+ path: string;
36
+ /** Full replacement content for `path` after the fix. */
37
+ newContent: string;
38
+ ruleId: string;
39
+ source: "codemod" | "llm";
40
+ }
41
+ /** An LLM-proposed fix before it enters the deterministic pipeline. */
42
+ export interface FixProposal {
43
+ fingerprint: string;
44
+ path: string;
45
+ newContent: string;
46
+ explanation: string;
47
+ }
48
+ //# sourceMappingURL=agent-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-types.d.ts","sourceRoot":"","sources":["../src/agent-types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE7D,0DAA0D;AAC1D,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,CAAC;AAExE,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,YAAY,CAAC;IACpB,IAAI,EAAE;QACJ,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,EAAE,QAAQ,CAAC;QACnB,IAAI,EAAE,OAAO,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,4DAA4D;IAC5D,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;2EAE2E;AAC3E,MAAM,WAAW,aAAc,SAAQ,gBAAgB;IACrD,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,wEAAwE;AACxE,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,yDAAyD;IACzD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,SAAS,GAAG,KAAK,CAAC;CAC3B;AAED,uEAAuE;AACvE,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACrB"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=agent-types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-types.js","sourceRoot":"","sources":["../src/agent-types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,27 @@
1
+ import type { Detector, Finding } from "./types.js";
2
+ /** One cached file: the content hash it was computed for, and its findings. */
3
+ export interface CacheEntry {
4
+ hash: string;
5
+ findings: Finding[];
6
+ }
7
+ /** sha256 of a file's content (hex). */
8
+ export declare function hashContent(content: string): string;
9
+ /**
10
+ * Fingerprint of everything that changes what a scan produces: the tool version,
11
+ * the active detector ids (sorted), and the disabled-rule set (sorted). A change
12
+ * to any of these invalidates the whole cache.
13
+ */
14
+ export declare function rulesetFingerprint(detectors: readonly Detector[], disabledRules: readonly string[] | undefined): string;
15
+ /**
16
+ * Load the cache file into a `Map<relPath, CacheEntry>`. Returns an empty map
17
+ * when the file is missing, unparseable, the wrong version, or was written for a
18
+ * different ruleset (in which case its entries are stale and must not be reused).
19
+ */
20
+ export declare function loadCache(cacheFile: string, ruleset: string): Promise<Map<string, CacheEntry>>;
21
+ /**
22
+ * Write the cache atomically (temp file + rename) so a concurrent reader never
23
+ * sees a half-written file. Errors are swallowed — a cache is an optimization,
24
+ * never a reason to fail a scan.
25
+ */
26
+ export declare function saveCache(cacheFile: string, ruleset: string, entries: Map<string, CacheEntry>): Promise<void>;
27
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAKpD,+EAA+E;AAC/E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,OAAO,EAAE,CAAC;CACrB;AAQD,wCAAwC;AACxC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,SAAS,QAAQ,EAAE,EAC9B,aAAa,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,GAC3C,MAAM,CAIR;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CA8BlC;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAC/B,OAAO,CAAC,IAAI,CAAC,CAef"}
package/dist/cache.js ADDED
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Optional on-disk scan cache. Keyed by file content hash so an unchanged file
3
+ * reuses its previous findings instead of re-running every detector — the big
4
+ * win on large monorepos where most files don't change between runs.
5
+ *
6
+ * Invalidation is conservative and whole-cache: the cache stores a RULESET
7
+ * FINGERPRINT (tool version + the active detector ids + disabled rules). If any
8
+ * of those differ from the current run, the entire cache is discarded and
9
+ * rebuilt, so upgrading the tool or changing the rules never serves stale
10
+ * results. Per file, a content-hash mismatch re-scans just that file.
11
+ *
12
+ * The cache is opt-in (`ScanOptions.cacheFile`); with no cache file, scans are
13
+ * exactly as before. A corrupt / unreadable / wrong-version cache file is
14
+ * ignored (treated as empty), never fatal.
15
+ */
16
+ import { createHash } from "node:crypto";
17
+ import { readFile, writeFile, mkdir } from "node:fs/promises";
18
+ import * as path from "node:path";
19
+ import { VERSION } from "./version.js";
20
+ const CACHE_VERSION = 1;
21
+ /** sha256 of a file's content (hex). */
22
+ export function hashContent(content) {
23
+ return createHash("sha256").update(content, "utf8").digest("hex");
24
+ }
25
+ /**
26
+ * Fingerprint of everything that changes what a scan produces: the tool version,
27
+ * the active detector ids (sorted), and the disabled-rule set (sorted). A change
28
+ * to any of these invalidates the whole cache.
29
+ */
30
+ export function rulesetFingerprint(detectors, disabledRules) {
31
+ const ids = detectors.map((d) => d.id).sort();
32
+ const disabled = [...(disabledRules ?? [])].sort();
33
+ return `v${VERSION}|d:${ids.join(",")}|x:${disabled.join(",")}`;
34
+ }
35
+ /**
36
+ * Load the cache file into a `Map<relPath, CacheEntry>`. Returns an empty map
37
+ * when the file is missing, unparseable, the wrong version, or was written for a
38
+ * different ruleset (in which case its entries are stale and must not be reused).
39
+ */
40
+ export async function loadCache(cacheFile, ruleset) {
41
+ let raw;
42
+ try {
43
+ raw = await readFile(cacheFile, "utf8");
44
+ }
45
+ catch {
46
+ return new Map();
47
+ }
48
+ let parsed;
49
+ try {
50
+ parsed = JSON.parse(raw);
51
+ }
52
+ catch {
53
+ return new Map();
54
+ }
55
+ if (parsed === null ||
56
+ typeof parsed !== "object" ||
57
+ parsed.version !== CACHE_VERSION ||
58
+ parsed.ruleset !== ruleset ||
59
+ typeof parsed.entries !== "object" ||
60
+ parsed.entries === null) {
61
+ return new Map();
62
+ }
63
+ const map = new Map();
64
+ for (const [file, entry] of Object.entries(parsed.entries)) {
65
+ if (entry && typeof entry.hash === "string" && Array.isArray(entry.findings)) {
66
+ map.set(file, entry);
67
+ }
68
+ }
69
+ return map;
70
+ }
71
+ /**
72
+ * Write the cache atomically (temp file + rename) so a concurrent reader never
73
+ * sees a half-written file. Errors are swallowed — a cache is an optimization,
74
+ * never a reason to fail a scan.
75
+ */
76
+ export async function saveCache(cacheFile, ruleset, entries) {
77
+ const doc = {
78
+ version: CACHE_VERSION,
79
+ ruleset,
80
+ entries: Object.fromEntries(entries),
81
+ };
82
+ try {
83
+ await mkdir(path.dirname(cacheFile), { recursive: true });
84
+ const tmp = `${cacheFile}.tmp-${process.pid}`;
85
+ await writeFile(tmp, JSON.stringify(doc), "utf8");
86
+ const { rename } = await import("node:fs/promises");
87
+ await rename(tmp, cacheFile);
88
+ }
89
+ catch {
90
+ // best effort
91
+ }
92
+ }
93
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../src/cache.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,aAAa,GAAG,CAAC,CAAC;AAcxB,wCAAwC;AACxC,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,SAA8B,EAC9B,aAA4C;IAE5C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IACnD,OAAO,IAAI,OAAO,MAAM,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;AAClE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,SAAiB,EACjB,OAAe;IAEf,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,IAAI,MAAsB,CAAC;IAC3B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAmB,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,IACE,MAAM,KAAK,IAAI;QACf,OAAO,MAAM,KAAK,QAAQ;QAC1B,MAAM,CAAC,OAAO,KAAK,aAAa;QAChC,MAAM,CAAC,OAAO,KAAK,OAAO;QAC1B,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ;QAClC,MAAM,CAAC,OAAO,KAAK,IAAI,EACvB,CAAC;QACD,OAAO,IAAI,GAAG,EAAE,CAAC;IACnB,CAAC;IACD,MAAM,GAAG,GAAG,IAAI,GAAG,EAAsB,CAAC;IAC1C,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3D,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7E,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,SAAiB,EACjB,OAAe,EACf,OAAgC;IAEhC,MAAM,GAAG,GAAmB;QAC1B,OAAO,EAAE,aAAa;QACtB,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC;KACrC,CAAC;IACF,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,GAAG,SAAS,QAAQ,OAAO,CAAC,GAAG,EAAE,CAAC;QAC9C,MAAM,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QAClD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,cAAc;IAChB,CAAC;AACH,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"cbom.d.ts","sourceRoot":"","sources":["../src/cbom.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAA6C,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxF,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AA8BD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAqFvD"}
1
+ {"version":3,"file":"cbom.d.ts","sourceRoot":"","sources":["../src/cbom.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAA6C,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxF,yEAAyE;AACzE,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,KAAK,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,UAAU,EAAE,aAAa,EAAE,CAAC;CAC7B;AAED,0DAA0D;AAC1D,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC1C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAwDD;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,YAAY,CAqFvD"}
package/dist/cbom.js CHANGED
@@ -32,6 +32,31 @@ function primitiveFor(category) {
32
32
  function isQuantumVulnerable(algorithm) {
33
33
  return algorithm !== "unknown";
34
34
  }
35
+ /**
36
+ * Approximate CLASSICAL security strength (bits) of the common parameterisation
37
+ * of a classical family — RSA-2048 / DH-2048 ≈ 112-bit, 256-bit curves ≈ 128-bit,
38
+ * X448 ≈ 224-bit. (The QUANTUM level is 0 for all of these: Shor breaks them.)
39
+ * 0 when the family is unknown. Reported so a CBOM doesn't imply these primitives
40
+ * have zero classical strength today.
41
+ */
42
+ function classicalSecurityLevelFor(algorithm) {
43
+ switch (algorithm) {
44
+ case "RSA":
45
+ case "DH":
46
+ case "DSA":
47
+ return 112;
48
+ case "ECDH":
49
+ case "ECDSA":
50
+ case "EdDSA":
51
+ case "X25519":
52
+ case "ECIES":
53
+ return 128;
54
+ case "X448":
55
+ return 224;
56
+ default:
57
+ return 0;
58
+ }
59
+ }
35
60
  /** Deterministic bom-ref for a (algorithm, primitive) asset key. */
36
61
  function bomRef(key) {
37
62
  return `crypto:${createHash("sha256").update(key, "utf8").digest("hex").slice(0, 16)}`;
@@ -75,7 +100,7 @@ export function toCbom(result) {
75
100
  primitive: g.primitive,
76
101
  parameterSetIdentifier: g.algorithm,
77
102
  executionEnvironment: "software-plain-ram",
78
- classicalSecurityLevel: 0,
103
+ classicalSecurityLevel: classicalSecurityLevelFor(g.algorithm),
79
104
  nistQuantumSecurityLevel: 0,
80
105
  cryptoFunctions: g.primitive === "signature"
81
106
  ? ["sign", "verify"]
package/dist/cbom.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cbom.js","sourceRoot":"","sources":["../src/cbom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cbom.js","sourceRoot":"","sources":["../src/cbom.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"changed.d.ts","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AAiCA;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAsClF"}
1
+ {"version":3,"file":"changed.d.ts","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"AAiCA;;;;;;;;;;GAUG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CA+ClF"}
package/dist/changed.js CHANGED
@@ -50,9 +50,21 @@ export async function changedFiles(root, since) {
50
50
  // than repo-root-relative, so `scan()` can join them against a sub-directory
51
51
  // root. Without it, a `--changed` scan of a subdirectory resolves nothing.
52
52
  if (since) {
53
- for (const f of toLines(await git(root, ["diff", "--name-only", "--relative", "--diff-filter=ACMR", since]))) {
54
- out.add(f);
53
+ // A `git diff` against `since` returns null ONLY when the command failed —
54
+ // almost always an unknown ref/range (a typo like `--since maiin`). Surface
55
+ // it instead of silently scanning just the uncommitted files and passing CI.
56
+ const diff = await git(root, [
57
+ "diff",
58
+ "--name-only",
59
+ "--relative",
60
+ "--diff-filter=ACMR",
61
+ since,
62
+ ]);
63
+ if (diff === null) {
64
+ throw new Error(`--since: git could not diff against "${since}" (unknown ref or range).`);
55
65
  }
66
+ for (const f of toLines(diff))
67
+ out.add(f);
56
68
  }
57
69
  // Always include local uncommitted edits (staged + unstaged), filtered to ACMR.
58
70
  for (const f of toLines(await git(root, ["diff", "--name-only", "--relative", "--diff-filter=ACMR"]))) {
@@ -1 +1 @@
1
- {"version":3,"file":"changed.js","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"changed.js","sourceRoot":"","sources":["../src/changed.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Codemod } from "./registry.js";
2
+ export declare const configToggleCodemod: Codemod;
3
+ //# sourceMappingURL=config-toggle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-toggle.d.ts","sourceRoot":"","sources":["../../src/codemods/config-toggle.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAE7C,eAAO,MAAM,mBAAmB,EAAE,OAsBjC,CAAC"}
@@ -0,0 +1,26 @@
1
+ export const configToggleCodemod = {
2
+ id: "config-toggle",
3
+ applies(finding) {
4
+ return finding.ruleId === "tls-legacy-version" || finding.ruleId === "tls-reject-unauthorized";
5
+ },
6
+ apply(content, finding) {
7
+ let out = content;
8
+ if (finding.ruleId === "tls-legacy-version") {
9
+ out = out
10
+ .replace(/((?:minVersion|maxVersion)\s*:\s*['"`])TLSv1(?:\.1)?(['"`])/g, "$1TLSv1.3$2")
11
+ .replace(/(secureProtocol\s*:\s*['"`])TLSv1(?:_1)?_method(['"`])/g, "$1TLSv1_3_method$2");
12
+ }
13
+ else if (finding.ruleId === "tls-reject-unauthorized") {
14
+ out = out.replace(/(rejectUnauthorized\s*:\s*)false/g, "$1true");
15
+ }
16
+ if (out === content)
17
+ return null;
18
+ return {
19
+ path: finding.location.file,
20
+ newContent: out,
21
+ ruleId: finding.ruleId,
22
+ source: "codemod",
23
+ };
24
+ },
25
+ };
26
+ //# sourceMappingURL=config-toggle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-toggle.js","sourceRoot":"","sources":["../../src/codemods/config-toggle.ts"],"names":[],"mappings":"AAYA,MAAM,CAAC,MAAM,mBAAmB,GAAY;IAC1C,EAAE,EAAE,eAAe;IACnB,OAAO,CAAC,OAAgB;QACtB,OAAO,OAAO,CAAC,MAAM,KAAK,oBAAoB,IAAI,OAAO,CAAC,MAAM,KAAK,yBAAyB,CAAC;IACjG,CAAC;IACD,KAAK,CAAC,OAAe,EAAE,OAAgB;QACrC,IAAI,GAAG,GAAG,OAAO,CAAC;QAClB,IAAI,OAAO,CAAC,MAAM,KAAK,oBAAoB,EAAE,CAAC;YAC5C,GAAG,GAAG,GAAG;iBACN,OAAO,CAAC,8DAA8D,EAAE,aAAa,CAAC;iBACtF,OAAO,CAAC,yDAAyD,EAAE,oBAAoB,CAAC,CAAC;QAC9F,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,yBAAyB,EAAE,CAAC;YACxD,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,mCAAmC,EAAE,QAAQ,CAAC,CAAC;QACnE,CAAC;QACD,IAAI,GAAG,KAAK,OAAO;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO;YACL,IAAI,EAAE,OAAO,CAAC,QAAQ,CAAC,IAAI;YAC3B,UAAU,EAAE,GAAG;YACf,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,MAAM,EAAE,SAAS;SAClB,CAAC;IACJ,CAAC;CACF,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Codemod registry — deterministic, template-able fixes keyed by finding.
3
+ *
4
+ * A codemod only earns a place here if its output reliably CLEARS the finding
5
+ * (the remediation pipeline enforces this with the `verify_fix` gate). That
6
+ * makes the set deliberately small: mechanical config toggles qualify;
7
+ * dependency swaps and source crypto rewrites generally do NOT (there is no
8
+ * safe drop-in replacement, and a manifest fix can't "remove" the finding
9
+ * without deleting the dependency) — those are left to triage + the LLM
10
+ * remediation layer, not an auto-codemod.
11
+ */
12
+ import type { Finding } from "../types.js";
13
+ import type { Patch } from "../agent-types.js";
14
+ /** A deterministic fix for a class of findings. */
15
+ export interface Codemod {
16
+ id: string;
17
+ /** True when this codemod can produce a deterministic fix for the finding. */
18
+ applies(finding: Finding): boolean;
19
+ /** Produce a patch (full new file content), or null if it changed nothing. */
20
+ apply(content: string, finding: Finding): Patch | null;
21
+ }
22
+ /** All registered codemods, in priority order. */
23
+ export declare const codemodRegistry: Codemod[];
24
+ /** The first codemod that applies to `finding`, or undefined. */
25
+ export declare function codemodFor(finding: Finding): Codemod | undefined;
26
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../src/codemods/registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAC;AAG/C,mDAAmD;AACnD,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,8EAA8E;IAC9E,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC;IACnC,8EAA8E;IAC9E,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,KAAK,GAAG,IAAI,CAAC;CACxD;AAED,kDAAkD;AAClD,eAAO,MAAM,eAAe,EAAE,OAAO,EAA0B,CAAC;AAEhE,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS,CAEhE"}
@@ -0,0 +1,8 @@
1
+ import { configToggleCodemod } from "./config-toggle.js";
2
+ /** All registered codemods, in priority order. */
3
+ export const codemodRegistry = [configToggleCodemod];
4
+ /** The first codemod that applies to `finding`, or undefined. */
5
+ export function codemodFor(finding) {
6
+ return codemodRegistry.find((c) => c.applies(finding));
7
+ }
8
+ //# sourceMappingURL=registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../src/codemods/registry.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAWzD,kDAAkD;AAClD,MAAM,CAAC,MAAM,eAAe,GAAc,CAAC,mBAAmB,CAAC,CAAC;AAEhE,iEAAiE;AACjE,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAO,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;AACzD,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Comment-aware false-positive suppression.
3
+ *
4
+ * The detectors are lexical (regex over source text), so a crypto API name
5
+ * written in a COMMENT — `// migrated off createECDH()` — fires a finding just
6
+ * like real code. This module computes the comment spans of a file (respecting
7
+ * string literals, so a `//` inside a string is not a comment) and drops any
8
+ * finding whose match starts inside one.
9
+ *
10
+ * The lexer is deliberately conservative: it only ever ENTERS a comment on a
11
+ * literal line comment, block comment, or `#` in code position (all of which ARE
12
+ * comments), so it never mis-classifies code as a comment and can only reduce
13
+ * false positives, not recall. The one inherent lexical ambiguity — a regex
14
+ * literal that looks like a block-comment open — is rare and guarded by the
15
+ * detection benchmark's recall gate.
16
+ */
17
+ import type { Finding } from "./types.js";
18
+ export type CommentStyle = "c" | "hash";
19
+ /** The comment style for a file path, or null when we don't strip comments for it. */
20
+ export declare function commentStyleForFile(file: string): CommentStyle | null;
21
+ /**
22
+ * Compute the comment spans (`[start, end)` offsets) of `content`, skipping over
23
+ * string literals so a comment marker inside a string is not treated as a
24
+ * comment. Spans are returned sorted and non-overlapping.
25
+ */
26
+ export declare function commentSpans(content: string, style: CommentStyle): Array<[number, number]>;
27
+ /** True if `offset` falls inside one of the (sorted, non-overlapping) spans. */
28
+ export declare function offsetInSpans(spans: ReadonlyArray<[number, number]>, offset: number): boolean;
29
+ /**
30
+ * Line numbers (1-based) suppressed by an inline ignore directive:
31
+ * - `qscan-ignore-line` on a line suppresses findings on THAT line.
32
+ * - `qscan-ignore-next-line` on a line suppresses findings on the NEXT line.
33
+ * The directive text is matched anywhere on the line (usually in a comment), so
34
+ * it is language-agnostic. `qscan-ignore-line` is not a substring of
35
+ * `qscan-ignore-next-line`, so the two never collide.
36
+ */
37
+ export declare function ignoredLines(content: string): Set<number>;
38
+ /** Drop findings on lines suppressed by an inline `qscan-ignore` directive. */
39
+ export declare function stripIgnoredFindings(findings: Finding[], content: string): Finding[];
40
+ /**
41
+ * Drop findings whose match starts inside a comment. No-op when the file's
42
+ * language has no comment style we handle, or when it has no comments.
43
+ */
44
+ export declare function stripCommentFindings(findings: Finding[], content: string, file: string): Finding[];
45
+ //# sourceMappingURL=comments.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.d.ts","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,MAAM,CAAC;AA8BxC,sFAAsF;AACtF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAKrE;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,GAAG,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAgD1F;AAED,gFAAgF;AAChF,wBAAgB,aAAa,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAW7F;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CASzD;AAED,+EAA+E;AAC/E,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE,CAKpF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,GACX,OAAO,EAAE,CAmBX"}
@@ -0,0 +1,164 @@
1
+ /** C-style (line + block) comment languages, by extension. */
2
+ const C_LIKE = [
3
+ ".js",
4
+ ".jsx",
5
+ ".ts",
6
+ ".tsx",
7
+ ".mjs",
8
+ ".cjs",
9
+ ".vue",
10
+ ".svelte",
11
+ ".go",
12
+ ".java",
13
+ ".kt",
14
+ ".kts",
15
+ ".cs",
16
+ ".rs",
17
+ ".c",
18
+ ".h",
19
+ ".cc",
20
+ ".cpp",
21
+ ".cxx",
22
+ ".hpp",
23
+ ".hh",
24
+ ];
25
+ /** Hash-style (`#`) comment languages, by extension. */
26
+ const HASH_LIKE = [".py", ".pyi", ".pyw", ".rb"];
27
+ /** The comment style for a file path, or null when we don't strip comments for it. */
28
+ export function commentStyleForFile(file) {
29
+ const lower = file.toLowerCase();
30
+ if (C_LIKE.some((e) => lower.endsWith(e)))
31
+ return "c";
32
+ if (HASH_LIKE.some((e) => lower.endsWith(e)))
33
+ return "hash";
34
+ return null;
35
+ }
36
+ /**
37
+ * Compute the comment spans (`[start, end)` offsets) of `content`, skipping over
38
+ * string literals so a comment marker inside a string is not treated as a
39
+ * comment. Spans are returned sorted and non-overlapping.
40
+ */
41
+ export function commentSpans(content, style) {
42
+ const spans = [];
43
+ const n = content.length;
44
+ let i = 0;
45
+ while (i < n) {
46
+ const c = content[i];
47
+ // String / template literal: skip to the matching unescaped delimiter.
48
+ if (c === '"' || c === "'" || c === "`") {
49
+ const quote = c;
50
+ i++;
51
+ while (i < n) {
52
+ if (content[i] === "\\") {
53
+ i += 2;
54
+ continue;
55
+ }
56
+ if (content[i] === quote) {
57
+ i++;
58
+ break;
59
+ }
60
+ i++;
61
+ }
62
+ continue;
63
+ }
64
+ if (style === "c" && c === "/" && content[i + 1] === "/") {
65
+ const start = i;
66
+ i += 2;
67
+ while (i < n && content[i] !== "\n")
68
+ i++;
69
+ spans.push([start, i]);
70
+ continue;
71
+ }
72
+ if (style === "c" && c === "/" && content[i + 1] === "*") {
73
+ const start = i;
74
+ i += 2;
75
+ while (i < n && !(content[i] === "*" && content[i + 1] === "/"))
76
+ i++;
77
+ i = Math.min(n, i + 2);
78
+ spans.push([start, i]);
79
+ continue;
80
+ }
81
+ if (style === "hash" && c === "#") {
82
+ const start = i;
83
+ i++;
84
+ while (i < n && content[i] !== "\n")
85
+ i++;
86
+ spans.push([start, i]);
87
+ continue;
88
+ }
89
+ i++;
90
+ }
91
+ return spans;
92
+ }
93
+ /** True if `offset` falls inside one of the (sorted, non-overlapping) spans. */
94
+ export function offsetInSpans(spans, offset) {
95
+ let lo = 0;
96
+ let hi = spans.length - 1;
97
+ while (lo <= hi) {
98
+ const mid = (lo + hi) >>> 1;
99
+ const [s, e] = spans[mid];
100
+ if (offset < s)
101
+ hi = mid - 1;
102
+ else if (offset >= e)
103
+ lo = mid + 1;
104
+ else
105
+ return true;
106
+ }
107
+ return false;
108
+ }
109
+ /**
110
+ * Line numbers (1-based) suppressed by an inline ignore directive:
111
+ * - `qscan-ignore-line` on a line suppresses findings on THAT line.
112
+ * - `qscan-ignore-next-line` on a line suppresses findings on the NEXT line.
113
+ * The directive text is matched anywhere on the line (usually in a comment), so
114
+ * it is language-agnostic. `qscan-ignore-line` is not a substring of
115
+ * `qscan-ignore-next-line`, so the two never collide.
116
+ */
117
+ export function ignoredLines(content) {
118
+ const ignored = new Set();
119
+ const lines = content.split("\n");
120
+ for (let i = 0; i < lines.length; i++) {
121
+ const line = lines[i];
122
+ if (line.includes("qscan-ignore-next-line"))
123
+ ignored.add(i + 2);
124
+ else if (line.includes("qscan-ignore-line"))
125
+ ignored.add(i + 1);
126
+ }
127
+ return ignored;
128
+ }
129
+ /** Drop findings on lines suppressed by an inline `qscan-ignore` directive. */
130
+ export function stripIgnoredFindings(findings, content) {
131
+ if (findings.length === 0 || !content.includes("qscan-ignore"))
132
+ return findings;
133
+ const ignored = ignoredLines(content);
134
+ if (ignored.size === 0)
135
+ return findings;
136
+ return findings.filter((f) => !ignored.has(f.location.line));
137
+ }
138
+ /**
139
+ * Drop findings whose match starts inside a comment. No-op when the file's
140
+ * language has no comment style we handle, or when it has no comments.
141
+ */
142
+ export function stripCommentFindings(findings, content, file) {
143
+ if (findings.length === 0)
144
+ return findings;
145
+ const style = commentStyleForFile(file);
146
+ if (!style)
147
+ return findings;
148
+ const spans = commentSpans(content, style);
149
+ if (spans.length === 0)
150
+ return findings;
151
+ // 1-based line → start offset, to turn a finding's (line, column) back into an
152
+ // absolute offset (column is 1-based: offset = lineStart + column - 1).
153
+ const lineStarts = [0];
154
+ for (let i = 0; i < content.length; i++) {
155
+ if (content[i] === "\n")
156
+ lineStarts.push(i + 1);
157
+ }
158
+ return findings.filter((f) => {
159
+ const start = lineStarts[f.location.line - 1] ?? 0;
160
+ const offset = start + ((f.location.column ?? 1) - 1);
161
+ return !offsetInSpans(spans, offset);
162
+ });
163
+ }
164
+ //# sourceMappingURL=comments.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../src/comments.ts"],"names":[],"mappings":"AAoBA,8DAA8D;AAC9D,MAAM,MAAM,GAAsB;IAChC,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,MAAM;IACN,SAAS;IACT,KAAK;IACL,OAAO;IACP,KAAK;IACL,MAAM;IACN,KAAK;IACL,KAAK;IACL,IAAI;IACJ,IAAI;IACJ,KAAK;IACL,MAAM;IACN,MAAM;IACN,MAAM;IACN,KAAK;CACN,CAAC;AAEF,wDAAwD;AACxD,MAAM,SAAS,GAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,CAAC;AAEpE,sFAAsF;AACtF,MAAM,UAAU,mBAAmB,CAAC,IAAY;IAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC;IACtD,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC5D,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,KAAmB;IAC/D,MAAM,KAAK,GAA4B,EAAE,CAAC;IAC1C,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;IACzB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACb,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACrB,uEAAuE;QACvE,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YACxC,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACb,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;oBACxB,CAAC,IAAI,CAAC,CAAC;oBACP,SAAS;gBACX,CAAC;gBACD,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,KAAK,EAAE,CAAC;oBACzB,CAAC,EAAE,CAAC;oBACJ,MAAM;gBACR,CAAC;gBACD,CAAC,EAAE,CAAC;YACN,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YACzD,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,CAAC,IAAI,CAAC,CAAC;YACP,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;gBAAE,CAAC,EAAE,CAAC;YACrE,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;YACvB,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,IAAI,KAAK,KAAK,MAAM,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;YAClC,MAAM,KAAK,GAAG,CAAC,CAAC;YAChB,CAAC,EAAE,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;gBAAE,CAAC,EAAE,CAAC;YACzC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YACvB,SAAS;QACX,CAAC;QACD,CAAC,EAAE,CAAC;IACN,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,KAAsC,EAAE,MAAc;IAClF,IAAI,EAAE,GAAG,CAAC,CAAC;IACX,IAAI,EAAE,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAC1B,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC;QAChB,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC;QAC5B,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,MAAM,GAAG,CAAC;YAAE,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;aACxB,IAAI,MAAM,IAAI,CAAC;YAAE,EAAE,GAAG,GAAG,GAAG,CAAC,CAAC;;YAC9B,OAAO,IAAI,CAAC;IACnB,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,IAAI,CAAC,QAAQ,CAAC,wBAAwB,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;aAC3D,IAAI,IAAI,CAAC,QAAQ,CAAC,mBAAmB,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,QAAmB,EAAE,OAAe;IACvE,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,QAAQ,CAAC;IAChF,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;IACtC,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IACxC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAAmB,EACnB,OAAe,EACf,IAAY;IAEZ,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC3C,MAAM,KAAK,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IACxC,IAAI,CAAC,KAAK;QAAE,OAAO,QAAQ,CAAC;IAC5B,MAAM,KAAK,GAAG,YAAY,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC;IAExC,+EAA+E;IAC/E,wEAAwE;IACxE,MAAM,UAAU,GAAa,CAAC,CAAC,CAAC,CAAC;IACjC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI;YAAE,UAAU,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QAC3B,MAAM,KAAK,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,MAAM,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QACtD,OAAO,CAAC,aAAa,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/config.d.ts CHANGED
@@ -9,7 +9,7 @@ export declare const CONFIG_FILENAME = "quantakrypto.config.json";
9
9
  * `root`, `files`, `detectors` (the programmatic detector array), and `onFile`
10
10
  * are intentionally NOT configurable from a file — they are call-site concerns.
11
11
  */
12
- export interface QuantakryptoFileConfig extends Partial<Pick<ScanOptions, "include" | "exclude" | "noDefaultIgnores" | "maxFileSize" | "scanMinified" | "source" | "dependencies" | "config">> {
12
+ export interface QuantakryptoFileConfig extends Partial<Pick<ScanOptions, "include" | "exclude" | "noDefaultIgnores" | "maxFileSize" | "scanMinified" | "source" | "dependencies" | "config" | "disabledRules">> {
13
13
  /** Gate severity (drives the exit code). Maps to qScan's `severityThreshold`. */
14
14
  severityThreshold?: Severity;
15
15
  /** Path to a baseline file, relative to the config file's directory. */
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExD,4DAA4D;AAC5D,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAgB1D;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,OAAO,CACrD,IAAI,CACF,WAAW,EACT,SAAS,GACT,SAAS,GACT,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,QAAQ,GACR,cAAc,GACd,QAAQ,CACX,CACF;IACC,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+EAA+E;AAC/E,qBAAa,WAAY,SAAQ,KAAK;IACpC,SAAkB,IAAI,iBAAiB;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBACtB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAIjD;AA8JD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAgC3B"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAExD,4DAA4D;AAC5D,eAAO,MAAM,eAAe,6BAA6B,CAAC;AAgB1D;;;;;;;GAOG;AACH,MAAM,WAAW,sBAAuB,SAAQ,OAAO,CACrD,IAAI,CACF,WAAW,EACT,SAAS,GACT,SAAS,GACT,kBAAkB,GAClB,aAAa,GACb,cAAc,GACd,QAAQ,GACR,cAAc,GACd,QAAQ,GACR,eAAe,CAClB,CACF;IACC,iFAAiF;IACjF,iBAAiB,CAAC,EAAE,QAAQ,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,qEAAqE;IACrE,MAAM,EAAE,sBAAsB,CAAC;IAC/B,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,+EAA+E;AAC/E,qBAAa,WAAY,SAAQ,KAAK;IACpC,SAAkB,IAAI,iBAAiB;IACvC,6DAA6D;IAC7D,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAC;gBACtB,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;CAIjD;AAqKD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAChC,OAAO,CAAC,gBAAgB,CAAC,CAgC3B"}