create-krispya 0.6.0 → 0.8.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.
- package/README.md +13 -341
- package/dist/chunks/index.cjs +741 -451
- package/dist/chunks/index.mjs +731 -452
- package/dist/cli.cjs +374 -573
- package/dist/cli.mjs +364 -563
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +40 -34
- package/dist/index.d.mts +40 -34
- package/dist/index.d.ts +40 -34
- package/dist/index.mjs +2 -2
- package/package.json +32 -15
- package/LICENSE +0 -15
package/dist/cli.cjs
CHANGED
|
@@ -1,32 +1,35 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
const module$1 = require('module');
|
|
5
|
-
const process$1 = require('process');
|
|
6
|
-
const path = require('path');
|
|
7
|
-
const promises = require('fs/promises');
|
|
8
|
-
const fs = require('fs');
|
|
9
|
-
const commander = require('commander');
|
|
10
4
|
const p = require('@clack/prompts');
|
|
11
5
|
const color = require('chalk');
|
|
6
|
+
const commander = require('commander');
|
|
7
|
+
const node_fs = require('node:fs');
|
|
8
|
+
const promises$1 = require('node:fs/promises');
|
|
9
|
+
const node_module = require('node:module');
|
|
10
|
+
const node_path = require('node:path');
|
|
11
|
+
const node_process = require('node:process');
|
|
12
12
|
const undici = require('undici');
|
|
13
13
|
const child_process = require('child_process');
|
|
14
14
|
const index = require('./chunks/index.cjs');
|
|
15
15
|
const Conf = require('conf');
|
|
16
|
+
const promises = require('fs/promises');
|
|
17
|
+
const fs = require('fs');
|
|
18
|
+
const path = require('path');
|
|
16
19
|
|
|
17
20
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
18
21
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
19
22
|
|
|
20
23
|
function _interopNamespaceCompat(e) {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
if (e && typeof e === 'object' && 'default' in e) return e;
|
|
25
|
+
const n = Object.create(null);
|
|
26
|
+
if (e) {
|
|
27
|
+
for (const k in e) {
|
|
28
|
+
n[k] = e[k];
|
|
29
|
+
}
|
|
26
30
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return n;
|
|
31
|
+
n.default = e;
|
|
32
|
+
return n;
|
|
30
33
|
}
|
|
31
34
|
|
|
32
35
|
const p__namespace = /*#__PURE__*/_interopNamespaceCompat(p);
|
|
@@ -85,11 +88,19 @@ function formatConfigSummary(options, inherited) {
|
|
|
85
88
|
} else {
|
|
86
89
|
lines.push(formatRow("Bundler", "vite"));
|
|
87
90
|
}
|
|
88
|
-
const
|
|
89
|
-
lines.push(
|
|
91
|
+
const engineInherited = inherited?.engine !== void 0;
|
|
92
|
+
lines.push(
|
|
93
|
+
formatRow(
|
|
94
|
+
"Engine",
|
|
95
|
+
`${index.getEngineName(options.engine)}@${options.engine?.version ?? "latest"}`,
|
|
96
|
+
engineInherited
|
|
97
|
+
)
|
|
98
|
+
);
|
|
90
99
|
const pmInherited = inherited?.packageManager !== void 0;
|
|
91
|
-
lines.push(
|
|
92
|
-
|
|
100
|
+
lines.push(
|
|
101
|
+
formatRow("Package manager", index.getPackageManagerName(options.packageManager), pmInherited)
|
|
102
|
+
);
|
|
103
|
+
if (index.getPackageManagerName(options.packageManager) === "pnpm") {
|
|
93
104
|
const versionManaged = options.pnpmManageVersions ? "yes" : "no";
|
|
94
105
|
const pnpmVersionInherited = inherited?.pnpmManageVersions !== void 0;
|
|
95
106
|
lines.push(formatRow("\u21B3 Version managed", versionManaged, pnpmVersionInherited, ""));
|
|
@@ -143,8 +154,10 @@ function formatMonorepoConfigSummary(options) {
|
|
|
143
154
|
const dots = color__default.gray(".".repeat(dotCount));
|
|
144
155
|
return `${indent}${label} ${dots} ${value}`;
|
|
145
156
|
};
|
|
146
|
-
lines.push(
|
|
147
|
-
|
|
157
|
+
lines.push(
|
|
158
|
+
formatRow("Engine", `${index.getEngineName(options.engine)}@${options.engine.version ?? "latest"}`)
|
|
159
|
+
);
|
|
160
|
+
lines.push(formatRow("Package manager", options.packageManager));
|
|
148
161
|
if (options.packageManager === "pnpm") {
|
|
149
162
|
const versionManaged = options.pnpmManageVersions ? "yes" : "no";
|
|
150
163
|
lines.push(formatRow("\u21B3 Version managed", versionManaged, ""));
|
|
@@ -172,9 +185,6 @@ function setReuseWindow(reuse) {
|
|
|
172
185
|
function getAiPlatforms() {
|
|
173
186
|
return config.get("aiPlatforms");
|
|
174
187
|
}
|
|
175
|
-
function setAiPlatforms(platforms) {
|
|
176
|
-
config.set("aiPlatforms", platforms);
|
|
177
|
-
}
|
|
178
188
|
function getConfigStrategy() {
|
|
179
189
|
return config.get("configStrategy") ?? "stealth";
|
|
180
190
|
}
|
|
@@ -195,9 +205,9 @@ function getDefaultOptions(template, name, projectType = "app", libraryBundler,
|
|
|
195
205
|
template,
|
|
196
206
|
projectType,
|
|
197
207
|
libraryBundler: projectType === "library" ? libraryBundler ?? "unbuild" : void 0,
|
|
198
|
-
packageManager: inheritedSettings?.packageManager ?? "pnpm",
|
|
208
|
+
packageManager: inheritedSettings?.packageManager ?? { name: "pnpm" },
|
|
199
209
|
pnpmManageVersions: inheritedSettings?.pnpmManageVersions ?? true,
|
|
200
|
-
|
|
210
|
+
engine: inheritedSettings?.engine ?? { name: "node", version: "latest" },
|
|
201
211
|
linter: inheritedSettings?.linter ?? "oxlint",
|
|
202
212
|
formatter: inheritedSettings?.formatter ?? "prettier",
|
|
203
213
|
// Libraries get vitest by default, apps don't
|
|
@@ -292,14 +302,14 @@ async function promptForCustomization(template, name, projectType, integrations,
|
|
|
292
302
|
}
|
|
293
303
|
libraryBundler = bundler;
|
|
294
304
|
}
|
|
295
|
-
let
|
|
296
|
-
let finalPackageManager = inheritedSettings?.packageManager ?? presets?.packageManager ?? "pnpm";
|
|
305
|
+
let engine = inheritedSettings?.engine ?? presets?.engine ?? { name: "node", version: "latest" };
|
|
306
|
+
let finalPackageManager = inheritedSettings?.packageManager?.name ?? presets?.packageManager ?? "pnpm";
|
|
297
307
|
let pnpmManageVersions = inheritedSettings?.pnpmManageVersions ?? presets?.pnpmManageVersions ?? true;
|
|
298
|
-
if (!inheritedSettings?.
|
|
308
|
+
if (!inheritedSettings?.engine?.version) {
|
|
299
309
|
const nodeVersionInput = await p__namespace.text({
|
|
300
310
|
message: "Node.js version",
|
|
301
|
-
placeholder: presets?.
|
|
302
|
-
defaultValue: presets?.
|
|
311
|
+
placeholder: presets?.engine?.version ?? "latest",
|
|
312
|
+
defaultValue: presets?.engine?.version ?? "latest",
|
|
303
313
|
validate: (value) => {
|
|
304
314
|
if (!value.length) return "Required";
|
|
305
315
|
if (value !== "latest" && !/^\d+(\.\d+(\.\d+)?)?$/.test(value)) {
|
|
@@ -311,7 +321,7 @@ async function promptForCustomization(template, name, projectType, integrations,
|
|
|
311
321
|
p__namespace.cancel("Operation cancelled.");
|
|
312
322
|
process.exit(0);
|
|
313
323
|
}
|
|
314
|
-
|
|
324
|
+
engine = { name: "node", version: nodeVersionInput };
|
|
315
325
|
}
|
|
316
326
|
if (!inheritedSettings?.packageManager) {
|
|
317
327
|
const packageManager = await p__namespace.select({
|
|
@@ -417,8 +427,8 @@ async function promptForCustomization(template, name, projectType, integrations,
|
|
|
417
427
|
template: finalTemplate,
|
|
418
428
|
projectType,
|
|
419
429
|
libraryBundler: projectType === "library" ? libraryBundler : void 0,
|
|
420
|
-
|
|
421
|
-
packageManager: finalPackageManager,
|
|
430
|
+
engine,
|
|
431
|
+
packageManager: { name: finalPackageManager },
|
|
422
432
|
pnpmManageVersions,
|
|
423
433
|
linter,
|
|
424
434
|
formatter,
|
|
@@ -464,9 +474,9 @@ function getDefaultMonorepoOptions(name) {
|
|
|
464
474
|
return {
|
|
465
475
|
name,
|
|
466
476
|
projectType: "monorepo",
|
|
467
|
-
packageManager: "pnpm",
|
|
477
|
+
packageManager: { name: "pnpm" },
|
|
468
478
|
pnpmManageVersions: true,
|
|
469
|
-
|
|
479
|
+
engine: { name: "node", version: "latest" },
|
|
470
480
|
linter: "oxlint",
|
|
471
481
|
formatter: "prettier"
|
|
472
482
|
};
|
|
@@ -474,8 +484,8 @@ function getDefaultMonorepoOptions(name) {
|
|
|
474
484
|
async function promptForMonorepoCustomization(name, presets) {
|
|
475
485
|
const nodeVersion = await p__namespace.text({
|
|
476
486
|
message: "Node.js version",
|
|
477
|
-
placeholder: presets?.
|
|
478
|
-
defaultValue: presets?.
|
|
487
|
+
placeholder: presets?.engine?.version ?? "latest",
|
|
488
|
+
defaultValue: presets?.engine?.version ?? "latest",
|
|
479
489
|
validate: (value) => {
|
|
480
490
|
if (!value.length) return "Required";
|
|
481
491
|
if (value !== "latest" && !/^\d+(\.\d+(\.\d+)?)?$/.test(value)) {
|
|
@@ -524,8 +534,8 @@ async function promptForMonorepoCustomization(name, presets) {
|
|
|
524
534
|
return {
|
|
525
535
|
name,
|
|
526
536
|
projectType: "monorepo",
|
|
527
|
-
nodeVersion,
|
|
528
|
-
packageManager: "pnpm",
|
|
537
|
+
engine: { name: "node", version: nodeVersion },
|
|
538
|
+
packageManager: { name: "pnpm" },
|
|
529
539
|
pnpmManageVersions: managePnpm,
|
|
530
540
|
linter,
|
|
531
541
|
formatter
|
|
@@ -536,15 +546,15 @@ async function promptForMonorepo(workspaceName, presets) {
|
|
|
536
546
|
if (presets) {
|
|
537
547
|
if (presets.linter) defaultOptions.linter = presets.linter;
|
|
538
548
|
if (presets.formatter) defaultOptions.formatter = presets.formatter;
|
|
539
|
-
if (presets.
|
|
549
|
+
if (presets.engine) defaultOptions.engine = presets.engine;
|
|
540
550
|
if (presets.pnpmManageVersions !== void 0)
|
|
541
551
|
defaultOptions.pnpmManageVersions = presets.pnpmManageVersions;
|
|
542
552
|
}
|
|
543
553
|
p__namespace.note(
|
|
544
554
|
formatMonorepoConfigSummary({
|
|
545
555
|
name: defaultOptions.name,
|
|
546
|
-
|
|
547
|
-
packageManager: defaultOptions.packageManager
|
|
556
|
+
engine: defaultOptions.engine ?? { name: "node", version: "latest" },
|
|
557
|
+
packageManager: index.getPackageManagerName(defaultOptions.packageManager),
|
|
548
558
|
pnpmManageVersions: defaultOptions.pnpmManageVersions,
|
|
549
559
|
linter: defaultOptions.linter ?? "oxlint",
|
|
550
560
|
formatter: defaultOptions.formatter ?? "prettier"
|
|
@@ -601,12 +611,7 @@ async function promptForOptions(name, presets) {
|
|
|
601
611
|
if (projectType === "monorepo") {
|
|
602
612
|
return promptForMonorepo(projectName, presets);
|
|
603
613
|
}
|
|
604
|
-
return promptForPackageOptions(
|
|
605
|
-
projectName,
|
|
606
|
-
projectType,
|
|
607
|
-
void 0,
|
|
608
|
-
presets
|
|
609
|
-
);
|
|
614
|
+
return promptForPackageOptions(projectName, projectType, void 0, presets);
|
|
610
615
|
}
|
|
611
616
|
function customTemplateToOptions(customTemplate, name, projectType, inheritedSettings) {
|
|
612
617
|
const baseTemplate = customTemplate.baseTemplate;
|
|
@@ -615,9 +620,9 @@ function customTemplateToOptions(customTemplate, name, projectType, inheritedSet
|
|
|
615
620
|
name,
|
|
616
621
|
template,
|
|
617
622
|
projectType,
|
|
618
|
-
packageManager: inheritedSettings?.packageManager ?? "pnpm",
|
|
623
|
+
packageManager: inheritedSettings?.packageManager ?? { name: "pnpm" },
|
|
619
624
|
pnpmManageVersions: inheritedSettings?.pnpmManageVersions ?? true,
|
|
620
|
-
|
|
625
|
+
engine: inheritedSettings?.engine ?? { name: "node", version: "latest" },
|
|
621
626
|
linter: inheritedSettings?.linter ?? customTemplate.linter,
|
|
622
627
|
formatter: inheritedSettings?.formatter ?? customTemplate.formatter,
|
|
623
628
|
testing: customTemplate.testing,
|
|
@@ -648,8 +653,8 @@ function presetsToInheritedSettings(presets) {
|
|
|
648
653
|
return {
|
|
649
654
|
linter: presets.linter,
|
|
650
655
|
formatter: presets.formatter,
|
|
651
|
-
packageManager: presets.packageManager,
|
|
652
|
-
|
|
656
|
+
packageManager: presets.packageManager ? { name: presets.packageManager } : void 0,
|
|
657
|
+
engine: presets.engine,
|
|
653
658
|
pnpmManageVersions: presets.pnpmManageVersions
|
|
654
659
|
};
|
|
655
660
|
}
|
|
@@ -751,53 +756,9 @@ async function promptForPackageOptions(projectName, projectType, inheritedSettin
|
|
|
751
756
|
);
|
|
752
757
|
}
|
|
753
758
|
|
|
754
|
-
async function
|
|
755
|
-
for (const path of paths) {
|
|
756
|
-
try {
|
|
757
|
-
await promises.access(path, promises.constants.F_OK);
|
|
758
|
-
return true;
|
|
759
|
-
} catch {
|
|
760
|
-
}
|
|
761
|
-
}
|
|
762
|
-
return false;
|
|
763
|
-
}
|
|
764
|
-
async function validateWorkspace(monorepoRoot) {
|
|
765
|
-
const errors = [];
|
|
766
|
-
const tsConfigPath = path.join(monorepoRoot, ".config/typescript/package.json");
|
|
767
|
-
try {
|
|
768
|
-
await promises.access(tsConfigPath, promises.constants.F_OK);
|
|
769
|
-
} catch {
|
|
770
|
-
errors.push("Missing .config/typescript package");
|
|
771
|
-
}
|
|
772
|
-
const linterPaths = [
|
|
773
|
-
path.join(monorepoRoot, ".config/oxlint/package.json"),
|
|
774
|
-
path.join(monorepoRoot, ".config/eslint/package.json"),
|
|
775
|
-
path.join(monorepoRoot, "eslint.config.js"),
|
|
776
|
-
path.join(monorepoRoot, "biome.json")
|
|
777
|
-
];
|
|
778
|
-
const hasLinter = await checkAnyExists(linterPaths);
|
|
779
|
-
if (!hasLinter) {
|
|
780
|
-
errors.push(
|
|
781
|
-
"Missing linter config (.config/oxlint, .config/eslint, eslint.config.js, or biome.json)"
|
|
782
|
-
);
|
|
783
|
-
}
|
|
784
|
-
const formatterPaths = [
|
|
785
|
-
path.join(monorepoRoot, ".config/oxfmt/package.json"),
|
|
786
|
-
path.join(monorepoRoot, ".config/prettier/package.json"),
|
|
787
|
-
path.join(monorepoRoot, ".prettierrc.json"),
|
|
788
|
-
path.join(monorepoRoot, "biome.json")
|
|
789
|
-
];
|
|
790
|
-
const hasFormatter = await checkAnyExists(formatterPaths);
|
|
791
|
-
if (!hasFormatter) {
|
|
792
|
-
errors.push(
|
|
793
|
-
"Missing formatter config (.config/oxfmt, .config/prettier, .prettierrc.json, or biome.json)"
|
|
794
|
-
);
|
|
795
|
-
}
|
|
796
|
-
return { valid: errors.length === 0, errors };
|
|
797
|
-
}
|
|
798
|
-
|
|
799
|
-
async function detectCurrentConfig(root) {
|
|
759
|
+
async function detectCurrentConfig(root, isMonorepo = true) {
|
|
800
760
|
let name = root.split(/[/\\]/).pop() ?? "workspace";
|
|
761
|
+
let packageManager = "pnpm";
|
|
801
762
|
try {
|
|
802
763
|
const pkgPath = path.join(root, "package.json");
|
|
803
764
|
const content = await promises.readFile(pkgPath, "utf-8");
|
|
@@ -805,47 +766,63 @@ async function detectCurrentConfig(root) {
|
|
|
805
766
|
if (pkgJson.name) {
|
|
806
767
|
name = pkgJson.name.replace(/^@/, "").replace(/\/.*$/, "");
|
|
807
768
|
}
|
|
769
|
+
if (pkgJson.packageManager) {
|
|
770
|
+
packageManager = pkgJson.packageManager.split("@")[0] ?? packageManager;
|
|
771
|
+
}
|
|
808
772
|
} catch {
|
|
809
773
|
}
|
|
810
774
|
const tooling = await index.detectTooling(root);
|
|
775
|
+
const configStrategy = isMonorepo ? void 0 : await detectStandaloneConfigStrategy(root);
|
|
811
776
|
return {
|
|
812
777
|
name,
|
|
813
778
|
linter: tooling.linter ?? "oxlint",
|
|
814
779
|
formatter: tooling.formatter ?? "prettier",
|
|
815
|
-
packageManager
|
|
780
|
+
packageManager,
|
|
781
|
+
isMonorepo,
|
|
782
|
+
configStrategy
|
|
816
783
|
};
|
|
817
784
|
}
|
|
818
|
-
function
|
|
819
|
-
const
|
|
785
|
+
async function detectStandaloneConfigStrategy(root) {
|
|
786
|
+
const hasStealthConfig = await Promise.all([
|
|
787
|
+
fileExists$1(path.join(root, ".config/tsconfig.app.json")),
|
|
788
|
+
fileExists$1(path.join(root, ".config/tsconfig.node.json")),
|
|
789
|
+
fileExists$1(path.join(root, ".config/prettier.json")),
|
|
790
|
+
fileExists$1(path.join(root, ".config/oxlint.json"))
|
|
791
|
+
]).then((matches) => matches.some(Boolean));
|
|
792
|
+
return hasStealthConfig ? "stealth" : "root";
|
|
793
|
+
}
|
|
794
|
+
async function generateExpectedFiles(config) {
|
|
795
|
+
const { name, linter, formatter, packageManager, isMonorepo, configStrategy } = config;
|
|
796
|
+
const versions = linter === "biome" || formatter === "biome" ? await index.resolveMonorepoRootPackageVersions({ linter, formatter }) : {};
|
|
820
797
|
const aiFilesMap = {};
|
|
821
798
|
index.generateAiFiles(aiFilesMap, {
|
|
822
799
|
name,
|
|
823
800
|
packageManager,
|
|
824
801
|
linter,
|
|
825
802
|
formatter,
|
|
826
|
-
isMonorepo
|
|
803
|
+
isMonorepo,
|
|
804
|
+
configStrategy,
|
|
827
805
|
platforms: index.ALL_AI_PLATFORMS
|
|
828
806
|
});
|
|
829
807
|
const vscodeFiles = {};
|
|
830
808
|
index.generateVscodeFiles(vscodeFiles, linter, formatter);
|
|
831
809
|
const configPackages = {};
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
810
|
+
if (isMonorepo) {
|
|
811
|
+
index.generateTypescriptConfigPackage(configPackages);
|
|
812
|
+
if (linter === "oxlint") {
|
|
813
|
+
index.generateOxlintConfigPackage(configPackages);
|
|
814
|
+
} else if (linter === "eslint") {
|
|
815
|
+
index.generateEslintConfigPackage(configPackages);
|
|
816
|
+
}
|
|
817
|
+
if (formatter === "oxfmt") {
|
|
818
|
+
index.generateOxfmtConfigPackage(configPackages);
|
|
819
|
+
} else if (formatter === "prettier") {
|
|
820
|
+
index.generatePrettierConfigPackage(configPackages);
|
|
821
|
+
}
|
|
842
822
|
}
|
|
843
823
|
const workspaceConfig = {};
|
|
844
824
|
const rootConfig = {};
|
|
845
|
-
rootConfig[".gitignore"] =
|
|
846
|
-
type: "text",
|
|
847
|
-
content: ["node_modules", "dist", "*.tsbuildinfo", ".DS_Store"].join("\n")
|
|
848
|
-
};
|
|
825
|
+
rootConfig[".gitignore"] = index.generateGitignore(isMonorepo ? "workspace-root" : "standalone");
|
|
849
826
|
rootConfig[".gitattributes"] = {
|
|
850
827
|
type: "text",
|
|
851
828
|
content: `* text=auto eol=lf
|
|
@@ -854,8 +831,9 @@ function generateExpectedFiles(config) {
|
|
|
854
831
|
`
|
|
855
832
|
};
|
|
856
833
|
if (linter === "biome" || formatter === "biome") {
|
|
834
|
+
const biomeVersion = index.getResolvedPackageVersion(versions, "@biomejs/biome");
|
|
857
835
|
const biomeConfig = {
|
|
858
|
-
$schema:
|
|
836
|
+
$schema: `https://biomejs.dev/schemas/${biomeVersion}/schema.json`,
|
|
859
837
|
vcs: {
|
|
860
838
|
enabled: true,
|
|
861
839
|
clientKind: "git",
|
|
@@ -989,9 +967,7 @@ onlyBuiltDependencies:
|
|
|
989
967
|
}
|
|
990
968
|
if (!currentContent.includes(".config/*") && !currentContent.includes('".config/*"')) {
|
|
991
969
|
const lines = updatedContent.split("\n");
|
|
992
|
-
const packagesIndex = lines.findIndex(
|
|
993
|
-
(line) => line.trim().startsWith("packages:")
|
|
994
|
-
);
|
|
970
|
+
const packagesIndex = lines.findIndex((line) => line.trim().startsWith("packages:"));
|
|
995
971
|
if (packagesIndex !== -1) {
|
|
996
972
|
lines.splice(packagesIndex + 1, 0, ' - ".config/*"');
|
|
997
973
|
updatedContent = lines.join("\n");
|
|
@@ -1057,6 +1033,14 @@ function needsMigration(current, target) {
|
|
|
1057
1033
|
async function getMigrationPlan(current, target, root) {
|
|
1058
1034
|
const toLinter = target.linter ?? current.linter;
|
|
1059
1035
|
const toFormatter = target.formatter ?? current.formatter;
|
|
1036
|
+
const targetVersions = toLinter === "biome" || toFormatter === "biome" ? await index.resolveMonorepoRootPackageVersions({
|
|
1037
|
+
linter: toLinter,
|
|
1038
|
+
formatter: toFormatter
|
|
1039
|
+
}) : {};
|
|
1040
|
+
const biomeSchemaUrl = toLinter === "biome" || toFormatter === "biome" ? `https://biomejs.dev/schemas/${index.getResolvedPackageVersion(
|
|
1041
|
+
targetVersions,
|
|
1042
|
+
"@biomejs/biome"
|
|
1043
|
+
)}/schema.json` : "";
|
|
1060
1044
|
const changes = [];
|
|
1061
1045
|
if (toLinter !== current.linter) {
|
|
1062
1046
|
if (current.linter !== "biome") {
|
|
@@ -1091,7 +1075,7 @@ async function getMigrationPlan(current, target, root) {
|
|
|
1091
1075
|
description: "Add biome.json config",
|
|
1092
1076
|
content: JSON.stringify(
|
|
1093
1077
|
{
|
|
1094
|
-
$schema:
|
|
1078
|
+
$schema: biomeSchemaUrl,
|
|
1095
1079
|
vcs: { enabled: true, clientKind: "git", useIgnoreFile: true },
|
|
1096
1080
|
linter: { enabled: true, rules: { recommended: true } },
|
|
1097
1081
|
formatter: { enabled: true }
|
|
@@ -1107,7 +1091,7 @@ async function getMigrationPlan(current, target, root) {
|
|
|
1107
1091
|
description: "Add biome.json config (linter only)",
|
|
1108
1092
|
content: JSON.stringify(
|
|
1109
1093
|
{
|
|
1110
|
-
$schema:
|
|
1094
|
+
$schema: biomeSchemaUrl,
|
|
1111
1095
|
vcs: { enabled: true, clientKind: "git", useIgnoreFile: true },
|
|
1112
1096
|
linter: { enabled: true, rules: { recommended: true } },
|
|
1113
1097
|
formatter: { enabled: false }
|
|
@@ -1160,7 +1144,7 @@ async function getMigrationPlan(current, target, root) {
|
|
|
1160
1144
|
description: "Add biome.json config (formatter only)",
|
|
1161
1145
|
content: JSON.stringify(
|
|
1162
1146
|
{
|
|
1163
|
-
$schema:
|
|
1147
|
+
$schema: biomeSchemaUrl,
|
|
1164
1148
|
vcs: { enabled: true, clientKind: "git", useIgnoreFile: true },
|
|
1165
1149
|
linter: { enabled: false },
|
|
1166
1150
|
formatter: { enabled: true }
|
|
@@ -1183,12 +1167,7 @@ async function getMigrationPlan(current, target, root) {
|
|
|
1183
1167
|
path: "package.json",
|
|
1184
1168
|
description: "Update root package.json (devDependencies, scripts)"
|
|
1185
1169
|
});
|
|
1186
|
-
const subPackageUpdates = await getSubPackageUpdates(
|
|
1187
|
-
root,
|
|
1188
|
-
current,
|
|
1189
|
-
toLinter,
|
|
1190
|
-
toFormatter
|
|
1191
|
-
);
|
|
1170
|
+
const subPackageUpdates = await getSubPackageUpdates(root, current, toLinter, toFormatter);
|
|
1192
1171
|
return {
|
|
1193
1172
|
fromLinter: current.linter,
|
|
1194
1173
|
toLinter,
|
|
@@ -1298,23 +1277,15 @@ async function updateRootPackageJson(root, plan) {
|
|
|
1298
1277
|
const oldFormatterDep = FORMATTER_DEPS[plan.fromFormatter];
|
|
1299
1278
|
delete devDeps[oldFormatterDep];
|
|
1300
1279
|
}
|
|
1280
|
+
const resolvedVersions = await index.resolveMonorepoRootPackageVersions({
|
|
1281
|
+
linter: plan.toLinter,
|
|
1282
|
+
formatter: plan.toFormatter
|
|
1283
|
+
});
|
|
1301
1284
|
const newLinterDep = LINTER_DEPS[plan.toLinter];
|
|
1302
|
-
|
|
1303
|
-
devDeps[newLinterDep] = "^1.36.0";
|
|
1304
|
-
} else if (plan.toLinter === "eslint") {
|
|
1305
|
-
devDeps[newLinterDep] = "^9.17.0";
|
|
1306
|
-
} else if (plan.toLinter === "biome") {
|
|
1307
|
-
devDeps[newLinterDep] = "^1.9.4";
|
|
1308
|
-
}
|
|
1285
|
+
devDeps[newLinterDep] = index.formatResolvedPackageVersion(resolvedVersions, newLinterDep);
|
|
1309
1286
|
if (plan.toFormatter !== plan.toLinter) {
|
|
1310
1287
|
const newFormatterDep = FORMATTER_DEPS[plan.toFormatter];
|
|
1311
|
-
|
|
1312
|
-
devDeps[newFormatterDep] = "^0.21.0";
|
|
1313
|
-
} else if (plan.toFormatter === "prettier") {
|
|
1314
|
-
devDeps[newFormatterDep] = "^3.4.2";
|
|
1315
|
-
} else if (plan.toFormatter === "biome") {
|
|
1316
|
-
devDeps[newFormatterDep] = "^1.9.4";
|
|
1317
|
-
}
|
|
1288
|
+
devDeps[newFormatterDep] = index.formatResolvedPackageVersion(resolvedVersions, newFormatterDep);
|
|
1318
1289
|
}
|
|
1319
1290
|
pkg.devDependencies = Object.fromEntries(
|
|
1320
1291
|
Object.entries(devDeps).sort(([a], [b]) => a.localeCompare(b))
|
|
@@ -1358,7 +1329,52 @@ function formatMigrationChange(change) {
|
|
|
1358
1329
|
return ` ${icon} ${change.description}`;
|
|
1359
1330
|
}
|
|
1360
1331
|
|
|
1361
|
-
|
|
1332
|
+
async function checkAnyExists(paths) {
|
|
1333
|
+
for (const path of paths) {
|
|
1334
|
+
try {
|
|
1335
|
+
await promises.access(path, promises.constants.F_OK);
|
|
1336
|
+
return true;
|
|
1337
|
+
} catch {
|
|
1338
|
+
}
|
|
1339
|
+
}
|
|
1340
|
+
return false;
|
|
1341
|
+
}
|
|
1342
|
+
async function validateWorkspace(monorepoRoot) {
|
|
1343
|
+
const errors = [];
|
|
1344
|
+
const tsConfigPath = path.join(monorepoRoot, ".config/typescript/package.json");
|
|
1345
|
+
try {
|
|
1346
|
+
await promises.access(tsConfigPath, promises.constants.F_OK);
|
|
1347
|
+
} catch {
|
|
1348
|
+
errors.push("Missing .config/typescript package");
|
|
1349
|
+
}
|
|
1350
|
+
const linterPaths = [
|
|
1351
|
+
path.join(monorepoRoot, ".config/oxlint/package.json"),
|
|
1352
|
+
path.join(monorepoRoot, ".config/eslint/package.json"),
|
|
1353
|
+
path.join(monorepoRoot, "eslint.config.js"),
|
|
1354
|
+
path.join(monorepoRoot, "biome.json")
|
|
1355
|
+
];
|
|
1356
|
+
const hasLinter = await checkAnyExists(linterPaths);
|
|
1357
|
+
if (!hasLinter) {
|
|
1358
|
+
errors.push(
|
|
1359
|
+
"Missing linter config (.config/oxlint, .config/eslint, eslint.config.js, or biome.json)"
|
|
1360
|
+
);
|
|
1361
|
+
}
|
|
1362
|
+
const formatterPaths = [
|
|
1363
|
+
path.join(monorepoRoot, ".config/oxfmt/package.json"),
|
|
1364
|
+
path.join(monorepoRoot, ".config/prettier/package.json"),
|
|
1365
|
+
path.join(monorepoRoot, ".prettierrc.json"),
|
|
1366
|
+
path.join(monorepoRoot, "biome.json")
|
|
1367
|
+
];
|
|
1368
|
+
const hasFormatter = await checkAnyExists(formatterPaths);
|
|
1369
|
+
if (!hasFormatter) {
|
|
1370
|
+
errors.push(
|
|
1371
|
+
"Missing formatter config (.config/oxfmt, .config/prettier, .prettierrc.json, or biome.json)"
|
|
1372
|
+
);
|
|
1373
|
+
}
|
|
1374
|
+
return { valid: errors.length === 0, errors };
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
const require$1 = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
|
|
1362
1378
|
const pkg = require$1("../package.json");
|
|
1363
1379
|
const META_OPTIONS = [
|
|
1364
1380
|
"clearConfig",
|
|
@@ -1378,7 +1394,7 @@ function hasConfigOptions(options) {
|
|
|
1378
1394
|
}
|
|
1379
1395
|
async function fileExists(path) {
|
|
1380
1396
|
try {
|
|
1381
|
-
await promises.access(path,
|
|
1397
|
+
await promises$1.access(path, node_fs.constants.F_OK);
|
|
1382
1398
|
return true;
|
|
1383
1399
|
} catch {
|
|
1384
1400
|
return false;
|
|
@@ -1409,7 +1425,7 @@ async function promptForAiPlatforms(isNonInteractive) {
|
|
|
1409
1425
|
label: index.AI_PLATFORM_LABELS[platform],
|
|
1410
1426
|
hint: index.AI_PLATFORM_HINTS[platform]
|
|
1411
1427
|
})),
|
|
1412
|
-
initialValues: [],
|
|
1428
|
+
initialValues: ["agents"],
|
|
1413
1429
|
required: false
|
|
1414
1430
|
});
|
|
1415
1431
|
if (p__namespace.isCancel(selected)) {
|
|
@@ -1419,26 +1435,19 @@ async function promptForAiPlatforms(isNonInteractive) {
|
|
|
1419
1435
|
if (platforms.length === 0) {
|
|
1420
1436
|
return [];
|
|
1421
1437
|
}
|
|
1422
|
-
const saveChoice = await p__namespace.confirm({
|
|
1423
|
-
message: "Save selection for future projects?",
|
|
1424
|
-
initialValue: true
|
|
1425
|
-
});
|
|
1426
|
-
if (!p__namespace.isCancel(saveChoice) && saveChoice) {
|
|
1427
|
-
setAiPlatforms(platforms);
|
|
1428
|
-
}
|
|
1429
1438
|
return platforms;
|
|
1430
1439
|
}
|
|
1431
1440
|
async function writeGeneratedFiles(basePath, files) {
|
|
1432
1441
|
const filePaths = Object.keys(files).sort();
|
|
1433
1442
|
for (const filePath of filePaths) {
|
|
1434
|
-
const fullFilePath =
|
|
1435
|
-
await promises.mkdir(
|
|
1443
|
+
const fullFilePath = node_path.join(basePath, filePath);
|
|
1444
|
+
await promises$1.mkdir(node_path.dirname(fullFilePath), { recursive: true });
|
|
1436
1445
|
const file = files[filePath];
|
|
1437
1446
|
if (file.type === "text") {
|
|
1438
|
-
await promises.writeFile(fullFilePath, file.content);
|
|
1447
|
+
await promises$1.writeFile(fullFilePath, file.content);
|
|
1439
1448
|
} else {
|
|
1440
1449
|
const response = await undici.fetch(file.url);
|
|
1441
|
-
await promises.writeFile(fullFilePath, response.body);
|
|
1450
|
+
await promises$1.writeFile(fullFilePath, response.body);
|
|
1442
1451
|
}
|
|
1443
1452
|
}
|
|
1444
1453
|
}
|
|
@@ -1447,26 +1456,37 @@ function calculateWorkspaceRoot(packagePath) {
|
|
|
1447
1456
|
return segments.map(() => "..").join("/");
|
|
1448
1457
|
}
|
|
1449
1458
|
async function detectMonorepoRoot() {
|
|
1450
|
-
let currentDir =
|
|
1451
|
-
const root =
|
|
1459
|
+
let currentDir = node_process.cwd();
|
|
1460
|
+
const root = node_path.resolve("/");
|
|
1452
1461
|
while (currentDir !== root) {
|
|
1453
|
-
const workspaceFile =
|
|
1462
|
+
const workspaceFile = node_path.join(currentDir, "pnpm-workspace.yaml");
|
|
1454
1463
|
try {
|
|
1455
|
-
await promises.access(workspaceFile,
|
|
1456
|
-
const content = await promises.readFile(workspaceFile, "utf-8");
|
|
1464
|
+
await promises$1.access(workspaceFile, node_fs.constants.F_OK);
|
|
1465
|
+
const content = await promises$1.readFile(workspaceFile, "utf-8");
|
|
1457
1466
|
if (content.includes("packages:")) {
|
|
1458
1467
|
return currentDir;
|
|
1459
1468
|
}
|
|
1460
1469
|
} catch {
|
|
1461
1470
|
}
|
|
1462
|
-
currentDir =
|
|
1471
|
+
currentDir = node_path.dirname(currentDir);
|
|
1463
1472
|
}
|
|
1464
1473
|
return null;
|
|
1465
1474
|
}
|
|
1475
|
+
async function detectPackageRoot() {
|
|
1476
|
+
let currentDir = node_process.cwd();
|
|
1477
|
+
const root = node_path.resolve("/");
|
|
1478
|
+
while (currentDir !== root) {
|
|
1479
|
+
if (await fileExists(node_path.join(currentDir, "package.json"))) {
|
|
1480
|
+
return currentDir;
|
|
1481
|
+
}
|
|
1482
|
+
currentDir = node_path.dirname(currentDir);
|
|
1483
|
+
}
|
|
1484
|
+
return await fileExists(node_path.join(root, "package.json")) ? root : null;
|
|
1485
|
+
}
|
|
1466
1486
|
async function parseWorkspaceDirectories(monorepoRoot) {
|
|
1467
1487
|
try {
|
|
1468
|
-
const workspaceFile =
|
|
1469
|
-
const content = await promises.readFile(workspaceFile, "utf-8");
|
|
1488
|
+
const workspaceFile = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
1489
|
+
const content = await promises$1.readFile(workspaceFile, "utf-8");
|
|
1470
1490
|
return index.parseWorkspaceYamlContent(content);
|
|
1471
1491
|
} catch {
|
|
1472
1492
|
return [];
|
|
@@ -1475,34 +1495,23 @@ async function parseWorkspaceDirectories(monorepoRoot) {
|
|
|
1475
1495
|
async function detectWorkspaceSettings(monorepoRoot) {
|
|
1476
1496
|
try {
|
|
1477
1497
|
const tooling = await index.detectTooling(monorepoRoot);
|
|
1478
|
-
const pkgPath =
|
|
1479
|
-
const content = await promises.readFile(pkgPath, "utf-8");
|
|
1498
|
+
const pkgPath = node_path.join(monorepoRoot, "package.json");
|
|
1499
|
+
const content = await promises$1.readFile(pkgPath, "utf-8");
|
|
1480
1500
|
const pkgJson = JSON.parse(content);
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
packageManager = pkgJson.packageManager.split("@")[0];
|
|
1484
|
-
}
|
|
1485
|
-
let nodeVersion;
|
|
1486
|
-
if (pkgJson.engines?.node) {
|
|
1487
|
-
const match = pkgJson.engines.node.match(/(\d+)/);
|
|
1488
|
-
if (match) {
|
|
1489
|
-
nodeVersion = match[1];
|
|
1490
|
-
}
|
|
1491
|
-
}
|
|
1501
|
+
const packageManager = index.parsePackageManager(pkgJson.packageManager);
|
|
1502
|
+
const engine = index.parseEngine(pkgJson.engines);
|
|
1492
1503
|
let pnpmManageVersions;
|
|
1493
1504
|
try {
|
|
1494
|
-
const workspaceFile =
|
|
1495
|
-
const workspaceContent = await promises.readFile(workspaceFile, "utf-8");
|
|
1496
|
-
pnpmManageVersions = workspaceContent.includes(
|
|
1497
|
-
"manage-package-manager-versions: true"
|
|
1498
|
-
);
|
|
1505
|
+
const workspaceFile = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
1506
|
+
const workspaceContent = await promises$1.readFile(workspaceFile, "utf-8");
|
|
1507
|
+
pnpmManageVersions = workspaceContent.includes("manage-package-manager-versions: true");
|
|
1499
1508
|
} catch {
|
|
1500
1509
|
}
|
|
1501
1510
|
return {
|
|
1502
1511
|
linter: tooling.linter,
|
|
1503
1512
|
formatter: tooling.formatter,
|
|
1504
1513
|
packageManager,
|
|
1505
|
-
|
|
1514
|
+
engine,
|
|
1506
1515
|
pnpmManageVersions
|
|
1507
1516
|
};
|
|
1508
1517
|
} catch {
|
|
@@ -1511,17 +1520,17 @@ async function detectWorkspaceSettings(monorepoRoot) {
|
|
|
1511
1520
|
}
|
|
1512
1521
|
async function detectExistingConfigs(monorepoRoot) {
|
|
1513
1522
|
const configs = {};
|
|
1514
|
-
const eslintPath =
|
|
1523
|
+
const eslintPath = node_path.join(monorepoRoot, "eslint.config.js");
|
|
1515
1524
|
if (await fileExists(eslintPath)) {
|
|
1516
1525
|
configs.linter = "eslint";
|
|
1517
1526
|
configs.eslintConfigPath = eslintPath;
|
|
1518
1527
|
}
|
|
1519
|
-
const prettierPath =
|
|
1528
|
+
const prettierPath = node_path.join(monorepoRoot, ".prettierrc.json");
|
|
1520
1529
|
if (await fileExists(prettierPath)) {
|
|
1521
1530
|
configs.formatter = "prettier";
|
|
1522
1531
|
configs.prettierConfigPath = prettierPath;
|
|
1523
1532
|
}
|
|
1524
|
-
const biomePath =
|
|
1533
|
+
const biomePath = node_path.join(monorepoRoot, "biome.json");
|
|
1525
1534
|
if (await fileExists(biomePath)) {
|
|
1526
1535
|
configs.biomeConfigPath = biomePath;
|
|
1527
1536
|
if (!configs.linter) configs.linter = "biome";
|
|
@@ -1531,8 +1540,8 @@ async function detectExistingConfigs(monorepoRoot) {
|
|
|
1531
1540
|
}
|
|
1532
1541
|
async function getMonorepoScope(monorepoRoot) {
|
|
1533
1542
|
try {
|
|
1534
|
-
const pkgPath =
|
|
1535
|
-
const content = await promises.readFile(pkgPath, "utf-8");
|
|
1543
|
+
const pkgPath = node_path.join(monorepoRoot, "package.json");
|
|
1544
|
+
const content = await promises$1.readFile(pkgPath, "utf-8");
|
|
1536
1545
|
const pkgJson = JSON.parse(content);
|
|
1537
1546
|
if (pkgJson.name) {
|
|
1538
1547
|
return pkgJson.name.replace(/^@/, "").replace(/\/.*$/, "");
|
|
@@ -1542,7 +1551,7 @@ async function getMonorepoScope(monorepoRoot) {
|
|
|
1542
1551
|
return monorepoRoot.split(/[/\\]/).pop() ?? "workspace";
|
|
1543
1552
|
}
|
|
1544
1553
|
async function getWorkspacePackages(monorepoRoot) {
|
|
1545
|
-
const packagesDir =
|
|
1554
|
+
const packagesDir = node_path.join(monorepoRoot, "packages");
|
|
1546
1555
|
try {
|
|
1547
1556
|
const { readdir } = await import('fs/promises');
|
|
1548
1557
|
const entries = await readdir(packagesDir, { withFileTypes: true });
|
|
@@ -1550,8 +1559,8 @@ async function getWorkspacePackages(monorepoRoot) {
|
|
|
1550
1559
|
for (const entry of entries) {
|
|
1551
1560
|
if (!entry.isDirectory()) continue;
|
|
1552
1561
|
try {
|
|
1553
|
-
const content = await promises.readFile(
|
|
1554
|
-
|
|
1562
|
+
const content = await promises$1.readFile(
|
|
1563
|
+
node_path.join(packagesDir, entry.name, "package.json"),
|
|
1555
1564
|
"utf-8"
|
|
1556
1565
|
);
|
|
1557
1566
|
const pkg2 = JSON.parse(content);
|
|
@@ -1565,25 +1574,23 @@ async function getWorkspacePackages(monorepoRoot) {
|
|
|
1565
1574
|
}
|
|
1566
1575
|
}
|
|
1567
1576
|
async function ensureConfigInWorkspace(monorepoRoot) {
|
|
1568
|
-
const workspacePath =
|
|
1577
|
+
const workspacePath = node_path.join(monorepoRoot, "pnpm-workspace.yaml");
|
|
1569
1578
|
let content;
|
|
1570
1579
|
try {
|
|
1571
|
-
content = await promises.readFile(workspacePath, "utf-8");
|
|
1580
|
+
content = await promises$1.readFile(workspacePath, "utf-8");
|
|
1572
1581
|
} catch {
|
|
1573
1582
|
content = `packages:
|
|
1574
1583
|
- ".config/*"
|
|
1575
1584
|
- "packages/*"
|
|
1576
1585
|
`;
|
|
1577
|
-
await promises.writeFile(workspacePath, content);
|
|
1586
|
+
await promises$1.writeFile(workspacePath, content);
|
|
1578
1587
|
return;
|
|
1579
1588
|
}
|
|
1580
1589
|
if (content.includes(".config/*") || content.includes('".config/*"')) {
|
|
1581
1590
|
return;
|
|
1582
1591
|
}
|
|
1583
1592
|
const lines = content.split("\n");
|
|
1584
|
-
const packagesIndex = lines.findIndex(
|
|
1585
|
-
(line) => line.trim().startsWith("packages:")
|
|
1586
|
-
);
|
|
1593
|
+
const packagesIndex = lines.findIndex((line) => line.trim().startsWith("packages:"));
|
|
1587
1594
|
if (packagesIndex === -1) {
|
|
1588
1595
|
content = `packages:
|
|
1589
1596
|
- ".config/*"
|
|
@@ -1592,14 +1599,14 @@ ${content}`;
|
|
|
1592
1599
|
lines.splice(packagesIndex + 1, 0, ' - ".config/*"');
|
|
1593
1600
|
content = lines.join("\n");
|
|
1594
1601
|
}
|
|
1595
|
-
await promises.writeFile(workspacePath, content);
|
|
1602
|
+
await promises$1.writeFile(workspacePath, content);
|
|
1596
1603
|
}
|
|
1597
1604
|
async function migrateEslintConfig(monorepoRoot, files) {
|
|
1598
1605
|
const configBasePath = ".config/eslint";
|
|
1599
|
-
const existingConfigPath =
|
|
1606
|
+
const existingConfigPath = node_path.join(monorepoRoot, "eslint.config.js");
|
|
1600
1607
|
let existingContent;
|
|
1601
1608
|
try {
|
|
1602
|
-
existingContent = await promises.readFile(existingConfigPath, "utf-8");
|
|
1609
|
+
existingContent = await promises$1.readFile(existingConfigPath, "utf-8");
|
|
1603
1610
|
} catch {
|
|
1604
1611
|
index.generateEslintConfigPackage(files);
|
|
1605
1612
|
return;
|
|
@@ -1675,10 +1682,10 @@ export default [
|
|
|
1675
1682
|
}
|
|
1676
1683
|
async function migratePrettierConfig(monorepoRoot, files) {
|
|
1677
1684
|
const configBasePath = ".config/prettier";
|
|
1678
|
-
const existingConfigPath =
|
|
1685
|
+
const existingConfigPath = node_path.join(monorepoRoot, ".prettierrc.json");
|
|
1679
1686
|
let existingContent;
|
|
1680
1687
|
try {
|
|
1681
|
-
existingContent = await promises.readFile(existingConfigPath, "utf-8");
|
|
1688
|
+
existingContent = await promises$1.readFile(existingConfigPath, "utf-8");
|
|
1682
1689
|
} catch {
|
|
1683
1690
|
index.generatePrettierConfigPackage(files);
|
|
1684
1691
|
return;
|
|
@@ -1748,7 +1755,7 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
1748
1755
|
const dirName = value.includes("/") ? value.split("/").pop() : value;
|
|
1749
1756
|
if (!dirName) return "Package name is required";
|
|
1750
1757
|
if (!hasCustomDirectories) {
|
|
1751
|
-
const targetPath =
|
|
1758
|
+
const targetPath = node_path.join(monorepoRoot, defaultDir, dirName);
|
|
1752
1759
|
try {
|
|
1753
1760
|
const { statSync } = require$1("fs");
|
|
1754
1761
|
statSync(targetPath);
|
|
@@ -1763,11 +1770,7 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
1763
1770
|
}
|
|
1764
1771
|
const scopedName = packageNameInput;
|
|
1765
1772
|
const shortName = scopedName.includes("/") ? scopedName.split("/").pop() : scopedName;
|
|
1766
|
-
const packageOptions = await promptForPackageOptions(
|
|
1767
|
-
scopedName,
|
|
1768
|
-
packageType,
|
|
1769
|
-
inheritedSettings
|
|
1770
|
-
);
|
|
1773
|
+
const packageOptions = await promptForPackageOptions(scopedName, packageType, inheritedSettings);
|
|
1771
1774
|
let targetDir = defaultDir;
|
|
1772
1775
|
if (hasCustomDirectories && workspaceDirectories.length > 0) {
|
|
1773
1776
|
const dirChoice = await p__namespace.select({
|
|
@@ -1782,7 +1785,7 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
1782
1785
|
return false;
|
|
1783
1786
|
}
|
|
1784
1787
|
targetDir = dirChoice;
|
|
1785
|
-
const targetPath =
|
|
1788
|
+
const targetPath = node_path.join(monorepoRoot, targetDir, shortName);
|
|
1786
1789
|
try {
|
|
1787
1790
|
const { statSync } = require$1("fs");
|
|
1788
1791
|
statSync(targetPath);
|
|
@@ -1791,81 +1794,13 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
1791
1794
|
} catch {
|
|
1792
1795
|
}
|
|
1793
1796
|
}
|
|
1794
|
-
const relativePkgPath =
|
|
1797
|
+
const relativePkgPath = node_path.join(targetDir, shortName);
|
|
1795
1798
|
const workspaceRoot = calculateWorkspaceRoot(relativePkgPath);
|
|
1796
1799
|
packageOptions.workspaceRoot = workspaceRoot;
|
|
1797
1800
|
packageOptions.name = scopedName;
|
|
1798
|
-
|
|
1799
|
-
|
|
1800
|
-
|
|
1801
|
-
packageOptions.yarnVersion = await index.getLatestYarnVersion();
|
|
1802
|
-
} else if (packageManager === "npm") {
|
|
1803
|
-
packageOptions.npmVersion = await index.getLatestNpmCliVersion();
|
|
1804
|
-
}
|
|
1805
|
-
const nodeVersion = packageOptions.nodeVersion ?? "latest";
|
|
1806
|
-
if (nodeVersion === "latest") {
|
|
1807
|
-
packageOptions.nodeVersion = await index.getLatestNodeVersion();
|
|
1808
|
-
}
|
|
1809
|
-
const versions = {};
|
|
1810
|
-
const versionPromises = [];
|
|
1811
|
-
const pkgIsLibrary = packageOptions.projectType === "library";
|
|
1812
|
-
const pkgTesting = packageOptions.testing ?? (pkgIsLibrary ? "vitest" : "none");
|
|
1813
|
-
if (pkgTesting === "vitest") {
|
|
1814
|
-
versionPromises.push(
|
|
1815
|
-
index.getLatestNpmVersion("vitest", "4.0.0").then((v) => {
|
|
1816
|
-
versions.vitest = v;
|
|
1817
|
-
})
|
|
1818
|
-
);
|
|
1819
|
-
}
|
|
1820
|
-
if (!pkgIsLibrary) {
|
|
1821
|
-
versionPromises.push(
|
|
1822
|
-
index.getLatestNpmVersion("vite", "6.3.4").then((v) => {
|
|
1823
|
-
versions.vite = v;
|
|
1824
|
-
})
|
|
1825
|
-
);
|
|
1826
|
-
}
|
|
1827
|
-
const linter = packageOptions.linter ?? "oxlint";
|
|
1828
|
-
if (linter === "eslint") {
|
|
1829
|
-
versionPromises.push(
|
|
1830
|
-
index.getLatestNpmVersion("eslint", "9.17.0").then((v) => {
|
|
1831
|
-
versions.eslint = v;
|
|
1832
|
-
})
|
|
1833
|
-
);
|
|
1834
|
-
} else if (linter === "oxlint") {
|
|
1835
|
-
versionPromises.push(
|
|
1836
|
-
index.getLatestNpmVersion("oxlint", "0.16.0").then((v) => {
|
|
1837
|
-
versions.oxlint = v;
|
|
1838
|
-
})
|
|
1839
|
-
);
|
|
1840
|
-
} else if (linter === "biome") {
|
|
1841
|
-
versionPromises.push(
|
|
1842
|
-
index.getLatestNpmVersion("@biomejs/biome", "1.9.4").then((v) => {
|
|
1843
|
-
versions.biome = v;
|
|
1844
|
-
})
|
|
1845
|
-
);
|
|
1846
|
-
}
|
|
1847
|
-
const formatter = packageOptions.formatter ?? "prettier";
|
|
1848
|
-
if (formatter === "prettier") {
|
|
1849
|
-
versionPromises.push(
|
|
1850
|
-
index.getLatestNpmVersion("prettier", "3.4.2").then((v) => {
|
|
1851
|
-
versions.prettier = v;
|
|
1852
|
-
})
|
|
1853
|
-
);
|
|
1854
|
-
} else if (formatter === "oxfmt") {
|
|
1855
|
-
versionPromises.push(
|
|
1856
|
-
index.getLatestNpmVersion("oxfmt", "0.1.0").then((v) => {
|
|
1857
|
-
versions.oxfmt = v;
|
|
1858
|
-
})
|
|
1859
|
-
);
|
|
1860
|
-
} else if (formatter === "biome" && linter !== "biome") {
|
|
1861
|
-
versionPromises.push(
|
|
1862
|
-
index.getLatestNpmVersion("@biomejs/biome", "1.9.4").then((v) => {
|
|
1863
|
-
versions.biome = v;
|
|
1864
|
-
})
|
|
1865
|
-
);
|
|
1866
|
-
}
|
|
1867
|
-
await Promise.all(versionPromises);
|
|
1868
|
-
packageOptions.versions = versions;
|
|
1801
|
+
packageOptions.packageManager = await index.resolvePackageManager(packageOptions);
|
|
1802
|
+
packageOptions.engine = await index.resolveEngine(packageOptions);
|
|
1803
|
+
packageOptions.versions = await index.resolveProjectPackageVersions(packageOptions);
|
|
1869
1804
|
const workspacePackages = packageType === "app" ? await getWorkspacePackages(monorepoRoot) : [];
|
|
1870
1805
|
if (workspacePackages.length > 0) {
|
|
1871
1806
|
const selectedDeps = await p__namespace.multiselect({
|
|
@@ -1877,15 +1812,13 @@ async function createPackageInWorkspace(monorepoRoot, packageManager, inheritedS
|
|
|
1877
1812
|
packageOptions.workspaceDependencies = selectedDeps;
|
|
1878
1813
|
}
|
|
1879
1814
|
}
|
|
1880
|
-
const outputPath =
|
|
1815
|
+
const outputPath = node_path.join(monorepoRoot, relativePkgPath);
|
|
1881
1816
|
const spinner = p__namespace.spinner();
|
|
1882
1817
|
spinner.start("Creating package...");
|
|
1883
1818
|
try {
|
|
1884
1819
|
const files = index.generate(packageOptions);
|
|
1885
1820
|
await writeGeneratedFiles(outputPath, files);
|
|
1886
|
-
spinner.stop(
|
|
1887
|
-
color__default.green.inverse(` \u2713 Package created at ${relativePkgPath}! `)
|
|
1888
|
-
);
|
|
1821
|
+
spinner.stop(color__default.green.inverse(` \u2713 Package created at ${relativePkgPath}! `));
|
|
1889
1822
|
const addAnother = await p__namespace.select({
|
|
1890
1823
|
message: "Add another package?",
|
|
1891
1824
|
options: [
|
|
@@ -2063,19 +1996,17 @@ async function handleFixCommand(options) {
|
|
|
2063
1996
|
try {
|
|
2064
1997
|
const files = {};
|
|
2065
1998
|
const tsConfigExists = await fileExists(
|
|
2066
|
-
|
|
1999
|
+
node_path.join(monorepoRoot, ".config/typescript/package.json")
|
|
2067
2000
|
);
|
|
2068
2001
|
if (!tsConfigExists) {
|
|
2069
2002
|
index.generateTypescriptConfigPackage(files);
|
|
2070
2003
|
}
|
|
2071
2004
|
if (linter === "oxlint") {
|
|
2072
|
-
const oxlintExists = await fileExists(
|
|
2073
|
-
path.join(monorepoRoot, ".config/oxlint/package.json")
|
|
2074
|
-
);
|
|
2005
|
+
const oxlintExists = await fileExists(node_path.join(monorepoRoot, ".config/oxlint/package.json"));
|
|
2075
2006
|
if (!oxlintExists) index.generateOxlintConfigPackage(files);
|
|
2076
2007
|
} else if (linter === "eslint") {
|
|
2077
2008
|
const eslintPkgExists = await fileExists(
|
|
2078
|
-
|
|
2009
|
+
node_path.join(monorepoRoot, ".config/eslint/package.json")
|
|
2079
2010
|
);
|
|
2080
2011
|
if (!eslintPkgExists) {
|
|
2081
2012
|
if (existingConfigs.eslintConfigPath) {
|
|
@@ -2086,13 +2017,11 @@ async function handleFixCommand(options) {
|
|
|
2086
2017
|
}
|
|
2087
2018
|
}
|
|
2088
2019
|
if (formatter === "oxfmt") {
|
|
2089
|
-
const oxfmtExists = await fileExists(
|
|
2090
|
-
path.join(monorepoRoot, ".config/oxfmt/package.json")
|
|
2091
|
-
);
|
|
2020
|
+
const oxfmtExists = await fileExists(node_path.join(monorepoRoot, ".config/oxfmt/package.json"));
|
|
2092
2021
|
if (!oxfmtExists) index.generateOxfmtConfigPackage(files);
|
|
2093
2022
|
} else if (formatter === "prettier") {
|
|
2094
2023
|
const prettierPkgExists = await fileExists(
|
|
2095
|
-
|
|
2024
|
+
node_path.join(monorepoRoot, ".config/prettier/package.json")
|
|
2096
2025
|
);
|
|
2097
2026
|
if (!prettierPkgExists) {
|
|
2098
2027
|
if (existingConfigs.prettierConfigPath) {
|
|
@@ -2103,8 +2032,13 @@ async function handleFixCommand(options) {
|
|
|
2103
2032
|
}
|
|
2104
2033
|
}
|
|
2105
2034
|
if ((linter === "biome" || formatter === "biome") && !existingConfigs.biomeConfigPath) {
|
|
2035
|
+
const versions = await index.resolveMonorepoRootPackageVersions({
|
|
2036
|
+
linter,
|
|
2037
|
+
formatter
|
|
2038
|
+
});
|
|
2039
|
+
const biomeVersion = index.getResolvedPackageVersion(versions, "@biomejs/biome");
|
|
2106
2040
|
const biomeConfig = {
|
|
2107
|
-
$schema:
|
|
2041
|
+
$schema: `https://biomejs.dev/schemas/${biomeVersion}/schema.json`,
|
|
2108
2042
|
vcs: {
|
|
2109
2043
|
enabled: true,
|
|
2110
2044
|
clientKind: "git",
|
|
@@ -2126,36 +2060,32 @@ async function handleFixCommand(options) {
|
|
|
2126
2060
|
};
|
|
2127
2061
|
}
|
|
2128
2062
|
for (const [filePath, file] of Object.entries(files)) {
|
|
2129
|
-
const fullPath =
|
|
2130
|
-
await promises.mkdir(
|
|
2131
|
-
await promises.writeFile(fullPath, file.content);
|
|
2063
|
+
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
2064
|
+
await promises$1.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
2065
|
+
await promises$1.writeFile(fullPath, file.content);
|
|
2132
2066
|
}
|
|
2133
2067
|
await ensureConfigInWorkspace(monorepoRoot);
|
|
2134
2068
|
if (existingConfigs.eslintConfigPath && linter === "eslint") {
|
|
2135
2069
|
try {
|
|
2136
|
-
await promises.unlink(existingConfigs.eslintConfigPath);
|
|
2070
|
+
await promises$1.unlink(existingConfigs.eslintConfigPath);
|
|
2137
2071
|
} catch {
|
|
2138
2072
|
}
|
|
2139
2073
|
}
|
|
2140
2074
|
if (existingConfigs.prettierConfigPath && formatter === "prettier") {
|
|
2141
2075
|
try {
|
|
2142
|
-
await promises.unlink(existingConfigs.prettierConfigPath);
|
|
2076
|
+
await promises$1.unlink(existingConfigs.prettierConfigPath);
|
|
2143
2077
|
} catch {
|
|
2144
2078
|
}
|
|
2145
2079
|
}
|
|
2146
2080
|
spinner.stop(color__default.green("\u2713") + " Workspace fixed!");
|
|
2147
|
-
const generated = Object.keys(files).filter(
|
|
2148
|
-
(f) => f.endsWith("package.json")
|
|
2149
|
-
);
|
|
2081
|
+
const generated = Object.keys(files).filter((f) => f.endsWith("package.json"));
|
|
2150
2082
|
for (const pkgFile of generated) {
|
|
2151
2083
|
const pkgName = pkgFile.replace("/package.json", "");
|
|
2152
2084
|
console.log(color__default.dim(` Generated ${pkgName}`));
|
|
2153
2085
|
}
|
|
2154
|
-
const vscodeSettingsExists = await fileExists(
|
|
2155
|
-
path.join(monorepoRoot, ".vscode/settings.json")
|
|
2156
|
-
);
|
|
2086
|
+
const vscodeSettingsExists = await fileExists(node_path.join(monorepoRoot, ".vscode/settings.json"));
|
|
2157
2087
|
const vscodeExtensionsExists = await fileExists(
|
|
2158
|
-
|
|
2088
|
+
node_path.join(monorepoRoot, ".vscode/extensions.json")
|
|
2159
2089
|
);
|
|
2160
2090
|
const vscodeExists = vscodeSettingsExists && vscodeExtensionsExists;
|
|
2161
2091
|
if (!vscodeExists) {
|
|
@@ -2173,17 +2103,15 @@ async function handleFixCommand(options) {
|
|
|
2173
2103
|
const vscodeFiles = {};
|
|
2174
2104
|
index.generateVscodeFiles(vscodeFiles, linter, formatter);
|
|
2175
2105
|
for (const [filePath, file] of Object.entries(vscodeFiles)) {
|
|
2176
|
-
const fullPath =
|
|
2177
|
-
await promises.mkdir(
|
|
2178
|
-
await promises.writeFile(fullPath, file.content);
|
|
2106
|
+
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
2107
|
+
await promises$1.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
2108
|
+
await promises$1.writeFile(fullPath, file.content);
|
|
2179
2109
|
}
|
|
2180
2110
|
console.log(color__default.dim(" Generated .vscode/settings.json"));
|
|
2181
2111
|
console.log(color__default.dim(" Generated .vscode/extensions.json"));
|
|
2182
2112
|
}
|
|
2183
2113
|
}
|
|
2184
|
-
const aiRulesExist = await fileExists(
|
|
2185
|
-
path.join(monorepoRoot, ".ai/workspace.md")
|
|
2186
|
-
);
|
|
2114
|
+
const aiRulesExist = await fileExists(node_path.join(monorepoRoot, ".ai/workspace.md"));
|
|
2187
2115
|
if (!aiRulesExist) {
|
|
2188
2116
|
const platforms = await promptForAiPlatforms(isNonInteractive);
|
|
2189
2117
|
if (platforms.length > 0) {
|
|
@@ -2198,9 +2126,9 @@ async function handleFixCommand(options) {
|
|
|
2198
2126
|
platforms
|
|
2199
2127
|
});
|
|
2200
2128
|
for (const [filePath, file] of Object.entries(aiFilesOutput)) {
|
|
2201
|
-
const fullPath =
|
|
2202
|
-
await promises.mkdir(
|
|
2203
|
-
await promises.writeFile(fullPath, file.content);
|
|
2129
|
+
const fullPath = node_path.join(monorepoRoot, filePath);
|
|
2130
|
+
await promises$1.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
2131
|
+
await promises$1.writeFile(fullPath, file.content);
|
|
2204
2132
|
console.log(color__default.dim(` Generated ${filePath}`));
|
|
2205
2133
|
}
|
|
2206
2134
|
}
|
|
@@ -2216,15 +2144,11 @@ async function handleMigration(config, target, root, options) {
|
|
|
2216
2144
|
const plan = await getMigrationPlan(config, target, root);
|
|
2217
2145
|
console.log(color__default.cyan("Migration:"));
|
|
2218
2146
|
if (plan.fromLinter !== plan.toLinter) {
|
|
2219
|
-
console.log(
|
|
2220
|
-
` Linter: ${color__default.dim(plan.fromLinter)} \u2192 ${color__default.green(plan.toLinter)}`
|
|
2221
|
-
);
|
|
2147
|
+
console.log(` Linter: ${color__default.dim(plan.fromLinter)} \u2192 ${color__default.green(plan.toLinter)}`);
|
|
2222
2148
|
}
|
|
2223
2149
|
if (plan.fromFormatter !== plan.toFormatter) {
|
|
2224
2150
|
console.log(
|
|
2225
|
-
` Formatter: ${color__default.dim(plan.fromFormatter)} \u2192 ${color__default.green(
|
|
2226
|
-
plan.toFormatter
|
|
2227
|
-
)}`
|
|
2151
|
+
` Formatter: ${color__default.dim(plan.fromFormatter)} \u2192 ${color__default.green(plan.toFormatter)}`
|
|
2228
2152
|
);
|
|
2229
2153
|
}
|
|
2230
2154
|
console.log();
|
|
@@ -2255,17 +2179,17 @@ async function handleMigration(config, target, root, options) {
|
|
|
2255
2179
|
}
|
|
2256
2180
|
}
|
|
2257
2181
|
await applyMigration(plan, root);
|
|
2258
|
-
const aiWorkspacePath =
|
|
2182
|
+
const aiWorkspacePath = node_path.join(root, ".ai/workspace.md");
|
|
2259
2183
|
const aiRulesExist = await fileExists(aiWorkspacePath);
|
|
2260
2184
|
if (aiRulesExist) {
|
|
2261
2185
|
console.log();
|
|
2262
2186
|
console.log(color__default.cyan("Updating AI rules..."));
|
|
2263
2187
|
const scope = await getMonorepoScope(root);
|
|
2264
2188
|
const existingPlatforms = [];
|
|
2265
|
-
if (await fileExists(
|
|
2189
|
+
if (await fileExists(node_path.join(root, "AGENTS.md"))) {
|
|
2266
2190
|
existingPlatforms.push("agents");
|
|
2267
2191
|
}
|
|
2268
|
-
if (await fileExists(
|
|
2192
|
+
if (await fileExists(node_path.join(root, "CLAUDE.md"))) {
|
|
2269
2193
|
existingPlatforms.push("claude");
|
|
2270
2194
|
}
|
|
2271
2195
|
const aiFilesOutput = {};
|
|
@@ -2278,94 +2202,94 @@ async function handleMigration(config, target, root, options) {
|
|
|
2278
2202
|
platforms: existingPlatforms.length > 0 ? existingPlatforms : ["agents"]
|
|
2279
2203
|
});
|
|
2280
2204
|
for (const [filePath, file] of Object.entries(aiFilesOutput)) {
|
|
2281
|
-
const fullPath =
|
|
2282
|
-
await promises.mkdir(
|
|
2283
|
-
await promises.writeFile(fullPath, file.content);
|
|
2205
|
+
const fullPath = node_path.join(root, filePath);
|
|
2206
|
+
await promises$1.mkdir(node_path.dirname(fullPath), { recursive: true });
|
|
2207
|
+
await promises$1.writeFile(fullPath, file.content);
|
|
2284
2208
|
console.log(color__default.dim(` ${filePath}`));
|
|
2285
2209
|
}
|
|
2286
2210
|
}
|
|
2287
2211
|
console.log();
|
|
2288
|
-
console.log(
|
|
2289
|
-
color__default.green("\u2713") + ` Migrated to ${plan.toLinter}/${plan.toFormatter}`
|
|
2290
|
-
);
|
|
2212
|
+
console.log(color__default.green("\u2713") + ` Migrated to ${plan.toLinter}/${plan.toFormatter}`);
|
|
2291
2213
|
console.log(color__default.dim(" Run `pnpm install` to update dependencies"));
|
|
2292
2214
|
process.exit(0);
|
|
2293
2215
|
}
|
|
2294
2216
|
async function handleUpdateCommand(options) {
|
|
2295
2217
|
const monorepoRoot = await detectMonorepoRoot();
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
console.log(color__default.
|
|
2218
|
+
const projectRoot = monorepoRoot ?? await detectPackageRoot();
|
|
2219
|
+
if (!projectRoot) {
|
|
2220
|
+
console.log(color__default.red("\u2717") + " Could not find a project root");
|
|
2221
|
+
console.log(color__default.dim(" Run this command from inside a generated project"));
|
|
2299
2222
|
process.exit(1);
|
|
2300
2223
|
}
|
|
2301
|
-
const
|
|
2302
|
-
if (
|
|
2303
|
-
|
|
2304
|
-
|
|
2305
|
-
console.log(color__default.
|
|
2224
|
+
const isMonorepo = monorepoRoot != null;
|
|
2225
|
+
if (isMonorepo) {
|
|
2226
|
+
const { valid, errors } = await validateWorkspace(projectRoot);
|
|
2227
|
+
if (!valid) {
|
|
2228
|
+
console.log(color__default.yellow("!") + " Workspace has issues:");
|
|
2229
|
+
for (const error of errors) {
|
|
2230
|
+
console.log(color__default.dim(` \u2022 ${error}`));
|
|
2231
|
+
}
|
|
2232
|
+
console.log();
|
|
2233
|
+
const shouldFix = options.yes || await p__namespace.confirm({
|
|
2234
|
+
message: "Run fix first to resolve these issues?",
|
|
2235
|
+
initialValue: true
|
|
2236
|
+
});
|
|
2237
|
+
if (p__namespace.isCancel(shouldFix) || !shouldFix) {
|
|
2238
|
+
console.log(color__default.dim(" Run `pnpm create krispya --fix` to fix manually"));
|
|
2239
|
+
process.exit(1);
|
|
2240
|
+
}
|
|
2241
|
+
const preFixConfig = await detectCurrentConfig(projectRoot);
|
|
2242
|
+
const fixOptions = {
|
|
2243
|
+
...options,
|
|
2244
|
+
linter: options.linter ?? preFixConfig.linter,
|
|
2245
|
+
formatter: options.formatter ?? preFixConfig.formatter
|
|
2246
|
+
};
|
|
2247
|
+
await handleFixCommand(fixOptions);
|
|
2306
2248
|
}
|
|
2249
|
+
} else if (options.linter || options.formatter) {
|
|
2250
|
+
console.log(
|
|
2251
|
+
color__default.yellow("!") + " Linter/formatter migrations in --update are currently monorepo-only"
|
|
2252
|
+
);
|
|
2253
|
+
console.log(color__default.dim(" Continuing with standalone shared config updates"));
|
|
2307
2254
|
console.log();
|
|
2308
|
-
const shouldFix = options.yes || await p__namespace.confirm({
|
|
2309
|
-
message: "Run fix first to resolve these issues?",
|
|
2310
|
-
initialValue: true
|
|
2311
|
-
});
|
|
2312
|
-
if (p__namespace.isCancel(shouldFix) || !shouldFix) {
|
|
2313
|
-
console.log(
|
|
2314
|
-
color__default.dim(" Run `pnpm create krispya --fix` to fix manually")
|
|
2315
|
-
);
|
|
2316
|
-
process.exit(1);
|
|
2317
|
-
}
|
|
2318
|
-
const preFixConfig = await detectCurrentConfig(monorepoRoot);
|
|
2319
|
-
const fixOptions = {
|
|
2320
|
-
...options,
|
|
2321
|
-
linter: options.linter ?? preFixConfig.linter,
|
|
2322
|
-
formatter: options.formatter ?? preFixConfig.formatter
|
|
2323
|
-
};
|
|
2324
|
-
await handleFixCommand(fixOptions);
|
|
2325
2255
|
}
|
|
2326
|
-
const config = await detectCurrentConfig(
|
|
2256
|
+
const config = await detectCurrentConfig(projectRoot, isMonorepo);
|
|
2327
2257
|
const targetLinter = options.linter;
|
|
2328
2258
|
const targetFormatter = options.formatter;
|
|
2329
2259
|
const migrationTarget = { linter: targetLinter, formatter: targetFormatter };
|
|
2330
|
-
if (needsMigration(config, migrationTarget)) {
|
|
2331
|
-
await handleMigration(config, migrationTarget,
|
|
2260
|
+
if (isMonorepo && needsMigration(config, migrationTarget)) {
|
|
2261
|
+
await handleMigration(config, migrationTarget, projectRoot, options);
|
|
2332
2262
|
return;
|
|
2333
2263
|
}
|
|
2334
2264
|
console.log(
|
|
2335
2265
|
color__default.cyan("Checking for updates...") + color__default.dim(` (${config.linter}/${config.formatter})`)
|
|
2336
2266
|
);
|
|
2337
2267
|
console.log();
|
|
2338
|
-
const expected = generateExpectedFiles(config);
|
|
2339
|
-
const categories = await compareWithDisk(expected,
|
|
2340
|
-
const
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
|
|
2347
|
-
|
|
2348
|
-
|
|
2349
|
-
|
|
2350
|
-
|
|
2351
|
-
|
|
2352
|
-
|
|
2353
|
-
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
if (configPkgIndex !== -1) {
|
|
2357
|
-
allCategories.splice(configPkgIndex + 1, 0, workspaceCategory);
|
|
2358
|
-
} else {
|
|
2359
|
-
allCategories.push(workspaceCategory);
|
|
2268
|
+
const expected = await generateExpectedFiles(config);
|
|
2269
|
+
const categories = await compareWithDisk(expected, projectRoot);
|
|
2270
|
+
const allCategories = categories.filter((c) => c.category !== "workspace-config");
|
|
2271
|
+
if (isMonorepo) {
|
|
2272
|
+
const workspaceConfigChanges = await getWorkspaceConfigUpdates(projectRoot);
|
|
2273
|
+
const workspaceCategory = {
|
|
2274
|
+
category: "workspace-config",
|
|
2275
|
+
label: "Workspace Config",
|
|
2276
|
+
changes: workspaceConfigChanges,
|
|
2277
|
+
hasUserModifications: workspaceConfigChanges.some((c) => c.status === "modified")
|
|
2278
|
+
};
|
|
2279
|
+
if (workspaceConfigChanges.length > 0) {
|
|
2280
|
+
const configPkgIndex = allCategories.findIndex((c) => c.category === "config-packages");
|
|
2281
|
+
if (configPkgIndex !== -1) {
|
|
2282
|
+
allCategories.splice(configPkgIndex + 1, 0, workspaceCategory);
|
|
2283
|
+
} else {
|
|
2284
|
+
allCategories.push(workspaceCategory);
|
|
2285
|
+
}
|
|
2360
2286
|
}
|
|
2361
2287
|
}
|
|
2362
2288
|
let updatedCount = 0;
|
|
2363
2289
|
let skippedCount = 0;
|
|
2364
2290
|
for (const category of allCategories) {
|
|
2365
2291
|
const newChanges = category.changes.filter((c) => c.status === "added");
|
|
2366
|
-
const modifiedChanges = category.changes.filter(
|
|
2367
|
-
(c) => c.status === "modified"
|
|
2368
|
-
);
|
|
2292
|
+
const modifiedChanges = category.changes.filter((c) => c.status === "modified");
|
|
2369
2293
|
const hasNew = newChanges.length > 0;
|
|
2370
2294
|
const hasModified = modifiedChanges.length > 0;
|
|
2371
2295
|
const hasChanges = hasNew || hasModified;
|
|
@@ -2376,19 +2300,15 @@ async function handleUpdateCommand(options) {
|
|
|
2376
2300
|
if (category.category === "ai-files") {
|
|
2377
2301
|
if (hasNew) {
|
|
2378
2302
|
console.log(color__default.cyan(category.label + ":"));
|
|
2379
|
-
console.log(
|
|
2380
|
-
color__default.dim(` ${newChanges.length} AI file(s) can be added`)
|
|
2381
|
-
);
|
|
2303
|
+
console.log(color__default.dim(` ${newChanges.length} AI file(s) can be added`));
|
|
2382
2304
|
console.log();
|
|
2383
2305
|
const applyAi = options.yes ? true : await p__namespace.confirm({
|
|
2384
2306
|
message: "Add AI rules?",
|
|
2385
2307
|
initialValue: true
|
|
2386
2308
|
});
|
|
2387
2309
|
if (!p__namespace.isCancel(applyAi) && applyAi) {
|
|
2388
|
-
await applyUpdates(newChanges,
|
|
2389
|
-
console.log(
|
|
2390
|
-
color__default.green("\u2713") + ` Added ${newChanges.length} AI file(s)`
|
|
2391
|
-
);
|
|
2310
|
+
await applyUpdates(newChanges, projectRoot);
|
|
2311
|
+
console.log(color__default.green("\u2713") + ` Added ${newChanges.length} AI file(s)`);
|
|
2392
2312
|
updatedCount++;
|
|
2393
2313
|
} else {
|
|
2394
2314
|
console.log(color__default.dim(` Skipped ${category.label}`));
|
|
@@ -2409,7 +2329,7 @@ async function handleUpdateCommand(options) {
|
|
|
2409
2329
|
initialValue: false
|
|
2410
2330
|
});
|
|
2411
2331
|
if (!p__namespace.isCancel(updateExisting) && updateExisting) {
|
|
2412
|
-
await applyUpdates(modifiedChanges,
|
|
2332
|
+
await applyUpdates(modifiedChanges, projectRoot);
|
|
2413
2333
|
console.log(color__default.green("\u2713") + " Updated existing AI files");
|
|
2414
2334
|
}
|
|
2415
2335
|
}
|
|
@@ -2452,9 +2372,7 @@ async function handleUpdateCommand(options) {
|
|
|
2452
2372
|
process.exit(0);
|
|
2453
2373
|
}
|
|
2454
2374
|
if (selectedFiles.length > 0) {
|
|
2455
|
-
changesToApply = allChanges.filter(
|
|
2456
|
-
(c) => selectedFiles.includes(c.path)
|
|
2457
|
-
);
|
|
2375
|
+
changesToApply = allChanges.filter((c) => selectedFiles.includes(c.path));
|
|
2458
2376
|
}
|
|
2459
2377
|
} else if (hasNew) {
|
|
2460
2378
|
console.log(color__default.cyan(category.label + ":"));
|
|
@@ -2492,13 +2410,9 @@ async function handleUpdateCommand(options) {
|
|
|
2492
2410
|
}
|
|
2493
2411
|
}
|
|
2494
2412
|
if (changesToApply.length > 0) {
|
|
2495
|
-
await applyUpdates(changesToApply,
|
|
2496
|
-
const addedCount = changesToApply.filter(
|
|
2497
|
-
|
|
2498
|
-
).length;
|
|
2499
|
-
const updatedFilesCount = changesToApply.filter(
|
|
2500
|
-
(c) => c.status === "modified"
|
|
2501
|
-
).length;
|
|
2413
|
+
await applyUpdates(changesToApply, projectRoot);
|
|
2414
|
+
const addedCount = changesToApply.filter((c) => c.status === "added").length;
|
|
2415
|
+
const updatedFilesCount = changesToApply.filter((c) => c.status === "modified").length;
|
|
2502
2416
|
const parts = [];
|
|
2503
2417
|
if (addedCount > 0) parts.push(`added ${addedCount}`);
|
|
2504
2418
|
if (updatedFilesCount > 0) parts.push(`updated ${updatedFilesCount}`);
|
|
@@ -2525,20 +2439,12 @@ async function handleUpdateCommand(options) {
|
|
|
2525
2439
|
async function handleWorkspaceCommand(name, options) {
|
|
2526
2440
|
const monorepoRoot = await detectMonorepoRoot();
|
|
2527
2441
|
if (!monorepoRoot) {
|
|
2528
|
-
console.error(
|
|
2529
|
-
color__default.red("Error:") + " --workspace flag requires being inside a monorepo"
|
|
2530
|
-
);
|
|
2442
|
+
console.error(color__default.red("Error:") + " --workspace flag requires being inside a monorepo");
|
|
2531
2443
|
process.exit(1);
|
|
2532
2444
|
}
|
|
2533
2445
|
if (!name) {
|
|
2534
|
-
console.error(
|
|
2535
|
-
|
|
2536
|
-
);
|
|
2537
|
-
console.log(
|
|
2538
|
-
color__default.dim(
|
|
2539
|
-
" Example: pnpm create krispya my-lib --workspace --type library"
|
|
2540
|
-
)
|
|
2541
|
-
);
|
|
2446
|
+
console.error(color__default.red("Error:") + " Package name is required with --workspace flag");
|
|
2447
|
+
console.log(color__default.dim(" Example: pnpm create krispya my-lib --workspace --type library"));
|
|
2542
2448
|
process.exit(1);
|
|
2543
2449
|
}
|
|
2544
2450
|
const scope = await getMonorepoScope(monorepoRoot);
|
|
@@ -2549,32 +2455,23 @@ async function handleWorkspaceCommand(name, options) {
|
|
|
2549
2455
|
const template = options.template ?? "vanilla";
|
|
2550
2456
|
const baseTemplate = index.getBaseTemplate(template);
|
|
2551
2457
|
const scopedName = name.startsWith("@") ? name : `@${scope}/${name}`;
|
|
2552
|
-
const fullPackagePath =
|
|
2458
|
+
const fullPackagePath = node_path.join(monorepoRoot, targetDir, name);
|
|
2553
2459
|
try {
|
|
2554
|
-
await promises.access(fullPackagePath,
|
|
2555
|
-
console.error(
|
|
2556
|
-
color__default.red("Error:") + ` Directory ${targetDir}/${name} already exists`
|
|
2557
|
-
);
|
|
2460
|
+
await promises$1.access(fullPackagePath, node_fs.constants.F_OK);
|
|
2461
|
+
console.error(color__default.red("Error:") + ` Directory ${targetDir}/${name} already exists`);
|
|
2558
2462
|
process.exit(1);
|
|
2559
2463
|
} catch {
|
|
2560
2464
|
}
|
|
2561
|
-
const versions = {};
|
|
2562
|
-
const versionPromises = [];
|
|
2563
|
-
const isLibrary = projectType === "library";
|
|
2564
|
-
if (!isLibrary) {
|
|
2565
|
-
versionPromises.push(
|
|
2566
|
-
index.getLatestNpmVersion("vite", "6.3.4").then((v) => {
|
|
2567
|
-
versions.vite = v;
|
|
2568
|
-
})
|
|
2569
|
-
);
|
|
2570
|
-
}
|
|
2571
2465
|
const linter = inheritedSettings.linter ?? options.linter ?? "oxlint";
|
|
2572
2466
|
const formatter = inheritedSettings.formatter ?? options.formatter ?? "prettier";
|
|
2573
|
-
const packageManager = inheritedSettings.packageManager ?? "pnpm";
|
|
2574
|
-
const
|
|
2467
|
+
const packageManager = inheritedSettings.packageManager?.name ?? "pnpm";
|
|
2468
|
+
const engine = inheritedSettings.engine ?? {
|
|
2469
|
+
name: "node",
|
|
2470
|
+
version: "latest"
|
|
2471
|
+
};
|
|
2575
2472
|
const pnpmManageVersions = inheritedSettings.pnpmManageVersions ?? true;
|
|
2576
|
-
|
|
2577
|
-
const relativePkgPath =
|
|
2473
|
+
const isLibrary = projectType === "library";
|
|
2474
|
+
const relativePkgPath = node_path.join(targetDir, name);
|
|
2578
2475
|
const workspaceRoot = calculateWorkspaceRoot(relativePkgPath);
|
|
2579
2476
|
const generateOptions = {
|
|
2580
2477
|
name: scopedName,
|
|
@@ -2583,11 +2480,10 @@ async function handleWorkspaceCommand(name, options) {
|
|
|
2583
2480
|
template,
|
|
2584
2481
|
linter,
|
|
2585
2482
|
formatter,
|
|
2586
|
-
packageManager,
|
|
2587
|
-
|
|
2483
|
+
packageManager: { name: packageManager },
|
|
2484
|
+
engine,
|
|
2588
2485
|
pnpmManageVersions,
|
|
2589
2486
|
workspaceRoot,
|
|
2590
|
-
versions,
|
|
2591
2487
|
...baseTemplate === "r3f" && {
|
|
2592
2488
|
drei: options.drei ? {} : void 0,
|
|
2593
2489
|
handle: options.handle ? {} : void 0,
|
|
@@ -2603,15 +2499,14 @@ async function handleWorkspaceCommand(name, options) {
|
|
|
2603
2499
|
triplex: options.triplex ? {} : void 0
|
|
2604
2500
|
}
|
|
2605
2501
|
};
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
);
|
|
2502
|
+
generateOptions.packageManager = await index.resolvePackageManager(generateOptions);
|
|
2503
|
+
generateOptions.engine = await index.resolveEngine(generateOptions);
|
|
2504
|
+
generateOptions.versions = await index.resolveProjectPackageVersions(generateOptions);
|
|
2505
|
+
console.log(color__default.cyan("Creating") + ` ${scopedName} in ${targetDir}/${name}...`);
|
|
2609
2506
|
try {
|
|
2610
2507
|
const files = index.generate(generateOptions);
|
|
2611
2508
|
await writeGeneratedFiles(fullPackagePath, files);
|
|
2612
|
-
console.log(
|
|
2613
|
-
color__default.green("\u2713") + ` Created ${scopedName} at ${targetDir}/${name}`
|
|
2614
|
-
);
|
|
2509
|
+
console.log(color__default.green("\u2713") + ` Created ${scopedName} at ${targetDir}/${name}`);
|
|
2615
2510
|
process.exit(0);
|
|
2616
2511
|
} catch (error) {
|
|
2617
2512
|
console.error(color__default.red("Error:") + " Failed to create package");
|
|
@@ -2621,20 +2516,16 @@ async function handleWorkspaceCommand(name, options) {
|
|
|
2621
2516
|
}
|
|
2622
2517
|
async function handleMonorepoCreation(generateOptions, isNonInteractive) {
|
|
2623
2518
|
const { generateMonorepo } = await import('./chunks/index.cjs').then(function (n) { return n.monorepo; });
|
|
2624
|
-
const packageManager = generateOptions.packageManager
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
generateOptions.
|
|
2629
|
-
|
|
2630
|
-
generateOptions.
|
|
2631
|
-
}
|
|
2632
|
-
const nodeVersion = generateOptions.nodeVersion ?? "latest";
|
|
2633
|
-
if (nodeVersion === "latest") {
|
|
2634
|
-
generateOptions.nodeVersion = await index.getLatestNodeVersion();
|
|
2635
|
-
}
|
|
2519
|
+
const packageManager = index.getPackageManagerName(generateOptions.packageManager);
|
|
2520
|
+
generateOptions.packageManager = await index.resolvePackageManager(generateOptions);
|
|
2521
|
+
generateOptions.engine = await index.resolveEngine(generateOptions);
|
|
2522
|
+
generateOptions.versions = await index.resolveMonorepoRootPackageVersions({
|
|
2523
|
+
linter: generateOptions.linter ?? "oxlint",
|
|
2524
|
+
formatter: generateOptions.formatter ?? "prettier",
|
|
2525
|
+
versions: generateOptions.versions
|
|
2526
|
+
});
|
|
2636
2527
|
const aiPlatforms = await promptForAiPlatforms(isNonInteractive);
|
|
2637
|
-
const projectPath =
|
|
2528
|
+
const projectPath = node_path.join(node_process.cwd(), generateOptions.name);
|
|
2638
2529
|
const spinner = p__namespace.spinner();
|
|
2639
2530
|
spinner.start("Creating monorepo workspace...");
|
|
2640
2531
|
try {
|
|
@@ -2642,19 +2533,21 @@ async function handleMonorepoCreation(generateOptions, isNonInteractive) {
|
|
|
2642
2533
|
name: generateOptions.name,
|
|
2643
2534
|
linter: generateOptions.linter ?? "oxlint",
|
|
2644
2535
|
formatter: generateOptions.formatter ?? "prettier",
|
|
2645
|
-
packageManager
|
|
2646
|
-
|
|
2536
|
+
packageManager: generateOptions.packageManager ?? {
|
|
2537
|
+
name: packageManager
|
|
2538
|
+
},
|
|
2647
2539
|
pnpmManageVersions: generateOptions.pnpmManageVersions,
|
|
2648
|
-
|
|
2540
|
+
engine: generateOptions.engine,
|
|
2541
|
+
versions: generateOptions.versions,
|
|
2649
2542
|
aiPlatforms: aiPlatforms.length > 0 ? aiPlatforms : void 0
|
|
2650
2543
|
});
|
|
2651
2544
|
const filePaths = Object.keys(files).sort();
|
|
2652
2545
|
for (const filePath of filePaths) {
|
|
2653
|
-
const fullFilePath =
|
|
2654
|
-
await promises.mkdir(
|
|
2546
|
+
const fullFilePath = node_path.join(projectPath, filePath);
|
|
2547
|
+
await promises$1.mkdir(node_path.dirname(fullFilePath), { recursive: true });
|
|
2655
2548
|
const file = files[filePath];
|
|
2656
2549
|
if (file.type === "text") {
|
|
2657
|
-
await promises.writeFile(fullFilePath, file.content);
|
|
2550
|
+
await promises$1.writeFile(fullFilePath, file.content);
|
|
2658
2551
|
}
|
|
2659
2552
|
}
|
|
2660
2553
|
spinner.stop(color__default.green.inverse(" \u2713 Monorepo workspace created! "));
|
|
@@ -2664,8 +2557,10 @@ async function handleMonorepoCreation(generateOptions, isNonInteractive) {
|
|
|
2664
2557
|
const newWorkspaceSettings = {
|
|
2665
2558
|
linter: generateOptions.linter,
|
|
2666
2559
|
formatter: generateOptions.formatter,
|
|
2667
|
-
packageManager
|
|
2668
|
-
|
|
2560
|
+
packageManager: generateOptions.packageManager ?? {
|
|
2561
|
+
name: packageManager
|
|
2562
|
+
},
|
|
2563
|
+
engine: generateOptions.engine,
|
|
2669
2564
|
pnpmManageVersions: generateOptions.pnpmManageVersions
|
|
2670
2565
|
};
|
|
2671
2566
|
const scope = generateOptions.name;
|
|
@@ -2701,88 +2596,19 @@ async function handleStandaloneProjectCreation(generateOptions, isNonInteractive
|
|
|
2701
2596
|
if (aiPlatforms.length > 0) {
|
|
2702
2597
|
generateOptions.aiPlatforms = aiPlatforms;
|
|
2703
2598
|
}
|
|
2704
|
-
const packageManager = generateOptions.packageManager
|
|
2705
|
-
if (packageManager === "pnpm") {
|
|
2706
|
-
generateOptions.pnpmVersion = await index.getLatestPnpmVersion();
|
|
2707
|
-
} else if (packageManager === "yarn") {
|
|
2708
|
-
generateOptions.yarnVersion = await index.getLatestYarnVersion();
|
|
2709
|
-
} else if (packageManager === "npm") {
|
|
2710
|
-
generateOptions.npmVersion = await index.getLatestNpmCliVersion();
|
|
2711
|
-
}
|
|
2712
|
-
const nodeVersion = generateOptions.nodeVersion ?? "latest";
|
|
2713
|
-
if (nodeVersion === "latest") {
|
|
2714
|
-
generateOptions.nodeVersion = await index.getLatestNodeVersion();
|
|
2715
|
-
}
|
|
2716
|
-
const versions = {};
|
|
2717
|
-
const versionPromises = [];
|
|
2599
|
+
const packageManager = index.getPackageManagerName(generateOptions.packageManager);
|
|
2718
2600
|
const isLibrary = generateOptions.projectType === "library";
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
versions.vitest = v;
|
|
2724
|
-
})
|
|
2725
|
-
);
|
|
2726
|
-
}
|
|
2727
|
-
if (!isLibrary) {
|
|
2728
|
-
versionPromises.push(
|
|
2729
|
-
index.getLatestNpmVersion("vite", "6.3.4").then((v) => {
|
|
2730
|
-
versions.vite = v;
|
|
2731
|
-
})
|
|
2732
|
-
);
|
|
2733
|
-
}
|
|
2734
|
-
const linter = generateOptions.linter ?? "oxlint";
|
|
2735
|
-
if (linter === "eslint") {
|
|
2736
|
-
versionPromises.push(
|
|
2737
|
-
index.getLatestNpmVersion("eslint", "9.17.0").then((v) => {
|
|
2738
|
-
versions.eslint = v;
|
|
2739
|
-
})
|
|
2740
|
-
);
|
|
2741
|
-
} else if (linter === "oxlint") {
|
|
2742
|
-
versionPromises.push(
|
|
2743
|
-
index.getLatestNpmVersion("oxlint", "0.16.0").then((v) => {
|
|
2744
|
-
versions.oxlint = v;
|
|
2745
|
-
})
|
|
2746
|
-
);
|
|
2747
|
-
} else if (linter === "biome") {
|
|
2748
|
-
versionPromises.push(
|
|
2749
|
-
index.getLatestNpmVersion("@biomejs/biome", "1.9.4").then((v) => {
|
|
2750
|
-
versions.biome = v;
|
|
2751
|
-
})
|
|
2752
|
-
);
|
|
2753
|
-
}
|
|
2754
|
-
const formatter = generateOptions.formatter ?? "prettier";
|
|
2755
|
-
if (formatter === "prettier") {
|
|
2756
|
-
versionPromises.push(
|
|
2757
|
-
index.getLatestNpmVersion("prettier", "3.4.2").then((v) => {
|
|
2758
|
-
versions.prettier = v;
|
|
2759
|
-
})
|
|
2760
|
-
);
|
|
2761
|
-
} else if (formatter === "oxfmt") {
|
|
2762
|
-
versionPromises.push(
|
|
2763
|
-
index.getLatestNpmVersion("oxfmt", "0.1.0").then((v) => {
|
|
2764
|
-
versions.oxfmt = v;
|
|
2765
|
-
})
|
|
2766
|
-
);
|
|
2767
|
-
} else if (formatter === "biome" && linter !== "biome") {
|
|
2768
|
-
versionPromises.push(
|
|
2769
|
-
index.getLatestNpmVersion("@biomejs/biome", "1.9.4").then((v) => {
|
|
2770
|
-
versions.biome = v;
|
|
2771
|
-
})
|
|
2772
|
-
);
|
|
2773
|
-
}
|
|
2774
|
-
await Promise.all(versionPromises);
|
|
2775
|
-
generateOptions.versions = versions;
|
|
2776
|
-
const projectPath = path.join(process$1.cwd(), generateOptions.name);
|
|
2601
|
+
generateOptions.packageManager = await index.resolvePackageManager(generateOptions);
|
|
2602
|
+
generateOptions.engine = await index.resolveEngine(generateOptions);
|
|
2603
|
+
generateOptions.versions = await index.resolveProjectPackageVersions(generateOptions);
|
|
2604
|
+
const projectPath = node_path.join(node_process.cwd(), generateOptions.name);
|
|
2777
2605
|
const spinner = p__namespace.spinner();
|
|
2778
2606
|
spinner.start("Creating project...");
|
|
2779
2607
|
try {
|
|
2780
2608
|
const files = index.generate(generateOptions);
|
|
2781
2609
|
await writeGeneratedFiles(projectPath, files);
|
|
2782
2610
|
spinner.stop(color__default.green.inverse(" \u2713 Project created! "));
|
|
2783
|
-
if (isNonInteractive)
|
|
2784
|
-
process.exit(0);
|
|
2785
|
-
}
|
|
2611
|
+
if (isNonInteractive) process.exit(0);
|
|
2786
2612
|
const nextSteps = isLibrary ? [
|
|
2787
2613
|
`cd ${generateOptions.name}`,
|
|
2788
2614
|
`${packageManager} install`,
|
|
@@ -2821,7 +2647,7 @@ async function handleInteractiveMonorepoMode(monorepoRoot) {
|
|
|
2821
2647
|
const settingsInfo = [
|
|
2822
2648
|
inheritedSettings.linter && `linter: ${inheritedSettings.linter}`,
|
|
2823
2649
|
inheritedSettings.formatter && `formatter: ${inheritedSettings.formatter}`,
|
|
2824
|
-
inheritedSettings.packageManager && `pm: ${inheritedSettings.packageManager}`
|
|
2650
|
+
inheritedSettings.packageManager && `pm: ${inheritedSettings.packageManager.name}`
|
|
2825
2651
|
].filter(Boolean).join(", ");
|
|
2826
2652
|
p__namespace.log.info(`Using workspace settings (${settingsInfo})`);
|
|
2827
2653
|
}
|
|
@@ -2830,39 +2656,25 @@ async function handleInteractiveMonorepoMode(monorepoRoot) {
|
|
|
2830
2656
|
while (addMore) {
|
|
2831
2657
|
addMore = await createPackageInWorkspace(
|
|
2832
2658
|
monorepoRoot,
|
|
2833
|
-
inheritedSettings.packageManager ?? "pnpm",
|
|
2659
|
+
inheritedSettings.packageManager?.name ?? "pnpm",
|
|
2834
2660
|
inheritedSettings,
|
|
2835
2661
|
scope
|
|
2836
2662
|
);
|
|
2837
2663
|
}
|
|
2838
|
-
p__namespace.note(
|
|
2839
|
-
[`cd ${monorepoRoot}`, "pnpm install", "pnpm run dev"].join("\n"),
|
|
2840
|
-
"Next steps"
|
|
2841
|
-
);
|
|
2664
|
+
p__namespace.note([`cd ${monorepoRoot}`, "pnpm install", "pnpm run dev"].join("\n"), "Next steps");
|
|
2842
2665
|
await promptAndOpenEditor(monorepoRoot);
|
|
2843
2666
|
p__namespace.outro(color__default.green("Happy coding! \u2728"));
|
|
2844
2667
|
process.exit(0);
|
|
2845
2668
|
}
|
|
2846
2669
|
}
|
|
2847
2670
|
async function main() {
|
|
2848
|
-
const program = new commander.Command().name("create-krispya").description(
|
|
2849
|
-
"CLI for creating Vanilla, React, and React Three Fiber projects"
|
|
2850
|
-
).argument("[name]", "name for the project").option("--type <type>", "project type: app or library (default: app)").option(
|
|
2671
|
+
const program = new commander.Command().name("create-krispya").description("CLI for creating Vanilla, React, and React Three Fiber projects").argument("[name]", "name for the project").option("--type <type>", "project type: app or library (default: app)").option(
|
|
2851
2672
|
"--bundler <bundler>",
|
|
2852
2673
|
"library bundler: unbuild or tsdown (default: unbuild, only for libraries)"
|
|
2853
2674
|
).option(
|
|
2854
2675
|
"--template <type>",
|
|
2855
2676
|
"project template: vanilla, vanilla-js, react, react-js, r3f, r3f-js (default: vanilla)"
|
|
2856
|
-
).option(
|
|
2857
|
-
"--linter <type>",
|
|
2858
|
-
"linter: eslint, oxlint, or biome (default: oxlint)"
|
|
2859
|
-
).option(
|
|
2860
|
-
"--formatter <type>",
|
|
2861
|
-
"formatter: prettier, oxfmt, or biome (default: prettier)"
|
|
2862
|
-
).option("--drei", "add @react-three/drei (r3f only)").option("--handle", "add @react-three/handle (r3f only)").option("--leva", "add leva (r3f only)").option("--postprocessing", "add @react-three/postprocessing (r3f only)").option("--rapier", "add @react-three/rapier (r3f only)").option("--xr", "add @react-three/xr (r3f only)").option("--uikit", "add @react-three/uikit (r3f only)").option("--offscreen", "add @react-three/offscreen (r3f only)").option("--zustand", "add zustand (r3f only)").option("--koota", "add koota (r3f only)").option("--triplex", "set up triplex development environment (r3f only)").option("--viverse", "set up viverse deployment (r3f only)").option(
|
|
2863
|
-
"--package-manager <manager>",
|
|
2864
|
-
"specify package manager (e.g. npm, yarn, pnpm)"
|
|
2865
|
-
).option(
|
|
2677
|
+
).option("--linter <type>", "linter: eslint, oxlint, or biome (default: oxlint)").option("--formatter <type>", "formatter: prettier, oxfmt, or biome (default: prettier)").option("--drei", "add @react-three/drei (r3f only)").option("--handle", "add @react-three/handle (r3f only)").option("--leva", "add leva (r3f only)").option("--postprocessing", "add @react-three/postprocessing (r3f only)").option("--rapier", "add @react-three/rapier (r3f only)").option("--xr", "add @react-three/xr (r3f only)").option("--uikit", "add @react-three/uikit (r3f only)").option("--offscreen", "add @react-three/offscreen (r3f only)").option("--zustand", "add zustand (r3f only)").option("--koota", "add koota (r3f only)").option("--triplex", "set up triplex development environment (r3f only)").option("--viverse", "set up viverse deployment (r3f only)").option("--package-manager <manager>", "specify package manager (e.g. npm, yarn, pnpm)").option(
|
|
2866
2678
|
"--pnpm-manage-versions",
|
|
2867
2679
|
"enable manage-package-manager-versions in pnpm-workspace.yaml (default: true)"
|
|
2868
2680
|
).option(
|
|
@@ -2871,16 +2683,7 @@ async function main() {
|
|
|
2871
2683
|
).option(
|
|
2872
2684
|
"--node-version <version>",
|
|
2873
2685
|
'set Node.js version for engines.node field (default: "latest")'
|
|
2874
|
-
).option(
|
|
2875
|
-
"--workspace",
|
|
2876
|
-
"Add package to current monorepo workspace (non-interactive)"
|
|
2877
|
-
).option(
|
|
2878
|
-
"--dir <directory>",
|
|
2879
|
-
"Target directory for --workspace (default: apps/ or packages/)"
|
|
2880
|
-
).option("--clear-config", "Clear saved preferences (e.g. editor choice)").option("--config-path", "Print the path to the config file").option(
|
|
2881
|
-
"--check",
|
|
2882
|
-
"Check if current directory is in a valid monorepo workspace"
|
|
2883
|
-
).option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option(
|
|
2686
|
+
).option("--workspace", "Add package to current monorepo workspace (non-interactive)").option("--dir <directory>", "Target directory for --workspace (default: apps/ or packages/)").option("--clear-config", "Clear saved preferences (e.g. editor choice)").option("--config-path", "Print the path to the config file").option("--check", "Check if current directory is in a valid monorepo workspace").option("--fix", "Fix monorepo by generating missing .config packages").option("--update", "Update monorepo workspace to latest configuration").option("-y, --yes", "Non-interactive mode - accept all prompts").option(
|
|
2884
2687
|
"--path <directory>",
|
|
2885
2688
|
"Run in specified directory instead of current working directory"
|
|
2886
2689
|
).action(async (name, options) => {
|
|
@@ -2942,9 +2745,7 @@ async function main() {
|
|
|
2942
2745
|
if (options.dir && !options.workspace) {
|
|
2943
2746
|
console.error(color__default.red("Error:") + " --dir requires --workspace flag");
|
|
2944
2747
|
console.log(
|
|
2945
|
-
color__default.dim(
|
|
2946
|
-
" Example: pnpm create krispya my-lib --workspace --dir examples"
|
|
2947
|
-
)
|
|
2748
|
+
color__default.dim(" Example: pnpm create krispya my-lib --workspace --dir examples")
|
|
2948
2749
|
);
|
|
2949
2750
|
process.exit(1);
|
|
2950
2751
|
}
|
|
@@ -2984,9 +2785,9 @@ async function main() {
|
|
|
2984
2785
|
viverse: options.viverse ? {} : void 0,
|
|
2985
2786
|
triplex: options.triplex ? {} : void 0
|
|
2986
2787
|
},
|
|
2987
|
-
packageManager: options.packageManager,
|
|
2788
|
+
packageManager: options.packageManager ? { name: options.packageManager } : void 0,
|
|
2988
2789
|
pnpmManageVersions: options.pnpmManageVersions,
|
|
2989
|
-
|
|
2790
|
+
engine: { name: "node", version: options.nodeVersion ?? "latest" }
|
|
2990
2791
|
};
|
|
2991
2792
|
} else {
|
|
2992
2793
|
const presets = hasConfigOptions(options) ? {
|
|
@@ -2996,7 +2797,7 @@ async function main() {
|
|
|
2996
2797
|
linter: options.linter,
|
|
2997
2798
|
formatter: options.formatter,
|
|
2998
2799
|
packageManager: options.packageManager,
|
|
2999
|
-
nodeVersion: options.nodeVersion,
|
|
2800
|
+
engine: options.nodeVersion ? { name: "node", version: options.nodeVersion } : void 0,
|
|
3000
2801
|
pnpmManageVersions: options.pnpmManageVersions,
|
|
3001
2802
|
drei: options.drei,
|
|
3002
2803
|
handle: options.handle,
|