browser-debugger-cli 0.12.0 → 0.13.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 +4 -4
- package/README.md +1 -0
- 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 +62 -12
- package/dist/commands/dom/DomElementResolver.d.ts +3 -1
- package/dist/commands/dom/DomElementResolver.js +10 -3
- package/dist/commands/dom/a11y.js +3 -2
- package/dist/commands/dom/eval.d.ts +3 -2
- package/dist/commands/dom/eval.js +11 -5
- package/dist/commands/dom/form.js +10 -9
- package/dist/commands/dom/formInteraction.js +8 -7
- package/dist/commands/dom/get.js +8 -8
- 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 +4 -2
- package/dist/commands/dom/query.d.ts +19 -2
- package/dist/commands/dom/query.js +37 -6
- package/dist/commands/dom/screenshot.js +2 -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 +111 -40
- 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 +22 -12
- package/dist/commands/optionBehaviors.js +33 -11
- package/dist/commands/shared/daemonErrorHandler.d.ts +5 -2
- package/dist/commands/shared/daemonErrorHandler.js +20 -9
- package/dist/commands/shared/dataFetcher.d.ts +12 -4
- package/dist/commands/shared/dataFetcher.js +12 -4
- package/dist/commands/shared/followMode.d.ts +9 -1
- package/dist/commands/shared/followMode.js +22 -4
- package/dist/commands/shared/optionTypes.d.ts +4 -1
- package/dist/commands/shared/outputFile.js +6 -1
- 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/launcher.js +3 -2
- package/dist/daemon/SessionController.js +6 -1
- package/dist/daemon/launcher.d.ts +3 -2
- package/dist/daemon/launcher.js +47 -3
- package/dist/daemon/session/Session.d.ts +4 -1
- package/dist/daemon/session/Session.js +33 -2
- package/dist/daemon/session/TelemetryStore.d.ts +8 -1
- package/dist/daemon/session/TelemetryStore.js +13 -1
- package/dist/daemon/session/commandRegistry.js +29 -13
- package/dist/daemon/session/interactions.d.ts +2 -1
- package/dist/daemon/session/interactions.js +13 -1
- package/dist/daemon/session/plugins.js +16 -2
- package/dist/daemon/session/teardown.js +1 -1
- package/dist/daemon.js +1622 -748
- package/dist/errors/messages.d.ts +54 -11
- package/dist/errors/messages.js +109 -22
- package/dist/index.js +13733 -8796
- 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 +12 -0
- package/dist/ipc/protocol/domTypes.d.ts +12 -0
- package/dist/ipc/protocol/inspectTypes.d.ts +2 -0
- package/dist/ipc/session/types.d.ts +2 -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 +10 -3
- package/dist/runtime/dom/elementGeometry.js +27 -4
- package/dist/runtime/dom/elementInfo.d.ts +74 -18
- package/dist/runtime/dom/elementInfo.js +187 -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/inspect.js +5 -6
- package/dist/runtime/dom/inspectAllStyles.js +1 -0
- package/dist/runtime/dom/inspectHints.d.ts +1 -1
- package/dist/runtime/dom/inspectModel.d.ts +2 -1
- 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/inspectScripts.d.ts +29 -2
- package/dist/runtime/dom/inspectScripts.js +49 -10
- package/dist/runtime/dom/layout.js +9 -7
- package/dist/runtime/dom/reactEventHelpers.d.ts +14 -4
- package/dist/runtime/dom/reactEventHelpers.js +63 -27
- package/dist/runtime/dom/targetNode.d.ts +18 -5
- package/dist/runtime/dom/targetNode.js +268 -8
- 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.js +2 -2
- package/dist/telemetry/console.d.ts +2 -1
- package/dist/telemetry/console.js +30 -21
- package/dist/telemetry/pageCrash.d.ts +26 -0
- package/dist/telemetry/pageCrash.js +53 -0
- package/dist/types.d.ts +16 -0
- 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 +3 -1
- package/dist/ui/formatters/console/follow.d.ts +2 -1
- package/dist/ui/formatters/console/follow.js +2 -2
- package/dist/ui/formatters/console/json.d.ts +2 -2
- package/dist/ui/formatters/console/json.js +11 -5
- package/dist/ui/formatters/console/shared.d.ts +30 -0
- package/dist/ui/formatters/console/shared.js +16 -0
- package/dist/ui/formatters/console/summarize.d.ts +9 -2
- package/dist/ui/formatters/console/summarize.js +40 -9
- package/dist/ui/formatters/console.d.ts +2 -1
- package/dist/ui/formatters/console.js +7 -5
- package/dist/ui/formatters/details.js +3 -1
- package/dist/ui/formatters/dom.d.ts +1 -1
- package/dist/ui/formatters/dom.js +5 -6
- 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 +2 -1
- package/dist/ui/formatters/networkList.d.ts +1 -1
- package/dist/ui/formatters/networkList.js +1 -2
- package/dist/ui/formatters/preview.d.ts +2 -0
- package/dist/ui/formatters/preview.js +17 -7
- package/dist/ui/formatters/sessions.d.ts +2 -2
- package/dist/ui/formatters/sessions.js +9 -2
- package/dist/ui/logging/logger.d.ts +1 -1
- package/dist/ui/messages/commands.d.ts +124 -4
- package/dist/ui/messages/commands.js +162 -7
- package/dist/ui/messages/consoleMessages.d.ts +24 -0
- package/dist/ui/messages/consoleMessages.js +32 -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/process.d.ts +12 -0
- package/dist/utils/process.js +25 -0
- package/package.json +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Cleanup behind the user-facing `bdg cleanup` command.
|
|
3
3
|
*/
|
|
4
4
|
import * as fs from 'fs';
|
|
5
|
-
import { killOrphanedChrome, readLiveDaemonPid, removeStaleDaemonFiles, } from './staleSession.js';
|
|
5
|
+
import { killOrphanedChrome, killSessionChromes, readLiveDaemonPid, removeStaleDaemonFiles, } from './staleSession.js';
|
|
6
6
|
import { isDaemonAlive } from '../daemonSocket.js';
|
|
7
7
|
import { clearLastSessionEnd } from '../lastSession.js';
|
|
8
8
|
import { SESSION_STATE_FILES, getSessionFilePath } from '../paths.js';
|
|
@@ -15,7 +15,10 @@ const DAEMON_EXIT_WAIT_MS = 2000;
|
|
|
15
15
|
*
|
|
16
16
|
* With `force`, a live daemon is killed first (after verifying its command
|
|
17
17
|
* line). Then stale daemon files are removed and an orphaned bdg Chrome, if
|
|
18
|
-
* any, is killed
|
|
18
|
+
* any, is killed, and, once no daemon of the session runs, every other
|
|
19
|
+
* Chrome launched for this session directory (one chrome.pid lost track of).
|
|
20
|
+
* The record of a session that ended without `bdg stop` is removed too, and
|
|
21
|
+
* counts as cleaned session files.
|
|
19
22
|
*
|
|
20
23
|
* @param options - Cleanup options
|
|
21
24
|
* @returns What was cleaned, plus warnings
|
|
@@ -25,13 +28,15 @@ export async function performSessionCleanup(options) {
|
|
|
25
28
|
const filesBefore = countSessionFiles();
|
|
26
29
|
const daemonKilled = options.force ? await killLiveDaemon(warnings) : false;
|
|
27
30
|
const session = await removeStaleDaemonFiles();
|
|
28
|
-
const
|
|
31
|
+
const orphan = killOrphanedChrome();
|
|
32
|
+
const unrecorded = readLiveDaemonPid() === null ? killSessionChromes() : [];
|
|
33
|
+
const chrome = orphan || unrecorded.length > 0;
|
|
29
34
|
const output = options.removeOutput ? removeOutputFile(warnings) : false;
|
|
30
35
|
const filesRemoved = countSessionFiles() < filesBefore;
|
|
31
|
-
clearLastSessionEnd();
|
|
36
|
+
const endedRecordRemoved = clearLastSessionEnd();
|
|
32
37
|
return {
|
|
33
38
|
cleaned: {
|
|
34
|
-
session: session || daemonKilled || filesRemoved,
|
|
39
|
+
session: session || daemonKilled || filesRemoved || endedRecordRemoved,
|
|
35
40
|
chrome,
|
|
36
41
|
daemons: daemonKilled,
|
|
37
42
|
output,
|
|
@@ -22,4 +22,14 @@ export declare function probeDaemonSocket(socketPath?: string, timeoutMs?: numbe
|
|
|
22
22
|
* @returns True if the daemon socket accepts a connection
|
|
23
23
|
*/
|
|
24
24
|
export declare function isDaemonAlive(): Promise<boolean>;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the daemon socket certainly cannot be reached: there is no socket
|
|
27
|
+
* file, or connecting is refused. A daemon that is only slow to accept (busy,
|
|
28
|
+
* a timeout) does not count, so it is never taken for a dead one.
|
|
29
|
+
*
|
|
30
|
+
* @param socketPath - Socket path (defaults to the session's daemon socket)
|
|
31
|
+
* @param timeoutMs - Connection timeout
|
|
32
|
+
* @returns True when the socket is missing or refuses connections
|
|
33
|
+
*/
|
|
34
|
+
export declare function isDaemonSocketGone(socketPath?: string, timeoutMs?: number): Promise<boolean>;
|
|
25
35
|
//# sourceMappingURL=daemonSocket.d.ts.map
|
|
@@ -37,4 +37,26 @@ export function probeDaemonSocket(socketPath = getSessionFilePath('DAEMON_SOCKET
|
|
|
37
37
|
export async function isDaemonAlive() {
|
|
38
38
|
return (await probeDaemonSocket()) === 'alive';
|
|
39
39
|
}
|
|
40
|
+
/**
|
|
41
|
+
* Whether the daemon socket certainly cannot be reached: there is no socket
|
|
42
|
+
* file, or connecting is refused. A daemon that is only slow to accept (busy,
|
|
43
|
+
* a timeout) does not count, so it is never taken for a dead one.
|
|
44
|
+
*
|
|
45
|
+
* @param socketPath - Socket path (defaults to the session's daemon socket)
|
|
46
|
+
* @param timeoutMs - Connection timeout
|
|
47
|
+
* @returns True when the socket is missing or refuses connections
|
|
48
|
+
*/
|
|
49
|
+
export function isDaemonSocketGone(socketPath = getSessionFilePath('DAEMON_SOCKET'), timeoutMs = PROBE_TIMEOUT_MS) {
|
|
50
|
+
return new Promise((resolve) => {
|
|
51
|
+
const socket = net.createConnection(socketPath);
|
|
52
|
+
const finish = (gone) => {
|
|
53
|
+
clearTimeout(timer);
|
|
54
|
+
socket.destroy();
|
|
55
|
+
resolve(gone);
|
|
56
|
+
};
|
|
57
|
+
const timer = setTimeout(() => finish(false), timeoutMs);
|
|
58
|
+
socket.once('connect', () => finish(false));
|
|
59
|
+
socket.once('error', (error) => finish(error.code === 'ENOENT' || error.code === 'ECONNREFUSED'));
|
|
60
|
+
});
|
|
61
|
+
}
|
|
40
62
|
//# sourceMappingURL=daemonSocket.js.map
|
|
@@ -18,12 +18,15 @@ export interface LastSessionEnd {
|
|
|
18
18
|
export declare function writeLastSessionEnd(reason: UnexpectedEndReason): void;
|
|
19
19
|
/**
|
|
20
20
|
* Forget the last session's end (a new session is starting, or `cleanup` ran).
|
|
21
|
+
*
|
|
22
|
+
* @returns True if there was a record to remove
|
|
21
23
|
*/
|
|
22
|
-
export declare function clearLastSessionEnd():
|
|
24
|
+
export declare function clearLastSessionEnd(): boolean;
|
|
23
25
|
/**
|
|
24
|
-
* How the last session ended, if it ended unexpectedly.
|
|
26
|
+
* How the last session of a directory ended, if it ended unexpectedly.
|
|
25
27
|
*
|
|
28
|
+
* @param dir - Session directory (default: the selected session's)
|
|
26
29
|
* @returns The record, or null
|
|
27
30
|
*/
|
|
28
|
-
export declare function readLastSessionEnd(): LastSessionEnd | null;
|
|
31
|
+
export declare function readLastSessionEnd(dir?: string): LastSessionEnd | null;
|
|
29
32
|
//# sourceMappingURL=lastSession.d.ts.map
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* `bdg status` can explain why there is no session any more.
|
|
4
4
|
*/
|
|
5
5
|
import * as fs from 'fs';
|
|
6
|
-
import { getSessionFilePath } from './paths.js';
|
|
6
|
+
import { getSessionDir, getSessionFilePath, sessionFilePathIn } from './paths.js';
|
|
7
7
|
import { createLogger } from '../ui/logging/index.js';
|
|
8
8
|
import { AtomicFileWriter } from '../utils/atomicFile.js';
|
|
9
9
|
import { getErrorMessage } from '../utils/errors.js';
|
|
@@ -23,18 +23,24 @@ export function writeLastSessionEnd(reason) {
|
|
|
23
23
|
}
|
|
24
24
|
/**
|
|
25
25
|
* Forget the last session's end (a new session is starting, or `cleanup` ran).
|
|
26
|
+
*
|
|
27
|
+
* @returns True if there was a record to remove
|
|
26
28
|
*/
|
|
27
29
|
export function clearLastSessionEnd() {
|
|
28
|
-
|
|
30
|
+
const file = getSessionFilePath('LAST_SESSION');
|
|
31
|
+
const existed = fs.existsSync(file);
|
|
32
|
+
fs.rmSync(file, { force: true });
|
|
33
|
+
return existed;
|
|
29
34
|
}
|
|
30
35
|
/**
|
|
31
|
-
* How the last session ended, if it ended unexpectedly.
|
|
36
|
+
* How the last session of a directory ended, if it ended unexpectedly.
|
|
32
37
|
*
|
|
38
|
+
* @param dir - Session directory (default: the selected session's)
|
|
33
39
|
* @returns The record, or null
|
|
34
40
|
*/
|
|
35
|
-
export function readLastSessionEnd() {
|
|
41
|
+
export function readLastSessionEnd(dir = getSessionDir()) {
|
|
36
42
|
try {
|
|
37
|
-
const data = JSON.parse(fs.readFileSync(
|
|
43
|
+
const data = JSON.parse(fs.readFileSync(sessionFilePathIn(dir, 'LAST_SESSION'), 'utf8'));
|
|
38
44
|
return typeof data.endedAt === 'number' ? data : null;
|
|
39
45
|
}
|
|
40
46
|
catch (error) {
|
package/dist/session/paths.d.ts
CHANGED
|
@@ -124,8 +124,10 @@ export declare function getDaemonSocketPath(): string;
|
|
|
124
124
|
* Ensure the session directory exists.
|
|
125
125
|
*
|
|
126
126
|
* Creates ~/.bdg/ if it doesn't exist. Safe to call multiple times (idempotent).
|
|
127
|
+
* A path that cannot hold a directory is refused before `mkdir`, which
|
|
128
|
+
* would spin on a pseudo-filesystem ({@link makeDirectory}).
|
|
127
129
|
*
|
|
128
|
-
* @throws Error if directory
|
|
130
|
+
* @throws Error if the directory cannot be created
|
|
129
131
|
*/
|
|
130
132
|
export declare function ensureSessionDir(): void;
|
|
131
133
|
export {};
|
package/dist/session/paths.js
CHANGED
|
@@ -9,6 +9,7 @@ import * as fs from 'fs';
|
|
|
9
9
|
import * as os from 'os';
|
|
10
10
|
import * as path from 'path';
|
|
11
11
|
import { createLogger, logDebugError } from '../ui/logging/index.js';
|
|
12
|
+
import { makeDirectory } from '../utils/directories.js';
|
|
12
13
|
const log = createLogger('session');
|
|
13
14
|
/**
|
|
14
15
|
* Session file paths relative to ~/.bdg/
|
|
@@ -166,13 +167,12 @@ export function getDaemonSocketPath() {
|
|
|
166
167
|
* Ensure the session directory exists.
|
|
167
168
|
*
|
|
168
169
|
* Creates ~/.bdg/ if it doesn't exist. Safe to call multiple times (idempotent).
|
|
170
|
+
* A path that cannot hold a directory is refused before `mkdir`, which
|
|
171
|
+
* would spin on a pseudo-filesystem ({@link makeDirectory}).
|
|
169
172
|
*
|
|
170
|
-
* @throws Error if directory
|
|
173
|
+
* @throws Error if the directory cannot be created
|
|
171
174
|
*/
|
|
172
175
|
export function ensureSessionDir() {
|
|
173
|
-
|
|
174
|
-
if (!fs.existsSync(dir)) {
|
|
175
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
176
|
-
}
|
|
176
|
+
makeDirectory(getSessionDir());
|
|
177
177
|
}
|
|
178
178
|
//# sourceMappingURL=paths.js.map
|
|
@@ -20,6 +20,7 @@ import * as path from 'path';
|
|
|
20
20
|
import { getSessionBaseDir, getSessionDir, listSessionDirs, sessionFilePathIn, } from './paths.js';
|
|
21
21
|
import { createLogger, logDebugError } from '../ui/logging/index.js';
|
|
22
22
|
import { delay } from '../utils/async.js';
|
|
23
|
+
import { makeDirectory } from '../utils/directories.js';
|
|
23
24
|
const log = createLogger('session');
|
|
24
25
|
/** Lock file guarding port selection, in the port registry (or base session) directory */
|
|
25
26
|
const PORT_LOCK_FILE = 'port.lock';
|
|
@@ -93,8 +94,8 @@ function trustedRegistryDir(create) {
|
|
|
93
94
|
const dir = getPortRegistryDir();
|
|
94
95
|
try {
|
|
95
96
|
if (create) {
|
|
96
|
-
|
|
97
|
-
|
|
97
|
+
makeDirectory(path.dirname(dir));
|
|
98
|
+
makeDirectory(path.join(dir, CLAIMS_DIR), 0o700);
|
|
98
99
|
}
|
|
99
100
|
if (!fs.existsSync(dir))
|
|
100
101
|
return null;
|
|
@@ -266,7 +267,7 @@ function releaseLock(lockPath, token) {
|
|
|
266
267
|
export async function withPortLock(select) {
|
|
267
268
|
const registryDir = trustedRegistryDir(true);
|
|
268
269
|
const lockDir = registryDir ?? getSessionBaseDir();
|
|
269
|
-
|
|
270
|
+
makeDirectory(lockDir);
|
|
270
271
|
const lockPath = path.join(lockDir, PORT_LOCK_FILE);
|
|
271
272
|
const token = `${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}`;
|
|
272
273
|
const locked = await acquireLock(lockPath, token);
|
|
@@ -4,13 +4,15 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { StatusResponseData } from '../ipc/session/queries.js';
|
|
6
6
|
import { type SocketProbeResult } from './daemonSocket.js';
|
|
7
|
+
import { type UnexpectedEndReason } from './lastSession.js';
|
|
7
8
|
import { type SessionDirEntry } from './paths.js';
|
|
8
9
|
/**
|
|
9
10
|
* State of a session: its daemon runs (`active`, `starting`, `ending`,
|
|
10
|
-
* `unresponsive`),
|
|
11
|
-
* files (`stale`)
|
|
11
|
+
* `unresponsive`), died and left its Chrome running (`crashed`) or only
|
|
12
|
+
* files (`stale`), or exited after the session ended without `bdg stop`
|
|
13
|
+
* (`ended`: Chrome crashed or was closed, the page was closed, `--timeout`).
|
|
12
14
|
*/
|
|
13
|
-
export type RunningSessionState = 'active' | 'starting' | 'ending' | 'unresponsive' | 'crashed' | 'stale';
|
|
15
|
+
export type RunningSessionState = 'active' | 'starting' | 'ending' | 'unresponsive' | 'crashed' | 'stale' | 'ended';
|
|
14
16
|
/**
|
|
15
17
|
* One session in the list.
|
|
16
18
|
*/
|
|
@@ -27,6 +29,10 @@ export interface RunningSessionInfo {
|
|
|
27
29
|
chromePid?: number;
|
|
28
30
|
/** Command that cleans up a crashed or stale session */
|
|
29
31
|
cleanup?: string;
|
|
32
|
+
/** Why an `ended` session ended */
|
|
33
|
+
endReason?: UnexpectedEndReason;
|
|
34
|
+
/** When an `ended` session ended (epoch ms) */
|
|
35
|
+
endedAt?: number;
|
|
30
36
|
}
|
|
31
37
|
/**
|
|
32
38
|
* Summarize a daemon's status response.
|
|
@@ -38,8 +44,10 @@ export interface RunningSessionInfo {
|
|
|
38
44
|
export declare function toRunningSession(name: string | null, data: StatusResponseData): RunningSessionInfo;
|
|
39
45
|
/**
|
|
40
46
|
* A session whose daemon is gone: `crashed` while the Chrome bdg launched for
|
|
41
|
-
* it still runs, `stale` when only its files are left
|
|
42
|
-
*
|
|
47
|
+
* it still runs, `stale` when only its files are left, `ended` when it left
|
|
48
|
+
* only the record of an end without `bdg stop` ({@link describeEnded}).
|
|
49
|
+
* Nothing is changed on disk; `cleanup` names the command that removes
|
|
50
|
+
* leftover files.
|
|
43
51
|
*
|
|
44
52
|
* @param entry - Session directory
|
|
45
53
|
* @param probe - Result of probing its daemon socket
|
|
@@ -6,6 +6,7 @@ import * as fs from 'fs';
|
|
|
6
6
|
import { getStatus } from '../ipc/client.js';
|
|
7
7
|
import { isSessionChrome, readLiveDaemonPid } from './cleanup/staleSession.js';
|
|
8
8
|
import { probeDaemonSocket } from './daemonSocket.js';
|
|
9
|
+
import { readLastSessionEnd } from './lastSession.js';
|
|
9
10
|
import { SESSION_STATE_FILES, getNamedSessionDir, listSessionDirs, sessionFilePathIn, } from './paths.js';
|
|
10
11
|
import { readPidFromFile } from './pid.js';
|
|
11
12
|
import { readPortFile } from './portClaims.js';
|
|
@@ -58,9 +59,10 @@ async function describeSession(entry) {
|
|
|
58
59
|
return { name, state: 'unresponsive' };
|
|
59
60
|
}
|
|
60
61
|
/**
|
|
61
|
-
* A session whose daemon socket does not answer: `
|
|
62
|
-
* (from daemon.pid, verified by command line) runs
|
|
63
|
-
* socket
|
|
62
|
+
* A session whose daemon socket does not answer: `ending` while its daemon
|
|
63
|
+
* (from daemon.pid, verified by command line) still runs, since a daemon
|
|
64
|
+
* writes daemon.pid only after it opened its socket and removes the socket
|
|
65
|
+
* first when it shuts down; otherwise see {@link describeLeftovers}.
|
|
64
66
|
*
|
|
65
67
|
* @param entry - Session directory
|
|
66
68
|
* @param probe - Result of probing its daemon socket
|
|
@@ -69,13 +71,15 @@ async function describeSession(entry) {
|
|
|
69
71
|
function describeWithoutSocket(entry, probe) {
|
|
70
72
|
const daemonPid = readLiveDaemonPid(entry.dir);
|
|
71
73
|
if (daemonPid !== null)
|
|
72
|
-
return { name: entry.name, state: '
|
|
74
|
+
return { name: entry.name, state: 'ending', daemonPid };
|
|
73
75
|
return describeLeftovers(entry, probe);
|
|
74
76
|
}
|
|
75
77
|
/**
|
|
76
78
|
* A session whose daemon is gone: `crashed` while the Chrome bdg launched for
|
|
77
|
-
* it still runs, `stale` when only its files are left
|
|
78
|
-
*
|
|
79
|
+
* it still runs, `stale` when only its files are left, `ended` when it left
|
|
80
|
+
* only the record of an end without `bdg stop` ({@link describeEnded}).
|
|
81
|
+
* Nothing is changed on disk; `cleanup` names the command that removes
|
|
82
|
+
* leftover files.
|
|
79
83
|
*
|
|
80
84
|
* @param entry - Session directory
|
|
81
85
|
* @param probe - Result of probing its daemon socket
|
|
@@ -87,7 +91,7 @@ export function describeLeftovers({ name, dir }, probe) {
|
|
|
87
91
|
const leftover = probe === 'stale' ||
|
|
88
92
|
SESSION_STATE_FILES.some((type) => fs.existsSync(sessionFilePathIn(dir, type)));
|
|
89
93
|
if (!orphan && !leftover)
|
|
90
|
-
return
|
|
94
|
+
return describeEnded({ name, dir });
|
|
91
95
|
const port = leftoverPort(dir);
|
|
92
96
|
return {
|
|
93
97
|
name,
|
|
@@ -97,6 +101,26 @@ export function describeLeftovers({ name, dir }, probe) {
|
|
|
97
101
|
cleanup: sessionCommand('bdg cleanup', name),
|
|
98
102
|
};
|
|
99
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* A session that ended without `bdg stop` and whose daemon exited cleanly:
|
|
106
|
+
* `ended`, with why and when, until the session starts again or
|
|
107
|
+
* `bdg cleanup` clears the record.
|
|
108
|
+
*
|
|
109
|
+
* @param entry - Session directory
|
|
110
|
+
* @returns Session info, or null when the directory holds no such record
|
|
111
|
+
*/
|
|
112
|
+
function describeEnded({ name, dir }) {
|
|
113
|
+
const end = readLastSessionEnd(dir);
|
|
114
|
+
if (end === null)
|
|
115
|
+
return null;
|
|
116
|
+
return {
|
|
117
|
+
name,
|
|
118
|
+
state: 'ended',
|
|
119
|
+
endReason: end.reason,
|
|
120
|
+
endedAt: end.endedAt,
|
|
121
|
+
cleanup: sessionCommand('bdg cleanup', name),
|
|
122
|
+
};
|
|
123
|
+
}
|
|
100
124
|
/**
|
|
101
125
|
* The port a dead session used: from its metadata, else its `port.txt`.
|
|
102
126
|
*
|
package/dist/telemetry/a11y.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CommandError } from '../errors/index.js';
|
|
2
2
|
import { unknownQueryFieldError } from '../errors/messages.js';
|
|
3
|
-
import { callCDP } from '../ipc/client.js';
|
|
3
|
+
import { callBdgScript, callCDP } from '../ipc/client.js';
|
|
4
4
|
import { MASKED_VALUE, SENSITIVE_FIELD_JS } from '../runtime/dom/elementInfo.js';
|
|
5
5
|
import { childFrameIds } from '../runtime/dom/frameLayout.js';
|
|
6
6
|
import { ConcurrencyLimiter } from '../utils/concurrency.js';
|
|
@@ -118,7 +118,7 @@ async function sensitiveNodeIds(tree) {
|
|
|
118
118
|
*/
|
|
119
119
|
async function isSensitiveField(backendNodeId) {
|
|
120
120
|
const objectGroup = 'bdg-a11y-secret';
|
|
121
|
-
const resolved = await
|
|
121
|
+
const resolved = await callBdgScript('DOM.resolveNode', { backendNodeId, objectGroup });
|
|
122
122
|
const objectId = resolved.data?.result?.object
|
|
123
123
|
?.objectId;
|
|
124
124
|
if (!objectId)
|
|
@@ -31,7 +31,8 @@ export declare function formatExceptionText(details: Protocol.Runtime.ExceptionD
|
|
|
31
31
|
* @param messages - Array to populate with console messages
|
|
32
32
|
* @param includeAll - If true, disable default pattern filtering
|
|
33
33
|
* @param getCurrentNavigationId - Function to get current navigation ID
|
|
34
|
+
* @param onDropped - Called for each message dropped at the limit (the oldest go first)
|
|
34
35
|
* @returns Cleanup function to remove event handlers
|
|
35
36
|
*/
|
|
36
|
-
export declare function startConsoleCollection(cdp: CDPConnection, messages: ConsoleMessage[], includeAll?: boolean, getCurrentNavigationId?: () => number): Promise<CleanupFunction>;
|
|
37
|
+
export declare function startConsoleCollection(cdp: CDPConnection, messages: ConsoleMessage[], includeAll?: boolean, getCurrentNavigationId?: () => number, onDropped?: () => void): Promise<CleanupFunction>;
|
|
37
38
|
//# sourceMappingURL=console.d.ts.map
|
|
@@ -75,15 +75,23 @@ function createMessage(type, text, timestamp, args, context) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
/**
|
|
78
|
-
* Insert a message in timestamp order
|
|
79
|
-
*
|
|
78
|
+
* Insert a message in timestamp order (async expansion can deliver a message
|
|
79
|
+
* late). At {@link MAX_CONSOLE_MESSAGES} the oldest message is dropped to
|
|
80
|
+
* make room, so the newest are kept; a late message older than all kept ones
|
|
81
|
+
* is dropped itself.
|
|
80
82
|
*
|
|
81
|
-
* @
|
|
83
|
+
* @param messages - Messages, oldest first (updated)
|
|
84
|
+
* @param message - Message to add
|
|
85
|
+
* @param onDropped - Called for each message dropped
|
|
86
|
+
* @returns False when the message itself was dropped
|
|
82
87
|
*/
|
|
83
|
-
function insertMessageByTimestamp(messages, message) {
|
|
88
|
+
function insertMessageByTimestamp(messages, message, onDropped) {
|
|
84
89
|
if (messages.length >= MAX_CONSOLE_MESSAGES) {
|
|
85
|
-
|
|
86
|
-
|
|
90
|
+
const oldest = messages[0];
|
|
91
|
+
onDropped();
|
|
92
|
+
if (oldest && message.timestamp < oldest.timestamp)
|
|
93
|
+
return false;
|
|
94
|
+
messages.shift();
|
|
87
95
|
}
|
|
88
96
|
const insertIndex = findInsertIndex(messages, message.timestamp);
|
|
89
97
|
messages.splice(insertIndex, 0, message);
|
|
@@ -111,32 +119,31 @@ function findInsertIndex(messages, timestamp) {
|
|
|
111
119
|
/**
|
|
112
120
|
* Handle a console API call event with object expansion.
|
|
113
121
|
*/
|
|
114
|
-
function handleConsoleAPICall(cdp,
|
|
122
|
+
function handleConsoleAPICall(cdp, insert, params, context, includeAll) {
|
|
115
123
|
const basicText = formatConsoleArgs(params.args);
|
|
116
124
|
if (shouldExcludeConsoleMessage(basicText, params.type, includeAll)) {
|
|
117
125
|
return;
|
|
118
126
|
}
|
|
119
127
|
if (hasArgsNeedingExpansion(params.args) && !usesFormatSpecifiers(params.args)) {
|
|
120
|
-
handleExpandableMessage(cdp,
|
|
128
|
+
handleExpandableMessage(cdp, insert, params, context, basicText);
|
|
121
129
|
}
|
|
122
130
|
else {
|
|
123
|
-
|
|
124
|
-
insertMessageByTimestamp(messages, message);
|
|
131
|
+
insert(createMessage(params.type, basicText, params.timestamp, params.args, context));
|
|
125
132
|
}
|
|
126
133
|
}
|
|
127
134
|
/**
|
|
128
135
|
* Handle a message with expandable objects.
|
|
129
136
|
*/
|
|
130
|
-
function handleExpandableMessage(cdp,
|
|
137
|
+
function handleExpandableMessage(cdp, insert, params, context, fallbackText) {
|
|
131
138
|
void expandConsoleArgs(cdp, params.args)
|
|
132
139
|
.then((expandedText) => {
|
|
133
140
|
const message = createMessage(params.type, expandedText, params.timestamp, params.args, context);
|
|
134
|
-
|
|
141
|
+
insert(message);
|
|
135
142
|
})
|
|
136
143
|
.catch((error) => {
|
|
137
144
|
log.debug(`Object expansion failed, using basic text: ${String(error)}`);
|
|
138
145
|
const message = createMessage(params.type, fallbackText, params.timestamp, params.args, context);
|
|
139
|
-
|
|
146
|
+
insert(message);
|
|
140
147
|
});
|
|
141
148
|
}
|
|
142
149
|
/**
|
|
@@ -178,14 +185,14 @@ export function formatExceptionText(details) {
|
|
|
178
185
|
*
|
|
179
186
|
* @returns The message added, undefined when filtered out or over the limit
|
|
180
187
|
*/
|
|
181
|
-
function handleExceptionThrown(
|
|
188
|
+
function handleExceptionThrown(insert, params, context, includeAll) {
|
|
182
189
|
const exception = params.exceptionDetails;
|
|
183
190
|
const text = formatExceptionText(exception);
|
|
184
191
|
if (shouldExcludeConsoleMessage(text, 'error', includeAll)) {
|
|
185
192
|
return undefined;
|
|
186
193
|
}
|
|
187
194
|
const message = createMessage('error', text, params.timestamp, undefined, context);
|
|
188
|
-
return
|
|
195
|
+
return insert(message) ? message : undefined;
|
|
189
196
|
}
|
|
190
197
|
/** CDP's text of an unhandled promise rejection (the only kind Chrome revokes) */
|
|
191
198
|
const UNHANDLED_REJECTION_TEXT = 'Uncaught (in promise)';
|
|
@@ -270,7 +277,7 @@ class RevocableRejections {
|
|
|
270
277
|
* Worker entries are skipped: workers are attached directly, so their console
|
|
271
278
|
* calls already arrive (with arguments) from the worker's own session.
|
|
272
279
|
*/
|
|
273
|
-
function handleLogEntry(
|
|
280
|
+
function handleLogEntry(insert, entry, navigationId, includeAll) {
|
|
274
281
|
const type = LOG_LEVEL_TYPES[entry.level];
|
|
275
282
|
if (entry.source === 'worker' || shouldExcludeConsoleMessage(entry.text, type, includeAll)) {
|
|
276
283
|
return;
|
|
@@ -287,7 +294,7 @@ function handleLogEntry(messages, entry, navigationId, includeAll) {
|
|
|
287
294
|
stackTrace: convertStackTrace(entry.stackTrace) ?? location,
|
|
288
295
|
source: entry.source,
|
|
289
296
|
};
|
|
290
|
-
|
|
297
|
+
insert(createMessage(type, entry.text, entry.timestamp, undefined, context));
|
|
291
298
|
}
|
|
292
299
|
/**
|
|
293
300
|
* Enable console and log events on an attached target's session.
|
|
@@ -325,17 +332,19 @@ async function startOptionalSources(cdp, typed) {
|
|
|
325
332
|
* @param messages - Array to populate with console messages
|
|
326
333
|
* @param includeAll - If true, disable default pattern filtering
|
|
327
334
|
* @param getCurrentNavigationId - Function to get current navigation ID
|
|
335
|
+
* @param onDropped - Called for each message dropped at the limit (the oldest go first)
|
|
328
336
|
* @returns Cleanup function to remove event handlers
|
|
329
337
|
*/
|
|
330
|
-
export async function startConsoleCollection(cdp, messages, includeAll = false, getCurrentNavigationId) {
|
|
338
|
+
export async function startConsoleCollection(cdp, messages, includeAll = false, getCurrentNavigationId, onDropped = () => undefined) {
|
|
331
339
|
const registry = new CDPHandlerRegistry();
|
|
332
340
|
const typed = new TypedCDPConnection(cdp);
|
|
341
|
+
const insert = (message) => insertMessageByTimestamp(messages, message, onDropped);
|
|
333
342
|
registry.registerTyped(typed, 'Runtime.consoleAPICalled', (params, sessionId) => {
|
|
334
343
|
const context = {
|
|
335
344
|
navigationId: getCurrentNavigationId?.(),
|
|
336
345
|
stackTrace: convertStackTrace(params.stackTrace),
|
|
337
346
|
};
|
|
338
|
-
handleConsoleAPICall(senderFor(cdp, sessionId),
|
|
347
|
+
handleConsoleAPICall(senderFor(cdp, sessionId), insert, params, context, includeAll);
|
|
339
348
|
});
|
|
340
349
|
const rejections = new RevocableRejections();
|
|
341
350
|
registry.registerTyped(typed, 'Runtime.exceptionThrown', (params, sessionId) => {
|
|
@@ -343,7 +352,7 @@ export async function startConsoleCollection(cdp, messages, includeAll = false,
|
|
|
343
352
|
navigationId: getCurrentNavigationId?.(),
|
|
344
353
|
stackTrace: convertStackTrace(params.exceptionDetails.stackTrace),
|
|
345
354
|
};
|
|
346
|
-
const message = handleExceptionThrown(
|
|
355
|
+
const message = handleExceptionThrown(insert, params, context, includeAll);
|
|
347
356
|
if (message)
|
|
348
357
|
rejections.track(params.exceptionDetails, message, sessionId);
|
|
349
358
|
});
|
|
@@ -357,7 +366,7 @@ export async function startConsoleCollection(cdp, messages, includeAll = false,
|
|
|
357
366
|
rejections.forgetSession(sessionId);
|
|
358
367
|
});
|
|
359
368
|
registry.registerTyped(typed, 'Log.entryAdded', ({ entry }) => {
|
|
360
|
-
handleLogEntry(
|
|
369
|
+
handleLogEntry(insert, entry, getCurrentNavigationId?.(), includeAll);
|
|
361
370
|
});
|
|
362
371
|
try {
|
|
363
372
|
await typed.send('Runtime.enable', {});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer crash tracking: Chrome reports a crashed page with
|
|
3
|
+
* `Inspector.targetCrashed` and keeps the connection open, so without this a
|
|
4
|
+
* session looks active while every page command waits for a timeout. A
|
|
5
|
+
* reload (or any main-frame navigation) brings the page back.
|
|
6
|
+
*/
|
|
7
|
+
import type { CDPConnection } from '../connection/cdp.js';
|
|
8
|
+
import { CommandError } from '../errors/index.js';
|
|
9
|
+
import type { CleanupFunction } from '../types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Start tracking renderer crashes of the page.
|
|
12
|
+
*
|
|
13
|
+
* @param cdp - CDP connection to the page
|
|
14
|
+
* @param onChange - Called with the crash time when the page crashes, and
|
|
15
|
+
* with undefined when it is loaded again
|
|
16
|
+
* @returns Cleanup that stops tracking
|
|
17
|
+
*/
|
|
18
|
+
export declare function startCrashTracking(cdp: CDPConnection, onChange: (crashedAt: number | undefined) => void): Promise<CleanupFunction>;
|
|
19
|
+
/**
|
|
20
|
+
* Error for a page command after the page's renderer crashed (exit 107).
|
|
21
|
+
*
|
|
22
|
+
* @param crashedAt - When it crashed (epoch ms)
|
|
23
|
+
* @returns Error with the way back
|
|
24
|
+
*/
|
|
25
|
+
export declare function pageCrashedCommandError(crashedAt: number): CommandError;
|
|
26
|
+
//# sourceMappingURL=pageCrash.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renderer crash tracking: Chrome reports a crashed page with
|
|
3
|
+
* `Inspector.targetCrashed` and keeps the connection open, so without this a
|
|
4
|
+
* session looks active while every page command waits for a timeout. A
|
|
5
|
+
* reload (or any main-frame navigation) brings the page back.
|
|
6
|
+
*/
|
|
7
|
+
import { CDPHandlerRegistry } from '../connection/handlers.js';
|
|
8
|
+
import { TypedCDPConnection } from '../connection/typed-cdp.js';
|
|
9
|
+
import { CommandError } from '../errors/index.js';
|
|
10
|
+
import { pageCrashedError } from '../errors/messages.js';
|
|
11
|
+
import { createLogger } from '../ui/logging/index.js';
|
|
12
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
13
|
+
import { EXIT_CODES } from '../utils/exitCodes.js';
|
|
14
|
+
const log = createLogger('page-crash');
|
|
15
|
+
/**
|
|
16
|
+
* Start tracking renderer crashes of the page.
|
|
17
|
+
*
|
|
18
|
+
* @param cdp - CDP connection to the page
|
|
19
|
+
* @param onChange - Called with the crash time when the page crashes, and
|
|
20
|
+
* with undefined when it is loaded again
|
|
21
|
+
* @returns Cleanup that stops tracking
|
|
22
|
+
*/
|
|
23
|
+
export async function startCrashTracking(cdp, onChange) {
|
|
24
|
+
const registry = new CDPHandlerRegistry();
|
|
25
|
+
const typed = new TypedCDPConnection(cdp);
|
|
26
|
+
registry.registerTyped(typed, 'Inspector.targetCrashed', () => {
|
|
27
|
+
log.info('The page crashed (renderer gone)');
|
|
28
|
+
onChange(Date.now());
|
|
29
|
+
});
|
|
30
|
+
registry.registerTyped(typed, 'Inspector.targetReloadedAfterCrash', () => onChange(undefined));
|
|
31
|
+
registry.registerTyped(typed, 'Page.frameNavigated', ({ frame }) => {
|
|
32
|
+
if (frame.parentId === undefined)
|
|
33
|
+
onChange(undefined);
|
|
34
|
+
});
|
|
35
|
+
try {
|
|
36
|
+
await cdp.send('Inspector.enable');
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
log.debug(`Crash reports unavailable: ${getErrorMessage(error)}`);
|
|
40
|
+
}
|
|
41
|
+
return () => registry.cleanup();
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Error for a page command after the page's renderer crashed (exit 107).
|
|
45
|
+
*
|
|
46
|
+
* @param crashedAt - When it crashed (epoch ms)
|
|
47
|
+
* @returns Error with the way back
|
|
48
|
+
*/
|
|
49
|
+
export function pageCrashedCommandError(crashedAt) {
|
|
50
|
+
const err = pageCrashedError(crashedAt);
|
|
51
|
+
return new CommandError(err.message, { suggestion: err.suggestion }, EXIT_CODES.PAGE_CRASHED);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=pageCrash.js.map
|
package/dist/types.d.ts
CHANGED
|
@@ -226,10 +226,14 @@ export interface BdgOutput {
|
|
|
226
226
|
};
|
|
227
227
|
/** Navigation id of the page currently loaded (live previews) */
|
|
228
228
|
currentNavigationId?: number;
|
|
229
|
+
/** When the page's renderer crashed (epoch ms), while it is not loaded again */
|
|
230
|
+
pageCrashedAt?: number;
|
|
229
231
|
/** Counts of all captured items matching the request (e.g. `peek --type`), when `data` holds only the most recent ones */
|
|
230
232
|
totals?: {
|
|
231
233
|
network: number;
|
|
232
234
|
console: number;
|
|
235
|
+
/** Console messages dropped at the limit, oldest first (indices start after them) */
|
|
236
|
+
consoleDropped?: number;
|
|
233
237
|
};
|
|
234
238
|
error?: string;
|
|
235
239
|
partial?: boolean;
|
|
@@ -327,6 +331,8 @@ export interface DomContext {
|
|
|
327
331
|
children?: string[];
|
|
328
332
|
/** Number of child elements, for an element without text */
|
|
329
333
|
childCount?: number;
|
|
334
|
+
/** The children listed are those of its shadow root (a web component) */
|
|
335
|
+
shadowChildren?: boolean;
|
|
330
336
|
/** Attributes that identify it by its type (see {@link KeyAttributes}) */
|
|
331
337
|
attributes?: KeyAttributes;
|
|
332
338
|
/** A field holding a secret (password, card, one-time code): its value is shown masked */
|
|
@@ -438,6 +444,14 @@ export interface DomQueryResult {
|
|
|
438
444
|
/** Unique selector for this node (set by form discovery) */
|
|
439
445
|
selector?: string;
|
|
440
446
|
}>;
|
|
447
|
+
/** Matches not listed (`--limit`); `count` is all of them */
|
|
448
|
+
omitted?: number;
|
|
449
|
+
/** Matches usable by index (described and cached), when fewer than `count` */
|
|
450
|
+
indexed?: number;
|
|
451
|
+
/** First matches whose viewport position was checked (`inViewport`), when more are listed */
|
|
452
|
+
viewportChecked?: number;
|
|
453
|
+
/** Identity of the page document the matches belong to (cached results only) */
|
|
454
|
+
document?: string;
|
|
441
455
|
}
|
|
442
456
|
/**
|
|
443
457
|
* Result of a DOM get operation.
|
|
@@ -679,5 +693,7 @@ export interface InstalledSkill {
|
|
|
679
693
|
target: SkillTarget;
|
|
680
694
|
path: string;
|
|
681
695
|
status: 'installed' | 'updated' | 'unchanged';
|
|
696
|
+
/** Where the replaced copy was kept (`updated` only) */
|
|
697
|
+
backup?: string;
|
|
682
698
|
}
|
|
683
699
|
//# sourceMappingURL=types.d.ts.map
|