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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@runa-cmd/completions

v0.1.0

Published

Shell completion script generation for Runa CLIs. Auto-generate bash, zsh, and fish completions from your Zod schemas.

Readme

@runa-cmd/completions

Auto-generate shell completion scripts for any Runa CLI. One command, three shells — bash, zsh, and fish.

Your Zod schema is the source of truth: enum values become completion candidates, commands and subcommands get tab-completed, and option flags (including --no-* booleans) work out of the box.

Install

pnpm add @runa-cmd/completions

Peer dependencies: @runa-cmd/core and zod ^4.0.0. Zero runtime dependencies.

Quick Start

import { defineCLI, defineCommand } from '@runa-cmd/core';
import { z } from '@runa-cmd/core/zod';
import { completionsPlugin } from '@runa-cmd/completions';

const deploy = defineCommand({
  meta: { name: 'deploy', description: 'Deploy a service' },
  options: {
    env: z.enum(['staging', 'production']).describe('Target environment'),
  },
  run({ options }) {
    console.log(`Deploying to ${options.env}...`);
  },
});

const cli = defineCLI({
  meta: { name: 'my-tool', version: '1.0.0' },
  commands: { deploy },
  plugins: [completionsPlugin()],
});

cli.run();
# Generate and install bash completions
$ my-tool completions bash > ~/.local/share/bash-completion/completions/my-tool

# Or get install instructions
$ my-tool completions bash --instructions

# Tab-complete in action
$ my-tool d<TAB>         → deploy
$ my-tool deploy --e<TAB> → --env
$ my-tool deploy --env <TAB> → staging  production

Supported Shells

| Shell | Script Type | Features | |---|---|---| | Bash | complete -F with compgen | Commands, subcommands, options, enum values, --no-* booleans | | Zsh | _arguments -C with state dispatch | Same + grouped option specs with descriptions | | Fish | complete -c directives | Same + native condition-based filtering |

How It Works

  1. The plugin registers a completions command with addCommands capability
  2. The command takes a positional shell arg (bash, zsh, or fish)
  3. On execution, it introspects the CLI schema via api.getSchema()
  4. A shell-specific generator produces a self-contained completion script
  5. The script is written to stdout — pipe it to a file or eval it

What Gets Completed

| Element | Example | Completed? | |---|---|---| | Top-level commands | my-tool de<TAB>deploy | ✅ | | Nested subcommands | my-tool config g<TAB>get | ✅ | | Long options | my-tool deploy --e<TAB>--env | ✅ | | Short aliases | my-tool deploy -e<TAB> | ✅ | | Boolean negation | my-tool --no-<TAB>--no-color | ✅ | | Enum values | --env <TAB>staging production | ✅ | | Command descriptions | Shown in zsh/fish completions | ✅ |

API

completionsPlugin(options?)

Creates the completions plugin. Returns a PluginConfig compatible with defineCLI.

import { completionsPlugin } from '@runa-cmd/completions';

completionsPlugin({
  commandName: 'complete', // Override command name (default: 'completions')
});

CompletionsPluginOptions

interface CompletionsPluginOptions {
  commandName?: string; // Override the command name (default: 'completions')
}

Direct Generator Functions

For advanced use cases (custom output, testing, etc.), the generators are exported directly:

import {
  generateBashCompletions,
  generateZshCompletions,
  generateFishCompletions,
} from '@runa-cmd/completions';

// schema: CLISchema from api.getSchema()
const bashScript = generateBashCompletions(schema, 'my-tool');
const zshScript = generateZshCompletions(schema, 'my-tool');
const fishScript = generateFishCompletions(schema, 'my-tool');

getInstallInstructions(shell, binName)

Returns shell-specific install instructions as a string:

import { getInstallInstructions } from '@runa-cmd/completions';

console.log(getInstallInstructions('bash', 'my-tool'));
// # Bash completions for my-tool
// #
// # Option 1: Add to your .bashrc (loads on every shell start)
// #   echo 'eval "$(my-tool completions bash)"' >> ~/.bashrc
// ...

Install Instructions by Shell

Bash

# Option 1: Source in .bashrc
echo 'eval "$(my-tool completions bash)"' >> ~/.bashrc

# Option 2: Save to bash-completion directory (recommended)
my-tool completions bash > ~/.local/share/bash-completion/completions/my-tool

Zsh

# Save to a completions directory in your fpath
mkdir -p ~/.zsh/completions
my-tool completions zsh > ~/.zsh/completions/_my-tool

# Add to .zshrc (before compinit):
#   fpath=(~/.zsh/completions $fpath)
#   autoload -Uz compinit && compinit

Fish

# Save to fish completions directory (auto-loaded)
my-tool completions fish > ~/.config/fish/completions/my-tool.fish

With Other Plugins

Completions work alongside help and MCP — just add all plugins:

import { helpPlugin } from '@runa-cmd/help';
import { mcpPlugin } from '@runa-cmd/mcp';
import { completionsPlugin } from '@runa-cmd/completions';

const cli = defineCLI({
  meta: { name: 'my-tool', version: '1.0.0' },
  commands: { deploy, init },
  plugins: [helpPlugin(), mcpPlugin(), completionsPlugin()],
});
$ my-tool --help              # Human-readable help
$ my-tool --mcp               # MCP server for AI agents
$ my-tool completions bash    # Shell completions script

Shell Escaping

All values (command names, descriptions, enum values) are properly escaped for each shell context:

| Shell | Escaping Strategy | |---|---| | Bash | Single-quote context: ''\'' | | Zsh | Same as bash | | Fish | '\', \\\ |

Descriptions are truncated to 80 characters and newlines are collapsed to spaces.

Architecture

completionsPlugin()
    │
    ├── plugin.ts          Runa plugin (adds completions command)
    ├── generators/
    │   ├── bash.ts        Bash completion script generator
    │   ├── zsh.ts         Zsh completion script generator
    │   ├── fish.ts        Fish completion script generator
    │   └── escape.ts      Shell-specific string escaping
    ├── install.ts         Install instruction templates
    └── types.ts           Shell type and plugin options

Zero runtime dependencies. Everything is derived from CLISchema at generation time.

License

MIT