Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions src/cli/tui/screens/create/CreateScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,16 @@ export function CreateScreen({ cwd, isInteractive, onExit, onNavigate }: CreateS
onExit,
]);

// Esc on the create-type prompt returns to the project-name input (matching the
// "Esc back" footer); on every other phase it falls through to the top-level exit.
const handleBack = useCallback(() => {
if (flow.phase === 'create-type-prompt') {
flow.goBackToInput();
} else {
handleExit();
}
}, [flow, handleExit]);

// Auto-exit when project creation completes successfully
useEffect(() => {
if (allSuccess) {
Expand All @@ -287,7 +297,7 @@ export function CreateScreen({ cwd, isInteractive, onExit, onNavigate }: CreateS
onSelect: item => {
flow.handleCreateTypeSelection(item.id as 'harness' | 'agent' | 'skip');
},
onExit: handleExit,
onExit: handleBack,
isActive: flow.phase === 'create-type-prompt',
});

Expand Down Expand Up @@ -342,7 +352,7 @@ export function CreateScreen({ cwd, isInteractive, onExit, onNavigate }: CreateS
: undefined;

return (
<Screen title="AgentCore Create" onExit={handleExit} headerContent={headerContent} helpText={helpText}>
<Screen title="AgentCore Create" onExit={handleBack} headerContent={headerContent} helpText={helpText}>
{phase === 'existing-project-error' && (
<Box marginBottom={1} flexDirection="column">
<Text color="red">A project already exists at this location.</Text>
Expand Down
39 changes: 39 additions & 0 deletions src/cli/tui/screens/create/__tests__/CreateScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { CreateScreen } from '../CreateScreen.js';
import { render } from 'ink-testing-library';
import { mkdtempSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
import React from 'react';
import { afterEach, describe, expect, it, vi } from 'vitest';

const ENTER = '\r';
const ESCAPE = '\x1B';

const tick = () => new Promise(resolve => setTimeout(resolve, 20));

afterEach(() => vi.restoreAllMocks());

describe('CreateScreen Esc on create-type prompt', () => {
it('returns to the project-name input without exiting the CLI', async () => {
const cwd = mkdtempSync(join(tmpdir(), 'create-screen-'));
const onExit = vi.fn();
const { stdin, lastFrame } = render(<CreateScreen cwd={cwd} isInteractive onExit={onExit} />);

// Wait for the existing-project check to resolve into the input phase.
await tick();
expect(lastFrame()).toContain('Create a new AgentCore project');

// Submit a valid project name -> advances to the create-type prompt.
stdin.write('MyProject');
await tick();
stdin.write(ENTER);
await tick();
expect(lastFrame()).toContain('What would you like to build?');

// Esc must go back to the name input, not quit the CLI.
stdin.write(ESCAPE);
await tick();
expect(lastFrame()).toContain('Create a new AgentCore project');
expect(onExit).not.toHaveBeenCalled();
});
});
6 changes: 6 additions & 0 deletions src/cli/tui/screens/create/useCreateFlow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ interface CreateFlowState {
// Project name actions
setProjectName: (name: string) => void;
confirmProjectName: () => void;
goBackToInput: () => void;
// Create type selection
handleCreateTypeSelection: (choice: 'harness' | 'agent' | 'skip') => void;
// Add agent config (set when AddAgentScreen completes)
Expand Down Expand Up @@ -180,6 +181,10 @@ export function useCreateFlow(cwd: string): CreateFlowState {
setPhase('create-type-prompt');
}, []);

const goBackToInput = useCallback(() => {
setPhase('input');
}, []);

const updateStep = (index: number, update: Partial<Step>) => {
setSteps(prev => prev.map((s, i) => (i === index ? { ...s, ...update } : s)));
};
Expand Down Expand Up @@ -756,6 +761,7 @@ export function useCreateFlow(cwd: string): CreateFlowState {
logFilePath,
setProjectName,
confirmProjectName,
goBackToInput,
// Create type selection
handleCreateTypeSelection,
// Add agent
Expand Down
Loading