@optique/core 1.2.0-dev.2261 → 1.2.0-dev.2264
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/package.json +14 -5
- package/skills/optique/SKILL.md +229 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@optique/core",
|
|
3
|
-
"version": "1.2.0-dev.
|
|
3
|
+
"version": "1.2.0-dev.2264",
|
|
4
4
|
"description": "Type-safe combinatorial command-line interface parser",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"CLI",
|
|
@@ -36,8 +36,17 @@
|
|
|
36
36
|
"files": [
|
|
37
37
|
"dist/",
|
|
38
38
|
"package.json",
|
|
39
|
-
"README.md"
|
|
39
|
+
"README.md",
|
|
40
|
+
"skills/optique/SKILL.md"
|
|
40
41
|
],
|
|
42
|
+
"agents": {
|
|
43
|
+
"skills": [
|
|
44
|
+
{
|
|
45
|
+
"name": "optique",
|
|
46
|
+
"path": "./skills/optique"
|
|
47
|
+
}
|
|
48
|
+
]
|
|
49
|
+
},
|
|
41
50
|
"type": "module",
|
|
42
51
|
"module": "./dist/index.js",
|
|
43
52
|
"main": "./dist/index.cjs",
|
|
@@ -216,14 +225,14 @@
|
|
|
216
225
|
"fast-check": "^4.7.0",
|
|
217
226
|
"tsdown": "^0.13.0",
|
|
218
227
|
"typescript": "^5.8.3",
|
|
219
|
-
"@optique/env": "1.2.0-dev.
|
|
228
|
+
"@optique/env": "1.2.0-dev.2264+4a8db163"
|
|
220
229
|
},
|
|
221
230
|
"scripts": {
|
|
222
231
|
"build": "tsdown",
|
|
223
232
|
"prepublish": "tsdown",
|
|
224
233
|
"test": "node --test",
|
|
225
234
|
"test:bun": "bun test",
|
|
226
|
-
"test:deno": "deno test",
|
|
227
|
-
"test-all": "tsdown && node --test && bun test && deno test"
|
|
235
|
+
"test:deno": "deno test --allow-read --allow-env",
|
|
236
|
+
"test-all": "tsdown && node --test && bun test && deno test --allow-read --allow-env"
|
|
228
237
|
}
|
|
229
238
|
}
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: optique
|
|
3
|
+
description: >
|
|
4
|
+
Use this skill when writing any code that builds a command-line interface
|
|
5
|
+
with Optique in TypeScript or JavaScript. Covers the combinatorial parser
|
|
6
|
+
model, choosing @optique/core vs @optique/run, value parsers, structured
|
|
7
|
+
messages, optional()/withDefault()/multiple(), subcommands with command()
|
|
8
|
+
and or(), shell completion, async parsing, the integration packages, and
|
|
9
|
+
common mistakes to avoid. Trigger whenever the user is parsing command-line
|
|
10
|
+
arguments, building a CLI, or adding options or subcommands to a tool.
|
|
11
|
+
license: MIT
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
Optique is a type-safe combinatorial CLI parser. Use it by describing the CLI
|
|
15
|
+
grammar with parsers and combinators, not by manually walking `argv`.
|
|
16
|
+
|
|
17
|
+
If web access is available, start from <https://optique.dev/llms.txt> for the
|
|
18
|
+
maintained documentation index. Keep the rules below in mind even when offline;
|
|
19
|
+
they cover the parts agents most often get wrong.
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
Core rules
|
|
23
|
+
----------
|
|
24
|
+
|
|
25
|
+
- Use `run()` from `@optique/run` for real CLI applications. It reads
|
|
26
|
+
`process.argv`/`Deno.args`, handles help, version output, errors, exit
|
|
27
|
+
codes, colors, terminal width, and shell completion. Use `parse()` from
|
|
28
|
+
`@optique/core/parser` or `runParser()` from `@optique/core/facade` when
|
|
29
|
+
embedding Optique in tests, libraries, tools, or custom runtimes.
|
|
30
|
+
- Compose parsers with `object()`, `tuple()`, `seq()`, `or()`, `merge()`, and
|
|
31
|
+
modifiers. Do not write imperative `if`/`else` argument scanners around
|
|
32
|
+
Optique parsers.
|
|
33
|
+
- Let TypeScript infer the parsed value type from the parser. Do not
|
|
34
|
+
hand-maintain a separate interface for the result unless another API
|
|
35
|
+
boundary requires it.
|
|
36
|
+
- Most parsers are required until you wrap them. `optional(p)` yields
|
|
37
|
+
`undefined`; `withDefault(p, value)` yields a fallback value. For Boolean
|
|
38
|
+
flags, use `withDefault(flag("--name"), false)` when absence should mean
|
|
39
|
+
`false`.
|
|
40
|
+
- Use `message` from `@optique/core/message` for descriptions, help text, and
|
|
41
|
+
custom errors. Prefer semantic message helpers such as `optionName()` and
|
|
42
|
+
`metavar()` over string concatenation when naming CLI elements.
|
|
43
|
+
- Use value parsers such as `integer()`, `choice()`, `url()`, and `uuid()`
|
|
44
|
+
instead of validating raw strings after parsing. Use `path()` from
|
|
45
|
+
`@optique/run/valueparser` for file-system paths. Write a custom
|
|
46
|
+
`{ mode, metavar, parse, format }` value parser only when the catalog does
|
|
47
|
+
not cover the domain.
|
|
48
|
+
- Async value parsers make the containing parser async. If you use packages
|
|
49
|
+
such as `@optique/git`, remember to `await run(...)`, `await parse(...)`, or
|
|
50
|
+
`await runParser(...)` as appropriate.
|
|
51
|
+
- Build subcommands with `command()` combined by `or()`. Put a literal field
|
|
52
|
+
such as `command: constant("serve")` in each branch when you want a
|
|
53
|
+
discriminated union.
|
|
54
|
+
- Enable completion through `run(parser, { completion: "both" })` for CLI
|
|
55
|
+
apps. Do not hand-write completion scripts from parser metadata.
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Canonical app shape
|
|
59
|
+
-------------------
|
|
60
|
+
|
|
61
|
+
~~~~ typescript
|
|
62
|
+
import { object } from "@optique/core/constructs";
|
|
63
|
+
import { message } from "@optique/core/message";
|
|
64
|
+
import { withDefault } from "@optique/core/modifiers";
|
|
65
|
+
import { argument, flag, option } from "@optique/core/primitives";
|
|
66
|
+
import { integer, string } from "@optique/core/valueparser";
|
|
67
|
+
import { run } from "@optique/run";
|
|
68
|
+
|
|
69
|
+
const parser = object({
|
|
70
|
+
input: argument(string({ metavar: "FILE" }), {
|
|
71
|
+
description: message`Input file to process.`,
|
|
72
|
+
}),
|
|
73
|
+
port: withDefault(
|
|
74
|
+
option("--port", integer({ min: 1, max: 65535 }), {
|
|
75
|
+
description: message`Port to listen on.`,
|
|
76
|
+
}),
|
|
77
|
+
3000,
|
|
78
|
+
),
|
|
79
|
+
verbose: withDefault(
|
|
80
|
+
flag("-v", "--verbose", { description: message`Enable verbose logging.` }),
|
|
81
|
+
false,
|
|
82
|
+
),
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const config = run(parser, {
|
|
86
|
+
brief: message`Process a file.`,
|
|
87
|
+
completion: "both",
|
|
88
|
+
showDefault: true,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
console.log(`Processing ${config.input} on port ${config.port}.`);
|
|
92
|
+
~~~~
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
Subcommands
|
|
96
|
+
-----------
|
|
97
|
+
|
|
98
|
+
Use `command()` for each branch and `or()` to require exactly one matching
|
|
99
|
+
subcommand. Use `optional(or(...))` only when no subcommand is valid.
|
|
100
|
+
|
|
101
|
+
~~~~ typescript
|
|
102
|
+
import { object, or } from "@optique/core/constructs";
|
|
103
|
+
import { withDefault } from "@optique/core/modifiers";
|
|
104
|
+
import { parse } from "@optique/core/parser";
|
|
105
|
+
import { command, constant, flag, option } from "@optique/core/primitives";
|
|
106
|
+
import { integer } from "@optique/core/valueparser";
|
|
107
|
+
|
|
108
|
+
const parser = or(
|
|
109
|
+
command("build", object({
|
|
110
|
+
command: constant("build"),
|
|
111
|
+
watch: withDefault(flag("--watch"), false),
|
|
112
|
+
})),
|
|
113
|
+
command("serve", object({
|
|
114
|
+
command: constant("serve"),
|
|
115
|
+
port: withDefault(option("--port", integer({ min: 1 })), 3000),
|
|
116
|
+
})),
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
const result = parse(parser, ["serve", "--port", "8080"]);
|
|
120
|
+
|
|
121
|
+
if (result.success) {
|
|
122
|
+
switch (result.value.command) {
|
|
123
|
+
case "build":
|
|
124
|
+
result.value.watch;
|
|
125
|
+
break;
|
|
126
|
+
case "serve":
|
|
127
|
+
result.value.port;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
~~~~
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
Custom value parsers
|
|
135
|
+
--------------------
|
|
136
|
+
|
|
137
|
+
Prefer the built-in catalog first. When a custom domain is needed, keep the
|
|
138
|
+
validation in a value parser so help, errors, defaults, prompts, and completion
|
|
139
|
+
all see the same typed value.
|
|
140
|
+
|
|
141
|
+
~~~~ typescript
|
|
142
|
+
import { message } from "@optique/core/message";
|
|
143
|
+
import type { ValueParser, ValueParserResult } from "@optique/core/valueparser";
|
|
144
|
+
|
|
145
|
+
const levels = ["debug", "info", "warn", "error"] as const;
|
|
146
|
+
type Level = typeof levels[number];
|
|
147
|
+
|
|
148
|
+
function isLevel(input: string): input is Level {
|
|
149
|
+
return (levels as readonly string[]).includes(input);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
function logLevel(): ValueParser<"sync", Level> {
|
|
153
|
+
return {
|
|
154
|
+
mode: "sync",
|
|
155
|
+
metavar: "LEVEL",
|
|
156
|
+
placeholder: "info",
|
|
157
|
+
parse(input: string): ValueParserResult<Level> {
|
|
158
|
+
if (isLevel(input)) return { success: true, value: input };
|
|
159
|
+
return { success: false, error: message`Invalid log level: ${input}.` };
|
|
160
|
+
},
|
|
161
|
+
format(value: Level): string {
|
|
162
|
+
return value;
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const parser = logLevel();
|
|
168
|
+
~~~~
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
Common mistakes checklist
|
|
172
|
+
-------------------------
|
|
173
|
+
|
|
174
|
+
- Do not parse `process.argv` manually before calling Optique. Pass the parser
|
|
175
|
+
to `run()` for applications, or pass explicit argument arrays to `parse()`
|
|
176
|
+
in tests and embedded use.
|
|
177
|
+
- Do not treat `or(a, b)` as “zero or more alternatives.” It requires one
|
|
178
|
+
matching branch unless the whole `or()` is wrapped in `optional()` or
|
|
179
|
+
`withDefault()`.
|
|
180
|
+
- Do not use `object()` for mutually exclusive subcommands. Use
|
|
181
|
+
`or(command(...), command(...))`.
|
|
182
|
+
- Do not forget that `flag("--x")` is required. Wrap it in `optional()` or
|
|
183
|
+
`withDefault(..., false)` for ordinary optional flags.
|
|
184
|
+
- Do not expect `multiple(p)` to fail when absent; it returns `[]`. Wrap with
|
|
185
|
+
`nonEmpty()` when at least one value is required.
|
|
186
|
+
- Do not confuse free-order parsing with `seq()`. Most constructs let child
|
|
187
|
+
parsers compete by priority; use `seq()` only when the grammar is truly
|
|
188
|
+
ordered.
|
|
189
|
+
- Do not concatenate plain strings for errors or descriptions. Use structured
|
|
190
|
+
`message` values.
|
|
191
|
+
- Do not forget to register source contexts when using `bindEnv()`,
|
|
192
|
+
`bindConfig()`, or `bindDerivedDefault()`.
|
|
193
|
+
|
|
194
|
+
For the detailed maintained guide, use <https://optique.dev/pitfalls.md>.
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
Reference links
|
|
198
|
+
---------------
|
|
199
|
+
|
|
200
|
+
- Documentation index for agents: <https://optique.dev/llms.txt>
|
|
201
|
+
- Runners and entry points: <https://optique.dev/concepts/runners.md>
|
|
202
|
+
- Primitive parsers: <https://optique.dev/concepts/primitives.md>
|
|
203
|
+
- Construct combinators: <https://optique.dev/concepts/constructs.md>
|
|
204
|
+
- Modifiers: <https://optique.dev/concepts/modifiers.md>
|
|
205
|
+
- Value parser catalog: <https://optique.dev/concepts/valueparsers.md>
|
|
206
|
+
- Structured messages: <https://optique.dev/concepts/messages.md>
|
|
207
|
+
- Shell completion: <https://optique.dev/concepts/completion.md>
|
|
208
|
+
- Command discovery: <https://optique.dev/concepts/discover.md>
|
|
209
|
+
- Man pages: <https://optique.dev/concepts/man.md>
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
Integration packages
|
|
213
|
+
--------------------
|
|
214
|
+
|
|
215
|
+
| Package | Use for | Docs |
|
|
216
|
+
| --------------------------- | ----------------------------------------- | -------------------------------------------------- |
|
|
217
|
+
| `@optique/env` | Environment variable fallbacks | <https://optique.dev/integrations/env.md> |
|
|
218
|
+
| `@optique/config` | Configuration file fallbacks | <https://optique.dev/integrations/config.md> |
|
|
219
|
+
| `@optique/derived-defaults` | Defaults computed from first-pass results | <https://optique.dev/concepts/derived-defaults.md> |
|
|
220
|
+
| `@optique/prompt` | Generic prompt adapter foundation | <https://optique.dev/integrations/prompt.md> |
|
|
221
|
+
| `@optique/clack` | Clack interactive fallback prompts | <https://optique.dev/integrations/clack.md> |
|
|
222
|
+
| `@optique/inquirer` | Inquirer.js interactive fallback prompts | <https://optique.dev/integrations/inquirer.md> |
|
|
223
|
+
| `@optique/zod` | Zod-backed value parsing | <https://optique.dev/integrations/zod.md> |
|
|
224
|
+
| `@optique/valibot` | Valibot-backed value parsing | <https://optique.dev/integrations/valibot.md> |
|
|
225
|
+
| `@optique/temporal` | Temporal date and time parsers | <https://optique.dev/integrations/temporal.md> |
|
|
226
|
+
| `@optique/git` | Async Git reference validation | <https://optique.dev/integrations/git.md> |
|
|
227
|
+
| `@optique/logtape` | LogTape verbosity and log-level options | <https://optique.dev/integrations/logtape.md> |
|
|
228
|
+
| `@optique/man` | Man page generation | <https://optique.dev/concepts/man.md> |
|
|
229
|
+
| `@optique/discover` | File-based command discovery | <https://optique.dev/concepts/discover.md> |
|