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,13 +2,30 @@
|
|
|
2
2
|
* `bdg dom query` — find elements by CSS selector and populate the query cache.
|
|
3
3
|
*/
|
|
4
4
|
import type { DomQueryCommandOptions } from '../shared/optionTypes.js';
|
|
5
|
+
import type { DomQueryResult } from '../../types.js';
|
|
6
|
+
/** Matches `dom query` lists without `--limit` (human output) */
|
|
7
|
+
export declare const QUERY_LIST_LIMIT = 50;
|
|
5
8
|
/**
|
|
6
9
|
* Handle `bdg dom query <selector>`.
|
|
7
10
|
*
|
|
8
|
-
* Runs the selector, caches the
|
|
9
|
-
* elements by index, and
|
|
11
|
+
* Runs the selector, caches the described matches so later commands can
|
|
12
|
+
* reference elements by index, and lists the first `--limit` of them (50,
|
|
13
|
+
* or {@link QUERY_CACHE_LIMIT} with `--json`; 0 = all) with the total count.
|
|
10
14
|
* No match exits 83, like `dom get` and `dom a11y`, and clears the cache so
|
|
11
15
|
* indices of an earlier query are not used by mistake.
|
|
12
16
|
*/
|
|
13
17
|
export declare function handleDomQuery(selector: string, options: DomQueryCommandOptions): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* The matches to list: the first `limit` (all with 0), with how many were
|
|
20
|
+
* left out and, when not every match was described, how many can be used by
|
|
21
|
+
* index. Nothing is added when the limit cut nothing (a match that could not
|
|
22
|
+
* be described is just missing, as before). When more than
|
|
23
|
+
* {@link VIEWPORT_HINT_LIMIT} are listed, `viewportChecked` says that only
|
|
24
|
+
* the first ones have a viewport position.
|
|
25
|
+
*
|
|
26
|
+
* @param result - Query result with every described match
|
|
27
|
+
* @param limit - Matches to list (0 = all)
|
|
28
|
+
* @returns Result to output
|
|
29
|
+
*/
|
|
30
|
+
export declare function listedMatches(result: DomQueryResult, limit: number): DomQueryResult;
|
|
14
31
|
//# sourceMappingURL=query.d.ts.map
|
|
@@ -1,22 +1,28 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `bdg dom query` — find elements by CSS selector and populate the query cache.
|
|
3
3
|
*/
|
|
4
|
-
import { noMatchesError, queryDOMElements } from './helpers/index.js';
|
|
4
|
+
import { noMatchesError, pageDocumentId, queryDOMElements } from './helpers/index.js';
|
|
5
|
+
import { QUERY_CACHE_LIMIT, VIEWPORT_HINT_LIMIT } from './helpers/query.js';
|
|
5
6
|
import { runCommand } from '../shared/CommandRunner.js';
|
|
6
7
|
import { QueryCacheManager } from '../../session/QueryCacheManager.js';
|
|
7
8
|
import { formatDomQuery } from '../../ui/formatters/dom.js';
|
|
8
9
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
10
|
+
/** Matches `dom query` lists without `--limit` (human output) */
|
|
11
|
+
export const QUERY_LIST_LIMIT = 50;
|
|
9
12
|
/**
|
|
10
13
|
* Handle `bdg dom query <selector>`.
|
|
11
14
|
*
|
|
12
|
-
* Runs the selector, caches the
|
|
13
|
-
* elements by index, and
|
|
15
|
+
* Runs the selector, caches the described matches so later commands can
|
|
16
|
+
* reference elements by index, and lists the first `--limit` of them (50,
|
|
17
|
+
* or {@link QUERY_CACHE_LIMIT} with `--json`; 0 = all) with the total count.
|
|
14
18
|
* No match exits 83, like `dom get` and `dom a11y`, and clears the cache so
|
|
15
19
|
* indices of an earlier query are not used by mistake.
|
|
16
20
|
*/
|
|
17
21
|
export async function handleDomQuery(selector, options) {
|
|
22
|
+
const limit = options.limit ?? (options.json ? QUERY_CACHE_LIMIT : QUERY_LIST_LIMIT);
|
|
18
23
|
await runCommand(async () => {
|
|
19
|
-
const
|
|
24
|
+
const document = await pageDocumentId();
|
|
25
|
+
const result = await queryDOMElements(selector, limit);
|
|
20
26
|
const cache = QueryCacheManager.getInstance();
|
|
21
27
|
if (result.count === 0) {
|
|
22
28
|
await cache.clear();
|
|
@@ -28,8 +34,33 @@ export async function handleDomQuery(selector, options) {
|
|
|
28
34
|
errorContext: { suggestion: err.suggestion },
|
|
29
35
|
};
|
|
30
36
|
}
|
|
31
|
-
await cache.set(result);
|
|
32
|
-
return { success: true, data: result };
|
|
37
|
+
await cache.set(result, document);
|
|
38
|
+
return { success: true, data: listedMatches(result, limit) };
|
|
33
39
|
}, options, formatDomQuery);
|
|
34
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* The matches to list: the first `limit` (all with 0), with how many were
|
|
43
|
+
* left out and, when not every match was described, how many can be used by
|
|
44
|
+
* index. Nothing is added when the limit cut nothing (a match that could not
|
|
45
|
+
* be described is just missing, as before). When more than
|
|
46
|
+
* {@link VIEWPORT_HINT_LIMIT} are listed, `viewportChecked` says that only
|
|
47
|
+
* the first ones have a viewport position.
|
|
48
|
+
*
|
|
49
|
+
* @param result - Query result with every described match
|
|
50
|
+
* @param limit - Matches to list (0 = all)
|
|
51
|
+
* @returns Result to output
|
|
52
|
+
*/
|
|
53
|
+
export function listedMatches(result, limit) {
|
|
54
|
+
const listed = limit === 0 || result.count <= limit
|
|
55
|
+
? result
|
|
56
|
+
: {
|
|
57
|
+
...result,
|
|
58
|
+
nodes: result.nodes.slice(0, limit),
|
|
59
|
+
omitted: result.count - Math.min(limit, result.nodes.length),
|
|
60
|
+
...(result.nodes.length < result.count && { indexed: result.nodes.length }),
|
|
61
|
+
};
|
|
62
|
+
return listed.nodes.length > VIEWPORT_HINT_LIMIT
|
|
63
|
+
? { ...listed, viewportChecked: VIEWPORT_HINT_LIMIT }
|
|
64
|
+
: listed;
|
|
65
|
+
}
|
|
35
66
|
//# sourceMappingURL=query.js.map
|
|
@@ -14,6 +14,7 @@ import { OutputBuilder, buildSuccessResponse } from '../../ui/OutputBuilder.js';
|
|
|
14
14
|
import { formatDomScreenshot } from '../../ui/formatters/dom.js';
|
|
15
15
|
import { createLogger } from '../../ui/logging/index.js';
|
|
16
16
|
import { delay } from '../../utils/async.js';
|
|
17
|
+
import { makeDirectory } from '../../utils/directories.js';
|
|
17
18
|
import { getErrorMessage } from '../../utils/errors.js';
|
|
18
19
|
import { EXIT_CODES } from '../../utils/exitCodes.js';
|
|
19
20
|
import { filterDefined } from '../../utils/objects.js';
|
|
@@ -110,7 +111,7 @@ function ensureDirectory(dirPath, fs) {
|
|
|
110
111
|
throw new CommandError(`--follow needs a directory, but ${dirPath} is a file`, { suggestion: 'Give a directory for the frames, e.g. bdg dom screenshot ./frames --follow' }, EXIT_CODES.INVALID_ARGUMENTS);
|
|
111
112
|
}
|
|
112
113
|
try {
|
|
113
|
-
|
|
114
|
+
makeDirectory(dirPath);
|
|
114
115
|
}
|
|
115
116
|
catch (error) {
|
|
116
117
|
throw outputPathError(dirPath, error);
|
|
@@ -21,10 +21,11 @@ export interface SemanticNodeWithContext {
|
|
|
21
21
|
* link's href, a field's type and name), like `dom query` does, and is
|
|
22
22
|
* followed by up to 500 characters of the element's text
|
|
23
23
|
* (all of it with `dom get --full`) when it is longer than the one-line
|
|
24
|
-
* preview
|
|
24
|
+
* preview or the role line shows an accessible name other than the text,
|
|
25
|
+
* or, for an element without text or name, what it holds.
|
|
25
26
|
*
|
|
26
27
|
* @param data - Accessibility node and optional DOM context
|
|
27
|
-
* @returns Role line, plus a text line for elements with longer text
|
|
28
|
+
* @returns Role line, plus a text line for elements with longer or differently named text
|
|
28
29
|
*/
|
|
29
30
|
export declare function formatSemanticNodeWithContext(data: SemanticNodeWithContext): string;
|
|
30
31
|
/**
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* their surrounding DOM context and to fall back gracefully when only one
|
|
6
6
|
* of the two data sources is available.
|
|
7
7
|
*/
|
|
8
|
-
import { MASKED_VALUE } from '../../runtime/dom/elementInfo.js';
|
|
8
|
+
import { MASKED_VALUE, isLabelClass } from '../../runtime/dom/elementInfo.js';
|
|
9
9
|
import { synthesizeA11yNode } from '../../telemetry/roleInference.js';
|
|
10
10
|
import { keyAttributeItems } from '../../ui/formatters/keyAttributes.js';
|
|
11
11
|
import { joinLines } from '../../ui/formatting.js';
|
|
@@ -29,9 +29,8 @@ function buildContextText(node, domContext) {
|
|
|
29
29
|
}
|
|
30
30
|
if (domContext) {
|
|
31
31
|
const tagPart = `<${domContext.tag}`;
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
: '';
|
|
32
|
+
const classes = (domContext.classes ?? []).filter(isLabelClass).slice(0, 3);
|
|
33
|
+
const classPart = classes.length > 0 ? `.${classes.join('.')}` : '';
|
|
35
34
|
const previewPart = domContext.preview && !domContext.text ? ` "${domContext.preview}"` : '';
|
|
36
35
|
return ` ${tagPart}${classPart}>${previewPart}`;
|
|
37
36
|
}
|
|
@@ -86,10 +85,11 @@ function buildPropertiesText(node) {
|
|
|
86
85
|
* link's href, a field's type and name), like `dom query` does, and is
|
|
87
86
|
* followed by up to 500 characters of the element's text
|
|
88
87
|
* (all of it with `dom get --full`) when it is longer than the one-line
|
|
89
|
-
* preview
|
|
88
|
+
* preview or the role line shows an accessible name other than the text,
|
|
89
|
+
* or, for an element without text or name, what it holds.
|
|
90
90
|
*
|
|
91
91
|
* @param data - Accessibility node and optional DOM context
|
|
92
|
-
* @returns Role line, plus a text line for elements with longer text
|
|
92
|
+
* @returns Role line, plus a text line for elements with longer or differently named text
|
|
93
93
|
*/
|
|
94
94
|
export function formatSemanticNodeWithContext(data) {
|
|
95
95
|
const { node, domContext } = data;
|
|
@@ -99,13 +99,44 @@ export function formatSemanticNodeWithContext(data) {
|
|
|
99
99
|
const propsText = buildPropertiesText(node);
|
|
100
100
|
const inferredText = node.inferred ? ' (inferred from DOM)' : '';
|
|
101
101
|
const line = `${roleText}${contextText}${keysText}${propsText}${inferredText}`;
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
const text = textNotOnRoleLine(node, domContext);
|
|
103
|
+
if (text)
|
|
104
|
+
return joinLines(line, elementTextLine(text));
|
|
104
105
|
if (domContext?.childCount !== undefined && !node.name) {
|
|
105
|
-
return joinLines(line, emptyElementLine(domContext.children ?? [], domContext.childCount));
|
|
106
|
+
return joinLines(line, emptyElementLine(domContext.children ?? [], domContext.childCount, domContext.shadowChildren));
|
|
106
107
|
}
|
|
107
108
|
return line;
|
|
108
109
|
}
|
|
110
|
+
/**
|
|
111
|
+
* The element's text when the role line does not show it: text longer than
|
|
112
|
+
* the one-line preview, or the visible text of an element whose accessible
|
|
113
|
+
* name is something else (an editor named by its aria-label), unless its
|
|
114
|
+
* name or value shows that text (a long heading with inline children is
|
|
115
|
+
* named by all of it). Texts are compared ignoring case and whitespace.
|
|
116
|
+
* A sensitive field's text is never shown.
|
|
117
|
+
*
|
|
118
|
+
* @param node - Accessibility node
|
|
119
|
+
* @param domContext - DOM context with the text
|
|
120
|
+
* @returns Text for the text line, or undefined
|
|
121
|
+
*/
|
|
122
|
+
function textNotOnRoleLine(node, domContext) {
|
|
123
|
+
if (domContext?.sensitive)
|
|
124
|
+
return undefined;
|
|
125
|
+
const text = domContext?.text ?? (node.name ? domContext?.preview : undefined);
|
|
126
|
+
if (!text)
|
|
127
|
+
return undefined;
|
|
128
|
+
const shown = [node.name, node.value].map((value) => comparableText(value ?? ''));
|
|
129
|
+
return shown.includes(comparableText(text)) ? undefined : text;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Text in the form texts are compared in.
|
|
133
|
+
*
|
|
134
|
+
* @param text - Text
|
|
135
|
+
* @returns Lowercased text with whitespace collapsed
|
|
136
|
+
*/
|
|
137
|
+
function comparableText(text) {
|
|
138
|
+
return text.replace(/\s+/g, ' ').trim().toLowerCase();
|
|
139
|
+
}
|
|
109
140
|
/**
|
|
110
141
|
* Resolve an a11y node, falling back to a DOM-synthesized one when only
|
|
111
142
|
* DOM context is available. Returns null when neither source can produce one.
|
|
@@ -78,9 +78,30 @@ export interface CommandMetadata {
|
|
|
78
78
|
arguments: ArgumentMetadata[];
|
|
79
79
|
/** Command options */
|
|
80
80
|
options: OptionMetadata[];
|
|
81
|
+
/** Text shown after the options in `--help` (examples, output legend) */
|
|
82
|
+
helpText?: string;
|
|
81
83
|
/** Subcommands */
|
|
82
84
|
subcommands: CommandMetadata[];
|
|
83
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* Command summary for the compact root help: one-line description, arguments
|
|
88
|
+
* and flags with their descriptions (behaviors, defaults and choices are in
|
|
89
|
+
* `bdg <command> --help --json`).
|
|
90
|
+
*/
|
|
91
|
+
export interface CompactCommand {
|
|
92
|
+
/** Command name */
|
|
93
|
+
name: string;
|
|
94
|
+
/** Command aliases (only when it has some) */
|
|
95
|
+
aliases?: readonly string[];
|
|
96
|
+
/** First line of the description */
|
|
97
|
+
description: string;
|
|
98
|
+
/** Arguments as in usage, e.g. "<selector> [index]" (only when it takes some) */
|
|
99
|
+
arguments?: string;
|
|
100
|
+
/** Visible options: flags to description */
|
|
101
|
+
options?: Record<string, string>;
|
|
102
|
+
/** Subcommands (only for command groups) */
|
|
103
|
+
subcommands?: CompactCommand[];
|
|
104
|
+
}
|
|
84
105
|
/**
|
|
85
106
|
* Runtime state information for dynamic command availability.
|
|
86
107
|
*/
|
|
@@ -112,7 +133,7 @@ export interface Capabilities {
|
|
|
112
133
|
};
|
|
113
134
|
}
|
|
114
135
|
/**
|
|
115
|
-
* Root machine-readable help structure.
|
|
136
|
+
* Root machine-readable help structure (`bdg --help --json --full`).
|
|
116
137
|
*/
|
|
117
138
|
export interface MachineReadableHelp {
|
|
118
139
|
/** CLI name */
|
|
@@ -142,10 +163,34 @@ export interface MachineReadableHelp {
|
|
|
142
163
|
capabilities: Capabilities;
|
|
143
164
|
}
|
|
144
165
|
/**
|
|
145
|
-
*
|
|
166
|
+
* Compact root help (`bdg --help --json`): the full help with a command tree
|
|
167
|
+
* of names, one-line descriptions and flags.
|
|
168
|
+
*/
|
|
169
|
+
export interface CompactHelp extends Omit<MachineReadableHelp, 'command'> {
|
|
170
|
+
/** Where the details are */
|
|
171
|
+
details: string;
|
|
172
|
+
/** Root command summary */
|
|
173
|
+
command: CompactCommand;
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Help for one command (`bdg <command> --help --json`): its full metadata
|
|
177
|
+
* (option behaviors, defaults, choices, help text), its subcommands in compact
|
|
178
|
+
* form, and the exit codes.
|
|
179
|
+
*/
|
|
180
|
+
export interface CommandHelp extends Pick<MachineReadableHelp, 'name' | 'version' | 'description' | 'exitCodes'> {
|
|
181
|
+
/** Full command path, e.g. "bdg dom query" */
|
|
182
|
+
path: string;
|
|
183
|
+
/** Command metadata; subcommands summarized (ask each for its details) */
|
|
184
|
+
command: Omit<CommandMetadata, 'subcommands'> & {
|
|
185
|
+
subcommands: CompactCommand[];
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Generates the full machine-readable help from a Commander program
|
|
190
|
+
* (`bdg --help --json --full`).
|
|
146
191
|
*
|
|
147
192
|
* Includes comprehensive metadata for agent discovery:
|
|
148
|
-
* - Command structure and options
|
|
193
|
+
* - Command structure and options with behaviors
|
|
149
194
|
* - Exit codes with semantic meanings
|
|
150
195
|
* - Task-to-command mappings with CDP alternatives
|
|
151
196
|
* - Runtime state and command availability
|
|
@@ -154,34 +199,52 @@ export interface MachineReadableHelp {
|
|
|
154
199
|
*
|
|
155
200
|
* @param program - Commander program instance
|
|
156
201
|
* @returns Machine-readable help structure
|
|
202
|
+
*/
|
|
203
|
+
export declare function generateMachineReadableHelp(program: Command): MachineReadableHelp;
|
|
204
|
+
/**
|
|
205
|
+
* Generates the compact root help (`bdg --help --json`): the full help with
|
|
206
|
+
* the command tree reduced to names, one-line descriptions and flags.
|
|
207
|
+
*
|
|
208
|
+
* @param program - Commander program instance
|
|
209
|
+
* @returns Compact help structure
|
|
210
|
+
*/
|
|
211
|
+
export declare function generateCompactHelp(program: Command): CompactHelp;
|
|
212
|
+
/**
|
|
213
|
+
* The command a command line addresses: follows the words that name
|
|
214
|
+
* subcommands and skips the others (option values, arguments), stopping at a
|
|
215
|
+
* command without subcommands.
|
|
216
|
+
*
|
|
217
|
+
* @param program - Root Commander program instance
|
|
218
|
+
* @param words - Command-line words, e.g. ['dom', 'query', '.item']
|
|
219
|
+
* @returns The addressed command (the program when no word names one)
|
|
157
220
|
*
|
|
158
221
|
* @example
|
|
159
222
|
* ```typescript
|
|
160
|
-
*
|
|
161
|
-
* import { generateMachineReadableHelp } from './help/machineReadableHelp.js';
|
|
162
|
-
*
|
|
163
|
-
* const help = generateMachineReadableHelp(program);
|
|
164
|
-
* console.log(JSON.stringify(help, null, 2));
|
|
223
|
+
* resolveCommand(program, ['--session', 'a', 'dom', 'query', '.item']).name(); // 'query'
|
|
165
224
|
* ```
|
|
166
225
|
*/
|
|
167
|
-
export declare function
|
|
226
|
+
export declare function resolveCommand(program: Command, words: string[]): Command;
|
|
168
227
|
/**
|
|
169
|
-
*
|
|
228
|
+
* Full command path, e.g. "bdg dom query".
|
|
170
229
|
*
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
|
|
230
|
+
* @param command - Commander command instance
|
|
231
|
+
* @returns Names from the program down to the command
|
|
232
|
+
*/
|
|
233
|
+
export declare function commandPath(command: Command): string;
|
|
234
|
+
/**
|
|
235
|
+
* Generates machine-readable help for one command: its full metadata,
|
|
236
|
+
* compact subcommands (a group lists them like the root help does) and the
|
|
237
|
+
* exit codes.
|
|
174
238
|
*
|
|
175
239
|
* @param program - Root Commander program instance
|
|
176
|
-
* @param
|
|
177
|
-
* @returns
|
|
240
|
+
* @param command - The command (from {@link resolveCommand})
|
|
241
|
+
* @returns Help for the command
|
|
178
242
|
*
|
|
179
243
|
* @example
|
|
180
244
|
* ```typescript
|
|
181
|
-
*
|
|
182
|
-
*
|
|
183
|
-
* console.log(help.command.name); // 'query'
|
|
245
|
+
* const help = generateCommandHelp(program, resolveCommand(program, ['dom', 'query']));
|
|
246
|
+
* console.log(help.path); // 'bdg dom query'
|
|
184
247
|
* ```
|
|
185
248
|
*/
|
|
186
|
-
export declare function
|
|
249
|
+
export declare function generateCommandHelp(program: Command, command: Command): CommandHelp;
|
|
187
250
|
//# sourceMappingURL=helpJson.d.ts.map
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { getAllDomainSummaries } from '../cdp/schema.js';
|
|
5
5
|
import { getOptionBehavior } from './optionBehaviors.js';
|
|
6
6
|
import { readLiveDaemonPid } from '../session/cleanup/staleSession.js';
|
|
7
|
+
import { helpJsonDetailsNote } from '../ui/messages/commands.js';
|
|
7
8
|
import { getAllDecisionTrees } from '../utils/decisionTrees.js';
|
|
8
9
|
import { EXIT_CODE_REGISTRY } from '../utils/exitCodes.js';
|
|
9
10
|
import { getAllTaskMappings } from '../utils/taskMappings.js';
|
|
@@ -65,6 +66,21 @@ function convertArgument(argument) {
|
|
|
65
66
|
}
|
|
66
67
|
return metadata;
|
|
67
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* The text a command adds after its options in `--help` (examples, output
|
|
71
|
+
* legend), collected from its `afterHelp` listeners. Commander's Command is an
|
|
72
|
+
* EventEmitter at runtime; its typings leave that out.
|
|
73
|
+
*
|
|
74
|
+
* @param command - Commander command instance
|
|
75
|
+
* @returns The text, or undefined when the command adds none
|
|
76
|
+
*/
|
|
77
|
+
function afterHelpText(command) {
|
|
78
|
+
const chunks = [];
|
|
79
|
+
const emitter = command;
|
|
80
|
+
emitter.emit('afterHelp', { error: false, command, write: (text) => chunks.push(text) });
|
|
81
|
+
const text = chunks.join('').trim();
|
|
82
|
+
return text || undefined;
|
|
83
|
+
}
|
|
68
84
|
/**
|
|
69
85
|
* Recursively converts a Commander Command to CommandMetadata.
|
|
70
86
|
*
|
|
@@ -75,6 +91,7 @@ function convertArgument(argument) {
|
|
|
75
91
|
*/
|
|
76
92
|
function convertCommand(command) {
|
|
77
93
|
const commandName = command.name();
|
|
94
|
+
const helpText = afterHelpText(command);
|
|
78
95
|
return {
|
|
79
96
|
name: commandName,
|
|
80
97
|
aliases: command.aliases(),
|
|
@@ -82,9 +99,45 @@ function convertCommand(command) {
|
|
|
82
99
|
usage: command.usage(),
|
|
83
100
|
arguments: command.registeredArguments.map(convertArgument),
|
|
84
101
|
options: command.options.map((opt) => convertOption(opt, commandName)),
|
|
102
|
+
...(helpText && { helpText }),
|
|
85
103
|
subcommands: command.commands.map(convertCommand),
|
|
86
104
|
};
|
|
87
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* An argument as written in usage: `<name>`, `[name]`, `<name...>`.
|
|
108
|
+
*
|
|
109
|
+
* @param argument - Commander argument instance
|
|
110
|
+
* @returns Usage term
|
|
111
|
+
*/
|
|
112
|
+
function argumentTerm(argument) {
|
|
113
|
+
const name = `${argument.name()}${argument.variadic ? '...' : ''}`;
|
|
114
|
+
return argument.required ? `<${name}>` : `[${name}]`;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Recursively converts a Commander Command to its compact summary: first
|
|
118
|
+
* description line, arguments, and visible options with their descriptions.
|
|
119
|
+
* Empty fields are left out.
|
|
120
|
+
*
|
|
121
|
+
* @param command - Commander command instance
|
|
122
|
+
* @returns Compact command summary
|
|
123
|
+
*/
|
|
124
|
+
function convertCompactCommand(command) {
|
|
125
|
+
const aliases = command.aliases();
|
|
126
|
+
const args = command.registeredArguments.map(argumentTerm).join(' ');
|
|
127
|
+
const options = command.options.filter((option) => !option.hidden);
|
|
128
|
+
return {
|
|
129
|
+
name: command.name(),
|
|
130
|
+
...(aliases.length > 0 && { aliases }),
|
|
131
|
+
description: command.description().split('\n')[0] ?? '',
|
|
132
|
+
...(args && { arguments: args }),
|
|
133
|
+
...(options.length > 0 && {
|
|
134
|
+
options: Object.fromEntries(options.map((option) => [option.flags, option.description])),
|
|
135
|
+
}),
|
|
136
|
+
...(command.commands.length > 0 && {
|
|
137
|
+
subcommands: command.commands.map(convertCompactCommand),
|
|
138
|
+
}),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
88
141
|
/**
|
|
89
142
|
* Generates runtime state information.
|
|
90
143
|
*
|
|
@@ -150,10 +203,11 @@ function generateCapabilities() {
|
|
|
150
203
|
};
|
|
151
204
|
}
|
|
152
205
|
/**
|
|
153
|
-
* Generates machine-readable help from a Commander program
|
|
206
|
+
* Generates the full machine-readable help from a Commander program
|
|
207
|
+
* (`bdg --help --json --full`).
|
|
154
208
|
*
|
|
155
209
|
* Includes comprehensive metadata for agent discovery:
|
|
156
|
-
* - Command structure and options
|
|
210
|
+
* - Command structure and options with behaviors
|
|
157
211
|
* - Exit codes with semantic meanings
|
|
158
212
|
* - Task-to-command mappings with CDP alternatives
|
|
159
213
|
* - Runtime state and command availability
|
|
@@ -162,15 +216,6 @@ function generateCapabilities() {
|
|
|
162
216
|
*
|
|
163
217
|
* @param program - Commander program instance
|
|
164
218
|
* @returns Machine-readable help structure
|
|
165
|
-
*
|
|
166
|
-
* @example
|
|
167
|
-
* ```typescript
|
|
168
|
-
* import { program } from 'commander';
|
|
169
|
-
* import { generateMachineReadableHelp } from './help/machineReadableHelp.js';
|
|
170
|
-
*
|
|
171
|
-
* const help = generateMachineReadableHelp(program);
|
|
172
|
-
* console.log(JSON.stringify(help, null, 2));
|
|
173
|
-
* ```
|
|
174
219
|
*/
|
|
175
220
|
export function generateMachineReadableHelp(program) {
|
|
176
221
|
return {
|
|
@@ -186,56 +231,82 @@ export function generateMachineReadableHelp(program) {
|
|
|
186
231
|
};
|
|
187
232
|
}
|
|
188
233
|
/**
|
|
189
|
-
*
|
|
234
|
+
* Generates the compact root help (`bdg --help --json`): the full help with
|
|
235
|
+
* the command tree reduced to names, one-line descriptions and flags.
|
|
236
|
+
*
|
|
237
|
+
* @param program - Commander program instance
|
|
238
|
+
* @returns Compact help structure
|
|
239
|
+
*/
|
|
240
|
+
export function generateCompactHelp(program) {
|
|
241
|
+
return {
|
|
242
|
+
...generateMachineReadableHelp(program),
|
|
243
|
+
details: helpJsonDetailsNote(),
|
|
244
|
+
command: convertCompactCommand(program),
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* The command a command line addresses: follows the words that name
|
|
249
|
+
* subcommands and skips the others (option values, arguments), stopping at a
|
|
250
|
+
* command without subcommands.
|
|
190
251
|
*
|
|
191
252
|
* @param program - Root Commander program instance
|
|
192
|
-
* @param
|
|
193
|
-
* @returns The
|
|
253
|
+
* @param words - Command-line words, e.g. ['dom', 'query', '.item']
|
|
254
|
+
* @returns The addressed command (the program when no word names one)
|
|
255
|
+
*
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* resolveCommand(program, ['--session', 'a', 'dom', 'query', '.item']).name(); // 'query'
|
|
259
|
+
* ```
|
|
194
260
|
*/
|
|
195
|
-
function
|
|
261
|
+
export function resolveCommand(program, words) {
|
|
196
262
|
let current = program;
|
|
197
|
-
for (const
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
263
|
+
for (const word of words) {
|
|
264
|
+
if (current.commands.length === 0)
|
|
265
|
+
break;
|
|
266
|
+
const found = current.commands.find((cmd) => cmd.name() === word || cmd.aliases().includes(word));
|
|
267
|
+
if (found)
|
|
268
|
+
current = found;
|
|
203
269
|
}
|
|
204
270
|
return current;
|
|
205
271
|
}
|
|
206
272
|
/**
|
|
207
|
-
*
|
|
273
|
+
* Full command path, e.g. "bdg dom query".
|
|
208
274
|
*
|
|
209
|
-
*
|
|
210
|
-
*
|
|
211
|
-
|
|
275
|
+
* @param command - Commander command instance
|
|
276
|
+
* @returns Names from the program down to the command
|
|
277
|
+
*/
|
|
278
|
+
export function commandPath(command) {
|
|
279
|
+
const names = [];
|
|
280
|
+
for (let level = command; level; level = level.parent)
|
|
281
|
+
names.unshift(level.name());
|
|
282
|
+
return names.join(' ');
|
|
283
|
+
}
|
|
284
|
+
/**
|
|
285
|
+
* Generates machine-readable help for one command: its full metadata,
|
|
286
|
+
* compact subcommands (a group lists them like the root help does) and the
|
|
287
|
+
* exit codes.
|
|
212
288
|
*
|
|
213
289
|
* @param program - Root Commander program instance
|
|
214
|
-
* @param
|
|
215
|
-
* @returns
|
|
290
|
+
* @param command - The command (from {@link resolveCommand})
|
|
291
|
+
* @returns Help for the command
|
|
216
292
|
*
|
|
217
293
|
* @example
|
|
218
294
|
* ```typescript
|
|
219
|
-
*
|
|
220
|
-
*
|
|
221
|
-
* console.log(help.command.name); // 'query'
|
|
295
|
+
* const help = generateCommandHelp(program, resolveCommand(program, ['dom', 'query']));
|
|
296
|
+
* console.log(help.path); // 'bdg dom query'
|
|
222
297
|
* ```
|
|
223
298
|
*/
|
|
224
|
-
export function
|
|
225
|
-
const targetCommand = findSubcommand(program, commandPath);
|
|
226
|
-
if (!targetCommand) {
|
|
227
|
-
return generateMachineReadableHelp(program);
|
|
228
|
-
}
|
|
299
|
+
export function generateCommandHelp(program, command) {
|
|
229
300
|
return {
|
|
230
301
|
name: program.name(),
|
|
231
302
|
version: program.version() ?? 'unknown',
|
|
232
303
|
description: program.description(),
|
|
233
|
-
|
|
304
|
+
path: commandPath(command),
|
|
305
|
+
command: {
|
|
306
|
+
...convertCommand(command),
|
|
307
|
+
subcommands: command.commands.map(convertCompactCommand),
|
|
308
|
+
},
|
|
234
309
|
exitCodes: [...EXIT_CODE_DOCS],
|
|
235
|
-
taskMappings: getAllTaskMappings(),
|
|
236
|
-
runtimeState: generateRuntimeState(),
|
|
237
|
-
decisionTrees: getAllDecisionTrees(),
|
|
238
|
-
capabilities: generateCapabilities(),
|
|
239
310
|
};
|
|
240
311
|
}
|
|
241
312
|
//# sourceMappingURL=helpJson.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* `bdg help <command...>` topics and Commander usage-error hints.
|
|
3
3
|
*/
|
|
4
|
-
import type { Command } from 'commander';
|
|
4
|
+
import type { Command, CommanderError } from 'commander';
|
|
5
5
|
/**
|
|
6
6
|
* The command path of `bdg help <path...>`: the words before the first option.
|
|
7
7
|
*
|
|
@@ -29,4 +29,19 @@ export declare function splitCommanderHint(text: string): {
|
|
|
29
29
|
message: string;
|
|
30
30
|
suggestion?: string;
|
|
31
31
|
};
|
|
32
|
+
/**
|
|
33
|
+
* Message and suggestion for a Commander usage error: a did-you-mean for an
|
|
34
|
+
* unknown option or command, otherwise a pointer to the command's `--help`.
|
|
35
|
+
* A word typed after a single dash (`-josn`) is matched against the long
|
|
36
|
+
* options.
|
|
37
|
+
*
|
|
38
|
+
* @param error - Commander error (not a help or version display)
|
|
39
|
+
* @param command - Command the error came from (see resolveCommand)
|
|
40
|
+
* @param argv - Process arguments (to name an option as typed)
|
|
41
|
+
* @returns Message and suggestion
|
|
42
|
+
*/
|
|
43
|
+
export declare function usageErrorDetails(error: CommanderError, command: Command, argv?: string[]): {
|
|
44
|
+
message: string;
|
|
45
|
+
suggestion: string;
|
|
46
|
+
};
|
|
32
47
|
//# sourceMappingURL=helpTopic.d.ts.map
|