fix: pass draft starter text as command arguments

This commit is contained in:
Bohdan Triapitsyn
2026-07-29 18:32:26 +03:00
parent 1fd51745c7
commit 4a56527d1b
4 changed files with 19 additions and 14 deletions
@@ -516,7 +516,7 @@ const DraftWelcome: React.FC = () => {
)}
</h1>
<DraftPresetChips
onSubmit={(text) => useInputStore.getState().requestPresetSubmit(text)}
onSubmit={(starter) => useInputStore.getState().requestPresetSubmit(starter.submitText, starter.ref.type)}
className="oc-draft-starters mt-8 max-w-md"
/>
</div>
@@ -1271,12 +1271,14 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
}, [inputMode, getCurrentInputSnapshot, currentSessionId, sessionPhase, autoReviewRunning, followUpBehavior, handleQueueMessage]);
// Draft welcome presets: submit immediately.
const submitPresetPrompt = React.useCallback((text: string) => {
const submitPresetPrompt = React.useCallback((text: string, type: 'command' | 'skill') => {
// The text goes straight into the submit (see SubmitOptions.presetText)
// instead of through the composer input — the collapsed mobile pill has
// no mounted textarea to stage it in.
const draft = (composerRef.current?.getValue() ?? messageRef.current).trim();
const presetText = draft ? `${text}\n${draft}` : text;
// OpenCode recognizes slash commands only when their arguments follow
// the command on the same line. Skills retain the multiline prompt form.
const presetText = draft ? `${text}${type === 'command' ? ' ' : '\n'}${draft}` : text;
void handleSubmitRef.current({ presetText });
}, []);
@@ -1308,7 +1310,7 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
React.useEffect(() => {
if (pendingPresetSubmit == null) return;
const text = useInputStore.getState().consumePendingPresetSubmit();
if (text) submitPresetPrompt(text);
if (text) submitPresetPrompt(text.text, text.type);
}, [pendingPresetSubmit, submitPresetPrompt]);
const handleKeyDown = (e: KeyboardEvent) => {
@@ -2718,7 +2720,10 @@ const ChatInputComponent: React.FC<ChatInputProps> = ({ onOpenSettings, scrollTo
) : null}
</div>
{newSessionDraftOpen && !isDesktopExpanded && !isMobile && !isVSCode && !isMiniChatSurface ? (
<DraftPresetChips onSubmit={submitPresetPrompt} className="chat-input-column mt-4" />
<DraftPresetChips
onSubmit={(starter) => submitPresetPrompt(starter.submitText, starter.ref.type)}
className="chat-input-column mt-4"
/>
) : null}
</form>
@@ -41,8 +41,8 @@ import {
} from './useDraftStarters';
type DraftPresetChipsProps = {
/** Called with the resolved text (command or skill invocation) when a chip is clicked. */
onSubmit: (text: string) => void;
/** Called with the resolved starter invocation when a chip is clicked. */
onSubmit: (starter: ResolvedStarter) => void;
/** Extra classes for the wrapper (e.g. width/spacing per surface). */
className?: string;
};
@@ -66,7 +66,7 @@ const PICKER_SECTIONS: { key: PinnableSection; headingKey: 'chat.draftStarters.s
const SortableChip: React.FC<{
item: ResolvedStarter;
onSubmit: (text: string) => void;
onSubmit: (starter: ResolvedStarter) => void;
onRemove: () => void;
/** Hide the per-chip hover "x" (mobile uses the trash drop-zone instead). */
hideRemove?: boolean;
@@ -91,7 +91,7 @@ const SortableChip: React.FC<{
type="button"
{...attributes}
{...listeners}
onClick={() => onSubmit(item.submitText)}
onClick={() => onSubmit(item)}
className="group inline-flex touch-none select-none items-center gap-1.5 rounded-full border px-3 py-1.5 text-sm text-muted-foreground transition-colors hover:bg-[var(--interactive-hover)] hover:text-foreground"
style={chipStyle}
>
@@ -116,7 +116,7 @@ const SortableChip: React.FC<{
const StarterGroup: React.FC<{
items: ResolvedStarter[];
onSubmit: (text: string) => void;
onSubmit: (starter: ResolvedStarter) => void;
onRemove: (item: ResolvedStarter) => void;
hideRemove?: boolean;
}> = ({ items, onSubmit, onRemove, hideRemove }) => (