forked from aws/agentcore-cli
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathNextSteps.tsx
More file actions
107 lines (98 loc) · 2.98 KB
/
Copy pathNextSteps.tsx
File metadata and controls
107 lines (98 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import { useListNavigation } from '../hooks';
import { STATUS_COLORS } from '../theme';
import { SelectList } from './SelectList';
import { Box, Text } from 'ink';
/**
* Defines a next step action after a command completes.
*/
export interface NextStep {
/** The command to run (e.g., 'invoke', 'deploy') */
command: string;
/** Human-readable label (e.g., 'Test your agent') */
label: string;
}
export interface NextStepsProps {
/** List of next step options */
steps: NextStep[];
/** Whether running in interactive TUI mode */
isInteractive: boolean;
/** Callback when a step is selected (interactive mode) */
onSelect?: (step: NextStep) => void;
/** Callback when user wants to go back to home (interactive mode) */
onBack?: () => void;
/** Whether the component is active for keyboard input */
isActive?: boolean;
}
/**
* Renders next steps after a command completes.
*
* Interactive mode: Shows a selectable list with "return" option to go back to main menu
* Non-interactive mode: Shows a text hint and exits
*/
export function NextSteps({ steps, isInteractive, onSelect, onBack, isActive = true }: NextStepsProps) {
// Build items for interactive mode (add "return to main menu" as last option)
const interactiveItems = [
...steps.map(step => ({
id: step.command,
title: step.command,
description: step.label,
})),
{ id: '_back', title: 'return', description: 'Return to main menu' },
];
const { selectedIndex } = useListNavigation({
items: interactiveItems,
onSelect: item => {
if (item.id === '_back') {
onBack?.();
} else {
const step = steps.find(s => s.command === item.id);
if (step) {
onSelect?.(step);
}
}
},
onExit: onBack,
isActive: isInteractive && isActive,
});
if (isInteractive) {
return (
<Box flexDirection="column" marginTop={1}>
<Text>Next steps:</Text>
<Box marginTop={1}>
<SelectList items={interactiveItems} selectedIndex={selectedIndex} />
</Box>
</Box>
);
}
// Non-interactive mode: render as text hint
if (steps.length === 0) {
return null;
}
if (steps.length === 1) {
const step = steps[0]!;
return (
<Box flexDirection="column" marginTop={1}>
<Text dimColor>
Next: Run <Text color={STATUS_COLORS.info}>agentcore {step.command}</Text> to {step.label.toLowerCase()}
</Text>
</Box>
);
}
// Multiple steps: format as "Run X to do Y, or Z to do W"
const parts = steps.map((step, i) => {
const isLast = i === steps.length - 1;
const separator = isLast ? ', or ' : i > 0 ? ', ' : '';
return (
<Text key={step.command}>
{separator}
<Text color={STATUS_COLORS.info}>agentcore {step.command}</Text>
<Text> to {step.label.toLowerCase()}</Text>
</Text>
);
});
return (
<Box flexDirection="column" marginTop={1}>
<Text dimColor>Next: Run {parts}</Text>
</Box>
);
}