cbrowser 18.72.6 → 18.73.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 (46) hide show
  1. package/dist/browser/selector-cache.d.ts +11 -0
  2. package/dist/browser/selector-cache.d.ts.map +1 -1
  3. package/dist/browser/selector-cache.js +41 -4
  4. package/dist/browser/selector-cache.js.map +1 -1
  5. package/dist/browser/session-manager.d.ts +10 -3
  6. package/dist/browser/session-manager.d.ts.map +1 -1
  7. package/dist/browser/session-manager.js +38 -7
  8. package/dist/browser/session-manager.js.map +1 -1
  9. package/dist/browser.d.ts.map +1 -1
  10. package/dist/browser.js +28 -4
  11. package/dist/browser.js.map +1 -1
  12. package/dist/cli.js +51 -11
  13. package/dist/cli.js.map +1 -1
  14. package/dist/mcp-server-remote.d.ts +45 -0
  15. package/dist/mcp-server-remote.d.ts.map +1 -1
  16. package/dist/mcp-server-remote.js +323 -54
  17. package/dist/mcp-server-remote.js.map +1 -1
  18. package/dist/mcp-server.d.ts.map +1 -1
  19. package/dist/mcp-server.js +8 -0
  20. package/dist/mcp-server.js.map +1 -1
  21. package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
  22. package/dist/mcp-tools/base/audit-tools.js +8 -4
  23. package/dist/mcp-tools/base/audit-tools.js.map +1 -1
  24. package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
  25. package/dist/mcp-tools/base/persona-comparison-tools.js +0 -2
  26. package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
  27. package/dist/mcp-tools/base/session-tools.js +3 -3
  28. package/dist/mcp-tools/base/session-tools.js.map +1 -1
  29. package/dist/mcp-tools/index.d.ts.map +1 -1
  30. package/dist/mcp-tools/index.js +13 -4
  31. package/dist/mcp-tools/index.js.map +1 -1
  32. package/dist/mcp-tools/security-layer.d.ts +27 -0
  33. package/dist/mcp-tools/security-layer.d.ts.map +1 -0
  34. package/dist/mcp-tools/security-layer.js +145 -0
  35. package/dist/mcp-tools/security-layer.js.map +1 -0
  36. package/dist/output.d.ts +20 -0
  37. package/dist/output.d.ts.map +1 -1
  38. package/dist/output.js +157 -4
  39. package/dist/output.js.map +1 -1
  40. package/dist/site-model/manager.d.ts.map +1 -1
  41. package/dist/site-model/manager.js +27 -3
  42. package/dist/site-model/manager.js.map +1 -1
  43. package/dist/stealth/framework.d.ts.map +1 -1
  44. package/dist/stealth/framework.js +6 -1
  45. package/dist/stealth/framework.js.map +1 -1
  46. package/package.json +4 -2
package/dist/cli.js CHANGED
@@ -36,7 +36,7 @@ import { getLightpandaStatus, LIGHTPANDA_SETUP_GUIDE, LIGHTPANDA_SECURITY_WARNIN
36
36
  // Version from package.json - single source of truth
37
37
  import { VERSION } from "./version.js";
38
38
  // Accessible output system (v18.54.0)
39
- import { detectOutputOptions, setOutputOptions, getOutputOptions, installOutputWrappers, emitJson, } from "./output.js";
39
+ import { detectOutputOptions, setOutputOptions, getOutputOptions, installOutputWrappers, emitJson, emitJsonFallback, } from "./output.js";
40
40
  // Node readline for interactive input
41
41
  import * as readline from "readline";
42
42
  /**
@@ -778,7 +778,9 @@ OPTIONS
778
778
  --locale <locale> Browser locale (e.g., en-US, fr-FR)
779
779
  --timezone <tz> Timezone (e.g., America/New_York)
780
780
  --record-video Enable video recording
781
- --force Bypass red zone safety checks
781
+ --force Bypass red zone safety checks (CLI only; over MCP,
782
+ zone enforcement is opt-in via CBROWSER_ENFORCE_RED_ZONE
783
+ because MCP has no force affordance)
782
784
  --headless Run browser in headless mode
783
785
  --no-persistent Disable persistent browser context (default: enabled)
784
786
  --no-restore Skip session URL restoration (preserves page state after interactions)
@@ -2390,19 +2392,36 @@ async function runDoctor(outputOpts) {
2390
2392
  fix: "Install Node.js 18+ from https://nodejs.org",
2391
2393
  });
2392
2394
  }
2393
- // Check 2: Playwright chromium — verify binary exists without launching a full browser
2395
+ // Check 2: Playwright chromium — the binary must actually be on disk.
2396
+ //
2397
+ // This used to shell out to `npx playwright install --dry-run chromium`, which
2398
+ // only PRINTS the install plan and exits 0 whether or not the browser exists —
2399
+ // so the check could not go red. Demonstrated 2026-07-26: with
2400
+ // PLAYWRIGHT_BROWSERS_PATH=/nonexistent-browsers-xyz the dry-run still exited 0
2401
+ // and doctor still reported "Playwright Chromium: Installed". A health check
2402
+ // that cannot fail is worse than no health check, because it is believed.
2403
+ // executablePath() resolves the path Playwright would actually launch, so an
2404
+ // absent browser now fails the way a missing browser should.
2394
2405
  try {
2395
- execSync("npx playwright install --dry-run chromium 2>&1", {
2396
- encoding: "utf8",
2397
- timeout: 15000,
2398
- });
2399
- checks.push({ name: "Playwright Chromium", status: "pass", message: "Installed" });
2406
+ const { chromium } = await import("playwright");
2407
+ const exe = chromium.executablePath();
2408
+ if (exe && existsSync(exe)) {
2409
+ checks.push({ name: "Playwright Chromium", status: "pass", message: `Installed (${exe})` });
2410
+ }
2411
+ else {
2412
+ checks.push({
2413
+ name: "Playwright Chromium",
2414
+ status: "fail",
2415
+ message: exe ? `Not on disk at ${exe}` : "Playwright reports no chromium executable path",
2416
+ fix: "Run: npx playwright install chromium",
2417
+ });
2418
+ }
2400
2419
  }
2401
- catch {
2420
+ catch (err) {
2402
2421
  checks.push({
2403
2422
  name: "Playwright Chromium",
2404
2423
  status: "fail",
2405
- message: "Not installed or not launchable",
2424
+ message: `Not installed or not resolvable (${err instanceof Error ? err.message : String(err)})`,
2406
2425
  fix: "Run: npx playwright install chromium",
2407
2426
  });
2408
2427
  }
@@ -2444,6 +2463,10 @@ async function runDoctor(outputOpts) {
2444
2463
  meta: { version: VERSION },
2445
2464
  };
2446
2465
  emitJson(jsonResult);
2466
+ // Same rule as the human path below: a failed check must be visible to a
2467
+ // shell, not only to a reader.
2468
+ if (!jsonResult.success)
2469
+ process.exitCode = 1;
2447
2470
  return;
2448
2471
  }
2449
2472
  const passSymbol = outputOpts.plain ? "[PASS]" : "✅";
@@ -2482,6 +2505,13 @@ async function runDoctor(outputOpts) {
2482
2505
  : `❌ ${failCount} check(s) failed. Fix the issues above to use CBrowser.`);
2483
2506
  }
2484
2507
  console.log("");
2508
+ // A health command that reports failures and still exits 0 cannot gate
2509
+ // anything — `cbrowser doctor && deploy` would proceed on a broken
2510
+ // environment, and the project ISA's own probe for this criterion is
2511
+ // "doctor exits 0", which was unfalsifiable as a result. Failures now exit 1;
2512
+ // warnings still exit 0, since a warning is not a broken environment.
2513
+ if (failCount > 0)
2514
+ process.exitCode = 1;
2485
2515
  }
2486
2516
  function parseGeoLocation(location) {
2487
2517
  // Check if it's a preset
@@ -2505,6 +2535,14 @@ async function main() {
2505
2535
  const outputOpts = detectOutputOptions(options);
2506
2536
  setOutputOptions(outputOpts);
2507
2537
  installOutputWrappers();
2538
+ // --json-output must never leave stdout empty. Only two commands in this file
2539
+ // call emitJson, so without this every other command printed nothing at all and
2540
+ // still exited 0 — a CI step piping to jq saw empty input beside a success code.
2541
+ // An exit hook rather than a call after main(): the command paths below exit
2542
+ // through ~20 separate process.exit() sites, and a hook covers all of them.
2543
+ if (outputOpts.json) {
2544
+ process.on("exit", () => emitJsonFallback(command ?? "unknown", VERSION));
2545
+ }
2508
2546
  // `--help`/`-h` are aliases for `help`, matching how `--version`/`-v` alias
2509
2547
  // `version` below. `help <command>` and `<command> --help` both narrow to a
2510
2548
  // single section rather than dumping the whole manual.
@@ -2524,7 +2562,9 @@ async function main() {
2524
2562
  // Doctor command - environment health check (v18.54.0)
2525
2563
  if (command === "doctor") {
2526
2564
  await runDoctor(outputOpts);
2527
- process.exit(0);
2565
+ // Honour the exit code runDoctor set. A hard exit(0) here made the failure
2566
+ // path unreachable from a shell no matter what the checks found.
2567
+ process.exit(process.exitCode ?? 0);
2528
2568
  }
2529
2569
  // MCP Server mode - runs before browser instantiation
2530
2570
  if (command === "mcp-server") {