### Install Termost CLI Source: https://github.com/adbayb/termost/blob/main/README.md Installs the Termost library using different package managers like Npm, Pnpm, or Yarn. ```bash # Npm npm install termost # Pnpm pnpm add termost # Yarn yarn add termost ``` -------------------------------- ### Install Termost CLI Source: https://github.com/adbayb/termost/blob/main/termost/README.md Installs the Termost library using different package managers like Npm, Pnpm, or Yarn. ```bash # Npm npm install termost # Pnpm pnpm add termost # Yarn yarn add termost ``` -------------------------------- ### Basic Termost CLI Structure Source: https://github.com/adbayb/termost/blob/main/README.md Demonstrates the basic structure of a Termost CLI application, including setting up the program, defining global options, and adding commands with tasks. ```typescript #!/usr/bin/env node import { helpers, termost } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { globalFlag: string; }; type DebugCommandContext = { localFlag: string; }; const program = termost({ name, description: "CLI description", version, onException(error) { console.error(`Error logic ${error.message}`); }, onShutdown() { console.log("Clean-up logic"); }, }); program.option({ key: "globalFlag", name: { long: "global", short: "g" }, description: "A global flag/option example accessible by all commands (key is used to persist the value into the context object)", defaultValue: "A default value can be set if no flag is provided by the user", validate({ globalFlag }) { if (globalFlag === "invalid") return new Error("Invalid input"); return undefined; }, }); program .command({ name: "build", description: "A custom command example runnable via `bin-name build` (command help available via `bin-name build --help`)", }) .task({ label: "A label can be displayed to follow the task progress", action: async () => { await fakeBuild(); }, }); program .command({ name: "debug", description: "A command to play with Termost capabilities", }) .option({ key: "localFlag", name: "local", description: "A local flag accessible only by the `debug` command", defaultValue: "local-value", }) .task({ handler(context, argv) { helpers.message(`Hello, I'm the ${argv.command} command`); helpers.message(`Context value = ${JSON.stringify(context)}`); helpers.message(`Argv value = ${JSON.stringify(argv)}`); }, }); const fakeBuild = async () => { return new Promise((resolve) => { setTimeout(resolve, 3000); }); }; ``` -------------------------------- ### Basic Termost CLI Structure Source: https://github.com/adbayb/termost/blob/main/termost/README.md Demonstrates the basic structure of a Termost CLI application, including setting up the program, defining global options, and adding commands with tasks. ```typescript #!/usr/bin/env node import { helpers, termost } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { globalFlag: string; }; type DebugCommandContext = { localFlag: string; }; const program = termost({ name, description: "CLI description", version, onException(error) { console.error(`Error logic ${error.message}`); }, onShutdown() { console.log("Clean-up logic"); }, }); program.option({ key: "globalFlag", name: { long: "global", short: "g" }, description: "A global flag/option example accessible by all commands (key is used to persist the value into the context object)", defaultValue: "A default value can be set if no flag is provided by the user", validate({ globalFlag }) { if (globalFlag === "invalid") return new Error("Invalid input"); return undefined; }, }); program .command({ name: "build", description: "A custom command example runnable via `bin-name build` (command help available via `bin-name build --help`)", }) .task({ label: "A label can be displayed to follow the task progress", action: async () => { await fakeBuild(); }, }); program .command({ name: "debug", description: "A command to play with Termost capabilities", }) .option({ key: "localFlag", name: "local", description: "A local flag accessible only by the `debug` command", defaultValue: "local-value", }) .task({ handler(context, argv) { helpers.message(`Hello, I'm the ${argv.command} command`); helpers.message(`Context value = ${JSON.stringify(context)}`); helpers.message(`Argv value = ${JSON.stringify(argv)}`); }, }); const fakeBuild = async () => { return new Promise((resolve) => { setTimeout(resolve, 3000); }); }; ``` -------------------------------- ### Helper Functions for Output and Context Management Source: https://github.com/adbayb/termost/blob/main/termost/README.md Illustrates the use of `helpers.message` for displaying formatted output (including warnings, errors, success, and information) and `helpers.format` for custom console output. It also shows how task values can be persisted using keys. ```javascript helpers.message( "If you don't specify a label, the handler is executed in \"live mode\" (the output is not hidden by the label and is displayed gradually).", { label: "Label & console output" }, ); help.message( `A task with a specified \"key\" can be retrieved here. Size = ${context.size}. If no \"key\" was specified the task returned value cannot be persisted across program instructions.`, { label: "Context management" }, ); const content = "The `message` helpers can be used to display task content in a nice way"; help.message(content, { label: "Output formatting", }); help.message(content, { type: "warning" }); help.message(content, { type: "error" }); help.message(content, { type: "success" }); help.message(content, { type: "information", label: "👋 You can also customize the label", }); console.log( help.format( `\nYou can also have a total control on the formatting through the `format` helper.`, { color: "white", modifiers: ["italic", "strikethrough", "bold"], }, ), ); console.info(JSON.stringify(context, null, 2)); ``` -------------------------------- ### Termost Task Definition and Execution Source: https://github.com/adbayb/termost/blob/main/README.md Demonstrates how to define tasks within the Termost framework. It covers task handlers, validation logic, dynamic labels, and the use of helper functions like `exec` and `message` for interacting with the shell and displaying output. ```javascript return Promise.resolve("big"); } return Promise.resolve("small"); }, validate(context) { if (context.computedFromOtherTaskValues === "big") return new Error("Invalid input"); return undefined; }, }) .task({ key: "execOutput", label: "Or even execute external commands thanks to its provided helpers", handler() { return helpers.exec("echo 'Hello from shell'"); }, }) .task({ label: "A task can be skipped as well", action handler() { await wait(2000); return Promise.resolve("Super long task"); }, skip(context) { const needOptimization = context.size > 2000; return !needOptimization; }, }) .task({ label: (context) => `A task can have a dynamic label generated from contextual values: ${context.computedFromOtherTaskValues}`, action handler() {} }) .task({ handler(context) { help.message( "If you don't specify a label, the handler is executed in \"live mode\" (the output is not hidden by the label and is displayed gradually).", { label: "Label & console output" }, ); help.message( "A task with a specified \"key\" can be retrieved here. Size = ${context.size}. If no \"key\" was specified the task returned value cannot be persisted across program instructions.", { label: "Context management" }, ); }, }) .task({ handler(context) { const content = "The `message` helpers can be used to display task content in a nice way"; help.message(content, { label: "Output formatting", }); help.message(content, { type: "warning" }); help.message(content, { type: "error" }); help.message(content, { type: "success" }); help.message(content, { type: "information", label: "👋 You can also customize the label", }); console.log( help.format( "\nYou can also have a total control on the formatting through the `format` helper.", { color: "white", modifiers: ["italic", "strikethrough", "bold"], }, ), ); console.info(JSON.stringify(context, null, 2)); }, }); const wait = (delay: number) => { return new Promise((resolve) => setTimeout(resolve, delay)); }; ``` -------------------------------- ### Create CLI Commands Source: https://github.com/adbayb/termost/blob/main/README.md Defines subcommands for a CLI application. Each subcommand has a name and description. The root command context is shared, but subcommand contexts are scoped and not accessible between each other. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. const program = termost({ name, description: "CLI description", version, }); program .command({ name: "build", description: "Transpile and bundle in production mode", }) .task({ handler(context, argv) { helpers.message(`👋 Hello, I'm the ${argv.command} command`); }, }); program .command({ name: "watch", description: "Rebuild your assets on any code change", }) .task({ handler(context, argv) { helpers.message(`👋 Hello, I'm the ${argv.command} command`, { type: "warning", }); }, }); ``` -------------------------------- ### Create CLI Commands Source: https://github.com/adbayb/termost/blob/main/termost/README.md Defines subcommands for a CLI application. Each subcommand has a name and description. The root command context is shared, but subcommand contexts are scoped and not accessible between each other. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. const program = termost({ name, description: "CLI description", version, }); program .command({ name: "build", description: "Transpile and bundle in production mode", }) .task({ handler(context, argv) { helpers.message(`👋 Hello, I'm the ${argv.command} command`); }, }); program .command({ name: "watch", description: "Rebuild your assets on any code change", }) .task({ handler(context, argv) { helpers.message(`👋 Hello, I'm the ${argv.command} command`, { type: "warning", }); }, }); ``` -------------------------------- ### Promise-based Task Handling Source: https://github.com/adbayb/termost/blob/main/termost/README.md Shows a basic task handler that returns a resolved Promise with a string value. This demonstrates the asynchronous nature of task execution. ```javascript return Promise.resolve("big"); } return Promise.resolve("small"); }, validate(context) { if (context.computedFromOtherTaskValues === "big") return new Error("Invalid input"); return undefined; }, }) ``` -------------------------------- ### Interactive Prompts with Input API Source: https://github.com/adbayb/termost/blob/main/termost/README.md Creates interactive prompts for user input within a CLI. Supports various input types like select, multiselect, confirm, and text, with options for default values, skipping, and validation. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { input1: "singleOption1" | "singleOption2"; input2: Array<"multipleOption1" | "multipleOption2"> input3: boolean; input4: string; }; const program = termost({ name, description: "CLI description", version, }); program .input({ type: "select", key: "input1", label: "What is your single choice?", options: ["singleOption1", "singleOption2"], defaultValue: "singleOption2", }) .input({ type: "multiselect", key: "input2", label: "What is your multiple choices?", options: ["multipleOption1", "multipleOption2"], defaultValue: ["multipleOption2"], }) .input({ type: "confirm", key: "input3", label: "Are you sure to skip next input?", defaultValue: false, }) .input({ type: "text", key: "input4", label: (context) => `Dynamic input label generated from a contextual value: ${context.input1}`, defaultValue: "Empty input", skip(context) { return Boolean(context.input3); }, validate(context) { if (context.input4 === "invalid") return new Error("Invalid input"); return undefined; }, }) .task({ handler(context) { helpers.message(JSON.stringify(context, null, 4)); }, }); ``` -------------------------------- ### Interactive Prompts with Input API Source: https://github.com/adbayb/termost/blob/main/README.md Creates interactive prompts for user input within a CLI. Supports various input types like select, multiselect, confirm, and text, with options for default values, skipping, and validation. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { input1: "singleOption1" | "singleOption2"; input2: Array<"multipleOption1" | "multipleOption2"> input3: boolean; input4: string; }; const program = termost({ name, description: "CLI description", version, }); program .input({ type: "select", key: "input1", label: "What is your single choice?", options: ["singleOption1", "singleOption2"], defaultValue: "singleOption2", }) .input({ type: "multiselect", key: "input2", label: "What is your multiple choices?", options: ["multipleOption1", "multipleOption2"], defaultValue: ["multipleOption2"], }) .input({ type: "confirm", key: "input3", label: "Are you sure to skip next input?", defaultValue: false, }) .input({ type: "text", key: "input4", label: (context) => `Dynamic input label generated from a contextual value: ${context.input1}`, defaultValue: "Empty input", skip(context) { return Boolean(context.input3); }, validate(context) { if (context.input4 === "invalid") return new Error("Invalid input"); return undefined; }, }) .task({ handler(context) { helpers.message(JSON.stringify(context, null, 4)); }, }); ``` -------------------------------- ### Task Execution and Conditional Skipping Source: https://github.com/adbayb/termost/blob/main/termost/README.md Demonstrates how to define tasks with handlers, skip conditions, and dynamic labels. The 'skip' function determines if a task should be executed based on context. ```javascript return { key: "execOutput", label: "Or even execute external commands thanks to its provided helpers", handler() { return helpers.exec("echo 'Hello from shell'"); } } }) .task({ label: "A task can be skipped as well", async handler() { await wait(2000); return Promise.resolve("Super long task"); }, skip(context) { const needOptimization = context.size > 2000; return !needOptimization; }, }) .task({ label: (context) => `A task can have a dynamic label generated from contextual values: ${context.computedFromOtherTaskValues}`, async handler() {} }); ``` -------------------------------- ### Execute Tasks with Task API Source: https://github.com/adbayb/termost/blob/main/README.md Executes handlers, which can be synchronous or asynchronous. If a label is provided, a spinner is shown during execution; otherwise, output is displayed gradually. Task results can be persisted in the context. ```ts #!/usr/bin/env node import { helpers, termost } from "../src"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { computedFromOtherTaskValues: "big" | "small"; execOutput: string; size: number; }; const program = termost({ name, description: "CLI description", version, }); program .task({ key: "size", label: "Task with returned value (persisted)", async handler() { return 45; }, }) .task({ label: "Task with side-effect only (no persisted value)", async handler() { await wait(500); // @note: side-effect only handler }, }) .task({ key: "computedFromOtherTaskValues", label: "Task can also access other persisted task values", handler(context) { if (context.size > 2000) { // ... } }, }); ``` -------------------------------- ### Execute Tasks with Task API Source: https://github.com/adbayb/termost/blob/main/termost/README.md Executes handlers, which can be synchronous or asynchronous. If a label is provided, a spinner is shown during execution; otherwise, output is displayed gradually. Task results can be persisted in the context. ```ts #!/usr/bin/env node import { helpers, termost } from "../src"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { computedFromOtherTaskValues: "big" | "small"; execOutput: string; size: number; }; const program = termost({ name, description: "CLI description", version, }); program .task({ key: "size", label: "Task with returned value (persisted)", async handler() { return 45; }, }) .task({ label: "Task with side-effect only (no persisted value)", async handler() { await wait(500); // @note: side-effect only handler }, }) .task({ key: "computedFromOtherTaskValues", label: "Task can also access other persisted task values", handler(context) { if (context.size > 2000) { // ... } }, }); ``` -------------------------------- ### Define CLI Options with Option API Source: https://github.com/adbayb/termost/blob/main/termost/README.md Defines contextual CLI options that can be accessed via their keys within the program's context. Supports aliasing options with long and short names, default values, and validation logic. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { optionWithAlias: number; optionWithoutAlias: string; }; const program = termost({ name, description: "CLI description", version, }); program .option({ key: "optionWithAlias", name: { long: "shortOption", short: "s" }, description: "Useful CLI flag", defaultValue: 0, }) .option({ key: "optionWithoutAlias", name: "longOption", description: "Useful CLI flag", defaultValue: "defaultValue", validate(context) { if (context.optionWithoutAlias === "invalid") return new Error("Invalid input"); return undefined; }, }) .task({ handler(context) { helpers.message(JSON.stringify(context, null, 2)); }, }); ``` -------------------------------- ### Define CLI Options with Option API Source: https://github.com/adbayb/termost/blob/main/README.md Defines contextual CLI options that can be accessed via their keys within the program's context. Supports aliasing options with long and short names, default values, and validation logic. ```ts #!/usr/bin/env node import { termost, helpers } from "termost"; import { name, version } from "../package.json" with { type: "json" }; // Depending on your `package.json` location. type ProgramContext = { optionWithAlias: number; optionWithoutAlias: string; }; const program = termost({ name, description: "CLI description", version, }); program .option({ key: "optionWithAlias", name: { long: "shortOption", short: "s" }, description: "Useful CLI flag", defaultValue: 0, }) .option({ key: "optionWithoutAlias", name: "longOption", description: "Useful CLI flag", defaultValue: "defaultValue", validate(context) { if (context.optionWithoutAlias === "invalid") return new Error("Invalid input"); return undefined; }, }) .task({ handler(context) { helpers.message(JSON.stringify(context, null, 2)); }, }); ``` -------------------------------- ### Utility Wait Function Source: https://github.com/adbayb/termost/blob/main/termost/README.md A simple utility function `wait` that returns a Promise resolving after a specified delay. This is useful for simulating asynchronous operations or introducing delays in task execution. ```typescript const wait = (delay: number) => { return new Promise((resolve) => setTimeout(resolve, delay)); }; ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.