@luxkit/cli 1.0.6 → 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +9 -9
  2. package/dist/index.js +181 -141
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -28,9 +28,9 @@
28
28
 
29
29
  | Feature | Description |
30
30
  | :------------------------- | :----------------------------------------------------------------------------- |
31
- | 🎯 **One Command Setup** | `lux fmt web` generates all linting & formatting configs instantly |
32
- | 🔧 **5 Fmt Presets** | `web` · `electron` · `uniapp` · `node` · `nest` — each with curated rules |
33
- | 🖥️ **6 VSCode Presets** | `web` · `electron` · `uniapp` · `node` · `nest` · `go` — settings + extensions |
31
+ | 🎯 **One Command Setup** | `lux fmt web-vue` generates all linting & formatting configs instantly |
32
+ | 🔧 **5 Fmt Presets** | `web-vue` · `electron-vue` · `uniapp` · `node` · `nest` — each with curated rules |
33
+ | 🖥️ **6 VSCode Presets** | `web-vue` · `electron-vue` · `uniapp` · `node` · `nest` · `go` — settings + extensions |
34
34
  | 🔀 **Smart Merge** | Preset wins for linting keys; user wins for personal preferences |
35
35
  | 🛡️ **Conflict Resolution** | `neverOverwrite` / `forceOverwrite` lists + `--force` flag |
36
36
  | 📦 **Auto Install** | Detects bun / pnpm / yarn / npm and installs devDependencies |
@@ -51,10 +51,10 @@ npm install -g @luxkit/cli
51
51
  bun add -g @luxkit/cli
52
52
 
53
53
  # Initialize formatting configs
54
- lux fmt web # Generate ESLint, Prettier, Stylelint, CSpell, EditorConfig
54
+ lux fmt web-vue # Generate ESLint, Prettier, Stylelint, CSpell, EditorConfig
55
55
 
56
56
  # Initialize VSCode settings
57
- lux vscode web # Generate .vscode/settings.json + extensions.json
57
+ lux vscode web-vue # Generate .vscode/settings.json + extensions.json
58
58
 
59
59
  # List available presets
60
60
  lux fmt list
@@ -86,8 +86,8 @@ lux vscode list
86
86
 
87
87
  | Preset | Fmt | VSCode | Stack |
88
88
  | :--------- | :-: | :----: | :--------------------------- |
89
- | `web` | ✅ | ✅ | Vue / React / TS / CSS |
90
- | `electron` | ✅ | ✅ | Electron + Web stack |
89
+ | `web-vue` | ✅ | ✅ | Vue / React / TS / CSS |
90
+ | `electron-vue` | ✅ | ✅ | Electron + Web stack |
91
91
  | `uniapp` | ✅ | ✅ | UniApp / WeChat Mini Program |
92
92
  | `node` | ✅ | ✅ | Node.js backend |
93
93
  | `nest` | ✅ | ✅ | NestJS backend |
@@ -110,7 +110,7 @@ lux fmt <preset> [options]
110
110
  ### How It Works
111
111
 
112
112
  ```
113
- lux fmt web
113
+ lux fmt web-vue
114
114
 
115
115
 
116
116
  Parse CLI args ──► Resolve preset (fuzzy match on typo)
@@ -154,7 +154,7 @@ cd lux
154
154
  bun install
155
155
 
156
156
  bun link # Register `lux` globally for testing
157
- lux fmt web # Test it on any project
157
+ lux fmt web-vue # Test it on any project
158
158
 
159
159
  bun test # Run tests
160
160
  bun build # Build to dist/
package/dist/index.js CHANGED
@@ -6,9 +6,9 @@ import { program } from "commander";
6
6
  // src/commands/fmt.ts
7
7
  import path4 from "path";
8
8
 
9
- // src/presets/fmt/electron.ts
10
- var electronFmt = {
11
- name: "electron",
9
+ // src/presets/fmt/electron-vue.ts
10
+ var electronVueFmt = {
11
+ name: "electron-vue",
12
12
  description: "Vue 3 + Electron desktop app",
13
13
  eslint: () => `import withVue from '@vue/eslint-config-typescript'
14
14
  import withPrettier from '@vue/eslint-config-prettier/skip-formatting'
@@ -156,7 +156,6 @@ dist/
156
156
  build/
157
157
  coverage/
158
158
  `,
159
- // No stylelint for NestJS
160
159
  cspell: () => JSON.stringify(
161
160
  {
162
161
  $schema: "https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json",
@@ -240,7 +239,7 @@ export default defineConfig(
240
239
  trailingComma: "all",
241
240
  singleQuote: true,
242
241
  printWidth: 100,
243
- tabWidth: 3,
242
+ tabWidth: 2,
244
243
  useTabs: false,
245
244
  quoteProps: "as-needed",
246
245
  jsxSingleQuote: true,
@@ -278,7 +277,7 @@ coverage/
278
277
  [*]
279
278
  charset = utf-8
280
279
  indent_style = space
281
- indent_size = 3
280
+ indent_size = 2
282
281
  end_of_line = lf
283
282
  insert_final_newline = true
284
283
  trim_trailing_whitespace = true
@@ -432,9 +431,9 @@ trim_trailing_whitespace = false
432
431
  }
433
432
  };
434
433
 
435
- // src/presets/fmt/web.ts
436
- var webFmt = {
437
- name: "web",
434
+ // src/presets/fmt/web-vue.ts
435
+ var webVueFmt = {
436
+ name: "web-vue",
438
437
  description: "Vue 3 Web frontend (Vite + Vue + TypeScript)",
439
438
  eslint: () => `import withVue from '@vue/eslint-config-typescript'
440
439
  import withPrettier from '@vue/eslint-config-prettier/skip-formatting'
@@ -552,7 +551,7 @@ trim_trailing_whitespace = false
552
551
  };
553
552
 
554
553
  // src/presets/fmt/index.ts
555
- var FMT_PRESETS = [webFmt, electronFmt, uniappFmt, nodeFmt, nestFmt];
554
+ var FMT_PRESETS = [webVueFmt, electronVueFmt, uniappFmt, nodeFmt, nestFmt];
556
555
 
557
556
  // src/utils/logger.ts
558
557
  import chalk from "chalk";
@@ -700,6 +699,7 @@ function generateConfigFile(preset, filename, content, opts) {
700
699
  function generateAllFmt(preset, opts) {
701
700
  const result = { created: [], overwritten: [], skipped: [] };
702
701
  for (const { filename, getContent } of CONFIG_FILES) {
702
+ if (opts.noStylelint && filename.includes("stylelint")) continue;
703
703
  const content = getContent(preset);
704
704
  if (content === void 0) continue;
705
705
  const action = generateConfigFile(preset, filename, content, opts);
@@ -781,9 +781,22 @@ async function installDevDeps(packages, cwd, pm) {
781
781
  }
782
782
 
783
783
  // src/commands/fmt.ts
784
+ function filterStylelintScripts(scripts) {
785
+ const filtered = {};
786
+ for (const [key, value] of Object.entries(scripts)) {
787
+ if (key.startsWith("stylelint")) continue;
788
+ filtered[key] = value.replace(/\s*&&\s*<pm>\s+stylelint\S*/g, "");
789
+ }
790
+ return filtered;
791
+ }
792
+ function isNotStylelintDep(dep) {
793
+ if (dep.includes("stylelint")) return false;
794
+ if (dep === "postcss-html" || dep === "postcss-scss") return false;
795
+ return true;
796
+ }
784
797
  function registerFmtCommand(program2) {
785
798
  const fmt = program2.command("fmt").description("Initialize formatting config with preset");
786
- fmt.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--no-install", "Skip dependency installation").option("--dry-run", "Preview without writing files").action(
799
+ fmt.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--no-install", "Skip dependency installation").option("--dry-run", "Preview without writing files").option("--no-stylelint", "Skip Stylelint config generation").action(
787
800
  async (presetName, options) => {
788
801
  const preset = resolvePreset(FMT_PRESETS, presetName);
789
802
  if (!preset) return;
@@ -793,6 +806,7 @@ function registerFmtCommand(program2) {
793
806
  cwd,
794
807
  force: options.force ?? false,
795
808
  dryRun: options.dryRun ?? false,
809
+ noStylelint: options.stylelint === false,
796
810
  lockfile: pm ? getLockfileName(pm) : void 0
797
811
  };
798
812
  const result = generateAllFmt(preset, opts);
@@ -806,21 +820,23 @@ function registerFmtCommand(program2) {
806
820
  warnMissingPackageJson(preset, options.install !== false);
807
821
  return;
808
822
  }
809
- if (preset.scripts) {
810
- await injectScripts(preset.scripts, opts, pm);
823
+ const scripts = opts.noStylelint && preset.scripts ? filterStylelintScripts(preset.scripts) : preset.scripts;
824
+ if (scripts) {
825
+ await injectScripts(scripts, opts, pm);
811
826
  }
812
827
  if (!preset.dependencies?.dev) return;
828
+ const devDeps = opts.noStylelint ? preset.dependencies.dev.filter(isNotStylelintDep) : preset.dependencies.dev;
813
829
  if (options.install === false) {
814
- logger.log(`Dependencies: ${preset.dependencies.dev.join(", ")}`);
830
+ logger.log(`Dependencies: ${devDeps.join(", ")}`);
815
831
  return;
816
832
  }
817
833
  if (opts.dryRun) {
818
- logger.log(`[dry-run] Would install: ${preset.dependencies.dev.join(", ")}`);
834
+ logger.log(`[dry-run] Would install: ${devDeps.join(", ")}`);
819
835
  return;
820
836
  }
821
837
  try {
822
838
  logger.log(`Installing dependencies with ${pm}...`);
823
- await installDevDeps(preset.dependencies.dev, cwd, pm);
839
+ await installDevDeps(devDeps, cwd, pm);
824
840
  logger.success("Dependencies installed successfully");
825
841
  } catch {
826
842
  logger.warn("Dependency installation failed. You can install manually.");
@@ -1063,12 +1079,12 @@ function registerUpdateCommand(program2) {
1063
1079
  });
1064
1080
  }
1065
1081
 
1066
- // src/presets/vscode/web.ts
1067
- var webVscode = {
1068
- name: "web",
1082
+ // src/presets/vscode/web-vue.ts
1083
+ var webVueVscode = {
1084
+ name: "web-vue",
1069
1085
  description: "VSCode config for Vue 3 Web",
1070
1086
  settings: () => ({
1071
- // ===== 编辑器爱好设置 =====
1087
+ // ===== Editor Preferences =====
1072
1088
  "editor.tabSize": 2,
1073
1089
  "editor.detectIndentation": false,
1074
1090
  "editor.insertSpaces": true,
@@ -1081,26 +1097,25 @@ var webVscode = {
1081
1097
  "source.fixAll.stylelint": "explicit",
1082
1098
  "source.organizeImports": "never"
1083
1099
  },
1084
- // 光标与动画
1100
+ // Cursor & Animation
1085
1101
  "editor.cursorBlinking": "expand",
1086
1102
  "editor.cursorSmoothCaretAnimation": "on",
1087
1103
  "editor.largeFileOptimizations": true,
1088
- // 代码辅助
1104
+ // Code Assistance
1089
1105
  "editor.inlineSuggest.enabled": true,
1090
1106
  "editor.suggestSelection": "recentlyUsedByPrefix",
1091
1107
  "editor.acceptSuggestionOnEnter": "smart",
1092
1108
  "editor.bracketPairColorization.enabled": true,
1093
1109
  "editor.autoClosingBrackets": "beforeWhitespace",
1094
1110
  "editor.autoClosingOvertype": "always",
1095
- // ===== TypeScript 专项优化 =====
1111
+ // ===== TypeScript =====
1096
1112
  "js/ts.inlayHints.enumMemberValues.enabled": true,
1097
1113
  "js/ts.preferences.preferTypeOnlyAutoImports": true,
1098
1114
  "js/ts.preferences.includePackageJsonAutoImports": "on",
1099
1115
  "js/ts.preferences.importModuleSpecifier": "relative",
1100
1116
  "js/ts.suggest.autoImports": true,
1101
1117
  "js/ts.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"],
1102
- "js/ts.tsdk.path": "node_modules/typescript/lib",
1103
- // ===== 语言特定格式化 =====
1118
+ // ===== Language-specific Formatting =====
1104
1119
  "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1105
1120
  "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1106
1121
  "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
@@ -1114,18 +1129,22 @@ var webVscode = {
1114
1129
  },
1115
1130
  "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1116
1131
  "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1117
- // ===== 终端配置 =====
1132
+ // ===== Terminal =====
1118
1133
  "terminal.integrated.cursorBlinking": true,
1119
1134
  "terminal.integrated.tabs.enabled": true,
1120
1135
  "terminal.integrated.scrollback": 1e4,
1121
- // ===== 文件排除 =====
1136
+ // ===== File Exclusion =====
1122
1137
  "files.watcherExclude": {
1123
1138
  "**/.git/objects/**": true,
1124
1139
  "**/.git/subtree-cache/**": true,
1125
1140
  "**/.vscode/**": true,
1126
1141
  "**/node_modules/**": true,
1127
1142
  "**/tmp/**": true,
1128
- "**/dist/**": true
1143
+ "**/dist/**": true,
1144
+ "**/pnpm-lock.yaml": true,
1145
+ "**/package-lock.json": true,
1146
+ "**/bun.lock": true,
1147
+ "**/yarn.lock": true
1129
1148
  },
1130
1149
  "search.exclude": {
1131
1150
  "**/node_modules": true,
@@ -1136,13 +1155,16 @@ var webVscode = {
1136
1155
  "**/.vscode": false,
1137
1156
  "**/tmp": true,
1138
1157
  node_modules: true,
1139
- "**/pnpm-lock.yaml": true
1158
+ "**/pnpm-lock.yaml": true,
1159
+ "**/package-lock.json": true,
1160
+ "**/bun.lock": true,
1161
+ "**/yarn.lock": true
1140
1162
  },
1141
- // ===== 文件嵌套(美观优化)=====
1163
+ // ===== File Nesting =====
1142
1164
  "explorer.fileNesting.enabled": true,
1143
1165
  "explorer.fileNesting.expand": false,
1144
1166
  "explorer.fileNesting.patterns": {
1145
- "package.json": "pnpm-lock.yaml, .gitignore, .browserslistrc, .npmrc, cspell.json",
1167
+ "package.json": "pnpm-lock.yaml,yarn.lock,bun.lock, .gitignore, .browserslistrc, .npmrc, cspell.json,README.md, LICENSE*,.editorconfig",
1146
1168
  "eslint.config.mjs": ".prettierignore, .prettierrc, .prettierrc.json, .editorconfig",
1147
1169
  "tsconfig.json": "tsconfig.*.json",
1148
1170
  "tailwind.config.js": "postcss.config.js",
@@ -1164,7 +1186,6 @@ var webVscode = {
1164
1186
  ],
1165
1187
  // ===== Stylelint =====
1166
1188
  "stylelint.enable": true,
1167
- "stylelint.packageManager": "pnpm",
1168
1189
  "stylelint.validate": ["css", "scss", "vue"],
1169
1190
  "stylelint.customSyntax": "postcss-html",
1170
1191
  "stylelint.snippet": ["css", "scss", "vue"],
@@ -1172,9 +1193,7 @@ var webVscode = {
1172
1193
  "less.validate": false,
1173
1194
  "scss.validate": false,
1174
1195
  // ===== CSpell =====
1175
- "cSpell.language": "en",
1176
- // ===== 包管理器 =====
1177
- "npm.packageManager": "pnpm"
1196
+ "cSpell.language": "en"
1178
1197
  }),
1179
1198
  extensions: () => [
1180
1199
  "vue.volar",
@@ -1183,21 +1202,16 @@ var webVscode = {
1183
1202
  "stylelint.vscode-stylelint",
1184
1203
  "mrmlnc.vscode-scss",
1185
1204
  "streetsidesoftware.code-spell-checker",
1186
- "yoavbls.pretty-ts-errors",
1187
- "editorconfig.editorconfig",
1188
- "aaron-bond.better-comments",
1189
- "usernamehw.errorlens",
1190
- "christian-kohler.path-intellisense",
1191
- "vscode-icons-team.vscode-icons"
1205
+ "editorconfig.editorconfig"
1192
1206
  ]
1193
1207
  };
1194
1208
 
1195
1209
  // src/presets/vscode/electron.ts
1196
- var electronVscode = {
1197
- name: "electron",
1210
+ var electronVueVscode = {
1211
+ name: "electron-vue",
1198
1212
  description: "VSCode config for Vue 3 + Electron",
1199
1213
  settings: () => ({
1200
- // ===== 编辑器爱好设置 =====
1214
+ // ===== Editor Preferences =====
1201
1215
  "editor.tabSize": 2,
1202
1216
  "editor.detectIndentation": false,
1203
1217
  "editor.insertSpaces": true,
@@ -1219,7 +1233,7 @@ var electronVscode = {
1219
1233
  "editor.bracketPairColorization.enabled": true,
1220
1234
  "editor.autoClosingBrackets": "beforeWhitespace",
1221
1235
  "editor.autoClosingOvertype": "always",
1222
- // ===== TypeScript 专项优化 =====
1236
+ // ===== TypeScript =====
1223
1237
  "js/ts.inlayHints.enumMemberValues.enabled": true,
1224
1238
  "js/ts.preferences.preferTypeOnlyAutoImports": true,
1225
1239
  "js/ts.preferences.includePackageJsonAutoImports": "on",
@@ -1227,7 +1241,7 @@ var electronVscode = {
1227
1241
  "js/ts.suggest.autoImports": true,
1228
1242
  "js/ts.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"],
1229
1243
  "js/ts.tsdk.path": "node_modules/typescript/lib",
1230
- // ===== 语言特定格式化 =====
1244
+ // ===== Language-specific Formatting =====
1231
1245
  "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1232
1246
  "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1233
1247
  "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
@@ -1241,11 +1255,11 @@ var electronVscode = {
1241
1255
  },
1242
1256
  "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1243
1257
  "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1244
- // ===== 终端配置 =====
1258
+ // ===== Terminal =====
1245
1259
  "terminal.integrated.cursorBlinking": true,
1246
1260
  "terminal.integrated.tabs.enabled": true,
1247
1261
  "terminal.integrated.scrollback": 1e4,
1248
- // ===== 文件排除 =====
1262
+ // ===== File Exclusion =====
1249
1263
  "files.watcherExclude": {
1250
1264
  "**/.git/objects/**": true,
1251
1265
  "**/.git/subtree-cache/**": true,
@@ -1254,7 +1268,11 @@ var electronVscode = {
1254
1268
  "**/tmp/**": true,
1255
1269
  "**/dist/**": true,
1256
1270
  "**/release/**": true,
1257
- "**/out/**": true
1271
+ "**/out/**": true,
1272
+ "**/pnpm-lock.yaml": true,
1273
+ "**/package-lock.json": true,
1274
+ "**/bun.lock": true,
1275
+ "**/yarn.lock": true
1258
1276
  },
1259
1277
  "search.exclude": {
1260
1278
  "**/node_modules": true,
@@ -1267,14 +1285,17 @@ var electronVscode = {
1267
1285
  "**/.vscode": false,
1268
1286
  "**/tmp": true,
1269
1287
  node_modules: true,
1270
- "**/pnpm-lock.yaml": true
1288
+ "**/pnpm-lock.yaml": true,
1289
+ "**/package-lock.json": true,
1290
+ "**/bun.lock": true,
1291
+ "**/yarn.lock": true
1271
1292
  },
1272
- // ===== 文件嵌套 =====
1293
+ // ===== File Nesting =====
1273
1294
  "explorer.fileNesting.enabled": true,
1274
1295
  "explorer.fileNesting.expand": false,
1275
1296
  "explorer.fileNesting.patterns": {
1276
- "package.json": "pnpm-lock.yaml, .gitignore, .browserslistrc, .npmrc, cspell.json",
1277
- "eslint.config.mjs": ".prettierignore, .prettierrc.json, .editorconfig",
1297
+ "package.json": "pnpm-lock.yaml,yarn.lock,bun.lock, .gitignore, .browserslistrc, .npmrc, cspell.json,README.md, LICENSE*,.editorconfig",
1298
+ "eslint.config.mjs": ".prettierignore, .prettierrc, .prettierrc.json, .editorconfig",
1278
1299
  "tsconfig.json": "tsconfig.*.json",
1279
1300
  "tailwind.config.js": "postcss.config.js",
1280
1301
  "vite.config.{js,ts}": "vite.*.{js,ts}",
@@ -1306,7 +1327,7 @@ var electronVscode = {
1306
1327
  "scss.validate": false,
1307
1328
  // ===== CSpell =====
1308
1329
  "cSpell.language": "en",
1309
- // ===== 包管理器 =====
1330
+ // ===== Package Manager =====
1310
1331
  "npm.packageManager": "pnpm"
1311
1332
  }),
1312
1333
  extensions: () => [
@@ -1316,12 +1337,7 @@ var electronVscode = {
1316
1337
  "stylelint.vscode-stylelint",
1317
1338
  "mrmlnc.vscode-scss",
1318
1339
  "streetsidesoftware.code-spell-checker",
1319
- "yoavbls.pretty-ts-errors",
1320
- "editorconfig.editorconfig",
1321
- "aaron-bond.better-comments",
1322
- "usernamehw.errorlens",
1323
- "christian-kohler.path-intellisense",
1324
- "vscode-icons-team.vscode-icons"
1340
+ "editorconfig.editorconfig"
1325
1341
  ]
1326
1342
  };
1327
1343
 
@@ -1330,7 +1346,7 @@ var uniappVscode = {
1330
1346
  name: "uniapp",
1331
1347
  description: "VSCode config for UniApp",
1332
1348
  settings: () => ({
1333
- // ===== 编辑器爱好设置 =====
1349
+ // ===== Editor Preferences =====
1334
1350
  "editor.tabSize": 2,
1335
1351
  "editor.detectIndentation": false,
1336
1352
  "editor.insertSpaces": true,
@@ -1352,7 +1368,7 @@ var uniappVscode = {
1352
1368
  "editor.bracketPairColorization.enabled": true,
1353
1369
  "editor.autoClosingBrackets": "beforeWhitespace",
1354
1370
  "editor.autoClosingOvertype": "always",
1355
- // ===== TypeScript 专项优化 =====
1371
+ // ===== TypeScript =====
1356
1372
  "js/ts.inlayHints.enumMemberValues.enabled": true,
1357
1373
  "js/ts.preferences.preferTypeOnlyAutoImports": true,
1358
1374
  "js/ts.preferences.includePackageJsonAutoImports": "on",
@@ -1360,7 +1376,7 @@ var uniappVscode = {
1360
1376
  "js/ts.suggest.autoImports": true,
1361
1377
  "js/ts.tsserver.exclude": ["**/node_modules", "**/dist", "**/unpackage"],
1362
1378
  "js/ts.tsdk.path": "node_modules/typescript/lib",
1363
- // ===== 语言特定格式化 =====
1379
+ // ===== Language-specific Formatting =====
1364
1380
  "[html]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1365
1381
  "[css]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1366
1382
  "[scss]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
@@ -1374,18 +1390,22 @@ var uniappVscode = {
1374
1390
  },
1375
1391
  "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1376
1392
  "[vue]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1377
- // ===== 终端配置 =====
1393
+ // ===== Terminal =====
1378
1394
  "terminal.integrated.cursorBlinking": true,
1379
1395
  "terminal.integrated.tabs.enabled": true,
1380
1396
  "terminal.integrated.scrollback": 1e4,
1381
- // ===== 文件排除 =====
1397
+ // ===== File Exclusion =====
1382
1398
  "files.watcherExclude": {
1383
1399
  "**/.git/objects/**": true,
1384
1400
  "**/.git/subtree-cache/**": true,
1385
1401
  "**/node_modules/**": true,
1386
1402
  "**/tmp/**": true,
1387
1403
  "**/dist/**": true,
1388
- "**/unpackage/**": true
1404
+ "**/unpackage/**": true,
1405
+ "**/pnpm-lock.yaml": true,
1406
+ "**/package-lock.json": true,
1407
+ "**/bun.lock": true,
1408
+ "**/yarn.lock": true
1389
1409
  },
1390
1410
  "search.exclude": {
1391
1411
  "**/node_modules": true,
@@ -1394,14 +1414,17 @@ var uniappVscode = {
1394
1414
  "**/unpackage": true,
1395
1415
  "**/.git": true,
1396
1416
  "**/tmp": true,
1397
- "**/pnpm-lock.yaml": true
1417
+ "**/pnpm-lock.yaml": true,
1418
+ "**/package-lock.json": true,
1419
+ "**/bun.lock": true,
1420
+ "**/yarn.lock": true
1398
1421
  },
1399
- // ===== 文件嵌套 =====
1422
+ // ===== File Nesting =====
1400
1423
  "explorer.fileNesting.enabled": true,
1401
1424
  "explorer.fileNesting.expand": false,
1402
1425
  "explorer.fileNesting.patterns": {
1403
- "package.json": "pnpm-lock.yaml, .gitignore, manifest.json, pages.json",
1404
- "eslint.config.mjs": ".prettierignore, .prettierrc.json",
1426
+ "package.json": "pnpm-lock.yaml,yarn.lock,bun.lock, .gitignore, manifest.json, pages.json,cspell.json,README.md, LICENSE*,.editorconfig",
1427
+ "eslint.config.mjs": ".prettierignore, .prettierrc, .prettierrc.json, .editorconfig",
1405
1428
  "tsconfig.json": "tsconfig.*.json",
1406
1429
  ".env": ".env.*"
1407
1430
  },
@@ -1420,7 +1443,6 @@ var uniappVscode = {
1420
1443
  ],
1421
1444
  // ===== Stylelint =====
1422
1445
  "stylelint.enable": true,
1423
- "stylelint.packageManager": "pnpm",
1424
1446
  "stylelint.validate": ["css", "scss", "vue"],
1425
1447
  "stylelint.customSyntax": "postcss-html",
1426
1448
  "stylelint.snippet": ["css", "scss", "vue"],
@@ -1428,9 +1450,7 @@ var uniappVscode = {
1428
1450
  "less.validate": false,
1429
1451
  "scss.validate": false,
1430
1452
  // ===== CSpell =====
1431
- "cSpell.language": "en",
1432
- // ===== 包管理器 =====
1433
- "npm.packageManager": "pnpm"
1453
+ "cSpell.language": "en"
1434
1454
  }),
1435
1455
  extensions: () => [
1436
1456
  "vue.volar",
@@ -1439,12 +1459,7 @@ var uniappVscode = {
1439
1459
  "stylelint.vscode-stylelint",
1440
1460
  "mrmlnc.vscode-scss",
1441
1461
  "streetsidesoftware.code-spell-checker",
1442
- "yoavbls.pretty-ts-errors",
1443
- "editorconfig.editorconfig",
1444
- "aaron-bond.better-comments",
1445
- "usernamehw.errorlens",
1446
- "christian-kohler.path-intellisense",
1447
- "vscode-icons-team.vscode-icons"
1462
+ "editorconfig.editorconfig"
1448
1463
  ]
1449
1464
  };
1450
1465
 
@@ -1453,8 +1468,8 @@ var nodeVscode = {
1453
1468
  name: "node",
1454
1469
  description: "VSCode config for Node.js",
1455
1470
  settings: () => ({
1456
- // ===== 编辑器爱好设置 =====
1457
- "editor.tabSize": 3,
1471
+ // ===== Editor Preferences =====
1472
+ "editor.tabSize": 2,
1458
1473
  "editor.detectIndentation": false,
1459
1474
  "editor.insertSpaces": true,
1460
1475
  "editor.renderWhitespace": "selection",
@@ -1474,15 +1489,14 @@ var nodeVscode = {
1474
1489
  "editor.bracketPairColorization.enabled": true,
1475
1490
  "editor.autoClosingBrackets": "beforeWhitespace",
1476
1491
  "editor.autoClosingOvertype": "always",
1477
- // ===== TypeScript 专项优化 =====
1492
+ // ===== TypeScript =====
1478
1493
  "js/ts.inlayHints.enumMemberValues.enabled": true,
1479
1494
  "js/ts.preferences.preferTypeOnlyAutoImports": true,
1480
1495
  "js/ts.preferences.includePackageJsonAutoImports": "on",
1481
1496
  "js/ts.preferences.importModuleSpecifier": "relative",
1482
1497
  "js/ts.suggest.autoImports": true,
1483
1498
  "js/ts.tsserver.exclude": ["**/node_modules", "**/dist"],
1484
- "js/ts.tsdk.path": "node_modules/typescript/lib",
1485
- // ===== 语言特定格式化 =====
1499
+ // ===== Language-specific Formatting =====
1486
1500
  "[typescript]": {
1487
1501
  "editor.defaultFormatter": "esbenp.prettier-vscode",
1488
1502
  "editor.formatOnSave": true
@@ -1492,17 +1506,21 @@ var nodeVscode = {
1492
1506
  "editor.formatOnSave": true
1493
1507
  },
1494
1508
  "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1495
- // ===== 终端配置 =====
1509
+ // ===== Terminal =====
1496
1510
  "terminal.integrated.cursorBlinking": true,
1497
1511
  "terminal.integrated.tabs.enabled": true,
1498
1512
  "terminal.integrated.scrollback": 1e4,
1499
- // ===== 文件排除 =====
1513
+ // ===== File Exclusion =====
1500
1514
  "files.watcherExclude": {
1501
1515
  "**/.git/objects/**": true,
1502
1516
  "**/.git/subtree-cache/**": true,
1503
1517
  "**/node_modules/**": true,
1504
1518
  "**/tmp/**": true,
1505
- "**/dist/**": true
1519
+ "**/dist/**": true,
1520
+ "**/pnpm-lock.yaml": true,
1521
+ "**/package-lock.json": true,
1522
+ "**/bun.lock": true,
1523
+ "**/yarn.lock": true
1506
1524
  },
1507
1525
  "search.exclude": {
1508
1526
  "**/node_modules": true,
@@ -1511,13 +1529,16 @@ var nodeVscode = {
1511
1529
  "**/.git": true,
1512
1530
  "**/tmp": true,
1513
1531
  node_modules: true,
1514
- "**/bun.lock": true
1532
+ "**/pnpm-lock.yaml": true,
1533
+ "**/package-lock.json": true,
1534
+ "**/bun.lock": true,
1535
+ "**/yarn.lock": true
1515
1536
  },
1516
- // ===== 文件嵌套 =====
1537
+ // ===== File Nesting =====
1517
1538
  "explorer.fileNesting.enabled": true,
1518
1539
  "explorer.fileNesting.expand": false,
1519
1540
  "explorer.fileNesting.patterns": {
1520
- "package.json": "bun.lock, .gitignore, .npmrc, cspell.json",
1541
+ "package.json": "pnpm-lock.yaml,yarn.lock,bun.lock, .gitignore, .npmrc, cspell.json,README.md,LICENSE*,.editorconfig",
1521
1542
  "eslint.config.mjs": ".prettierignore, .prettierrc.json, .editorconfig,.prettierrc",
1522
1543
  "tsconfig.json": "tsconfig.*.json",
1523
1544
  ".env": ".env.*"
@@ -1525,20 +1546,13 @@ var nodeVscode = {
1525
1546
  // ===== ESLint =====
1526
1547
  "eslint.validate": ["javascript", "typescript", "json", "jsonc", "json5"],
1527
1548
  // ===== CSpell =====
1528
- "cSpell.language": "en",
1529
- // ===== 包管理器 =====
1530
- "npm.packageManager": "bun"
1549
+ "cSpell.language": "en"
1531
1550
  }),
1532
1551
  extensions: () => [
1533
1552
  "dbaeumer.vscode-eslint",
1534
1553
  "esbenp.prettier-vscode",
1535
1554
  "streetsidesoftware.code-spell-checker",
1536
- "yoavbls.pretty-ts-errors",
1537
- "editorconfig.editorconfig",
1538
- "aaron-bond.better-comments",
1539
- "usernamehw.errorlens",
1540
- "christian-kohler.path-intellisense",
1541
- "vscode-icons-team.vscode-icons"
1555
+ "editorconfig.editorconfig"
1542
1556
  ]
1543
1557
  };
1544
1558
 
@@ -1547,7 +1561,7 @@ var nestVscode = {
1547
1561
  name: "nest",
1548
1562
  description: "VSCode config for NestJS",
1549
1563
  settings: () => ({
1550
- // ===== 编辑器爱好设置 =====
1564
+ // ===== Editor Preferences =====
1551
1565
  "editor.tabSize": 2,
1552
1566
  "editor.detectIndentation": false,
1553
1567
  "editor.insertSpaces": true,
@@ -1565,7 +1579,7 @@ var nestVscode = {
1565
1579
  "editor.bracketPairColorization.enabled": true,
1566
1580
  "editor.autoClosingBrackets": "beforeWhitespace",
1567
1581
  "editor.autoClosingOvertype": "always",
1568
- // ===== TypeScript 专项优化 =====
1582
+ // ===== TypeScript =====
1569
1583
  "js/ts.inlayHints.enumMemberValues.enabled": true,
1570
1584
  "js/ts.preferences.preferTypeOnlyAutoImports": true,
1571
1585
  "js/ts.preferences.includePackageJsonAutoImports": "on",
@@ -1573,7 +1587,7 @@ var nestVscode = {
1573
1587
  "js/ts.suggest.autoImports": true,
1574
1588
  "js/ts.tsserver.exclude": ["**/node_modules", "**/dist", "**/.turbo"],
1575
1589
  "js/ts.tsdk.path": "node_modules/typescript/lib",
1576
- // ===== 语言特定格式化 =====
1590
+ // ===== Language-specific Formatting =====
1577
1591
  "[typescript]": {
1578
1592
  "editor.defaultFormatter": "esbenp.prettier-vscode",
1579
1593
  "editor.formatOnSave": true
@@ -1583,17 +1597,21 @@ var nestVscode = {
1583
1597
  "editor.formatOnSave": true
1584
1598
  },
1585
1599
  "[json]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
1586
- // ===== 终端配置 =====
1600
+ // ===== Terminal =====
1587
1601
  "terminal.integrated.cursorBlinking": true,
1588
1602
  "terminal.integrated.tabs.enabled": true,
1589
1603
  "terminal.integrated.scrollback": 1e4,
1590
- // ===== 文件排除 =====
1604
+ // ===== File Exclusion =====
1591
1605
  "files.watcherExclude": {
1592
1606
  "**/.git/objects/**": true,
1593
1607
  "**/.git/subtree-cache/**": true,
1594
1608
  "**/node_modules/**": true,
1595
1609
  "**/tmp/**": true,
1596
- "**/dist/**": true
1610
+ "**/dist/**": true,
1611
+ "**/pnpm-lock.yaml": true,
1612
+ "**/package-lock.json": true,
1613
+ "**/bun.lock": true,
1614
+ "**/yarn.lock": true
1597
1615
  },
1598
1616
  "search.exclude": {
1599
1617
  "**/node_modules": true,
@@ -1601,14 +1619,17 @@ var nestVscode = {
1601
1619
  "**/dist": true,
1602
1620
  "**/.git": true,
1603
1621
  "**/tmp": true,
1604
- "**/pnpm-lock.yaml": true
1622
+ "**/pnpm-lock.yaml": true,
1623
+ "**/package-lock.json": true,
1624
+ "**/bun.lock": true,
1625
+ "**/yarn.lock": true
1605
1626
  },
1606
- // ===== 文件嵌套 =====
1627
+ // ===== File Nesting =====
1607
1628
  "explorer.fileNesting.enabled": true,
1608
1629
  "explorer.fileNesting.expand": false,
1609
1630
  "explorer.fileNesting.patterns": {
1610
- "package.json": "pnpm-lock.yaml, .gitignore, .npmrc, nest-cli.json",
1611
- "eslint.config.mjs": ".prettierignore, .prettierrc.json, .editorconfig",
1631
+ "package.json": "pnpm-lock.yaml,yarn.lock,bun.lock, .gitignore, .npmrc, nest-cli.json,cspell.json,README.md, LICENSE*,.editorconfig",
1632
+ "eslint.config.mjs": ".prettierignore, .prettierrc, .prettierrc.json, .editorconfig",
1612
1633
  "tsconfig.json": "tsconfig.*.json",
1613
1634
  ".env": ".env.*",
1614
1635
  "*.controller.ts": "$(capture).controller.spec.ts",
@@ -1636,13 +1657,7 @@ var nestVscode = {
1636
1657
  "dbaeumer.vscode-eslint",
1637
1658
  "esbenp.prettier-vscode",
1638
1659
  "streetsidesoftware.code-spell-checker",
1639
- "yoavbls.pretty-ts-errors",
1640
- "editorconfig.editorconfig",
1641
- "firsttris.vscode-jest-runner",
1642
- "aaron-bond.better-comments",
1643
- "usernamehw.errorlens",
1644
- "christian-kohler.path-intellisense",
1645
- "vscode-icons-team.vscode-icons"
1660
+ "editorconfig.editorconfig"
1646
1661
  ]
1647
1662
  };
1648
1663
 
@@ -1681,8 +1696,8 @@ var goVscode = {
1681
1696
 
1682
1697
  // src/presets/vscode/index.ts
1683
1698
  var VSCODE_PRESETS = [
1684
- webVscode,
1685
- electronVscode,
1699
+ webVueVscode,
1700
+ electronVueVscode,
1686
1701
  uniappVscode,
1687
1702
  nodeVscode,
1688
1703
  nestVscode,
@@ -1735,13 +1750,21 @@ function isPlainObject(val) {
1735
1750
  }
1736
1751
 
1737
1752
  // src/generators/vscode.ts
1753
+ var STYLELINT_SETTINGS_PREFIXES = [
1754
+ "stylelint.",
1755
+ "css.validate",
1756
+ "less.validate",
1757
+ "scss.validate"
1758
+ ];
1759
+ var STYLELINT_EXTENSION = "stylelint.vscode-stylelint";
1738
1760
  function generateVscodeSettings(preset, opts) {
1739
1761
  const settingsPath = `${opts.cwd}/.vscode/settings.json`;
1740
1762
  if (opts.dryRun) {
1741
1763
  const existingSettings2 = readJson(settingsPath);
1742
1764
  return existingSettings2 ? "overwritten" : "created";
1743
1765
  }
1744
- const presetSettings = preset.settings();
1766
+ const rawSettings = preset.settings();
1767
+ const presetSettings = opts.noStylelint ? filterStylelintSettings(rawSettings) : rawSettings;
1745
1768
  const existingSettings = readJson(settingsPath);
1746
1769
  if (existingSettings) {
1747
1770
  const backupPath = `${settingsPath}.bak`;
@@ -1758,7 +1781,8 @@ function generateVscodeSettings(preset, opts) {
1758
1781
  }
1759
1782
  function generateVscodeExtensions(preset, opts) {
1760
1783
  if (opts.dryRun) return "created";
1761
- writeJson(`${opts.cwd}/.vscode/extensions.json`, { recommendations: preset.extensions() });
1784
+ const extensions = opts.noStylelint ? preset.extensions().filter((ext) => ext !== STYLELINT_EXTENSION) : preset.extensions();
1785
+ writeJson(`${opts.cwd}/.vscode/extensions.json`, { recommendations: extensions });
1762
1786
  return "created";
1763
1787
  }
1764
1788
  function generateAllVscode(preset, opts) {
@@ -1770,31 +1794,47 @@ function generateAllVscode(preset, opts) {
1770
1794
  if (extAction === "created") result.created.push(".vscode/extensions.json");
1771
1795
  return result;
1772
1796
  }
1797
+ function filterStylelintSettings(settings) {
1798
+ const filtered = Object.fromEntries(
1799
+ Object.entries(settings).filter(
1800
+ ([key]) => !STYLELINT_SETTINGS_PREFIXES.some((prefix) => key.startsWith(prefix))
1801
+ )
1802
+ );
1803
+ if (typeof filtered["editor.codeActionsOnSave"] === "object" && filtered["editor.codeActionsOnSave"] !== null) {
1804
+ const actions = { ...filtered["editor.codeActionsOnSave"] };
1805
+ delete actions["source.fixAll.stylelint"];
1806
+ filtered["editor.codeActionsOnSave"] = actions;
1807
+ }
1808
+ return filtered;
1809
+ }
1773
1810
 
1774
1811
  // src/commands/vscode.ts
1775
1812
  function registerVscodeCommand(program2) {
1776
1813
  const vscode = program2.command("vscode").description("Initialize VSCode config with preset");
1777
- vscode.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--dry-run", "Preview without writing files").action(async (presetName, options) => {
1778
- const preset = resolvePreset(VSCODE_PRESETS, presetName);
1779
- if (!preset) return;
1780
- const cwd = process.cwd();
1781
- const opts = {
1782
- cwd,
1783
- force: options.force ?? false,
1784
- dryRun: options.dryRun ?? false
1785
- };
1786
- const result = generateAllVscode(preset, opts);
1787
- const files = [...result.created, ...result.overwritten];
1788
- if (files.length === 0) {
1789
- logger.warn("No files generated");
1790
- return;
1791
- }
1792
- if (opts.dryRun) {
1793
- logger.log(`[dry-run] Would create ${files.join(", ")}`);
1794
- return;
1814
+ vscode.argument("<preset>").option("-F, --force", "Force overwrite existing files").option("--dry-run", "Preview without writing files").option("--no-stylelint", "Skip Stylelint settings and extension").action(
1815
+ async (presetName, options) => {
1816
+ const preset = resolvePreset(VSCODE_PRESETS, presetName);
1817
+ if (!preset) return;
1818
+ const cwd = process.cwd();
1819
+ const opts = {
1820
+ cwd,
1821
+ force: options.force ?? false,
1822
+ dryRun: options.dryRun ?? false,
1823
+ noStylelint: options.stylelint === false
1824
+ };
1825
+ const result = generateAllVscode(preset, opts);
1826
+ const files = [...result.created, ...result.overwritten];
1827
+ if (files.length === 0) {
1828
+ logger.warn("No files generated");
1829
+ return;
1830
+ }
1831
+ if (opts.dryRun) {
1832
+ logger.log(`[dry-run] Would create ${files.join(", ")}`);
1833
+ return;
1834
+ }
1835
+ logger.log(`Created ${files.join(", ")}`);
1795
1836
  }
1796
- logger.log(`Created ${files.join(", ")}`);
1797
- });
1837
+ );
1798
1838
  vscode.command("list").description("List available vscode presets").action(() => {
1799
1839
  for (const p of VSCODE_PRESETS) {
1800
1840
  console.log(`${p.name.padEnd(12)} ${p.description}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@luxkit/cli",
3
- "version": "1.0.6",
3
+ "version": "1.0.8",
4
4
  "description": "One-click project formatting & VSCode config CLI",
5
5
  "type": "module",
6
6
  "bin": {