@vyuhlabs/dxkit 2.9.4 → 2.11.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 (177) hide show
  1. package/CHANGELOG.md +236 -0
  2. package/dist/allowlist/annotate.d.ts +71 -0
  3. package/dist/allowlist/annotate.d.ts.map +1 -0
  4. package/dist/allowlist/annotate.js +105 -0
  5. package/dist/allowlist/annotate.js.map +1 -0
  6. package/dist/allowlist/cli.d.ts +29 -23
  7. package/dist/allowlist/cli.d.ts.map +1 -1
  8. package/dist/allowlist/cli.js +141 -70
  9. package/dist/allowlist/cli.js.map +1 -1
  10. package/dist/allowlist/file.d.ts +7 -1
  11. package/dist/allowlist/file.d.ts.map +1 -1
  12. package/dist/allowlist/file.js +7 -1
  13. package/dist/allowlist/file.js.map +1 -1
  14. package/dist/analysis-result.d.ts +10 -0
  15. package/dist/analysis-result.d.ts.map +1 -1
  16. package/dist/analyzers/cache.d.ts +1 -0
  17. package/dist/analyzers/cache.d.ts.map +1 -1
  18. package/dist/analyzers/cache.js +69 -0
  19. package/dist/analyzers/cache.js.map +1 -1
  20. package/dist/analyzers/dashboard/index.d.ts.map +1 -1
  21. package/dist/analyzers/dashboard/index.js +6 -1
  22. package/dist/analyzers/dashboard/index.js.map +1 -1
  23. package/dist/analyzers/health.d.ts.map +1 -1
  24. package/dist/analyzers/health.js +17 -2
  25. package/dist/analyzers/health.js.map +1 -1
  26. package/dist/analyzers/security/actions.d.ts.map +1 -1
  27. package/dist/analyzers/security/actions.js +13 -0
  28. package/dist/analyzers/security/actions.js.map +1 -1
  29. package/dist/analyzers/security/aggregator.d.ts +97 -79
  30. package/dist/analyzers/security/aggregator.d.ts.map +1 -1
  31. package/dist/analyzers/security/aggregator.js +168 -56
  32. package/dist/analyzers/security/aggregator.js.map +1 -1
  33. package/dist/analyzers/security/gather.d.ts +2 -0
  34. package/dist/analyzers/security/gather.d.ts.map +1 -1
  35. package/dist/analyzers/security/gather.js +36 -4
  36. package/dist/analyzers/security/gather.js.map +1 -1
  37. package/dist/analyzers/security/index.d.ts.map +1 -1
  38. package/dist/analyzers/security/index.js +81 -2
  39. package/dist/analyzers/security/index.js.map +1 -1
  40. package/dist/analyzers/security/scanner-drift.d.ts +21 -0
  41. package/dist/analyzers/security/scanner-drift.d.ts.map +1 -0
  42. package/dist/analyzers/security/scanner-drift.js +113 -0
  43. package/dist/analyzers/security/scanner-drift.js.map +1 -0
  44. package/dist/analyzers/security/shallow.d.ts.map +1 -1
  45. package/dist/analyzers/security/shallow.js +24 -2
  46. package/dist/analyzers/security/shallow.js.map +1 -1
  47. package/dist/analyzers/security/types.d.ts +64 -4
  48. package/dist/analyzers/security/types.d.ts.map +1 -1
  49. package/dist/analyzers/tools/fingerprint.d.ts +133 -20
  50. package/dist/analyzers/tools/fingerprint.d.ts.map +1 -1
  51. package/dist/analyzers/tools/fingerprint.js +194 -20
  52. package/dist/analyzers/tools/fingerprint.js.map +1 -1
  53. package/dist/analyzers/tools/gitleaks.d.ts +2 -2
  54. package/dist/analyzers/tools/gitleaks.d.ts.map +1 -1
  55. package/dist/analyzers/tools/gitleaks.js +7 -1
  56. package/dist/analyzers/tools/gitleaks.js.map +1 -1
  57. package/dist/analyzers/tools/graphify.d.ts +11 -0
  58. package/dist/analyzers/tools/graphify.d.ts.map +1 -1
  59. package/dist/analyzers/tools/graphify.js +457 -413
  60. package/dist/analyzers/tools/graphify.js.map +1 -1
  61. package/dist/analyzers/tools/grep-secrets.d.ts.map +1 -1
  62. package/dist/analyzers/tools/grep-secrets.js +31 -12
  63. package/dist/analyzers/tools/grep-secrets.js.map +1 -1
  64. package/dist/analyzers/tools/osv-scanner-fix.d.ts.map +1 -1
  65. package/dist/analyzers/tools/osv-scanner-fix.js +12 -1
  66. package/dist/analyzers/tools/osv-scanner-fix.js.map +1 -1
  67. package/dist/analyzers/tools/salt.d.ts +68 -0
  68. package/dist/analyzers/tools/salt.d.ts.map +1 -0
  69. package/dist/{baseline → analyzers/tools}/salt.js +59 -18
  70. package/dist/analyzers/tools/salt.js.map +1 -0
  71. package/dist/analyzers/tools/semgrep.d.ts +7 -7
  72. package/dist/analyzers/tools/semgrep.d.ts.map +1 -1
  73. package/dist/analyzers/tools/semgrep.js +14 -7
  74. package/dist/analyzers/tools/semgrep.js.map +1 -1
  75. package/dist/analyzers/tools/tool-registry.d.ts.map +1 -1
  76. package/dist/analyzers/tools/tool-registry.js +78 -43
  77. package/dist/analyzers/tools/tool-registry.js.map +1 -1
  78. package/dist/analyzers/tools/walk-source-files.d.ts +10 -0
  79. package/dist/analyzers/tools/walk-source-files.d.ts.map +1 -1
  80. package/dist/analyzers/tools/walk-source-files.js +14 -0
  81. package/dist/analyzers/tools/walk-source-files.js.map +1 -1
  82. package/dist/analyzers/types.d.ts +9 -0
  83. package/dist/analyzers/types.d.ts.map +1 -1
  84. package/dist/baseline/baseline-file.d.ts +9 -2
  85. package/dist/baseline/baseline-file.d.ts.map +1 -1
  86. package/dist/baseline/baseline-file.js.map +1 -1
  87. package/dist/baseline/check-renderers.d.ts.map +1 -1
  88. package/dist/baseline/check-renderers.js +14 -0
  89. package/dist/baseline/check-renderers.js.map +1 -1
  90. package/dist/baseline/check.d.ts +33 -0
  91. package/dist/baseline/check.d.ts.map +1 -1
  92. package/dist/baseline/check.js +78 -2
  93. package/dist/baseline/check.js.map +1 -1
  94. package/dist/baseline/create.d.ts +1 -1
  95. package/dist/baseline/create.d.ts.map +1 -1
  96. package/dist/baseline/create.js +3 -1
  97. package/dist/baseline/create.js.map +1 -1
  98. package/dist/baseline/entry-to-located.d.ts +12 -5
  99. package/dist/baseline/entry-to-located.d.ts.map +1 -1
  100. package/dist/baseline/entry-to-located.js +21 -7
  101. package/dist/baseline/entry-to-located.js.map +1 -1
  102. package/dist/baseline/finding-identity.d.ts +20 -13
  103. package/dist/baseline/finding-identity.d.ts.map +1 -1
  104. package/dist/baseline/finding-identity.js +51 -20
  105. package/dist/baseline/finding-identity.js.map +1 -1
  106. package/dist/baseline/git-aware-match.d.ts +7 -5
  107. package/dist/baseline/git-aware-match.d.ts.map +1 -1
  108. package/dist/baseline/git-aware-match.js +78 -5
  109. package/dist/baseline/git-aware-match.js.map +1 -1
  110. package/dist/baseline/migrate.d.ts +94 -0
  111. package/dist/baseline/migrate.d.ts.map +1 -0
  112. package/dist/baseline/migrate.js +238 -0
  113. package/dist/baseline/migrate.js.map +1 -0
  114. package/dist/baseline/producers/security.d.ts +9 -9
  115. package/dist/baseline/producers/security.d.ts.map +1 -1
  116. package/dist/baseline/producers/security.js +16 -4
  117. package/dist/baseline/producers/security.js.map +1 -1
  118. package/dist/baseline/types.d.ts +145 -95
  119. package/dist/baseline/types.d.ts.map +1 -1
  120. package/dist/baseline/types.js +30 -26
  121. package/dist/baseline/types.js.map +1 -1
  122. package/dist/explore/context-hook.d.ts +49 -29
  123. package/dist/explore/context-hook.d.ts.map +1 -1
  124. package/dist/explore/context-hook.js +304 -29
  125. package/dist/explore/context-hook.js.map +1 -1
  126. package/dist/explore/finding-context.d.ts +17 -0
  127. package/dist/explore/finding-context.d.ts.map +1 -1
  128. package/dist/explore/finding-context.js +34 -0
  129. package/dist/explore/finding-context.js.map +1 -1
  130. package/dist/explore/queries.d.ts +32 -15
  131. package/dist/explore/queries.d.ts.map +1 -1
  132. package/dist/explore/queries.js +36 -6
  133. package/dist/explore/queries.js.map +1 -1
  134. package/dist/generator.d.ts.map +1 -1
  135. package/dist/generator.js +13 -7
  136. package/dist/generator.js.map +1 -1
  137. package/dist/ingest/normalize.d.ts +1 -1
  138. package/dist/ingest/normalize.d.ts.map +1 -1
  139. package/dist/ingest/normalize.js +5 -1
  140. package/dist/ingest/normalize.js.map +1 -1
  141. package/dist/ingest/sarif.d.ts.map +1 -1
  142. package/dist/ingest/sarif.js +16 -7
  143. package/dist/ingest/sarif.js.map +1 -1
  144. package/dist/ingest/snyk-policy.d.ts +22 -1
  145. package/dist/ingest/snyk-policy.d.ts.map +1 -1
  146. package/dist/ingest/snyk-policy.js +75 -18
  147. package/dist/ingest/snyk-policy.js.map +1 -1
  148. package/dist/ingest/types.d.ts +23 -12
  149. package/dist/ingest/types.d.ts.map +1 -1
  150. package/dist/languages/capabilities/types.d.ts +64 -53
  151. package/dist/languages/capabilities/types.d.ts.map +1 -1
  152. package/dist/languages/capabilities/types.js +4 -4
  153. package/dist/languages/index.d.ts +28 -5
  154. package/dist/languages/index.d.ts.map +1 -1
  155. package/dist/languages/index.js +38 -7
  156. package/dist/languages/index.js.map +1 -1
  157. package/dist/languages/typescript.d.ts.map +1 -1
  158. package/dist/languages/typescript.js +19 -0
  159. package/dist/languages/typescript.js.map +1 -1
  160. package/dist/scoring/dimensions/security.d.ts +17 -0
  161. package/dist/scoring/dimensions/security.d.ts.map +1 -1
  162. package/dist/scoring/dimensions/security.js +12 -0
  163. package/dist/scoring/dimensions/security.js.map +1 -1
  164. package/dist/update.d.ts.map +1 -1
  165. package/dist/update.js +49 -0
  166. package/dist/update.js.map +1 -1
  167. package/dist/upgrade.d.ts.map +1 -1
  168. package/dist/upgrade.js +2 -1
  169. package/dist/upgrade.js.map +1 -1
  170. package/package.json +6 -3
  171. package/templates/.claude/skills/dxkit-action/SKILL.md +11 -2
  172. package/templates/.claude/skills/dxkit-allowlist/SKILL.md +9 -0
  173. package/templates/.claude/skills/dxkit-onboard/SKILL.md +2 -2
  174. package/templates/.claude/skills/dxkit-update/SKILL.md +45 -4
  175. package/dist/baseline/salt.d.ts +0 -45
  176. package/dist/baseline/salt.d.ts.map +0 -1
  177. package/dist/baseline/salt.js.map +0 -1
@@ -7,19 +7,27 @@
7
7
  *
8
8
  * Two fingerprint families live here:
9
9
  *
10
- * 1. Dependency-advisory fingerprints — stable hash of
11
- * `(package, installedVersion, id)`. Used by `gatherDepVulns` +
12
- * BoM. Excludes severity / cvssScore / enrichment fields
13
- * (epssScore, kev, reachable, riskScore), producer `tool`, and
14
- * `upgradeAdvice` / `upgradePlan` so re-scoring the same advisory
15
- * against the same install never mints a new identity.
10
+ * 1. Dependency-advisory fingerprints — stable hash of
11
+ * `(package, canonicalAdvisoryId)`. Used by `gatherDepVulns` +
12
+ * BoM. Excludes severity / cvssScore / enrichment fields
13
+ * (epssScore, kev, reachable, riskScore), producer `tool`, and
14
+ * `upgradeAdvice` / `upgradePlan` so re-scoring the same advisory
15
+ * against the same install never mints a new identity. Crucially
16
+ * it also excludes `installedVersion`: that value is only known
17
+ * when the dependency tree is installed (npm-audit reads
18
+ * node_modules), so a lockfile-only scanner (osv-scanner, or any
19
+ * gather in a bare git worktree) omits it — and including it forked
20
+ * the SAME advisory into two identities depending on the scan
21
+ * environment. The version is display metadata, not identity:
22
+ * bumping to a still-vulnerable version is the same finding, and
23
+ * bumping to a fixed version makes the finding disappear on its own.
16
24
  *
17
- * 2. Code/secret/config-finding fingerprints — stable hash of
18
- * `(canonicalRule, file, lineWindow)`. The canonical-rule map
19
- * collapses cross-tool overlaps (e.g. semgrep + a per-language
20
- * grep-based pattern both reporting the same TLS-bypass
21
- * construct). The line-window absorbs the small offset between
22
- * tools that report the declaration vs. the assignment.
25
+ * 2. Code/secret/config-finding fingerprints — stable hash of
26
+ * `(canonicalRule, file, lineWindow)`. The canonical-rule map
27
+ * collapses cross-tool overlaps (e.g. semgrep + a per-language
28
+ * grep-based pattern both reporting the same TLS-bypass
29
+ * construct). The line-window absorbs the small offset between
30
+ * tools that report the declaration vs. the assignment.
23
31
  *
24
32
  * Both families share format: 16-char lowercase hex (first 8 bytes of
25
33
  * SHA-1). Short enough to embed inline in reports, long enough to make
@@ -27,26 +35,70 @@
27
35
  * repo scale. Producers may render either inline interchangeably.
28
36
  */
29
37
  Object.defineProperty(exports, "__esModule", { value: true });
30
- exports.CODE_FINGERPRINT_LINE_WINDOW = exports.CANONICAL_RULE_MAP = void 0;
38
+ exports.SECRET_CANONICAL_RULE = exports.CODE_FINGERPRINT_LINE_WINDOW = exports.CANONICAL_RULE_MAP = void 0;
39
+ exports.canonicalAdvisoryId = canonicalAdvisoryId;
31
40
  exports.computeFingerprint = computeFingerprint;
41
+ exports.computeFingerprintV1 = computeFingerprintV1;
32
42
  exports.stampFingerprints = stampFingerprints;
33
43
  exports.collectFingerprints = collectFingerprints;
34
44
  exports.canonicalRuleFor = canonicalRuleFor;
35
45
  exports.lineWindowFor = lineWindowFor;
36
46
  exports.computeCodeFingerprint = computeCodeFingerprint;
47
+ exports.normalizeSpan = normalizeSpan;
48
+ exports.spanHash = spanHash;
49
+ exports.codeContentAnchor = codeContentAnchor;
50
+ exports.codeContentAnchorFromHash = codeContentAnchorFromHash;
51
+ exports.secretContentAnchor = secretContentAnchor;
52
+ exports.computeContentFingerprint = computeContentFingerprint;
37
53
  exports.computeSecretHmac = computeSecretHmac;
38
54
  const crypto_1 = require("crypto");
39
55
  /**
40
- * Stable 16-char hex fingerprint for one DepVulnFinding. Input tuple
41
- * is NUL-separated (not present in any legal package / version / id)
42
- * so distinct tuples can never collide via concatenation tricks.
56
+ * Canonical advisory id for dep-vuln identity. Scanners label the same
57
+ * advisory differently npm-audit emits an uppercase `GHSA-…`, while
58
+ * osv-scanner may primary an `OSV-…` / `CVE-…` / `GHSA-…` id and carry
59
+ * the rest in `aliases`. Collapse them to one token so the SAME
60
+ * vulnerability fingerprints identically regardless of which tool found
61
+ * it: prefer GHSA (the namespace every supported scanner shares), then
62
+ * CVE (the next-best cross-tool token), else the producer's own id.
63
+ * Lowercased so `GHSA-AB` and `ghsa-ab` don't fork identity.
64
+ */
65
+ function canonicalAdvisoryId(finding) {
66
+ const candidates = [finding.id, ...(finding.aliases ?? [])]
67
+ .filter((x) => typeof x === 'string' && x.trim().length > 0)
68
+ .map((x) => x.trim());
69
+ const ghsa = candidates.find((c) => /^GHSA-/i.test(c));
70
+ if (ghsa)
71
+ return ghsa.toLowerCase();
72
+ const cve = candidates.find((c) => /^CVE-/i.test(c));
73
+ if (cve)
74
+ return cve.toLowerCase();
75
+ return finding.id.toLowerCase();
76
+ }
77
+ /**
78
+ * Stable 16-char hex fingerprint for one DepVulnFinding. Input tuple is
79
+ * NUL-separated (not present in any legal package name / advisory id) so
80
+ * distinct tuples can never collide via concatenation tricks.
43
81
  *
44
- * `installedVersion` is normalized to the empty string when absent so
45
- * version-less findings (rare some providers omit it when the lock
46
- * file is missing) still get a deterministic fingerprint instead of
47
- * mixing an ambient `undefined` into the hash input.
82
+ * Identity is `(package, canonicalAdvisoryId)` deliberately NOT the
83
+ * installed version (see the module header): the version is unavailable
84
+ * to lockfile-only scanners, so including it forked identity by scan
85
+ * environment.
48
86
  */
49
87
  function computeFingerprint(finding) {
88
+ const input = `${finding.package}\0${canonicalAdvisoryId(finding)}`;
89
+ return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
90
+ }
91
+ /**
92
+ * Pre-2.11 dependency-advisory fingerprint: `(package, installedVersion,
93
+ * id)`. Superseded by `computeFingerprint` (which drops the
94
+ * environment-dependent installed version and canonicalizes the advisory
95
+ * id), but retained verbatim so the identity-scheme migrator can
96
+ * recompute a finding's PRIOR-scheme id and remap allowlist entries onto
97
+ * the current scheme. Never delete a shipped scheme's id function — a
98
+ * migration from it must always be able to reproduce its output
99
+ * byte-for-byte. Not used to mint new identities.
100
+ */
101
+ function computeFingerprintV1(finding) {
50
102
  const input = `${finding.package}\0${finding.installedVersion ?? ''}\0${finding.id}`;
51
103
  return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
52
104
  }
@@ -148,6 +200,128 @@ function computeCodeFingerprint(canonicalRule, file, line) {
148
200
  const input = `${canonicalRule}\0${file}\0${lineWindowFor(line)}`;
149
201
  return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
150
202
  }
203
+ // ─── Content-anchored finding identity (scheme v2) ─────────────────────
204
+ // The line-based fingerprint above re-mints identity whenever a finding
205
+ // shifts more than CODE_FINGERPRINT_LINE_WINDOW lines, which strands
206
+ // allowlist entries + churns baselines on unrelated edits. The
207
+ // content-anchored scheme replaces the line component with an anchor
208
+ // derived from WHAT the finding is, not WHERE it sits:
209
+ //
210
+ // secret → secretContentAnchor(ordinal): (canonicalRule, file) plus an
211
+ // ordinal among same-(canonicalRule, file) secrets. Deliberately free of
212
+ // the captured value AND the salt, so a secret's identity is identical no
213
+ // matter which scanner found it (gitleaks and the grep fallback capture
214
+ // different text) or how the salt resolves (env var / file / root-SHA
215
+ // differ across environments). The value HMAC lives on only in the
216
+ // separate `secret-hmac` kind, which recognizes the same value relocating
217
+ // across files — a different question from per-occurrence identity.
218
+ // code → codeContentAnchor(scope, span, ordinal): the normalized
219
+ // matched span, scoped to its enclosing symbol when the graph
220
+ // resolves one (else file-level), with an ordinal to keep
221
+ // identical constructs in one scope distinct.
222
+ // config → '' — identity is just (canonicalRule, file); inherently
223
+ // line-independent (a file is tracked / on disk or it isn't).
224
+ //
225
+ // `line` becomes display metadata only. The dispatch (`identityFor`) and
226
+ // the security aggregator prefer this anchor when one is available and
227
+ // fall back to the line-window hash otherwise.
228
+ //
229
+ // Known limitation (code only): the code anchor's `spanHash` is the hash
230
+ // of the tool-captured matched span, which differs between engines
231
+ // (semgrep `extra.lines` vs an ingested SARIF `region.snippet.text` vs a
232
+ // grep capture). When the SAME construct is found by different engines
233
+ // across two environments — and the cross-tool dedup doesn't merge them
234
+ // because only one environment ran the second engine — the code finding's
235
+ // identity can drift across those environments. It does not affect
236
+ // secrets (their anchor carries no tool-captured content) and only
237
+ // surfaces under inconsistent multi-engine ingestion, never on the
238
+ // bundled-semgrep default path. A future release should anchor code
239
+ // identity to a content representation that is stable across engines.
240
+ /**
241
+ * Normalize a matched code span so cosmetic reformatting (reindentation,
242
+ * collapsed vs expanded whitespace, trailing space) doesn't re-mint
243
+ * identity. Runs of whitespace collapse to a single space; ends trimmed.
244
+ * Deliberately conservative — it does NOT strip comments or rename
245
+ * identifiers, so a real change to the construct still re-mints.
246
+ */
247
+ function normalizeSpan(span) {
248
+ return span.replace(/\s+/g, ' ').trim();
249
+ }
250
+ /** 16-char hex hash of a normalized matched span. */
251
+ function spanHash(span) {
252
+ return (0, crypto_1.createHash)('sha1').update(normalizeSpan(span)).digest('hex').slice(0, 16);
253
+ }
254
+ /**
255
+ * Build the content anchor for a CODE finding: `scope\0spanHash\0ordinal`.
256
+ * `scope` is the enclosing symbol (graph-resolved) or '' (file-level
257
+ * fallback). `ordinal` is the index among findings sharing the same
258
+ * `(scope, spanHash)` in document order, so identical constructs in one
259
+ * scope stay distinct. NUL-separated so the parts can't collide via
260
+ * concatenation.
261
+ */
262
+ function codeContentAnchor(scope, span, ordinal) {
263
+ return codeContentAnchorFromHash(scope, spanHash(span), ordinal);
264
+ }
265
+ /**
266
+ * Build a code content anchor from an ALREADY-HASHED span. The gather
267
+ * boundary hashes the matched span once (`spanHash`) and carries only
268
+ * that 16-char digest downstream — never the raw source text — so the
269
+ * matched code never bloats reports or rides through the dashboard /
270
+ * JSON surfaces. The aggregator, which knows the enclosing `scope` (from
271
+ * the graph scope pre-pass) and the in-scope `ordinal`, assembles the
272
+ * final anchor from that carried digest via this helper. Equivalent to
273
+ * `codeContentAnchor` when fed `spanHash(span)`.
274
+ */
275
+ function codeContentAnchorFromHash(scope, spanHashHex, ordinal) {
276
+ return `${scope}\0${spanHashHex}\0${ordinal}`;
277
+ }
278
+ /**
279
+ * Build the content anchor for a SECRET finding: `secret\0<ordinal>`.
280
+ * The `(canonicalRule, file)` half of identity already lives in
281
+ * `computeContentFingerprint`, so the anchor only has to disambiguate
282
+ * multiple secrets of the same rule in the same file — the ordinal does
283
+ * that, assigned in document order by the aggregator.
284
+ *
285
+ * Crucially it carries NEITHER the captured value NOR the salt. That
286
+ * makes a secret's per-occurrence identity byte-identical across scanners
287
+ * (gitleaks' `Secret` field and the grep fallback's capture group differ)
288
+ * and across environments (the salt resolves differently via env var /
289
+ * file / root-SHA), which is what a baseline/allowlist needs to stay
290
+ * matched between a developer's machine and CI. The `secret` prefix
291
+ * namespaces it away from code anchors (`scope\0spanHash\0ordinal`) so the
292
+ * two schemes can never collide.
293
+ *
294
+ * The value HMAC is not lost — the separate `secret-hmac` identity kind
295
+ * still pins it, for recognizing the same value relocating across files.
296
+ */
297
+ function secretContentAnchor(ordinal) {
298
+ return `secret\0${ordinal}`;
299
+ }
300
+ /**
301
+ * The tool-independent rule discriminator for SECRET identity. Unlike code
302
+ * findings — where two different rules firing on one construct are two
303
+ * distinct findings, so the rule must stay in identity — every secret
304
+ * detection means the same thing ("a hardcoded/leaked credential", CWE-798).
305
+ * Folding them onto one constant makes a secret's identity independent of
306
+ * WHICH scanner found it and under what rule name (gitleaks `aws-access-key`
307
+ * vs the grep fallback's `hardcoded-password` describe the same leak). Used
308
+ * in place of `canonicalRuleFor(tool, rule)` when fingerprinting secrets;
309
+ * the per-tool canonical rule is still used for intra-run dedup grouping and
310
+ * survives on the finding as display metadata.
311
+ */
312
+ exports.SECRET_CANONICAL_RULE = 'canonical:secret';
313
+ /**
314
+ * Content-anchored finding fingerprint (scheme v2). Identity is
315
+ * `(canonicalRule, file, contentAnchor)` — the anchor carries the
316
+ * stable, location-independent content (built by the caller per kind:
317
+ * secret=HMAC, code=`codeContentAnchor(...)`, config=''). A finding that
318
+ * moves to a new line keeps its fingerprint; it re-mints only when the
319
+ * matched content (or, for code, its enclosing symbol) changes.
320
+ */
321
+ function computeContentFingerprint(canonicalRule, file, contentAnchor) {
322
+ const input = `${canonicalRule}\0${file}\0${contentAnchor}`;
323
+ return (0, crypto_1.createHash)('sha1').update(input).digest('hex').slice(0, 16);
324
+ }
151
325
  // ─── Secret HMAC primitive ───────────────────────────────────────────────────
152
326
  /**
153
327
  * HMAC-SHA256 of a detected secret value, keyed by a per-repo salt.
@@ -1 +1 @@
1
- {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fingerprint.js","sourceRoot":"","sources":["../../../src/analyzers/tools/fingerprint.ts"],"names":[],"mappings":"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"}
@@ -17,8 +17,8 @@ export interface GitleaksRawSecret {
17
17
  readonly line: number;
18
18
  readonly rule: string;
19
19
  /** The matched secret value as reported by gitleaks. Process-only;
20
- * callers MUST NOT write this to disk, log it, or include it in
21
- * any output payload. */
20
+ * callers MUST NOT write this to disk, log it, or include it in
21
+ * any output payload. */
22
22
  readonly secret: string;
23
23
  }
24
24
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAUvF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;8BAE0B;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CAC9C,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgB5C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAMtE;AAiHD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,aAAa,CAM9D,CAAC"}
1
+ {"version":3,"file":"gitleaks.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAiB,aAAa,EAAE,MAAM,oCAAoC,CAAC;AAUvF;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;6BAEyB;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAC5B;IACE,IAAI,EAAE,SAAS,CAAC;IAChB,QAAQ,EAAE,aAAa,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,UAAU,EAAE,aAAa,CAAC,iBAAiB,CAAC,CAAC;CAC9C,GACD;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAgB5C;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,oBAAoB,CAMtE;AAuHD;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,aAAa,CAM9D,CAAC"}
@@ -160,10 +160,16 @@ function computeGitleaksOutcome(cwd) {
160
160
  // Apply `.dxkit-suppressions.json` so known-false positives don't count.
161
161
  const suppressions = (0, suppressions_1.loadSuppressions)(cwd);
162
162
  const { kept, suppressed } = (0, suppressions_1.applySuppressions)(filteredCombined, suppressions.gitleaks, (c) => c.finding.rule, (c) => c.finding.file);
163
+ // Per-occurrence secret identity is (canonicalRule, file, ordinal),
164
+ // assembled in the aggregator — value- and salt-free, so it stays stable
165
+ // across scanners and environments. The envelope therefore carries no
166
+ // content anchor. (The raw value still flows out via `rawSecrets` below,
167
+ // where the `secret-hmac` producer HMACs it for cross-file relocation
168
+ // matching — a separate identity kind.)
163
169
  const envelope = {
164
170
  schemaVersion: 1,
165
171
  tool: 'gitleaks',
166
- findings: kept.map((c) => c.finding),
172
+ findings: kept.map((c) => ({ ...c.finding })),
167
173
  suppressedCount: suppressed.length,
168
174
  };
169
175
  const rawSecrets = kept.map((c) => ({
@@ -1 +1 @@
1
- {"version":3,"file":"gitleaks.js","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gitleaks.js","sourceRoot":"","sources":["../../../src/analyzers/tools/gitleaks.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwFA,oDAMC;AA9FD;;;;;;;;;GASG;AACH,uCAAyB;AACzB,uCAAyB;AACzB,2CAA6B;AAC7B,qCAAuC;AACvC,mDAAsD;AACtD,6CAA8C;AAC9C,mCAA4C;AAC5C,iDAAqE;AAmDrE;;;;;;;;;;;GAWG;AACH,MAAM,oBAAoB,GAAG,IAAI,GAAG,EAAgC,CAAC;AAErE;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,GAAW;IAC9C,MAAM,MAAM,GAAG,oBAAoB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7C,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC;IAC1B,MAAM,OAAO,GAAG,sBAAsB,CAAC,GAAG,CAAC,CAAC;IAC5C,oBAAoB,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAS,sBAAsB,CAAC,GAAW;IACzC,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACtC,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,eAAe,EAAE,CAAC;IAE1E,yEAAyE;IACzE,iEAAiE;IACjE,oEAAoE;IACpE,kEAAkE;IAClE,6DAA6D;IAC7D,oEAAoE;IACpE,cAAc;IACd,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,kBAAkB,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC/E,IAAA,oBAAW,EACT,WAAW,EACX;QACE,QAAQ;QACR,UAAU;QACV,GAAG;QACH,iBAAiB;QACjB,MAAM;QACN,eAAe;QACf,UAAU;QACV,UAAU;QACV,aAAa;QACb,GAAG;KACJ,EACD,GAAG,EACH,MAAM,CACP,CAAC;IACF,6DAA6D;IAC7D,6DAA6D;IAC7D,kEAAkE;IAClE,kEAAkE;IAClE,0DAA0D;IAC1D,6DAA6D;IAC7D,YAAY;IACZ,IAAI,SAAiB,CAAC;IACtB,IAAI,CAAC;QACH,SAAS,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAAC,MAAM,CAAC;QACP,SAAS,GAAG,EAAE,CAAC;IACjB,CAAC;IACD,mEAAmE;IACnE,IAAI,CAAC;QACH,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,+CAA+C;IACjD,CAAC;IAED,IAAI,CAAC,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAEpE,IAAI,MAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAsB,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,wEAAwE;QACxE,MAAM,QAAQ,GAAkB;YAC9B,aAAa,EAAE,CAAC;YAChB,IAAI,EAAE,UAAU;YAChB,QAAQ,EAAE,EAAE;YACZ,eAAe,EAAE,CAAC;SACnB,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,CAAC,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;IAC3E,CAAC;IAMD,MAAM,QAAQ,GAAe,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC9C,OAAO,EAAE;YACP,IAAI,EAAE,IAAA,yBAAiB,EAAC,GAAG,EAAE,CAAC,CAAC,IAAI,CAAC;YACpC,IAAI,EAAE,CAAC,CAAC,SAAS;YACjB,IAAI,EAAE,CAAC,CAAC,MAAM;YACd,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,MAAM;YAChE,KAAK,EAAE,CAAC,CAAC,WAAW;SACrB;QACD,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;IAEJ,sEAAsE;IACtE,+DAA+D;IAC/D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAA,2BAAc,EAAC,GAAG,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IAEtF,yEAAyE;IACzE,MAAM,YAAY,GAAG,IAAA,+BAAgB,EAAC,GAAG,CAAC,CAAC;IAC3C,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,IAAA,gCAAiB,EAC5C,gBAAgB,EAChB,YAAY,CAAC,QAAQ,EACrB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EACrB,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CACtB,CAAC;IAEF,oEAAoE;IACpE,yEAAyE;IACzE,sEAAsE;IACtE,yEAAyE;IACzE,sEAAsE;IACtE,wCAAwC;IACxC,MAAM,QAAQ,GAAkB;QAC9B,aAAa,EAAE,CAAC;QAChB,IAAI,EAAE,UAAU;QAChB,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,eAAe,EAAE,UAAU,CAAC,MAAM;KACnC,CAAC;IACF,MAAM,UAAU,GAAwB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACvD,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;QACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;QACpB,IAAI,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI;QACpB,MAAM,EAAE,CAAC,CAAC,MAAM;KACjB,CAAC,CAAC,CAAC;IACJ,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,eAAe,EAAE,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,CAAC;AACvF,CAAC;AAED;;;;GAIG;AACU,QAAA,gBAAgB,GAAsC;IACjE,MAAM,EAAE,UAAU;IAClB,KAAK,CAAC,MAAM,CAAC,GAAG;QACd,MAAM,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;QAC1C,OAAO,OAAO,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;IAC9D,CAAC;CACF,CAAC;AAEF,SAAS,YAAY,CAAC,GAAW;IAC/B,MAAM,MAAM,GAAG,IAAA,wBAAQ,EAAC,yBAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACjD,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC"}
@@ -15,6 +15,17 @@ interface GraphifyResult {
15
15
  sourceFilesInGraph: number;
16
16
  graph?: GraphJson;
17
17
  }
18
+ /**
19
+ * Build the graphify Python script with cwd-specific exclusions baked in.
20
+ *
21
+ * Exported so the structural contract of the generated script — the
22
+ * `if __name__ == '__main__'` guard that keeps ProcessPoolExecutor workers
23
+ * from re-running extraction under spawn/forkserver (Python 3.14's Linux
24
+ * default), and the public `extract(cache_root=...)` cache redirect that
25
+ * replaced the fragile `cache_dir` monkeypatch — is unit-testable without a
26
+ * Python interpreter or graphify installed (mirrors `buildGraphifyEnvelope`).
27
+ */
28
+ export declare function buildGraphifyScript(cwd: string): string;
18
29
  /**
19
30
  * Outcome union mirrors the other global wrappers (gitleaks, semgrep,
20
31
  * jscpd). The capability provider collapses this to `StructuralResult
@@ -1 +1 @@
1
- {"version":3,"file":"graphify.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"AAwBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAExE,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AA0mBD;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAwB5C;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAKxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAQ7B;AA2KD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAiBzF;AAED;;;;GAIG;AAOH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,GAAG;IACpE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAU9D,CAAC"}
1
+ {"version":3,"file":"graphify.d.ts","sourceRoot":"","sources":["../../../src/analyzers/tools/graphify.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAExE,UAAU,cAAc;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CA6nBvD;AAED;;;;;;;GAOG;AACH,MAAM,MAAM,uBAAuB,GAC/B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,gBAAgB,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAC1B;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,SAAS,CAAA;CAAE,GACrC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAwB5C;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAKxF;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,IAAI,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACnC,OAAO,CAAC,kBAAkB,CAAC,CAQ7B;AAoLD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,MAAM,GAAG,gBAAgB,CAiBzF;AAED;;;;GAIG;AAOH,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,gBAAgB,CAAC,GAAG;IACpE,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAAC;CAU9D,CAAC"}