@black942026/pi-ask-user 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/types.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  * answered through one of two routes:
6
6
  *
7
7
  * - `custom` — a custom terminal UI (only a real Pi TUI)
8
- * - `native` — native input dialogs (`ctx.hasUI` + callable input), one question
9
- * at a time
8
+ * - `native` — native dialogs (`ctx.hasUI` + callable input), one logical
9
+ * question at a time (a form uses sequential per-field dialogs)
10
10
  *
11
11
  * The route is resolved **once, when the host adapter is created**, from
12
12
  * trustworthy inputs only:
@@ -25,7 +25,10 @@
25
25
  */
26
26
 
27
27
  /** The kind of question. */
28
- export type QuestionKind = "single" | "multi" | "input";
28
+ export type QuestionKind = "single" | "multi" | "input" | "bool" | "simple-form";
29
+
30
+ /** The non-nesting field kinds accepted by a `simple-form` question. */
31
+ export type FormFieldKind = Exclude<QuestionKind, "simple-form">;
29
32
 
30
33
  /** Custom-UI presentation: floating overlay or inline prompt area. */
31
34
  export type AskUserDisplayMode = "overlay" | "inline";
@@ -40,31 +43,110 @@ export interface AskUserOption {
40
43
  preview?: string;
41
44
  }
42
45
 
43
- /** One question in a questionnaire. */
44
- export interface AskUserQuestion {
46
+ interface AskUserFormFieldBase {
47
+ /** Literal output key: 1..64 ASCII letters/digits/`_`/`-`, starting with a letter or `_`. */
48
+ name: string;
49
+ /** Label shown beside the field. */
50
+ label: string;
51
+ /** When true, an explicit non-empty value (or a valid default) is required. */
52
+ required?: boolean;
53
+ }
54
+
55
+ export interface AskUserBoolField extends AskUserFormFieldBase {
56
+ kind: "bool";
57
+ options?: never;
58
+ default?: boolean;
59
+ }
60
+
61
+ export interface AskUserSingleField extends AskUserFormFieldBase {
62
+ kind: "single";
63
+ options: AskUserOption[];
64
+ default?: string;
65
+ }
66
+
67
+ export interface AskUserMultiField extends AskUserFormFieldBase {
68
+ kind: "multi";
69
+ options: AskUserOption[];
70
+ default?: string[];
71
+ }
72
+
73
+ export interface AskUserInputField extends AskUserFormFieldBase {
74
+ kind: "input";
75
+ options?: never;
76
+ default?: string;
77
+ }
78
+
79
+ /** One non-nesting, kind-typed field in a flat `simple-form` question. */
80
+ export type AskUserFormField = AskUserBoolField | AskUserSingleField | AskUserMultiField | AskUserInputField;
81
+
82
+ /** Flat typed value returned by a `simple-form`. */
83
+ export type AskUserFormValue = Record<string, boolean | string | string[]>;
84
+
85
+ interface AskUserQuestionBase {
45
86
  /** Stable id. Generated (`q1`, `q2`, ...) when omitted. */
46
87
  id?: string;
47
88
  /** Question heading (required). */
48
89
  title: string;
49
90
  /** Optional extra hint or context rendered under the heading. */
50
91
  prompt?: string;
51
- /** `single` = choose one, `multi` = choose several, `input` = free text only. */
52
- kind: QuestionKind;
53
- /** 1..5 options. Required for `single`/`multi`; ignored for `input`. */
92
+ }
93
+
94
+ export interface AskUserSingleQuestion extends AskUserQuestionBase {
95
+ kind: "single";
96
+ options: AskUserOption[];
97
+ default?: string;
98
+ fields?: never;
99
+ }
100
+
101
+ export interface AskUserMultiQuestion extends AskUserQuestionBase {
102
+ kind: "multi";
103
+ options: AskUserOption[];
104
+ default?: string;
105
+ fields?: never;
106
+ }
107
+
108
+ export interface AskUserInputQuestion extends AskUserQuestionBase {
109
+ kind: "input";
110
+ /** Kept for legacy callers: validated by normalization, then dropped. */
54
111
  options?: AskUserOption[];
55
- /**
56
- * Default answer. When present the question may be skipped and the default
57
- * is used; when absent the question must be answered.
58
- */
59
112
  default?: string;
113
+ fields?: never;
60
114
  }
61
115
 
116
+ export interface AskUserBoolQuestion extends AskUserQuestionBase {
117
+ kind: "bool";
118
+ options?: never;
119
+ default?: boolean;
120
+ fields?: never;
121
+ }
122
+
123
+ export interface AskUserSimpleFormQuestion extends AskUserQuestionBase {
124
+ kind: "simple-form";
125
+ options?: never;
126
+ default?: never;
127
+ fields: AskUserFormField[];
128
+ }
129
+
130
+ /** One kind-typed question in a questionnaire. */
131
+ export type AskUserQuestion =
132
+ | AskUserSingleQuestion
133
+ | AskUserMultiQuestion
134
+ | AskUserInputQuestion
135
+ | AskUserBoolQuestion
136
+ | AskUserSimpleFormQuestion;
137
+
62
138
  /** A model-facing (or caller-facing) request. */
63
139
  export interface AskUserRequest {
64
140
  /** 1..5 questions. */
65
141
  questions: AskUserQuestion[];
66
142
  /** Optional heading shown above the questionnaire. */
67
143
  header?: string;
144
+ /**
145
+ * Allow supplemental/free-text answers on single/multi questions. Defaults to true.
146
+ * False also uses native selectors for single/bool (including form fields);
147
+ * native multi/text continue using input boxes.
148
+ */
149
+ allowFreeText?: boolean;
68
150
  /** Custom-UI presentation. Defaults to `overlay`. */
69
151
  displayMode?: AskUserDisplayMode;
70
152
  /**
@@ -88,6 +170,8 @@ export interface AskUserAnswer {
88
170
  freeText?: string;
89
171
  /** True when the answer came from the question default rather than user input. */
90
172
  usedDefault: boolean;
173
+ /** Typed value for `bool` and `simple-form`. `false` is a complete answer. */
174
+ value?: boolean | AskUserFormValue;
91
175
  }
92
176
 
93
177
  /**
@@ -325,12 +409,28 @@ export interface NormalizedQuestion {
325
409
  prompt?: string;
326
410
  kind: QuestionKind;
327
411
  options: AskUserOption[];
328
- default?: string;
412
+ /** False disables free text for single/multi; absent preserves legacy behavior. */
413
+ allowFreeText?: boolean;
414
+ default?: string | boolean;
415
+ hasDefault: boolean;
416
+ /** Present for `simple-form`; omitted by older already-normalized callers. */
417
+ fields?: NormalizedFormField[];
418
+ }
419
+
420
+ export interface NormalizedFormField {
421
+ name: string;
422
+ label: string;
423
+ kind: FormFieldKind;
424
+ required: boolean;
425
+ options: AskUserOption[];
426
+ default?: boolean | string | string[];
329
427
  hasDefault: boolean;
330
428
  }
331
429
 
332
430
  export interface NormalizedRequest {
333
431
  header?: string;
432
+ /** Absent in older normalized callers means true. */
433
+ allowFreeText?: boolean;
334
434
  questions: NormalizedQuestion[];
335
435
  displayMode: AskUserDisplayMode;
336
436
  timeoutPerQuestionMs: number;