@timmyjl12/pi-ask-user

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.

Packages

Package details

extension

Install @timmyjl12/pi-ask-user from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@timmyjl12/pi-ask-user
Package
@timmyjl12/pi-ask-user
Version
0.4.0
Published
Nov 8, 2026
Downloads
350/mo · 19/wk
Author
timmyjl12
License
MIT
Types
extension
Size
90.9 KB
Dependencies
0 dependencies · 2 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

@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 preview shown 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 — n on 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 as label (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 or Other, and supplying those labels fails closed with an exact constraint message.
  • Short header chips (≤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.
  • Tab marker while a question waits — the terminal title gets a leading ? and the tab spinner stops, so a pending question never looks like work in progress.

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 mode
/ask-user history    Browse this session's ask_user answers

The 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.

History

/ask-user history lists the ask_user calls on the current session branch, newest first (latest 20): time, [user]/[auto]/[declined]/[partial], answers and notes. Pick one to see the full questions and auto reasons. It reads the session log on demand — the details already stored on each tool result — so it keeps no in-memory state, writes no new entries, and adds nothing to the model's context. Other sessions and abandoned branches are not shown.

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:

  1. Interactive (TUI) — the full questionnaire above. While it waits, the tab title carries a leading ? and pi's terminal progress spinner (terminal.showTerminalProgress) is paused; answering restores both, and the spinner only returns while the run is still live.
  2. 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).
  3. 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-user

Or 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