browser-debugger-cli 0.12.0 → 0.14.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.
- package/.claude/skills/bdg/SKILL.md +100 -186
- package/README.md +5 -4
- package/dist/commands/cdp.d.ts +22 -1
- package/dist/commands/cdp.js +100 -43
- package/dist/commands/console.d.ts +12 -0
- package/dist/commands/console.js +67 -13
- package/dist/commands/dom/DomElementResolver.d.ts +3 -1
- package/dist/commands/dom/DomElementResolver.js +10 -3
- package/dist/commands/dom/a11y.d.ts +1 -1
- package/dist/commands/dom/a11y.js +23 -22
- package/dist/commands/dom/eval.d.ts +4 -2
- package/dist/commands/dom/eval.js +31 -7
- package/dist/commands/dom/form.js +10 -9
- package/dist/commands/dom/formInteraction.js +9 -8
- package/dist/commands/dom/get.js +32 -14
- package/dist/commands/dom/helpers/index.d.ts +1 -1
- package/dist/commands/dom/helpers/index.js +1 -1
- package/dist/commands/dom/helpers/query.d.ts +27 -3
- package/dist/commands/dom/helpers/query.js +152 -64
- package/dist/commands/dom/helpers/screenshot.js +13 -13
- package/dist/commands/dom/index.js +10 -3
- package/dist/commands/dom/query.d.ts +20 -2
- package/dist/commands/dom/query.js +39 -6
- package/dist/commands/dom/screenshot.js +3 -1
- package/dist/commands/dom/semanticUtils.d.ts +3 -2
- package/dist/commands/dom/semanticUtils.js +40 -9
- package/dist/commands/helpJson.d.ts +82 -19
- package/dist/commands/helpJson.js +112 -41
- package/dist/commands/helpTopic.d.ts +16 -1
- package/dist/commands/helpTopic.js +59 -1
- package/dist/commands/installSkill.d.ts +15 -5
- package/dist/commands/installSkill.js +86 -16
- package/dist/commands/network/list.js +65 -12
- package/dist/commands/optionBehaviors.d.ts +25 -2
- package/dist/commands/optionBehaviors.js +81 -46
- package/dist/commands/peek.js +3 -0
- package/dist/commands/shared/CommandRunner.js +13 -13
- package/dist/commands/shared/daemonErrorHandler.d.ts +5 -2
- package/dist/commands/shared/daemonErrorHandler.js +21 -10
- package/dist/commands/shared/dataFetcher.d.ts +14 -4
- package/dist/commands/shared/dataFetcher.js +20 -4
- package/dist/commands/shared/followMode.d.ts +9 -1
- package/dist/commands/shared/followMode.js +22 -4
- package/dist/commands/shared/handleValidationError.js +3 -3
- package/dist/commands/shared/optionTypes.d.ts +17 -3
- package/dist/commands/shared/outputFile.js +6 -1
- package/dist/commands/shared/startHelpers.js +3 -3
- package/dist/commands/start.d.ts +7 -5
- package/dist/commands/start.js +65 -21
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.js +24 -1
- package/dist/commands.js +1 -1
- package/dist/connection/cdp.d.ts +7 -0
- package/dist/connection/cdp.js +9 -0
- package/dist/connection/chromeIdentity.d.ts +8 -2
- package/dist/connection/chromeIdentity.js +85 -13
- package/dist/connection/launcher.js +3 -2
- package/dist/constants.d.ts +29 -1
- package/dist/constants.js +35 -1
- package/dist/daemon/SessionController.js +8 -1
- package/dist/daemon/launcher.d.ts +3 -2
- package/dist/daemon/launcher.js +47 -3
- package/dist/daemon/session/Session.d.ts +5 -1
- package/dist/daemon/session/Session.js +42 -3
- package/dist/daemon/session/TelemetryStore.d.ts +15 -1
- package/dist/daemon/session/TelemetryStore.js +19 -1
- package/dist/daemon/session/commandRegistry.js +52 -18
- package/dist/daemon/session/interactions.d.ts +2 -1
- package/dist/daemon/session/interactions.js +13 -1
- package/dist/daemon/session/matchedStylesReset.d.ts +26 -0
- package/dist/daemon/session/matchedStylesReset.js +46 -0
- package/dist/daemon/session/plugins.js +17 -2
- package/dist/daemon/session/teardown.js +1 -1
- package/dist/daemon/session/triggeredRequests.d.ts +0 -5
- package/dist/daemon/session/triggeredRequests.js +13 -7
- package/dist/daemon.js +2385 -1229
- package/dist/errors/messages.d.ts +62 -11
- package/dist/errors/messages.js +119 -22
- package/dist/index.js +14995 -9866
- package/dist/ipc/client.d.ts +18 -2
- package/dist/ipc/client.js +26 -5
- package/dist/ipc/protocol/auditTypes.d.ts +8 -2
- package/dist/ipc/protocol/commands.d.ts +16 -0
- package/dist/ipc/protocol/domTypes.d.ts +12 -0
- package/dist/ipc/protocol/inspectTypes.d.ts +7 -2
- package/dist/ipc/session/types.d.ts +7 -1
- package/dist/program.d.ts +14 -0
- package/dist/program.js +53 -0
- package/dist/runtime/dom/actionEffects.d.ts +5 -1
- package/dist/runtime/dom/actionEffects.js +26 -14
- package/dist/runtime/dom/audit.js +3 -2
- package/dist/runtime/dom/auditModel.js +6 -1
- package/dist/runtime/dom/auditScripts.d.ts +9 -3
- package/dist/runtime/dom/auditScripts.js +41 -5
- package/dist/runtime/dom/elementGeometry.d.ts +33 -3
- package/dist/runtime/dom/elementGeometry.js +44 -19
- package/dist/runtime/dom/elementInfo.d.ts +76 -18
- package/dist/runtime/dom/elementInfo.js +190 -40
- package/dist/runtime/dom/evalHelpers.d.ts +12 -2
- package/dist/runtime/dom/evalHelpers.js +67 -7
- package/dist/runtime/dom/formDiscovery.d.ts +6 -2
- package/dist/runtime/dom/formDiscovery.js +20 -3
- package/dist/runtime/dom/formFillHelpers/fill.js +7 -11
- package/dist/runtime/dom/formFillHelpers/pressKey.js +2 -2
- package/dist/runtime/dom/formFillHelpers/shared.d.ts +16 -10
- package/dist/runtime/dom/formFillHelpers/shared.js +19 -52
- package/dist/runtime/dom/formSubmitHelpers.js +4 -3
- package/dist/runtime/dom/frameLayout.js +1 -0
- package/dist/runtime/dom/frameScopedConnection.d.ts +7 -0
- package/dist/runtime/dom/frameScopedConnection.js +2 -2
- package/dist/runtime/dom/inspect.d.ts +17 -3
- package/dist/runtime/dom/inspect.js +45 -32
- package/dist/runtime/dom/inspectAllStyles.js +1 -0
- package/dist/runtime/dom/inspectHints.d.ts +1 -1
- package/dist/runtime/dom/inspectModel.d.ts +5 -4
- package/dist/runtime/dom/inspectModel.js +7 -3
- package/dist/runtime/dom/inspectPaintModel.d.ts +2 -0
- package/dist/runtime/dom/inspectPaintModel.js +3 -1
- package/dist/runtime/dom/inspectRules.d.ts +29 -3
- package/dist/runtime/dom/inspectRules.js +205 -11
- package/dist/runtime/dom/inspectScripts.d.ts +29 -2
- package/dist/runtime/dom/inspectScripts.js +49 -10
- package/dist/runtime/dom/layout.d.ts +0 -2
- package/dist/runtime/dom/layout.js +10 -9
- package/dist/runtime/dom/reactEventHelpers.d.ts +17 -4
- package/dist/runtime/dom/reactEventHelpers.js +71 -28
- package/dist/runtime/dom/targetNode.d.ts +27 -10
- package/dist/runtime/dom/targetNode.js +283 -16
- package/dist/runtime/dom/wait.js +2 -1
- package/dist/runtime/page/bdgWorld.d.ts +57 -0
- package/dist/runtime/page/bdgWorld.js +180 -0
- package/dist/runtime/page/replacedBuiltins.d.ts +28 -0
- package/dist/runtime/page/replacedBuiltins.js +136 -0
- package/dist/session/QueryCacheManager.d.ts +4 -1
- package/dist/session/QueryCacheManager.js +5 -2
- package/dist/session/chrome.d.ts +4 -1
- package/dist/session/chrome.js +7 -1
- package/dist/session/cleanup/staleSession.d.ts +21 -4
- package/dist/session/cleanup/staleSession.js +79 -9
- package/dist/session/cleanup/userCommands.d.ts +4 -1
- package/dist/session/cleanup/userCommands.js +10 -5
- package/dist/session/daemonSocket.d.ts +10 -0
- package/dist/session/daemonSocket.js +22 -0
- package/dist/session/lastSession.d.ts +6 -3
- package/dist/session/lastSession.js +11 -5
- package/dist/session/paths.d.ts +3 -1
- package/dist/session/paths.js +5 -5
- package/dist/session/portClaims.js +4 -3
- package/dist/session/sessionList.d.ts +13 -5
- package/dist/session/sessionList.js +31 -7
- package/dist/telemetry/a11y.d.ts +15 -1
- package/dist/telemetry/a11y.js +85 -2
- package/dist/telemetry/console.d.ts +2 -1
- package/dist/telemetry/console.js +30 -21
- package/dist/telemetry/har/builder.js +1 -1
- package/dist/telemetry/network.d.ts +13 -16
- package/dist/telemetry/network.js +30 -52
- package/dist/telemetry/networkRetention.d.ts +83 -0
- package/dist/telemetry/networkRetention.js +117 -0
- package/dist/telemetry/pageCrash.d.ts +26 -0
- package/dist/telemetry/pageCrash.js +53 -0
- package/dist/types.d.ts +42 -0
- package/dist/ui/OutputBuilder.d.ts +10 -0
- package/dist/ui/OutputBuilder.js +12 -0
- package/dist/ui/formatters/a11y.d.ts +5 -7
- package/dist/ui/formatters/a11y.js +7 -61
- package/dist/ui/formatters/audit.js +14 -5
- package/dist/ui/formatters/cdp.d.ts +138 -0
- package/dist/ui/formatters/cdp.js +131 -0
- package/dist/ui/formatters/console/chronological.js +7 -5
- package/dist/ui/formatters/console/follow.d.ts +5 -2
- package/dist/ui/formatters/console/follow.js +7 -4
- package/dist/ui/formatters/console/json.d.ts +4 -7
- package/dist/ui/formatters/console/json.js +16 -14
- package/dist/ui/formatters/console/shared.d.ts +47 -2
- package/dist/ui/formatters/console/shared.js +33 -0
- package/dist/ui/formatters/console/summarize.d.ts +9 -2
- package/dist/ui/formatters/console/summarize.js +57 -11
- package/dist/ui/formatters/console.d.ts +3 -2
- package/dist/ui/formatters/console.js +8 -10
- package/dist/ui/formatters/details.js +4 -2
- package/dist/ui/formatters/dom.d.ts +14 -5
- package/dist/ui/formatters/dom.js +30 -13
- package/dist/ui/formatters/helpFormatters.js +1 -1
- package/dist/ui/formatters/inspect.js +9 -3
- package/dist/ui/formatters/installSkill.d.ts +9 -1
- package/dist/ui/formatters/installSkill.js +32 -6
- package/dist/ui/formatters/layout.js +4 -2
- package/dist/ui/formatters/longValues.d.ts +14 -0
- package/dist/ui/formatters/longValues.js +23 -0
- package/dist/ui/formatters/networkList.d.ts +8 -2
- package/dist/ui/formatters/networkList.js +11 -3
- package/dist/ui/formatters/preview.d.ts +6 -1
- package/dist/ui/formatters/preview.js +67 -15
- package/dist/ui/formatters/sessions.d.ts +2 -2
- package/dist/ui/formatters/sessions.js +9 -2
- package/dist/ui/formatters/status.js +7 -0
- package/dist/ui/formatters/triggeredRequests.js +2 -1
- package/dist/ui/logging/logger.d.ts +1 -1
- package/dist/ui/messages/chrome.d.ts +20 -1
- package/dist/ui/messages/chrome.js +29 -3
- package/dist/ui/messages/commands.d.ts +153 -12
- package/dist/ui/messages/commands.js +198 -15
- package/dist/ui/messages/consoleMessages.d.ts +24 -0
- package/dist/ui/messages/consoleMessages.js +32 -0
- package/dist/ui/messages/networkMessages.d.ts +24 -0
- package/dist/ui/messages/networkMessages.js +45 -0
- package/dist/ui/messages/preview.d.ts +6 -0
- package/dist/ui/messages/preview.js +9 -1
- package/dist/ui/messages/session.d.ts +13 -2
- package/dist/ui/messages/session.js +22 -3
- package/dist/utils/directories.d.ts +34 -0
- package/dist/utils/directories.js +88 -0
- package/dist/utils/display.d.ts +16 -0
- package/dist/utils/display.js +42 -0
- package/dist/utils/exitCodes.d.ts +1 -0
- package/dist/utils/exitCodes.js +6 -0
- package/dist/utils/http.d.ts +9 -2
- package/dist/utils/http.js +4 -3
- package/dist/utils/process.d.ts +12 -0
- package/dist/utils/process.js +25 -0
- package/dist/utils/strings.d.ts +19 -0
- package/dist/utils/strings.js +16 -0
- package/package.json +2 -2
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks for a directory bdg is about to create and write (the session
|
|
3
|
+
* directory, a Chrome profile) before it touches it: `fs.mkdirSync` with
|
|
4
|
+
* `recursive` spins forever on Linux pseudo-filesystems (`/proc/x` kept a
|
|
5
|
+
* start at full CPU until SIGKILL), and a profile Chrome cannot use wedges
|
|
6
|
+
* the session.
|
|
7
|
+
*/
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
/** Pseudo-filesystems no directory can be created on */
|
|
11
|
+
const PSEUDO_FILESYSTEM = /^\/(proc|sys)(\/|$)/;
|
|
12
|
+
/**
|
|
13
|
+
* Nearest path at or above `dir` that exists.
|
|
14
|
+
*
|
|
15
|
+
* @param dir - Absolute path
|
|
16
|
+
* @returns The path itself, or its nearest existing ancestor
|
|
17
|
+
*/
|
|
18
|
+
function nearestExisting(dir) {
|
|
19
|
+
let current = dir;
|
|
20
|
+
while (!fs.existsSync(current)) {
|
|
21
|
+
const parent = path.dirname(current);
|
|
22
|
+
if (parent === current)
|
|
23
|
+
return current;
|
|
24
|
+
current = parent;
|
|
25
|
+
}
|
|
26
|
+
return current;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Why `dir` cannot be created or written: it (or the path to it) is on a
|
|
30
|
+
* pseudo-filesystem, a part of it is a file, or its nearest existing
|
|
31
|
+
* directory is not writable.
|
|
32
|
+
*
|
|
33
|
+
* @param dir - Directory path (resolved against the working directory)
|
|
34
|
+
* @returns The problem, or null when the directory can be used
|
|
35
|
+
*/
|
|
36
|
+
export function directoryProblem(dir) {
|
|
37
|
+
const resolved = path.resolve(dir);
|
|
38
|
+
const existing = nearestExisting(resolved);
|
|
39
|
+
let real;
|
|
40
|
+
try {
|
|
41
|
+
real = fs.realpathSync(existing);
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
return { reason: error.code ?? String(error), denied: false };
|
|
45
|
+
}
|
|
46
|
+
if (PSEUDO_FILESYSTEM.test(resolved) || PSEUDO_FILESYSTEM.test(real)) {
|
|
47
|
+
const root = (PSEUDO_FILESYSTEM.exec(resolved) ?? PSEUDO_FILESYSTEM.exec(real))?.[0] ?? '';
|
|
48
|
+
return { reason: `${root.replace(/\/$/, '')} is a pseudo-filesystem`, denied: false };
|
|
49
|
+
}
|
|
50
|
+
if (!fs.statSync(real).isDirectory()) {
|
|
51
|
+
return {
|
|
52
|
+
reason: existing === resolved ? 'it is a file' : `${existing} is a file`,
|
|
53
|
+
denied: false,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
try {
|
|
57
|
+
fs.accessSync(real, fs.constants.W_OK);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
const code = error.code ?? String(error);
|
|
61
|
+
return { reason: `${existing} is not writable (${code})`, denied: true };
|
|
62
|
+
}
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Create a directory (and its parents) after {@link directoryProblem} found
|
|
67
|
+
* nothing wrong, so a pseudo-filesystem fails at once instead of spinning.
|
|
68
|
+
*
|
|
69
|
+
* @param dir - Directory to create
|
|
70
|
+
* @param mode - Permissions of the directories created
|
|
71
|
+
* @throws Error with `code` `EPSEUDOFS` (pseudo-filesystem), `ENOTDIR` (a
|
|
72
|
+
* file on the path), `EACCES` (not writable), or the `mkdir` error
|
|
73
|
+
*/
|
|
74
|
+
export function makeDirectory(dir, mode) {
|
|
75
|
+
if (fs.existsSync(dir))
|
|
76
|
+
return;
|
|
77
|
+
const problem = directoryProblem(dir);
|
|
78
|
+
if (problem) {
|
|
79
|
+
const code = problem.denied
|
|
80
|
+
? 'EACCES'
|
|
81
|
+
: /pseudo-filesystem/.test(problem.reason)
|
|
82
|
+
? 'EPSEUDOFS'
|
|
83
|
+
: 'ENOTDIR';
|
|
84
|
+
throw Object.assign(new Error(problem.reason), { code });
|
|
85
|
+
}
|
|
86
|
+
fs.mkdirSync(dir, { recursive: true, ...(mode !== undefined && { mode }) });
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=directories.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether Chrome can show a window, which decides the default of
|
|
3
|
+
* `--headless`.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether a display is available for Chrome's window: on Linux an X11 or
|
|
7
|
+
* Wayland display (`DISPLAY`, `WAYLAND_DISPLAY`; WSLg sets them too), on
|
|
8
|
+
* macOS the desktop unless the shell came in over SSH (`SSH_CONNECTION`,
|
|
9
|
+
* `SSH_TTY`) or runs in CI (`CI`, unless `false` or `0`). Servers, containers and CI stay headless.
|
|
10
|
+
*
|
|
11
|
+
* @param env - Environment variables
|
|
12
|
+
* @param platform - Operating system (`process.platform`)
|
|
13
|
+
* @returns True when Chrome should show a window by default
|
|
14
|
+
*/
|
|
15
|
+
export declare function hasDisplay(env?: NodeJS.ProcessEnv, platform?: NodeJS.Platform): boolean;
|
|
16
|
+
//# sourceMappingURL=display.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether Chrome can show a window, which decides the default of
|
|
3
|
+
* `--headless`.
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* Whether an environment variable is set and not empty.
|
|
7
|
+
*
|
|
8
|
+
* @param env - Environment variables
|
|
9
|
+
* @param name - Variable name
|
|
10
|
+
* @returns True when set to a non-empty value
|
|
11
|
+
*/
|
|
12
|
+
function isSet(env, name) {
|
|
13
|
+
const value = env[name];
|
|
14
|
+
return value !== undefined && value !== '';
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Whether the environment says it is CI: `CI` set to anything but `false`
|
|
18
|
+
* or `0` (`CI=false` is how a CI flag is turned off).
|
|
19
|
+
*
|
|
20
|
+
* @param env - Environment variables
|
|
21
|
+
* @returns True in CI
|
|
22
|
+
*/
|
|
23
|
+
function isCi(env) {
|
|
24
|
+
return isSet(env, 'CI') && !['false', '0'].includes(env['CI']?.toLowerCase() ?? '');
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Whether a display is available for Chrome's window: on Linux an X11 or
|
|
28
|
+
* Wayland display (`DISPLAY`, `WAYLAND_DISPLAY`; WSLg sets them too), on
|
|
29
|
+
* macOS the desktop unless the shell came in over SSH (`SSH_CONNECTION`,
|
|
30
|
+
* `SSH_TTY`) or runs in CI (`CI`, unless `false` or `0`). Servers, containers and CI stay headless.
|
|
31
|
+
*
|
|
32
|
+
* @param env - Environment variables
|
|
33
|
+
* @param platform - Operating system (`process.platform`)
|
|
34
|
+
* @returns True when Chrome should show a window by default
|
|
35
|
+
*/
|
|
36
|
+
export function hasDisplay(env = process.env, platform = process.platform) {
|
|
37
|
+
if (platform === 'darwin') {
|
|
38
|
+
return !isSet(env, 'SSH_CONNECTION') && !isSet(env, 'SSH_TTY') && !isCi(env);
|
|
39
|
+
}
|
|
40
|
+
return isSet(env, 'DISPLAY') || isSet(env, 'WAYLAND_DISPLAY');
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=display.js.map
|
|
@@ -53,6 +53,7 @@ export declare const EXIT_CODES: {
|
|
|
53
53
|
readonly UNHANDLED_EXCEPTION: 104;
|
|
54
54
|
readonly SIGNAL_HANDLER_ERROR: 105;
|
|
55
55
|
readonly SESSION_START_FAILURE: 106;
|
|
56
|
+
readonly PAGE_CRASHED: 107;
|
|
56
57
|
readonly SOFTWARE_ERROR: 110;
|
|
57
58
|
readonly INTERRUPTED: 130;
|
|
58
59
|
readonly TERMINATED: 143;
|
package/dist/utils/exitCodes.js
CHANGED
|
@@ -53,6 +53,7 @@ export const EXIT_CODES = {
|
|
|
53
53
|
UNHANDLED_EXCEPTION: 104,
|
|
54
54
|
SIGNAL_HANDLER_ERROR: 105,
|
|
55
55
|
SESSION_START_FAILURE: 106,
|
|
56
|
+
PAGE_CRASHED: 107,
|
|
56
57
|
SOFTWARE_ERROR: 110,
|
|
57
58
|
INTERRUPTED: 130,
|
|
58
59
|
TERMINATED: 143,
|
|
@@ -165,6 +166,11 @@ export const EXIT_CODE_REGISTRY = [
|
|
|
165
166
|
name: 'SESSION_START_FAILURE',
|
|
166
167
|
description: 'Session failed to start (Chrome launch or CDP connection)',
|
|
167
168
|
},
|
|
169
|
+
{
|
|
170
|
+
code: EXIT_CODES.PAGE_CRASHED,
|
|
171
|
+
name: 'PAGE_CRASHED',
|
|
172
|
+
description: 'The page crashed (its renderer is gone); bdg page reload brings it back',
|
|
173
|
+
},
|
|
168
174
|
{
|
|
169
175
|
code: EXIT_CODES.SOFTWARE_ERROR,
|
|
170
176
|
name: 'SOFTWARE_ERROR',
|
package/dist/utils/http.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { CDPTarget } from '../types.js';
|
|
2
2
|
import type { Logger } from '../ui/logging/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* Timeout for CDP HTTP requests in milliseconds.
|
|
5
|
+
*
|
|
6
|
+
* Chrome's HTTP API should respond quickly when running.
|
|
7
|
+
* A 5-second timeout helps detect when Chrome is not responding.
|
|
8
|
+
*/
|
|
9
|
+
export declare const CDP_HTTP_TIMEOUT_MS = 5000;
|
|
3
10
|
/**
|
|
4
11
|
* Options for CDP HTTP target fetch.
|
|
5
12
|
*/
|
|
@@ -47,10 +54,10 @@ export type DevToolsProbe = {
|
|
|
47
54
|
*
|
|
48
55
|
* @param port - Chrome debugging port
|
|
49
56
|
* @param logger - Optional logger for debug output
|
|
50
|
-
* @param options - Host and
|
|
57
|
+
* @param options - Host, HTTPS and request timeout
|
|
51
58
|
* @returns What answered
|
|
52
59
|
*/
|
|
53
|
-
export declare function probeDevToolsEndpoint(port: number, logger?: Logger, options?:
|
|
60
|
+
export declare function probeDevToolsEndpoint(port: number, logger?: Logger, options?: FetchCDPTargetsOptions): Promise<DevToolsProbe>;
|
|
54
61
|
/**
|
|
55
62
|
* The browser-level DevTools WebSocket URL of a Chrome (`/json/version`).
|
|
56
63
|
*
|
package/dist/utils/http.js
CHANGED
|
@@ -6,7 +6,7 @@ import { getErrorMessage } from './errors.js';
|
|
|
6
6
|
* Chrome's HTTP API should respond quickly when running.
|
|
7
7
|
* A 5-second timeout helps detect when Chrome is not responding.
|
|
8
8
|
*/
|
|
9
|
-
const CDP_HTTP_TIMEOUT_MS = 5000;
|
|
9
|
+
export const CDP_HTTP_TIMEOUT_MS = 5000;
|
|
10
10
|
/**
|
|
11
11
|
* Fetch CDP targets from Chrome's HTTP API.
|
|
12
12
|
*
|
|
@@ -67,14 +67,15 @@ export async function fetchCDPTargets(port = DEFAULT_CDP_PORT, logger, options)
|
|
|
67
67
|
*
|
|
68
68
|
* @param port - Chrome debugging port
|
|
69
69
|
* @param logger - Optional logger for debug output
|
|
70
|
-
* @param options - Host and
|
|
70
|
+
* @param options - Host, HTTPS and request timeout
|
|
71
71
|
* @returns What answered
|
|
72
72
|
*/
|
|
73
73
|
export async function probeDevToolsEndpoint(port, logger, options) {
|
|
74
74
|
const url = `${options?.secure ? 'https' : 'http'}://${options?.host ?? HTTP_LOCALHOST}:${port}/json/version`;
|
|
75
|
+
const timeoutMs = options?.timeoutMs ?? CDP_HTTP_TIMEOUT_MS;
|
|
75
76
|
let response;
|
|
76
77
|
try {
|
|
77
|
-
response = await fetch(url, { signal: AbortSignal.timeout(
|
|
78
|
+
response = await fetch(url, { signal: AbortSignal.timeout(timeoutMs) });
|
|
78
79
|
}
|
|
79
80
|
catch (error) {
|
|
80
81
|
logger?.debug(`Chrome version request failed: ${getErrorMessage(error)} (${url})`);
|
package/dist/utils/process.d.ts
CHANGED
|
@@ -52,4 +52,16 @@ export declare function killChromeProcess(pid: number, signal?: NodeJS.Signals):
|
|
|
52
52
|
* @returns Command line, or null if unavailable (process gone, or unsupported platform)
|
|
53
53
|
*/
|
|
54
54
|
export declare function getProcessCommand(pid: number): string | null;
|
|
55
|
+
/** A running process and its command line */
|
|
56
|
+
export interface ProcessEntry {
|
|
57
|
+
pid: number;
|
|
58
|
+
command: string;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Every running process with its command line: from `/proc` on Linux
|
|
62
|
+
* (minimal containers' BusyBox `ps` lacks `-o`), else from `ps` (macOS).
|
|
63
|
+
*
|
|
64
|
+
* @returns Processes, empty when they cannot be listed (Windows)
|
|
65
|
+
*/
|
|
66
|
+
export declare function listProcesses(): ProcessEntry[];
|
|
55
67
|
//# sourceMappingURL=process.d.ts.map
|
package/dist/utils/process.js
CHANGED
|
@@ -120,4 +120,29 @@ export function getProcessCommand(pid) {
|
|
|
120
120
|
const command = result.stdout.trim();
|
|
121
121
|
return command.length > 0 ? command : null;
|
|
122
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Every running process with its command line: from `/proc` on Linux
|
|
125
|
+
* (minimal containers' BusyBox `ps` lacks `-o`), else from `ps` (macOS).
|
|
126
|
+
*
|
|
127
|
+
* @returns Processes, empty when they cannot be listed (Windows)
|
|
128
|
+
*/
|
|
129
|
+
export function listProcesses() {
|
|
130
|
+
if (process.platform === 'win32')
|
|
131
|
+
return [];
|
|
132
|
+
if (fs.existsSync('/proc/self/cmdline')) {
|
|
133
|
+
return fs
|
|
134
|
+
.readdirSync('/proc')
|
|
135
|
+
.filter((name) => /^\d+$/.test(name))
|
|
136
|
+
.map((name) => ({ pid: Number(name), command: getProcessCommand(Number(name)) ?? '' }))
|
|
137
|
+
.filter((entry) => entry.command !== '');
|
|
138
|
+
}
|
|
139
|
+
const result = spawnSync('ps', ['-A', '-ww', '-o', 'pid=,command='], { encoding: 'utf-8' });
|
|
140
|
+
if (result.error || result.status !== 0)
|
|
141
|
+
return [];
|
|
142
|
+
return result.stdout
|
|
143
|
+
.split('\n')
|
|
144
|
+
.map((line) => /^\s*(\d+)\s+(.*)$/.exec(line))
|
|
145
|
+
.filter((match) => match !== null)
|
|
146
|
+
.map(([, pid, command]) => ({ pid: Number(pid), command: command ?? '' }));
|
|
147
|
+
}
|
|
123
148
|
//# sourceMappingURL=process.js.map
|
package/dist/utils/strings.d.ts
CHANGED
|
@@ -11,4 +11,23 @@
|
|
|
11
11
|
* @returns Truncated text with ellipsis if needed
|
|
12
12
|
*/
|
|
13
13
|
export declare function truncateByLength(text: string, maxLength?: number): string;
|
|
14
|
+
/**
|
|
15
|
+
* A text cut to a maximum length, with its original length when it was cut.
|
|
16
|
+
*/
|
|
17
|
+
export interface CappedText {
|
|
18
|
+
/** The text, or its first `maxLength` characters */
|
|
19
|
+
text: string;
|
|
20
|
+
/** Original length, set only when the text was cut */
|
|
21
|
+
truncatedFrom?: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Cut a text to its first `maxLength` characters (UTF-16 code units),
|
|
25
|
+
* keeping the original length (the `truncatedFrom` of JSON output). A
|
|
26
|
+
* surrogate pair (an emoji) is never split: the cut ends before it.
|
|
27
|
+
*
|
|
28
|
+
* @param text - Text to cut
|
|
29
|
+
* @param maxLength - Characters kept (at most)
|
|
30
|
+
* @returns The text, with `truncatedFrom` when it was cut
|
|
31
|
+
*/
|
|
32
|
+
export declare function capLength(text: string, maxLength: number): CappedText;
|
|
14
33
|
//# sourceMappingURL=strings.d.ts.map
|
package/dist/utils/strings.js
CHANGED
|
@@ -20,4 +20,20 @@ export function truncateByLength(text, maxLength = DEFAULT_MAX_LENGTH) {
|
|
|
20
20
|
}
|
|
21
21
|
return text.slice(0, maxLength - 1) + '…';
|
|
22
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* Cut a text to its first `maxLength` characters (UTF-16 code units),
|
|
25
|
+
* keeping the original length (the `truncatedFrom` of JSON output). A
|
|
26
|
+
* surrogate pair (an emoji) is never split: the cut ends before it.
|
|
27
|
+
*
|
|
28
|
+
* @param text - Text to cut
|
|
29
|
+
* @param maxLength - Characters kept (at most)
|
|
30
|
+
* @returns The text, with `truncatedFrom` when it was cut
|
|
31
|
+
*/
|
|
32
|
+
export function capLength(text, maxLength) {
|
|
33
|
+
if (text.length <= maxLength)
|
|
34
|
+
return { text };
|
|
35
|
+
const lastKept = text.charCodeAt(maxLength - 1);
|
|
36
|
+
const end = lastKept >= 0xd800 && lastKept <= 0xdbff ? maxLength - 1 : maxLength;
|
|
37
|
+
return { text: text.slice(0, end), truncatedFrom: text.length };
|
|
38
|
+
}
|
|
23
39
|
//# sourceMappingURL=strings.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "browser-debugger-cli",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.14.0",
|
|
4
4
|
"description": "DevTools telemetry in your terminal. For humans and agents. Direct WebSocket to Chrome's debugging port.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"validate:ts-version": "node -e \"const ts = require('typescript'); const v = ts.version.split('.'); if (parseInt(v[0]) < 5 || (parseInt(v[0]) === 5 && parseInt(v[1]) < 6)) { console.error('Requires TypeScript 5.6+, found:', ts.version); process.exit(1); } else { console.log('✅ TypeScript version:', ts.version); }\"",
|
|
28
28
|
"check": "npm run format:check && npm run type-check && npm run lint",
|
|
29
29
|
"check:enhanced": "npm run format:check && npm run type-check && npm run lint && npm run validate:module-type && npm run validate:ts-version",
|
|
30
|
-
"test": "tsx --test 'src/**/__tests__/**/!(*.smoke).test.ts'",
|
|
30
|
+
"test": "tsx --test --test-timeout=120000 'src/**/__tests__/**/!(*.smoke).test.ts'",
|
|
31
31
|
"test:watch": "tsx --test --watch 'src/**/__tests__/**/!(*.smoke).test.ts'",
|
|
32
32
|
"test:coverage": "c8 npm test",
|
|
33
33
|
"test:smoke": "tsx --test --test-concurrency=1 'src/__tests__/smoke/*.smoke.test.ts'",
|