(options: CreateAppOptions)
| 31 | } |
| 32 | |
| 33 | export async function runCreateApp(options: CreateAppOptions): Promise<void> { |
| 34 | const interactive = !options.noInteractive; |
| 35 | const t0 = Date.now(); |
| 36 | telemetry.register({ is_interactive: interactive }); |
| 37 | |
| 38 | const args = await resolveArgs( |
| 39 | { |
| 40 | name: options.name |
| 41 | ? { value: options.name } |
| 42 | : { prompt: { type: "input", message: "Project name?" }, required: true }, |
| 43 | template: options.template |
| 44 | ? { value: options.template } |
| 45 | : { |
| 46 | prompt: { |
| 47 | type: "select", |
| 48 | message: "Which template?", |
| 49 | choices: [ |
| 50 | { |
| 51 | value: "openui-cloud", |
| 52 | name: "OpenUI Cloud — managed conversations, artifacts & streaming", |
| 53 | }, |
| 54 | { |
| 55 | value: "openui-self-hosted", |
| 56 | name: "OpenUI Self Hosted — starter setup with OpenAI SDK", |
| 57 | }, |
| 58 | ], |
| 59 | }, |
| 60 | required: true, |
| 61 | }, |
| 62 | }, |
| 63 | interactive, |
| 64 | ); |
| 65 | |
| 66 | const { name, template } = args as { name: string; template: TemplateName }; |
| 67 | telemetry.register({ template }); |
| 68 | telemetry.capture("cli_create_started", { interactive }); |
| 69 | telemetry.capture("cli_template_selected", { template }); |
| 70 | |
| 71 | const targetDir = path.resolve(process.cwd(), name); |
| 72 | if (fs.existsSync(targetDir)) { |
| 73 | throw new CreateError("dir_exists", `Directory "${name}" already exists.`); |
| 74 | } |
| 75 | |
| 76 | const packageManager = resolveInstallPackageManager(); |
| 77 | telemetry.register({ package_manager: packageManager.name }); |
| 78 | const templateDir = path.join(__dirname, "..", "templates", template); |
| 79 | if (!fs.existsSync(templateDir)) { |
| 80 | throw new CreateError( |
| 81 | "template_missing", |
| 82 | `Template "${template}" not found. Rebuild the CLI with \`pnpm build\`.`, |
| 83 | ); |
| 84 | } |
| 85 | |
| 86 | console.info(`\nScaffolding ${template} into "${name}"...\n`); |
| 87 | fs.cpSync(templateDir, targetDir, { |
| 88 | recursive: true, |
| 89 | filter: (src) => shouldCopyTemplatePath(templateDir, src), |
| 90 | }); |
no test coverage detected