1+ import { existsSync } from "node:fs" ;
2+ import { join } from "node:path" ;
13import process from "node:process" ;
24
35import * as vscode from "vscode" ;
@@ -23,6 +25,7 @@ import {
2325 type TaskCompletion ,
2426} from "./tasks" ;
2527import { CLI_COMMANDS , quickMenuItems , quickMenuStatusText } from "./commands" ;
28+ import { runNewProjectFlow , validateNewProjectName } from "./newProject" ;
2629
2730export interface McppCliControllerOptions {
2831 output : vscode . OutputChannel ;
@@ -82,6 +85,7 @@ export class McppCliController {
8285 const disposables : vscode . Disposable [ ] = [
8386 this . status ,
8487 vscode . commands . registerCommand ( CLI_COMMANDS . showMenu , this . guarded ( ( ) => this . showMenu ( ) ) ) ,
88+ vscode . commands . registerCommand ( CLI_COMMANDS . newProject , this . guarded ( ( ) => this . newProject ( ) ) ) ,
8589 vscode . commands . registerCommand ( CLI_COMMANDS . build , this . guarded ( ( ) => this . runProjectTask ( "build" ) ) ) ,
8690 vscode . commands . registerCommand ( CLI_COMMANDS . run , this . guarded ( ( ) => this . runProjectTask ( "run" ) ) ) ,
8791 vscode . commands . registerCommand ( CLI_COMMANDS . test , this . guarded ( ( ) => this . runProjectTask ( "test" ) ) ) ,
@@ -493,6 +497,57 @@ export class McppCliController {
493497 }
494498 }
495499
500+ public async newProject ( ) : Promise < void > {
501+ if ( ! this . requireTrusted ( ) ) {
502+ return ;
503+ }
504+
505+ const input = await vscode . window . showInputBox ( {
506+ title : "新建 mcpp 工程(1/2)" ,
507+ prompt : "输入项目名,将在所选位置创建同名项目文件夹" ,
508+ placeHolder : "hello-mcpp" ,
509+ validateInput : validateNewProjectName ,
510+ } ) ;
511+ if ( input === undefined ) {
512+ return ;
513+ }
514+ const projectName = input . trim ( ) ;
515+
516+ const picked = await vscode . window . showOpenDialog ( {
517+ title : "选择项目位置(2/2)" ,
518+ canSelectFiles : false ,
519+ canSelectFolders : true ,
520+ canSelectMany : false ,
521+ openLabel : "在此创建项目" ,
522+ } ) ;
523+ const location = picked ?. [ 0 ] ;
524+ if ( location === undefined ) {
525+ return ;
526+ }
527+
528+ const projectRoot = join ( location . fsPath , projectName ) ;
529+ const confirmCreate = "创建并打开" ;
530+ await runNewProjectFlow ( projectName , location . fsPath , projectRoot , {
531+ exists : existsSync ,
532+ confirm : async ( message ) =>
533+ ( await vscode . window . showWarningMessage ( message , { modal : true } , confirmCreate ) )
534+ === confirmCreate ,
535+ run : async ( name , cwd ) => {
536+ const executable = this . mcppExecutable ( undefined ) ;
537+ const args = mcppCommandArguments ( "new" , name ) ;
538+ const result = await runProcess ( executable , args , cwd ) ;
539+ this . appendShortCommand ( "新建工程" , executable , args , result ) ;
540+ return result . exitCode ;
541+ } ,
542+ openFolder : async ( path ) => {
543+ await vscode . commands . executeCommand ( "vscode.openFolder" , vscode . Uri . file ( path ) ) ;
544+ } ,
545+ showError : async ( message ) => {
546+ await vscode . window . showErrorMessage ( message ) ;
547+ } ,
548+ } ) ;
549+ }
550+
496551 private guarded ( operation : ( ) => Promise < void > ) : ( ) => Promise < void > {
497552 return async ( ) => {
498553 try {
0 commit comments