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

pi-dstui

v0.1.1

Published

Lisp DSL runtime for composable, on-demand TUI components

Downloads

328

Readme

tui

https://github.com/user-attachments/assets/4e62e1ad-fd89-4266-b615-a0d0a344da12

Rich, interactive terminal UI components for pi agent

— defined in a small Lisp DSL, persisted to disk, and rendered as full-screen overlays on demand.

Most agent interactions collapse to text: the agent asks a question, you type an answer, and both sides guess at structure. tui replaces that back-and-forth with purpose-built input widgets. Instead of typing "option 2" in response to a numbered list, you navigate a radio picker. Instead of describing a number with a note about the valid range, you turn a rotary dial. The agent gets a typed value; you get a clear, keyboard-driven UI.

This makes tui a single replacement for question-prompt plugins, checklist plugins, checkbox plugins, and any other extension whose job is structured input — while keeping the entire widget definition inside the conversation context as a tiny Lisp source file.


Install

pi install npm:tui

Or for a project-local install:

pi install -l npm:tui

After install, pi loads the extension automatically. No configuration needed.


Use cases

Confirmation dialogs

Replace yes/no text prompts with a keyboard-navigable confirm widget. The agent defines it once and reuses it anywhere a destructive action needs approval.

Radio and checklist pickers

Replace numbered-list answers with a real picker. The agent passes a list of options; you select with arrow keys and confirm with Enter. The return value is the chosen item, not a string to parse.

Multi-step forms

Chain multiple overlays to collect structured input across several fields — filenames, environment names, feature flags — without a free-text round-trip for each one.

Progress and status displays

Render progress bars, gauges, and live-updating dashboards during long-running tasks. Timers drive re-renders without waiting for a new tool call.

Domain-specific controls

When a project has a recurring input pattern — selecting from a config enum, adjusting a numeric threshold, picking a deployment target — the agent can define a custom component for it once and save it to .pi/ui-components/. Every subsequent conversation in that project gets the control for free.


pi tools

Installing tui registers two tools in the pi agent.

tui_define_component

Saves a Lisp DSL module to .pi/ui-components/<name>.lisp and registers it in the runtime. The agent calls this to create or update a component definition.

{
  "source": "(defcomponent confirm (message) ...)",
  "scope": "local",
  "module": "confirm"
}

| Parameter | Description | |-----------|-------------| | source | Full Lisp module source — one or more defcomponent / defview forms | | scope | "local" (project, .pi/ui-components/) or "global" (~/.pi/agent/ui-components/). Default: "local" | | module | File/module name. Inferred from the first defcomponent or defview name if omitted |

Global components are available in every project. Local components are scoped to the current working directory.

tui_create_dynamic_ui

Launches a saved component by name as a full-screen overlay and returns the emitted value to the agent.

{
  "componentId": "confirm-delete-123",
  "type": "confirm",
  "title": "Confirm deletion",
  "config": { "message": "Delete production database?" }
}

| Parameter | Description | |-----------|-------------| | type | Component name as registered by tui_define_component | | config | Props object — keys map to the component's param list | | title | Displayed in the overlay header | | componentId | Unique identifier for this invocation |

Returns the value passed to (emit ...) in the DSL, or null if the user dismisses with Escape / Ctrl+C.

Hotload: the component's source file is re-read from disk on every tui_create_dynamic_ui call. Edit a .lisp file and the next invocation picks up the change without restarting the agent.


Skill

Installing tui also registers the tui-runtime-components skill, which gives the agent:

  • Full DSL syntax reference and layout primitives
  • A component catalog with ready-to-use patterns (radio list, rotary encoder, progress gauge)
  • Guidance on when to define a new component vs. reuse a saved one

The agent uses the skill automatically when writing DSL source — you do not need to instruct it.


Hotload

Every tui_create_dynamic_ui call re-reads the component's source file from disk before instantiation:

.pi/ui-components/
  confirm.lisp          ← edit here, runs immediately on next call
  my-picker.lisp
  rotary-encoder.lisp

The load order:

  1. Look up the component name in the in-memory index
  2. Re-read its .lisp file from disk and re-compile
  3. If not yet registered, scan local then global directories for <name>.lisp
  4. Instantiate the freshly compiled ComponentDef

This means the agent can call tui_define_component to write a new version of a component, then immediately call tui_create_dynamic_ui to run it — all within the same message.


Bundled components

The package ships three ready-to-use components in .pi/ui-components/:

| Component | Description | |-----------|-------------| | radio-list | Single-select list with keyboard navigation and optional pre-selection | | rotary-encoder | Numeric dial with configurable min, max, step, and initial value | | progress-gauge | Animated progress display driven by a timer |

The agent can use these directly or use them as templates when defining new ones.


Writing your own components

See docs/dsl.md for the full DSL reference — layout primitives, state, bindings, timers, control flow, and built-in functions.


Programmatic API

The runtime is also importable as a library for use in other pi extensions or tools:

import { compileModule, instantiate, ModuleLoader } from "tui";

See docs/api.md for the full API reference.


Package structure

index.ts               pi extension entry — registers tui_define_component and tui_create_dynamic_ui
src/
  parser.ts            Lisp S-expression parser
  runtime.ts           DSL evaluator, layout engine, component instantiation
  loader.ts            ModuleLoader — persistence and hotload
  runner.ts            makeUiRunner — pi-tui overlay adapter
  index.ts             Public API exports
.pi/
  skills/
    tui-runtime-components/   Skill loaded by pi agent
  ui-components/              Saved component files (created at runtime)
docs/
  dsl.md               DSL language reference
  api.md               Programmatic API reference