tap

module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 21, 2025 License: MIT

README ΒΆ

πŸš€ Tap

Tap is a Go port of the popular TypeScript Clack library for building beautiful, interactive command-line applications.

Tap Demo

⚠️ Heavy Development: This project is currently in heavy development. APIs may change, and some features are still being implemented. Use with caution in production environments.

🎯 About

Clack is a library that makes building interactive command-line applications effortless with beautiful, minimal, and opinionated CLI prompts. Tap brings this elegant experience to the Go ecosystem while maintaining the same design philosophy and user experience.

βœ… What's Ported

Core Functionality
  • βœ… Event-driven prompt system - Complete with proper state management and event loop architecture
  • βœ… Terminal management - Raw terminal mode, keyboard input handling, and cursor control
  • βœ… Mock testing utilities - Full test coverage with mock input/output for reliable testing
Prompts (Unstyled - Core Package)
  • βœ… Text Input - Single-line text input with cursor navigation, validation, and default values
  • βœ… Confirm - Yes/No prompts with keyboard navigation
  • βœ… Select - Single selection from a list with cursor navigation and wrap-around
Prompts (Styled - Prompts Package)
  • βœ… Text Input - Beautifully styled text prompts with symbols, bars, placeholders, and error states
  • βœ… Confirm - Styled confirmation prompts with radio button interface
  • βœ… Select - Styled selection prompts with radio buttons, hints, and color-coded options
  • βœ… Progress Bar - Animated progress with messages and final states
  • βœ… Box - Styled message boxes with rounded/square borders, alignment, and auto-wrapping
  • βœ… Symbols & Styling - Unicode symbols, ANSI colors, and consistent visual design
Still To Come
  • πŸ”„ Password Input - Masked text input
  • πŸ”„ Multi-Select - Multiple selection from a list
  • πŸ”„ Autocomplete - Text input with autocomplete suggestions
  • πŸ”„ Spinner - Loading indicators for long-running operations
  • πŸ”„ Group - Grouped prompts for complex workflows
  • πŸ”„ Note/Log - Informational messages and logging utilities

πŸš€ Quick Start

Installation
go get github.com/yarlson/tap
Basic Usage
package main

import (
    "fmt"
    "github.com/yarlson/tap/prompts"
    "github.com/yarlson/tap/terminal"
)

func main() {
    // Initialize terminal
    term, err := terminal.New()
    if err != nil {
        panic(err)
    }
    defer term.Close()

    // Text input
    name := prompts.Text(prompts.TextOptions{
        Message: "What's your name?",
        Input:   term.Reader,
        Output:  term.Writer,
    })

    // Confirmation
    confirmed := prompts.Confirm(prompts.ConfirmOptions{
        Message: fmt.Sprintf("Hello %s! Continue?", name),
        Input:   term.Reader,
        Output:  term.Writer,
    })

    if confirmed.(bool) {
        fmt.Println("Let's go! πŸŽ‰")
    }
}
Advanced Features
// Text with validation and default value
email := prompts.Text(prompts.TextOptions{
    Message:      "Enter your email:",
    Placeholder:  "user@example.com",
    DefaultValue: "anonymous@example.com",
    Validate: func(input string) error {
        if !strings.Contains(input, "@") {
            return errors.New("Please enter a valid email")
        }
        return nil
    },
    Input:  term.Reader,
    Output: term.Writer,
})

// Confirmation with custom labels
proceed := prompts.Confirm(prompts.ConfirmOptions{
    Message:      "Deploy to production?",
    Active:       "Deploy",
    Inactive:     "Cancel",
    InitialValue: false,
    Input:        term.Reader,
    Output:       term.Writer,
})
Progress Bar
// Progress bar with animated frames and messages
prog := prompts.NewProgress(prompts.ProgressOptions{
    Style:  "heavy",   // "light", "heavy", or "block"
    Max:    100,        // total units of work
    Size:   40,         // bar width in characters
    Output: term.Writer, // implements prompts.Writer
})

prog.Start("Processing...")

// Update progress and optionally the message
for i := 0; i <= 100; i += 10 {
    time.Sleep(200 * time.Millisecond)
    prog.Advance(10, fmt.Sprintf("Processing... %d%%", i))
}

// Stop with final status. code: 0=success, 1=cancel, other=error
prog.Stop("Done!", 0)

πŸ—οΈ Architecture

Tap follows a clean, event-driven architecture:

  • core - Core prompt engine with unstyled, functional prompts
  • prompts - Beautifully styled prompts built on top of core
  • terminal - Terminal management and keyboard input handling
Event Loop Design

Tap uses a pure event loop architecture (no mutexes or atomic operations) for excellent performance and race-condition-free operation:

// Events flow through a single event loop
for event := range prompt.events {
    event(&state)           // Update state
    prompt.render(&state)   // Render changes
    prompt.updateSnapshot(&state) // Update atomic snapshot
}

πŸ§ͺ Testing

All prompts include comprehensive test coverage with mock input/output:

# Run all tests
go test ./...

# Run with race detection
go test -race ./...

# Run specific package tests
go test ./prompts -v

πŸ“ Project Structure

go/
β”œβ”€β”€ README.md
β”œβ”€β”€ go.mod
β”œβ”€β”€ go.sum
β”œβ”€β”€ LICENSE
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ confirm/
β”‚   β”‚   └── main.go
β”‚   β”œβ”€β”€ multiple/
β”‚   β”‚   β”œβ”€β”€ demo.tape
β”‚   β”‚   └── main.go
β”‚   β”œβ”€β”€ progress/
β”‚   β”‚   └── main.go
β”‚   β”œβ”€β”€ select/
β”‚   β”‚   └── main.go
β”‚   └── text/
β”‚       └── main.go
β”œβ”€β”€ core/                 # Core prompt engine (unstyled)
β”‚   β”œβ”€β”€ confirm.go
β”‚   β”œβ”€β”€ confirm_test.go
β”‚   β”œβ”€β”€ mock.go
β”‚   β”œβ”€β”€ prompt.go
β”‚   β”œβ”€β”€ prompt_test.go
β”‚   β”œβ”€β”€ select.go
β”‚   β”œβ”€β”€ select_test.go
β”‚   β”œβ”€β”€ text.go
β”‚   β”œβ”€β”€ text_test.go
β”‚   └── types.go
β”œβ”€β”€ prompts/              # Styled prompts and primitives
β”‚   β”œβ”€β”€ box.go
β”‚   β”œβ”€β”€ box_test.go
β”‚   β”œβ”€β”€ confirm.go
β”‚   β”œβ”€β”€ confirm_test.go
β”‚   β”œβ”€β”€ messages.go
β”‚   β”œβ”€β”€ messages_test.go
β”‚   β”œβ”€β”€ progress.go
β”‚   β”œβ”€β”€ progress_test.go
β”‚   β”œβ”€β”€ select.go
β”‚   β”œβ”€β”€ select_test.go
β”‚   β”œβ”€β”€ symbols.go
β”‚   β”œβ”€β”€ text.go
β”‚   β”œβ”€β”€ text_test.go
β”‚   └── types.go
└── terminal/
	└── terminal.go

🀝 Contributing

We welcome contributions! This project is in active development and there's lots to build.

Development Setup
# Clone the repository
git clone https://github.com/yarlson/tap.git
cd tap

# Run tests
go test ./...

# Try examples
go run examples/text/main.go
go run examples/confirm/main.go
go run examples/select/main.go
go run examples/progress/main.go
go run examples/multiple/main.go
What Needs Help
  • New Prompt Types: Multi-Select, Password, Autocomplete
  • Enhanced Styling: Better color support, themes, custom symbols
  • Documentation: More examples, API documentation, tutorials
  • Testing: Edge cases, cross-platform testing, performance tests
  • Bug Fixes: Race conditions, rendering issues, keyboard handling
Coding Standards
  • Follow Go best practices and gofmt formatting
  • Maintain test coverage above 80%
  • Use event-driven architecture (no mutexes/atomics)
  • Write clear, self-documenting code
  • Add examples for new features

πŸ“„ License

MIT License - see LICENSE file for details.

πŸ™ Acknowledgments

  • Clack - The original TypeScript library that inspired this project
  • @eiannone/keyboard - Cross-platform keyboard input for Go
  • The Go community for excellent tooling and libraries

Made with ❀️ for the Go community. Building interactive CLIs shouldn't be so hard!

Directories ΒΆ

Path Synopsis
examples
confirm command
multiple command
progress command
select command
text command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL