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

@moikapy/kapy

v0.4.2

Published

The extensible CLI framework. Commands, hooks, middleware, extensions.

Readme

@moikapy/kapy

The agent-first CLI framework — build AI tools from the terminal. Commands, hooks, middleware, TUI — everything snaps together.

Install

bun add -g @moikapy/kapy
# or
npm install -g @moikapy/kapy

Quick Start

Standalone mode

Run kapy directly. It ships with meta-commands — its CLI surface is empty until you install extensions:

kapy install npm:@foo/kapy-deploy
kapy deploy:aws --region us-east-1
kapy tui

Embedded mode

Build your own extensible CLI on top of kapy:

import { kapy } from "@moikapy/kapy"

kapy()
  .command("deploy", {
    description: "Deploy your application",
    args: [{ name: "env", description: "Environment", default: "staging" }],
    flags: {
      verbose: { type: "boolean", alias: "v", description: "Verbose output" },
    },
  }, async (ctx) => {
    ctx.log(`Deploying to ${ctx.args.env}...`)
  })
  .run()

Built-in Commands

| Command | Description | |---|---| | kapy init <name> | Scaffold a new kapy-powered CLI project | | kapy install <pkg> | Install an extension (npm/git/local) | | kapy list | Show installed extensions | | kapy update [name] | Update all or a specific extension | | kapy remove <name> | Uninstall an extension | | kapy upgrade [--pm bun\|npm\|yarn\|pnpm] | Upgrade kapy (auto-detects package manager) | | kapy config | View/edit configuration | | kapy dev | Run CLI in dev mode with hot reload | | kapy commands | List all registered commands | | kapy inspect | Dump full state (extensions, config, hooks) | | kapy tui | Launch interactive terminal UI |

AI Agent Support

Kapy puts agents first. Every command supports --json and --no-input for machine-readable, non-interactive output:

kapy commands --json
kapy deploy:aws --json --no-input
kapy inspect --json

Extensions declare agentHints — structured metadata that AI agents can parse to understand what a command does and how to call it. Structured exit codes give agents unambiguous signal: 0 success, 1 error, 2 invalid args, 3 extension error, 4 config error, 5 network error, 10 aborted by hook/middleware.

Compose extensions into agent toolchains. Hooks and middleware let you inject auth, rate-limiting, logging, and retries without touching command logic.

Command Context API

Every command handler receives a ctx object:

async (ctx) => {
  // Basic
  ctx.args                    // Parsed args + flags
  ctx.config                  // Merged config
  ctx.log(msg)                // Styled success output
  ctx.warn(msg)               // Styled warning
  ctx.error(msg)              // Styled error
  ctx.spinner(text)           // Progress spinner
  ctx.prompt(msg)             // Interactive input
  ctx.confirm(msg)            // Yes/no confirm
  ctx.abort(code?)            // Cancel execution

  // Process-Aware (v0.2.0+)
  ctx.isInteractive           // True when TTY + !json + !noInput
  ctx.spawn(cmd, opts?)       // Spawn subprocess (TTY passthrough, abort-safe)
  ctx.exitCode                // Writable exit code (propagated to process.exit)
  ctx.teardown(fn)            // Register cleanup callback (LIFO, async-safe)
}

ctx.spawn() Options

const result = await ctx.spawn(["tmux", "new-session", "-s", "dev"], {
  tty: true,           // Pass through stdin/stdout/stderr for interactive processes
  stream: false,       // Stream output in real-time (default: collect)
  env: { FOO: "bar" }, // Merge env vars with process.env
  cwd: "/tmp",         // Working directory
  abortOnError: true,  // Auto-kill process on ctx.abort()
  suppressOutput: true, // Suppress stdout in --json mode
})
// result: { exitCode, stdout, stderr, aborted }

Extensions

Extensions are TypeScript modules that export a register function:

import type { KapyExtensionAPI } from "@moikapy/kapy"

export async function register(api: KapyExtensionAPI) {
  api.addCommand("deploy:aws", {
    description: "Deploy to AWS",
  }, async (ctx) => {
    ctx.log("Deploying to AWS...")
  })

  api.addHook("before:deploy", async (ctx) => {
    // auth check, etc.
  })

  api.addMiddleware(async (ctx, next) => {
    const start = Date.now()
    await next()
    ctx.log(`Completed in ${Date.now() - start}ms`)
  })

  api.addScreen({
    name: "dashboard",
    label: "Dashboard",
    icon: "📊",
    render(ctx) {
      return { type: "Text", props: { content: "Project Dashboard" } }
    },
  })
}

export const meta = {
  name: "@foo/kapy-deploy-aws",
  version: "1.0.0",
  dependencies: [],
}

Install from npm, git, or local paths:

kapy install npm:@foo/kapy-ext
kapy install npm:@foo/[email protected]
kapy install git:github.com/user/repo
kapy install ./path/to/ext

kapy tui

Launch the interactive terminal UI:

kapy tui
kapy tui --screen dashboard

Extensions register screens via api.addScreen(). The TUI provides sidebar navigation, screen switching, and a status bar.

Built-in screens: Home 📊, Extensions 📦, Config 🔧, Terminal ⚡

Config

Config hierarchy (later overrides earlier):

kapy defaults → kapy.config.ts → ~/.kapy/config.json → env vars → CLI flags
// kapy.config.ts
import { defineConfig } from "@moikapy/kapy"

export default defineConfig({
  name: "my-cli",
  extensions: ["npm:@foo/kapy-deploy"],
  envPrefix: "MY_CLI",
})
# Environment variables
KAPY_DEPLOY_AWS_REGION=us-west-2 kapy deploy:aws

# Custom prefix (embedded mode)
MY_CLI_DEPLOY_AWS_REGION=us-west-2 my-cli deploy:aws

Extension API

KapyExtensionAPI:
  addCommand(definition)                    // Register a command
  addCommand(name, options, handler)          // Register a command with name
  addHook(event, handler)                    // Register a hook
  addMiddleware(middleware)                   // Register middleware
  declareConfig(schema)                      // Declare config schema (auto-namespaced)
  addScreen(screenDefinition)                // Register a TUI screen
  emit(event, data?)                         // Emit a custom event
  on(event, handler)                         // Listen for a custom event

Packages

| Package | Purpose | |---|---| | @moikapy/kapy | Runtime + CLI bin + TUI shell + agent support. Install this. | | @moikapy/kapy-components | UI components on @opentui/core (Banner, Box, Text, Input, Select, ScrollBox, Code, Diff, Spinner, Sidebar, StatusBar). Re-exported by @moikapy/kapy. |

Tech Stack

TypeScript · Bun · @opentui/core · picocolors · Biome

Exit Codes

| Code | Meaning | |---|---| | 0 | Success | | 1 | General error | | 2 | Invalid arguments / unknown command | | 3 | Extension error | | 4 | Config error | | 5 | Network error | | 10 | Aborted by hook/middleware |

License

MIT