create-krispya 0.5.3 → 0.6.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 +115 -11
- package/dist/chunks/index.cjs +487 -277
- package/dist/chunks/index.mjs +484 -278
- package/dist/cli.cjs +1261 -273
- package/dist/cli.mjs +1264 -276
- package/dist/index.cjs +4 -0
- package/dist/index.d.cts +21 -5
- package/dist/index.d.mts +21 -5
- package/dist/index.d.ts +21 -5
- package/dist/index.mjs +4 -1
- package/package.json +1 -1
package/dist/chunks/index.cjs
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
const color = require('chalk');
|
|
4
|
+
const promises = require('fs/promises');
|
|
5
|
+
const fs = require('fs');
|
|
6
|
+
const path = require('path');
|
|
4
7
|
|
|
5
8
|
function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
|
|
6
9
|
|
|
@@ -96,6 +99,34 @@ const defaultFormatterConfig = {
|
|
|
96
99
|
bracketSpacing: true,
|
|
97
100
|
arrowParens: "always"
|
|
98
101
|
};
|
|
102
|
+
const defaultPrettierConfig = {
|
|
103
|
+
$schema: "https://json.schemastore.org/prettierrc",
|
|
104
|
+
...defaultFormatterConfig,
|
|
105
|
+
overrides: [
|
|
106
|
+
{
|
|
107
|
+
files: ["*.json", "**/*.json"],
|
|
108
|
+
options: { tabWidth: 2 }
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
files: ["*.md", "**/*.md"],
|
|
112
|
+
options: { tabWidth: 2, semi: false }
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
files: ["*.yml", "*.yaml", "**/*.yml", "**/*.yaml"],
|
|
116
|
+
options: { tabWidth: 2, semi: false }
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
};
|
|
120
|
+
const defaultOxfmtConfig = {
|
|
121
|
+
printWidth: defaultFormatterConfig.printWidth,
|
|
122
|
+
tabWidth: defaultFormatterConfig.tabWidth,
|
|
123
|
+
useTabs: defaultFormatterConfig.useTabs,
|
|
124
|
+
semi: defaultFormatterConfig.semi,
|
|
125
|
+
singleQuote: defaultFormatterConfig.singleQuote,
|
|
126
|
+
trailingComma: defaultFormatterConfig.trailingComma,
|
|
127
|
+
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
128
|
+
arrowParens: defaultFormatterConfig.arrowParens
|
|
129
|
+
};
|
|
99
130
|
const defaultLinterConfig = {
|
|
100
131
|
ignorePatterns: ["dist"],
|
|
101
132
|
rules: {
|
|
@@ -112,9 +143,88 @@ const defaultLinterConfig = {
|
|
|
112
143
|
}
|
|
113
144
|
};
|
|
114
145
|
|
|
146
|
+
const ALL_AI_PLATFORMS = ["agents", "claude"];
|
|
147
|
+
const AI_PLATFORM_LABELS = {
|
|
148
|
+
agents: "AGENTS.md",
|
|
149
|
+
claude: "CLAUDE.md"
|
|
150
|
+
};
|
|
151
|
+
const AI_PLATFORM_HINTS = {
|
|
152
|
+
agents: "OpenAI, Cursor, Windsurf, etc.",
|
|
153
|
+
claude: "Claude Code"
|
|
154
|
+
};
|
|
155
|
+
function generateAiFiles(files, params) {
|
|
156
|
+
const { platforms, isMonorepo, configStrategy, ...rest } = params;
|
|
157
|
+
if (platforms.length === 0) return;
|
|
158
|
+
files[".ai/workspace.md"] = {
|
|
159
|
+
type: "text",
|
|
160
|
+
content: generateWorkspace({
|
|
161
|
+
...rest,
|
|
162
|
+
isMonorepo: !!isMonorepo,
|
|
163
|
+
configStrategy: configStrategy ?? "stealth"
|
|
164
|
+
})
|
|
165
|
+
};
|
|
166
|
+
const pointer = "See `.ai/` for project rules.\n";
|
|
167
|
+
for (const platform of platforms) {
|
|
168
|
+
const path = platform === "agents" ? "AGENTS.md" : "CLAUDE.md";
|
|
169
|
+
files[path] = { type: "text", content: pointer };
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function generateWorkspace(ctx) {
|
|
173
|
+
const { name, packageManager, linter, formatter, isMonorepo, configStrategy } = ctx;
|
|
174
|
+
const sections = [
|
|
175
|
+
`# ${name}`,
|
|
176
|
+
"",
|
|
177
|
+
`- **Type:** ${isMonorepo ? "pnpm monorepo" : "standalone project"}`,
|
|
178
|
+
`- **Package Manager:** ${packageManager}`,
|
|
179
|
+
`- **Linter:** ${linter}`,
|
|
180
|
+
`- **Formatter:** ${formatter}`,
|
|
181
|
+
"",
|
|
182
|
+
"## Commands",
|
|
183
|
+
"",
|
|
184
|
+
`- \`${packageManager} test\` \u2014 run tests`,
|
|
185
|
+
`- \`${packageManager} build\` \u2014 build`,
|
|
186
|
+
`- \`${packageManager} lint\` and \`${packageManager} format\` \u2014 run before committing`
|
|
187
|
+
];
|
|
188
|
+
if (isMonorepo) {
|
|
189
|
+
sections.push(
|
|
190
|
+
"",
|
|
191
|
+
"## Structure",
|
|
192
|
+
"",
|
|
193
|
+
"- `apps/` \u2014 applications",
|
|
194
|
+
"- `packages/` \u2014 shared libraries",
|
|
195
|
+
"- `.config/` \u2014 shared config packages",
|
|
196
|
+
"",
|
|
197
|
+
"## Monorepo",
|
|
198
|
+
"",
|
|
199
|
+
"- Use `workspace:*` for internal dependencies",
|
|
200
|
+
`- New packages: \`${packageManager} create krispya <name> --workspace\``
|
|
201
|
+
);
|
|
202
|
+
} else if (configStrategy === "root") {
|
|
203
|
+
sections.push(
|
|
204
|
+
"",
|
|
205
|
+
"## Structure",
|
|
206
|
+
"",
|
|
207
|
+
"- `src/` \u2014 source code",
|
|
208
|
+
"- `dist/` \u2014 generated, don't edit",
|
|
209
|
+
"- Config files (`tsconfig.json`, etc.) are at project root"
|
|
210
|
+
);
|
|
211
|
+
} else {
|
|
212
|
+
sections.push(
|
|
213
|
+
"",
|
|
214
|
+
"## Structure",
|
|
215
|
+
"",
|
|
216
|
+
"- `src/` \u2014 source code",
|
|
217
|
+
"- `.config/` \u2014 configs, don't move",
|
|
218
|
+
"- `dist/` \u2014 generated, don't edit"
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
sections.push("");
|
|
222
|
+
return sections.join("\n");
|
|
223
|
+
}
|
|
224
|
+
|
|
115
225
|
function generateTypescriptConfig(baseTemplateOrParams) {
|
|
116
226
|
const params = typeof baseTemplateOrParams === "string" ? { baseTemplate: baseTemplateOrParams } : baseTemplateOrParams;
|
|
117
|
-
const { baseTemplate, useConfigPackage } = params;
|
|
227
|
+
const { baseTemplate, useConfigPackage, configStrategy = "stealth" } = params;
|
|
118
228
|
const isReact = baseTemplate === "react";
|
|
119
229
|
const isR3f = baseTemplate === "r3f";
|
|
120
230
|
const files = {};
|
|
@@ -143,58 +253,113 @@ function generateTypescriptConfig(baseTemplateOrParams) {
|
|
|
143
253
|
};
|
|
144
254
|
return { files, devDependencies };
|
|
145
255
|
}
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
256
|
+
if (configStrategy === "stealth") {
|
|
257
|
+
const tsConfig = {
|
|
258
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
259
|
+
files: [],
|
|
260
|
+
references: [{ path: "./.config/tsconfig.app.json" }, { path: "./.config/tsconfig.node.json" }]
|
|
261
|
+
};
|
|
262
|
+
files["tsconfig.json"] = {
|
|
263
|
+
type: "text",
|
|
264
|
+
content: JSON.stringify(tsConfig, null, 2)
|
|
265
|
+
};
|
|
266
|
+
const tsConfigApp = {
|
|
267
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
268
|
+
compilerOptions: {
|
|
269
|
+
target: "ESNext",
|
|
270
|
+
module: "ESNext",
|
|
271
|
+
moduleResolution: "bundler",
|
|
272
|
+
lib: ["DOM", "DOM.Iterable", "ESNext"],
|
|
273
|
+
esModuleInterop: true,
|
|
274
|
+
allowSyntheticDefaultImports: true,
|
|
275
|
+
strict: true,
|
|
276
|
+
skipLibCheck: true,
|
|
277
|
+
composite: true,
|
|
278
|
+
rewriteRelativeImportExtensions: true,
|
|
279
|
+
erasableSyntaxOnly: true,
|
|
280
|
+
...isReact || isR3f ? { jsx: "react-jsx" } : {}
|
|
281
|
+
},
|
|
282
|
+
include: ["../src", "../tests"]
|
|
283
|
+
};
|
|
284
|
+
files[".config/tsconfig.app.json"] = {
|
|
285
|
+
type: "text",
|
|
286
|
+
content: JSON.stringify(tsConfigApp, null, 2)
|
|
287
|
+
};
|
|
288
|
+
const tsConfigNode = {
|
|
289
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
290
|
+
compilerOptions: {
|
|
291
|
+
target: "ESNext",
|
|
292
|
+
module: "ESNext",
|
|
293
|
+
moduleResolution: "bundler",
|
|
294
|
+
lib: ["ESNext"],
|
|
295
|
+
esModuleInterop: true,
|
|
296
|
+
allowSyntheticDefaultImports: true,
|
|
297
|
+
strict: true,
|
|
298
|
+
skipLibCheck: true,
|
|
299
|
+
composite: true,
|
|
300
|
+
rewriteRelativeImportExtensions: true,
|
|
301
|
+
erasableSyntaxOnly: true
|
|
302
|
+
},
|
|
303
|
+
include: ["../*.config.ts", "./*.ts"]
|
|
304
|
+
};
|
|
305
|
+
files[".config/tsconfig.node.json"] = {
|
|
306
|
+
type: "text",
|
|
307
|
+
content: JSON.stringify(tsConfigNode, null, 2)
|
|
308
|
+
};
|
|
309
|
+
} else {
|
|
310
|
+
const tsConfig = {
|
|
311
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
312
|
+
files: [],
|
|
313
|
+
references: [{ path: "./tsconfig.app.json" }, { path: "./tsconfig.node.json" }]
|
|
314
|
+
};
|
|
315
|
+
files["tsconfig.json"] = {
|
|
316
|
+
type: "text",
|
|
317
|
+
content: JSON.stringify(tsConfig, null, 2)
|
|
318
|
+
};
|
|
319
|
+
const tsConfigApp = {
|
|
320
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
321
|
+
compilerOptions: {
|
|
322
|
+
target: "ESNext",
|
|
323
|
+
module: "ESNext",
|
|
324
|
+
moduleResolution: "bundler",
|
|
325
|
+
lib: ["DOM", "DOM.Iterable", "ESNext"],
|
|
326
|
+
esModuleInterop: true,
|
|
327
|
+
allowSyntheticDefaultImports: true,
|
|
328
|
+
strict: true,
|
|
329
|
+
skipLibCheck: true,
|
|
330
|
+
composite: true,
|
|
331
|
+
rewriteRelativeImportExtensions: true,
|
|
332
|
+
erasableSyntaxOnly: true,
|
|
333
|
+
...isReact || isR3f ? { jsx: "react-jsx" } : {}
|
|
334
|
+
},
|
|
335
|
+
include: ["src", "tests"]
|
|
336
|
+
};
|
|
337
|
+
files["tsconfig.app.json"] = {
|
|
338
|
+
type: "text",
|
|
339
|
+
content: JSON.stringify(tsConfigApp, null, 2)
|
|
340
|
+
};
|
|
341
|
+
const tsConfigNode = {
|
|
342
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
343
|
+
compilerOptions: {
|
|
344
|
+
target: "ESNext",
|
|
345
|
+
module: "ESNext",
|
|
346
|
+
moduleResolution: "bundler",
|
|
347
|
+
lib: ["ESNext"],
|
|
348
|
+
esModuleInterop: true,
|
|
349
|
+
allowSyntheticDefaultImports: true,
|
|
350
|
+
strict: true,
|
|
351
|
+
skipLibCheck: true,
|
|
352
|
+
composite: true,
|
|
353
|
+
rewriteRelativeImportExtensions: true,
|
|
354
|
+
erasableSyntaxOnly: true
|
|
355
|
+
},
|
|
356
|
+
include: ["*.config.ts"]
|
|
357
|
+
};
|
|
358
|
+
files["tsconfig.node.json"] = {
|
|
359
|
+
type: "text",
|
|
360
|
+
content: JSON.stringify(tsConfigNode, null, 2)
|
|
361
|
+
};
|
|
362
|
+
}
|
|
198
363
|
return { files, devDependencies };
|
|
199
364
|
}
|
|
200
365
|
|
|
@@ -604,9 +769,12 @@ function generateVscodeFiles$1(params) {
|
|
|
604
769
|
};
|
|
605
770
|
}
|
|
606
771
|
if (Object.keys(vscodeSettings).length > 0) {
|
|
772
|
+
const sortedSettings = Object.fromEntries(
|
|
773
|
+
Object.entries(vscodeSettings).sort(([a], [b]) => a.localeCompare(b))
|
|
774
|
+
);
|
|
607
775
|
files[".vscode/settings.json"] = {
|
|
608
776
|
type: "text",
|
|
609
|
-
content: JSON.stringify(
|
|
777
|
+
content: JSON.stringify(sortedSettings, null, " ")
|
|
610
778
|
};
|
|
611
779
|
}
|
|
612
780
|
return files;
|
|
@@ -659,128 +827,6 @@ function generateViteConfig(params) {
|
|
|
659
827
|
return { type: "text", content: viteConfigContent };
|
|
660
828
|
}
|
|
661
829
|
|
|
662
|
-
function generateAiFiles(files, params) {
|
|
663
|
-
const { name, packageManager, linter, formatter, aiFiles } = params;
|
|
664
|
-
const content = getAiInstructionsContent({
|
|
665
|
-
name,
|
|
666
|
-
packageManager,
|
|
667
|
-
linter,
|
|
668
|
-
formatter
|
|
669
|
-
});
|
|
670
|
-
for (const fileChoice of aiFiles) {
|
|
671
|
-
switch (fileChoice) {
|
|
672
|
-
case "cursor-rules":
|
|
673
|
-
files[".cursor/rules"] = { type: "text", content };
|
|
674
|
-
break;
|
|
675
|
-
case "agents-md":
|
|
676
|
-
files["AGENTS.md"] = { type: "text", content };
|
|
677
|
-
break;
|
|
678
|
-
case "claude-md":
|
|
679
|
-
files["CLAUDE.md"] = { type: "text", content };
|
|
680
|
-
break;
|
|
681
|
-
case "copilot-md":
|
|
682
|
-
files[".github/copilot-instructions.md"] = { type: "text", content };
|
|
683
|
-
break;
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
}
|
|
687
|
-
function getConfigPackagesDescription(linter, formatter) {
|
|
688
|
-
const packages = ["`@config/typescript`"];
|
|
689
|
-
if (linter !== "biome") {
|
|
690
|
-
packages.push(`\`@config/${linter}\``);
|
|
691
|
-
}
|
|
692
|
-
if (formatter !== "biome" && formatter !== linter) {
|
|
693
|
-
packages.push(`\`@config/${formatter}\``);
|
|
694
|
-
}
|
|
695
|
-
let description = `- \`.config/\`: shared config packages (${packages.join(", ")})`;
|
|
696
|
-
if (linter === "biome" || formatter === "biome") {
|
|
697
|
-
description += "\n- `biome.json`: Biome configuration (root level)";
|
|
698
|
-
}
|
|
699
|
-
return description;
|
|
700
|
-
}
|
|
701
|
-
function getAiInstructionsContent(params) {
|
|
702
|
-
const { name, packageManager, linter, formatter } = params;
|
|
703
|
-
const configDescription = getConfigPackagesDescription(linter, formatter);
|
|
704
|
-
return `# ${name}
|
|
705
|
-
|
|
706
|
-
This is a pnpm monorepo workspace generated with \`create-krispya\`.
|
|
707
|
-
|
|
708
|
-
## Most important rule (package creation)
|
|
709
|
-
|
|
710
|
-
If you need a new app/package for any reason, **ALWAYS** create it with \`create-krispya\` (do not hand-create folders/package.json).
|
|
711
|
-
|
|
712
|
-
### Non-interactive (preferred for agents)
|
|
713
|
-
|
|
714
|
-
\`\`\`bash
|
|
715
|
-
${packageManager} create krispya <name> --workspace [options]
|
|
716
|
-
\`\`\`
|
|
717
|
-
|
|
718
|
-
- The package directory will be \`apps/<name>\` (apps) or \`packages/<name>\` (libraries), unless \`--dir\` is provided.
|
|
719
|
-
- Package names default to \`@${name}/<name>\` but you can pass any name (scoped or unscoped).
|
|
720
|
-
|
|
721
|
-
### Workspace maintenance (non-interactive)
|
|
722
|
-
|
|
723
|
-
\`\`\`bash
|
|
724
|
-
${packageManager} create krispya --check # validate workspace
|
|
725
|
-
${packageManager} create krispya --fix --linter ${linter} --formatter ${formatter} # fix missing .config packages
|
|
726
|
-
\`\`\`
|
|
727
|
-
|
|
728
|
-
For non-interactive \`--fix\`, you MUST provide both \`--linter\` and \`--formatter\` flags.
|
|
729
|
-
|
|
730
|
-
## Package creation options (CLI truth)
|
|
731
|
-
|
|
732
|
-
| Option | Values | Notes |
|
|
733
|
-
|--------|--------|-------|
|
|
734
|
-
| \`--type\` | app, library | default: app |
|
|
735
|
-
| \`--template\` | vanilla, vanilla-js, react, react-js, r3f, r3f-js | default: vanilla |
|
|
736
|
-
| \`--dir\` | any directory | requires \`--workspace\`; default: \`apps/\` or \`packages/\` |
|
|
737
|
-
| \`--bundler\` | unbuild, tsdown | libraries only; default: unbuild |
|
|
738
|
-
|
|
739
|
-
### R3F flags (r3f templates only)
|
|
740
|
-
|
|
741
|
-
\`--drei\` \`--handle\` \`--leva\` \`--postprocessing\` \`--rapier\` \`--xr\` \`--uikit\` \`--offscreen\` \`--zustand\` \`--koota\` \`--triplex\` \`--viverse\`
|
|
742
|
-
|
|
743
|
-
### Examples
|
|
744
|
-
|
|
745
|
-
\`\`\`bash
|
|
746
|
-
# React library (@${name}/ui) in packages/ui
|
|
747
|
-
${packageManager} create krispya ui --workspace --type library --template react
|
|
748
|
-
|
|
749
|
-
# R3F app with physics + controls (@${name}/game) in apps/game
|
|
750
|
-
${packageManager} create krispya game --workspace --type app --template r3f --drei --rapier --leva
|
|
751
|
-
|
|
752
|
-
# App in a custom directory
|
|
753
|
-
${packageManager} create krispya demo --workspace --type app --template react --dir examples
|
|
754
|
-
\`\`\`
|
|
755
|
-
|
|
756
|
-
## After creating a package
|
|
757
|
-
|
|
758
|
-
\`\`\`bash
|
|
759
|
-
${packageManager} install
|
|
760
|
-
\`\`\`
|
|
761
|
-
|
|
762
|
-
- Use \`"workspace:*"\` for internal deps (e.g. \`"@${name}/ui": "workspace:*"\`).
|
|
763
|
-
|
|
764
|
-
## Workspace commands
|
|
765
|
-
|
|
766
|
-
\`\`\`bash
|
|
767
|
-
${packageManager} install # Install all dependencies
|
|
768
|
-
${packageManager} run dev # Run all apps in dev mode
|
|
769
|
-
${packageManager} run build # Build packages then apps
|
|
770
|
-
${packageManager} run test # Run all tests
|
|
771
|
-
${packageManager} run lint # Lint with ${linter}
|
|
772
|
-
${packageManager} run format # Format with ${formatter}
|
|
773
|
-
\`\`\`
|
|
774
|
-
|
|
775
|
-
## Structure + conventions
|
|
776
|
-
|
|
777
|
-
- \`apps/\`: applications (\`--type app\`)
|
|
778
|
-
- \`packages/\`: libraries (\`--type library\`)
|
|
779
|
-
${configDescription}
|
|
780
|
-
- TS configs extend \`@config/typescript/*\` (base/app/node/react)
|
|
781
|
-
`;
|
|
782
|
-
}
|
|
783
|
-
|
|
784
830
|
function generateTypescriptConfigPackage(files) {
|
|
785
831
|
const basePath = ".config/typescript";
|
|
786
832
|
files[`${basePath}/package.json`] = {
|
|
@@ -1132,20 +1178,7 @@ Or in \`.prettierrc.json\`:
|
|
|
1132
1178
|
};
|
|
1133
1179
|
files[`${basePath}/base.json`] = {
|
|
1134
1180
|
type: "text",
|
|
1135
|
-
content: JSON.stringify(
|
|
1136
|
-
{
|
|
1137
|
-
printWidth: defaultFormatterConfig.printWidth,
|
|
1138
|
-
tabWidth: defaultFormatterConfig.tabWidth,
|
|
1139
|
-
useTabs: defaultFormatterConfig.useTabs,
|
|
1140
|
-
semi: defaultFormatterConfig.semi,
|
|
1141
|
-
singleQuote: defaultFormatterConfig.singleQuote,
|
|
1142
|
-
trailingComma: defaultFormatterConfig.trailingComma,
|
|
1143
|
-
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
1144
|
-
arrowParens: defaultFormatterConfig.arrowParens
|
|
1145
|
-
},
|
|
1146
|
-
null,
|
|
1147
|
-
2
|
|
1148
|
-
)
|
|
1181
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1149
1182
|
};
|
|
1150
1183
|
}
|
|
1151
1184
|
function generateOxfmtConfigPackage(files) {
|
|
@@ -1184,20 +1217,7 @@ oxfmt -c node_modules/@config/oxfmt/base.json --write .
|
|
|
1184
1217
|
};
|
|
1185
1218
|
files[`${basePath}/base.json`] = {
|
|
1186
1219
|
type: "text",
|
|
1187
|
-
content: JSON.stringify(
|
|
1188
|
-
{
|
|
1189
|
-
printWidth: defaultFormatterConfig.printWidth,
|
|
1190
|
-
tabWidth: defaultFormatterConfig.tabWidth,
|
|
1191
|
-
useTabs: defaultFormatterConfig.useTabs,
|
|
1192
|
-
semi: defaultFormatterConfig.semi,
|
|
1193
|
-
singleQuote: defaultFormatterConfig.singleQuote,
|
|
1194
|
-
trailingComma: defaultFormatterConfig.trailingComma,
|
|
1195
|
-
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
1196
|
-
arrowParens: defaultFormatterConfig.arrowParens
|
|
1197
|
-
},
|
|
1198
|
-
null,
|
|
1199
|
-
2
|
|
1200
|
-
)
|
|
1220
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1201
1221
|
};
|
|
1202
1222
|
}
|
|
1203
1223
|
|
|
@@ -1210,7 +1230,7 @@ function generateMonorepo(params) {
|
|
|
1210
1230
|
pnpmVersion,
|
|
1211
1231
|
pnpmManageVersions,
|
|
1212
1232
|
nodeVersion,
|
|
1213
|
-
|
|
1233
|
+
aiPlatforms
|
|
1214
1234
|
} = params;
|
|
1215
1235
|
const files = {};
|
|
1216
1236
|
const isPnpm = packageManager === "pnpm";
|
|
@@ -1237,7 +1257,7 @@ function generateMonorepo(params) {
|
|
|
1237
1257
|
build: "pnpm --filter './packages/*' run build && pnpm --filter './apps/*' run build",
|
|
1238
1258
|
test: "pnpm -r run test",
|
|
1239
1259
|
lint: linter === "oxlint" ? "oxlint ." : linter === "biome" ? "biome check ." : "eslint .",
|
|
1240
|
-
format: formatter === "oxfmt" ? "oxfmt ." : formatter === "biome" ? "biome format . --write" : "prettier --write ."
|
|
1260
|
+
format: formatter === "oxfmt" ? "oxfmt -c .config/oxfmt/base.json ." : formatter === "biome" ? "biome format . --write" : "prettier --config .config/prettier/base.json --write ."
|
|
1241
1261
|
},
|
|
1242
1262
|
devDependencies
|
|
1243
1263
|
};
|
|
@@ -1276,11 +1296,43 @@ function generateMonorepo(params) {
|
|
|
1276
1296
|
content: workspaceLines.join("\n")
|
|
1277
1297
|
};
|
|
1278
1298
|
}
|
|
1299
|
+
files["tsconfig.json"] = {
|
|
1300
|
+
type: "text",
|
|
1301
|
+
content: JSON.stringify(
|
|
1302
|
+
{
|
|
1303
|
+
extends: "@config/typescript/base.json",
|
|
1304
|
+
compilerOptions: {
|
|
1305
|
+
noEmit: true
|
|
1306
|
+
},
|
|
1307
|
+
references: []
|
|
1308
|
+
},
|
|
1309
|
+
null,
|
|
1310
|
+
2
|
|
1311
|
+
)
|
|
1312
|
+
};
|
|
1279
1313
|
generateTypescriptConfigPackage(files);
|
|
1280
1314
|
if (linter === "oxlint") {
|
|
1281
1315
|
generateOxlintConfigPackage(files);
|
|
1316
|
+
files["oxlint.json"] = {
|
|
1317
|
+
type: "text",
|
|
1318
|
+
content: JSON.stringify(
|
|
1319
|
+
{
|
|
1320
|
+
$schema: "./node_modules/oxlint/configuration_schema.json",
|
|
1321
|
+
extends: ["@config/oxlint/base.json"]
|
|
1322
|
+
},
|
|
1323
|
+
null,
|
|
1324
|
+
2
|
|
1325
|
+
)
|
|
1326
|
+
};
|
|
1282
1327
|
} else if (linter === "eslint") {
|
|
1283
1328
|
generateEslintConfigPackage(files);
|
|
1329
|
+
files["eslint.config.js"] = {
|
|
1330
|
+
type: "text",
|
|
1331
|
+
content: `import base from "@config/eslint/base";
|
|
1332
|
+
|
|
1333
|
+
export default [...base];
|
|
1334
|
+
`
|
|
1335
|
+
};
|
|
1284
1336
|
} else if (linter === "biome") {
|
|
1285
1337
|
const biomeConfig = {
|
|
1286
1338
|
$schema: "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
@@ -1347,13 +1399,14 @@ This monorepo workspace was generated with create-krispya.
|
|
|
1347
1399
|
To add a new package to this workspace, run create-krispya from this directory and it will detect the monorepo.
|
|
1348
1400
|
`
|
|
1349
1401
|
};
|
|
1350
|
-
if (
|
|
1402
|
+
if (aiPlatforms && aiPlatforms.length > 0) {
|
|
1351
1403
|
generateAiFiles(files, {
|
|
1352
1404
|
name,
|
|
1353
1405
|
packageManager,
|
|
1354
1406
|
linter,
|
|
1355
1407
|
formatter,
|
|
1356
|
-
|
|
1408
|
+
isMonorepo: true,
|
|
1409
|
+
platforms: aiPlatforms
|
|
1357
1410
|
});
|
|
1358
1411
|
}
|
|
1359
1412
|
return { files };
|
|
@@ -1425,14 +1478,11 @@ function generateBiome(generator, options) {
|
|
|
1425
1478
|
if (options == null || !options.linter && !options.formatter) {
|
|
1426
1479
|
return;
|
|
1427
1480
|
}
|
|
1428
|
-
const version = generator.versions.biome ?? "
|
|
1481
|
+
const version = generator.versions.biome ?? "2.0.0";
|
|
1429
1482
|
generator.addDevDependency("@biomejs/biome", `^${version}`);
|
|
1430
1483
|
const { rules } = defaultLinterConfig;
|
|
1431
1484
|
const biomeConfig = {
|
|
1432
|
-
$schema:
|
|
1433
|
-
files: {
|
|
1434
|
-
ignore: defaultLinterConfig.ignorePatterns
|
|
1435
|
-
}
|
|
1485
|
+
$schema: `https://biomejs.dev/schemas/${version}/schema.json`
|
|
1436
1486
|
};
|
|
1437
1487
|
if (options.linter) {
|
|
1438
1488
|
biomeConfig.linter = {
|
|
@@ -1465,27 +1515,52 @@ function generateBiome(generator, options) {
|
|
|
1465
1515
|
arrowParentheses: "always"
|
|
1466
1516
|
}
|
|
1467
1517
|
};
|
|
1518
|
+
biomeConfig.json = {
|
|
1519
|
+
formatter: {
|
|
1520
|
+
indentWidth: 2
|
|
1521
|
+
}
|
|
1522
|
+
};
|
|
1468
1523
|
} else {
|
|
1469
1524
|
biomeConfig.formatter = {
|
|
1470
1525
|
enabled: false
|
|
1471
1526
|
};
|
|
1472
1527
|
}
|
|
1473
|
-
generator.
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1528
|
+
const isStealth = generator.isStealthConfig();
|
|
1529
|
+
if (isStealth) {
|
|
1530
|
+
generator.addFile(".config/biome.json", {
|
|
1531
|
+
type: "text",
|
|
1532
|
+
content: JSON.stringify(biomeConfig, null, 2)
|
|
1533
|
+
});
|
|
1534
|
+
if (options.linter) {
|
|
1535
|
+
generator.addScript("lint", "biome lint --config-path .config .");
|
|
1536
|
+
}
|
|
1537
|
+
if (options.formatter) {
|
|
1538
|
+
generator.addScript(
|
|
1539
|
+
"format",
|
|
1540
|
+
"biome format --config-path .config --write ."
|
|
1541
|
+
);
|
|
1542
|
+
}
|
|
1543
|
+
generator.addVscodeSetting("biome.linter.configPath", ".config/biome.json");
|
|
1544
|
+
} else {
|
|
1545
|
+
generator.addFile("biome.json", {
|
|
1546
|
+
type: "text",
|
|
1547
|
+
content: JSON.stringify(biomeConfig, null, 2)
|
|
1548
|
+
});
|
|
1549
|
+
if (options.linter) {
|
|
1550
|
+
generator.addScript("lint", "biome lint .");
|
|
1551
|
+
}
|
|
1552
|
+
if (options.formatter) {
|
|
1553
|
+
generator.addScript("format", "biome format --write .");
|
|
1554
|
+
}
|
|
1482
1555
|
}
|
|
1483
1556
|
const roles = [];
|
|
1484
1557
|
if (options.linter) roles.push("linter");
|
|
1485
1558
|
if (options.formatter) roles.push("formatter");
|
|
1486
1559
|
generator.inject(
|
|
1487
1560
|
"readme-tools",
|
|
1488
|
-
`[Biome](https://biomejs.dev/) - Fast ${roles.join(
|
|
1561
|
+
`[Biome](https://biomejs.dev/) - Fast ${roles.join(
|
|
1562
|
+
" and "
|
|
1563
|
+
)} for JavaScript and TypeScript`
|
|
1489
1564
|
);
|
|
1490
1565
|
generator.inject("vscode-extension-suggestion", "biomejs.biome");
|
|
1491
1566
|
generator.addVscodeSetting("biome.enabled", true);
|
|
@@ -1570,11 +1645,23 @@ function generateEslint(generator, options) {
|
|
|
1570
1645
|
},`,
|
|
1571
1646
|
"]"
|
|
1572
1647
|
].filter(Boolean).join("\n");
|
|
1573
|
-
generator.
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1648
|
+
const isStealth = generator.isStealthConfig();
|
|
1649
|
+
if (isStealth) {
|
|
1650
|
+
generator.addFile(".config/eslint.config.js", {
|
|
1651
|
+
type: "text",
|
|
1652
|
+
content: configContent
|
|
1653
|
+
});
|
|
1654
|
+
generator.addScript("lint", "eslint --config .config/eslint.config.js .");
|
|
1655
|
+
generator.addVscodeSetting("eslint.options", {
|
|
1656
|
+
overrideConfigFile: ".config/eslint.config.js"
|
|
1657
|
+
});
|
|
1658
|
+
} else {
|
|
1659
|
+
generator.addFile("eslint.config.js", {
|
|
1660
|
+
type: "text",
|
|
1661
|
+
content: configContent
|
|
1662
|
+
});
|
|
1663
|
+
generator.addScript("lint", "eslint .");
|
|
1664
|
+
}
|
|
1578
1665
|
generator.inject(
|
|
1579
1666
|
"readme-tools",
|
|
1580
1667
|
"[ESLint](https://eslint.org/) - Linter for JavaScript and TypeScript"
|
|
@@ -1744,22 +1831,21 @@ function generateOxfmt(generator, options) {
|
|
|
1744
1831
|
} else {
|
|
1745
1832
|
const version = generator.versions.oxfmt ?? "0.1.0";
|
|
1746
1833
|
generator.addDevDependency("oxfmt", `^${version}`);
|
|
1747
|
-
const
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
generator.addVscodeSetting("oxc.fmt.configPath", ".config/oxfmt.json");
|
|
1834
|
+
const isStealth = generator.isStealthConfig();
|
|
1835
|
+
if (isStealth) {
|
|
1836
|
+
generator.addFile(".config/oxfmt.json", {
|
|
1837
|
+
type: "text",
|
|
1838
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1839
|
+
});
|
|
1840
|
+
generator.addScript("format", "oxfmt -c .config/oxfmt.json --write .");
|
|
1841
|
+
generator.addVscodeSetting("oxc.fmt.configPath", ".config/oxfmt.json");
|
|
1842
|
+
} else {
|
|
1843
|
+
generator.addFile("oxfmt.json", {
|
|
1844
|
+
type: "text",
|
|
1845
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1846
|
+
});
|
|
1847
|
+
generator.addScript("format", "oxfmt -c oxfmt.json --write .");
|
|
1848
|
+
}
|
|
1763
1849
|
}
|
|
1764
1850
|
generator.inject(
|
|
1765
1851
|
"readme-tools",
|
|
@@ -1773,6 +1859,12 @@ function generateOxfmt(generator, options) {
|
|
|
1773
1859
|
generator.addVscodeSetting("[jsonc]", {
|
|
1774
1860
|
"editor.defaultFormatter": "vscode.json-language-features"
|
|
1775
1861
|
});
|
|
1862
|
+
generator.addVscodeSetting("[markdown]", {
|
|
1863
|
+
"editor.defaultFormatter": "vscode.markdown-language-features"
|
|
1864
|
+
});
|
|
1865
|
+
generator.addVscodeSetting("[yaml]", {
|
|
1866
|
+
"editor.defaultFormatter": "redhat.vscode-yaml"
|
|
1867
|
+
});
|
|
1776
1868
|
}
|
|
1777
1869
|
|
|
1778
1870
|
function toOxlintLevel(level) {
|
|
@@ -1791,13 +1883,14 @@ function generateOxlint(generator, options) {
|
|
|
1791
1883
|
} else {
|
|
1792
1884
|
const version = generator.versions.oxlint ?? "0.16.0";
|
|
1793
1885
|
generator.addDevDependency("oxlint", `^${version}`);
|
|
1886
|
+
const isStealth = generator.isStealthConfig();
|
|
1794
1887
|
const { rules } = defaultLinterConfig;
|
|
1795
1888
|
const plugins = ["unicorn", "typescript", "oxc"];
|
|
1796
1889
|
if (isReact) {
|
|
1797
1890
|
plugins.push("react");
|
|
1798
1891
|
}
|
|
1799
1892
|
const oxlintConfig = {
|
|
1800
|
-
$schema: "../node_modules/oxlint/configuration_schema.json",
|
|
1893
|
+
$schema: isStealth ? "../node_modules/oxlint/configuration_schema.json" : "./node_modules/oxlint/configuration_schema.json",
|
|
1801
1894
|
plugins,
|
|
1802
1895
|
rules: {
|
|
1803
1896
|
"no-unused-vars": [
|
|
@@ -1816,12 +1909,20 @@ function generateOxlint(generator, options) {
|
|
|
1816
1909
|
},
|
|
1817
1910
|
ignorePatterns: defaultLinterConfig.ignorePatterns
|
|
1818
1911
|
};
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1912
|
+
if (isStealth) {
|
|
1913
|
+
generator.addFile(".config/oxlint.json", {
|
|
1914
|
+
type: "text",
|
|
1915
|
+
content: JSON.stringify(oxlintConfig, null, 2)
|
|
1916
|
+
});
|
|
1917
|
+
generator.addScript("lint", "oxlint -c .config/oxlint.json");
|
|
1918
|
+
generator.addVscodeSetting("oxc.configPath", ".config/oxlint.json");
|
|
1919
|
+
} else {
|
|
1920
|
+
generator.addFile("oxlint.json", {
|
|
1921
|
+
type: "text",
|
|
1922
|
+
content: JSON.stringify(oxlintConfig, null, 2)
|
|
1923
|
+
});
|
|
1924
|
+
generator.addScript("lint", "oxlint");
|
|
1925
|
+
}
|
|
1825
1926
|
}
|
|
1826
1927
|
generator.inject(
|
|
1827
1928
|
"readme-tools",
|
|
@@ -1852,25 +1953,33 @@ function generatePostprocessing(generator, options) {
|
|
|
1852
1953
|
function generatePrettier(generator, options) {
|
|
1853
1954
|
const version = generator.versions.prettier ?? "3.4.2";
|
|
1854
1955
|
generator.addDevDependency("prettier", `^${version}`);
|
|
1855
|
-
const
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
|
|
1870
|
-
|
|
1871
|
-
|
|
1956
|
+
const isStealth = generator.isStealthConfig();
|
|
1957
|
+
if (isStealth) {
|
|
1958
|
+
generator.addFile(".config/prettier.json", {
|
|
1959
|
+
type: "text",
|
|
1960
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1961
|
+
});
|
|
1962
|
+
generator.addScript(
|
|
1963
|
+
"format",
|
|
1964
|
+
"prettier --config .config/prettier.json --write ."
|
|
1965
|
+
);
|
|
1966
|
+
generator.addVscodeSetting("prettier.configPath", ".config/prettier.json");
|
|
1967
|
+
} else {
|
|
1968
|
+
generator.addFile(".prettierrc", {
|
|
1969
|
+
type: "text",
|
|
1970
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1971
|
+
});
|
|
1972
|
+
generator.addScript("format", "prettier --write .");
|
|
1973
|
+
}
|
|
1974
|
+
generator.inject(
|
|
1975
|
+
"readme-tools",
|
|
1976
|
+
"[Prettier](https://prettier.io/) - Opinionated code formatter"
|
|
1977
|
+
);
|
|
1872
1978
|
generator.inject("vscode-extension-suggestion", "esbenp.prettier-vscode");
|
|
1873
|
-
generator.addVscodeSetting(
|
|
1979
|
+
generator.addVscodeSetting(
|
|
1980
|
+
"editor.defaultFormatter",
|
|
1981
|
+
"esbenp.prettier-vscode"
|
|
1982
|
+
);
|
|
1874
1983
|
}
|
|
1875
1984
|
|
|
1876
1985
|
function generateRapier(generator, options) {
|
|
@@ -2120,18 +2229,19 @@ function generateUnbuild(generator) {
|
|
|
2120
2229
|
}
|
|
2121
2230
|
buildConfigLines.push(` },`);
|
|
2122
2231
|
buildConfigLines.push(`})`);
|
|
2123
|
-
|
|
2124
|
-
|
|
2232
|
+
const isStealth = generator.isStealthConfig() && !isMonorepo;
|
|
2233
|
+
if (isStealth) {
|
|
2234
|
+
generator.addFile(`.config/build.config.${ext}`, {
|
|
2125
2235
|
type: "text",
|
|
2126
2236
|
content: buildConfigLines.join("\n")
|
|
2127
2237
|
});
|
|
2128
|
-
generator.addScript("build",
|
|
2238
|
+
generator.addScript("build", `unbuild --config .config/build.config.${ext}`);
|
|
2129
2239
|
} else {
|
|
2130
|
-
generator.addFile(
|
|
2240
|
+
generator.addFile(`build.config.${ext}`, {
|
|
2131
2241
|
type: "text",
|
|
2132
2242
|
content: buildConfigLines.join("\n")
|
|
2133
2243
|
});
|
|
2134
|
-
generator.addScript("build",
|
|
2244
|
+
generator.addScript("build", "unbuild");
|
|
2135
2245
|
}
|
|
2136
2246
|
generator.inject(
|
|
2137
2247
|
"readme-libraries",
|
|
@@ -2439,6 +2549,82 @@ function parseWorkspaceYamlContent(content) {
|
|
|
2439
2549
|
}
|
|
2440
2550
|
return directories;
|
|
2441
2551
|
}
|
|
2552
|
+
async function pathExists(path) {
|
|
2553
|
+
try {
|
|
2554
|
+
await promises.access(path, fs.constants.F_OK);
|
|
2555
|
+
return true;
|
|
2556
|
+
} catch {
|
|
2557
|
+
return false;
|
|
2558
|
+
}
|
|
2559
|
+
}
|
|
2560
|
+
function detectLinterFromScript(script) {
|
|
2561
|
+
if (!script) return void 0;
|
|
2562
|
+
if (script.includes("oxlint")) return "oxlint";
|
|
2563
|
+
if (script.includes("eslint")) return "eslint";
|
|
2564
|
+
if (script.includes("biome check") || script.includes("biome lint")) return "biome";
|
|
2565
|
+
return void 0;
|
|
2566
|
+
}
|
|
2567
|
+
function detectFormatterFromScript(script) {
|
|
2568
|
+
if (!script) return void 0;
|
|
2569
|
+
if (script.includes("prettier")) return "prettier";
|
|
2570
|
+
if (script.includes("oxfmt")) return "oxfmt";
|
|
2571
|
+
if (script.includes("biome format")) return "biome";
|
|
2572
|
+
return void 0;
|
|
2573
|
+
}
|
|
2574
|
+
async function detectLinterFromConfig(root) {
|
|
2575
|
+
if (await pathExists(path.join(root, ".config/oxlint"))) return "oxlint";
|
|
2576
|
+
if (await pathExists(path.join(root, ".config/eslint"))) return "eslint";
|
|
2577
|
+
if (await pathExists(path.join(root, "biome.json"))) {
|
|
2578
|
+
try {
|
|
2579
|
+
const content = await promises.readFile(path.join(root, "biome.json"), "utf-8");
|
|
2580
|
+
const config = JSON.parse(content);
|
|
2581
|
+
if (config.linter?.enabled !== false) return "biome";
|
|
2582
|
+
} catch {
|
|
2583
|
+
return "biome";
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
return void 0;
|
|
2587
|
+
}
|
|
2588
|
+
async function detectFormatterFromConfig(root) {
|
|
2589
|
+
if (await pathExists(path.join(root, ".config/prettier"))) return "prettier";
|
|
2590
|
+
if (await pathExists(path.join(root, ".config/oxfmt"))) return "oxfmt";
|
|
2591
|
+
if (await pathExists(path.join(root, "biome.json"))) {
|
|
2592
|
+
try {
|
|
2593
|
+
const content = await promises.readFile(path.join(root, "biome.json"), "utf-8");
|
|
2594
|
+
const config = JSON.parse(content);
|
|
2595
|
+
if (config.formatter?.enabled !== false) return "biome";
|
|
2596
|
+
} catch {
|
|
2597
|
+
return "biome";
|
|
2598
|
+
}
|
|
2599
|
+
}
|
|
2600
|
+
return void 0;
|
|
2601
|
+
}
|
|
2602
|
+
function detectLinterFromDeps(devDeps) {
|
|
2603
|
+
if (!devDeps) return void 0;
|
|
2604
|
+
if (devDeps["@biomejs/biome"]) return "biome";
|
|
2605
|
+
if (devDeps.eslint) return "eslint";
|
|
2606
|
+
if (devDeps.oxlint) return "oxlint";
|
|
2607
|
+
return void 0;
|
|
2608
|
+
}
|
|
2609
|
+
function detectFormatterFromDeps(devDeps) {
|
|
2610
|
+
if (!devDeps) return void 0;
|
|
2611
|
+
if (devDeps["@biomejs/biome"]) return "biome";
|
|
2612
|
+
if (devDeps.prettier) return "prettier";
|
|
2613
|
+
if (devDeps.oxfmt) return "oxfmt";
|
|
2614
|
+
return void 0;
|
|
2615
|
+
}
|
|
2616
|
+
async function detectTooling(root) {
|
|
2617
|
+
try {
|
|
2618
|
+
const pkgPath = path.join(root, "package.json");
|
|
2619
|
+
const content = await promises.readFile(pkgPath, "utf-8");
|
|
2620
|
+
const pkg = JSON.parse(content);
|
|
2621
|
+
const linter = detectLinterFromScript(pkg.scripts?.lint) ?? await detectLinterFromConfig(root) ?? detectLinterFromDeps(pkg.devDependencies);
|
|
2622
|
+
const formatter = detectFormatterFromScript(pkg.scripts?.format) ?? await detectFormatterFromConfig(root) ?? detectFormatterFromDeps(pkg.devDependencies);
|
|
2623
|
+
return { linter, formatter };
|
|
2624
|
+
} catch {
|
|
2625
|
+
return { linter: void 0, formatter: void 0 };
|
|
2626
|
+
}
|
|
2627
|
+
}
|
|
2442
2628
|
function generateRandomName() {
|
|
2443
2629
|
const adjectives = [
|
|
2444
2630
|
"red",
|
|
@@ -2560,7 +2746,8 @@ function generate(options) {
|
|
|
2560
2746
|
if (language === "typescript") {
|
|
2561
2747
|
const tsResult = generateTypescriptConfig({
|
|
2562
2748
|
baseTemplate,
|
|
2563
|
-
useConfigPackage: clonedOptions.workspaceRoot != null
|
|
2749
|
+
useConfigPackage: clonedOptions.workspaceRoot != null,
|
|
2750
|
+
configStrategy: clonedOptions.configStrategy
|
|
2564
2751
|
});
|
|
2565
2752
|
Object.assign(files, tsResult.files);
|
|
2566
2753
|
Object.assign(devDependencies, tsResult.devDependencies);
|
|
@@ -2572,7 +2759,9 @@ function generate(options) {
|
|
|
2572
2759
|
build: "vite build"
|
|
2573
2760
|
};
|
|
2574
2761
|
if (!isLibrary && (isReact || isR3f)) {
|
|
2575
|
-
codeSnippets["vite-config-import"] = [
|
|
2762
|
+
codeSnippets["vite-config-import"] = [
|
|
2763
|
+
"import react from '@vitejs/plugin-react'"
|
|
2764
|
+
];
|
|
2576
2765
|
}
|
|
2577
2766
|
if (!isLibrary && isR3f) {
|
|
2578
2767
|
codeSnippets["import"] = [`import { Canvas } from "@react-three/fiber"`];
|
|
@@ -2592,6 +2781,9 @@ function generate(options) {
|
|
|
2592
2781
|
const generator = {
|
|
2593
2782
|
options: clonedOptions,
|
|
2594
2783
|
versions,
|
|
2784
|
+
isStealthConfig() {
|
|
2785
|
+
return (clonedOptions.configStrategy ?? "stealth") === "stealth";
|
|
2786
|
+
},
|
|
2595
2787
|
addDependency(name2, semver) {
|
|
2596
2788
|
dependencies[name2];
|
|
2597
2789
|
dependencies[name2] = semver;
|
|
@@ -2648,7 +2840,10 @@ function generate(options) {
|
|
|
2648
2840
|
generateTsdown(generator);
|
|
2649
2841
|
}
|
|
2650
2842
|
const packageManager2 = clonedOptions.packageManager ?? "pnpm";
|
|
2651
|
-
generator.addScript(
|
|
2843
|
+
generator.addScript(
|
|
2844
|
+
"release",
|
|
2845
|
+
`${packageManager2} run build && ${packageManager2} publish`
|
|
2846
|
+
);
|
|
2652
2847
|
}
|
|
2653
2848
|
const testing = clonedOptions.testing ?? (isLibrary ? "vitest" : "none");
|
|
2654
2849
|
if (testing === "vitest") {
|
|
@@ -2741,9 +2936,24 @@ function generate(options) {
|
|
|
2741
2936
|
};
|
|
2742
2937
|
files[".gitattributes"] = { type: "text", content: GitAttributes };
|
|
2743
2938
|
}
|
|
2939
|
+
if (!isMonorepoPackage && clonedOptions.aiPlatforms?.length) {
|
|
2940
|
+
generateAiFiles(files, {
|
|
2941
|
+
name,
|
|
2942
|
+
packageManager: clonedOptions.packageManager ?? "pnpm",
|
|
2943
|
+
linter: clonedOptions.linter ?? "oxlint",
|
|
2944
|
+
formatter: clonedOptions.formatter ?? "prettier",
|
|
2945
|
+
isMonorepo: false,
|
|
2946
|
+
configStrategy: clonedOptions.configStrategy,
|
|
2947
|
+
platforms: clonedOptions.aiPlatforms
|
|
2948
|
+
});
|
|
2949
|
+
}
|
|
2744
2950
|
return files;
|
|
2745
2951
|
}
|
|
2746
2952
|
|
|
2953
|
+
exports.AI_PLATFORM_HINTS = AI_PLATFORM_HINTS;
|
|
2954
|
+
exports.AI_PLATFORM_LABELS = AI_PLATFORM_LABELS;
|
|
2955
|
+
exports.ALL_AI_PLATFORMS = ALL_AI_PLATFORMS;
|
|
2956
|
+
exports.detectTooling = detectTooling;
|
|
2747
2957
|
exports.generate = generate;
|
|
2748
2958
|
exports.generateAiFiles = generateAiFiles;
|
|
2749
2959
|
exports.generateEslintConfigPackage = generateEslintConfigPackage;
|