pi-ask-user
Interactive ask_user tool for pi-coding-agent with searchable split-pane selection UI, multi-select, and freeform input
Package details
Install pi-ask-user from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-ask-user- Package
pi-ask-user- Version
0.9.0- Published
- May 4, 2026
- Downloads
- 5,606/mo · 2,480/wk
- Author
- edlsh
- License
- MIT
- Types
- extension, skill
- Size
- 84.7 KB
- Dependencies
- 0 dependencies · 3 peers
Pi manifest JSON
{
"extensions": [
"./index.ts"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README
pi-ask-user
A Pi package that adds an interactive ask_user tool for collecting user decisions during an agent run.
Demo

High-quality video: ask-user-demo.mp4
Features
- Searchable single-select option lists with wrapped titles and descriptions
- Responsive split-pane details preview on wide terminals with single-column fallback on narrow terminals
- Multi-select option lists
- Optional freeform responses
- User-toggleable extra context on structured selections
- Context display support
- Configurable display mode:
overlay(modal, default) orinline(rendered directly in the flow) - Runtime overlay toggle: press the configured overlay-toggle key (
alt+oby default, configurable per call or via env var) while the prompt is open to temporarily hide/show the popup so you can read prior agent output, then press it again to bring it back - Pi-TUI-aligned keybinding and editor behavior
- Custom TUI rendering for tool calls and results
- System prompt integration via
promptSnippetandpromptGuidelines - Optional timeout for auto-dismiss in both overlay and fallback input modes
- Structured
detailson all results for session state reconstruction - Graceful fallback when interactive UI is unavailable
- Bundled
ask-userskill for mandatory decision-gating in high-stakes or ambiguous tasks
Bundled skill: ask-user
This package now ships a skill at skills/ask-user/SKILL.md that nudges/mandates the agent to use ask_user when:
- architectural trade-offs are high impact
- requirements are ambiguous or conflicting
- assumptions would materially change implementation
The skill follows a "decision handshake" flow:
- Gather evidence and summarize context
- Ask one focused question via
ask_user - Wait for explicit user choice
- Confirm the decision, then proceed
See: skills/ask-user/references/ask-user-skill-extension-spec.md.
Install
pi install npm:pi-ask-user
Tool name
The registered tool name is:
ask_user
Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
question |
string |
required | The question to ask the user |
context |
string? |
— | Relevant context summary shown before the question |
options |
(string | {title, description?})[]? |
[] |
Multiple-choice options |
allowMultiple |
boolean? |
false |
Enable multi-select mode |
allowFreeform |
boolean? |
true |
Add a "Type something" freeform option |
allowComment |
boolean? |
false |
Expose a user-toggleable extra-context option in the custom UI (ctrl+g or the toggle row) and collect an optional comment in fallback dialogs |
displayMode |
"overlay" | "inline"? |
env var or "overlay" |
Controls custom UI rendering: overlay shows the centered modal (current behavior), inline renders without overlay framing |
overlayToggleKey |
string? |
env var or "alt+o" |
Shortcut for hiding/showing the overlay popup (overlay mode only). Pi-TUI key spec, e.g. "alt+o", "ctrl+shift+h". Pass "off" to disable. |
commentToggleKey |
string? |
env var or "ctrl+g" |
Shortcut for toggling the optional comment/extra-context row when allowComment: true. Pass "off" to disable. |
timeout |
number? |
— | Auto-dismiss after N ms and return null if the prompt times out |
Example usage shape
{
"question": "Which option should we use?",
"context": "We are choosing a deploy target.",
"options": [
"staging",
{ "title": "production", "description": "Customer-facing" }
],
"allowMultiple": false,
"allowFreeform": true,
"allowComment": true,
"displayMode": "inline"
}
displayMode: "inline" uses the same interaction logic but skips overlay mode when calling ctx.ui.custom(...). RPC/headless fallback behavior is unchanged.
Personal preferences via environment variables
Configure your defaults globally by setting these in your shell profile (~/.zshrc, ~/.bash_profile, etc.):
export PI_ASK_USER_DISPLAY_MODE=inline
export PI_ASK_USER_OVERLAY_TOGGLE_KEY=alt+h
export PI_ASK_USER_COMMENT_TOGGLE_KEY=alt+c
Display mode
Effective order:
- Per-call
displayModeparameter (if provided) PI_ASK_USER_DISPLAY_MODE(if set to"overlay"or"inline")- Fallback default:
"overlay"
Unrecognised values are silently ignored and fall back to "overlay".
Shortcuts
Effective order for both overlayToggleKey and commentToggleKey:
- Per-call parameter (if provided)
- Matching env var (
PI_ASK_USER_OVERLAY_TOGGLE_KEY/PI_ASK_USER_COMMENT_TOGGLE_KEY) - Built-in defaults:
alt+oandctrl+g
Pass "off", "none", or "disabled" (at any level) to disable the shortcut entirely. Invalid specs are silently dropped and the next source is used. Specs follow the Pi-TUI KeyId format: [mod+]...key where modifiers are ctrl, shift, alt, super, in any order, joined by + (e.g. ctrl+g, alt+shift+x, escape, tab).
Controls
While an ask_user prompt is open:
| Key | Action |
|---|---|
alt+o (configurable via overlayToggleKey) |
Hide/show the overlay popup so you can read the agent's prior output. Available in overlay mode only. The first time you hide it, a notification reminds you which key brings it back. |
ctrl+g (configurable via commentToggleKey) |
Toggle the optional comment/extra-context row (when allowComment: true). |
enter |
Confirm the focused option, submit a freeform response, or submit/skip an optional comment. |
esc |
Clear the search filter, exit freeform/comment mode, or cancel the prompt. |
↑ / ↓ |
Navigate options. |
If you prefer never to see the overlay, set displayMode: "inline" per call or PI_ASK_USER_DISPLAY_MODE=inline globally.
Result details
All tool results include a structured details object for rendering and session state reconstruction:
type AskResponse =
| { kind: "selection"; selections: string[]; comment?: string }
| { kind: "freeform"; text: string };
interface AskToolDetails {
question: string;
context?: string;
options: QuestionOption[];
response: AskResponse | null;
cancelled: boolean;
}
Changelog
See CHANGELOG.md.