Termost

A framework to build your next CLI application: Get the most of your termin...

README

💻 Termost


Get the most of your terminal

✨ Features


Termost allows building command line tools in a minute thanks to its:

Fluent syntax to express your CLI configurations with instructions such as:
Subcommand support
Long and short option support
User input support
Task support

Shareable output between instructions
Auto-generated help and version metadata
TypeScript support to foster a type-safe API
Built-in helpers to make stdin/stdout management a breeze (including exec, and message helpers...)

🚀 Quickstart


Install the library:

  1. ``` shell
  2. # Npm
  3. npm install termost
  4. # Pnpm
  5. pnpm add termost
  6. # Yarn
  7. yarn add termost
  8. ```

Once you're done, you can play with the API:

  1. ``` ts
  2. #!/usr/bin/env node

  3. import { helpers, termost } from "termost";

  4. type ProgramContext = {
  5. globalFlag: string;
  6. };

  7. type DebugCommandContext = {
  8. localFlag: string;
  9. };

  10. const program = termost<ProgramContext>("CLI example", {
  11. onException(error) {
  12.   console.error(`Error logic ${error.message}`);
  13. },
  14. onShutdown() {
  15.   console.log("Clean-up logic");
  16. },
  17. });

  18. program.option({
  19. key: "globalFlag",
  20. name: { long: "global", short: "g" },
  21. description:
  22.   "A global flag/option example accessible by all commands (key is used to persist the value into the context object)",
  23. defaultValue:
  24.   "A default value can be set if no flag is provided by the user",
  25. });

  26. program
  27. .command({
  28.   name: "build",
  29.   description:
  30.    "A custom command example runnable via `bin-name build` (command help available via `bin-name build --help`)",
  31. })
  32. .task({
  33.   label: "A label can be displayed to follow the task progress",
  34.   async handler() {
  35.    await fakeBuild();
  36.   },
  37. });

  38. program
  39. .command<DebugCommandContext>({
  40.   name: "debug",
  41.   description: "A command to play with Termost capabilities",
  42. })
  43. .option({
  44.   key: "localFlag",
  45.   name: "local",
  46.   description: "A local flag accessible only by the `debug` command",
  47.   defaultValue: "local-value",
  48. })
  49. .task({
  50.   handler(context, argv) {
  51.    helpers.message(`Hello, I'm the ${argv.command} command`);
  52.    helpers.message(`Context value = ${JSON.stringify(context)}`);
  53.    helpers.message(`Argv value = ${JSON.stringify(argv)}`);
  54.   },
  55. });

  56. const fakeBuild = async () => {
  57. return new Promise((resolve) => {
  58.   setTimeout(resolve, 3000);
  59. });
  60. };
  61. ```

Depending on the command, the output will look like this (bin-nameis the program name automatically retrieved from the package.json>name):

✍️ Usage


Here's an API overview:

command({ name, description })

The API creates a new subcommand context.Please note that the root command context is shared across subcommands but subcommand's contexts are scoped and not accessible between each other.

  1. ``` ts

  2. ```

input({ key, label, type, skip, ...typeParameters })

The API creates an interactive prompt.It supports several types:

  1. ``` ts

  2. ```

option({ key, name, description, defaultValue, skip })

The API defines a contextual CLI option.The option value can be accessed through its property from the current context.

  1. ``` ts

  2. ```

task({ key, label, handler, skip })

The executes a handler (either a synchronous or an asynchronous one).The output can be either:

Displayed gradually if no is provided
Displayed until the promise is fulfilled if a property is specified (in the meantime, a spinner with the label is showcased)

  1. ``` ts

  2. ```

🤩 Built with Termost


Quickbundle The zero-configuration bundler powered by ESBuild

💙 Acknowledgements


This project is built upon solid open-source foundations. We'd like to thank:

enquirer for managing inputinternals
listr2 for managing taskinternals

📖 License


MIT