From 6fc5fc6ec9a554750cab4e7ff9bdaa94f7f37868 Mon Sep 17 00:00:00 2001 From: JosXa Date: Fri, 16 Jan 2026 03:45:04 +0100 Subject: [PATCH] feat: use agent description as prompt placeholder - Show agent description in placeholder when available - Fall back to randomized hints for build agent or no description - Implement in both CLI (TUI) and app (web) components - Add .padEnd(70) workaround for text rendering ghosting bug Fixes issue where switching agents caused visual corruption with ghost characters from previous placeholder remaining visible. TODO: Find proper fix for text layout cache invalidation instead of padding workaround. --- packages/app/src/components/prompt-input.tsx | 23 +++++++++++++++---- .../cli/cmd/tui/component/prompt/index.tsx | 14 ++++++++++- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx index 2f85652a93e..9f7b8e3089d 100644 --- a/packages/app/src/components/prompt-input.tsx +++ b/packages/app/src/components/prompt-input.tsx @@ -190,6 +190,23 @@ export const PromptInput: Component = (props) => { applyingHistory: false, }) + const placeholderText = createMemo(() => { + const currentAgent = local.agent.current() + if (currentAgent?.name === "build" || !currentAgent?.description) { + // TODO: Padding workaround for rendering bug where ghost characters from previous + // placeholder remain visible when switching to shorter text. Browser doesn't properly + // clear cached text layout with truncate/ellipsis CSS. Proper fix would be to force + // element recreation or use a different rendering approach. + return `Ask anything... "${PLACEHOLDERS[store.placeholder]}"`.padEnd(70, " ") + } + return currentAgent.description.padEnd(70, " ") + }) + + const shouldRotatePlaceholder = createMemo(() => { + const currentAgent = local.agent.current() + return currentAgent?.name === "build" || !currentAgent?.description + }) + const MAX_HISTORY = 100 const [history, setHistory] = persisted( Persist.global("prompt-history", ["prompt-history.v1"]), @@ -256,7 +273,7 @@ export const PromptInput: Component = (props) => { createEffect(() => { params.id editorRef.focus() - if (params.id) return + if (params.id || !shouldRotatePlaceholder()) return const interval = setInterval(() => { setStore("placeholder", (prev) => (prev + 1) % PLACEHOLDERS.length) }, 6500) @@ -1541,9 +1558,7 @@ export const PromptInput: Component = (props) => { />
- {store.mode === "shell" - ? "Enter shell command..." - : `Ask anything... "${PLACEHOLDERS[store.placeholder]}"`} + {store.mode === "shell" ? "Enter shell command..." : placeholderText()}
diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 96b9e8ffd57..f9c54ef0072 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -344,6 +344,18 @@ export function Prompt(props: PromptProps) { }, } + const placeholderText = createMemo(() => { + const currentAgent = local.agent.current() + if (currentAgent.name === "build" || !currentAgent.description) { + // TODO: Padding workaround for rendering bug where ghost characters from previous + // placeholder remain visible when switching to shorter text. Browser/terminal doesn't + // properly clear cached text layout. Proper fix would be to force element recreation + // or find why OpenTUI textarea doesn't invalidate placeholder rendering. + return `Ask anything... "${PLACEHOLDERS[store.placeholder]}"`.padEnd(70, " ") + } + return currentAgent.description.padEnd(70, " ") + }) + createEffect(() => { if (props.visible !== false) input?.focus() if (props.visible === false) input?.blur() @@ -761,7 +773,7 @@ export function Prompt(props: PromptProps) { flexGrow={1} >