11import { createExternalGatewayTarget } from '../../../operations/mcp/create-mcp' ;
2- import { ErrorPrompt , Panel , Screen , TextInput , WizardSelect } from '../../components' ;
3- import type { SelectableItem } from '../../components' ;
4- import { HELP_TEXT } from '../../constants' ;
5- import { useListNavigation } from '../../hooks' ;
6- import { useAgents , useBindMcpRuntime , useMcpRuntimeTools } from '../../hooks/useAttach' ;
2+ import { ErrorPrompt } from '../../components' ;
73import { useCreateGatewayTarget , useExistingGateways , useExistingToolNames } from '../../hooks/useCreateMcp' ;
84import { AddSuccessScreen } from '../add/AddSuccessScreen' ;
95import { AddGatewayTargetScreen } from './AddGatewayTargetScreen' ;
106import type { AddGatewayTargetConfig } from './types' ;
11- import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
7+ import React , { useCallback , useEffect , useState } from 'react' ;
128
139type FlowState =
14- | { name : 'mode-select' }
1510 | { name : 'create-wizard' }
16- | { name : 'bind-select-runtime' }
17- | { name : 'bind-select-agent' ; mcpRuntimeName : string }
18- | { name : 'bind-enter-envvar' ; mcpRuntimeName : string ; targetAgent : string }
1911 | { name : 'create-success' ; toolName : string ; projectPath : string ; loading ?: boolean ; loadingMessage ?: string }
20- | { name : 'bind-success' ; mcpRuntimeName : string ; targetAgent : string }
2112 | { name : 'error' ; message : string } ;
2213
2314interface AddGatewayTargetFlowProps {
@@ -31,10 +22,7 @@ interface AddGatewayTargetFlowProps {
3122 onDeploy ?: ( ) => void ;
3223}
3324
34- const MODE_OPTIONS : SelectableItem [ ] = [
35- { id : 'create' , title : 'Create new MCP tool' , description : 'Define a new MCP tool project' } ,
36- { id : 'bind' , title : 'Bind existing MCP runtime' , description : 'Add an agent to an existing MCP runtime' } ,
37- ] ;
25+
3826
3927export function AddGatewayTargetFlow ( {
4028 isInteractive = true ,
@@ -46,63 +34,15 @@ export function AddGatewayTargetFlow({
4634 const { createTool, reset : resetCreate } = useCreateGatewayTarget ( ) ;
4735 const { gateways : existingGateways } = useExistingGateways ( ) ;
4836 const { toolNames : existingToolNames } = useExistingToolNames ( ) ;
49- const [ flow , setFlow ] = useState < FlowState > ( { name : 'mode-select' } ) ;
50-
51- // Bind flow hooks
52- const { agents : allAgents , isLoading : isLoadingAgents } = useAgents ( ) ;
53- const { tools : mcpRuntimeTools } = useMcpRuntimeTools ( ) ;
54- const { bind : bindMcpRuntime } = useBindMcpRuntime ( ) ;
37+ const [ flow , setFlow ] = useState < FlowState > ( { name : 'create-wizard' } ) ;
5538
5639 // In non-interactive mode, exit after success (but not while loading)
5740 useEffect ( ( ) => {
58- if ( ! isInteractive ) {
59- if ( ( flow . name === 'create-success' && ! flow . loading ) || flow . name === 'bind-success' ) {
60- onExit ( ) ;
61- }
41+ if ( ! isInteractive && flow . name === 'create-success' && ! flow . loading ) {
42+ onExit ( ) ;
6243 }
6344 } , [ isInteractive , flow , onExit ] ) ;
6445
65- // Mode selection navigation
66- const modeNav = useListNavigation ( {
67- items : MODE_OPTIONS ,
68- onSelect : item => {
69- if ( item . id === 'create' ) {
70- setFlow ( { name : 'create-wizard' } ) ;
71- } else {
72- setFlow ( { name : 'bind-select-runtime' } ) ;
73- }
74- } ,
75- onExit : onBack ,
76- isActive : flow . name === 'mode-select' ,
77- } ) ;
78-
79- // MCP Runtime selection for bind flow
80- const runtimeItems : SelectableItem [ ] = useMemo (
81- ( ) => mcpRuntimeTools . map ( name => ( { id : name , title : name } ) ) ,
82- [ mcpRuntimeTools ]
83- ) ;
84-
85- const runtimeNav = useListNavigation ( {
86- items : runtimeItems ,
87- onSelect : item => setFlow ( { name : 'bind-select-agent' , mcpRuntimeName : item . id } ) ,
88- onExit : ( ) => setFlow ( { name : 'mode-select' } ) ,
89- isActive : flow . name === 'bind-select-runtime' ,
90- } ) ;
91-
92- // Agent selection for bind flow
93- const agentItems : SelectableItem [ ] = useMemo ( ( ) => allAgents . map ( name => ( { id : name , title : name } ) ) , [ allAgents ] ) ;
94-
95- const agentNav = useListNavigation ( {
96- items : agentItems ,
97- onSelect : item => {
98- if ( flow . name === 'bind-select-agent' ) {
99- setFlow ( { name : 'bind-enter-envvar' , mcpRuntimeName : flow . mcpRuntimeName , targetAgent : item . id } ) ;
100- }
101- } ,
102- onExit : ( ) => setFlow ( { name : 'bind-select-runtime' } ) ,
103- isActive : flow . name === 'bind-select-agent' ,
104- } ) ;
105-
10646 const handleCreateComplete = useCallback (
10747 ( config : AddGatewayTargetConfig ) => {
10848 setFlow ( {
@@ -135,133 +75,18 @@ export function AddGatewayTargetFlow({
13575 [ createTool ]
13676 ) ;
13777
138- const handleBindComplete = useCallback (
139- async ( envVarName : string ) => {
140- if ( flow . name !== 'bind-enter-envvar' ) return ;
141-
142- const result = await bindMcpRuntime ( flow . mcpRuntimeName , {
143- agentName : flow . targetAgent ,
144- envVarName,
145- } ) ;
146-
147- if ( result . ok ) {
148- setFlow ( { name : 'bind-success' , mcpRuntimeName : flow . mcpRuntimeName , targetAgent : flow . targetAgent } ) ;
149- } else {
150- setFlow ( { name : 'error' , message : result . error } ) ;
151- }
152- } ,
153- [ flow , bindMcpRuntime ]
154- ) ;
155-
156- // Mode selection screen
157- if ( flow . name === 'mode-select' ) {
158- // Check if there are MCP runtimes to bind
159- const hasRuntimesToBind = mcpRuntimeTools . length > 0 ;
160-
161- // If no MCP runtimes exist to bind, skip to create
162- if ( ! hasRuntimesToBind ) {
163- return (
164- < AddGatewayTargetScreen
165- existingGateways = { existingGateways }
166- existingToolNames = { existingToolNames }
167- onComplete = { handleCreateComplete }
168- onExit = { onBack }
169- />
170- ) ;
171- }
172-
173- return (
174- < Screen title = "Add MCP Tool" onExit = { onBack } helpText = { HELP_TEXT . NAVIGATE_SELECT } >
175- < Panel >
176- < WizardSelect
177- title = "What would you like to do?"
178- description = "Create a new MCP tool or bind an agent to an existing MCP runtime"
179- items = { MODE_OPTIONS }
180- selectedIndex = { modeNav . selectedIndex }
181- />
182- </ Panel >
183- </ Screen >
184- ) ;
185- }
186-
18778 // Create wizard
18879 if ( flow . name === 'create-wizard' ) {
18980 return (
19081 < AddGatewayTargetScreen
19182 existingGateways = { existingGateways }
19283 existingToolNames = { existingToolNames }
19384 onComplete = { handleCreateComplete }
194- onExit = { ( ) => setFlow ( { name : 'mode-select' } ) }
85+ onExit = { onBack }
19586 />
19687 ) ;
19788 }
19889
199- // Bind flow - select MCP runtime
200- if ( flow . name === 'bind-select-runtime' ) {
201- return (
202- < Screen
203- title = "Bind MCP Runtime"
204- onExit = { ( ) => setFlow ( { name : 'mode-select' } ) }
205- helpText = { HELP_TEXT . NAVIGATE_SELECT }
206- >
207- < Panel >
208- < WizardSelect
209- title = "Select MCP runtime"
210- description = "Which MCP runtime should the agent be bound to?"
211- items = { runtimeItems }
212- selectedIndex = { runtimeNav . selectedIndex }
213- emptyMessage = "No MCP runtimes available. Create an MCP tool first."
214- />
215- </ Panel >
216- </ Screen >
217- ) ;
218- }
219-
220- // Bind flow - select agent
221- if ( flow . name === 'bind-select-agent' ) {
222- if ( isLoadingAgents ) {
223- return null ;
224- }
225- return (
226- < Screen
227- title = "Bind MCP Runtime"
228- onExit = { ( ) => setFlow ( { name : 'bind-select-runtime' } ) }
229- helpText = { HELP_TEXT . NAVIGATE_SELECT }
230- >
231- < Panel >
232- < WizardSelect
233- title = "Select agent to bind"
234- description = { `Which agent should have access to ${ flow . mcpRuntimeName } ?` }
235- items = { agentItems }
236- selectedIndex = { agentNav . selectedIndex }
237- emptyMessage = "No agents defined. Add an agent first."
238- />
239- </ Panel >
240- </ Screen >
241- ) ;
242- }
243-
244- // Bind flow - enter env var name
245- if ( flow . name === 'bind-enter-envvar' ) {
246- const defaultEnvVar = `${ flow . mcpRuntimeName . toUpperCase ( ) . replace ( / [ ^ A - Z 0 - 9 ] / g, '_' ) } _MCP_RUNTIME_URL` ;
247- return (
248- < Screen
249- title = "Bind MCP Runtime"
250- onExit = { ( ) => setFlow ( { name : 'bind-select-agent' , mcpRuntimeName : flow . mcpRuntimeName } ) }
251- helpText = { HELP_TEXT . TEXT_INPUT }
252- >
253- < Panel >
254- < TextInput
255- prompt = "Environment variable name for MCP runtime URL"
256- initialValue = { defaultEnvVar }
257- onSubmit = { value => void handleBindComplete ( value ) }
258- onCancel = { ( ) => setFlow ( { name : 'bind-select-agent' , mcpRuntimeName : flow . mcpRuntimeName } ) }
259- />
260- </ Panel >
261- </ Screen >
262- ) ;
263- }
264-
26590 // Create success
26691 if ( flow . name === 'create-success' ) {
26792 return (
@@ -280,30 +105,14 @@ export function AddGatewayTargetFlow({
280105 ) ;
281106 }
282107
283- // Bind success
284- if ( flow . name === 'bind-success' ) {
285- return (
286- < AddSuccessScreen
287- isInteractive = { isInteractive }
288- message = { `Bound agent to MCP runtime` }
289- detail = { `Agent "${ flow . targetAgent } " is now bound to MCP runtime "${ flow . mcpRuntimeName } ".` }
290- showDevOption = { true }
291- onAddAnother = { onBack }
292- onDev = { onDev }
293- onDeploy = { onDeploy }
294- onExit = { onExit }
295- />
296- ) ;
297- }
298-
299108 // Error
300109 return (
301110 < ErrorPrompt
302111 message = "Failed to add MCP tool"
303112 detail = { flow . message }
304113 onBack = { ( ) => {
305114 resetCreate ( ) ;
306- setFlow ( { name : 'mode-select ' } ) ;
115+ setFlow ( { name : 'create-wizard ' } ) ;
307116 } }
308117 onExit = { onExit }
309118 />
0 commit comments