hazmat-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/README.md +39 -0
  2. package/dist/src/cli.d.ts +2 -0
  3. package/dist/src/cli.js +239 -0
  4. package/dist/src/cli.js.map +1 -0
  5. package/dist/src/codex.d.ts +3 -0
  6. package/dist/src/codex.js +135 -0
  7. package/dist/src/codex.js.map +1 -0
  8. package/dist/src/detectors.d.ts +20 -0
  9. package/dist/src/detectors.js +120 -0
  10. package/dist/src/detectors.js.map +1 -0
  11. package/dist/src/jsonl.d.ts +4 -0
  12. package/dist/src/jsonl.js +136 -0
  13. package/dist/src/jsonl.js.map +1 -0
  14. package/dist/src/publish.d.ts +16 -0
  15. package/dist/src/publish.js +121 -0
  16. package/dist/src/publish.js.map +1 -0
  17. package/dist/src/report.d.ts +6 -0
  18. package/dist/src/report.js +192 -0
  19. package/dist/src/report.js.map +1 -0
  20. package/dist/src/scanner.d.ts +15 -0
  21. package/dist/src/scanner.js +43 -0
  22. package/dist/src/scanner.js.map +1 -0
  23. package/dist/src/scoring.d.ts +4 -0
  24. package/dist/src/scoring.js +27 -0
  25. package/dist/src/scoring.js.map +1 -0
  26. package/dist/src/scrub.d.ts +8 -0
  27. package/dist/src/scrub.js +61 -0
  28. package/dist/src/scrub.js.map +1 -0
  29. package/dist/src/sources.d.ts +8 -0
  30. package/dist/src/sources.js +101 -0
  31. package/dist/src/sources.js.map +1 -0
  32. package/dist/src/sqlite.d.ts +2 -0
  33. package/dist/src/sqlite.js +104 -0
  34. package/dist/src/sqlite.js.map +1 -0
  35. package/dist/src/sqliteScrub.d.ts +9 -0
  36. package/dist/src/sqliteScrub.js +128 -0
  37. package/dist/src/sqliteScrub.js.map +1 -0
  38. package/dist/src/state.d.ts +5 -0
  39. package/dist/src/state.js +21 -0
  40. package/dist/src/state.js.map +1 -0
  41. package/dist/src/types.d.ts +63 -0
  42. package/dist/src/types.js +2 -0
  43. package/dist/src/types.js.map +1 -0
  44. package/dist/src/ui.d.ts +19 -0
  45. package/dist/src/ui.js +65 -0
  46. package/dist/src/ui.js.map +1 -0
  47. package/package.json +32 -0
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Hazmat
2
+
3
+ Local exposure scanner and scrubber for AI coding-agent transcripts.
4
+
5
+ Current pre-v0 supports scan/report/export plus in-place scrubbing for discovered Codex, Claude, pi, OpenCode, and best-effort Cursor transcript sources.
6
+
7
+ ```bash
8
+ bun install
9
+ bun run build
10
+ node dist/src/cli.js scan
11
+ node dist/src/cli.js report
12
+ node dist/src/cli.js export --out report.json
13
+ node dist/src/cli.js scrub --dry-run
14
+ ```
15
+
16
+ Publish flow:
17
+
18
+ ```bash
19
+ # terminal 1
20
+ cd web && bun run dev
21
+
22
+ # terminal 2
23
+ export HAZMAT_API_URL=http://localhost:3000
24
+ export HAZMAT_GITHUB_CLIENT_ID=<github-oauth-client-id>
25
+ node dist/src/cli.js login
26
+ node dist/src/cli.js export --publish
27
+ # or: node dist/src/cli.js scan --publish
28
+ ```
29
+
30
+ For CLI login, enable Device Flow on the GitHub OAuth App.
31
+
32
+ Planned package binary:
33
+
34
+ ```bash
35
+ hazmat scan
36
+ hazmat report
37
+ hazmat export --publish
38
+ hazmat scrub
39
+ ```
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,239 @@
1
+ #!/usr/bin/env node
2
+ import { writeFile } from "node:fs/promises";
3
+ import { cpus } from "node:os";
4
+ import { createInterface } from "node:readline/promises";
5
+ import { stdin as input, stdout as output } from "node:process";
6
+ import { Command } from "commander";
7
+ import { scanCodexFile } from "./codex.js";
8
+ import { scanGenericTranscriptFile } from "./jsonl.js";
9
+ import { buildScanReport, buildSharePayload, formatReport } from "./report.js";
10
+ import { loginWithGithubDeviceFlow, publishPayload } from "./publish.js";
11
+ import { scanSQLiteSource } from "./sqlite.js";
12
+ import { discoverDefaultSources, discoverPathSources } from "./sources.js";
13
+ import { dryRunSQLiteScrub, scrubSQLiteInPlace } from "./sqliteScrub.js";
14
+ import { dryRunScrubTextFile, scrubTextFileInPlace } from "./scrub.js";
15
+ import { latestScanPath, loadLatestScan, saveLatestScan } from "./state.js";
16
+ import { c, printBanner, progressLine, savedLine, scrubSummary } from "./ui.js";
17
+ installWarningFilter();
18
+ const program = new Command();
19
+ program
20
+ .name("hazmat")
21
+ .description("Local exposure scanner for AI coding-agent transcripts")
22
+ .version("0.0.0");
23
+ program
24
+ .command("scan")
25
+ .description("Scan agent transcripts for sensitive exposure")
26
+ .argument("[paths...]", "optional files or directories to scan; defaults to known transcript locations")
27
+ .option("--json", "print JSON instead of terminal report")
28
+ .option("--publish", "publish the privacy-safe export after scanning")
29
+ .action(async (paths, options) => {
30
+ const report = await runScan(paths, { quiet: Boolean(options.json) });
31
+ if (options.json)
32
+ console.log(JSON.stringify(report, null, 2));
33
+ else {
34
+ console.log(formatReport(report));
35
+ console.log("");
36
+ console.log(savedLine(latestScanPath));
37
+ }
38
+ if (options.publish)
39
+ await publishReport(report);
40
+ });
41
+ program
42
+ .command("scrub")
43
+ .description("Redact secret values in transcript files/databases in-place")
44
+ .argument("[paths...]", "optional files, directories, or DBs to scrub; defaults to known transcript locations")
45
+ .option("--dry-run", "show what would change without modifying files")
46
+ .option("--yes", "skip confirmation prompt")
47
+ .action(async (paths, options) => {
48
+ const scrubSources = paths.length > 0 ? await discoverPathSources(paths) : await discoverDefaultSources();
49
+ if (!options.dryRun && !options.yes) {
50
+ const ok = await confirmScrub(scrubSources.length, paths.length === 0);
51
+ if (!ok) {
52
+ console.error("Scrub cancelled.");
53
+ process.exitCode = 1;
54
+ return;
55
+ }
56
+ }
57
+ const concurrency = Math.max(1, Math.min(4, cpus().length || 1));
58
+ console.error(`${options.dryRun ? "Checking" : "Scrubbing"} ${scrubSources.length} sources with concurrency ${concurrency}...`);
59
+ const results = await mapLimit(scrubSources, concurrency, async (source, index) => {
60
+ console.error(progressLine("start", index + 1, scrubSources.length, source.harness, source.path));
61
+ try {
62
+ const result = await scrubSource(source, Boolean(options.dryRun));
63
+ console.error(progressLine("done", index + 1, scrubSources.length, source.harness, source.path));
64
+ return result;
65
+ }
66
+ catch (error) {
67
+ const message = error instanceof Error ? error.message : String(error);
68
+ console.error(`${c.warn("skip")} ${source.harness} ${source.path}: ${message}`);
69
+ return null;
70
+ }
71
+ });
72
+ const completed = results.filter((result) => result !== null);
73
+ const skipped = scrubSources.length - completed.length;
74
+ const changedFiles = completed.filter((result) => result.changed > 0).length;
75
+ const redactions = completed.reduce((total, result) => total + result.redactions, 0);
76
+ const changedLines = completed.reduce((total, result) => total + result.changed, 0);
77
+ console.log(scrubSummary(changedFiles, scrubSources.length, redactions, changedLines, Boolean(options.dryRun), skipped));
78
+ });
79
+ program
80
+ .command("export")
81
+ .description("Export or publish the privacy-safe aggregate report from the latest scan")
82
+ .option("--json", "print privacy-safe JSON to stdout")
83
+ .option("--out <path>", "write privacy-safe JSON to a file")
84
+ .option("--publish", "publish the privacy-safe export to the configured backend")
85
+ .action(async (options) => {
86
+ const report = await loadLatestScan();
87
+ if (!report) {
88
+ console.error("No scan report found. Run: hazmat scan");
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ const payload = buildSharePayload(report);
93
+ const json = `${JSON.stringify(payload, null, 2)}\n`;
94
+ if (options.out) {
95
+ await writeFile(options.out, json, "utf8");
96
+ console.log(`Wrote privacy-safe export: ${options.out}`);
97
+ }
98
+ if (options.publish)
99
+ await publishReport(report);
100
+ if (options.json || (!options.out && !options.publish))
101
+ console.log(json);
102
+ });
103
+ program
104
+ .command("share", { hidden: true })
105
+ .description("Alias for export")
106
+ .option("--out <path>", "write privacy-safe JSON to a file")
107
+ .option("--publish", "publish the privacy-safe export to the configured backend")
108
+ .action(async (options) => {
109
+ const report = await loadLatestScan();
110
+ if (!report) {
111
+ console.error("No scan report found. Run: hazmat scan");
112
+ process.exitCode = 1;
113
+ return;
114
+ }
115
+ const payload = buildSharePayload(report);
116
+ if (options.out) {
117
+ await writeFile(options.out, `${JSON.stringify(payload, null, 2)}\n`, "utf8");
118
+ console.log(`Wrote privacy-safe export: ${options.out}`);
119
+ }
120
+ if (options.publish)
121
+ await publishReport(report);
122
+ if (!options.out && !options.publish)
123
+ console.log(`${JSON.stringify(payload, null, 2)}\n`);
124
+ });
125
+ program
126
+ .command("login")
127
+ .description("Log in with GitHub for publishing reports")
128
+ .action(async () => {
129
+ await loginWithGithubDeviceFlow();
130
+ });
131
+ program
132
+ .command("report")
133
+ .description("Show latest saved scan report")
134
+ .option("--json", "print JSON instead of terminal report")
135
+ .option("--verbose", "show per-session fingerprints and paths")
136
+ .action(async (options) => {
137
+ const report = await loadLatestScan();
138
+ if (!report) {
139
+ console.error("No scan report found. Run: hazmat scan");
140
+ process.exitCode = 1;
141
+ return;
142
+ }
143
+ if (options.json)
144
+ console.log(JSON.stringify(report, null, 2));
145
+ else {
146
+ printBanner();
147
+ console.log(formatReport(report, { verbose: options.verbose }));
148
+ }
149
+ });
150
+ function installWarningFilter() {
151
+ const originalEmitWarning = process.emitWarning.bind(process);
152
+ process.emitWarning = ((warning, ...args) => {
153
+ const message = typeof warning === "string" ? warning : warning.message;
154
+ if (message.includes("SQLite is an experimental feature"))
155
+ return;
156
+ return originalEmitWarning(warning, ...args);
157
+ });
158
+ }
159
+ async function runScan(paths, options) {
160
+ const scanSources = paths.length > 0 ? await discoverPathSources(paths) : await discoverDefaultSources();
161
+ const concurrency = Math.max(1, Math.min(4, cpus().length || 1));
162
+ if (!options.quiet) {
163
+ printBanner();
164
+ console.log(`${c.heading("Scanning")} ${c.value(String(scanSources.length))} sources ${c.muted(`with concurrency ${concurrency}`)}...`);
165
+ }
166
+ const sourceResults = await mapLimit(scanSources, concurrency, async (source, index) => {
167
+ if (!options.quiet)
168
+ console.log(progressLine("start", index + 1, scanSources.length, source.harness, source.path));
169
+ const result = await scanSource(source);
170
+ if (!options.quiet)
171
+ console.log(progressLine("done", index + 1, scanSources.length, source.harness, source.path));
172
+ return result;
173
+ });
174
+ const report = buildScanReport(sourceResults.filter((source) => source !== null));
175
+ await saveLatestScan(report);
176
+ return report;
177
+ }
178
+ async function publishReport(report) {
179
+ const payload = buildSharePayload(report);
180
+ const result = await publishPayload(payload);
181
+ console.log(`${c.good("✓")} Published report: ${c.accent(result.url)}`);
182
+ }
183
+ async function scanSource(source) {
184
+ if (source.kind === "sqlite")
185
+ return scanSQLiteSource(source.path, source.harness);
186
+ if (source.harness === "codex")
187
+ return scanCodexFile(source.path);
188
+ return scanGenericTranscriptFile(source.path, source.harness);
189
+ }
190
+ async function scrubSource(source, dryRun) {
191
+ if (source.kind === "sqlite") {
192
+ const result = dryRun
193
+ ? await dryRunSQLiteScrub(source.path, source.harness)
194
+ : await scrubSQLiteInPlace(source.path, source.harness);
195
+ if (!result)
196
+ return null;
197
+ return { changed: result.rowsChanged, redactions: result.redactions };
198
+ }
199
+ const result = dryRun ? await dryRunScrubTextFile(source.path) : await scrubTextFileInPlace(source.path);
200
+ return { changed: result.linesChanged, redactions: result.redactions };
201
+ }
202
+ async function confirmScrub(fileCount, isDefaultDiscovery) {
203
+ if (!process.stdin.isTTY) {
204
+ console.error("Non-interactive shell detected. Re-run with --yes to scrub.");
205
+ return false;
206
+ }
207
+ const scope = isDefaultDiscovery ? "all discovered transcript sources" : "the selected transcript sources";
208
+ const rl = createInterface({ input, output });
209
+ try {
210
+ const answer = await rl.question(`This will redact secret-like values in-place in ${fileCount} files (${scope}). Continue? [Y/n] `);
211
+ const normalized = answer.trim().toLowerCase();
212
+ return normalized === "" || normalized === "y" || normalized === "yes";
213
+ }
214
+ finally {
215
+ rl.close();
216
+ }
217
+ }
218
+ async function mapLimit(items, limit, fn) {
219
+ const results = new Array(items.length);
220
+ let nextIndex = 0;
221
+ async function worker() {
222
+ while (true) {
223
+ const index = nextIndex;
224
+ nextIndex += 1;
225
+ if (index >= items.length)
226
+ return;
227
+ results[index] = await fn(items[index], index);
228
+ }
229
+ }
230
+ const workers = Array.from({ length: Math.min(limit, items.length) }, () => worker());
231
+ await Promise.all(workers);
232
+ return results;
233
+ }
234
+ program.parseAsync(process.argv).catch((error) => {
235
+ const message = error instanceof Error ? error.message : String(error);
236
+ console.error(`hazmat: ${message}`);
237
+ process.exit(1);
238
+ });
239
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { SourceReport } from "./types.js";
2
+ export declare function discoverCodexFiles(inputPaths?: string[]): Promise<string[]>;
3
+ export declare function scanCodexFile(filePath: string): Promise<SourceReport>;
@@ -0,0 +1,135 @@
1
+ import { createReadStream } from "node:fs";
2
+ import { access, readdir, stat } from "node:fs/promises";
3
+ import { createInterface } from "node:readline";
4
+ import { homedir } from "node:os";
5
+ import path from "node:path";
6
+ import { hasDetectorHint } from "./detectors.js";
7
+ import { buildSourceReport, createFindingState, scanCandidateText } from "./scanner.js";
8
+ const CODEX_DIR = path.join(homedir(), ".codex");
9
+ const CODEX_SESSIONS_DIR = path.join(CODEX_DIR, "sessions");
10
+ const CODEX_EXTRA_FILES = [path.join(CODEX_DIR, "history.jsonl"), path.join(CODEX_DIR, "session_index.jsonl")];
11
+ const SCANNABLE_EXTENSIONS = new Set([".jsonl", ".json", ".log", ".txt"]);
12
+ export async function discoverCodexFiles(inputPaths = []) {
13
+ const roots = inputPaths.length > 0 ? inputPaths.map(expandHome) : [CODEX_SESSIONS_DIR, ...CODEX_EXTRA_FILES];
14
+ const files = new Set();
15
+ for (const root of roots) {
16
+ if (!(await exists(root)))
17
+ continue;
18
+ const rootStat = await stat(root);
19
+ if (rootStat.isDirectory()) {
20
+ for await (const file of walk(root))
21
+ if (isScannable(file))
22
+ files.add(file);
23
+ }
24
+ else if (rootStat.isFile() && isScannable(root))
25
+ files.add(root);
26
+ }
27
+ return [...files].sort();
28
+ }
29
+ export async function scanCodexFile(filePath) {
30
+ const state = createFindingState();
31
+ let linesScanned = 0;
32
+ const rl = createInterface({ input: createReadStream(filePath, { encoding: "utf8" }), crlfDelay: Infinity });
33
+ for await (const line of rl) {
34
+ linesScanned += 1;
35
+ for (const text of extractCodexScanTexts(line))
36
+ scanCandidateText(text, state);
37
+ }
38
+ return buildSourceReport({ harness: "codex", path: filePath, linesScanned, state });
39
+ }
40
+ function extractCodexScanTexts(line) {
41
+ if (!hasDetectorHint(line))
42
+ return [];
43
+ let entry;
44
+ try {
45
+ entry = JSON.parse(line);
46
+ }
47
+ catch {
48
+ return [line];
49
+ }
50
+ if (!isObject(entry))
51
+ return [line];
52
+ const type = stringValue(entry.type);
53
+ const payload = isObject(entry.payload) ? entry.payload : undefined;
54
+ if (!payload)
55
+ return [];
56
+ const payloadType = stringValue(payload.type);
57
+ if (type === "event_msg") {
58
+ if (payloadType === "user_message" || payloadType === "agent_message")
59
+ return compactStrings([payload.message]);
60
+ if (payloadType === "task_complete")
61
+ return compactStrings([payload.last_agent_message]);
62
+ return [];
63
+ }
64
+ if (type === "response_item") {
65
+ if (payloadType === "function_call")
66
+ return compactStrings([payload.name, payload.arguments]);
67
+ if (payloadType === "function_call_output")
68
+ return compactStrings([payload.output]);
69
+ if (payloadType === "message")
70
+ return extractContentText(payload.content);
71
+ if (payloadType === "reasoning")
72
+ return extractContentText(payload.summary);
73
+ return [];
74
+ }
75
+ if (type === "turn_context")
76
+ return compactStrings([payload.user_instructions, payload.summary]);
77
+ if (type === "session_meta")
78
+ return [];
79
+ return extractLikelyText(payload);
80
+ }
81
+ function extractContentText(value) {
82
+ if (!Array.isArray(value))
83
+ return compactStrings([value]);
84
+ const out = [];
85
+ for (const item of value) {
86
+ if (typeof item === "string")
87
+ out.push(item);
88
+ else if (isObject(item))
89
+ out.push(...compactStrings([item.text, item.content, item.message, item.output]));
90
+ }
91
+ return out;
92
+ }
93
+ function extractLikelyText(value, depth = 0) {
94
+ if (depth > 4)
95
+ return [];
96
+ if (typeof value === "string")
97
+ return [value];
98
+ if (Array.isArray(value))
99
+ return value.flatMap((item) => extractLikelyText(item, depth + 1));
100
+ if (!isObject(value))
101
+ return [];
102
+ const out = [];
103
+ for (const [key, nested] of Object.entries(value)) {
104
+ if (["encrypted_content", "rate_limits", "usage", "base_instructions"].includes(key))
105
+ continue;
106
+ if (["message", "text", "content", "output", "arguments", "user_instructions", "last_agent_message"].includes(key))
107
+ out.push(...extractLikelyText(nested, depth + 1));
108
+ }
109
+ return out;
110
+ }
111
+ async function* walk(dir) {
112
+ const entries = await readdir(dir, { withFileTypes: true });
113
+ for (const entry of entries) {
114
+ const fullPath = path.join(dir, entry.name);
115
+ if (entry.isDirectory())
116
+ yield* walk(fullPath);
117
+ else if (entry.isFile())
118
+ yield fullPath;
119
+ }
120
+ }
121
+ function compactStrings(values) { return values.filter((value) => typeof value === "string" && value.length > 0); }
122
+ function stringValue(value) { return typeof value === "string" ? value : undefined; }
123
+ function isObject(value) { return typeof value === "object" && value !== null; }
124
+ function isScannable(filePath) { return SCANNABLE_EXTENSIONS.has(path.extname(filePath).toLowerCase()); }
125
+ function expandHome(input) { if (input === "~")
126
+ return homedir(); if (input.startsWith("~/"))
127
+ return path.join(homedir(), input.slice(2)); return path.resolve(input); }
128
+ async function exists(filePath) { try {
129
+ await access(filePath);
130
+ return true;
131
+ }
132
+ catch {
133
+ return false;
134
+ } }
135
+ //# sourceMappingURL=codex.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codex.js","sourceRoot":"","sources":["../../src/codex.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { FileRefFinding, SecretFinding } from "./types.js";
2
+ type SecretMatch = {
3
+ label: string;
4
+ value: string;
5
+ };
6
+ type FileRefMatch = {
7
+ label: string;
8
+ value: string;
9
+ };
10
+ export declare function hasDetectorHint(text: string): boolean;
11
+ export declare function detectSecrets(text: string): SecretMatch[];
12
+ export declare function detectFileReferences(text: string): FileRefMatch[];
13
+ export declare function redactText(text: string): {
14
+ text: string;
15
+ redactions: number;
16
+ };
17
+ export declare function fingerprint(value: string): string;
18
+ export declare function addSecretFinding(map: Map<string, SecretFinding>, match: SecretMatch): void;
19
+ export declare function addFileRefFinding(map: Map<string, FileRefFinding>, match: FileRefMatch): void;
20
+ export {};
@@ -0,0 +1,120 @@
1
+ import { createHash } from "node:crypto";
2
+ const secretPatterns = [
3
+ {
4
+ label: "private-key",
5
+ hints: ["PRIVATE KEY"],
6
+ regex: /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]+?-----END [A-Z ]*PRIVATE KEY-----/g,
7
+ },
8
+ {
9
+ label: "anthropic-api-key",
10
+ hints: ["sk-ant-"],
11
+ regex: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
12
+ },
13
+ {
14
+ label: "openai-api-key",
15
+ hints: ["sk-"],
16
+ regex: /\bsk-[A-Za-z0-9_-]{20,}\b/g,
17
+ },
18
+ {
19
+ label: "github-token",
20
+ hints: ["ghp_", "gho_", "ghu_", "ghs_", "ghr_"],
21
+ regex: /\bgh[pousr]_[A-Za-z0-9_]{20,}\b/g,
22
+ },
23
+ {
24
+ label: "database-url",
25
+ hints: ["postgres://", "postgresql://", "mysql://", "mongodb://", "mongodb+srv://", "redis://"],
26
+ regex: /(?:postgres(?:ql)?|mysql|mongodb(?:\+srv)?|redis):\/\/[^\s"'`<>\\]+/gi,
27
+ },
28
+ {
29
+ label: "jwt",
30
+ hints: ["eyJ"],
31
+ regex: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g,
32
+ },
33
+ {
34
+ label: "webhook-url",
35
+ hints: ["webhook", "hooks.slack", "discord.com/api/webhooks", "discordapp.com/api/webhooks"],
36
+ regex: /https:\/\/[^\s"'`<>]*(?:webhook|hooks\.slack|discord(?:app)?\.com\/api\/webhooks)[^\s"'`<>]*/gi,
37
+ },
38
+ {
39
+ label: "env-secret-assignment",
40
+ hints: ["KEY", "TOKEN", "SECRET", "PASSWORD", "DATABASE_URL", "DB_URL", "AUTH"],
41
+ regex: /(?:^|\\n|[^A-Za-z0-9_])([A-Z][A-Z0-9_]*(?:KEY|TOKEN|SECRET|PASSWORD|PASS|DATABASE_URL|DB_URL|AUTH)[A-Z0-9_]*)\s*=\s*(["']?)([^\s"'`\\<>]{8,})\2/g,
42
+ valueGroup: 3,
43
+ },
44
+ ];
45
+ const fileReferenceHints = [".env", "id_rsa", "id_ed25519", ".pem", ".p12", ".pfx", "wallet", "keypair"];
46
+ const fileRefPattern = /(?:^|[\/\s"'`])((?:\.env(?:\.[A-Za-z0-9_-]+)?|id_rsa|id_ed25519|[^\s"'`]+\.(?:pem|p12|pfx)|[^\s"'`]*wallet[^\s"'`]*\.json|[^\s"'`]*keypair[^\s"'`]*\.json))(?=$|[\s"'`,:;])/gi;
47
+ export function hasDetectorHint(text) {
48
+ return secretPatterns.some((pattern) => pattern.hints.some((hint) => text.includes(hint))) ||
49
+ fileReferenceHints.some((hint) => text.includes(hint));
50
+ }
51
+ export function detectSecrets(text) {
52
+ const matches = [];
53
+ for (const pattern of secretPatterns) {
54
+ if (!pattern.hints.some((hint) => text.includes(hint)))
55
+ continue;
56
+ pattern.regex.lastIndex = 0;
57
+ for (const match of text.matchAll(pattern.regex)) {
58
+ const value = match[pattern.valueGroup ?? 0];
59
+ if (!value)
60
+ continue;
61
+ matches.push({ label: pattern.label, value });
62
+ }
63
+ }
64
+ return matches;
65
+ }
66
+ export function detectFileReferences(text) {
67
+ const matches = [];
68
+ if (!fileReferenceHints.some((hint) => text.includes(hint)))
69
+ return matches;
70
+ fileRefPattern.lastIndex = 0;
71
+ for (const match of text.matchAll(fileRefPattern)) {
72
+ const value = match[1];
73
+ if (!value)
74
+ continue;
75
+ matches.push({ label: "sensitive-file-reference", value });
76
+ }
77
+ return matches;
78
+ }
79
+ export function redactText(text) {
80
+ let redactions = 0;
81
+ let output = text;
82
+ for (const pattern of secretPatterns) {
83
+ if (!pattern.hints.some((hint) => output.includes(hint)))
84
+ continue;
85
+ pattern.regex.lastIndex = 0;
86
+ output = output.replace(pattern.regex, (...args) => {
87
+ const match = String(args[0] ?? "");
88
+ const value = pattern.valueGroup === undefined ? match : String(args[pattern.valueGroup] ?? "");
89
+ if (!value)
90
+ return match;
91
+ redactions += 1;
92
+ const replacement = `<redacted:${pattern.label}:${fingerprint(value)}>`;
93
+ if (pattern.valueGroup === undefined)
94
+ return replacement;
95
+ return match.replace(value, replacement);
96
+ });
97
+ }
98
+ return { text: output, redactions };
99
+ }
100
+ export function fingerprint(value) {
101
+ return createHash("sha256").update(value).digest("hex").slice(0, 8);
102
+ }
103
+ export function addSecretFinding(map, match) {
104
+ const fp = fingerprint(match.value);
105
+ const key = `${match.label}:${fp}`;
106
+ const existing = map.get(key);
107
+ if (existing)
108
+ existing.count += 1;
109
+ else
110
+ map.set(key, { kind: "secret", label: match.label, fingerprint: fp, count: 1 });
111
+ }
112
+ export function addFileRefFinding(map, match) {
113
+ const key = `${match.label}:${match.value}`;
114
+ const existing = map.get(key);
115
+ if (existing)
116
+ existing.count += 1;
117
+ else
118
+ map.set(key, { kind: "file-reference", label: match.label, value: match.value, count: 1 });
119
+ }
120
+ //# sourceMappingURL=detectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detectors.js","sourceRoot":"","sources":["../../src/detectors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { Harness, SourceReport } from "./types.js";
2
+ export declare function discoverFiles(roots: string[]): Promise<string[]>;
3
+ export declare function scanGenericTranscriptFile(filePath: string, harness: Harness): Promise<SourceReport>;
4
+ export declare function expandHome(input: string): string;