@zgltyq/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 @zgltyq/pi-ask-user from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:@zgltyq/pi-ask-user- Package
@zgltyq/pi-ask-user- Version
0.7.0- Published
- Apr 27, 2026
- Downloads
- 65/mo · 65/wk
- Author
- zgltyq
- License
- MIT
- Types
- extension, skill
- Size
- 75.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
@zgltyq/pi-ask-user
A fork of pi-ask-user with critical bug fixes and UX improvements for the interactive ask_user tool.
What's fixed in this fork
This fork addresses several issues found in the original extension:
Full-screen mode instead of overlay — Switches from a floating overlay (
overlay: true) to a full-screencustom()component. This eliminates image overlap issues in terminals using persistent graphics layers (Kitty, Ghostty, WezTerm).Selection not lost / LLM sees the answer — Adds a
safeOnDoneguard that preventsdone()from being called multiple times due to key-repeat, buffered escape sequences, or trailing input events. Previously, a valid selection could be silently overwritten withnull(cancelled).Timeout race condition fixed — Adds a
safeDonewrapper at the factory level that clears the timeout and removes the abort listener as soon as the user answers. Previously, answering before the timeout expired could still result in the timeout callback overwriting the answer withnull.Abort listener memory leak — The abort signal listener is now explicitly removed when
safeDoneresolves, preventing accumulation across tool calls.Performance: cached box borders —
BoxBorderTopandBoxBorderBottomare created once in the constructor and reused, instead of being allocated on everyrender()frame (which happens on every keystroke during search).Multi-select uses full terminal height — Removed the hardcoded 10-row cap on
MultiSelectList. Now dynamically computes available rows from terminal height, same as single-select.Removed all
as anycasts — Editor methods (getText,setText,focused) now use the properly typed public API instead of runtime reflection.dispose()cleanup — Added adispose()method that nulls out all callbacks (onSubmit,onCancel,onEnterFreeform) when the component closes, preventing closure references from leaking.Number keys work for 10+ options — Regex changed from
/^[1-9]$/to/^[1-9][0-9]?$/with bounds checking, so options beyond 9 can be selected by typing their number.Cleaned up unused code — Removed
ASK_USER_VERSION,createRequire, overlay constants, and the version label from the bottom border (saves one row of vertical space).
Demo

High-quality video: ask-user-demo.mp4
Fork notice
This is a maintained fork of the original edlsh/pi-ask-user. All fixes above are applied on top of v0.6.1. If you are using the original package, consider switching to this fork for the stability improvements.
Features
- Full-screen interactive UI — replaces the terminal, no overlay compositing issues with persistent images (e.g. Kitty graphics protocol)
- 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 with full terminal height utilization
- Optional freeform responses
- User-toggleable extra context on structured selections
- Context display support
- 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 full-screen 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 overlay (ctrl+g or the toggle row) and collect an optional comment in fallback dialogs |
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
}
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.