@d3ara1n/pi-ask-user 2.1.2 → 2.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/package.json +1 -1
- package/src/index.ts +24 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@d3ara1n/pi-ask-user",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ask-user tool for pi — renders in the bottom editor slot (not a screen overlay), so the transcript stays visible and scrollable above the panel while you decide",
|
|
6
6
|
"main": "src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -860,6 +860,19 @@ class AskUserPanel implements Component, Focusable {
|
|
|
860
860
|
}
|
|
861
861
|
}
|
|
862
862
|
|
|
863
|
+
/** Build a bordered content row that ALWAYS fits innerW: truncateToWidth
|
|
864
|
+
* is the hard safety net (any content — LLM-generated headers, user-typed
|
|
865
|
+
* custom answers, tab names — is clamped so the TUI render can never crash
|
|
866
|
+
* on an over-wide line), padRight then fills short content to keep the
|
|
867
|
+
* right border aligned. Shared by every bordered screen so the width
|
|
868
|
+
* invariant holds uniformly. */
|
|
869
|
+
private makeRow(th: Theme, borderColor: ThemeColor, innerW: number) {
|
|
870
|
+
return (content: string) => {
|
|
871
|
+
const fitted = truncateToWidth(content, innerW);
|
|
872
|
+
return th.fg(borderColor, "│") + padRight(fitted, innerW) + th.fg(borderColor, "│");
|
|
873
|
+
};
|
|
874
|
+
}
|
|
875
|
+
|
|
863
876
|
// ── render ──
|
|
864
877
|
|
|
865
878
|
render(width: number): string[] {
|
|
@@ -933,8 +946,7 @@ class AskUserPanel implements Component, Focusable {
|
|
|
933
946
|
const th = this.theme;
|
|
934
947
|
const innerW = Math.max(20, width - 2);
|
|
935
948
|
const lines: string[] = [];
|
|
936
|
-
const row = (
|
|
937
|
-
th.fg("border", "│") + padRight(content, innerW) + th.fg("border", "│");
|
|
949
|
+
const row = this.makeRow(th, "border", innerW);
|
|
938
950
|
|
|
939
951
|
if (this.messageEditing) {
|
|
940
952
|
return this.renderMessageEditor(width, innerW, th);
|
|
@@ -1053,7 +1065,7 @@ class AskUserPanel implements Component, Focusable {
|
|
|
1053
1065
|
// unmistakable as the review/confirm screen — not another question. The
|
|
1054
1066
|
// question screen keeps the default "border" color.
|
|
1055
1067
|
const bc: import("@earendil-works/pi-coding-agent").ThemeColor = "success";
|
|
1056
|
-
const row = (
|
|
1068
|
+
const row = this.makeRow(th, bc, innerW);
|
|
1057
1069
|
lines.push(th.fg(bc, `╭${"─".repeat(innerW)}╮`));
|
|
1058
1070
|
lines.push(row(this.renderTabBarContent(th)));
|
|
1059
1071
|
lines.push(row(""));
|
|
@@ -1128,7 +1140,7 @@ class AskUserPanel implements Component, Focusable {
|
|
|
1128
1140
|
private renderMessageEditor(_width: number, innerW: number, th: Theme): string[] {
|
|
1129
1141
|
const lines: string[] = [];
|
|
1130
1142
|
const bc: import("@earendil-works/pi-coding-agent").ThemeColor = "success";
|
|
1131
|
-
const row = (
|
|
1143
|
+
const row = this.makeRow(th, bc, innerW);
|
|
1132
1144
|
lines.push(th.fg(bc, `╭${"─".repeat(innerW)}╮`));
|
|
1133
1145
|
lines.push(row(` ${th.fg("accent", th.bold(`${ICON_OTHER} Note to assistant`))}`));
|
|
1134
1146
|
lines.push(th.fg(bc, `├${"─".repeat(innerW)}┤`));
|
|
@@ -1164,7 +1176,13 @@ class AskUserPanel implements Component, Focusable {
|
|
|
1164
1176
|
const customAnswered = !!committedCustom;
|
|
1165
1177
|
const glyph = this.optionGlyph(opt, i, st, multi, th, isCursor, customAnswered);
|
|
1166
1178
|
// For "Type something.", show the committed text instead of the placeholder.
|
|
1167
|
-
|
|
1179
|
+
// Custom text is arbitrary-length user input — truncate to the label
|
|
1180
|
+
// column (the full text appears on the review screen and result card,
|
|
1181
|
+
// both of which wrap). Without this a long custom answer makes the row
|
|
1182
|
+
// exceed the terminal width and crashes the TUI render.
|
|
1183
|
+
const labelMaxW = Math.max(0, innerW - 5); // 1 lead + 2 prefix + 1 glyph + 1 space
|
|
1184
|
+
const displayLabel =
|
|
1185
|
+
opt.isOther && customAnswered ? truncForDisplay(committedCustom!, labelMaxW) : opt.label;
|
|
1168
1186
|
const labelColor = isCursor
|
|
1169
1187
|
? "accent"
|
|
1170
1188
|
: opt.isOther
|
|
@@ -1400,7 +1418,7 @@ class AskUserResultView implements Component {
|
|
|
1400
1418
|
};
|
|
1401
1419
|
for (const q of this.questions) {
|
|
1402
1420
|
const ans = this.result.answers.find((a) => a.tab === q.tab);
|
|
1403
|
-
lines.push(th.fg("muted", q.header));
|
|
1421
|
+
lines.push(truncateToWidth(th.fg("muted", q.header), width));
|
|
1404
1422
|
if (!ans) {
|
|
1405
1423
|
lines.push(`${indent}${th.fg("dim", "(no answer)")}`);
|
|
1406
1424
|
} else if (ans.kind === "skipped") {
|