--- title: Terminal Interface description: Terminal UI, styling, and interactive prompts available in Bunmagic scripts. --- Bunmagic provides utilities for creating interactive command-line interfaces, making your scripts more user-friendly and dynamic. ## Interactive Prompts ### ack() **Usage:** `ack(question: string, defaultOption?: 'y' | 'n'): boolean` Asks a Yes/No question and waits for user input synchronously. **Parameters:** - `question` - The question text to display - `defaultOption` - Optional default selection ('y' or 'n') **Returns:** - `true` for Yes or `false` for No **Examples:** ```ts // Basic confirmation const proceed = ack("Continue with installation?") if (proceed) { console.log("Installing...") } else { console.log("Cancelled") } // With default option const overwrite = ack("Overwrite existing file?", "n") // Default to no if (overwrite) { await $`rm -f ./file.txt` } // In a workflow if (ack("Add remote origin?", "y")) { const remote = await input("Enter remote URL:") await $`git remote add origin ${remote}` } ``` ### ask() **Usage:** `ask(question: string, defaultValue?: string): Promise` Prompts the user for text input. **Parameters:** - `question` - The prompt text to display - `defaultValue` - Optional default value to use if user provides no input **Returns:** - Promise resolving to the user's input string **Examples:** ```ts // Basic text input const name = await ask("What is your name?") console.log(`Hello, ${name}!`) // With default value const branch = await ask("Branch name:", "main") await $`git checkout -b ${branch}` // Using the input in a command const commitMsg = await ask("Commit message:") await $`git commit -m ${commitMsg}` ``` ### getPassword() **Usage:** `getPassword(prompt?: string): Promise` Securely prompts the user for a password with masked input. **Parameters:** - `prompt` - The prompt text to display (default: "Password:") **Returns:** - Promise resolving to the entered password **Examples:** ```ts // Basic password input const password = await getPassword() // Custom prompt const apiKey = await getPassword("Enter API key:") // Authentication flow const username = await ask("Username:") const password = await getPassword("Password:") const success = await authenticate(username, password) ``` ### select() **Usage:** `select(question: string, options: string[]): Promise` Displays an interactive selection menu and returns the selected option. **Parameters:** - `question` - The prompt text to display - `options` - Array of string options to choose from **Returns:** - Promise resolving to the selected option string **Examples:** ```ts // Basic selection const options = ["typescript", "javascript", "python"] const language = await select("Choose a language:", options) console.log(`Selected ${language}`) // Dynamic options const branches = (await $`git branch`.text()).split("\n") .map(b => b.trim().replace("* ", "")) .filter(Boolean) const branch = await select("Choose a branch to checkout:", branches) await $`git checkout ${branch}` // With conditional logic const action = await select("What would you like to do?", [ "Create new project", "Open existing project", "Exit" ]) switch (action) { case "Create new project": // Handle creation break case "Open existing project": // Handle opening break default: // Exit } ``` ### autoselect() **Usage:** `autoselect(message: string, options: T[], flag: string): Promise` Displays an interactive selection menu with auto-complete functionality. If the specified flag is set via command-line arguments, that value is returned instead of prompting the user. **Parameters:** - `message` - The prompt text to display - `options` - Array of string options to choose from - `flag` - Command-line flag name to check for override value **Returns:** - Promise resolving to the selected option string **Examples:** ```ts // Basic auto-complete selection const commands = ["install", "update", "remove", "list", "help"] const action = await autoselect("What would you like to do?", commands, "action") // With dynamic options const files = await glob("**/*.ts") const fileToEdit = await autoselect("Select file to edit:", files, "file") await openEditor(fileToEdit) // Using auto-complete for long lists const countries = ["Afghanistan", "Albania", "Algeria", /* ... */] const country = await autoselect("Select your country:", countries, "country") // Flag override example - if --action=install is passed, skips selection const action = await autoselect("Choose action:", ["install", "remove"], "action") // Returns "install" without prompting if --action=install was provided ``` ## Progress Indicators ### $spinner **Usage:** - `$spinner(label: string, callback: ($: typeof $, setLabel: (text: string) => void) => Promise): Promise` - `$spinner(callback: ($: typeof $, setLabel: (text: string) => void) => Promise): Promise` Executes operations within a spinner context. The spinner automatically starts before the callback and stops after completion. Commands executed with the provided `$` are quieted unless debug mode is enabled. **Parameters:** - `label` - Optional text to display next to the spinner - `callback` - Async function to execute. Receives a quieted `$` command and `setLabel` function **Returns:** - Promise resolving to the callback's return value **Examples:** ```ts // Basic usage with label const result = await $spinner("Loading data...", async ($, setLabel) => { const data = await $`curl -s https://api.example.com/data`.json() return data }) // Without label const files = await $spinner(async ($, setLabel) => { return await $`find . -name "*.ts"`.lines() }) // Updating the label during execution await $spinner("Processing...", async ($, setLabel) => { setLabel("Downloading dependencies...") await $`npm install` setLabel("Running tests...") await $`npm test` setLabel("Building project...") await $`npm run build` }) // Error handling (spinner automatically shows error state) try { await $spinner("Deploying...", async ($, setLabel) => { await $`deploy.sh` }) console.log(ansis.green("Deployment successful!")) } catch (error) { console.error(ansis.red(`Deployment failed: ${error.message}`)) } ``` ## Terminal Styling Bunmagic includes [ansis](https://www.npmjs.com/package/ansis) as a global utility for terminal text styling. The `chalk` alias is also available for backwards compatibility. **Usage:** `ansis.