vite-plus 0.2.7 → 0.2.9

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 (89) hide show
  1. package/AGENTS.md +7 -0
  2. package/LICENSE +5 -1
  3. package/README.md +9 -3
  4. package/bin/vpr +3 -2
  5. package/binding/index.cjs +193 -80
  6. package/binding/index.d.cts +106 -11
  7. package/dist/agent-DQU8uS6P.js +416 -0
  8. package/dist/bin.js +1388 -23
  9. package/dist/{cli-truncate-BVOlIIPy.js → cli-truncate-Bg3RDXpi.js} +0 -2
  10. package/dist/client/bundledDevClient.mjs +1 -0
  11. package/dist/config/bin.js +32 -133
  12. package/dist/{constants-BsuzPowC.js → constants-CG513DRa.js} +10 -2
  13. package/dist/create/bin.js +255 -268
  14. package/dist/{define-config-C2KfLHpC.js → define-config-CV4bQG_8.js} +3 -3
  15. package/dist/{define-config-eLQH9us2.d.ts → define-config-DWoAkNdp.d.ts} +16 -0
  16. package/dist/{define-config-DLh9fE95.cjs → define-config-DyNLA_f0.cjs} +1 -1
  17. package/dist/define-config.cjs +1 -1
  18. package/dist/define-config.d.ts +1 -1
  19. package/dist/define-config.js +1 -1
  20. package/dist/{dist-CKz3vcoG.js → dist-BDYZP12R.js} +196 -157
  21. package/dist/dist-Dqv1-Clg.js +3 -0
  22. package/dist/{agent-CPwWJ4qf.js → editor-g4PosU99.js} +819 -628
  23. package/dist/hooks/bin.d.ts +1 -0
  24. package/dist/hooks/bin.js +130 -0
  25. package/dist/hooks-pNCBWtFT.js +570 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.d.ts +1 -1
  28. package/dist/index.js +1 -1
  29. package/dist/{json-DiRs8ceZ.js → json-qlK6UH0r.js} +40 -38
  30. package/dist/migration/bin.js +65 -58
  31. package/dist/{oxlint-plugin-config-Bxgc4cwF.js → oxlint-plugin-config-BEZ9IUf7.js} +1 -1
  32. package/dist/oxlint-plugin.js +1 -1
  33. package/dist/pack-bin.js +1 -1
  34. package/dist/{package-Ds3uThLb.js → package-B4T8RGMG.js} +2 -2
  35. package/dist/{tsconfig-Jia2vgMG.js → prompts-CHz_98bJ.js} +169 -219
  36. package/dist/{resolve-vite-config-BiuLZnn8.js → resolve-vite-config-Dmeyeyj-.js} +2 -9
  37. package/dist/{rolldown-runtime-C7HZzL1F.js → rolldown-runtime-CMFfr-1z.js} +1 -1
  38. package/dist/staged/bin.js +241 -226
  39. package/dist/terminal-Bz-ps6rJ.js +128 -0
  40. package/dist/test/browser/providers/playwright/context.d.ts +1 -1
  41. package/dist/test/browser/providers/playwright.d.ts +6 -6
  42. package/dist/test/browser/providers/preview/context.d.ts +1 -1
  43. package/dist/test/browser/providers/preview.d.ts +4 -4
  44. package/dist/test/browser/providers/webdriverio/context.d.ts +1 -1
  45. package/dist/test/browser/providers/webdriverio.d.ts +6 -6
  46. package/dist/test/browser-playwright/context.d.ts +1 -1
  47. package/dist/test/browser-playwright.d.ts +6 -6
  48. package/dist/test/browser-preview/context.d.ts +1 -1
  49. package/dist/test/browser-preview.d.ts +4 -4
  50. package/dist/test/browser-webdriverio/context.d.ts +1 -1
  51. package/dist/test/browser-webdriverio.d.ts +6 -6
  52. package/dist/test/context.d.ts +3 -3
  53. package/dist/test/locators.d.ts +1 -1
  54. package/dist/toolchain.d.ts +25 -0
  55. package/dist/toolchain.js +194 -0
  56. package/dist/toolchain.json +193 -0
  57. package/dist/tsconfig-7v_BHagU.js +151 -0
  58. package/dist/{tsgolint-path-B-yOos8p.js → tsgolint-path-CbDReEOx.js} +5 -3
  59. package/dist/tsgolint-path.js +1 -1
  60. package/dist/version.js +6 -6
  61. package/dist/versions.d.ts +3 -3
  62. package/dist/versions.js +6 -6
  63. package/docs/config/index.md +13 -0
  64. package/docs/config/staged.md +2 -1
  65. package/docs/guide/ci.md +37 -4
  66. package/docs/guide/commit-hooks.md +112 -21
  67. package/docs/guide/create.md +7 -4
  68. package/docs/guide/env.md +8 -4
  69. package/docs/guide/fmt.md +2 -2
  70. package/docs/guide/github-actions-cache.md +5 -1
  71. package/docs/guide/ide-integration.md +61 -2
  72. package/docs/guide/index.md +4 -2
  73. package/docs/guide/install.md +27 -0
  74. package/docs/guide/installer-env-vars.md +14 -3
  75. package/docs/guide/lint.md +3 -1
  76. package/docs/guide/migrate.md +49 -4
  77. package/docs/guide/monorepo.md +98 -10
  78. package/docs/guide/troubleshooting.md +12 -3
  79. package/docs/guide/upgrade.md +27 -4
  80. package/docs/package.json +1 -1
  81. package/docs/pnpm-workspace.yaml +7 -0
  82. package/docs/vite.config.ts +3 -0
  83. package/package.json +21 -23
  84. package/rules/vite-tools.yml +0 -7
  85. package/dist/dist-CtM2JRbM.js +0 -3
  86. package/dist/editor-BbT1lTNc.js +0 -675
  87. package/dist/help-YP84FSEz.js +0 -61
  88. package/dist/terminal-uTv0ZaMr.js +0 -33
  89. package/dist/{log-update-DHZRyJ2m.js → log-update-CoW8Z4Dl.js} +1 -1
@@ -1,34 +1,23 @@
1
- import { r as __toESM, t as __commonJSMin } from "../rolldown-runtime-C7HZzL1F.js";
2
- import { s as VITE_PLUS_NAME } from "../constants-BsuzPowC.js";
3
- import { A as intro, B as runCommandSilently, C as resolveApproveBuildTargets, E as PackageManager, F as spinner, I as text, L as require_picocolors, M as multiselect, O as cancel, P as select, R as isCancel, S as detectGatedBuilds, T as DependencyType, V as require_cross_spawn, d as downloadPackageManager$1, f as promptGitHooks, g as selectPackageManager, h as runViteInstall, j as log, k as confirm, m as runViteFmt, p as resolveGitInit, u as defaultInteractive, v as editYamlFile, x as approveBuilds, y as readYamlFile, z as runCommand$1 } from "../tsconfig-Jia2vgMG.js";
4
- import { a as printHeader, i as muted, o as success, r as log$1, t as accent } from "../terminal-uTv0ZaMr.js";
5
- import { i as readJsonFile, n as editJsonFile } from "../json-DiRs8ceZ.js";
6
- import { a as resolveViteConfig, n as findWorkspaceRoot, r as hasViteConfig, t as findViteConfig } from "../resolve-vite-config-BiuLZnn8.js";
1
+ import { r as __toESM, t as __commonJSMin } from "../rolldown-runtime-CMFfr-1z.js";
2
+ import { a as muted, i as log, l as renderCliDoc, o as printHeader, r as formatDuration, s as success, t as accent } from "../terminal-Bz-ps6rJ.js";
3
+ import { c as VITE_PLUS_NAME } from "../constants-CG513DRa.js";
4
+ import { A as isCancel, C as log$1, D as spinner, E as select, M as runCommandSilently, N as require_cross_spawn, O as text, S as intro, a as resolveGitInit, c as selectPackageManager, d as readYamlFile, h as resolveApproveBuildTargets, i as promptGitHooks, j as runCommand$1, k as require_picocolors, m as detectGatedBuilds, n as defaultInteractive, o as runViteFmt, p as approveBuilds, r as downloadPackageManager$1, s as runViteInstall, t as cancelAndExit, u as editYamlFile, v as DependencyType, w as multiselect, x as confirm, y as PackageManager } from "../prompts-CHz_98bJ.js";
5
+ import { i as readJsonFile, n as editJsonFile } from "../json-qlK6UH0r.js";
6
+ import { a as resolveViteConfig, n as findWorkspaceRoot, r as hasViteConfig, t as findViteConfig } from "../resolve-vite-config-Dmeyeyj-.js";
7
7
  import { t as lib_default } from "../lib-L3DWSRQp.js";
8
- import { o as fetchNpmResource, s as getNpmRegistry, t as checkNpmPackageExists } from "../package-Ds3uThLb.js";
9
- import { I as promptEslintMigration, J as templatesDir, N as detectEslintProject, S as injectCreateDefaultTemplate, a as selectAgentTargets, c as writeCopilotSetupWorkflow, d as rewriteStandaloneProject, g as setPackageManager, l as rewriteMonorepo, q as displayRelative, r as detectExistingAgentTargetPaths, s as writeAgentInstructions, t as COPILOT_AGENT_ID, u as rewriteMonorepoProject, y as installGitHooks } from "../agent-CPwWJ4qf.js";
10
- import { a as writeEditorConfigs, c as updatePackageJsonWithDeps, d as detectFramework, f as hasFrameworkShim, g as promptPrettierMigration, i as selectEditors, l as updateWorkspaceConfig, m as detectPrettierProject, n as detectExistingEditors, o as detectWorkspace$1, s as isBingoTemplate, u as addFrameworkShim } from "../editor-BbT1lTNc.js";
11
- import { t as renderCliDoc } from "../help-YP84FSEz.js";
8
+ import { o as fetchNpmResource, r as getScopeFromPackageName, s as getNpmRegistry, t as checkNpmPackageExists } from "../package-B4T8RGMG.js";
9
+ import { a as selectAgentTargets, c as writeCopilotSetupWorkflow, d as templatesDir, l as displayRelative, r as detectExistingAgentTargetPaths, s as writeAgentInstructions, t as COPILOT_AGENT_ID } from "../agent-DQU8uS6P.js";
10
+ import { A as isBingoTemplate, F as hasFrameworkShim, G as promptEslintMigration, H as detectEslintProject, L as detectPrettierProject, M as updateWorkspaceConfig, N as addFrameworkShim, P as detectFramework, a as selectEditors, b as initGitRepository, c as rewriteMonorepoProject, g as installGitHooks, j as updatePackageJsonWithDeps, k as detectWorkspace$1, l as rewriteStandaloneProject, m as setPackageManager, n as detectExistingEditors, o as writeEditorConfigs, s as rewriteMonorepo, v as shouldSkipStagedMigrationForHooks, x as injectCreateDefaultTemplate, y as findGitRoot, z as promptPrettierMigration } from "../editor-g4PosU99.js";
12
11
  import path from "node:path";
13
12
  import { runCommand, upsertJsonConfig, vitePlusHeader } from "../../binding/index.js";
14
- import fs from "node:fs";
15
13
  import { styleText } from "node:util";
16
- import { createHash, randomUUID } from "node:crypto";
14
+ import fs from "node:fs";
17
15
  import os from "node:os";
16
+ import { createHash, randomUUID } from "node:crypto";
18
17
  import fsPromises from "node:fs/promises";
19
18
  import assert from "node:assert";
20
- //#region src/utils/git.ts
21
- var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
22
- async function initGitRepository(cwd) {
23
- return (await runCommandSilently({
24
- command: "git",
25
- args: ["init"],
26
- cwd,
27
- envs: process.env
28
- })).exitCode === 0;
29
- }
30
- //#endregion
31
19
  //#region src/create/command.ts
20
+ var import_cross_spawn = /* @__PURE__ */ __toESM(require_cross_spawn(), 1);
32
21
  async function runCommandAndDetectProjectDir(options, parentDir) {
33
22
  const cwd = parentDir ? path.join(options.cwd, parentDir) : options.cwd;
34
23
  const existingDirs = /* @__PURE__ */ new Set();
@@ -296,7 +285,7 @@ function verifyIntegrity(bytes, integrity) {
296
285
  const actual = hash.digest("base64");
297
286
  if (actual !== parsed.expected) throw new Error(`integrity check failed: expected ${integrity}, got ${parsed.algorithm}-${actual}`);
298
287
  }
299
- const MAX_TARBALL_BYTES = 50 * 1024 * 1024;
288
+ const MAX_TARBALL_BYTES = 52428800;
300
289
  async function downloadTarball(url) {
301
290
  const response = await fetchNpmResource(url, { timeoutMs: 3e4 });
302
291
  if (!response.ok) throw new Error(`failed to download tarball (${response.status}): ${url}`);
@@ -418,7 +407,7 @@ async function extractTarballTo(bytes, destDir) {
418
407
  throw error;
419
408
  }
420
409
  }
421
- const STAGING_STALE_MS = 1440 * 60 * 1e3;
410
+ const STAGING_STALE_MS = 864e5;
422
411
  /**
423
412
  * Remove `<destDir>.tmp-*` siblings left behind by a previous crash so
424
413
  * repeated aborts don't accumulate orphaned staging trees. Only deletes
@@ -637,7 +626,8 @@ function validateCreateTemplates(templates) {
637
626
  });
638
627
  }
639
628
  async function fetchPackument(scope, packageName) {
640
- const response = await fetchNpmResource(`${getNpmRegistry(scope)}/${packageName}`, {
629
+ const url = `${getNpmRegistry(scope)}/${packageName}`;
630
+ const response = await fetchNpmResource(url, {
641
631
  headers: { accept: "application/json" },
642
632
  timeoutMs: 5e3
643
633
  });
@@ -962,6 +952,140 @@ function formatManifestTable(manifest, isMonorepo) {
962
952
  };
963
953
  }
964
954
  //#endregion
955
+ //#region src/create/org-resolve.ts
956
+ function printNonInteractiveTable(manifest, orgSpec, isMonorepo) {
957
+ const { lines, filteredCount } = formatManifestTable(manifest, isMonorepo);
958
+ const [firstVisible] = filterManifestForContext(manifest.templates, isMonorepo);
959
+ const body = [
960
+ "",
961
+ `A template name is required when running \`vp create ${orgSpec.scope}\` in non-interactive mode.`,
962
+ "",
963
+ `Available templates in ${manifest.packageName}:`,
964
+ "",
965
+ ...lines
966
+ ];
967
+ if (filteredCount > 0) body.push("", `(omitted ${filteredCount} monorepo-only ${filteredCount === 1 ? "entry" : "entries"} because this workspace is already a monorepo)`);
968
+ body.push("", "Examples:");
969
+ if (firstVisible) body.push(" # Scaffold a specific template from the org", ` vp create ${orgSpec.scope}:${firstVisible.name} --no-interactive`, "");
970
+ body.push(" # Or use a Vite+ built-in template", " vp create vite:application --no-interactive", "");
971
+ process.stderr.write(body.join("\n"));
972
+ }
973
+ function rejectMonorepoEntryInsideMonorepo(entry, isMonorepo) {
974
+ if (entry.monorepo && isMonorepo) {
975
+ log$1.info("You are already in a monorepo workspace.\nUse a different template or run this command outside the monorepo");
976
+ cancelAndExit("Cannot create a monorepo inside an existing monorepo", 1);
977
+ }
978
+ }
979
+ async function resolveEntry(manifest, entry) {
980
+ if (isRelativePath(entry.template)) return {
981
+ kind: "bundled",
982
+ bundledLocalPath: resolveBundledPath(await ensureOrgPackageExtracted(manifest), entry.template),
983
+ entryName: entry.name,
984
+ scope: manifest.scope,
985
+ ...entry.monorepo === true ? { monorepo: true } : {}
986
+ };
987
+ return {
988
+ kind: "replaced",
989
+ templateName: entry.template
990
+ };
991
+ }
992
+ /**
993
+ * If `selectedTemplateName` points at an `@scope[/name]` org whose
994
+ * `@scope/create` package publishes a `createConfig.templates` manifest, apply the
995
+ * manifest rules (picker / direct lookup / escape hatch / bundled
996
+ * extraction) and report the outcome.
997
+ *
998
+ * The caller — `packages/cli/src/create/bin.ts` — decides what to do next
999
+ * based on the returned variant.
1000
+ */
1001
+ async function resolveOrgManifestForCreate(args) {
1002
+ const orgSpec = parseOrgScopedSpec(args.templateName);
1003
+ if (!orgSpec) return { kind: "passthrough" };
1004
+ let manifest;
1005
+ try {
1006
+ manifest = await readOrgManifest(orgSpec.scope, orgSpec.version);
1007
+ } catch (error) {
1008
+ const message = error instanceof OrgManifestSchemaError ? error.message : `Failed to read ${orgSpec.scope}/create manifest: ${error.message}`;
1009
+ cancelAndExit(message, 1);
1010
+ }
1011
+ if (!manifest) {
1012
+ if (orgSpec.name !== void 0) cancelAndExit(`No \`createConfig.templates\` manifest in ${orgSpec.scope}/create — \`@org:name\` requires one.`, 1);
1013
+ log$1.info(`No \`createConfig.templates\` manifest in ${orgSpec.scope}/create — running it as a normal package.`);
1014
+ return { kind: "passthrough" };
1015
+ }
1016
+ if (orgSpec.name === void 0) {
1017
+ if (!args.interactive) {
1018
+ printNonInteractiveTable(manifest, orgSpec, args.isMonorepo);
1019
+ process.exit(1);
1020
+ }
1021
+ const picked = await pickOrgTemplate(manifest, { isMonorepo: args.isMonorepo });
1022
+ if (picked === ORG_PICKER_CANCEL) cancelAndExit();
1023
+ if (picked === ORG_PICKER_BUILTIN_ESCAPE) {
1024
+ if (args.isMonorepo && manifest.templates.every((t) => t.monorepo)) log$1.info(`No templates from ${manifest.packageName} are applicable inside a monorepo — showing Vite+ built-in templates instead.`);
1025
+ return { kind: "escape-hatch" };
1026
+ }
1027
+ rejectMonorepoEntryInsideMonorepo(picked.entry, args.isMonorepo);
1028
+ return resolveEntry(manifest, picked.entry);
1029
+ }
1030
+ const entry = manifest.templates.find((candidate) => candidate.name === orgSpec.name);
1031
+ if (!entry) {
1032
+ const available = filterManifestForContext(manifest.templates, args.isMonorepo).map((t) => t.name).join(", ");
1033
+ cancelAndExit(`No template named "${orgSpec.name}" in ${manifest.packageName}. Available: ${available || "(none applicable in this context)"}.`, 1);
1034
+ }
1035
+ rejectMonorepoEntryInsideMonorepo(entry, args.isMonorepo);
1036
+ return resolveEntry(manifest, entry);
1037
+ }
1038
+ /**
1039
+ * Read the `create` config (`defaultTemplate` + validated `templates`) from
1040
+ * a workspace's `vite.config.ts` in a single config evaluation.
1041
+ *
1042
+ * By default, walks up from `startDir` via `findWorkspaceRoot` (monorepo
1043
+ * markers only — `pnpm-workspace.yaml`, `workspaces` in `package.json`,
1044
+ * `lerna.json`) so monorepo invocations from any subdirectory still pick up
1045
+ * the root config. Pass `walkUp: false` to read `startDir` directly when the
1046
+ * caller already holds the exact workspace root.
1047
+ *
1048
+ * Best-effort for resolution: a missing or unresolvable config reads as
1049
+ * empty. A present-but-malformed `create.templates` still throws a
1050
+ * {@link CreateConfigSchemaError} so the misconfiguration surfaces.
1051
+ *
1052
+ * Pass `throwOnReadError: true` for read-modify-write callers (registration):
1053
+ * if a config file exists but cannot be evaluated, an empty read would let a
1054
+ * later write clobber the real `create` block, so the eval error is rethrown
1055
+ * instead of swallowed.
1056
+ */
1057
+ async function getConfiguredCreate(startDir, options) {
1058
+ const projectRoot = options?.walkUp === false ? startDir : findWorkspaceRoot(startDir) ?? startDir;
1059
+ if (!hasViteConfig(projectRoot)) return { templates: [] };
1060
+ let create;
1061
+ try {
1062
+ create = (await resolveViteConfig(projectRoot)).create;
1063
+ } catch (error) {
1064
+ if (options?.throwOnReadError) throw error;
1065
+ return { templates: [] };
1066
+ }
1067
+ const defaultTemplate = typeof create?.defaultTemplate === "string" && create.defaultTemplate.length > 0 ? create.defaultTemplate : void 0;
1068
+ const templates = validateCreateTemplates(create?.templates);
1069
+ return {
1070
+ ...defaultTemplate !== void 0 ? { defaultTemplate } : {},
1071
+ templates
1072
+ };
1073
+ }
1074
+ /**
1075
+ * Read `create.defaultTemplate` only. Best-effort for missing or unresolvable
1076
+ * configs (returns `undefined`), but a malformed `create.templates` still
1077
+ * rethrows its {@link CreateConfigSchemaError}: swallowing it here would
1078
+ * silently drop a valid `defaultTemplate` along with the diagnostic.
1079
+ */
1080
+ async function getConfiguredDefaultTemplate(startDir) {
1081
+ try {
1082
+ return (await getConfiguredCreate(startDir)).defaultTemplate;
1083
+ } catch (error) {
1084
+ if (error instanceof CreateConfigSchemaError) throw error;
1085
+ return;
1086
+ }
1087
+ }
1088
+ //#endregion
965
1089
  //#region ../../node_modules/.pnpm/validate-npm-package-name@7.0.2/node_modules/validate-npm-package-name/lib/builtin-modules.json
966
1090
  var require_builtin_modules = /* @__PURE__ */ __commonJSMin(((exports, module) => {
967
1091
  module.exports = [
@@ -4053,7 +4177,7 @@ async function promptPackageNameAndTargetDir(defaultPackageName, interactive) {
4053
4177
  } else {
4054
4178
  packageName = defaultPackageName;
4055
4179
  targetDir = getProjectDirFromPackageName(packageName);
4056
- log.info(`Using default package name: ${accent(packageName)}`);
4180
+ log$1.info(`Using default package name: ${accent(packageName)}`);
4057
4181
  }
4058
4182
  return {
4059
4183
  packageName,
@@ -4073,7 +4197,7 @@ async function promptTargetDir(defaultTargetDir, interactive, options) {
4073
4197
  targetDir = validateTargetDir(selected ?? defaultTargetDir, options?.cwd).directory;
4074
4198
  } else {
4075
4199
  targetDir = validateTargetDir(defaultTargetDir, options?.cwd).directory;
4076
- log.info(`Using default target directory: ${accent(targetDir)}`);
4200
+ log$1.info(`Using default target directory: ${accent(targetDir)}`);
4077
4201
  }
4078
4202
  return targetDir;
4079
4203
  }
@@ -4089,7 +4213,7 @@ function suggestAvailableTargetDir(defaultTargetDir, cwd) {
4089
4213
  async function checkProjectDirExists(projectDirFullPath, interactive) {
4090
4214
  if (isTargetDirAvailable(projectDirFullPath)) return;
4091
4215
  if (!interactive) {
4092
- log.info("Use --directory to specify a different location or remove the directory first");
4216
+ log$1.info("Use --directory to specify a different location or remove the directory first");
4093
4217
  cancelAndExit(`Target directory "${projectDirFullPath}" is not empty`, 1);
4094
4218
  }
4095
4219
  const overwrite = await select({
@@ -4110,10 +4234,6 @@ async function checkProjectDirExists(projectDirFullPath, interactive) {
4110
4234
  case "no": cancelAndExit();
4111
4235
  }
4112
4236
  }
4113
- function cancelAndExit(message = "Operation cancelled", exitCode = 0) {
4114
- cancel(message);
4115
- process.exit(exitCode);
4116
- }
4117
4237
  function isEmpty(path) {
4118
4238
  const files = fs.readdirSync(path);
4119
4239
  return files.length === 0 || files.length === 1 && files[0] === ".git";
@@ -4157,139 +4277,6 @@ function validateTargetDir(input, cwd) {
4157
4277
  return { directory: targetDir };
4158
4278
  }
4159
4279
  //#endregion
4160
- //#region src/create/org-resolve.ts
4161
- function printNonInteractiveTable(manifest, orgSpec, isMonorepo) {
4162
- const { lines, filteredCount } = formatManifestTable(manifest, isMonorepo);
4163
- const [firstVisible] = filterManifestForContext(manifest.templates, isMonorepo);
4164
- const body = [
4165
- "",
4166
- `A template name is required when running \`vp create ${orgSpec.scope}\` in non-interactive mode.`,
4167
- "",
4168
- `Available templates in ${manifest.packageName}:`,
4169
- "",
4170
- ...lines
4171
- ];
4172
- if (filteredCount > 0) body.push("", `(omitted ${filteredCount} monorepo-only ${filteredCount === 1 ? "entry" : "entries"} because this workspace is already a monorepo)`);
4173
- body.push("", "Examples:");
4174
- if (firstVisible) body.push(" # Scaffold a specific template from the org", ` vp create ${orgSpec.scope}:${firstVisible.name} --no-interactive`, "");
4175
- body.push(" # Or use a Vite+ built-in template", " vp create vite:application --no-interactive", "");
4176
- process.stderr.write(body.join("\n"));
4177
- }
4178
- function rejectMonorepoEntryInsideMonorepo(entry, isMonorepo) {
4179
- if (entry.monorepo && isMonorepo) {
4180
- log.info("You are already in a monorepo workspace.\nUse a different template or run this command outside the monorepo");
4181
- cancelAndExit("Cannot create a monorepo inside an existing monorepo", 1);
4182
- }
4183
- }
4184
- async function resolveEntry(manifest, entry) {
4185
- if (isRelativePath(entry.template)) return {
4186
- kind: "bundled",
4187
- bundledLocalPath: resolveBundledPath(await ensureOrgPackageExtracted(manifest), entry.template),
4188
- entryName: entry.name,
4189
- scope: manifest.scope,
4190
- ...entry.monorepo === true ? { monorepo: true } : {}
4191
- };
4192
- return {
4193
- kind: "replaced",
4194
- templateName: entry.template
4195
- };
4196
- }
4197
- /**
4198
- * If `selectedTemplateName` points at an `@scope[/name]` org whose
4199
- * `@scope/create` package publishes a `createConfig.templates` manifest, apply the
4200
- * manifest rules (picker / direct lookup / escape hatch / bundled
4201
- * extraction) and report the outcome.
4202
- *
4203
- * The caller — `packages/cli/src/create/bin.ts` — decides what to do next
4204
- * based on the returned variant.
4205
- */
4206
- async function resolveOrgManifestForCreate(args) {
4207
- const orgSpec = parseOrgScopedSpec(args.templateName);
4208
- if (!orgSpec) return { kind: "passthrough" };
4209
- let manifest;
4210
- try {
4211
- manifest = await readOrgManifest(orgSpec.scope, orgSpec.version);
4212
- } catch (error) {
4213
- cancelAndExit(error instanceof OrgManifestSchemaError ? error.message : `Failed to read ${orgSpec.scope}/create manifest: ${error.message}`, 1);
4214
- }
4215
- if (!manifest) {
4216
- if (orgSpec.name !== void 0) cancelAndExit(`No \`createConfig.templates\` manifest in ${orgSpec.scope}/create — \`@org:name\` requires one.`, 1);
4217
- log.info(`No \`createConfig.templates\` manifest in ${orgSpec.scope}/create — running it as a normal package.`);
4218
- return { kind: "passthrough" };
4219
- }
4220
- if (orgSpec.name === void 0) {
4221
- if (!args.interactive) {
4222
- printNonInteractiveTable(manifest, orgSpec, args.isMonorepo);
4223
- process.exit(1);
4224
- }
4225
- const picked = await pickOrgTemplate(manifest, { isMonorepo: args.isMonorepo });
4226
- if (picked === ORG_PICKER_CANCEL) cancelAndExit();
4227
- if (picked === ORG_PICKER_BUILTIN_ESCAPE) {
4228
- if (args.isMonorepo && manifest.templates.every((t) => t.monorepo)) log.info(`No templates from ${manifest.packageName} are applicable inside a monorepo — showing Vite+ built-in templates instead.`);
4229
- return { kind: "escape-hatch" };
4230
- }
4231
- rejectMonorepoEntryInsideMonorepo(picked.entry, args.isMonorepo);
4232
- return resolveEntry(manifest, picked.entry);
4233
- }
4234
- const entry = manifest.templates.find((candidate) => candidate.name === orgSpec.name);
4235
- if (!entry) {
4236
- const available = filterManifestForContext(manifest.templates, args.isMonorepo).map((t) => t.name).join(", ");
4237
- cancelAndExit(`No template named "${orgSpec.name}" in ${manifest.packageName}. Available: ${available || "(none applicable in this context)"}.`, 1);
4238
- }
4239
- rejectMonorepoEntryInsideMonorepo(entry, args.isMonorepo);
4240
- return resolveEntry(manifest, entry);
4241
- }
4242
- /**
4243
- * Read the `create` config (`defaultTemplate` + validated `templates`) from
4244
- * a workspace's `vite.config.ts` in a single config evaluation.
4245
- *
4246
- * By default, walks up from `startDir` via `findWorkspaceRoot` (monorepo
4247
- * markers only — `pnpm-workspace.yaml`, `workspaces` in `package.json`,
4248
- * `lerna.json`) so monorepo invocations from any subdirectory still pick up
4249
- * the root config. Pass `walkUp: false` to read `startDir` directly when the
4250
- * caller already holds the exact workspace root.
4251
- *
4252
- * Best-effort for resolution: a missing or unresolvable config reads as
4253
- * empty. A present-but-malformed `create.templates` still throws a
4254
- * {@link CreateConfigSchemaError} so the misconfiguration surfaces.
4255
- *
4256
- * Pass `throwOnReadError: true` for read-modify-write callers (registration):
4257
- * if a config file exists but cannot be evaluated, an empty read would let a
4258
- * later write clobber the real `create` block, so the eval error is rethrown
4259
- * instead of swallowed.
4260
- */
4261
- async function getConfiguredCreate(startDir, options) {
4262
- const projectRoot = options?.walkUp === false ? startDir : findWorkspaceRoot(startDir) ?? startDir;
4263
- if (!hasViteConfig(projectRoot)) return { templates: [] };
4264
- let create;
4265
- try {
4266
- create = (await resolveViteConfig(projectRoot)).create;
4267
- } catch (error) {
4268
- if (options?.throwOnReadError) throw error;
4269
- return { templates: [] };
4270
- }
4271
- const defaultTemplate = typeof create?.defaultTemplate === "string" && create.defaultTemplate.length > 0 ? create.defaultTemplate : void 0;
4272
- const templates = validateCreateTemplates(create?.templates);
4273
- return {
4274
- ...defaultTemplate !== void 0 ? { defaultTemplate } : {},
4275
- templates
4276
- };
4277
- }
4278
- /**
4279
- * Read `create.defaultTemplate` only. Best-effort for missing or unresolvable
4280
- * configs (returns `undefined`), but a malformed `create.templates` still
4281
- * rethrows its {@link CreateConfigSchemaError}: swallowing it here would
4282
- * silently drop a valid `defaultTemplate` along with the diagnostic.
4283
- */
4284
- async function getConfiguredDefaultTemplate(startDir) {
4285
- try {
4286
- return (await getConfiguredCreate(startDir)).defaultTemplate;
4287
- } catch (error) {
4288
- if (error instanceof CreateConfigSchemaError) throw error;
4289
- return;
4290
- }
4291
- }
4292
- //#endregion
4293
4280
  //#region src/create/register-template.ts
4294
4281
  /**
4295
4282
  * Register a local template into `create.templates` in a monorepo's root
@@ -4325,7 +4312,7 @@ async function registerLocalTemplate(workspaceRoot, entry, silent = false) {
4325
4312
  });
4326
4313
  const existingEntry = existing.templates.find((t) => t.name === entry.name);
4327
4314
  if (existingEntry) {
4328
- if (existingEntry.template !== entry.template) log.warn(`create.templates already has an entry named '${entry.name}' pointing at '${existingEntry.template}'; left unchanged.\nUpdate it by hand if it should run '${entry.template}' instead.`);
4315
+ if (existingEntry.template !== entry.template) log$1.warn(`create.templates already has an entry named '${entry.name}' pointing at '${existingEntry.template}'; left unchanged.\nUpdate it by hand if it should run '${entry.template}' instead.`);
4329
4316
  return;
4330
4317
  }
4331
4318
  const nextCreate = {
@@ -4343,7 +4330,7 @@ async function registerLocalTemplate(workspaceRoot, entry, silent = false) {
4343
4330
  function ensureViteConfig(workspaceRoot, silent) {
4344
4331
  const configPath = path.join(workspaceRoot, "vite.config.ts");
4345
4332
  fs.writeFileSync(configPath, `import { defineConfig } from '${VITE_PLUS_NAME}';\n\nexport default defineConfig({});\n`);
4346
- if (!silent) log.success(`✔ Created vite.config.ts in ${displayRelative(configPath)}`);
4333
+ if (!silent) log$1.success(`✔ Created vite.config.ts in ${displayRelative(configPath)}`);
4347
4334
  return configPath;
4348
4335
  }
4349
4336
  /**
@@ -4371,7 +4358,7 @@ function writeCreateBlock(configPath, create) {
4371
4358
  //#endregion
4372
4359
  //#region src/create/templates/generator.ts
4373
4360
  async function executeGeneratorScaffold(workspaceInfo, templateInfo, options) {
4374
- if (!options?.silent) log.step("Creating generator scaffold...");
4361
+ if (!options?.silent) log$1.step("Creating generator scaffold...");
4375
4362
  let description;
4376
4363
  if (templateInfo.interactive) {
4377
4364
  const defaultDescription = "Generate new components for our monorepo";
@@ -4390,7 +4377,7 @@ async function executeGeneratorScaffold(workspaceInfo, templateInfo, options) {
4390
4377
  if (description) pkg.description = description;
4391
4378
  return pkg;
4392
4379
  });
4393
- if (!options?.silent) log.success("Generator scaffold created");
4380
+ if (!options?.silent) log$1.success("Generator scaffold created");
4394
4381
  return {
4395
4382
  exitCode: 0,
4396
4383
  projectDir: templateInfo.targetDir
@@ -4402,14 +4389,14 @@ var import_picocolors = /* @__PURE__ */ __toESM(require_picocolors(), 1);
4402
4389
  const { gray, yellow } = import_picocolors.default;
4403
4390
  async function executeRemoteTemplate(workspaceInfo, templateInfo, options) {
4404
4391
  const silent = options?.silent ?? false;
4405
- if (!silent) log.step("Generating project…");
4392
+ if (!silent) log$1.step("Generating project…");
4406
4393
  let isGitHubTemplate = templateInfo.command === "degit";
4407
4394
  let result;
4408
4395
  if (templateInfo.command === "node") {
4409
4396
  const command = templateInfo.command;
4410
4397
  const args = templateInfo.args;
4411
4398
  const envs = templateInfo.envs;
4412
- if (!silent) log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
4399
+ if (!silent) log$1.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
4413
4400
  result = await runCommandAndDetectProjectDir({
4414
4401
  command,
4415
4402
  args,
@@ -4419,7 +4406,7 @@ async function executeRemoteTemplate(workspaceInfo, templateInfo, options) {
4419
4406
  } else {
4420
4407
  if (!isGitHubTemplate) {
4421
4408
  if (!await checkNpmPackageExists(templateInfo.command)) {
4422
- if (!silent) log.error(`Template "${templateInfo.command}" not found on npm. Run ${yellow("vp create --list")} to see available templates.`);
4409
+ if (!silent) log$1.error(`Template "${templateInfo.command}" not found on npm. Run ${yellow("vp create --list")} to see available templates.`);
4423
4410
  return { exitCode: 1 };
4424
4411
  }
4425
4412
  }
@@ -4427,13 +4414,13 @@ async function executeRemoteTemplate(workspaceInfo, templateInfo, options) {
4427
4414
  }
4428
4415
  const exitCode = result.exitCode;
4429
4416
  if (exitCode === 127) {
4430
- log.info(yellow("\nTroubleshooting:"));
4431
- log.info(` ${gray("•")} Command not found. Make sure Node.js is installed`);
4417
+ log$1.info(yellow("\nTroubleshooting:"));
4418
+ log$1.info(` ${gray("•")} Command not found. Make sure Node.js is installed`);
4432
4419
  } else if (isGitHubTemplate && exitCode !== 0) {
4433
- log.info(yellow("\nTroubleshooting:"));
4434
- log.info(` ${gray("•")} Make sure the GitHub repository exists`);
4435
- log.info(` ${gray("•")} Check your internet connection`);
4436
- log.info(` ${gray("•")} Repository might be private (requires authentication)`);
4420
+ log$1.info(yellow("\nTroubleshooting:"));
4421
+ log$1.info(` ${gray("•")} Make sure the GitHub repository exists`);
4422
+ log$1.info(` ${gray("•")} Check your internet connection`);
4423
+ log$1.info(` ${gray("•")} Repository might be private (requires authentication)`);
4437
4424
  }
4438
4425
  return result;
4439
4426
  }
@@ -4443,7 +4430,7 @@ async function runRemoteTemplateCommand(workspaceInfo, cwd, templateInfo, detect
4443
4430
  const execArgs = [...templateInfo.args];
4444
4431
  const envs = templateInfo.envs;
4445
4432
  const { command, args } = formatDlxCommand(remotePackageName, execArgs, workspaceInfo);
4446
- if (!silent) log.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
4433
+ if (!silent) log$1.info(`Running: ${gray(`${command} ${args.join(" ")}`)}`);
4447
4434
  if (detectCreatedProjectDir) return await runCommandAndDetectProjectDir({
4448
4435
  command,
4449
4436
  args,
@@ -4504,7 +4491,7 @@ async function executeBuiltinTemplate(workspaceInfo, templateInfo, options) {
4504
4491
  };
4505
4492
  }
4506
4493
  if (templateInfo.command.startsWith("vite:")) {
4507
- if (!options?.silent) log.error(`Unknown builtin template "${templateInfo.command}". Run ${import_picocolors.default.yellow("vp create --list")} to see available templates.`);
4494
+ if (!options?.silent) log$1.error(`Unknown builtin template "${templateInfo.command}". Run ${import_picocolors.default.yellow("vp create --list")} to see available templates.`);
4508
4495
  return { exitCode: 1 };
4509
4496
  }
4510
4497
  const result = await runRemoteTemplateCommand(workspaceInfo, workspaceInfo.rootDir, templateInfo, false, options?.silent ?? false);
@@ -4550,8 +4537,8 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, options) {
4550
4537
  workspaceInfo.monorepoScope = getScopeFromPackageName(templateInfo.packageName);
4551
4538
  const fullPath = path.join(workspaceInfo.rootDir, templateInfo.targetDir);
4552
4539
  if (!options?.silent) {
4553
- log.info(`Target directory: ${formatDisplayTargetDir(templateInfo.targetDir)}`);
4554
- log.step("Creating Vite+ monorepo...");
4540
+ log$1.info(`Target directory: ${formatDisplayTargetDir(templateInfo.targetDir)}`);
4541
+ log$1.step("Creating Vite+ monorepo...");
4555
4542
  }
4556
4543
  copyDir(path.join(templatesDir, "monorepo"), fullPath);
4557
4544
  renameFiles(fullPath);
@@ -4584,8 +4571,8 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, options) {
4584
4571
  const yarnrcPath = path.join(fullPath, ".yarnrc.yml");
4585
4572
  if (fs.existsSync(yarnrcPath)) fs.unlinkSync(yarnrcPath);
4586
4573
  }
4587
- if (!options?.silent) log.success("Monorepo template created");
4588
- if (!options?.silent) log.step("Creating default application in apps/website...");
4574
+ if (!options?.silent) log$1.success("Monorepo template created");
4575
+ if (!options?.silent) log$1.step("Creating default application in apps/website...");
4589
4576
  const appResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, discoverTemplate("create-vite@latest", [
4590
4577
  InitialMonorepoAppDir,
4591
4578
  "--template",
@@ -4593,7 +4580,7 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, options) {
4593
4580
  "--no-interactive"
4594
4581
  ], workspaceInfo), false, options?.silent ?? false);
4595
4582
  if (appResult.exitCode !== 0) {
4596
- log.error(`Failed to create default application: ${appResult.exitCode}`);
4583
+ log$1.error(`Failed to create default application: ${appResult.exitCode}`);
4597
4584
  return appResult;
4598
4585
  }
4599
4586
  const appPackageName = workspaceInfo.monorepoScope ? `${workspaceInfo.monorepoScope}/website` : "website";
@@ -4601,11 +4588,11 @@ async function executeMonorepoTemplate(workspaceInfo, templateInfo, options) {
4601
4588
  setPackageName(appProjectPath, appPackageName);
4602
4589
  rewriteMonorepoProject(appProjectPath, workspaceInfo.packageManager, void 0, options?.silent ?? false);
4603
4590
  dropAliasedRuntimeDevDeps(appProjectPath, workspaceInfo.packageManager);
4604
- if (!options?.silent) log.step("Creating default library in packages/utils...");
4591
+ if (!options?.silent) log$1.step("Creating default library in packages/utils...");
4605
4592
  const libraryDir = "packages/utils";
4606
4593
  const libraryResult = await runRemoteTemplateCommand(workspaceInfo, fullPath, discoverTemplate(LibraryTemplateRepo, [libraryDir], workspaceInfo), false, options?.silent ?? false);
4607
4594
  if (libraryResult.exitCode !== 0) {
4608
- log.error(`Failed to create default library, exit code: ${libraryResult.exitCode}`);
4595
+ log$1.error(`Failed to create default library, exit code: ${libraryResult.exitCode}`);
4609
4596
  return libraryResult;
4610
4597
  }
4611
4598
  const libraryPackageName = workspaceInfo.monorepoScope ? `${workspaceInfo.monorepoScope}/utils` : "utils";
@@ -4674,10 +4661,6 @@ function dropAliasedRuntimeDevDeps(appProjectPath, packageManager) {
4674
4661
  return changed ? pkg : void 0;
4675
4662
  });
4676
4663
  }
4677
- function getScopeFromPackageName(packageName) {
4678
- if (packageName.startsWith("@")) return packageName.split("/")[0];
4679
- return "";
4680
- }
4681
4664
  //#endregion
4682
4665
  //#region src/create/bin.ts
4683
4666
  const helpMessage = renderCliDoc({
@@ -4958,42 +4941,27 @@ function formatTemplateName(templateName) {
4958
4941
  const baseName = isTypeScript ? templateName.slice(0, -3) : templateName;
4959
4942
  return `${templateAliases[baseName] ?? baseName.split(/[-_]/).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join(" ")} + ${isTypeScript ? "TypeScript" : "JavaScript"}`;
4960
4943
  }
4961
- function formatDuration(durationMs) {
4962
- if (durationMs < 1e3) return `${Math.max(1, durationMs)}ms`;
4963
- const durationSeconds = durationMs / 1e3;
4964
- if (durationSeconds < 10) return `${durationSeconds.toFixed(1)}s`;
4965
- return `${Math.round(durationSeconds)}s`;
4966
- }
4967
4944
  function getNextCommand(projectDir, command) {
4968
4945
  if (!projectDir || projectDir === ".") return command;
4969
4946
  return `cd ${projectDir} && ${command}`;
4970
4947
  }
4971
- function findGitRoot(startPath) {
4972
- let dir = startPath;
4973
- while (true) {
4974
- if (fs.existsSync(path.join(dir, ".git"))) return dir;
4975
- const parent = path.dirname(dir);
4976
- if (parent === dir) return;
4977
- dir = parent;
4978
- }
4979
- }
4980
4948
  function getCopilotSetupRoot(projectRoot, isExistingMonorepo) {
4981
4949
  if (!isExistingMonorepo) return projectRoot;
4982
4950
  return findGitRoot(projectRoot) ?? projectRoot;
4983
4951
  }
4984
4952
  function showCreateSummary(options) {
4985
4953
  const { description, installSummary, nextCommand, packageManager, packageManagerVersion, projectDir } = options;
4986
- log$1(`${styleText("magenta", "◇")} Scaffolded ${accent(projectDir)}${description ? ` with ${description}` : ""}`);
4987
- log$1(`${styleText("gray", "•")} Node ${process.versions.node} ${packageManager} ${packageManagerVersion}`);
4988
- if (installSummary?.status === "installed") log$1(`${styleText("green", "✓")} Dependencies installed in ${formatDuration(installSummary.durationMs)}`);
4989
- log$1(`${styleText("blue", "→")} Next: ${accent(nextCommand)}`);
4954
+ log(`${styleText("magenta", "◇")} Scaffolded ${accent(projectDir)}${description ? ` with ${description}` : ""}`);
4955
+ log(`${styleText("gray", "•")} Node ${process.versions.node} ${packageManager} ${packageManagerVersion}`);
4956
+ if (installSummary?.status === "installed") log(`${styleText("green", "✓")} Dependencies installed in ${formatDuration(installSummary.durationMs)}`);
4957
+ log(`${styleText("blue", "→")} Next: ${accent(nextCommand)}`);
4990
4958
  }
4991
4959
  async function main() {
4992
4960
  const { templateName, options, templateArgs } = parseArgs();
4993
4961
  let compactOutput = !options.verbose;
4994
4962
  if (options.help) {
4995
4963
  printHeader();
4996
- log$1(helpMessage);
4964
+ log(helpMessage);
4997
4965
  return;
4998
4966
  }
4999
4967
  if (options.list) {
@@ -5006,7 +4974,7 @@ async function main() {
5006
4974
  if (options.directory) {
5007
4975
  const formatted = formatTargetDir(options.directory);
5008
4976
  if (formatted.error) {
5009
- log.error(formatted.error);
4977
+ log$1.error(formatted.error);
5010
4978
  cancelAndExit("The --directory option is invalid", 1);
5011
4979
  }
5012
4980
  targetDir = formatted.directory;
@@ -5039,7 +5007,7 @@ async function main() {
5039
5007
  if (!selectedTemplateName && configuredCreate.defaultTemplate) selectedTemplateName = configuredCreate.defaultTemplate;
5040
5008
  } catch (error) {
5041
5009
  if (error instanceof CreateConfigSchemaError) cancelAndExit(error.message, 1);
5042
- log.warn(`Could not read \`create\` config from the workspace vite.config (${error.message}); local templates are unavailable`);
5010
+ log$1.warn(`Could not read \`create\` config from the workspace vite.config (${error.message}); local templates are unavailable`);
5043
5011
  }
5044
5012
  else if (!selectedTemplateName) {
5045
5013
  let defaultTemplate;
@@ -5102,15 +5070,15 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5102
5070
  if (!isDirectScaffoldTemplate) compactOutput = false;
5103
5071
  if (targetDir && !isDirectScaffoldTemplate) cancelAndExit("The --directory option is only available for builtin and bundled @org templates", 1);
5104
5072
  if (selectedTemplateName === BuiltinTemplate.monorepo && isMonorepo) {
5105
- log.info("You are already in a monorepo workspace.\nUse a different template or run this command outside the monorepo");
5073
+ log$1.info("You are already in a monorepo workspace.\nUse a different template or run this command outside the monorepo");
5106
5074
  cancelAndExit("Cannot create a monorepo inside an existing monorepo", 1);
5107
5075
  }
5108
5076
  if (selectedTemplateName === BuiltinTemplate.generator && !isMonorepo) {
5109
- log.info("The vite:generator template requires a monorepo workspace.\nRun this command inside a Vite+ monorepo, or create one first with `vp create vite:monorepo`");
5077
+ log$1.info("The vite:generator template requires a monorepo workspace.\nRun this command inside a Vite+ monorepo, or create one first with `vp create vite:monorepo`");
5110
5078
  cancelAndExit("Cannot create a generator outside a monorepo", 1);
5111
5079
  }
5112
5080
  if (isMonorepo && options.git !== void 0) cancelAndExit("The --git/--no-git options are not available when adding a package to an existing monorepo", 1);
5113
- if (isInSubdirectory && !compactOutput) log.info(`Detected monorepo root at ${accent(workspaceInfoOptional.rootDir)}`);
5081
+ if (isInSubdirectory && !compactOutput) log$1.info(`Detected monorepo root at ${accent(workspaceInfoOptional.rootDir)}`);
5114
5082
  if (isMonorepo && options.interactive && !targetDir) {
5115
5083
  let parentDir;
5116
5084
  if (workspaceInfoOptional.parentDirs.length > 0 || isInSubdirectory) {
@@ -5129,10 +5097,11 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5129
5097
  value: "other",
5130
5098
  hint: "Enter a custom target directory"
5131
5099
  });
5100
+ const defaultParentDir = shouldOfferCwdOption ? cwdRelativeToRoot : inferParentDir(selectedTemplateName, workspaceInfoOptional, isLocalTemplate) ?? workspaceInfoOptional.parentDirs[0];
5132
5101
  const selected = await select({
5133
5102
  message: "Where should the new package be added to the monorepo:",
5134
5103
  options: dirOptions,
5135
- initialValue: shouldOfferCwdOption ? cwdRelativeToRoot : inferParentDir(selectedTemplateName, workspaceInfoOptional, isLocalTemplate) ?? workspaceInfoOptional.parentDirs[0]
5104
+ initialValue: defaultParentDir
5136
5105
  });
5137
5106
  if (isCancel(selected)) cancelAndExit();
5138
5107
  if (selected !== "other") parentDir = selected;
@@ -5151,48 +5120,55 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5151
5120
  selectedParentDir = parentDir;
5152
5121
  }
5153
5122
  if (isMonorepo && !options.interactive && !targetDir) {
5154
- if (isInSubdirectory && !compactOutput) log.info(`Use ${accent("--directory")} to specify a different target location.`);
5123
+ if (isInSubdirectory && !compactOutput) log$1.info(`Use ${accent("--directory")} to specify a different target location.`);
5155
5124
  selectedParentDir = inferParentDir(selectedTemplateName, workspaceInfoOptional, isLocalTemplate) ?? workspaceInfoOptional.parentDirs[0];
5156
5125
  }
5157
- if (isGitHubUrl(selectedTemplateName)) if (hasExplicitTargetDir(selectedTemplateArgs)) remoteTargetDir = selectedTemplateArgs[0];
5158
- else {
5159
- const inferredTargetDir = inferGitHubRepoName(selectedTemplateName) ?? "template";
5160
- const remoteTargetBaseDir = selectedParentDir ? path.join(workspaceInfoOptional.rootDir, selectedParentDir) : workspaceInfoOptional.rootDir;
5161
- const defaultTargetDir = suggestAvailableTargetDir(inferredTargetDir, remoteTargetBaseDir);
5162
- if (defaultTargetDir !== inferredTargetDir && options.interactive) log.info(` Target directory "${inferredTargetDir}" already exists. Suggested: ${accent(defaultTargetDir)}`);
5163
- remoteTargetDir = await promptTargetDir(defaultTargetDir, options.interactive, { cwd: remoteTargetBaseDir });
5164
- selectedTemplateArgs = [remoteTargetDir, ...selectedTemplateArgs];
5126
+ if (isGitHubUrl(selectedTemplateName)) {
5127
+ if (hasExplicitTargetDir(selectedTemplateArgs)) remoteTargetDir = selectedTemplateArgs[0];
5128
+ else {
5129
+ const inferredTargetDir = inferGitHubRepoName(selectedTemplateName) ?? "template";
5130
+ const remoteTargetBaseDir = selectedParentDir ? path.join(workspaceInfoOptional.rootDir, selectedParentDir) : workspaceInfoOptional.rootDir;
5131
+ const defaultTargetDir = suggestAvailableTargetDir(inferredTargetDir, remoteTargetBaseDir);
5132
+ if (defaultTargetDir !== inferredTargetDir && options.interactive) log$1.info(` Target directory "${inferredTargetDir}" already exists. Suggested: ${accent(defaultTargetDir)}`);
5133
+ remoteTargetDir = await promptTargetDir(defaultTargetDir, options.interactive, { cwd: remoteTargetBaseDir });
5134
+ selectedTemplateArgs = [remoteTargetDir, ...selectedTemplateArgs];
5135
+ }
5165
5136
  }
5166
5137
  const directScaffoldFallbackName = bundled ? `vite-plus-${bundled.entryName}` : selectedTemplateName === BuiltinTemplate.monorepo ? "vite-plus-monorepo" : `vite-plus-${selectedTemplateName.split(":")[1]}`;
5167
- if (isDirectScaffoldTemplate && (!targetDir || targetDir === ".")) if (targetDir === ".") {
5168
- packageName = deriveDefaultPackageName(cwd, workspaceInfoOptional.monorepoScope, directScaffoldFallbackName);
5169
- if (isMonorepo) {
5170
- if (!cwdRelativeToRoot) cancelAndExit("Cannot scaffold into the monorepo root directory. Use --directory to specify a target directory", 1);
5171
- const enclosingPackage = workspaceInfoOptional.packages.find((pkg) => cwdRelativeToRoot === pkg.path || cwdRelativeToRoot.startsWith(`${pkg.path}/`));
5172
- if (enclosingPackage) cancelAndExit(`Cannot scaffold inside existing package "${enclosingPackage.name}" (${enclosingPackage.path}). Use --directory to specify a different location`, 1);
5173
- targetDir = cwdRelativeToRoot;
5138
+ if (isDirectScaffoldTemplate && (!targetDir || targetDir === ".")) {
5139
+ if (targetDir === ".") {
5140
+ packageName = deriveDefaultPackageName(cwd, workspaceInfoOptional.monorepoScope, directScaffoldFallbackName);
5141
+ if (isMonorepo) {
5142
+ if (!cwdRelativeToRoot) cancelAndExit("Cannot scaffold into the monorepo root directory. Use --directory to specify a target directory", 1);
5143
+ const enclosingPackage = workspaceInfoOptional.packages.find((pkg) => cwdRelativeToRoot === pkg.path || cwdRelativeToRoot.startsWith(`${pkg.path}/`));
5144
+ if (enclosingPackage) cancelAndExit(`Cannot scaffold inside existing package "${enclosingPackage.name}" (${enclosingPackage.path}). Use --directory to specify a different location`, 1);
5145
+ targetDir = cwdRelativeToRoot;
5146
+ }
5147
+ log$1.info(`Using package name: ${accent(packageName)}`);
5148
+ } else if (selectedTemplateName === BuiltinTemplate.monorepo) {
5149
+ const selected = await promptPackageNameAndTargetDir(getRandomProjectName({ fallbackName: "vite-plus-monorepo" }), options.interactive);
5150
+ packageName = selected.packageName;
5151
+ targetDir = selected.targetDir;
5152
+ } else {
5153
+ const selected = await promptPackageNameAndTargetDir(getRandomProjectName({
5154
+ scope: workspaceInfoOptional.monorepoScope,
5155
+ fallbackName: directScaffoldFallbackName
5156
+ }), options.interactive);
5157
+ packageName = selected.packageName;
5158
+ targetDir = selectedParentDir ? path.join(selectedParentDir, selected.targetDir).split(path.sep).join("/") : selected.targetDir;
5174
5159
  }
5175
- log.info(`Using package name: ${accent(packageName)}`);
5176
- } else if (selectedTemplateName === BuiltinTemplate.monorepo) {
5177
- const selected = await promptPackageNameAndTargetDir(getRandomProjectName({ fallbackName: "vite-plus-monorepo" }), options.interactive);
5178
- packageName = selected.packageName;
5179
- targetDir = selected.targetDir;
5180
- } else {
5181
- const selected = await promptPackageNameAndTargetDir(getRandomProjectName({
5182
- scope: workspaceInfoOptional.monorepoScope,
5183
- fallbackName: directScaffoldFallbackName
5184
- }), options.interactive);
5185
- packageName = selected.packageName;
5186
- targetDir = selectedParentDir ? path.join(selectedParentDir, selected.targetDir).split(path.sep).join("/") : selected.targetDir;
5187
5160
  }
5188
5161
  if (options.packageManager && !Object.values(PackageManager).includes(options.packageManager)) {
5189
5162
  const valid = Object.values(PackageManager).join(", ");
5190
- log.error(`Invalid package manager: ${options.packageManager}. Must be one of: ${valid}`);
5163
+ log$1.error(`Invalid package manager: ${options.packageManager}. Must be one of: ${valid}`);
5191
5164
  cancelAndExit("Invalid --package-manager value", 1);
5192
5165
  }
5193
- const packageManager = workspaceInfoOptional.packageManager ?? options.packageManager ?? await selectPackageManager(options.interactive, compactOutput);
5166
+ const requestedPackageManager = options.packageManager;
5167
+ const detectedPackageManager = workspaceInfoOptional.packageManager;
5168
+ const packageManager = (isMonorepo ? detectedPackageManager ?? requestedPackageManager : requestedPackageManager ?? detectedPackageManager) ?? await selectPackageManager(options.interactive, compactOutput);
5169
+ const packageManagerVersion = packageManager === detectedPackageManager ? workspaceInfoOptional.packageManagerVersion : "latest";
5194
5170
  const shouldSilencePackageManagerInstallLog = compactOutput || isMonorepo && workspaceInfoOptional.packageManager !== void 0;
5195
- const downloadResult = await downloadPackageManager$1(packageManager, workspaceInfoOptional.packageManagerVersion, options.interactive, shouldSilencePackageManagerInstallLog);
5171
+ const downloadResult = await downloadPackageManager$1(packageManager, packageManagerVersion, options.interactive, shouldSilencePackageManagerInstallLog);
5196
5172
  const workspaceInfo = {
5197
5173
  ...workspaceInfoOptional,
5198
5174
  packageManager,
@@ -5261,7 +5237,8 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5261
5237
  const handleIgnoredBuilds = async (projectPath, installCwd, summary) => {
5262
5238
  if (summary?.status !== "installed") return;
5263
5239
  const reportedBuilds = [.../* @__PURE__ */ new Set([...summary.pendingBuilds ?? [], ...migratePendingBuilds])];
5264
- const targets = resolveApproveBuildTargets(projectPath, await detectGatedBuilds(installCwd, workspaceInfo.packageManager, reportedBuilds), workspaceInfo.packageManager);
5240
+ const pendingBuilds = await detectGatedBuilds(installCwd, workspaceInfo.packageManager, reportedBuilds);
5241
+ const targets = resolveApproveBuildTargets(projectPath, pendingBuilds, workspaceInfo.packageManager);
5265
5242
  if (targets.length === 0) return;
5266
5243
  pauseCreateProgress();
5267
5244
  const approved = await approveBuilds({
@@ -5297,10 +5274,10 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5297
5274
  });
5298
5275
  resumeCreateProgress();
5299
5276
  if (isCancel(selected)) {
5300
- log.info("Operation cancelled. Skipping git initialization");
5277
+ log$1.info("Operation cancelled. Skipping git initialization");
5301
5278
  shouldInitGit = false;
5302
5279
  } else shouldInitGit = selected;
5303
- } else if (shouldInitGit && !compactOutput) log.info("Initializing git repository (default: yes)");
5280
+ } else if (shouldInitGit && !compactOutput) log$1.info("Initializing git repository (default: yes)");
5304
5281
  updateCreateProgress("Creating monorepo");
5305
5282
  await checkProjectDirExists(path.join(workspaceInfo.rootDir, targetDir), options.interactive);
5306
5283
  const result = isBundledMonorepo ? await executeBundledTemplate(workspaceInfo, {
@@ -5318,17 +5295,22 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5318
5295
  cancelAndExit(`Failed to create monorepo, exit code: ${result.exitCode}`, result.exitCode);
5319
5296
  }
5320
5297
  const fullPath = path.join(workspaceInfo.rootDir, projectDir);
5298
+ const scaffoldedWorkspace = await detectWorkspace$1(fullPath);
5299
+ workspaceInfo.isMonorepo = true;
5300
+ workspaceInfo.workspacePatterns = scaffoldedWorkspace.workspacePatterns;
5301
+ workspaceInfo.parentDirs = scaffoldedWorkspace.parentDirs;
5302
+ workspaceInfo.packages = scaffoldedWorkspace.packages;
5321
5303
  if (shouldInitGit) {
5322
5304
  const gitResult = import_cross_spawn.default.sync("git", ["init"], {
5323
5305
  stdio: "pipe",
5324
5306
  cwd: fullPath
5325
5307
  });
5326
5308
  if (gitResult.status === 0) {
5327
- if (!compactOutput) log.success("Git repository initialized");
5309
+ if (!compactOutput) log$1.success("Git repository initialized");
5328
5310
  ensureDefaultGitignoreEntries(fullPath);
5329
5311
  } else {
5330
- log.warn("Failed to initialize git repository");
5331
- if (gitResult.stderr) log.info(gitResult.stderr.toString());
5312
+ log$1.warn("Failed to initialize git repository");
5313
+ if (gitResult.stderr) log$1.info(gitResult.stderr.toString());
5332
5314
  }
5333
5315
  }
5334
5316
  updateCreateProgress("Writing agent instructions");
@@ -5351,19 +5333,21 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5351
5333
  editorId: selectedEditors,
5352
5334
  interactive: options.interactive,
5353
5335
  silent: compactOutput,
5354
- extraVsCodeSettings: { "npm.scriptRunner": "vp" }
5336
+ extraVsCodeSettings: { "npm.scriptRunner": "vp" },
5337
+ packageManager
5355
5338
  });
5356
5339
  if (selectedEditors?.includes("vscode")) ensureGitignoreVsCodeEditorConfigs(fullPath);
5357
5340
  resumeCreateProgress();
5358
5341
  workspaceInfo.rootDir = fullPath;
5359
5342
  updateCreateProgress("Integrating monorepo");
5360
- rewriteMonorepo(workspaceInfo, void 0, compactOutput);
5343
+ const skipStagedMigration = shouldSkipStagedMigrationForHooks(fullPath, shouldSetupHooks, workspaceInfo.packageManager, workspaceInfo.packages);
5344
+ rewriteMonorepo(workspaceInfo, skipStagedMigration, compactOutput);
5361
5345
  if (shouldSetupGit) {
5362
5346
  updateCreateProgress("Initializing git repository");
5363
5347
  if (await initGitRepository(fullPath)) ensureDefaultGitignoreEntries(fullPath);
5364
5348
  }
5365
5349
  if (bundled?.monorepo) injectCreateDefaultTemplate(fullPath, bundled.scope, compactOutput);
5366
- if (shouldSetupHooks) installGitHooks(fullPath, compactOutput, void 0, workspaceInfo.packageManager);
5350
+ if (shouldSetupHooks) installGitHooks(fullPath, compactOutput, void 0, workspaceInfo.packageManager, workspaceInfo.packages);
5367
5351
  updateCreateProgress("Installing dependencies");
5368
5352
  const installSummary = await runViteInstall(fullPath, options.interactive, installArgs, {
5369
5353
  silent: compactOutput,
@@ -5442,7 +5426,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5442
5426
  template: generatorTemplatePath
5443
5427
  }, compactOutput);
5444
5428
  } catch (error) {
5445
- log.warn(`Could not register the generator in create.templates (${error.message}).\nAdd it by hand: { name: '${generatorName || path.basename(projectDir)}', template: '${generatorTemplatePath}' }`);
5429
+ log$1.warn(`Could not register the generator in create.templates (${error.message}).\nAdd it by hand: { name: '${generatorName || path.basename(projectDir)}', template: '${generatorTemplatePath}' }`);
5446
5430
  }
5447
5431
  resumeCreateProgress();
5448
5432
  }
@@ -5468,7 +5452,8 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5468
5452
  editorId: selectedEditors,
5469
5453
  interactive: options.interactive,
5470
5454
  silent: compactOutput,
5471
- extraVsCodeSettings: { "npm.scriptRunner": "vp" }
5455
+ extraVsCodeSettings: { "npm.scriptRunner": "vp" },
5456
+ packageManager
5472
5457
  });
5473
5458
  if (selectedEditors?.includes("vscode")) ensureGitignoreVsCodeEditorConfigs(fullPath);
5474
5459
  resumeCreateProgress();
@@ -5497,7 +5482,7 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5497
5482
  resumeCreateProgress();
5498
5483
  };
5499
5484
  if (isMonorepo) {
5500
- if (!compactOutput) log.step("Monorepo integration...");
5485
+ if (!compactOutput) log$1.step("Monorepo integration...");
5501
5486
  if (workspaceInfo.packages.length > 0) {
5502
5487
  if (options.interactive) {
5503
5488
  pauseCreateProgress();
@@ -5532,7 +5517,8 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5532
5517
  updateWorkspaceConfig(projectDir, workspaceInfo);
5533
5518
  if (shouldMigrateLintFmtTools) await installAndMigrate(workspaceInfo.rootDir);
5534
5519
  updateCreateProgress("Integrating into monorepo");
5535
- rewriteMonorepoProject(fullPath, workspaceInfo.packageManager, void 0, compactOutput);
5520
+ const skipStagedMigration = shouldSkipStagedMigrationForHooks(fullPath, shouldSetupHooks, workspaceInfo.packageManager);
5521
+ rewriteMonorepoProject(fullPath, workspaceInfo.packageManager, skipStagedMigration, compactOutput);
5536
5522
  for (const framework of detectFramework(fullPath)) if (!hasFrameworkShim(fullPath, framework)) addFrameworkShim(fullPath, framework);
5537
5523
  updateCreateProgress("Installing dependencies");
5538
5524
  installSummary = await runViteInstall(workspaceInfo.rootDir, options.interactive, installArgs, {
@@ -5546,14 +5532,15 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5546
5532
  const fmtPaths = registeredConfigPath ? [projectDir, path.relative(workspaceInfo.rootDir, registeredConfigPath)] : [projectDir];
5547
5533
  await runViteFmt(workspaceInfo.rootDir, options.interactive, fmtPaths, { silent: compactOutput });
5548
5534
  } else {
5549
- if (shouldMigrateLintFmtTools) await installAndMigrate(fullPath);
5550
- updateCreateProgress("Applying Vite+ project setup");
5551
- rewriteStandaloneProject(fullPath, workspaceInfo, void 0, compactOutput);
5552
- for (const framework of detectFramework(fullPath)) if (!hasFrameworkShim(fullPath, framework)) addFrameworkShim(fullPath, framework);
5553
5535
  if (shouldSetupGit) {
5554
5536
  updateCreateProgress("Initializing git repository");
5555
5537
  if (await initGitRepository(fullPath)) ensureDefaultGitignoreEntries(fullPath);
5556
5538
  }
5539
+ if (shouldMigrateLintFmtTools) await installAndMigrate(fullPath);
5540
+ updateCreateProgress("Applying Vite+ project setup");
5541
+ const skipStagedMigration = shouldSkipStagedMigrationForHooks(fullPath, shouldSetupHooks, workspaceInfo.packageManager);
5542
+ rewriteStandaloneProject(fullPath, workspaceInfo, skipStagedMigration, compactOutput);
5543
+ for (const framework of detectFramework(fullPath)) if (!hasFrameworkShim(fullPath, framework)) addFrameworkShim(fullPath, framework);
5557
5544
  if (shouldSetupHooks) installGitHooks(fullPath, compactOutput, void 0, workspaceInfo.packageManager);
5558
5545
  updateCreateProgress("Installing dependencies");
5559
5546
  installSummary = await runViteInstall(fullPath, options.interactive, installArgs, {
@@ -5578,10 +5565,10 @@ Use \`vp create --list\` to list all available templates, or run \`vp create --h
5578
5565
  }
5579
5566
  async function showAvailableTemplates() {
5580
5567
  printHeader();
5581
- log$1(listTemplatesMessage);
5568
+ log(listTemplatesMessage);
5582
5569
  }
5583
5570
  main().catch((err) => {
5584
- log.error(err.message);
5571
+ log$1.error(err.message);
5585
5572
  console.error(err);
5586
5573
  cancelAndExit(`Failed to generate code: ${err.message}`, 1);
5587
5574
  });