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:
Auto
2026-01-12 10:35:36 +02:00
parent b1473cdfb9
commit c1985eb285
22 changed files with 3360 additions and 66 deletions

View File

@@ -21,6 +21,8 @@ import type {
Settings,
SettingsUpdate,
ModelsResponse,
DevServerStatusResponse,
DevServerConfig,
} from './types'
const API_BASE = '/api'
@@ -301,3 +303,33 @@ export async function updateSettings(settings: SettingsUpdate): Promise<Settings
body: JSON.stringify(settings),
})
}
// ============================================================================
// Dev Server API
// ============================================================================
export async function getDevServerStatus(projectName: string): Promise<DevServerStatusResponse> {
return fetchJSON(`/projects/${encodeURIComponent(projectName)}/devserver/status`)
}
export async function startDevServer(
projectName: string,
command?: string
): Promise<{ success: boolean; message: string }> {
return fetchJSON(`/projects/${encodeURIComponent(projectName)}/devserver/start`, {
method: 'POST',
body: JSON.stringify({ command }),
})
}
export async function stopDevServer(
projectName: string
): Promise<{ success: boolean; message: string }> {
return fetchJSON(`/projects/${encodeURIComponent(projectName)}/devserver/stop`, {
method: 'POST',
})
}
export async function getDevServerConfig(projectName: string): Promise<DevServerConfig> {
return fetchJSON(`/projects/${encodeURIComponent(projectName)}/devserver/config`)
}