fix(tui): cap sparse ask other gaps

This commit is contained in:
can1357
2026-07-01 21:09:29 +02:00
parent 278b715ab8
commit 3b80dc01de
2 changed files with 28 additions and 4 deletions
+4 -4
View File
@@ -259,9 +259,9 @@ function pickCustomInputOptionWindow(
interface CustomInputRow {
text: string;
/** Lower priority drops first when over budget; negative values are pinned
* and never dropped (question, blank, option labels, gap markers, prompt). */
priority: number;
/** Lower priority drops first when over budget; negative values are pinned.
* Gap markers are budgeted rows too so sparse checked selections cannot
* push the editor input off-screen. */
}
function buildCustomInputRows(
@@ -284,7 +284,7 @@ function buildCustomInputRows(
` … ${gap.total} more option${gap.total === 1 ? "" : "s"}${checkedSuffix} …`,
contentWidth,
),
priority: -1,
priority: 2,
});
};
@@ -682,6 +682,30 @@ describe("AskTool custom input", () => {
expect(title).toContain("Enter your response:");
});
it("keeps sparse checked gap markers within the Other title budget", async () => {
const tool = new AskTool(createSession());
const editor = vi.fn(async (_title: string) => "custom");
const checkedLabels = [10, 20, 30, 40, 50, 60].map(i => `opt-${i}`);
const options = Array.from({ length: 61 }, (_, i) => ({ label: `opt-${i}` }));
const questions = [{ id: "pick", question: "Pick sparse", options, multi: true }];
let call = 0;
const context = createContext({
select: async (_prompt, opts) => {
const next = checkedLabels[call++];
return next ? selectItemLabel(opts.find(o => selectItemLabel(o) === next)) : "Other (type your own)";
},
editor,
});
await tool.execute("call-editor-cap-sparse-checked", { questions }, undefined, undefined, context);
const title = editor.mock.calls[0]?.[0] ?? "";
expect(title.split("\n").length).toBeLessThanOrEqual(16);
expect(title).toContain("Other (type your own)");
expect(title).toContain("more option");
expect(title).toContain("Enter your response:");
});
it("enforces total title row budget under narrow terminals", async () => {
const originalColumns = process.stdout.columns;
// Force an 80-wide terminal so long descriptions would wrap to multiple