npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

cmdeagle

v0.11.1

Published

A powerful and precise CLI framework for any language.

Downloads

149

Readme

cmdeagle

WARNING: This is very much a work in progress, but we're close to releasing a stable version 1. Check back soon. Feedback is also much appreciated.

A versatile framework that allows users to build cross-platform command-line tools using the language of their choice. It's designed to simplify the process of creating complex CLI applications by referencing external scripts and binaries, using a YAML configuration file to define commands, arguments, flags, build commands and more.

Internally, it heavily leverages existing CLI libraries and tools such as:

- Cobra [https://github.com/spf13/cobra](https://github.com/spf13/cobra)
- Viper [https://github.com/spf13/viper](https://github.com/spf13/viper)
- pflag [https://github.com/spf13/pflag](https://github.com/spf13/pflag)
- huh [https://github.com/charmbracelet/huh](https://github.com/charmbracelet/huh)
- log [https://github.com/charmbracelet/log](https://github.com/charmbracelet/log)

Big thanks to @spf13 and @charmbracelet for their work on these libraries. Building cmdeagle was made possible with their contributions to the opensource community.

Prerequisites

  • Go 1.22 or higher: You need to have Go installed to install cmdeagle and build CLIs. You can install Go by following the instructions at https://go.dev/doc/install.
  • Node.js 14.0 or higher

Installation

With Go installed, you can install cmdeagle by running:

go install github.com/migsc/cmdeagle

With Node.js installed, you can install cmdeagle by running:

npm install -g cmdeagle

Install from source

git clone https://github.com/migsc/cmdeagle.git
cd cmdeagle
make build # or `npm run build` for Node.js

Adding to PATH

For invoking the cmdeagle command directly from your cloned repository, you need to add the bin directory to your PATH.

Unix (Linux/macOS)

Then add the following line to your .zshrc or .bashrc to make it easier to invoke cmdeagle directly. Then run source ~/.zshrc or source ~/.bashrc to apply the changes.

PATH="$PATH:PATH_TO_YOUR_CLONE_DIR/cmdeagle/bin"

Where PATH_TO_YOUR_CLONE_DIR is the path to the directory you cloned cmdeagle into.

Windows

You can add the directory to your PATH through:

  1. Using System Properties (GUI): - Right-click on 'This PC' or 'My Computer' - Click 'Properties' - Click 'Advanced system settings' - Click 'Environment Variables' - Under 'User variables', select 'Path' - Click 'Edit' - Click 'New' - Add the full path to the cmdeagle bin directory (e.g., C:\Users\YourUsername\Projects\cmdeagle\bin) - Click 'OK' on all windows

  2. Using Command Prompt (CLI):

setx PATH "%PATH%;C:\Path\To\Your\cmdeagle\bin"

Note: You'll need to restart your terminal for the changes to take effect.

Usage

  1. Initialize a new CLI project by running in a directory of your choice:
mdkir ./mycli && cd mycli
cmdeagle init

This will create a .cmd.yaml file in your project root to define your CLI structure. You can read the comments in the file to understand what each field does.

  1. Build your CLI:
cmdeagle build

Running your CLI on Unix (Linux/macOS)

For Linux and macOS, if you have ./.local/bin in your PATH you can simply run:

mycli

Otherwise you can run it like so:

cd
./.local/bin/mycli

If you need help setting up your PATH variable, add the following line in your .zshrc or .bashrc. This will make it easier to run your CLI by invoking it directly. Then run source ~/.zshrc or source ~/.bashrc to apply the changes.

PATH="$PATH:~/.local/bin"

Running your CLI on Windows

Your CLI will be automatically be installed to %LocalAppData%\Programs\mycli\bin. You can run it by:

%LocalAppData%\Programs\mycli\bin\mycli.exe

To add to your PATH permanently (so you can just run mycli):

  1. Using System Properties: - Right-click on 'This PC' or 'My Computer' - Click 'Properties' - Click 'Advanced system settings' - Click 'Environment Variables' - Under 'User variables', select 'Path' - Click 'Edit' - Click 'New' - Add %LocalAppData%\Programs\mycli\bin - Click 'OK' on all windows

  2. Using Command Prompt:

setx PATH "%PATH%;%LocalAppData%\Programs\mycli\bin"

Note: You'll need to open a new terminal for the PATH changes to take effect.

Configuration Guide

The .cmd.yaml file is the heart of your CLI application. It defines your commands, arguments, flags, and their behaviors.

Basic Structure

name: "mycli"                    # Name of your CLI binary
description: "My CLI tool"       # Description shown in help
version: "1.0.0"                # Version of your CLI
author: "Your Name"             # Author information
license: "MIT"                  # License information

# Dependencies required to run your CLI
requires:
  node: ">=16.0.0"              # Specify version constraints
  python3: "*"                  # Any version is acceptable
  go: "^1.22.0"                # Major version must match

# Files to bundle with your CLI
includes:
- "./scripts/helper.sh"
- "./config/default.json"

# Command definitions
commands:
- name: greet                   # Command name (invoked as: mycli greet)
  description: "Greet user"     # Command description

Defining Arguments

Arguments can be defined with various types and validations:

args:
  vars:
  - name: username              # Argument name
    type: string               # Type: string, number, boolean
    description: "Username"    # Description for help text
    required: true            # Is this argument required?
    default: "guest"          # Default value if not provided

  - name: age
    type: number
    description: "User age"
    constraints:              # Validation constraints
      min: 18
      max: 100
    depends-on:              # Dependency relationships
    - name: username         # Only valid if username is provided

  rules:
    minimum-n-args: 1        # Minimum number of arguments
    maximum-n-args: 2        # Maximum number of arguments

Defining Flags

Flags provide optional modifications to command behavior:

flags:
- name: verbose               # Flag name (--verbose)
  shorthand: v               # Short form (-v)
  type: boolean             # Type: boolean, string, number
  description: "Enable verbose output"
  default: false            # Default value

- name: format
  shorthand: f
  type: string
  description: "Output format"
  default: "text"
  conflicts-with:           # Mutually exclusive flags
  - json
  - yaml

- name: count
  shorthand: c
  type: number
  description: "Number of iterations"
  default: 1

Command Execution

You can specify how commands are executed using the start field:

commands:
- name: process
  description: "Process files"
  start: |
    if [ "${flags.verbose}" = "true" ]; then
      echo "Processing ${args.filename}..."
    fi
    python3 ./scripts/process.py

Build Commands

Each command can specify a build script that runs during the CLI's build phase. This is different from the start script which runs when the command is executed.

commands:
- name: generate
  description: "Generate code"
  build: |
    # This script runs when you build your CLI with 'cmdeagle build'
    go generate ./...
    tsc --build
  start: |
    # This script runs when someone executes 'mycli generate'
    node ./dist/generator.js

- name: docs
  description: "Generate documentation"
  build: |
    # Compile documentation during build
    mdbook build docs/
    cp -r docs/book/* static/docs/

The build key is useful for:

  • Compiling assets
  • Generating code
  • Building documentation
  • Running pre-processing steps
  • Setting up command dependencies

Build scripts run in the context of your project directory during the cmdeagle build phase, before your CLI is packaged into a binary.

Including Files

The includes key allows you to bundle files with your CLI. They are bundled immediately after the build phase. These files will be packaged into your binary and extracted when the user first runs your CLI.

includes:
- "./scripts/helper.sh"     # Shell scripts
- "./templates/config.json" # Configuration files
- "./assets/logo.png"      # Static assets
- "./data/defaults.yaml"   # Data files

When your CLI runs for the first time, the files are extracted to the following locations:

  • For macOS and Linux: Files are installed to /usr/local/share/<cli-name> or ~/.local/share/<cli-name>
  • For Windows: Files are installed to %LocalAppData%\<cli-name>

You can also specify includes at the command level:

commands:
- name: generate
  description: "Generate files"
  includes:
  - "./templates/component.ts"
  - "./templates/test.ts"
  start: |
    node ./templates/generator.js

The included files will be available in the same relative path as specified in your configuration when your command executes.

Version Constraints

The requires field supports various version constraint operators:

  • *: Any version
  • ^: Major version must match (^1.2.3 allows 1.x.x)
  • ~: Minor version must match (~1.2.3 allows 1.2.x)
  • >: Greater than
  • <: Less than
  • >=: Greater than or equal
  • <=: Less than or equal
  • No operator: Exact match

Example:

requires:
  node: ">=14.0.0"
  python3: "^3.8.0"
  go: "~1.22.0"

Nested Commands

Commands can be nested to create command hierarchies:

commands:
- name: user
  description: "User management"
  commands:
  - name: create
    description: "Create user"
    args:
      vars:
      - name: username
        type: string
        required: true
    start: |
      ./scripts/create-user.sh

  - name: delete
    description: "Delete user"
    flags:
    - name: force
      shorthand: f
      type: boolean
      description: "Force deletion"

Environment Variables

When your commands execute, cmdeagle automatically provides arguments and flags as environment variables:

  • Arguments: ARGS_<NAME> (e.g., ARGS_USERNAME)
  • Flags: FLAGS_<NAME> (e.g., FLAGS_VERBOSE)

These can be accessed in your scripts:

# Python example
import os
username = os.environ.get('ARGS_USERNAME')
verbose = os.environ.get('FLAGS_VERBOSE') == 'true'
// JavaScript example
const username = process.env.ARGS_USERNAME;
const verbose = process.env.FLAGS_VERBOSE === 'true';
# Shell example
username="${ARGS_USERNAME}"
if [ "${FLAGS_VERBOSE}" = "true" ]; then
  echo "Verbose mode enabled"
fi

For more examples, check out the sample CLI in the examples/mycli directory.

Distribution

This tool does not help you with releasing or codesigning your resulting binary. It's highly recommendeded for you and your users' security that you do some sort of codesigning before distributing your CLI. You can use something like goreleaser to build and distribute your CLI for multiple platforms and handle codesigning. Worth noiting that cmdeagle itself uses this.

Contributing

This project is under active development. Contributions, ideas, and feedback are welcome! Please open an issue or submit a pull request on the GitHub repository.

License

MIT License