@optique/core 1.4.0-dev.2899 → 1.4.0-dev.2928
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/constructs.cjs +18 -5
- package/dist/constructs.js +18 -5
- package/dist/doc-pages.cjs +480 -0
- package/dist/doc-pages.d.cts +98 -0
- package/dist/doc-pages.d.ts +98 -0
- package/dist/doc-pages.js +479 -0
- 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/internal/doc-metadata.cjs +121 -0
- package/dist/internal/doc-metadata.d.cts +72 -0
- package/dist/internal/doc-metadata.d.ts +72 -0
- package/dist/internal/doc-metadata.js +118 -0
- package/dist/modifiers.cjs +16 -3
- package/dist/modifiers.js +16 -3
- package/dist/primitives.cjs +33 -4
- package/dist/primitives.js +33 -4
- package/dist/usage-internals.cjs +104 -1
- package/dist/usage-internals.js +104 -2
- package/dist/valueparser.cjs +20 -10
- package/dist/valueparser.js +20 -10
- package/package.json +10 -2
- package/skills/optique/SKILL.md +6 -6
package/dist/usage-internals.cjs
CHANGED
|
@@ -2,6 +2,108 @@ 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
|
+
const orderedPrefix = prefix.some((term) => term.type === "option" || term.type === "argument" || term.type === "literal");
|
|
64
|
+
const preserveOrder = (terms$1) => orderedPrefix ? [{
|
|
65
|
+
type: "sequence",
|
|
66
|
+
terms: terms$1
|
|
67
|
+
}] : terms$1;
|
|
68
|
+
if (host.type === "command") {
|
|
69
|
+
if (host.name !== path[offset] || require_usage.isUsageHidden(host.hidden)) return void 0;
|
|
70
|
+
const rest = projectCommandTerms(suffix, path, offset + 1);
|
|
71
|
+
return rest == null ? void 0 : preserveOrder([
|
|
72
|
+
...prefix,
|
|
73
|
+
host,
|
|
74
|
+
...rest
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
if (containsCommand(suffix)) return void 0;
|
|
78
|
+
if (host.type === "sequence") {
|
|
79
|
+
const terms$1 = projectCommandTerms(host.terms, path, offset);
|
|
80
|
+
return terms$1 == null ? void 0 : preserveOrder([
|
|
81
|
+
...prefix,
|
|
82
|
+
{
|
|
83
|
+
...host,
|
|
84
|
+
terms: terms$1
|
|
85
|
+
},
|
|
86
|
+
...suffix
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
if (host.type !== "exclusive") return void 0;
|
|
90
|
+
let selected;
|
|
91
|
+
for (const branch of host.terms) {
|
|
92
|
+
const names = firstCommandNames(branch);
|
|
93
|
+
if (names == null) return void 0;
|
|
94
|
+
if (!names.includes(path[offset])) continue;
|
|
95
|
+
if (selected != null) return void 0;
|
|
96
|
+
selected = branch;
|
|
97
|
+
}
|
|
98
|
+
if (selected == null) return void 0;
|
|
99
|
+
const terms = projectCommandTerms(selected, path, offset);
|
|
100
|
+
return terms == null ? void 0 : preserveOrder([
|
|
101
|
+
...prefix,
|
|
102
|
+
...terms,
|
|
103
|
+
...suffix
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
5
107
|
* Collects option names and command names that are valid as the *immediate*
|
|
6
108
|
* next token at the current parse position ("leading candidates").
|
|
7
109
|
*
|
|
@@ -152,4 +254,5 @@ exports.collectActiveOptionNames = collectActiveOptionNames;
|
|
|
152
254
|
exports.collectLeadingCandidates = collectLeadingCandidates;
|
|
153
255
|
exports.collectOptionNamesAtCurrentCommandDepth = collectOptionNamesAtCurrentCommandDepth;
|
|
154
256
|
exports.collectRootOptionNames = collectRootOptionNames;
|
|
155
|
-
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
|
257
|
+
exports.extractLeadingCommandNames = extractLeadingCommandNames;
|
|
258
|
+
exports.projectCommandUsage = projectCommandUsage;
|
package/dist/usage-internals.js
CHANGED
|
@@ -1,7 +1,109 @@
|
|
|
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
|
+
const orderedPrefix = prefix.some((term) => term.type === "option" || term.type === "argument" || term.type === "literal");
|
|
64
|
+
const preserveOrder = (terms$1) => orderedPrefix ? [{
|
|
65
|
+
type: "sequence",
|
|
66
|
+
terms: terms$1
|
|
67
|
+
}] : terms$1;
|
|
68
|
+
if (host.type === "command") {
|
|
69
|
+
if (host.name !== path[offset] || isUsageHidden(host.hidden)) return void 0;
|
|
70
|
+
const rest = projectCommandTerms(suffix, path, offset + 1);
|
|
71
|
+
return rest == null ? void 0 : preserveOrder([
|
|
72
|
+
...prefix,
|
|
73
|
+
host,
|
|
74
|
+
...rest
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
if (containsCommand(suffix)) return void 0;
|
|
78
|
+
if (host.type === "sequence") {
|
|
79
|
+
const terms$1 = projectCommandTerms(host.terms, path, offset);
|
|
80
|
+
return terms$1 == null ? void 0 : preserveOrder([
|
|
81
|
+
...prefix,
|
|
82
|
+
{
|
|
83
|
+
...host,
|
|
84
|
+
terms: terms$1
|
|
85
|
+
},
|
|
86
|
+
...suffix
|
|
87
|
+
]);
|
|
88
|
+
}
|
|
89
|
+
if (host.type !== "exclusive") return void 0;
|
|
90
|
+
let selected;
|
|
91
|
+
for (const branch of host.terms) {
|
|
92
|
+
const names = firstCommandNames(branch);
|
|
93
|
+
if (names == null) return void 0;
|
|
94
|
+
if (!names.includes(path[offset])) continue;
|
|
95
|
+
if (selected != null) return void 0;
|
|
96
|
+
selected = branch;
|
|
97
|
+
}
|
|
98
|
+
if (selected == null) return void 0;
|
|
99
|
+
const terms = projectCommandTerms(selected, path, offset);
|
|
100
|
+
return terms == null ? void 0 : preserveOrder([
|
|
101
|
+
...prefix,
|
|
102
|
+
...terms,
|
|
103
|
+
...suffix
|
|
104
|
+
]);
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
5
107
|
* Collects option names and command names that are valid as the *immediate*
|
|
6
108
|
* next token at the current parse position ("leading candidates").
|
|
7
109
|
*
|
|
@@ -148,4 +250,4 @@ function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
|
|
|
148
250
|
}
|
|
149
251
|
|
|
150
252
|
//#endregion
|
|
151
|
-
export { collectActiveOptionNames, collectLeadingCandidates, collectOptionNamesAtCurrentCommandDepth, collectRootOptionNames, extractLeadingCommandNames };
|
|
253
|
+
export { collectActiveOptionNames, collectLeadingCandidates, collectOptionNamesAtCurrentCommandDepth, collectRootOptionNames, extractLeadingCommandNames, projectCommandUsage };
|
package/dist/valueparser.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
const require_message = require('./message.cjs');
|
|
2
2
|
const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
|
|
3
3
|
const require_internal_dependency = require('./internal/dependency.cjs');
|
|
4
|
+
const require_internal_doc_metadata = require('./internal/doc-metadata.cjs');
|
|
4
5
|
const require_suggestion = require('./suggestion.cjs');
|
|
5
6
|
const require_nonempty = require('./nonempty.cjs');
|
|
6
7
|
|
|
@@ -92,7 +93,7 @@ function choice(choices, options = {}) {
|
|
|
92
93
|
const numberInvalidChoice = options.errors?.invalidChoice;
|
|
93
94
|
const numberStrings = numberChoices.map((v) => Object.is(v, -0) ? "-0" : String(v));
|
|
94
95
|
const frozenNumberChoices = Object.freeze(numberChoices);
|
|
95
|
-
return {
|
|
96
|
+
return require_internal_doc_metadata.captureDocValue({
|
|
96
97
|
mode: "sync",
|
|
97
98
|
metavar: metavar$1,
|
|
98
99
|
placeholder: choices[0],
|
|
@@ -156,7 +157,12 @@ function choice(choices, options = {}) {
|
|
|
156
157
|
text: valueStr
|
|
157
158
|
}));
|
|
158
159
|
}
|
|
159
|
-
}
|
|
160
|
+
}, {
|
|
161
|
+
kind: "number",
|
|
162
|
+
choices: numberChoices,
|
|
163
|
+
preserveNegativeZero: true,
|
|
164
|
+
canFormatDefault: true
|
|
165
|
+
});
|
|
160
166
|
}
|
|
161
167
|
const stringChoices = Object.freeze([...new Set(choices)]);
|
|
162
168
|
const stringOptions = options;
|
|
@@ -203,7 +209,7 @@ function choice(choices, options = {}) {
|
|
|
203
209
|
maxDistance: stringSuggest.maxDistance,
|
|
204
210
|
maxSuggestions: stringSuggest.maxSuggestions
|
|
205
211
|
} : stringSuggest;
|
|
206
|
-
return {
|
|
212
|
+
return require_internal_doc_metadata.captureDocValue({
|
|
207
213
|
mode: "sync",
|
|
208
214
|
metavar: metavar$1,
|
|
209
215
|
placeholder: choices[0],
|
|
@@ -240,7 +246,11 @@ function choice(choices, options = {}) {
|
|
|
240
246
|
text: value
|
|
241
247
|
}));
|
|
242
248
|
}
|
|
243
|
-
}
|
|
249
|
+
}, {
|
|
250
|
+
kind: "string",
|
|
251
|
+
choices: stringChoices,
|
|
252
|
+
canFormatDefault: customKey === void 0 && !caseInsensitive
|
|
253
|
+
});
|
|
244
254
|
}
|
|
245
255
|
function biject(mapping) {
|
|
246
256
|
if (mapping === null || typeof mapping !== "object") throw new TypeError("Expected object.");
|
|
@@ -723,7 +733,7 @@ function string(options = {}) {
|
|
|
723
733
|
const patternSource = options.pattern?.source ?? null;
|
|
724
734
|
const patternFlags = options.pattern?.flags ?? null;
|
|
725
735
|
const patternMismatch = options.errors?.patternMismatch;
|
|
726
|
-
return {
|
|
736
|
+
return require_internal_doc_metadata.captureDocValue({
|
|
727
737
|
mode: "sync",
|
|
728
738
|
metavar: metavar$1,
|
|
729
739
|
placeholder: options.placeholder ?? "",
|
|
@@ -747,7 +757,7 @@ function string(options = {}) {
|
|
|
747
757
|
format(value) {
|
|
748
758
|
return value;
|
|
749
759
|
}
|
|
750
|
-
};
|
|
760
|
+
}, { kind: "string" });
|
|
751
761
|
}
|
|
752
762
|
/**
|
|
753
763
|
* Creates a {@link ValueParser} that compiles regular expression sources.
|
|
@@ -1179,7 +1189,7 @@ function integer(options) {
|
|
|
1179
1189
|
if (options?.type === "bigint") {
|
|
1180
1190
|
const metavar$2 = options.metavar ?? "INTEGER";
|
|
1181
1191
|
require_nonempty.ensureNonEmptyString(metavar$2);
|
|
1182
|
-
return {
|
|
1192
|
+
return require_internal_doc_metadata.captureDocValue({
|
|
1183
1193
|
mode: "sync",
|
|
1184
1194
|
metavar: metavar$2,
|
|
1185
1195
|
placeholder: options?.placeholder ?? (options?.min != null && options.min > 0n ? options.min : options?.max != null && options.max < 0n ? options.max : 0n),
|
|
@@ -1205,7 +1215,7 @@ function integer(options) {
|
|
|
1205
1215
|
format(value) {
|
|
1206
1216
|
return value.toString();
|
|
1207
1217
|
}
|
|
1208
|
-
};
|
|
1218
|
+
}, { kind: "bigint" });
|
|
1209
1219
|
}
|
|
1210
1220
|
const metavar$1 = options?.metavar ?? "INTEGER";
|
|
1211
1221
|
require_nonempty.ensureNonEmptyString(metavar$1);
|
|
@@ -1223,7 +1233,7 @@ function integer(options) {
|
|
|
1223
1233
|
error: unsafeIntegerError ? typeof unsafeIntegerError === "function" ? unsafeIntegerError(input) : unsafeIntegerError : require_message.message`Expected a safe integer between ${require_message.text(Number.MIN_SAFE_INTEGER.toLocaleString("en"))} and ${require_message.text(Number.MAX_SAFE_INTEGER.toLocaleString("en"))}, but got ${input}. Use type: "bigint" for large values.`
|
|
1224
1234
|
};
|
|
1225
1235
|
}
|
|
1226
|
-
return {
|
|
1236
|
+
return require_internal_doc_metadata.captureDocValue({
|
|
1227
1237
|
mode: "sync",
|
|
1228
1238
|
metavar: metavar$1,
|
|
1229
1239
|
placeholder: options?.placeholder ?? (firstAllowed > 0 ? firstAllowed : lastAllowed < 0 ? lastAllowed : 0),
|
|
@@ -1256,7 +1266,7 @@ function integer(options) {
|
|
|
1256
1266
|
format(value) {
|
|
1257
1267
|
return value.toString();
|
|
1258
1268
|
}
|
|
1259
|
-
};
|
|
1269
|
+
}, { kind: "number" });
|
|
1260
1270
|
}
|
|
1261
1271
|
/**
|
|
1262
1272
|
* Creates a {@link ValueParser} for floating-point numbers.
|
package/dist/valueparser.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { cloneMessage, lineBreak, message, metavar, text, valueSet } from "./message.js";
|
|
2
2
|
import { mapMaybePromiseByMode, wrapForMode, wrapIterableForMode } from "./internal/mode-dispatch.js";
|
|
3
3
|
import { defaultValues, dependencyId, dependencyIds, derivedValueParserMarker, getSnapshottedDefaultDependencyValues, isDependencySource, isDerivedValueParser, parseWithDependency, singleDefaultValue, snapshotDefaultDependencyValues, suggestWithDependency } from "./internal/dependency.js";
|
|
4
|
+
import { captureDocValue } from "./internal/doc-metadata.js";
|
|
4
5
|
import { appendValueHint, appendValueSuggestions, deduplicateSuggestions } from "./suggestion.js";
|
|
5
6
|
import { ensureNonEmptyString, isNonEmptyString } from "./nonempty.js";
|
|
6
7
|
|
|
@@ -92,7 +93,7 @@ function choice(choices, options = {}) {
|
|
|
92
93
|
const numberInvalidChoice = options.errors?.invalidChoice;
|
|
93
94
|
const numberStrings = numberChoices.map((v) => Object.is(v, -0) ? "-0" : String(v));
|
|
94
95
|
const frozenNumberChoices = Object.freeze(numberChoices);
|
|
95
|
-
return {
|
|
96
|
+
return captureDocValue({
|
|
96
97
|
mode: "sync",
|
|
97
98
|
metavar: metavar$1,
|
|
98
99
|
placeholder: choices[0],
|
|
@@ -156,7 +157,12 @@ function choice(choices, options = {}) {
|
|
|
156
157
|
text: valueStr
|
|
157
158
|
}));
|
|
158
159
|
}
|
|
159
|
-
}
|
|
160
|
+
}, {
|
|
161
|
+
kind: "number",
|
|
162
|
+
choices: numberChoices,
|
|
163
|
+
preserveNegativeZero: true,
|
|
164
|
+
canFormatDefault: true
|
|
165
|
+
});
|
|
160
166
|
}
|
|
161
167
|
const stringChoices = Object.freeze([...new Set(choices)]);
|
|
162
168
|
const stringOptions = options;
|
|
@@ -203,7 +209,7 @@ function choice(choices, options = {}) {
|
|
|
203
209
|
maxDistance: stringSuggest.maxDistance,
|
|
204
210
|
maxSuggestions: stringSuggest.maxSuggestions
|
|
205
211
|
} : stringSuggest;
|
|
206
|
-
return {
|
|
212
|
+
return captureDocValue({
|
|
207
213
|
mode: "sync",
|
|
208
214
|
metavar: metavar$1,
|
|
209
215
|
placeholder: choices[0],
|
|
@@ -240,7 +246,11 @@ function choice(choices, options = {}) {
|
|
|
240
246
|
text: value
|
|
241
247
|
}));
|
|
242
248
|
}
|
|
243
|
-
}
|
|
249
|
+
}, {
|
|
250
|
+
kind: "string",
|
|
251
|
+
choices: stringChoices,
|
|
252
|
+
canFormatDefault: customKey === void 0 && !caseInsensitive
|
|
253
|
+
});
|
|
244
254
|
}
|
|
245
255
|
function biject(mapping) {
|
|
246
256
|
if (mapping === null || typeof mapping !== "object") throw new TypeError("Expected object.");
|
|
@@ -723,7 +733,7 @@ function string(options = {}) {
|
|
|
723
733
|
const patternSource = options.pattern?.source ?? null;
|
|
724
734
|
const patternFlags = options.pattern?.flags ?? null;
|
|
725
735
|
const patternMismatch = options.errors?.patternMismatch;
|
|
726
|
-
return {
|
|
736
|
+
return captureDocValue({
|
|
727
737
|
mode: "sync",
|
|
728
738
|
metavar: metavar$1,
|
|
729
739
|
placeholder: options.placeholder ?? "",
|
|
@@ -747,7 +757,7 @@ function string(options = {}) {
|
|
|
747
757
|
format(value) {
|
|
748
758
|
return value;
|
|
749
759
|
}
|
|
750
|
-
};
|
|
760
|
+
}, { kind: "string" });
|
|
751
761
|
}
|
|
752
762
|
/**
|
|
753
763
|
* Creates a {@link ValueParser} that compiles regular expression sources.
|
|
@@ -1179,7 +1189,7 @@ function integer(options) {
|
|
|
1179
1189
|
if (options?.type === "bigint") {
|
|
1180
1190
|
const metavar$2 = options.metavar ?? "INTEGER";
|
|
1181
1191
|
ensureNonEmptyString(metavar$2);
|
|
1182
|
-
return {
|
|
1192
|
+
return captureDocValue({
|
|
1183
1193
|
mode: "sync",
|
|
1184
1194
|
metavar: metavar$2,
|
|
1185
1195
|
placeholder: options?.placeholder ?? (options?.min != null && options.min > 0n ? options.min : options?.max != null && options.max < 0n ? options.max : 0n),
|
|
@@ -1205,7 +1215,7 @@ function integer(options) {
|
|
|
1205
1215
|
format(value) {
|
|
1206
1216
|
return value.toString();
|
|
1207
1217
|
}
|
|
1208
|
-
};
|
|
1218
|
+
}, { kind: "bigint" });
|
|
1209
1219
|
}
|
|
1210
1220
|
const metavar$1 = options?.metavar ?? "INTEGER";
|
|
1211
1221
|
ensureNonEmptyString(metavar$1);
|
|
@@ -1223,7 +1233,7 @@ function integer(options) {
|
|
|
1223
1233
|
error: unsafeIntegerError ? typeof unsafeIntegerError === "function" ? unsafeIntegerError(input) : unsafeIntegerError : message`Expected a safe integer between ${text(Number.MIN_SAFE_INTEGER.toLocaleString("en"))} and ${text(Number.MAX_SAFE_INTEGER.toLocaleString("en"))}, but got ${input}. Use type: "bigint" for large values.`
|
|
1224
1234
|
};
|
|
1225
1235
|
}
|
|
1226
|
-
return {
|
|
1236
|
+
return captureDocValue({
|
|
1227
1237
|
mode: "sync",
|
|
1228
1238
|
metavar: metavar$1,
|
|
1229
1239
|
placeholder: options?.placeholder ?? (firstAllowed > 0 ? firstAllowed : lastAllowed < 0 ? lastAllowed : 0),
|
|
@@ -1256,7 +1266,7 @@ function integer(options) {
|
|
|
1256
1266
|
format(value) {
|
|
1257
1267
|
return value.toString();
|
|
1258
1268
|
}
|
|
1259
|
-
};
|
|
1269
|
+
}, { kind: "number" });
|
|
1260
1270
|
}
|
|
1261
1271
|
/**
|
|
1262
1272
|
* Creates a {@link ValueParser} for floating-point numbers.
|
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.2928",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -251,6 +251,14 @@
|
|
|
251
251
|
},
|
|
252
252
|
"import": "./dist/internal/help-request.js",
|
|
253
253
|
"require": "./dist/internal/help-request.cjs"
|
|
254
|
+
},
|
|
255
|
+
"./doc-pages": {
|
|
256
|
+
"types": {
|
|
257
|
+
"import": "./dist/doc-pages.d.ts",
|
|
258
|
+
"require": "./dist/doc-pages.d.cts"
|
|
259
|
+
},
|
|
260
|
+
"import": "./dist/doc-pages.js",
|
|
261
|
+
"require": "./dist/doc-pages.cjs"
|
|
254
262
|
}
|
|
255
263
|
},
|
|
256
264
|
"imports": {
|
|
@@ -261,7 +269,7 @@
|
|
|
261
269
|
},
|
|
262
270
|
"sideEffects": false,
|
|
263
271
|
"devDependencies": {
|
|
264
|
-
"@optique/env": "1.4.0-dev.
|
|
272
|
+
"@optique/env": "1.4.0-dev.2928+80c003f2",
|
|
265
273
|
"@types/node": "^24.0.0",
|
|
266
274
|
"fast-check": "^4.7.0",
|
|
267
275
|
"tsdown": "^0.13.0",
|
package/skills/optique/SKILL.md
CHANGED
|
@@ -80,9 +80,9 @@ Core rules
|
|
|
80
80
|
Show hidden `aliases` in help with `showAliases` on `command()` or runner.
|
|
81
81
|
- Use `run(parser, { completion: "both" })` for completion, or the object form
|
|
82
82
|
with `completion.errors` for custom shell errors. Do not hand-write scripts.
|
|
83
|
-
- Use `usageLine: [{ type: "ellipsis" }]`
|
|
84
|
-
|
|
85
|
-
|
|
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.
|
|
86
86
|
- Use `showUsage: false` in runner options when full help should show the
|
|
87
87
|
brief and sections without `Usage:`. Set `command()`'s `showUsage: true`
|
|
88
88
|
to restore it; children inherit the nearest explicit ancestor setting.
|
|
@@ -263,6 +263,7 @@ For the detailed maintained guide, use <https://optique.dev/pitfalls.md>.
|
|
|
263
263
|
Reference links
|
|
264
264
|
---------------
|
|
265
265
|
|
|
266
|
+
- Documentation index for agents: <https://optique.dev/llms.txt>
|
|
266
267
|
- Runners and entry points: <https://optique.dev/concepts/runners.md>
|
|
267
268
|
- Primitive parsers: <https://optique.dev/concepts/primitives.md>
|
|
268
269
|
- Construct combinators: <https://optique.dev/concepts/constructs.md>
|
|
@@ -272,8 +273,7 @@ Reference links
|
|
|
272
273
|
- Structured messages: <https://optique.dev/concepts/messages.md>
|
|
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
|
+
- Markdown references: <https://optique.dev/concepts/markdown-reference.md>
|
|
277
277
|
|
|
278
278
|
|
|
279
279
|
Integration packages
|
|
@@ -294,6 +294,6 @@ Integration packages
|
|
|
294
294
|
| `@optique/temporal` | Temporal date and time parsers | <https://optique.dev/integrations/temporal.md> |
|
|
295
295
|
| `@optique/git` | Async Git reference validation | <https://optique.dev/integrations/git.md> |
|
|
296
296
|
| `@optique/logtape` | LogTape levels and formatter/output options | <https://optique.dev/integrations/logtape.md> |
|
|
297
|
-
| `@optique/man` | Man
|
|
297
|
+
| `@optique/man` | Man pages and Markdown references | <https://optique.dev/concepts/man.md> |
|
|
298
298
|
| `@optique/discover` | Command discovery; opt-in `help.bareGroup` | <https://optique.dev/concepts/discover.md> |
|
|
299
299
|
| `@optique/testing` | Layered CLI testing at a chosen boundary | <https://optique.dev/concepts/testing.md> |
|