diff --git a/backend/server.js b/backend/server.js index 6a19746..d15cc7e 100644 --- a/backend/server.js +++ b/backend/server.js @@ -837,6 +837,20 @@ wss.on('connection', async (ws, req) => { // Note: ExitPlanMode is now handled exclusively via Control Protocol (can_use_tool) // to avoid tool_result/control_response confusion and message compaction issues + // Debug: Write all events to file for context analysis + const debugLogPath = '/tmp/claude-events-debug.jsonl'; + const debugEntry = { + timestamp: new Date().toISOString(), + sessionId, + event + }; + try { + const fs = await import('fs'); + fs.appendFileSync(debugLogPath, JSON.stringify(debugEntry) + '\n'); + } catch (e) { + // Ignore write errors + } + sendToClient('claude_event', { event }); } catch (e) { // Non-JSON output, send as raw @@ -848,10 +862,26 @@ wss.on('connection', async (ws, req) => { }); // Handle stderr - claudeProcess.stderr.on('data', (data) => { + claudeProcess.stderr.on('data', async (data) => { const content = data.toString(); // Always log stderr for SSH connections (exit code 255 debugging) if (DEBUG || isSSH) console.log(`[${sessionId}] stderr:`, content); + + // Debug: Write stderr to file for context analysis + const debugLogPath = '/tmp/claude-events-debug.jsonl'; + const debugEntry = { + timestamp: new Date().toISOString(), + sessionId, + type: 'stderr', + content + }; + try { + const fs = await import('fs'); + fs.appendFileSync(debugLogPath, JSON.stringify(debugEntry) + '\n'); + } catch (e) { + // Ignore write errors + } + sendToClient('stderr', { content }); }); diff --git a/frontend/src/components/ChatInput.jsx b/frontend/src/components/ChatInput.jsx index 0378144..cbfa981 100644 --- a/frontend/src/components/ChatInput.jsx +++ b/frontend/src/components/ChatInput.jsx @@ -38,6 +38,7 @@ function saveHistory(history) { // Available slash commands for autocomplete const COMMANDS = [ + { name: 'compact', description: 'Compact context (summarize conversation)' }, { name: 'help', description: 'Show available commands' }, { name: 'clear', description: 'Clear chat history' }, { name: 'export', description: 'Export chat as Markdown' }, @@ -295,6 +296,24 @@ export const ChatInput = memo(function ChatInput({ onSend, onStop, disabled, isP } }; + // Handle input changes for slash command detection (lightweight, no state updates for value) + const handleInput = useCallback(() => { + const value = textareaRef.current?.value || ''; + + // Show command menu when typing "/" at the start + if (value.startsWith('/')) { + const query = value.slice(1).toLowerCase(); + const filtered = COMMANDS.filter(cmd => + cmd.name.toLowerCase().includes(query) + ); + setFilteredCommands(filtered); + setShowCommands(filtered.length > 0); + setSelectedIndex(0); + } else { + setShowCommands(false); + } + }, []); + return (