whatileaked 0.5.0 → 0.5.2
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 +5 -3
- package/dist/cli.js +32 -16
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,7 +58,7 @@ is all — no network connection is made at any point.
|
|
|
58
58
|
### When it finds nothing
|
|
59
59
|
|
|
60
60
|
```
|
|
61
|
-
scanned 561 transcripts · 197,016 messages
|
|
61
|
+
scanned 561 transcripts · 197,016 messages · 3 memory files
|
|
62
62
|
|
|
63
63
|
No credentials found.
|
|
64
64
|
```
|
|
@@ -68,7 +68,7 @@ Nothing to do. This is the good outcome.
|
|
|
68
68
|
### When it finds something
|
|
69
69
|
|
|
70
70
|
```
|
|
71
|
-
scanned 561 transcripts · 196,986 messages
|
|
71
|
+
scanned 561 transcripts · 196,986 messages · 3 memory files
|
|
72
72
|
|
|
73
73
|
* aws-access-token 2 secrets
|
|
74
74
|
f0b93847 billing-api sent 25 times
|
|
@@ -206,7 +206,7 @@ npx whatileaked scan || echo "found something"
|
|
|
206
206
|
| Agent | Folder |
|
|
207
207
|
| --- | --- |
|
|
208
208
|
| Claude Code | `~/.claude/projects/` · `~/.claude/history.jsonl` · `~/.claude/paste-cache/` · `~/.claude/CLAUDE.md` |
|
|
209
|
-
| Codex | `~/.codex/sessions/` · `~/.codex/archived_sessions/` · `~/.codex/history.jsonl` · `~/.codex/AGENTS.md` |
|
|
209
|
+
| Codex | `~/.codex/sessions/` · `~/.codex/archived_sessions/` · `~/.codex/history.jsonl` · `~/.codex/AGENTS.md` · `~/.codex/AGENTS.override.md` |
|
|
210
210
|
| Cursor | `~/.cursor/projects/*/agent-transcripts/` |
|
|
211
211
|
| opencode | `~/.local/share/opencode/opencode.db` |
|
|
212
212
|
|
|
@@ -220,6 +220,8 @@ opencode, and rotate.
|
|
|
220
220
|
Cursor keeps its older Ask-mode chats in SQLite as well, and those are not
|
|
221
221
|
scanned yet. Agent transcripts are covered; Ask history is not.
|
|
222
222
|
|
|
223
|
+
Claude Code transcripts it set aside (`*.jsonl.superseded-*`) are scanned too.
|
|
224
|
+
|
|
223
225
|
Transcripts record credentials that were already sent. So does prompt history,
|
|
224
226
|
which keeps every prompt you typed and every long paste after the session itself
|
|
225
227
|
has been cleaned up. Instruction and memory files are worse: they are read again
|
package/dist/cli.js
CHANGED
|
@@ -161,8 +161,7 @@ var TerminalReporter = class {
|
|
|
161
161
|
if (totals.length === 0) {
|
|
162
162
|
this.#write(green("No credentials found."));
|
|
163
163
|
this.#write("");
|
|
164
|
-
this.#
|
|
165
|
-
if (stats.unread.length > 0) this.#write("");
|
|
164
|
+
if (this.#notScanned(stats)) this.#write("");
|
|
166
165
|
this.#write(dim(DISCLOSURE));
|
|
167
166
|
this.#share(sent, stats);
|
|
168
167
|
return;
|
|
@@ -188,12 +187,7 @@ var TerminalReporter = class {
|
|
|
188
187
|
red("Remove them there as well as rotating, or the next session sends them again.")
|
|
189
188
|
);
|
|
190
189
|
}
|
|
191
|
-
|
|
192
|
-
this.#write(
|
|
193
|
-
yellow(`${plural(stats.unscannable, "message")} could not be scanned and are not counted.`)
|
|
194
|
-
);
|
|
195
|
-
}
|
|
196
|
-
this.#unread(stats);
|
|
190
|
+
this.#notScanned(stats);
|
|
197
191
|
this.#write("");
|
|
198
192
|
this.#write(dim("The 8-character code is a fingerprint, never the secret: a truncated"));
|
|
199
193
|
this.#write(dim("SHA-256, so one credential shows the same code everywhere it leaked."));
|
|
@@ -202,12 +196,23 @@ var TerminalReporter = class {
|
|
|
202
196
|
this.#write(dim(DISCLOSURE));
|
|
203
197
|
this.#share(sent, stats);
|
|
204
198
|
}
|
|
205
|
-
/**
|
|
206
|
-
*
|
|
207
|
-
|
|
199
|
+
/**
|
|
200
|
+
* Everything that was found and not looked at: refused messages, then one
|
|
201
|
+
* plain line per file not read. Printed under a clean result too, which is
|
|
202
|
+
* exactly where leaving it out would mislead — a clean scan once returned
|
|
203
|
+
* before the refused count, so a partial scan read as a clean one. Answers
|
|
204
|
+
* whether it wrote anything.
|
|
205
|
+
*/
|
|
206
|
+
#notScanned(stats) {
|
|
207
|
+
if (stats.unscannable > 0) {
|
|
208
|
+
this.#write(
|
|
209
|
+
yellow(`${plural(stats.unscannable, "message")} could not be scanned and are not counted.`)
|
|
210
|
+
);
|
|
211
|
+
}
|
|
208
212
|
for (const file of stats.unread) {
|
|
209
213
|
this.#write(yellow(`Found ${shorten(file.path)} but did not scan it: ${file.reason}.`));
|
|
210
214
|
}
|
|
215
|
+
return stats.unscannable > 0 || stats.unread.length > 0;
|
|
211
216
|
}
|
|
212
217
|
/**
|
|
213
218
|
* The one line meant to be pasted somewhere public. Everything above it names
|
|
@@ -2426,7 +2431,16 @@ var FileExtension = {
|
|
|
2426
2431
|
database: ".db"
|
|
2427
2432
|
};
|
|
2428
2433
|
function isJsonl(path) {
|
|
2429
|
-
return path.endsWith(FileExtension.jsonl);
|
|
2434
|
+
return path.endsWith(FileExtension.jsonl) || supersededJsonl.test(path);
|
|
2435
|
+
}
|
|
2436
|
+
var supersededJsonl = /\.jsonl\.superseded-[^/\\]+$/;
|
|
2437
|
+
async function listJsonl(dir) {
|
|
2438
|
+
try {
|
|
2439
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
2440
|
+
return entries.filter((entry) => entry.isFile() && isJsonl(entry.name)).map((entry) => entry.name);
|
|
2441
|
+
} catch {
|
|
2442
|
+
return [];
|
|
2443
|
+
}
|
|
2430
2444
|
}
|
|
2431
2445
|
async function listFiles(dir, extension) {
|
|
2432
2446
|
try {
|
|
@@ -2633,7 +2647,7 @@ var ClaudeCodeSource = class {
|
|
|
2633
2647
|
const dir = join2(root, slug);
|
|
2634
2648
|
let project = slug;
|
|
2635
2649
|
for (const nested of await walkDirectories(dir)) {
|
|
2636
|
-
for (const file of await
|
|
2650
|
+
for (const file of await listJsonl(nested)) {
|
|
2637
2651
|
const path = join2(nested, file);
|
|
2638
2652
|
const cwd = await firstCwd(path);
|
|
2639
2653
|
if (cwd !== null) project = basename(cwd);
|
|
@@ -2677,9 +2691,11 @@ var CodexSource = class {
|
|
|
2677
2691
|
this.#home = home2;
|
|
2678
2692
|
}
|
|
2679
2693
|
async *discover() {
|
|
2680
|
-
const
|
|
2681
|
-
|
|
2682
|
-
|
|
2694
|
+
for (const name of ["AGENTS.override.md", "AGENTS.md"]) {
|
|
2695
|
+
const instructions = await resolveFile(join3(this.#home, ".codex", name));
|
|
2696
|
+
if (instructions !== null) {
|
|
2697
|
+
yield { source: this.name, kind: FileKind.memory, path: instructions, project: this.name };
|
|
2698
|
+
}
|
|
2683
2699
|
}
|
|
2684
2700
|
const history = await resolveFile(join3(this.#home, ".codex", "history.jsonl"));
|
|
2685
2701
|
if (history !== null) {
|
package/package.json
CHANGED