project-athena 0.4.0 → 0.5.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 (51) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +10 -0
  3. package/dist/{activity-BKW7G4I5.js → activity-XCHKBZTG.js} +4 -4
  4. package/dist/{agents-DFSNEOP5.js → agents-HUJ4JXIB.js} +4 -4
  5. package/dist/{ai-ASL4FFQ7.js → ai-LGTLQKL4.js} +3 -3
  6. package/dist/{analyze-ZY3MXBOI.js → analyze-AP4XJT7D.js} +7 -7
  7. package/dist/{chunk-ZB7LC6FP.js → chunk-3KFOI2X4.js} +2 -2
  8. package/dist/{chunk-MPG3IEGB.js → chunk-44EGCEB2.js} +23 -14
  9. package/dist/{chunk-GGXPG6OE.js → chunk-4FETKOY3.js} +8 -7
  10. package/dist/chunk-4IIBVTBS.js +76 -0
  11. package/dist/{chunk-LEMPCNAY.js → chunk-56EXAGTM.js} +3 -3
  12. package/dist/{chunk-DZDI2HRT.js → chunk-6OSQMXUP.js} +5 -5
  13. package/dist/{chunk-OLPSEQS5.js → chunk-AKOI4VTD.js} +10 -1
  14. package/dist/{chunk-FVCDMQUQ.js → chunk-C25FDXOO.js} +133 -23
  15. package/dist/{chunk-7DZK6WSQ.js → chunk-DH5AGULY.js} +2 -2
  16. package/dist/{chunk-TDNZ2RYA.js → chunk-F65QINMR.js} +2 -2
  17. package/dist/{chunk-WVQC2EGO.js → chunk-GU3ZX2J7.js} +2 -2
  18. package/dist/{chunk-UAZLPNVC.js → chunk-GYQG4Q2N.js} +4 -4
  19. package/dist/chunk-IDODPGTX.js +595 -0
  20. package/dist/chunk-KJYSNZXS.js +934 -0
  21. package/dist/{chunk-3XSDI5WF.js → chunk-L2EHJCH4.js} +5 -5
  22. package/dist/{chunk-65TSRDQ3.js → chunk-P4TRQMES.js} +2 -2
  23. package/dist/{chunk-KHMBNT66.js → chunk-PZPMWCXS.js} +5 -5
  24. package/dist/{chunk-XDCKZ5TV.js → chunk-R5AX7VST.js} +2 -2
  25. package/dist/{chunk-QLW657NT.js → chunk-RQKGT2EK.js} +2 -2
  26. package/dist/{chunk-VSYBC3VY.js → chunk-UMWX4UTK.js} +2 -2
  27. package/dist/{chunk-RXNRMIZP.js → chunk-WUIC65QO.js} +2 -2
  28. package/dist/{chunk-JCGDR4UV.js → chunk-WWQ5NKEC.js} +3 -1
  29. package/dist/{chunk-RVTNSNGK.js → chunk-X7EYOAEX.js} +2 -2
  30. package/dist/chunk-Y6SDMZET.js +278 -0
  31. package/dist/{clean-MDBYH62P.js → clean-LQOG56AM.js} +2 -2
  32. package/dist/cli.js +2 -2
  33. package/dist/{context-PLPCAPCO.js → context-G5YHY3L2.js} +8 -8
  34. package/dist/{doctor-BX677KRE.js → doctor-L34QJ7WR.js} +8 -8
  35. package/dist/{event-TNT6CQZR.js → event-6YW6TGFI.js} +3 -3
  36. package/dist/{git-hook-YZNZGAAP.js → git-hook-Y7Y262F7.js} +2 -2
  37. package/dist/{init-WQCAOJ2R.js → init-427QR5AS.js} +7 -7
  38. package/dist/{mcp-U7EPH43L.js → mcp-DWNWRGJW.js} +51 -14
  39. package/dist/{memory-VSVNLEJC.js → memory-XBZCYQLW.js} +3 -3
  40. package/dist/{open-UJZRYF4E.js → open-LJMOB6U2.js} +33 -31
  41. package/dist/{program-CWJNGCTZ.js → program-DCP526LU.js} +46 -32
  42. package/dist/{review-OOKXSYMP.js → review-VEJBPACX.js} +10 -9
  43. package/dist/{rules-4FXJUCXB.js → rules-M4DLLXBL.js} +4 -4
  44. package/dist/scan-JVKCVHPD.js +939 -0
  45. package/dist/{security-LME3XFL3.js → security-JTJN3E7K.js} +13 -11
  46. package/dist/{staged-check-X24C3YRD.js → staged-check-PQSLGQBW.js} +11 -11
  47. package/dist/{status-RR57ZNGI.js → status-PO27BSOZ.js} +4 -4
  48. package/dist/{sync-KFJANRXF.js → sync-GVO2VHPI.js} +10 -10
  49. package/dist/{watch-CY7QHIYN.js → watch-TEHFO47V.js} +10 -10
  50. package/package.json +3 -1
  51. package/dist/chunk-SJ4DQFIJ.js +0 -379
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  committedAiWarning
4
- } from "./chunk-RXNRMIZP.js";
4
+ } from "./chunk-WUIC65QO.js";
5
5
  import {
6
6
  whichExecutable
7
- } from "./chunk-VSYBC3VY.js";
7
+ } from "./chunk-UMWX4UTK.js";
8
8
  import {
9
9
  readRecentEvents
10
- } from "./chunk-65TSRDQ3.js";
10
+ } from "./chunk-P4TRQMES.js";
11
11
  import {
12
12
  listRules,
13
13
  parseRules
@@ -21,7 +21,7 @@ import {
21
21
  import {
22
22
  gitAvailable,
23
23
  isGitRepo
24
- } from "./chunk-OLPSEQS5.js";
24
+ } from "./chunk-AKOI4VTD.js";
25
25
  import {
26
26
  ADAPTERS
27
27
  } from "./chunk-YRIS7ZS6.js";
@@ -176,4 +176,4 @@ export {
176
176
  findRunningInstance,
177
177
  runDoctor
178
178
  };
179
- //# sourceMappingURL=chunk-3XSDI5WF.js.map
179
+ //# sourceMappingURL=chunk-L2EHJCH4.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  redact
4
- } from "./chunk-JCGDR4UV.js";
4
+ } from "./chunk-WWQ5NKEC.js";
5
5
  import {
6
6
  toPosix
7
7
  } from "./chunk-XW3MLHI2.js";
@@ -121,4 +121,4 @@ export {
121
121
  readRecentEvents,
122
122
  summarizeSessions
123
123
  };
124
- //# sourceMappingURL=chunk-65TSRDQ3.js.map
124
+ //# sourceMappingURL=chunk-P4TRQMES.js.map
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  projectSession
4
- } from "./chunk-WVQC2EGO.js";
4
+ } from "./chunk-GU3ZX2J7.js";
5
5
  import {
6
6
  impactOf
7
7
  } from "./chunk-GR4DL2VM.js";
@@ -11,13 +11,13 @@ import {
11
11
  indexWithIntegrations,
12
12
  planKnowledge,
13
13
  writePlannedKnowledge
14
- } from "./chunk-GGXPG6OE.js";
14
+ } from "./chunk-4FETKOY3.js";
15
15
  import {
16
16
  analyzeProject
17
- } from "./chunk-MPG3IEGB.js";
17
+ } from "./chunk-44EGCEB2.js";
18
18
  import {
19
19
  headMovement
20
- } from "./chunk-OLPSEQS5.js";
20
+ } from "./chunk-AKOI4VTD.js";
21
21
  import {
22
22
  KNOWLEDGE_DOCS
23
23
  } from "./chunk-FQEGEVLY.js";
@@ -396,4 +396,4 @@ export {
396
396
  HISTORY_SECTIONS,
397
397
  staleForCheck
398
398
  };
399
- //# sourceMappingURL=chunk-KHMBNT66.js.map
399
+ //# sourceMappingURL=chunk-PZPMWCXS.js.map
@@ -33,7 +33,7 @@ import {
33
33
  } from "./chunk-XFN7UZCS.js";
34
34
  import {
35
35
  runPipeline
36
- } from "./chunk-GGXPG6OE.js";
36
+ } from "./chunk-4FETKOY3.js";
37
37
  import {
38
38
  ADAPTERS,
39
39
  resolveAdapters
@@ -433,4 +433,4 @@ export {
433
433
  printSummary,
434
434
  summarize
435
435
  };
436
- //# sourceMappingURL=chunk-XDCKZ5TV.js.map
436
+ //# sourceMappingURL=chunk-R5AX7VST.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  readRecentEvents,
4
4
  summarizeSessions
5
- } from "./chunk-65TSRDQ3.js";
5
+ } from "./chunk-P4TRQMES.js";
6
6
  import {
7
7
  ADAPTERS,
8
8
  applyChanges,
@@ -92,4 +92,4 @@ export {
92
92
  configureAgents,
93
93
  removeAgents
94
94
  };
95
- //# sourceMappingURL=chunk-QLW657NT.js.map
95
+ //# sourceMappingURL=chunk-RQKGT2EK.js.map
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- // src/services/which.ts
3
+ // src/core/util/which.ts
4
4
  import { promises as fs } from "fs";
5
5
  import path from "path";
6
6
  async function whichExecutable(command) {
@@ -25,4 +25,4 @@ async function whichExecutable(command) {
25
25
  export {
26
26
  whichExecutable
27
27
  };
28
- //# sourceMappingURL=chunk-VSYBC3VY.js.map
28
+ //# sourceMappingURL=chunk-UMWX4UTK.js.map
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  redact,
7
7
  scanText
8
- } from "./chunk-JCGDR4UV.js";
8
+ } from "./chunk-WWQ5NKEC.js";
9
9
  import {
10
10
  KNOWLEDGE_DOCS
11
11
  } from "./chunk-FQEGEVLY.js";
@@ -387,4 +387,4 @@ export {
387
387
  buildEnrichPayload,
388
388
  enrich
389
389
  };
390
- //# sourceMappingURL=chunk-RXNRMIZP.js.map
390
+ //# sourceMappingURL=chunk-WUIC65QO.js.map
@@ -174,9 +174,11 @@ function isSecretLikeName(name) {
174
174
  }
175
175
 
176
176
  export {
177
+ MAX_GENERIC_LINE,
178
+ SECRET_PATTERNS,
177
179
  ephemeralFingerprint,
178
180
  scanText,
179
181
  redact,
180
182
  isSecretLikeName
181
183
  };
182
- //# sourceMappingURL=chunk-JCGDR4UV.js.map
184
+ //# sourceMappingURL=chunk-WWQ5NKEC.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  planSnapshot,
4
4
  planSync
5
- } from "./chunk-KHMBNT66.js";
5
+ } from "./chunk-PZPMWCXS.js";
6
6
 
7
7
  // src/services/scheduler.ts
8
8
  var DEFAULT_FULL_WALK_EVERY_MS = 5 * 6e4;
@@ -179,4 +179,4 @@ var AnalysisScheduler = class {
179
179
  export {
180
180
  AnalysisScheduler
181
181
  };
182
- //# sourceMappingURL=chunk-RVTNSNGK.js.map
182
+ //# sourceMappingURL=chunk-X7EYOAEX.js.map
@@ -0,0 +1,278 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ MAX_SECRET_FINDINGS,
4
+ scanFilesForSecrets
5
+ } from "./chunk-44EGCEB2.js";
6
+ import {
7
+ walkProject
8
+ } from "./chunk-ELKFRTZT.js";
9
+ import {
10
+ MAX_GENERIC_LINE,
11
+ SECRET_PATTERNS,
12
+ ephemeralFingerprint
13
+ } from "./chunk-WWQ5NKEC.js";
14
+
15
+ // src/core/findings/finding.ts
16
+ import { z } from "zod";
17
+ var CATEGORIES = ["secret", "dependency", "sast", "iac", "license", "quality", "review", "memory"];
18
+ var SEVERITIES = ["critical", "high", "medium", "low", "info", "unrated"];
19
+ var SEVERITY_RANK = { critical: 5, high: 4, medium: 3, low: 2, info: 1, unrated: 0 };
20
+ var CONFIDENCES = ["high", "medium", "low"];
21
+ var CONFIDENCE_RANK = { high: 3, medium: 2, low: 1 };
22
+ var Location = z.object({
23
+ file: z.string(),
24
+ startLine: z.number().int().positive().optional(),
25
+ startColumn: z.number().int().positive().optional(),
26
+ endLine: z.number().int().positive().optional(),
27
+ endColumn: z.number().int().positive().optional()
28
+ });
29
+ var PackageRef = z.object({
30
+ ecosystem: z.string(),
31
+ name: z.string(),
32
+ version: z.string().optional(),
33
+ /** Manifest or lockfile the package comes from, if known. */
34
+ manifest: z.string().optional(),
35
+ advisoryIds: z.array(z.string()).default([]),
36
+ vulnerableRange: z.string().optional(),
37
+ fixedIn: z.string().optional(),
38
+ fixAvailable: z.boolean().optional()
39
+ });
40
+ var Finding = z.object({
41
+ /** Stable identity (32 hex). Never derived from a secret's value; see fingerprint.ts. */
42
+ fingerprint: z.string().regex(/^[a-f0-9]{32}$/),
43
+ /** e.g. `secret/stripe-key`, `dependency/vulnerable-package`, `review/env-file`, `sast/js/sql-concat`. */
44
+ ruleId: z.string().regex(/^[a-z0-9][a-z0-9._/-]{1,120}$/),
45
+ category: z.enum(CATEGORIES),
46
+ severity: z.enum(SEVERITIES),
47
+ confidence: z.enum(CONFIDENCES),
48
+ label: z.enum(["FACT", "DETECTED", "INFERRED"]),
49
+ /** Heuristic: "worth checking", not a confirmed problem. Rendered as "Potential …". */
50
+ potential: z.boolean().default(false),
51
+ title: z.string(),
52
+ message: z.string(),
53
+ cwe: z.array(z.string().regex(/^CWE-\d+$/)).default([]),
54
+ owasp: z.array(z.string()).default([]),
55
+ location: Location.optional(),
56
+ package: PackageRef.optional(),
57
+ /** Which engine produced it: `athena`, `npm-audit`, `semgrep`, … */
58
+ engine: z.object({ id: z.string(), version: z.string().optional() }),
59
+ /** Other engines that reported the same problem (after de-duplication). */
60
+ alsoReportedBy: z.array(z.string()).default([]),
61
+ help: z.object({ text: z.string(), url: z.string().optional() }).optional()
62
+ });
63
+ var Coverage = z.object({
64
+ engine: z.string(),
65
+ category: z.enum(CATEGORIES),
66
+ /** ok: ran · unavailable: not installed / nothing to scan · skipped: excluded by policy or options · failed/timeout: ran without usable output */
67
+ status: z.enum(["ok", "unavailable", "skipped", "failed", "timeout"]),
68
+ reason: z.string().optional(),
69
+ /** What was scanned when an engine runs per input (e.g. a requirements file). */
70
+ target: z.string().optional(),
71
+ languages: z.array(z.string()).default([]),
72
+ filesScanned: z.number().int().nonnegative().optional(),
73
+ filesSkipped: z.object({
74
+ tooLarge: z.number().int().nonnegative().default(0),
75
+ binary: z.number().int().nonnegative().default(0),
76
+ minified: z.number().int().nonnegative().default(0),
77
+ unreadable: z.number().int().nonnegative().default(0),
78
+ unsupported: z.number().int().nonnegative().default(0)
79
+ }).optional(),
80
+ /** Whether the engine contacted the network (e.g. an audit tool querying an advisory database). */
81
+ network: z.boolean().default(false),
82
+ durationMs: z.number().nonnegative()
83
+ });
84
+ var SCAN_SCOPES = ["all", "base", "staged", "changed"];
85
+ var ScanResult = z.object({
86
+ schemaVersion: z.literal(1),
87
+ scannedAt: z.string(),
88
+ durationMs: z.number().nonnegative(),
89
+ scope: z.object({ mode: z.enum(SCAN_SCOPES), base: z.string().optional(), files: z.number().int().nonnegative().optional() }),
90
+ findings: z.array(Finding),
91
+ coverage: z.array(Coverage)
92
+ });
93
+ function compareFindings(a, b) {
94
+ return SEVERITY_RANK[b.severity] - SEVERITY_RANK[a.severity] || CONFIDENCE_RANK[b.confidence] - CONFIDENCE_RANK[a.confidence] || a.category.localeCompare(b.category) || a.ruleId.localeCompare(b.ruleId) || (a.location?.file ?? "").localeCompare(b.location?.file ?? "") || (a.location?.startLine ?? 0) - (b.location?.startLine ?? 0) || a.fingerprint.localeCompare(b.fingerprint);
95
+ }
96
+ function dedupeFindings(findings) {
97
+ const byFp = /* @__PURE__ */ new Map();
98
+ for (const f of findings) {
99
+ const prev = byFp.get(f.fingerprint);
100
+ if (!prev) {
101
+ byFp.set(f.fingerprint, { ...f, alsoReportedBy: [...f.alsoReportedBy] });
102
+ continue;
103
+ }
104
+ const other = f.engine.id;
105
+ if (other !== prev.engine.id && !prev.alsoReportedBy.includes(other)) prev.alsoReportedBy.push(other);
106
+ if (SEVERITY_RANK[f.severity] > SEVERITY_RANK[prev.severity]) prev.severity = f.severity;
107
+ if (CONFIDENCE_RANK[f.confidence] > CONFIDENCE_RANK[prev.confidence]) prev.confidence = f.confidence;
108
+ }
109
+ return [...byFp.values()].sort(compareFindings);
110
+ }
111
+
112
+ // src/core/scanners/secrets.ts
113
+ import { promises as fs } from "fs";
114
+ import path from "path";
115
+
116
+ // src/core/findings/fingerprint.ts
117
+ import crypto from "crypto";
118
+ var FINGERPRINT_VERSION = 1;
119
+ var hash = (parts) => crypto.createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
120
+ function normalizeLine(text, mask) {
121
+ const masked = mask ? `${text.slice(0, mask[0])}\u27E8v\u27E9${text.slice(mask[1])}` : text;
122
+ return masked.replace(/\s+/g, " ").trim();
123
+ }
124
+ function codeFingerprint(input) {
125
+ return hash(["v1", "code", input.ruleId, input.file, normalizeLine(input.lineText, input.mask), String(input.occurrence ?? 0)]);
126
+ }
127
+ function packageFingerprint(input) {
128
+ return hash(["v1", "package", input.ruleId, input.ecosystem, input.name, input.manifest ?? "", input.advisoryId ?? ""]);
129
+ }
130
+ function fileFingerprint(input) {
131
+ return hash(["v1", "file", input.ruleId, input.file ?? "", input.key ?? ""]);
132
+ }
133
+ function occurrenceCounter() {
134
+ const seen = /* @__PURE__ */ new Map();
135
+ return (ruleId, file, normalized) => {
136
+ const key = `${ruleId}\0${file}\0${normalized}`;
137
+ const n = seen.get(key) ?? 0;
138
+ seen.set(key, n + 1);
139
+ return n;
140
+ };
141
+ }
142
+
143
+ // src/core/scanners/secrets.ts
144
+ var SECRETS_ENGINE = "athena-secrets";
145
+ var CRITICAL = /* @__PURE__ */ new Set(["private-key", "aws-access-key-id", "aws-secret-access-key", "gcp-service-account", "azure-storage-key"]);
146
+ var GENERIC = /* @__PURE__ */ new Set(["generic-secret-assignment", "env-secret-assignment"]);
147
+ var MEDIUM_CONFIDENCE = /* @__PURE__ */ new Set(["jwt", "connection-string-credentials"]);
148
+ var DESCRIPTION = new Map(SECRET_PATTERNS.map((p) => [p.id, p.description]));
149
+ function secretSeverity(type) {
150
+ if (CRITICAL.has(type)) return { severity: "critical", confidence: "high", potential: false };
151
+ if (GENERIC.has(type)) return { severity: "medium", confidence: "low", potential: true };
152
+ return { severity: "high", confidence: MEDIUM_CONFIDENCE.has(type) ? "medium" : "high", potential: false };
153
+ }
154
+ function secretFinding(hit, occurrence = 0, engineId = "athena") {
155
+ const ruleId = `secret/${hit.type}`;
156
+ const { severity, confidence, potential } = secretSeverity(hit.type);
157
+ const description = DESCRIPTION.get(hit.type) ?? hit.type;
158
+ return {
159
+ fingerprint: codeFingerprint({ ruleId, file: hit.file, lineText: hit.lineText, mask: hit.mask, occurrence }),
160
+ ruleId,
161
+ category: "secret",
162
+ severity,
163
+ confidence,
164
+ label: "DETECTED",
165
+ potential,
166
+ title: potential ? `Potential hardcoded secret (${description.toLowerCase()})` : `Hardcoded ${description}`,
167
+ message: `${potential ? "A value that looks like a secret" : `A ${description}`} appears in ${hit.file}:${hit.line}. Athena does not store the value.`,
168
+ cwe: ["CWE-798"],
169
+ owasp: ["A07:2021"],
170
+ location: {
171
+ file: hit.file,
172
+ startLine: hit.line,
173
+ ...hit.column ? { startColumn: hit.column } : {},
174
+ ...hit.endLine ? { endLine: hit.endLine } : {},
175
+ ...hit.endColumn ? { endColumn: hit.endColumn } : {}
176
+ },
177
+ engine: { id: engineId },
178
+ help: {
179
+ text: potential ? "Check whether this is a real credential. If it is, move it to an environment variable or secret manager and rotate it." : "Remove the value, load it from an environment variable or secret manager, and rotate the credential \u2014 assume it is compromised once committed."
180
+ }
181
+ };
182
+ }
183
+ function hitsFromMatches(file, text, matches) {
184
+ const lineStart = (offset) => text.lastIndexOf("\n", offset - 1) + 1;
185
+ return matches.map((m) => {
186
+ const start = lineStart(m.start);
187
+ let end = text.indexOf("\n", m.start);
188
+ if (end < 0) end = text.length;
189
+ let lineText = text.slice(start, end);
190
+ if (lineText.endsWith("\r")) lineText = lineText.slice(0, -1);
191
+ const maskEnd = Math.min(m.end, start + lineText.length) - start;
192
+ const span = text.slice(m.start, m.end);
193
+ const extraLines = (span.match(/\n/g) ?? []).length;
194
+ const lastStart = extraLines ? lineStart(m.end) : start;
195
+ return {
196
+ type: m.type,
197
+ file,
198
+ line: m.line,
199
+ column: m.start - start + 1,
200
+ endLine: m.line + extraLines,
201
+ endColumn: m.end - lastStart + 1,
202
+ lineText,
203
+ mask: [m.start - start, Math.max(maskEnd, m.start - start)]
204
+ };
205
+ });
206
+ }
207
+ function secretFindings(hits, engineId = "athena") {
208
+ const occurrence = occurrenceCounter();
209
+ return hits.map((h) => secretFinding(h, occurrence(`secret/${h.type}`, h.file, normalizeLine(h.lineText, h.mask)), engineId));
210
+ }
211
+ async function scanSecrets(ctx, opts = {}) {
212
+ const started = Date.now();
213
+ let files = opts.walk ?? (await walkProject(ctx.root, { config: ctx.config, signal: ctx.signal })).files;
214
+ if (ctx.files) {
215
+ const scope = new Set(ctx.files);
216
+ files = files.filter((f) => scope.has(f.path));
217
+ }
218
+ const hits = [];
219
+ const read = async (rel) => fs.readFile(path.join(ctx.root, rel), "utf8").catch(() => null);
220
+ const r = await scanFilesForSecrets(files, read, {
221
+ fingerprint: ephemeralFingerprint,
222
+ signal: ctx.signal,
223
+ onFile: (file, text, matches) => hits.push(...hitsFromMatches(file, text, matches))
224
+ });
225
+ const notes = [];
226
+ if (r.truncated) notes.push(`stopped after ${MAX_SECRET_FINDINGS} findings; remaining files were not scanned`);
227
+ if (r.skippedLongLines) notes.push(`generic keyword patterns not applied to ${r.skippedLongLines} line(s) longer than ${MAX_GENERIC_LINE} characters`);
228
+ if (r.files.excluded) notes.push(`${r.files.excluded} lockfile/snapshot/SVG file(s) not scanned`);
229
+ const coverage = {
230
+ engine: SECRETS_ENGINE,
231
+ category: "secret",
232
+ status: "ok",
233
+ ...notes.length ? { reason: notes.join("; ") } : {},
234
+ filesScanned: r.files.scanned,
235
+ filesSkipped: { tooLarge: r.files.tooLarge, binary: r.files.binary, minified: r.files.minified, unreadable: r.files.unreadable, unsupported: r.files.excluded },
236
+ network: false,
237
+ durationMs: Date.now() - started
238
+ };
239
+ return {
240
+ findings: secretFindings(hits),
241
+ coverage: [coverage],
242
+ summary: { count: hits.length, files: [...new Set(hits.map((h) => h.file))], skippedLongLines: r.skippedLongLines, truncated: r.truncated }
243
+ };
244
+ }
245
+ var secretsScanner = {
246
+ id: SECRETS_ENGINE,
247
+ category: "secret",
248
+ title: "Hardcoded secrets",
249
+ async run(ctx) {
250
+ const { findings, coverage } = await scanSecrets(ctx);
251
+ return { findings, coverage };
252
+ }
253
+ };
254
+
255
+ export {
256
+ FINGERPRINT_VERSION,
257
+ normalizeLine,
258
+ codeFingerprint,
259
+ packageFingerprint,
260
+ fileFingerprint,
261
+ occurrenceCounter,
262
+ SECRETS_ENGINE,
263
+ hitsFromMatches,
264
+ secretFindings,
265
+ scanSecrets,
266
+ secretsScanner,
267
+ CATEGORIES,
268
+ SEVERITIES,
269
+ SEVERITY_RANK,
270
+ CONFIDENCES,
271
+ CONFIDENCE_RANK,
272
+ Finding,
273
+ Coverage,
274
+ ScanResult,
275
+ compareFindings,
276
+ dedupeFindings
277
+ };
278
+ //# sourceMappingURL=chunk-Y6SDMZET.js.map
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  cleanCommand,
4
4
  confirm
5
- } from "./chunk-7DZK6WSQ.js";
5
+ } from "./chunk-DH5AGULY.js";
6
6
  import "./chunk-Z6QWMJLK.js";
7
7
  import "./chunk-XFN7UZCS.js";
8
8
  import "./chunk-KBO7XRBW.js";
@@ -20,4 +20,4 @@ export {
20
20
  cleanCommand,
21
21
  confirm
22
22
  };
23
- //# sourceMappingURL=clean-MDBYH62P.js.map
23
+ //# sourceMappingURL=clean-LQOG56AM.js.map
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  // src/cli/index.ts
4
4
  async function runEvent(args) {
5
- const { parseEventArgs, eventCommand } = await import("./event-TNT6CQZR.js");
5
+ const { parseEventArgs, eventCommand } = await import("./event-6YW6TGFI.js");
6
6
  const opts = parseEventArgs(args);
7
7
  if (!opts) return false;
8
8
  let signalled = false;
@@ -21,7 +21,7 @@ function eventFailed(err) {
21
21
  return true;
22
22
  }
23
23
  if (process.argv[2] !== "event" || !await runEvent(process.argv.slice(3)).catch(eventFailed)) {
24
- const { main } = await import("./program-CWJNGCTZ.js");
24
+ const { main } = await import("./program-DCP526LU.js");
25
25
  await main();
26
26
  }
27
27
  //# sourceMappingURL=cli.js.map
@@ -3,10 +3,10 @@ import {
3
3
  getRelevantContext,
4
4
  graphSummary,
5
5
  refreshGraph
6
- } from "./chunk-UAZLPNVC.js";
6
+ } from "./chunk-GYQG4Q2N.js";
7
7
  import {
8
8
  formatContext
9
- } from "./chunk-TDNZ2RYA.js";
9
+ } from "./chunk-F65QINMR.js";
10
10
  import "./chunk-3IS2X2Z7.js";
11
11
  import {
12
12
  bullet,
@@ -24,17 +24,17 @@ import {
24
24
  requireProjectRoot
25
25
  } from "./chunk-XFN7UZCS.js";
26
26
  import "./chunk-KBO7XRBW.js";
27
- import "./chunk-WVQC2EGO.js";
28
- import "./chunk-MPG3IEGB.js";
29
- import "./chunk-ELKFRTZT.js";
27
+ import "./chunk-GU3ZX2J7.js";
28
+ import "./chunk-44EGCEB2.js";
30
29
  import "./chunk-PVCIGUIT.js";
31
- import "./chunk-OLPSEQS5.js";
30
+ import "./chunk-ELKFRTZT.js";
31
+ import "./chunk-AKOI4VTD.js";
32
32
  import {
33
33
  loadGraph,
34
34
  neighbors
35
35
  } from "./chunk-SVTEJYMS.js";
36
36
  import "./chunk-QCC4VJUH.js";
37
- import "./chunk-JCGDR4UV.js";
37
+ import "./chunk-WWQ5NKEC.js";
38
38
  import "./chunk-673EPYYH.js";
39
39
  import "./chunk-FQEGEVLY.js";
40
40
  import "./chunk-2DY4PUR4.js";
@@ -158,4 +158,4 @@ export {
158
158
  contextCommand,
159
159
  graphCommand
160
160
  };
161
- //# sourceMappingURL=context-PLPCAPCO.js.map
161
+ //# sourceMappingURL=context-G5YHY3L2.js.map
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runDoctor
4
- } from "./chunk-3XSDI5WF.js";
5
- import "./chunk-RXNRMIZP.js";
6
- import "./chunk-VSYBC3VY.js";
7
- import "./chunk-65TSRDQ3.js";
4
+ } from "./chunk-L2EHJCH4.js";
5
+ import "./chunk-WUIC65QO.js";
6
+ import "./chunk-UMWX4UTK.js";
7
+ import "./chunk-P4TRQMES.js";
8
8
  import "./chunk-3IS2X2Z7.js";
9
9
  import {
10
10
  c,
@@ -21,8 +21,8 @@ import {
21
21
  import "./chunk-KBO7XRBW.js";
22
22
  import "./chunk-2R6PXY6Z.js";
23
23
  import "./chunk-PVCIGUIT.js";
24
- import "./chunk-OLPSEQS5.js";
25
- import "./chunk-JCGDR4UV.js";
24
+ import "./chunk-AKOI4VTD.js";
25
+ import "./chunk-WWQ5NKEC.js";
26
26
  import "./chunk-YRIS7ZS6.js";
27
27
  import "./chunk-GHFRQAYT.js";
28
28
  import "./chunk-INT3IGMQ.js";
@@ -39,7 +39,7 @@ async function doctorCommand(opts) {
39
39
  const cwd = await resolveCwd(opts);
40
40
  const { checks, root } = await runDoctor(cwd);
41
41
  if (root) {
42
- const m = await (await import("./memory-VSVNLEJC.js")).memorySummary(root);
42
+ const m = await (await import("./memory-XBZCYQLW.js")).memorySummary(root);
43
43
  if (m?.total) {
44
44
  const pending = [m.unreviewed ? `${m.unreviewed} unreviewed` : "", m.stale ? `${m.stale} stale` : ""].filter(Boolean);
45
45
  checks.push({ area: "Memory", level: "info", message: `${m.total} project memory ${m.total === 1 ? "entry" : "entries"}${pending.length ? ` (${pending.join(", ")})` : ""}`, hint: pending.length ? "Review with `athena memory review` and `athena memory stale`." : void 0 });
@@ -66,4 +66,4 @@ async function doctorCommand(opts) {
66
66
  export {
67
67
  doctorCommand
68
68
  };
69
- //# sourceMappingURL=doctor-BX677KRE.js.map
69
+ //# sourceMappingURL=doctor-L34QJ7WR.js.map
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  appendEvent
4
- } from "./chunk-65TSRDQ3.js";
4
+ } from "./chunk-P4TRQMES.js";
5
5
  import {
6
6
  findProjectRoot
7
7
  } from "./chunk-KBO7XRBW.js";
8
- import "./chunk-JCGDR4UV.js";
8
+ import "./chunk-WWQ5NKEC.js";
9
9
  import {
10
10
  normalizeHookEvent
11
11
  } from "./chunk-INT3IGMQ.js";
@@ -98,4 +98,4 @@ export {
98
98
  eventCommand,
99
99
  parseEventArgs
100
100
  };
101
- //# sourceMappingURL=event-TNT6CQZR.js.map
101
+ //# sourceMappingURL=event-6YW6TGFI.js.map
@@ -15,7 +15,7 @@ import {
15
15
  import "./chunk-KBO7XRBW.js";
16
16
  import {
17
17
  git
18
- } from "./chunk-OLPSEQS5.js";
18
+ } from "./chunk-AKOI4VTD.js";
19
19
  import {
20
20
  hookCommand
21
21
  } from "./chunk-GHFRQAYT.js";
@@ -249,4 +249,4 @@ export {
249
249
  gitHookStatusCommand,
250
250
  gitHookUninstallCommand
251
251
  };
252
- //# sourceMappingURL=git-hook-YZNZGAAP.js.map
252
+ //# sourceMappingURL=git-hook-Y7Y262F7.js.map
@@ -5,19 +5,19 @@ import {
5
5
  printSummary,
6
6
  runWithProgress,
7
7
  summarize
8
- } from "./chunk-XDCKZ5TV.js";
8
+ } from "./chunk-R5AX7VST.js";
9
9
  import "./chunk-SHKXELUX.js";
10
10
  import "./chunk-Z6QWMJLK.js";
11
11
  import "./chunk-XFN7UZCS.js";
12
12
  import "./chunk-KBO7XRBW.js";
13
- import "./chunk-GGXPG6OE.js";
14
- import "./chunk-MPG3IEGB.js";
15
- import "./chunk-ELKFRTZT.js";
13
+ import "./chunk-4FETKOY3.js";
16
14
  import "./chunk-2R6PXY6Z.js";
15
+ import "./chunk-44EGCEB2.js";
17
16
  import "./chunk-PVCIGUIT.js";
18
- import "./chunk-OLPSEQS5.js";
17
+ import "./chunk-ELKFRTZT.js";
18
+ import "./chunk-AKOI4VTD.js";
19
19
  import "./chunk-QCC4VJUH.js";
20
- import "./chunk-JCGDR4UV.js";
20
+ import "./chunk-WWQ5NKEC.js";
21
21
  import "./chunk-YRIS7ZS6.js";
22
22
  import "./chunk-GHFRQAYT.js";
23
23
  import "./chunk-INT3IGMQ.js";
@@ -35,4 +35,4 @@ export {
35
35
  runWithProgress,
36
36
  summarize
37
37
  };
38
- //# sourceMappingURL=init-WQCAOJ2R.js.map
38
+ //# sourceMappingURL=init-427QR5AS.js.map