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

@yaos-git/run-ctx

v126.0.4

Published

Context-aware command alias CLI — run the right command based on cwd, files, and env vars

Readme

Node Version TypeScript Version React Version

Uses Ink Uses Vitest Uses Biome


Table of Contents

Getting Started

Configuration

TUI Editor

Development


Overview

run-ctx is a globally-installed CLI that aliases commands based on context -- your current working directory, the files present, and environment variables.

Define a single alias like dev, and run-ctx resolves it to the right command for whatever project you are in:

# In a Node project (has package.json):
run-ctx dev  # --> npm run dev

# In a PHP project (has composer.json):
run-ctx dev  # --> composer serve

# In a Rust project (has Cargo.toml):
run-ctx dev  # --> cargo watch -x run

No more remembering which command goes with which project.

What Makes This Project Unique

  • Context-Aware: Automatically detects project type via files, cwd, and env vars
  • Specificity Scoring: Multi-condition rules with CSS-style cascade resolution
  • TUI Editor: Interactive terminal UI for managing aliases and rules
  • Zero Config Per-Project: One global config works across all your projects

Installation

# Install globally from npm
npm install -g run-ctx

# Or install as a dev dependency
npm install -D run-ctx

From Source

# Clone the repository
git clone https://github.com/YAOSGit/run-ctx.git
cd run-ctx

# Install dependencies
npm install

# Build the project
npm run build

# Link globally (optional)
npm link

Quick Start

  1. Generate a starter configuration file automatically:
run-ctx --init

Note: This automatically creates ~/.config/run-ctx/config.json populated with common smart aliases like dev, build, test, lint, and start configured for popular languages and frameworks.

  1. Run it:
cd ~/my-node-project
run-ctx dev
# Executes: npm run dev

Config Format

The config file lives at ~/.config/run-ctx/config.json (or $XDG_CONFIG_HOME/run-ctx/config.json if set).

Schema

{
  "version": 2,
  "aliases": {
    "<alias-name>": {
      "description": "Optional human-readable description",
      "rules": [
        {
          "match": {
            "file": "<glob pattern>",
            "cwd": "<regex pattern>",
            "env": "<VAR_NAME>"
          },
          "command": "<shell command to run>",
          "shell": false
        }
      ],
      "fallback": "<optional command when no rules match>",
      "shell": false
    }
  }
}

Example

{
  "aliases": {
    "dev": {
      "description": "Start development server",
      "rules": [
        {
          "match": { "file": "package.json", "cwd": "frontend" },
          "command": "npm run dev"
        },
        {
          "match": { "file": "composer.json" },
          "command": "composer serve"
        }
      ],
      "fallback": "echo 'No dev server configured for this project'"
    }
  }
}

Match Conditions

Each rule has a match object with one or more conditions. All specified conditions must be satisfied for the rule to match.

| Condition | Type | What it checks | Example | |-----------|----------|-------------------------------------------------------|----------------------------| | file | Glob | Whether a file matching the pattern exists in cwd | "package.json", "*.go" | | cwd | Regex | Whether the current directory path matches | "frontend", "/api$" | | env | Var name | Whether the environment variable is set and non-empty | "CI", "DOCKER" |


Specificity Scoring

Each condition in a rule that is defined and satisfied scores 1 point. The rule with the highest total score wins.

  • A rule with file + cwd + env all matching scores 3.
  • A rule with only file matching scores 1.
  • When two rules have the same score, the later rule in the array wins (CSS-style cascade).
  • If no rules match and a fallback is defined, the fallback command runs.

CLI Usage

run-ctx <alias> [args...]       Run alias, pass through additional args
run-ctx --list, -l              Show all aliases and matched commands for current context
run-ctx --dry-run <alias>       Show what command would run without executing
run-ctx --edit, -e              Launch the TUI editor (run-ctx-editor)
run-ctx --completions <shell>   Generate shell completion script (bash, zsh, fish)
run-ctx --shell                 Run command in shell (allows pipe, redirect, &&)
run-ctx --verbose, -V           Show detailed rule evaluation logs
run-ctx --help, -h              Show help message
run-ctx --version, -v           Show version information

Examples

# Run the "test" alias with extra args
run-ctx test --coverage

# See what every alias resolves to in the current directory
run-ctx --list

# Preview the resolved command without executing
run-ctx --dry-run build

# Open the interactive config editor
run-ctx --edit

# Configure bash tab-completion for rc/run-ctx
eval "$(rc --completions bash)"

TUI Editor

Launch with run-ctx-editor or run-ctx --edit. The editor provides three screens for managing your config interactively.

AliasList (home screen)

| Key | Action | |-----------|-----------------------| | Up / Down | Navigate aliases | | Enter | Edit selected alias | | n | Create new alias | | d | Delete selected alias | | q / Esc | Quit editor |

RuleEditor (alias detail)

| Key | Action | |-----------|----------------------| | Up / Down | Navigate rules | | Enter | Edit selected rule | | n | Add new rule | | d | Delete selected rule | | j | Move rule down | | J | Move rule up | | q / Esc | Back to alias list |

RuleDetail (rule fields)

| Key | Action | |-----------|-------------------------------------------| | Up / Down | Navigate fields (command, file, cwd, env) | | Enter | Edit field value | | Esc | Save and go back |


Config Example

A realistic config for a polyglot developer:

{
  "aliases": {
    "dev": {
      "description": "Start development server",
      "rules": [
        { "match": { "file": "package.json" }, "command": "npm run dev" },
        { "match": { "file": "composer.json" }, "command": "php artisan serve" },
        { "match": { "file": "Cargo.toml" }, "command": "cargo watch -x run" },
        { "match": { "file": "go.mod" }, "command": "go run ." }
      ]
    },
    "test": {
      "description": "Run tests",
      "rules": [
        { "match": { "file": "package.json" }, "command": "npm test" },
        { "match": { "file": "composer.json" }, "command": "php artisan test" },
        { "match": { "file": "Cargo.toml" }, "command": "cargo test" },
        { "match": { "file": "go.mod" }, "command": "go test ./..." }
      ]
    },
    "build": {
      "description": "Build project",
      "rules": [
        { "match": { "file": "package.json" }, "command": "npm run build" },
        { "match": { "file": "Cargo.toml" }, "command": "cargo build --release" },
        { "match": { "file": "go.mod" }, "command": "go build -o bin/app ." }
      ],
      "fallback": "echo 'No build configured'"
    },
    "lint": {
      "description": "Lint code",
      "rules": [
        { "match": { "file": "biome.json" }, "command": "npx biome check ." },
        { "match": { "file": ".eslintrc*" }, "command": "npx eslint ." },
        { "match": { "file": "Cargo.toml" }, "command": "cargo clippy" },
        { "match": { "file": "go.mod" }, "command": "golangci-lint run" }
      ]
    },
    "deploy": {
      "description": "Deploy (CI only)",
      "rules": [
        {
          "match": { "file": "package.json", "env": "CI" },
          "command": "npm run deploy"
        }
      ]
    }
  }
}

Available Scripts

Development Scripts

| Script | Description | |--------|-------------| | npm run dev | Run tests in watch mode | | npm run dev:typescript | Run TypeScript type checking in watch mode |

Build Scripts

| Script | Description | |--------|-------------| | npm run build | Bundle the CLI with esbuild |

Lint Scripts

| Script | Description | |--------|-------------| | npm run lint | Run type checking, linting, formatting, and audit | | npm run lint:check | Check code for linting issues with Biome | | npm run lint:fix | Check and fix linting issues with Biome | | npm run lint:format | Format all files with Biome | | npm run lint:types | Run TypeScript type checking only | | npm run lint:audit | Run npm audit |

Testing Scripts

| Script | Description | |--------|-------------| | npm test | Run all tests (unit, react) | | npm run test:unit | Run unit tests | | npm run test:react | Run React component tests |


Tech Stack

Core

Build & Development

UI Components


Project Structure

run-ctx/
├── src/
│   ├── app/                    # Application entry points
│   │   ├── cli.ts              # CLI entry point
│   │   ├── editor-cli.tsx      # TUI editor entry point
│   │   └── app.tsx             # Main application component
│   ├── components/             # React components
│   │   ├── AliasList/          # Home screen - list all aliases
│   │   ├── RuleEditor/         # Edit rules for an alias
│   │   └── RuleDetail/         # Edit individual rule fields
│   ├── types/                  # TypeScript type definitions
│   │   ├── Alias/              # Alias type definitions
│   │   ├── Color/              # Color constants and types
│   │   ├── Config/             # Config type definitions
│   │   └── Rule/               # Rule type definitions
│   └── utils/                  # Utility functions
│       ├── config/             # Load/save config from ~/.config/run-ctx
│       ├── executor/           # Execute resolved commands
│       ├── matcher/            # Match rules based on conditions
│       └── resolver/           # Resolve alias to command
├── docs/                       # Documentation and plans
├── dist/                       # Built output
├── biome.json                  # Biome configuration
├── tsconfig.json               # TypeScript configuration
├── tsconfig.app.json           # App TypeScript configuration
├── vitest.unit.config.ts       # Unit test configuration
├── vitest.react.config.ts      # React test configuration
├── esbuild.config.js           # esbuild bundler configuration
└── package.json

Versioning

This project uses a custom versioning scheme: MAJORYY.MINOR.PATCH

| Part | Description | Example | |------|-------------|---------| | MAJOR | Major version number | 1 | | YY | Year (last 2 digits) | 26 for 2026 | | MINOR | Minor version | 0 | | PATCH | Patch version | 0 |

Example: 126.0.0 = Major version 1, released in 2026, minor 0, patch 0

This format allows you to quickly identify both the major version and the year of release at a glance.


Style Guide

Conventions for contributing to this project. All rules are enforced by code review; Biome handles formatting and lint.

Exports

  • Named exports only — no export default. Every module uses export function, export const, or export type.
  • import type — always use import type for type-only imports.
  • .js extensions — all relative imports use explicit .js extensions (ESM requirement).

File Structure

src/
├── app/              # Entry points, root component, providers wrapper
├── components/       # React components (PascalCase directories)
│   └── MyComponent/
│       ├── index.tsx
│       ├── MyComponent.types.ts
│       └── MyComponent.test.tsx
├── hooks/            # Custom hooks (camelCase directories)
│   └── useMyHook/
│       ├── index.ts
│       ├── useMyHook.types.ts
│       └── useMyHook.test.tsx
├── providers/        # React context providers (PascalCase directories)
│   └── MyProvider/
│       ├── index.tsx
│       ├── MyProvider.types.ts
│       └── MyProvider.test.tsx
├── types/            # Shared type definitions (PascalCase directories)
│   └── MyType/
│       ├── index.ts
│       └── MyType.test-d.ts
└── utils/            # Pure utility functions (camelCase directories)
    └── myUtil/
        ├── index.ts
        └── myUtil.test.ts

Components & Providers

  • Components use function declarations: export function MyComponent(props: MyComponentProps) {}
  • Providers use React.FC arrow syntax: export const MyProvider: React.FC<Props> = ({ children }) => {}
  • Props are defined in a co-located .types.ts file using the interface keyword.
  • Components receive data via props — never read process.stdout or global state directly.

Types

  • Use type for data shapes and unions. Use interface for component props.
  • Shared types live in src/types/TypeName/index.ts with a co-located TypeName.test-d.ts.
  • Local types live in co-located .types.ts files — never inline in implementation files.
  • No duplicate type definitions — import from the canonical source.
  • Runtime constants must not live in src/types/ — use .consts.ts files.

Constants

  • Named constants go in .consts.ts files (e.g., useMyHook.consts.ts).
  • No magic numbers in implementation files — extract to named constants.

Testing

  • Every module has a co-located test file.
  • Components: ComponentName.test.tsx
  • Hooks: hookName.test.tsx
  • Utils: utilName.test.ts
  • Types: TypeName.test-d.ts (type-level tests using expectTypeOf/assertType)

License

ISC