From 185c0dea2f828a49b88b29e114ff0de86f8edea1 Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Wed, 25 Mar 2026 01:59:44 +0900 Subject: [PATCH 1/3] fix(create): handle unknown vite templates and improve error logging --- packages/cli/src/create/templates/builtin.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/packages/cli/src/create/templates/builtin.ts b/packages/cli/src/create/templates/builtin.ts index 568f51534b..0cb6ceed08 100644 --- a/packages/cli/src/create/templates/builtin.ts +++ b/packages/cli/src/create/templates/builtin.ts @@ -1,6 +1,9 @@ import assert from 'node:assert'; import path from 'node:path'; +import * as prompts from '@voidzero-dev/vite-plus-prompts'; +import colors from 'picocolors'; + import type { WorkspaceInfo } from '../../types/index.js'; import type { ExecutionResult } from '../command.js'; import { discoverTemplate } from '../discovery.js'; @@ -41,11 +44,24 @@ export async function executeBuiltinTemplate( false, options?.silent ?? false, ); + if (result.exitCode !== 0) { + return { ...result, projectDir: templateInfo.targetDir }; + } const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir); setPackageName(fullPath, templateInfo.packageName); return { ...result, projectDir: templateInfo.targetDir }; } + // Unknown vite: template (e.g. vite:test) — application was already rewritten to create-vite@latest + if (templateInfo.command.startsWith('vite:')) { + if (!options?.silent) { + prompts.log.error( + `Unknown builtin template "${templateInfo.command}". Run ${colors.yellow('vp create --list')} to see available templates.`, + ); + } + return { exitCode: 1 }; + } + // Handle remote/external templates with fspy monitoring const result = await runRemoteTemplateCommand( workspaceInfo, @@ -54,6 +70,9 @@ export async function executeBuiltinTemplate( false, options?.silent ?? false, ); + if (result.exitCode !== 0) { + return { ...result, projectDir: templateInfo.targetDir }; + } const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir); // set package name in the project directory setPackageName(fullPath, templateInfo.packageName); From 0bad70609cb97a371538e5bf12eef7ddbcb76f5e Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Wed, 25 Mar 2026 01:59:50 +0900 Subject: [PATCH 2/3] test(create): add tests for handling unknown vite templates --- .../cli/src/create/__tests__/builtin.spec.ts | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 packages/cli/src/create/__tests__/builtin.spec.ts diff --git a/packages/cli/src/create/__tests__/builtin.spec.ts b/packages/cli/src/create/__tests__/builtin.spec.ts new file mode 100644 index 0000000000..d63370f272 --- /dev/null +++ b/packages/cli/src/create/__tests__/builtin.spec.ts @@ -0,0 +1,66 @@ +import { describe, expect, it, vi } from 'vitest'; + +import { executeBuiltinTemplate } from '../templates/builtin.js'; + +const { mockLogError } = vi.hoisted(() => ({ mockLogError: vi.fn() })); + +vi.mock('../templates/remote.js', () => ({ + runRemoteTemplateCommand: vi.fn(), +})); + +vi.mock('@voidzero-dev/vite-plus-prompts', () => ({ + log: { error: mockLogError }, +})); + +const workspaceInfo = { + rootDir: '/tmp/workspace', +} as any; + +const baseTemplateInfo = { + packageName: 'wage-meeting', + targetDir: 'wage-meeting', + args: [], + envs: {}, + type: 'builtin' as any, + interactive: false, +}; + +describe('executeBuiltinTemplate', () => { + it('returns exitCode 1 for unknown vite: template', async () => { + const { runRemoteTemplateCommand } = await import('../templates/remote.js'); + + const result = await executeBuiltinTemplate(workspaceInfo, { + ...baseTemplateInfo, + command: 'vite:test', + }); + + expect(result.exitCode).toBe(1); + expect(runRemoteTemplateCommand).not.toHaveBeenCalled(); + }); + + it('shows error message with template name and --list hint', async () => { + mockLogError.mockClear(); + + await executeBuiltinTemplate(workspaceInfo, { + ...baseTemplateInfo, + command: 'vite:unknown', + }); + + expect(mockLogError).toHaveBeenCalledOnce(); + const message = mockLogError.mock.calls[0][0] as string; + expect(message).toContain('vite:unknown'); + expect(message).toContain('vp create --list'); + }); + + it('does not show error message in silent mode', async () => { + mockLogError.mockClear(); + + await executeBuiltinTemplate( + workspaceInfo, + { ...baseTemplateInfo, command: 'vite:test' }, + { silent: true }, + ); + + expect(mockLogError).not.toHaveBeenCalled(); + }); +}); From 55d1b692ee814ce489a44ba335b86743db2a1e10 Mon Sep 17 00:00:00 2001 From: naokihaba <59875779+naokihaba@users.noreply.github.com> Date: Wed, 25 Mar 2026 03:24:03 +0900 Subject: [PATCH 3/3] fix(create): return only exitCode on error for remote template commands --- packages/cli/src/create/templates/builtin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/cli/src/create/templates/builtin.ts b/packages/cli/src/create/templates/builtin.ts index 0cb6ceed08..0670365a4a 100644 --- a/packages/cli/src/create/templates/builtin.ts +++ b/packages/cli/src/create/templates/builtin.ts @@ -45,7 +45,7 @@ export async function executeBuiltinTemplate( options?.silent ?? false, ); if (result.exitCode !== 0) { - return { ...result, projectDir: templateInfo.targetDir }; + return { exitCode: result.exitCode }; } const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir); setPackageName(fullPath, templateInfo.packageName); @@ -71,7 +71,7 @@ export async function executeBuiltinTemplate( options?.silent ?? false, ); if (result.exitCode !== 0) { - return { ...result, projectDir: templateInfo.targetDir }; + return { exitCode: result.exitCode }; } const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir); // set package name in the project directory