@@ -19,6 +19,7 @@ import { type SecretsManager } from "./core/secretsManager";
1919import { CertificateError } from "./error" ;
2020import { getGlobalFlags } from "./globalFlags" ;
2121import { type Logger } from "./logging/logger" ;
22+ import { maybeAskAgent , maybeAskUrl } from "./promptUtils" ;
2223import { escapeCommandArg , toRemoteAuthority , toSafeHost } from "./util" ;
2324import {
2425 AgentTreeItem ,
@@ -58,129 +59,6 @@ export class Commands {
5859 this . contextManager = serviceContainer . getContextManager ( ) ;
5960 }
6061
61- /**
62- * Find the requested agent if specified, otherwise return the agent if there
63- * is only one or ask the user to pick if there are multiple. Return
64- * undefined if the user cancels.
65- */
66- public async maybeAskAgent (
67- agents : WorkspaceAgent [ ] ,
68- filter ?: string ,
69- ) : Promise < WorkspaceAgent | undefined > {
70- const filteredAgents = filter
71- ? agents . filter ( ( agent ) => agent . name === filter )
72- : agents ;
73- if ( filteredAgents . length === 0 ) {
74- throw new Error ( "Workspace has no matching agents" ) ;
75- } else if ( filteredAgents . length === 1 ) {
76- return filteredAgents [ 0 ] ;
77- } else {
78- const quickPick = vscode . window . createQuickPick ( ) ;
79- quickPick . title = "Select an agent" ;
80- quickPick . busy = true ;
81- const agentItems : vscode . QuickPickItem [ ] = filteredAgents . map ( ( agent ) => {
82- let icon = "$(debug-start)" ;
83- if ( agent . status !== "connected" ) {
84- icon = "$(debug-stop)" ;
85- }
86- return {
87- alwaysShow : true ,
88- label : `${ icon } ${ agent . name } ` ,
89- detail : `${ agent . name } • Status: ${ agent . status } ` ,
90- } ;
91- } ) ;
92- quickPick . items = agentItems ;
93- quickPick . busy = false ;
94- quickPick . show ( ) ;
95-
96- const selected = await new Promise < WorkspaceAgent | undefined > (
97- ( resolve ) => {
98- quickPick . onDidHide ( ( ) => resolve ( undefined ) ) ;
99- quickPick . onDidChangeSelection ( ( selected ) => {
100- if ( selected . length < 1 ) {
101- return resolve ( undefined ) ;
102- }
103- const agent = filteredAgents [ quickPick . items . indexOf ( selected [ 0 ] ) ] ;
104- resolve ( agent ) ;
105- } ) ;
106- } ,
107- ) ;
108- quickPick . dispose ( ) ;
109- return selected ;
110- }
111- }
112-
113- /**
114- * Ask the user for the URL, letting them choose from a list of recent URLs or
115- * CODER_URL or enter a new one. Undefined means the user aborted.
116- */
117- private async askURL ( selection ?: string ) : Promise < string | undefined > {
118- const defaultURL = vscode . workspace
119- . getConfiguration ( )
120- . get < string > ( "coder.defaultUrl" )
121- ?. trim ( ) ;
122- const quickPick = vscode . window . createQuickPick ( ) ;
123- quickPick . value =
124- selection || defaultURL || process . env . CODER_URL ?. trim ( ) || "" ;
125- quickPick . placeholder = "https://example.coder.com" ;
126- quickPick . title = "Enter the URL of your Coder deployment." ;
127-
128- // Initial items.
129- quickPick . items = this . mementoManager
130- . withUrlHistory ( defaultURL , process . env . CODER_URL )
131- . map ( ( url ) => ( {
132- alwaysShow : true ,
133- label : url ,
134- } ) ) ;
135-
136- // Quick picks do not allow arbitrary values, so we add the value itself as
137- // an option in case the user wants to connect to something that is not in
138- // the list.
139- quickPick . onDidChangeValue ( ( value ) => {
140- quickPick . items = this . mementoManager
141- . withUrlHistory ( defaultURL , process . env . CODER_URL , value )
142- . map ( ( url ) => ( {
143- alwaysShow : true ,
144- label : url ,
145- } ) ) ;
146- } ) ;
147-
148- quickPick . show ( ) ;
149-
150- const selected = await new Promise < string | undefined > ( ( resolve ) => {
151- quickPick . onDidHide ( ( ) => resolve ( undefined ) ) ;
152- quickPick . onDidChangeSelection ( ( selected ) => resolve ( selected [ 0 ] ?. label ) ) ;
153- } ) ;
154- quickPick . dispose ( ) ;
155- return selected ;
156- }
157-
158- /**
159- * Ask the user for the URL if it was not provided, letting them choose from a
160- * list of recent URLs or the default URL or CODER_URL or enter a new one, and
161- * normalizes the returned URL. Undefined means the user aborted.
162- */
163- public async maybeAskUrl (
164- providedUrl : string | undefined | null ,
165- lastUsedUrl ?: string ,
166- ) : Promise < string | undefined > {
167- let url = providedUrl || ( await this . askURL ( lastUsedUrl ) ) ;
168- if ( ! url ) {
169- // User aborted.
170- return undefined ;
171- }
172-
173- // Normalize URL.
174- if ( ! url . startsWith ( "http://" ) && ! url . startsWith ( "https://" ) ) {
175- // Default to HTTPS if not provided so URLs can be typed more easily.
176- url = "https://" + url ;
177- }
178- while ( url . endsWith ( "/" ) ) {
179- url = url . substring ( 0 , url . length - 1 ) ;
180- }
181- return url ;
182- }
183-
18462 /**
18563 * Log into the provided deployment. If the deployment URL is not specified,
18664 * ask for it first with a menu showing recent URLs along with the default URL
@@ -197,7 +75,7 @@ export class Commands {
19775 }
19876 this . logger . info ( "Logging in" ) ;
19977
200- const url = await this . maybeAskUrl ( args ?. url ) ;
78+ const url = await maybeAskUrl ( this . mementoManager , args ?. url ) ;
20179 if ( ! url ) {
20280 return ; // The user aborted.
20381 }
@@ -488,7 +366,7 @@ export class Commands {
488366 ) ;
489367 } else if ( item instanceof WorkspaceTreeItem ) {
490368 const agents = await this . extractAgentsWithFallback ( item . workspace ) ;
491- const agent = await this . maybeAskAgent ( agents ) ;
369+ const agent = await maybeAskAgent ( agents ) ;
492370 if ( ! agent ) {
493371 // User declined to pick an agent.
494372 return ;
@@ -611,7 +489,7 @@ export class Commands {
611489 }
612490
613491 const agents = await this . extractAgentsWithFallback ( workspace ) ;
614- const agent = await this . maybeAskAgent ( agents , agentName ) ;
492+ const agent = await maybeAskAgent ( agents , agentName ) ;
615493 if ( ! agent ) {
616494 // User declined to pick an agent.
617495 return ;
0 commit comments