@timmyjl12/pi-ask-user
v0.3.0
Published
Structured multiple-choice questions for the pi coding agent — ask the user up to 4 questions with options, descriptions, markdown previews, multi-select, per-selection notes, and free-text answers.
Maintainers
Readme
@timmyjl12/pi-ask-user
Structured multiple-choice questions for the pi coding agent — ask the user up to 4 questions in one tool call, with options, descriptions, markdown previews, multi-select, per-selection notes, and a free-text row. Opt-in session auto mode selects the working agent's recommended answers without interrupting you.
──────────────────────────────────────────────────────────────
← ■ Database □ Region ✓ Submit →
Which database should the service use?
> 1. PostgreSQL ✎ needs Redis
Battle-tested relational
2. SQLite
Embedded, zero-config
3. Type something.
Tab/←→ switch questions • ↑↓ move • n adds a note • Enter selects • Esc cancels
──────────────────────────────────────────────────────────────What it does
Registers one tool, ask_user, that the model calls when it needs your decisions instead of guessing or stopping to ask in plain text:
- 1–4 questions per call — batched, with a tab bar and answered/unanswered markers.
- 2–4 options per question — each with a label (≤60 chars), optional description, and optional markdown
previewshown for the focused option (single-select only; beside the list on wide terminals, below it on narrow ones). multiSelect— Space toggles, Enter submits the question with the whole toggled set.- Per-selection notes —
non any option opens a note editor bound to that choice; Enter saves (empty clears), Escape keeps the prior note. Each note rides its selection into the model's answer aslabel (note: text)— on single-select, multi-select, and RPC hosts alike. - Reserved
Type something.row — appended to every question automatically; the model cannot author it orOther, and supplying those labels fails closed with an exact constraint message. - Short
headerchips (≤16 chars) identify each question in the tab bar and the result. - Session auto mode — select the main agent's best-fit recommendations, with rationale and explicit automatic-answer attribution; no extra model call or dependency on pi-todo.
Auto mode
Manual is the default. Use the extension's own controls:
/ask-user Open the Manual / Auto menu
/ask-user auto on Enable automatic answers for this session
/ask-user auto off Return to manual questioning
/ask-user status Show the current modeThe footer shows Ask: auto while enabled. The setting survives reload/resume in the same session and follows its active branch; new/forked sessions start manual, even if they copy history. There is no global/project default or config file. Cancelling the mode menu changes nothing.
For ordinary questions, the main agent supplies its best-fit choice and a short reason, based on your instructions and project constraints. Auto mode validates and returns that choice immediately, without TUI/RPC dialogs—even on headless hosts. It does not blindly choose the first option or make another model call.
Example tool parameters (recommendation indices are zero-based, unlike the RPC manual input's 1-based indices):
{
"questions": [{
"question": "Which database should the local tool use?",
"header": "Database",
"options": [{ "label": "PostgreSQL" }, { "label": "SQLite" }],
"recommendation": {
"optionIndices": [1],
"reason": "Embedded storage matches the approved single-user scope."
}
}]
}Each recommendation needs unique integer indices within the supplied options and a nonblank reason of at most 500 characters. Single-select needs exactly one index; multi-select may recommend multiple options. Invalid metadata fails closed. Missing recommendations return guidance for the main agent to repair the call—not a routine dialog, arbitrary default, or user decline.
Human boundaries: use top-level "requiresHuman": true when real human-only facts or explicit approval are needed. It applies to the entire call and keeps the existing manual UI/no-UI behavior. Auto mode does not invent secrets, user notes, or human approval, and other extensions' confirmation/approval gates remain unaffected. A cancelled automatic call is not automatically retried.
Automatic results say the agent selected the answers and include the reason. details.source is "auto", each answer includes autoReason, and transcript lines show [auto: …]. Old/manual results retain their user attribution and optional notes.
pi-todo is unchanged: Pi continues naturally after an answer is returned. This extension adds no task runner, continuation loop, or timer.
Behavior
| Input | Result |
|---|---|
| Enter on an option | Selects it and advances (single-question runs submit immediately) |
| Enter on Type something. | Opens an inline editor; Enter submits, empty returns to the list |
| Space (multiSelect) | Toggles the focused option |
| n on an option | Opens that option's note editor; Enter saves (empty clears), Esc keeps the prior note. Notes travel with their selection; a note on an unselected option is dropped |
| Tab / Shift+Tab / ← / → | Switch questions (multi-question runs); answers and notes persist |
| Escape in the editor | Returns to the options |
| Escape on the options | Cancels the whole questionnaire — the model sees a decline, not an error |
Result envelopes are structured (details.questions, details.answers with parallel selected/wasCustom/notes arrays, details.cancelled) so the transcript renders ✓ header: answer lines, (wrote) markers for typed answers, and (note: …) for noted selections. Answers persisted before notes existed (v0.1.0 sessions) still render.
Host support
Manual calls and calls marked requiresHuman degrade by host capability. Ordinary auto-mode calls bypass this ladder and succeed without UI when recommendations are valid:
- Interactive (TUI) — the full questionnaire above.
- RPC hosts (e.g. editor integrations) — each question is asked through the host's native select/input dialogs via the extension UI sub-protocol: single-select via select dialog, multi-select via one typed input (comma-separated labels or 1-based indices; unmatched entries are kept as custom selections), and an optional note prompt after each matched selection (Enter to skip; skipping or dismissing a note never cancels the questionnaire).
- Headless (print/JSON) — a structured error telling the model the user never saw the questions, so it falls back to plain text instead of misreading a decline.
Install
pi install npm:@timmyjl12/pi-ask-userOr try it for one run without installing: pi -e npm:@timmyjl12/pi-ask-user. Restart pi (or run /reload) after installing. Requires pi 1.0 or newer.
Design provenance
Built for stability alongside the @timmyjl12/pi-* extension family, synthesizing four reference implementations — rpiv-ask-user-question (limits, reserved labels, fail-closed validation, RPC walker, n-key notes), edlsh/pi-ask-user (flat schema shapes, Esc ladder, typed-selections RPC multi-select), UniPi ask-user (width-crash regression discipline, per-option custom text), picc-tasks (tool description style) — plus the official pi question.ts/questionnaire.ts examples. Global/project config files, timeouts, fuzzy search, and task-continuation scheduling remain out of scope. Auto mode uses session lifecycle hooks only.
Development
npm install
npm run check # typecheck + full vitest suite (incl. widths 1-200 regression)License: MIT
