From 2f60a0b2a2cf92c43e168e87ae47c89efcf7c07c Mon Sep 17 00:00:00 2001 From: rekram1-node Date: Wed, 19 Aug 2026 21:47:19 +0000 Subject: [PATCH] fix(tui): apply cursor config in mini --- packages/tui/src/mini/footer.form.tsx | 4 +++- packages/tui/src/mini/footer.permission.tsx | 6 +++++- packages/tui/src/mini/footer.prompt.tsx | 3 +++ packages/tui/src/mini/footer.ts | 1 + packages/tui/src/mini/footer.view.tsx | 5 +++++ packages/tui/src/mini/types.ts | 2 +- packages/tui/test/mini/footer.view.test.tsx | 13 +++++++++++++ 7 files changed, 31 insertions(+), 3 deletions(-) diff --git a/packages/tui/src/mini/footer.form.tsx b/packages/tui/src/mini/footer.form.tsx index eba1ec36765e..3fb92bb4f49a 100644 --- a/packages/tui/src/mini/footer.form.tsx +++ b/packages/tui/src/mini/footer.form.tsx @@ -33,11 +33,12 @@ import { } from "./form.shared" import type { FormBodyState } from "./form.shared" import type { RunFooterTheme } from "./theme" -import type { FormCancel, FormReply, MiniFormRequest } from "./types" +import type { FormCancel, FormReply, MiniFormRequest, RunTuiConfig } from "./types" export function RunFormBody(props: { request: MiniFormRequest theme: RunFooterTheme + cursor?: RunTuiConfig["cursor"] onReply: (input: FormReply) => void | Promise onCancel: (input: FormCancel) => void | Promise openExternal?: (url: string) => Promise @@ -320,6 +321,7 @@ export function RunFormBody(props: { backgroundColor={props.theme.surface} focusedBackgroundColor={props.theme.surface} cursorColor={props.theme.text} + cursorStyle={props.cursor} focused onSubmit={commitInput} onContentChange={() => { diff --git a/packages/tui/src/mini/footer.permission.tsx b/packages/tui/src/mini/footer.permission.tsx index 4d28bbcc2ce3..0798994c65d8 100644 --- a/packages/tui/src/mini/footer.permission.tsx +++ b/packages/tui/src/mini/footer.permission.tsx @@ -31,7 +31,7 @@ import { import { footerWidthPolicy } from "./footer.width" import { toolFiletype } from "./tool" import { transparent, type RunBlockTheme, type RunFooterTheme } from "./theme" -import type { MiniPermissionRequest, PermissionReply } from "./types" +import type { MiniPermissionRequest, PermissionReply, RunTuiConfig } from "./types" import { PatchDiff } from "../component/patch-diff" function buttons( @@ -74,6 +74,7 @@ function buttons( /** @internal Exported to test managed textarea submission without permission navigation. */ export function RejectField(props: { theme: RunFooterTheme + cursor?: RunTuiConfig["cursor"] text: string disabled: boolean onChange: (text: string) => void @@ -113,6 +114,7 @@ export function RejectField(props: { backgroundColor={props.theme.surface} focusedBackgroundColor={props.theme.surface} cursorColor={props.theme.text} + cursorStyle={props.cursor} focused={!props.disabled} onSubmit={props.onConfirm} onContentChange={() => { @@ -139,6 +141,7 @@ export function RunPermissionBody(props: { request: MiniPermissionRequest directory?: () => string theme: RunFooterTheme + cursor?: RunTuiConfig["cursor"] block: RunBlockTheme onReply: (input: PermissionReply) => void | Promise mono?: boolean @@ -327,6 +330,7 @@ export function RunPermissionBody(props: { { diff --git a/packages/tui/src/mini/footer.prompt.tsx b/packages/tui/src/mini/footer.prompt.tsx index 488cbf685974..1e2b9f7ab2be 100644 --- a/packages/tui/src/mini/footer.prompt.tsx +++ b/packages/tui/src/mini/footer.prompt.tsx @@ -42,6 +42,7 @@ import type { RunPrompt, RunPromptPart, RunReference, + RunTuiConfig, } from "./types" const AUTOCOMPLETE_ROWS = FOOTER_MENU_ROWS @@ -175,6 +176,7 @@ export function selectedCommand(text: string, command: RunPrompt["command"]) { export function RunPromptBody(props: { theme: () => RunFooterTheme + cursor?: RunTuiConfig["cursor"] background: () => ColorInput placeholder: () => StyledText | string onSubmit: () => void @@ -239,6 +241,7 @@ export function RunPromptBody(props: { backgroundColor={props.background()} focusedBackgroundColor={props.background()} cursorColor={props.theme().text} + cursorStyle={props.cursor} onSubmit={props.onSubmit} onKeyDown={props.onKeyDown} onPaste={() => { diff --git a/packages/tui/src/mini/footer.ts b/packages/tui/src/mini/footer.ts index 088a46c13e32..0522c25c3a31 100644 --- a/packages/tui/src/mini/footer.ts +++ b/packages/tui/src/mini/footer.ts @@ -335,6 +335,7 @@ export class RunFooter implements FooterApi { variants: footer.variants, currentVariant: footer.currentVariant, theme: footer.theme, + cursor: options.tuiConfig.cursor, mono: options.mono, miniSettings: footer.miniSettings, history: footer.history, diff --git a/packages/tui/src/mini/footer.view.tsx b/packages/tui/src/mini/footer.view.tsx index efb333e6b17a..cc4d6b6bc20f 100644 --- a/packages/tui/src/mini/footer.view.tsx +++ b/packages/tui/src/mini/footer.view.tsx @@ -55,6 +55,7 @@ import type { RunPrompt, RunProvider, RunReference, + RunTuiConfig, } from "./types" import type { RunTheme } from "./theme" @@ -92,6 +93,7 @@ type RunFooterViewProps = { subagent?: () => FooterSubagentState queuedPrompts?: () => FooterQueuedPrompt[] theme: () => RunTheme + cursor?: RunTuiConfig["cursor"] mono: boolean miniSettings: () => MiniSettings history?: () => RunPrompt[] @@ -733,6 +735,7 @@ export function RunFooterView(props: RunFooterViewProps) { runTheme().background} placeholder={composer.placeholder} onSubmit={composer.onSubmit} @@ -882,6 +885,7 @@ export function RunFooterView(props: RunFooterViewProps) { request={permission()!.request} directory={props.directory} theme={theme()} + cursor={props.cursor} block={block()} onReply={props.onPermissionReply} mono={props.mono} @@ -893,6 +897,7 @@ export function RunFooterView(props: RunFooterViewProps) { { if (!formsAbsent && !settledForms.has(state.formID)) diff --git a/packages/tui/src/mini/types.ts b/packages/tui/src/mini/types.ts index 37c3f42d86a0..7ca3c809c13d 100644 --- a/packages/tui/src/mini/types.ts +++ b/packages/tui/src/mini/types.ts @@ -392,7 +392,7 @@ export type FormCancel = { location?: LocationRef } -export type RunTuiConfig = Pick +export type RunTuiConfig = Pick export type MiniSettings = { thinking: "show" | "hide" diff --git a/packages/tui/test/mini/footer.view.test.tsx b/packages/tui/test/mini/footer.view.test.tsx index acef1c999cb3..dc0e65aa9d98 100644 --- a/packages/tui/test/mini/footer.view.test.tsx +++ b/packages/tui/test/mini/footer.view.test.tsx @@ -169,6 +169,7 @@ async function renderFooter( subagent={subagents} queuedPrompts={() => input.queuedPrompts ?? []} theme={input.theme ?? (() => RUN_THEME_FALLBACK)} + cursor={config.cursor} mono={input.mono ?? false} miniSettings={miniSettings} onSubmit={input.onSubmit ?? (() => true)} @@ -342,6 +343,18 @@ test("direct footer composer area does not adopt footer surface", async () => { } }) +test("direct footer composer uses the configured cursor style", async () => { + const cursor = { style: "underline" as const, blinking: false } + const app = await renderFooter({ tuiConfig: { ...tuiConfig, cursor } }) + + try { + await app.renderOnce() + expect(app.renderer.currentFocusedEditor?.cursorStyle).toEqual(cursor) + } finally { + app.cleanup() + } +}) + test("run entry content updates when live commit text changes", async () => { const [commit, setCommit] = createSignal({ kind: "tool",