by edlsh
Interactive decision-gating extension for pi — lets AI agents ask users questions with multiple-choice and freeform answers
# Add to your Claude Code skills
git clone https://github.com/edlsh/pi-ask-userGuides for using ai agents skills like pi-ask-user.
Last scanned: 6/21/2026
{
"issues": [
{
"type": "npm-audit",
"message": "@earendil-works/pi-coding-agent: Pi Agent: Potential XSS in HTML session exports via Markdown URL sanitization bypass",
"severity": "high"
}
],
"status": "WARNING",
"scannedAt": "2026-06-21T08:34:19.329Z",
"npmAuditRan": true,
"pipAuditRan": true,
"promptInjectionRan": true
}See how pi-ask-user compares with popular alternatives.
pi-ask-user is an open-source ai agents skill for AI coding assistants such as Claude Code, Codex CLI, and ChatGPT, built by edlsh. Interactive decision-gating extension for pi — lets AI agents ask users questions with multiple-choice and freeform answers. It has 177 GitHub stars.
pi-ask-user returned warnings in SkillsLLM's automated security scan. It has no critical vulnerabilities, but review the flagged issues in the Security Report section before adding it to your workflow.
Clone the repository with "git clone https://github.com/edlsh/pi-ask-user" and add it to your Claude Code skills directory (see the Installation section above).
pi-ask-user is primarily written in TypeScript. It is open-source under edlsh on GitHub, so you can review or fork the full source.
Yes. SkillsLLM lists many other AI Agents skills you can browse and compare side by side. Open the AI Agents category from the badge at the top of this page, or use the Related Skills and comparison links further down to weigh pi-ask-user against similar tools.
No comments yet. Be the first to share your thoughts!
Requires a passing catalog security scan.
⚠️ Third-Party Software Notice
This skill is third-party open-source software developed and hosted independently on GitHub. SkillsLLM is an informational directory and does not control or maintain the underlying repository.
Any security checks, ratings, or warnings displayed by SkillsLLM are automated and limited in scope. They do not constitute a security certification or guarantee that the software is safe, error-free, or free from malicious code, vulnerabilities, compromised dependencies, or prompt-injection risks.
Review the source code, permissions, dependencies, and configuration before installing or running any third-party skill. Use is at your own risk. To the maximum extent permitted by applicable law, SkillsLLM is not liable for losses arising from third-party software.
A Pi package that adds an interactive ask_user tool for collecting user decisions during an agent run.

High-quality video: ask-user-demo.mp4
overlay (modal, default) or inline (rendered directly in the flow)alt+o by default, configurable per call, via env var, or in ask-user.json) 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 backpromptSnippet and promptGuidelinesherdr:blocked lifecycle events while waiting for interactive inputdetails for session state reconstructionask-user skill for mandatory decision-gating in high-stakes or ambiguous tasksask-userThis package now ships a skill at skills/ask-user/SKILL.md that nudges/mandates the agent to use ask_user when:
The skill follows a "decision handshake" flow:
ask_userSee: skills/ask-user/references/ask-user-skill-extension-spec.md.
pi install npm:pi-ask-user
The registered tool name is:
ask_user| Parameter | Type | Default | Description |
|---|---|---|---|
question |
string? |
— | The question to ask the user. Each call needs question or questions; when both are sent, question is only shown as the batch heading |
questions |
{question, context?, options?, allowMultiple?, allowFreeform?}[]? |
— | 2-4 independent questions shown together, used instead of question. Set context, options, allowMultiple, and allowFreeform on each entry; top-level values for them are ignored. The remaining parameters apply to the whole batch. See Asking several questions at once |
context |
string? |
— | Relevant context summary shown before the question |
options |
{title, description?}[]? |
[] |
Multiple-choice options. The schema is a flat object shape (no anyOf, which some provider proxies strip or reject); plain strings and common alias keys (label, text, value, name, option) are still accepted at runtime |
allowMultiple |
boolean? |
false |
Enable multi-select mode |
allowFreeform |
boolean? |
true |
Add a "Type something" freeform option |
allowComment |
boolean? |
env var, settings file, or 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, settings file, or "overlay" |
Controls custom UI rendering: overlay shows the centered modal (current behavior), inline renders without overlay framing |
singleSelectLayout |
"auto" | "list"? |
env var, settings file, or "auto" |
Use the responsive details pane automatically or always render descriptions below their options |
contextExpanded |
boolean? |
env var, settings file, or false |
Start with oversized context expanded. Per-call value overrides PI_ASK_USER_CONTEXT_EXPANDED |
overlayToggleKey |
string? |
env var, settings file, 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, settings file, 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 |
{
"question": "Which option should we use?",
"context": "We are choosing a deploy target.",
"options": [
{ "title": "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.
Use questions for 2-4 decisions that are independent of each other and whose prerequisites are already settled. Anything that depends on another answer belongs in a later ask_user call.
{
"questions": [
{
"question": "Which database should the service use?",
"context": "Both are supported by the ORM; the service is single-region.",
"options": [
{ "title": "Postgres", "description": "Managed, JSONB support" },
{ "title": "SQLite", "description": "No extra infrastructure" }
]
},
{
"question": "Which deploy target?",
"options": [{ "title": "Fly.io" }, { "title": "Cloudflare" }],
"allowFreeform": false
},
{ "question": "Anything else we should know before starting?" }
],
"timeout": 300000
}
The prompt shows one page per question plus a review page. Confirming a page records its answer and moves to the next unanswered question, then to the review page. tab / shift+tab switch pages without losing filters, drafts, or checked options, and number keys on the review page jump back to a question. Only the review page submits. If questions are still unanswered, the first press warns and a second press submits them as skipped. Questions without options open straight in a text editor.
In RPC/headless mode the questions are asked one after another with the fallback dialogs. There is no review page there, so cancelling any question cancels the whole batch.
Defaults can be configured in a settings file or through environment variables. Per-call tool parameters override both.
Create ~/.pi/agent/ask-user.json (or <agent-dir>/ask-user.json when PI_CODING_AGENT_DIR is set):
{
"displayMode": "inline",
"singleSelectLayout": "list",
"allowComment": false,
"contextExpanded": false,
"overlayToggleKey": "alt+o",
"commentToggleKey": "ctrl+g",
"emitFullEvents": false
}
All keys are optional; unknown keys and wrong-typed values are ignored, matching the env-var behavior. Shortcut keys accept the same "off" / "none" / "disabled" disables and Pi-TUI key specs as the tool parameters. The file is read on every ask_user call, so edits apply without restarting Pi. A file that exists but is not valid JSON fails the call with the path in the error, so a configuration mistake is visible instead of silently ignored.
Privacy: Setting "emitFullEvents": true in this file shares answers and prompt context with other installed extensions through lifecycle events, including selections, comments, freeform text, and offered options on cancellation. Keep it false (the default) unless an extension you trust needs that data. See Events and #51.
Configure per-launch defaults by setting these in your shell profile (~/.zshrc, ~/.bash_profile, etc.):
export PI_ASK_USER_DISPLAY_MODE=inline
export PI_ASK_USER_SINGLE_SELECT_LAYOUT=list
export PI_ASK_USER_ALLOW_COMMENT=true
export PI_ASK_USER_OVERLAY_TOGGLE_KEY=alt+h
export PI_ASK_USER_COMMENT_TOGGLE_KEY=alt+c
export PI_ASK_USER_CONTEXT_EXPANDED=true
Environment variables must be present in the process that launches Pi. If Pi is launched from a desktop app or a different shell, changes in ~/.zshrc may not be inherited; launch Pi from a terminal where echo $PI_ASK_USER_DISPLAY_MODE shows the expected value. Environment variables win over ask-user.json, so one-off launches such as PI_ASK_USER_DISPLAY_MODE=inline pi still work while the settings file holds the persistent defaults.
Effective order:
displayMode parameter (if provided)PI_ASK_USER_DISPLAY_MODE (if set to "overlay" or "inline")displayMode in ask-user.json"overlay"Unrecognised values are silently ignored and fall back to "overlay".
Effective order:
singleSelectLayout parameter (if provided)PI_ASK_USER_SINGLE_SELECT_LAYOUT (when set to list or auto)singleSelectLayout in ask-user.jsonautoauto shows the details pane on wide terminals. list keeps descriptions below their options at every width.
Effective order:
allowComment parameter (if provided)PI_ASK_USER_ALLOW_COMMENT (true, 1, yes, or on; corresponding false value