pi-ask-herdr

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

Packages

Package details

extension

Install pi-ask-herdr from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-ask-herdr
Package
pi-ask-herdr
Version
0.2.2
Published
Jul 22, 2026
Downloads
610/mo · 318/wk
Author
lesetong
License
MIT
Types
extension
Size
36.5 KB
Dependencies
0 dependencies · 4 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

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/pi-ask-herdr@v0.2.2

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