@optique/core 1.4.0-dev.2893 → 1.4.0-dev.2895
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/dist/facade.cjs +10 -3
- package/dist/facade.d.cts +11 -0
- package/dist/facade.d.ts +11 -0
- package/dist/facade.js +11 -4
- package/dist/usage-internals.cjs +99 -1
- package/dist/usage-internals.js +99 -2
- package/package.json +2 -2
- package/skills/optique/SKILL.md +6 -6
package/dist/facade.cjs
CHANGED
|
@@ -818,7 +818,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
818
818
|
options = optionsParam ?? {};
|
|
819
819
|
}
|
|
820
820
|
require_validate.validateProgramName(programName);
|
|
821
|
-
const { colors, messageFormatter, theme: requestedTheme, maxWidth: requestedMaxWidth, termWidth, showDefault, showChoices, showAliases, showEnvironment, sectionOrder, helpSections, showUsage, usageLine, commandList = "recursive", aboveError = "usage", onError = () => {
|
|
821
|
+
const { colors, messageFormatter, theme: requestedTheme, maxWidth: requestedMaxWidth, termWidth, showDefault, showChoices, showAliases, showEnvironment, sectionOrder, helpSections, showUsage, usageLine, commandList = "recursive", aboveError = "usage", errorUsage = "root", onError = () => {
|
|
822
822
|
throw new RunParserError("Failed to parse command line arguments.");
|
|
823
823
|
}, stderr = console.error, stdout = console.log, brief, description, examples, author, bugs, footer } = options;
|
|
824
824
|
let maxWidth = requestedMaxWidth;
|
|
@@ -1117,8 +1117,15 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
1117
1117
|
})));
|
|
1118
1118
|
}
|
|
1119
1119
|
if (effectiveAboveError === "usage") {
|
|
1120
|
-
|
|
1121
|
-
|
|
1120
|
+
const rootUsage = augmentedParser.usage;
|
|
1121
|
+
const optionCount = Number(helpParsers.helpOption != null) + Number(versionParsers.versionOption != null);
|
|
1122
|
+
const alternativeCount = optionCount + Number(helpParsers.helpCommand != null) + Number(versionParsers.versionCommand != null) + Number(completionParsers.completionCommand != null);
|
|
1123
|
+
const errorUsageTerms = aboveError === "usage" && errorUsage === "command" ? require_usage_internals.projectCommandUsage(rootUsage, classified.commandPath, alternativeCount === 0 ? void 0 : {
|
|
1124
|
+
optionCount,
|
|
1125
|
+
alternativeCount
|
|
1126
|
+
}) ?? rootUsage : rootUsage;
|
|
1127
|
+
resolveUsageWidth(errorUsageTerms);
|
|
1128
|
+
stderr(`${usageLabel()}${indentLines(require_usage.formatUsage(programName, errorUsageTerms, {
|
|
1122
1129
|
theme,
|
|
1123
1130
|
colors,
|
|
1124
1131
|
maxWidth: maxWidth == null ? void 0 : maxWidth - usageLabelWidth(),
|
package/dist/facade.d.cts
CHANGED
|
@@ -326,6 +326,17 @@ interface RunOptions<THelp, TError> {
|
|
|
326
326
|
* @default `"usage"`
|
|
327
327
|
*/
|
|
328
328
|
readonly aboveError?: "usage" | "help" | "none";
|
|
329
|
+
/**
|
|
330
|
+
* Scope of the compact preamble when `aboveError` is `"usage"`.
|
|
331
|
+
* `"command"` uses the failed parse's canonical command path and usage
|
|
332
|
+
* metadata, retaining parent options. Hidden or unresolved paths and
|
|
333
|
+
* unsupported compositions fall back to root usage. Neither mode applies
|
|
334
|
+
* help-only `usageLine` overrides or evaluates the parser again.
|
|
335
|
+
*
|
|
336
|
+
* @default `"root"`
|
|
337
|
+
* @since 1.4.0
|
|
338
|
+
*/
|
|
339
|
+
readonly errorUsage?: "root" | "command";
|
|
329
340
|
/**
|
|
330
341
|
* Callback invoked after error output for a parse failure, an invalid
|
|
331
342
|
* command path before help, or a missing or unsupported completion shell.
|
package/dist/facade.d.ts
CHANGED
|
@@ -326,6 +326,17 @@ interface RunOptions<THelp, TError> {
|
|
|
326
326
|
* @default `"usage"`
|
|
327
327
|
*/
|
|
328
328
|
readonly aboveError?: "usage" | "help" | "none";
|
|
329
|
+
/**
|
|
330
|
+
* Scope of the compact preamble when `aboveError` is `"usage"`.
|
|
331
|
+
* `"command"` uses the failed parse's canonical command path and usage
|
|
332
|
+
* metadata, retaining parent options. Hidden or unresolved paths and
|
|
333
|
+
* unsupported compositions fall back to root usage. Neither mode applies
|
|
334
|
+
* help-only `usageLine` overrides or evaluates the parser again.
|
|
335
|
+
*
|
|
336
|
+
* @default `"root"`
|
|
337
|
+
* @since 1.4.0
|
|
338
|
+
*/
|
|
339
|
+
readonly errorUsage?: "root" | "command";
|
|
329
340
|
/**
|
|
330
341
|
* Callback invoked after error output for a parse failure, an invalid
|
|
331
342
|
* command path before help, or a missing or unsupported completion shell.
|
package/dist/facade.js
CHANGED
|
@@ -12,7 +12,7 @@ import { collectExplicitSourceValues, collectExplicitSourceValuesAsync, createDe
|
|
|
12
12
|
import { createInputTrace } from "./input-trace.js";
|
|
13
13
|
import { attemptParseAsync, attemptParseSync, createEffectfulCompletionSession, createParserContext, getDocPage } from "./internal/parser.js";
|
|
14
14
|
import { bash, fish, nu, pwsh, zsh } from "./completion.js";
|
|
15
|
-
import { collectActiveOptionNames, collectRootOptionNames } from "./usage-internals.js";
|
|
15
|
+
import { collectActiveOptionNames, collectRootOptionNames, projectCommandUsage } from "./usage-internals.js";
|
|
16
16
|
import { allowDuplicateLeadingCommandNamesKey, hiddenCommandAliasesKey } from "./internal/command-alias.js";
|
|
17
17
|
import { completeOrExtractPhase2Seed } from "./phase2-seed.js";
|
|
18
18
|
import { multiple, optional, withDefault } from "./modifiers.js";
|
|
@@ -818,7 +818,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
818
818
|
options = optionsParam ?? {};
|
|
819
819
|
}
|
|
820
820
|
validateProgramName(programName);
|
|
821
|
-
const { colors, messageFormatter, theme: requestedTheme, maxWidth: requestedMaxWidth, termWidth, showDefault, showChoices, showAliases, showEnvironment, sectionOrder, helpSections, showUsage, usageLine, commandList = "recursive", aboveError = "usage", onError = () => {
|
|
821
|
+
const { colors, messageFormatter, theme: requestedTheme, maxWidth: requestedMaxWidth, termWidth, showDefault, showChoices, showAliases, showEnvironment, sectionOrder, helpSections, showUsage, usageLine, commandList = "recursive", aboveError = "usage", errorUsage = "root", onError = () => {
|
|
822
822
|
throw new RunParserError("Failed to parse command line arguments.");
|
|
823
823
|
}, stderr = console.error, stdout = console.log, brief, description, examples, author, bugs, footer } = options;
|
|
824
824
|
let maxWidth = requestedMaxWidth;
|
|
@@ -1117,8 +1117,15 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
|
|
|
1117
1117
|
})));
|
|
1118
1118
|
}
|
|
1119
1119
|
if (effectiveAboveError === "usage") {
|
|
1120
|
-
|
|
1121
|
-
|
|
1120
|
+
const rootUsage = augmentedParser.usage;
|
|
1121
|
+
const optionCount = Number(helpParsers.helpOption != null) + Number(versionParsers.versionOption != null);
|
|
1122
|
+
const alternativeCount = optionCount + Number(helpParsers.helpCommand != null) + Number(versionParsers.versionCommand != null) + Number(completionParsers.completionCommand != null);
|
|
1123
|
+
const errorUsageTerms = aboveError === "usage" && errorUsage === "command" ? projectCommandUsage(rootUsage, classified.commandPath, alternativeCount === 0 ? void 0 : {
|
|
1124
|
+
optionCount,
|
|
1125
|
+
alternativeCount
|
|
1126
|
+
}) ?? rootUsage : rootUsage;
|
|
1127
|
+
resolveUsageWidth(errorUsageTerms);
|
|
1128
|
+
stderr(`${usageLabel()}${indentLines(formatUsage(programName, errorUsageTerms, {
|
|
1122
1129
|
theme,
|
|
1123
1130
|
colors,
|
|
1124
1131
|
maxWidth: maxWidth == null ? void 0 : maxWidth - usageLabelWidth(),
|
package/dist/usage-internals.cjs
CHANGED
|
@@ -2,6 +2,103 @@ const require_usage = require('./usage.cjs');
|
|
|
2
2
|
|
|
3
3
|
//#region src/usage-internals.ts
|
|
4
4
|
/**
|
|
5
|
+
* Projects augmented runner usage onto a recorded canonical command path.
|
|
6
|
+
* Unsupported or ambiguous metadata returns undefined, preserving root usage.
|
|
7
|
+
* No parser, documentation, or usage-override callbacks are evaluated.
|
|
8
|
+
* @param usage The runner's original augmented usage.
|
|
9
|
+
* @param path The canonical path recorded by the failed parse.
|
|
10
|
+
* @param meta The known augmentation boundary, absent without alternatives.
|
|
11
|
+
* @returns The selected grammar, or undefined when projection is uncertain.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
function projectCommandUsage(usage, path, meta) {
|
|
15
|
+
if (path.length === 0) return void 0;
|
|
16
|
+
if (meta == null) return projectCommandTerms(usage, path, 0);
|
|
17
|
+
const top = usage[0];
|
|
18
|
+
if (usage.length !== 1 || top.type !== "exclusive" || top.terms.length !== meta.alternativeCount + 1) return void 0;
|
|
19
|
+
const selected = projectCommandTerms(top.terms[meta.optionCount], path, 0);
|
|
20
|
+
if (selected == null) return void 0;
|
|
21
|
+
const options = top.terms.slice(0, meta.optionCount).filter((branch) => branch.some((term) => term.type === "option" && !require_usage.isUsageHidden(term.hidden)));
|
|
22
|
+
return options.length === 0 ? selected : [{
|
|
23
|
+
type: "exclusive",
|
|
24
|
+
terms: [...options, selected]
|
|
25
|
+
}];
|
|
26
|
+
}
|
|
27
|
+
function containsCommand(usage) {
|
|
28
|
+
return usage.some((term) => {
|
|
29
|
+
switch (term.type) {
|
|
30
|
+
case "command": return true;
|
|
31
|
+
case "exclusive": return term.terms.some(containsCommand);
|
|
32
|
+
case "optional":
|
|
33
|
+
case "multiple":
|
|
34
|
+
case "sequence": return containsCommand(term.terms);
|
|
35
|
+
default: return false;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Undefined distinguishes unsupported metadata from a command-free branch. */
|
|
40
|
+
function firstCommandNames(usage) {
|
|
41
|
+
const hosts = usage.filter((term) => containsCommand([term]));
|
|
42
|
+
const first = hosts[0];
|
|
43
|
+
if (first == null) return [];
|
|
44
|
+
if (first.type === "command") return [first.name];
|
|
45
|
+
if (hosts.length !== 1) return void 0;
|
|
46
|
+
if (first.type === "sequence") return firstCommandNames(first.terms);
|
|
47
|
+
if (first.type !== "exclusive") return void 0;
|
|
48
|
+
const names = [];
|
|
49
|
+
for (const branch of first.terms) {
|
|
50
|
+
const found = firstCommandNames(branch);
|
|
51
|
+
if (found == null) return void 0;
|
|
52
|
+
names.push(...found);
|
|
53
|
+
}
|
|
54
|
+
return names;
|
|
55
|
+
}
|
|
56
|
+
function projectCommandTerms(usage, path, offset) {
|
|
57
|
+
if (offset === path.length) return usage;
|
|
58
|
+
const index = usage.findIndex((term) => containsCommand([term]));
|
|
59
|
+
if (index < 0) return void 0;
|
|
60
|
+
const host = usage[index];
|
|
61
|
+
const prefix = usage.slice(0, index);
|
|
62
|
+
const suffix = usage.slice(index + 1);
|
|
63
|
+
if (host.type === "command") {
|
|
64
|
+
if (host.name !== path[offset] || require_usage.isUsageHidden(host.hidden)) return void 0;
|
|
65
|
+
const rest = projectCommandTerms(suffix, path, offset + 1);
|
|
66
|
+
return rest == null ? void 0 : [
|
|
67
|
+
...prefix,
|
|
68
|
+
host,
|
|
69
|
+
...rest
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
if (containsCommand(suffix)) return void 0;
|
|
73
|
+
if (host.type === "sequence") {
|
|
74
|
+
const terms$1 = projectCommandTerms(host.terms, path, offset);
|
|
75
|
+
return terms$1 == null ? void 0 : [
|
|
76
|
+
...prefix,
|
|
77
|
+
{
|
|
78
|
+
...host,
|
|
79
|
+
terms: terms$1
|
|
80
|
+
},
|
|
81
|
+
...suffix
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
if (host.type !== "exclusive") return void 0;
|
|
85
|
+
let selected;
|
|
86
|
+
for (const branch of host.terms) {
|
|
87
|
+
const names = firstCommandNames(branch);
|
|
88
|
+
if (names == null) return void 0;
|
|
89
|
+
if (!names.includes(path[offset])) continue;
|
|
90
|
+
if (selected != null) return void 0;
|
|
91
|
+
selected = branch;
|
|
92
|
+
}
|
|
93
|
+
if (selected == null) return void 0;
|
|
94
|
+
const terms = projectCommandTerms(selected, path, offset);
|
|
95
|
+
return terms == null ? void 0 : [
|
|
96
|
+
...prefix,
|
|
97
|
+
...terms,
|
|
98
|
+
...suffix
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
5
102
|
* Collects option names and command names that are valid as the *immediate*
|
|
6
103
|
* next token at the current parse position ("leading candidates").
|
|
7
104
|
*
|
|
@@ -152,4 +249,5 @@ exports.collectActiveOptionNames = collectActiveOptionNames;
|
|
|
152
249
|
exports.collectLeadingCandidates = collectLeadingCandidates;
|
|
153
250
|
exports.collectOptionNamesAtCurrentCommandDepth = collectOptionNamesAtCurrentCommandDepth;
|
|
154
251
|
exports.collectRootOptionNames = collectRootOptionNames;
|
|
155
|
-
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
|
252
|
+
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
|
253
|
+
exports.projectCommandUsage = projectCommandUsage;
|
package/dist/usage-internals.js
CHANGED
|
@@ -1,7 +1,104 @@
|
|
|
1
|
-
import { isSuggestionHidden } from "./usage.js";
|
|
1
|
+
import { isSuggestionHidden, isUsageHidden } from "./usage.js";
|
|
2
2
|
|
|
3
3
|
//#region src/usage-internals.ts
|
|
4
4
|
/**
|
|
5
|
+
* Projects augmented runner usage onto a recorded canonical command path.
|
|
6
|
+
* Unsupported or ambiguous metadata returns undefined, preserving root usage.
|
|
7
|
+
* No parser, documentation, or usage-override callbacks are evaluated.
|
|
8
|
+
* @param usage The runner's original augmented usage.
|
|
9
|
+
* @param path The canonical path recorded by the failed parse.
|
|
10
|
+
* @param meta The known augmentation boundary, absent without alternatives.
|
|
11
|
+
* @returns The selected grammar, or undefined when projection is uncertain.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
function projectCommandUsage(usage, path, meta) {
|
|
15
|
+
if (path.length === 0) return void 0;
|
|
16
|
+
if (meta == null) return projectCommandTerms(usage, path, 0);
|
|
17
|
+
const top = usage[0];
|
|
18
|
+
if (usage.length !== 1 || top.type !== "exclusive" || top.terms.length !== meta.alternativeCount + 1) return void 0;
|
|
19
|
+
const selected = projectCommandTerms(top.terms[meta.optionCount], path, 0);
|
|
20
|
+
if (selected == null) return void 0;
|
|
21
|
+
const options = top.terms.slice(0, meta.optionCount).filter((branch) => branch.some((term) => term.type === "option" && !isUsageHidden(term.hidden)));
|
|
22
|
+
return options.length === 0 ? selected : [{
|
|
23
|
+
type: "exclusive",
|
|
24
|
+
terms: [...options, selected]
|
|
25
|
+
}];
|
|
26
|
+
}
|
|
27
|
+
function containsCommand(usage) {
|
|
28
|
+
return usage.some((term) => {
|
|
29
|
+
switch (term.type) {
|
|
30
|
+
case "command": return true;
|
|
31
|
+
case "exclusive": return term.terms.some(containsCommand);
|
|
32
|
+
case "optional":
|
|
33
|
+
case "multiple":
|
|
34
|
+
case "sequence": return containsCommand(term.terms);
|
|
35
|
+
default: return false;
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
/** Undefined distinguishes unsupported metadata from a command-free branch. */
|
|
40
|
+
function firstCommandNames(usage) {
|
|
41
|
+
const hosts = usage.filter((term) => containsCommand([term]));
|
|
42
|
+
const first = hosts[0];
|
|
43
|
+
if (first == null) return [];
|
|
44
|
+
if (first.type === "command") return [first.name];
|
|
45
|
+
if (hosts.length !== 1) return void 0;
|
|
46
|
+
if (first.type === "sequence") return firstCommandNames(first.terms);
|
|
47
|
+
if (first.type !== "exclusive") return void 0;
|
|
48
|
+
const names = [];
|
|
49
|
+
for (const branch of first.terms) {
|
|
50
|
+
const found = firstCommandNames(branch);
|
|
51
|
+
if (found == null) return void 0;
|
|
52
|
+
names.push(...found);
|
|
53
|
+
}
|
|
54
|
+
return names;
|
|
55
|
+
}
|
|
56
|
+
function projectCommandTerms(usage, path, offset) {
|
|
57
|
+
if (offset === path.length) return usage;
|
|
58
|
+
const index = usage.findIndex((term) => containsCommand([term]));
|
|
59
|
+
if (index < 0) return void 0;
|
|
60
|
+
const host = usage[index];
|
|
61
|
+
const prefix = usage.slice(0, index);
|
|
62
|
+
const suffix = usage.slice(index + 1);
|
|
63
|
+
if (host.type === "command") {
|
|
64
|
+
if (host.name !== path[offset] || isUsageHidden(host.hidden)) return void 0;
|
|
65
|
+
const rest = projectCommandTerms(suffix, path, offset + 1);
|
|
66
|
+
return rest == null ? void 0 : [
|
|
67
|
+
...prefix,
|
|
68
|
+
host,
|
|
69
|
+
...rest
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
if (containsCommand(suffix)) return void 0;
|
|
73
|
+
if (host.type === "sequence") {
|
|
74
|
+
const terms$1 = projectCommandTerms(host.terms, path, offset);
|
|
75
|
+
return terms$1 == null ? void 0 : [
|
|
76
|
+
...prefix,
|
|
77
|
+
{
|
|
78
|
+
...host,
|
|
79
|
+
terms: terms$1
|
|
80
|
+
},
|
|
81
|
+
...suffix
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
if (host.type !== "exclusive") return void 0;
|
|
85
|
+
let selected;
|
|
86
|
+
for (const branch of host.terms) {
|
|
87
|
+
const names = firstCommandNames(branch);
|
|
88
|
+
if (names == null) return void 0;
|
|
89
|
+
if (!names.includes(path[offset])) continue;
|
|
90
|
+
if (selected != null) return void 0;
|
|
91
|
+
selected = branch;
|
|
92
|
+
}
|
|
93
|
+
if (selected == null) return void 0;
|
|
94
|
+
const terms = projectCommandTerms(selected, path, offset);
|
|
95
|
+
return terms == null ? void 0 : [
|
|
96
|
+
...prefix,
|
|
97
|
+
...terms,
|
|
98
|
+
...suffix
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
5
102
|
* Collects option names and command names that are valid as the *immediate*
|
|
6
103
|
* next token at the current parse position ("leading candidates").
|
|
7
104
|
*
|
|
@@ -148,4 +245,4 @@ function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
|
148
245
|
}
|
|
149
246
|
|
|
150
247
|
//#endregion
|
|
151
|
-
export { collectActiveOptionNames, collectLeadingCandidates, collectOptionNamesAtCurrentCommandDepth, collectRootOptionNames, extractLeadingCommandNames };
|
|
248
|
+
export { collectActiveOptionNames, collectLeadingCandidates, collectOptionNamesAtCurrentCommandDepth, collectRootOptionNames, extractLeadingCommandNames, projectCommandUsage };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.4.0-dev.
|
|
3
|
+
"version": "1.4.0-dev.2895",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -261,7 +261,7 @@
|
|
|
261
261
|
},
|
|
262
262
|
"sideEffects": false,
|
|
263
263
|
"devDependencies": {
|
|
264
|
-
"@optique/env": "1.4.0-dev.
|
|
264
|
+
"@optique/env": "1.4.0-dev.2895+fb7758c4",
|
|
265
265
|
"@types/node": "^24.0.0",
|
|
266
266
|
"fast-check": "^4.7.0",
|
|
267
267
|
"tsdown": "^0.13.0",
|
package/skills/optique/SKILL.md
CHANGED
|
@@ -53,8 +53,9 @@ Core rules
|
|
|
53
53
|
- Async value parsers like *@optique/git* make containing parsers async.
|
|
54
54
|
Await `run()`/`parse()`/`runParser()` or, for `bindKeyring()`, `runAsync()`.
|
|
55
55
|
- Use `dependency()` when one value parser controls another's valid values.
|
|
56
|
-
|
|
57
|
-
|
|
56
|
+
For a multi-level chain, wrap the middle derivation too:
|
|
57
|
+
`dependency(source.deriveSync(...))`. Optique resolves such chains by
|
|
58
|
+
dependency order, independently of object/tuple field order.
|
|
58
59
|
- Use `derivePromptConfig(source, resolver)` from *@optique/prompt* or its
|
|
59
60
|
adapters for choices/messages depending on parsed values; use
|
|
60
61
|
`[sourceA, sourceB]` for several sources. Async resolvers run at fallback
|
|
@@ -79,9 +80,9 @@ Core rules
|
|
|
79
80
|
Show hidden `aliases` in help with `showAliases` on `command()` or runner.
|
|
80
81
|
- Use `run(parser, { completion: "both" })` for completion, or the object form
|
|
81
82
|
with `completion.errors` for custom shell errors. Do not hand-write scripts.
|
|
82
|
-
- Use `usageLine: [{ type: "ellipsis" }]`
|
|
83
|
-
|
|
84
|
-
|
|
83
|
+
- Use `usageLine: [{ type: "ellipsis" }]` for compact root full help and the
|
|
84
|
+
override on `command()` for subcommand help. `errorUsage: "command"` scopes
|
|
85
|
+
usage above errors with root fallback, ignoring help-only overrides.
|
|
85
86
|
- Use `showUsage: false` in runner options when full help should show the
|
|
86
87
|
brief and sections without `Usage:`. Set `command()`'s `showUsage: true`
|
|
87
88
|
to restore it; children inherit the nearest explicit ancestor setting.
|
|
@@ -273,7 +274,6 @@ Reference links
|
|
|
273
274
|
- Shell completion: <https://optique.dev/concepts/completion.md>
|
|
274
275
|
- Command discovery: <https://optique.dev/concepts/discover.md>
|
|
275
276
|
- Man pages: <https://optique.dev/concepts/man.md>
|
|
276
|
-
- Consumer skills: <https://optique.dev/consumer-skills.md>
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
Integration packages
|