Skip to content

Commit 3fc5d1f

Browse files
authored
fix: container dev now has a starting container status (#346)
1 parent 6ed4411 commit 3fc5d1f

File tree

2 files changed

+38
-16
lines changed

2 files changed

+38
-16
lines changed

src/cli/tui/hooks/useDevServer.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ export interface ConversationMessage {
2828

2929
const MAX_LOG_ENTRIES = 50;
3030

31-
export function useDevServer(options: { workingDir: string; port: number; agentName?: string }) {
31+
export function useDevServer(options: { workingDir: string; port: number; agentName?: string; onReady?: () => void }) {
3232
const [logs, setLogs] = useState<LogEntry[]>([]);
3333
const [status, setStatus] = useState<ServerStatus>('starting');
3434
const [isStreaming, setIsStreaming] = useState(false);
@@ -45,6 +45,8 @@ export function useDevServer(options: { workingDir: string; port: number; agentN
4545

4646
const serverRef = useRef<DevServer | null>(null);
4747
const loggerRef = useRef<DevLogger | null>(null);
48+
const onReadyRef = useRef(options.onReady);
49+
onReadyRef.current = options.onReady;
4850
// Track instance ID to ignore callbacks from stale server instances
4951
const instanceIdRef = useRef(0);
5052
// Track if we're intentionally restarting to ignore exit callbacks
@@ -127,6 +129,7 @@ export function useDevServer(options: { workingDir: string; port: number; agentN
127129
) {
128130
serverReady = true;
129131
setStatus('running');
132+
onReadyRef.current?.();
130133
addLog('system', `Server ready at http://localhost:${port}/invocations`);
131134
} else {
132135
addLog(level, message);

src/cli/tui/screens/dev/DevScreen.tsx

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -127,15 +127,15 @@ export function DevScreen(props: DevScreenProps) {
127127
const found = agents.find(a => a.name === props.agentName);
128128
if (found) {
129129
setSelectedAgentName(props.agentName);
130-
setMode('input');
130+
setMode('chat');
131131
} else if (agents.length > 0) {
132132
// Agent not found or not supported, show selection
133133
setSelectedAgentName(undefined);
134134
}
135135
} else if (agents.length === 1 && agents[0]) {
136136
// Auto-select if only one agent
137137
setSelectedAgentName(agents[0].name);
138-
setMode('input');
138+
setMode('chat');
139139
} else if (agents.length === 0) {
140140
// No supported agents, show error screen
141141
setNoAgentsError(true);
@@ -146,7 +146,10 @@ export function DevScreen(props: DevScreenProps) {
146146
void load();
147147
}, [workingDir, props.agentName]);
148148

149+
const onServerReady = useCallback(() => setMode(prev => (prev === 'chat' ? 'input' : prev)), []);
150+
149151
const {
152+
logs,
150153
status,
151154
isStreaming,
152155
conversation,
@@ -165,6 +168,7 @@ export function DevScreen(props: DevScreenProps) {
165168
workingDir,
166169
port: props.port ?? 8080,
167170
agentName: selectedAgentName,
171+
onReady: onServerReady,
168172
});
169173

170174
// Handle exit with brief "stopping" message
@@ -259,7 +263,7 @@ export function DevScreen(props: DevScreenProps) {
259263
const agent = supportedAgents[selectedAgentIndex];
260264
if (agent) {
261265
setSelectedAgentName(agent.name);
262-
setMode('input');
266+
setMode('chat');
263267
}
264268
}
265269
return;
@@ -289,8 +293,8 @@ export function DevScreen(props: DevScreenProps) {
289293
// Clear the flag on any other key
290294
justCancelledRef.current = false;
291295

292-
// Enter to start typing (only when not streaming)
293-
if (key.return && !isStreaming) {
296+
// Enter to start typing (only when not streaming and server is running)
297+
if (key.return && !isStreaming && status === 'running') {
294298
setMode('input');
295299
return;
296300
}
@@ -314,7 +318,7 @@ export function DevScreen(props: DevScreenProps) {
314318
setUserScrolled(false);
315319
return;
316320
}
317-
if (key.ctrl && input === 'r') {
321+
if (key.ctrl && input === 'r' && status !== 'starting') {
318322
restart();
319323
return;
320324
}
@@ -355,11 +359,13 @@ export function DevScreen(props: DevScreenProps) {
355359
? '↑↓ select · Enter confirm · q quit'
356360
: mode === 'input'
357361
? 'Enter send · Esc cancel'
358-
: isStreaming
359-
? '↑↓ scroll'
360-
: conversation.length > 0
361-
? `↑↓ scroll · Enter invoke · C clear · Ctrl+R restart · ${supportedAgents.length > 1 ? 'Esc back' : 'Esc quit'}`
362-
: `Enter to send a message · Ctrl+R restart · ${supportedAgents.length > 1 ? 'Esc back' : 'Esc quit'}`;
362+
: status === 'starting'
363+
? `${supportedAgents.length > 1 ? 'Esc back' : 'Esc quit'}`
364+
: isStreaming
365+
? '↑↓ scroll'
366+
: conversation.length > 0
367+
? `↑↓ scroll · Enter invoke · C clear · Ctrl+R restart · ${supportedAgents.length > 1 ? 'Esc back' : 'Esc quit'}`
368+
: `Enter to send a message · Ctrl+R restart · ${supportedAgents.length > 1 ? 'Esc back' : 'Esc quit'}`;
363369

364370
// Agent selection screen
365371
if (mode === 'select-agent') {
@@ -394,12 +400,25 @@ export function DevScreen(props: DevScreenProps) {
394400
<Text>Server: </Text>
395401
<Text color="cyan">http://localhost:{actualPort}/invocations</Text>
396402
</Box>
397-
{status !== 'starting' && !isExiting && (
403+
{!isExiting && (
398404
<Box>
399405
<Text>Status: </Text>
400-
<Text color={statusColor}>{status}</Text>
406+
{status === 'starting' ? (
407+
<Text color="yellow">{config?.buildType === 'Container' ? 'Starting container...' : 'Starting...'}</Text>
408+
) : (
409+
<Text color={statusColor}>{status}</Text>
410+
)}
401411
</Box>
402412
)}
413+
{status === 'error' &&
414+
logs
415+
.filter(l => l.level === 'error')
416+
.slice(-3)
417+
.map((l, i) => (
418+
<Text key={i} color="red">
419+
{l.message}
420+
</Text>
421+
))}
403422
{isExiting && (
404423
<Box>
405424
<Text color="yellow">Stopping server...</Text>
@@ -444,12 +463,12 @@ export function DevScreen(props: DevScreenProps) {
444463
{/* Input line - always visible at bottom */}
445464
{/* Unfocused: dim arrow, press Enter to focus */}
446465
{/* Focused: blue arrow with cursor, type and press Enter to send */}
447-
{mode === 'chat' && !isStreaming && (
466+
{status === 'running' && mode === 'chat' && !isStreaming && (
448467
<Box>
449468
<Text dimColor>&gt; </Text>
450469
</Box>
451470
)}
452-
{mode === 'input' && (
471+
{status === 'running' && mode === 'input' && (
453472
<Box>
454473
<Text color="blue">&gt; </Text>
455474
<TextInput

0 commit comments

Comments
 (0)