or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

advanced-workflows.mdcancellation-handling.mdindex.mdinteractive-prompts.mdlogging-system.mdprogress-indicators.mdselection-prompts.mdsession-management.mdsettings-configuration.md
tile.json

selection-prompts.mddocs/

Selection Prompts

Menu-driven selection components for choosing from predefined options with keyboard navigation, hints, and grouping support.

Capabilities

Single Selection

Choose one option from a list with keyboard navigation and optional hints.

/**
 * Creates a selection prompt for choosing one option from a list
 * @param opts - Configuration options for the selection prompt
 * @returns Promise resolving to selected value or cancellation symbol
 */
function select<Value>(opts: SelectOptions<Value>): Promise<Value | symbol>;

interface SelectOptions<Value> {
  /** The prompt message displayed to the user */
  message: string;
  /** Array of options to choose from */
  options: Option<Value>[];
  /** Initial selected value */
  initialValue?: Value;
  /** Maximum number of items to display at once (defaults to terminal height) */
  maxItems?: number;
}

type Option<Value> = Value extends Primitive
  ? {
      /** Internal data for this option */
      value: Value;
      /** The optional, user-facing text for this option (defaults to string conversion of value) */
      label?: string;
      /** Optional hint displayed when this option might be selected */
      hint?: string;
    }
  : {
      /** Internal data for this option */
      value: Value;
      /** Required user-facing text for this option */
      label: string;
      /** Optional hint displayed when this option might be selected */
      hint?: string;
    };

type Primitive = Readonly<string | boolean | number>;

Usage Examples:

import { select, isCancel, cancel } from "@clack/prompts";

// Basic selection with string values
const framework = await select({
  message: "Pick a framework:",
  options: [
    { value: "react", label: "React" },
    { value: "vue", label: "Vue" },
    { value: "svelte", label: "Svelte" },
  ],
});

if (isCancel(framework)) {
  cancel("Operation cancelled");
  process.exit(0);
}

// Selection with hints and initial value
const deployment = await select({
  message: "Choose deployment target:",
  initialValue: "vercel",
  options: [
    { value: "vercel", label: "Vercel", hint: "recommended" },
    { value: "netlify", label: "Netlify" },
    { value: "aws", label: "AWS", hint: "advanced" },
    { value: "self", label: "Self-hosted", hint: "requires setup" },
  ],
});

// Selection with complex values
const config = await select({
  message: "Choose configuration:",
  options: [
    {
      value: { env: "development", debug: true },
      label: "Development",
      hint: "with debug enabled"
    },
    {
      value: { env: "production", debug: false },
      label: "Production",
      hint: "optimized build"
    },
  ],
});

Keyboard-Driven Selection

Select options using keyboard shortcuts for faster interaction.

/**
 * Creates a keyboard-driven selection prompt using key shortcuts
 * @param opts - Configuration options for the key selection prompt
 * @returns Promise resolving to selected value or cancellation symbol
 */
function selectKey<Value extends string>(opts: SelectOptions<Value>): Promise<Value | symbol>;

Usage Examples:

import { selectKey, isCancel, cancel } from "@clack/prompts";

// Quick selection using keyboard shortcuts
const action = await selectKey({
  message: "What would you like to do?",
  options: [
    { value: "c", label: "Create new project" },
    { value: "i", label: "Install dependencies" },
    { value: "b", label: "Build project" },
    { value: "t", label: "Run tests" },
  ],
});

if (isCancel(action)) {
  cancel("Operation cancelled");
  process.exit(0);
}

// User can press 'c', 'i', 'b', or 't' to select
console.log(`Selected action: ${action}`);

Multiple Selection

Choose multiple options from a list with checkbox-style interface.

/**
 * Creates a multi-selection prompt for choosing multiple options
 * @param opts - Configuration options for the multi-selection prompt
 * @returns Promise resolving to array of selected values or cancellation symbol
 */
function multiselect<Value>(opts: MultiSelectOptions<Value>): Promise<Value[] | symbol>;

interface MultiSelectOptions<Value> {
  /** The prompt message displayed to the user */
  message: string;
  /** Array of options to choose from */
  options: Option<Value>[];
  /** Array of initially selected values */
  initialValues?: Value[];
  /** Maximum number of items to display at once */
  maxItems?: number;
  /** Whether at least one selection is required (defaults to true) */
  required?: boolean;
  /** Value to position cursor at initially */
  cursorAt?: Value;
}

Usage Examples:

import { multiselect, isCancel, cancel } from "@clack/prompts";

// Basic multi-selection
const tools = await multiselect({
  message: "Select development tools:",
  options: [
    { value: "eslint", label: "ESLint", hint: "code linting" },
    { value: "prettier", label: "Prettier", hint: "code formatting" },
    { value: "jest", label: "Jest", hint: "testing framework" },
    { value: "typescript", label: "TypeScript", hint: "type checking" },
  ],
});

if (isCancel(tools)) {
  cancel("Operation cancelled");
  process.exit(0);
}

console.log(`Selected tools: ${tools.join(", ")}`);

// Multi-selection with initial values and optional selection
const features = await multiselect({
  message: "Choose optional features:",
  required: false,
  initialValues: ["auth"],
  options: [
    { value: "auth", label: "Authentication" },
    { value: "db", label: "Database integration" },
    { value: "api", label: "REST API" },
    { value: "docs", label: "Documentation" },
  ],
});

Grouped Multiple Selection

Choose multiple options from categorized groups with optional group selection.

/**
 * Creates a grouped multi-selection prompt with categorized options
 * @param opts - Configuration options for the grouped multi-selection prompt
 * @returns Promise resolving to array of selected values or cancellation symbol
 */
function groupMultiselect<Value>(opts: GroupMultiSelectOptions<Value>): Promise<Value[] | symbol>;

interface GroupMultiSelectOptions<Value> {
  /** The prompt message displayed to the user */
  message: string;
  /** Object with group names as keys and option arrays as values */
  options: Record<string, Option<Value>[]>;
  /** Array of initially selected values */
  initialValues?: Value[];
  /** Whether at least one selection is required (defaults to true) */
  required?: boolean;
  /** Value to position cursor at initially */
  cursorAt?: Value;
  /** Whether group headers can be selected to toggle all items in group (defaults to true) */
  selectableGroups?: boolean;
}

Usage Examples:

import { groupMultiselect, isCancel, cancel } from "@clack/prompts";

// Grouped selection with categories
const packages = await groupMultiselect({
  message: "Select packages to install:",
  options: {
    "Frontend": [
      { value: "react", label: "React" },
      { value: "vue", label: "Vue" },
      { value: "svelte", label: "Svelte" },
    ],
    "Build Tools": [
      { value: "webpack", label: "Webpack" },
      { value: "vite", label: "Vite", hint: "recommended" },
      { value: "rollup", label: "Rollup" },
    ],
    "Testing": [
      { value: "jest", label: "Jest" },
      { value: "vitest", label: "Vitest" },
      { value: "cypress", label: "Cypress" },
    ],
  },
});

if (isCancel(packages)) {
  cancel("Operation cancelled");
  process.exit(0);
}

// Group selection without selectable groups
const permissions = await groupMultiselect({
  message: "Grant permissions:",
  selectableGroups: false,
  options: {
    "Read Access": [
      { value: "read-files", label: "Read files" },
      { value: "read-config", label: "Read configuration" },
    ],
    "Write Access": [
      { value: "write-files", label: "Write files" },
      { value: "write-config", label: "Modify configuration" },
    ],
  },
});

Navigation

All selection prompts support consistent keyboard navigation:

  • Arrow Keys: Navigate up/down through options
  • Enter: Select current option (single select) or confirm selection (multi-select)
  • Space: Toggle selection (multi-select only)
  • Ctrl+C: Cancel the prompt

For selectKey, users can press the key corresponding to the option's value for instant selection.

Scrolling

When there are more options than can fit on screen, the prompts automatically handle scrolling:

  • Use maxItems to control how many options are visible at once
  • Options above/below the visible area are indicated with "..." ellipsis
  • Navigation automatically scrolls to reveal more options

Option Types

Options can contain different value types:

// Primitive values (string, number, boolean) have optional labels
const stringOptions: Option<string>[] = [
  { value: "react", label: "React Framework" },
  { value: "vue" }, // label defaults to "vue"
];

// Complex values require explicit labels
interface ProjectConfig {
  framework: string;
  typescript: boolean;
}

const objectOptions: Option<ProjectConfig>[] = [
  {
    value: { framework: "react", typescript: true },
    label: "React with TypeScript",
    hint: "recommended setup"
  },
];