whatileaked 0.3.0 → 0.4.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 (3) hide show
  1. package/README.md +14 -1
  2. package/dist/cli.js +29 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # whatileaked
2
2
 
3
+ [![ci](https://github.com/selan-ai/whatileaked/actions/workflows/ci.yml/badge.svg)](https://github.com/selan-ai/whatileaked/actions/workflows/ci.yml)
4
+
3
5
  Your coding agent saves every conversation to your disk. If you ever pasted an
4
6
  API key into a chat, or asked the agent to read a `.env` file, that key is now
5
7
  sitting in a log file on your laptop — and it was uploaded to Anthropic or
@@ -103,6 +105,17 @@ same credential always produces the same code, so two rows sharing a code are
103
105
  one key you reused in two places, and two different codes are two different
104
106
  keys.
105
107
 
108
+ ### Sharing it
109
+
110
+ The last line of every scan is made only of counts — no project, path, rule or
111
+ fingerprint — so it is the part you can paste or screenshot anywhere:
112
+
113
+ ```
114
+ whatileaked: 3 credentials sent to a model provider, across 561 transcripts.
115
+ ```
116
+
117
+ A clean scan ends the same way, with `no credentials`.
118
+
106
119
  ---
107
120
 
108
121
  ## Is it a real key, or just a test fixture?
@@ -193,7 +206,7 @@ npx whatileaked scan || echo "found something"
193
206
  | Agent | Folder |
194
207
  | --- | --- |
195
208
  | Claude Code | `~/.claude/projects/` · `~/.claude/CLAUDE.md` |
196
- | Codex | `~/.codex/sessions/` · `~/.codex/AGENTS.md` |
209
+ | Codex | `~/.codex/sessions/` · `~/.codex/archived_sessions/` · `~/.codex/AGENTS.md` |
197
210
  | Cursor | `~/.cursor/projects/*/agent-transcripts/` |
198
211
 
199
212
  Cursor keeps its older Ask-mode chats in SQLite rather than jsonl, and those are
package/dist/cli.js CHANGED
@@ -162,6 +162,7 @@ var TerminalReporter = class {
162
162
  this.#write(green("No credentials found."));
163
163
  this.#write("");
164
164
  this.#write(dim(DISCLOSURE));
165
+ this.#share(sent, stats);
165
166
  return;
166
167
  }
167
168
  for (const total of totals) {
@@ -196,6 +197,22 @@ var TerminalReporter = class {
196
197
  this.#write(dim("Some findings will be test fixtures \u2014 open the file to tell."));
197
198
  this.#write("");
198
199
  this.#write(dim(DISCLOSURE));
200
+ this.#share(sent, stats);
201
+ }
202
+ /**
203
+ * The one line meant to be pasted somewhere public. Everything above it names
204
+ * projects, paths and fingerprints, so nobody shares it; this is counts only,
205
+ * and stays that way. It is last so a screenshot can crop to it, unstyled so
206
+ * a copy carries nothing but the words, and it repeats the headline's
207
+ * transmitted-only count for the same reason the headline keeps memory files
208
+ * out of it.
209
+ */
210
+ #share(sent, stats) {
211
+ const credentials = sent === 0 ? "no credentials" : plural(sent, "credential");
212
+ this.#write("");
213
+ this.#write(
214
+ `whatileaked: ${credentials} sent to a model provider, across ${plural(stats.transcripts, "transcript")}.`
215
+ );
199
216
  }
200
217
  };
201
218
  function count(value) {
@@ -2606,17 +2623,18 @@ var CodexSource = class {
2606
2623
  if (instructions !== null) {
2607
2624
  yield { source: this.name, kind: FileKind.memory, path: instructions, project: this.name };
2608
2625
  }
2609
- const root = join3(this.#home, ".codex", "sessions");
2610
- for (const dir of await walkDirectories(root)) {
2611
- for (const file of await listFiles(dir, FileExtension.jsonl)) {
2612
- const path = join3(dir, file);
2613
- const cwd = await firstCwd2(path);
2614
- yield {
2615
- source: this.name,
2616
- kind: FileKind.transcript,
2617
- path,
2618
- project: cwd === null ? basename2(dir) : basename2(cwd)
2619
- };
2626
+ for (const root of ["sessions", "archived_sessions"]) {
2627
+ for (const dir of await walkDirectories(join3(this.#home, ".codex", root))) {
2628
+ for (const file of await listFiles(dir, FileExtension.jsonl)) {
2629
+ const path = join3(dir, file);
2630
+ const cwd = await firstCwd2(path);
2631
+ yield {
2632
+ source: this.name,
2633
+ kind: FileKind.transcript,
2634
+ path,
2635
+ project: cwd === null ? basename2(dir) : basename2(cwd)
2636
+ };
2637
+ }
2620
2638
  }
2621
2639
  }
2622
2640
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "whatileaked",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "Scan your local Claude Code, Codex and Cursor transcripts for credentials you already sent to a model provider.",
5
5
  "type": "module",
6
6
  "imports": {