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

@juanbenjumea/pi-ask-herdr

v0.2.2

Published

Pi extension that adds an ask_user tool and integrates with Herdr notifications/agent state.

Readme

pi-ask-herdr

A Pi extension that adds an ask_user tool, with optional integration with Herdr agent state.

Structure

index.ts      # Pi auto-discovery entry point
src/
  tool.ts     # Tool registration and parameter schema
  ui.ts       # Batch question wizard (text, confirm, select, multiselect)
  herdr.ts    # Herdr event-bus integration
  options.ts  # Option normalization
  types.ts    # Shared TypeScript types

What it does

  • Registers an ask_user tool that asks the user one or more questions in a single call. Each question can be:
    • free-form text (type: "text")
    • yes/no confirmation (type: "confirm")
    • single choice from a list (type: "select")
    • multiple choices from a list (type: "multiselect")
  • All questions are answered inside one wizard UI:
    • a progress header (Question 2/4 + progress bar) when there are multiple questions
    • Enter submits and moves to the next question
    • Esc steps back one layer (custom input → options → previous question)
    • Ctrl+C cancels the whole batch immediately
    • previously answered questions keep their answers when navigating back
    • long option labels and descriptions wrap instead of being truncated, including continuous CJK text and long unbroken words
  • Agent-facing results stay compact (1 -> answer), while the tool result UI retains each question alongside its answer for easy review.
  • For select and multiselect, an "Other (custom)" option is always available so the user can type their own answer.
  • For confirm, you can enable the same custom option with "allow_custom": true.
  • No extra slash command is registered — only the ask_user tool.
  • When Pi runs inside a Herdr pane, it reports the pane state as blocked while waiting, shows the pending question(s) as a sidebar token, and restores both after the user answers. (Herdr itself shows a notification for blocked panes, so the extension no longer sends its own.)

Install

From npm (recommended)

pi install npm:pi-ask-herdr

Then reload Pi with /reload.

From git

pi install git:github.com/leset0ng/[email protected]

Manual

Copy or clone this directory into Pi's extensions folder:

# Global
cp -R pi-ask-herdr ~/.pi/agent/extensions/

# Or project-local
cp -R pi-ask-herdr .pi/extensions/

Then reload Pi with /reload, or test it directly with:

pi -e ~/.pi/agent/extensions/pi-ask-herdr/index.ts

Tool usage

A single question (one-element questions array):

{
  "questions": [
    {
      "question": "Which database should we use?",
      "type": "select",
      "options": ["PostgreSQL", "SQLite", "MySQL"]
    }
  ]
}

Multiple questions in one call:

{
  "questions": [
    {
      "question": "Which database should we use?",
      "type": "select",
      "options": [
        { "label": "PostgreSQL", "description": "Full-featured relational database" },
        { "label": "SQLite", "description": "Zero-config file database" },
        { "label": "MySQL", "description": "Widely used open-source RDBMS" }
      ]
    },
    {
      "question": "Which features should we enable?",
      "type": "multiselect",
      "options": ["dark mode", "notifications", "auto-save"]
    },
    {
      "question": "Any additional notes?",
      "type": "text"
    }
  ]
}

Parameters

| Name | Type | Required | Description | |--------------|------------|----------|---------------------------------------------------------------| | questions | object[] | yes | Questions to ask, in order (min 1). See per-question fields. | | timeout | number | no | Total timeout in milliseconds for the whole batch |

Per-question fields:

| Name | Type | Required | Description | |--------------|----------------------|----------|--------------------------------------------------| | question | string | yes | The question to display | | type | string | no | "text", "confirm", "select", "multiselect" (default: text) | | options | string[] or object[] | no | Required when type is select or multiselect. Each item can be a string or { "label": string, "description"?: string } | | default | string | no | Prefilled value for text input | | allow_custom | boolean | no | For confirm: also offer "Other (custom)" |

Key bindings

| Key | Action | |--------|-------------------------------------------------------------------| | Enter | Submit current question and advance (on the last question: finish) | | Esc | Step back one layer: custom input → options → previous question | | Ctrl+C | Cancel the whole batch immediately (answers are discarded) | | Space | Toggle an option in multiselect questions |

Herdr integration

The extension detects Herdr via the environment variables that Herdr injects into its panes:

  • HERDR_ENV=1
  • HERDR_SOCKET_PATH
  • HERDR_PANE_ID

If these are present, the extension:

  • emits herdr:blocked with active: true before prompting (the official Herdr Pi integration turns this into a blocked pane state, which Herdr surfaces as a notification)
  • reports the first pending question and remaining count as separate pane metadata tokens while waiting, allowing Herdr to truncate the question as the sidebar is resized while preserving +N
  • emits herdr:blocked with active: false and clears the token after the user answers

Sidebar display

For one question the row shows the question text itself. For multiple questions, Herdr renders the short count as a separate token, for example ❓ Which database should we use? · +2. Keeping $ask_count separate ensures it remains visible while $ask is truncated responsively as the sidebar is resized.

To render the tokens in Herdr's sidebar, add $ask and $ask_count to the same agent row in ~/.config/herdr/config.toml, then run herdr server reload-config:

[ui.sidebar.agents]
rows = [["state_icon", "workspace", "tab"], ["agent", "$ask", "$ask_count"]]

Without this config the token is simply not displayed; everything else works the same.

No extra configuration is required.

License

MIT