modular_cli_sdk 0.3.2
modular_cli_sdk: ^0.3.2 copied to clipboard
Command-centric SDK for building modular CLIs with Dart — Command/Input/Output contract, structured errors, output formatting, and automatic TTY detection. Built on cli_router.
Changelog #
All notable changes to this project will be documented in this file.
The format loosely follows Keep a Changelog and the project adheres to Semantic Versioning.
0.3.2 #
Fixed #
- A command can now declare that it accepts no options, and be enforced.
paramsdefaulted toconst [], so declaring an empty contract was the same value as declaring none: a zero-argument command was indistinguishable from an undeclared one and its arguments went unchecked —init --host fooran, silently doing nothing the flag implied.paramsis now nullable (null= declares nothing, unenforced, as before;[]= declares no options, and any option is rejected)
Changed #
ModularCli.command/ModuleBuilder.commandtakeList<CliParam>? params(wasList<CliParam> params = const []). Source-compatible: omittingparamsbehaves exactly as beforeCommandContract.paramsisList<CliParam>?, withisDeclaredanddeclaredParamsfor the two readings
0.3.1 #
Fixed #
- A registered root route owns the empty invocation.
ModularClirewrote bare<cli>intohelpunconditionally, on the assumption that no route can serve the empty invocation. A CLI that registers one — a dashboard, a status screen, a banner — had that command silently replaced by the help. The rewrite now applies only when nothing claims the empty route; a CLI without a root route is unaffected - The help listing names the root route. Having no token to type, it rendered as a description hanging off a blank column. It is now listed as
(no arguments)— the only way it can be invoked
Added #
- The example registers a root command, so the bare invocation is exercised. Its absence is why no test could see either defect above
0.3.0 #
Added #
- Command contract —
CliParamdeclares a command's parameters (kind, type, short alias, required, default, allowed values) on itsInput, andcommand(...)accepts them viaparams:(#7) - Native help —
help, no arguments,--helpand-hprint the command list to stdout with exit 0. Unknown or invalid usage stays on stderr with exit 64. Ahelpcommand registered by the developer overrides the built-in one - Focused help —
<command> --helprenders that command's contract;<module> --helprenders every command in the module help --json— the full contract catalog as JSON (help.json), the machine twin of the text help, through the existingJsonCliOutput- Enforcement — the declaration governs parsing: aliases resolved, declared defaults applied, values coerced to their declared type, undeclared options and values outside
allowedrejected with exit 7. A rejected invocation is answered with the contract it failed to honour
Changed #
Input.schemaFieldsis now typedList<CliParam>?(wasList<dynamic>?, documented as reserved)- Requires
cli_router: ^0.1.0, which adds theonNotFoundhook the SDK uses to render its own catalog on the error path, and route metadata for positionals
Notes #
- Commands that declare no
paramsbehave exactly as before: not described in help, not enforced
0.2.1 #
0.2.0 #
Added #
ModularCli.command<I, O>()— register root-level commands without a module prefix- Root commands reuse the full
Command<I, O>lifecycle (validate → execute → format) - Root commands honor
--json,--quiet,CommandException, and semantic exit codes - Example
versionroot command inexample/commands/version.dart - 4 new integration tests for root commands
0.1.0 #
Added #
ModularCli— entry point that orchestrates modules, global flags, and TTY detectionModuleBuilder— per-module command registration viacommand()Command<I, O>— abstract unit of work withvalidate()andexecute()lifecycleInput— abstract inbound DTO (deserialize fromCliRequestflags/params)Output— abstract outbound DTO withtoJson()andexitCodeCommandException— structured error withcode,message,details,isRetryableExitCode— semantic exit code constants (0, 1, 2, 4, 5, 6, 7, 64)CliOutput/JsonCliOutput/TextCliOutput— output formatting abstraction--jsonglobal flag — machine-readable JSON output--quiet/-qglobal flag — suppress informational messages- Working example with two modules (greetings + math)
- Full test suite (unit + integration)