create-krispya 0.13.0 → 0.14.0

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.
@@ -3,189 +3,32 @@
3
3
  const promises = require('fs/promises');
4
4
  const fs = require('fs');
5
5
  const path = require('path');
6
+ const Conf = require('conf');
6
7
  const color = require('chalk');
7
8
 
8
9
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
9
10
 
11
+ const Conf__default = /*#__PURE__*/_interopDefaultCompat(Conf);
10
12
  const color__default = /*#__PURE__*/_interopDefaultCompat(color);
11
13
 
12
- const gitAttributesContent = [
13
- "* text eol=lf",
14
- "*.png binary",
15
- "*.jpg binary",
16
- "*.jpeg binary",
17
- "*.gif binary",
18
- "*.ico binary",
19
- "*.mov binary",
20
- "*.mp4 binary",
21
- "*.mp3 binary",
22
- "*.flv binary",
23
- "*.fla binary",
24
- "*.wav binary",
25
- "*.swf binary",
26
- "*.gz binary",
27
- "*.zip binary",
28
- "*.7z binary",
29
- "*.ttf binary",
30
- "*.eot binary",
31
- "*.woff binary",
32
- "*.pyc binary",
33
- "*.pdf binary",
34
- "*.glb binary",
35
- "*.gltf binary"
36
- ].join("\n");
37
-
38
- const ALL_AI_PLATFORMS = ["agents", "claude"];
39
- const AI_PLATFORM_LABELS = {
40
- agents: "AGENTS.md",
41
- claude: "CLAUDE.md"
42
- };
43
- const AI_PLATFORM_HINTS = {
44
- agents: "OpenAI, Cursor, Windsurf, etc.",
45
- claude: "Claude Code"
46
- };
47
- function renderAiFiles(files, params) {
48
- const { platforms, isMonorepo, configStrategy, hasTypecheck, ...rest } = params;
49
- if (platforms.length === 0) return;
50
- const content = generateWorkspace({
51
- ...rest,
52
- isMonorepo: !!isMonorepo,
53
- configStrategy: configStrategy ?? "stealth",
54
- hasTypecheck: hasTypecheck ?? false
55
- });
56
- const pointer = "See [`AGENTS.md`](./Agents.md) for agent context.\n";
57
- const hasAgents = platforms.includes("agents");
58
- const hasClaude = platforms.includes("claude");
59
- const isSingleton = platforms.length === 1;
60
- if (hasAgents) files["AGENTS.md"] = { type: "text", content };
61
- if (hasClaude) {
62
- if (isSingleton) {
63
- files["CLAUDE.md"] = { type: "text", content };
64
- } else {
65
- files["CLAUDE.md"] = { type: "text", content: pointer };
66
- }
67
- }
14
+ const PACKAGE_MANAGER_NAMES = /* @__PURE__ */ new Set(["pnpm", "npm", "yarn"]);
15
+ function isPackageManagerName(value) {
16
+ return PACKAGE_MANAGER_NAMES.has(value);
68
17
  }
69
- function generateWorkspace(ctx) {
70
- const { packageManager, linter, formatter, hasTypecheck } = ctx;
71
- const exampleFiles = "src/App.tsx src/core/systems/move-entity.ts";
72
- const commands = getAfterEditingCommands(ctx, exampleFiles);
73
- const sections = [
74
- "# Workspace Tools",
75
- "",
76
- `- **Package Manager:** ${packageManager}`,
77
- `- **Linter:** ${linter}`,
78
- `- **Formatter:** ${formatter}`,
79
- "",
80
- "## After Editing",
81
- ""
82
- ];
83
- if (hasTypecheck) {
84
- sections.push(
85
- "\u2705 After editing files, check the types for errors and then format and lint only the files changed for the current task."
86
- );
87
- } else {
88
- sections.push(
89
- "\u2705 After editing files, format and lint only the files changed for the current task."
90
- );
91
- }
92
- sections.push("", "```sh", "# Example");
93
- if (hasTypecheck) {
94
- sections.push(runScript(packageManager, "typecheck"));
95
- }
96
- sections.push(
97
- "# Run format and lint for only files modified",
98
- commands.format,
99
- commands.lint,
100
- "```",
101
- "",
102
- "\u274C Avoid unless explicitly approved:",
103
- "",
104
- "```sh",
105
- runScript(packageManager, "format"),
106
- runScript(packageManager, "lint"),
107
- "```",
108
- ""
109
- );
110
- return sections.join("\n");
111
- }
112
- function getAfterEditingCommands(ctx, files) {
113
- return {
114
- format: getFormatChangedFilesCommand(ctx, files),
115
- lint: getLintChangedFilesCommand(ctx, files)
116
- };
117
- }
118
- function getFormatChangedFilesCommand(ctx, files) {
119
- const exec = getExecCommand(ctx.packageManager);
120
- if (ctx.formatter === "prettier") {
121
- const configPath = getPrettierConfigPath(ctx);
122
- const ignorePath = getPrettierIgnorePath(ctx);
123
- const configFlag2 = configPath == null ? "" : ` --config ${configPath}`;
124
- const ignoreFlag = ignorePath == null ? "" : ` --ignore-path ${ignorePath}`;
125
- return `${exec} prettier${configFlag2}${ignoreFlag} --write ${files}`;
126
- }
127
- if (ctx.formatter === "oxfmt") {
128
- const configPath = getOxfmtConfigPath(ctx);
129
- return `${exec} oxfmt -c ${configPath} --write ${files}`;
130
- }
131
- const configFlag = ctx.isMonorepo || ctx.configStrategy === "root" ? "" : " --config-path .config";
132
- return `${exec} biome format${configFlag} --write ${files}`;
133
- }
134
- function getLintChangedFilesCommand(ctx, files) {
135
- const exec = getExecCommand(ctx.packageManager);
136
- if (ctx.linter === "oxlint") {
137
- if (!ctx.isMonorepo) {
138
- return runScript(ctx.packageManager, "lint", files);
139
- }
140
- return `${exec} oxlint ${files}`;
141
- }
142
- if (ctx.linter === "eslint") {
143
- const configFlag2 = ctx.configStrategy === "stealth" ? " --config .config/eslint.config.js" : "";
144
- return `${exec} eslint${configFlag2} ${files}`;
18
+ function parsePackageManagerSpec(value) {
19
+ if (value == null || value.length === 0) {
20
+ return void 0;
145
21
  }
146
- const configFlag = ctx.isMonorepo || ctx.configStrategy === "root" ? "" : " --config-path .config";
147
- return `${exec} biome lint${configFlag} ${files}`;
148
- }
149
- function getPrettierConfigPath(ctx) {
150
- if (ctx.isMonorepo) return ".config/prettier/base.json";
151
- if (ctx.configStrategy === "stealth") return ".config/prettier.json";
152
- return void 0;
153
- }
154
- function getPrettierIgnorePath(ctx) {
155
- if (ctx.isMonorepo) return ".config/prettier/prettierignore";
156
- if (ctx.configStrategy === "stealth") return ".config/prettierignore";
157
- return void 0;
158
- }
159
- function getOxfmtConfigPath(ctx) {
160
- if (ctx.isMonorepo) return ".config/oxfmt/base.json";
161
- if (ctx.configStrategy === "stealth") return ".config/oxfmt.json";
162
- return "oxfmt.json";
163
- }
164
- function runScript(packageManager, script, args) {
165
- const suffix = args == null ? "" : ` ${args}`;
166
- if (packageManager === "npm") {
167
- return `npm run ${script}${args == null ? "" : ` --${suffix}`}`;
22
+ const atIndex = value.indexOf("@");
23
+ const name = atIndex === -1 ? value : value.slice(0, atIndex);
24
+ if (!isPackageManagerName(name)) {
25
+ return void 0;
168
26
  }
169
- if (packageManager === "yarn") {
170
- return `yarn ${script}${suffix}`;
27
+ if (atIndex === -1) {
28
+ return { name };
171
29
  }
172
- return `${packageManager} ${script}${args == null ? "" : ` --${suffix}`}`;
173
- }
174
- function getExecCommand(packageManager) {
175
- if (packageManager === "npm") return "npm exec --";
176
- if (packageManager === "yarn") return "yarn exec";
177
- return `${packageManager} exec`;
178
- }
179
-
180
- function getLanguageFromTemplate(template) {
181
- return template.endsWith("-js") ? "javascript" : "typescript";
182
- }
183
- function getBaseTemplate(template) {
184
- return template.replace("-js", "");
185
- }
186
- function shouldEnableReactCompiler(options) {
187
- const template = options.template ?? "vanilla";
188
- return getBaseTemplate(template) === "react" && (options.projectType ?? "app") === "app";
30
+ const version = value.slice(atIndex + 1);
31
+ return version.length > 0 ? { name, version } : { name };
189
32
  }
190
33
 
191
34
  function unique(...array) {
@@ -274,6 +117,10 @@ function validatePackageName(name) {
274
117
  }
275
118
  return validateNameSegment(name, "Package name");
276
119
  }
120
+ function getPackageDirectoryName(name) {
121
+ const slashIndex = name.indexOf("/");
122
+ return slashIndex === -1 ? name : name.slice(slashIndex + 1);
123
+ }
277
124
 
278
125
  function generateRandomName() {
279
126
  const adjectives = [
@@ -385,150 +232,600 @@ async function detectLinterFromConfig(root) {
385
232
  return "biome";
386
233
  }
387
234
  }
388
- return void 0;
235
+ return void 0;
236
+ }
237
+ async function detectFormatterFromConfig(root) {
238
+ if (await pathExists(path.join(root, ".config/prettier"))) return "prettier";
239
+ if (await pathExists(path.join(root, ".config/oxfmt"))) return "oxfmt";
240
+ if (await pathExists(path.join(root, "biome.json"))) {
241
+ try {
242
+ const content = await promises.readFile(path.join(root, "biome.json"), "utf-8");
243
+ const config = JSON.parse(content);
244
+ if (config.formatter?.enabled !== false) return "biome";
245
+ } catch {
246
+ return "biome";
247
+ }
248
+ }
249
+ return void 0;
250
+ }
251
+ function detectLinterFromDeps(devDeps) {
252
+ if (!devDeps) return void 0;
253
+ if (devDeps["@biomejs/biome"]) return "biome";
254
+ if (devDeps.eslint) return "eslint";
255
+ if (devDeps.oxlint) return "oxlint";
256
+ return void 0;
257
+ }
258
+ function detectFormatterFromDeps(devDeps) {
259
+ if (!devDeps) return void 0;
260
+ if (devDeps["@biomejs/biome"]) return "biome";
261
+ if (devDeps.prettier) return "prettier";
262
+ if (devDeps.oxfmt) return "oxfmt";
263
+ return void 0;
264
+ }
265
+ async function detectTooling(root) {
266
+ try {
267
+ const pkgPath = path.join(root, "package.json");
268
+ const content = await promises.readFile(pkgPath, "utf-8");
269
+ const pkg = JSON.parse(content);
270
+ const linter = detectLinterFromScript(pkg.scripts?.lint) ?? await detectLinterFromConfig(root) ?? detectLinterFromDeps(pkg.devDependencies);
271
+ const formatter = detectFormatterFromScript(pkg.scripts?.format) ?? await detectFormatterFromConfig(root) ?? detectFormatterFromDeps(pkg.devDependencies);
272
+ return { linter, formatter };
273
+ } catch {
274
+ return { linter: void 0, formatter: void 0 };
275
+ }
276
+ }
277
+
278
+ const DEFAULT_MINIMUM_RELEASE_AGE_MINUTES = 1440;
279
+ const MINUTE_IN_MS = 60 * 1e3;
280
+ function getMinimumReleaseAgeMinutes(options) {
281
+ return Math.max(0, options?.minimumReleaseAgeMinutes ?? DEFAULT_MINIMUM_RELEASE_AGE_MINUTES);
282
+ }
283
+ function isVersionOldEnough(version, time, options) {
284
+ const minimumReleaseAgeMinutes = getMinimumReleaseAgeMinutes(options);
285
+ if (minimumReleaseAgeMinutes === 0) return true;
286
+ const publishedAt = time?.[version];
287
+ if (publishedAt == null) return false;
288
+ const publishedTime = Date.parse(publishedAt);
289
+ if (!Number.isFinite(publishedTime)) return false;
290
+ return (options?.now ?? Date.now()) - publishedTime >= minimumReleaseAgeMinutes * MINUTE_IN_MS;
291
+ }
292
+ function getInstallableVersions(versions, time, options) {
293
+ return [...versions].filter((version) => isVersionOldEnough(version, time, options));
294
+ }
295
+ async function fetchNpmPackageMetadata(packageName) {
296
+ const response = await fetch(`https://registry.npmjs.org/${packageName}`);
297
+ return await response.json();
298
+ }
299
+ async function getLatestNpmVersion(packageName, fallback, options) {
300
+ try {
301
+ if (getMinimumReleaseAgeMinutes(options) === 0) {
302
+ const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
303
+ const data2 = await response.json();
304
+ return data2.version;
305
+ }
306
+ const data = await fetchNpmPackageMetadata(packageName);
307
+ const latestVersion = data["dist-tags"]?.latest;
308
+ if (latestVersion != null && isVersionOldEnough(latestVersion, data.time, options)) {
309
+ return latestVersion;
310
+ }
311
+ const latestInstallableVersion = getInstallableVersions(
312
+ Object.keys(data.versions ?? {}),
313
+ data.time,
314
+ options
315
+ ).sort((a, b) => compareNumericSemver(b, a))[0];
316
+ return latestInstallableVersion ?? fallback;
317
+ } catch {
318
+ return fallback;
319
+ }
320
+ }
321
+ function getSemverMajor(version) {
322
+ if (version == null) return void 0;
323
+ const major = Number.parseInt(version, 10);
324
+ return Number.isFinite(major) ? major : void 0;
325
+ }
326
+ function getSemverMajorString(version) {
327
+ return String(getSemverMajor(version) ?? version.split(".")[0]);
328
+ }
329
+ function compareNumericSemver(a, b) {
330
+ const aParts = a.split(".").map((part) => Number.parseInt(part, 10) || 0);
331
+ const bParts = b.split(".").map((part) => Number.parseInt(part, 10) || 0);
332
+ const maxLength = Math.max(aParts.length, bParts.length);
333
+ for (let index = 0; index < maxLength; index += 1) {
334
+ const difference = (aParts[index] ?? 0) - (bParts[index] ?? 0);
335
+ if (difference !== 0) {
336
+ return difference;
337
+ }
338
+ }
339
+ return 0;
340
+ }
341
+ function getLatestMatchingMajorVersion(versions, majorVersion, time, options) {
342
+ return getInstallableVersions(versions, time, options).filter((version) => version.split(".")[0] === majorVersion).sort((a, b) => compareNumericSemver(b, a))[0];
343
+ }
344
+ async function getLatestNpmMajorVersion(packageName, majorVersion, fallback, options) {
345
+ try {
346
+ const data = await fetchNpmPackageMetadata(packageName);
347
+ const latestMatchingVersion = getLatestMatchingMajorVersion(
348
+ Object.keys(data.versions ?? {}),
349
+ majorVersion,
350
+ data.time,
351
+ options
352
+ );
353
+ return latestMatchingVersion ?? fallback;
354
+ } catch {
355
+ return fallback;
356
+ }
357
+ }
358
+ async function getLatestNpmMajorVersionAtOrBelow(packageName, majorVersion, fallback, options) {
359
+ try {
360
+ const data = await fetchNpmPackageMetadata(packageName);
361
+ const versions = Object.keys(data.versions ?? {});
362
+ const requestedMajor = getSemverMajor(majorVersion);
363
+ if (requestedMajor !== void 0) {
364
+ for (let major = requestedMajor; major >= 0; major -= 1) {
365
+ const latestMatchingVersion = getLatestMatchingMajorVersion(
366
+ versions,
367
+ String(major),
368
+ data.time,
369
+ options
370
+ );
371
+ if (latestMatchingVersion != null) {
372
+ return latestMatchingVersion;
373
+ }
374
+ }
375
+ }
376
+ return fallback;
377
+ } catch {
378
+ return fallback;
379
+ }
380
+ }
381
+ async function getLatestPnpmVersion() {
382
+ return getLatestNpmVersion("pnpm", "10.11.0");
383
+ }
384
+ async function getLatestYarnVersion() {
385
+ return getLatestNpmVersion("yarn", "4.6.0");
386
+ }
387
+ async function getLatestNpmCliVersion() {
388
+ return getLatestNpmVersion("npm", "11.0.0");
389
+ }
390
+ async function getLatestNodeVersion() {
391
+ try {
392
+ const response = await fetch("https://nodejs.org/dist/index.json");
393
+ const data = await response.json();
394
+ const latestVersion = data[0];
395
+ if (latestVersion) {
396
+ return latestVersion.version.replace(/^v/, "");
397
+ }
398
+ return "25.0.0";
399
+ } catch {
400
+ return "25.0.0";
401
+ }
402
+ }
403
+
404
+ function parseWorkspaceYamlContent(content) {
405
+ const directories = [];
406
+ let inPackagesSection = false;
407
+ for (const line of content.split("\n")) {
408
+ const trimmed = line.trim();
409
+ if (trimmed === "packages:") {
410
+ inPackagesSection = true;
411
+ continue;
412
+ }
413
+ if (inPackagesSection && trimmed && !line.startsWith(" ") && !line.startsWith(" ") && !trimmed.startsWith("-")) {
414
+ break;
415
+ }
416
+ if (inPackagesSection && trimmed.startsWith("-")) {
417
+ const entry = trimmed.slice(1).trim().replace(/^["']|["']$/g, "").replace(/^\.\//, "").replace(/\/\*.*$/, "");
418
+ if (entry && !entry.startsWith(".")) {
419
+ directories.push(entry);
420
+ }
421
+ }
422
+ }
423
+ return directories;
424
+ }
425
+
426
+ const pnpm10Capabilities = {
427
+ pnpmWorkspaceVersionPolicy: "manage-package-manager-versions",
428
+ pnpmBuildDependencyPolicy: "onlyBuiltDependencies"
429
+ };
430
+ const pnpm10Requirements = {
431
+ node: "18.12"
432
+ };
433
+ const pnpm11Capabilities = {
434
+ pnpmWorkspaceVersionPolicy: "pmOnFail",
435
+ pnpmBuildDependencyPolicy: "allowBuilds"
436
+ };
437
+ const pnpm11Requirements = {
438
+ node: "22.13"
439
+ };
440
+ function getPnpmCapabilities(major) {
441
+ switch (major) {
442
+ case 10:
443
+ return pnpm10Capabilities;
444
+ case 11:
445
+ return pnpm11Capabilities;
446
+ default:
447
+ if (major != null && major >= 12) return pnpm11Capabilities;
448
+ else return pnpm10Capabilities;
449
+ }
450
+ }
451
+ function getPnpmRequirements(major) {
452
+ switch (major) {
453
+ case 10:
454
+ return pnpm10Requirements;
455
+ case 11:
456
+ return pnpm11Requirements;
457
+ default:
458
+ if (major != null && major >= 12) return pnpm11Requirements;
459
+ else return pnpm10Requirements;
460
+ }
461
+ }
462
+ function getPnpmProfile(spec) {
463
+ const major = getSemverMajor(spec.version);
464
+ return {
465
+ ...spec,
466
+ major,
467
+ capabilities: getPnpmCapabilities(major),
468
+ requirements: getPnpmRequirements(major)
469
+ };
470
+ }
471
+ function renderPnpmWorkspaceConfig(options) {
472
+ const {
473
+ profile,
474
+ manageVersions = true,
475
+ packages = [],
476
+ buildDependencies = { esbuild: true }
477
+ } = options;
478
+ const lines = [];
479
+ if (manageVersions) {
480
+ if (profile.capabilities.pnpmWorkspaceVersionPolicy === "pmOnFail") {
481
+ lines.push("pmOnFail: download", "");
482
+ } else {
483
+ lines.push("manage-package-manager-versions: true", "");
484
+ }
485
+ }
486
+ if (packages.length > 0) {
487
+ lines.push("packages:", ...packages.map((pattern) => ` - "${pattern}"`), "");
488
+ }
489
+ if (profile.capabilities.pnpmBuildDependencyPolicy === "allowBuilds") {
490
+ lines.push("allowBuilds:");
491
+ for (const [dependency, allowed] of Object.entries(buildDependencies)) {
492
+ lines.push(` ${dependency}: ${allowed ? "true" : "false"}`);
493
+ }
494
+ } else {
495
+ const allowedDependencies = Object.entries(buildDependencies).filter(([, allowed]) => allowed).map(([dependency]) => dependency);
496
+ lines.push("onlyBuiltDependencies:");
497
+ for (const dependency of allowedDependencies) {
498
+ lines.push(` - ${dependency}`);
499
+ }
500
+ }
501
+ return lines.join("\n");
502
+ }
503
+
504
+ function getPackageManagerProfile(spec) {
505
+ const major = getSemverMajor(spec.version);
506
+ if (spec.name === "pnpm") {
507
+ return getPnpmProfile(spec);
508
+ }
509
+ return {
510
+ ...spec,
511
+ major,
512
+ capabilities: {},
513
+ requirements: {}
514
+ };
515
+ }
516
+
517
+ function getPackageManagerSpec(packageManager) {
518
+ return packageManager ?? { name: "pnpm" };
519
+ }
520
+ function getPackageManagerName(packageManager) {
521
+ return getPackageManagerSpec(packageManager).name;
522
+ }
523
+ function formatPackageManager(packageManager) {
524
+ const spec = getPackageManagerSpec(packageManager);
525
+ return spec.version ? `${spec.name}@${spec.version}` : spec.name;
526
+ }
527
+
528
+ async function resolvePackageManager(options) {
529
+ const packageManager = getPackageManagerSpec(options.packageManager);
530
+ if (packageManager.version == null) {
531
+ if (packageManager.name === "pnpm") {
532
+ packageManager.version = await getLatestPnpmVersion();
533
+ } else if (packageManager.name === "yarn") {
534
+ packageManager.version = await getLatestYarnVersion();
535
+ } else if (packageManager.name === "npm") {
536
+ packageManager.version = await getLatestNpmCliVersion();
537
+ }
538
+ } else if (/^\d+$/.test(packageManager.version)) {
539
+ const fallback = `${packageManager.version}.0.0`;
540
+ packageManager.version = await getLatestNpmMajorVersion(
541
+ packageManager.name,
542
+ packageManager.version,
543
+ fallback
544
+ );
545
+ }
546
+ return packageManager;
547
+ }
548
+ async function resolvePackageManagerProfile(options) {
549
+ return getPackageManagerProfile(await resolvePackageManager(options));
550
+ }
551
+
552
+ function getEngineSpec(engine) {
553
+ return engine ?? { name: "node" };
554
+ }
555
+ function getEngineName(engine) {
556
+ return getEngineSpec(engine).name;
557
+ }
558
+ function formatEngine(engine) {
559
+ const spec = getEngineSpec(engine);
560
+ return spec.version ? `${spec.name}@${spec.version}` : spec.name;
561
+ }
562
+ function parseEngine(engines) {
563
+ if (engines == null) {
564
+ return void 0;
565
+ }
566
+ const [name, range] = Object.entries(engines).find(
567
+ ([engineName]) => engineName !== "npm" && engineName !== "pnpm" && engineName !== "yarn"
568
+ ) ?? [];
569
+ if (name == null) {
570
+ return void 0;
571
+ }
572
+ const version = range?.match(/(\d+(?:\.\d+(?:\.\d+)?)?)/)?.[1];
573
+ return { name, version };
574
+ }
575
+ async function resolveEngine(options) {
576
+ const engine = getEngineSpec(options.engine);
577
+ if ((engine.version == null || engine.version === "latest") && engine.name === "node") {
578
+ engine.version = await getLatestNodeVersion();
579
+ }
580
+ return engine;
581
+ }
582
+
583
+ function getLanguageFromTemplate(template) {
584
+ return template.endsWith("-js") ? "javascript" : "typescript";
585
+ }
586
+ function getBaseTemplate(template) {
587
+ return template.replace("-js", "");
588
+ }
589
+ function shouldEnableReactCompiler(options) {
590
+ const template = options.template ?? "vanilla";
591
+ return getBaseTemplate(template) === "react" && (options.projectType ?? "app") === "app";
592
+ }
593
+
594
+ const config = new Conf__default({
595
+ projectName: "create-krispya"
596
+ });
597
+ function getAiPlatforms() {
598
+ return config.get("aiPlatforms");
599
+ }
600
+ function setAiPlatforms(platforms) {
601
+ config.set("aiPlatforms", platforms);
602
+ }
603
+ function getConfigStrategy() {
604
+ return config.get("configStrategy") ?? "stealth";
605
+ }
606
+ function setConfigStrategy(strategy) {
607
+ config.set("configStrategy", strategy);
608
+ }
609
+ function clearConfig() {
610
+ config.clear();
611
+ }
612
+ function getConfigPath() {
613
+ return config.path;
614
+ }
615
+
616
+ const ALL_AI_PLATFORMS = ["agents", "claude"];
617
+ const AI_PLATFORM_LABELS = {
618
+ agents: "AGENTS.md",
619
+ claude: "CLAUDE.md"
620
+ };
621
+ const AI_PLATFORM_HINTS = {
622
+ agents: "OpenAI, Cursor, Windsurf, etc.",
623
+ claude: "Claude Code"
624
+ };
625
+ function renderAiFiles(files, params) {
626
+ const { platforms, isMonorepo, configStrategy, hasTypecheck, ...rest } = params;
627
+ if (platforms.length === 0) return;
628
+ const content = generateWorkspace({
629
+ ...rest,
630
+ isMonorepo: !!isMonorepo,
631
+ configStrategy: configStrategy ?? "stealth",
632
+ hasTypecheck: hasTypecheck ?? false
633
+ });
634
+ const pointer = "See [`AGENTS.md`](./Agents.md) for agent context.\n";
635
+ const hasAgents = platforms.includes("agents");
636
+ const hasClaude = platforms.includes("claude");
637
+ const isSingleton = platforms.length === 1;
638
+ if (hasAgents) files["AGENTS.md"] = { type: "text", content };
639
+ if (hasClaude) {
640
+ if (isSingleton) {
641
+ files["CLAUDE.md"] = { type: "text", content };
642
+ } else {
643
+ files["CLAUDE.md"] = { type: "text", content: pointer };
644
+ }
645
+ }
646
+ }
647
+ function generateWorkspace(ctx) {
648
+ const { packageManager, linter, formatter, hasTypecheck } = ctx;
649
+ const exampleFiles = "src/App.tsx src/core/systems/move-entity.ts";
650
+ const commands = getAfterEditingCommands(ctx, exampleFiles);
651
+ const sections = [
652
+ "# Workspace Tools",
653
+ "",
654
+ `- **Package Manager:** ${packageManager}`,
655
+ `- **Linter:** ${linter}`,
656
+ `- **Formatter:** ${formatter}`,
657
+ "",
658
+ "## After Editing",
659
+ ""
660
+ ];
661
+ if (hasTypecheck) {
662
+ sections.push(
663
+ "\u2705 After editing files, check the types for errors and then format and lint only the files changed for the current task."
664
+ );
665
+ } else {
666
+ sections.push(
667
+ "\u2705 After editing files, format and lint only the files changed for the current task."
668
+ );
669
+ }
670
+ sections.push("", "```sh", "# Example");
671
+ if (hasTypecheck) {
672
+ sections.push(runScript(packageManager, "typecheck"));
673
+ }
674
+ sections.push(
675
+ "# Run format and lint for only files modified",
676
+ commands.format,
677
+ commands.lint,
678
+ "```",
679
+ "",
680
+ "\u274C Avoid unless explicitly approved:",
681
+ "",
682
+ "```sh",
683
+ runScript(packageManager, "format"),
684
+ runScript(packageManager, "lint"),
685
+ "```",
686
+ ""
687
+ );
688
+ return sections.join("\n");
689
+ }
690
+ function getAfterEditingCommands(ctx, files) {
691
+ return {
692
+ format: getFormatChangedFilesCommand(ctx, files),
693
+ lint: getLintChangedFilesCommand(ctx, files)
694
+ };
695
+ }
696
+ function getFormatChangedFilesCommand(ctx, files) {
697
+ const exec = getExecCommand(ctx.packageManager);
698
+ if (ctx.formatter === "prettier") {
699
+ const configPath = getPrettierConfigPath(ctx);
700
+ const ignorePath = getPrettierIgnorePath(ctx);
701
+ const configFlag2 = configPath == null ? "" : ` --config ${configPath}`;
702
+ const ignoreFlag = ignorePath == null ? "" : ` --ignore-path ${ignorePath}`;
703
+ return `${exec} prettier${configFlag2}${ignoreFlag} --write ${files}`;
704
+ }
705
+ if (ctx.formatter === "oxfmt") {
706
+ const configPath = getOxfmtConfigPath(ctx);
707
+ return `${exec} oxfmt -c ${configPath} --write ${files}`;
708
+ }
709
+ const configFlag = ctx.isMonorepo || ctx.configStrategy === "root" ? "" : " --config-path .config";
710
+ return `${exec} biome format${configFlag} --write ${files}`;
389
711
  }
390
- async function detectFormatterFromConfig(root) {
391
- if (await pathExists(path.join(root, ".config/prettier"))) return "prettier";
392
- if (await pathExists(path.join(root, ".config/oxfmt"))) return "oxfmt";
393
- if (await pathExists(path.join(root, "biome.json"))) {
394
- try {
395
- const content = await promises.readFile(path.join(root, "biome.json"), "utf-8");
396
- const config = JSON.parse(content);
397
- if (config.formatter?.enabled !== false) return "biome";
398
- } catch {
399
- return "biome";
712
+ function getLintChangedFilesCommand(ctx, files) {
713
+ const exec = getExecCommand(ctx.packageManager);
714
+ if (ctx.linter === "oxlint") {
715
+ if (!ctx.isMonorepo) {
716
+ return runScript(ctx.packageManager, "lint", files);
400
717
  }
718
+ return `${exec} oxlint ${files}`;
401
719
  }
402
- return void 0;
720
+ if (ctx.linter === "eslint") {
721
+ const configFlag2 = ctx.configStrategy === "stealth" ? " --config .config/eslint.config.js" : "";
722
+ return `${exec} eslint${configFlag2} ${files}`;
723
+ }
724
+ const configFlag = ctx.isMonorepo || ctx.configStrategy === "root" ? "" : " --config-path .config";
725
+ return `${exec} biome lint${configFlag} ${files}`;
403
726
  }
404
- function detectLinterFromDeps(devDeps) {
405
- if (!devDeps) return void 0;
406
- if (devDeps["@biomejs/biome"]) return "biome";
407
- if (devDeps.eslint) return "eslint";
408
- if (devDeps.oxlint) return "oxlint";
727
+ function getPrettierConfigPath(ctx) {
728
+ if (ctx.isMonorepo) return ".config/prettier/base.json";
729
+ if (ctx.configStrategy === "stealth") return ".config/prettier.json";
409
730
  return void 0;
410
731
  }
411
- function detectFormatterFromDeps(devDeps) {
412
- if (!devDeps) return void 0;
413
- if (devDeps["@biomejs/biome"]) return "biome";
414
- if (devDeps.prettier) return "prettier";
415
- if (devDeps.oxfmt) return "oxfmt";
732
+ function getPrettierIgnorePath(ctx) {
733
+ if (ctx.isMonorepo) return ".config/prettier/prettierignore";
734
+ if (ctx.configStrategy === "stealth") return ".config/prettierignore";
416
735
  return void 0;
417
736
  }
418
- async function detectTooling(root) {
419
- try {
420
- const pkgPath = path.join(root, "package.json");
421
- const content = await promises.readFile(pkgPath, "utf-8");
422
- const pkg = JSON.parse(content);
423
- const linter = detectLinterFromScript(pkg.scripts?.lint) ?? await detectLinterFromConfig(root) ?? detectLinterFromDeps(pkg.devDependencies);
424
- const formatter = detectFormatterFromScript(pkg.scripts?.format) ?? await detectFormatterFromConfig(root) ?? detectFormatterFromDeps(pkg.devDependencies);
425
- return { linter, formatter };
426
- } catch {
427
- return { linter: void 0, formatter: void 0 };
428
- }
737
+ function getOxfmtConfigPath(ctx) {
738
+ if (ctx.isMonorepo) return ".config/oxfmt/base.json";
739
+ if (ctx.configStrategy === "stealth") return ".config/oxfmt.json";
740
+ return "oxfmt.json";
429
741
  }
430
-
431
- async function getLatestNpmVersion(packageName, fallback) {
432
- try {
433
- const response = await fetch(`https://registry.npmjs.org/${packageName}/latest`);
434
- const data = await response.json();
435
- return data.version;
436
- } catch {
437
- return fallback;
742
+ function runScript(packageManager, script, args) {
743
+ const suffix = args == null ? "" : ` ${args}`;
744
+ if (packageManager === "npm") {
745
+ return `npm run ${script}${args == null ? "" : ` --${suffix}`}`;
438
746
  }
439
- }
440
- function compareNumericSemver(a, b) {
441
- const aParts = a.split(".").map((part) => Number.parseInt(part, 10) || 0);
442
- const bParts = b.split(".").map((part) => Number.parseInt(part, 10) || 0);
443
- const maxLength = Math.max(aParts.length, bParts.length);
444
- for (let index = 0; index < maxLength; index += 1) {
445
- const difference = (aParts[index] ?? 0) - (bParts[index] ?? 0);
446
- if (difference !== 0) {
447
- return difference;
448
- }
747
+ if (packageManager === "yarn") {
748
+ return `yarn ${script}${suffix}`;
449
749
  }
450
- return 0;
451
- }
452
- function getLatestMatchingMajorVersion(versions, majorVersion) {
453
- return [...versions].filter((version) => version.split(".")[0] === majorVersion).sort((a, b) => compareNumericSemver(b, a))[0];
750
+ return `${packageManager} ${script}${args == null ? "" : ` --${suffix}`}`;
454
751
  }
455
- async function getLatestNpmMajorVersion(packageName, majorVersion, fallback) {
456
- try {
457
- const response = await fetch(`https://registry.npmjs.org/${packageName}`);
458
- const data = await response.json();
459
- const latestMatchingVersion = getLatestMatchingMajorVersion(
460
- Object.keys(data.versions ?? {}),
461
- majorVersion
462
- );
463
- return latestMatchingVersion ?? fallback;
464
- } catch {
465
- return fallback;
466
- }
752
+ function getExecCommand(packageManager) {
753
+ if (packageManager === "npm") return "npm exec --";
754
+ if (packageManager === "yarn") return "yarn exec";
755
+ return `${packageManager} exec`;
467
756
  }
468
- async function getLatestNpmMajorVersionAtOrBelow(packageName, majorVersion, fallback) {
469
- try {
470
- const response = await fetch(`https://registry.npmjs.org/${packageName}`);
471
- const data = await response.json();
472
- const versions = Object.keys(data.versions ?? {});
473
- const requestedMajor = Number.parseInt(majorVersion, 10);
474
- if (Number.isFinite(requestedMajor)) {
475
- for (let major = requestedMajor; major >= 0; major -= 1) {
476
- const latestMatchingVersion = getLatestMatchingMajorVersion(versions, String(major));
477
- if (latestMatchingVersion != null) {
478
- return latestMatchingVersion;
479
- }
480
- }
757
+
758
+ async function checkAnyExists(paths) {
759
+ for (const path of paths) {
760
+ try {
761
+ await promises.access(path, promises.constants.F_OK);
762
+ return true;
763
+ } catch {
481
764
  }
482
- return fallback;
483
- } catch {
484
- return fallback;
485
765
  }
766
+ return false;
486
767
  }
487
- async function getLatestPnpmVersion() {
488
- return getLatestNpmVersion("pnpm", "10.11.0");
489
- }
490
- async function getLatestYarnVersion() {
491
- return getLatestNpmVersion("yarn", "4.6.0");
492
- }
493
- async function getLatestNpmCliVersion() {
494
- return getLatestNpmVersion("npm", "11.0.0");
495
- }
496
- async function getLatestNodeVersion() {
768
+ async function validateWorkspace(monorepoRoot) {
769
+ const errors = [];
770
+ const tsConfigPath = path.join(monorepoRoot, ".config/typescript/package.json");
497
771
  try {
498
- const response = await fetch("https://nodejs.org/dist/index.json");
499
- const data = await response.json();
500
- const latestVersion = data[0];
501
- if (latestVersion) {
502
- return latestVersion.version.replace(/^v/, "");
503
- }
504
- return "25.0.0";
772
+ await promises.access(tsConfigPath, promises.constants.F_OK);
505
773
  } catch {
506
- return "25.0.0";
774
+ errors.push("Missing .config/typescript package");
507
775
  }
508
- }
509
-
510
- function parseWorkspaceYamlContent(content) {
511
- const directories = [];
512
- let inPackagesSection = false;
513
- for (const line of content.split("\n")) {
514
- const trimmed = line.trim();
515
- if (trimmed === "packages:") {
516
- inPackagesSection = true;
517
- continue;
518
- }
519
- if (inPackagesSection && trimmed && !line.startsWith(" ") && !line.startsWith(" ") && !trimmed.startsWith("-")) {
520
- break;
521
- }
522
- if (inPackagesSection && trimmed.startsWith("-")) {
523
- const entry = trimmed.slice(1).trim().replace(/^["']|["']$/g, "").replace(/^\.\//, "").replace(/\/\*.*$/, "");
524
- if (entry && !entry.startsWith(".")) {
525
- directories.push(entry);
526
- }
527
- }
776
+ const linterPaths = [
777
+ path.join(monorepoRoot, ".config/oxlint/package.json"),
778
+ path.join(monorepoRoot, ".config/eslint/package.json"),
779
+ path.join(monorepoRoot, "eslint.config.js"),
780
+ path.join(monorepoRoot, "biome.json")
781
+ ];
782
+ const hasLinter = await checkAnyExists(linterPaths);
783
+ if (!hasLinter) {
784
+ errors.push(
785
+ "Missing linter config (.config/oxlint, .config/eslint, eslint.config.js, or biome.json)"
786
+ );
528
787
  }
529
- return directories;
788
+ const formatterPaths = [
789
+ path.join(monorepoRoot, ".config/oxfmt/package.json"),
790
+ path.join(monorepoRoot, ".config/prettier/package.json"),
791
+ path.join(monorepoRoot, ".prettierrc.json"),
792
+ path.join(monorepoRoot, "biome.json")
793
+ ];
794
+ const hasFormatter = await checkAnyExists(formatterPaths);
795
+ if (!hasFormatter) {
796
+ errors.push(
797
+ "Missing formatter config (.config/oxfmt, .config/prettier, .prettierrc.json, or biome.json)"
798
+ );
799
+ }
800
+ return { valid: errors.length === 0, errors };
530
801
  }
531
802
 
803
+ const gitAttributesContent = [
804
+ "* text eol=lf",
805
+ "*.png binary",
806
+ "*.jpg binary",
807
+ "*.jpeg binary",
808
+ "*.gif binary",
809
+ "*.ico binary",
810
+ "*.mov binary",
811
+ "*.mp4 binary",
812
+ "*.mp3 binary",
813
+ "*.flv binary",
814
+ "*.fla binary",
815
+ "*.wav binary",
816
+ "*.swf binary",
817
+ "*.gz binary",
818
+ "*.zip binary",
819
+ "*.7z binary",
820
+ "*.ttf binary",
821
+ "*.eot binary",
822
+ "*.woff binary",
823
+ "*.pyc binary",
824
+ "*.pdf binary",
825
+ "*.glb binary",
826
+ "*.gltf binary"
827
+ ].join("\n");
828
+
532
829
  const PACKAGE_VERSION_DEFINITIONS = {
533
830
  "@babel/core": { fallbackVersion: "7.29.0" },
534
831
  "@biomejs/biome": { fallbackVersion: "2.0.0" },
@@ -600,68 +897,6 @@ function formatResolvedPackageVersion(versions, packageName, prefix) {
600
897
  function assignResolvedPackageVersion(target, versions, packageName, prefix) {
601
898
  target[packageName] = formatResolvedPackageVersion(versions, packageName, prefix);
602
899
  }
603
- function getPackageManagerSpec(packageManager) {
604
- return packageManager ?? { name: "pnpm" };
605
- }
606
- function getPackageManagerName(packageManager) {
607
- return getPackageManagerSpec(packageManager).name;
608
- }
609
- function formatPackageManager(packageManager) {
610
- const spec = getPackageManagerSpec(packageManager);
611
- return spec.version ? `${spec.name}@${spec.version}` : spec.name;
612
- }
613
- function parsePackageManager(packageManager) {
614
- if (packageManager == null || packageManager.length === 0) {
615
- return void 0;
616
- }
617
- const atIndex = packageManager.indexOf("@");
618
- if (atIndex === -1) {
619
- return { name: packageManager };
620
- }
621
- return {
622
- name: packageManager.slice(0, atIndex),
623
- version: packageManager.slice(atIndex + 1)
624
- };
625
- }
626
- function getEngineSpec(engine) {
627
- return engine ?? { name: "node" };
628
- }
629
- function getEngineName(engine) {
630
- return getEngineSpec(engine).name;
631
- }
632
- function parseEngine(engines) {
633
- if (engines == null) {
634
- return void 0;
635
- }
636
- const [name, range] = Object.entries(engines).find(
637
- ([engineName]) => engineName !== "npm" && engineName !== "pnpm" && engineName !== "yarn"
638
- ) ?? [];
639
- if (name == null) {
640
- return void 0;
641
- }
642
- const version = range?.match(/(\d+(?:\.\d+(?:\.\d+)?)?)/)?.[1];
643
- return { name, version };
644
- }
645
- async function resolvePackageManager(options) {
646
- const packageManager = getPackageManagerSpec(options.packageManager);
647
- if (packageManager.version == null) {
648
- if (packageManager.name === "pnpm") {
649
- packageManager.version = await getLatestPnpmVersion();
650
- } else if (packageManager.name === "yarn") {
651
- packageManager.version = await getLatestYarnVersion();
652
- } else if (packageManager.name === "npm") {
653
- packageManager.version = await getLatestNpmCliVersion();
654
- }
655
- }
656
- return packageManager;
657
- }
658
- async function resolveEngine(options) {
659
- const engine = getEngineSpec(options.engine);
660
- if ((engine.version == null || engine.version === "latest") && engine.name === "node") {
661
- engine.version = await getLatestNodeVersion();
662
- }
663
- return engine;
664
- }
665
900
  function formatNodeTypesVersion(versions = {}, _engine) {
666
901
  const resolvedVersion = versions["@types/node"];
667
902
  if (resolvedVersion != null) {
@@ -678,7 +913,7 @@ async function resolveNodeTypesVersion(engine, versions = {}) {
678
913
  return void 0;
679
914
  }
680
915
  const nodeVersion = engineSpec.version ?? await getLatestNodeVersion();
681
- const majorVersion = nodeVersion.split(".")[0];
916
+ const majorVersion = getSemverMajorString(nodeVersion);
682
917
  return getLatestNpmMajorVersionAtOrBelow(
683
918
  "@types/node",
684
919
  majorVersion,
@@ -1201,12 +1436,12 @@ function renderPackageJson(params) {
1201
1436
  if (!isMonorepoPackage) {
1202
1437
  const engines = {};
1203
1438
  if (packageManager.version != null) {
1204
- const majorVersion = packageManager.version.split(".")[0];
1439
+ const majorVersion = getSemverMajorString(packageManager.version);
1205
1440
  engines[packageManager.name] = `>=${majorVersion}.0.0`;
1206
1441
  packageJson.packageManager = formatPackageManager(packageManager);
1207
1442
  }
1208
1443
  if (engine.version != null) {
1209
- const majorVersion = engine.version.split(".")[0];
1444
+ const majorVersion = getSemverMajorString(engine.version);
1210
1445
  engines[engine.name] = `>=${majorVersion}.0.0`;
1211
1446
  }
1212
1447
  if (Object.keys(engines).length > 0) {
@@ -1218,15 +1453,12 @@ function renderPackageJson(params) {
1218
1453
  content: JSON.stringify(packageJson, null, 2)
1219
1454
  };
1220
1455
  if (isPnpm && !options.workspaceRoot) {
1221
- const manageVersions = options.pnpmManageVersions ?? true;
1222
- const workspaceLines = [];
1223
- if (manageVersions) {
1224
- workspaceLines.push("manage-package-manager-versions: true", "");
1225
- }
1226
- workspaceLines.push("onlyBuiltDependencies:", " - esbuild");
1227
1456
  files["pnpm-workspace.yaml"] = {
1228
1457
  type: "text",
1229
- content: workspaceLines.join("\n")
1458
+ content: renderPnpmWorkspaceConfig({
1459
+ profile: getPackageManagerProfile(packageManager),
1460
+ manageVersions: options.pnpmManageVersions ?? true
1461
+ })
1230
1462
  };
1231
1463
  }
1232
1464
  return { files };
@@ -2375,12 +2607,12 @@ function renderMonorepo(params) {
2375
2607
  };
2376
2608
  const engines = {};
2377
2609
  if (isPnpm && packageManager.version) {
2378
- const majorVersion = packageManager.version.split(".")[0];
2610
+ const majorVersion = getSemverMajorString(packageManager.version);
2379
2611
  engines.pnpm = `>=${majorVersion}.0.0`;
2380
2612
  rootPackageJson.packageManager = formatPackageManager(packageManager);
2381
2613
  }
2382
2614
  if (engine?.version) {
2383
- const majorVersion = engine.version.split(".")[0];
2615
+ const majorVersion = getSemverMajorString(engine.version);
2384
2616
  engines[engine.name] = `>=${majorVersion}.0.0`;
2385
2617
  }
2386
2618
  if (Object.keys(engines).length > 0) {
@@ -2391,15 +2623,13 @@ function renderMonorepo(params) {
2391
2623
  content: JSON.stringify(rootPackageJson, null, 2)
2392
2624
  };
2393
2625
  if (isPnpm) {
2394
- const workspaceLines = [];
2395
- if (pnpmManageVersions) {
2396
- workspaceLines.push("manage-package-manager-versions: true", "");
2397
- }
2398
- workspaceLines.push("packages:", ' - ".config/*"', ' - "apps/*"', ' - "packages/*"', "");
2399
- workspaceLines.push("onlyBuiltDependencies:", " - esbuild");
2400
2626
  files["pnpm-workspace.yaml"] = {
2401
2627
  type: "text",
2402
- content: workspaceLines.join("\n")
2628
+ content: renderPnpmWorkspaceConfig({
2629
+ profile: getPackageManagerProfile(packageManager),
2630
+ manageVersions: pnpmManageVersions,
2631
+ packages: [".config/*", "apps/*", "packages/*"]
2632
+ })
2403
2633
  };
2404
2634
  }
2405
2635
  files["tsconfig.json"] = {
@@ -3624,6 +3854,21 @@ async function resolveWorkspaceFacts(input) {
3624
3854
  });
3625
3855
  }
3626
3856
 
3857
+ function materializeJobs(jobs) {
3858
+ const files = {};
3859
+ for (const job of jobs) {
3860
+ if (job.type === "write-file") {
3861
+ files[job.path] = job.file;
3862
+ } else if (job.type === "merge-pnpm-workspace") {
3863
+ files[job.path] = {
3864
+ type: "text",
3865
+ content: job.content
3866
+ };
3867
+ }
3868
+ }
3869
+ return files;
3870
+ }
3871
+
3627
3872
  async function planProject(input) {
3628
3873
  const planInput = isProjectPlanInput(input) ? input : resolveProjectPlanInput(input);
3629
3874
  return createProjectPlan(await resolveProjectFacts(planInput));
@@ -3902,8 +4147,13 @@ function createProjectPlan(planInput) {
3902
4147
  platforms: planInput.aiAgents.config.platforms
3903
4148
  });
3904
4149
  }
4150
+ const jobs = Object.entries(files).map(([path, file]) => ({
4151
+ type: "write-file",
4152
+ path,
4153
+ file
4154
+ }));
3905
4155
  return {
3906
- files,
4156
+ files: materializeJobs(jobs),
3907
4157
  dependencies,
3908
4158
  devDependencies,
3909
4159
  peerDependencies,
@@ -3931,8 +4181,13 @@ async function planWorkspace(input) {
3931
4181
  const planInput = isWorkspacePlanInput(input) ? input : resolveWorkspacePlanInput(input);
3932
4182
  const resolvedInput = await resolveWorkspaceFacts(planInput);
3933
4183
  const { files } = renderMonorepo(workspacePlanInputToMonorepoParams(resolvedInput));
4184
+ const jobs = Object.entries(files).map(([path, file]) => ({
4185
+ type: "write-file",
4186
+ path,
4187
+ file
4188
+ }));
3934
4189
  return {
3935
- files,
4190
+ files: materializeJobs(jobs),
3936
4191
  dependencies: {},
3937
4192
  devDependencies: {},
3938
4193
  peerDependencies: {},
@@ -3948,11 +4203,22 @@ async function planWorkspace(input) {
3948
4203
  exports.AI_PLATFORM_HINTS = AI_PLATFORM_HINTS;
3949
4204
  exports.AI_PLATFORM_LABELS = AI_PLATFORM_LABELS;
3950
4205
  exports.ALL_AI_PLATFORMS = ALL_AI_PLATFORMS;
4206
+ exports.DEFAULT_MINIMUM_RELEASE_AGE_MINUTES = DEFAULT_MINIMUM_RELEASE_AGE_MINUTES;
4207
+ exports.assignResolvedPackageVersion = assignResolvedPackageVersion;
4208
+ exports.clearConfig = clearConfig;
4209
+ exports.compareNumericSemver = compareNumericSemver;
3951
4210
  exports.detectTooling = detectTooling;
4211
+ exports.formatEngine = formatEngine;
4212
+ exports.formatNodeTypesVersion = formatNodeTypesVersion;
4213
+ exports.formatPackageManager = formatPackageManager;
3952
4214
  exports.formatResolvedPackageVersion = formatResolvedPackageVersion;
3953
4215
  exports.generateRandomName = generateRandomName;
4216
+ exports.getAiPlatforms = getAiPlatforms;
3954
4217
  exports.getBaseTemplate = getBaseTemplate;
4218
+ exports.getConfigPath = getConfigPath;
4219
+ exports.getConfigStrategy = getConfigStrategy;
3955
4220
  exports.getEngineName = getEngineName;
4221
+ exports.getEngineSpec = getEngineSpec;
3956
4222
  exports.getLanguageFromTemplate = getLanguageFromTemplate;
3957
4223
  exports.getLatestNodeVersion = getLatestNodeVersion;
3958
4224
  exports.getLatestNpmCliVersion = getLatestNpmCliVersion;
@@ -3961,13 +4227,21 @@ exports.getLatestNpmMajorVersionAtOrBelow = getLatestNpmMajorVersionAtOrBelow;
3961
4227
  exports.getLatestNpmVersion = getLatestNpmVersion;
3962
4228
  exports.getLatestPnpmVersion = getLatestPnpmVersion;
3963
4229
  exports.getLatestYarnVersion = getLatestYarnVersion;
4230
+ exports.getPackageDirectoryName = getPackageDirectoryName;
4231
+ exports.getPackageFallbackVersion = getPackageFallbackVersion;
3964
4232
  exports.getPackageManagerName = getPackageManagerName;
4233
+ exports.getPackageManagerProfile = getPackageManagerProfile;
4234
+ exports.getPackageManagerSpec = getPackageManagerSpec;
3965
4235
  exports.getResolvedPackageVersion = getResolvedPackageVersion;
4236
+ exports.getSemverMajor = getSemverMajor;
4237
+ exports.getSemverMajorString = getSemverMajorString;
4238
+ exports.isPackageManagerName = isPackageManagerName;
4239
+ exports.materializeJobs = materializeJobs;
3966
4240
  exports.merge = merge;
3967
4241
  exports.mergePackageJsonScripts = mergePackageJsonScripts;
3968
4242
  exports.packageJsonScripts = packageJsonScripts;
3969
4243
  exports.parseEngine = parseEngine;
3970
- exports.parsePackageManager = parsePackageManager;
4244
+ exports.parsePackageManagerSpec = parsePackageManagerSpec;
3971
4245
  exports.parseWorkspaceYamlContent = parseWorkspaceYamlContent;
3972
4246
  exports.planProject = planProject;
3973
4247
  exports.planWorkspace = planWorkspace;
@@ -3979,17 +4253,28 @@ exports.renderGitignore = renderGitignore;
3979
4253
  exports.renderOxfmtConfigPackage = renderOxfmtConfigPackage;
3980
4254
  exports.renderOxlintConfig = renderOxlintConfig;
3981
4255
  exports.renderOxlintConfigPackage = renderOxlintConfigPackage;
4256
+ exports.renderPnpmWorkspaceConfig = renderPnpmWorkspaceConfig;
3982
4257
  exports.renderPrettierConfigPackage = renderPrettierConfigPackage;
3983
4258
  exports.renderTypescriptConfigPackage = renderTypescriptConfigPackage;
3984
4259
  exports.renderViteConfig = renderViteConfig;
3985
4260
  exports.renderVscodeFiles = renderVscodeFiles;
3986
4261
  exports.renderVscodeFiles$1 = renderVscodeFiles$1;
3987
4262
  exports.resolveDefaultPackageJsonScripts = resolveDefaultPackageJsonScripts;
4263
+ exports.resolveEngine = resolveEngine;
3988
4264
  exports.resolveMonorepoRootPackageVersions = resolveMonorepoRootPackageVersions;
4265
+ exports.resolvePackageManager = resolvePackageManager;
4266
+ exports.resolvePackageManagerProfile = resolvePackageManagerProfile;
4267
+ exports.resolvePackageVersions = resolvePackageVersions;
4268
+ exports.resolveProjectFacts = resolveProjectFacts;
4269
+ exports.resolveProjectPackageVersions = resolveProjectPackageVersions;
3989
4270
  exports.resolveProjectPlanInput = resolveProjectPlanInput;
4271
+ exports.resolveWorkspaceFacts = resolveWorkspaceFacts;
3990
4272
  exports.resolveWorkspacePlanInput = resolveWorkspacePlanInput;
4273
+ exports.setAiPlatforms = setAiPlatforms;
4274
+ exports.setConfigStrategy = setConfigStrategy;
3991
4275
  exports.shouldEnableReactCompiler = shouldEnableReactCompiler;
3992
4276
  exports.toPrettierIgnoreContent = toPrettierIgnoreContent;
3993
4277
  exports.unique = unique;
3994
4278
  exports.validatePackageName = validatePackageName;
4279
+ exports.validateWorkspace = validateWorkspace;
3995
4280
  exports.workspacePlanInputToMonorepoParams = workspacePlanInputToMonorepoParams;