cliweave 0.1.0 copy "cliweave: ^0.1.0" to clipboard
cliweave: ^0.1.0 copied to clipboard

A typed CLI framework: command routing, argument scanning with kebab/camel aliasing, did-you-mean suggestions, rendered help, structured exit codes, shell-completion proposals, and a terminal logger, [...]

cliweave #

A typed CLI framework for Dart: command routing, argument scanning, rendered help, structured exit codes, and shell-completion proposals — plus a terminal logger, spinner, and colour theme.

Status: 0.x. The API is in production use but can still change before 1.0. Dotweave is its first consumer.

Why not package:args? #

package:args is the right choice for most Dart CLIs. Reach for this one only if you need what it does not provide:

  • Completion, end to end, for four shells. proposeCompletions computes the candidate list for any partial command line — including per-argument dynamic values (file paths, remote names) from your own callback — and CompletionScripts generates the bash, zsh, fish, and PowerShell scripts that call back into it. package:args has no completion API; cli_completion adds one for bash and zsh only.
  • Full control of help layout. Help is rendered by this package rather than a private class, so USAGE / FLAGS / ARGUMENTS / COMMANDS sections, column alignment, and the --flag/--no-flag presentation are all part of the contract you can pin in tests.
  • kebab⇄camelCase aliasing. --dry-run and --dryRun both bind to a dryRun flag, without per-option alias lists.
  • Structured exit codes. Distinct negative codes for unknown command, invalid argument, and command-load failure, plus a hook to derive an exit code from a thrown error.

Libraries #

import 'package:cliweave/cliweave.dart'; // commands, flags, help, completion
import 'package:cliweave/terminal.dart'; // logger, spinner, colour theme

They are separate so that a consumer who only needs argument parsing does not pull in the terminal layer.

Example #

See example/main.dart for a runnable two-command app. The shape is:

final greetCommand = buildCommand(
  docs: const CommandDocs(brief: 'Greet someone'),
  parameters: const CommandParameters(
    flags: {'loud': BooleanFlag(brief: 'Shout the greeting', optional: true)},
    positional: TuplePositionalParameters([
      PositionalParameter(
        brief: 'Who to greet',
        parse: stringParser,
        placeholder: 'name',
      ),
    ]),
  ),
  func: (context, flags, positional) {
    final greeting = 'Hello, ${positional[0]}!';

    context.process.stdout.write(
      '${flags['loud'] == true ? greeting.toUpperCase() : greeting}\n',
    );

    return null;
  },
);
$ dart run example/main.dart greet --loud world
HELLO, WORLD!

$ dart run example/main.dart gret world
No command registered for `gret`, did you mean `greet`?

$ dart run example/main.dart --help
USAGE
  example greet [--loud] <name>
  example --help

Example CLI

FLAGS
  -h --help  Print help information and exit

COMMANDS
  greet  Greet someone

Shell completion #

Register a hidden route that answers with one completion<TAB>description line per candidate, then print the matching script from a user-facing command:

final scripts = CompletionScripts(executableName: 'example');

// Inside the hidden `__complete` command:
final candidates = await proposeCompletions(
  app,
  scripts.resolveCompletionInputs(positional.cast<String>()),
  context,
);

// Inside `example completion zsh`:
context.process.stdout.write(scripts.zsh);

resolveCompletionInputs normalizes what the shell passed: it prefers COMP_LINE when set (which preserves a trailing space, meaning "start a new word") and drops a leading executable token. Shell function names are derived from the executable with illegal characters replaced, so my-cli produces __my_cli_complete rather than an unparseable __my-cli_complete.

Environment access #

Anywhere this package consults the environment (NO_COLOR, FORCE_COLOR, CI, TERM, STRICLI_NO_COLOR) it takes an EnvLookup — a String? Function(String name) — defaulting to lookupPlatformEnv, which reads Platform.environment with a case-insensitive fallback on Windows. Pass your own to read from a validated wrapper, a config overlay, or a test double.

Origin #

This is a Dart implementation of the design introduced by Bloomberg's TypeScript @stricli/core: its command model, help layout, scanner error messages, and completion approach were the reference. It is an independent project, not a binding, and is not affiliated with or endorsed by Bloomberg.

0
likes
0
points
885
downloads

Publisher

verified publishertinyrack.net

Weekly Downloads

A typed CLI framework: command routing, argument scanning with kebab/camel aliasing, did-you-mean suggestions, rendered help, structured exit codes, shell-completion proposals, and a terminal logger, spinner, and colour theme.

Repository (GitHub)
View/report issues

Topics

#cli #command-line #argument-parser #shell-completion

License

unknown (license)

More

Packages that depend on cliweave