import { useState, useRef, useEffect, useCallback } from 'react'; import { useClaudeSession } from './hooks/useClaudeSession'; import { MessageList } from './components/MessageList'; import { ChatInput } from './components/ChatInput'; import { Sidebar } from './components/Sidebar'; import { Header } from './components/Header'; // Slash command definitions const SLASH_COMMANDS = { clear: { description: 'Clear chat history (UI only)', execute: ({ clearMessages, addSystemMessage }) => { clearMessages(); addSystemMessage('Chat cleared'); } }, help: { description: 'Show available commands', execute: ({ addSystemMessage }) => { const helpText = Object.entries(SLASH_COMMANDS) .map(([cmd, { description }]) => `/${cmd} - ${description}`) .join('\n'); addSystemMessage(`Available commands:\n${helpText}`); } }, export: { description: 'Export chat as Markdown', execute: ({ messages, addSystemMessage }) => { const markdown = messages.map(m => { if (m.type === 'user') return `**You:** ${m.content}`; if (m.type === 'assistant') return `**Claude:** ${m.content}`; if (m.type === 'tool_use') return `> Tool: ${m.tool}`; if (m.type === 'system') return `_${m.content}_`; return ''; }).filter(Boolean).join('\n\n'); const blob = new Blob([markdown], { type: 'text/markdown' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `claude-chat-${new Date().toISOString().slice(0,10)}.md`; a.click(); URL.revokeObjectURL(url); addSystemMessage('Chat exported as Markdown'); } }, scroll: { description: 'Scroll to top or bottom (/scroll top|bottom)', execute: ({ args, addSystemMessage }) => { const direction = args[0] || 'bottom'; const container = document.querySelector('.overflow-y-auto'); if (container) { if (direction === 'top') { container.scrollTo({ top: 0, behavior: 'smooth' }); } else { container.scrollTo({ top: container.scrollHeight, behavior: 'smooth' }); } } addSystemMessage(`Scrolled to ${direction}`); } }, new: { description: 'Start a new session (clears history)', execute: ({ clearMessages, stopSession, startSession, selectedProject, addSystemMessage }) => { stopSession(); clearMessages(); setTimeout(() => { startSession(selectedProject, false); // false = don't resume }, 500); addSystemMessage('Starting new session...'); } }, info: { description: 'Show session info', execute: ({ connected, sessionActive, currentProject, messages, addSystemMessage }) => { const info = [ `Connected: ${connected ? 'Yes' : 'No'}`, `Session: ${sessionActive ? 'Active' : 'Inactive'}`, `Project: ${currentProject || 'None'}`, `Messages: ${messages.length}` ].join('\n'); addSystemMessage(info); } } }; function App() { const { connected, sessionActive, messages, currentProject, isProcessing, error, startSession, sendMessage, stopSession, clearMessages, setError, setMessages } = useClaudeSession(); const [selectedProject, setSelectedProject] = useState('/projects/claude-web-ui'); const [selectedHost, setSelectedHost] = useState('local'); const [sidebarOpen, setSidebarOpen] = useState(true); const [resumeSession, setResumeSession] = useState(true); // Add system message helper const addSystemMessage = useCallback((content) => { setMessages(prev => [...prev, { type: 'system', content, timestamp: Date.now() }]); }, [setMessages]); const handleStartSession = () => { startSession(selectedProject, resumeSession, selectedHost); }; // Handle slash commands const handleCommand = useCallback((command, args) => { const cmd = SLASH_COMMANDS[command.toLowerCase()]; if (cmd) { cmd.execute({ clearMessages, addSystemMessage, messages, stopSession, startSession, selectedProject, connected, sessionActive, currentProject, args }); return true; } return false; }, [clearMessages, addSystemMessage, messages, stopSession, startSession, selectedProject, connected, sessionActive, currentProject]); const handleSendMessage = (message) => { if (!message.trim()) return; // Check for slash command if (message.startsWith('/')) { const parts = message.slice(1).split(' '); const command = parts[0]; const args = parts.slice(1); if (handleCommand(command, args)) { return; // Command handled } else { addSystemMessage(`Unknown command: /${command}. Type /help for available commands.`); return; } } // Regular message sendMessage(message); }; return (