import React, { useState, useCallback } from 'react'; import { Box, Text } from 'ink'; import TextInput from 'ink-text-input'; import type { ParsedCommand } from '@mosaic/types'; import { parseSlashCommand, commandRegistry } from '../commands/index.js'; export interface InputBarProps { onSubmit: (value: string) => void; onSystemMessage?: (message: string) => void; onLocalCommand?: (parsed: ParsedCommand) => void; onGatewayCommand?: (parsed: ParsedCommand) => void; isStreaming: boolean; connected: boolean; placeholder?: string; } export function InputBar({ onSubmit, onSystemMessage, onLocalCommand, onGatewayCommand, isStreaming, connected, placeholder: placeholderOverride, }: InputBarProps) { const [input, setInput] = useState(''); const handleSubmit = useCallback( (value: string) => { if (!value.trim() || isStreaming || !connected) return; const trimmed = value.trim(); if (trimmed.startsWith('/')) { const parsed = parseSlashCommand(trimmed); if (!parsed) { onSystemMessage?.(`Unknown command format: ${trimmed}`); setInput(''); return; } const def = commandRegistry.find(parsed.command); if (!def) { onSystemMessage?.( `Unknown command: /${parsed.command}. Type /help for available commands.`, ); setInput(''); return; } if (def.execution === 'local') { onLocalCommand?.(parsed); setInput(''); return; } // Gateway-executed commands onGatewayCommand?.(parsed); setInput(''); return; } onSubmit(value); setInput(''); }, [onSubmit, onSystemMessage, onLocalCommand, onGatewayCommand, isStreaming, connected], ); const placeholder = placeholderOverride ?? (!connected ? 'disconnected — waiting for gateway…' : isStreaming ? 'waiting for response…' : 'message mosaic…'); return ( {'❯ '} ); }