mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-03-18 03:13:08 +00:00
feat: add interactive terminal and dev server management
Add new features for interactive terminal sessions and dev server control: Terminal Component: - New Terminal.tsx component using xterm.js for full terminal emulation - WebSocket-based PTY communication with bidirectional I/O - Cross-platform support (Windows via winpty, Unix via built-in pty) - Auto-reconnection with exponential backoff - Fix duplicate WebSocket connection bug by checking CONNECTING state - Add manual close flag to prevent auto-reconnect race conditions - Add project tracking to avoid duplicate connects on initial activation Dev Server Management: - New DevServerControl.tsx for starting/stopping dev servers - DevServerManager service for subprocess management - WebSocket streaming of dev server output - Project configuration service for reading package.json scripts Backend Infrastructure: - Terminal router with WebSocket endpoint for PTY I/O - DevServer router for server lifecycle management - Terminal session manager with callback-based output streaming - Enhanced WebSocket schemas for terminal and dev server messages UI Integration: - New Terminal and Dev Server tabs in the main application - Updated DebugLogViewer with improved UI and functionality - Extended useWebSocket hook for terminal message handling Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -13,12 +13,13 @@ import { ProgressDashboard } from './components/ProgressDashboard'
|
||||
import { SetupWizard } from './components/SetupWizard'
|
||||
import { AddFeatureForm } from './components/AddFeatureForm'
|
||||
import { FeatureModal } from './components/FeatureModal'
|
||||
import { DebugLogViewer } from './components/DebugLogViewer'
|
||||
import { DebugLogViewer, type TabType } from './components/DebugLogViewer'
|
||||
import { AgentThought } from './components/AgentThought'
|
||||
import { AssistantFAB } from './components/AssistantFAB'
|
||||
import { AssistantPanel } from './components/AssistantPanel'
|
||||
import { ExpandProjectModal } from './components/ExpandProjectModal'
|
||||
import { SettingsModal } from './components/SettingsModal'
|
||||
import { DevServerControl } from './components/DevServerControl'
|
||||
import { Loader2, Settings } from 'lucide-react'
|
||||
import type { Feature } from './lib/types'
|
||||
|
||||
@@ -37,6 +38,7 @@ function App() {
|
||||
const [setupComplete, setSetupComplete] = useState(true) // Start optimistic
|
||||
const [debugOpen, setDebugOpen] = useState(false)
|
||||
const [debugPanelHeight, setDebugPanelHeight] = useState(288) // Default height
|
||||
const [debugActiveTab, setDebugActiveTab] = useState<TabType>('agent')
|
||||
const [assistantOpen, setAssistantOpen] = useState(false)
|
||||
const [showSettings, setShowSettings] = useState(false)
|
||||
const [isSpecCreating, setIsSpecCreating] = useState(false)
|
||||
@@ -88,6 +90,22 @@ function App() {
|
||||
setDebugOpen(prev => !prev)
|
||||
}
|
||||
|
||||
// T : Toggle terminal tab in debug panel
|
||||
if (e.key === 't' || e.key === 'T') {
|
||||
e.preventDefault()
|
||||
if (!debugOpen) {
|
||||
// If panel is closed, open it and switch to terminal tab
|
||||
setDebugOpen(true)
|
||||
setDebugActiveTab('terminal')
|
||||
} else if (debugActiveTab === 'terminal') {
|
||||
// If already on terminal tab, close the panel
|
||||
setDebugOpen(false)
|
||||
} else {
|
||||
// If open but on different tab, switch to terminal
|
||||
setDebugActiveTab('terminal')
|
||||
}
|
||||
}
|
||||
|
||||
// N : Add new feature (when project selected)
|
||||
if ((e.key === 'n' || e.key === 'N') && selectedProject) {
|
||||
e.preventDefault()
|
||||
@@ -133,7 +151,7 @@ function App() {
|
||||
|
||||
window.addEventListener('keydown', handleKeyDown)
|
||||
return () => window.removeEventListener('keydown', handleKeyDown)
|
||||
}, [selectedProject, showAddFeature, showExpandProject, selectedFeature, debugOpen, assistantOpen, features, showSettings, isSpecCreating])
|
||||
}, [selectedProject, showAddFeature, showExpandProject, selectedFeature, debugOpen, debugActiveTab, assistantOpen, features, showSettings, isSpecCreating])
|
||||
|
||||
// Combine WebSocket progress with feature data
|
||||
const progress = wsState.progress.total > 0 ? wsState.progress : {
|
||||
@@ -178,6 +196,12 @@ function App() {
|
||||
status={wsState.agentStatus}
|
||||
/>
|
||||
|
||||
<DevServerControl
|
||||
projectName={selectedProject}
|
||||
status={wsState.devServerStatus}
|
||||
url={wsState.devServerUrl}
|
||||
/>
|
||||
|
||||
<button
|
||||
onClick={() => setShowSettings(true)}
|
||||
className="neo-btn text-sm py-2 px-3"
|
||||
@@ -285,10 +309,15 @@ function App() {
|
||||
{selectedProject && (
|
||||
<DebugLogViewer
|
||||
logs={wsState.logs}
|
||||
devLogs={wsState.devLogs}
|
||||
isOpen={debugOpen}
|
||||
onToggle={() => setDebugOpen(!debugOpen)}
|
||||
onClear={wsState.clearLogs}
|
||||
onClearDevLogs={wsState.clearDevLogs}
|
||||
onHeightChange={setDebugPanelHeight}
|
||||
projectName={selectedProject}
|
||||
activeTab={debugActiveTab}
|
||||
onTabChange={setDebugActiveTab}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user