cbrowser 19.0.2 → 19.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.
@@ -0,0 +1,68 @@
1
+ /**
2
+ * What `npm uninstall -g cbrowser` leaves behind, and how to remove it.
3
+ *
4
+ * npm removes the package. It does not remove anything the package wrote, and
5
+ * this tool writes a lot: measured on one real install, 403MB under
6
+ * ~/.cbrowser including an Anthropic API key, an IPRoyal proxy password, and
7
+ * 253MB of Chrome profile data with live session cookies for every site the
8
+ * user had tested. It also installs a Claude skill into ~/.claude/skills, which
9
+ * is outside the package entirely and which npm therefore cannot know about.
10
+ *
11
+ * A user who uninstalls reasonably believes they are done. They are not, and
12
+ * what survives is exactly the sensitive part.
13
+ *
14
+ * Design notes:
15
+ *
16
+ * - Reporting is separate from deleting. `planUninstall()` is pure -- it
17
+ * stats the filesystem and returns a plan -- so the command can show the
18
+ * user what will happen, and so tests can assert the target set without
19
+ * removing anything.
20
+ * - Dry run is the default at the CLI. Deleting a user's captured work
21
+ * because they typed a command to see what it did is not recoverable.
22
+ * - Credentials are listed first and labelled, because they are the reason
23
+ * this exists. Disk space is the least interesting thing here.
24
+ *
25
+ * @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
26
+ * @license MIT
27
+ */
28
+ /** Why a target matters, which drives ordering and labelling. */
29
+ export type TargetKind = "credential" | "session" | "artifact" | "integration";
30
+ export interface UninstallTarget {
31
+ path: string;
32
+ kind: TargetKind;
33
+ /** What this is, in the user's terms, not the filesystem's. */
34
+ description: string;
35
+ exists: boolean;
36
+ bytes: number;
37
+ /** Retained by --keep-config, which exists for the reinstall case. */
38
+ isConfig: boolean;
39
+ }
40
+ export interface UninstallPlan {
41
+ targets: UninstallTarget[];
42
+ totalBytes: number;
43
+ /** Credentials and sessions, i.e. what makes this a security matter. */
44
+ sensitiveCount: number;
45
+ }
46
+ /** Recursive size. Returns 0 for anything unreadable rather than throwing. */
47
+ export declare function directorySize(path: string): number;
48
+ export declare function formatBytes(bytes: number): string;
49
+ /** Stat the filesystem and describe what removal would do. Deletes nothing. */
50
+ export declare function defaultSkillDir(): string;
51
+ export declare function planUninstall(opts?: {
52
+ dataDir?: string;
53
+ skillDir?: string;
54
+ keepConfig?: boolean;
55
+ }): UninstallPlan;
56
+ export interface UninstallResult {
57
+ removed: string[];
58
+ failed: Array<{
59
+ path: string;
60
+ error: string;
61
+ }>;
62
+ bytesFreed: number;
63
+ }
64
+ /** Execute a plan. The caller is responsible for having confirmed it. */
65
+ export declare function executeUninstall(plan: UninstallPlan): UninstallResult;
66
+ /** The human-facing report for a plan. Returned rather than printed, so it is testable. */
67
+ export declare function renderPlan(plan: UninstallPlan, dryRun: boolean): string;
68
+ //# sourceMappingURL=uninstall.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.d.ts","sourceRoot":"","sources":["../src/uninstall.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAOH,iEAAiE;AACjE,MAAM,MAAM,UAAU,GAAG,YAAY,GAAG,SAAS,GAAG,UAAU,GAAG,aAAa,CAAC;AAE/E,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,CAAC;IACjB,+DAA+D;IAC/D,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,sEAAsE;IACtE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAclD;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUjD;AAuFD,+EAA+E;AAC/E,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,wBAAgB,aAAa,CAC3B,IAAI,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,OAAO,CAAA;CAAO,GACvE,aAAa,CAoCf;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,eAAe,CAwBrE;AAED,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAqCvE"}
@@ -0,0 +1,235 @@
1
+ /**
2
+ * What `npm uninstall -g cbrowser` leaves behind, and how to remove it.
3
+ *
4
+ * npm removes the package. It does not remove anything the package wrote, and
5
+ * this tool writes a lot: measured on one real install, 403MB under
6
+ * ~/.cbrowser including an Anthropic API key, an IPRoyal proxy password, and
7
+ * 253MB of Chrome profile data with live session cookies for every site the
8
+ * user had tested. It also installs a Claude skill into ~/.claude/skills, which
9
+ * is outside the package entirely and which npm therefore cannot know about.
10
+ *
11
+ * A user who uninstalls reasonably believes they are done. They are not, and
12
+ * what survives is exactly the sensitive part.
13
+ *
14
+ * Design notes:
15
+ *
16
+ * - Reporting is separate from deleting. `planUninstall()` is pure -- it
17
+ * stats the filesystem and returns a plan -- so the command can show the
18
+ * user what will happen, and so tests can assert the target set without
19
+ * removing anything.
20
+ * - Dry run is the default at the CLI. Deleting a user's captured work
21
+ * because they typed a command to see what it did is not recoverable.
22
+ * - Credentials are listed first and labelled, because they are the reason
23
+ * this exists. Disk space is the least interesting thing here.
24
+ *
25
+ * @copyright 2026 Alexandria Eden alexandria.shai.eden@gmail.com https://cbrowser.ai
26
+ * @license MIT
27
+ */
28
+ import { existsSync, statSync, readdirSync, rmSync } from "node:fs";
29
+ import { join } from "node:path";
30
+ import { homedir } from "node:os";
31
+ import { getDataDir } from "./config.js";
32
+ /** Recursive size. Returns 0 for anything unreadable rather than throwing. */
33
+ export function directorySize(path) {
34
+ let total = 0;
35
+ let entries;
36
+ try {
37
+ const st = statSync(path);
38
+ if (!st.isDirectory())
39
+ return st.size;
40
+ entries = readdirSync(path);
41
+ }
42
+ catch {
43
+ return 0;
44
+ }
45
+ for (const entry of entries) {
46
+ total += directorySize(join(path, entry));
47
+ }
48
+ return total;
49
+ }
50
+ export function formatBytes(bytes) {
51
+ if (bytes < 1024)
52
+ return `${bytes} B`;
53
+ const units = ["KB", "MB", "GB"];
54
+ let value = bytes / 1024;
55
+ let unit = 0;
56
+ while (value >= 1024 && unit < units.length - 1) {
57
+ value /= 1024;
58
+ unit++;
59
+ }
60
+ return `${value.toFixed(1)} ${units[unit]}`;
61
+ }
62
+ /**
63
+ * Everything this tool writes outside its own npm package.
64
+ *
65
+ * Declared as data so it can be reviewed and tested. A hand-written deletion
66
+ * sequence is how a target gets forgotten, and a forgotten credential is the
67
+ * failure this module exists to prevent.
68
+ */
69
+ function targetSpecs(dataDir, skillDir) {
70
+ return [
71
+ {
72
+ path: join(dataDir, "config.json"),
73
+ kind: "credential",
74
+ description: "Anthropic API key",
75
+ isConfig: true,
76
+ },
77
+ {
78
+ path: join(dataDir, "geo-proxy.json"),
79
+ kind: "credential",
80
+ description: "residential proxy credentials",
81
+ isConfig: true,
82
+ },
83
+ {
84
+ path: join(dataDir, "accounts"),
85
+ kind: "credential",
86
+ description: "saved account credentials and keys",
87
+ isConfig: false,
88
+ },
89
+ {
90
+ path: join(dataDir, "browser-state"),
91
+ kind: "session",
92
+ description: "browser profile: cookies and logged-in sessions",
93
+ isConfig: false,
94
+ },
95
+ {
96
+ path: join(dataDir, "sessions"),
97
+ kind: "session",
98
+ description: "saved browser sessions",
99
+ isConfig: false,
100
+ },
101
+ {
102
+ path: join(dataDir, "har"),
103
+ kind: "session",
104
+ description: "HAR captures (include request headers, so may contain auth tokens)",
105
+ isConfig: false,
106
+ },
107
+ {
108
+ path: skillDir,
109
+ kind: "integration",
110
+ description: "Claude skill installed by `cbrowser install-skill`",
111
+ isConfig: false,
112
+ },
113
+ ];
114
+ }
115
+ /**
116
+ * Directories under the data dir that hold generated output rather than
117
+ * anything sensitive. Enumerated by reading the data dir, so a capture type
118
+ * added later is still removed -- the alternative is a hand-kept list that goes
119
+ * stale exactly the way the WCAG list did.
120
+ */
121
+ function artifactTargets(dataDir, claimed) {
122
+ if (!existsSync(dataDir))
123
+ return [];
124
+ let entries;
125
+ try {
126
+ entries = readdirSync(dataDir);
127
+ }
128
+ catch {
129
+ return [];
130
+ }
131
+ return entries
132
+ .map((e) => join(dataDir, e))
133
+ .filter((p) => !claimed.has(p))
134
+ .map((p) => ({
135
+ path: p,
136
+ kind: "artifact",
137
+ description: "captured output (screenshots, baselines, reports)",
138
+ isConfig: false,
139
+ }));
140
+ }
141
+ /** Stat the filesystem and describe what removal would do. Deletes nothing. */
142
+ export function defaultSkillDir() {
143
+ return join(homedir(), ".claude", "skills", "CBrowser");
144
+ }
145
+ export function planUninstall(opts = {}) {
146
+ const dataDir = opts.dataDir ?? getDataDir();
147
+ // Injectable, and not merely for tidiness. This path used to be computed from
148
+ // homedir() inside targetSpecs, so a test that passed a temporary dataDir
149
+ // still got the REAL ~/.claude/skills/CBrowser in its plan -- and a test that
150
+ // then called executeUninstall deleted it off the developer's machine. It
151
+ // did, here, on the first run.
152
+ //
153
+ // Any path a deletion module can reach must be injectable, or its tests are
154
+ // live fire against the machine running them.
155
+ const skillDir = opts.skillDir ?? defaultSkillDir();
156
+ const specs = targetSpecs(dataDir, skillDir);
157
+ const claimed = new Set(specs.map((s) => s.path));
158
+ const all = [...specs, ...artifactTargets(dataDir, claimed)];
159
+ const order = {
160
+ credential: 0,
161
+ session: 1,
162
+ integration: 2,
163
+ artifact: 3,
164
+ };
165
+ const targets = all
166
+ .filter((s) => !(opts.keepConfig && s.isConfig))
167
+ .map((s) => {
168
+ const exists = existsSync(s.path);
169
+ return { ...s, exists, bytes: exists ? directorySize(s.path) : 0 };
170
+ })
171
+ .filter((t) => t.exists)
172
+ .sort((a, b) => order[a.kind] - order[b.kind] || b.bytes - a.bytes);
173
+ return {
174
+ targets,
175
+ totalBytes: targets.reduce((sum, t) => sum + t.bytes, 0),
176
+ sensitiveCount: targets.filter((t) => t.kind === "credential" || t.kind === "session").length,
177
+ };
178
+ }
179
+ /** Execute a plan. The caller is responsible for having confirmed it. */
180
+ export function executeUninstall(plan) {
181
+ const removed = [];
182
+ const failed = [];
183
+ let bytesFreed = 0;
184
+ for (const target of plan.targets) {
185
+ try {
186
+ rmSync(target.path, { recursive: true, force: true });
187
+ // Confirm rather than assume: rmSync with force:true does not throw for a
188
+ // path it could not remove, so trusting it would report a credential as
189
+ // deleted while it is still on disk. That is the precise failure this
190
+ // whole module exists to prevent, so it is checked.
191
+ if (existsSync(target.path)) {
192
+ failed.push({ path: target.path, error: "still present after removal" });
193
+ continue;
194
+ }
195
+ removed.push(target.path);
196
+ bytesFreed += target.bytes;
197
+ }
198
+ catch (e) {
199
+ failed.push({ path: target.path, error: e.message });
200
+ }
201
+ }
202
+ return { removed, failed, bytesFreed };
203
+ }
204
+ /** The human-facing report for a plan. Returned rather than printed, so it is testable. */
205
+ export function renderPlan(plan, dryRun) {
206
+ if (plan.targets.length === 0) {
207
+ return "Nothing to remove — no CBrowser data found on this machine.";
208
+ }
209
+ const lines = [];
210
+ lines.push(dryRun ? "The following would be removed:" : "Removing:");
211
+ lines.push("");
212
+ const labels = {
213
+ credential: "CREDENTIAL",
214
+ session: "SESSION ",
215
+ integration: "INTEGRATION",
216
+ artifact: "artifact ",
217
+ };
218
+ for (const t of plan.targets) {
219
+ lines.push(` [${labels[t.kind]}] ${t.path}`);
220
+ lines.push(` ${t.description} — ${formatBytes(t.bytes)}`);
221
+ }
222
+ lines.push("");
223
+ lines.push(` ${plan.targets.length} items, ${formatBytes(plan.totalBytes)}`);
224
+ if (plan.sensitiveCount > 0) {
225
+ lines.push(` ${plan.sensitiveCount} contain credentials or live session cookies — ` +
226
+ `these survive \`npm uninstall\`.`);
227
+ }
228
+ if (dryRun) {
229
+ lines.push("");
230
+ lines.push(" This was a dry run. Nothing has been removed.");
231
+ lines.push(" Run `cbrowser uninstall --yes` to remove it.");
232
+ }
233
+ return lines.join("\n");
234
+ }
235
+ //# sourceMappingURL=uninstall.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"uninstall.js","sourceRoot":"","sources":["../src/uninstall.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cbrowser",
3
- "version": "19.0.2",
3
+ "version": "19.1.0",
4
4
  "type": "module",
5
5
  "description": "Cognitive browser automation that thinks like your users—and helps AI agents navigate too. Simulate real user cognition with abandonment detection, constitutional safety, chaos engineering, and UX friction discovery. Sites that pass CBrowser's cognitive tests are easier for both humans and AI agents to navigate.",
6
6
  "main": "dist/index.js",