vite-plus 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/binding/index.cjs +2 -0
  2. package/binding/index.d.cts +32 -0
  3. package/dist/global/{prompts-CAIahN1u.js → agent-CpNB3GIY.js} +475 -1350
  4. package/dist/global/{browser-CY4NBwxR.js → browser-CBapUTD0.js} +579 -1023
  5. package/dist/global/{browser-DFpJ6sKb.js → browser-EZnNDcaO.js} +2 -3
  6. package/dist/global/{chunk-CtfvYSle.js → chunk-CgnkrU7a.js} +13 -22
  7. package/dist/global/{cli-truncate-BxinOqz5.js → cli-truncate-Da6Y8aM8.js} +25 -74
  8. package/dist/global/config.js +86 -166
  9. package/dist/global/create.js +626 -615
  10. package/dist/global/{terminal-Cb-NuRkb.js → help-BAGHa8fD.js} +22 -54
  11. package/dist/global/{json-Bfvtp2rL.js → json-BRdVJ52a.js} +24 -58
  12. package/dist/global/{lib-CibYHP32.js → lib-DxappLRQ.js} +19 -43
  13. package/dist/global/{log-update-DdU6_LCN.js → log-update-C8WCYCbc.js} +102 -281
  14. package/dist/global/mcp.js +97 -169
  15. package/dist/global/migrate.js +330 -86
  16. package/dist/global/{package-Pq2biU7_.js → package-YAMvX5PJ.js} +6 -13
  17. package/dist/global/{slice-ansi-BhwAwMdF.js → slice-ansi-Fap0ehe9.js} +21 -52
  18. package/dist/global/{src-C6aLHRsS.js → src-DwSJ0s0I.js} +28 -110
  19. package/dist/global/staged.js +1353 -2112
  20. package/dist/global/{strip-ansi-BL-dgd7n.js → strip-ansi-CE-VDMdw.js} +20 -67
  21. package/dist/global/version.js +16 -37
  22. package/dist/global/{workspace-MTwAF3M9.js → workspace-CiqQdO1L.js} +1711 -2834
  23. package/dist/global/wrap-ansi-Ou9oAs-a.js +3 -0
  24. package/dist/global/{wrap-ansi-Iww6Ak1s.js → wrap-ansi-eywLlPVQ.js} +29 -80
  25. package/dist/index.d.ts +1 -1
  26. package/dist/init-config.js +10 -2
  27. package/dist/utils/agent.d.ts +15 -1
  28. package/dist/utils/agent.js +104 -20
  29. package/dist/utils/constants.d.ts +1 -0
  30. package/dist/utils/constants.js +2 -0
  31. package/dist/utils/editor.d.ts +16 -3
  32. package/dist/utils/editor.js +55 -17
  33. package/dist/utils/prompts.d.ts +33 -4
  34. package/dist/utils/prompts.js +34 -10
  35. package/dist/utils/tsconfig.d.ts +6 -0
  36. package/dist/utils/tsconfig.js +16 -0
  37. package/package.json +14 -14
  38. package/templates/monorepo/package.json +1 -1
  39. package/dist/global/wrap-ansi-BJxjUEQR.js +0 -4
  40. package/dist/oxlint-config.d.ts +0 -498
  41. package/dist/oxlint-config.js +0 -309
@@ -1,32 +1,27 @@
1
- import { i as __toESM, t as __commonJSMin } from "./chunk-CtfvYSle.js";
2
- import { C as log, D as select, E as outro, O as text, S as intro, _ as templatesDir, a as runViteFmt, b as cancel, f as selectAgentTargetPaths, i as promptGitHooks, k as Ct, m as displayRelative, n as defaultInteractive, o as runViteInstall, p as writeAgentInstructions, r as downloadPackageManager$1, s as selectPackageManager, u as detectExistingAgentTargetPaths, v as DependencyType, w as multiselect, x as confirm, y as PackageManager } from "./prompts-CAIahN1u.js";
3
- import { t as lib_default } from "./lib-CibYHP32.js";
4
- import { a as selectEditor, d as rewriteMonorepo, f as rewriteMonorepoProject, i as detectExistingEditor, l as installGitHooks, n as updatePackageJsonWithDeps, o as writeEditorConfigs, p as rewriteStandaloneProject, r as updateWorkspaceConfig, t as detectWorkspace$1 } from "./workspace-MTwAF3M9.js";
5
- import "./browser-CY4NBwxR.js";
6
- import { r as readJsonFile, t as editJsonFile } from "./json-Bfvtp2rL.js";
7
- import "./package-Pq2biU7_.js";
8
- import { a as renderCliDoc, i as success, n as log$1, r as muted, t as accent } from "./terminal-Cb-NuRkb.js";
1
+ import { i as __toESM, t as __commonJSMin } from "./chunk-CgnkrU7a.js";
2
+ import { A as select, C as cancel, D as multiselect, E as log, M as text, N as Ct, S as PackageManager, T as intro, a as selectAgentTargetPaths, c as defaultInteractive, d as promptGitHooks, f as runViteFmt, g as displayRelative, j as spinner, l as downloadPackageManager$1, m as selectPackageManager, o as writeAgentInstructions, p as runViteInstall, r as detectExistingAgentTargetPaths, w as confirm, x as DependencyType, y as templatesDir } from "./agent-CpNB3GIY.js";
3
+ import { t as lib_default } from "./lib-DxappLRQ.js";
4
+ import { _ as rewriteMonorepo, a as detectExistingEditor, f as installGitHooks, n as updatePackageJsonWithDeps, o as selectEditor, r as updateWorkspaceConfig, s as writeEditorConfigs, t as detectWorkspace$1, v as rewriteMonorepoProject, y as rewriteStandaloneProject } from "./workspace-CiqQdO1L.js";
5
+ import "./browser-CBapUTD0.js";
6
+ import { r as readJsonFile, t as editJsonFile } from "./json-BRdVJ52a.js";
7
+ import "./package-YAMvX5PJ.js";
8
+ import { a as success, i as muted, n as accent, r as log$1, t as renderCliDoc } from "./help-BAGHa8fD.js";
9
9
  import path from "node:path";
10
10
  import { styleText } from "node:util";
11
- import colors from "picocolors";
11
+ import color from "picocolors";
12
12
  import fs from "node:fs";
13
13
  import { runCommand, vitePlusHeader } from "../../binding/index.js";
14
14
  import spawn from "cross-spawn";
15
15
  import fsPromises from "node:fs/promises";
16
16
  import assert from "node:assert";
17
-
18
17
  //#region src/create/command.ts
19
18
  async function runCommandAndDetectProjectDir(options, parentDir) {
20
19
  const cwd = parentDir ? path.join(options.cwd, parentDir) : options.cwd;
21
- const existingDirs = new Set();
20
+ const existingDirs = /* @__PURE__ */ new Set();
22
21
  if (parentDir) {
23
22
  await fsPromises.mkdir(cwd, { recursive: true });
24
23
  const entries = await fsPromises.readdir(cwd, { withFileTypes: true });
25
- for (const entry of entries) {
26
- if (entry.isDirectory()) {
27
- existingDirs.add(entry.name);
28
- }
29
- }
24
+ for (const entry of entries) if (entry.isDirectory()) existingDirs.add(entry.name);
30
25
  }
31
26
  const result = await runCommand({
32
27
  binName: options.command,
@@ -36,37 +31,56 @@ async function runCommandAndDetectProjectDir(options, parentDir) {
36
31
  });
37
32
  let projectDir;
38
33
  let minDepth = Infinity;
39
- for (const [filePath, pathAccess] of Object.entries(result.pathAccesses)) {
40
- if (pathAccess.write && filePath.endsWith("package.json") && !filePath.includes("node_modules")) {
41
- const dir = path.dirname(filePath);
42
- if (dir === "." || dir === "") {
43
- continue;
44
- }
45
- if (existingDirs.has(dir)) {
46
- continue;
47
- }
48
- const depth = dir.split(path.sep).length;
49
- if (depth < minDepth) {
50
- minDepth = depth;
51
- projectDir = dir;
52
- }
34
+ for (const [filePath, pathAccess] of Object.entries(result.pathAccesses)) if (pathAccess.write && filePath.endsWith("package.json") && !filePath.includes("node_modules")) {
35
+ const dir = path.dirname(filePath);
36
+ if (dir === "." || dir === "") continue;
37
+ if (existingDirs.has(dir)) continue;
38
+ const depth = dir.split(path.sep).length;
39
+ if (depth < minDepth) {
40
+ minDepth = depth;
41
+ projectDir = dir;
53
42
  }
54
43
  }
55
- if (parentDir && projectDir) {
56
- projectDir = path.join(parentDir, projectDir);
57
- }
44
+ if (parentDir && projectDir) projectDir = path.join(parentDir, projectDir);
58
45
  return {
59
46
  exitCode: result.exitCode,
60
47
  projectDir
61
48
  };
62
49
  }
50
+ async function runCommandSilently(options) {
51
+ const child = spawn(options.command, options.args, {
52
+ stdio: "pipe",
53
+ cwd: options.cwd,
54
+ env: options.envs
55
+ });
56
+ return await new Promise((resolve, reject) => {
57
+ const stdout = [];
58
+ const stderr = [];
59
+ child.stdout?.on("data", (data) => {
60
+ stdout.push(data);
61
+ });
62
+ child.stderr?.on("data", (data) => {
63
+ stderr.push(data);
64
+ });
65
+ child.on("close", (code) => {
66
+ resolve({
67
+ exitCode: code ?? 0,
68
+ stdout: Buffer.concat(stdout),
69
+ stderr: Buffer.concat(stderr)
70
+ });
71
+ });
72
+ child.on("error", (err) => {
73
+ reject(err);
74
+ });
75
+ });
76
+ }
63
77
  async function runCommand$1(options) {
64
78
  const child = spawn(options.command, options.args, {
65
79
  stdio: "inherit",
66
80
  cwd: options.cwd,
67
81
  env: options.envs
68
82
  });
69
- const promise = new Promise((resolve, reject) => {
83
+ return await new Promise((resolve, reject) => {
70
84
  child.on("close", (code) => {
71
85
  resolve({ exitCode: code ?? 0 });
72
86
  });
@@ -74,7 +88,6 @@ async function runCommand$1(options) {
74
88
  reject(err);
75
89
  });
76
90
  });
77
- return await promise;
78
91
  }
79
92
  function getPackageRunner(workspaceInfo) {
80
93
  switch (workspaceInfo.packageManager) {
@@ -86,7 +99,6 @@ function getPackageRunner(workspaceInfo) {
86
99
  command: "yarn",
87
100
  args: ["dlx"]
88
101
  };
89
- case "npm":
90
102
  default: return {
91
103
  command: "npx",
92
104
  args: []
@@ -109,13 +121,9 @@ function prependToPathToEnvs(extraPath, envs) {
109
121
  const delimiter = path.delimiter;
110
122
  const pathKey = Object.keys(envs).find((key) => key.toLowerCase() === "path") ?? "PATH";
111
123
  const current = envs[pathKey] ?? "";
112
- const parts = current.split(delimiter).filter(Boolean);
113
- if (!parts.includes(extraPath)) {
114
- envs[pathKey] = extraPath + (current ? delimiter + current : "");
115
- }
124
+ if (!current.split(delimiter).filter(Boolean).includes(extraPath)) envs[pathKey] = extraPath + (current ? delimiter + current : "");
116
125
  return envs;
117
126
  }
118
-
119
127
  //#endregion
120
128
  //#region src/create/templates/types.ts
121
129
  const BuiltinTemplate = {
@@ -129,65 +137,53 @@ const TemplateType = {
129
137
  bingo: "bingo",
130
138
  remote: "remote"
131
139
  };
132
-
133
140
  //#endregion
134
141
  //#region src/create/discovery.ts
135
142
  function isGitHubUrl(templateName) {
136
143
  return templateName.startsWith("https://github.com/") || templateName.startsWith("github:") || templateName.includes("github.com/");
137
144
  }
138
145
  function parseGitHubUrl(url) {
139
- if (url.startsWith("github:")) {
140
- return url.slice(7);
141
- }
146
+ if (url.startsWith("github:")) return url.slice(7);
142
147
  const match = url.match(/github\.com\/([^/]+\/[^/]+)/);
143
- if (match) {
144
- return match[1].replace(/\.git$/, "");
145
- }
148
+ if (match) return match[1].replace(/\.git$/, "");
146
149
  return null;
147
150
  }
151
+ function inferGitHubRepoName(templateName) {
152
+ const degitPath = parseGitHubUrl(templateName);
153
+ if (!degitPath) return null;
154
+ return degitPath.split("/").pop() || null;
155
+ }
148
156
  function discoverTemplate(templateName, templateArgs, workspaceInfo, interactive) {
149
157
  const envs = prependToPathToEnvs(workspaceInfo.downloadPackageManager.binPrefix, { ...process.env });
150
158
  const parentDir = inferParentDir(templateName, workspaceInfo);
151
- if (templateName.startsWith("vite:")) {
152
- return {
153
- command: templateName,
154
- args: [...templateArgs],
159
+ if (templateName.startsWith("vite:")) return {
160
+ command: templateName,
161
+ args: [...templateArgs],
162
+ envs,
163
+ type: TemplateType.builtin,
164
+ parentDir,
165
+ interactive
166
+ };
167
+ if (isGitHubUrl(templateName)) {
168
+ const degitPath = parseGitHubUrl(templateName);
169
+ if (degitPath) return {
170
+ command: "degit",
171
+ args: [degitPath, ...templateArgs],
155
172
  envs,
156
- type: TemplateType.builtin,
173
+ type: TemplateType.remote,
157
174
  parentDir,
158
175
  interactive
159
176
  };
160
177
  }
161
- if (isGitHubUrl(templateName)) {
162
- const degitPath = parseGitHubUrl(templateName);
163
- if (degitPath) {
164
- return {
165
- command: "degit",
166
- args: [
167
- degitPath,
168
- templateName,
169
- ...templateArgs
170
- ],
171
- envs,
172
- type: TemplateType.remote,
173
- parentDir,
174
- interactive
175
- };
176
- }
177
- }
178
178
  const localPackage = workspaceInfo.packages.find((pkg) => pkg.name === templateName);
179
179
  if (localPackage) {
180
180
  const localPackagePath = path.join(workspaceInfo.rootDir, localPackage.path);
181
- const packageJsonPath = path.join(localPackagePath, "package.json");
182
- const pkg = readJsonFile(packageJsonPath);
181
+ const pkg = readJsonFile(path.join(localPackagePath, "package.json"));
183
182
  let binPath = "";
184
- if (pkg.bin) {
185
- if (typeof pkg.bin === "string") {
186
- binPath = path.join(localPackagePath, pkg.bin);
187
- } else {
188
- const binName = Object.keys(pkg.bin)[0];
189
- binPath = path.join(localPackagePath, pkg.bin[binName]);
190
- }
183
+ if (pkg.bin) if (typeof pkg.bin === "string") binPath = path.join(localPackagePath, pkg.bin);
184
+ else {
185
+ const binName = Object.keys(pkg.bin)[0];
186
+ binPath = path.join(localPackagePath, pkg.bin[binName]);
191
187
  }
192
188
  const args = [binPath, ...templateArgs];
193
189
  let type = TemplateType.remote;
@@ -195,20 +191,17 @@ function discoverTemplate(templateName, templateArgs, workspaceInfo, interactive
195
191
  type = TemplateType.bingo;
196
192
  args.push("--skip-requests");
197
193
  }
198
- if (binPath) {
199
- return {
200
- command: "node",
201
- args,
202
- envs,
203
- type,
204
- parentDir,
205
- interactive
206
- };
207
- }
194
+ if (binPath) return {
195
+ command: "node",
196
+ args,
197
+ envs,
198
+ type,
199
+ parentDir,
200
+ interactive
201
+ };
208
202
  }
209
- const expandedName = expandCreateShorthand(templateName);
210
203
  return {
211
- command: expandedName,
204
+ command: expandCreateShorthand(templateName),
212
205
  args: [...templateArgs],
213
206
  envs,
214
207
  type: TemplateType.remote,
@@ -232,56 +225,33 @@ function discoverTemplate(templateName, templateArgs, workspaceInfo, interactive
232
225
  * - Names already starting with `create-` (or `@scope/create-`)
233
226
  */
234
227
  function expandCreateShorthand(templateName) {
235
- if (templateName.includes(":")) {
236
- return templateName;
237
- }
238
- if (isGitHubUrl(templateName)) {
239
- return templateName;
240
- }
241
- if (templateName.startsWith("./") || templateName.startsWith("../") || templateName.startsWith("/")) {
242
- return templateName;
243
- }
228
+ if (templateName.includes(":")) return templateName;
229
+ if (isGitHubUrl(templateName)) return templateName;
230
+ if (templateName.startsWith("./") || templateName.startsWith("../") || templateName.startsWith("/")) return templateName;
244
231
  if (templateName.startsWith("@")) {
245
232
  const slashIndex = templateName.indexOf("/");
246
- if (slashIndex === -1) {
247
- return templateName;
248
- }
233
+ if (slashIndex === -1) return templateName;
249
234
  const scope = templateName.slice(0, slashIndex);
250
235
  const rest = templateName.slice(slashIndex + 1);
251
236
  const atIndex = rest.indexOf("@");
252
237
  const name = atIndex === -1 ? rest : rest.slice(0, atIndex);
253
238
  const version = atIndex === -1 ? "" : rest.slice(atIndex);
254
- if (name.startsWith("create-")) {
255
- return templateName;
256
- }
239
+ if (name.startsWith("create-")) return templateName;
257
240
  return `${scope}/create-${name}${version}`;
258
241
  }
259
242
  const atIndex = templateName.indexOf("@");
260
243
  const name = atIndex === -1 ? templateName : templateName.slice(0, atIndex);
261
244
  const version = atIndex === -1 ? "" : templateName.slice(atIndex);
262
- if (name.startsWith("create-")) {
263
- return templateName;
264
- }
245
+ if (name.startsWith("create-")) return templateName;
265
246
  return `create-${name}${version}`;
266
247
  }
267
248
  function inferParentDir(templateName, workspaceInfo) {
268
- if (workspaceInfo.parentDirs.length === 0) {
269
- return;
270
- }
249
+ if (workspaceInfo.parentDirs.length === 0) return;
271
250
  let rule = /app/i;
272
- if (templateName === BuiltinTemplate.library) {
273
- rule = /lib|component|package/i;
274
- } else if (templateName === BuiltinTemplate.generator) {
275
- rule = /generator|tool/i;
276
- }
277
- for (const parentDir of workspaceInfo.parentDirs) {
278
- if (rule.test(parentDir)) {
279
- return parentDir;
280
- }
281
- }
282
- return;
251
+ if (templateName === BuiltinTemplate.library) rule = /lib|component|package/i;
252
+ else if (templateName === BuiltinTemplate.generator) rule = /generator|tool/i;
253
+ for (const parentDir of workspaceInfo.parentDirs) if (rule.test(parentDir)) return parentDir;
283
254
  }
284
-
285
255
  //#endregion
286
256
  //#region ../../node_modules/.pnpm/validate-npm-package-name@7.0.2/node_modules/validate-npm-package-name/lib/builtin-modules.json
287
257
  var require_builtin_modules = /* @__PURE__ */ __commonJSMin(((exports, module) => {
@@ -360,12 +330,11 @@ var require_builtin_modules = /* @__PURE__ */ __commonJSMin(((exports, module) =
360
330
  "node:test/reporters"
361
331
  ];
362
332
  }));
363
-
364
333
  //#endregion
365
- //#region ../../node_modules/.pnpm/validate-npm-package-name@7.0.2/node_modules/validate-npm-package-name/lib/index.js
366
- var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
334
+ //#region ../../node_modules/.pnpm/@nkzw+safe-word-list@3.1.0/node_modules/@nkzw/safe-word-list/index.js
335
+ var import_lib = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((exports, module) => {
367
336
  const builtins = require_builtin_modules();
368
- var scopedPackagePattern = new RegExp("^(?:@([^/]+?)[/])?([^/]+?)$");
337
+ var scopedPackagePattern = /* @__PURE__ */ new RegExp("^(?:@([^/]+?)[/])?([^/]+?)$");
369
338
  var exclusionList = ["node_modules", "favicon.ico"];
370
339
  function validate(name) {
371
340
  var warnings = [];
@@ -374,7 +343,7 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
374
343
  errors.push("name cannot be null");
375
344
  return done(warnings, errors);
376
345
  }
377
- if (name === undefined) {
346
+ if (name === void 0) {
378
347
  errors.push("name cannot be undefined");
379
348
  return done(warnings, errors);
380
349
  }
@@ -382,49 +351,25 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
382
351
  errors.push("name must be a string");
383
352
  return done(warnings, errors);
384
353
  }
385
- if (!name.length) {
386
- errors.push("name length must be greater than zero");
387
- }
388
- if (name.startsWith(".")) {
389
- errors.push("name cannot start with a period");
390
- }
391
- if (name.startsWith("-")) {
392
- errors.push("name cannot start with a hyphen");
393
- }
394
- if (name.match(/^_/)) {
395
- errors.push("name cannot start with an underscore");
396
- }
397
- if (name.trim() !== name) {
398
- errors.push("name cannot contain leading or trailing spaces");
399
- }
354
+ if (!name.length) errors.push("name length must be greater than zero");
355
+ if (name.startsWith(".")) errors.push("name cannot start with a period");
356
+ if (name.startsWith("-")) errors.push("name cannot start with a hyphen");
357
+ if (name.match(/^_/)) errors.push("name cannot start with an underscore");
358
+ if (name.trim() !== name) errors.push("name cannot contain leading or trailing spaces");
400
359
  exclusionList.forEach(function(excludedName) {
401
- if (name.toLowerCase() === excludedName) {
402
- errors.push(excludedName + " is not a valid package name");
403
- }
360
+ if (name.toLowerCase() === excludedName) errors.push(excludedName + " is not a valid package name");
404
361
  });
405
- if (builtins.includes(name.toLowerCase())) {
406
- warnings.push(name + " is a core module name");
407
- }
408
- if (name.length > 214) {
409
- warnings.push("name can no longer contain more than 214 characters");
410
- }
411
- if (name.toLowerCase() !== name) {
412
- warnings.push("name can no longer contain capital letters");
413
- }
414
- if (/[~'!()*]/.test(name.split("/").slice(-1)[0])) {
415
- warnings.push("name can no longer contain special characters (\"~'!()*\")");
416
- }
362
+ if (builtins.includes(name.toLowerCase())) warnings.push(name + " is a core module name");
363
+ if (name.length > 214) warnings.push("name can no longer contain more than 214 characters");
364
+ if (name.toLowerCase() !== name) warnings.push("name can no longer contain capital letters");
365
+ if (/[~'!()*]/.test(name.split("/").slice(-1)[0])) warnings.push("name can no longer contain special characters (\"~'!()*\")");
417
366
  if (encodeURIComponent(name) !== name) {
418
367
  var nameMatch = name.match(scopedPackagePattern);
419
368
  if (nameMatch) {
420
369
  var user = nameMatch[1];
421
370
  var pkg = nameMatch[2];
422
- if (pkg.startsWith(".")) {
423
- errors.push("name cannot start with a period");
424
- }
425
- if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) {
426
- return done(warnings, errors);
427
- }
371
+ if (pkg.startsWith(".")) errors.push("name cannot start with a period");
372
+ if (encodeURIComponent(user) === user && encodeURIComponent(pkg) === pkg) return done(warnings, errors);
428
373
  }
429
374
  errors.push("name can only contain URL-friendly characters");
430
375
  }
@@ -437,207 +382,12 @@ var require_lib = /* @__PURE__ */ __commonJSMin(((exports, module) => {
437
382
  warnings,
438
383
  errors
439
384
  };
440
- if (!result.warnings.length) {
441
- delete result.warnings;
442
- }
443
- if (!result.errors.length) {
444
- delete result.errors;
445
- }
385
+ if (!result.warnings.length) delete result.warnings;
386
+ if (!result.errors.length) delete result.errors;
446
387
  return result;
447
388
  };
448
389
  module.exports = validate;
449
- }));
450
-
451
- //#endregion
452
- //#region src/create/utils.ts
453
- var import_lib = /* @__PURE__ */ __toESM(require_lib(), 1);
454
- function copy(src, dest) {
455
- const stat = fs.statSync(src);
456
- if (stat.isDirectory()) {
457
- copyDir(src, dest);
458
- } else {
459
- fs.copyFileSync(src, dest);
460
- }
461
- }
462
- function copyDir(srcDir, destDir) {
463
- fs.mkdirSync(destDir, { recursive: true });
464
- for (const file of fs.readdirSync(srcDir)) {
465
- const srcFile = path.resolve(srcDir, file);
466
- const destFile = path.resolve(destDir, file);
467
- copy(srcFile, destFile);
468
- }
469
- }
470
- /**
471
- * Format the target directory into a valid directory name and package name
472
- *
473
- * Examples:
474
- * ```
475
- * # invalid target directories
476
- * ./ -> { directory: '', packageName: '', error: 'Invalid target directory' }
477
- * /foo/bar -> { directory: '', packageName: '', error: 'Absolute path is not allowed' }
478
- * @scope/ -> { directory: '', packageName: '', error: 'Invalid target directory' }
479
- * ../../foo/bar -> { directory: '', packageName: '', error: 'Invalid target directory' }
480
- *
481
- * # valid target directories
482
- * ./my-package -> { directory: './my-package', packageName: 'my-package' }
483
- * ./foo/bar-package -> { directory: './foo/bar-package', packageName: 'bar-package' }
484
- * ./foo/bar-package/ -> { directory: './foo/bar-package', packageName: 'bar-package' }
485
- * my-package -> { directory: 'my-package', packageName: 'my-package' }
486
- * @my-scope/my-package -> { directory: 'my-package', packageName: '@my-scope/my-package' }
487
- * foo/@my-scope/my-package -> { directory: 'foo/my-package', packageName: '@scope/my-package' }
488
- * ./foo/@my-scope/my-package -> { directory: './foo/my-package', packageName: '@scope/my-package' }
489
- * ./foo/bar/@scope/my-package -> { directory: './foo/bar/my-package', packageName: '@scope/my-package' }
490
- * ```
491
- */
492
- function formatTargetDir(input) {
493
- let targetDir = path.normalize(input.trim());
494
- const parsed = path.parse(targetDir);
495
- if (parsed.root || path.isAbsolute(targetDir)) {
496
- return {
497
- directory: "",
498
- packageName: "",
499
- error: "Absolute path is not allowed"
500
- };
501
- }
502
- if (targetDir.includes("..")) {
503
- return {
504
- directory: "",
505
- packageName: "",
506
- error: "Relative path contains \"..\" which is not allowed"
507
- };
508
- }
509
- let packageName = parsed.base;
510
- const parentName = path.basename(parsed.dir);
511
- if (parentName.startsWith("@")) {
512
- targetDir = path.join(path.dirname(parsed.dir), packageName);
513
- packageName = `${parentName}/${packageName}`;
514
- }
515
- const result = (0, import_lib.default)(packageName);
516
- if (!result.validForNewPackages) {
517
- const message = result.errors?.[0] ?? result.warnings?.[0] ?? "Invalid package name";
518
- return {
519
- directory: "",
520
- packageName: "",
521
- error: `Parsed package name "${packageName}" is invalid: ${message}`
522
- };
523
- }
524
- return {
525
- directory: targetDir,
526
- packageName
527
- };
528
- }
529
- function getProjectDirFromPackageName(packageName) {
530
- if (packageName.startsWith("@")) {
531
- return packageName.split("/")[1];
532
- }
533
- return packageName;
534
- }
535
- function setPackageName(projectDir, packageName) {
536
- editJsonFile(path.join(projectDir, "package.json"), (pkg) => {
537
- pkg.name = packageName;
538
- return pkg;
539
- });
540
- }
541
- function formatDisplayTargetDir(targetDir) {
542
- const normalized = targetDir.split(path.sep).join("/");
543
- if (normalized === "" || normalized === ".") {
544
- return "./";
545
- }
546
- if (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("/") || normalized.startsWith("~")) {
547
- return normalized;
548
- }
549
- return `./${normalized}`;
550
- }
551
-
552
- //#endregion
553
- //#region src/create/prompts.ts
554
- async function promptPackageNameAndTargetDir(defaultPackageName, interactive) {
555
- let packageName;
556
- let targetDir;
557
- if (interactive) {
558
- const selected = await text({
559
- message: "Package name:",
560
- placeholder: defaultPackageName,
561
- defaultValue: defaultPackageName,
562
- validate: (value) => {
563
- if (value == null || value.length === 0) {
564
- return;
565
- }
566
- const result = value ? (0, import_lib.default)(value) : null;
567
- if (result?.validForNewPackages) {
568
- return;
569
- }
570
- return result?.errors?.[0] ?? result?.warnings?.[0] ?? "Invalid package name";
571
- }
572
- });
573
- if (Ct(selected)) {
574
- cancelAndExit();
575
- }
576
- packageName = selected;
577
- targetDir = getProjectDirFromPackageName(packageName);
578
- } else {
579
- packageName = defaultPackageName;
580
- targetDir = getProjectDirFromPackageName(packageName);
581
- log.info(`Using default package name: ${accent(packageName)}`);
582
- }
583
- return {
584
- packageName,
585
- targetDir
586
- };
587
- }
588
- async function checkProjectDirExists(projectDirFullPath, interactive) {
589
- if (!fs.existsSync(projectDirFullPath) || isEmpty(projectDirFullPath)) {
590
- return;
591
- }
592
- if (!interactive) {
593
- log.info("Use --directory to specify a different location or remove the directory first");
594
- cancelAndExit(`Target directory "${projectDirFullPath}" is not empty`, 1);
595
- }
596
- const overwrite = await select({
597
- message: `Target directory "${projectDirFullPath}" is not empty. Please choose how to proceed:`,
598
- options: [{
599
- label: "Cancel operation",
600
- value: "no"
601
- }, {
602
- label: "Remove existing files and continue",
603
- value: "yes"
604
- }]
605
- });
606
- if (Ct(overwrite)) {
607
- cancelAndExit();
608
- }
609
- switch (overwrite) {
610
- case "yes":
611
- emptyDir(projectDirFullPath);
612
- break;
613
- case "no": cancelAndExit();
614
- }
615
- }
616
- function cancelAndExit(message = "Operation cancelled", exitCode = 0) {
617
- cancel(message);
618
- process.exit(exitCode);
619
- }
620
- function isEmpty(path) {
621
- const files = fs.readdirSync(path);
622
- return files.length === 0 || files.length === 1 && files[0] === ".git";
623
- }
624
- function emptyDir(dir) {
625
- if (!fs.existsSync(dir)) {
626
- return;
627
- }
628
- for (const file of fs.readdirSync(dir)) {
629
- if (file === ".git") {
630
- continue;
631
- }
632
- fs.rmSync(path.resolve(dir, file), {
633
- recursive: true,
634
- force: true
635
- });
636
- }
637
- }
638
-
639
- //#endregion
640
- //#region ../../node_modules/.pnpm/@nkzw+safe-word-list@3.1.0/node_modules/@nkzw/safe-word-list/index.js
390
+ })))(), 1);
641
391
  const words = [
642
392
  "ability",
643
393
  "able",
@@ -3372,16 +3122,15 @@ const random = (min, max) => Math.floor(min + Math.random() * (max - min + 1));
3372
3122
  function getRandomWord() {
3373
3123
  return words[random(0, words.length - 1)];
3374
3124
  }
3375
-
3376
3125
  //#endregion
3377
3126
  //#region src/create/random-name.ts
3378
3127
  const isTest = process.env.VITE_PLUS_CLI_TEST === "1";
3379
3128
  function getRandomWords() {
3380
3129
  const first = getRandomWord();
3381
3130
  let second;
3382
- do {
3131
+ do
3383
3132
  second = getRandomWord();
3384
- } while (second === first);
3133
+ while (second === first);
3385
3134
  return [first, second];
3386
3135
  }
3387
3136
  function getRandomProjectName(options = {}) {
@@ -3389,11 +3138,217 @@ function getRandomProjectName(options = {}) {
3389
3138
  const projectName = isTest && fallbackName ? fallbackName : getRandomWords().join("-");
3390
3139
  return scope ? `${scope}/${projectName}` : projectName;
3391
3140
  }
3392
-
3141
+ //#endregion
3142
+ //#region src/create/utils.ts
3143
+ function copy(src, dest) {
3144
+ if (fs.statSync(src).isDirectory()) copyDir(src, dest);
3145
+ else fs.copyFileSync(src, dest);
3146
+ }
3147
+ function copyDir(srcDir, destDir) {
3148
+ fs.mkdirSync(destDir, { recursive: true });
3149
+ for (const file of fs.readdirSync(srcDir)) copy(path.resolve(srcDir, file), path.resolve(destDir, file));
3150
+ }
3151
+ /**
3152
+ * Format the target directory into a valid directory name and package name
3153
+ *
3154
+ * Examples:
3155
+ * ```
3156
+ * # invalid target directories
3157
+ * ./ -> { directory: '', packageName: '', error: 'Invalid target directory' }
3158
+ * /foo/bar -> { directory: '', packageName: '', error: 'Absolute path is not allowed' }
3159
+ * @scope/ -> { directory: '', packageName: '', error: 'Invalid target directory' }
3160
+ * ../../foo/bar -> { directory: '', packageName: '', error: 'Invalid target directory' }
3161
+ *
3162
+ * # valid target directories
3163
+ * ./my-package -> { directory: './my-package', packageName: 'my-package' }
3164
+ * ./foo/bar-package -> { directory: './foo/bar-package', packageName: 'bar-package' }
3165
+ * ./foo/bar-package/ -> { directory: './foo/bar-package', packageName: 'bar-package' }
3166
+ * my-package -> { directory: 'my-package', packageName: 'my-package' }
3167
+ * @my-scope/my-package -> { directory: 'my-package', packageName: '@my-scope/my-package' }
3168
+ * foo/@my-scope/my-package -> { directory: 'foo/my-package', packageName: '@scope/my-package' }
3169
+ * ./foo/@my-scope/my-package -> { directory: './foo/my-package', packageName: '@scope/my-package' }
3170
+ * ./foo/bar/@scope/my-package -> { directory: './foo/bar/my-package', packageName: '@scope/my-package' }
3171
+ * ```
3172
+ */
3173
+ function formatTargetDir(input) {
3174
+ let targetDir = path.normalize(input.trim());
3175
+ const parsed = path.parse(targetDir);
3176
+ if (parsed.root || path.isAbsolute(targetDir)) return {
3177
+ directory: "",
3178
+ packageName: "",
3179
+ error: "Absolute path is not allowed"
3180
+ };
3181
+ if (targetDir.includes("..")) return {
3182
+ directory: "",
3183
+ packageName: "",
3184
+ error: "Relative path contains \"..\" which is not allowed"
3185
+ };
3186
+ let packageName = parsed.base;
3187
+ const parentName = path.basename(parsed.dir);
3188
+ if (parentName.startsWith("@")) {
3189
+ targetDir = path.join(path.dirname(parsed.dir), packageName);
3190
+ packageName = `${parentName}/${packageName}`;
3191
+ }
3192
+ const result = (0, import_lib.default)(packageName);
3193
+ if (!result.validForNewPackages) {
3194
+ const message = result.errors?.[0] ?? result.warnings?.[0] ?? "Invalid package name";
3195
+ return {
3196
+ directory: "",
3197
+ packageName: "",
3198
+ error: `Parsed package name "${packageName}" is invalid: ${message}`
3199
+ };
3200
+ }
3201
+ return {
3202
+ directory: targetDir,
3203
+ packageName
3204
+ };
3205
+ }
3206
+ function getProjectDirFromPackageName(packageName) {
3207
+ if (packageName.startsWith("@")) return packageName.split("/")[1];
3208
+ return packageName;
3209
+ }
3210
+ function setPackageName(projectDir, packageName) {
3211
+ editJsonFile(path.join(projectDir, "package.json"), (pkg) => {
3212
+ pkg.name = packageName;
3213
+ return pkg;
3214
+ });
3215
+ }
3216
+ function formatDisplayTargetDir(targetDir) {
3217
+ const normalized = targetDir.split(path.sep).join("/");
3218
+ if (normalized === "" || normalized === ".") return "./";
3219
+ if (normalized.startsWith("./") || normalized.startsWith("../") || normalized.startsWith("/") || normalized.startsWith("~")) return normalized;
3220
+ return `./${normalized}`;
3221
+ }
3222
+ //#endregion
3223
+ //#region src/create/prompts.ts
3224
+ async function promptPackageNameAndTargetDir(defaultPackageName, interactive) {
3225
+ let packageName;
3226
+ let targetDir;
3227
+ if (interactive) {
3228
+ const selected = await text({
3229
+ message: "Package name:",
3230
+ placeholder: defaultPackageName,
3231
+ defaultValue: defaultPackageName,
3232
+ validate: (value) => {
3233
+ if (value == null || value.length === 0) return;
3234
+ const result = value ? (0, import_lib.default)(value) : null;
3235
+ if (result?.validForNewPackages) return;
3236
+ return result?.errors?.[0] ?? result?.warnings?.[0] ?? "Invalid package name";
3237
+ }
3238
+ });
3239
+ if (Ct(selected)) cancelAndExit();
3240
+ packageName = selected;
3241
+ targetDir = getProjectDirFromPackageName(packageName);
3242
+ } else {
3243
+ packageName = defaultPackageName;
3244
+ targetDir = getProjectDirFromPackageName(packageName);
3245
+ log.info(`Using default package name: ${accent(packageName)}`);
3246
+ }
3247
+ return {
3248
+ packageName,
3249
+ targetDir
3250
+ };
3251
+ }
3252
+ async function promptTargetDir(defaultTargetDir, interactive, options) {
3253
+ let targetDir;
3254
+ if (interactive) {
3255
+ const selected = await text({
3256
+ message: "Target directory:",
3257
+ placeholder: defaultTargetDir,
3258
+ defaultValue: defaultTargetDir,
3259
+ validate: (value) => validateTargetDir(value ?? defaultTargetDir, options?.cwd).error
3260
+ });
3261
+ if (Ct(selected)) cancelAndExit();
3262
+ targetDir = validateTargetDir(selected ?? defaultTargetDir, options?.cwd).directory;
3263
+ } else {
3264
+ targetDir = validateTargetDir(defaultTargetDir, options?.cwd).directory;
3265
+ log.info(`Using default target directory: ${accent(targetDir)}`);
3266
+ }
3267
+ return targetDir;
3268
+ }
3269
+ function suggestAvailableTargetDir(defaultTargetDir, cwd) {
3270
+ let suggestedTargetDir = defaultTargetDir;
3271
+ let attempt = 1;
3272
+ while (!isTargetDirAvailable(path.join(cwd, suggestedTargetDir))) {
3273
+ suggestedTargetDir = getRandomProjectName({ fallbackName: `${defaultTargetDir}-${attempt}` });
3274
+ attempt++;
3275
+ }
3276
+ return suggestedTargetDir;
3277
+ }
3278
+ async function checkProjectDirExists(projectDirFullPath, interactive) {
3279
+ if (isTargetDirAvailable(projectDirFullPath)) return;
3280
+ if (!interactive) {
3281
+ log.info("Use --directory to specify a different location or remove the directory first");
3282
+ cancelAndExit(`Target directory "${projectDirFullPath}" is not empty`, 1);
3283
+ }
3284
+ const overwrite = await select({
3285
+ message: `Target directory "${projectDirFullPath}" is not empty. Please choose how to proceed:`,
3286
+ options: [{
3287
+ label: "Cancel operation",
3288
+ value: "no"
3289
+ }, {
3290
+ label: "Remove existing files and continue",
3291
+ value: "yes"
3292
+ }]
3293
+ });
3294
+ if (Ct(overwrite)) cancelAndExit();
3295
+ switch (overwrite) {
3296
+ case "yes":
3297
+ emptyDir(projectDirFullPath);
3298
+ break;
3299
+ case "no": cancelAndExit();
3300
+ }
3301
+ }
3302
+ function cancelAndExit(message = "Operation cancelled", exitCode = 0) {
3303
+ cancel(message);
3304
+ process.exit(exitCode);
3305
+ }
3306
+ function isEmpty(path) {
3307
+ const files = fs.readdirSync(path);
3308
+ return files.length === 0 || files.length === 1 && files[0] === ".git";
3309
+ }
3310
+ function emptyDir(dir) {
3311
+ if (!fs.existsSync(dir)) return;
3312
+ for (const file of fs.readdirSync(dir)) {
3313
+ if (file === ".git") continue;
3314
+ fs.rmSync(path.resolve(dir, file), {
3315
+ recursive: true,
3316
+ force: true
3317
+ });
3318
+ }
3319
+ }
3320
+ function isTargetDirAvailable(projectDirFullPath) {
3321
+ return !fs.existsSync(projectDirFullPath) || isEmpty(projectDirFullPath);
3322
+ }
3323
+ function validateTargetDir(input, cwd) {
3324
+ const value = input?.trim() ?? "";
3325
+ if (!value) return {
3326
+ directory: "",
3327
+ error: "Target directory is required"
3328
+ };
3329
+ const targetDir = path.normalize(value);
3330
+ if (!targetDir || targetDir === ".") return {
3331
+ directory: "",
3332
+ error: "Target directory is required"
3333
+ };
3334
+ if (path.isAbsolute(targetDir)) return {
3335
+ directory: "",
3336
+ error: "Absolute path is not allowed"
3337
+ };
3338
+ if (targetDir.includes("..")) return {
3339
+ directory: "",
3340
+ error: "Relative path contains \"..\" which is not allowed"
3341
+ };
3342
+ if (cwd && !isTargetDirAvailable(path.join(cwd, targetDir))) return {
3343
+ directory: "",
3344
+ error: `Target directory "${targetDir}" already exists`
3345
+ };
3346
+ return { directory: targetDir };
3347
+ }
3393
3348
  //#endregion
3394
3349
  //#region src/create/templates/generator.ts
3395
- async function executeGeneratorScaffold(workspaceInfo, templateInfo) {
3396
- log.step("Creating generator scaffold...");
3350
+ async function executeGeneratorScaffold(workspaceInfo, templateInfo, options) {
3351
+ if (!options?.silent) log.step("Creating generator scaffold...");
3397
3352
  let description;
3398
3353
  if (templateInfo.interactive) {
3399
3354
  const defaultDescription = "Generate new components for our monorepo";
@@ -3402,49 +3357,42 @@ async function executeGeneratorScaffold(workspaceInfo, templateInfo) {
3402
3357
  placeholder: defaultDescription,
3403
3358
  defaultValue: defaultDescription
3404
3359
  });
3405
- if (!Ct(descPrompt)) {
3406
- description = descPrompt;
3407
- }
3360
+ if (!Ct(descPrompt)) description = descPrompt;
3408
3361
  }
3409
3362
  const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir);
3410
- const templateDir = path.join(templatesDir, "generator");
3411
- copyDir(templateDir, fullPath);
3363
+ copyDir(path.join(templatesDir, "generator"), fullPath);
3412
3364
  fs.chmodSync(path.join(fullPath, "bin/index.ts"), "755");
3413
3365
  editJsonFile(path.join(fullPath, "package.json"), (pkg) => {
3414
3366
  pkg.name = templateInfo.packageName;
3415
- if (description) {
3416
- pkg.description = description;
3417
- }
3367
+ if (description) pkg.description = description;
3418
3368
  return pkg;
3419
3369
  });
3420
- log.success("Generator scaffold created");
3370
+ if (!options?.silent) log.success("Generator scaffold created");
3421
3371
  return {
3422
3372
  exitCode: 0,
3423
3373
  projectDir: templateInfo.targetDir
3424
3374
  };
3425
3375
  }
3426
-
3427
3376
  //#endregion
3428
3377
  //#region src/create/templates/remote.ts
3429
- const { gray, yellow } = colors;
3430
- async function executeRemoteTemplate(workspaceInfo, templateInfo) {
3431
- log.step("Generating project…");
3378
+ const { gray, yellow } = color;
3379
+ async function executeRemoteTemplate(workspaceInfo, templateInfo, options) {
3380
+ const silent = options?.silent ?? false;
3381
+ if (!silent) log.step("Generating project…");
3432
3382
  let isGitHubTemplate = templateInfo.command === "degit";
3433
3383
  let result;
3434
3384
  if (templateInfo.command === "node") {
3435
3385
  const command = templateInfo.command;
3436
3386
  const args = templateInfo.args;
3437
3387
  const envs = templateInfo.envs;
3438
- log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
3388
+ if (!silent) log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
3439
3389
  result = await runCommandAndDetectProjectDir({
3440
3390
  command,
3441
3391
  args,
3442
3392
  cwd: workspaceInfo.rootDir,
3443
3393
  envs
3444
3394
  }, templateInfo.parentDir);
3445
- } else {
3446
- result = await runRemoteTemplateCommand(workspaceInfo, workspaceInfo.rootDir, templateInfo, true);
3447
- }
3395
+ } else result = await runRemoteTemplateCommand(workspaceInfo, workspaceInfo.rootDir, templateInfo, true, silent);
3448
3396
  const exitCode = result.exitCode;
3449
3397
  if (exitCode === 127) {
3450
3398
  log.info(yellow("\nTroubleshooting:"));
@@ -3457,21 +3405,25 @@ async function executeRemoteTemplate(workspaceInfo, templateInfo) {
3457
3405
  }
3458
3406
  return result;
3459
3407
  }
3460
- async function runRemoteTemplateCommand(workspaceInfo, cwd, templateInfo, detectCreatedProjectDir) {
3408
+ async function runRemoteTemplateCommand(workspaceInfo, cwd, templateInfo, detectCreatedProjectDir, silent = false) {
3461
3409
  autoFixRemoteTemplateCommand(templateInfo, workspaceInfo);
3462
3410
  const remotePackageName = templateInfo.command;
3463
3411
  const execArgs = [...templateInfo.args];
3464
3412
  const envs = templateInfo.envs;
3465
3413
  const { command, args } = formatDlxCommand(remotePackageName, execArgs, workspaceInfo);
3466
- log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
3467
- if (detectCreatedProjectDir) {
3468
- return await runCommandAndDetectProjectDir({
3469
- command,
3470
- args,
3471
- cwd,
3472
- envs
3473
- }, templateInfo.parentDir);
3474
- }
3414
+ if (!silent) log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
3415
+ if (detectCreatedProjectDir) return await runCommandAndDetectProjectDir({
3416
+ command,
3417
+ args,
3418
+ cwd,
3419
+ envs
3420
+ }, templateInfo.parentDir);
3421
+ if (silent) return await runCommandSilently({
3422
+ command,
3423
+ args,
3424
+ cwd,
3425
+ envs
3426
+ });
3475
3427
  return await runCommand$1({
3476
3428
  command,
3477
3429
  args,
@@ -3482,9 +3434,7 @@ async function runRemoteTemplateCommand(workspaceInfo, cwd, templateInfo, detect
3482
3434
  function autoFixRemoteTemplateCommand(templateInfo, workspaceInfo) {
3483
3435
  let packageName = templateInfo.command;
3484
3436
  const indexOfAt = packageName.indexOf("@", 2);
3485
- if (indexOfAt !== -1) {
3486
- packageName = packageName.substring(0, indexOfAt);
3487
- }
3437
+ if (indexOfAt !== -1) packageName = packageName.substring(0, indexOfAt);
3488
3438
  if (packageName === "create-vite") {
3489
3439
  templateInfo.args.push("--no-immediate");
3490
3440
  templateInfo.args.push("--no-rolldown");
@@ -3493,49 +3443,37 @@ function autoFixRemoteTemplateCommand(templateInfo, workspaceInfo) {
3493
3443
  templateInfo.args.push("--no-toolchain");
3494
3444
  }
3495
3445
  if (workspaceInfo.isMonorepo) {
3496
- if (packageName === "create-nuxt") {
3497
- templateInfo.args.push("--no-gitInit");
3498
- } else if (packageName === "@tanstack/create-start") {
3499
- templateInfo.args.push("--no-git");
3500
- }
3446
+ if (packageName === "create-nuxt") templateInfo.args.push("--no-gitInit");
3447
+ else if (packageName === "@tanstack/create-start") templateInfo.args.push("--no-git");
3501
3448
  }
3502
3449
  }
3503
-
3504
3450
  //#endregion
3505
3451
  //#region src/create/templates/builtin.ts
3506
- async function executeBuiltinTemplate(workspaceInfo, templateInfo) {
3452
+ async function executeBuiltinTemplate(workspaceInfo, templateInfo, options) {
3507
3453
  assert(templateInfo.targetDir, "targetDir is required");
3508
3454
  assert(templateInfo.packageName, "packageName is required");
3509
- if (templateInfo.command === BuiltinTemplate.generator) {
3510
- return await executeGeneratorScaffold(workspaceInfo, templateInfo);
3511
- }
3455
+ if (templateInfo.command === BuiltinTemplate.generator) return await executeGeneratorScaffold(workspaceInfo, templateInfo, options);
3512
3456
  if (templateInfo.command === BuiltinTemplate.application) {
3513
3457
  templateInfo.command = "create-vite@latest";
3514
- if (!templateInfo.interactive) {
3515
- templateInfo.args.push("--no-interactive");
3516
- }
3458
+ if (!templateInfo.interactive) templateInfo.args.push("--no-interactive");
3517
3459
  } else if (templateInfo.command === BuiltinTemplate.library) {
3518
3460
  templateInfo.command = "create-tsdown@latest";
3519
- if (!templateInfo.interactive) {
3520
- if (!templateInfo.args.find((arg) => arg.startsWith("--template") || arg.startsWith("-t"))) {
3521
- templateInfo.args.push("--template", "default");
3522
- }
3461
+ if (!templateInfo.interactive || options?.silent) {
3462
+ if (!templateInfo.args.some((arg) => arg.startsWith("--template") || arg.startsWith("-t"))) templateInfo.args.push("--template", "default");
3523
3463
  }
3524
3464
  }
3525
3465
  templateInfo.args.unshift(templateInfo.targetDir);
3526
- const result = await runRemoteTemplateCommand(workspaceInfo, workspaceInfo.rootDir, templateInfo, false);
3527
- const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir);
3528
- setPackageName(fullPath, templateInfo.packageName);
3466
+ const result = await runRemoteTemplateCommand(workspaceInfo, workspaceInfo.rootDir, templateInfo, false, options?.silent ?? false);
3467
+ setPackageName(path.join(workspaceInfo.rootDir, templateInfo.targetDir), templateInfo.packageName);
3529
3468
  return {
3530
3469
  ...result,
3531
3470
  projectDir: templateInfo.targetDir
3532
3471
  };
3533
3472
  }
3534
-
3535
3473
  //#endregion
3536
3474
  //#region src/create/templates/monorepo.ts
3537
3475
  const InitialMonorepoAppDir = "apps/website";
3538
- async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive) {
3476
+ async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive, options) {
3539
3477
  assert(templateInfo.packageName, "packageName is required");
3540
3478
  assert(templateInfo.targetDir, "targetDir is required");
3541
3479
  workspaceInfo.monorepoScope = getScopeFromPackageName(templateInfo.packageName);
@@ -3549,16 +3487,13 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive)
3549
3487
  if (Ct(selected)) {
3550
3488
  log.info("Operation cancelled. Skipping git initialization");
3551
3489
  initGit = false;
3552
- } else {
3553
- initGit = selected;
3554
- }
3555
- } else {
3556
- log.info(`Initializing git repository (default: yes)`);
3490
+ } else initGit = selected;
3491
+ } else if (!options?.silent) log.info(`Initializing git repository (default: yes)`);
3492
+ if (!options?.silent) {
3493
+ log.info(`Target directory: ${formatDisplayTargetDir(templateInfo.targetDir)}`);
3494
+ log.step("Creating Vite+ monorepo...");
3557
3495
  }
3558
- log.info(`Target directory: ${formatDisplayTargetDir(templateInfo.targetDir)}`);
3559
- log.step("Creating Vite+ monorepo...");
3560
- const templateDir = path.join(templatesDir, "monorepo");
3561
- copyDir(templateDir, fullPath);
3496
+ copyDir(path.join(templatesDir, "monorepo"), fullPath);
3562
3497
  renameFiles(fullPath);
3563
3498
  editJsonFile(path.join(fullPath, "package.json"), (pkg) => {
3564
3499
  pkg.name = templateInfo.packageName;
@@ -3566,60 +3501,49 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive)
3566
3501
  });
3567
3502
  if (workspaceInfo.packageManager === PackageManager.pnpm) {
3568
3503
  editJsonFile(path.join(fullPath, "package.json"), (pkg) => {
3569
- pkg.workspaces = undefined;
3570
- pkg.resolutions = undefined;
3504
+ pkg.workspaces = void 0;
3505
+ pkg.resolutions = void 0;
3571
3506
  return pkg;
3572
3507
  });
3573
3508
  const yarnrcPath = path.join(fullPath, ".yarnrc.yml");
3574
- if (fs.existsSync(yarnrcPath)) {
3575
- fs.unlinkSync(yarnrcPath);
3576
- }
3509
+ if (fs.existsSync(yarnrcPath)) fs.unlinkSync(yarnrcPath);
3577
3510
  } else if (workspaceInfo.packageManager === PackageManager.yarn) {
3578
3511
  editJsonFile(path.join(fullPath, "package.json"), (pkg) => {
3579
- pkg.pnpm = undefined;
3512
+ pkg.pnpm = void 0;
3580
3513
  return pkg;
3581
3514
  });
3582
3515
  const pnpmWorkspacePath = path.join(fullPath, "pnpm-workspace.yaml");
3583
- if (fs.existsSync(pnpmWorkspacePath)) {
3584
- fs.unlinkSync(pnpmWorkspacePath);
3585
- }
3516
+ if (fs.existsSync(pnpmWorkspacePath)) fs.unlinkSync(pnpmWorkspacePath);
3586
3517
  } else {
3587
3518
  editJsonFile(path.join(fullPath, "package.json"), (pkg) => {
3588
- pkg.pnpm = undefined;
3519
+ pkg.pnpm = void 0;
3589
3520
  return pkg;
3590
3521
  });
3591
3522
  const pnpmWorkspacePath = path.join(fullPath, "pnpm-workspace.yaml");
3592
- if (fs.existsSync(pnpmWorkspacePath)) {
3593
- fs.unlinkSync(pnpmWorkspacePath);
3594
- }
3523
+ if (fs.existsSync(pnpmWorkspacePath)) fs.unlinkSync(pnpmWorkspacePath);
3595
3524
  const yarnrcPath = path.join(fullPath, ".yarnrc.yml");
3596
- if (fs.existsSync(yarnrcPath)) {
3597
- fs.unlinkSync(yarnrcPath);
3598
- }
3525
+ if (fs.existsSync(yarnrcPath)) fs.unlinkSync(yarnrcPath);
3599
3526
  }
3600
- log.success("Monorepo template created");
3527
+ if (!options?.silent) log.success("Monorepo template created");
3601
3528
  if (initGit) {
3602
3529
  const gitResult = spawn.sync("git", ["init"], {
3603
3530
  stdio: "pipe",
3604
3531
  cwd: fullPath
3605
3532
  });
3606
3533
  if (gitResult.status === 0) {
3607
- log.success("Git repository initialized");
3534
+ if (!options?.silent) log.success("Git repository initialized");
3608
3535
  } else {
3609
3536
  log.warn("Failed to initialize git repository");
3610
- if (gitResult.stderr) {
3611
- log.info(gitResult.stderr.toString());
3612
- }
3537
+ if (gitResult.stderr) log.info(gitResult.stderr.toString());
3613
3538
  }
3614
3539
  }
3615
- log.step("Creating default application in apps/website...");
3616
- const appTemplateInfo = discoverTemplate("create-vite@latest", [
3540
+ if (!options?.silent) log.step("Creating default application in apps/website...");
3541
+ const appResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, discoverTemplate("create-vite@latest", [
3617
3542
  InitialMonorepoAppDir,
3618
3543
  "--template",
3619
3544
  "vanilla-ts",
3620
3545
  "--no-interactive"
3621
- ], workspaceInfo);
3622
- const appResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, appTemplateInfo);
3546
+ ], workspaceInfo), false, options?.silent ?? false);
3623
3547
  if (appResult.exitCode !== 0) {
3624
3548
  log.error(`Failed to create default application: ${appResult.exitCode}`);
3625
3549
  return appResult;
@@ -3627,15 +3551,14 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive)
3627
3551
  const appPackageName = workspaceInfo.monorepoScope ? `${workspaceInfo.monorepoScope}/website` : "website";
3628
3552
  const appProjectPath = path.join(fullPath, InitialMonorepoAppDir);
3629
3553
  setPackageName(appProjectPath, appPackageName);
3630
- rewriteMonorepoProject(appProjectPath, workspaceInfo.packageManager);
3631
- log.step("Creating default library in packages/utils...");
3554
+ rewriteMonorepoProject(appProjectPath, workspaceInfo.packageManager, void 0, options?.silent ?? false);
3555
+ if (!options?.silent) log.step("Creating default library in packages/utils...");
3632
3556
  const libraryDir = "packages/utils";
3633
- const libraryTemplateInfo = discoverTemplate("create-tsdown@latest", [
3557
+ const libraryResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, discoverTemplate("create-tsdown@latest", [
3634
3558
  libraryDir,
3635
3559
  "--template",
3636
3560
  "default"
3637
- ], workspaceInfo);
3638
- const libraryResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, libraryTemplateInfo);
3561
+ ], workspaceInfo), false, options?.silent ?? false);
3639
3562
  if (libraryResult.exitCode !== 0) {
3640
3563
  log.error(`Failed to create default library, exit code: ${libraryResult.exitCode}`);
3641
3564
  return libraryResult;
@@ -3643,7 +3566,7 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, interactive)
3643
3566
  const libraryPackageName = workspaceInfo.monorepoScope ? `${workspaceInfo.monorepoScope}/utils` : "utils";
3644
3567
  const libraryProjectPath = path.join(fullPath, libraryDir);
3645
3568
  setPackageName(libraryProjectPath, libraryPackageName);
3646
- rewriteMonorepoProject(libraryProjectPath, workspaceInfo.packageManager);
3569
+ rewriteMonorepoProject(libraryProjectPath, workspaceInfo.packageManager, void 0, options?.silent ?? false);
3647
3570
  return {
3648
3571
  exitCode: 0,
3649
3572
  projectDir: templateInfo.targetDir
@@ -3657,18 +3580,13 @@ const RENAME_FILES = {
3657
3580
  function renameFiles(projectDir) {
3658
3581
  for (const [from, to] of Object.entries(RENAME_FILES)) {
3659
3582
  const fromPath = path.join(projectDir, from);
3660
- if (fs.existsSync(fromPath)) {
3661
- fs.renameSync(fromPath, path.join(projectDir, to));
3662
- }
3583
+ if (fs.existsSync(fromPath)) fs.renameSync(fromPath, path.join(projectDir, to));
3663
3584
  }
3664
3585
  }
3665
3586
  function getScopeFromPackageName(packageName) {
3666
- if (packageName.startsWith("@")) {
3667
- return packageName.split("/")[0];
3668
- }
3587
+ if (packageName.startsWith("@")) return packageName.split("/")[0];
3669
3588
  return "";
3670
3589
  }
3671
-
3672
3590
  //#endregion
3673
3591
  //#region src/create/bin.ts
3674
3592
  const helpMessage = renderCliDoc({
@@ -3711,6 +3629,10 @@ const helpMessage = renderCliDoc({
3711
3629
  label: "--no-hooks",
3712
3630
  description: "Skip pre-commit hooks setup"
3713
3631
  },
3632
+ {
3633
+ label: "--verbose",
3634
+ description: "Show detailed scaffolding output"
3635
+ },
3714
3636
  {
3715
3637
  label: "--no-interactive",
3716
3638
  description: "Run in non-interactive mode"
@@ -3838,7 +3760,8 @@ function parseArgs() {
3838
3760
  "list",
3839
3761
  "all",
3840
3762
  "interactive",
3841
- "hooks"
3763
+ "hooks",
3764
+ "verbose"
3842
3765
  ],
3843
3766
  string: [
3844
3767
  "directory",
@@ -3847,14 +3770,14 @@ function parseArgs() {
3847
3770
  ],
3848
3771
  default: { interactive: defaultInteractive() }
3849
3772
  });
3850
- const templateName = parsed._[0];
3851
3773
  return {
3852
- templateName,
3774
+ templateName: parsed._[0],
3853
3775
  options: {
3854
3776
  directory: parsed.directory,
3855
3777
  interactive: parsed.interactive,
3856
3778
  list: parsed.list || false,
3857
3779
  help: parsed.help || false,
3780
+ verbose: parsed.verbose || false,
3858
3781
  agent: parsed.agent,
3859
3782
  editor: parsed.editor,
3860
3783
  hooks: parsed.hooks
@@ -3862,8 +3785,59 @@ function parseArgs() {
3862
3785
  templateArgs
3863
3786
  };
3864
3787
  }
3788
+ function describeScaffold(templateName, templateArgs) {
3789
+ if (templateName === BuiltinTemplate.monorepo) return "Vite+ monorepo";
3790
+ if (templateName === BuiltinTemplate.generator) return "generator scaffold";
3791
+ if (templateName === BuiltinTemplate.library) return "TypeScript library";
3792
+ const selectedTemplate = getTemplateOption(templateArgs);
3793
+ if (selectedTemplate) return formatTemplateName(selectedTemplate);
3794
+ if (templateName === BuiltinTemplate.application) return "Vite application";
3795
+ }
3796
+ function getTemplateOption(args) {
3797
+ for (let index = 0; index < args.length; index++) {
3798
+ const arg = args[index];
3799
+ if (arg === "--template" || arg === "-t") return args[index + 1];
3800
+ if (arg.startsWith("--template=")) return arg.slice(11);
3801
+ }
3802
+ }
3803
+ function hasExplicitTargetDir(args) {
3804
+ return args[0] !== void 0 && !args[0].startsWith("-");
3805
+ }
3806
+ function formatTemplateName(templateName) {
3807
+ const templateAliases = {
3808
+ lit: "Lit",
3809
+ preact: "Preact",
3810
+ react: "React",
3811
+ "react-router": "React Router",
3812
+ solid: "Solid",
3813
+ svelte: "Svelte",
3814
+ vanilla: "Vanilla",
3815
+ vue: "Vue"
3816
+ };
3817
+ const isTypeScript = templateName.endsWith("-ts");
3818
+ const baseName = isTypeScript ? templateName.slice(0, -3) : templateName;
3819
+ return `${templateAliases[baseName] ?? baseName.split(/[-_]/).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ")} + ${isTypeScript ? "TypeScript" : "JavaScript"}`;
3820
+ }
3821
+ function formatDuration(durationMs) {
3822
+ if (durationMs < 1e3) return `${Math.max(1, durationMs)}ms`;
3823
+ const durationSeconds = durationMs / 1e3;
3824
+ if (durationSeconds < 10) return `${durationSeconds.toFixed(1)}s`;
3825
+ return `${Math.round(durationSeconds)}s`;
3826
+ }
3827
+ function getNextCommand(projectDir, command) {
3828
+ if (!projectDir || projectDir === ".") return command;
3829
+ return `cd ${projectDir} && ${command}`;
3830
+ }
3831
+ function showCreateSummary(options) {
3832
+ const { description, installSummary, nextCommand, packageManager, packageManagerVersion, projectDir } = options;
3833
+ log$1(`${styleText("magenta", "◇")} Scaffolded ${accent(projectDir)}${description ? ` with ${description}` : ""}`);
3834
+ log$1(`${styleText("gray", "•")} Node ${process.versions.node} ${packageManager} ${packageManagerVersion}`);
3835
+ if (installSummary?.status === "installed") log$1(`${styleText("green", "✓")} Dependencies installed in ${formatDuration(installSummary.durationMs)}`);
3836
+ log$1(`${styleText("blue", "→")} Next: ${accent(nextCommand)}`);
3837
+ }
3865
3838
  async function main() {
3866
3839
  const { templateName, options, templateArgs } = parseArgs();
3840
+ const compactOutput = !options.verbose;
3867
3841
  if (options.help) {
3868
3842
  log$1(vitePlusHeader() + "\n");
3869
3843
  log$1(helpMessage);
@@ -3887,7 +3861,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
3887
3861
  `);
3888
3862
  process.exit(1);
3889
3863
  }
3890
- intro(vitePlusHeader());
3864
+ if (options.interactive) intro(vitePlusHeader());
3891
3865
  let targetDir = "";
3892
3866
  let packageName = "";
3893
3867
  if (options.directory) {
@@ -3902,9 +3876,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
3902
3876
  const cwd = process.cwd();
3903
3877
  const workspaceInfoOptional = await detectWorkspace$1(cwd);
3904
3878
  const isMonorepo = workspaceInfoOptional.isMonorepo;
3905
- if (!isMonorepo) {
3906
- workspaceInfoOptional.rootDir = cwd;
3907
- }
3879
+ if (!isMonorepo) workspaceInfoOptional.rootDir = cwd;
3908
3880
  const cwdRelativeToRoot = isMonorepo && workspaceInfoOptional.rootDir !== cwd ? displayRelative(cwd, workspaceInfoOptional.rootDir) : "";
3909
3881
  const isInSubdirectory = cwdRelativeToRoot !== "";
3910
3882
  const cwdUnderParentDir = isInSubdirectory ? workspaceInfoOptional.parentDirs.some((dir) => cwdRelativeToRoot === dir || cwdRelativeToRoot.startsWith(`${dir}/`)) : true;
@@ -3914,25 +3886,21 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
3914
3886
  let selectedAgentTargetPaths;
3915
3887
  let selectedEditor;
3916
3888
  let selectedParentDir;
3889
+ let remoteTargetDir;
3890
+ let shouldSetupHooks = false;
3917
3891
  if (!selectedTemplateName) {
3918
3892
  const templates = [];
3919
3893
  if (isMonorepo) {
3920
- for (const pkg of workspaceInfoOptional.packages) {
3921
- if (pkg.isTemplatePackage) {
3922
- templates.push({
3923
- label: pkg.name,
3924
- value: pkg.name,
3925
- hint: pkg.description ?? pkg.path
3926
- });
3927
- }
3928
- }
3929
- } else {
3930
- templates.push({
3931
- label: "Vite+ Monorepo",
3932
- value: BuiltinTemplate.monorepo,
3933
- hint: "Create a new Vite+ monorepo project"
3894
+ for (const pkg of workspaceInfoOptional.packages) if (pkg.isTemplatePackage) templates.push({
3895
+ label: pkg.name,
3896
+ value: pkg.name,
3897
+ hint: pkg.description ?? pkg.path
3934
3898
  });
3935
- }
3899
+ } else templates.push({
3900
+ label: "Vite+ Monorepo",
3901
+ value: BuiltinTemplate.monorepo,
3902
+ hint: "Create a new Vite+ monorepo project"
3903
+ });
3936
3904
  const template = await select({
3937
3905
  message: "",
3938
3906
  options: [
@@ -3964,71 +3932,51 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
3964
3932
  }
3965
3933
  ]
3966
3934
  });
3967
- if (Ct(template)) {
3968
- cancelAndExit();
3969
- }
3935
+ if (Ct(template)) cancelAndExit();
3970
3936
  if (template === "other") {
3971
3937
  const customTemplate = await text({
3972
3938
  message: "Enter the template package name:",
3973
3939
  placeholder: "e.g., create-next-app, create-nuxt",
3974
3940
  validate: (value) => {
3975
- if (!value || value.trim().length === 0) {
3976
- return "Template name is required";
3977
- }
3941
+ if (!value || value.trim().length === 0) return "Template name is required";
3978
3942
  }
3979
3943
  });
3980
- if (Ct(customTemplate)) {
3981
- cancelAndExit();
3982
- }
3944
+ if (Ct(customTemplate)) cancelAndExit();
3983
3945
  selectedTemplateName = customTemplate;
3984
- } else {
3985
- selectedTemplateName = template;
3986
- }
3946
+ } else selectedTemplateName = template;
3987
3947
  }
3988
3948
  const isBuiltinTemplate = selectedTemplateName.startsWith("vite:");
3989
- if (targetDir && !isBuiltinTemplate) {
3990
- cancelAndExit("The --directory option is only available for builtin templates", 1);
3991
- }
3949
+ if (targetDir && !isBuiltinTemplate) cancelAndExit("The --directory option is only available for builtin templates", 1);
3992
3950
  if (selectedTemplateName === BuiltinTemplate.monorepo && isMonorepo) {
3993
3951
  log.info("You are already in a monorepo workspace.\nUse a different template or run this command outside the monorepo");
3994
3952
  cancelAndExit("Cannot create a monorepo inside an existing monorepo", 1);
3995
3953
  }
3996
- if (isInSubdirectory) {
3997
- log.info(`Detected monorepo root at ${accent(workspaceInfoOptional.rootDir)}`);
3998
- }
3954
+ if (isInSubdirectory && !compactOutput) log.info(`Detected monorepo root at ${accent(workspaceInfoOptional.rootDir)}`);
3999
3955
  if (isMonorepo && options.interactive && !targetDir) {
4000
3956
  let parentDir;
4001
- const hasParentDirs = workspaceInfoOptional.parentDirs.length > 0;
4002
- if (hasParentDirs || isInSubdirectory) {
3957
+ if (workspaceInfoOptional.parentDirs.length > 0 || isInSubdirectory) {
4003
3958
  const dirOptions = workspaceInfoOptional.parentDirs.map((dir) => ({
4004
3959
  label: `${dir}/`,
4005
3960
  value: dir,
4006
3961
  hint: ""
4007
3962
  }));
4008
- if (shouldOfferCwdOption) {
4009
- dirOptions.push({
4010
- label: `${cwdRelativeToRoot}/ (current directory)`,
4011
- value: cwdRelativeToRoot,
4012
- hint: ""
4013
- });
4014
- }
3963
+ if (shouldOfferCwdOption) dirOptions.push({
3964
+ label: `${cwdRelativeToRoot}/ (current directory)`,
3965
+ value: cwdRelativeToRoot,
3966
+ hint: ""
3967
+ });
4015
3968
  dirOptions.push({
4016
3969
  label: "other directory",
4017
3970
  value: "other",
4018
3971
  hint: "Enter a custom target directory"
4019
3972
  });
4020
- const defaultParentDir = shouldOfferCwdOption ? cwdRelativeToRoot : inferParentDir(selectedTemplateName, workspaceInfoOptional) ?? workspaceInfoOptional.parentDirs[0];
4021
3973
  const selected = await select({
4022
3974
  message: "Where should the new package be added to the monorepo:",
4023
3975
  options: dirOptions,
4024
- initialValue: defaultParentDir
3976
+ initialValue: shouldOfferCwdOption ? cwdRelativeToRoot : inferParentDir(selectedTemplateName, workspaceInfoOptional) ?? workspaceInfoOptional.parentDirs[0]
4025
3977
  });
4026
- if (Ct(selected)) {
4027
- cancelAndExit();
4028
- }
4029
- if (selected !== "other") {
4030
- parentDir = selected;
4031
- }
3978
+ if (Ct(selected)) cancelAndExit();
3979
+ if (selected !== "other") parentDir = selected;
4032
3980
  }
4033
3981
  if (!parentDir) {
4034
3982
  const customTargetDir = await text({
@@ -4038,144 +3986,214 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
4038
3986
  return value ? formatTargetDir(value).error : "Target directory is required";
4039
3987
  }
4040
3988
  });
4041
- if (Ct(customTargetDir)) {
4042
- cancelAndExit();
4043
- }
3989
+ if (Ct(customTargetDir)) cancelAndExit();
4044
3990
  parentDir = customTargetDir;
4045
3991
  }
4046
3992
  selectedParentDir = parentDir;
4047
3993
  }
4048
3994
  if (isMonorepo && !options.interactive && !targetDir) {
4049
- if (isInSubdirectory) {
4050
- log.info(`Use ${accent("--directory")} to specify a different target location.`);
4051
- }
4052
- const inferredParentDir = inferParentDir(selectedTemplateName, workspaceInfoOptional) ?? workspaceInfoOptional.parentDirs[0];
4053
- selectedParentDir = inferredParentDir;
3995
+ if (isInSubdirectory && !compactOutput) log.info(`Use ${accent("--directory")} to specify a different target location.`);
3996
+ selectedParentDir = inferParentDir(selectedTemplateName, workspaceInfoOptional) ?? workspaceInfoOptional.parentDirs[0];
4054
3997
  }
4055
- if (isBuiltinTemplate && !targetDir) {
4056
- if (selectedTemplateName === BuiltinTemplate.monorepo) {
4057
- const selected = await promptPackageNameAndTargetDir(getRandomProjectName({ fallbackName: "vite-plus-monorepo" }), options.interactive);
4058
- packageName = selected.packageName;
4059
- targetDir = selected.targetDir;
4060
- } else {
4061
- const defaultPackageName = getRandomProjectName({
4062
- scope: workspaceInfoOptional.monorepoScope,
4063
- fallbackName: `vite-plus-${selectedTemplateName.split(":")[1]}`
4064
- });
4065
- const selected = await promptPackageNameAndTargetDir(defaultPackageName, options.interactive);
4066
- packageName = selected.packageName;
4067
- targetDir = selectedParentDir ? path.join(selectedParentDir, selected.targetDir) : selected.targetDir;
4068
- }
3998
+ if (isGitHubUrl(selectedTemplateName)) if (hasExplicitTargetDir(selectedTemplateArgs)) remoteTargetDir = selectedTemplateArgs[0];
3999
+ else {
4000
+ const inferredTargetDir = inferGitHubRepoName(selectedTemplateName) ?? "template";
4001
+ const remoteTargetBaseDir = selectedParentDir ? path.join(workspaceInfoOptional.rootDir, selectedParentDir) : workspaceInfoOptional.rootDir;
4002
+ const defaultTargetDir = suggestAvailableTargetDir(inferredTargetDir, remoteTargetBaseDir);
4003
+ if (defaultTargetDir !== inferredTargetDir && options.interactive) log.info(` Target directory "${inferredTargetDir}" already exists. Suggested: ${accent(defaultTargetDir)}`);
4004
+ remoteTargetDir = await promptTargetDir(defaultTargetDir, options.interactive, { cwd: remoteTargetBaseDir });
4005
+ selectedTemplateArgs = [remoteTargetDir, ...selectedTemplateArgs];
4006
+ }
4007
+ if (isBuiltinTemplate && !targetDir) if (selectedTemplateName === BuiltinTemplate.monorepo) {
4008
+ const selected = await promptPackageNameAndTargetDir(getRandomProjectName({ fallbackName: "vite-plus-monorepo" }), options.interactive);
4009
+ packageName = selected.packageName;
4010
+ targetDir = selected.targetDir;
4011
+ } else {
4012
+ const selected = await promptPackageNameAndTargetDir(getRandomProjectName({
4013
+ scope: workspaceInfoOptional.monorepoScope,
4014
+ fallbackName: `vite-plus-${selectedTemplateName.split(":")[1]}`
4015
+ }), options.interactive);
4016
+ packageName = selected.packageName;
4017
+ targetDir = selectedParentDir ? path.join(selectedParentDir, selected.targetDir) : selected.targetDir;
4069
4018
  }
4070
- const packageManager = workspaceInfoOptional.packageManager ?? await selectPackageManager(options.interactive);
4071
- const shouldSilencePackageManagerInstallLog = isMonorepo && workspaceInfoOptional.packageManager !== undefined;
4019
+ const packageManager = workspaceInfoOptional.packageManager ?? await selectPackageManager(options.interactive, compactOutput);
4020
+ const shouldSilencePackageManagerInstallLog = compactOutput || isMonorepo && workspaceInfoOptional.packageManager !== void 0;
4072
4021
  const downloadResult = await downloadPackageManager$1(packageManager, workspaceInfoOptional.packageManagerVersion, options.interactive, shouldSilencePackageManagerInstallLog);
4073
4022
  const workspaceInfo = {
4074
4023
  ...workspaceInfoOptional,
4075
4024
  packageManager,
4076
4025
  downloadPackageManager: downloadResult
4077
4026
  };
4078
- const existingAgentTargetPaths = options.agent !== undefined || !options.interactive ? undefined : detectExistingAgentTargetPaths(workspaceInfoOptional.rootDir);
4079
- selectedAgentTargetPaths = existingAgentTargetPaths !== undefined ? existingAgentTargetPaths : await selectAgentTargetPaths({
4027
+ const existingAgentTargetPaths = options.agent !== void 0 || !options.interactive ? void 0 : detectExistingAgentTargetPaths(workspaceInfoOptional.rootDir);
4028
+ selectedAgentTargetPaths = existingAgentTargetPaths !== void 0 ? existingAgentTargetPaths : await selectAgentTargetPaths({
4080
4029
  interactive: options.interactive,
4081
4030
  agent: options.agent,
4082
4031
  onCancel: () => cancelAndExit()
4083
4032
  });
4084
- const existingEditor = options.editor || !options.interactive ? undefined : detectExistingEditor(workspaceInfoOptional.rootDir);
4085
- selectedEditor = existingEditor ?? await selectEditor({
4033
+ selectedEditor = (options.editor || !options.interactive ? void 0 : detectExistingEditor(workspaceInfoOptional.rootDir)) ?? await selectEditor({
4086
4034
  interactive: options.interactive,
4087
4035
  editor: options.editor,
4088
4036
  onCancel: () => cancelAndExit()
4089
4037
  });
4038
+ shouldSetupHooks = await promptGitHooks(options);
4039
+ const createProgress = options.interactive && compactOutput ? spinner({ indicator: "timer" }) : void 0;
4040
+ let createProgressStarted = false;
4041
+ let createProgressMessage = "Scaffolding project";
4042
+ const updateCreateProgress = (message) => {
4043
+ createProgressMessage = message;
4044
+ if (!createProgress) return;
4045
+ if (createProgressStarted) {
4046
+ createProgress.message(message);
4047
+ return;
4048
+ }
4049
+ createProgress.start(message);
4050
+ createProgressStarted = true;
4051
+ };
4052
+ const clearCreateProgress = () => {
4053
+ if (createProgress && createProgressStarted) {
4054
+ createProgress.clear();
4055
+ createProgressStarted = false;
4056
+ }
4057
+ };
4058
+ const failCreateProgress = (message) => {
4059
+ if (createProgress && createProgressStarted) {
4060
+ createProgress.error(message);
4061
+ createProgressStarted = false;
4062
+ }
4063
+ };
4064
+ const pauseCreateProgress = () => {
4065
+ if (createProgress && createProgressStarted) {
4066
+ createProgress.pause();
4067
+ createProgressStarted = false;
4068
+ }
4069
+ };
4070
+ const resumeCreateProgress = () => {
4071
+ if (createProgress && !createProgressStarted) {
4072
+ createProgress.resume(createProgressMessage);
4073
+ createProgressStarted = true;
4074
+ }
4075
+ };
4076
+ updateCreateProgress("Scaffolding project");
4090
4077
  const templateInfo = discoverTemplate(selectedTemplateName, selectedTemplateArgs, workspaceInfo, options.interactive);
4091
- if (selectedParentDir) {
4092
- templateInfo.parentDir = selectedParentDir;
4093
- }
4094
- if (targetDir) {
4095
- templateInfo.parentDir = undefined;
4078
+ if (selectedParentDir) templateInfo.parentDir = selectedParentDir;
4079
+ if (targetDir) templateInfo.parentDir = void 0;
4080
+ if (remoteTargetDir) {
4081
+ const projectDir = templateInfo.parentDir ? path.join(templateInfo.parentDir, remoteTargetDir) : remoteTargetDir;
4082
+ pauseCreateProgress();
4083
+ await checkProjectDirExists(path.join(workspaceInfo.rootDir, projectDir), options.interactive);
4084
+ resumeCreateProgress();
4096
4085
  }
4097
4086
  if (templateInfo.command === BuiltinTemplate.monorepo) {
4087
+ updateCreateProgress("Creating monorepo");
4098
4088
  await checkProjectDirExists(path.join(workspaceInfo.rootDir, targetDir), options.interactive);
4099
4089
  const result = await executeMonorepoTemplate(workspaceInfo, {
4100
4090
  ...templateInfo,
4101
4091
  packageName,
4102
4092
  targetDir
4103
- }, options.interactive);
4093
+ }, options.interactive, { silent: compactOutput });
4104
4094
  const { projectDir } = result;
4105
4095
  if (result.exitCode !== 0 || !projectDir) {
4096
+ failCreateProgress("Scaffolding failed");
4106
4097
  cancelAndExit(`Failed to create monorepo, exit code: ${result.exitCode}`, result.exitCode);
4107
4098
  }
4108
4099
  const fullPath = path.join(workspaceInfo.rootDir, projectDir);
4100
+ updateCreateProgress("Writing agent instructions");
4101
+ pauseCreateProgress();
4109
4102
  await writeAgentInstructions({
4110
4103
  projectRoot: fullPath,
4111
4104
  targetPaths: selectedAgentTargetPaths,
4112
- interactive: options.interactive
4105
+ interactive: options.interactive,
4106
+ silent: compactOutput
4113
4107
  });
4108
+ resumeCreateProgress();
4109
+ updateCreateProgress("Writing editor configs");
4110
+ pauseCreateProgress();
4114
4111
  await writeEditorConfigs({
4115
4112
  projectRoot: fullPath,
4116
4113
  editorId: selectedEditor,
4117
- interactive: options.interactive
4114
+ interactive: options.interactive,
4115
+ silent: compactOutput
4118
4116
  });
4117
+ resumeCreateProgress();
4119
4118
  workspaceInfo.rootDir = fullPath;
4120
- rewriteMonorepo(workspaceInfo);
4121
- const shouldSetupHooks = await promptGitHooks(options);
4122
- if (shouldSetupHooks) {
4123
- installGitHooks(fullPath);
4124
- }
4125
- await runViteInstall(fullPath, options.interactive);
4126
- await runViteFmt(fullPath, options.interactive);
4127
- outro(`✔ Created ${accent(projectDir)}!`);
4128
- log$1(styleText("bold", "Next steps:"));
4129
- log$1(` ${accent(`cd ${projectDir}`)}`);
4130
- log$1(` ${accent(`vp dev ${InitialMonorepoAppDir}`)}`);
4119
+ updateCreateProgress("Integrating monorepo");
4120
+ rewriteMonorepo(workspaceInfo, void 0, compactOutput);
4121
+ if (shouldSetupHooks) installGitHooks(fullPath, compactOutput);
4122
+ updateCreateProgress("Installing dependencies");
4123
+ const installSummary = await runViteInstall(fullPath, options.interactive, void 0, { silent: compactOutput });
4124
+ updateCreateProgress("Formatting code");
4125
+ await runViteFmt(fullPath, options.interactive, void 0, { silent: compactOutput });
4126
+ clearCreateProgress();
4127
+ showCreateSummary({
4128
+ description: describeScaffold(selectedTemplateName, selectedTemplateArgs),
4129
+ installSummary,
4130
+ nextCommand: getNextCommand(projectDir, `vp dev ${InitialMonorepoAppDir}`),
4131
+ packageManager: workspaceInfo.packageManager,
4132
+ packageManagerVersion: workspaceInfo.downloadPackageManager.version,
4133
+ projectDir
4134
+ });
4131
4135
  return;
4132
4136
  }
4133
4137
  let result;
4134
4138
  if (templateInfo.type === TemplateType.builtin) {
4135
4139
  if (!targetDir) {
4136
- const defaultPackageName = getRandomProjectName({
4140
+ const selected = await promptPackageNameAndTargetDir(getRandomProjectName({
4137
4141
  scope: workspaceInfo.monorepoScope,
4138
4142
  fallbackName: `vite-plus-${templateInfo.command.split(":")[1]}`
4139
- });
4140
- const selected = await promptPackageNameAndTargetDir(defaultPackageName, options.interactive);
4143
+ }), options.interactive);
4141
4144
  packageName = selected.packageName;
4142
4145
  targetDir = templateInfo.parentDir ? path.join(templateInfo.parentDir, selected.targetDir) : selected.targetDir;
4143
4146
  }
4147
+ pauseCreateProgress();
4144
4148
  await checkProjectDirExists(targetDir, options.interactive);
4145
- log.info(`Target directory: ${accent(formatDisplayTargetDir(targetDir))}`);
4149
+ resumeCreateProgress();
4150
+ updateCreateProgress("Generating project");
4146
4151
  result = await executeBuiltinTemplate(workspaceInfo, {
4147
4152
  ...templateInfo,
4148
4153
  packageName,
4149
4154
  targetDir
4150
- });
4155
+ }, { silent: compactOutput });
4151
4156
  } else {
4152
- result = await executeRemoteTemplate(workspaceInfo, templateInfo);
4157
+ updateCreateProgress("Generating project");
4158
+ result = await executeRemoteTemplate(workspaceInfo, templateInfo, { silent: compactOutput });
4153
4159
  }
4154
4160
  if (result.exitCode !== 0) {
4161
+ failCreateProgress("Scaffolding failed");
4155
4162
  process.exit(result.exitCode);
4156
4163
  }
4157
4164
  const projectDir = result.projectDir;
4158
4165
  if (!projectDir) {
4166
+ clearCreateProgress();
4159
4167
  process.exit(0);
4160
4168
  }
4161
- log.success(`Project directory: ${accent(projectDir)}`);
4162
4169
  const fullPath = path.join(workspaceInfo.rootDir, projectDir);
4163
4170
  const agentInstructionsRoot = isMonorepo ? workspaceInfo.rootDir : fullPath;
4171
+ updateCreateProgress("Writing agent instructions");
4172
+ pauseCreateProgress();
4164
4173
  await writeAgentInstructions({
4165
4174
  projectRoot: agentInstructionsRoot,
4166
4175
  targetPaths: selectedAgentTargetPaths,
4167
- interactive: options.interactive
4176
+ interactive: options.interactive,
4177
+ silent: compactOutput
4168
4178
  });
4179
+ resumeCreateProgress();
4180
+ updateCreateProgress("Writing editor configs");
4181
+ pauseCreateProgress();
4169
4182
  await writeEditorConfigs({
4170
4183
  projectRoot: fullPath,
4171
4184
  editorId: selectedEditor,
4172
- interactive: options.interactive
4185
+ interactive: options.interactive,
4186
+ silent: compactOutput
4173
4187
  });
4188
+ resumeCreateProgress();
4189
+ let installSummary;
4174
4190
  if (isMonorepo) {
4175
- log.step("Monorepo integration...");
4176
- rewriteMonorepoProject(fullPath, workspaceInfo.packageManager);
4191
+ if (!compactOutput) log.step("Monorepo integration...");
4192
+ updateCreateProgress("Integrating into monorepo");
4193
+ rewriteMonorepoProject(fullPath, workspaceInfo.packageManager, void 0, compactOutput);
4177
4194
  if (workspaceInfo.packages.length > 0) {
4178
4195
  if (options.interactive) {
4196
+ pauseCreateProgress();
4179
4197
  const selectedDepTypeOptions = await multiselect({
4180
4198
  message: `Add workspace dependencies to ${accent(projectDir)}?`,
4181
4199
  options: [
@@ -4187,9 +4205,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
4187
4205
  required: false
4188
4206
  });
4189
4207
  let selectedDepTypes = [];
4190
- if (!Ct(selectedDepTypeOptions)) {
4191
- selectedDepTypes = selectedDepTypeOptions;
4192
- }
4208
+ if (!Ct(selectedDepTypeOptions)) selectedDepTypes = selectedDepTypeOptions;
4193
4209
  for (const selectedDepType of selectedDepTypes) {
4194
4210
  const selected = await multiselect({
4195
4211
  message: `Which packages should be added as ${selectedDepType} to ${success(projectDir)}?`,
@@ -4200,39 +4216,35 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
4200
4216
  required: false
4201
4217
  });
4202
4218
  let selectedDeps = [];
4203
- if (!Ct(selected)) {
4204
- selectedDeps = selected;
4205
- }
4206
- if (selectedDeps.length > 0) {
4207
- updatePackageJsonWithDeps(workspaceInfo.rootDir, projectDir, selectedDeps, selectedDepType);
4208
- }
4219
+ if (!Ct(selected)) selectedDeps = selected;
4220
+ if (selectedDeps.length > 0) updatePackageJsonWithDeps(workspaceInfo.rootDir, projectDir, selectedDeps, selectedDepType);
4209
4221
  }
4222
+ resumeCreateProgress();
4210
4223
  }
4211
4224
  }
4212
4225
  updateWorkspaceConfig(projectDir, workspaceInfo);
4213
- await runViteInstall(workspaceInfo.rootDir, options.interactive);
4214
- await runViteFmt(workspaceInfo.rootDir, options.interactive, [projectDir]);
4226
+ updateCreateProgress("Installing dependencies");
4227
+ installSummary = await runViteInstall(workspaceInfo.rootDir, options.interactive, void 0, { silent: compactOutput });
4228
+ updateCreateProgress("Formatting code");
4229
+ await runViteFmt(workspaceInfo.rootDir, options.interactive, [projectDir], { silent: compactOutput });
4215
4230
  } else {
4216
- rewriteStandaloneProject(fullPath, workspaceInfo);
4217
- const shouldSetupHooks = await promptGitHooks(options);
4218
- if (shouldSetupHooks) {
4219
- installGitHooks(fullPath);
4220
- }
4221
- await runViteInstall(fullPath, options.interactive);
4222
- await runViteFmt(fullPath, options.interactive);
4231
+ updateCreateProgress("Applying Vite+ project setup");
4232
+ rewriteStandaloneProject(fullPath, workspaceInfo, void 0, compactOutput);
4233
+ if (shouldSetupHooks) installGitHooks(fullPath, compactOutput);
4234
+ updateCreateProgress("Installing dependencies");
4235
+ installSummary = await runViteInstall(fullPath, options.interactive, void 0, { silent: compactOutput });
4236
+ updateCreateProgress("Formatting code");
4237
+ await runViteFmt(fullPath, options.interactive, void 0, { silent: compactOutput });
4223
4238
  }
4224
- outro(`✔ Created ${accent(projectDir)}!`);
4225
- showNextSteps(projectDir, isMonorepo);
4226
- }
4227
- function showNextSteps(projectDir, isMonorepo) {
4228
- log$1(styleText("bold", "Next steps:"));
4229
- if (isMonorepo) {
4230
- log$1(` ${accent(`vp dev ${projectDir}`)}`);
4231
- } else {
4232
- log$1(` ${accent(`cd ${projectDir}`)}`);
4233
- log$1(` ${accent("vp dev")}`);
4234
- }
4235
- log$1("");
4239
+ clearCreateProgress();
4240
+ showCreateSummary({
4241
+ description: describeScaffold(selectedTemplateName, selectedTemplateArgs),
4242
+ installSummary,
4243
+ nextCommand: isMonorepo ? `vp dev ${projectDir}` : getNextCommand(projectDir, "vp dev"),
4244
+ packageManager: workspaceInfo.packageManager,
4245
+ packageManagerVersion: workspaceInfo.downloadPackageManager.version,
4246
+ projectDir
4247
+ });
4236
4248
  }
4237
4249
  async function showAvailableTemplates() {
4238
4250
  log$1(vitePlusHeader() + "\n");
@@ -4243,5 +4255,4 @@ main().catch((err) => {
4243
4255
  console.error(err);
4244
4256
  cancelAndExit(`Failed to generate code: ${err.message}`, 1);
4245
4257
  });
4246
-
4247
- //#endregion
4258
+ //#endregion