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.
- package/README.md +39 -0
- package/dist/src/cli.d.ts +2 -0
- package/dist/src/cli.js +239 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/codex.d.ts +3 -0
- package/dist/src/codex.js +135 -0
- package/dist/src/codex.js.map +1 -0
- package/dist/src/detectors.d.ts +20 -0
- package/dist/src/detectors.js +120 -0
- package/dist/src/detectors.js.map +1 -0
- package/dist/src/jsonl.d.ts +4 -0
- package/dist/src/jsonl.js +136 -0
- package/dist/src/jsonl.js.map +1 -0
- package/dist/src/publish.d.ts +16 -0
- package/dist/src/publish.js +121 -0
- package/dist/src/publish.js.map +1 -0
- package/dist/src/report.d.ts +6 -0
- package/dist/src/report.js +192 -0
- package/dist/src/report.js.map +1 -0
- package/dist/src/scanner.d.ts +15 -0
- package/dist/src/scanner.js +43 -0
- package/dist/src/scanner.js.map +1 -0
- package/dist/src/scoring.d.ts +4 -0
- package/dist/src/scoring.js +27 -0
- package/dist/src/scoring.js.map +1 -0
- package/dist/src/scrub.d.ts +8 -0
- package/dist/src/scrub.js +61 -0
- package/dist/src/scrub.js.map +1 -0
- package/dist/src/sources.d.ts +8 -0
- package/dist/src/sources.js +101 -0
- package/dist/src/sources.js.map +1 -0
- package/dist/src/sqlite.d.ts +2 -0
- package/dist/src/sqlite.js +104 -0
- package/dist/src/sqlite.js.map +1 -0
- package/dist/src/sqliteScrub.d.ts +9 -0
- package/dist/src/sqliteScrub.js +128 -0
- package/dist/src/sqliteScrub.js.map +1 -0
- package/dist/src/state.d.ts +5 -0
- package/dist/src/state.js +21 -0
- package/dist/src/state.js.map +1 -0
- package/dist/src/types.d.ts +63 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/ui.d.ts +19 -0
- package/dist/src/ui.js +65 -0
- package/dist/src/ui.js.map +1 -0
- 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
|
+
```
|
package/dist/src/cli.js
ADDED
|
@@ -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,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":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAGxF,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,CAAC,CAAC;AACjD,MAAM,kBAAkB,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;AAC5D,MAAM,iBAAiB,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CAAC,CAAC;AAC/G,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;AAE1E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAU,GAAa,EAAE;IAChE,MAAM,KAAK,GAAG,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,kBAAkB,EAAE,GAAG,iBAAiB,CAAC,CAAC;IAC9G,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,CAAC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAClC,IAAI,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;YAC3B,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;gBAAE,IAAI,WAAW,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9E,CAAC;aAAM,IAAI,QAAQ,CAAC,MAAM,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,QAAgB;IAClD,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;IACnC,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,gBAAgB,CAAC,QAAQ,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE7G,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,EAAE,EAAE,CAAC;QAC5B,YAAY,IAAI,CAAC,CAAC;QAClB,KAAK,MAAM,IAAI,IAAI,qBAAqB,CAAC,IAAI,CAAC;YAAE,iBAAiB,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;IACjF,CAAC;IAED,OAAO,iBAAiB,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,YAAY,EAAE,KAAK,EAAE,CAAC,CAAC;AACtF,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,IAAI,KAAc,CAAC;IACnB,IAAI,CAAC;QAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,CAAC;IAC1D,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,IAAI,GAAG,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;IACpE,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAE9C,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,IAAI,WAAW,KAAK,cAAc,IAAI,WAAW,KAAK,eAAe;YAAE,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QAChH,IAAI,WAAW,KAAK,eAAe;YAAE,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC;QACzF,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;QAC7B,IAAI,WAAW,KAAK,eAAe;YAAE,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;QAC9F,IAAI,WAAW,KAAK,sBAAsB;YAAE,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;QACpF,IAAI,WAAW,KAAK,SAAS;YAAE,OAAO,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC1E,IAAI,WAAW,KAAK,WAAW;YAAE,OAAO,kBAAkB,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;QAC5E,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,cAAc,CAAC,CAAC,OAAO,CAAC,iBAAiB,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACjG,IAAI,IAAI,KAAK,cAAc;QAAE,OAAO,EAAE,CAAC;IACvC,OAAO,iBAAiB,CAAC,OAAO,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,kBAAkB,CAAC,KAAc;IACxC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,cAAc,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;IAC1D,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,OAAO,IAAI,KAAK,QAAQ;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACxC,IAAI,QAAQ,CAAC,IAAI,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC7G,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAS,iBAAiB,CAAC,KAAc,EAAE,KAAK,GAAG,CAAC;IAClD,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,EAAE,CAAC;IACzB,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,iBAAiB,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IAC7F,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAChC,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QAClD,IAAI,CAAC,mBAAmB,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QAC/F,IAAI,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,EAAE,mBAAmB,EAAE,oBAAoB,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,GAAG,CAAC,IAAI,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;IACxK,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,KAAK,SAAS,CAAC,CAAC,IAAI,CAAC,GAAW;IAC9B,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,WAAW,EAAE;YAAE,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;aAC1C,IAAI,KAAK,CAAC,MAAM,EAAE;YAAE,MAAM,QAAQ,CAAC;IAC1C,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAiB,IAAc,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACzJ,SAAS,WAAW,CAAC,KAAc,IAAwB,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;AAClH,SAAS,QAAQ,CAAC,KAAc,IAAsC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC;AAC3H,SAAS,WAAW,CAAC,QAAgB,IAAa,OAAO,oBAAoB,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;AAC1H,SAAS,UAAU,CAAC,KAAa,IAAY,IAAI,KAAK,KAAK,GAAG;IAAE,OAAO,OAAO,EAAE,CAAC,CAAC,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC;IAAE,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACxL,KAAK,UAAU,MAAM,CAAC,QAAgB,IAAsB,IAAI,CAAC;IAAC,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;IAAC,OAAO,IAAI,CAAC;AAAC,CAAC;AAAC,MAAM,CAAC;IAAC,OAAO,KAAK,CAAC;AAAC,CAAC,CAAC,CAAC"}
|
|
@@ -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;
|