cbrowser 19.2.0 → 19.2.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 +2 -2
- package/dist/analysis/accessibility-empathy.d.ts +6 -0
- package/dist/analysis/accessibility-empathy.d.ts.map +1 -1
- package/dist/analysis/accessibility-empathy.js +28 -77
- package/dist/analysis/accessibility-empathy.js.map +1 -1
- package/dist/analysis/competitive-benchmark.js +2 -2
- package/dist/analysis/competitive-benchmark.js.map +1 -1
- package/dist/analysis/persona-comparison.d.ts.map +1 -1
- package/dist/analysis/persona-comparison.js +5 -1
- package/dist/analysis/persona-comparison.js.map +1 -1
- package/dist/browser.js +2 -2
- package/dist/browser.js.map +1 -1
- package/dist/cli.js +44 -7
- package/dist/cli.js.map +1 -1
- package/dist/daemon.d.ts +2 -0
- package/dist/daemon.d.ts.map +1 -1
- package/dist/daemon.js +8 -1
- package/dist/daemon.js.map +1 -1
- package/dist/mcp-server-remote.d.ts +3 -0
- package/dist/mcp-server-remote.d.ts.map +1 -1
- package/dist/mcp-server-remote.js +12 -1
- package/dist/mcp-server-remote.js.map +1 -1
- package/dist/mcp-tools/account-personas.d.ts +3 -2
- package/dist/mcp-tools/account-personas.d.ts.map +1 -1
- package/dist/mcp-tools/account-personas.js +13 -4
- package/dist/mcp-tools/account-personas.js.map +1 -1
- package/dist/mcp-tools/base/advanced-interaction-tools.js +1 -1
- package/dist/mcp-tools/base/advanced-interaction-tools.js.map +1 -1
- package/dist/mcp-tools/base/audit-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/audit-tools.js +49 -15
- package/dist/mcp-tools/base/audit-tools.js.map +1 -1
- package/dist/mcp-tools/base/browser-state-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/browser-state-tools.js +25 -4
- package/dist/mcp-tools/base/browser-state-tools.js.map +1 -1
- package/dist/mcp-tools/base/cognitive-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/cognitive-tools.js +14 -2
- package/dist/mcp-tools/base/cognitive-tools.js.map +1 -1
- package/dist/mcp-tools/base/gif-tools.d.ts +19 -0
- package/dist/mcp-tools/base/gif-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/gif-tools.js +53 -24
- package/dist/mcp-tools/base/gif-tools.js.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/persona-comparison-tools.js +44 -28
- package/dist/mcp-tools/base/persona-comparison-tools.js.map +1 -1
- package/dist/mcp-tools/base/values-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/values-tools.js +12 -0
- package/dist/mcp-tools/base/values-tools.js.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.d.ts +17 -0
- package/dist/mcp-tools/base/visual-testing-tools.d.ts.map +1 -1
- package/dist/mcp-tools/base/visual-testing-tools.js +184 -148
- package/dist/mcp-tools/base/visual-testing-tools.js.map +1 -1
- package/dist/mcp-tools/inline-image.d.ts +82 -0
- package/dist/mcp-tools/inline-image.d.ts.map +1 -0
- package/dist/mcp-tools/inline-image.js +163 -0
- package/dist/mcp-tools/inline-image.js.map +1 -0
- package/dist/personas.d.ts +37 -0
- package/dist/personas.d.ts.map +1 -1
- package/dist/personas.js +137 -3
- package/dist/personas.js.map +1 -1
- package/dist/security/audit-wrapper.d.ts.map +1 -1
- package/dist/security/audit-wrapper.js +1 -0
- package/dist/security/audit-wrapper.js.map +1 -1
- package/dist/security/script-gate.d.ts +33 -0
- package/dist/security/script-gate.d.ts.map +1 -0
- package/dist/security/script-gate.js +37 -0
- package/dist/security/script-gate.js.map +1 -0
- package/dist/security/tool-permissions.d.ts.map +1 -1
- package/dist/security/tool-permissions.js +4 -0
- package/dist/security/tool-permissions.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -24,6 +24,7 @@ import { DEVICE_PRESETS, LOCATION_PRESETS } from "./types.js";
|
|
|
24
24
|
import { startMcpServer } from "./mcp-server.js";
|
|
25
25
|
import { startRemoteMcpServer } from "./mcp-server-remote.js";
|
|
26
26
|
import { startDaemon, stopDaemon, getDaemonStatus, isDaemonRunning, sendToDaemon, runDaemonServer } from "./daemon.js";
|
|
27
|
+
import { evaluateScriptRefusal } from "./security/script-gate.js";
|
|
27
28
|
import { getStatusInfo, formatStatus, getDataDir, getPaths } from "./config.js";
|
|
28
29
|
import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, unlinkSync, writeFileSync } from "node:fs";
|
|
29
30
|
import { resolveCookieDomain, hostFromUrl } from "./utils.js";
|
|
@@ -105,6 +106,9 @@ EXTRACTION
|
|
|
105
106
|
|
|
106
107
|
SCRIPTING
|
|
107
108
|
evaluate "<js>" Run JavaScript in the page and print the result
|
|
109
|
+
--force Required: page script is red zone (it can click,
|
|
110
|
+
submit or delete without the element gate), so
|
|
111
|
+
evaluate refuses and runs nothing without it
|
|
108
112
|
--file <path> Read the script from a file instead of argv
|
|
109
113
|
--arg <json> Argument for the script (repeatable, JSON-typed)
|
|
110
114
|
--json Always print JSON
|
|
@@ -112,9 +116,9 @@ SCRIPTING
|
|
|
112
116
|
--wait-for <selector> Wait for the selector before evaluating
|
|
113
117
|
--expect-truthy Exit 1 when the result is falsy (CI assertion)
|
|
114
118
|
Examples:
|
|
115
|
-
cbrowser evaluate "document.title"
|
|
116
|
-
cbrowser evaluate --file check.js --arg '"#main"' --expect-truthy
|
|
117
|
-
cbrowser evaluate "(sel) => !!document.querySelector(sel)" --arg '"nav"'
|
|
119
|
+
cbrowser evaluate "document.title" --force
|
|
120
|
+
cbrowser evaluate --file check.js --arg '"#main"' --expect-truthy --force
|
|
121
|
+
cbrowser evaluate "(sel) => !!document.querySelector(sel)" --arg '"nav"' --force
|
|
118
122
|
|
|
119
123
|
KEYBOARD
|
|
120
124
|
keyboard <token> [token...] Send a key sequence: chords, keys and text
|
|
@@ -995,8 +999,8 @@ const COMMAND_FLAGS = {
|
|
|
995
999
|
// this command deletes credentials, so "--kep-config did nothing" is a bad
|
|
996
1000
|
// way to find out.
|
|
997
1001
|
uninstall: ["yes", "keep-config"],
|
|
998
|
-
evaluate: ["file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy"],
|
|
999
|
-
eval: ["file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy"],
|
|
1002
|
+
evaluate: ["file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy", "force"],
|
|
1003
|
+
eval: ["file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy", "force"],
|
|
1000
1004
|
keyboard: ["delay", "selector", "hold", "repeat", "text", "force"],
|
|
1001
1005
|
"test-suite": [
|
|
1002
1006
|
"capture", "capture-fps", "capture-format", "capture-out",
|
|
@@ -1740,10 +1744,23 @@ function reportAutoCapture(capture) {
|
|
|
1740
1744
|
// =========================================================================
|
|
1741
1745
|
/** Flags `evaluate` understands; anything else is rejected rather than ignored. */
|
|
1742
1746
|
const EVALUATE_FLAGS = new Set([
|
|
1743
|
-
"file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy",
|
|
1747
|
+
"file", "arg", "json", "raw", "wait-for", "timeout", "expect-truthy", "force",
|
|
1744
1748
|
"url", "browser", "device", "headless", "persistent", "restore",
|
|
1745
1749
|
"locale", "timezone", "geo", "verbose",
|
|
1746
1750
|
]);
|
|
1751
|
+
/**
|
|
1752
|
+
* `--force` is a bare flag, but the parser gives any flag the next non-flag
|
|
1753
|
+
* word as its value, so `evaluate --force "document.title"` reads the SCRIPT as
|
|
1754
|
+
* the value of --force and leaves no script. The gate would refuse it anyway
|
|
1755
|
+
* (only `true` opens it); this says why instead of a confusing refusal.
|
|
1756
|
+
*/
|
|
1757
|
+
function rejectForceValue(options) {
|
|
1758
|
+
if (typeof options.force === "string") {
|
|
1759
|
+
console.error(`Error: --force takes no value, so "${options.force}" was read as one.`);
|
|
1760
|
+
console.error(' Put the script first: cbrowser evaluate "<javascript>" --force');
|
|
1761
|
+
process.exit(1);
|
|
1762
|
+
}
|
|
1763
|
+
}
|
|
1747
1764
|
/**
|
|
1748
1765
|
* Collect a repeatable flag's values.
|
|
1749
1766
|
*
|
|
@@ -1828,6 +1845,7 @@ async function runEvaluate(browser, args, options) {
|
|
|
1828
1845
|
console.error("Error: --json and --raw are mutually exclusive - pick one");
|
|
1829
1846
|
process.exit(1);
|
|
1830
1847
|
}
|
|
1848
|
+
rejectForceValue(options);
|
|
1831
1849
|
const fromFile = typeof options.file === "string";
|
|
1832
1850
|
if (fromFile && args[0]) {
|
|
1833
1851
|
console.error("Error: pass the script as an argument OR --file, not both");
|
|
@@ -1875,6 +1893,16 @@ async function runEvaluate(browser, args, options) {
|
|
|
1875
1893
|
process.exit(1);
|
|
1876
1894
|
}
|
|
1877
1895
|
});
|
|
1896
|
+
// Red zone, refused before the page is touched: no navigation, no wait, no
|
|
1897
|
+
// script. A script can click what click refuses (src/security/script-gate.ts).
|
|
1898
|
+
const refusal = evaluateScriptRefusal(options.force === true);
|
|
1899
|
+
if (refusal) {
|
|
1900
|
+
console.error(`✗ ${refusal}`);
|
|
1901
|
+
console.error(" Re-run with --force to run it anyway.");
|
|
1902
|
+
process.exit(1);
|
|
1903
|
+
}
|
|
1904
|
+
// Said on stderr so stdout stays exactly the result (--raw / --json pipes).
|
|
1905
|
+
console.error("⚠ Red zone: running caller-supplied page script (--force)");
|
|
1878
1906
|
if (options.url)
|
|
1879
1907
|
await browser.navigate(options.url);
|
|
1880
1908
|
const page = await browser.getPage();
|
|
@@ -2932,6 +2960,7 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
|
|
|
2932
2960
|
case "eval":
|
|
2933
2961
|
case "evaluate": {
|
|
2934
2962
|
validateCommandFlags(command, options);
|
|
2963
|
+
rejectForceValue(options);
|
|
2935
2964
|
const script = typeof options.file === "string"
|
|
2936
2965
|
? readFileSync(resolve(options.file), "utf-8")
|
|
2937
2966
|
: args[0];
|
|
@@ -2939,7 +2968,15 @@ Documentation: https://github.com/alexandriashai/cbrowser/wiki
|
|
|
2939
2968
|
console.error('Usage: cbrowser evaluate "<javascript>" | --file <path>');
|
|
2940
2969
|
process.exit(1);
|
|
2941
2970
|
}
|
|
2942
|
-
|
|
2971
|
+
// Refused here, before the request leaves, and again daemon-side
|
|
2972
|
+
// (anything on this machine can POST to the daemon).
|
|
2973
|
+
const refusal = evaluateScriptRefusal(options.force === true);
|
|
2974
|
+
if (refusal) {
|
|
2975
|
+
console.error(`✗ ${refusal}`);
|
|
2976
|
+
console.error(" Re-run with --force to run it anyway.");
|
|
2977
|
+
process.exit(1);
|
|
2978
|
+
}
|
|
2979
|
+
daemonArgs = { body: `return (function(){ ${/\breturn\b/.test(script) ? script : `return (${script});`} })();`, args: [], force: true };
|
|
2943
2980
|
break;
|
|
2944
2981
|
}
|
|
2945
2982
|
case "screenshot": {
|