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

@sundaeswap/sprinkles

v0.8.2

Published

A TypeScript library for building interactive CLI menus and TUI applications with TypeBox schema validation

Readme

Sprinkles

Note: This is an early release (v0.x). The API may change between minor versions as we refine the library based on community feedback.

A TypeScript library for building action-centric CLI applications with TypeBox schema validation. Define your actions once, and Sprinkles exposes them through three facades: an interactive TUI, a CLI with auto-generated flags and help, and an MCP server for AI agent integration.

Architecture

Sprinkles follows an action-centric design. The core building block is an IAction — a typed, self-describing unit of work with input/output schemas:

                ┌──────────────┐
                │   Actions    │  ← define once
                │  (IAction)   │
                └──────┬───────┘
                       │
          ┌────────────┼────────────┐
          ▼            ▼            ▼
     ┌─────────┐ ┌─────────┐ ┌─────────┐
     │   TUI   │ │   CLI   │ │   MCP   │  ← three facades
     │ (menu)  │ │ (flags) │ │ (tools) │
     └─────────┘ └─────────┘ └─────────┘
  • TUI — Interactive menu-driven interface. Users select actions from a menu, and Sprinkles auto-generates prompts from input schemas.
  • CLI — Non-interactive command execution. Actions become subcommands with auto-generated --flags from input schemas and structured JSON output.
  • MCP — Model Context Protocol server. Actions are exposed as tools that AI agents can discover and call with typed JSON input/output.

Sprinkle.run() detects the mode from process.argv and dispatches automatically.

Features

  • Action-centric: Define actions with TypeBox input/output schemas; get TUI, CLI, and MCP for free
  • Schema-driven UI: Automatic prompt generation from TypeBox schemas
  • Multi-profile support: Multiple named profiles with independent settings
  • Persistent settings: JSON-based storage with BigInt support and optional encryption
  • 14 built-in actions: Profile management, settings, wallet operations, and transaction handling
  • Cardano integration: Built-in helpers for Blaze SDK wallet and provider management
  • Type-safe: Full TypeScript support with type inference from schemas

Installation

npm install @sundaeswap/sprinkles

Optional peer dependencies:

  • @blaze-cardano/sdk + @blaze-cardano/query — for wallet and transaction actions
  • @modelcontextprotocol/sdk — for MCP mode

Quick Start

import { Type } from "@sinclair/typebox";
import type { TSchema } from "@sinclair/typebox";
import {
  Sprinkle,
  promptAndExecute,
  getBuiltinActions,
  NetworkSchema,
  ProviderSettingsSchema,
  WalletSettingsSchema,
} from "@sundaeswap/sprinkles";
import type { AnyAction, IAction, IMenu } from "@sundaeswap/sprinkles";

// 1. Define your settings schema
const AppSettings = Type.Object({
  network: NetworkSchema,
  provider: ProviderSettingsSchema,
  wallet: WalletSettingsSchema,
});

// 2. Define a custom action
const greetAction: IAction<
  { name: string },
  { greeting: string },
  TSchema
> = {
  name: "greet",
  description: "Say hello to someone.",
  category: "app",
  inputSchema: Type.Object({
    name: Type.String({ description: "Person to greet" }),
  }),
  outputSchema: Type.Object({
    greeting: Type.String(),
  }),
  execute: async (input) => ({
    greeting: `Hello, ${input.name}!`,
  }),
};

// 3. Define a TUI menu
const menu: IMenu<typeof AppSettings> = {
  title: "My App",
  items: [
    {
      title: "Greet someone",
      action: async (sprinkle) => {
        const result = await promptAndExecute(sprinkle, greetAction);
        if (result.success) {
          console.log(result.data.greeting);
        } else if (result.error.code !== "USER_CANCELLED") {
          console.error("Error:", result.error.message);
        }
      },
    },
  ],
};

// 4. Run — mode is detected automatically
await Sprinkle.run({
  type: AppSettings,
  storagePath: `${process.env["HOME"]}/.config/my-app`,
  menu,
  actions: [
    greetAction as unknown as AnyAction<typeof AppSettings>,
    ...getBuiltinActions<typeof AppSettings>(),
  ],
});

This single entry point gives you:

# TUI mode (interactive)
my-app

# CLI mode
my-app greet --name Alice
my-app list-profiles
my-app get-settings

# MCP mode (AI agent)
my-app --mcp

# Help
my-app --help
my-app greet --help

Actions

Defining Actions

An action is an object implementing IAction<TInput, TOutput, TSettings>:

const myAction: IAction<
  { url: string; timeout?: number },
  { status: number },
  TSchema
> = {
  name: "check-health",
  description: "Check if a service is healthy.",
  category: "ops",
  inputSchema: Type.Object({
    url: Type.String({ description: "Service URL" }),
    timeout: Type.Optional(Type.Number({ description: "Timeout in ms", default: 5000 })),
  }),
  outputSchema: Type.Object({
    status: Type.Number(),
  }),
  execute: async (input, context) => {
    // context.settings gives you the current profile's settings
    // context.sprinkle gives you the Sprinkle instance
    const res = await fetch(input.url, { signal: AbortSignal.timeout(input.timeout ?? 5000) });
    return { status: res.status };
  },
};

Built-in Actions

Sprinkles includes 14 built-in actions available via getBuiltinActions():

| Category | Action | Description | |----------|--------|-------------| | sprinkles | list-profiles | List all profiles | | sprinkles | get-profile | Get profile metadata and settings | | sprinkles | set-profile | Switch active profile | | sprinkles | create-profile | Create a new profile | | sprinkles | delete-profile | Delete a profile | | sprinkles | get-settings | Get current settings | | sprinkles | update-settings | Update settings | | wallet | get-wallet-address | Get wallet address | | wallet | get-wallet-balance | Get ADA and token balances | | wallet | get-wallet-utxos | Get UTxO set | | wallet | sign-transaction | Sign a transaction (hot wallet only) | | wallet | submit-transaction | Submit a signed transaction | | wallet | sign-and-submit | Sign and submit in one step | | transaction | decode-transaction | Decode transaction CBOR |

Running Actions Programmatically

import { executeAction } from "@sundaeswap/sprinkles";

const result = await executeAction(myAction, { url: "https://example.com" }, context);
if (result.success) {
  console.log(result.data.status);
} else {
  console.error(result.error.code, result.error.message);
}

Built-in Schemas

Sprinkles exports common Cardano schemas for use in your settings:

NetworkSchema

Type.Union([Type.Literal("mainnet"), Type.Literal("preview"), Type.Literal("preprod")])

ProviderSettingsSchema

Type.Union([
  Type.Object({
    type: Type.Literal("blockfrost"),
    projectId: Type.String({ minLength: 1, title: "Blockfrost Project ID" }),
  }),
  Type.Object({
    type: Type.Literal("maestro"),
    apiKey: Type.String({ minLength: 1, title: "Maestro API Key" }),
  }),
])

WalletSettingsSchema

Type.Union([
  Type.Object({
    type: Type.Literal("hot"),
    privateKey: Type.String({ minLength: 1, title: "Hot Wallet Private Key", sensitive: true }),
  }),
  Type.Object({
    type: Type.Literal("cold"),
    address: Type.String({ minLength: 1, title: "Cold Wallet Address" }),
  }),
])

Examples

See examples/ for runnable examples:

  • demo-app/ — Full-featured testing harness exercising all built-in actions across TUI, CLI, and MCP modes
  • action-example.ts — Multi-mode example with a custom action
  • action-in-menu.ts — TUI menu integration patterns

License

MIT