@mickyyy68/pi-ask

Grouped single- and multi-select questions for Pi, with custom answers and stable values.

Packages

Package details

extension

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

$ pi install npm:@mickyyy68/pi-ask
Package
@mickyyy68/pi-ask
Version
0.1.1
Published
Jul 13, 2026
Downloads
216/mo · 216/wk
Author
mickyyy68
License
MIT
Types
extension
Size
77.4 KB
Dependencies
0 dependencies · 3 peers
Pi manifest JSON
{
  "extensions": [
    "./index.ts"
  ],
  "image": "https://raw.githubusercontent.com/mickyyy68/pi-ask/main/demo-image.png"
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-ask

pi-ask adds an interactive ask_user tool to Pi. It lets the model group related clarification questions into one terminal questionnaire instead of guessing or interrupting the user with several plain-text prompts.

Grouped multi-select questionnaire in pi-ask

Features

  • Ask 1–4 related questions in one dialog.
  • Present 2–5 choices per question.
  • Mix single-select and multi-select questions.
  • Add a free-form custom answer to either selection mode.
  • Edit an existing custom answer, or submit it blank to remove it.
  • Return optional stable machine-readable values independently of display labels.
  • Review all answers before submitting.
  • Navigate with tabs, arrows, Enter, and Space.
  • Render safely in narrow terminals with ANSI-aware wrapping.
  • Run sequentially so multiple interactive tool calls cannot compete for focus.
┌ Scope ✓ ─ Features ─ Review ┐
│ Which features should ship? │
│ [x] Linting                 │
│ [ ] Formatting              │
│ [x] Tests                   │
│ [ ] Write my own answer…    │
│     Continue →              │
│                             │
│ ↑↓ move • Space/Enter toggle│
│ Tab switch • Esc dismiss    │
└─────────────────────────────┘

Installation

Install from npm:

pi install npm:@mickyyy68/pi-ask

Or install directly from GitHub:

pi install git:github.com/mickyyy68/pi-ask

Then restart Pi or run /reload in an existing interactive session.

From a local checkout:

pi install "$PWD"

Tool

The package registers one tool:

ask_user

Pi adds tool-specific guidance that encourages the model to group related questions, use multi-select only for non-exclusive choices, and provide stable values when labels are not reliable identifiers.

Minimal example

ask_user({
  questions: [
    {
      question: "Which database should the project use?",
      options: [
        {
          value: "postgres",
          label: "PostgreSQL",
          description: "Full relational database with production tooling."
        },
        {
          value: "sqlite",
          label: "SQLite",
          description: "Embedded database with minimal setup."
        }
      ]
    }
  ]
})

Grouped and multi-select example

ask_user({
  questions: [
    {
      id: "language",
      header: "Language",
      question: "Which language should the project use?",
      options: [
        { value: "typescript", label: "TypeScript" },
        { value: "python", label: "Python" }
      ]
    },
    {
      id: "features",
      header: "Features",
      question: "Which features should be included?",
      multiSelect: true,
      options: [
        { value: "auth", label: "Authentication" },
        { value: "api", label: "REST API" },
        { value: "jobs", label: "Background jobs" }
      ]
    }
  ]
})

Input schema

interface AskUserInput {
  questions: Array<{
    id?: string;
    header?: string;
    question: string;
    multiSelect?: boolean;
    options: Array<{
      value?: string;
      label: string;
      description?: string;
    }>;
  }>;
}
Field Behavior
questions Between 1 and 4 questions.
id Optional stable question identifier; defaults to q1, q2, and so on.
header Optional tab label, maximum 16 characters; defaults to Q1, Q2, and so on.
question Non-empty question text.
multiSelect Defaults to false.
options Between 2 and 5 choices.
value Optional stable value; defaults to the trimmed label.
label Non-empty display label, maximum 60 characters.
description Optional text rendered below the option.

Question IDs must be unique within an invocation. Option values must be unique within their question. Runtime control labels such as Write my own answer… and Continue → are reserved.

Stable values

Display labels are written for people and may change. Stable values are written for tools and workflows:

{ value: "postgres", label: "PostgreSQL" }

The result contains both values:

{
  "value": "postgres",
  "label": "PostgreSQL",
  "custom": false
}

When value is omitted, the normalized label is used for both fields.

Custom answers

Every question includes Write my own answer….

  • On a single-select question, a custom answer becomes the only selection.
  • On a multi-select question, it is added alongside predefined selections.
  • Reopen the custom row to edit an existing answer.
  • Clear the editor and press Enter to remove the existing custom answer.
  • Press Escape while editing to discard uncommitted changes and keep the existing answer.

A custom selection uses the submitted text as both its value and label and sets custom: true.

Keyboard controls

Key Action
/ Move through options or review actions.
Enter Select a single choice, toggle a multi-select choice, open/save custom input, advance, or submit.
Space Toggle a multi-select choice or open the custom row.
Tab / Move to the next question or Review tab.
Shift+Tab / Move to the previous tab.
Escape Leave custom editing or dismiss the questionnaire.

Single-select answers advance automatically. Multi-select questions use a Continue → row. The Review tab refuses submission until every question has at least one selection.

Result contract

A successful result stores the same selection shape for single- and multi-select questions:

interface AskUserDetails {
  answers: Array<{
    questionId: string;
    question: string;
    selections: Array<{
      value: string;
      label: string;
      custom: boolean;
    }>;
  }>;
  cancelled: false;
}

Example:

{
  "answers": [
    {
      "questionId": "features",
      "question": "Which features should be included?",
      "selections": [
        { "value": "api", "label": "REST API", "custom": false },
        { "value": "Dark mode", "label": "Dark mode", "custom": true }
      ]
    }
  ],
  "cancelled": false
}

Dismissal discards unsubmitted choices:

{
  "answers": [],
  "cancelled": true
}

Validation and environment failures add an error field. Current codes are:

  • no_ui
  • aborted
  • no_questions
  • too_many_questions
  • too_few_options
  • too_many_options
  • empty_question
  • empty_question_id
  • empty_header
  • header_too_long
  • empty_option_label
  • label_too_long
  • empty_option_value
  • duplicate_question_id
  • duplicate_option_value
  • reserved_label

pi-ask requires Pi's interactive TUI. In print, JSON, and RPC modes it returns no_ui and tells the model to ask in plain text. Pi may handle cancellation before dispatching the tool; aborts received while the questionnaire is open are returned as aborted with no partial answers.

Why sequential execution?

Pi can execute independent sibling tool calls concurrently. Interactive dialogs should not overlap or compete for keyboard focus, so ask_user declares:

executionMode: "sequential"

This does not affect normal parallel execution for other tools.

Development

Requirements:

  • Node.js 22.19 or newer
  • npm
npm install
npm run check
npm test
npm run pack:check

Run every validation step together:

npm run validate

See CONTRIBUTING.md for the source layout and contribution expectations.

Limitations

The initial release intentionally does not include preview panes, localization, per-option notes, or non-TUI questionnaire transport. It focuses on a compact, predictable grouped-question flow.

License

MIT