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.mjs
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
import color from 'chalk';
|
|
2
|
+
import { readFile, access } from 'fs/promises';
|
|
3
|
+
import { constants } from 'fs';
|
|
4
|
+
import { join } from 'path';
|
|
2
5
|
|
|
3
6
|
const HtmlContent = `<!DOCTYPE html>
|
|
4
7
|
<html lang="en">
|
|
@@ -90,6 +93,34 @@ const defaultFormatterConfig = {
|
|
|
90
93
|
bracketSpacing: true,
|
|
91
94
|
arrowParens: "always"
|
|
92
95
|
};
|
|
96
|
+
const defaultPrettierConfig = {
|
|
97
|
+
$schema: "https://json.schemastore.org/prettierrc",
|
|
98
|
+
...defaultFormatterConfig,
|
|
99
|
+
overrides: [
|
|
100
|
+
{
|
|
101
|
+
files: ["*.json", "**/*.json"],
|
|
102
|
+
options: { tabWidth: 2 }
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
files: ["*.md", "**/*.md"],
|
|
106
|
+
options: { tabWidth: 2, semi: false }
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
files: ["*.yml", "*.yaml", "**/*.yml", "**/*.yaml"],
|
|
110
|
+
options: { tabWidth: 2, semi: false }
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
};
|
|
114
|
+
const defaultOxfmtConfig = {
|
|
115
|
+
printWidth: defaultFormatterConfig.printWidth,
|
|
116
|
+
tabWidth: defaultFormatterConfig.tabWidth,
|
|
117
|
+
useTabs: defaultFormatterConfig.useTabs,
|
|
118
|
+
semi: defaultFormatterConfig.semi,
|
|
119
|
+
singleQuote: defaultFormatterConfig.singleQuote,
|
|
120
|
+
trailingComma: defaultFormatterConfig.trailingComma,
|
|
121
|
+
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
122
|
+
arrowParens: defaultFormatterConfig.arrowParens
|
|
123
|
+
};
|
|
93
124
|
const defaultLinterConfig = {
|
|
94
125
|
ignorePatterns: ["dist"],
|
|
95
126
|
rules: {
|
|
@@ -106,9 +137,88 @@ const defaultLinterConfig = {
|
|
|
106
137
|
}
|
|
107
138
|
};
|
|
108
139
|
|
|
140
|
+
const ALL_AI_PLATFORMS = ["agents", "claude"];
|
|
141
|
+
const AI_PLATFORM_LABELS = {
|
|
142
|
+
agents: "AGENTS.md",
|
|
143
|
+
claude: "CLAUDE.md"
|
|
144
|
+
};
|
|
145
|
+
const AI_PLATFORM_HINTS = {
|
|
146
|
+
agents: "OpenAI, Cursor, Windsurf, etc.",
|
|
147
|
+
claude: "Claude Code"
|
|
148
|
+
};
|
|
149
|
+
function generateAiFiles(files, params) {
|
|
150
|
+
const { platforms, isMonorepo, configStrategy, ...rest } = params;
|
|
151
|
+
if (platforms.length === 0) return;
|
|
152
|
+
files[".ai/workspace.md"] = {
|
|
153
|
+
type: "text",
|
|
154
|
+
content: generateWorkspace({
|
|
155
|
+
...rest,
|
|
156
|
+
isMonorepo: !!isMonorepo,
|
|
157
|
+
configStrategy: configStrategy ?? "stealth"
|
|
158
|
+
})
|
|
159
|
+
};
|
|
160
|
+
const pointer = "See `.ai/` for project rules.\n";
|
|
161
|
+
for (const platform of platforms) {
|
|
162
|
+
const path = platform === "agents" ? "AGENTS.md" : "CLAUDE.md";
|
|
163
|
+
files[path] = { type: "text", content: pointer };
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function generateWorkspace(ctx) {
|
|
167
|
+
const { name, packageManager, linter, formatter, isMonorepo, configStrategy } = ctx;
|
|
168
|
+
const sections = [
|
|
169
|
+
`# ${name}`,
|
|
170
|
+
"",
|
|
171
|
+
`- **Type:** ${isMonorepo ? "pnpm monorepo" : "standalone project"}`,
|
|
172
|
+
`- **Package Manager:** ${packageManager}`,
|
|
173
|
+
`- **Linter:** ${linter}`,
|
|
174
|
+
`- **Formatter:** ${formatter}`,
|
|
175
|
+
"",
|
|
176
|
+
"## Commands",
|
|
177
|
+
"",
|
|
178
|
+
`- \`${packageManager} test\` \u2014 run tests`,
|
|
179
|
+
`- \`${packageManager} build\` \u2014 build`,
|
|
180
|
+
`- \`${packageManager} lint\` and \`${packageManager} format\` \u2014 run before committing`
|
|
181
|
+
];
|
|
182
|
+
if (isMonorepo) {
|
|
183
|
+
sections.push(
|
|
184
|
+
"",
|
|
185
|
+
"## Structure",
|
|
186
|
+
"",
|
|
187
|
+
"- `apps/` \u2014 applications",
|
|
188
|
+
"- `packages/` \u2014 shared libraries",
|
|
189
|
+
"- `.config/` \u2014 shared config packages",
|
|
190
|
+
"",
|
|
191
|
+
"## Monorepo",
|
|
192
|
+
"",
|
|
193
|
+
"- Use `workspace:*` for internal dependencies",
|
|
194
|
+
`- New packages: \`${packageManager} create krispya <name> --workspace\``
|
|
195
|
+
);
|
|
196
|
+
} else if (configStrategy === "root") {
|
|
197
|
+
sections.push(
|
|
198
|
+
"",
|
|
199
|
+
"## Structure",
|
|
200
|
+
"",
|
|
201
|
+
"- `src/` \u2014 source code",
|
|
202
|
+
"- `dist/` \u2014 generated, don't edit",
|
|
203
|
+
"- Config files (`tsconfig.json`, etc.) are at project root"
|
|
204
|
+
);
|
|
205
|
+
} else {
|
|
206
|
+
sections.push(
|
|
207
|
+
"",
|
|
208
|
+
"## Structure",
|
|
209
|
+
"",
|
|
210
|
+
"- `src/` \u2014 source code",
|
|
211
|
+
"- `.config/` \u2014 configs, don't move",
|
|
212
|
+
"- `dist/` \u2014 generated, don't edit"
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
sections.push("");
|
|
216
|
+
return sections.join("\n");
|
|
217
|
+
}
|
|
218
|
+
|
|
109
219
|
function generateTypescriptConfig(baseTemplateOrParams) {
|
|
110
220
|
const params = typeof baseTemplateOrParams === "string" ? { baseTemplate: baseTemplateOrParams } : baseTemplateOrParams;
|
|
111
|
-
const { baseTemplate, useConfigPackage } = params;
|
|
221
|
+
const { baseTemplate, useConfigPackage, configStrategy = "stealth" } = params;
|
|
112
222
|
const isReact = baseTemplate === "react";
|
|
113
223
|
const isR3f = baseTemplate === "r3f";
|
|
114
224
|
const files = {};
|
|
@@ -137,58 +247,113 @@ function generateTypescriptConfig(baseTemplateOrParams) {
|
|
|
137
247
|
};
|
|
138
248
|
return { files, devDependencies };
|
|
139
249
|
}
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
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
|
-
|
|
250
|
+
if (configStrategy === "stealth") {
|
|
251
|
+
const tsConfig = {
|
|
252
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
253
|
+
files: [],
|
|
254
|
+
references: [{ path: "./.config/tsconfig.app.json" }, { path: "./.config/tsconfig.node.json" }]
|
|
255
|
+
};
|
|
256
|
+
files["tsconfig.json"] = {
|
|
257
|
+
type: "text",
|
|
258
|
+
content: JSON.stringify(tsConfig, null, 2)
|
|
259
|
+
};
|
|
260
|
+
const tsConfigApp = {
|
|
261
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
262
|
+
compilerOptions: {
|
|
263
|
+
target: "ESNext",
|
|
264
|
+
module: "ESNext",
|
|
265
|
+
moduleResolution: "bundler",
|
|
266
|
+
lib: ["DOM", "DOM.Iterable", "ESNext"],
|
|
267
|
+
esModuleInterop: true,
|
|
268
|
+
allowSyntheticDefaultImports: true,
|
|
269
|
+
strict: true,
|
|
270
|
+
skipLibCheck: true,
|
|
271
|
+
composite: true,
|
|
272
|
+
rewriteRelativeImportExtensions: true,
|
|
273
|
+
erasableSyntaxOnly: true,
|
|
274
|
+
...isReact || isR3f ? { jsx: "react-jsx" } : {}
|
|
275
|
+
},
|
|
276
|
+
include: ["../src", "../tests"]
|
|
277
|
+
};
|
|
278
|
+
files[".config/tsconfig.app.json"] = {
|
|
279
|
+
type: "text",
|
|
280
|
+
content: JSON.stringify(tsConfigApp, null, 2)
|
|
281
|
+
};
|
|
282
|
+
const tsConfigNode = {
|
|
283
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
284
|
+
compilerOptions: {
|
|
285
|
+
target: "ESNext",
|
|
286
|
+
module: "ESNext",
|
|
287
|
+
moduleResolution: "bundler",
|
|
288
|
+
lib: ["ESNext"],
|
|
289
|
+
esModuleInterop: true,
|
|
290
|
+
allowSyntheticDefaultImports: true,
|
|
291
|
+
strict: true,
|
|
292
|
+
skipLibCheck: true,
|
|
293
|
+
composite: true,
|
|
294
|
+
rewriteRelativeImportExtensions: true,
|
|
295
|
+
erasableSyntaxOnly: true
|
|
296
|
+
},
|
|
297
|
+
include: ["../*.config.ts", "./*.ts"]
|
|
298
|
+
};
|
|
299
|
+
files[".config/tsconfig.node.json"] = {
|
|
300
|
+
type: "text",
|
|
301
|
+
content: JSON.stringify(tsConfigNode, null, 2)
|
|
302
|
+
};
|
|
303
|
+
} else {
|
|
304
|
+
const tsConfig = {
|
|
305
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
306
|
+
files: [],
|
|
307
|
+
references: [{ path: "./tsconfig.app.json" }, { path: "./tsconfig.node.json" }]
|
|
308
|
+
};
|
|
309
|
+
files["tsconfig.json"] = {
|
|
310
|
+
type: "text",
|
|
311
|
+
content: JSON.stringify(tsConfig, null, 2)
|
|
312
|
+
};
|
|
313
|
+
const tsConfigApp = {
|
|
314
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
315
|
+
compilerOptions: {
|
|
316
|
+
target: "ESNext",
|
|
317
|
+
module: "ESNext",
|
|
318
|
+
moduleResolution: "bundler",
|
|
319
|
+
lib: ["DOM", "DOM.Iterable", "ESNext"],
|
|
320
|
+
esModuleInterop: true,
|
|
321
|
+
allowSyntheticDefaultImports: true,
|
|
322
|
+
strict: true,
|
|
323
|
+
skipLibCheck: true,
|
|
324
|
+
composite: true,
|
|
325
|
+
rewriteRelativeImportExtensions: true,
|
|
326
|
+
erasableSyntaxOnly: true,
|
|
327
|
+
...isReact || isR3f ? { jsx: "react-jsx" } : {}
|
|
328
|
+
},
|
|
329
|
+
include: ["src", "tests"]
|
|
330
|
+
};
|
|
331
|
+
files["tsconfig.app.json"] = {
|
|
332
|
+
type: "text",
|
|
333
|
+
content: JSON.stringify(tsConfigApp, null, 2)
|
|
334
|
+
};
|
|
335
|
+
const tsConfigNode = {
|
|
336
|
+
$schema: "https://json.schemastore.org/tsconfig",
|
|
337
|
+
compilerOptions: {
|
|
338
|
+
target: "ESNext",
|
|
339
|
+
module: "ESNext",
|
|
340
|
+
moduleResolution: "bundler",
|
|
341
|
+
lib: ["ESNext"],
|
|
342
|
+
esModuleInterop: true,
|
|
343
|
+
allowSyntheticDefaultImports: true,
|
|
344
|
+
strict: true,
|
|
345
|
+
skipLibCheck: true,
|
|
346
|
+
composite: true,
|
|
347
|
+
rewriteRelativeImportExtensions: true,
|
|
348
|
+
erasableSyntaxOnly: true
|
|
349
|
+
},
|
|
350
|
+
include: ["*.config.ts"]
|
|
351
|
+
};
|
|
352
|
+
files["tsconfig.node.json"] = {
|
|
353
|
+
type: "text",
|
|
354
|
+
content: JSON.stringify(tsConfigNode, null, 2)
|
|
355
|
+
};
|
|
356
|
+
}
|
|
192
357
|
return { files, devDependencies };
|
|
193
358
|
}
|
|
194
359
|
|
|
@@ -598,9 +763,12 @@ function generateVscodeFiles$1(params) {
|
|
|
598
763
|
};
|
|
599
764
|
}
|
|
600
765
|
if (Object.keys(vscodeSettings).length > 0) {
|
|
766
|
+
const sortedSettings = Object.fromEntries(
|
|
767
|
+
Object.entries(vscodeSettings).sort(([a], [b]) => a.localeCompare(b))
|
|
768
|
+
);
|
|
601
769
|
files[".vscode/settings.json"] = {
|
|
602
770
|
type: "text",
|
|
603
|
-
content: JSON.stringify(
|
|
771
|
+
content: JSON.stringify(sortedSettings, null, " ")
|
|
604
772
|
};
|
|
605
773
|
}
|
|
606
774
|
return files;
|
|
@@ -653,128 +821,6 @@ function generateViteConfig(params) {
|
|
|
653
821
|
return { type: "text", content: viteConfigContent };
|
|
654
822
|
}
|
|
655
823
|
|
|
656
|
-
function generateAiFiles(files, params) {
|
|
657
|
-
const { name, packageManager, linter, formatter, aiFiles } = params;
|
|
658
|
-
const content = getAiInstructionsContent({
|
|
659
|
-
name,
|
|
660
|
-
packageManager,
|
|
661
|
-
linter,
|
|
662
|
-
formatter
|
|
663
|
-
});
|
|
664
|
-
for (const fileChoice of aiFiles) {
|
|
665
|
-
switch (fileChoice) {
|
|
666
|
-
case "cursor-rules":
|
|
667
|
-
files[".cursor/rules"] = { type: "text", content };
|
|
668
|
-
break;
|
|
669
|
-
case "agents-md":
|
|
670
|
-
files["AGENTS.md"] = { type: "text", content };
|
|
671
|
-
break;
|
|
672
|
-
case "claude-md":
|
|
673
|
-
files["CLAUDE.md"] = { type: "text", content };
|
|
674
|
-
break;
|
|
675
|
-
case "copilot-md":
|
|
676
|
-
files[".github/copilot-instructions.md"] = { type: "text", content };
|
|
677
|
-
break;
|
|
678
|
-
}
|
|
679
|
-
}
|
|
680
|
-
}
|
|
681
|
-
function getConfigPackagesDescription(linter, formatter) {
|
|
682
|
-
const packages = ["`@config/typescript`"];
|
|
683
|
-
if (linter !== "biome") {
|
|
684
|
-
packages.push(`\`@config/${linter}\``);
|
|
685
|
-
}
|
|
686
|
-
if (formatter !== "biome" && formatter !== linter) {
|
|
687
|
-
packages.push(`\`@config/${formatter}\``);
|
|
688
|
-
}
|
|
689
|
-
let description = `- \`.config/\`: shared config packages (${packages.join(", ")})`;
|
|
690
|
-
if (linter === "biome" || formatter === "biome") {
|
|
691
|
-
description += "\n- `biome.json`: Biome configuration (root level)";
|
|
692
|
-
}
|
|
693
|
-
return description;
|
|
694
|
-
}
|
|
695
|
-
function getAiInstructionsContent(params) {
|
|
696
|
-
const { name, packageManager, linter, formatter } = params;
|
|
697
|
-
const configDescription = getConfigPackagesDescription(linter, formatter);
|
|
698
|
-
return `# ${name}
|
|
699
|
-
|
|
700
|
-
This is a pnpm monorepo workspace generated with \`create-krispya\`.
|
|
701
|
-
|
|
702
|
-
## Most important rule (package creation)
|
|
703
|
-
|
|
704
|
-
If you need a new app/package for any reason, **ALWAYS** create it with \`create-krispya\` (do not hand-create folders/package.json).
|
|
705
|
-
|
|
706
|
-
### Non-interactive (preferred for agents)
|
|
707
|
-
|
|
708
|
-
\`\`\`bash
|
|
709
|
-
${packageManager} create krispya <name> --workspace [options]
|
|
710
|
-
\`\`\`
|
|
711
|
-
|
|
712
|
-
- The package directory will be \`apps/<name>\` (apps) or \`packages/<name>\` (libraries), unless \`--dir\` is provided.
|
|
713
|
-
- Package names default to \`@${name}/<name>\` but you can pass any name (scoped or unscoped).
|
|
714
|
-
|
|
715
|
-
### Workspace maintenance (non-interactive)
|
|
716
|
-
|
|
717
|
-
\`\`\`bash
|
|
718
|
-
${packageManager} create krispya --check # validate workspace
|
|
719
|
-
${packageManager} create krispya --fix --linter ${linter} --formatter ${formatter} # fix missing .config packages
|
|
720
|
-
\`\`\`
|
|
721
|
-
|
|
722
|
-
For non-interactive \`--fix\`, you MUST provide both \`--linter\` and \`--formatter\` flags.
|
|
723
|
-
|
|
724
|
-
## Package creation options (CLI truth)
|
|
725
|
-
|
|
726
|
-
| Option | Values | Notes |
|
|
727
|
-
|--------|--------|-------|
|
|
728
|
-
| \`--type\` | app, library | default: app |
|
|
729
|
-
| \`--template\` | vanilla, vanilla-js, react, react-js, r3f, r3f-js | default: vanilla |
|
|
730
|
-
| \`--dir\` | any directory | requires \`--workspace\`; default: \`apps/\` or \`packages/\` |
|
|
731
|
-
| \`--bundler\` | unbuild, tsdown | libraries only; default: unbuild |
|
|
732
|
-
|
|
733
|
-
### R3F flags (r3f templates only)
|
|
734
|
-
|
|
735
|
-
\`--drei\` \`--handle\` \`--leva\` \`--postprocessing\` \`--rapier\` \`--xr\` \`--uikit\` \`--offscreen\` \`--zustand\` \`--koota\` \`--triplex\` \`--viverse\`
|
|
736
|
-
|
|
737
|
-
### Examples
|
|
738
|
-
|
|
739
|
-
\`\`\`bash
|
|
740
|
-
# React library (@${name}/ui) in packages/ui
|
|
741
|
-
${packageManager} create krispya ui --workspace --type library --template react
|
|
742
|
-
|
|
743
|
-
# R3F app with physics + controls (@${name}/game) in apps/game
|
|
744
|
-
${packageManager} create krispya game --workspace --type app --template r3f --drei --rapier --leva
|
|
745
|
-
|
|
746
|
-
# App in a custom directory
|
|
747
|
-
${packageManager} create krispya demo --workspace --type app --template react --dir examples
|
|
748
|
-
\`\`\`
|
|
749
|
-
|
|
750
|
-
## After creating a package
|
|
751
|
-
|
|
752
|
-
\`\`\`bash
|
|
753
|
-
${packageManager} install
|
|
754
|
-
\`\`\`
|
|
755
|
-
|
|
756
|
-
- Use \`"workspace:*"\` for internal deps (e.g. \`"@${name}/ui": "workspace:*"\`).
|
|
757
|
-
|
|
758
|
-
## Workspace commands
|
|
759
|
-
|
|
760
|
-
\`\`\`bash
|
|
761
|
-
${packageManager} install # Install all dependencies
|
|
762
|
-
${packageManager} run dev # Run all apps in dev mode
|
|
763
|
-
${packageManager} run build # Build packages then apps
|
|
764
|
-
${packageManager} run test # Run all tests
|
|
765
|
-
${packageManager} run lint # Lint with ${linter}
|
|
766
|
-
${packageManager} run format # Format with ${formatter}
|
|
767
|
-
\`\`\`
|
|
768
|
-
|
|
769
|
-
## Structure + conventions
|
|
770
|
-
|
|
771
|
-
- \`apps/\`: applications (\`--type app\`)
|
|
772
|
-
- \`packages/\`: libraries (\`--type library\`)
|
|
773
|
-
${configDescription}
|
|
774
|
-
- TS configs extend \`@config/typescript/*\` (base/app/node/react)
|
|
775
|
-
`;
|
|
776
|
-
}
|
|
777
|
-
|
|
778
824
|
function generateTypescriptConfigPackage(files) {
|
|
779
825
|
const basePath = ".config/typescript";
|
|
780
826
|
files[`${basePath}/package.json`] = {
|
|
@@ -1126,20 +1172,7 @@ Or in \`.prettierrc.json\`:
|
|
|
1126
1172
|
};
|
|
1127
1173
|
files[`${basePath}/base.json`] = {
|
|
1128
1174
|
type: "text",
|
|
1129
|
-
content: JSON.stringify(
|
|
1130
|
-
{
|
|
1131
|
-
printWidth: defaultFormatterConfig.printWidth,
|
|
1132
|
-
tabWidth: defaultFormatterConfig.tabWidth,
|
|
1133
|
-
useTabs: defaultFormatterConfig.useTabs,
|
|
1134
|
-
semi: defaultFormatterConfig.semi,
|
|
1135
|
-
singleQuote: defaultFormatterConfig.singleQuote,
|
|
1136
|
-
trailingComma: defaultFormatterConfig.trailingComma,
|
|
1137
|
-
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
1138
|
-
arrowParens: defaultFormatterConfig.arrowParens
|
|
1139
|
-
},
|
|
1140
|
-
null,
|
|
1141
|
-
2
|
|
1142
|
-
)
|
|
1175
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1143
1176
|
};
|
|
1144
1177
|
}
|
|
1145
1178
|
function generateOxfmtConfigPackage(files) {
|
|
@@ -1178,20 +1211,7 @@ oxfmt -c node_modules/@config/oxfmt/base.json --write .
|
|
|
1178
1211
|
};
|
|
1179
1212
|
files[`${basePath}/base.json`] = {
|
|
1180
1213
|
type: "text",
|
|
1181
|
-
content: JSON.stringify(
|
|
1182
|
-
{
|
|
1183
|
-
printWidth: defaultFormatterConfig.printWidth,
|
|
1184
|
-
tabWidth: defaultFormatterConfig.tabWidth,
|
|
1185
|
-
useTabs: defaultFormatterConfig.useTabs,
|
|
1186
|
-
semi: defaultFormatterConfig.semi,
|
|
1187
|
-
singleQuote: defaultFormatterConfig.singleQuote,
|
|
1188
|
-
trailingComma: defaultFormatterConfig.trailingComma,
|
|
1189
|
-
bracketSpacing: defaultFormatterConfig.bracketSpacing,
|
|
1190
|
-
arrowParens: defaultFormatterConfig.arrowParens
|
|
1191
|
-
},
|
|
1192
|
-
null,
|
|
1193
|
-
2
|
|
1194
|
-
)
|
|
1214
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1195
1215
|
};
|
|
1196
1216
|
}
|
|
1197
1217
|
|
|
@@ -1204,7 +1224,7 @@ function generateMonorepo(params) {
|
|
|
1204
1224
|
pnpmVersion,
|
|
1205
1225
|
pnpmManageVersions,
|
|
1206
1226
|
nodeVersion,
|
|
1207
|
-
|
|
1227
|
+
aiPlatforms
|
|
1208
1228
|
} = params;
|
|
1209
1229
|
const files = {};
|
|
1210
1230
|
const isPnpm = packageManager === "pnpm";
|
|
@@ -1231,7 +1251,7 @@ function generateMonorepo(params) {
|
|
|
1231
1251
|
build: "pnpm --filter './packages/*' run build && pnpm --filter './apps/*' run build",
|
|
1232
1252
|
test: "pnpm -r run test",
|
|
1233
1253
|
lint: linter === "oxlint" ? "oxlint ." : linter === "biome" ? "biome check ." : "eslint .",
|
|
1234
|
-
format: formatter === "oxfmt" ? "oxfmt ." : formatter === "biome" ? "biome format . --write" : "prettier --write ."
|
|
1254
|
+
format: formatter === "oxfmt" ? "oxfmt -c .config/oxfmt/base.json ." : formatter === "biome" ? "biome format . --write" : "prettier --config .config/prettier/base.json --write ."
|
|
1235
1255
|
},
|
|
1236
1256
|
devDependencies
|
|
1237
1257
|
};
|
|
@@ -1270,11 +1290,43 @@ function generateMonorepo(params) {
|
|
|
1270
1290
|
content: workspaceLines.join("\n")
|
|
1271
1291
|
};
|
|
1272
1292
|
}
|
|
1293
|
+
files["tsconfig.json"] = {
|
|
1294
|
+
type: "text",
|
|
1295
|
+
content: JSON.stringify(
|
|
1296
|
+
{
|
|
1297
|
+
extends: "@config/typescript/base.json",
|
|
1298
|
+
compilerOptions: {
|
|
1299
|
+
noEmit: true
|
|
1300
|
+
},
|
|
1301
|
+
references: []
|
|
1302
|
+
},
|
|
1303
|
+
null,
|
|
1304
|
+
2
|
|
1305
|
+
)
|
|
1306
|
+
};
|
|
1273
1307
|
generateTypescriptConfigPackage(files);
|
|
1274
1308
|
if (linter === "oxlint") {
|
|
1275
1309
|
generateOxlintConfigPackage(files);
|
|
1310
|
+
files["oxlint.json"] = {
|
|
1311
|
+
type: "text",
|
|
1312
|
+
content: JSON.stringify(
|
|
1313
|
+
{
|
|
1314
|
+
$schema: "./node_modules/oxlint/configuration_schema.json",
|
|
1315
|
+
extends: ["@config/oxlint/base.json"]
|
|
1316
|
+
},
|
|
1317
|
+
null,
|
|
1318
|
+
2
|
|
1319
|
+
)
|
|
1320
|
+
};
|
|
1276
1321
|
} else if (linter === "eslint") {
|
|
1277
1322
|
generateEslintConfigPackage(files);
|
|
1323
|
+
files["eslint.config.js"] = {
|
|
1324
|
+
type: "text",
|
|
1325
|
+
content: `import base from "@config/eslint/base";
|
|
1326
|
+
|
|
1327
|
+
export default [...base];
|
|
1328
|
+
`
|
|
1329
|
+
};
|
|
1278
1330
|
} else if (linter === "biome") {
|
|
1279
1331
|
const biomeConfig = {
|
|
1280
1332
|
$schema: "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
@@ -1341,13 +1393,14 @@ This monorepo workspace was generated with create-krispya.
|
|
|
1341
1393
|
To add a new package to this workspace, run create-krispya from this directory and it will detect the monorepo.
|
|
1342
1394
|
`
|
|
1343
1395
|
};
|
|
1344
|
-
if (
|
|
1396
|
+
if (aiPlatforms && aiPlatforms.length > 0) {
|
|
1345
1397
|
generateAiFiles(files, {
|
|
1346
1398
|
name,
|
|
1347
1399
|
packageManager,
|
|
1348
1400
|
linter,
|
|
1349
1401
|
formatter,
|
|
1350
|
-
|
|
1402
|
+
isMonorepo: true,
|
|
1403
|
+
platforms: aiPlatforms
|
|
1351
1404
|
});
|
|
1352
1405
|
}
|
|
1353
1406
|
return { files };
|
|
@@ -1419,14 +1472,11 @@ function generateBiome(generator, options) {
|
|
|
1419
1472
|
if (options == null || !options.linter && !options.formatter) {
|
|
1420
1473
|
return;
|
|
1421
1474
|
}
|
|
1422
|
-
const version = generator.versions.biome ?? "
|
|
1475
|
+
const version = generator.versions.biome ?? "2.0.0";
|
|
1423
1476
|
generator.addDevDependency("@biomejs/biome", `^${version}`);
|
|
1424
1477
|
const { rules } = defaultLinterConfig;
|
|
1425
1478
|
const biomeConfig = {
|
|
1426
|
-
$schema:
|
|
1427
|
-
files: {
|
|
1428
|
-
ignore: defaultLinterConfig.ignorePatterns
|
|
1429
|
-
}
|
|
1479
|
+
$schema: `https://biomejs.dev/schemas/${version}/schema.json`
|
|
1430
1480
|
};
|
|
1431
1481
|
if (options.linter) {
|
|
1432
1482
|
biomeConfig.linter = {
|
|
@@ -1459,27 +1509,52 @@ function generateBiome(generator, options) {
|
|
|
1459
1509
|
arrowParentheses: "always"
|
|
1460
1510
|
}
|
|
1461
1511
|
};
|
|
1512
|
+
biomeConfig.json = {
|
|
1513
|
+
formatter: {
|
|
1514
|
+
indentWidth: 2
|
|
1515
|
+
}
|
|
1516
|
+
};
|
|
1462
1517
|
} else {
|
|
1463
1518
|
biomeConfig.formatter = {
|
|
1464
1519
|
enabled: false
|
|
1465
1520
|
};
|
|
1466
1521
|
}
|
|
1467
|
-
generator.
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1522
|
+
const isStealth = generator.isStealthConfig();
|
|
1523
|
+
if (isStealth) {
|
|
1524
|
+
generator.addFile(".config/biome.json", {
|
|
1525
|
+
type: "text",
|
|
1526
|
+
content: JSON.stringify(biomeConfig, null, 2)
|
|
1527
|
+
});
|
|
1528
|
+
if (options.linter) {
|
|
1529
|
+
generator.addScript("lint", "biome lint --config-path .config .");
|
|
1530
|
+
}
|
|
1531
|
+
if (options.formatter) {
|
|
1532
|
+
generator.addScript(
|
|
1533
|
+
"format",
|
|
1534
|
+
"biome format --config-path .config --write ."
|
|
1535
|
+
);
|
|
1536
|
+
}
|
|
1537
|
+
generator.addVscodeSetting("biome.linter.configPath", ".config/biome.json");
|
|
1538
|
+
} else {
|
|
1539
|
+
generator.addFile("biome.json", {
|
|
1540
|
+
type: "text",
|
|
1541
|
+
content: JSON.stringify(biomeConfig, null, 2)
|
|
1542
|
+
});
|
|
1543
|
+
if (options.linter) {
|
|
1544
|
+
generator.addScript("lint", "biome lint .");
|
|
1545
|
+
}
|
|
1546
|
+
if (options.formatter) {
|
|
1547
|
+
generator.addScript("format", "biome format --write .");
|
|
1548
|
+
}
|
|
1476
1549
|
}
|
|
1477
1550
|
const roles = [];
|
|
1478
1551
|
if (options.linter) roles.push("linter");
|
|
1479
1552
|
if (options.formatter) roles.push("formatter");
|
|
1480
1553
|
generator.inject(
|
|
1481
1554
|
"readme-tools",
|
|
1482
|
-
`[Biome](https://biomejs.dev/) - Fast ${roles.join(
|
|
1555
|
+
`[Biome](https://biomejs.dev/) - Fast ${roles.join(
|
|
1556
|
+
" and "
|
|
1557
|
+
)} for JavaScript and TypeScript`
|
|
1483
1558
|
);
|
|
1484
1559
|
generator.inject("vscode-extension-suggestion", "biomejs.biome");
|
|
1485
1560
|
generator.addVscodeSetting("biome.enabled", true);
|
|
@@ -1564,11 +1639,23 @@ function generateEslint(generator, options) {
|
|
|
1564
1639
|
},`,
|
|
1565
1640
|
"]"
|
|
1566
1641
|
].filter(Boolean).join("\n");
|
|
1567
|
-
generator.
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1642
|
+
const isStealth = generator.isStealthConfig();
|
|
1643
|
+
if (isStealth) {
|
|
1644
|
+
generator.addFile(".config/eslint.config.js", {
|
|
1645
|
+
type: "text",
|
|
1646
|
+
content: configContent
|
|
1647
|
+
});
|
|
1648
|
+
generator.addScript("lint", "eslint --config .config/eslint.config.js .");
|
|
1649
|
+
generator.addVscodeSetting("eslint.options", {
|
|
1650
|
+
overrideConfigFile: ".config/eslint.config.js"
|
|
1651
|
+
});
|
|
1652
|
+
} else {
|
|
1653
|
+
generator.addFile("eslint.config.js", {
|
|
1654
|
+
type: "text",
|
|
1655
|
+
content: configContent
|
|
1656
|
+
});
|
|
1657
|
+
generator.addScript("lint", "eslint .");
|
|
1658
|
+
}
|
|
1572
1659
|
generator.inject(
|
|
1573
1660
|
"readme-tools",
|
|
1574
1661
|
"[ESLint](https://eslint.org/) - Linter for JavaScript and TypeScript"
|
|
@@ -1738,22 +1825,21 @@ function generateOxfmt(generator, options) {
|
|
|
1738
1825
|
} else {
|
|
1739
1826
|
const version = generator.versions.oxfmt ?? "0.1.0";
|
|
1740
1827
|
generator.addDevDependency("oxfmt", `^${version}`);
|
|
1741
|
-
const
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
generator.addVscodeSetting("oxc.fmt.configPath", ".config/oxfmt.json");
|
|
1828
|
+
const isStealth = generator.isStealthConfig();
|
|
1829
|
+
if (isStealth) {
|
|
1830
|
+
generator.addFile(".config/oxfmt.json", {
|
|
1831
|
+
type: "text",
|
|
1832
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1833
|
+
});
|
|
1834
|
+
generator.addScript("format", "oxfmt -c .config/oxfmt.json --write .");
|
|
1835
|
+
generator.addVscodeSetting("oxc.fmt.configPath", ".config/oxfmt.json");
|
|
1836
|
+
} else {
|
|
1837
|
+
generator.addFile("oxfmt.json", {
|
|
1838
|
+
type: "text",
|
|
1839
|
+
content: JSON.stringify(defaultOxfmtConfig, null, 2)
|
|
1840
|
+
});
|
|
1841
|
+
generator.addScript("format", "oxfmt -c oxfmt.json --write .");
|
|
1842
|
+
}
|
|
1757
1843
|
}
|
|
1758
1844
|
generator.inject(
|
|
1759
1845
|
"readme-tools",
|
|
@@ -1767,6 +1853,12 @@ function generateOxfmt(generator, options) {
|
|
|
1767
1853
|
generator.addVscodeSetting("[jsonc]", {
|
|
1768
1854
|
"editor.defaultFormatter": "vscode.json-language-features"
|
|
1769
1855
|
});
|
|
1856
|
+
generator.addVscodeSetting("[markdown]", {
|
|
1857
|
+
"editor.defaultFormatter": "vscode.markdown-language-features"
|
|
1858
|
+
});
|
|
1859
|
+
generator.addVscodeSetting("[yaml]", {
|
|
1860
|
+
"editor.defaultFormatter": "redhat.vscode-yaml"
|
|
1861
|
+
});
|
|
1770
1862
|
}
|
|
1771
1863
|
|
|
1772
1864
|
function toOxlintLevel(level) {
|
|
@@ -1785,13 +1877,14 @@ function generateOxlint(generator, options) {
|
|
|
1785
1877
|
} else {
|
|
1786
1878
|
const version = generator.versions.oxlint ?? "0.16.0";
|
|
1787
1879
|
generator.addDevDependency("oxlint", `^${version}`);
|
|
1880
|
+
const isStealth = generator.isStealthConfig();
|
|
1788
1881
|
const { rules } = defaultLinterConfig;
|
|
1789
1882
|
const plugins = ["unicorn", "typescript", "oxc"];
|
|
1790
1883
|
if (isReact) {
|
|
1791
1884
|
plugins.push("react");
|
|
1792
1885
|
}
|
|
1793
1886
|
const oxlintConfig = {
|
|
1794
|
-
$schema: "../node_modules/oxlint/configuration_schema.json",
|
|
1887
|
+
$schema: isStealth ? "../node_modules/oxlint/configuration_schema.json" : "./node_modules/oxlint/configuration_schema.json",
|
|
1795
1888
|
plugins,
|
|
1796
1889
|
rules: {
|
|
1797
1890
|
"no-unused-vars": [
|
|
@@ -1810,12 +1903,20 @@ function generateOxlint(generator, options) {
|
|
|
1810
1903
|
},
|
|
1811
1904
|
ignorePatterns: defaultLinterConfig.ignorePatterns
|
|
1812
1905
|
};
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1906
|
+
if (isStealth) {
|
|
1907
|
+
generator.addFile(".config/oxlint.json", {
|
|
1908
|
+
type: "text",
|
|
1909
|
+
content: JSON.stringify(oxlintConfig, null, 2)
|
|
1910
|
+
});
|
|
1911
|
+
generator.addScript("lint", "oxlint -c .config/oxlint.json");
|
|
1912
|
+
generator.addVscodeSetting("oxc.configPath", ".config/oxlint.json");
|
|
1913
|
+
} else {
|
|
1914
|
+
generator.addFile("oxlint.json", {
|
|
1915
|
+
type: "text",
|
|
1916
|
+
content: JSON.stringify(oxlintConfig, null, 2)
|
|
1917
|
+
});
|
|
1918
|
+
generator.addScript("lint", "oxlint");
|
|
1919
|
+
}
|
|
1819
1920
|
}
|
|
1820
1921
|
generator.inject(
|
|
1821
1922
|
"readme-tools",
|
|
@@ -1846,25 +1947,33 @@ function generatePostprocessing(generator, options) {
|
|
|
1846
1947
|
function generatePrettier(generator, options) {
|
|
1847
1948
|
const version = generator.versions.prettier ?? "3.4.2";
|
|
1848
1949
|
generator.addDevDependency("prettier", `^${version}`);
|
|
1849
|
-
const
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1950
|
+
const isStealth = generator.isStealthConfig();
|
|
1951
|
+
if (isStealth) {
|
|
1952
|
+
generator.addFile(".config/prettier.json", {
|
|
1953
|
+
type: "text",
|
|
1954
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1955
|
+
});
|
|
1956
|
+
generator.addScript(
|
|
1957
|
+
"format",
|
|
1958
|
+
"prettier --config .config/prettier.json --write ."
|
|
1959
|
+
);
|
|
1960
|
+
generator.addVscodeSetting("prettier.configPath", ".config/prettier.json");
|
|
1961
|
+
} else {
|
|
1962
|
+
generator.addFile(".prettierrc", {
|
|
1963
|
+
type: "text",
|
|
1964
|
+
content: JSON.stringify(defaultPrettierConfig, null, 2)
|
|
1965
|
+
});
|
|
1966
|
+
generator.addScript("format", "prettier --write .");
|
|
1967
|
+
}
|
|
1968
|
+
generator.inject(
|
|
1969
|
+
"readme-tools",
|
|
1970
|
+
"[Prettier](https://prettier.io/) - Opinionated code formatter"
|
|
1971
|
+
);
|
|
1866
1972
|
generator.inject("vscode-extension-suggestion", "esbenp.prettier-vscode");
|
|
1867
|
-
generator.addVscodeSetting(
|
|
1973
|
+
generator.addVscodeSetting(
|
|
1974
|
+
"editor.defaultFormatter",
|
|
1975
|
+
"esbenp.prettier-vscode"
|
|
1976
|
+
);
|
|
1868
1977
|
}
|
|
1869
1978
|
|
|
1870
1979
|
function generateRapier(generator, options) {
|
|
@@ -2114,18 +2223,19 @@ function generateUnbuild(generator) {
|
|
|
2114
2223
|
}
|
|
2115
2224
|
buildConfigLines.push(` },`);
|
|
2116
2225
|
buildConfigLines.push(`})`);
|
|
2117
|
-
|
|
2118
|
-
|
|
2226
|
+
const isStealth = generator.isStealthConfig() && !isMonorepo;
|
|
2227
|
+
if (isStealth) {
|
|
2228
|
+
generator.addFile(`.config/build.config.${ext}`, {
|
|
2119
2229
|
type: "text",
|
|
2120
2230
|
content: buildConfigLines.join("\n")
|
|
2121
2231
|
});
|
|
2122
|
-
generator.addScript("build",
|
|
2232
|
+
generator.addScript("build", `unbuild --config .config/build.config.${ext}`);
|
|
2123
2233
|
} else {
|
|
2124
|
-
generator.addFile(
|
|
2234
|
+
generator.addFile(`build.config.${ext}`, {
|
|
2125
2235
|
type: "text",
|
|
2126
2236
|
content: buildConfigLines.join("\n")
|
|
2127
2237
|
});
|
|
2128
|
-
generator.addScript("build",
|
|
2238
|
+
generator.addScript("build", "unbuild");
|
|
2129
2239
|
}
|
|
2130
2240
|
generator.inject(
|
|
2131
2241
|
"readme-libraries",
|
|
@@ -2433,6 +2543,82 @@ function parseWorkspaceYamlContent(content) {
|
|
|
2433
2543
|
}
|
|
2434
2544
|
return directories;
|
|
2435
2545
|
}
|
|
2546
|
+
async function pathExists(path) {
|
|
2547
|
+
try {
|
|
2548
|
+
await access(path, constants.F_OK);
|
|
2549
|
+
return true;
|
|
2550
|
+
} catch {
|
|
2551
|
+
return false;
|
|
2552
|
+
}
|
|
2553
|
+
}
|
|
2554
|
+
function detectLinterFromScript(script) {
|
|
2555
|
+
if (!script) return void 0;
|
|
2556
|
+
if (script.includes("oxlint")) return "oxlint";
|
|
2557
|
+
if (script.includes("eslint")) return "eslint";
|
|
2558
|
+
if (script.includes("biome check") || script.includes("biome lint")) return "biome";
|
|
2559
|
+
return void 0;
|
|
2560
|
+
}
|
|
2561
|
+
function detectFormatterFromScript(script) {
|
|
2562
|
+
if (!script) return void 0;
|
|
2563
|
+
if (script.includes("prettier")) return "prettier";
|
|
2564
|
+
if (script.includes("oxfmt")) return "oxfmt";
|
|
2565
|
+
if (script.includes("biome format")) return "biome";
|
|
2566
|
+
return void 0;
|
|
2567
|
+
}
|
|
2568
|
+
async function detectLinterFromConfig(root) {
|
|
2569
|
+
if (await pathExists(join(root, ".config/oxlint"))) return "oxlint";
|
|
2570
|
+
if (await pathExists(join(root, ".config/eslint"))) return "eslint";
|
|
2571
|
+
if (await pathExists(join(root, "biome.json"))) {
|
|
2572
|
+
try {
|
|
2573
|
+
const content = await readFile(join(root, "biome.json"), "utf-8");
|
|
2574
|
+
const config = JSON.parse(content);
|
|
2575
|
+
if (config.linter?.enabled !== false) return "biome";
|
|
2576
|
+
} catch {
|
|
2577
|
+
return "biome";
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
return void 0;
|
|
2581
|
+
}
|
|
2582
|
+
async function detectFormatterFromConfig(root) {
|
|
2583
|
+
if (await pathExists(join(root, ".config/prettier"))) return "prettier";
|
|
2584
|
+
if (await pathExists(join(root, ".config/oxfmt"))) return "oxfmt";
|
|
2585
|
+
if (await pathExists(join(root, "biome.json"))) {
|
|
2586
|
+
try {
|
|
2587
|
+
const content = await readFile(join(root, "biome.json"), "utf-8");
|
|
2588
|
+
const config = JSON.parse(content);
|
|
2589
|
+
if (config.formatter?.enabled !== false) return "biome";
|
|
2590
|
+
} catch {
|
|
2591
|
+
return "biome";
|
|
2592
|
+
}
|
|
2593
|
+
}
|
|
2594
|
+
return void 0;
|
|
2595
|
+
}
|
|
2596
|
+
function detectLinterFromDeps(devDeps) {
|
|
2597
|
+
if (!devDeps) return void 0;
|
|
2598
|
+
if (devDeps["@biomejs/biome"]) return "biome";
|
|
2599
|
+
if (devDeps.eslint) return "eslint";
|
|
2600
|
+
if (devDeps.oxlint) return "oxlint";
|
|
2601
|
+
return void 0;
|
|
2602
|
+
}
|
|
2603
|
+
function detectFormatterFromDeps(devDeps) {
|
|
2604
|
+
if (!devDeps) return void 0;
|
|
2605
|
+
if (devDeps["@biomejs/biome"]) return "biome";
|
|
2606
|
+
if (devDeps.prettier) return "prettier";
|
|
2607
|
+
if (devDeps.oxfmt) return "oxfmt";
|
|
2608
|
+
return void 0;
|
|
2609
|
+
}
|
|
2610
|
+
async function detectTooling(root) {
|
|
2611
|
+
try {
|
|
2612
|
+
const pkgPath = join(root, "package.json");
|
|
2613
|
+
const content = await readFile(pkgPath, "utf-8");
|
|
2614
|
+
const pkg = JSON.parse(content);
|
|
2615
|
+
const linter = detectLinterFromScript(pkg.scripts?.lint) ?? await detectLinterFromConfig(root) ?? detectLinterFromDeps(pkg.devDependencies);
|
|
2616
|
+
const formatter = detectFormatterFromScript(pkg.scripts?.format) ?? await detectFormatterFromConfig(root) ?? detectFormatterFromDeps(pkg.devDependencies);
|
|
2617
|
+
return { linter, formatter };
|
|
2618
|
+
} catch {
|
|
2619
|
+
return { linter: void 0, formatter: void 0 };
|
|
2620
|
+
}
|
|
2621
|
+
}
|
|
2436
2622
|
function generateRandomName() {
|
|
2437
2623
|
const adjectives = [
|
|
2438
2624
|
"red",
|
|
@@ -2554,7 +2740,8 @@ function generate(options) {
|
|
|
2554
2740
|
if (language === "typescript") {
|
|
2555
2741
|
const tsResult = generateTypescriptConfig({
|
|
2556
2742
|
baseTemplate,
|
|
2557
|
-
useConfigPackage: clonedOptions.workspaceRoot != null
|
|
2743
|
+
useConfigPackage: clonedOptions.workspaceRoot != null,
|
|
2744
|
+
configStrategy: clonedOptions.configStrategy
|
|
2558
2745
|
});
|
|
2559
2746
|
Object.assign(files, tsResult.files);
|
|
2560
2747
|
Object.assign(devDependencies, tsResult.devDependencies);
|
|
@@ -2566,7 +2753,9 @@ function generate(options) {
|
|
|
2566
2753
|
build: "vite build"
|
|
2567
2754
|
};
|
|
2568
2755
|
if (!isLibrary && (isReact || isR3f)) {
|
|
2569
|
-
codeSnippets["vite-config-import"] = [
|
|
2756
|
+
codeSnippets["vite-config-import"] = [
|
|
2757
|
+
"import react from '@vitejs/plugin-react'"
|
|
2758
|
+
];
|
|
2570
2759
|
}
|
|
2571
2760
|
if (!isLibrary && isR3f) {
|
|
2572
2761
|
codeSnippets["import"] = [`import { Canvas } from "@react-three/fiber"`];
|
|
@@ -2586,6 +2775,9 @@ function generate(options) {
|
|
|
2586
2775
|
const generator = {
|
|
2587
2776
|
options: clonedOptions,
|
|
2588
2777
|
versions,
|
|
2778
|
+
isStealthConfig() {
|
|
2779
|
+
return (clonedOptions.configStrategy ?? "stealth") === "stealth";
|
|
2780
|
+
},
|
|
2589
2781
|
addDependency(name2, semver) {
|
|
2590
2782
|
dependencies[name2];
|
|
2591
2783
|
dependencies[name2] = semver;
|
|
@@ -2642,7 +2834,10 @@ function generate(options) {
|
|
|
2642
2834
|
generateTsdown(generator);
|
|
2643
2835
|
}
|
|
2644
2836
|
const packageManager2 = clonedOptions.packageManager ?? "pnpm";
|
|
2645
|
-
generator.addScript(
|
|
2837
|
+
generator.addScript(
|
|
2838
|
+
"release",
|
|
2839
|
+
`${packageManager2} run build && ${packageManager2} publish`
|
|
2840
|
+
);
|
|
2646
2841
|
}
|
|
2647
2842
|
const testing = clonedOptions.testing ?? (isLibrary ? "vitest" : "none");
|
|
2648
2843
|
if (testing === "vitest") {
|
|
@@ -2735,7 +2930,18 @@ function generate(options) {
|
|
|
2735
2930
|
};
|
|
2736
2931
|
files[".gitattributes"] = { type: "text", content: GitAttributes };
|
|
2737
2932
|
}
|
|
2933
|
+
if (!isMonorepoPackage && clonedOptions.aiPlatforms?.length) {
|
|
2934
|
+
generateAiFiles(files, {
|
|
2935
|
+
name,
|
|
2936
|
+
packageManager: clonedOptions.packageManager ?? "pnpm",
|
|
2937
|
+
linter: clonedOptions.linter ?? "oxlint",
|
|
2938
|
+
formatter: clonedOptions.formatter ?? "prettier",
|
|
2939
|
+
isMonorepo: false,
|
|
2940
|
+
configStrategy: clonedOptions.configStrategy,
|
|
2941
|
+
platforms: clonedOptions.aiPlatforms
|
|
2942
|
+
});
|
|
2943
|
+
}
|
|
2738
2944
|
return files;
|
|
2739
2945
|
}
|
|
2740
2946
|
|
|
2741
|
-
export { getLanguageFromTemplate as a, generateRandomName as b,
|
|
2947
|
+
export { ALL_AI_PLATFORMS as A, getLanguageFromTemplate as a, generateRandomName as b, generateAiFiles as c, detectTooling as d, generateVscodeFiles as e, generateTypescriptConfigPackage as f, getBaseTemplate as g, generateOxlintConfigPackage as h, generateEslintConfigPackage as i, generateOxfmtConfigPackage as j, generatePrettierConfigPackage as k, getLatestNpmVersion as l, generate as m, getLatestPnpmVersion as n, getLatestYarnVersion as o, parseWorkspaceYamlContent as p, getLatestNpmCliVersion as q, getLatestNodeVersion as r, AI_PLATFORM_LABELS as s, AI_PLATFORM_HINTS as t, generateMonorepo as u, validatePackageName as v, monorepo as w };
|