import { useCallback, useState } from 'react'; import { toast } from 'sonner'; import { ChatInput } from '@/components/ChatInput'; interface Props { projectId: string; sessionId: string; agentId?: string | null; onAgentChange?: (agentId: string | null) => void | Promise; onSend: (content: string) => void; // Slash-command (skill) send from the landing page. The parent creates the // chat, assigns it to the pane (so it transitions to ChatPane), and invokes // the skill — same transition the text send uses. See useSessionChats. onSkillInvoke: (skillName: string, userMessage: string | null) => void; createChat: () => Promise<{ id: string }>; } export function SessionLandingPage({ projectId, sessionId, agentId, onAgentChange, onSend, onSkillInvoke, createChat, }: Props) { const [chatId, setChatId] = useState(null); const ensureChat = useCallback(async (): Promise => { if (chatId) return chatId; try { const chat = await createChat(); setChatId(chat.id); return chat.id; } catch (err) { toast.error(err instanceof Error ? err.message : 'Failed to create chat'); throw err; } }, [chatId, createChat]); const handleSend = useCallback(async (content: string) => { const text = content.trim(); if (!text) return; try { await ensureChat(); onSend(text); } catch { // Error already surfaced via toast. } }, [ensureChat, onSend]); // Route to the parent, which creates the chat, assigns it to the pane (so the // pane transitions to ChatPane and subscribes to the stream), then invokes the // skill — mirroring the text-send transition. Doing the skill invoke locally // (without the pane assignment) left the landing pane stuck/blank. const handleSlashCommand = useCallback((skillName: string, userMessage: string) => { onSkillInvoke(skillName, userMessage.length > 0 ? userMessage : null); }, [onSkillInvoke]); return (

Send a message to start.

); }