clack-guidelines

Comprehensive guide for building beautiful interactive command-line interfaces using Clack. Use when creating CLI tools with text input, selections, autocomplete, progress tracking, and streaming output.

16 stars

Best use case

clack-guidelines is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Comprehensive guide for building beautiful interactive command-line interfaces using Clack. Use when creating CLI tools with text input, selections, autocomplete, progress tracking, and streaming output.

Teams using clack-guidelines should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/clack-guidelines/SKILL.md --create-dirs "https://raw.githubusercontent.com/diegosouzapw/awesome-omni-skill/main/skills/tools/clack-guidelines/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/clack-guidelines/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How clack-guidelines Compares

Feature / Agentclack-guidelinesStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Comprehensive guide for building beautiful interactive command-line interfaces using Clack. Use when creating CLI tools with text input, selections, autocomplete, progress tracking, and streaming output.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Clack Guidelines

## Overview

This skill provides guidance for building beautiful interactive command-line interfaces using Clack. It covers common patterns for text input, selections, autocomplete, progress tracking, streaming output, and creating complete interactive CLI applications.

## Quick Start

### Installation

```bash
npm install @clack/prompts
```

### Basic Program

```javascript
import { text, isCancel, cancel } from "@clack/prompts";

const projectPath = await text({
  message: "Where should we create your project?",
  placeholder: "./my-awesome-project",
  initialValue: "./sparkling-solid",
  validate: (value) => {
    if (!value) return "Please enter a path.";
    if (value[0] !== ".") return "Please enter a relative path.";
  },
});

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

console.log(`Creating project at: ${projectPath}`);
```

### Complete Interactive CLI

```javascript
import * as p from "@clack/prompts";
import color from "picocolors";

async function createApp() {
  console.clear();
  p.intro(color.bgCyan(color.black(" create-myapp ")));

  const config = await p.group(
    {
      name: () =>
        p.text({
          message: "What is your project name?",
          placeholder: "my-awesome-app",
          validate: (value) => {
            if (!value) return "Project name is required";
          },
        }),

      framework: () =>
        p.select({
          message: "Choose your framework",
          options: [
            { value: "react", label: "React", hint: "Popular" },
            { value: "vue", label: "Vue" },
            { value: "svelte", label: "Svelte" },
          ],
        }),

      typescript: () =>
        p.confirm({
          message: "Use TypeScript?",
          initialValue: true,
        }),
    },
    {
      onCancel: () => {
        p.cancel("Setup cancelled");
        process.exit(0);
      },
    },
  );

  console.log(config);
}

createApp().catch(console.error);
```

## Common Patterns

### Text Input

Single-line text input with validation and placeholders.

```javascript
import { text } from "@clack/prompts";

const name = await text({
  message: "Enter your name",
  placeholder: "John Doe",
  validate: (value) => {
    if (!value) return "Name is required";
  },
});
```

### Password Input

Secure password input with masking.

```javascript
import { password } from "@clack/prompts";

const userPassword = await password({
  message: "Provide a password",
  mask: "•",
  validate: (value) => {
    if (!value) return "Please enter a password.";
    if (value.length < 8) return "Password should have at least 8 characters.";
  },
});
```

### Autocomplete Single Selection

Type-ahead search with real-time filtering.

```javascript
import { autocomplete } from "@clack/prompts";

const country = await autocomplete({
  message: "Select a country",
  options: [
    { value: "us", label: "United States", hint: "NA" },
    { value: "ca", label: "Canada", hint: "NA" },
    { value: "uk", label: "United Kingdom", hint: "EU" },
  ],
  placeholder: "Type to search countries...",
  maxItems: 8,
  initialValue: "us",
});
```

### Autocomplete Multi-Select

Type-ahead search with multi-selection.

```javascript
import { autocompleteMultiselect } from "@clack/prompts";

const frameworks = await autocompleteMultiselect({
  message: "Select frameworks (type to filter)",
  options: [
    { value: "react", label: "React", hint: "Frontend/UI" },
    { value: "vue", label: "Vue.js", hint: "Frontend/UI" },
    { value: "nextjs", label: "Next.js", hint: "React Framework" },
  ],
  placeholder: "Type to filter...",
  maxItems: 8,
  initialValues: ["react", "nextjs"],
  required: true,
});
```

### Single Selection Menu

Choose one option from a scrollable list.

```javascript
import { select } from "@clack/prompts";

const projectType = await select({
  message: "Pick a project type",
  initialValue: "ts",
  maxItems: 5,
  options: [
    { value: "ts", label: "TypeScript" },
    { value: "js", label: "JavaScript" },
    { value: "rust", label: "Rust" },
    { value: "go", label: "Go" },
  ],
});
```

### Multi-Select Menu

Select multiple options from a list.

```javascript
import { multiselect } from "@clack/prompts";

const tools = await multiselect({
  message: "Select additional tools",
  initialValues: ["prettier", "eslint"],
  required: true,
  options: [
    { value: "prettier", label: "Prettier", hint: "recommended" },
    { value: "eslint", label: "ESLint", hint: "recommended" },
    { value: "stylelint", label: "Stylelint" },
  ],
});
```

### Confirmation Dialog

Binary yes/no choice.

```javascript
import { confirm } from "@clack/prompts";

const shouldInstallDeps = await confirm({
  message: "Install dependencies?",
  active: "Yes, please",
  inactive: "No, skip",
  initialValue: false,
});
```

### Progress Bar

Visual progress indicator for long-running operations.

```javascript
import { progress } from "@clack/prompts";
import { setTimeout } from "node:timers/promises";

const downloadProgress = progress({
  style: "block",
  max: 100,
  size: 40,
});

downloadProgress.start("Downloading packages");

for (let i = 0; i < 100; i += 10) {
  await setTimeout(500);
  downloadProgress.advance(10);
  downloadProgress.message(`Downloaded ${i + 10}%`);
}

downloadProgress.stop("Download complete!");
```

### Spinner Loading Indicator

Display progress for long-running operations.

```javascript
import { spinner } from "@clack/prompts";
import { setTimeout } from "node:timers/promises";

const s = spinner();

s.start("Installing packages via pnpm");
await setTimeout(2000);

s.message("Downloading dependencies");
await setTimeout(1500);

s.stop("Installation complete!");
```

### Task Log with Live Output

Display streaming output that clears on success and persists on error.

```javascript
import { taskLog } from "@clack/prompts";
import { spawn } from "node:child_process";

const log = taskLog({
  title: "Running npm install",
  limit: 10,
  retainLog: true,
  spacing: 1,
});

const npmInstall = spawn("npm", ["install"]);

npmInstall.stdout.on("data", (data) => {
  log.message(data.toString(), { raw: true });
});

npmInstall.on("close", (code) => {
  if (code === 0) {
    log.success("Installation complete!");
  } else {
    log.error("Installation failed!", { showLog: true });
  }
});
```

### Streaming Output for LLMs

Stream dynamic content from async iterables.

```javascript
import { stream } from "@clack/prompts";
import { setTimeout } from "node:timers/promises";

await stream.step(
  (async function* () {
    const words = "Building your application with modern tools".split(" ");
    for (const word of words) {
      yield word;
      yield " ";
      await setTimeout(100);
    }
  })(),
);
```

### Grouped Prompts with Sequential Execution

Execute multiple prompts in sequence with shared state.

```javascript
import * as p from "@clack/prompts";
import color from "picocolors";

p.intro(color.bgCyan(color.black(" create-app ")));

const project = await p.group(
  {
    path: () =>
      p.text({
        message: "Where should we create your project?",
        placeholder: "./sparkling-solid",
        validate: (value) => {
          if (!value) return "Please enter a path.";
          if (value[0] !== ".") return "Please enter a relative path.";
        },
      }),

    type: ({ results }) =>
      p.select({
        message: `Pick a project type within "${results.path}"`,
        initialValue: "ts",
        options: [
          { value: "ts", label: "TypeScript" },
          { value: "js", label: "JavaScript" },
          { value: "rust", label: "Rust" },
        ],
      }),

    tools: () =>
      p.multiselect({
        message: "Select additional tools",
        options: [
          { value: "prettier", label: "Prettier", hint: "recommended" },
          { value: "eslint", label: "ESLint", hint: "recommended" },
        ],
      }),

    install: () =>
      p.confirm({
        message: "Install dependencies?",
        initialValue: true,
      }),
  },
  {
    onCancel: () => {
      p.cancel("Operation cancelled.");
      process.exit(0);
    },
  },
);

console.log(project.path, project.type, project.tools, project.install);
```

### Task Execution with Spinners

Run multiple tasks with automatic spinner management.

```javascript
import * as p from "@clack/prompts";
import { setTimeout } from "node:timers/promises";

await p.tasks([
  {
    title: "Installing dependencies",
    task: async (message) => {
      message("Downloading packages");
      await setTimeout(1000);
      message("Building native modules");
      await setTimeout(500);
      return "Installed 127 packages";
    },
  },
  {
    title: "Running linter",
    task: async () => {
      // Run linter
      return "No issues found";
    },
  },
]);
```

### Logging Messages

Display formatted status messages with different severity levels.

```javascript
import { log } from "@clack/prompts";
import color from "picocolors";

log.info("Starting build process...");
log.step("Compiling TypeScript");
log.success("Build completed successfully!");
log.warn("Some dependencies are outdated");
log.error("Failed to connect to database");

// Custom symbol
log.message("Custom message", {
  symbol: color.cyan("→"),
});
```

### Intro, Outro, and Notes

Frame your CLI sessions with beautiful headers.

```javascript
import { intro, outro, note } from "@clack/prompts";
import color from "picocolors";

intro(color.bgCyan(color.black(" my-cli-tool v2.0.0 ")));

// ... prompts and operations ...

note("cd my-project\nnpm install\nnpm run dev", "Next steps");

outro(
  `Problems? ${color.underline(color.cyan("https://github.com/myorg/myproject/issues"))}`,
);
```

### Custom Key Bindings

Configure alternative key mappings for navigation.

```javascript
import { updateSettings } from "@clack/prompts";

// Enable WASD navigation
updateSettings({
  aliases: {
    w: "up",
    s: "down",
    a: "left",
    d: "right",
  },
});
```

### Non-Interactive Mode Detection

Handle CI environments where prompts aren't supported.

```javascript
import { text, block } from "@clack/prompts";

// In CI environments, prompts automatically use defaults
const name = await text({
  message: "Project name?",
  defaultValue: "default-project",
});

// block() utility prevents input in non-TTY environments
const unblock = block();
// Perform operations
unblock();
```

### Cancellation and Error Handling

Robust error handling for user cancellations and validation errors.

```javascript
import * as p from "@clack/prompts";

async function setupProject() {
  try {
    const responses = await p.group({
      name: () =>
        p.text({
          message: "Project name?",
          validate: (v) => {
            if (!v) return "Required";
          },
        }),

      confirm: ({ results }) =>
        p.confirm({
          message: `Create "${results.name}"?`,
        }),
    });

    // Check if any step was cancelled
    if (p.isCancel(responses.name) || p.isCancel(responses.confirm)) {
      p.cancel("Setup cancelled");
      return;
    }

    if (!responses.confirm) {
      p.outro("Setup aborted");
      return;
    }

    // Proceed with setup
    p.outro("Project created!");
  } catch (error) {
    p.log.error(`Setup failed: ${error.message}`);
    process.exit(1);
  }
}

setupProject();
```

## Advanced Features

### Custom Render Function with @clack/core

Build custom prompts with full control over rendering.

```javascript
import { TextPrompt } from "@clack/core";
import color from "picocolors";

const customPrompt = new TextPrompt({
  validate: (value) => (value.length < 3 ? "Too short!" : undefined),
  render() {
    const title = `>>> ${color.bold("Enter your name")}:`;
    const input = this.valueWithCursor || color.dim("(empty)");

    switch (this.state) {
      case "error":
        return `${title}\n${color.red(input)}\n${color.red(this.error)}`;
      case "submit":
        return `${title} ${color.green(this.value)}`;
      case "cancel":
        return `${title} ${color.strikethrough(this.value)}`;
      default:
        return `${title}\n${color.cyan(input)}`;
    }
  },
});

const result = await customPrompt.prompt();
console.log(`Result: ${result}`);
```

### Event-Driven Custom Prompt

Subscribe to prompt events for advanced interactions.

```javascript
import { TextPrompt } from "@clack/core";

const prompt = new TextPrompt({
  render() {
    return `Input: ${this.valueWithCursor}`;
  },
});

// Listen to events
prompt.on("value", (value) => {
  console.log(`Current value: ${value}`);
});

prompt.on("submit", () => {
  console.log("User submitted the form");
});

prompt.on("cancel", () => {
  console.log("User cancelled");
});

const result = await prompt.prompt();
```

### Complete CLI Application Example

Full-featured setup wizard combining multiple prompt types.

```javascript
import { setTimeout } from "node:timers/promises";
import * as p from "@clack/prompts";
import color from "picocolors";

async function createApp() {
  console.clear();

  p.intro(color.bgCyan(color.black(" create-myapp ")));

  const config = await p.group(
    {
      name: () =>
        p.text({
          message: "What is your project name?",
          placeholder: "my-awesome-app",
          validate: (value) => {
            if (!value) return "Project name is required";
            if (!/^[a-z0-9-]+$/.test(value)) {
              return "Use only lowercase letters, numbers, and hyphens";
            }
          },
        }),

      framework: () =>
        p.select({
          message: "Choose your framework",
          options: [
            { value: "react", label: "React", hint: "Popular" },
            { value: "vue", label: "Vue" },
            { value: "svelte", label: "Svelte" },
            { value: "solid", label: "Solid" },
          ],
        }),

      features: () =>
        p.multiselect({
          message: "Select features",
          required: false,
          options: [
            { value: "router", label: "Router" },
            { value: "state", label: "State Management" },
            { value: "testing", label: "Testing Setup" },
            { value: "ci", label: "CI/CD Pipeline" },
          ],
        }),

      typescript: () =>
        p.confirm({
          message: "Use TypeScript?",
          initialValue: true,
        }),

      install: () =>
        p.confirm({
          message: "Install dependencies now?",
          initialValue: true,
        }),
    },
    {
      onCancel: () => {
        p.cancel("Setup cancelled");
        process.exit(0);
      },
    },
  );

  // Execute setup tasks
  await p.tasks([
    {
      title: "Creating project structure",
      task: async () => {
        // Create project files
        return `Created ${config.name}`;
      },
    },
    {
      title: "Installing dependencies",
      task: async (message) => {
        message("Resolving packages...");
        await setTimeout(1000);
        message("Downloading...");
        await setTimeout(2000);
        return "Installed 42 packages";
      },
      enabled: config.install,
    },
  ]);

  // Display next steps
  const nextSteps = [
    `cd ${config.name}`,
    config.install ? "" : "npm install",
    "npm run dev",
  ]
    .filter(Boolean)
    .join("\n");

  p.note(nextSteps, "Next steps");

  p.outro(
    `All set! ${color.underline(color.cyan("https://docs.example.com"))}`,
  );
}

async function createProjectFiles(config) {
  // Implementation...
}

createApp().catch(console.error);
```

## Detailed API Reference

For comprehensive API documentation including all prompt types, configuration options, and advanced features, see the detailed API reference:

**[references/clack-api.md](references/clack-api.md)**

This reference includes:
- Complete prompt type documentation
- Configuration options for each prompt
- Validation and error handling patterns
- Streaming and async patterns
- Custom key bindings and settings
- Integration with @clack/core
- TypeScript support
- And more

## Resources

### references/
This skill includes detailed API documentation:

- **clack-api.md** - Comprehensive API reference for Clack prompts, organized by prompt type with code examples for each feature.

Related Skills

agents-md-guidelines

16
from diegosouzapw/awesome-omni-skill

Guidelines for writing small, stable AGENTS.md files. Use when creating, refactoring, or reviewing AGENTS.md.

agent-guidelines

16
from diegosouzapw/awesome-omni-skill

When you need to understand the project's core mandate, operational rules, or "Constitution". Use this skill to align with the project's identity and strict coding standards.

documentation-guidelines

16
from diegosouzapw/awesome-omni-skill

Write or update backend feature documentation that follows a repo's DOCUMENTATION_GUIDELINES.md (or equivalent) across any project. Use when asked to create/update module docs, API contracts, or backend documentation that must include architecture, endpoints, payloads, Mermaid diagrams, and seeding instructions.

developer-guidelines

16
from diegosouzapw/awesome-omni-skill

Guidelines for the Developer role: strict adherence, no unsolicited refactoring, documentation, security.

artifact-guidelines

16
from diegosouzapw/awesome-omni-skill

Guidelines for writing reports, organizing files, and generating code artifacts

web-design-guidelines

16
from diegosouzapw/awesome-omni-skill

Review UI code for Web Interface Guidelines compliance. Use when asked to "review my UI", "check accessibility", "audit design", "review UX", or "check my site against best practices".

vercel-web-design-guidelines

16
from diegosouzapw/awesome-omni-skill

Reviews UI code for compliance with web interface best practices. Use when auditing accessibility, reviewing UI/UX patterns, checking performance, or improving web design quality. Triggers on "check my site", "audit design", "accessibility review", "UX best practices", or UI code review tasks. Covers 100+ rules for accessibility, performance, and user experience.

swift-human-guidelines

16
from diegosouzapw/awesome-omni-skill

Comprehensive Swift 6 and SwiftUI development guidelines for building iOS 26, iOS 18, iPadOS, macOS, watchOS, visionOS, and tvOS applications. Covers Foundation Models API, BGContinuedProcessingTask, Call Translation API, Liquid Glass design system, data-race safety, typed throws, synchronization primitives, SwiftUI/UIKit interoperability, zoom transitions, and document-based apps. Use when building new Apple platform apps, implementing Apple Intelligence features, optimizing performance with Swift 6 concurrency, following Apple Human Interface Guidelines, creating cross-platform applications, or working with iOS 26/18 APIs. Triggers on Swift code, SwiftUI views, Xcode projects, app architecture, background processing, translation features, Foundation Models, synchronization, actors, Sendable types, or modern Apple platform development.

react-guidelines

16
from diegosouzapw/awesome-omni-skill

React coding guidelines and best practices. MUST follow these rules. Use when reviewing or writing React code or tasks.

python-backend-guidelines

16
from diegosouzapw/awesome-omni-skill

FastAPI/Django backend patterns and best practices

project-guidelines-example

16
from diegosouzapw/awesome-omni-skill

Example project-specific skill template based on a real production application.

nextjs-frontend-guidelines

16
from diegosouzapw/awesome-omni-skill

Next.js 15 frontend development guidelines for YGS (영영사) React 19/TypeScript application. Modern patterns including App Router, Server/Client Components, shadcn/ui components, Tailwind CSS 4, multi-method authentication (Firebase/Kakao/JWT), admin dashboard patterns, and Korean localization. Use when creating components, pages, API routes, fetching data, styling, or working with frontend code.