Optique changelog
Version 0.7.0
Released on November 25, 2025.
@optique/core
Added duplicate option name detection to parser combinators. The
object(),tuple(),merge(), andgroup()combinators now validate at parse time that option names are unique across their child parsers. When duplicate option names are detected, parsing fails with a clear error message indicating which option name is duplicated and in which fields or positions. [#37]- Added
ObjectOptions.allowDuplicatesfield to opt out of validation. - Added
TupleOptionsinterface withallowDuplicatesfield. - Added
MergeOptionsinterface withallowDuplicatesfield. - Added
tuple()overloads accepting optionalTupleOptionsparameter. - Added
extractOptionNames()function to@optique/core/usagemodule.
- Added
Changed parsing behavior:
object(),tuple(),merge(), andgroup()now reject parsers with duplicate option names by default. Previously, duplicate option names would result in ambiguous parsing where the first matching parser consumed the option and subsequent parsers silently received default values. This breaking change prevents unintentional bugs from option name conflicts.To restore previous behavior, set
allowDuplicates: truein options. [#37]The
or()combinator continues to allow duplicate option names across branches since alternatives are mutually exclusive. [#37]Added “Did you mean?” suggestion system for typos in option names and command names. When users make typos in command-line arguments, Optique now automatically suggests similar valid options to help them correct the mistake:
typescriptconst parser = object({ verbose: option("-v", "--verbose"), version: option("--version"), }); // User types: --verbos (typo) const result = parse(parser, ["--verbos"]); // Error: No matched option for `--verbos`. // Did you mean `--verbose`?The suggestion system uses Levenshtein distance to find similar names, suggesting up to 3 alternatives when the edit distance is at most 3 characters and the distance ratio is at most 0.5. Comparison is case-insensitive by default. Suggestions work automatically for both option names and subcommand names in all error contexts (
option(),flag(),command(),object(),or(), andlongestMatch()parsers). This feature is implemented internally and requires no user configuration. [#38]Added customization support for “Did you mean?” suggestion messages. All parsers that generate suggestion messages now support customizing how suggestions are formatted or disabling them entirely through the
errorsoption:typescript// Custom suggestion format for option/flag parsers const portOption = option("--port", integer(), { errors: { noMatch: (invalidOption, suggestions) => suggestions.length > 0 ? message`Unknown option ${invalidOption}. Try: ${values(suggestions)}` : message`Unknown option ${invalidOption}.` } }); // Custom suggestion format for command parser const addCmd = command("add", object({}), { errors: { notMatched: (expected, actual, suggestions) => suggestions && suggestions.length > 0 ? message`Unknown command ${actual}. Similar: ${values(suggestions)}` : message`Expected ${expected} command.` } }); // Custom suggestion formatter for combinators const config = object({ host: option("--host", string()), port: option("--port", integer()) }, { errors: { suggestions: (suggestions) => suggestions.length > 0 ? message`Available options: ${values(suggestions)}` : [] } });The customization system allows complete control over suggestion formatting while maintaining backward compatibility. When custom error messages are provided, they receive the array of suggestions and can format, filter, or disable them as needed. This enables applications to provide context-specific error messages that match their CLI's style and user expectations. [#38]
- Extended
OptionErrorOptionsinterface withnoMatchfield. - Extended
FlagErrorOptionsinterface withnoMatchfield. - Extended
CommandErrorOptions.notMatchedsignature to include optionalsuggestionsparameter. - Extended
OrErrorOptionsinterface withsuggestionsfield. - Extended
LongestMatchErrorOptionsinterface withsuggestionsfield. - Extended
ObjectErrorOptionsinterface withsuggestionsfield.
- Extended
Improved
formatMessage()line break handling to distinguish between soft breaks (word wrap) and hard breaks (paragraph separation):Single newlines (
\n) are now treated as soft breaks, converted to spaces for natural word wrapping. This allows long error messages to be written across multiple lines in source code while rendering as continuous text.Double or more consecutive newlines (
\n\n+) are treated as hard breaks, creating actual paragraph separations in the output.
This change improves the readability of multi-part error messages, such as those with “Did you mean?” suggestions, by ensuring proper spacing between the base error and suggestions:
Error: Unexpected option or subcommand: comit. Did you mean commit?Previously, single newlines in
text()terms would be silently dropped during word wrapping, causing messages to run together without spacing.Improved error messages for
or(),longestMatch(), andobject()combinators to provide context-aware feedback based on expected input types. Error messages now accurately reflect what's missing (options, commands, or arguments) instead of showing generic "No matching option or command found" for all cases. [#45]typescript// When only arguments are expected const parser1 = or(argument(string()), argument(integer())); // Error: Missing required argument. // When only commands are expected const parser2 = or(command("add", ...), command("remove", ...)); // Error: No matching command found. // When both options and arguments are expected const parser3 = object({ port: option("--port", integer()), file: argument(string()), }); // Error: No matching option or argument found.Added function-form support for
errors.noMatchoption inor(),longestMatch(), andobject()combinators. Error messages can now be dynamically generated based on context, enabling use cases like internationalization:typescriptconst parser = or( command("add", constant("add")), command("remove", constant("remove")), { errors: { noMatch: ({ hasOptions, hasCommands, hasArguments }) => { if (hasCommands && !hasOptions && !hasArguments) { return message`일치하는 명령을 찾을 수 없습니다.`; // Korean } return message`잘못된 입력입니다.`; } } } );The callback receives a
NoMatchContextobject with boolean flags (hasOptions,hasCommands,hasArguments) indicating what types of inputs are expected. This allows generating language-specific or context-specific error messages while maintaining backward compatibility with static message form. [#45]- Added
NoMatchContextinterface. - Extended
OrErrorOptions.noMatchto acceptMessage | ((context: NoMatchContext) => Message). - Extended
LongestMatchErrorOptions.noMatchto acceptMessage | ((context: NoMatchContext) => Message). - Extended
ObjectErrorOptions.endOfInputto acceptMessage | ((context: NoMatchContext) => Message). - Added
extractArgumentMetavars()function to@optique/core/usagemodule.
- Added
Added configuration for shell completion naming conventions. The
run()function now supports both singular (completion,--completion) and plural (completions,--completions) naming styles. By default, both forms are accepted ("both"), but this can be restricted to just one style using the newnameoption in the completion configuration:typescriptrun(parser, { completion: { // Use "completions" and "--completions" only name: "plural", } });This allows CLI tools to match their preferred style guide or exist alongside other commands. The help text examples automatically reflect the configured naming style. [#42]
- Added
nameoption toRunOptions.completionconfiguration ("singular","plural", or"both").
- Added
@optique/valibot
The @optique/valibot package was introduced in this release, providing integration with the Valibot validation library. This package enables using Valibot schemas as value parsers, bringing Valibot's powerful validation capabilities with a significantly smaller bundle size (~10KB vs Zod's ~52KB) to command-line argument parsing. Supports Valibot version 0.42.0 and above. [#40]
- Added
valibot()value parser for validating command-line arguments using Valibot schemas. - Added
ValibotParserOptionsinterface for configuring metavar and custom error messages. - Added automatic metavar inference from Valibot schema types (
STRING,EMAIL,NUMBER,INTEGER,CHOICE, etc.).
@optique/zod
The @optique/zod package was introduced in this release, providing integration with the Zod validation library. This package enables using Zod schemas as value parsers, bringing Zod's powerful validation capabilities to command-line argument parsing. Supports both Zod v3.25.0+ and v4.0.0+. [#39]
- Added
zod()value parser for validating command-line arguments using Zod schemas. - Added
ZodParserOptionsinterface for configuring metavar and custom error messages.
Version 0.6.3
Released on November 25, 2025.
@optique/core
- Fixed shell completion scripts using
completionsubcommand even whencompletion.modeis set to"option". Now, when the mode is"option", the generated scripts correctly use--completioninstead ofcompletion. [#41]
Version 0.6.2
Released on October 27, 2025.
@optique/core
- Fixed incorrect CommonJS type export paths in
package.json. The"require"type paths for submodules were incorrectly pointing to"*.cts"files instead of"*.d.cts"files, causing type resolution issues when importing submodules in CommonJS environments. [#36]
@optique/run
- Fixed incorrect CommonJS type export paths in
package.json. The"require"type paths for submodules were incorrectly pointing to"*.cts"files instead of"*.d.cts"files, causing type resolution issues when importing submodules in CommonJS environments. [#36]
Version 0.6.1
Released on October 8, 2025.
@optique/run
- Fixed inconsistent error message coloring in Bun runtime by replacing reliance on default
console.error()andconsole.log()with directprocess.stderr.write()andprocess.stdout.write()calls. Previously, Bun'sconsole.error()would add red coloring by default, which interfered with ANSI formatting in error messages. This change ensures consistent output formatting across all JavaScript runtimes (Node.js, Bun, and Deno).
Version 0.6.0
Released on October 2, 2025.
@optique/core
Added shell completion support for Bash, zsh, fish, PowerShell, and Nushell. Optique now provides built-in completion functionality that integrates seamlessly with the existing parser architecture. This allows CLI applications to offer intelligent suggestions for commands, options, and arguments without requiring additional configuration. [#5, #30, #31, #33]
- Added
Suggestiontype. - Added
Parser.suggest()method. - Added
ValueParser.suggest()method. - Added
suggest()function. - Added
@optique/core/completionmodule. - Added
ShellCompletioninterface. - Added
bash,zsh,fish,pwsh, andnushell completion generators. - Added
RunOptions.completionoption.
- Added
Added
briefandfooteroptions tocommand()parser for improved documentation control. Thebriefoption provides a short description for command listings (e.g.,myapp help), whiledescriptionis used for detailed help (e.g.,myapp help subcommandormyapp subcommand --help). Thefooteroption allows adding examples or additional information at the bottom of command-specific help text.- Added
CommandOptions.brieffield. - Added
CommandOptions.footerfield. - Added
DocFragments.footerfield.
- Added
Added
commandLinemessage term type for formatting command-line examples in help text and error messages. This allows command-line snippets to be displayed with distinct styling (cyan color in terminals) to make examples more visually clear.- Added
commandLine()function for creating command-line message terms. - Updated
MessageTermtype to includecommandLinevariant. - Updated
formatMessage()to support styling command-line examples.
- Added
@optique/run
Added completion integration to the
run()function. Applications can now enable shell completion by setting thecompletionoption, which automatically handles completion script generation and runtime completion requests. [#5]- Added
RunOptions.completionoption.
- Added
Version 0.5.3
Released on October 27, 2025.
@optique/core
- Fixed incorrect CommonJS type export paths in
package.json. The"require"type paths for submodules were incorrectly pointing to"*.cts"files instead of"*.d.cts"files, causing type resolution issues when importing submodules in CommonJS environments. [#36]
@optique/run
- Fixed incorrect CommonJS type export paths in
package.json. The"require"type paths for submodules were incorrectly pointing to"*.cts"files instead of"*.d.cts"files, causing type resolution issues when importing submodules in CommonJS environments. [#36]
Version 0.5.2
Released on October 8, 2025.
@optique/run
- Fixed inconsistent error message coloring in Bun runtime by replacing reliance on default
console.error()andconsole.log()with directprocess.stderr.write()andprocess.stdout.write()calls. Previously, Bun'sconsole.error()would add red coloring by default, which interfered with ANSI formatting in error messages. This change ensures consistent output formatting across all JavaScript runtimes (Node.js, Bun, and Deno).
Version 0.5.1
Released on September 26, 2025.
@optique/core
- Fixed an issue where empty group sections were displayed in help output for nested subcommands. When using
group()with nested commands, help text would show empty group headers when the grouped items were no longer available in the current command context. TheformatDocPage()function now skips sections with no entries. [#29]
Version 0.5.0
Released on September 23, 2025.
@optique/core
Refactored parser modules for better code organization by splitting the large
@optique/core/parsermodule into focused, specialized modules. This improves maintainability, reduces module size, and provides clearer separation of concerns. All changes maintain full backward compatibility through re-exports.Primitive parsers: Moved primitive parsers (
constant(),option(),flag(),argument(),command()) and their related types to a dedicated@optique/core/primitivesmodule. These core building blocks are now logically separated from parser combinators.Modifying combinators: Moved parser modifier functions (
optional(),withDefault(),map(),multiple()) and their related types to a dedicated@optique/core/modifiersmodule. These higher-order functions that transform and enhance parsers are now grouped together.Construct combinators: Moved parser combinators (
object(),tuple(),or(),merge(),concat(),longestMatch(),group()) and their related types to a dedicated@optique/core/constructsmodule. These combinator functions that compose and combine parsers are now organized in a separate module.
For backward compatibility, all functions continue to be re-exported from
@optique/core/parser, so existing code will work unchanged. However, the recommended approach going forward is to import directly from the specialized modules:typescript// Recommended: import directly from specialized modules import { option, flag, argument } from "@optique/core/primitives"; import { optional, withDefault, multiple } from "@optique/core/modifiers"; import { object, or, merge } from "@optique/core/constructs"; // Still supported: import everything from parser module (backward compatibility) import { option, flag, optional, withDefault, object, or } from "@optique/core/parser";This refactoring only affects internal code organization and does not impact the public API or runtime behavior of any parsers.
Added automatic error handling for
withDefault()default value callbacks. When a default value callback throws an error, it is now automatically caught and converted to a parser-level error. This allows users to handle validation errors (like missing environment variables) directly at the parser level instead of after callingrun(). [#18, #21]Added
WithDefaultErrorclass for structured error messages inwithDefault()callbacks. This error type accepts aMessageobject instead of just a string, enabling rich formatting with colors and structured content in error messages. Regular errors are still supported and automatically converted to plain text messages. [#18, #21]typescript// Regular error (automatically converted to text) withDefault(option("--url", url()), () => { throw new Error("Environment variable not set"); }); // Structured error with rich formatting withDefault(option("--config", string()), () => { throw new WithDefaultError( message`Environment variable ${envVar("CONFIG_PATH")} is not set` ); });Added
envVarmessage term type for environment variable references. Environment variables are displayed with bold and underline formatting to distinguish them from other message components like option names and metavariables. TheenvVar()helper function creates environment variable terms for use in structured messages.typescriptimport { envVar, message } from "@optique/core/message"; const configError = message`Environment variable ${envVar("API_URL")} is not set.`; // Displays: Environment variable API_URL is not set. (bold + underlined)Added custom help display messages for
withDefault()parsers. ThewithDefault()modifier now accepts an optional third parameter to customize how default values are displayed in help text. This allows showing descriptive text instead of actual default values, which is particularly useful for environment variables, computed defaults, or sensitive information. [#19]typescriptimport { message, envVar } from "@optique/core/message"; import { withDefault } from "@optique/core/parser"; // Show custom help text instead of actual values const parser = object({ apiUrl: withDefault( option("--api-url", url()), new URL("https://api.example.com"), { message: message`Default API endpoint` } ), token: withDefault( option("--token", string()), () => process.env.API_TOKEN || "", { message: message`${envVar("API_TOKEN")}` } ) }); // Help output shows: --token STRING [API_TOKEN] // Instead of the actual token valueEnhanced
formatMessage()withresetSuffixsupport for better ANSI color handling. Thecolorsoption can now be an object with aresetSuffixproperty that maintains parent styling context after ANSI reset sequences. This fixes issues where dim styling was interrupted by inner ANSI codes in default value display. [#19]typescriptformatMessage(msg, { colors: { resetSuffix: "\x1b[2m" }, // Maintains dim after resets quotes: false });Updated
DocEntry.defaultfield type fromstringtoMessagefor rich formatting support in documentation. This change enables structured default value display with colors, environment variables, and other message components while maintaining full backward compatibility. [#19]Added comprehensive error message customization system that allows users to customize error messages for all parser types and combinators. This addresses the need for better user-facing error messages in CLI applications by enabling context-specific error text with support for both static messages and dynamic error generation functions. [#27]
Parser error options: All primitive parsers (
option(),flag(),argument(),command()) now accept anerrorsoption to customize error messages:typescriptconst parser = option("--port", integer(), { errors: { missing: message`Port number is required for server operation.`, invalidValue: (error) => message`Invalid port: ${error}` } });Combinator error options: Parser combinators (
or(),longestMatch(),object(),multiple()) support error customization for various failure scenarios:typescriptconst parser = or( flag("--verbose"), flag("--quiet"), { errors: { noMatch: message`Please specify either --verbose or --quiet.` } } );Value parser error customization: All value parsers now support customizable error messages through an
errorsoption in their configuration. This enables application-specific error messages that better guide users:typescript// Core value parsers const portOption = option("--port", integer({ min: 1024, max: 65535, errors: { invalidInteger: message`Port must be a whole number.`, belowMinimum: (value, min) => message`Port ${text(value.toString())} too low. Use ${text(min.toString())} or higher.`, aboveMaximum: (value, max) => message`Port ${text(value.toString())} too high. Maximum is ${text(max.toString())}.` } })); const formatOption = option("--format", choice(["json", "yaml", "xml"], { errors: { invalidChoice: (input, choices) => message`Format ${input} not supported. Available: ${values(choices)}.` } }));Function-based error messages: Error options can be functions that receive context parameters to generate dynamic error messages:
typescriptconst parser = command("deploy", argument(string()), { errors: { notMatched: (expected, actual) => message`Expected "${expected}" command, but got "${actual ?? "nothing"}".` } });Type-safe error interfaces: Each parser type has its own error options interface (
OptionErrorOptions,FlagErrorOptions,ArgumentErrorOptions,CommandErrorOptions,ObjectOptions,MultipleOptions,OrOptions,LongestMatchOptions) providing IntelliSense support and type safety.Improved default messages: Default error messages have been improved to be more user-friendly, changing generic messages like “No parser matched” to specific ones like “No matching option or command found.”
Backward compatibility: All error customization is optional and maintains full backward compatibility. Existing code continues to work unchanged while new APIs are available when needed.
@optique/run
Added comprehensive error message customization for the
path()value parser. Path validation now supports custom error messages for all validation scenarios, enabling more user-friendly error messages in file and directory operations:typescriptimport { path } from "@optique/run/valueparser"; import { message, values } from "@optique/core/message"; // Configuration file with custom validation errors const configFile = option("--config", path({ mustExist: true, type: "file", extensions: [".json", ".yaml", ".yml"], errors: { pathNotFound: (input) => message`Configuration file ${input} not found.`, notAFile: message`Configuration must be a file, not a directory.`, invalidExtension: (input, extensions, actualExt) => message`Config file ${input} has wrong extension ${actualExt}. Expected: ${values(extensions)}.`, } }));The
PathOptionsinterface now includes anerrorsfield with support for customizingpathNotFound,notAFile,notADirectory,invalidExtension, andparentNotFounderror messages. All error customization options support both staticMessageobjects and dynamic functions that receive validation context parameters. [#27]
@optique/temporal
Added comprehensive error message customization for all temporal value parsers. This enables application-specific error messages for date, time, and timezone validation scenarios:
typescriptimport { instant, duration, timeZone } from "@optique/temporal"; import { message } from "@optique/core/message"; // Timestamp parser with user-friendly errors const startTime = option("--start", instant({ errors: { invalidFormat: (input) => message`Start time ${input} is invalid. Use ISO 8601 format like 2023-12-25T10:30:00Z.`, } })); // Duration parser with contextual errors const timeout = option("--timeout", duration({ errors: { invalidFormat: message`Timeout must be in ISO 8601 duration format (e.g., PT30S, PT5M, PT1H).`, } })); // Timezone parser with helpful suggestions const timezone = option("--timezone", timeZone({ errors: { invalidFormat: (input) => message`Timezone ${input} is not valid. Use IANA identifiers like America/New_York or UTC.`, } }));All temporal parsers (
instant(),duration(),zonedDateTime(),plainDate(),plainTime(),plainDateTime(),plainYearMonth(),plainMonthDay(),timeZone()) now support anerrorsoption withinvalidFormaterror message customization. This maintains consistency with the error customization system across all Optique packages. [#27]
Version 0.4.4
Released on September 18, 2025.
@optique/core
- Fixed subcommand help display bug in the
run()function when using thehelpoption. Previously,cli my-cmd --helpwould incorrectly show root-level help instead of subcommand-specific help when parsers were combined withor(). Now--helpcorrectly shows help for the specific subcommand being used. [[#26]]
Version 0.4.3
Released on September 16, 2025.
@optique/temporal
- Fixed timezone identifier validation failure in Deno 2.5.0. The
timeZone()parser now works correctly with all supported timezones by removing explicit zero values for hour, minute, and second fields when creating validationZonedDateTimeobjects. This addresses a regression in Deno 2.5.0's Temporal API implementation that rejected zero values for time fields.
Version 0.4.2
Released on September 10, 2025.
@optique/run
- Fixed dependency resolution bug where @optique/core dependency was not properly versioned, causing installations to use outdated stable versions instead of matching development versions. This resolves type errors and message formatting issues when using dev versions. [#22]
Version 0.4.1
Released on September 8, 2025.
@optique/run
- Fixed inconsistent error message coloring across JavaScript runtimes by replacing
console.error()andconsole.log()with directprocess.stderr.write()andprocess.stdout.write()calls. Previously, runtimes like Bun would displayconsole.error()output in red, causing ANSI reset codes in formatted option names to interrupt the error coloring. This change ensures consistent output formatting across all JavaScript runtimes. [#20]
Version 0.4.0
Released on September 6, 2025.
@optique/core
Improved type inference for
tuple()parser by usingconsttype parameter. The generic type parameter now preserves tuple literal types more accurately, providing better type safety and inference when working with tuple parsers.Extended
merge()combinator to support up to 10 parsers (previously limited to 5), allowing more complex CLI configurations with larger numbers of parsers to be combined into a single object structure.Added optional label parameter to
merge()combinator for better help text organization. Similar toobject(),merge()now accepts an optional first string parameter to label the merged group in documentation:typescript// Without label (existing usage) merge(apiParser, dbParser, serverParser) // With label (new feature) merge("Configuration", apiParser, dbParser, serverParser)This addresses the inconsistency where developers had to choose between clean code structure using
merge()or organized help output using labeledobject()calls. The label appears as a section header in help text, making it easier to group related options from multiple parsers. [#12]Added
group()combinator for organizing any parser under a labeled section in help text. This wrapper function applies a group label to any parser for documentation purposes without affecting parsing behavior:typescript// Group mutually exclusive options const outputFormat = group( "Output Format", or( map(flag("--json"), () => "json"), map(flag("--yaml"), () => "yaml"), map(flag("--xml"), () => "xml"), ), );Unlike
merge()andobject()which have built-in label support,group()can be used with any parser type (or(),flag(),multiple(), etc.) that doesn't natively support labeling. This enables clean code organization while maintaining well-structured help text. [#12]Improved type safety for
merge()combinator by enforcing stricter parameter constraints. The function now rejects parsers that return non-object values (arrays, primitives, etc.) at compile time, producing clear “No overload matches this call” errors instead of allowing invalid combinations that would fail at runtime:typescript// These now produce compile-time errors (previously allowed): merge( object({ port: option("--port", integer()) }), // ✅ Returns object multiple(argument(string())), // ❌ Returns array ); merge( object({ verbose: flag("--verbose") }), // ✅ Returns object flag("--debug"), // ❌ Returns boolean );This prevents a class of runtime errors where
merge()would receive incompatible parser types. Existing code usingmerge()with only object-producing parsers (the intended usage) continues to work unchanged.Improved help and version handling in
run()function with better edge case support and more consistent behavior. The implementation was refactored from a complex conditional parser generator into modular helper functions, improving maintainability and test coverage:- Enhanced last-option-wins pattern:
--version --helpshows help,--help --versionshows version - Added support for options terminator (
--) to prevent help/version flags after--from being interpreted as options - Improved handling of multiple identical flags (e.g.,
--version --version)
The public API remains unchanged - existing
run()usage continues to work identically while benefiting from more robust edge case handling. [#13]- Enhanced last-option-wins pattern:
Added
showDefaultoption to display default values in help text. When enabled, options and arguments created withwithDefault()will display their default values in the help output:typescriptconst parser = object({ port: withDefault(option("--port", integer()), 3000), format: withDefault(option("--format", string()), "json"), }); // Basic usage shows: --port [3000], --format [json] formatDocPage("myapp", doc, { showDefault: true }); // Custom formatting formatDocPage("myapp", doc, { showDefault: { prefix: " (default: ", suffix: ")" } }); // Shows: --port (default: 3000), --format (default: json)The feature is opt-in and backward compatible. Default values are automatically dimmed when colors are enabled. A new
ShowDefaultOptionsinterface provides type-safe customization of the display format. [#14]Added
brief,description, andfooteroptions to theRunOptionsinterface in therun()function. These fields allow users to provide rich documentation that appears in help text without modifying parser definitions:typescriptimport { run } from "@optique/core/facade"; import { message } from "@optique/core/message"; run(parser, "myapp", args, { brief: message`A powerful CLI tool for data processing`, description: message`This tool provides comprehensive data processing capabilities with support for multiple formats and transformations.`, footer: message`For more information, visit https://example.com`, help: { mode: "option" }, });The documentation fields appear in both help output (when
--helpis used) and error output (whenaboveError: "help"is configured). These options augment theDocPagegenerated bygetDocPage(), with user-provided values taking precedence over parser-generated content. [#15]
@optique/run
Added
showDefaultoption to theRunOptionsinterface. This option works identically to the same option in@optique/core/facade, allowing users to display default values in help text when using the process-integratedrun()function:typescriptimport { run } from "@optique/run"; const result = run(parser, { showDefault: true, // Shows default values in help colors: true, // With dim styling });This ensures feature parity between the low-level facade API and the high-level run package. [#14]
Added
brief,description, andfooteroptions to theRunOptionsinterface. These fields provide the same rich documentation capabilities as the corresponding options in@optique/core/facade, but with the convenience of automatic process integration:typescriptimport { run } from "@optique/run"; import { message } from "@optique/core/message"; const result = run(parser, { brief: message`A powerful CLI tool for data processing`, description: message`This tool provides comprehensive data processing capabilities with support for multiple formats and transformations.`, footer: message`For more information, visit https://example.com`, help: "option", // Enables --help option version: "1.0.0", // Enables --version option });This maintains feature parity between the low-level facade API and the high-level run package, allowing developers to create rich CLI documentation regardless of which API they use. [#15]
@optique/temporal
The @optique/temporal package was introduced in this release, providing parsers for JavaScript Temporal types. This package depends on the @js-temporal/polyfill package for environments that do not yet support Temporal natively.
- Added
TimeZonetype. - Added
instant()value parser. - Added
InstantOptionsinterface. - Added
duration()value parser. - Added
DurationOptionsinterface. - added
zonedDateTime()value parser. - Added
ZonedDateTimeOptionsinterface. - Added
plainDate()value parser. - Added
PlainDateOptionsinterface. - Added
plainTime()value parser. - Added
PlainTimeOptionsinterface. - Added
plainDateTime()value parser. - Added
PlainDateTimeOptionsinterface. - Added
plainYearMonth()value parser. - Added
PlainYearMonthOptionsinterface. - Added
plainMonthDay()value parser. - Added
PlainMonthDayOptionsinterface. - Added
timeZone()value parser. - Added
TimeZoneOptionsinterface.
Version 0.3.2
Released on September 10, 2025.
@optique/run
- Fixed dependency resolution bug where @optique/core dependency was not properly versioned, causing installations to use outdated stable versions instead of matching development versions. This resolves type errors and message formatting issues when using dev versions. [#22]
Version 0.3.1
Released on September 8, 2025.
@optique/run
- Fixed inconsistent error message coloring across JavaScript runtimes by replacing
console.error()andconsole.log()with directprocess.stderr.write()andprocess.stdout.write()calls. Previously, runtimes like Bun would displayconsole.error()output in red, causing ANSI reset codes in formatted option names to interrupt the error coloring. This change ensures consistent output formatting across all JavaScript runtimes. [#20]
Version 0.3.0
Released on August 29, 2025.
@optique/core
Added
flag()parser for creating required Boolean flags that must be explicitly provided. Unlikeoption()which defaults tofalsewhen not present,flag()fails parsing when not provided, making it useful for dependent options and conditional parsing scenarios.Extended
or()combinator to support up to 10 parsers (previously limited to 5), enabling more complex command-line interfaces with larger numbers of mutually exclusive subcommands or options.Enhanced
withDefault()to support union types when the default value is a different type from the parser result. The result type is nowT | TDefaultinstead of requiring the default to match the parser type. This enables patterns like conditional CLI structures with dependent options where different default structures are needed based on flag states.Modified
object()parser to use greedy parsing behavior. The parser now attempts to consume all matching fields in a single parse call, rather than returning after the first successful field match. This enables dependent options patterns where multiple related options need to be parsed together (e.g.,--flag --dependent-option). While this change maintains backward compatibility for most use cases, it may affect performance and parsing order in complex scenarios.Enhanced
merge()combinator type constraints to accept any parser that produces object-like values, not justobject()parsers. This enables combiningwithDefault(),map(), and other parsers that generate objects withmerge(). The combinator also now properly supports parsers with different state management strategies using specialized state handling to preserve the expected state format for each parser type.Modified
Parser.getDocFragments()method signature to useDocState<TState>discriminated union instead of direct state values. The new signature isgetDocFragments(state: DocState<TState>, ...args). This change improves type safety by explicitly modeling when parser state is available versus unavailable, fixing crashes in help generation when usingmerge()withor()combinations. This only affects advanced users who directly callgetDocFragments()or implement custom parsers.- Added
DocStatetype. - Changed the type of
Parser.getDocFragments()'s first parameter fromTStatetoDocState<TState>.
- Added
Added
longestMatch()combinator that selects the parser which consumes the most input tokens. Unlikeor()which returns the first successful match,longestMatch()tries all provided parsers and chooses the one with the longest match. This enables context-aware parsing where more specific patterns take precedence over general ones, making it ideal for implementing sophisticated help systems wherecommand --helpshows command-specific help rather than global help. The combinator supports function overloads for 2–5 parsers plus a variadic version, with full type inference for discriminated union results.Modified
run()function in@optique/core/facadeto uselongestMatch()instead ofor()for help parsing. This enables context-aware help behavior wheresubcommand --helpshows help specific to that command instead of global help. For example,myapp list --helpnow displays help for thelistcommand rather than the global application help. This change affects all help modes ("command","option", and"both"). Applications using therun()function will automatically benefit from improved help UX without code changes.Refactored
run()function help API to group related options together for better type safety. The new API prevents invalid combinations and provides a cleaner interface:typescriptrun(parser, args, { help: { mode: "both", // "command" | "option" | "both" onShow: process.exit, // Optional callback } });Added
versionfunctionality to therun()function, supporting both--versionoption andversioncommand modes:typescriptrun(parser, args, { version: { mode: "option", // "command" | "option" | "both" value: "1.0.0", // Version string to display onShow: process.exit, // Optional callback } });The
versionconfiguration follows the same pattern ashelp, with three modes:"option": Only--versionflag is available"command": Onlyversionsubcommand is available"both": Both--versionandversionsubcommand work
@optique/run
The
run()function now provides context-aware help behavior, automatically inheriting the improvements from@optique/core/facade. Applications using@optique/runwill see the same enhanced help system wheresubcommand --helpshows command-specific help instead of global help.Simplified help API by removing the
"none"option. Since disabling help can be achieved by simply omitting thehelpoption, the explicit"none"value is no longer needed:typescript// Old API run(parser, { help: "none" }); // Explicitly disable help run(parser, { help: "both" }); // Enable help // New API run(parser, {}); // Help disabled (omit the option) run(parser, { help: "both" }); // Enable help: "command" | "option" | "both"The help option now only accepts
"command" | "option" | "both". To disable help functionality, simply omit thehelpoption entirely.Added
versionfunctionality with a flexible API that supports both simple string and detailed object configurations:typescript// Simple version configuration (uses default "option" mode) run(parser, { version: "1.0.0" }); // Advanced version configuration run(parser, { version: { value: "1.0.0", mode: "both" // "command" | "option" | "both" } });The version functionality automatically calls
process.exit(0)when version information is requested, making it suitable for CLI applications that need to display version and exit.Added structured message output functions for CLI applications with automatic terminal detection and consistent formatting:
- Added
print()function for general output to stdout. - Added
printError()function for error output to stderr with automaticError:prefix and optional process exit. - Added
createPrinter()function for custom output scenarios with predefined formatting options. - Added
PrintOptionsandPrintErrorOptionsinterfaces for type-safe configuration. - Added
Printertype for custom printer functions.
All output functions automatically detect terminal capabilities (colors, width) and format structured messages consistently across different environments.
- Added
Version 0.2.1
Released on September 9, 2025.
@optique/run
- Fixed dependency resolution bug where @optique/core dependency was not properly versioned, causing installations to use outdated stable versions instead of matching development versions. This resolves type errors and message formatting issues when using dev versions. [#22]
Version 0.2.0
Released on August 22, 2025.
@optique/core
Added
concat()function for concatenating multipletuple()parsers into a single flattened tuple, similar to howmerge()works forobject()parsers. [#1]Fixed an infinite loop issue in the main parsing loop that could occur when parsers succeeded but didn't consume input.
Fixed bundled short options (e.g.,
-vdffor-v -d -f) not being parsed correctly in some cases.
Version 0.1.2
Released on September 9, 2025.
@optique/run
- Fixed dependency resolution bug where @optique/core dependency was not properly versioned, causing installations to use outdated stable versions instead of matching development versions. This resolves type errors and message formatting issues when using dev versions. [#22]
Version 0.1.1
Released on August 21, 2025.
@optique/core
- Fixed a bug where
object()parsers containing only Boolean flags would fail when no arguments were provided, instead of defaulting the flags tofalse. [#6]
Version 0.1.0
Released on August 21, 2025. Initial release.