@hank-warren/pi-ask-user-question 0.5.1 → 0.5.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/CHANGELOG.md +31 -0
- package/package.json +2 -2
- package/tool/schema.ts +1 -2
- package/tool/validate.ts +9 -9
- package/view/dialog.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# @hank-warren/pi-ask-user-question
|
|
2
2
|
|
|
3
|
+
## 0.5.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 36230c0: Let option labels grow, and wrap descriptions instead of cutting them off.
|
|
8
|
+
|
|
9
|
+
`ask_user_question` no longer rejects a questionnaire because an option label
|
|
10
|
+
is longer than 60 characters. The renderer already wraps label rows and clamps
|
|
11
|
+
every line to the box's inner width, so the cap could only ever discard a
|
|
12
|
+
questionnaire that would have rendered fine. Label length is now guidance in
|
|
13
|
+
the schema description rather than a gate; an empty or whitespace-only label
|
|
14
|
+
takes its place as the fatal case, and `header`'s 16-character cap is
|
|
15
|
+
unchanged.
|
|
16
|
+
|
|
17
|
+
The shared `OptionSelector` now wraps long option descriptions at the row's
|
|
18
|
+
continuation indent instead of truncating them with an ellipsis.
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [36230c0]
|
|
21
|
+
- @hank-warren/pi-permission-selector@1.4.0
|
|
22
|
+
|
|
23
|
+
## 0.5.2
|
|
24
|
+
|
|
25
|
+
### Patch Changes
|
|
26
|
+
|
|
27
|
+
- 3fbf632: Make backspace delete a whole character rather than half a surrogate pair. Both text-entry surfaces sliced UTF-16 code units, so one backspace after an emoji left a lone surrogate — an ill-formed string that was then submitted as an approval note or a free-text answer.
|
|
28
|
+
|
|
29
|
+
`pi-permission-selector` adds a code-point-aware `removeLastCharacter` export (additive; the frozen shared surface gains a name and loses none), and `pi-ask-user-question` uses it for the custom-answer field.
|
|
30
|
+
|
|
31
|
+
- Updated dependencies [3fbf632]
|
|
32
|
+
- @hank-warren/pi-permission-selector@1.3.0
|
|
33
|
+
|
|
3
34
|
## 0.5.1
|
|
4
35
|
|
|
5
36
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hank-warren/pi-ask-user-question",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.3",
|
|
4
4
|
"description": "Structured questionnaire tool for Pi with numbered options, digit hotkeys and Tab-to-comment, composed from the shared permission-selector component.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"CHANGELOG.md"
|
|
47
47
|
],
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@hank-warren/pi-permission-selector": "^1.
|
|
49
|
+
"@hank-warren/pi-permission-selector": "^1.4.0"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@earendil-works/pi-coding-agent": "*",
|
package/tool/schema.ts
CHANGED
|
@@ -27,7 +27,6 @@ export const maxOptionsFor = (multiSelect?: boolean): number =>
|
|
|
27
27
|
multiSelect ? MAX_MULTI_OPTIONS : MAX_OPTIONS;
|
|
28
28
|
|
|
29
29
|
export const MAX_HEADER_LENGTH = 16;
|
|
30
|
-
export const MAX_LABEL_LENGTH = 60;
|
|
31
30
|
|
|
32
31
|
/**
|
|
33
32
|
* Labels the model may not author, because the dialog appends its own
|
|
@@ -46,7 +45,7 @@ export const MULTI_SELECT_JOIN = ", ";
|
|
|
46
45
|
export const OptionSchema = Type.Object({
|
|
47
46
|
label: Type.String({
|
|
48
47
|
description:
|
|
49
|
-
"
|
|
48
|
+
"The display text for this option that the user will see and select. Aim for 1-5 words, but there is no hard limit: a longer label is fine when it genuinely helps, and long labels wrap in the dialog rather than being rejected.",
|
|
50
49
|
}),
|
|
51
50
|
description: Type.String({
|
|
52
51
|
description:
|
package/tool/validate.ts
CHANGED
|
@@ -2,8 +2,12 @@
|
|
|
2
2
|
* Parameter validation for `ask_user_question`. Pure — no pi imports, no I/O.
|
|
3
3
|
*
|
|
4
4
|
* typebox enforces structure (array bounds, required fields, types). This
|
|
5
|
-
* module enforces the semantic rules typebox cannot express:
|
|
6
|
-
*
|
|
5
|
+
* module enforces the semantic rules typebox cannot express: the header chip's
|
|
6
|
+
* length cap, non-empty text, reserved sentinel labels, and duplicates.
|
|
7
|
+
*
|
|
8
|
+
* Option labels are deliberately uncapped: the renderer wraps them and clamps
|
|
9
|
+
* its own lines, so a length rule could only ever discard a questionnaire that
|
|
10
|
+
* would have rendered fine.
|
|
7
11
|
*
|
|
8
12
|
* Violations return a structured error that becomes a normal tool error the
|
|
9
13
|
* model can read and retry against — never a thrown exception, which would
|
|
@@ -13,7 +17,6 @@
|
|
|
13
17
|
import {
|
|
14
18
|
type AskUserParams,
|
|
15
19
|
MAX_HEADER_LENGTH,
|
|
16
|
-
MAX_LABEL_LENGTH,
|
|
17
20
|
MAX_QUESTIONS,
|
|
18
21
|
maxOptionsFor,
|
|
19
22
|
MIN_OPTIONS,
|
|
@@ -25,7 +28,7 @@ export type ValidationCode =
|
|
|
25
28
|
| "bad_question_count"
|
|
26
29
|
| "bad_option_count"
|
|
27
30
|
| "header_too_long"
|
|
28
|
-
| "
|
|
31
|
+
| "empty_label"
|
|
29
32
|
| "reserved_label"
|
|
30
33
|
| "duplicate_label"
|
|
31
34
|
| "empty_question";
|
|
@@ -84,11 +87,8 @@ export function validateParams(params: AskUserParams): ValidationError | undefin
|
|
|
84
87
|
for (let j = 0; j < q.options.length; j++) {
|
|
85
88
|
const option = q.options[j];
|
|
86
89
|
const at = `${where}.options[${j}]`;
|
|
87
|
-
if (option.label
|
|
88
|
-
return {
|
|
89
|
-
code: "label_too_long",
|
|
90
|
-
message: `${at}.label is ${option.label.length} characters; the hard limit is ${MAX_LABEL_LENGTH}.`,
|
|
91
|
-
};
|
|
90
|
+
if (!option.label?.trim()) {
|
|
91
|
+
return { code: "empty_label", message: `${at}.label must not be empty.` };
|
|
92
92
|
}
|
|
93
93
|
if (isReserved(option.label)) {
|
|
94
94
|
return {
|
package/view/dialog.ts
CHANGED
|
@@ -49,6 +49,7 @@ import {
|
|
|
49
49
|
isRightKey,
|
|
50
50
|
isShiftTabKey,
|
|
51
51
|
isTabKey,
|
|
52
|
+
removeLastCharacter,
|
|
52
53
|
} from "@hank-warren/pi-permission-selector/keys.ts";
|
|
53
54
|
import { OptionSelector, type SelectorOption } from "@hank-warren/pi-permission-selector/selector.ts";
|
|
54
55
|
import {
|
|
@@ -426,7 +427,9 @@ export class QuestionnaireDialog {
|
|
|
426
427
|
return;
|
|
427
428
|
}
|
|
428
429
|
if (isBackspaceKey(keyData)) {
|
|
429
|
-
|
|
430
|
+
// Code-point aware: a UTF-16 slice would split a surrogate pair and
|
|
431
|
+
// leave a lone surrogate in the answer that reaches the model.
|
|
432
|
+
tab.customText = removeLastCharacter(tab.customText);
|
|
430
433
|
this.repaint();
|
|
431
434
|
return;
|
|
432
435
|
}
|