From d77a3e154a27015d60dbb753be32cb69f595d7b3 Mon Sep 17 00:00:00 2001 From: roboomp Date: Tue, 14 Jul 2026 18:23:30 +0000 Subject: [PATCH] fix(tui): aligned ask "Other" custom-input chrome to prompt gutter The prompt-style HookEditorComponent (used by the ask tool's "Other" custom-input flow) rendered its title, option list, and hint via Text(padX=1) while the borderless editor beneath renders its `> ` gutter at column 0, leaving the input row one column left of everything else. Pad the prompt-style chrome at column 0 to match the gutter; hook-style (bordered) chrome keeps its 1-column indent that lines up with the bordered editor body. Fixes #5313 --- packages/coding-agent/CHANGELOG.md | 4 ++++ .../src/modes/components/hook-editor.ts | 9 +++++--- .../coding-agent/test/hook-editor.test.ts | 22 ++++++++++++++++++- 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/packages/coding-agent/CHANGELOG.md b/packages/coding-agent/CHANGELOG.md index e0b1b1608..7aca25bc2 100644 --- a/packages/coding-agent/CHANGELOG.md +++ b/packages/coding-agent/CHANGELOG.md @@ -10,6 +10,10 @@ - Updated status event log to prioritize the most recent entries in the display window +### Fixed + +- Fixed the ask tool's "Other" custom-input dialog rendering the title, options, and hint one column to the right of the `> ` input gutter; the prompt-style editor chrome now aligns to column 0 ([#5313](https://github.com/can1357/oh-my-pi/issues/5313)) + ### Removed - Removed the unreliable Bing and Yahoo HTML-scraping web search providers diff --git a/packages/coding-agent/src/modes/components/hook-editor.ts b/packages/coding-agent/src/modes/components/hook-editor.ts index 19fe74c18..aa06b759d 100644 --- a/packages/coding-agent/src/modes/components/hook-editor.ts +++ b/packages/coding-agent/src/modes/components/hook-editor.ts @@ -47,8 +47,11 @@ export class HookEditorComponent extends Container { this.addChild(new DynamicBorder()); this.addChild(new Spacer(1)); - // Title - this.addChild(new Text(theme.fg("accent", title), 1, 0)); + // Title. Prompt-style renders the borderless editor's `> ` gutter at + // column 0, so pad the title to match; hook-style keeps the 1-col indent + // that lines up with its bordered editor body (#5313). + const chromePadX = this.#promptStyle ? 0 : 1; + this.addChild(new Text(theme.fg("accent", title), chromePadX, 0)); this.addChild(new Spacer(1)); // Editor @@ -69,7 +72,7 @@ export class HookEditorComponent extends Container { const hint = this.#promptStyle ? "enter or ctrl+q submit esc cancel ctrl+g external editor" : "ctrl+q/ctrl+enter submit esc cancel ctrl+g external editor"; - this.addChild(new Text(theme.fg("dim", hint), 1, 0)); + this.addChild(new Text(theme.fg("dim", hint), chromePadX, 0)); this.addChild(new Spacer(1)); this.addChild(new DynamicBorder()); diff --git a/packages/coding-agent/test/hook-editor.test.ts b/packages/coding-agent/test/hook-editor.test.ts index a42ace9fc..a816391d6 100644 --- a/packages/coding-agent/test/hook-editor.test.ts +++ b/packages/coding-agent/test/hook-editor.test.ts @@ -359,7 +359,7 @@ describe("HookEditorComponent prompt-style mode", () => { expect(lines[0]).toMatch(/^─+$/); expect(lines.at(-1)).toMatch(/^─+$/); expect(lines[4]?.startsWith("> ")).toBe(true); - expect(rendered).toContain(" enter or ctrl+q submit esc cancel"); + expect(rendered).toContain("enter or ctrl+q submit esc cancel"); expect(rendered).not.toContain("shift+enter newline"); expect(rendered).toContain("ctrl+g external editor"); }); @@ -419,6 +419,26 @@ describe("HookEditorComponent prompt-style mode", () => { expect(onCancel).toHaveBeenCalledTimes(1); expect(onSubmit).not.toHaveBeenCalled(); }); + + it("aligns the title and hint with the editor prompt gutter at column zero (#5313)", () => { + const title = "◆ Other (type your own)\nEnter your response:"; + const component = new HookEditorComponent(createTui(), title, "不太清楚,", vi.fn(), vi.fn(), { + promptStyle: true, + }); + const lines = renderLines(component); + + const titleRow = lines.find(line => line.includes("Enter your response:")); + const gutterRow = lines.find(line => line.startsWith("> ")); + const hintRow = lines.find(line => line.includes("esc cancel")); + + expect(titleRow).toBeDefined(); + expect(gutterRow).toBeDefined(); + expect(hintRow).toBeDefined(); + // The borderless prompt-style editor renders `> ` starting at column 0, so + // the surrounding title/hint chrome must not carry a leading indent. + expect(titleRow!.startsWith("Enter your response:")).toBe(true); + expect(hintRow!.startsWith(" ")).toBe(false); + }); }); describe("ExtensionUiController hook editor abort", () => {