@@ -45,9 +45,9 @@ const TEMPLATES: Record<TemplateKey, TemplateInfo> = {
4545} ;
4646
4747const INVOKE_SAMPLES : Record < string , string > = {
48- 'ts-basic ' : 'kernel invoke ts-basic get-page-title --payload \'{"url": "https://www.google.com"}\'' ,
49- 'python-basic ' : 'kernel invoke python-basic get-page-title --payload \'{"url": "https://www.google.com"}\'' ,
50- 'python-bu ' : 'kernel invoke python-bu bu-task --payload \'{"task": "Compare the price of gpt-4o and DeepSeek-V3", "openai_api_key": "XXX "}\''
48+ 'typescript-sample-app ' : 'kernel invoke ts-basic get-page-title --payload \'{"url": "https://www.google.com"}\'' ,
49+ 'python-sample-app ' : 'kernel invoke python-basic get-page-title --payload \'{"url": "https://www.google.com"}\'' ,
50+ 'python-browser-use ' : 'kernel invoke python-bu bu-task --payload \'{"task": "Compare the price of gpt-4o and DeepSeek-V3"}\''
5151} ;
5252
5353const CONFIG = {
@@ -227,52 +227,24 @@ async function setupDependencies(appPath: string, language: LanguageKey): Promis
227227// Print success message with next steps
228228function printNextSteps ( appName : string , language : LanguageKey , template : TemplateKey ) : void {
229229 // Determine which sample command to show based on language and template
230- let sampleCommand = '' ;
231- if ( language === LANGUAGE_TYPESCRIPT ) {
232- sampleCommand = INVOKE_SAMPLES [ 'ts-basic' ] ;
233- } else if ( language === LANGUAGE_PYTHON ) {
234- sampleCommand = template === TEMPLATE_SAMPLE_APP
235- ? INVOKE_SAMPLES [ 'python-basic' ]
236- : INVOKE_SAMPLES [ 'python-bu' ] ;
237- }
230+ const deployCommand = language === LANGUAGE_TYPESCRIPT ? 'kernel deploy index.ts'
231+ : language === LANGUAGE_PYTHON && template === TEMPLATE_SAMPLE_APP ? 'kernel deploy main.py'
232+ : language === LANGUAGE_PYTHON && template === TEMPLATE_BROWSER_USE ? 'kernel deploy main.py --env OPENAI_API_KEY=XXX'
233+ : '' ;
238234
235+
239236 console . log ( chalk . green ( `
240237🎉 Kernel app created successfully!
241238
242239Next steps:
243240 cd ${ appName }
244- ${ language === LANGUAGE_PYTHON ? 'uv venv && source .venv/bin/activate && uv sync' : '' }
245241 export KERNEL_API_KEY=<YOUR_API_KEY>
246- kernel deploy ${ language === LANGUAGE_TYPESCRIPT ? 'index.ts' : 'main.py' }
247- kernel invoke ${ sampleCommand }
242+ ${ language === LANGUAGE_PYTHON ? 'uv venv && source .venv/bin/activate && uv sync' : '' }
243+ ${ deployCommand }
244+ ${ INVOKE_SAMPLES [ `${ language } -${ template } ` ] }
248245 ` ) ) ;
249246}
250247
251- // Validate language and template combination only when both are explicitly provided
252- function validateLanguageTemplateCombination ( language : LanguageKey | null , template : TemplateKey | null ) : { isValid : boolean ; errorMessage ?: string } {
253- // If either is not provided, consider it valid (will be prompted later)
254- if ( ! language || ! template ) {
255- return { isValid : true } ;
256- }
257-
258- if ( ! TEMPLATES [ template as TemplateKey ] ) {
259- return {
260- isValid : false ,
261- errorMessage : `Invalid template '${ template } '. Available templates: ${ Object . keys ( TEMPLATES ) . join ( ', ' ) } `
262- } ;
263- }
264-
265- if ( ! isTemplateValidForLanguage ( template , language ) ) {
266- return {
267- isValid : false ,
268- errorMessage : `Template '${ template } ' is not available for ${ LANGUAGES [ language ] . name } . ` +
269- `This template is only available for: ${ TEMPLATES [ template as TemplateKey ] . languages . map ( l => LANGUAGES [ l ] . name ) . join ( ', ' ) } `
270- } ;
271- }
272-
273- return { isValid : true } ;
274- }
275-
276248// Main program
277249const program = new Command ( ) ;
278250
@@ -285,22 +257,44 @@ program
285257 . option ( '-t, --template <template>' , `Template type (${ TEMPLATE_SAMPLE_APP } , ${ TEMPLATE_BROWSER_USE } )` )
286258 . action ( async ( appName : string , options : { language ?: string ; template ?: string } ) => {
287259 try {
288- // Only validate if both language and template are provided
289- if ( options . language ?. toLowerCase ( ) && options . template ?. toLowerCase ( ) ) {
290- const normalizedLanguage = normalizeLanguage ( options . language ) ;
291- const validation = validateLanguageTemplateCombination ( normalizedLanguage , options . template as TemplateKey ) ;
292-
293- if ( ! validation . isValid ) {
294- console . error ( chalk . red ( 'Error:' ) , validation . errorMessage ) ;
295- console . log ( chalk . yellow ( '\nPlease try again with a valid combination.' ) ) ;
296- process . exit ( 1 ) ;
260+ let normalizedLanguage : LanguageKey | null = null ;
261+ let normalizedTemplate : TemplateKey | null = null ;
262+
263+ // Try to normalize and validate language if provided
264+ if ( options . language ?. toLowerCase ( ) ) {
265+ normalizedLanguage = normalizeLanguage ( options . language ) ;
266+ if ( ! normalizedLanguage ) {
267+ console . log ( chalk . yellow ( `\nInvalid language '${ options . language } '. Please select a valid language.` ) ) ;
268+ }
269+ }
270+
271+ // Try to normalize and validate template if provided
272+ if ( options . template ?. toLowerCase ( ) ) {
273+ normalizedTemplate = options . template as TemplateKey ;
274+ if ( ! TEMPLATES [ normalizedTemplate ] ) {
275+ console . log ( chalk . yellow ( `\nInvalid template '${ options . template } '. Please select a valid template.` ) ) ;
276+ normalizedTemplate = null ;
277+ }
278+ }
279+
280+ // If both are provided, validate the combination
281+ if ( normalizedLanguage && normalizedTemplate ) {
282+ console . log ( normalizedLanguage , normalizedTemplate ) ;
283+ const isValid = isTemplateValidForLanguage ( normalizedTemplate , normalizedLanguage ) ;
284+ if ( ! isValid ) {
285+ const errorMessage = `Template '${ normalizedTemplate } ' is not available for ${ LANGUAGES [ normalizedLanguage ] . name } . ` +
286+ `This template is only available for: ${ TEMPLATES [ normalizedTemplate as TemplateKey ] . languages . map ( l => LANGUAGES [ l ] . name ) . join ( ', ' ) } `
287+ console . log ( chalk . yellow ( `\n${ errorMessage } ` ) ) ;
288+ // Reset both to force prompting
289+ normalizedLanguage = null ;
290+ normalizedTemplate = null ;
297291 }
298292 }
299293
300294 // Get user inputs (with prompts if needed)
301295 const finalAppName = await promptForAppName ( appName ) ;
302- const language = await promptForLanguage ( options . language ) ;
303- const template = await promptForTemplate ( language , options . template ) ;
296+ const language = await promptForLanguage ( normalizedLanguage || undefined ) ;
297+ const template = await promptForTemplate ( language , normalizedTemplate || undefined ) ;
304298
305299 const appPath = path . resolve ( finalAppName ) ;
306300
0 commit comments