@dreki-gg/pi-questionnaire0.3.0
Tool-first questionnaire flow for pi with shared tabbed TUI and custom rendering
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
@dreki-gg/pi-questionnaire
Tool-first questionnaire extension for pi.
It adds:
- a
questionnairetool for collecting 1-5 structured answers in one interaction - a
/questionnairedemo command powered by the same shared tabbed TUI flow
Install
pi install npm:@dreki-gg/pi-questionnaire
What it provides
| Feature | Name | Notes |
|---|---|---|
| Tool | questionnaire |
Collects structured user answers with single/multi select + optional Other text |
| Command | /questionnaire |
Demo flow using Scope, Priority, Approach |
Input schema (summary)
{
questions: Array<{
id: string;
label?: string;
prompt: string;
selectionMode?: 'single' | 'multiple';
options: Array<{
value: string;
label: string;
description?: string;
}>;
allowOther?: boolean; // defaults to true at runtime
}> // min 1, max 5
}
Validation includes:
- 1-5 question limit
- non-empty option lists
- duplicate question id rejection
- duplicate option value rejection per question
Normalized output schema (summary)
{
questions: NormalizedQuestion[];
answers: Array<{
questionId: string;
questionLabel: string;
selectedOptions: Array<{ value: string; label: string }>;
otherText: string | null;
wasOtherSelected: boolean;
}>;
context: string | null;
cancelled: boolean;
}
Other answers are rendered explicitly as:
Other: "GraphQL"
The Review tab also includes an optional Anything else? field. Its trimmed value is returned as context, or null when left empty.
Keyboard model
← / →: switch tabs (question tabs + Review tab)↑ / ↓: move option cursor (question tab) or row cursor (Review tab, includingAnything else?)Space:- question tab: select/toggle option or enter Other input
- review tab: jump to the selected question for editing, or open
Anything else?
r: jump to Review tabEschierarchy:- exit Other or
Anything else?input mode - from Review, go back to the prior question tab
- from question tab outermost, cancel questionnaire
- exit Other or
Enter:- in an editor: submit the current text
- in Review: submit only when all required answers are valid
Example tool call
{
"name": "questionnaire",
"arguments": {
"questions": [
{
"id": "scope",
"label": "Scope",
"prompt": "What is the project scope?",
"selectionMode": "single",
"options": [
{ "value": "low", "label": "Low" },
{ "value": "high", "label": "High" }
]
},
{
"id": "priority",
"label": "Priority",
"prompt": "What priority should we assign?",
"selectionMode": "single",
"options": [
{ "value": "p0", "label": "P0" },
{ "value": "p1", "label": "P1" }
]
}
]
}
}
Example result summaries
Completed (collapsed):
✓ Scope: High • Priority: P1 • Approach: Other: "GraphQL"
Cancelled:
⚠ Cancelled
Modes
The questionnaire runs in whatever UI Pi provides:
- Interactive (TUI): the tabbed component with keyboard navigation described above.
- RPC (for example the Pi VS Code panel): one dialog per question.
Selectlists the options, anOtherchoice opens a text input, a multi-select question toggles options and finishes onDone, and a final input collects the optionalAnything else?context.ctx.ui.custom()is undefined outside the TUI, which is why RPC mode uses Pi's dialog methods instead.
The result shape is identical in both modes.
Cancellation and non-interactive behavior
- User cancellation is not treated as an error (
cancelled: truein details). - Modes without a UI (
ctx.hasUI === false) return an immediate error result (isError: true).