MCPcopy Index your code
hub / github.com/agilira/orpheus

github.com/agilira/orpheus @v1.4.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v1.4.1 ↗ · + Follow
915 symbols 4,799 edges 58 files 552 documented · 60%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Orpheus: High-Performance CLI framework for Go

Orpheus Banner

CI/CD Pipeline CodeQL Security Go Report Card Coverage OpenSSF Best Practices Mentioned in Awesome Go

Orpheus is a high-performance CLI framework designed to be super simple and ~30x faster than popular alternatives with zero third-party dependencies. Built on FlashFlags & go-errors, Orpheus provides a simple interface to create modern, secure, fast CLI apps similar to git.

Live Demo

See Orpheus in action - building a Git-like CLI with subcommands in minutes:

Orpheus CLI Demo

Click to view interactive demo

FeaturesPerformanceSecurityQuick StartStorage SystemObservabilityExamplesAPI ReferencePhilosophy

Features

  • Zero Third-Party Dependencies: Built exclusively on AGILira libraries and Go extended standard library (golang.org/x)
  • Native Subcommands: Git-style nested commands with automatic help generation
  • Pluggable Storage System: Dynamic .so plugin loading for persistent storage (SQLite, Redis, File, custom providers)
  • Clean API: Fluent interface for rapid development
  • Context Propagation: Run is signal-aware by default; RunContext supports custom cancellation, deadlines, and tracing
  • Auto-completion: Built-in bash/zsh/fish completion generation
  • Type-safe Errors: Structured error handling with exit codes
  • Hot-swappable Commands: Dynamic command registration and modification
  • Production Observability: Zero-overhead logging, audit trails, tracing, and metrics interfaces
  • Interactive Prompts: Built-in Prompter interface for user input (text, secrets, menus, confirmations) with terminal-safe masking
  • Secure by Design: Red-team tested and fuzz tested
  • Security Validation: Including input sanitization, path traversal protection, and various security controls

Compatibility and Support

Orpheus is designed for Go 1.25.9+ environments and follows Long-Term Support guidelines to ensure consistent performance across production deployments.

Performance

Benchmark results comparing CLI framework performance:

AMD Ryzen 5 7520U with Radeon Graphics
BenchmarkOrpheus-8       1908495           634.5 ns/op          96 B/op       3 allocs/op
BenchmarkCobra-8              66        18439562 ns/op        3145 B/op      33 allocs/op
BenchmarkUrfaveCli-8       40767           30097 ns/op        8549 B/op     318 allocs/op
BenchmarkKingpin-8        293697           4294 ns/op         1988 B/op      40 allocs/op
BenchmarkStdFlag-8       1027216           1039 ns/op          945 B/op      13 allocs/op

Scenario: Command parsing with 3 flags (string, bool, string) and handler execution.

Reproduce benchmarks:

cd benchmarks/
go test -bench=. -benchmem

Complete Performance Benchmarks →

Security

Orpheus implements defense-in-depth security with comprehensive validation against CLI attack vectors.

Protected Vectors: - Path traversal (case-insensitive, URL encoding, Windows device names) - Command/SQL/Script injection prevention - Control character and null byte filtering - Cross-platform consistency (Windows, Linux, macOS)

Run Security Tests:

make security      # Run security test suite
make fuzz          # Quick fuzz testing (30s)
make fuzz-long     # Extended fuzzing (5min)

Quick Start

Installation

go get github.com/agilira/orpheus@v1.4.0   # Latest stable release
# or simply
go get github.com/agilira/orpheus          # Always latest

Basic Usage

package main

import (
    "fmt"
    "log"
    "os"

    "github.com/agilira/orpheus"
)

func main() {
    app := orpheus.New("myapp").
        SetDescription("My awesome CLI application").
        SetVersion("1.0.0")

    // Add commands with fluent interface
    app.Command("start", "Start the service", func(ctx *orpheus.Context) error {
        fmt.Println("Service starting...")
        return nil
    })

    app.Command("stop", "Stop the service", func(ctx *orpheus.Context) error {
        fmt.Println("Service stopping...")
        return nil
    })

    // Run the application
    if err := app.Run(os.Args[1:]); err != nil {
        log.Fatal(err)
    }
}

Context-aware Execution

Run installs Orpheus' default signal-aware context, so command handlers can observe Ctrl-C/SIGTERM cancellation through ctx.Context() without extra setup:

app.Command("sync", "Synchronize data", func(ctx *orpheus.Context) error {
    return syncData(ctx.Context())
})

if err := app.Run(os.Args[1:]); err != nil {
    log.Fatal(err)
}

Use RunContext when your application owns the lifecycle, needs a deadline, or wants to provide a parent tracing context:

runCtx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()

app.Command("sync", "Synchronize data", func(ctx *orpheus.Context) error {
    return syncData(ctx.Context())
})

if err := app.RunContext(runCtx, os.Args[1:]); err != nil {
    log.Fatal(err)
}

Auto-completion

Generate shell completion scripts for your CLI:

# Bash completion (add to ~/.bashrc)
./myapp completion bash > /etc/bash_completion.d/myapp

# Zsh completion (add to ~/.zshrc)
./myapp completion zsh > /usr/local/share/zsh/site-functions/_myapp

# Fish completion
./myapp completion fish > ~/.config/fish/completions/myapp.fish

Subcommands

// Create a command with subcommands
remoteCmd := orpheus.NewCommand("remote", "Manage remote repositories")

// Add subcommands using fluent API (v1.0.7+ - now works correctly)
remoteCmd.Subcommand("add", "Add a remote", func(ctx *orpheus.Context) error {
    name, url := ctx.GetArg(0), ctx.GetArg(1)
    fmt.Printf("Added remote: %s -> %s\n", name, url)
    return nil
}).AddFlag("--force", "Force add remote")

remoteCmd.Subcommand("list", "List remotes", func(ctx *orpheus.Context) error {
    fmt.Println("origin\thttps://github.com/user/repo.git")
    return nil
}).AddFlag("--verbose", "Show detailed information")

app.AddCommand(remoteCmd)

// Usage: ./myapp remote add --force origin https://github.com/user/repo.git
//        ./myapp remote list --verbose

Note on subcommands vs positional arguments: if a parent command accepts both subcommands and free positional arguments (like git stash [save] vs git stash pop), the first non-flag argument is always matched as a subcommand. Design commands so that subcommand names do not collide with expected positional values. If a command needs both, use explicit subcommands for all variants (e.g., stash save, stash pop, stash show).

Storage System

Orpheus provides a pluggable storage system that allows CLI applications to persist state using various backends through a unified interface:

import (
    "log"
    "os"

    "github.com/agilira/orpheus/pkg/orpheus"
)

func main() {
    app := orpheus.New("myapp").
        SetDescription("CLI app with persistent storage").
        SetVersion("1.0.0")

    // Configure storage (supports SQLite, Redis, File, and custom providers)
    config := &orpheus.StorageConfig{
        Provider: "sqlite",
        Config: map[string]interface{}{
            "path": "./myapp.db",
        },
        EnableMetrics: true,
    }
    app.ConfigureStorage(config)

    // Commands can now use persistent storage
    app.Command("set", "Store a key-value pair", setCommand)
    app.Command("get", "Retrieve a value", getCommand)

    if err := app.Run(os.Args[1:]); err != nil {
        log.Fatal(err)
    }
}

func setCommand(ctx *orpheus.Context) error {
    storage := ctx.Storage()
    if storage == nil {
        return orpheus.ErrStorageNotConfigured
    }

    key := ctx.GetArg(0)
    value := ctx.GetArg(1)

    return storage.Set(ctx, key, []byte(value))
}

func getCommand(ctx *orpheus.Context) error {
    storage, err := ctx.RequireStorage()
    if err != nil {
        return err
    }

    key := ctx.GetArg(0)
    value, err := storage.Get(ctx, key)
    if err != nil {
        return err
    }

    fmt.Printf("Value: %s\n", string(value))
    return nil
}

Key Features: - Plugin Architecture: Dynamic .so loading for storage providers - Zero Dependencies: No external storage libraries required
- Security Hardened: Input validation and plugin security checks - Production Ready: Metrics, tracing, and audit logging integration - Provider Agnostic: Unified interface for SQLite, Redis, File, and custom backends

Complete Storage Documentation →

Interactive Prompts

Orpheus includes a built-in Prompter interface for interactive CLI workflows -- setup wizards, first-run configuration, guided input. Secrets are masked at the terminal level via golang.org/x/term.

app := orpheus.New("myapp").
    SetDescription("Interactive CLI").
    SetVersion("1.0.0").
    SetPrompter(orpheus.NewTerminalPrompter())

app.Command("setup", "Run first-time setup", func(ctx *orpheus.Context) error {
    p, err := ctx.RequirePrompter()
    if err != nil {
        return err
    }

    name, err := p.Ask("Your name:", "")
    if err != nil {
        return err
    }

    apiKey, err := p.AskSecret("API key:")
    if err != nil {
        return err
    }

    provider, err := p.Choose("LLM provider:", []string{"OpenAI", "Anthropic", "Ollama"})
    if err != nil {
        return err
    }

    confirm, err := p.Confirm("Save configuration?", true)
    if err != nil {
        return err
    }

    fmt.Printf("Name: %s, Provider: %d, Confirmed: %v\n", name, provider, confirm)
    _ = apiKey // use securely
    return nil
})

Prompter methods:

Method Purpose Return
Ask(prompt, default) Free-text input with optional default (string, error)
AskSecret(prompt) Masked password/key entry (string, error)
Choose(prompt, options) Numbered menu selection (int, error) (0-based)
Confirm(prompt, defaultYes) Yes/no question (bool, error)

The Prompter interface is testable by design: inject a custom implementation for unit tests without touching a real terminal.

Observability

Zero-overhead observability interfaces for production CLI applications:

import "context"

// Configure observability (all interfaces are optional)
app := orpheus.New("myapp").
    SetLogger(myLogger).           // Structured logging
    SetAuditLogger(myAuditLogger). // Compliance and security
    SetTracer(myTracer).           // Distributed tracing
    SetMetricsCollector(myMetrics) // Performance metrics

app.Command("deploy", "Deploy application", func(ctx *orpheus.Context) error {
    // Structured logging
    if logger := ctx.Logger(); logger != nil {
        logger.Info(context.Background(), "Deployment started",
            orpheus.StringField("environment", "production"),
            orpheus.StringField("version", "v1.2.3"),
        )
    }

    // Audit trail
    if audit := ctx.AuditLogger(); audit != nil {
        audit.LogCommand(context.Background(), "deploy", ctx.Args(), "demo-user")
        audit.LogAccess(context.Background(), "production", "deploy", true)
    }

    // Distributed tracing
    if tracer := ctx.Tracer(); tracer != nil {
        spanCtx, span := tracer.StartSpan(context.Background(), "deploy_operation")
        defer span.End()
        // ... use spanCtx for downstream operations
    }

    // Performance metrics
    if metrics := ctx.MetricsCollector(); metrics != nil {
        counter := metrics.Counter("deployments_total", "Total deployments", "env")
        counter.Inc(context.Background(), "production")
    }

    fmt.Println("Deployment completed")
    return nil
})

Performance: Zero overhead when not configured (0.24 ns/op), minimal overhead when enabled (~24 ns/op)

Complete Observability Guide →

Complete Examples →

The Philosophy Behind Orpheus

Orpheus's lyre was no ordinary instrument. It could make rivers pause mid-flow, convince stones to dance, and move even Hades and Persephone to tears. When the great musician played, the impossible became inevitable—not through force, but through the pure beauty of perfect harmony.

Yet Orpheu

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Function 497
Method 349
Struct 50
Interface 13
TypeAlias 4
FuncType 2

Languages

Go100%

Modules by API surface

pkg/orpheus/observability.go47 symbols
pkg/orpheus/storage_plugin_test.go46 symbols
pkg/orpheus/app.go45 symbols
pkg/orpheus/observability_test.go39 symbols
pkg/orpheus/prompt_test.go35 symbols
pkg/orpheus/command.go34 symbols
pkg/orpheus/context.go28 symbols
examples/storage/main_test.go28 symbols
examples/filemanager/main.go28 symbols
pkg/orpheus/security.go27 symbols
pkg/orpheus/validation.go26 symbols
pkg/orpheus/security_test.go25 symbols

For agents

$ claude mcp add orpheus \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page