codiedev 0.10.0-beta.11 → 0.10.0-beta.14
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/dist/cli.js +39 -0
- package/dist/commands/scrub.js +91 -0
- package/dist/hook.js +14 -0
- package/dist/localScrub.js +711 -0
- package/dist/localScrubReport.js +249 -0
- package/dist/scrub/rules.js +389 -0
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,38 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
3
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
37
|
const connect_1 = require("./connect");
|
|
5
38
|
const cliSession_1 = require("./cliSession");
|
|
@@ -110,6 +143,7 @@ Privacy:
|
|
|
110
143
|
codiedev ignore <path> Never capture this folder or its children
|
|
111
144
|
codiedev unignore <path> Stop ignoring a folder
|
|
112
145
|
codiedev ignored [path] List ignored folders, or check one path
|
|
146
|
+
codiedev scrub [--dry-run] Remove keys from past agent sessions on this machine
|
|
113
147
|
|
|
114
148
|
Capture:
|
|
115
149
|
codiedev note "<text>" Capture a passing thought
|
|
@@ -545,6 +579,11 @@ async function main() {
|
|
|
545
579
|
case "read":
|
|
546
580
|
await (0, inbox_1.runRead)(rest);
|
|
547
581
|
return;
|
|
582
|
+
case "scrub": {
|
|
583
|
+
const { runScrubCommand } = await Promise.resolve().then(() => __importStar(require("./commands/scrub")));
|
|
584
|
+
process.exitCode = await runScrubCommand(rest);
|
|
585
|
+
return;
|
|
586
|
+
}
|
|
548
587
|
case "note":
|
|
549
588
|
await (0, note_1.runNote)(rest);
|
|
550
589
|
return;
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCRUB_HELP = void 0;
|
|
4
|
+
exports.parseScrubArgs = parseScrubArgs;
|
|
5
|
+
exports.formatScrubSummary = formatScrubSummary;
|
|
6
|
+
exports.runScrubCommand = runScrubCommand;
|
|
7
|
+
const localScrub_1 = require("../localScrub");
|
|
8
|
+
exports.SCRUB_HELP = `codiedev scrub — remove keys from past agent sessions on this machine
|
|
9
|
+
|
|
10
|
+
Usage:
|
|
11
|
+
codiedev scrub [--dry-run] [--path <file>]... [--session <id>]... [--min-age <minutes>]
|
|
12
|
+
|
|
13
|
+
Cleans the session files Claude Code, Codex, Cursor, Copilot, OpenCode/Codie
|
|
14
|
+
and pi keep locally, using the same rules as the Codiedev server. Each key is
|
|
15
|
+
replaced with [REDACTED:<kind>]. Sessions changed in the last hour are skipped
|
|
16
|
+
so open sessions are never touched. When signed in, what was found (session,
|
|
17
|
+
key type and last 4, removed or not) shows on your Security page; the keys
|
|
18
|
+
themselves never leave this machine.
|
|
19
|
+
|
|
20
|
+
--dry-run Count what would be cleaned; change nothing
|
|
21
|
+
--path <file> Only this file (repeatable)
|
|
22
|
+
--session <id> With --path <opencode.db>: only this OpenCode/Codie session
|
|
23
|
+
--min-age <min> Skip files changed in the last <min> minutes (default 60)
|
|
24
|
+
`;
|
|
25
|
+
function parseScrubArgs(args) {
|
|
26
|
+
let dryRun = false;
|
|
27
|
+
let help = false;
|
|
28
|
+
const only = [];
|
|
29
|
+
const sessions = [];
|
|
30
|
+
let minAgeMs = localScrub_1.MIN_AGE_MS;
|
|
31
|
+
for (let i = 0; i < args.length; i++) {
|
|
32
|
+
const a = args[i];
|
|
33
|
+
if (a === "--dry-run")
|
|
34
|
+
dryRun = true;
|
|
35
|
+
else if (a === "--help" || a === "-h")
|
|
36
|
+
help = true;
|
|
37
|
+
else if (a === "--path" && args[i + 1])
|
|
38
|
+
only.push(args[++i]);
|
|
39
|
+
else if (a === "--session" && args[i + 1])
|
|
40
|
+
sessions.push(args[++i]);
|
|
41
|
+
else if (a === "--min-age" && args[i + 1]) {
|
|
42
|
+
const m = Number(args[++i]);
|
|
43
|
+
if (Number.isFinite(m) && m >= 0)
|
|
44
|
+
minAgeMs = m * 60_000;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { dryRun, help, minAgeMs, ...(only.length ? { only } : {}), ...(sessions.length ? { onlySessions: sessions } : {}) };
|
|
48
|
+
}
|
|
49
|
+
function formatScrubSummary(s) {
|
|
50
|
+
const lines = [];
|
|
51
|
+
const verb = s.dryRun ? "Would remove" : "Removed";
|
|
52
|
+
lines.push(s.redactions === 0
|
|
53
|
+
? `No keys found in ${s.scanned} session file${s.scanned === 1 ? "" : "s"} checked.`
|
|
54
|
+
: `${verb} ${s.redactions} key${s.redactions === 1 ? "" : "s"}${s.dryRun ? "" : ` from ${s.cleaned} file${s.cleaned === 1 ? "" : "s"}`} (${s.scanned} checked).`);
|
|
55
|
+
for (const [h, t] of Object.entries(s.byHarness))
|
|
56
|
+
lines.push(` ${h}: ${t.redactions} in ${t.files} file${t.files === 1 ? "" : "s"}`);
|
|
57
|
+
if (s.skippedRecent)
|
|
58
|
+
lines.push(`Skipped ${s.skippedRecent} changed in the last hour (may be open).`);
|
|
59
|
+
if (s.skippedLarge)
|
|
60
|
+
lines.push(`Skipped ${s.skippedLarge} over 100 MB.`);
|
|
61
|
+
if (s.changedWhileCleaning)
|
|
62
|
+
lines.push(`Left ${s.changedWhileCleaning} alone: changed while cleaning.`);
|
|
63
|
+
if (s.errors)
|
|
64
|
+
lines.push(`${s.errors} couldn't be read or written.`);
|
|
65
|
+
if (s.unfinished)
|
|
66
|
+
lines.push("Stopped at the time limit; the next run continues.");
|
|
67
|
+
if (s.leftInCursor.keys > 0) {
|
|
68
|
+
const { keys, chats } = s.leftInCursor;
|
|
69
|
+
lines.push(`${keys} key${keys === 1 ? " is" : "s are"} still in ${chats} Cursor chat${chats === 1 ? "" : "s"}. ` +
|
|
70
|
+
"Cursor's own chat store can't be cleaned without breaking the chat; delete those chats in Cursor to remove them.");
|
|
71
|
+
}
|
|
72
|
+
return lines.join("\n");
|
|
73
|
+
}
|
|
74
|
+
async function runScrubCommand(args) {
|
|
75
|
+
const opts = parseScrubArgs(args);
|
|
76
|
+
if (opts.help) {
|
|
77
|
+
console.log(exports.SCRUB_HELP);
|
|
78
|
+
return 0;
|
|
79
|
+
}
|
|
80
|
+
const summary = await (0, localScrub_1.runAndReport)({
|
|
81
|
+
dryRun: opts.dryRun,
|
|
82
|
+
only: opts.only,
|
|
83
|
+
onlySessions: opts.onlySessions,
|
|
84
|
+
minAgeMs: opts.minAgeMs,
|
|
85
|
+
budgetMs: 10 * 60_000,
|
|
86
|
+
});
|
|
87
|
+
console.log(formatScrubSummary(summary));
|
|
88
|
+
if (summary.reported)
|
|
89
|
+
console.log("Sent to your Security page in Codiedev (key type and last 4 only, never the key).");
|
|
90
|
+
return summary.errors > 0 ? 1 : 0;
|
|
91
|
+
}
|
package/dist/hook.js
CHANGED
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
})();
|
|
36
36
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
37
|
exports.buildDiscoveryContext = buildDiscoveryContext;
|
|
38
|
+
const localScrub_1 = require("./localScrub");
|
|
38
39
|
const captureSignals_1 = require("./captureSignals");
|
|
39
40
|
const transcriptModels_1 = require("./transcriptModels");
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
@@ -442,6 +443,16 @@ async function main() {
|
|
|
442
443
|
}
|
|
443
444
|
process.exit(0);
|
|
444
445
|
}
|
|
446
|
+
if (process.argv[2] === "local-scrub") {
|
|
447
|
+
try {
|
|
448
|
+
const { runAndReport, scrubAllowed } = await Promise.resolve().then(() => __importStar(require("./localScrub")));
|
|
449
|
+
if (await scrubAllowed())
|
|
450
|
+
await runAndReport();
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
}
|
|
454
|
+
process.exit(0);
|
|
455
|
+
}
|
|
445
456
|
if (process.argv[2] === "self-update") {
|
|
446
457
|
await (0, selfUpdate_1.runSelfUpdate)(process.argv[1]);
|
|
447
458
|
process.exit(0);
|
|
@@ -489,6 +500,8 @@ async function main() {
|
|
|
489
500
|
await runCodexLimitSweep(hookInput.session_id);
|
|
490
501
|
if (source === "codex")
|
|
491
502
|
(0, sync_1.maybeSpawnPackSync)({ connected: Boolean((0, utils_1.readConfig)()), cli: path.join(__dirname, "cli.js") });
|
|
503
|
+
if (source === "codex")
|
|
504
|
+
(0, localScrub_1.maybeSpawnLocalScrub)({ connected: Boolean((0, utils_1.readConfig)()) });
|
|
492
505
|
if (source !== "copilot")
|
|
493
506
|
await runDiscover(hookInput.prompt);
|
|
494
507
|
return;
|
|
@@ -530,6 +543,7 @@ async function main() {
|
|
|
530
543
|
process.argv[2] === "session-start-opencode" ||
|
|
531
544
|
process.argv[2] === "session-start-pi") {
|
|
532
545
|
(0, sync_1.maybeSpawnPackSync)({ connected: Boolean((0, utils_1.readConfig)()), cli: path.join(__dirname, "cli.js") });
|
|
546
|
+
(0, localScrub_1.maybeSpawnLocalScrub)({ connected: Boolean((0, utils_1.readConfig)()) });
|
|
533
547
|
const packNag = process.argv[2] === "session-start-opencode" || process.argv[2] === "session-start-pi" ? null : (0, sync_1.packNagLine)();
|
|
534
548
|
if (packNag && process.argv[2] === "session-start")
|
|
535
549
|
process.stdout.write(`${packNag}\n`);
|