CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-clack--core

Low-level primitives for building command-line interface applications with customizable prompt components.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

selection.mddocs/

Selection Prompts

Selection functionality for single and multiple choice scenarios from lists of options.

Capabilities

Select Prompt

Single selection from a list of options with keyboard navigation.

/**
 * Prompt for selecting a single option from a list
 * @template T - Type of option objects, must have a 'value' property
 */
class SelectPrompt<T extends { value: any }> extends Prompt<T['value']> {
  constructor(opts: SelectOptions<T>);
  
  /** Array of available options */
  options: T[];
  /** Current cursor position (index of highlighted option) */
  cursor: number;
}

/**
 * Configuration options for SelectPrompt
 * @template T - Type of option objects
 */
interface SelectOptions<T> extends PromptOptions<SelectPrompt<T>> {
  /** Array of options to choose from */
  options: T[];
  /** Initial value to select (matches option.value) */
  initialValue?: T['value'];
}

Usage Examples:

import { SelectPrompt, isCancel } from '@clack/core';

// Basic single selection
const colorPrompt = new SelectPrompt({
  render() {
    return `Choose a color:\n${this.options
      .map((option, i) => {
        const isSelected = i === this.cursor;
        const prefix = isSelected ? '→' : ' ';
        return `${prefix} ${option.label}`;
      })
      .join('\n')}`;
  },
  options: [
    { value: 'red', label: 'Red' },
    { value: 'green', label: 'Green' },
    { value: 'blue', label: 'Blue' }
  ]
});

const selectedColor = await colorPrompt.prompt();
if (isCancel(selectedColor)) {
  process.exit(0);
}

// Selection with initial value
const frameworkPrompt = new SelectPrompt({
  render() {
    return `Choose framework:\n${this.options
      .map((option, i) => {
        const isSelected = i === this.cursor;
        const prefix = isSelected ? '●' : '○';
        return `${prefix} ${option.label} - ${option.description}`;
      })
      .join('\n')}`;
  },
  options: [
    { value: 'react', label: 'React', description: 'A JavaScript library for building user interfaces' },
    { value: 'vue', label: 'Vue', description: 'The Progressive JavaScript Framework' },
    { value: 'svelte', label: 'Svelte', description: 'Cybernetically enhanced web apps' }
  ],
  initialValue: 'react'
});

const framework = await frameworkPrompt.prompt();

Multi-Select Prompt

Multiple selection from a list of options with individual item toggling.

/**
 * Prompt for selecting multiple options from a list
 * @template T - Type of option objects, must have a 'value' property
 */
class MultiSelectPrompt<T extends { value: any }> extends Prompt<T['value'][]> {
  constructor(opts: MultiSelectOptions<T>);
  
  /** Array of available options */
  options: T[];
  /** Current cursor position (index of highlighted option) */
  cursor: number;
}

/**
 * Configuration options for MultiSelectPrompt
 * @template T - Type of option objects
 */
interface MultiSelectOptions<T> extends PromptOptions<MultiSelectPrompt<T>> {
  /** Array of options to choose from */
  options: T[];
  /** Initial values to select (array of option.value) */
  initialValues?: T['value'][];
  /** Whether at least one selection is required */
  required?: boolean;
  /** Initial cursor position (option.value to start at) */
  cursorAt?: T['value'];
}

Usage Examples:

import { MultiSelectPrompt, isCancel } from '@clack/core';

// Basic multi-selection
const featuresPrompt = new MultiSelectPrompt({
  render() {
    return `Select features to install:\n${this.options
      .map((option, i) => {
        const isSelected = i === this.cursor;
        const isChecked = this.value?.includes(option.value);
        const cursor = isSelected ? '→' : ' ';
        const checkbox = isChecked ? '☑' : '☐';
        return `${cursor} ${checkbox} ${option.label}`;
      })
      .join('\n')}`;
  },
  options: [
    { value: 'typescript', label: 'TypeScript support' },
    { value: 'eslint', label: 'ESLint configuration' },
    { value: 'prettier', label: 'Prettier formatting' },
    { value: 'tests', label: 'Test setup' }
  ]
});

const selectedFeatures = await featuresPrompt.prompt();
if (isCancel(selectedFeatures)) {
  process.exit(0);
}

// Multi-selection with initial values and required selection
const toolsPrompt = new MultiSelectPrompt({
  render() {
    const selectedCount = this.value?.length || 0;
    return `Select development tools (${selectedCount} selected):\n${this.options
      .map((option, i) => {
        const isSelected = i === this.cursor;
        const isChecked = this.value?.includes(option.value);
        const cursor = isSelected ? '▶' : ' ';
        const checkbox = isChecked ? '✓' : ' ';
        return `${cursor} [${checkbox}] ${option.label}`;
      })
      .join('\n')}`;
  },
  options: [
    { value: 'webpack', label: 'Webpack bundler' },
    { value: 'vite', label: 'Vite build tool' },
    { value: 'rollup', label: 'Rollup bundler' }
  ],
  initialValues: ['vite'],
  required: true,
  cursorAt: 'vite'
});

const tools = await toolsPrompt.prompt();

Select Key Prompt

Selection by pressing specific keys assigned to each option.

/**
 * Prompt for selecting options by pressing assigned keys
 * @template T - Type of option objects, must have a 'value' property
 */
class SelectKeyPrompt<T extends { value: any }> extends Prompt<T['value']> {
  constructor(opts: SelectKeyOptions<T>);
  
  /** Array of available options */
  options: T[];
  /** Current cursor position (index of highlighted option) */
  cursor: number;
}

/**
 * Configuration options for SelectKeyPrompt
 * @template T - Type of option objects
 */
interface SelectKeyOptions<T> extends PromptOptions<SelectKeyPrompt<T>> {
  /** Array of options to choose from */
  options: T[];
}

Usage Examples:

import { SelectKeyPrompt, isCancel } from '@clack/core';

// Key-based selection
const actionPrompt = new SelectKeyPrompt({
  render() {
    return `Choose an action:\n${this.options
      .map((option) => `  [${option.key}] ${option.label}`)
      .join('\n')}\n\nPress a key...`;
  },
  options: [
    { value: 'create', label: 'Create new project', key: 'c' },
    { value: 'update', label: 'Update existing project', key: 'u' },
    { value: 'delete', label: 'Delete project', key: 'd' },
    { value: 'exit', label: 'Exit', key: 'x' }
  ]
});

const action = await actionPrompt.prompt();
if (isCancel(action)) {
  process.exit(0);
}

docs

advanced-selection.md

base-prompt.md

confirmation.md

index.md

selection.md

text-input.md

utilities.md

tile.json