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
|
@@ -6,7 +6,7 @@ import { runCommand } from '../shared/CommandRunner.js';
|
|
|
6
6
|
import { jsonOption } from '../shared/commonOptions.js';
|
|
7
7
|
import { noteFollowConnected } from '../shared/daemonErrorHandler.js';
|
|
8
8
|
import { fetchNetworkRequests, createErrorResult } from '../shared/dataFetcher.js';
|
|
9
|
-
import { followFetchFailure, setupFollowMode, } from '../shared/followMode.js';
|
|
9
|
+
import { followFetchFailure, newPageCrashes, setupFollowMode, } from '../shared/followMode.js';
|
|
10
10
|
import { handleValidationError } from '../shared/handleValidationError.js';
|
|
11
11
|
import { positiveIntRule, resourceTypeRule } from '../shared/validation.js';
|
|
12
12
|
import { applyFilters, getFilterHelpText, validateFilterString } from '../../telemetry/filterDsl.js';
|
|
@@ -14,6 +14,7 @@ import { resolvePreset, FILTER_PRESETS } from '../../telemetry/filterPresets.js'
|
|
|
14
14
|
import { filterByResourceType } from '../../telemetry/filters.js';
|
|
15
15
|
import { buildSuccessResponse } from '../../ui/OutputBuilder.js';
|
|
16
16
|
import { formatNetworkFollowRows, formatNetworkList, pageStartOf, } from '../../ui/formatters/networkList.js';
|
|
17
|
+
import { pageCrashedNote, withPageCrashedNote } from '../../ui/messages/commands.js';
|
|
17
18
|
import { followingNetworkMessage, stoppedFollowingNetworkMessage, } from '../../ui/messages/networkMessages.js';
|
|
18
19
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
19
20
|
import { validateFilterOption } from './shared.js';
|
|
@@ -111,12 +112,51 @@ function buildFormatOptions(options, result, lastLimit) {
|
|
|
111
112
|
totalCount: result.totalCount,
|
|
112
113
|
filteredCount: result.filteredCount,
|
|
113
114
|
...(result.pageStart && { pageStart: result.pageStart }),
|
|
115
|
+
evictions: {
|
|
116
|
+
requestsDropped: result.dropped ?? 0,
|
|
117
|
+
bodiesEvicted: result.bodiesEvicted ?? 0,
|
|
118
|
+
},
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Watch the session's dropped/evicted counts across follow polls, so the
|
|
123
|
+
* stream notes them once per kind instead of on every poll.
|
|
124
|
+
*
|
|
125
|
+
* @returns Function giving the counts when requests or bodies were let go
|
|
126
|
+
* for the first time since the stream started, otherwise undefined
|
|
127
|
+
*/
|
|
128
|
+
function newEvictionKinds() {
|
|
129
|
+
let requestsNoted = false;
|
|
130
|
+
let bodiesNoted = false;
|
|
131
|
+
return (counts) => {
|
|
132
|
+
const newRequests = !requestsNoted && counts.requestsDropped > 0;
|
|
133
|
+
const newBodies = !bodiesNoted && counts.bodiesEvicted > 0;
|
|
134
|
+
requestsNoted ||= newRequests;
|
|
135
|
+
bodiesNoted ||= newBodies;
|
|
136
|
+
return newRequests || newBodies ? counts : undefined;
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* JSON fields of the dropped/evicted counts (the non-zero ones).
|
|
141
|
+
*
|
|
142
|
+
* @param counts - Counts to report, if any
|
|
143
|
+
* @returns `dropped` and `bodiesEvicted` when non-zero
|
|
144
|
+
*/
|
|
145
|
+
function evictionFields(counts) {
|
|
146
|
+
if (!counts)
|
|
147
|
+
return {};
|
|
148
|
+
return {
|
|
149
|
+
...(counts.requestsDropped > 0 && { dropped: counts.requestsDropped }),
|
|
150
|
+
...(counts.bodiesEvicted > 0 && { bodiesEvicted: counts.bodiesEvicted }),
|
|
114
151
|
};
|
|
115
152
|
}
|
|
116
153
|
/**
|
|
117
154
|
* Stream network requests: the last `lastN` finished ones at start, then
|
|
118
155
|
* each request once, when it has finished loading or failed (a request whose
|
|
119
|
-
* headers arrived but whose body is still loading waits), like `tail -f
|
|
156
|
+
* headers arrived but whose body is still loading waits), like `tail -f`,
|
|
157
|
+
* with a warning (JSON `pageCrashedAt`) once when the page crashes, and a
|
|
158
|
+
* note (JSON `dropped`, `bodiesEvicted`) the first time the session drops
|
|
159
|
+
* requests or evicts bodies at its limits.
|
|
120
160
|
*
|
|
121
161
|
* @param options - Command options
|
|
122
162
|
* @param resourceTypes - Validated resource types
|
|
@@ -124,6 +164,8 @@ function buildFormatOptions(options, result, lastLimit) {
|
|
|
124
164
|
*/
|
|
125
165
|
async function runFollowMode(options, resourceTypes, lastN) {
|
|
126
166
|
const shown = new Set();
|
|
167
|
+
const newCrash = newPageCrashes();
|
|
168
|
+
const newEviction = newEvictionKinds();
|
|
127
169
|
let started = false;
|
|
128
170
|
const showNetwork = async () => {
|
|
129
171
|
const result = await fetchNetworkRequests(filtersNeedHeaders(options));
|
|
@@ -131,32 +173,40 @@ async function runFollowMode(options, resourceTypes, lastN) {
|
|
|
131
173
|
return followFetchFailure(result, { json: options.json, retryIntervalMs: FOLLOW_INTERVAL });
|
|
132
174
|
}
|
|
133
175
|
noteFollowConnected();
|
|
134
|
-
const
|
|
135
|
-
const
|
|
176
|
+
const { requests } = result.data;
|
|
177
|
+
const crashedAt = newCrash(result.data.pageCrashedAt);
|
|
178
|
+
const evictions = newEviction(result.data.evictions);
|
|
179
|
+
const finished = filterRequests(requests, options, resourceTypes).filter((request) => request.duration !== undefined && !shown.has(request.requestId));
|
|
180
|
+
const present = new Set(requests.map((request) => request.requestId));
|
|
136
181
|
for (const id of shown)
|
|
137
182
|
if (!present.has(id))
|
|
138
183
|
shown.delete(id);
|
|
139
184
|
finished.forEach((request) => shown.add(request.requestId));
|
|
140
185
|
const fresh = started || lastN === 0 ? finished : finished.slice(-lastN);
|
|
141
186
|
if (options.json) {
|
|
142
|
-
if (!started || fresh.length > 0) {
|
|
187
|
+
if (!started || fresh.length > 0 || crashedAt !== undefined || evictions) {
|
|
143
188
|
const data = {
|
|
144
189
|
requests: fresh,
|
|
145
|
-
totalCount:
|
|
190
|
+
totalCount: requests.length,
|
|
146
191
|
filteredCount: fresh.length,
|
|
192
|
+
...(crashedAt !== undefined && { pageCrashedAt: crashedAt }),
|
|
193
|
+
...evictionFields(evictions),
|
|
147
194
|
};
|
|
148
|
-
console.log(JSON.stringify(buildSuccessResponse(data)
|
|
195
|
+
console.log(JSON.stringify(buildSuccessResponse(data)));
|
|
149
196
|
}
|
|
150
197
|
}
|
|
151
198
|
else {
|
|
152
|
-
const pageStart = pageStartOf(
|
|
199
|
+
const pageStart = pageStartOf(requests);
|
|
153
200
|
const text = formatNetworkFollowRows(fresh, {
|
|
154
201
|
header: !started,
|
|
155
202
|
verbose: options.verbose ?? false,
|
|
156
203
|
...(pageStart && { pageStart }),
|
|
204
|
+
...(evictions && { evictions }),
|
|
157
205
|
});
|
|
158
206
|
if (text)
|
|
159
207
|
console.log(text);
|
|
208
|
+
if (crashedAt !== undefined)
|
|
209
|
+
console.log(pageCrashedNote(crashedAt));
|
|
160
210
|
}
|
|
161
211
|
started = true;
|
|
162
212
|
return undefined;
|
|
@@ -219,18 +269,21 @@ export function registerListCommand(networkCmd) {
|
|
|
219
269
|
}
|
|
220
270
|
return createErrorResult(result.error, result.exitCode, result.suggestion);
|
|
221
271
|
}
|
|
222
|
-
const
|
|
223
|
-
const
|
|
272
|
+
const { requests, pageCrashedAt, evictions } = result.data;
|
|
273
|
+
const filtered = filterRequests(requests, options, resourceTypes);
|
|
274
|
+
const pageStart = pageStartOf(requests);
|
|
224
275
|
return {
|
|
225
276
|
success: true,
|
|
226
277
|
data: {
|
|
227
278
|
requests: lastN === 0 ? filtered : filtered.slice(-lastN),
|
|
228
|
-
totalCount:
|
|
279
|
+
totalCount: requests.length,
|
|
229
280
|
filteredCount: filtered.length,
|
|
230
281
|
...(pageStart && { pageStart }),
|
|
282
|
+
...(pageCrashedAt !== undefined && { pageCrashedAt }),
|
|
283
|
+
...evictionFields(evictions),
|
|
231
284
|
},
|
|
232
285
|
};
|
|
233
|
-
}, options, (data) => formatNetworkList(data.requests, buildFormatOptions(options, data, lastN)));
|
|
286
|
+
}, options, (data) => withPageCrashedNote(formatNetworkList(data.requests, buildFormatOptions(options, data, lastN)), data.pageCrashedAt));
|
|
234
287
|
});
|
|
235
288
|
}
|
|
236
289
|
//# sourceMappingURL=list.js.map
|
|
@@ -6,13 +6,36 @@
|
|
|
6
6
|
*
|
|
7
7
|
* @see docs/principles/SELF_DOCUMENTING_SYSTEMS.md
|
|
8
8
|
*/
|
|
9
|
+
import type { Option } from 'commander';
|
|
9
10
|
import type { OptionBehavior } from './helpJson.js';
|
|
11
|
+
/**
|
|
12
|
+
* Registry key format: last command name, colon, long flag (the short flag
|
|
13
|
+
* when there is no long one), e.g. "screenshot:--no-resize", "bdg:--headless"
|
|
14
|
+
*/
|
|
15
|
+
type BehaviorKey = string;
|
|
16
|
+
/**
|
|
17
|
+
* Build behavior registry key from command and option: the command's own
|
|
18
|
+
* name (`bdg` for the root) and the option's long flag, or its short flag
|
|
19
|
+
* when it has no long one.
|
|
20
|
+
*
|
|
21
|
+
* @param commandName - Command name (e.g., "screenshot")
|
|
22
|
+
* @param option - Commander option
|
|
23
|
+
* @returns Registry key
|
|
24
|
+
*/
|
|
25
|
+
export declare function behaviorKey(commandName: string, option: Option): BehaviorKey;
|
|
26
|
+
/**
|
|
27
|
+
* Every key in the behavior registry.
|
|
28
|
+
*
|
|
29
|
+
* @returns Registry keys
|
|
30
|
+
*/
|
|
31
|
+
export declare function listBehaviorKeys(): BehaviorKey[];
|
|
10
32
|
/**
|
|
11
33
|
* Look up behavioral metadata for an option.
|
|
12
34
|
*
|
|
13
35
|
* @param commandName - Name of the command containing the option
|
|
14
|
-
* @param
|
|
36
|
+
* @param option - Commander option
|
|
15
37
|
* @returns Behavioral metadata if registered, undefined otherwise
|
|
16
38
|
*/
|
|
17
|
-
export declare function getOptionBehavior(commandName: string,
|
|
39
|
+
export declare function getOptionBehavior(commandName: string, option: Option): OptionBehavior | undefined;
|
|
40
|
+
export {};
|
|
18
41
|
//# sourceMappingURL=optionBehaviors.d.ts.map
|
|
@@ -17,6 +17,8 @@ const STILL_CHANGING_BEHAVIOR = 'When the page was still changing as the action
|
|
|
17
17
|
const SHOWN_BEHAVIOR = 'Elements the action showed are listed (Shown: <element> "<text>"; JSON shown [{ text, element }], at most 3, outermost first): elements with visible text added inside the target\'s form, search box, dialog or combobox (else its grandparent, or its parent when that is the body), and popups and messages added anywhere (tooltip, menu, listbox, dialog, alert, status roles, popover, aria-live, message-like classes); widgets elsewhere on the page and re-rendered elements whose text was there before do not count';
|
|
18
18
|
/** What `--no-wait` does to a DOM action's triggered requests */
|
|
19
19
|
const NO_WAIT_TRIGGERED_REQUESTS = 'Returns immediately without waiting for network; triggeredRequests lists only requests bdg saw start before returning (often none yet; check bdg network list later)';
|
|
20
|
+
/** How every follow mode (peek, console, network list) runs and ends */
|
|
21
|
+
const FOLLOW_BEHAVIOR = 'Stops with exit 83 when the session it follows ends, 130 on Ctrl-C, 143 on SIGTERM; with --json prints one compact object per line (NDJSON). Other failures (a busy page, a timeout) are retried: reported once in text, as one error line per refresh in JSON';
|
|
20
22
|
/**
|
|
21
23
|
* Behavioral metadata registry.
|
|
22
24
|
*
|
|
@@ -63,8 +65,9 @@ const OPTION_BEHAVIORS = {
|
|
|
63
65
|
},
|
|
64
66
|
'get:--full': {
|
|
65
67
|
default: 'Semantic output shows the element text up to 500 characters (whitespace collapsed; close buttons such as "×" and aria-hidden icons left out)',
|
|
66
|
-
whenEnabled: 'Shows all of the element text;
|
|
67
|
-
|
|
68
|
+
whenEnabled: 'Shows all of the element text; with --raw (or --node-id) prints the whole outer HTML instead of its first 20000 characters, and JSON outerHTML is whole too (else cut to 20000 with truncatedFrom, the original length)',
|
|
69
|
+
automaticBehavior: 'Without --full, --raw output cuts each element\'s HTML at 20000 characters and ends it with "… N more chars (use --full)"',
|
|
70
|
+
tokenImpact: 'A page-sized container can add thousands of tokens; dom get body --raw --full on Wikipedia is about 3.4 MB. Target the element you need',
|
|
68
71
|
},
|
|
69
72
|
'get:--all': {
|
|
70
73
|
default: 'Returns first matching element only',
|
|
@@ -73,40 +76,52 @@ const OPTION_BEHAVIORS = {
|
|
|
73
76
|
'get:--index': {
|
|
74
77
|
default: 'Returns the first matching element (body without a selector)',
|
|
75
78
|
whenEnabled: 'Returns that match of the selector (0-based), in semantic and --raw output; --nth is an alias',
|
|
76
|
-
automaticBehavior: '
|
|
79
|
+
automaticBehavior: 'Past the last match exits 81; a numeric index argument (a cached query index) past the indexed matches, or from an earlier page, exits 87 (re-run dom query)',
|
|
77
80
|
},
|
|
78
81
|
'query:--limit': {
|
|
79
|
-
default: 'dom a11y query
|
|
82
|
+
default: 'dom query and dom a11y query list the first 50 matches and say how many more there are; --json lists the first 100 with count (all matches) and omitted (the rest)',
|
|
80
83
|
whenEnabled: 'Lists that many matches (0 = all), in human and JSON output; count is always the total, JSON omitted the rest',
|
|
81
|
-
automaticBehavior: '
|
|
82
|
-
tokenImpact: 'About one line per match; a page can have
|
|
84
|
+
automaticBehavior: 'Matches are cached for index-based access (bdg dom click 55 works even when 50 are listed): all of them for dom a11y query, the first 1000 (or --limit, if higher) for dom query, which describes only those, so a page with 50000 matches answers in under a second; an element the page and frame trees both report is listed once. Indices work with click, fill, hover, pressKey, scroll, submit, layout, get and listeners, also for elements of a cross-origin iframe of the same site (a consent dialog), whose scripts then run in that frame',
|
|
85
|
+
tokenImpact: 'About one line per match (piped JSON about 160 bytes per dom query match, 230 per a11y match); a page can have thousands of links: on Wikipedia "United States" --limit 0 --json is 1.0 MB (dom query a) and 1.3 MB (dom a11y query role:link), the default 16 KB and 23 KB',
|
|
86
|
+
},
|
|
87
|
+
'tree:--limit': {
|
|
88
|
+
default: 'dom a11y tree lists the first 50 meaningful nodes depth-first, in human and JSON output; JSON count is the whole tree = nodes listed + omitted (cut by --limit/--depth) + skipped (never listed)',
|
|
89
|
+
whenEnabled: 'Lists that many nodes; 0 = all listed nodes (text boxes and empty wrappers are always skipped)',
|
|
90
|
+
automaticBehavior: 'Ignored nodes, text boxes, blank text, text repeating its parent name and nameless layout wrappers (generic, none, presentation, layout tables) are never listed (JSON skipped counts them); their children move up a level. For the raw tree with every node use bdg cdp Accessibility.getFullAXTree --json. JSON nodes carry depth (0 = root) instead of childIds; nodes outside the root (frame content) follow the root tree',
|
|
91
|
+
tokenImpact: 'About 140 bytes per piped JSON node (7 KB by default); the whole tree of a long page is megabytes (Wikipedia "United States": 51k nodes, 20k listed, 2.6 MB with --limit 0 --json), so prefer --depth or dom a11y query "role:<role>"',
|
|
92
|
+
},
|
|
93
|
+
'tree:--depth': {
|
|
94
|
+
default: 'dom a11y tree lists every level (up to --limit nodes)',
|
|
95
|
+
whenEnabled: 'Lists nodes down to that level (0 = root only); deeper nodes are counted in omitted',
|
|
96
|
+
tokenImpact: 'An outline of a page (landmarks, headings) in a few levels',
|
|
83
97
|
},
|
|
84
98
|
'eval:--frame': {
|
|
85
99
|
default: "Evaluates in the page's main frame",
|
|
86
100
|
whenEnabled: "Evaluates in one iframe's main world (its own globals), including cross-origin (out-of-process) iframes; output gains a frame field (its URL)",
|
|
87
101
|
automaticBehavior: 'The value is matched as: a 0-based index (bdg dom frames order: document order of the <iframe> elements, nested ones depth-first, main page not counted), else an exact name/id attribute, else a case-insensitive part of the name, id or URL. Several matches fail with 81 listing them; none fails with 83 listing all frames. Frames are looked up on every call (a reloaded iframe is found again). An index that names another frame than in the last bdg dom frames listing (iframes added, removed or moved, or the page navigated) fails with 87 STALE_CACHE: re-run bdg dom frames or pick the frame by name.',
|
|
88
102
|
},
|
|
89
|
-
'
|
|
90
|
-
default: '
|
|
91
|
-
whenEnabled: '
|
|
92
|
-
|
|
103
|
+
'eval:--full': {
|
|
104
|
+
default: 'Human output prints the first 20000 characters of the value followed by "… N more chars (use --full)"; in JSON a string result is cut to 20000 characters with truncatedFrom (the original length). Objects and arrays in JSON are not cut',
|
|
105
|
+
whenEnabled: 'Prints the whole value, byte for byte',
|
|
106
|
+
tokenImpact: 'dom eval document.documentElement.outerHTML on Wikipedia is about 3.6 MB with --full; select what you need in the expression instead',
|
|
107
|
+
},
|
|
108
|
+
'console:--full': {
|
|
109
|
+
default: 'Message texts are cut: human output (summary, --list, --follow) at 200 characters followed by "… N more chars (use --full)"; JSON text at 10000 characters with truncatedFrom (the original length)',
|
|
110
|
+
whenEnabled: 'Message texts are printed whole, in human and JSON output',
|
|
111
|
+
tokenImpact: 'A page that logs a large payload or throws a long error can add megabytes; bdg details console <n> shows one message whole',
|
|
93
112
|
},
|
|
94
113
|
'console:--history': {
|
|
95
114
|
default: 'Shows messages from current page load only (most recent navigation)',
|
|
96
115
|
whenEnabled: 'Shows messages from ALL page loads during the session',
|
|
97
116
|
automaticBehavior: 'Page navigations create new "navigation contexts" - default filters to latest context',
|
|
98
117
|
},
|
|
99
|
-
'console:-l': {
|
|
100
|
-
default: 'Smart summary with errors deduplicated and warnings grouped',
|
|
101
|
-
whenEnabled: 'Lists all messages chronologically without deduplication',
|
|
102
|
-
},
|
|
103
118
|
'console:--list': {
|
|
104
|
-
default: 'Smart summary with errors deduplicated and warnings grouped',
|
|
119
|
+
default: 'Smart summary with errors deduplicated and warnings grouped: the newest 50 distinct errors and warnings, with a note for the earlier ones. The session keeps the newest 10000 messages; dropped ones are counted (dropped in JSON)',
|
|
105
120
|
whenEnabled: 'Lists all messages chronologically without deduplication',
|
|
106
121
|
},
|
|
107
122
|
'console:--last': {
|
|
108
123
|
default: 'Smart summary (without --list); a list shows the last 100 messages',
|
|
109
|
-
whenEnabled: 'Lists the last N messages (0 = all) chronologically, also without --list; JSON gets messages',
|
|
124
|
+
whenEnabled: 'Lists the last N messages (0 = all) chronologically, also without --list; JSON gets messages and N distinct errors and warnings (0 = all; default 50)',
|
|
110
125
|
automaticBehavior: 'The [n] shown are positions in the session message list (what bdg details console <n> takes); when the page or level filter left messages out between the listed ones, a note says how many and why',
|
|
111
126
|
},
|
|
112
127
|
'console:--level': {
|
|
@@ -126,7 +141,7 @@ const OPTION_BEHAVIORS = {
|
|
|
126
141
|
'click:--no-wait': {
|
|
127
142
|
default: 'Waits for network stability after click (150ms idle, up to 2s)',
|
|
128
143
|
whenDisabled: NO_WAIT_TRIGGERED_REQUESTS,
|
|
129
|
-
automaticBehavior: `Network wait helps ensure AJAX requests triggered by click complete. ${TRIGGERED_REQUESTS_BEHAVIOR}. The click itself uses real mouse events in the visible part of the element (method "mouse"); if the element is covered or has no size it falls back to DOM events (method "dom", with a warning; --strict refuses instead). Results the page shows later (timers, spinners, slow renders) are not waited for but reported as pending work: use bdg dom wait <selector> --visible. ${ACTION_EFFECTS_BEHAVIOR}. ${STILL_CHANGING_BEHAVIOR}. A click with no DOM change, no request and no
|
|
144
|
+
automaticBehavior: `Network wait helps ensure AJAX requests triggered by click complete. ${TRIGGERED_REQUESTS_BEHAVIOR}. The click itself uses real mouse events in the visible part of the element (method "mouse"); if the element is covered or has no size it falls back to DOM events (method "dom", with a warning; --strict refuses instead). Results the page shows later (timers, spinners, slow renders) are not waited for but reported as pending work: use bdg dom wait <selector> --visible. ${ACTION_EFFECTS_BEHAVIOR}. ${STILL_CHANGING_BEHAVIOR}. A click with no DOM change, no request, no navigation and no console message (checked again 300 ms later, which adds 300 ms plus at most 250 ms for the read) is reported as ⚠ Element Clicked (no visible effect observed: no DOM change, requests or navigation within 300 ms) and effect: "none" in JSON (exit code stays 0); not claimed with --no-wait, for hover or right-click, after a copy or cut, or when the click hit a form control, label, media, iframe, popover button, a mailto:/tel:/javascript: or other non-http link, a link to another window or a custom element with a closed shadow root, or moved focus to an element that is not a button or link. Effects outside the DOM (CSS :hover/:focus-within styles, canvas, clipboard without a copy event) are not seen`,
|
|
130
145
|
tokenImpact: 'A click that navigates lists the whole page load in JSON triggeredRequests',
|
|
131
146
|
},
|
|
132
147
|
'click:--double': {
|
|
@@ -145,7 +160,7 @@ const OPTION_BEHAVIORS = {
|
|
|
145
160
|
'hover:--no-wait': {
|
|
146
161
|
default: 'Waits for network stability after moving the mouse (menus may load content)',
|
|
147
162
|
whenDisabled: NO_WAIT_TRIGGERED_REQUESTS,
|
|
148
|
-
automaticBehavior: `The mouse stays over the element afterwards, so hover menus stay open until the next mouse action. ${TRIGGERED_REQUESTS_BEHAVIOR}. ${ACTION_EFFECTS_BEHAVIOR}. ${SHOWN_BEHAVIOR}; for a hover also elements around it (its parent's subtree) and tooltips, menus, listboxes, dialogs and popovers anywhere that were hidden before, so captions shown by CSS :hover count (hidden elements noted by identity right before the mouse moves: up to 1500, within 8 ms). A hover never claims "no visible effect" and does not check whether the page was still changing`,
|
|
163
|
+
automaticBehavior: `The element is scrolled into view first; when the page moved, Scrolled (JSON scrolledBy) says how far. The mouse stays over the element afterwards, so hover menus stay open until the next mouse action. ${TRIGGERED_REQUESTS_BEHAVIOR}. ${ACTION_EFFECTS_BEHAVIOR}. ${SHOWN_BEHAVIOR}; for a hover also elements around it (its parent's subtree) and tooltips, menus, listboxes, dialogs and popovers anywhere that were hidden before, so captions shown by CSS :hover count (hidden elements noted by identity right before the mouse moves: up to 1500, within 8 ms). A hover never claims "no visible effect" and does not check whether the page was still changing`,
|
|
149
164
|
},
|
|
150
165
|
'hover:--strict': {
|
|
151
166
|
default: 'A covered, hidden or zero-size element gets synthetic mouseover/mouseenter events (method "dom", with a warning)',
|
|
@@ -215,7 +230,7 @@ const OPTION_BEHAVIORS = {
|
|
|
215
230
|
'audit:--level': {
|
|
216
231
|
default: 'Text must reach WCAG AA: 4.5, or 3 for large text (24px, or 18.66px bold); every text-drawing element is checked, composited like dom inspect',
|
|
217
232
|
whenEnabled: '--level AAA asks 7, or 4.5 for large text',
|
|
218
|
-
automaticBehavior: 'One walk over the rendered elements (open shadow roots included, at most 20000; capped says when it stopped). Findings are sorted weakest first; --limit (default 20) lists that many per check and the rest are counted. Overflow leaves out content inside horizontal scrollers and visually-hidden 1px text; identical findings are grouped (×N)',
|
|
233
|
+
automaticBehavior: 'One walk over the rendered elements (open shadow roots included, at most 20000; capped says when it stopped). Findings are sorted weakest first; --limit (default 20) lists that many per check and the rest are counted. Overflow leaves out content inside horizontal scrollers and visually-hidden 1px text; identical findings are grouped (×N). Contrast is approximate (approximate: …) when something is painted behind or on top of text in view (hit-tested), or for text out of view whose ancestors paint nothing below body (only its ancestors were checked). Canvas animations cannot be listed; visible canvas elements are counted (canvases)',
|
|
219
234
|
tokenImpact: 'About one line per finding; --limit bounds it',
|
|
220
235
|
},
|
|
221
236
|
'layout:--index': {
|
|
@@ -228,12 +243,12 @@ const OPTION_BEHAVIORS = {
|
|
|
228
243
|
default: 'Inspects the first rendered match (the first when none is rendered) and notes how many matched; a numeric argument inspects that cached element (from dom query, dom form or dom a11y query)',
|
|
229
244
|
whenEnabled: 'Inspects the nth match (0-based); out of range exits 81',
|
|
230
245
|
automaticBehavior: 'Answers "what does it look like" without a screenshot, grouped like Figma Dev Mode: header (element, text, size and page position, [flex]/[grid], [not rendered]/[hidden]/[offscreen]/[covered by …], prefers-color-scheme), box (margin, padding, border widths, box-sizing, overflow, scroll size), layout (display, position, flex/grid container and item settings), parent (its display and layout, distances to its content edges, gaps to the neighbouring siblings), text (first font family → the font Chrome rendered, (webfont) or local; weight size/line-height; color; WCAG contrast against the composited background; only for elements with text), fill, border (sides, radius, outline), fx (shadow, transform, filter, opacity, blend), state (cursor, pointer-events, user-select, appearance), pseudo (::before/::after with content, ::placeholder) and a child tree (depth 2, 20 rows, identical siblings grouped). Values that change nothing (0, none, transparent, normal) are left out; colors are hex (lab/oklch from Tailwind converted), lengths px without the unit, rounded to 0.1. Secrets are never shown. JSON uses Figma-aligned names (rect, box, layout.sizing hug/fill/fixed, text, fills, strokes, radius, effects, children). Also by default: hints, the element\'s own declarations that have no effect (justify-content on a block, width on an inline element, top on a static one, var() of an unset custom property) with the reason, the fix and the rule\'s file:line',
|
|
231
|
-
tokenImpact: 'About
|
|
246
|
+
tokenImpact: 'About 80–130 tokens for a button: 80–100 for the styles, up to 50 per hint (--no-hints drops them), and 30–70 more for a child tree (--tree 0 drops it), against about 1,500 for a screenshot or 3,000+ for raw computed styles',
|
|
232
247
|
},
|
|
233
248
|
'inspect:--all': {
|
|
234
249
|
default: 'Shows the curated groups (the properties that define the look)',
|
|
235
250
|
whenEnabled: 'Lists every computed property that differs from the default of the same element type, longhands collapsed into shorthands, noise (logical duplicates, currentColor echoes, custom properties) dropped',
|
|
236
|
-
tokenImpact: 'About
|
|
251
|
+
tokenImpact: 'About as many tokens as the curated groups (about 90 for a button)',
|
|
237
252
|
},
|
|
238
253
|
'inspect:--props': {
|
|
239
254
|
default: 'Shows the curated groups',
|
|
@@ -251,6 +266,7 @@ const OPTION_BEHAVIORS = {
|
|
|
251
266
|
},
|
|
252
267
|
'inspect:--no-hints': {
|
|
253
268
|
default: "Hints at the element's own author declarations that have no effect (flex/grid properties without flex or grid, item properties without a flex or grid parent, offsets on static elements, sizes on inline ones, var() of an unset custom property, form controls in the browser's font), within a 1 s budget; hints none when nothing was found",
|
|
269
|
+
automaticBehavior: "After a hint read times out, later inspects on the same page skip the hints without waiting (hints skipped: this page's stylesheets are slow to read) until a read is fast again, a stylesheet changes or it navigates; --rules and --why still wait up to 5 s. Matched rules that took over 300 ms are reused for up to 5 s, until a command that may change the page or a stylesheet or DOM change",
|
|
254
270
|
whenEnabled: 'Skips the hints and does not read the matched rules',
|
|
255
271
|
},
|
|
256
272
|
'scroll:--down': {
|
|
@@ -291,36 +307,52 @@ const OPTION_BEHAVIORS = {
|
|
|
291
307
|
whenEnabled: 'Quick scan: field names, types, and required status only',
|
|
292
308
|
tokenImpact: 'Reduces output ~50% for initial discovery',
|
|
293
309
|
},
|
|
310
|
+
'peek:--full': {
|
|
311
|
+
default: 'Console message texts are cut: human output at 200 characters (compact output also at 2 lines) followed by "… N more chars (use --full)"; JSON text at 10000 characters with truncatedFrom (the original length)',
|
|
312
|
+
whenEnabled: 'Console message texts are printed whole, in human and JSON output',
|
|
313
|
+
tokenImpact: 'A page that logs a large payload can add megabytes per peek',
|
|
314
|
+
},
|
|
294
315
|
'peek:--type': {
|
|
295
316
|
whenEnabled: 'Filters network requests by CDP resource type. Case-insensitive, comma-separated. Valid: Document, Stylesheet, Image, Media, Font, Script, XHR, Fetch, WebSocket, etc.',
|
|
296
317
|
},
|
|
297
|
-
'peek:-f': {
|
|
298
|
-
default: 'Shows snapshot of current data',
|
|
299
|
-
whenEnabled: 'Continuous monitoring (like tail -f): refreshes every second, or every --interval ms (100-60000). Replaces the deprecated bdg tail',
|
|
300
|
-
},
|
|
301
318
|
'peek:--follow': {
|
|
302
319
|
default: 'Shows snapshot of current data',
|
|
303
320
|
whenEnabled: 'Continuous monitoring (like tail -f): refreshes every second, or every --interval ms (100-60000). Replaces the deprecated bdg tail',
|
|
321
|
+
automaticBehavior: FOLLOW_BEHAVIOR,
|
|
322
|
+
},
|
|
323
|
+
'console:--follow': {
|
|
324
|
+
default: 'Prints the messages logged so far and exits',
|
|
325
|
+
whenEnabled: 'Streams new messages as they come (the last --last at start)',
|
|
326
|
+
automaticBehavior: FOLLOW_BEHAVIOR,
|
|
327
|
+
},
|
|
328
|
+
'list:--follow': {
|
|
329
|
+
default: 'Lists the requests captured so far and exits',
|
|
330
|
+
whenEnabled: 'Streams requests as they finish',
|
|
331
|
+
automaticBehavior: FOLLOW_BEHAVIOR,
|
|
304
332
|
},
|
|
305
|
-
'peek
|
|
333
|
+
'peek:--verbose': {
|
|
306
334
|
default: 'Compact output (truncated URLs, no resource types)',
|
|
307
335
|
whenEnabled: 'Verbose output with full URLs and resource types',
|
|
308
336
|
},
|
|
309
|
-
'
|
|
337
|
+
'bdg:--headless': {
|
|
338
|
+
default: 'A window when there is a display: on macOS unless over SSH (SSH_CONNECTION, SSH_TTY) or CI is set; on Linux when DISPLAY or WAYLAND_DISPLAY is set. Servers, containers and CI run headless',
|
|
339
|
+
whenEnabled: 'Chrome runs without a window (pass it when running unattended on a Mac)',
|
|
340
|
+
},
|
|
341
|
+
'bdg:--no-headless': {
|
|
342
|
+
default: 'A window when there is a display: on macOS unless over SSH (SSH_CONNECTION, SSH_TTY) or CI is set; on Linux when DISPLAY or WAYLAND_DISPLAY is set',
|
|
343
|
+
whenEnabled: 'Chrome shows its window even without a detected display (it fails without one)',
|
|
344
|
+
},
|
|
345
|
+
'bdg:--all': {
|
|
310
346
|
default: 'Tracking/analytics requests and console noise are filtered; bodies of binary responses (images, fonts) are not captured',
|
|
311
347
|
whenEnabled: 'Everything is captured, including binary response bodies (base64, flagged by responseBodyBase64, within --max-body-size)',
|
|
312
348
|
tokenImpact: 'details network --json and HAR exports can grow considerably on media-heavy pages',
|
|
313
349
|
},
|
|
314
|
-
'peek:--verbose': {
|
|
315
|
-
default: 'Compact output (truncated URLs, no resource types)',
|
|
316
|
-
whenEnabled: 'Verbose output with full URLs and resource types',
|
|
317
|
-
},
|
|
318
350
|
'bdg:--session': {
|
|
319
351
|
default: 'The default session in ~/.bdg (or $BDG_SESSION_DIR); BDG_SESSION=<name> selects a named session like the flag',
|
|
320
352
|
whenEnabled: 'Uses the named session in ~/.bdg/sessions/<name>/ (or $BDG_SESSION_DIR/sessions/<name>/) with its own daemon, Chrome, profile and port; every command (status, stop, cleanup, ...) acts on that session only',
|
|
321
353
|
automaticBehavior: 'Accepted before or after any subcommand; --session wins over BDG_SESSION. Names are case-insensitive (lower-cased: ALPHA is alpha). Without --port a named session takes the first free port above 9222 not claimed by another running session, and keeps it in port.txt. Names: 1-40 letters, digits, "-" or "_", starting with a letter or digit (exit 81 otherwise, also when the socket path would be too long). Hints and suggestions in its output carry --session <name>',
|
|
322
354
|
},
|
|
323
|
-
'cleanup
|
|
355
|
+
'cleanup:--force': {
|
|
324
356
|
default: 'Refuses to run while a session is active; removes files left by a crashed session',
|
|
325
357
|
whenEnabled: 'Kills the running daemon and its Chrome first (use when a session is stuck)',
|
|
326
358
|
},
|
|
@@ -355,36 +387,39 @@ const OPTION_BEHAVIORS = {
|
|
|
355
387
|
default: 'Chrome launched by bdg is always closed on stop; an attached Chrome (--chrome-ws-url) is left running',
|
|
356
388
|
whenEnabled: 'No additional effect; kept for compatibility',
|
|
357
389
|
},
|
|
358
|
-
'status:-v': {
|
|
359
|
-
default: 'Basic session status (daemon running, session active, URL)',
|
|
360
|
-
whenEnabled: 'Includes Chrome diagnostics and CDP connection details',
|
|
361
|
-
},
|
|
362
390
|
'status:--verbose': {
|
|
363
391
|
default: 'Basic session status (daemon running, session active, URL)',
|
|
364
392
|
whenEnabled: 'Includes Chrome diagnostics and CDP connection details',
|
|
365
393
|
},
|
|
366
394
|
};
|
|
367
395
|
/**
|
|
368
|
-
* Build behavior registry key from command and
|
|
396
|
+
* Build behavior registry key from command and option: the command's own
|
|
397
|
+
* name (`bdg` for the root) and the option's long flag, or its short flag
|
|
398
|
+
* when it has no long one.
|
|
369
399
|
*
|
|
370
400
|
* @param commandName - Command name (e.g., "screenshot")
|
|
371
|
-
* @param
|
|
401
|
+
* @param option - Commander option
|
|
372
402
|
* @returns Registry key
|
|
373
403
|
*/
|
|
374
|
-
function
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
404
|
+
export function behaviorKey(commandName, option) {
|
|
405
|
+
return `${commandName}:${option.long ?? option.short ?? option.flags}`;
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Every key in the behavior registry.
|
|
409
|
+
*
|
|
410
|
+
* @returns Registry keys
|
|
411
|
+
*/
|
|
412
|
+
export function listBehaviorKeys() {
|
|
413
|
+
return Object.keys(OPTION_BEHAVIORS);
|
|
378
414
|
}
|
|
379
415
|
/**
|
|
380
416
|
* Look up behavioral metadata for an option.
|
|
381
417
|
*
|
|
382
418
|
* @param commandName - Name of the command containing the option
|
|
383
|
-
* @param
|
|
419
|
+
* @param option - Commander option
|
|
384
420
|
* @returns Behavioral metadata if registered, undefined otherwise
|
|
385
421
|
*/
|
|
386
|
-
export function getOptionBehavior(commandName,
|
|
387
|
-
|
|
388
|
-
return OPTION_BEHAVIORS[key];
|
|
422
|
+
export function getOptionBehavior(commandName, option) {
|
|
423
|
+
return OPTION_BEHAVIORS[behaviorKey(commandName, option)];
|
|
389
424
|
}
|
|
390
425
|
//# sourceMappingURL=optionBehaviors.js.map
|
package/dist/commands/peek.js
CHANGED
|
@@ -8,6 +8,7 @@ import { fetchPreviewOutput, createErrorResult, } from './shared/dataFetcher.js'
|
|
|
8
8
|
import { followFetchFailure, setupFollowMode, } from './shared/followMode.js';
|
|
9
9
|
import { handleValidationError } from './shared/handleValidationError.js';
|
|
10
10
|
import { MAX_LAST_ITEMS, positiveIntRule, resourceTypeRule } from './shared/validation.js';
|
|
11
|
+
import { MAX_CONSOLE_JSON_TEXT_LENGTH, MAX_CONSOLE_TEXT_LENGTH } from '../constants.js';
|
|
11
12
|
import { CommandError } from '../errors/index.js';
|
|
12
13
|
import { intervalWithoutFollowError } from '../errors/messages.js';
|
|
13
14
|
import { filterByResourceType } from '../telemetry/filters.js';
|
|
@@ -137,6 +138,7 @@ function previewDisplayOptions(options, lastN) {
|
|
|
137
138
|
last: lastN,
|
|
138
139
|
verbose: options.verbose,
|
|
139
140
|
follow: options.follow,
|
|
141
|
+
full: options.full,
|
|
140
142
|
};
|
|
141
143
|
}
|
|
142
144
|
/**
|
|
@@ -162,6 +164,7 @@ export function registerPeekCommand(program) {
|
|
|
162
164
|
.option('--interval <ms>', 'Refresh interval of --follow in ms, 100-60000 (default: 1000)')
|
|
163
165
|
.option('--last <count>', 'Show last N items, 0 for all', '10')
|
|
164
166
|
.option('--type <types>', 'Filter network requests by resource type (comma-separated: Document,XHR,Fetch,etc.)')
|
|
167
|
+
.option('--full', `Print console message texts whole (default: the first ${MAX_CONSOLE_TEXT_LENGTH} characters, ${MAX_CONSOLE_JSON_TEXT_LENGTH} in JSON)`, false)
|
|
165
168
|
.action(async (options) => {
|
|
166
169
|
showBothSectionsWhenBothRequested(options);
|
|
167
170
|
if (options.network && !options.json) {
|
|
@@ -2,7 +2,7 @@ import { getQuickIPCRequestTimeout } from '../../constants.js';
|
|
|
2
2
|
import { CommandError, isDaemonConnectionError } from '../../errors/index.js';
|
|
3
3
|
import { daemonNotRunningError, unknownError, genericError, commandTimedOutError, sessionNotRespondingError, sessionEndedDuringCommandError, } from '../../errors/messages.js';
|
|
4
4
|
import { IPCEarlyCloseError, IPCTimeoutError } from '../../ipc/transport/IPCError.js';
|
|
5
|
-
import { OutputBuilder, buildSuccessResponse } from '../../ui/OutputBuilder.js';
|
|
5
|
+
import { OutputBuilder, buildSuccessResponse, stringifyEnvelope } from '../../ui/OutputBuilder.js';
|
|
6
6
|
import { escapeControlChars } from '../../ui/formatting.js';
|
|
7
7
|
import { noActiveSessionMessage, startSessionSuggestion } from '../../ui/messages/sessionCommand.js';
|
|
8
8
|
import { getErrorExitCode, getErrorMessage } from '../../utils/errors.js';
|
|
@@ -36,7 +36,7 @@ export function noActiveSessionError() {
|
|
|
36
36
|
export async function runJsonCommand(fn) {
|
|
37
37
|
try {
|
|
38
38
|
const data = await fn();
|
|
39
|
-
console.log(
|
|
39
|
+
console.log(stringifyEnvelope(buildSuccessResponse(data)));
|
|
40
40
|
process.exit(EXIT_CODES.SUCCESS);
|
|
41
41
|
}
|
|
42
42
|
catch (caught) {
|
|
@@ -49,10 +49,10 @@ export async function runJsonCommand(fn) {
|
|
|
49
49
|
const suggestion = error instanceof CommandError && typeof error.metadata['suggestion'] === 'string'
|
|
50
50
|
? error.metadata['suggestion']
|
|
51
51
|
: undefined;
|
|
52
|
-
console.log(
|
|
52
|
+
console.log(stringifyEnvelope(OutputBuilder.buildJsonError(getErrorMessage(error), {
|
|
53
53
|
exitCode,
|
|
54
54
|
...(suggestion && { suggestion }),
|
|
55
|
-
})
|
|
55
|
+
})));
|
|
56
56
|
process.exit(exitCode);
|
|
57
57
|
}
|
|
58
58
|
}
|
|
@@ -112,10 +112,10 @@ export async function runCommand(handler, options, formatter) {
|
|
|
112
112
|
if (!result.success) {
|
|
113
113
|
const exitCode = result.exitCode ?? EXIT_CODES.UNHANDLED_EXCEPTION;
|
|
114
114
|
if (options.json) {
|
|
115
|
-
console.log(
|
|
115
|
+
console.log(stringifyEnvelope(OutputBuilder.buildJsonError(result.error ?? 'Unknown error', {
|
|
116
116
|
...result.errorContext,
|
|
117
117
|
exitCode,
|
|
118
|
-
})
|
|
118
|
+
})));
|
|
119
119
|
}
|
|
120
120
|
else {
|
|
121
121
|
console.error(result.error ? genericError(result.error) : unknownError());
|
|
@@ -133,14 +133,14 @@ export async function runCommand(handler, options, formatter) {
|
|
|
133
133
|
console.error(escapeControlChars(result.hint));
|
|
134
134
|
}
|
|
135
135
|
if (options.json) {
|
|
136
|
-
console.log(
|
|
136
|
+
console.log(stringifyEnvelope(buildSuccessResponse(result.data)));
|
|
137
137
|
}
|
|
138
138
|
else if (formatter) {
|
|
139
139
|
const formattedOutput = formatter(result.data);
|
|
140
140
|
console.log(escapeControlChars(formattedOutput));
|
|
141
141
|
}
|
|
142
142
|
else {
|
|
143
|
-
console.log(
|
|
143
|
+
console.log(stringifyEnvelope(buildSuccessResponse(result.data)));
|
|
144
144
|
}
|
|
145
145
|
process.exit(EXIT_CODES.SUCCESS);
|
|
146
146
|
}
|
|
@@ -152,10 +152,10 @@ export async function runCommand(handler, options, formatter) {
|
|
|
152
152
|
: caught;
|
|
153
153
|
if (error instanceof CommandError) {
|
|
154
154
|
if (options.json) {
|
|
155
|
-
console.log(
|
|
155
|
+
console.log(stringifyEnvelope(OutputBuilder.buildJsonError(error.message, {
|
|
156
156
|
...error.metadata,
|
|
157
157
|
exitCode: error.exitCode,
|
|
158
|
-
})
|
|
158
|
+
})));
|
|
159
159
|
}
|
|
160
160
|
else {
|
|
161
161
|
console.error(genericError(error.message));
|
|
@@ -168,10 +168,10 @@ export async function runCommand(handler, options, formatter) {
|
|
|
168
168
|
const errorMessage = getErrorMessage(error);
|
|
169
169
|
if (isDaemonConnectionError(error)) {
|
|
170
170
|
if (options.json) {
|
|
171
|
-
console.log(
|
|
171
|
+
console.log(stringifyEnvelope(OutputBuilder.buildJsonError(noActiveSessionMessage(), {
|
|
172
172
|
suggestion: startSessionSuggestion(),
|
|
173
173
|
exitCode: EXIT_CODES.RESOURCE_NOT_FOUND,
|
|
174
|
-
})
|
|
174
|
+
})));
|
|
175
175
|
}
|
|
176
176
|
else {
|
|
177
177
|
console.error(daemonNotRunningError());
|
|
@@ -180,7 +180,7 @@ export async function runCommand(handler, options, formatter) {
|
|
|
180
180
|
}
|
|
181
181
|
const exitCode = getErrorExitCode(error, EXIT_CODES.UNHANDLED_EXCEPTION);
|
|
182
182
|
if (options.json) {
|
|
183
|
-
console.log(
|
|
183
|
+
console.log(stringifyEnvelope(OutputBuilder.buildJsonError(errorMessage, { exitCode })));
|
|
184
184
|
}
|
|
185
185
|
else {
|
|
186
186
|
console.error(genericError(errorMessage));
|
|
@@ -28,8 +28,11 @@ export declare function noteFollowConnected(): void;
|
|
|
28
28
|
* Handle daemon connection errors with consistent formatting and behavior.
|
|
29
29
|
*
|
|
30
30
|
* Outside follow mode the command exits. In follow mode, a session that never
|
|
31
|
-
* answered exits too (there is nothing to follow, exit 83)
|
|
32
|
-
*
|
|
31
|
+
* answered exits too (there is nothing to follow, exit 83), and so does one
|
|
32
|
+
* that ends while followed (no session any more, exit 83), so a follower
|
|
33
|
+
* running in the background finds out. Other failures (a busy page, a
|
|
34
|
+
* timeout) are retried: reported once in text, and on every failed refresh
|
|
35
|
+
* in JSON, one object per line.
|
|
33
36
|
*
|
|
34
37
|
* @param error - Error message to display
|
|
35
38
|
* @param options - Error handling options
|