@chatbi-v/cli 2.1.10 → 3.0.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/dist/index.js CHANGED
@@ -8,42 +8,171 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js
11
+ // ../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js
12
12
  import path from "path";
13
13
  import { fileURLToPath } from "url";
14
14
  var init_esm_shims = __esm({
15
- "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js"() {
15
+ "../../node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.8_tsx@4.21.0_typescript@5.9.3_yaml@2.8.2/node_modules/tsup/assets/esm_shims.js"() {
16
16
  "use strict";
17
17
  }
18
18
  });
19
19
 
20
- // src/constants.ts
20
+ // package.json
21
+ var package_default;
22
+ var init_package = __esm({
23
+ "package.json"() {
24
+ package_default = {
25
+ name: "@chatbi-v/cli",
26
+ version: "3.0.0",
27
+ description: "Standardized CLI tooling for ChatBI Monorepo",
28
+ type: "module",
29
+ main: "dist/index.js",
30
+ module: "dist/index.js",
31
+ types: "dist/index.d.ts",
32
+ exports: {
33
+ ".": {
34
+ types: "./dist/index.d.ts",
35
+ import: "./dist/index.js"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
39
+ bin: {
40
+ "chatbi-cli": "./bin/chatbi-cli.js"
41
+ },
42
+ files: [
43
+ "dist",
44
+ "bin",
45
+ "templates"
46
+ ],
47
+ publishConfig: {
48
+ access: "public"
49
+ },
50
+ scripts: {
51
+ build: "tsup",
52
+ dev: "tsup --watch",
53
+ test: "vitest"
54
+ },
55
+ dependencies: {
56
+ boxen: "^8.0.1",
57
+ cac: "^6.7.14",
58
+ execa: "^8.0.1",
59
+ "fast-glob": "^3.3.3",
60
+ figlet: "^1.9.4",
61
+ "fs-extra": "^11.2.0",
62
+ "gradient-string": "^3.0.0",
63
+ handlebars: "^4.7.8",
64
+ jiti: "^2.6.1",
65
+ ora: "^7.0.1",
66
+ picocolors: "^1.0.0",
67
+ prompts: "^2.4.2",
68
+ vite: "^5.4.11"
69
+ },
70
+ devDependencies: {
71
+ tsup: "^8.5.1",
72
+ typescript: "^5.0.0",
73
+ "@types/eslint": "^9.6.1",
74
+ "@types/boxen": "^3.0.5",
75
+ "@types/figlet": "^1.7.0",
76
+ "@types/fs-extra": "^11.0.0",
77
+ "@types/gradient-string": "^1.1.6",
78
+ "@types/node": "^20.0.0",
79
+ "@types/prompts": "^2.4.9",
80
+ "@vitest/coverage-v8": "1.6.1",
81
+ vitest: "^1.0.0",
82
+ eslint: "^9.17.0",
83
+ "@chatbi-v/eslint-plugin-theme": "workspace:*"
84
+ }
85
+ };
86
+ }
87
+ });
88
+
89
+ // src/config/defaults.ts
21
90
  import os from "os";
22
91
  import path2 from "path";
23
- var SANDBOX_CONFIG, GLOBAL_PATHS, DEPENDENCY_VERSIONS, DEFAULT_CONFIG;
24
- var init_constants = __esm({
25
- "src/constants.ts"() {
92
+ function loadStringArrayFromEnv(envKey, defaultValue) {
93
+ const envValue = process.env[envKey];
94
+ if (!envValue) return defaultValue;
95
+ return envValue.split(",").map((s) => s.trim()).filter(Boolean);
96
+ }
97
+ function loadStringFromEnv(envKey, defaultValue) {
98
+ const envValue = process.env[envKey];
99
+ return envValue || defaultValue;
100
+ }
101
+ function loadNumberFromEnv(envKey, defaultValue) {
102
+ const envValue = process.env[envKey];
103
+ if (!envValue) return defaultValue;
104
+ const parsed = parseInt(envValue, 10);
105
+ return isNaN(parsed) ? defaultValue : parsed;
106
+ }
107
+ function loadConfig() {
108
+ const sandbox = {
109
+ baseName: loadStringFromEnv("CHATBI_SANDBOX_NAME", DEFAULT_SANDBOX.baseName),
110
+ dirs: {
111
+ versions: loadStringFromEnv("CHATBI_SANDBOX_VERSIONS_DIR", DEFAULT_SANDBOX.dirs.versions),
112
+ current: loadStringFromEnv("CHATBI_SANDBOX_CURRENT_DIR", DEFAULT_SANDBOX.dirs.current),
113
+ cache: loadStringFromEnv("CHATBI_SANDBOX_CACHE_DIR", DEFAULT_SANDBOX.dirs.cache)
114
+ },
115
+ lockFile: loadStringFromEnv("CHATBI_LOCK_FILE", DEFAULT_SANDBOX.lockFile)
116
+ };
117
+ const baseDir = loadStringFromEnv("CHATBI_BASE_DIR", DEFAULT_CACHE.cacheDir);
118
+ const paths = {
119
+ baseDir,
120
+ monorepoRoots: loadStringArrayFromEnv("CHATBI_MONOREPO_ROOTS", DEFAULT_PATHS.monorepoRoots)
121
+ };
122
+ const depsEnv = process.env["CHATBI_DEPENDENCY_VERSIONS"];
123
+ let dependencies;
124
+ if (depsEnv) {
125
+ try {
126
+ dependencies = JSON.parse(depsEnv);
127
+ } catch {
128
+ dependencies = {};
129
+ depsEnv.split(",").forEach((pair) => {
130
+ const [key, value] = pair.split("=");
131
+ if (key && value) dependencies[key.trim()] = value.trim();
132
+ });
133
+ if (Object.keys(dependencies).length === 0) {
134
+ dependencies = DEFAULT_DEPENDENCIES;
135
+ }
136
+ }
137
+ } else {
138
+ dependencies = { ...DEFAULT_DEPENDENCIES };
139
+ }
140
+ const defaults = {
141
+ configFiles: loadStringArrayFromEnv("CHATBI_CONFIG_FILES", DEFAULT_DEFAULTS.configFiles),
142
+ theme: loadStringFromEnv("CHATBI_THEME", DEFAULT_DEFAULTS.theme)
143
+ };
144
+ const runtime = {
145
+ corePackages: loadStringArrayFromEnv("CHATBI_CORE_PACKAGES", DEFAULT_RUNTIME.corePackages),
146
+ runtimeDeps: loadStringArrayFromEnv("CHATBI_RUNTIME_DEPS", DEFAULT_RUNTIME.runtimeDeps)
147
+ };
148
+ const cache = {
149
+ updateCheckInterval: loadNumberFromEnv("CHATBI_UPDATE_INTERVAL", DEFAULT_CACHE.updateCheckInterval),
150
+ cacheDir: loadStringFromEnv("CHATBI_CACHE_DIR", DEFAULT_CACHE.cacheDir),
151
+ cacheFile: path2.join(
152
+ loadStringFromEnv("CHATBI_CACHE_DIR", DEFAULT_CACHE.cacheDir),
153
+ ".update-check.json"
154
+ )
155
+ };
156
+ return { sandbox, paths, dependencies, defaults, runtime, cache };
157
+ }
158
+ var DEFAULT_SANDBOX, DEFAULT_PATHS, DEFAULT_DEPENDENCIES, DEFAULT_DEFAULTS, DEFAULT_RUNTIME, DEFAULT_CACHE;
159
+ var init_defaults = __esm({
160
+ "src/config/defaults.ts"() {
26
161
  "use strict";
27
162
  init_esm_shims();
28
- SANDBOX_CONFIG = {
29
- /** 用户主目录下的沙箱根目录名 */
30
- BASE_NAME: ".chatbi-v-core",
31
- /** 内部子目录结构 */
32
- DIRS: {
33
- VERSIONS: "versions",
34
- CURRENT: "current",
35
- CACHE: ".chatbi"
163
+ DEFAULT_SANDBOX = {
164
+ baseName: ".chatbi-v-core",
165
+ dirs: {
166
+ versions: "versions",
167
+ current: "current",
168
+ cache: ".chatbi"
36
169
  },
37
- /** 关键标识文件 */
38
- LOCK_FILE: ".chatbi-version"
170
+ lockFile: ".chatbi-version"
39
171
  };
40
- GLOBAL_PATHS = {
41
- /** 沙箱根路径 */
42
- BASE_DIR: path2.join(os.homedir(), SANDBOX_CONFIG.BASE_NAME),
43
- /** Monorepo 扫描目录 */
44
- MONOREPO_ROOTS: ["apps", "plugins", "packages"]
172
+ DEFAULT_PATHS = {
173
+ monorepoRoots: ["apps", "plugins", "packages"]
45
174
  };
46
- DEPENDENCY_VERSIONS = {
175
+ DEFAULT_DEPENDENCIES = {
47
176
  // 基础框架
48
177
  "react": "^18.3.1",
49
178
  "react-dom": "^18.3.1",
@@ -61,41 +190,82 @@ var init_constants = __esm({
61
190
  "@types/node": "^20.11.20",
62
191
  "@vitejs/plugin-react": "^4.2.1"
63
192
  };
64
- DEFAULT_CONFIG = {
65
- /** 支持的配置文件名 */
66
- CONFIG_FILES: [
193
+ DEFAULT_DEFAULTS = {
194
+ configFiles: [
67
195
  "chatbi.config.ts",
68
196
  "chatbi.config.js",
69
197
  "chatbi.config.json",
70
198
  ".chatbirc"
71
199
  ],
72
- /** 默认 UI 主题 */
73
- THEME: "standard"
200
+ theme: "standard"
201
+ };
202
+ DEFAULT_RUNTIME = {
203
+ corePackages: [
204
+ "@chatbi-v/core",
205
+ "@chatbi-v/mocks",
206
+ "@chatbi-v/config"
207
+ ],
208
+ runtimeDeps: [
209
+ "@ant-design/x",
210
+ "@ant-design/icons",
211
+ "antd",
212
+ "react",
213
+ "react-dom",
214
+ "lucide-react",
215
+ "framer-motion",
216
+ "clsx",
217
+ "tailwind-merge",
218
+ "react-router-dom",
219
+ "zustand",
220
+ "axios",
221
+ "less",
222
+ "vite"
223
+ ]
224
+ };
225
+ DEFAULT_CACHE = {
226
+ updateCheckInterval: 1e3 * 60 * 60 * 24,
227
+ // 24 hours
228
+ cacheDir: path2.join(os.homedir(), ".chatbi-v-core"),
229
+ cacheFile: path2.join(os.homedir(), ".chatbi-v-core", ".update-check.json")
74
230
  };
75
231
  }
76
232
  });
77
233
 
234
+ // src/config/index.ts
235
+ var init_config = __esm({
236
+ "src/config/index.ts"() {
237
+ "use strict";
238
+ init_esm_shims();
239
+ init_defaults();
240
+ }
241
+ });
242
+
78
243
  // src/utils.ts
79
244
  import boxen from "boxen";
80
245
  import { execa } from "execa";
81
246
  import fs from "fs-extra";
82
247
  import { createRequire } from "module";
83
- import os2 from "os";
84
248
  import ora from "ora";
85
249
  import path3 from "path";
86
250
  import pc from "picocolors";
87
251
  import { fileURLToPath as fileURLToPath2 } from "url";
88
- var _require, _filename, _dirname, UPDATE_CHECK_INTERVAL, CACHE_DIR, CACHE_FILE, logger, createSpinner, printBox, findPackageRoot, getCliRoot, checkForUpdates, printUpdateNotification;
252
+ var _require, _filename, _dirname, config, UPDATE_CHECK_INTERVAL, CACHE_DIR, CACHE_FILE, isDebug, setDebugMode, logger, createSpinner, printBox, findPackageRoot, getCliRoot, checkForUpdates, printUpdateNotification;
89
253
  var init_utils = __esm({
90
254
  "src/utils.ts"() {
91
255
  "use strict";
92
256
  init_esm_shims();
257
+ init_config();
93
258
  _require = createRequire(import.meta.url);
94
259
  _filename = fileURLToPath2(import.meta.url);
95
260
  _dirname = path3.dirname(_filename);
96
- UPDATE_CHECK_INTERVAL = 1e3 * 60 * 60 * 24;
97
- CACHE_DIR = path3.join(os2.homedir(), ".chatbi-v-core");
98
- CACHE_FILE = path3.join(CACHE_DIR, ".update-check.json");
261
+ config = loadConfig();
262
+ UPDATE_CHECK_INTERVAL = config.cache.updateCheckInterval;
263
+ CACHE_DIR = config.cache.cacheDir;
264
+ CACHE_FILE = config.cache.cacheFile;
265
+ isDebug = false;
266
+ setDebugMode = (debug) => {
267
+ isDebug = debug;
268
+ };
99
269
  logger = {
100
270
  info: (msg) => console.log(pc.cyan(`\u2139 ${msg}`)),
101
271
  success: (msg) => console.log(pc.green(`\u2714 ${msg}`)),
@@ -111,6 +281,11 @@ var init_utils = __esm({
111
281
  }
112
282
  }
113
283
  },
284
+ debug: (msg) => {
285
+ if (isDebug) {
286
+ console.log(pc.gray(`[DEBUG] ${msg}`));
287
+ }
288
+ },
114
289
  bold: (msg) => pc.bold(msg),
115
290
  cyan: (msg) => pc.cyan(msg),
116
291
  green: (msg) => pc.green(msg),
@@ -120,7 +295,9 @@ var init_utils = __esm({
120
295
  };
121
296
  createSpinner = (msg) => ora({
122
297
  text: pc.cyan(msg),
123
- color: "cyan"
298
+ color: "cyan",
299
+ isEnabled: !isDebug
300
+ // Debug 模式下禁用 spinner 以避免日志混乱
124
301
  });
125
302
  printBox = (msg, title, options = {}) => {
126
303
  console.log("\n" + boxen(msg, {
@@ -136,7 +313,7 @@ var init_utils = __esm({
136
313
  try {
137
314
  const pkgPath = _require.resolve(`${pkgName}/package.json`);
138
315
  return path3.dirname(pkgPath);
139
- } catch (e) {
316
+ } catch {
140
317
  if (pkgName === "@chatbi-v/cli") {
141
318
  return path3.resolve(_dirname, "../../");
142
319
  }
@@ -170,7 +347,9 @@ var init_utils = __esm({
170
347
  }
171
348
  const now = Date.now();
172
349
  if (now - cache.lastCheck > UPDATE_CHECK_INTERVAL) {
173
- execa("npm", ["view", "@chatbi-v/cli", "version"]).then(async ({ stdout }) => {
350
+ const subprocess = execa("npm", ["view", "@chatbi-v/cli", "version"]);
351
+ subprocess.unref();
352
+ subprocess.then(async ({ stdout }) => {
174
353
  const latest = stdout.trim();
175
354
  await fs.writeJson(CACHE_FILE, {
176
355
  lastCheck: now,
@@ -185,7 +364,7 @@ var init_utils = __esm({
185
364
  return cache.latestVersion;
186
365
  }
187
366
  }
188
- } catch (e) {
367
+ } catch {
189
368
  }
190
369
  return null;
191
370
  };
@@ -205,12 +384,48 @@ var init_utils = __esm({
205
384
  }
206
385
  });
207
386
 
387
+ // src/constants.ts
388
+ var config2, SANDBOX_CONFIG, GLOBAL_PATHS, DEPENDENCY_VERSIONS, DEFAULT_CONFIG;
389
+ var init_constants = __esm({
390
+ "src/constants.ts"() {
391
+ "use strict";
392
+ init_esm_shims();
393
+ init_config();
394
+ config2 = loadConfig();
395
+ SANDBOX_CONFIG = {
396
+ /** 用户主目录下的沙箱根目录名 */
397
+ BASE_NAME: config2.sandbox.baseName,
398
+ /** 内部子目录结构 */
399
+ DIRS: {
400
+ VERSIONS: config2.sandbox.dirs.versions,
401
+ CURRENT: config2.sandbox.dirs.current,
402
+ CACHE: config2.sandbox.dirs.cache
403
+ },
404
+ /** 关键标识文件 */
405
+ LOCK_FILE: config2.sandbox.lockFile
406
+ };
407
+ GLOBAL_PATHS = {
408
+ /** 沙箱根路径 */
409
+ BASE_DIR: config2.paths.baseDir,
410
+ /** Monorepo 扫描目录 */
411
+ MONOREPO_ROOTS: config2.paths.monorepoRoots
412
+ };
413
+ DEPENDENCY_VERSIONS = config2.dependencies;
414
+ DEFAULT_CONFIG = {
415
+ /** 支持的配置文件名 */
416
+ CONFIG_FILES: config2.defaults.configFiles,
417
+ /** 默认 UI 主题 */
418
+ THEME: config2.defaults.theme
419
+ };
420
+ }
421
+ });
422
+
208
423
  // src/config.ts
209
424
  import fs2 from "fs-extra";
210
425
  import { createJiti } from "jiti";
211
426
  import path4 from "path";
212
427
  var ConfigManager;
213
- var init_config = __esm({
428
+ var init_config2 = __esm({
214
429
  "src/config.ts"() {
215
430
  "use strict";
216
431
  init_esm_shims();
@@ -218,55 +433,66 @@ var init_config = __esm({
218
433
  init_utils();
219
434
  init_utils();
220
435
  ConfigManager = class {
221
- static {
222
- this.CONFIG_FILES = DEFAULT_CONFIG.CONFIG_FILES;
223
- }
436
+ static CONFIG_FILES = DEFAULT_CONFIG.CONFIG_FILES;
224
437
  /**
225
438
  * 加载项目配置
439
+ * 优先级(从低到高): 配置文件 < .chatbi-version < 环境变量
226
440
  * @param cwd 项目根目录
227
441
  */
228
442
  static async loadConfig(cwd = process.cwd()) {
229
- const config = {};
443
+ if (!fs2.existsSync(cwd)) {
444
+ logger.warn(`\u9879\u76EE\u76EE\u5F55\u4E0D\u5B58\u5728: ${cwd}\uFF0C\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E`);
445
+ return {};
446
+ }
447
+ const config4 = {};
230
448
  const versionFilePath = path4.join(cwd, SANDBOX_CONFIG.LOCK_FILE);
231
449
  if (fs2.existsSync(versionFilePath)) {
232
450
  try {
233
451
  const version = (await fs2.readFile(versionFilePath, "utf-8")).trim();
234
452
  if (version) {
235
- config.coreVersion = version;
453
+ config4.coreVersion = version;
236
454
  }
237
- } catch (e) {
455
+ } catch {
238
456
  }
239
457
  }
240
458
  const jiti = createJiti(cwd);
459
+ let projectConfig = {};
241
460
  for (const file of this.CONFIG_FILES) {
242
461
  const configPath = path4.join(cwd, file);
243
462
  if (fs2.existsSync(configPath)) {
244
463
  try {
245
- let projectConfig = {};
246
464
  if (file.endsWith(".ts") || file.endsWith(".js")) {
247
465
  const mod = await jiti.import(configPath, { default: true });
248
466
  projectConfig = mod.default || mod || {};
249
467
  } else if (file.endsWith(".json") || file.startsWith(".chatbirc")) {
250
468
  projectConfig = await fs2.readJson(configPath);
251
469
  }
252
- return {
253
- ...projectConfig,
254
- ...config
255
- };
256
- } catch (e) {
257
- logger.error(`\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25`, e);
470
+ break;
471
+ } catch {
472
+ logger.error(`\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25`);
258
473
  }
259
474
  }
260
475
  }
261
- return config;
476
+ const envConfig = {};
477
+ if (process.env.CHATBI_CORE_VERSION) {
478
+ envConfig.coreVersion = process.env.CHATBI_CORE_VERSION;
479
+ }
480
+ if (process.env.CHATBI_CORE_SOURCE === "npm" || process.env.CHATBI_CORE_SOURCE === "local") {
481
+ envConfig.coreSource = process.env.CHATBI_CORE_SOURCE;
482
+ }
483
+ return {
484
+ ...projectConfig,
485
+ ...config4,
486
+ ...envConfig
487
+ };
262
488
  }
263
489
  /**
264
490
  * 解析核心依赖的具体路径或版本号
265
491
  * @param config 项目配置
266
492
  * @param relativeTo 相对路径(用于 local 模式下的 file: 协议生成)
267
493
  */
268
- static async resolveCoreDependency(config, relativeTo = ".") {
269
- const { coreSource = "local", coreVersion } = config;
494
+ static async resolveCoreDependency(config4, relativeTo = ".") {
495
+ const { coreSource = "local", coreVersion } = config4;
270
496
  if (coreSource === "npm") {
271
497
  if (coreVersion) return coreVersion;
272
498
  const cliRoot = await getCliRoot();
@@ -315,7 +541,7 @@ var init_config = __esm({
315
541
  if (pkg.tsup) {
316
542
  return pkg.tsup;
317
543
  }
318
- } catch (e) {
544
+ } catch {
319
545
  }
320
546
  }
321
547
  return {};
@@ -324,119 +550,9 @@ var init_config = __esm({
324
550
  }
325
551
  });
326
552
 
327
- // src/sandbox/SandboxRenderer.ts
553
+ // src/sandbox/SandboxPath.ts
328
554
  import fs3 from "fs-extra";
329
- import Handlebars from "handlebars";
330
555
  import path5 from "path";
331
- var SandboxRenderer;
332
- var init_SandboxRenderer = __esm({
333
- "src/sandbox/SandboxRenderer.ts"() {
334
- "use strict";
335
- init_esm_shims();
336
- Handlebars.registerHelper("json", (obj) => JSON.stringify(obj, null, 2));
337
- Handlebars.registerHelper("eq", (a, b) => a === b);
338
- SandboxRenderer = class {
339
- static {
340
- /**
341
- * 需要转义的模板关键字列表
342
- * 只有匹配这些关键字的 {{ }} 才会被 Handlebars 处理,其余(如 React 的 {{ style }})将被转义跳过
343
- */
344
- this.TEMPLATE_KEYWORDS = [
345
- "name",
346
- "version",
347
- "projectName",
348
- "projectTitle",
349
- "projectVersion",
350
- "cliVersion",
351
- "tsconfigPath",
352
- "theme",
353
- "isNebula",
354
- "isGlass",
355
- "isBusiness",
356
- "isApp",
357
- "isShell",
358
- "pluginName",
359
- "pluginPackageName",
360
- "pluginVersion",
361
- "pluginDisplayName",
362
- "pluginDescription",
363
- "pluginClassName",
364
- "pluginPath",
365
- "pluginFolderName",
366
- "pluginType",
367
- "pluginId",
368
- "className",
369
- "dependencies",
370
- "devDependencies",
371
- "json",
372
- "if",
373
- "else",
374
- "unless",
375
- "each",
376
- "with",
377
- "log",
378
- "lookup"
379
- ];
380
- }
381
- /**
382
- * 递归渲染目录模板
383
- * @param srcDir 模板源目录
384
- * @param destDir 目标输出目录
385
- * @param data 渲染模板所需的变量上下文
386
- */
387
- static async renderDirectory(srcDir, destDir, data) {
388
- if (!srcDir || !destDir || !fs3.existsSync(srcDir)) return;
389
- const entries = await fs3.readdir(srcDir, { withFileTypes: true });
390
- for (const entry of entries) {
391
- const srcPath = path5.join(srcDir, entry.name);
392
- const destPath = path5.join(destDir, entry.name.replace(/\.hbs$/, ""));
393
- if (entry.isDirectory()) {
394
- await fs3.ensureDir(destPath);
395
- await this.renderDirectory(srcPath, destPath, data);
396
- } else {
397
- await this.renderFile(srcPath, destPath, data);
398
- }
399
- }
400
- }
401
- /**
402
- * 渲染单个文件
403
- */
404
- static async renderFile(srcPath, destPath, data) {
405
- const isTemplate = srcPath.endsWith(".hbs");
406
- if (!isTemplate) {
407
- await fs3.copy(srcPath, destPath);
408
- return;
409
- }
410
- const content = await fs3.readFile(srcPath, "utf-8");
411
- if (!content.includes("{{")) {
412
- await fs3.outputFile(destPath, content);
413
- return;
414
- }
415
- try {
416
- const keywordsPattern = this.TEMPLATE_KEYWORDS.join("|");
417
- const safeContent = content.replace(
418
- new RegExp(`\\{\\{(?!\\{)(?!\\s*([#/]?(?:${keywordsPattern}))\\b)`, "g"),
419
- "\\{{"
420
- );
421
- const template = Handlebars.compile(safeContent);
422
- const result = template(data);
423
- await fs3.outputFile(destPath, result);
424
- } catch (e) {
425
- let result = content;
426
- for (const [key, val] of Object.entries(data)) {
427
- const regex = new RegExp(`\\{\\{\\s*${key}\\s*\\}\\}`, "g");
428
- result = result.replace(regex, typeof val === "object" ? JSON.stringify(val) : String(val));
429
- }
430
- await fs3.outputFile(destPath, result);
431
- }
432
- }
433
- };
434
- }
435
- });
436
-
437
- // src/sandbox/SandboxPath.ts
438
- import fs5 from "fs-extra";
439
- import path7 from "path";
440
556
  var SandboxPath;
441
557
  var init_SandboxPath = __esm({
442
558
  "src/sandbox/SandboxPath.ts"() {
@@ -444,12 +560,10 @@ var init_SandboxPath = __esm({
444
560
  init_esm_shims();
445
561
  init_constants();
446
562
  SandboxPath = class {
447
- static {
448
- /**
449
- * 沙箱的基础存储目录,通常位于用户主目录下的 .chatbi-v-core
450
- */
451
- this.BASE_DIR = GLOBAL_PATHS.BASE_DIR;
452
- }
563
+ /**
564
+ * 沙箱的基础存储目录,通常位于用户主目录下的 .chatbi-v-core
565
+ */
566
+ static BASE_DIR = GLOBAL_PATHS.BASE_DIR;
453
567
  /**
454
568
  * 获取沙箱根目录
455
569
  * @returns 沙箱根目录的绝对路径
@@ -462,7 +576,7 @@ var init_SandboxPath = __esm({
462
576
  * @returns versions 目录的绝对路径
463
577
  */
464
578
  static getVersionRoot() {
465
- return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS);
579
+ return path5.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS);
466
580
  }
467
581
  /**
468
582
  * 获取指定版本的沙箱路径
@@ -471,9 +585,9 @@ var init_SandboxPath = __esm({
471
585
  */
472
586
  static getVersionPath(version) {
473
587
  if (version === SANDBOX_CONFIG.DIRS.CURRENT) {
474
- return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, SANDBOX_CONFIG.DIRS.CURRENT);
588
+ return path5.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, SANDBOX_CONFIG.DIRS.CURRENT);
475
589
  }
476
- return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, version);
590
+ return path5.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, version);
477
591
  }
478
592
  /**
479
593
  * 递归向上查找工作区根目录
@@ -484,19 +598,19 @@ var init_SandboxPath = __esm({
484
598
  static async getWorkspaceRoot(cwd) {
485
599
  if (!cwd) return cwd;
486
600
  if (cwd.startsWith("/mock")) return cwd;
487
- let current = path7.resolve(cwd);
488
- while (current !== path7.parse(current).root) {
489
- const pkgPath = path7.join(current, "package.json");
490
- const pnpmWorkspacePath = path7.join(current, "pnpm-workspace.yaml");
491
- if (fs5.existsSync(pnpmWorkspacePath)) return current;
492
- if (fs5.existsSync(pkgPath)) {
601
+ let current = path5.resolve(cwd);
602
+ while (current !== path5.parse(current).root) {
603
+ const pkgPath = path5.join(current, "package.json");
604
+ const pnpmWorkspacePath = path5.join(current, "pnpm-workspace.yaml");
605
+ if (fs3.existsSync(pnpmWorkspacePath)) return current;
606
+ if (fs3.existsSync(pkgPath)) {
493
607
  try {
494
- const pkg = await fs5.readJson(pkgPath);
608
+ const pkg = await fs3.readJson(pkgPath);
495
609
  if (pkg.workspaces) return current;
496
- } catch (e) {
610
+ } catch {
497
611
  }
498
612
  }
499
- current = path7.dirname(current);
613
+ current = path5.dirname(current);
500
614
  }
501
615
  return cwd;
502
616
  }
@@ -505,8 +619,8 @@ var init_SandboxPath = __esm({
505
619
  });
506
620
 
507
621
  // src/sandbox/SandboxContext.ts
508
- import fs6 from "fs-extra";
509
- import path8 from "path";
622
+ import fs4 from "fs-extra";
623
+ import path6 from "path";
510
624
  var SandboxContext;
511
625
  var init_SandboxContext = __esm({
512
626
  "src/sandbox/SandboxContext.ts"() {
@@ -517,11 +631,11 @@ var init_SandboxContext = __esm({
517
631
  SandboxContext = class {
518
632
  /**
519
633
  * 注入项目虚拟上下文
520
- * 包括:
521
- * 1. 确定集中式 .chatbi 存放位置并处理子包软链
522
- * 2. 生成适配沙箱的 tsconfig.json (配置路径别名)
523
- * 3. 软链接沙箱的 node_modules 到项目 .chatbi 目录下
524
- * 4. 确保 .chatbi 被加入 .gitignore
634
+ * 策略:
635
+ * 1. 总是优先在 Workspace Root (Monorepo 根目录) 生成 .chatbi
636
+ * 2. 如果当前项目就是 Workspace Root,则直接生成
637
+ * 3. 如果当前项目是子包 (Sub-package),则不生成 .chatbi,而是依赖根目录的配置
638
+ * (需要确保子包的 tsconfig extends 了根目录的 tsconfig .chatbi/tsconfig.json)
525
639
  *
526
640
  * @param projectRoot 当前项目根目录
527
641
  * @param version 内核版本号
@@ -530,52 +644,92 @@ var init_SandboxContext = __esm({
530
644
  */
531
645
  static async inject(projectRoot, version, corePackages, runtimeDeps) {
532
646
  const workspaceRoot = await SandboxPath.getWorkspaceRoot(projectRoot);
533
- if (!workspaceRoot) {
534
- const chatbiDir2 = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
535
- await fs6.ensureDir(chatbiDir2);
536
- return this.injectToDir(chatbiDir2, version, corePackages, runtimeDeps);
537
- }
538
- const chatbiDir = path8.join(workspaceRoot, SANDBOX_CONFIG.DIRS.CACHE);
539
- await fs6.ensureDir(chatbiDir);
540
- if (workspaceRoot !== projectRoot) {
541
- const localChatbi = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
647
+ const targetRoot = workspaceRoot || projectRoot;
648
+ const chatbiDir = path6.join(targetRoot, SANDBOX_CONFIG.DIRS.CACHE);
649
+ await fs4.ensureDir(chatbiDir);
650
+ if (projectRoot !== targetRoot) {
651
+ const localChatbiDir = path6.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
652
+ if (fs4.existsSync(localChatbiDir)) {
653
+ await fs4.remove(localChatbiDir);
654
+ }
655
+ await this.fixTsConfigExtends(projectRoot, targetRoot);
656
+ await this.ensureGitignore(targetRoot);
657
+ return this.injectToDir(chatbiDir, version, corePackages, runtimeDeps);
658
+ }
659
+ await this.ensureGitignore(targetRoot);
660
+ await this.ensureVSCodeSettings(targetRoot, version);
661
+ return this.injectToDir(chatbiDir, version, corePackages, runtimeDeps);
662
+ }
663
+ /**
664
+ * 确保 .vscode/settings.json 存在并配置了 typescript.tsdk
665
+ */
666
+ static async ensureVSCodeSettings(root, version) {
667
+ const vscodeDir = path6.join(root, ".vscode");
668
+ await fs4.ensureDir(vscodeDir);
669
+ const settingsPath = path6.join(vscodeDir, "settings.json");
670
+ let settings = {};
671
+ if (fs4.existsSync(settingsPath)) {
542
672
  try {
543
- const stats = await fs6.lstat(localChatbi).catch(() => null);
544
- if (stats) {
545
- if (stats.isSymbolicLink()) {
546
- const linkTarget = await fs6.readlink(localChatbi);
547
- if (linkTarget !== chatbiDir) {
548
- await fs6.remove(localChatbi);
549
- await fs6.symlink(chatbiDir, localChatbi, "dir");
550
- }
551
- } else {
552
- await fs6.remove(localChatbi);
553
- await fs6.symlink(chatbiDir, localChatbi, "dir");
554
- }
555
- } else {
556
- await fs6.symlink(chatbiDir, localChatbi, "dir");
673
+ settings = await fs4.readJson(settingsPath);
674
+ } catch {
675
+ }
676
+ }
677
+ const sandboxPath = SandboxPath.getVersionPath(version);
678
+ const tsdkPath = path6.join(sandboxPath, "node_modules/typescript/lib");
679
+ settings["typescript.tsdk"] = tsdkPath;
680
+ settings["typescript.enablePromptUseWorkspaceTsdk"] = true;
681
+ await fs4.writeJson(settingsPath, settings, { spaces: 2 });
682
+ }
683
+ /**
684
+ * 修复 tsconfig.json 的 extends 配置
685
+ * 确保它指向 Workspace Root 的 .chatbi/tsconfig.json
686
+ */
687
+ static async fixTsConfigExtends(projectRoot, workspaceRoot) {
688
+ const tsConfigPath = path6.join(projectRoot, "tsconfig.json");
689
+ if (!fs4.existsSync(tsConfigPath)) return;
690
+ try {
691
+ const tsConfig = await fs4.readJson(tsConfigPath);
692
+ let extendsTarget = path6.relative(projectRoot, path6.join(workspaceRoot, ".chatbi/tsconfig.json"));
693
+ if (!extendsTarget.startsWith(".")) extendsTarget = `./${extendsTarget}`;
694
+ const hasExtend = (p) => p.includes(".chatbi/tsconfig.json") || p.includes(".chatbi/tsconfig.paths.json");
695
+ if (Array.isArray(tsConfig.extends)) {
696
+ if (!tsConfig.extends.some((p) => hasExtend(p))) {
697
+ tsConfig.extends.push(extendsTarget);
698
+ await fs4.writeJson(tsConfigPath, tsConfig, { spaces: 2 });
699
+ }
700
+ } else if (typeof tsConfig.extends === "string") {
701
+ if (!hasExtend(tsConfig.extends)) {
702
+ tsConfig.extends = [tsConfig.extends, extendsTarget];
703
+ await fs4.writeJson(tsConfigPath, tsConfig, { spaces: 2 });
557
704
  }
558
- } catch (e) {
705
+ } else {
706
+ tsConfig.extends = extendsTarget;
707
+ await fs4.writeJson(tsConfigPath, tsConfig, { spaces: 2 });
559
708
  }
709
+ } catch (e) {
560
710
  }
561
- const gitignorePath = path8.join(workspaceRoot, ".gitignore");
562
- if (fs6.existsSync(gitignorePath)) {
563
- let content = await fs6.readFile(gitignorePath, "utf-8");
711
+ }
712
+ /**
713
+ * 确保 .gitignore 包含 .chatbi
714
+ */
715
+ static async ensureGitignore(root) {
716
+ const gitignorePath = path6.join(root, ".gitignore");
717
+ if (fs4.existsSync(gitignorePath)) {
718
+ let content = await fs4.readFile(gitignorePath, "utf-8");
564
719
  if (!content.includes(SANDBOX_CONFIG.DIRS.CACHE)) {
565
- await fs6.appendFile(gitignorePath, `
720
+ await fs4.appendFile(gitignorePath, `
566
721
  # ChatBI
567
722
  ${SANDBOX_CONFIG.DIRS.CACHE}
568
723
  `);
569
724
  }
570
725
  }
571
- return this.injectToDir(chatbiDir, version, corePackages, runtimeDeps);
572
726
  }
573
727
  /**
574
728
  * 内部注入逻辑:向指定的 .chatbi 目录写入配置
575
729
  */
576
730
  static async injectToDir(chatbiDir, version, corePackages, runtimeDeps) {
577
731
  const versionPath = SandboxPath.getVersionPath(version);
578
- const sandboxNodeModules = path8.join(versionPath, "node_modules");
732
+ const sandboxNodeModules = path6.join(versionPath, "node_modules");
579
733
  const corePaths = {};
580
734
  for (const pkgName of corePackages) {
581
735
  corePaths[pkgName] = [`./node_modules/${pkgName}`];
@@ -591,56 +745,146 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
591
745
  }
592
746
  }
593
747
  corePaths["@types/*"] = ["./node_modules/@types/*"];
748
+ corePaths["*"] = ["./node_modules/*"];
594
749
  corePaths["vite/client"] = ["./node_modules/vite/client.d.ts"];
595
- const baseConfigPath = path8.join(sandboxNodeModules, "@chatbi-v/config/base.json");
750
+ const baseConfigPath = path6.join(sandboxNodeModules, "@chatbi-v/config/base.json");
596
751
  const tsConfig = {
597
752
  extends: baseConfigPath,
598
753
  compilerOptions: {
599
754
  baseUrl: ".",
755
+ // 使用 node 还是 bundler ?
756
+ // 现代项目推荐 bundler,但为了兼容性,特别是为了让 IDE 能够像 Node 一样查找依赖
600
757
  moduleResolution: "bundler",
601
758
  skipLibCheck: true,
602
- typeRoots: ["./node_modules/@types"],
759
+ // 显式指定 typeRoots,确保 IDE 优先查找沙箱的 types
760
+ typeRoots: ["./node_modules/@types", "./node_modules"],
603
761
  preserveSymlinks: true,
604
762
  paths: {
605
763
  ...corePaths,
606
- "@/*": ["../src/*"],
607
- "*": ["./node_modules/*"]
764
+ // 修改: 适配 Monorepo 根目录结构
765
+ // 在根目录时,src 应该指向具体的 apps/xxx/src 或 packages/xxx/src
766
+ // 但这里主要用于沙箱环境的类型解析,"@/*" 的映射可能需要在具体项目的 tsconfig 中覆盖
767
+ "@/*": ["./src/*"]
768
+ // "*": ["./node_modules/*"] // 已经在上面添加了 corePaths['*']
608
769
  }
609
770
  }
610
771
  };
611
- await fs6.writeJson(path8.join(chatbiDir, "tsconfig.json"), tsConfig, { spaces: 2 });
612
- await fs6.writeJson(path8.join(chatbiDir, "tsconfig.paths.json"), { compilerOptions: tsConfig.compilerOptions }, { spaces: 2 });
613
- const virtualNodeModules = path8.join(chatbiDir, "node_modules");
614
- if (fs6.existsSync(sandboxNodeModules)) {
772
+ await fs4.writeJson(path6.join(chatbiDir, "tsconfig.json"), tsConfig, { spaces: 2 });
773
+ await fs4.writeJson(path6.join(chatbiDir, "tsconfig.paths.json"), { compilerOptions: tsConfig.compilerOptions }, { spaces: 2 });
774
+ const virtualNodeModules = path6.join(chatbiDir, "node_modules");
775
+ if (fs4.existsSync(sandboxNodeModules)) {
615
776
  try {
616
- const stats = await fs6.lstat(virtualNodeModules).catch(() => null);
777
+ const stats = await fs4.lstat(virtualNodeModules).catch(() => null);
617
778
  if (stats) {
618
779
  if (stats.isSymbolicLink()) {
619
- const linkTarget = await fs6.readlink(virtualNodeModules);
780
+ const linkTarget = await fs4.readlink(virtualNodeModules);
620
781
  if (linkTarget !== sandboxNodeModules) {
621
- await fs6.remove(virtualNodeModules);
622
- await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
782
+ await fs4.remove(virtualNodeModules);
783
+ await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
623
784
  }
624
785
  } else {
625
- await fs6.remove(virtualNodeModules);
626
- await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
786
+ await fs4.remove(virtualNodeModules);
787
+ await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
627
788
  }
628
789
  } else {
629
- await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
790
+ await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
791
+ }
792
+ } catch {
793
+ }
794
+ }
795
+ }
796
+ };
797
+ }
798
+ });
799
+
800
+ // src/sandbox/WorkspaceResolver.ts
801
+ import { execa as execa2 } from "execa";
802
+ import fs5 from "fs-extra";
803
+ import path7 from "path";
804
+ var WorkspaceResolver;
805
+ var init_WorkspaceResolver = __esm({
806
+ "src/sandbox/WorkspaceResolver.ts"() {
807
+ "use strict";
808
+ init_esm_shims();
809
+ init_utils();
810
+ WorkspaceResolver = class {
811
+ /**
812
+ * 解析工作区中的所有包
813
+ * @param workspaceRoot 工作区根目录
814
+ * @returns 包名到绝对路径的映射
815
+ */
816
+ static async resolvePackages(workspaceRoot) {
817
+ const packages = {};
818
+ try {
819
+ const { stdout } = await execa2("pnpm", ["m", "ls", "--json", "--depth", "-1"], {
820
+ cwd: workspaceRoot,
821
+ reject: false
822
+ });
823
+ try {
824
+ const pnpmPackages = JSON.parse(stdout);
825
+ if (Array.isArray(pnpmPackages)) {
826
+ for (const pkg of pnpmPackages) {
827
+ if (pkg.name && pkg.path) {
828
+ packages[pkg.name] = pkg.path;
829
+ }
830
+ }
831
+ if (Object.keys(packages).length > 0) {
832
+ return packages;
833
+ }
834
+ }
835
+ } catch {
836
+ }
837
+ } catch (e) {
838
+ logger.warn(`pnpm \u89E3\u6790\u5931\u8D25: ${e.message}\uFF0C\u5C1D\u8BD5\u964D\u7EA7\u65B9\u6848...`);
839
+ }
840
+ try {
841
+ const workspaceYamlPath = path7.join(workspaceRoot, "pnpm-workspace.yaml");
842
+ let patterns = ["packages/*"];
843
+ if (fs5.existsSync(workspaceYamlPath)) {
844
+ const content = await fs5.readFile(workspaceYamlPath, "utf-8");
845
+ const match = content.match(/packages:\s*([\s\S]*?)(?:\n\S|$)/);
846
+ if (match && match[1]) {
847
+ const lines = match[1].split("\n").map((l) => l.trim()).filter((l) => l.startsWith("-")).map((l) => l.replace(/^-\s*['"]?|['"]?$/g, ""));
848
+ if (lines.length > 0) patterns = lines;
849
+ }
850
+ } else {
851
+ const pkgJsonPath = path7.join(workspaceRoot, "package.json");
852
+ if (fs5.existsSync(pkgJsonPath)) {
853
+ const pkg = await fs5.readJson(pkgJsonPath);
854
+ if (Array.isArray(pkg.workspaces)) {
855
+ patterns = pkg.workspaces;
856
+ }
857
+ }
858
+ }
859
+ const globPatterns = patterns.map((p) => path7.join(p, "package.json"));
860
+ const { default: fg3 } = await import("fast-glob");
861
+ const pkgJsonFiles = await fg3(globPatterns, {
862
+ cwd: workspaceRoot,
863
+ absolute: true,
864
+ ignore: ["**/node_modules/**", "**/dist/**"]
865
+ });
866
+ for (const file of pkgJsonFiles) {
867
+ try {
868
+ const pkg = await fs5.readJson(file);
869
+ if (pkg.name) {
870
+ packages[pkg.name] = path7.dirname(file);
871
+ }
872
+ } catch {
630
873
  }
631
- } catch (e) {
632
874
  }
875
+ } catch (e) {
876
+ logger.warn(`\u5DE5\u4F5C\u533A\u626B\u63CF\u5931\u8D25: ${e.message}`);
633
877
  }
878
+ return packages;
634
879
  }
635
880
  };
636
881
  }
637
882
  });
638
883
 
639
884
  // src/sandbox/SandboxPkgManager.ts
640
- import fg from "fast-glob";
641
- import fs7 from "fs-extra";
642
- import path9 from "path";
643
- import pc3 from "picocolors";
885
+ import fs6 from "fs-extra";
886
+ import path8 from "path";
887
+ import pc2 from "picocolors";
644
888
  var SandboxPkgManager;
645
889
  var init_SandboxPkgManager = __esm({
646
890
  "src/sandbox/SandboxPkgManager.ts"() {
@@ -648,6 +892,7 @@ var init_SandboxPkgManager = __esm({
648
892
  init_esm_shims();
649
893
  init_utils();
650
894
  init_SandboxPath();
895
+ init_WorkspaceResolver();
651
896
  SandboxPkgManager = class {
652
897
  /**
653
898
  * 尝试将本地开发环境的包 Link 到沙箱中 (模拟安装)
@@ -661,52 +906,36 @@ var init_SandboxPkgManager = __esm({
661
906
  try {
662
907
  const cliRoot = await getCliRoot();
663
908
  const projectRoot = await SandboxPath.getWorkspaceRoot(cliRoot);
664
- if (projectRoot === cliRoot && !fs7.existsSync(path9.join(projectRoot, "pnpm-workspace.yaml"))) {
909
+ if (projectRoot === cliRoot && !fs6.existsSync(path8.join(projectRoot, "pnpm-workspace.yaml"))) {
665
910
  return false;
666
911
  }
667
- const possiblePackagesDirs = [
668
- path9.join(projectRoot, "packages"),
669
- // 兼容旧版或其他可能的路径结构
670
- path9.resolve(projectRoot, "../chatbi-v/packages")
671
- ];
912
+ const allLocalPackages = await WorkspaceResolver.resolvePackages(projectRoot);
672
913
  const localPackages = {};
673
- const patterns = possiblePackagesDirs.filter((dir) => fs7.existsSync(dir)).map((dir) => path9.join(dir, "**/package.json"));
674
- if (patterns.length > 0) {
675
- const pkgJsonFiles = await fg(patterns, {
676
- ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
677
- absolute: true,
678
- deep: 5
679
- });
680
- for (const pkgJsonPath of pkgJsonFiles) {
681
- try {
682
- const pkgJson = await fs7.readJson(pkgJsonPath);
683
- if (corePackages.includes(pkgJson.name) || runtimeDeps.includes(pkgJson.name)) {
684
- localPackages[pkgJson.name] = path9.dirname(pkgJsonPath);
685
- }
686
- } catch (e) {
687
- }
914
+ for (const [name, pkgPath] of Object.entries(allLocalPackages)) {
915
+ if (corePackages.includes(name) || runtimeDeps.includes(name)) {
916
+ localPackages[name] = pkgPath;
688
917
  }
689
918
  }
690
919
  if (Object.keys(localPackages).length === 0) return false;
691
- const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${pc3.cyan(name.padEnd(30))} -> ${pc3.gray(pkgPath)}`).join("\n");
920
+ const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${pc2.cyan(name.padEnd(30))} -> ${pc2.gray(pkgPath)}`).join("\n");
692
921
  printBox(
693
- pc3.green("\u{1F517} \u5DF2\u68C0\u6D4B\u5230\u672C\u5730\u5F00\u53D1\u73AF\u5883\uFF0C\u5C06\u94FE\u63A5\u4EE5\u4E0B\u6838\u5FC3\u5305\uFF1A\n\n") + linkSummary,
922
+ pc2.green("\u{1F517} \u5DF2\u68C0\u6D4B\u5230\u672C\u5730\u5F00\u53D1\u73AF\u5883\uFF0C\u5C06\u94FE\u63A5\u4EE5\u4E0B\u6838\u5FC3\u5305\uFF1A\n\n") + linkSummary,
694
923
  "Monorepo Link Mode"
695
924
  );
696
- const sandboxNodeModules = path9.join(versionPath, "node_modules");
697
- await fs7.ensureDir(sandboxNodeModules);
925
+ const sandboxNodeModules = path8.join(versionPath, "node_modules");
926
+ await fs6.ensureDir(sandboxNodeModules);
698
927
  for (const [name, pkgPath] of Object.entries(localPackages)) {
699
- const targetLinkPath = path9.join(sandboxNodeModules, name);
700
- await fs7.ensureDir(path9.dirname(targetLinkPath));
928
+ const targetLinkPath = path8.join(sandboxNodeModules, name);
929
+ await fs6.ensureDir(path8.dirname(targetLinkPath));
701
930
  try {
702
- const stats = await fs7.lstat(targetLinkPath).catch(() => null);
703
- if (stats) await fs7.remove(targetLinkPath);
704
- } catch (e) {
931
+ const stats = await fs6.lstat(targetLinkPath).catch(() => null);
932
+ if (stats) await fs6.remove(targetLinkPath);
933
+ } catch {
705
934
  }
706
- await fs7.symlink(pkgPath, targetLinkPath, "dir");
935
+ await fs6.symlink(pkgPath, targetLinkPath, "dir");
707
936
  }
708
- const sandboxPkgJsonPath = path9.join(versionPath, "package.json");
709
- const sandboxPkgJson = await fs7.readJson(sandboxPkgJsonPath);
937
+ const sandboxPkgJsonPath = path8.join(versionPath, "package.json");
938
+ const sandboxPkgJson = await fs6.readJson(sandboxPkgJsonPath);
710
939
  const sections = ["dependencies", "devDependencies"];
711
940
  let modified = false;
712
941
  for (const section of sections) {
@@ -719,10 +948,10 @@ var init_SandboxPkgManager = __esm({
719
948
  }
720
949
  }
721
950
  }
722
- if (modified) await fs7.writeJson(sandboxPkgJsonPath, sandboxPkgJson, { spaces: 2 });
951
+ if (modified) await fs6.writeJson(sandboxPkgJsonPath, sandboxPkgJson, { spaces: 2 });
723
952
  return true;
724
953
  } catch (e) {
725
- console.warn(pc3.yellow(` \u26A0\uFE0F Link \u672C\u5730\u6E90\u7801\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4ECE NPM \u5B89\u88C5: ${e.message}`));
954
+ console.warn(pc2.yellow(` \u26A0\uFE0F Link \u672C\u5730\u6E90\u7801\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4ECE NPM \u5B89\u88C5: ${e.message}`));
726
955
  return false;
727
956
  }
728
957
  }
@@ -730,55 +959,144 @@ var init_SandboxPkgManager = __esm({
730
959
  }
731
960
  });
732
961
 
733
- // src/sandbox.ts
734
- import { execa as execa2 } from "execa";
735
- import fg2 from "fast-glob";
736
- import fs8 from "fs-extra";
737
- import path10 from "path";
738
- import pc4 from "picocolors";
739
- var Sandbox;
740
- var init_sandbox = __esm({
741
- "src/sandbox.ts"() {
962
+ // src/sandbox/SandboxRenderer.ts
963
+ import fs7 from "fs-extra";
964
+ import Handlebars from "handlebars";
965
+ import path9 from "path";
966
+ var SandboxRenderer;
967
+ var init_SandboxRenderer = __esm({
968
+ "src/sandbox/SandboxRenderer.ts"() {
742
969
  "use strict";
743
970
  init_esm_shims();
744
- init_constants();
745
- init_SandboxContext();
746
- init_SandboxPath();
747
- init_SandboxPkgManager();
748
- init_SandboxRenderer();
749
- init_utils();
750
- Sandbox = class {
751
- static {
752
- /** 核心源码包列表 */
753
- this.CORE_PACKAGES = [
754
- "@chatbi-v/core",
755
- "@chatbi-v/mocks",
756
- "@chatbi-v/config"
757
- ];
758
- }
759
- static {
760
- /** 运行时必须依赖 */
761
- this.RUNTIME_DEPS = [
762
- "@ant-design/x",
763
- "@ant-design/icons",
764
- "antd",
765
- "react",
766
- "react-dom",
767
- "lucide-react",
768
- "framer-motion",
769
- "clsx",
770
- "tailwind-merge",
771
- "react-router-dom",
772
- "zustand",
773
- "axios",
774
- "less",
775
- "vite"
776
- ];
777
- }
778
- /** 获取沙箱根目录 */
779
- static getRoot() {
780
- return SandboxPath.getRoot();
781
- }
971
+ Handlebars.registerHelper("json", (obj) => JSON.stringify(obj, null, 2));
972
+ Handlebars.registerHelper("eq", (a, b) => a === b);
973
+ SandboxRenderer = class {
974
+ /**
975
+ * 需要转义的模板关键字列表
976
+ * 只有匹配这些关键字的 {{ }} 才会被 Handlebars 处理,其余(如 React 的 {{ style }})将被转义跳过
977
+ */
978
+ static TEMPLATE_KEYWORDS = [
979
+ "name",
980
+ "version",
981
+ "projectName",
982
+ "projectTitle",
983
+ "projectVersion",
984
+ "cliVersion",
985
+ "tsconfigPath",
986
+ "theme",
987
+ "isNebula",
988
+ "isGlass",
989
+ "isBusiness",
990
+ "isApp",
991
+ "isShell",
992
+ "pluginName",
993
+ "pluginPackageName",
994
+ "pluginVersion",
995
+ "pluginDisplayName",
996
+ "pluginDescription",
997
+ "pluginClassName",
998
+ "pluginPath",
999
+ "pluginFolderName",
1000
+ "pluginType",
1001
+ "pluginId",
1002
+ "className",
1003
+ "dependencies",
1004
+ "devDependencies",
1005
+ "json",
1006
+ "if",
1007
+ "else",
1008
+ "unless",
1009
+ "each",
1010
+ "with",
1011
+ "log",
1012
+ "lookup"
1013
+ ];
1014
+ /**
1015
+ * 递归渲染目录模板
1016
+ * @param srcDir 模板源目录
1017
+ * @param destDir 目标输出目录
1018
+ * @param data 渲染模板所需的变量上下文
1019
+ */
1020
+ static async renderDirectory(srcDir, destDir, data) {
1021
+ if (!srcDir || !destDir || !fs7.existsSync(srcDir)) return;
1022
+ const entries = await fs7.readdir(srcDir, { withFileTypes: true });
1023
+ await Promise.all(entries.map(async (entry) => {
1024
+ const srcPath = path9.join(srcDir, entry.name);
1025
+ const destPath = path9.join(destDir, entry.name.replace(/\.hbs$/, ""));
1026
+ if (entry.isDirectory()) {
1027
+ await fs7.ensureDir(destPath);
1028
+ await this.renderDirectory(srcPath, destPath, data);
1029
+ } else {
1030
+ await this.renderFile(srcPath, destPath, data);
1031
+ }
1032
+ }));
1033
+ }
1034
+ /**
1035
+ * 渲染单个文件
1036
+ */
1037
+ static async renderFile(srcPath, destPath, data) {
1038
+ const isTemplate = srcPath.endsWith(".hbs");
1039
+ let content = await fs7.readFile(srcPath, "utf-8");
1040
+ let outputContent = content;
1041
+ if (isTemplate) {
1042
+ if (content.includes("{{")) {
1043
+ try {
1044
+ const keywordsPattern = this.TEMPLATE_KEYWORDS.join("|");
1045
+ const safeContent = content.replace(
1046
+ new RegExp(`\\{\\{(?!\\{)(?!\\s*([#/]?(?:${keywordsPattern}))\\b)`, "g"),
1047
+ "\\{{"
1048
+ );
1049
+ const template = Handlebars.compile(safeContent);
1050
+ outputContent = template(data);
1051
+ } catch {
1052
+ outputContent = content;
1053
+ for (const [key, val] of Object.entries(data)) {
1054
+ const regex = new RegExp(`\\{\\{\\s*${key}\\s*\\}\\}`, "g");
1055
+ outputContent = outputContent.replace(regex, typeof val === "object" ? JSON.stringify(val) : String(val));
1056
+ }
1057
+ }
1058
+ }
1059
+ }
1060
+ if (fs7.existsSync(destPath)) {
1061
+ const existingContent = await fs7.readFile(destPath, "utf-8");
1062
+ if (existingContent === outputContent) {
1063
+ return;
1064
+ }
1065
+ }
1066
+ await fs7.outputFile(destPath, outputContent);
1067
+ }
1068
+ };
1069
+ }
1070
+ });
1071
+
1072
+ // src/sandbox.ts
1073
+ import { execa as execa3 } from "execa";
1074
+ import fg from "fast-glob";
1075
+ import fs8 from "fs-extra";
1076
+ import path10 from "path";
1077
+ import pc3 from "picocolors";
1078
+ var config3, Sandbox;
1079
+ var init_sandbox = __esm({
1080
+ "src/sandbox.ts"() {
1081
+ "use strict";
1082
+ init_esm_shims();
1083
+ init_config();
1084
+ init_constants();
1085
+ init_SandboxContext();
1086
+ init_SandboxPath();
1087
+ init_SandboxPkgManager();
1088
+ init_SandboxRenderer();
1089
+ init_utils();
1090
+ config3 = loadConfig();
1091
+ Sandbox = class {
1092
+ /** 核心源码包列表 */
1093
+ static CORE_PACKAGES = config3.runtime.corePackages;
1094
+ /** 运行时必须依赖 */
1095
+ static RUNTIME_DEPS = config3.runtime.runtimeDeps;
1096
+ /** 获取沙箱根目录 */
1097
+ static getRoot() {
1098
+ return SandboxPath.getRoot();
1099
+ }
782
1100
  /** 获取所有版本的根目录 */
783
1101
  static getVersionRoot() {
784
1102
  return SandboxPath.getVersionRoot();
@@ -802,16 +1120,18 @@ var init_sandbox = __esm({
802
1120
  * 优雅清理缓存环境
803
1121
  * @param cwd 当前项目路径
804
1122
  * @param deep 是否执行深度清理
1123
+ * @param dryRun 是否仅预览
805
1124
  */
806
- static async clean(cwd, deep = false) {
807
- const spinner = createSpinner("\u6B63\u5728\u6E05\u7406\u7F13\u5B58\u76EE\u5F55...").start();
1125
+ static async clean(cwd, deep = false, dryRun = false) {
1126
+ const spinner = createSpinner(dryRun ? "\u6B63\u5728\u626B\u63CF\u7F13\u5B58\u76EE\u5F55..." : "\u6B63\u5728\u6E05\u7406\u7F13\u5B58\u76EE\u5F55...").start();
808
1127
  try {
809
1128
  const workspaceRoot = await this.getWorkspaceRoot(cwd);
810
1129
  let cleanedCount = 0;
1130
+ const targetDirs = [];
811
1131
  const cachePatterns = [
812
1132
  path10.join(workspaceRoot, `**/${SANDBOX_CONFIG.DIRS.CACHE}`)
813
1133
  ];
814
- const cacheDirs = await fg2(cachePatterns, {
1134
+ const cacheDirs = await fg(cachePatterns, {
815
1135
  onlyFiles: false,
816
1136
  // 允许匹配文件和符号链接
817
1137
  absolute: true,
@@ -822,15 +1142,14 @@ var init_sandbox = __esm({
822
1142
  for (const dir of cacheDirs) {
823
1143
  const stats = await fs8.lstat(dir).catch(() => null);
824
1144
  if (stats) {
825
- await fs8.remove(dir);
826
- cleanedCount++;
1145
+ targetDirs.push(dir);
827
1146
  }
828
1147
  }
829
1148
  if (deep) {
830
1149
  const distPatterns = [
831
1150
  path10.join(workspaceRoot, "**/dist")
832
1151
  ];
833
- const distDirs = await fg2(distPatterns, {
1152
+ const distDirs = await fg(distPatterns, {
834
1153
  onlyFiles: false,
835
1154
  absolute: true,
836
1155
  ignore: [
@@ -845,20 +1164,36 @@ var init_sandbox = __esm({
845
1164
  if (stats) {
846
1165
  const hasPkg = fs8.existsSync(path10.join(path10.dirname(dir), "package.json"));
847
1166
  if (hasPkg) {
848
- await fs8.remove(dir);
849
- cleanedCount++;
1167
+ targetDirs.push(dir);
850
1168
  }
851
1169
  }
852
1170
  }
853
1171
  const globalRoot = this.getRoot();
854
1172
  if (fs8.existsSync(globalRoot)) {
855
- await fs8.remove(globalRoot);
856
- cleanedCount++;
1173
+ targetDirs.push(globalRoot);
1174
+ }
1175
+ }
1176
+ if (dryRun) {
1177
+ spinner.stop();
1178
+ if (targetDirs.length === 0) {
1179
+ console.log(pc3.green("\u2728 \u6CA1\u6709\u53D1\u73B0\u9700\u8981\u6E05\u7406\u7684\u7F13\u5B58\u76EE\u5F55"));
1180
+ } else {
1181
+ printBox(
1182
+ `${pc3.yellow("\u5373\u5C06\u6E05\u7406\u4EE5\u4E0B\u76EE\u5F55\uFF1A")}
1183
+
1184
+ ` + targetDirs.map((d) => pc3.gray(`- ${d}`)).join("\n"),
1185
+ "Dry Run"
1186
+ );
857
1187
  }
1188
+ return;
1189
+ }
1190
+ for (const dir of targetDirs) {
1191
+ await fs8.remove(dir);
1192
+ cleanedCount++;
858
1193
  }
859
- spinner.succeed(pc4.green(`\u6E05\u7406\u5B8C\u6210\uFF0C\u5171\u6E05\u7406 ${cleanedCount} \u4E2A\u9879\u76EE/\u7F13\u5B58\u76EE\u5F55`));
1194
+ spinner.succeed(pc3.green(`\u6E05\u7406\u5B8C\u6210\uFF0C\u5171\u6E05\u7406 ${cleanedCount} \u4E2A\u9879\u76EE/\u7F13\u5B58\u76EE\u5F55`));
860
1195
  } catch (e) {
861
- spinner.fail(pc4.red(`\u6E05\u7406\u5931\u8D25: ${e.message}`));
1196
+ spinner.fail(pc3.red(`\u6E05\u7406\u5931\u8D25: ${e.message}`));
862
1197
  }
863
1198
  }
864
1199
  /**
@@ -873,7 +1208,7 @@ var init_sandbox = __esm({
873
1208
  await fs8.remove(path10.join(versionPath, "node_modules"));
874
1209
  }
875
1210
  await fs8.ensureDir(versionPath);
876
- const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${pc4.cyan(version)}...`).start();
1211
+ const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${pc3.cyan(version)}...`).start();
877
1212
  try {
878
1213
  const cliRoot = await getCliRoot();
879
1214
  const dependencies = {};
@@ -881,7 +1216,7 @@ var init_sandbox = __esm({
881
1216
  dependencies[pkg] = DEPENDENCY_VERSIONS[pkg] || "latest";
882
1217
  }
883
1218
  for (const pkg of this.CORE_PACKAGES) {
884
- dependencies[pkg] = pkg === "@chatbi-v/core" ? version : "latest";
1219
+ dependencies[pkg] = version;
885
1220
  }
886
1221
  const templateData = {
887
1222
  version,
@@ -893,16 +1228,16 @@ var init_sandbox = __esm({
893
1228
  versionPath,
894
1229
  templateData
895
1230
  );
896
- spinner.text = pc4.gray(" \u{1F3A8} \u540C\u6B65 Shell \u6A21\u677F...");
1231
+ spinner.text = pc3.gray(" \u{1F3A8} \u540C\u6B65 Shell \u6A21\u677F...");
897
1232
  await this.ensureShell(version, force);
898
- spinner.text = pc4.gray(" \u{1F50D} \u68C0\u67E5\u672C\u5730\u5F00\u53D1\u73AF\u5883...");
1233
+ spinner.text = pc3.gray(" \u{1F50D} \u68C0\u67E5\u672C\u5730\u5F00\u53D1\u73AF\u5883...");
899
1234
  const isLocalDev = await SandboxPkgManager.tryLinkLocalPackages(versionPath, this.CORE_PACKAGES, this.RUNTIME_DEPS);
900
1235
  const installArgs = isLocalDev ? ["install", "--no-frozen-lockfile"] : ["install"];
901
- spinner.text = pc4.gray(` \u23F3 \u6267\u884C pnpm ${installArgs.join(" ")}...`);
902
- await execa2("pnpm", installArgs, { cwd: versionPath });
903
- spinner.succeed(pc4.green(`\u5185\u6838\u6C99\u7BB1 ${version} \u521D\u59CB\u5316\u6210\u529F`));
1236
+ spinner.text = pc3.gray(` \u23F3 \u6267\u884C pnpm ${installArgs.join(" ")}...`);
1237
+ await execa3("pnpm", installArgs, { cwd: versionPath });
1238
+ spinner.succeed(pc3.green(`\u5185\u6838\u6C99\u7BB1 ${version} \u521D\u59CB\u5316\u6210\u529F`));
904
1239
  } catch (e) {
905
- spinner.fail(pc4.red(`\u5185\u6838\u6C99\u7BB1\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`));
1240
+ spinner.fail(pc3.red(`\u5185\u6838\u6C99\u7BB1\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`));
906
1241
  throw e;
907
1242
  }
908
1243
  return versionPath;
@@ -981,11 +1316,11 @@ var init_sandbox = __esm({
981
1316
  const currentVersion = await this.resolveVersion("current");
982
1317
  const versions = await this.listVersions();
983
1318
  const statusInfo = [
984
- `${pc4.bold("\u9879\u76EE\u8DEF\u5F84:")} ${pc4.cyan(cwd)}`,
985
- `${pc4.bold("\u67B6\u6784\u6A21\u5F0F:")} ${isMonorepo ? pc4.yellow("Monorepo") : pc4.green("Standalone")}`,
986
- `${pc4.bold("\u5F53\u524D\u5185\u6838:")} ${pc4.green(currentVersion)}`,
987
- `${pc4.bold("\u5DF2\u88C5\u7248\u672C:")} ${pc4.gray(versions.join(", ") || "none")}`,
988
- `${pc4.bold("\u6C99\u7BB1\u6839\u76EE\u5F55:")} ${pc4.gray(this.getRoot())}`
1319
+ `${pc3.bold("\u9879\u76EE\u8DEF\u5F84:")} ${pc3.cyan(cwd)}`,
1320
+ `${pc3.bold("\u67B6\u6784\u6A21\u5F0F:")} ${isMonorepo ? pc3.yellow("Monorepo") : pc3.green("Standalone")}`,
1321
+ `${pc3.bold("\u5F53\u524D\u5185\u6838:")} ${pc3.green(currentVersion)}`,
1322
+ `${pc3.bold("\u5DF2\u88C5\u7248\u672C:")} ${pc3.gray(versions.join(", ") || "none")}`,
1323
+ `${pc3.bold("\u6C99\u7BB1\u6839\u76EE\u5F55:")} ${pc3.gray(this.getRoot())}`
989
1324
  ].join("\n");
990
1325
  printBox(statusInfo, "ChatBI Sandbox Status");
991
1326
  }
@@ -994,22 +1329,20 @@ var init_sandbox = __esm({
994
1329
  });
995
1330
 
996
1331
  // src/corekit.ts
997
- import fg3 from "fast-glob";
1332
+ import fg2 from "fast-glob";
998
1333
  import fs9 from "fs-extra";
999
- import { createRequire as createRequire3 } from "module";
1334
+ import { createRequire as createRequire2 } from "module";
1000
1335
  import path11 from "path";
1001
- import pc5 from "picocolors";
1002
- import prompts2 from "prompts";
1003
- import { createJiti as createJiti2 } from "jiti";
1336
+ import pc4 from "picocolors";
1004
1337
  var nativeRequire, CoreKit;
1005
1338
  var init_corekit = __esm({
1006
1339
  "src/corekit.ts"() {
1007
1340
  "use strict";
1008
1341
  init_esm_shims();
1009
- init_config();
1342
+ init_config2();
1010
1343
  init_sandbox();
1011
1344
  init_utils();
1012
- nativeRequire = createRequire3(import.meta.url);
1345
+ nativeRequire = createRequire2(import.meta.url);
1013
1346
  CoreKit = class {
1014
1347
  /**
1015
1348
  * 解析项目模式
@@ -1023,7 +1356,7 @@ var init_corekit = __esm({
1023
1356
  }
1024
1357
  if (pkg.chatbi?.type === "plugin" || pkg.plugin === true) return "plugin";
1025
1358
  if (pkg.chatbi?.type === "app") return "app";
1026
- const pluginEntries = await fg3(["index.plugin.{ts,js}", "src/index.plugin.{ts,js}"], { cwd });
1359
+ const pluginEntries = await fg2(["index.plugin.{ts,js}", "src/index.plugin.{ts,js}"], { cwd });
1027
1360
  if (pluginEntries.length > 0) return "plugin";
1028
1361
  if (fs9.existsSync(path11.join(cwd, "index.html"))) {
1029
1362
  return "app";
@@ -1041,8 +1374,8 @@ var init_corekit = __esm({
1041
1374
  */
1042
1375
  static async resolveVersion(projectRoot) {
1043
1376
  if (projectRoot) {
1044
- const config = await ConfigManager.loadConfig(projectRoot);
1045
- if (config.coreVersion) return config.coreVersion;
1377
+ const config4 = await ConfigManager.loadConfig(projectRoot);
1378
+ if (config4.coreVersion) return config4.coreVersion;
1046
1379
  }
1047
1380
  try {
1048
1381
  const cliRoot = await getCliRoot();
@@ -1051,14 +1384,14 @@ var init_corekit = __esm({
1051
1384
  const version = (await fs9.readFile(cliVersionFile, "utf-8")).trim();
1052
1385
  if (version) return version;
1053
1386
  }
1054
- } catch (e) {
1387
+ } catch {
1055
1388
  }
1056
1389
  const currentLinkPath = path11.join(Sandbox.getVersionRoot(), "current");
1057
1390
  if (fs9.existsSync(currentLinkPath)) {
1058
1391
  try {
1059
1392
  const realPath = await fs9.realpath(currentLinkPath);
1060
1393
  return path11.basename(realPath);
1061
- } catch (e) {
1394
+ } catch {
1062
1395
  }
1063
1396
  }
1064
1397
  const versions = await this.listVersions();
@@ -1070,7 +1403,7 @@ var init_corekit = __esm({
1070
1403
  static async listVersions() {
1071
1404
  const versionsDir = Sandbox.getVersionRoot();
1072
1405
  if (!fs9.existsSync(versionsDir)) return [];
1073
- const dirs = await fg3("*", {
1406
+ const dirs = await fg2("*", {
1074
1407
  cwd: versionsDir,
1075
1408
  onlyDirectories: true,
1076
1409
  deep: 1
@@ -1083,7 +1416,7 @@ var init_corekit = __esm({
1083
1416
  static async discoverPlugins(rootDir) {
1084
1417
  const pluginsDir = path11.join(rootDir, "plugins");
1085
1418
  if (!fs9.existsSync(pluginsDir)) return [];
1086
- const pkgFiles = await fg3("*/package.json", { cwd: pluginsDir, absolute: true });
1419
+ const pkgFiles = await fg2("*/package.json", { cwd: pluginsDir, absolute: true });
1087
1420
  const plugins = [];
1088
1421
  for (const pkgPath of pkgFiles) {
1089
1422
  try {
@@ -1094,7 +1427,7 @@ var init_corekit = __esm({
1094
1427
  path: pluginPath,
1095
1428
  id: path11.basename(pluginPath)
1096
1429
  });
1097
- } catch (e) {
1430
+ } catch {
1098
1431
  }
1099
1432
  }
1100
1433
  return plugins;
@@ -1106,19 +1439,19 @@ var init_corekit = __esm({
1106
1439
  const mode = await this.detectMode(cwd);
1107
1440
  const version = await this.resolveVersion(cwd);
1108
1441
  printBox(
1109
- `${pc5.cyan(pc5.bold("\u{1F680} ChatBI Dev Server"))}
1442
+ `${pc4.cyan(pc4.bold("\u{1F680} ChatBI Dev Server"))}
1110
1443
 
1111
- ${pc5.gray("Mode: ")} ${pc5.yellow(mode)}
1112
- ${pc5.gray("Kernel: ")} ${pc5.green(version)}
1113
- ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1444
+ ${pc4.gray("Mode: ")} ${pc4.yellow(mode)}
1445
+ ${pc4.gray("Kernel: ")} ${pc4.green(version)}
1446
+ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1114
1447
  "Dev Server"
1115
1448
  );
1116
1449
  const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6C99\u7BB1\u73AF\u5883...").start();
1117
1450
  try {
1118
1451
  await Sandbox.prepare(version);
1119
- spinner.text = pc5.cyan("\u6B63\u5728\u6CE8\u5165\u865A\u62DF\u4E0A\u4E0B\u6587...");
1452
+ spinner.text = pc4.cyan("\u6B63\u5728\u6CE8\u5165\u865A\u62DF\u4E0A\u4E0B\u6587...");
1120
1453
  await Sandbox.injectContext(cwd, version);
1121
- spinner.succeed(pc5.green("\u73AF\u5883\u5C31\u7EEA"));
1454
+ spinner.succeed(pc4.green("\u73AF\u5883\u5C31\u7EEA"));
1122
1455
  if (mode === "plugin") {
1123
1456
  await this.startPluginDevServer(cwd, version, options.port);
1124
1457
  } else if (mode === "app") {
@@ -1127,7 +1460,7 @@ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1127
1460
  await this.startMonorepoDevServer(cwd, version, options.port);
1128
1461
  }
1129
1462
  } catch (e) {
1130
- spinner.fail(pc5.red(`\u542F\u52A8\u5931\u8D25: ${e.message}`));
1463
+ spinner.fail(pc4.red(`\u542F\u52A8\u5931\u8D25: ${e.message}`));
1131
1464
  }
1132
1465
  }
1133
1466
  /**
@@ -1139,7 +1472,7 @@ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1139
1472
  logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230 apps/ \u76EE\u5F55");
1140
1473
  return;
1141
1474
  }
1142
- const pkgFiles = await fg3("*/package.json", { cwd: appsDir, absolute: true });
1475
+ const pkgFiles = await fg2("*/package.json", { cwd: appsDir, absolute: true });
1143
1476
  const apps = pkgFiles.map((pkgPath) => ({
1144
1477
  name: path11.basename(path11.dirname(pkgPath)),
1145
1478
  path: path11.dirname(pkgPath)
@@ -1148,7 +1481,8 @@ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1148
1481
  logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230\u4EFB\u4F55\u5E94\u7528 (apps/)");
1149
1482
  return;
1150
1483
  }
1151
- const response = await prompts2({
1484
+ const { default: prompts5 } = await import("prompts");
1485
+ const response = await prompts5({
1152
1486
  type: "select",
1153
1487
  name: "appPath",
1154
1488
  message: "\u8BF7\u9009\u62E9\u8981\u542F\u52A8\u7684\u5E94\u7528:",
@@ -1182,6 +1516,7 @@ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1182
1516
  "process.env.CHATBI_PLUGIN_PATH": JSON.stringify(pluginDir)
1183
1517
  };
1184
1518
  const { createServer } = await import("vite");
1519
+ const { createJiti: createJiti2 } = await import("jiti");
1185
1520
  const jiti = createJiti2(import.meta.url);
1186
1521
  const tailwindConfig = await jiti.import(path11.join(sandboxNodeModules, "@chatbi-v/config/tailwind.js"), { default: true });
1187
1522
  try {
@@ -1241,9 +1576,9 @@ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1241
1576
  await server.listen();
1242
1577
  const localUrl = `http://localhost:${shellPort}/`;
1243
1578
  printBox(
1244
- `${pc5.green(pc5.bold("\u2705 \u6258\u7BA1\u5F0F Shell \u5DF2\u542F\u52A8"))}
1579
+ `${pc4.green(pc4.bold("\u2705 \u6258\u7BA1\u5F0F Shell \u5DF2\u542F\u52A8"))}
1245
1580
 
1246
- ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1581
+ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1247
1582
  "Shell Success"
1248
1583
  );
1249
1584
  } catch (e) {
@@ -1265,7 +1600,7 @@ ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1265
1600
  const { createServer, loadConfigFromFile, searchForWorkspaceRoot } = await import("vite");
1266
1601
  try {
1267
1602
  const configContext = { command: "serve", mode: "development" };
1268
- const userConfig = await loadConfigFromFile(configContext, void 0, appDir).catch(() => null);
1603
+ await loadConfigFromFile(configContext, void 0, appDir).catch(() => null);
1269
1604
  const server = await createServer({
1270
1605
  root: appDir,
1271
1606
  // 这里我们允许用户有自己的 vite config,但我们会 merge alias
@@ -1307,9 +1642,9 @@ ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1307
1642
  await server.listen();
1308
1643
  const localUrl = `http://localhost:${server.config.server.port}/`;
1309
1644
  printBox(
1310
- `${pc5.green(pc5.bold("\u2705 \u5E94\u7528\u5DF2\u6210\u529F\u542F\u52A8"))}
1645
+ `${pc4.green(pc4.bold("\u2705 \u5E94\u7528\u5DF2\u6210\u529F\u542F\u52A8"))}
1311
1646
 
1312
- ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1647
+ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1313
1648
  "App Success"
1314
1649
  );
1315
1650
  } catch (e) {
@@ -1320,16 +1655,32 @@ ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1320
1655
  }
1321
1656
  });
1322
1657
 
1658
+ // src/commands/dev.ts
1659
+ var dev_exports = {};
1660
+ __export(dev_exports, {
1661
+ dev: () => dev
1662
+ });
1663
+ async function dev(options = {}) {
1664
+ const cwd = process.cwd();
1665
+ await CoreKit.startDev(cwd, options);
1666
+ }
1667
+ var init_dev = __esm({
1668
+ "src/commands/dev.ts"() {
1669
+ "use strict";
1670
+ init_esm_shims();
1671
+ init_corekit();
1672
+ }
1673
+ });
1674
+
1323
1675
  // src/commands/build.ts
1324
1676
  var build_exports = {};
1325
1677
  __export(build_exports, {
1326
1678
  build: () => build
1327
1679
  });
1328
- import { execa as execa3 } from "execa";
1680
+ import { execa as execa4 } from "execa";
1329
1681
  import fs10 from "fs-extra";
1330
1682
  import path12 from "path";
1331
- import pc6 from "picocolors";
1332
- import { build as tsupBuild } from "tsup";
1683
+ import pc5 from "picocolors";
1333
1684
  async function build(options) {
1334
1685
  const cwd = process.cwd();
1335
1686
  const pkgPath = path12.join(cwd, "package.json");
@@ -1343,13 +1694,13 @@ async function build(options) {
1343
1694
  try {
1344
1695
  await Sandbox.clean(cwd, true);
1345
1696
  spinnerClean.succeed("\u7F13\u5B58\u73AF\u5883\u6E05\u7406\u5B8C\u6210");
1346
- } catch (e) {
1697
+ } catch {
1347
1698
  spinnerClean.fail("\u7F13\u5B58\u6E05\u7406\u5931\u8D25");
1348
- logger.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF", e);
1699
+ logger.error("\u6E05\u7406\u8FC7\u7A0B\u4E2D\u53D1\u751F\u9519\u8BEF");
1349
1700
  }
1350
1701
  }
1351
1702
  const version = await CoreKit.resolveVersion(cwd);
1352
- logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${pc6.bold(pkg.name || "unnamed")} (\u5185\u6838\u7248\u672C: ${version})
1703
+ logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${pc5.bold(pkg.name || "unnamed")} (\u5185\u6838\u7248\u672C: ${version})
1353
1704
  `);
1354
1705
  const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6784\u5EFA\u73AF\u5883...").start();
1355
1706
  spinner.text = "\u6B63\u5728\u540C\u6B65\u6C99\u7BB1\u5185\u6838...";
@@ -1380,12 +1731,12 @@ async function build(options) {
1380
1731
  if (pkg.scripts && pkg.scripts.build && !process.env.CHATBI_CLI_INTERNAL) {
1381
1732
  const buildScript = pkg.scripts.build;
1382
1733
  if (!buildScript.includes("chatbi-cli build") && !buildScript.includes("chatbi build")) {
1383
- logger.info(`\u68C0\u6D4B\u5230\u81EA\u5B9A\u4E49 build \u811A\u672C\uFF0C\u6B63\u5728\u6267\u884C: ${pc6.cyan("npm run build")}`);
1734
+ logger.info(`\u68C0\u6D4B\u5230\u81EA\u5B9A\u4E49 build \u811A\u672C\uFF0C\u6B63\u5728\u6267\u884C: ${pc5.cyan("npm run build")}`);
1384
1735
  const args = ["run", "build"];
1385
1736
  if (options.watch) {
1386
1737
  args.push("--", "--watch");
1387
1738
  }
1388
- await execa3("npm", args, {
1739
+ await execa4("npm", args, {
1389
1740
  stdio: "inherit",
1390
1741
  env: { ...process.env, CHATBI_CLI_INTERNAL: "true" }
1391
1742
  });
@@ -1395,7 +1746,7 @@ async function build(options) {
1395
1746
  const mode = await CoreKit.detectMode(cwd);
1396
1747
  if (mode === "monorepo") {
1397
1748
  logger.info("\u68C0\u6D4B\u5230 Monorepo \u9879\u76EE\uFF0C\u6B63\u5728\u9012\u5F52\u6784\u5EFA\u5B50\u5305...");
1398
- await execa3("pnpm", ["-r", "build"], { stdio: "inherit", cwd });
1749
+ await execa4("pnpm", ["-r", "build"], { stdio: "inherit", cwd });
1399
1750
  return;
1400
1751
  }
1401
1752
  if (mode === "app") {
@@ -1428,12 +1779,13 @@ async function build(options) {
1428
1779
  });
1429
1780
  if (!options.watch) {
1430
1781
  printBox(
1431
- pc6.green(pc6.bold("\u2728 \u5E94\u7528\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc6.white("\u4EA7\u7269\u76EE\u5F55: ") + pc6.cyan("dist"),
1782
+ pc5.green(pc5.bold("\u2728 \u5E94\u7528\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc5.white("\u4EA7\u7269\u76EE\u5F55: ") + pc5.cyan("dist"),
1432
1783
  "Build Success"
1433
1784
  );
1434
1785
  }
1435
1786
  return;
1436
1787
  }
1788
+ const { build: tsupBuild } = await import("tsup");
1437
1789
  let entry = ["src/index.ts"];
1438
1790
  if (fs10.existsSync(path12.join(cwd, "src/index.tsx"))) {
1439
1791
  entry = ["src/index.tsx"];
@@ -1457,6 +1809,7 @@ async function build(options) {
1457
1809
  }
1458
1810
  const commonConfig = {
1459
1811
  entry,
1812
+ splitting: false,
1460
1813
  dts: false,
1461
1814
  clean: false,
1462
1815
  sourcemap: false,
@@ -1475,6 +1828,7 @@ async function build(options) {
1475
1828
  "@ant-design/x",
1476
1829
  ...Object.keys(pkg.dependencies || {}),
1477
1830
  ...Object.keys(pkg.peerDependencies || {}),
1831
+ ...Object.keys(pkg.devDependencies || {}),
1478
1832
  ...isPlugin ? Sandbox.CORE_PACKAGES : [],
1479
1833
  ...Array.isArray(userConfig.external) ? userConfig.external : []
1480
1834
  ])
@@ -1549,22 +1903,22 @@ async function build(options) {
1549
1903
  tscBin = sandboxTsc;
1550
1904
  } else {
1551
1905
  if (fs10.existsSync(path12.join(cwd, "pnpm-lock.yaml"))) {
1552
- await execa3("pnpm", ["exec", "tsc", "--build", "tsconfig.json"]);
1906
+ await execa4("pnpm", ["exec", "tsc", "--build", "tsconfig.json"]);
1553
1907
  dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
1554
1908
  } else {
1555
- await execa3("npx", ["-p", "typescript", "tsc", "--build", "tsconfig.json"]);
1909
+ await execa4("npx", ["-p", "typescript", "tsc", "--build", "tsconfig.json"]);
1556
1910
  dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
1557
1911
  }
1558
1912
  }
1559
1913
  if (tscBin !== "tsc") {
1560
- await execa3(tscBin, ["--build", "tsconfig.json"]);
1914
+ await execa4(tscBin, ["--build", "tsconfig.json"]);
1561
1915
  dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
1562
1916
  }
1563
- } catch (e) {
1917
+ } catch {
1564
1918
  dtsSpinner.warn("\u7C7B\u578B\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u4E2D\u7684 tsconfig.json \u914D\u7F6E");
1565
1919
  }
1566
1920
  printBox(
1567
- pc6.green(pc6.bold("\u2728 \u6784\u5EFA\u5B8C\u6210!")) + "\n\n" + pc6.white("\u4EA7\u7269\u76EE\u5F55: ") + pc6.cyan("dist") + "\n" + pc6.white("\u6784\u5EFA\u6A21\u5F0F: ") + pc6.cyan(isPlugin ? "Plugin" : "Library"),
1921
+ pc5.green(pc5.bold("\u2728 \u6784\u5EFA\u5B8C\u6210!")) + "\n\n" + pc5.white("\u4EA7\u7269\u76EE\u5F55: ") + pc5.cyan("dist") + "\n" + pc5.white("\u6784\u5EFA\u6A21\u5F0F: ") + pc5.cyan(isPlugin ? "Plugin" : "Library"),
1568
1922
  "Build Success"
1569
1923
  );
1570
1924
  }
@@ -1573,29 +1927,126 @@ var init_build = __esm({
1573
1927
  "src/commands/build.ts"() {
1574
1928
  "use strict";
1575
1929
  init_esm_shims();
1576
- init_config();
1930
+ init_config2();
1577
1931
  init_corekit();
1578
1932
  init_sandbox();
1579
1933
  init_utils();
1580
1934
  }
1581
1935
  });
1582
1936
 
1937
+ // src/commands/fetch.ts
1938
+ var fetch_exports = {};
1939
+ __export(fetch_exports, {
1940
+ fetch: () => fetch
1941
+ });
1942
+ import { execa as execa5 } from "execa";
1943
+ import path13 from "path";
1944
+ import pc6 from "picocolors";
1945
+ async function fetch(version, options = {}) {
1946
+ const fetchSpinner = createSpinner(`\u6B63\u5728\u83B7\u53D6\u5185\u6838\u7248\u672C ${pc6.cyan(version)}...`).start();
1947
+ const versionPath = await Sandbox.prepare(version, true);
1948
+ fetchSpinner.succeed(`\u5185\u6838\u7248\u672C ${pc6.cyan(version)} \u83B7\u53D6\u6210\u529F`);
1949
+ if (options.pack) {
1950
+ const packSpinner = createSpinner("\u6B63\u5728\u6253\u5305\u79BB\u7EBF\u8D44\u6E90...").start();
1951
+ const tgzName = `chatbi-core-${version}.tgz`;
1952
+ const tgzPath = path13.resolve(process.cwd(), tgzName);
1953
+ await execa5("tar", [
1954
+ "-czf",
1955
+ tgzPath,
1956
+ "-C",
1957
+ path13.dirname(versionPath),
1958
+ path13.basename(versionPath)
1959
+ ]);
1960
+ packSpinner.succeed("\u79BB\u7EBF\u8D44\u6E90\u6253\u5305\u5B8C\u6210");
1961
+ printBox(
1962
+ `${pc6.green(pc6.bold("\u2728 \u79BB\u7EBF\u5305\u5DF2\u751F\u6210!"))}
1963
+
1964
+ ${pc6.white("\u6587\u4EF6\u8DEF\u5F84: ")} ${pc6.cyan(tgzPath)}
1965
+ ${pc6.white("\u5B89\u88C5\u547D\u4EE4: ")} ${pc6.gray(`chatbi install ${tgzName}`)}`,
1966
+ "Pack Success"
1967
+ );
1968
+ } else {
1969
+ logger.success(`\u5185\u6838\u7248\u672C ${pc6.cyan(version)} \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002`);
1970
+ }
1971
+ }
1972
+ var init_fetch = __esm({
1973
+ "src/commands/fetch.ts"() {
1974
+ "use strict";
1975
+ init_esm_shims();
1976
+ init_sandbox();
1977
+ init_utils();
1978
+ }
1979
+ });
1980
+
1981
+ // src/commands/install.ts
1982
+ var install_exports = {};
1983
+ __export(install_exports, {
1984
+ install: () => install
1985
+ });
1986
+ import { execa as execa6 } from "execa";
1987
+ import fs11 from "fs-extra";
1988
+ import path14 from "path";
1989
+ import pc7 from "picocolors";
1990
+ async function install(target) {
1991
+ if (target.endsWith(".tgz") && fs11.existsSync(target)) {
1992
+ const spinner = createSpinner(`\u6B63\u5728\u5B89\u88C5\u672C\u5730\u79BB\u7EBF\u5305: ${pc7.bold(target)}...`).start();
1993
+ try {
1994
+ const tgzPath = path14.resolve(target);
1995
+ const match = path14.basename(target).match(/chatbi-core-(.+)\.tgz/);
1996
+ let version = "unknown";
1997
+ if (match) {
1998
+ version = match[1];
1999
+ }
2000
+ if (version === "unknown") {
2001
+ spinner.warn("\u65E0\u6CD5\u4ECE\u6587\u4EF6\u540D\u8BC6\u522B\u7248\u672C\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u65F6\u95F4\u6233\u4F5C\u4E3A\u7248\u672C\u53F7");
2002
+ version = `local-${Date.now()}`;
2003
+ }
2004
+ const versionRoot = Sandbox.getVersionRoot();
2005
+ await fs11.ensureDir(versionRoot);
2006
+ spinner.text = "\u6B63\u5728\u89E3\u538B\u6587\u4EF6...";
2007
+ await execa6("tar", ["-xzf", tgzPath, "-C", versionRoot]);
2008
+ spinner.succeed(`\u672C\u5730\u5305\u5DF2\u5B89\u88C5\u81F3\u6C99\u7BB1: ${version}`);
2009
+ spinner.text = "\u6B63\u5728\u51C6\u5907\u5185\u6838\u73AF\u5883...";
2010
+ await Sandbox.prepare(version);
2011
+ spinner.succeed("\u5185\u6838\u73AF\u5883\u5C31\u7EEA");
2012
+ printBox(
2013
+ pc7.green(pc7.bold("\u2728 \u672C\u5730\u5185\u6838\u5B89\u88C5\u6210\u529F!")) + "\n\n" + pc7.white("\u7248\u672C: ") + pc7.cyan(version) + "\n" + pc7.white("\u8DEF\u5F84: ") + pc7.gray(Sandbox.getVersionPath(version)),
2014
+ "Install Success"
2015
+ );
2016
+ } catch (e) {
2017
+ spinner.fail("\u5B89\u88C5\u5931\u8D25");
2018
+ throw e;
2019
+ }
2020
+ } else {
2021
+ const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
2022
+ await fetch2(target);
2023
+ }
2024
+ }
2025
+ var init_install = __esm({
2026
+ "src/commands/install.ts"() {
2027
+ "use strict";
2028
+ init_esm_shims();
2029
+ init_sandbox();
2030
+ init_utils();
2031
+ }
2032
+ });
2033
+
1583
2034
  // src/commands/sync.ts
1584
2035
  var sync_exports = {};
1585
2036
  __export(sync_exports, {
1586
2037
  sync: () => sync
1587
2038
  });
1588
- import fs11 from "fs-extra";
1589
- import path13 from "path";
2039
+ import fs12 from "fs-extra";
2040
+ import path15 from "path";
1590
2041
  import pc8 from "picocolors";
1591
2042
  async function sync(options = {}) {
1592
2043
  const cwd = options.cwd || process.cwd();
1593
- const pkgPath = path13.join(cwd, "package.json");
1594
- if (!fs11.existsSync(pkgPath)) {
2044
+ const pkgPath = path15.join(cwd, "package.json");
2045
+ if (!fs12.existsSync(pkgPath)) {
1595
2046
  logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u3002");
1596
2047
  return;
1597
2048
  }
1598
- const pkg = await fs11.readJson(pkgPath);
2049
+ const pkg = await fs12.readJson(pkgPath);
1599
2050
  let version = options.version;
1600
2051
  if (!version) {
1601
2052
  version = await CoreKit.resolveVersion(cwd);
@@ -1610,8 +2061,8 @@ async function sync(options = {}) {
1610
2061
  await Sandbox.prepare(version, options.force);
1611
2062
  mainSpinner.text = "\u6B63\u5728\u751F\u6210\u865A\u62DF\u4E0A\u4E0B\u6587...";
1612
2063
  if (options.version) {
1613
- const versionFilePath = path13.join(cwd, ".chatbi-version");
1614
- await fs11.writeFile(versionFilePath, version, "utf-8");
2064
+ const versionFilePath = path15.join(cwd, ".chatbi-version");
2065
+ await fs12.writeFile(versionFilePath, version, "utf-8");
1615
2066
  }
1616
2067
  await Sandbox.injectContext(cwd, version);
1617
2068
  let modified = false;
@@ -1633,7 +2084,7 @@ async function sync(options = {}) {
1633
2084
  if (modified) {
1634
2085
  pkg.dependencies = deps;
1635
2086
  pkg.devDependencies = devDeps;
1636
- await fs11.writeJson(pkgPath, pkg, { spaces: 2 });
2087
+ await fs12.writeJson(pkgPath, pkg, { spaces: 2 });
1637
2088
  mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210 (\u4F9D\u8D56\u5DF2\u4F18\u5316)");
1638
2089
  } else {
1639
2090
  mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210");
@@ -1660,63 +2111,18 @@ var init_sync = __esm({
1660
2111
  }
1661
2112
  });
1662
2113
 
1663
- // src/commands/fetch.ts
1664
- var fetch_exports = {};
1665
- __export(fetch_exports, {
1666
- fetch: () => fetch
1667
- });
1668
- import { execa as execa4 } from "execa";
1669
- import path15 from "path";
1670
- import pc10 from "picocolors";
1671
- async function fetch(version, options = {}) {
1672
- const fetchSpinner = createSpinner(`\u6B63\u5728\u83B7\u53D6\u5185\u6838\u7248\u672C ${pc10.cyan(version)}...`).start();
1673
- const versionPath = await Sandbox.prepare(version, true);
1674
- fetchSpinner.succeed(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u83B7\u53D6\u6210\u529F`);
1675
- if (options.pack) {
1676
- const packSpinner = createSpinner("\u6B63\u5728\u6253\u5305\u79BB\u7EBF\u8D44\u6E90...").start();
1677
- const tgzName = `chatbi-core-${version}.tgz`;
1678
- const tgzPath = path15.resolve(process.cwd(), tgzName);
1679
- await execa4("tar", [
1680
- "-czf",
1681
- tgzPath,
1682
- "-C",
1683
- path15.dirname(versionPath),
1684
- path15.basename(versionPath)
1685
- ]);
1686
- packSpinner.succeed("\u79BB\u7EBF\u8D44\u6E90\u6253\u5305\u5B8C\u6210");
1687
- printBox(
1688
- `${pc10.green(pc10.bold("\u2728 \u79BB\u7EBF\u5305\u5DF2\u751F\u6210!"))}
1689
-
1690
- ${pc10.white("\u6587\u4EF6\u8DEF\u5F84: ")} ${pc10.cyan(tgzPath)}
1691
- ${pc10.white("\u5B89\u88C5\u547D\u4EE4: ")} ${pc10.gray(`chatbi install ${tgzName}`)}`,
1692
- "Pack Success"
1693
- );
1694
- } else {
1695
- logger.success(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002`);
1696
- }
1697
- }
1698
- var init_fetch = __esm({
1699
- "src/commands/fetch.ts"() {
1700
- "use strict";
1701
- init_esm_shims();
1702
- init_sandbox();
1703
- init_utils();
1704
- }
1705
- });
1706
-
1707
2114
  // src/commands/init.ts
1708
2115
  var init_exports = {};
1709
2116
  __export(init_exports, {
1710
2117
  init: () => init
1711
2118
  });
1712
- import fs14 from "fs-extra";
1713
- import path17 from "path";
1714
- import pc12 from "picocolors";
1715
- import prompts4 from "prompts";
2119
+ import fs13 from "fs-extra";
2120
+ import path16 from "path";
2121
+ import pc9 from "picocolors";
2122
+ import prompts from "prompts";
1716
2123
  async function init(options) {
1717
- let { name, pluginType = "business", theme = DEFAULT_CONFIG.THEME, projectType, includeApp, includePlugin, cwd } = options;
1718
- const response = await prompts4([
1719
- // ... (prompts remain the same)
2124
+ let { name, pluginType = "business", theme = DEFAULT_CONFIG.THEME, projectType, includeApp, includePlugin, cwd, force } = options;
2125
+ const response = await prompts([
1720
2126
  {
1721
2127
  type: name ? null : "text",
1722
2128
  name: "projectName",
@@ -1785,32 +2191,61 @@ async function init(options) {
1785
2191
  const isAppIncluded = finalIncludeApp;
1786
2192
  const isPluginIncluded = finalIncludePlugin;
1787
2193
  const rootDir = cwd || process.cwd();
1788
- const targetDir = path17.resolve(rootDir, name);
1789
- if (fs14.existsSync(targetDir)) {
1790
- logger.error(`\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728\u3002`);
1791
- return;
2194
+ const targetDir = path16.resolve(rootDir, name);
2195
+ if (fs13.existsSync(targetDir)) {
2196
+ if (force) {
2197
+ await fs13.remove(targetDir);
2198
+ } else {
2199
+ const { action } = await prompts({
2200
+ type: "select",
2201
+ name: "action",
2202
+ message: `\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u9009\u62E9\u64CD\u4F5C:`,
2203
+ choices: [
2204
+ { title: "\u8986\u76D6 (Overwrite)", value: "overwrite", description: "\u6E05\u7A7A\u539F\u76EE\u5F55\u5E76\u91CD\u65B0\u521B\u5EFA" },
2205
+ { title: "\u5408\u5E76 (Merge)", value: "merge", description: "\u4FDD\u7559\u539F\u6709\u6587\u4EF6\uFF0C\u4EC5\u8986\u76D6\u51B2\u7A81\u6587\u4EF6" },
2206
+ { title: "\u53D6\u6D88 (Cancel)", value: "cancel" }
2207
+ ]
2208
+ });
2209
+ if (action === "cancel" || !action) {
2210
+ logger.warn("\u5DF2\u53D6\u6D88\u521D\u59CB\u5316");
2211
+ return;
2212
+ }
2213
+ if (action === "overwrite") {
2214
+ const { confirm } = await prompts({
2215
+ type: "confirm",
2216
+ name: "confirm",
2217
+ message: "\u786E\u5B9A\u8981\u6E05\u7A7A\u76EE\u6807\u76EE\u5F55\u5417\uFF1F\u6B64\u64CD\u4F5C\u4E0D\u53EF\u64A4\u9500\u3002",
2218
+ initial: false
2219
+ });
2220
+ if (!confirm) {
2221
+ logger.warn("\u5DF2\u53D6\u6D88\u8986\u76D6");
2222
+ return;
2223
+ }
2224
+ await fs13.remove(targetDir);
2225
+ }
2226
+ }
1792
2227
  }
1793
- logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${pc12.bold(name)}...`);
1794
- logger.info(pc12.gray(`\u7C7B\u578B: ${projectType} | \u4E3B\u9898: ${theme || "N/A"}`));
1795
- console.log("");
2228
+ logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${pc9.bold(name)}...`);
2229
+ logger.info(pc9.gray(`\u7C7B\u578B: ${projectType} | \u4E3B\u9898: ${theme || "N/A"}`));
2230
+ logger.info("");
1796
2231
  try {
1797
2232
  const myCliRoot = await getCliRoot();
1798
- const cliPkg = await fs14.readJson(path17.join(myCliRoot, "package.json"));
2233
+ const cliPkg = await fs13.readJson(path16.join(myCliRoot, "package.json"));
1799
2234
  const cliVersion = cliPkg.version;
1800
- const config = { coreSource: "npm" };
1801
- const kernelVersionFile = path17.join(myCliRoot, SANDBOX_CONFIG.LOCK_FILE);
1802
- if (fs14.existsSync(kernelVersionFile)) {
1803
- config.coreVersion = (await fs14.readFile(kernelVersionFile, "utf-8")).trim();
2235
+ const config4 = { coreSource: "npm" };
2236
+ const kernelVersionFile = path16.join(myCliRoot, SANDBOX_CONFIG.LOCK_FILE);
2237
+ if (fs13.existsSync(kernelVersionFile)) {
2238
+ config4.coreVersion = (await fs13.readFile(kernelVersionFile, "utf-8")).trim();
1804
2239
  }
1805
- const kernelVersion = await ConfigManager.resolveCoreDependency(config);
2240
+ const kernelVersion = await ConfigManager.resolveCoreDependency(config4);
1806
2241
  const renderTemplate = async (templateName, destDir, extraData = {}) => {
1807
- const srcDir = path17.join(myCliRoot, "templates", templateName);
1808
- if (!fs14.existsSync(srcDir)) {
2242
+ const srcDir = path16.join(myCliRoot, "templates", templateName);
2243
+ if (!fs13.existsSync(srcDir)) {
1809
2244
  throw new Error(`\u627E\u4E0D\u5230\u6A21\u677F: ${templateName}\uFF0C\u8BF7\u68C0\u67E5\u8DEF\u5F84 ${srcDir} \u662F\u5426\u6B63\u786E\u3002`);
1810
2245
  }
1811
- await fs14.ensureDir(destDir);
2246
+ await fs13.ensureDir(destDir);
1812
2247
  const templateData = {
1813
- name: path17.basename(destDir),
2248
+ name: path16.basename(destDir),
1814
2249
  projectName: name,
1815
2250
  // Original project name from CLI argument
1816
2251
  projectTitle: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" "),
@@ -1838,12 +2273,12 @@ async function init(options) {
1838
2273
  await renderTemplate("monorepo", targetDir, { name });
1839
2274
  if (isAppIncluded) {
1840
2275
  spinner.text = "\u6B63\u5728\u751F\u6210 Host App...";
1841
- const appDir = path17.join(targetDir, "apps", "main");
2276
+ const appDir = path16.join(targetDir, "apps", "main");
1842
2277
  await renderTemplate("app", appDir, { name: "@chatbi-v/main" });
1843
2278
  }
1844
2279
  if (isPluginIncluded) {
1845
2280
  spinner.text = "\u6B63\u5728\u751F\u6210 Demo Plugin...";
1846
- const pluginDir = path17.join(targetDir, "plugins", "plugin-demo");
2281
+ const pluginDir = path16.join(targetDir, "plugins", "plugin-demo");
1847
2282
  await renderTemplate("plugin", pluginDir, {
1848
2283
  name: "@chatbi-v/plugin-demo",
1849
2284
  pluginId: "demo",
@@ -1870,42 +2305,35 @@ async function init(options) {
1870
2305
  pluginPackageName: `@chatbi-v/plugin-${name}`,
1871
2306
  pluginVersion: "0.1.0",
1872
2307
  pluginDisplayName: name,
1873
- pluginDescription: "A ChatBI-V Plugin",
1874
- pluginClassName: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(""),
2308
+ pluginDescription: "\u8FD9\u662F\u4E00\u4E2A\u521D\u59CB\u5316\u7684\u793A\u4F8B\u63D2\u4EF6",
2309
+ pluginClassName: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Plugin",
1875
2310
  pluginPath: name,
1876
2311
  pluginFolderName: name,
1877
- className: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("")
2312
+ className: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join("") + "Plugin"
1878
2313
  });
1879
2314
  }
1880
- spinner.succeed("\u9879\u76EE\u7ED3\u6784\u751F\u6210\u5B8C\u6210");
1881
- const syncSpinner = createSpinner("\u6B63\u5728\u540C\u6B65\u5185\u6838\u4F9D\u8D56...").start();
1882
- await sync({ cwd: targetDir, silent: true });
1883
- syncSpinner.succeed("\u5185\u6838\u4F9D\u8D56\u540C\u6B65\u5B8C\u6210");
1884
- const configSpinner = createSpinner("\u6B63\u5728\u751F\u6210\u9879\u76EE\u914D\u7F6E...").start();
1885
- const cliConfig = {
1886
- coreVersion: kernelVersion
1887
- };
1888
- await fs14.writeJson(path17.join(targetDir, "chatbi.config.json"), cliConfig, { spaces: 2 });
1889
- configSpinner.succeed("\u9879\u76EE\u914D\u7F6E\u751F\u6210\u5B8C\u6210");
2315
+ spinner.succeed(pc9.green(`\u9879\u76EE ${name} \u521D\u59CB\u5316\u5B8C\u6210\uFF01`));
2316
+ logger.info("");
2317
+ logger.info(pc9.cyan("\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u73AF\u5883..."));
2318
+ const projectCwd = targetDir;
2319
+ await sync({ force: true, cwd: projectCwd });
2320
+ logger.info("");
1890
2321
  printBox(
1891
- `${pc12.green(pc12.bold("\u2728 \u9879\u76EE\u5DF2\u6210\u529F\u521B\u5EFA!"))}
2322
+ `${pc9.green("\u{1F389} \u9879\u76EE\u51C6\u5907\u5C31\u7EEA\uFF01")}
1892
2323
 
1893
- ${pc12.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
1894
- ${pc12.cyan(` cd ${name}`)}
1895
- ${pc12.cyan(" pnpm install")}
1896
- ${pc12.cyan(" pnpm dev")}`,
1897
- "Success"
2324
+ cd ${name}
2325
+ chatbi dev`,
2326
+ "Happy Coding"
1898
2327
  );
1899
- } catch (error) {
1900
- logger.error("\u521D\u59CB\u5316\u5931\u8D25", error);
1901
- throw error;
2328
+ } catch (e) {
2329
+ logger.error(`\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`);
1902
2330
  }
1903
2331
  }
1904
2332
  var init_init = __esm({
1905
2333
  "src/commands/init.ts"() {
1906
2334
  "use strict";
1907
2335
  init_esm_shims();
1908
- init_config();
2336
+ init_config2();
1909
2337
  init_constants();
1910
2338
  init_SandboxRenderer();
1911
2339
  init_utils();
@@ -1913,179 +2341,30 @@ var init_init = __esm({
1913
2341
  }
1914
2342
  });
1915
2343
 
1916
- // src/commands/bench.ts
1917
- var bench_exports = {};
1918
- __export(bench_exports, {
1919
- bench: () => bench
2344
+ // src/commands/add.ts
2345
+ var add_exports = {};
2346
+ __export(add_exports, {
2347
+ add: () => add
1920
2348
  });
1921
- import fs17 from "fs-extra";
1922
- import os3 from "os";
1923
- import path20 from "path";
1924
- import pc15 from "picocolors";
1925
- async function bench() {
1926
- logger.info("\u6B63\u5728\u542F\u52A8 CLI \u6027\u80FD\u57FA\u51C6\u6D4B\u8BD5...");
1927
- const results = [];
1928
- const tmpDir = path20.join(os3.tmpdir(), `chatbi-bench-${Date.now()}`);
1929
- await fs17.ensureDir(tmpDir);
1930
- try {
1931
- const initSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u521D\u59CB\u5316\u63D2\u4EF6\u9879\u76EE (init)...").start();
1932
- const startInit = Date.now();
1933
- const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
1934
- const testProjDir = path20.join(tmpDir, "bench-proj");
1935
- await init2({ name: "bench-proj", projectType: "plugin", cwd: tmpDir });
1936
- const endInit = Date.now();
1937
- const initTime = (endInit - startInit) / 1e3;
1938
- initSpinner.succeed(`\u521D\u59CB\u5316\u5B8C\u6210: ${pc15.cyan(initTime.toFixed(2) + "s")}`);
1939
- results.push({
1940
- scene: "\u521D\u59CB\u5316\u63D2\u4EF6\u9879\u76EE (init)",
1941
- target: "\u2264 5.0 s",
1942
- actual: `${initTime.toFixed(2)} s`
1943
- });
1944
- const syncSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u6C99\u7BB1\u73AF\u5883\u540C\u6B65 (sync)...").start();
1945
- const startSync = Date.now();
1946
- const { sync: sync2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
1947
- await sync2({ cwd: testProjDir });
1948
- const endSync = Date.now();
1949
- const syncTime = (endSync - startSync) / 1e3;
1950
- syncSpinner.succeed(`\u540C\u6B65\u5B8C\u6210: ${pc15.cyan(syncTime.toFixed(2) + "s")}`);
1951
- results.push({
1952
- scene: "\u6C99\u7BB1\u73AF\u5883\u540C\u6B65 (sync)",
1953
- target: "\u2264 2.0 s",
1954
- actual: `${syncTime.toFixed(2)} s`
1955
- });
1956
- const buildSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u63D2\u4EF6\u9879\u76EE\u6784\u5EFA (build)...").start();
1957
- const startBuild = Date.now();
1958
- const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
1959
- const originalCwd = process.cwd();
1960
- process.chdir(testProjDir);
1961
- await build2({ watch: false });
1962
- process.chdir(originalCwd);
1963
- const endBuild = Date.now();
1964
- const buildTime = (endBuild - startBuild) / 1e3;
1965
- buildSpinner.succeed(`\u6784\u5EFA\u5B8C\u6210: ${pc15.cyan(buildTime.toFixed(2) + "s")}`);
1966
- results.push({
1967
- scene: "\u63D2\u4EF6\u9879\u76EE\u6784\u5EFA (build)",
1968
- target: "\u2264 10.0 s",
1969
- actual: `${buildTime.toFixed(2)} s`
1970
- });
1971
- printBox(
1972
- `${pc15.green(pc15.bold("\u2728 \u57FA\u51C6\u6D4B\u8BD5\u5B8C\u6210!"))}
1973
-
1974
- ` + results.map((r) => `${pc15.white(r.scene.padEnd(20))}: ${pc15.cyan(r.actual)} (\u76EE\u6807 ${r.target})`).join("\n"),
1975
- "Benchmark Results"
1976
- );
1977
- } finally {
1978
- await fs17.remove(tmpDir);
1979
- }
1980
- }
1981
- var init_bench = __esm({
1982
- "src/commands/bench.ts"() {
1983
- "use strict";
1984
- init_esm_shims();
1985
- init_utils();
1986
- }
1987
- });
1988
-
1989
- // src/index.ts
1990
- init_esm_shims();
1991
- import boxen2 from "boxen";
1992
- import cac from "cac";
1993
- import figlet from "figlet";
1994
- import gradient from "gradient-string";
1995
- import pc16 from "picocolors";
1996
-
1997
- // package.json
1998
- var package_default = {
1999
- name: "@chatbi-v/cli",
2000
- version: "2.1.10",
2001
- description: "Standardized CLI tooling for ChatBI Monorepo",
2002
- type: "module",
2003
- main: "dist/index.js",
2004
- module: "dist/index.js",
2005
- types: "dist/index.d.ts",
2006
- exports: {
2007
- ".": {
2008
- types: "./dist/index.d.ts",
2009
- import: "./dist/index.js"
2010
- },
2011
- "./package.json": "./package.json"
2012
- },
2013
- bin: {
2014
- "chatbi-cli": "./bin/chatbi-cli.js"
2015
- },
2016
- files: [
2017
- "dist",
2018
- "bin",
2019
- "templates"
2020
- ],
2021
- publishConfig: {
2022
- access: "public"
2023
- },
2024
- scripts: {
2025
- build: "tsup",
2026
- dev: "tsup --watch",
2027
- test: "vitest"
2028
- },
2029
- dependencies: {
2030
- boxen: "^8.0.1",
2031
- cac: "^6.7.14",
2032
- execa: "^8.0.1",
2033
- "fast-glob": "^3.3.3",
2034
- figlet: "^1.9.4",
2035
- "fs-extra": "^11.2.0",
2036
- "gradient-string": "^3.0.0",
2037
- handlebars: "^4.7.8",
2038
- jiti: "^2.6.1",
2039
- ora: "^7.0.1",
2040
- picocolors: "^1.0.0",
2041
- prompts: "^2.4.2",
2042
- tsup: "^8.5.1",
2043
- typescript: "^5.0.0",
2044
- vite: "^5.4.21"
2045
- },
2046
- devDependencies: {
2047
- "@types/boxen": "^3.0.5",
2048
- "@types/figlet": "^1.7.0",
2049
- "@types/fs-extra": "^11.0.0",
2050
- "@types/gradient-string": "^1.1.6",
2051
- "@types/node": "^20.0.0",
2052
- "@types/prompts": "^2.4.9",
2053
- "@vitest/coverage-v8": "1.6.1",
2054
- tsup: "^8.5.1",
2055
- vitest: "^1.0.0"
2056
- }
2057
- };
2058
-
2059
- // src/commands/add.ts
2060
- init_esm_shims();
2061
- init_config();
2062
- init_constants();
2063
- init_SandboxRenderer();
2064
- init_utils();
2065
- import fs4 from "fs-extra";
2066
- import { createRequire as createRequire2 } from "module";
2067
- import path6 from "path";
2068
- import pc2 from "picocolors";
2069
- import prompts from "prompts";
2070
- import { fileURLToPath as fileURLToPath3 } from "url";
2071
- var _require2 = createRequire2(import.meta.url);
2072
- var _filename2 = fileURLToPath3(import.meta.url);
2073
- var _dirname2 = path6.dirname(_filename2);
2349
+ import fs14 from "fs-extra";
2350
+ import path17 from "path";
2351
+ import pc10 from "picocolors";
2352
+ import prompts2 from "prompts";
2074
2353
  async function add(options) {
2075
2354
  let { name, type, displayName, description } = options;
2076
2355
  const cwd = process.cwd();
2077
- const pkgPath = path6.join(cwd, "package.json");
2078
- if (!fs4.existsSync(pkgPath)) {
2356
+ const pkgPath = path17.join(cwd, "package.json");
2357
+ if (!fs14.existsSync(pkgPath)) {
2079
2358
  logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
2080
2359
  return;
2081
2360
  }
2082
- const pkg = await fs4.readJson(pkgPath);
2361
+ const pkg = await fs14.readJson(pkgPath);
2083
2362
  const isMonorepo = pkg.workspaces && (pkg.workspaces.includes("plugins/*") || pkg.workspaces.packages?.includes("plugins/*"));
2084
2363
  if (!isMonorepo) {
2085
2364
  logger.error("\u5F53\u524D\u4E0D\u662F Monorepo \u9879\u76EE\uFF0C\u65E0\u6CD5\u6DFB\u52A0\u63D2\u4EF6 (\u8BF7\u5728\u5305\u542B plugins/ \u5DE5\u4F5C\u7A7A\u95F4\u7684\u9879\u76EE\u4E2D\u8FD0\u884C)");
2086
2365
  process.exit(1);
2087
2366
  }
2088
- const response = await prompts([
2367
+ const response = await prompts2([
2089
2368
  {
2090
2369
  type: name ? null : "text",
2091
2370
  name: "pluginName",
@@ -2130,16 +2409,16 @@ async function add(options) {
2130
2409
  cleanName = cleanName.replace(/-plugin$/, "");
2131
2410
  }
2132
2411
  const folderName = cleanName.startsWith("plugin-") ? cleanName : `plugin-${cleanName}`;
2133
- const pluginDir = path6.resolve(cwd, "plugins", folderName);
2134
- if (fs4.existsSync(pluginDir)) {
2412
+ const pluginDir = path17.resolve(cwd, "plugins", folderName);
2413
+ if (fs14.existsSync(pluginDir)) {
2135
2414
  logger.error(`\u63D2\u4EF6\u76EE\u5F55 ${folderName} \u5DF2\u5B58\u5728\u3002`);
2136
2415
  return;
2137
2416
  }
2138
- const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${pc2.bold(name)}...`).start();
2417
+ const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${pc10.bold(name)}...`).start();
2139
2418
  const targetDir = pluginDir;
2140
2419
  spinner.text = "\u6B63\u5728\u52A0\u8F7D\u914D\u7F6E...";
2141
- const config = await ConfigManager.loadConfig(cwd);
2142
- const corePath = await ConfigManager.resolveCoreDependency(config, pluginDir);
2420
+ const config4 = await ConfigManager.loadConfig(cwd);
2421
+ const corePath = await ConfigManager.resolveCoreDependency(config4, pluginDir);
2143
2422
  const data = {
2144
2423
  // 兼容旧模板
2145
2424
  name: `@chatbi-v/${folderName}`,
@@ -2161,95 +2440,61 @@ async function add(options) {
2161
2440
  tsconfigPath: `../../${SANDBOX_CONFIG.DIRS.CACHE}/tsconfig.json`
2162
2441
  };
2163
2442
  const myCliRoot = await getCliRoot();
2164
- let templateDir = myCliRoot ? path6.join(myCliRoot, "templates/plugin") : "";
2443
+ let templateDir = myCliRoot ? path17.join(myCliRoot, "templates/plugin") : "";
2165
2444
  if (process.env.NODE_ENV === "test" && !templateDir) {
2166
2445
  templateDir = "/mock/templates/plugin";
2167
2446
  }
2168
2447
  if (process.env.NODE_ENV === "test") {
2169
- spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2170
- console.log(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2171
- console.log("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!");
2448
+ spinner.succeed(`\u63D2\u4EF6 ${pc10.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2449
+ logger.success(`\u63D2\u4EF6 ${pc10.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2450
+ logger.success("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!");
2172
2451
  return;
2173
2452
  }
2174
- if (!templateDir || !fs4.existsSync(templateDir)) {
2453
+ if (!templateDir || !fs14.existsSync(templateDir)) {
2175
2454
  spinner.fail("\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F");
2176
2455
  throw new Error(`\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F: ${templateDir || "undefined"}`);
2177
2456
  }
2178
2457
  spinner.text = "\u6B63\u5728\u751F\u6210\u63D2\u4EF6\u6587\u4EF6...";
2179
2458
  await SandboxRenderer.renderDirectory(templateDir, targetDir, data);
2180
- spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2459
+ spinner.succeed(`\u63D2\u4EF6 ${pc10.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2181
2460
  printBox(
2182
- `${pc2.green(pc2.bold("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!"))}
2461
+ `${pc10.green(pc10.bold("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!"))}
2183
2462
 
2184
- ${pc2.white("\u9879\u76EE\u8DEF\u5F84: ")} ${pc2.cyan(`plugins/${folderName}`)}
2185
- ${pc2.white("\u63D2\u4EF6 ID: ")} ${pc2.cyan(cleanName)}
2186
- ${pc2.white("\u63D2\u4EF6\u7C7B\u578B: ")} ${pc2.cyan(type)}
2463
+ ${pc10.white("\u9879\u76EE\u8DEF\u5F84: ")} ${pc10.cyan(`plugins/${folderName}`)}
2464
+ ${pc10.white("\u63D2\u4EF6 ID: ")} ${pc10.cyan(cleanName)}
2465
+ ${pc10.white("\u63D2\u4EF6\u7C7B\u578B: ")} ${pc10.cyan(type)}
2187
2466
 
2188
- ${pc2.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
2189
- ${pc2.cyan(" pnpm dev")} \u542F\u52A8\u5F00\u53D1\u73AF\u5883\u67E5\u770B\u6548\u679C`,
2467
+ ${pc10.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
2468
+ ${pc10.cyan(" pnpm dev")} \u542F\u52A8\u5F00\u53D1\u73AF\u5883\u67E5\u770B\u6548\u679C`,
2190
2469
  "Plugin Created"
2191
2470
  );
2192
2471
  }
2193
-
2194
- // src/index.ts
2195
- init_build();
2196
-
2197
- // src/commands/clean.ts
2198
- init_esm_shims();
2199
- init_sandbox();
2200
- async function clean(options) {
2201
- const cwd = process.cwd();
2202
- await Sandbox.clean(cwd, options.deep);
2203
- }
2204
-
2205
- // src/commands/dev.ts
2206
- init_esm_shims();
2207
- init_corekit();
2208
- async function dev(options = {}) {
2209
- const cwd = process.cwd();
2210
- await CoreKit.startDev(cwd, options);
2211
- }
2212
-
2213
- // src/commands/discover.ts
2214
- init_esm_shims();
2215
- init_corekit();
2216
- init_utils();
2217
- import pc7 from "picocolors";
2218
- async function discover() {
2219
- const cwd = process.cwd();
2220
- const spinner = createSpinner("\u6B63\u5728\u626B\u63CF\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6...").start();
2221
- const plugins = await CoreKit.discoverPlugins(cwd);
2222
- if (plugins.length === 0) {
2223
- spinner.warn("\u672A\u53D1\u73B0\u4EFB\u4F55\u63D2\u4EF6");
2224
- logger.info(pc7.gray("\u8BF7\u786E\u4FDD\u63D2\u4EF6\u4F4D\u4E8E plugins/ \u76EE\u5F55\u4E0B\uFF0C\u4E14\u5305\u542B package.json\u3002"));
2225
- } else {
2226
- spinner.succeed(`\u53D1\u73B0\u4E86 ${pc7.cyan(plugins.length)} \u4E2A\u63D2\u4EF6`);
2227
- const pluginList = plugins.map((p) => `- ${pc7.bold(p.name)} ${pc7.gray(`(${p.id})`)}
2228
- ${pc7.gray(p.path)}`).join("\n\n");
2229
- printBox(
2230
- `${pc7.green(pc7.bold("\u2728 \u63D2\u4EF6\u626B\u63CF\u7ED3\u679C"))}
2231
-
2232
- ${pluginList}`,
2233
- "Plugin Discovery"
2234
- );
2472
+ var init_add = __esm({
2473
+ "src/commands/add.ts"() {
2474
+ "use strict";
2475
+ init_esm_shims();
2476
+ init_config2();
2477
+ init_constants();
2478
+ init_SandboxRenderer();
2479
+ init_utils();
2235
2480
  }
2236
- }
2481
+ });
2237
2482
 
2238
2483
  // src/commands/doctor.ts
2239
- init_esm_shims();
2240
- init_corekit();
2241
- init_sandbox();
2242
- init_utils();
2484
+ var doctor_exports = {};
2485
+ __export(doctor_exports, {
2486
+ doctor: () => doctor
2487
+ });
2243
2488
  import glob from "fast-glob";
2244
- import fs12 from "fs-extra";
2245
- import path14 from "path";
2246
- import pc9 from "picocolors";
2489
+ import fs15 from "fs-extra";
2490
+ import path18 from "path";
2491
+ import pc11 from "picocolors";
2247
2492
  async function doctor(options = {}) {
2248
2493
  logger.info("\u6B63\u5728\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5...\n");
2249
2494
  const cwd = process.cwd();
2250
2495
  let hasIssues = false;
2251
2496
  const issues = [];
2252
- logger.info(pc9.bold("Step 1: \u68C0\u67E5\u57FA\u7840\u73AF\u5883..."));
2497
+ logger.info(pc11.bold("Step 1: \u68C0\u67E5\u57FA\u7840\u73AF\u5883..."));
2253
2498
  const nodeVersion = process.version;
2254
2499
  if (parseInt(nodeVersion.slice(1).split(".")[0]) < 18) {
2255
2500
  logger.error(`Node.js \u7248\u672C\u592A\u4F4E: ${nodeVersion} (\u8981\u6C42 >=18)`);
@@ -2259,47 +2504,55 @@ async function doctor(options = {}) {
2259
2504
  logger.success(`Node.js \u7248\u672C: ${nodeVersion}`);
2260
2505
  }
2261
2506
  try {
2262
- const { execa: execa7 } = await import("execa");
2263
- const { stdout: pnpmVer } = await execa7("pnpm", ["-v"]);
2507
+ const { execa: execa8 } = await import("execa");
2508
+ const { stdout: pnpmVer } = await execa8("pnpm", ["-v"]);
2264
2509
  logger.success(`pnpm \u7248\u672C: ${pnpmVer}`);
2265
- } catch (e) {
2510
+ } catch {
2266
2511
  logger.warn("\u672A\u68C0\u6D4B\u5230 pnpm\uFF0C\u5EFA\u8BAE\u5B89\u88C5\u4EE5\u83B7\u5F97\u6700\u4F73\u4F53\u9A8C");
2267
2512
  }
2268
- logger.info(pc9.bold("\nStep 2: \u68C0\u67E5\u5185\u6838\u6C99\u7BB1\u73AF\u5883..."));
2513
+ if (fs15.existsSync(path18.join(cwd, ".git"))) {
2514
+ try {
2515
+ const { execa: execa8 } = await import("execa");
2516
+ const { stdout } = await execa8("git", ["status", "--porcelain"], { cwd });
2517
+ if (stdout.trim()) {
2518
+ logger.warn("Git \u5DE5\u4F5C\u533A\u4E0D\u5E72\u51C0\uFF0C\u5EFA\u8BAE\u5728\u63D0\u4EA4\u540E\u8FDB\u884C\u64CD\u4F5C");
2519
+ } else {
2520
+ logger.success("Git \u5DE5\u4F5C\u533A\u5E72\u51C0");
2521
+ }
2522
+ } catch {
2523
+ }
2524
+ }
2525
+ logger.info(pc11.bold("\nStep 2: \u68C0\u67E5\u5185\u6838\u6C99\u7BB1\u73AF\u5883..."));
2269
2526
  const version = await CoreKit.resolveVersion(cwd);
2270
2527
  const versionPath = Sandbox.getVersionPath(version);
2271
- if (!fs12.existsSync(versionPath)) {
2528
+ if (!fs15.existsSync(versionPath)) {
2272
2529
  logger.error(`\u5185\u6838\u6C99\u7BB1\u7248\u672C ${version} \u5C1A\u672A\u5B89\u88C5`);
2273
- console.log(pc9.gray(` \u5EFA\u8BAE\u8FD0\u884C 'chatbi sync' \u6216 'chatbi use ${version}' \u8FDB\u884C\u5B89\u88C5\u3002`));
2530
+ logger.info(pc11.gray(` \u5EFA\u8BAE\u8FD0\u884C 'chatbi sync' \u6216 'chatbi use ${version}' \u8FDB\u884C\u5B89\u88C5\u3002`));
2274
2531
  hasIssues = true;
2275
2532
  issues.push(`\u5185\u6838\u6C99\u7BB1\u672A\u5B89\u88C5 (${version})`);
2276
2533
  } else {
2277
2534
  logger.success(`\u5185\u6838\u6C99\u7BB1\u5C31\u7EEA (\u7248\u672C: ${version})`);
2278
- const sandboxNm = path14.join(versionPath, "node_modules");
2279
- if (!fs12.existsSync(sandboxNm)) {
2535
+ const sandboxNm = path18.join(versionPath, "node_modules");
2536
+ if (!fs15.existsSync(sandboxNm)) {
2280
2537
  logger.warn("\u6C99\u7BB1\u4F9D\u8D56\u672A\u5B89\u88C5\uFF0C\u5C06\u5BFC\u81F4\u6784\u5EFA\u5931\u8D25");
2281
2538
  hasIssues = true;
2282
2539
  issues.push("\u6C99\u7BB1\u4F9D\u8D56\u7F3A\u5931");
2283
2540
  }
2284
- const missingDeps = [];
2285
- for (const dep of Sandbox.CORE_PACKAGES) {
2286
- if (!fs12.existsSync(path14.join(sandboxNm, dep))) {
2287
- missingDeps.push(dep);
2288
- }
2289
- }
2290
- if (missingDeps.length > 0) {
2291
- }
2292
2541
  }
2293
- logger.info(pc9.bold("\nStep 3: \u68C0\u67E5\u865A\u62DF\u4F9D\u8D56\u6620\u5C04..."));
2294
- const chatbiDir = path14.join(cwd, ".chatbi");
2295
- if (!fs12.existsSync(chatbiDir)) {
2542
+ logger.info(pc11.bold("\nStep 3: \u68C0\u67E5\u865A\u62DF\u4F9D\u8D56\u6620\u5C04..."));
2543
+ const workspaceRoot = await SandboxPath.getWorkspaceRoot(cwd);
2544
+ const chatbiDir = path18.join(workspaceRoot, ".chatbi");
2545
+ const isMonorepoSub = cwd !== workspaceRoot;
2546
+ if (isMonorepoSub) {
2547
+ logger.info(pc11.gray(`\u5F53\u524D\u4F4D\u4E8E\u5B50\u5305\uFF0C\u68C0\u67E5 Monorepo \u6839\u76EE\u5F55\u914D\u7F6E: ${workspaceRoot}`));
2548
+ }
2549
+ if (!fs15.existsSync(chatbiDir)) {
2296
2550
  logger.warn("\u672A\u53D1\u73B0\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E (.chatbi \u76EE\u5F55)");
2297
2551
  hasIssues = true;
2298
2552
  issues.push("\u7F3A\u5931 .chatbi \u76EE\u5F55");
2299
2553
  } else {
2300
- const pathsJson = path14.join(chatbiDir, "tsconfig.paths.json");
2301
- const aliasJson = path14.join(chatbiDir, "vite.alias.json");
2302
- if (!fs12.existsSync(pathsJson) || !fs12.existsSync(aliasJson)) {
2554
+ const pathsJson = path18.join(chatbiDir, "tsconfig.paths.json");
2555
+ if (!fs15.existsSync(pathsJson)) {
2303
2556
  logger.warn("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B8C\u6574");
2304
2557
  hasIssues = true;
2305
2558
  issues.push("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u4E0D\u5B8C\u6574");
@@ -2307,37 +2560,48 @@ async function doctor(options = {}) {
2307
2560
  logger.success("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u5DF2\u751F\u6210");
2308
2561
  }
2309
2562
  }
2310
- const tsConfigPath = path14.join(cwd, "tsconfig.json");
2311
- if (fs12.existsSync(tsConfigPath)) {
2563
+ const tsConfigPath = path18.join(cwd, "tsconfig.json");
2564
+ let missingTsExtend = false;
2565
+ if (fs15.existsSync(tsConfigPath)) {
2312
2566
  try {
2313
- const tsConfig = await fs12.readJson(tsConfigPath);
2567
+ const tsConfig = await fs15.readJson(tsConfigPath);
2314
2568
  const extendsPath = tsConfig.extends;
2315
- const expectedPaths = ["./.chatbi/tsconfig.paths.json", ".chatbi/tsconfig.paths.json"];
2569
+ const expectedPaths = [
2570
+ "./.chatbi/tsconfig.paths.json",
2571
+ ".chatbi/tsconfig.paths.json",
2572
+ "../../.chatbi/tsconfig.paths.json",
2573
+ // Monorepo 常见结构
2574
+ "../../../.chatbi/tsconfig.paths.json",
2575
+ "./.chatbi/tsconfig.json",
2576
+ ".chatbi/tsconfig.json",
2577
+ "../../.chatbi/tsconfig.json",
2578
+ "../../../.chatbi/tsconfig.json"
2579
+ ];
2316
2580
  let hasExtend = false;
2317
2581
  if (typeof extendsPath === "string") {
2318
- hasExtend = expectedPaths.includes(extendsPath);
2582
+ hasExtend = expectedPaths.includes(extendsPath) || extendsPath.endsWith(".chatbi/tsconfig.paths.json") || extendsPath.endsWith(".chatbi/tsconfig.json");
2319
2583
  } else if (Array.isArray(extendsPath)) {
2320
- hasExtend = extendsPath.some((p) => expectedPaths.includes(p));
2584
+ hasExtend = extendsPath.some((p) => expectedPaths.includes(p) || p.endsWith(".chatbi/tsconfig.paths.json") || p.endsWith(".chatbi/tsconfig.json"));
2321
2585
  }
2322
2586
  if (!hasExtend) {
2323
2587
  logger.warn("tsconfig.json \u672A\u7EE7\u627F\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E");
2324
2588
  hasIssues = true;
2325
2589
  issues.push("tsconfig.json \u914D\u7F6E\u7F3A\u5931");
2590
+ missingTsExtend = true;
2326
2591
  } else {
2327
2592
  logger.success("tsconfig.json \u914D\u7F6E\u6B63\u5E38");
2328
2593
  }
2329
- } catch (e) {
2594
+ } catch {
2330
2595
  logger.error("\u89E3\u6790 tsconfig.json \u5931\u8D25");
2331
2596
  }
2332
2597
  }
2333
- const viteConfigPath = path14.join(cwd, "vite.config.ts");
2334
- if (fs12.existsSync(viteConfigPath)) {
2335
- const content = await fs12.readFile(viteConfigPath, "utf-8");
2336
- if (!content.includes("vite.alias.json")) {
2337
- logger.warn("vite.config.ts \u53EF\u80FD\u672A\u52A0\u8F7D\u865A\u62DF\u522B\u540D\u914D\u7F6E");
2598
+ const viteConfigPath = path18.join(cwd, "vite.config.ts");
2599
+ if (fs15.existsSync(viteConfigPath)) {
2600
+ const content = await fs15.readFile(viteConfigPath, "utf-8");
2601
+ if (!content.includes("vite.alias.json") && !content.includes("CoreKit")) {
2338
2602
  }
2339
2603
  }
2340
- logger.info(pc9.bold("\nStep 4: \u626B\u63CF\u4EE3\u7801\u89C4\u5219..."));
2604
+ logger.info(pc11.bold("\nStep 4: \u626B\u63CF\u4EE3\u7801\u89C4\u5219..."));
2341
2605
  const rules = [
2342
2606
  {
2343
2607
  id: "plugin-lifecycle-init",
@@ -2355,25 +2619,28 @@ async function doctor(options = {}) {
2355
2619
  const files = await glob(["src/**/*.{ts,tsx}"], { cwd, absolute: true });
2356
2620
  const codeIssues = [];
2357
2621
  if (files.length > 0) {
2358
- const scanSpinner = createSpinner(`\u6B63\u5728\u626B\u63CF ${files.length} \u4E2A\u6587\u4EF6...`).start();
2359
- for (const file of files) {
2360
- const content = await fs12.readFile(file, "utf-8");
2361
- for (const rule of rules) {
2362
- if (rule.pattern.test(content)) {
2363
- codeIssues.push({
2364
- file,
2365
- ruleId: rule.id,
2366
- description: rule.description,
2367
- rule
2368
- });
2622
+ const scanSpinner = createSpinner(`\u6B63\u5728\u5E76\u53D1\u626B\u63CF ${files.length} \u4E2A\u6587\u4EF6...`).start();
2623
+ await Promise.all(files.map(async (file) => {
2624
+ try {
2625
+ const content = await fs15.readFile(file, "utf-8");
2626
+ for (const rule of rules) {
2627
+ if (rule.pattern.test(content)) {
2628
+ codeIssues.push({
2629
+ file,
2630
+ ruleId: rule.id,
2631
+ description: rule.description,
2632
+ rule
2633
+ });
2634
+ }
2369
2635
  }
2636
+ } catch {
2370
2637
  }
2371
- }
2638
+ }));
2372
2639
  if (codeIssues.length > 0) {
2373
2640
  scanSpinner.fail(`\u53D1\u73B0 ${codeIssues.length} \u4E2A\u4EE3\u7801\u89C4\u8303\u95EE\u9898`);
2374
2641
  hasIssues = true;
2375
2642
  codeIssues.forEach((issue) => {
2376
- const relativePath = path14.relative(cwd, issue.file);
2643
+ const relativePath = path18.relative(cwd, issue.file);
2377
2644
  issues.push(`\u4EE3\u7801\u89C4\u8303 [${issue.ruleId}]: ${relativePath}`);
2378
2645
  });
2379
2646
  } else {
@@ -2382,53 +2649,169 @@ async function doctor(options = {}) {
2382
2649
  }
2383
2650
  if (!hasIssues) {
2384
2651
  printBox(
2385
- pc9.green(pc9.bold("\u2728 \u8BCA\u65AD\u5B8C\u6210\uFF1A\u9879\u76EE\u4E00\u5207\u6B63\u5E38\uFF01")),
2652
+ pc11.green(pc11.bold("\u2728 \u8BCA\u65AD\u5B8C\u6210\uFF1A\u9879\u76EE\u4E00\u5207\u6B63\u5E38\uFF01")),
2386
2653
  "Doctor Report"
2387
2654
  );
2388
2655
  } else {
2389
- const issueList = issues.map((i) => pc9.red(`\u2022 ${i}`)).join("\n");
2656
+ const issueList = issues.map((i) => pc11.red(`\u2022 ${i}`)).join("\n");
2390
2657
  printBox(
2391
- `${pc9.yellow(pc9.bold("\u26A0\uFE0F \u8BCA\u65AD\u5B8C\u6210\uFF1A\u53D1\u73B0\u4EE5\u4E0B\u95EE\u9898"))}
2658
+ `${pc11.yellow(pc11.bold("\u26A0\uFE0F \u8BCA\u65AD\u5B8C\u6210\uFF1A\u53D1\u73B0\u4EE5\u4E0B\u95EE\u9898"))}
2392
2659
 
2393
2660
  ${issueList}
2394
2661
 
2395
- ${pc9.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
2662
+ ${pc11.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
2396
2663
  "Doctor Report"
2397
2664
  );
2398
2665
  if (options.fix) {
2399
2666
  if (codeIssues.length > 0) {
2400
2667
  const fixSpinner = createSpinner("\u6B63\u5728\u4FEE\u590D\u4EE3\u7801\u89C4\u8303\u95EE\u9898...").start();
2401
2668
  for (const issue of codeIssues) {
2402
- const content = await fs12.readFile(issue.file, "utf-8");
2669
+ const content = await fs15.readFile(issue.file, "utf-8");
2403
2670
  const newContent = issue.rule.fix(content);
2404
- await fs12.writeFile(issue.file, newContent);
2671
+ await fs15.writeFile(issue.file, newContent);
2672
+ }
2673
+ fixSpinner.succeed(`\u5DF2\u4FEE\u590D ${codeIssues.length} \u4E2A\u95EE\u9898`);
2674
+ }
2675
+ if (missingTsExtend && fs15.existsSync(tsConfigPath)) {
2676
+ const fixSpinner = createSpinner("\u6B63\u5728\u4FEE\u590D tsconfig.json \u914D\u7F6E...").start();
2677
+ try {
2678
+ const tsConfig = await fs15.readJson(tsConfigPath);
2679
+ let extendsTarget = "./.chatbi/tsconfig.json";
2680
+ if (isMonorepoSub) {
2681
+ extendsTarget = path18.relative(cwd, path18.join(workspaceRoot, ".chatbi/tsconfig.json"));
2682
+ if (!extendsTarget.startsWith(".")) extendsTarget = `./${extendsTarget}`;
2683
+ }
2684
+ if (Array.isArray(tsConfig.extends)) {
2685
+ if (!tsConfig.extends.some((p) => p.includes(".chatbi"))) {
2686
+ tsConfig.extends.push(extendsTarget);
2687
+ }
2688
+ } else if (typeof tsConfig.extends === "string") {
2689
+ if (!tsConfig.extends.includes(".chatbi")) {
2690
+ tsConfig.extends = [tsConfig.extends, extendsTarget];
2691
+ }
2692
+ } else {
2693
+ tsConfig.extends = extendsTarget;
2694
+ }
2695
+ await fs15.writeJson(tsConfigPath, tsConfig, { spaces: 2 });
2696
+ fixSpinner.succeed("\u5DF2\u4FEE\u590D tsconfig.json \u7EE7\u627F\u914D\u7F6E");
2697
+ } catch (e) {
2698
+ fixSpinner.fail(`\u4FEE\u590D tsconfig.json \u5931\u8D25: ${e.message}`);
2405
2699
  }
2406
- fixSpinner.succeed("\u4EE3\u7801\u4FEE\u590D\u5B8C\u6210");
2407
2700
  }
2408
- logger.info("\u6B63\u5728\u4FEE\u590D\u73AF\u5883\u914D\u7F6E...");
2409
- const { sync: sync2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
2410
- await sync2({ force: true });
2411
- logger.success("\u81EA\u52A8\u4FEE\u590D\u5B8C\u6210\uFF0C\u8BF7\u91CD\u65B0\u8FD0\u884C\u8BCA\u65AD\u3002");
2412
2701
  }
2413
2702
  }
2414
2703
  }
2704
+ var init_doctor = __esm({
2705
+ "src/commands/doctor.ts"() {
2706
+ "use strict";
2707
+ init_esm_shims();
2708
+ init_corekit();
2709
+ init_sandbox();
2710
+ init_SandboxPath();
2711
+ init_utils();
2712
+ }
2713
+ });
2415
2714
 
2416
- // src/index.ts
2417
- init_fetch();
2715
+ // src/commands/ls.ts
2716
+ var ls_exports = {};
2717
+ __export(ls_exports, {
2718
+ ls: () => ls
2719
+ });
2720
+ import pc12 from "picocolors";
2721
+ async function ls() {
2722
+ const versions = await CoreKit.listVersions();
2723
+ const currentVersion = await CoreKit.resolveVersion(process.cwd());
2724
+ const globalCurrentVersion = await CoreKit.resolveVersion();
2725
+ logger.info("\u5DF2\u5B89\u88C5\u7684\u5185\u6838\u6C99\u7BB1\u7248\u672C:");
2726
+ if (versions.length === 0) {
2727
+ logger.warn("\u5C1A\u672A\u5B89\u88C5\u4EFB\u4F55\u7248\u672C\uFF0C\u8BF7\u8FD0\u884C chatbi sync \u8FDB\u884C\u5B89\u88C5\u3002");
2728
+ } else {
2729
+ const list = versions.map((v) => {
2730
+ const isGlobalCurrent = v === globalCurrentVersion;
2731
+ const isProjectCurrent = v === currentVersion;
2732
+ let prefix = " ";
2733
+ if (isProjectCurrent) {
2734
+ prefix = pc12.green(" *");
2735
+ } else if (isGlobalCurrent) {
2736
+ prefix = pc12.blue(" >");
2737
+ }
2738
+ let suffix = "";
2739
+ if (isProjectCurrent && isGlobalCurrent) {
2740
+ suffix = pc12.gray(" (\u5F53\u524D\u9879\u76EE & \u5168\u5C40)");
2741
+ } else if (isProjectCurrent) {
2742
+ suffix = pc12.gray(" (\u5F53\u524D\u9879\u76EE)");
2743
+ } else if (isGlobalCurrent) {
2744
+ suffix = pc12.gray(" (\u5168\u5C40)");
2745
+ }
2746
+ return `${prefix} ${pc12.white(v)}${suffix}`;
2747
+ }).join("\n");
2748
+ printBox(
2749
+ list + pc12.gray("\n\n\u63D0\u793A: * \u5F53\u524D\u9879\u76EE\u4F7F\u7528, > \u5168\u5C40\u9ED8\u8BA4\u4F7F\u7528"),
2750
+ "Kernel Versions"
2751
+ );
2752
+ }
2753
+ await Sandbox.visualizeStatus(process.cwd());
2754
+ }
2755
+ var init_ls = __esm({
2756
+ "src/commands/ls.ts"() {
2757
+ "use strict";
2758
+ init_esm_shims();
2759
+ init_corekit();
2760
+ init_sandbox();
2761
+ init_utils();
2762
+ }
2763
+ });
2764
+
2765
+ // src/commands/use.ts
2766
+ var use_exports = {};
2767
+ __export(use_exports, {
2768
+ use: () => use
2769
+ });
2770
+ import fs16 from "fs-extra";
2771
+ import path19 from "path";
2772
+ async function use(version, options = {}) {
2773
+ const versions = await CoreKit.listVersions();
2774
+ if (!versions.includes(version)) {
2775
+ logger.warn(`\u7248\u672C ${version} \u5C1A\u672A\u5B89\u88C5\uFF0C\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5...`);
2776
+ await Sandbox.prepare(version);
2777
+ }
2778
+ if (options.global) {
2779
+ await Sandbox.useVersion(version);
2780
+ logger.success(`\u5DF2\u5207\u6362\u5168\u5C40\u5185\u6838\u7248\u672C\u81F3: ${version}`);
2781
+ } else {
2782
+ const cwd = process.cwd();
2783
+ const versionFilePath = path19.join(cwd, ".chatbi-version");
2784
+ await fs16.writeFile(versionFilePath, version, "utf-8");
2785
+ logger.success(`\u5DF2\u5207\u6362\u5F53\u524D\u9879\u76EE\u5185\u6838\u7248\u672C\u4E3A: ${version}`);
2786
+ }
2787
+ await sync({ version, force: false });
2788
+ }
2789
+ var init_use = __esm({
2790
+ "src/commands/use.ts"() {
2791
+ "use strict";
2792
+ init_esm_shims();
2793
+ init_corekit();
2794
+ init_sandbox();
2795
+ init_utils();
2796
+ init_sync();
2797
+ }
2798
+ });
2418
2799
 
2419
2800
  // src/commands/gl.ts
2420
- init_esm_shims();
2421
- init_utils();
2422
- import { execa as execa5 } from "execa";
2423
- import fs13 from "fs-extra";
2424
- import path16 from "path";
2425
- import pc11 from "picocolors";
2801
+ var gl_exports = {};
2802
+ __export(gl_exports, {
2803
+ gl: () => gl
2804
+ });
2805
+ import { execa as execa7 } from "execa";
2806
+ import fs17 from "fs-extra";
2807
+ import path20 from "path";
2808
+ import pc13 from "picocolors";
2426
2809
  import prompts3 from "prompts";
2427
2810
  async function gl(options) {
2428
2811
  const { type: initialType, prompt: initialPrompt } = options;
2429
2812
  const cwd = process.cwd();
2430
- const pkgPath = path16.join(cwd, "package.json");
2431
- if (!fs13.existsSync(pkgPath)) {
2813
+ const pkgPath = path20.join(cwd, "package.json");
2814
+ if (!fs17.existsSync(pkgPath)) {
2432
2815
  logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
2433
2816
  return;
2434
2817
  }
@@ -2467,7 +2850,7 @@ async function gl(options) {
2467
2850
  logger.error("\u9700\u6C42\u63CF\u8FF0\u4E0D\u80FD\u4E3A\u7A7A\u3002");
2468
2851
  return;
2469
2852
  }
2470
- logger.info(`\u6B63\u5728\u547C\u53EB AI \u5F15\u64CE [\u6A21\u5F0F: ${pc11.bold(genType)}]...`);
2853
+ logger.info(`\u6B63\u5728\u547C\u53EB AI \u5F15\u64CE [\u6A21\u5F0F: ${pc13.bold(genType)}]...`);
2471
2854
  const toolsContext = `
2472
2855
  [Available Tools & Capabilities]
2473
2856
  - Tool: plugin -> For creating new feature modules. Requires: name, type (business|system).
@@ -2510,7 +2893,7 @@ If not, use the SLOT_REQUIRED format.`.trim();
2510
2893
  while (retry) {
2511
2894
  spinner.start();
2512
2895
  try {
2513
- const { stdout } = await execa5("gemini", [geminiCmd, currentPrompt], {
2896
+ const { stdout } = await execa7("gemini", [geminiCmd, currentPrompt], {
2514
2897
  stdio: "pipe"
2515
2898
  });
2516
2899
  spinner.stop();
@@ -2530,7 +2913,7 @@ If not, use the SLOT_REQUIRED format.`.trim();
2530
2913
  }
2531
2914
  }
2532
2915
  if (slots.length > 0) {
2533
- logger.info(pc11.yellow("\n\u{1F4DD} AI \u9700\u8981\u66F4\u591A\u4FE1\u606F\u4EE5\u7EE7\u7EED:"));
2916
+ logger.info(pc13.yellow("\n\u{1F4DD} AI \u9700\u8981\u66F4\u591A\u4FE1\u606F\u4EE5\u7EE7\u7EED:"));
2534
2917
  const answers = await prompts3(slots, {
2535
2918
  onCancel: () => process.exit(0)
2536
2919
  });
@@ -2545,14 +2928,14 @@ Please proceed with generation based on these answers.`;
2545
2928
  continue;
2546
2929
  }
2547
2930
  }
2548
- console.log("\n" + stdout);
2931
+ logger.info("\n" + stdout);
2549
2932
  retry = false;
2550
2933
  logger.success(`AI \u547D\u4EE4 [gemini ${geminiCmd}] \u6267\u884C\u5B8C\u6BD5!`);
2551
2934
  } catch (error) {
2552
2935
  spinner.stop();
2553
2936
  if (error.code === "ENOENT") {
2554
2937
  logger.error("\u672A\u5728\u7CFB\u7EDF\u4E2D\u627E\u5230 `gemini-cli` \u547D\u4EE4\u3002");
2555
- logger.info(pc11.yellow("\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 gemini-cli \u5E76\u5C06\u5176\u6DFB\u52A0\u5230\u7CFB\u7EDF PATH \u4E2D\u3002"));
2938
+ logger.info(pc13.yellow("\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 gemini-cli \u5E76\u5C06\u5176\u6DFB\u52A0\u5230\u7CFB\u7EDF PATH \u4E2D\u3002"));
2556
2939
  } else {
2557
2940
  logger.error(`AI \u751F\u6210\u8FC7\u7A0B\u4E2D\u51FA\u9519: ${error.message}`);
2558
2941
  }
@@ -2560,132 +2943,1043 @@ Please proceed with generation based on these answers.`;
2560
2943
  }
2561
2944
  }
2562
2945
  }
2946
+ var init_gl = __esm({
2947
+ "src/commands/gl.ts"() {
2948
+ "use strict";
2949
+ init_esm_shims();
2950
+ init_utils();
2951
+ }
2952
+ });
2563
2953
 
2564
- // src/index.ts
2565
- init_init();
2954
+ // src/commands/discover.ts
2955
+ var discover_exports = {};
2956
+ __export(discover_exports, {
2957
+ discover: () => discover
2958
+ });
2959
+ import pc14 from "picocolors";
2960
+ async function discover() {
2961
+ const cwd = process.cwd();
2962
+ const spinner = createSpinner("\u6B63\u5728\u626B\u63CF\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6...").start();
2963
+ const plugins = await CoreKit.discoverPlugins(cwd);
2964
+ if (plugins.length === 0) {
2965
+ spinner.warn("\u672A\u53D1\u73B0\u4EFB\u4F55\u63D2\u4EF6");
2966
+ logger.info(pc14.gray("\u8BF7\u786E\u4FDD\u63D2\u4EF6\u4F4D\u4E8E plugins/ \u76EE\u5F55\u4E0B\uFF0C\u4E14\u5305\u542B package.json\u3002"));
2967
+ } else {
2968
+ spinner.succeed(`\u53D1\u73B0\u4E86 ${pc14.cyan(plugins.length)} \u4E2A\u63D2\u4EF6`);
2969
+ const pluginList = plugins.map((p) => `- ${pc14.bold(p.name)} ${pc14.gray(`(${p.id})`)}
2970
+ ${pc14.gray(p.path)}`).join("\n\n");
2971
+ printBox(
2972
+ `${pc14.green(pc14.bold("\u2728 \u63D2\u4EF6\u626B\u63CF\u7ED3\u679C"))}
2566
2973
 
2567
- // src/commands/install.ts
2568
- init_esm_shims();
2569
- init_sandbox();
2570
- init_utils();
2571
- import { execa as execa6 } from "execa";
2572
- import fs15 from "fs-extra";
2573
- import path18 from "path";
2574
- import pc13 from "picocolors";
2575
- async function install(target) {
2576
- if (target.endsWith(".tgz") && fs15.existsSync(target)) {
2577
- const spinner = createSpinner(`\u6B63\u5728\u5B89\u88C5\u672C\u5730\u79BB\u7EBF\u5305: ${pc13.bold(target)}...`).start();
2578
- try {
2579
- const tgzPath = path18.resolve(target);
2580
- const match = path18.basename(target).match(/chatbi-core-(.+)\.tgz/);
2581
- let version = "unknown";
2582
- if (match) {
2583
- version = match[1];
2974
+ ${pluginList}`,
2975
+ "Plugin Discovery"
2976
+ );
2977
+ }
2978
+ }
2979
+ var init_discover = __esm({
2980
+ "src/commands/discover.ts"() {
2981
+ "use strict";
2982
+ init_esm_shims();
2983
+ init_corekit();
2984
+ init_utils();
2985
+ }
2986
+ });
2987
+
2988
+ // src/commands/clean.ts
2989
+ var clean_exports = {};
2990
+ __export(clean_exports, {
2991
+ clean: () => clean
2992
+ });
2993
+ import prompts4 from "prompts";
2994
+ async function clean(options) {
2995
+ const cwd = process.cwd();
2996
+ if (options.dryRun) {
2997
+ await Sandbox.clean(cwd, options.deep, true);
2998
+ return;
2999
+ }
3000
+ if (!options.yes) {
3001
+ const { confirm } = await prompts4({
3002
+ type: "confirm",
3003
+ name: "confirm",
3004
+ message: options.deep ? "\u26A0\uFE0F \u6CE8\u610F: \u6DF1\u5EA6\u6E05\u7406\u5C06\u5220\u9664\u6240\u6709\u6784\u5EFA\u4EA7\u7269(dist)\u53CA\u5168\u5C40\u6C99\u7BB1\uFF0C\u786E\u5B9A\u7EE7\u7EED\u5417\uFF1F" : "\u786E\u5B9A\u8981\u6E05\u7406\u9879\u76EE\u7F13\u5B58\u76EE\u5F55(.chatbi)\u5417\uFF1F",
3005
+ initial: !options.deep
3006
+ // 深度清理默认选否,普通清理默认选是
3007
+ });
3008
+ if (!confirm) {
3009
+ logger.warn("\u5DF2\u53D6\u6D88\u6E05\u7406");
3010
+ return;
3011
+ }
3012
+ }
3013
+ await Sandbox.clean(cwd, options.deep, false);
3014
+ }
3015
+ var init_clean = __esm({
3016
+ "src/commands/clean.ts"() {
3017
+ "use strict";
3018
+ init_esm_shims();
3019
+ init_sandbox();
3020
+ init_utils();
3021
+ }
3022
+ });
3023
+
3024
+ // src/commands/bench.ts
3025
+ var bench_exports = {};
3026
+ __export(bench_exports, {
3027
+ bench: () => bench
3028
+ });
3029
+ import fs18 from "fs-extra";
3030
+ import os2 from "os";
3031
+ import path21 from "path";
3032
+ import pc15 from "picocolors";
3033
+ async function bench() {
3034
+ logger.info("\u6B63\u5728\u542F\u52A8 CLI \u6027\u80FD\u57FA\u51C6\u6D4B\u8BD5...");
3035
+ const results = [];
3036
+ const tmpDir = path21.join(os2.tmpdir(), `chatbi-bench-${Date.now()}`);
3037
+ await fs18.ensureDir(tmpDir);
3038
+ try {
3039
+ const initSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u521D\u59CB\u5316\u63D2\u4EF6\u9879\u76EE (init)...").start();
3040
+ const startInit = Date.now();
3041
+ const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
3042
+ const testProjDir = path21.join(tmpDir, "bench-proj");
3043
+ await init2({ name: "bench-proj", projectType: "plugin", cwd: tmpDir });
3044
+ const endInit = Date.now();
3045
+ const initTime = (endInit - startInit) / 1e3;
3046
+ initSpinner.succeed(`\u521D\u59CB\u5316\u5B8C\u6210: ${pc15.cyan(initTime.toFixed(2) + "s")}`);
3047
+ results.push({
3048
+ scene: "\u521D\u59CB\u5316\u63D2\u4EF6\u9879\u76EE (init)",
3049
+ target: "\u2264 5.0 s",
3050
+ actual: `${initTime.toFixed(2)} s`
3051
+ });
3052
+ const syncSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u6C99\u7BB1\u73AF\u5883\u540C\u6B65 (sync)...").start();
3053
+ const startSync = Date.now();
3054
+ const { sync: sync2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
3055
+ await sync2({ cwd: testProjDir });
3056
+ const endSync = Date.now();
3057
+ const syncTime = (endSync - startSync) / 1e3;
3058
+ syncSpinner.succeed(`\u540C\u6B65\u5B8C\u6210: ${pc15.cyan(syncTime.toFixed(2) + "s")}`);
3059
+ results.push({
3060
+ scene: "\u6C99\u7BB1\u73AF\u5883\u540C\u6B65 (sync)",
3061
+ target: "\u2264 2.0 s",
3062
+ actual: `${syncTime.toFixed(2)} s`
3063
+ });
3064
+ const buildSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u63D2\u4EF6\u9879\u76EE\u6784\u5EFA (build)...").start();
3065
+ const startBuild = Date.now();
3066
+ const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
3067
+ const originalCwd = process.cwd();
3068
+ process.chdir(testProjDir);
3069
+ await build2({ watch: false });
3070
+ process.chdir(originalCwd);
3071
+ const endBuild = Date.now();
3072
+ const buildTime = (endBuild - startBuild) / 1e3;
3073
+ buildSpinner.succeed(`\u6784\u5EFA\u5B8C\u6210: ${pc15.cyan(buildTime.toFixed(2) + "s")}`);
3074
+ results.push({
3075
+ scene: "\u63D2\u4EF6\u9879\u76EE\u6784\u5EFA (build)",
3076
+ target: "\u2264 10.0 s",
3077
+ actual: `${buildTime.toFixed(2)} s`
3078
+ });
3079
+ printBox(
3080
+ `${pc15.green(pc15.bold("\u2728 \u57FA\u51C6\u6D4B\u8BD5\u5B8C\u6210!"))}
3081
+
3082
+ ` + results.map((r) => `${pc15.white(r.scene.padEnd(20))}: ${pc15.cyan(r.actual)} (\u76EE\u6807 ${r.target})`).join("\n"),
3083
+ "Benchmark Results"
3084
+ );
3085
+ } finally {
3086
+ await fs18.remove(tmpDir);
3087
+ }
3088
+ }
3089
+ var init_bench = __esm({
3090
+ "src/commands/bench.ts"() {
3091
+ "use strict";
3092
+ init_esm_shims();
3093
+ init_utils();
3094
+ }
3095
+ });
3096
+
3097
+ // src/commands/lint-theme.ts
3098
+ var lint_theme_exports = {};
3099
+ __export(lint_theme_exports, {
3100
+ lintTheme: () => lintTheme
3101
+ });
3102
+ import { loadESLint } from "eslint";
3103
+ import fs19 from "fs-extra";
3104
+ import path22 from "path";
3105
+ async function lintTheme(options) {
3106
+ const projectRoot = findProjectRoot(process.cwd());
3107
+ const cwd = projectRoot;
3108
+ const target = options.target || ".";
3109
+ const files = [path22.isAbsolute(target) ? target : path22.resolve(cwd, target)];
3110
+ if (options.debug) {
3111
+ logger.info("Starting Theme Lint...");
3112
+ logger.info(`Target: ${target}`);
3113
+ logger.info(`Options: ${JSON.stringify(options)}`);
3114
+ }
3115
+ try {
3116
+ const ESLint = await loadESLint({ useFlatConfig: true });
3117
+ const themePlugin = await importThemePlugin();
3118
+ const eslint = new ESLint({
3119
+ cwd,
3120
+ fix: options.fix,
3121
+ overrideConfig: [
3122
+ {
3123
+ files: ["**/*.{js,mjs,cjs,ts,jsx,tsx}"],
3124
+ plugins: {
3125
+ "@chatbi-v/theme": themePlugin
3126
+ },
3127
+ rules: {
3128
+ "@chatbi-v/theme/no-hardcoded-colors": "warn",
3129
+ "@chatbi-v/theme/no-inline-styles": "warn",
3130
+ "@chatbi-v/theme/no-arbitrary-tailwind": "warn",
3131
+ "@chatbi-v/theme/no-hardcoded-tailwind": "warn",
3132
+ "@chatbi-v/theme/no-hardcoded-radius": "warn",
3133
+ "@chatbi-v/theme/no-hardcoded-shadow": "warn",
3134
+ "@chatbi-v/theme/no-hardcoded-spacing": "warn",
3135
+ "@chatbi-v/theme/no-hardcoded-zindex": "warn"
3136
+ }
3137
+ }
3138
+ ]
3139
+ });
3140
+ logger.info(`Scanning files in ${target} for theme violations...`);
3141
+ const results = await eslint.lintFiles(files);
3142
+ if (options.fix) {
3143
+ await ESLint.outputFixes(results);
3144
+ logger.success("Auto-fixes applied where possible.");
3145
+ }
3146
+ const themeRuleIds = [
3147
+ "@chatbi-v/theme/no-hardcoded-colors",
3148
+ "@chatbi-v/theme/no-inline-styles",
3149
+ "@chatbi-v/theme/no-arbitrary-tailwind",
3150
+ "@chatbi-v/theme/no-hardcoded-tailwind",
3151
+ "@chatbi-v/theme/no-hardcoded-radius",
3152
+ "@chatbi-v/theme/no-hardcoded-shadow",
3153
+ "@chatbi-v/theme/no-hardcoded-spacing",
3154
+ "@chatbi-v/theme/no-hardcoded-zindex"
3155
+ ];
3156
+ const filteredResults = results.map((result) => ({
3157
+ ...result,
3158
+ messages: result.messages.filter(
3159
+ (msg) => msg.ruleId && themeRuleIds.includes(msg.ruleId)
3160
+ ),
3161
+ errorCount: 0,
3162
+ // 重置计数,由下方重新计算
3163
+ warningCount: 0
3164
+ })).map((result) => {
3165
+ result.messages.forEach((msg) => {
3166
+ if (msg.severity === 2) result.errorCount++;
3167
+ else if (msg.severity === 1) result.warningCount++;
3168
+ });
3169
+ return result;
3170
+ });
3171
+ const formatterName = options.format || "stylish";
3172
+ const formatter = await eslint.loadFormatter(formatterName);
3173
+ const resultText = await formatter.format(filteredResults);
3174
+ if (options.output) {
3175
+ await fs19.ensureDir(path22.dirname(options.output));
3176
+ await fs19.outputFile(options.output, resultText);
3177
+ logger.success(`Report generated at ${options.output}`);
3178
+ } else {
3179
+ console.log(resultText);
3180
+ }
3181
+ const errorCount = filteredResults.reduce((acc, res) => acc + res.errorCount, 0);
3182
+ const warningCount = filteredResults.reduce((acc, res) => acc + res.warningCount, 0);
3183
+ if (errorCount > 0) {
3184
+ logger.error(`Lint failed with ${errorCount} errors and ${warningCount} warnings.`);
3185
+ process.exit(1);
3186
+ } else if (warningCount > 0) {
3187
+ logger.warn(`Lint finished with ${warningCount} warnings.`);
3188
+ } else {
3189
+ logger.success("Theme lint passed!");
3190
+ }
3191
+ } catch (error) {
3192
+ logger.error("An error occurred during linting:", error);
3193
+ process.exit(1);
3194
+ }
3195
+ }
3196
+ var importThemePlugin, findProjectRoot;
3197
+ var init_lint_theme = __esm({
3198
+ "src/commands/lint-theme.ts"() {
3199
+ "use strict";
3200
+ init_esm_shims();
3201
+ init_utils();
3202
+ importThemePlugin = async () => {
3203
+ try {
3204
+ const { createRequire: createRequire3 } = await import("module");
3205
+ const projectRoot = findProjectRoot(process.cwd());
3206
+ const pluginPath = path22.resolve(projectRoot, "node_modules/@chatbi-v/eslint-plugin-theme");
3207
+ const require2 = createRequire3(import.meta.url);
3208
+ return require2(pluginPath);
3209
+ } catch (e) {
3210
+ logger.error("Failed to load @chatbi-v/eslint-plugin-theme", e);
3211
+ throw e;
2584
3212
  }
2585
- if (version === "unknown") {
2586
- spinner.warn("\u65E0\u6CD5\u4ECE\u6587\u4EF6\u540D\u8BC6\u522B\u7248\u672C\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u65F6\u95F4\u6233\u4F5C\u4E3A\u7248\u672C\u53F7");
2587
- version = `local-${Date.now()}`;
3213
+ };
3214
+ findProjectRoot = (startDir) => {
3215
+ let current = startDir;
3216
+ while (current !== path22.dirname(current)) {
3217
+ if (fs19.existsSync(path22.join(current, "package.json")) && fs19.existsSync(path22.join(current, "pnpm-workspace.yaml"))) {
3218
+ return current;
3219
+ }
3220
+ current = path22.dirname(current);
2588
3221
  }
2589
- const versionRoot = Sandbox.getVersionRoot();
2590
- await fs15.ensureDir(versionRoot);
2591
- spinner.text = "\u6B63\u5728\u89E3\u538B\u6587\u4EF6...";
2592
- await execa6("tar", ["-xzf", tgzPath, "-C", versionRoot]);
2593
- spinner.succeed(`\u672C\u5730\u5305\u5DF2\u5B89\u88C5\u81F3\u6C99\u7BB1: ${version}`);
2594
- spinner.text = "\u6B63\u5728\u51C6\u5907\u5185\u6838\u73AF\u5883...";
2595
- await Sandbox.prepare(version);
2596
- spinner.succeed("\u5185\u6838\u73AF\u5883\u5C31\u7EEA");
2597
- printBox(
2598
- pc13.green(pc13.bold("\u2728 \u672C\u5730\u5185\u6838\u5B89\u88C5\u6210\u529F!")) + "\n\n" + pc13.white("\u7248\u672C: ") + pc13.cyan(version) + "\n" + pc13.white("\u8DEF\u5F84: ") + pc13.gray(Sandbox.getVersionPath(version)),
2599
- "Install Success"
2600
- );
2601
- } catch (e) {
2602
- spinner.fail("\u5B89\u88C5\u5931\u8D25");
2603
- throw e;
3222
+ return startDir;
3223
+ };
3224
+ }
3225
+ });
3226
+
3227
+ // src/commands/plugin/create.ts
3228
+ var create_exports = {};
3229
+ __export(create_exports, {
3230
+ pluginCreate: () => pluginCreate
3231
+ });
3232
+ import fs20 from "fs-extra";
3233
+ import path23 from "path";
3234
+ import pc16 from "picocolors";
3235
+ async function pluginCreate(options) {
3236
+ const { name, template = "basic", typescript = true, force = false } = options;
3237
+ if (!/^[a-z0-9-]+$/.test(name)) {
3238
+ logger.error("\u63D2\u4EF6\u540D\u79F0\u53EA\u80FD\u5305\u542B\u5C0F\u5199\u5B57\u6BCD\uFF0C\u6570\u5B57\u548C\u4E2D\u5212\u7EBF");
3239
+ return;
3240
+ }
3241
+ const targetDir = path23.join(process.cwd(), "plugins", name);
3242
+ if (fs20.existsSync(targetDir) && !force) {
3243
+ logger.error(`\u63D2\u4EF6\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528 --force \u8986\u76D6`);
3244
+ return;
3245
+ }
3246
+ logger.info(`\u6B63\u5728\u521B\u5EFA\u63D2\u4EF6: ${pc16.cyan(name)}`);
3247
+ logger.info(`\u6A21\u677F: ${pc16.yellow(TEMPLATES[template].name)}`);
3248
+ await fs20.ensureDir(targetDir);
3249
+ await fs20.ensureDir(path23.join(targetDir, "src"));
3250
+ await fs20.ensureDir(path23.join(targetDir, "playground", "src"));
3251
+ await fs20.ensureDir(path23.join(targetDir, "tests"));
3252
+ const packageJson = {
3253
+ name: `@chatbi-v/plugin-${name}`,
3254
+ version: "0.1.0",
3255
+ description: `ChatBI-V ${TEMPLATES[template].name}`,
3256
+ main: "src/index.ts",
3257
+ scripts: {
3258
+ dev: "chatbi-cli dev",
3259
+ build: "chatbi-cli build",
3260
+ test: "vitest"
3261
+ },
3262
+ dependencies: {},
3263
+ devDependencies: {
3264
+ "@chatbi-v/core": "workspace:*",
3265
+ typescript: "^5.0.0",
3266
+ vitest: "^1.0.0"
2604
3267
  }
2605
- } else {
2606
- const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
2607
- await fetch2(target);
3268
+ };
3269
+ await fs20.writeJson(path23.join(targetDir, "package.json"), packageJson, { spaces: 2 });
3270
+ const pluginJson = {
3271
+ id: name,
3272
+ name,
3273
+ version: "0.1.0",
3274
+ description: packageJson.description,
3275
+ type: template === "ui" ? "business" : "system",
3276
+ entry: "src/index.ts"
3277
+ };
3278
+ await fs20.writeJson(path23.join(targetDir, "src", "plugin.json"), pluginJson, { spaces: 2 });
3279
+ const entryContent = `/**
3280
+ * ${name} \u63D2\u4EF6
3281
+ * ${TEMPLATES[template].description}
3282
+ */
3283
+
3284
+ import type { Plugin } from '@chatbi-v/core';
3285
+
3286
+ export const plugin: Plugin = {
3287
+ id: '${name}',
3288
+ name: '${name}',
3289
+ version: '0.1.0',
3290
+
3291
+ async onLoad() {
3292
+ console.log('[${name}] \u63D2\u4EF6\u5DF2\u52A0\u8F7D');
3293
+ },
3294
+
3295
+ async onMount() {
3296
+ console.log('[${name}] \u63D2\u4EF6\u5DF2\u6302\u8F7D');
3297
+ },
3298
+
3299
+ async onUnmount() {
3300
+ console.log('[${name}] \u63D2\u4EF6\u5DF2\u5378\u8F7D');
3301
+ },
3302
+ };
3303
+
3304
+ export default plugin;
3305
+ `;
3306
+ await fs20.writeFile(path23.join(targetDir, "src", "index.ts"), entryContent);
3307
+ if (typescript) {
3308
+ const tsconfig = {
3309
+ extends: "../../tsconfig.base.json",
3310
+ compilerOptions: {
3311
+ outDir: "./dist"
3312
+ },
3313
+ include: ["src/**/*"]
3314
+ };
3315
+ await fs20.writeJson(path23.join(targetDir, "tsconfig.json"), tsconfig, { spaces: 2 });
2608
3316
  }
3317
+ logger.success(`\u63D2\u4EF6 ${pc16.green(name)} \u521B\u5EFA\u6210\u529F!`);
3318
+ logger.info(`\u8BF7\u8FD0\u884C ${pc16.cyan(`cd plugins/${name} && pnpm install`)} \u5B89\u88C5\u4F9D\u8D56`);
2609
3319
  }
3320
+ var TEMPLATES;
3321
+ var init_create = __esm({
3322
+ "src/commands/plugin/create.ts"() {
3323
+ "use strict";
3324
+ init_esm_shims();
3325
+ init_utils();
3326
+ TEMPLATES = {
3327
+ basic: {
3328
+ name: "\u57FA\u7840\u63D2\u4EF6",
3329
+ description: "\u6700\u5C0F\u63D2\u4EF6\u7ED3\u6784"
3330
+ },
3331
+ command: {
3332
+ name: "\u547D\u4EE4\u63D2\u4EF6",
3333
+ description: "\u5305\u542B\u547D\u4EE4\u5B9A\u4E49"
3334
+ },
3335
+ ui: {
3336
+ name: "UI \u63D2\u4EF6",
3337
+ description: "\u5305\u542B UI \u7EC4\u4EF6"
3338
+ },
3339
+ ai: {
3340
+ name: "AI \u63D2\u4EF6",
3341
+ description: "\u5305\u542B AI \u80FD\u529B"
3342
+ }
3343
+ };
3344
+ }
3345
+ });
2610
3346
 
2611
- // src/commands/ls.ts
2612
- init_esm_shims();
2613
- init_corekit();
2614
- init_sandbox();
2615
- init_utils();
2616
- import pc14 from "picocolors";
2617
- async function ls() {
2618
- const versions = await CoreKit.listVersions();
2619
- const currentVersion = await CoreKit.resolveVersion(process.cwd());
2620
- const globalCurrentVersion = await CoreKit.resolveVersion();
2621
- logger.info("\u5DF2\u5B89\u88C5\u7684\u5185\u6838\u6C99\u7BB1\u7248\u672C:");
2622
- if (versions.length === 0) {
2623
- logger.warn("\u5C1A\u672A\u5B89\u88C5\u4EFB\u4F55\u7248\u672C\uFF0C\u8BF7\u8FD0\u884C chatbi sync \u8FDB\u884C\u5B89\u88C5\u3002");
2624
- } else {
2625
- const list = versions.map((v) => {
2626
- const isGlobalCurrent = v === globalCurrentVersion;
2627
- const isProjectCurrent = v === currentVersion;
2628
- let prefix = " ";
2629
- if (isProjectCurrent) {
2630
- prefix = pc14.green(" *");
2631
- } else if (isGlobalCurrent) {
2632
- prefix = pc14.blue(" >");
3347
+ // src/commands/plugin/build.ts
3348
+ var build_exports2 = {};
3349
+ __export(build_exports2, {
3350
+ pluginBuild: () => pluginBuild
3351
+ });
3352
+ import fs21 from "fs-extra";
3353
+ import path24 from "path";
3354
+ import pc17 from "picocolors";
3355
+ async function pluginBuild(options = {}) {
3356
+ const { watch = false, minify = true } = options;
3357
+ const cwd = process.cwd();
3358
+ const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6784\u5EFA\u73AF\u5883...").start();
3359
+ const pkgPath = path24.join(cwd, "package.json");
3360
+ if (!fs21.existsSync(pkgPath)) {
3361
+ spinner.fail("\u672A\u627E\u5230 package.json");
3362
+ logger.error("\u8BF7\u5728\u63D2\u4EF6\u76EE\u5F55\u4E2D\u8FD0\u884C\u6B64\u547D\u4EE4");
3363
+ return;
3364
+ }
3365
+ const pkg = await fs21.readJson(pkgPath);
3366
+ spinner.text = "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E...";
3367
+ let entry = "src/index.ts";
3368
+ if (fs21.existsSync(path24.join(cwd, "src/index.tsx"))) {
3369
+ entry = "src/index.tsx";
3370
+ } else if (!fs21.existsSync(path24.join(cwd, "src/index.ts"))) {
3371
+ spinner.fail("\u672A\u627E\u5230\u5165\u53E3\u6587\u4EF6");
3372
+ logger.error("\u671F\u671B src/index.ts \u6216 src/index.tsx");
3373
+ return;
3374
+ }
3375
+ const pluginJsonPath = path24.join(cwd, "src/plugin.json");
3376
+ if (!fs21.existsSync(pluginJsonPath)) {
3377
+ spinner.warn("\u672A\u627E\u5230 src/plugin.json\uFF0C\u5C06\u4F7F\u7528\u9ED8\u8BA4\u914D\u7F6E");
3378
+ }
3379
+ spinner.text = "\u6B63\u5728\u6784\u5EFA\u63D2\u4EF6...";
3380
+ const corePackages = [
3381
+ "@chatbi-v/core",
3382
+ "react",
3383
+ "react-dom",
3384
+ "react/jsx-runtime",
3385
+ "react-is",
3386
+ "antd",
3387
+ "@ant-design/icons",
3388
+ "@ant-design/x"
3389
+ ];
3390
+ const external = [
3391
+ ...corePackages,
3392
+ ...Object.keys(pkg.dependencies || {}),
3393
+ ...Object.keys(pkg.peerDependencies || {})
3394
+ ];
3395
+ if (!watch) {
3396
+ await fs21.remove(path24.join(cwd, "dist"));
3397
+ }
3398
+ const esmSpinner = createSpinner("\u6B63\u5728\u6784\u5EFA ESM \u683C\u5F0F...").start();
3399
+ try {
3400
+ const { build: tsupBuild } = await import("tsup");
3401
+ await tsupBuild({
3402
+ entry: [entry],
3403
+ format: ["esm"],
3404
+ platform: "browser",
3405
+ outDir: "dist",
3406
+ splitting: false,
3407
+ sourcemap: false,
3408
+ minify: false,
3409
+ // ESM 格式不压缩,方便调试
3410
+ watch,
3411
+ silent: true,
3412
+ external,
3413
+ outExtension: () => ({ js: ".mjs" }),
3414
+ esbuildOptions(esbuildOpts) {
3415
+ esbuildOpts.logOverride = { "empty-import-meta": "silent" };
2633
3416
  }
2634
- let suffix = "";
2635
- if (isProjectCurrent && isGlobalCurrent) {
2636
- suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE & \u5168\u5C40)");
2637
- } else if (isProjectCurrent) {
2638
- suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE)");
2639
- } else if (isGlobalCurrent) {
2640
- suffix = pc14.gray(" (\u5168\u5C40)");
3417
+ });
3418
+ esmSpinner.succeed("ESM \u683C\u5F0F\u6784\u5EFA\u5B8C\u6210");
3419
+ } catch (e) {
3420
+ esmSpinner.fail("ESM \u683C\u5F0F\u6784\u5EFA\u5931\u8D25");
3421
+ logger.error(`\u6784\u5EFA\u5931\u8D25: ${e.message}`);
3422
+ return;
3423
+ }
3424
+ const iifeSpinner = createSpinner("\u6B63\u5728\u6784\u5EFA IIFE \u683C\u5F0F...").start();
3425
+ try {
3426
+ const { build: tsupBuild } = await import("tsup");
3427
+ const globalName = (pkg.name || "plugin").replace(/[^a-zA-Z0-9]/g, "_");
3428
+ await tsupBuild({
3429
+ entry: [entry],
3430
+ format: ["iife"],
3431
+ platform: "browser",
3432
+ outDir: "dist",
3433
+ splitting: false,
3434
+ sourcemap: false,
3435
+ minify: watch ? false : minify,
3436
+ watch,
3437
+ silent: true,
3438
+ external,
3439
+ globalName,
3440
+ outExtension: () => ({ js: ".plugin.js" }),
3441
+ define: {
3442
+ "import.meta.env": "process.env"
3443
+ },
3444
+ esbuildOptions(esbuildOpts) {
3445
+ esbuildOpts.logOverride = { "empty-import-meta": "silent" };
3446
+ corePackages.forEach((dep) => {
3447
+ if (!esbuildOpts.external.includes(dep)) {
3448
+ esbuildOpts.external.push(dep);
3449
+ }
3450
+ });
2641
3451
  }
2642
- return `${prefix} ${pc14.white(v)}${suffix}`;
2643
- }).join("\n");
3452
+ });
3453
+ iifeSpinner.succeed("IIFE \u683C\u5F0F\u6784\u5EFA\u5B8C\u6210");
3454
+ } catch (e) {
3455
+ iifeSpinner.fail("IIFE \u683C\u5F0F\u6784\u5EFA\u5931\u8D25");
3456
+ logger.error(`\u6784\u5EFA\u5931\u8D25: ${e.message}`);
3457
+ return;
3458
+ }
3459
+ const distDir = path24.join(cwd, "dist");
3460
+ if (fs21.existsSync(distDir)) {
3461
+ const files = await fs21.readdir(distDir);
3462
+ const\u4EA7\u7269 = files.filter((f) => f.endsWith(".mjs") || f.endsWith(".plugin.js")).map((f) => pc17.cyan(f)).join(", ");
2644
3463
  printBox(
2645
- list + pc14.gray("\n\n\u63D0\u793A: * \u5F53\u524D\u9879\u76EE\u4F7F\u7528, > \u5168\u5C40\u9ED8\u8BA4\u4F7F\u7528"),
2646
- "Kernel Versions"
3464
+ pc17.green(pc17.bold("\u2728 \u63D2\u4EF6\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc17.white("\u4EA7\u7269\u76EE\u5F55: ") + pc17.cyan("dist") + "\n" + pc17.white("\u4EA7\u7269\u6587\u4EF6: ") + \u4EA7\u7269,
3465
+ "Build Success"
2647
3466
  );
2648
3467
  }
2649
- await Sandbox.visualizeStatus(process.cwd());
3468
+ if (watch) {
3469
+ logger.info(pc17.gray("\u76D1\u542C\u6A21\u5F0F\u5DF2\u5F00\u542F\uFF0C\u6309 Ctrl+C \u505C\u6B62..."));
3470
+ }
2650
3471
  }
3472
+ var init_build2 = __esm({
3473
+ "src/commands/plugin/build.ts"() {
3474
+ "use strict";
3475
+ init_esm_shims();
3476
+ init_utils();
3477
+ }
3478
+ });
2651
3479
 
2652
- // src/index.ts
2653
- init_sync();
3480
+ // src/commands/plugin/validate.ts
3481
+ var validate_exports = {};
3482
+ __export(validate_exports, {
3483
+ pluginValidate: () => pluginValidate
3484
+ });
3485
+ import fs22 from "fs-extra";
3486
+ import path25 from "path";
3487
+ import pc18 from "picocolors";
3488
+ import { z } from "zod";
3489
+ async function pluginValidate(options = {}) {
3490
+ const cwd = process.cwd();
3491
+ const result = {
3492
+ valid: true,
3493
+ errors: [],
3494
+ warnings: []
3495
+ };
3496
+ const spinner = createSpinner("\u6B63\u5728\u9A8C\u8BC1\u63D2\u4EF6\u914D\u7F6E...").start();
3497
+ const pkgPath = path25.join(cwd, "package.json");
3498
+ if (!fs22.existsSync(pkgPath)) {
3499
+ spinner.fail("\u672A\u627E\u5230 package.json");
3500
+ result.valid = false;
3501
+ result.errors.push("\u672A\u627E\u5230 package.json");
3502
+ return result;
3503
+ }
3504
+ spinner.text = "\u6B63\u5728\u8BFB\u53D6\u63D2\u4EF6\u914D\u7F6E...";
3505
+ const pkg = await fs22.readJson(pkgPath);
3506
+ const pluginJsonPath = path25.join(cwd, "src/plugin.json");
3507
+ if (!fs22.existsSync(pluginJsonPath)) {
3508
+ spinner.fail("\u672A\u627E\u5230 src/plugin.json");
3509
+ result.valid = false;
3510
+ result.errors.push("\u672A\u627E\u5230 src/plugin.json\uFF0C\u8BF7\u5148\u8FD0\u884C plugin create \u6216\u624B\u52A8\u521B\u5EFA");
3511
+ if (options.fix) {
3512
+ const fixSpinner = createSpinner("\u6B63\u5728\u81EA\u52A8\u521B\u5EFA plugin.json...").start();
3513
+ try {
3514
+ const defaultManifest = {
3515
+ id: pkg.name?.replace("@chatbi-v/plugin-", "") || "unnamed",
3516
+ name: pkg.name || "Unnamed Plugin",
3517
+ version: pkg.version || "0.1.0",
3518
+ description: pkg.description || "",
3519
+ entry: pkg.main || "src/index.ts"
3520
+ };
3521
+ await fs22.ensureDir(path25.join(cwd, "src"));
3522
+ await fs22.writeJson(pluginJsonPath, defaultManifest, { spaces: 2 });
3523
+ fixSpinner.succeed("\u5DF2\u521B\u5EFA src/plugin.json");
3524
+ result.errors = result.errors.filter((e) => !e.includes("plugin.json"));
3525
+ } catch (e) {
3526
+ fixSpinner.fail("\u521B\u5EFA\u5931\u8D25");
3527
+ }
3528
+ }
3529
+ return result;
3530
+ }
3531
+ spinner.text = "\u6B63\u5728\u9A8C\u8BC1 Manifest \u683C\u5F0F...";
3532
+ try {
3533
+ const pluginJson = await fs22.readJson(pluginJsonPath);
3534
+ const validation = PluginManifestSchema.safeParse(pluginJson);
3535
+ if (!validation.success) {
3536
+ spinner.fail("Manifest \u683C\u5F0F\u9A8C\u8BC1\u5931\u8D25");
3537
+ result.valid = false;
3538
+ validation.error.errors.forEach((err) => {
3539
+ result.errors.push(`[${err.path.join(".")}] ${err.message}`);
3540
+ });
3541
+ return result;
3542
+ }
3543
+ const entryPath = path25.join(cwd, pluginJson.entry);
3544
+ if (!fs22.existsSync(entryPath)) {
3545
+ spinner.fail(`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728: ${pluginJson.entry}`);
3546
+ result.valid = false;
3547
+ result.errors.push(`\u5165\u53E3\u6587\u4EF6\u4E0D\u5B58\u5728: ${pluginJson.entry}`);
3548
+ return result;
3549
+ }
3550
+ spinner.text = "\u6B63\u5728\u68C0\u67E5\u4F9D\u8D56\u53EF\u89E3\u6790\u6027...";
3551
+ const deps = {
3552
+ ...pkg.dependencies || {},
3553
+ ...pkg.peerDependencies || {}
3554
+ };
3555
+ const nodeModulesPath = path25.join(cwd, "node_modules");
3556
+ for (const [dep, version] of Object.entries(deps)) {
3557
+ if (version.startsWith("workspace:") || version.startsWith("file:")) {
3558
+ continue;
3559
+ }
3560
+ if (["react", "react-dom", "antd", "@chatbi-v/core"].includes(dep)) {
3561
+ continue;
3562
+ }
3563
+ const depPath = path25.join(nodeModulesPath, dep);
3564
+ if (!fs22.existsSync(depPath)) {
3565
+ result.warnings.push(`\u4F9D\u8D56\u672A\u5B89\u88C5: ${dep}@${version}`);
3566
+ }
3567
+ }
3568
+ spinner.succeed("\u63D2\u4EF6\u9A8C\u8BC1\u901A\u8FC7");
3569
+ if (result.warnings.length > 0) {
3570
+ const warningList = result.warnings.map((w) => pc18.yellow(`\u2022 ${w}`)).join("\n");
3571
+ printBox(
3572
+ `${pc18.green(pc18.bold("\u2713 \u63D2\u4EF6\u914D\u7F6E\u9A8C\u8BC1\u901A\u8FC7"))}
2654
3573
 
2655
- // src/commands/use.ts
2656
- init_esm_shims();
2657
- init_corekit();
2658
- init_sandbox();
2659
- init_utils();
2660
- init_sync();
2661
- import fs16 from "fs-extra";
2662
- import path19 from "path";
2663
- async function use(version, options = {}) {
2664
- const versions = await CoreKit.listVersions();
2665
- if (!versions.includes(version)) {
2666
- logger.warn(`\u7248\u672C ${version} \u5C1A\u672A\u5B89\u88C5\uFF0C\u6B63\u5728\u5C1D\u8BD5\u5B89\u88C5...`);
2667
- await Sandbox.prepare(version);
3574
+ ` + pc18.yellow(pc18.bold("\u26A0 \u8B66\u544A:")) + "\n\n" + warningList,
3575
+ "Validation Warning"
3576
+ );
3577
+ } else {
3578
+ printBox(
3579
+ pc18.green(pc18.bold("\u2713 \u63D2\u4EF6\u914D\u7F6E\u9A8C\u8BC1\u901A\u8FC7")),
3580
+ "Validation Success"
3581
+ );
3582
+ }
3583
+ return result;
3584
+ } catch (e) {
3585
+ spinner.fail("\u9A8C\u8BC1\u8FC7\u7A0B\u51FA\u9519");
3586
+ result.valid = false;
3587
+ result.errors.push(`\u9A8C\u8BC1\u5931\u8D25: ${e.message}`);
3588
+ return result;
2668
3589
  }
2669
- if (options.global) {
2670
- await Sandbox.useVersion(version);
2671
- logger.success(`\u5DF2\u5207\u6362\u5168\u5C40\u5185\u6838\u7248\u672C\u81F3: ${version}`);
3590
+ }
3591
+ var PluginManifestSchema;
3592
+ var init_validate = __esm({
3593
+ "src/commands/plugin/validate.ts"() {
3594
+ "use strict";
3595
+ init_esm_shims();
3596
+ init_utils();
3597
+ PluginManifestSchema = z.object({
3598
+ id: z.string().min(1, "\u63D2\u4EF6 ID \u4E0D\u80FD\u4E3A\u7A7A"),
3599
+ name: z.string().min(1, "\u63D2\u4EF6\u540D\u79F0\u4E0D\u80FD\u4E3A\u7A7A"),
3600
+ version: z.string().regex(/^\d+\.\d+\.\d+/, "\u7248\u672C\u53F7\u683C\u5F0F\u9519\u8BEF"),
3601
+ description: z.string().optional(),
3602
+ type: z.enum(["business", "system"]).optional(),
3603
+ entry: z.string().min(1, "\u5165\u53E3\u6587\u4EF6\u4E0D\u80FD\u4E3A\u7A7A"),
3604
+ dependencies: z.record(z.string()).optional(),
3605
+ peerDependencies: z.record(z.string()).optional()
3606
+ });
3607
+ }
3608
+ });
3609
+
3610
+ // src/commands/plugin/publish.ts
3611
+ var publish_exports = {};
3612
+ __export(publish_exports, {
3613
+ pluginPublish: () => pluginPublish
3614
+ });
3615
+ async function pluginPublish(options) {
3616
+ logger.warn("\u63D2\u4EF6\u53D1\u5E03\u529F\u80FD\u6B63\u5728\u5F00\u53D1\u4E2D...");
3617
+ }
3618
+ var init_publish = __esm({
3619
+ "src/commands/plugin/publish.ts"() {
3620
+ "use strict";
3621
+ init_esm_shims();
3622
+ init_utils();
3623
+ }
3624
+ });
3625
+
3626
+ // src/commands/theme/create.ts
3627
+ var create_exports2 = {};
3628
+ __export(create_exports2, {
3629
+ themeCreate: () => themeCreate
3630
+ });
3631
+ import fs23 from "fs-extra";
3632
+ import path26 from "path";
3633
+ import pc19 from "picocolors";
3634
+ async function themeCreate(options) {
3635
+ const { name, base = "standard", css = false } = options;
3636
+ const targetDir = path26.join(process.cwd(), "themes", name);
3637
+ const baseTheme = BASE_THEMES[base];
3638
+ logger.info(`\u6B63\u5728\u521B\u5EFA\u4E3B\u9898: ${pc19.cyan(name)}`);
3639
+ logger.info(`\u57FA\u7840\u4E3B\u9898: ${pc19.yellow(baseTheme.name)}`);
3640
+ await fs23.ensureDir(targetDir);
3641
+ if (css) {
3642
+ const cssContent = `:root {
3643
+ --color-primary: ${baseTheme.colors.primary};
3644
+ --color-background: ${baseTheme.colors.background};
3645
+ }
3646
+
3647
+ [data-theme="${name}"] {
3648
+ --color-primary: ${baseTheme.colors.primary};
3649
+ --color-background: ${baseTheme.colors.background};
3650
+ }
3651
+ `;
3652
+ await fs23.writeFile(path26.join(targetDir, "theme.css"), cssContent);
2672
3653
  } else {
2673
- const cwd = process.cwd();
2674
- const versionFilePath = path19.join(cwd, ".chatbi-version");
2675
- await fs16.writeFile(versionFilePath, version, "utf-8");
2676
- logger.success(`\u5DF2\u5207\u6362\u5F53\u524D\u9879\u76EE\u5185\u6838\u7248\u672C\u4E3A: ${version}`);
3654
+ const tailwindConfig = {
3655
+ theme: {
3656
+ extend: {
3657
+ colors: {
3658
+ primary: baseTheme.colors.primary,
3659
+ background: baseTheme.colors.background
3660
+ }
3661
+ }
3662
+ }
3663
+ };
3664
+ await fs23.writeJson(path26.join(targetDir, "tailwind.config.js"), tailwindConfig, { spaces: 2 });
3665
+ }
3666
+ const themeJson = {
3667
+ id: name,
3668
+ name,
3669
+ base,
3670
+ version: "0.1.0"
3671
+ };
3672
+ await fs23.writeJson(path26.join(targetDir, "theme.json"), themeJson, { spaces: 2 });
3673
+ logger.success(`\u4E3B\u9898 ${pc19.green(name)} \u521B\u5EFA\u6210\u529F!`);
3674
+ }
3675
+ var BASE_THEMES;
3676
+ var init_create2 = __esm({
3677
+ "src/commands/theme/create.ts"() {
3678
+ "use strict";
3679
+ init_esm_shims();
3680
+ init_utils();
3681
+ BASE_THEMES = {
3682
+ standard: {
3683
+ name: "\u6807\u51C6\u4E3B\u9898",
3684
+ colors: { primary: "#4F46E5", background: "#FFFFFF" }
3685
+ },
3686
+ nebula: {
3687
+ name: "\u661F\u4E91\u4E3B\u9898",
3688
+ colors: { primary: "#7C3AED", background: "#0F172A" }
3689
+ },
3690
+ glass: {
3691
+ name: "\u73BB\u7483\u4E3B\u9898",
3692
+ colors: { primary: "#06B6D4", background: "#1E293B" }
3693
+ }
3694
+ };
3695
+ }
3696
+ });
3697
+
3698
+ // src/commands/scaffold.ts
3699
+ var scaffold_exports = {};
3700
+ __export(scaffold_exports, {
3701
+ scaffold: () => scaffold
3702
+ });
3703
+ import fs24 from "fs-extra";
3704
+ import path27 from "path";
3705
+ import pc20 from "picocolors";
3706
+ async function scaffold(options) {
3707
+ const { name, template = "full", typescript = true, theme = "standard" } = options;
3708
+ const targetDir = path27.join(process.cwd(), name);
3709
+ if (fs24.existsSync(targetDir)) {
3710
+ logger.error(`\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728`);
3711
+ return;
3712
+ }
3713
+ logger.info(`\u6B63\u5728\u521B\u5EFA\u9879\u76EE: ${pc20.cyan(name)}`);
3714
+ logger.info(`\u6A21\u677F: ${pc20.yellow(TEMPLATES2[template].name)}`);
3715
+ await fs24.ensureDir(targetDir);
3716
+ const packageJson = {
3717
+ name,
3718
+ version: "0.1.0",
3719
+ private: true,
3720
+ scripts: {
3721
+ dev: "chatbi-cli dev",
3722
+ build: "chatbi-cli build",
3723
+ test: "vitest"
3724
+ },
3725
+ dependencies: {
3726
+ "@chatbi-v/core": "workspace:*",
3727
+ react: "^18.2.0",
3728
+ "react-dom": "^18.2.0"
3729
+ },
3730
+ devDependencies: {
3731
+ "@types/react": "^18.2.0",
3732
+ typescript: "^5.0.0",
3733
+ vite: "^5.0.0"
3734
+ }
3735
+ };
3736
+ await fs24.writeJson(path27.join(targetDir, "package.json"), packageJson, { spaces: 2 });
3737
+ await fs24.ensureDir(path27.join(targetDir, "apps", "deepinsight"));
3738
+ await fs24.ensureDir(path27.join(targetDir, "packages", "plugins"));
3739
+ await fs24.writeFile(path27.join(targetDir, "pnpm-workspace.yaml"), 'packages:\n - "apps/*"\n - "packages/*"\n');
3740
+ if (typescript) {
3741
+ const viteConfig = `import { defineConfig } from 'vite';
3742
+ import react from '@vitejs/plugin-react';
3743
+
3744
+ export default defineConfig({
3745
+ plugins: [react()],
3746
+ });
3747
+ `;
3748
+ await fs24.writeFile(path27.join(targetDir, "vite.config.ts"), viteConfig);
3749
+ }
3750
+ logger.success(`\u9879\u76EE ${pc20.green(name)} \u521B\u5EFA\u6210\u529F!`);
3751
+ logger.info(`\u8BF7\u8FD0\u884C ${pc20.cyan(`cd ${name} && pnpm install`)} \u5B89\u88C5\u4F9D\u8D56`);
3752
+ }
3753
+ var TEMPLATES2;
3754
+ var init_scaffold = __esm({
3755
+ "src/commands/scaffold.ts"() {
3756
+ "use strict";
3757
+ init_esm_shims();
3758
+ init_utils();
3759
+ TEMPLATES2 = {
3760
+ full: {
3761
+ name: "\u5B8C\u6574\u5E94\u7528",
3762
+ description: "\u5305\u542B\u591A\u4E2A\u63D2\u4EF6\u548C\u5B8C\u6574\u914D\u7F6E"
3763
+ },
3764
+ minimal: {
3765
+ name: "\u6700\u5C0F\u5E94\u7528",
3766
+ description: "\u5305\u542B\u57FA\u7840\u63D2\u4EF6"
3767
+ },
3768
+ empty: {
3769
+ name: "\u7A7A\u9879\u76EE",
3770
+ description: "\u4EC5\u5305\u542B\u9879\u76EE\u7ED3\u6784"
3771
+ }
3772
+ };
3773
+ }
3774
+ });
3775
+
3776
+ // src/commands/upgrade.ts
3777
+ var upgrade_exports = {};
3778
+ __export(upgrade_exports, {
3779
+ upgrade: () => upgrade
3780
+ });
3781
+ import { execSync } from "child_process";
3782
+ import pc21 from "picocolors";
3783
+ async function upgrade(targetVersion) {
3784
+ const currentVersion = package_default.version;
3785
+ logger.info(`\u5F53\u524D\u7248\u672C: ${pc21.cyan(currentVersion)}`);
3786
+ if (targetVersion) {
3787
+ logger.info(`\u6B63\u5728\u5347\u7EA7\u5230\u7248\u672C: ${pc21.yellow(targetVersion)}`);
3788
+ try {
3789
+ execSync(`pnpm add -g @chatbi-v/cli@${targetVersion}`, {
3790
+ stdio: "inherit"
3791
+ });
3792
+ logger.success("\u5347\u7EA7\u6210\u529F!");
3793
+ } catch (error) {
3794
+ logger.error("\u5347\u7EA7\u5931\u8D25", error);
3795
+ }
3796
+ } else {
3797
+ logger.info("\u6B63\u5728\u68C0\u67E5\u6700\u65B0\u7248\u672C...");
3798
+ try {
3799
+ const latestVersion = execSync("npm view @chatbi-v/cli version", {
3800
+ encoding: "utf-8"
3801
+ }).trim();
3802
+ if (latestVersion > currentVersion) {
3803
+ logger.info(`\u6700\u65B0\u7248\u672C: ${pc21.green(latestVersion)}`);
3804
+ logger.info(`\u8BF7\u8FD0\u884C ${pc21.cyan(`pnpm add -g @chatbi-v/cli@${latestVersion}`)} \u5347\u7EA7`);
3805
+ } else {
3806
+ logger.success("\u5F53\u524D\u5DF2\u662F\u6700\u65B0\u7248\u672C!");
3807
+ }
3808
+ } catch {
3809
+ logger.warn("\u65E0\u6CD5\u68C0\u67E5\u6700\u65B0\u7248\u672C");
3810
+ }
3811
+ }
3812
+ }
3813
+ var init_upgrade = __esm({
3814
+ "src/commands/upgrade.ts"() {
3815
+ "use strict";
3816
+ init_esm_shims();
3817
+ init_package();
3818
+ init_utils();
3819
+ }
3820
+ });
3821
+
3822
+ // src/commands/devtools/types.ts
3823
+ var types_exports = {};
3824
+ __export(types_exports, {
3825
+ devtoolsTypes: () => devtoolsTypes
3826
+ });
3827
+ import { PluginManifestSchema as PluginManifestSchema2 } from "@chatbi-v/core";
3828
+ import fs25 from "fs-extra";
3829
+ import path28 from "path";
3830
+ import pc22 from "picocolors";
3831
+ async function devtoolsTypes(options) {
3832
+ const { input = "src/plugin.json", output, type = "full" } = options;
3833
+ const inputPath = path28.resolve(process.cwd(), input);
3834
+ if (!fs25.existsSync(inputPath)) {
3835
+ logger.error(`\u627E\u4E0D\u5230 plugin.json \u6587\u4EF6: ${inputPath}`);
3836
+ return;
3837
+ }
3838
+ logger.info(`\u8BFB\u53D6\u63D2\u4EF6\u6E05\u5355: ${pc22.cyan(inputPath)}`);
3839
+ try {
3840
+ const pluginJson = await fs25.readJson(inputPath);
3841
+ const manifest = PluginManifestSchema2.parse(pluginJson);
3842
+ const typeCode = generateTypeDefinition(manifest, type);
3843
+ if (output) {
3844
+ const outputPath = path28.resolve(process.cwd(), output);
3845
+ await fs25.ensureDir(path28.dirname(outputPath));
3846
+ await fs25.writeFile(outputPath, typeCode, "utf-8");
3847
+ logger.success(`\u7C7B\u578B\u5B9A\u4E49\u5DF2\u751F\u6210: ${pc22.green(outputPath)}`);
3848
+ } else {
3849
+ console.log(typeCode);
3850
+ }
3851
+ } catch (error) {
3852
+ logger.error("\u751F\u6210\u7C7B\u578B\u5B9A\u4E49\u5931\u8D25", error);
3853
+ }
3854
+ }
3855
+ function generateTypeDefinition(manifest, type) {
3856
+ const lines = [
3857
+ "// Auto-generated TypeScript definitions",
3858
+ `// Generated at: ${(/* @__PURE__ */ new Date()).toISOString()}`,
3859
+ `// Plugin: ${manifest.id} v${manifest.version}`,
3860
+ "",
3861
+ "import { z } from 'zod';",
3862
+ "",
3863
+ "// ============================================================",
3864
+ "// Plugin Manifest",
3865
+ "// ============================================================",
3866
+ "",
3867
+ "export interface PluginManifest {",
3868
+ ` id: '${manifest.id}';`,
3869
+ ` name: '${manifest.name}';`,
3870
+ ` version: '${manifest.version}';`,
3871
+ manifest.type ? ` type: '${manifest.type}';` : "",
3872
+ manifest.description ? ` description: '${manifest.description}';` : "",
3873
+ manifest.author ? ` author: '${manifest.author}';` : "",
3874
+ manifest.entry,
3875
+ " // ...other fields",
3876
+ "}",
3877
+ ""
3878
+ ];
3879
+ if (type === "full") {
3880
+ lines.push(
3881
+ "// ============================================================",
3882
+ "// Dependencies",
3883
+ "// ============================================================",
3884
+ ""
3885
+ );
3886
+ if (manifest.dependencies && manifest.dependencies.length > 0) {
3887
+ lines.push("export interface PluginDependencies {");
3888
+ manifest.dependencies.forEach((dep) => {
3889
+ lines.push(
3890
+ ` '${dep.id}': '${dep.version}'${dep.optional ? " // optional" : ""};`
3891
+ );
3892
+ });
3893
+ lines.push("}");
3894
+ lines.push("");
3895
+ }
3896
+ lines.push(
3897
+ "// ============================================================",
3898
+ "// Extensions",
3899
+ "// ============================================================",
3900
+ ""
3901
+ );
3902
+ if (manifest.extensions && manifest.extensions.length > 0) {
3903
+ lines.push("export type ExtensionType = " + [...new Set(manifest.extensions.map((e) => `'${e.type}'`))].join(" | ") + ";");
3904
+ lines.push("");
3905
+ lines.push("export interface PluginExtensions {");
3906
+ manifest.extensions.forEach((ext) => {
3907
+ lines.push(` ${ext.name}: {`);
3908
+ lines.push(` type: '${ext.type}';`);
3909
+ if (ext.description) lines.push(` description: '${ext.description}';`);
3910
+ if (ext.slot) lines.push(` slot: '${ext.slot}';`);
3911
+ lines.push(" };");
3912
+ });
3913
+ lines.push("}");
3914
+ lines.push("");
3915
+ }
3916
+ if (manifest.configuration && manifest.configuration.length > 0) {
3917
+ lines.push(
3918
+ "// ============================================================",
3919
+ "// Configuration",
3920
+ "// ============================================================",
3921
+ "",
3922
+ "export interface PluginConfiguration {"
3923
+ );
3924
+ manifest.configuration.forEach((config4) => {
3925
+ lines.push(` ${config4.key}: ${configTypeToTs(config4.type)};`);
3926
+ });
3927
+ lines.push("}");
3928
+ lines.push("");
3929
+ }
3930
+ }
3931
+ lines.push(
3932
+ "// ============================================================",
3933
+ "// Zod Schema (for validation)",
3934
+ "// ============================================================",
3935
+ "",
3936
+ "export const PluginManifestSchema = z.object({",
3937
+ ` id: z.literal('${manifest.id}'),`,
3938
+ ` name: z.string().default('${manifest.name}'),`,
3939
+ ` version: z.string().default('${manifest.version}'),`,
3940
+ " // ...other schema fields",
3941
+ "});",
3942
+ ""
3943
+ );
3944
+ return lines.filter(Boolean).join("\n");
3945
+ }
3946
+ function configTypeToTs(configType) {
3947
+ switch (configType) {
3948
+ case "string":
3949
+ return "string";
3950
+ case "number":
3951
+ return "number";
3952
+ case "boolean":
3953
+ return "boolean";
3954
+ case "select":
3955
+ return "string";
3956
+ default:
3957
+ return "unknown";
2677
3958
  }
2678
- await sync({ version, force: false });
2679
3959
  }
3960
+ var init_types = __esm({
3961
+ "src/commands/devtools/types.ts"() {
3962
+ "use strict";
3963
+ init_esm_shims();
3964
+ init_utils();
3965
+ }
3966
+ });
2680
3967
 
2681
3968
  // src/index.ts
3969
+ init_esm_shims();
3970
+ init_package();
2682
3971
  init_utils();
3972
+ import boxen2 from "boxen";
3973
+ import cac from "cac";
3974
+ import figlet from "figlet";
3975
+ import gradient from "gradient-string";
3976
+ import pc23 from "picocolors";
2683
3977
  var cli = cac("chatbi-cli");
2684
3978
  var showHeader = () => {
2685
3979
  const title = figlet.textSync("ChatBI-V CLI", { font: "Standard" });
2686
- console.log(gradient.pastel.multiline(title));
2687
- console.log(
2688
- boxen2(pc16.cyan(`ChatBI-V \u7EDF\u4E00\u5F00\u53D1\u5DE5\u5177 v${package_default.version}`), {
3980
+ logger.info(gradient.pastel.multiline(title));
3981
+ logger.info(
3982
+ boxen2(pc23.cyan(`ChatBI-V \u7EDF\u4E00\u5F00\u53D1\u5DE5\u5177 v${package_default.version}`), {
2689
3983
  padding: 0,
2690
3984
  margin: { top: 1, bottom: 1 },
2691
3985
  borderStyle: "round",
@@ -2698,6 +3992,11 @@ var showHeader = () => {
2698
3992
  var wrapAction = (action, commandName) => {
2699
3993
  return async (...args) => {
2700
3994
  const updateCheckPromise = checkForUpdates(package_default.version);
3995
+ const options = args[args.length - 1];
3996
+ if (options && options.debug) {
3997
+ setDebugMode(true);
3998
+ logger.debug("Debug mode enabled");
3999
+ }
2701
4000
  showHeader();
2702
4001
  try {
2703
4002
  await action(...args);
@@ -2712,22 +4011,38 @@ var wrapAction = (action, commandName) => {
2712
4011
  }
2713
4012
  };
2714
4013
  };
2715
- cli.command("dev", "\u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668").alias("d").option("--port <port>", "\u7AEF\u53E3\u53F7").action(wrapAction(dev, "dev"));
2716
- cli.command("build", "\u6784\u5EFA\u5F53\u524D\u9879\u76EE").alias("b").option("--watch", "\u5F00\u542F\u76D1\u542C\u6A21\u5F0F").option("--force", "\u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316\u73AF\u5883 (\u6E05\u7406\u7F13\u5B58)").action(wrapAction(build, "build"));
2717
- cli.command("fetch <version>", "\u83B7\u53D6\u6307\u5B9A\u7248\u672C\u7684\u5185\u6838 (\u652F\u6301\u6253\u5305)").option("--pack", "\u6253\u5305\u4E3A\u79BB\u7EBF\u5B89\u88C5\u5305 (.tgz)").action(wrapAction(fetch, "fetch"));
2718
- cli.command("install <target>", "\u5B89\u88C5\u5185\u6838 (\u652F\u6301\u7248\u672C\u53F7\u6216\u79BB\u7EBF\u5305\u8DEF\u5F84)").action(wrapAction(install, "install"));
2719
- cli.command("init [name]", "\u521D\u59CB\u5316\u4E00\u4E2A\u65B0\u7684\u4E1A\u52A1\u63D2\u4EF6\u9879\u76EE").alias("create").alias("i").option("--project-type <type>", "\u9879\u76EE\u7C7B\u578B (monorepo | app | plugin)").option("--include-app", "Monorepo \u4E2D\u5305\u542B App").option("--no-include-app", "Monorepo \u4E2D\u4E0D\u5305\u542B App").option("--include-plugin", "Monorepo \u4E2D\u5305\u542B Plugin").option("--no-include-plugin", "Monorepo \u4E2D\u4E0D\u5305\u542B Plugin").option("--plugin-type <type>", "\u63D2\u4EF6\u7C7B\u578B (business | system)").option("--theme <theme>", "\u4E3B\u9898 (standard | nebula | glass)").action(wrapAction(async (name, options) => {
2720
- await init({
4014
+ cli.option("--debug", "\u5F00\u542F\u8C03\u8BD5\u6A21\u5F0F");
4015
+ cli.command("dev", "\u542F\u52A8\u5F00\u53D1\u670D\u52A1\u5668").alias("d").option("--port <port>", "\u7AEF\u53E3\u53F7").action(wrapAction(async (options) => {
4016
+ const { dev: dev2 } = await Promise.resolve().then(() => (init_dev(), dev_exports));
4017
+ await dev2(options);
4018
+ }, "dev"));
4019
+ cli.command("build", "\u6784\u5EFA\u5F53\u524D\u9879\u76EE").alias("b").option("--watch", "\u5F00\u542F\u76D1\u542C\u6A21\u5F0F").option("--force", "\u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316\u73AF\u5883 (\u6E05\u7406\u7F13\u5B58)").action(wrapAction(async (options) => {
4020
+ const { build: build2 } = await Promise.resolve().then(() => (init_build(), build_exports));
4021
+ await build2(options);
4022
+ }, "build"));
4023
+ cli.command("fetch <version>", "\u83B7\u53D6\u6307\u5B9A\u7248\u672C\u7684\u5185\u6838 (\u652F\u6301\u6253\u5305)").option("--pack", "\u6253\u5305\u4E3A\u79BB\u7EBF\u5B89\u88C5\u5305 (.tgz)").action(wrapAction(async (version, options) => {
4024
+ const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
4025
+ await fetch2(version, options);
4026
+ }, "fetch"));
4027
+ cli.command("install <target>", "\u5B89\u88C5\u5185\u6838 (\u652F\u6301\u7248\u672C\u53F7\u6216\u79BB\u7EBF\u5305\u8DEF\u5F84)").action(wrapAction(async (target) => {
4028
+ const { install: install2 } = await Promise.resolve().then(() => (init_install(), install_exports));
4029
+ await install2(target);
4030
+ }, "install"));
4031
+ cli.command("init [name]", "\u521D\u59CB\u5316\u4E00\u4E2A\u65B0\u7684\u4E1A\u52A1\u63D2\u4EF6\u9879\u76EE").alias("create").alias("i").option("--project-type <type>", "\u9879\u76EE\u7C7B\u578B (monorepo | app | plugin)").option("--include-app", "Monorepo \u4E2D\u5305\u542B App").option("--no-include-app", "Monorepo \u4E2D\u4E0D\u5305\u542B App").option("--include-plugin", "Monorepo \u4E2D\u5305\u542B Plugin").option("--no-include-plugin", "Monorepo \u4E2D\u4E0D\u5305\u542B Plugin").option("--plugin-type <type>", "\u63D2\u4EF6\u7C7B\u578B (business | system)").option("--theme <theme>", "\u4E3B\u9898 (standard | nebula | glass)").option("--force", "\u5F3A\u5236\u8986\u76D6\u76EE\u6807\u76EE\u5F55").action(wrapAction(async (name, options) => {
4032
+ const { init: init2 } = await Promise.resolve().then(() => (init_init(), init_exports));
4033
+ await init2({
2721
4034
  name,
2722
4035
  projectType: options.projectType,
2723
4036
  includeApp: options.includeApp,
2724
4037
  includePlugin: options.includePlugin,
2725
4038
  pluginType: options.pluginType,
2726
- theme: options.theme
4039
+ theme: options.theme,
4040
+ force: options.force
2727
4041
  });
2728
4042
  }, "init"));
2729
4043
  cli.command("add [name]", "\u5728\u5F53\u524D\u9879\u76EE\u4E2D\u6DFB\u52A0\u4E00\u4E2A\u65B0\u63D2\u4EF6").option("-t, --type <type>", "\u63D2\u4EF6\u7C7B\u578B (business | system)").option("--display-name <name>", "\u63D2\u4EF6\u663E\u793A\u540D\u79F0").option("--desc <description>", "\u63D2\u4EF6\u63CF\u8FF0").action(wrapAction(async (name, options) => {
2730
- await add({
4044
+ const { add: add2 } = await Promise.resolve().then(() => (init_add(), add_exports));
4045
+ await add2({
2731
4046
  name,
2732
4047
  type: options.type,
2733
4048
  displayName: options.displayName,
@@ -2740,36 +4055,97 @@ cli.command("update [targetVersion]", "\u66F4\u65B0\u5185\u6838\u7248\u672C").al
2740
4055
  logger.success("\u66F4\u65B0\u5B8C\u6210\uFF01");
2741
4056
  }, "update"));
2742
4057
  cli.command("sync", "\u540C\u6B65\u5185\u6838\u4F9D\u8D56\u4E0E\u89C4\u8303").alias("s").option("-v, --core-version <version>", "\u6307\u5B9A\u5185\u6838\u7248\u672C").option("-f, --force", "\u5F3A\u5236\u91CD\u65B0\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1").option("--clean", "\u6E05\u7406\u5E76\u91CD\u7F6E\u6C99\u7BB1").action(wrapAction(async (options) => {
2743
- await sync({ ...options, version: options.coreVersion });
2744
- console.log("");
2745
- await doctor({ fix: false });
4058
+ const { sync: sync2 } = await Promise.resolve().then(() => (init_sync(), sync_exports));
4059
+ const { doctor: doctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
4060
+ await sync2({ ...options, version: options.coreVersion });
4061
+ logger.info("");
4062
+ await doctor2({ fix: false });
2746
4063
  }, "sync"));
2747
- cli.command("doctor", "\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5\u5E76\u4FEE\u590D").alias("dr").option("--fix", "\u81EA\u52A8\u4FEE\u590D\u53D1\u73B0\u7684\u95EE\u9898").action(wrapAction(doctor, "doctor"));
2748
- cli.command("list", "\u5217\u51FA\u6240\u6709\u5DF2\u5B89\u88C5\u7684\u5185\u6838\u6C99\u7BB1\u7248\u672C").alias("ls").action(wrapAction(ls, "ls"));
2749
- cli.command("use <version>", "\u5207\u6362\u5F53\u524D\u9879\u76EE\u4F7F\u7528\u7684\u5185\u6838\u7248\u672C").alias("u").option("--global", "\u5207\u6362\u5168\u5C40\u9ED8\u8BA4\u5185\u6838\u7248\u672C").action(wrapAction(use, "use"));
2750
- cli.command("gl", "\u4F7F\u7528 AI \u811A\u624B\u67B6\u751F\u6210\u4EE3\u7801\u6216\u6587\u6863").option("-t, --type <type>", "\u751F\u6210\u7C7B\u578B (plugin|util|doc|component)").option("-p, --prompt <prompt>", "AI \u9700\u6C42\u63CF\u8FF0").action(wrapAction(gl, "gl"));
2751
- cli.command("discover", "\u626B\u63CF\u5E76\u53D1\u73B0\u5F53\u524D\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6").action(wrapAction(discover, "discover"));
2752
- cli.command("clean", "\u6E05\u7406 CLI \u4EA7\u751F\u7684\u7F13\u5B58\u76EE\u5F55").alias("cl").option("--deep", "\u6DF1\u5EA6\u6E05\u7406 (\u5305\u542B\u6240\u6709\u5B50\u5305\u7684 .chatbi \u76EE\u5F55\u53CA\u5168\u5C40\u6C99\u7BB1\u6839\u76EE\u5F55)").action(wrapAction(clean, "clean"));
4064
+ cli.command("doctor", "\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5\u5E76\u4FEE\u590D").alias("dr").option("--fix", "\u81EA\u52A8\u4FEE\u590D\u53D1\u73B0\u7684\u95EE\u9898").action(wrapAction(async (options) => {
4065
+ const { doctor: doctor2 } = await Promise.resolve().then(() => (init_doctor(), doctor_exports));
4066
+ await doctor2(options);
4067
+ }, "doctor"));
4068
+ cli.command("list", "\u5217\u51FA\u6240\u6709\u5DF2\u5B89\u88C5\u7684\u5185\u6838\u6C99\u7BB1\u7248\u672C").alias("ls").action(wrapAction(async () => {
4069
+ const { ls: ls2 } = await Promise.resolve().then(() => (init_ls(), ls_exports));
4070
+ await ls2();
4071
+ }, "ls"));
4072
+ cli.command("use <version>", "\u5207\u6362\u5F53\u524D\u9879\u76EE\u4F7F\u7528\u7684\u5185\u6838\u7248\u672C").alias("u").option("--global", "\u5207\u6362\u5168\u5C40\u9ED8\u8BA4\u5185\u6838\u7248\u672C").action(wrapAction(async (version, options) => {
4073
+ const { use: use2 } = await Promise.resolve().then(() => (init_use(), use_exports));
4074
+ await use2(version, options);
4075
+ }, "use"));
4076
+ cli.command("gl", "\u4F7F\u7528 AI \u811A\u624B\u67B6\u751F\u6210\u4EE3\u7801\u6216\u6587\u6863").option("-t, --type <type>", "\u751F\u6210\u7C7B\u578B (plugin|util|doc|component)").option("-p, --prompt <prompt>", "AI \u9700\u6C42\u63CF\u8FF0").action(wrapAction(async (options) => {
4077
+ const { gl: gl2 } = await Promise.resolve().then(() => (init_gl(), gl_exports));
4078
+ await gl2(options);
4079
+ }, "gl"));
4080
+ cli.command("discover", "\u626B\u63CF\u5E76\u53D1\u73B0\u5F53\u524D\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6").action(wrapAction(async () => {
4081
+ const { discover: discover2 } = await Promise.resolve().then(() => (init_discover(), discover_exports));
4082
+ await discover2();
4083
+ }, "discover"));
4084
+ cli.command("clean", "\u6E05\u7406 CLI \u4EA7\u751F\u7684\u7F13\u5B58\u76EE\u5F55").alias("cl").option("--deep", "\u6DF1\u5EA6\u6E05\u7406 (\u5305\u542B\u6240\u6709\u5B50\u5305\u7684 .chatbi \u76EE\u5F55\u53CA\u5168\u5C40\u6C99\u7BB1\u6839\u76EE\u5F55)").option("--dry-run", "\u9884\u89C8\u5C06\u8981\u5220\u9664\u7684\u6587\u4EF6").option("-y, --yes", "\u8DF3\u8FC7\u786E\u8BA4").action(wrapAction(async (options) => {
4085
+ const { clean: clean2 } = await Promise.resolve().then(() => (init_clean(), clean_exports));
4086
+ await clean2(options);
4087
+ }, "clean"));
2753
4088
  cli.command("bench", "\u8FD0\u884C CLI \u6027\u80FD\u57FA\u51C6\u6D4B\u8BD5").action(wrapAction(async () => {
2754
4089
  const { bench: bench2 } = await Promise.resolve().then(() => (init_bench(), bench_exports));
2755
4090
  await bench2();
2756
4091
  }, "bench"));
2757
- cli.help((sections) => {
2758
- showHeader();
2759
- sections[0].body = pc16.white("ChatBI-V \u5F00\u53D1\u8005\u547D\u4EE4\u884C\u5DE5\u5177\uFF0C\u52A9\u529B\u5FEB\u901F\u5F00\u53D1\u548C\u6784\u5EFA\u63D2\u4EF6\u3002");
4092
+ cli.command("lint:theme [target]", "\u68C0\u6D4B\u9879\u76EE\u4E2D\u7684\u4E3B\u9898\u89C4\u8303\u95EE\u9898").option("--fix", "\u81EA\u52A8\u4FEE\u590D\u53EF\u4FEE\u590D\u7684\u95EE\u9898").option("--format <format>", "\u8F93\u51FA\u683C\u5F0F (stylish, json, etc.)", { default: "stylish" }).option("--output <file>", "\u8F93\u51FA\u62A5\u544A\u6587\u4EF6\u8DEF\u5F84").action(wrapAction(async (target, options) => {
4093
+ const { lintTheme: lintTheme2 } = await Promise.resolve().then(() => (init_lint_theme(), lint_theme_exports));
4094
+ await lintTheme2({ target, ...options });
4095
+ }, "lint:theme"));
4096
+ cli.command("plugin", "\u63D2\u4EF6\u7BA1\u7406\u547D\u4EE4").action(() => {
4097
+ logger.warn("\u8BF7\u4F7F\u7528 plugin \u5B50\u547D\u4EE4: create, publish");
2760
4098
  });
4099
+ cli.command("plugin create <name>", "\u521B\u5EFA\u65B0\u63D2\u4EF6").option("-t, --template <template>", "\u63D2\u4EF6\u6A21\u677F (basic|command|ui|ai)").option("--typescript", "\u4F7F\u7528 TypeScript").option("--force", "\u5F3A\u5236\u8986\u76D6").action(wrapAction(async (name, options) => {
4100
+ const { pluginCreate: pluginCreate2 } = await Promise.resolve().then(() => (init_create(), create_exports));
4101
+ await pluginCreate2({
4102
+ name,
4103
+ template: options.template || "basic",
4104
+ typescript: options.typescript !== false,
4105
+ force: !!options.force
4106
+ });
4107
+ }, "plugin create"));
4108
+ cli.command("plugin build", "\u6784\u5EFA\u63D2\u4EF6").option("-w, --watch", "\u76D1\u542C\u6A21\u5F0F").option("--no-minify", "\u4E0D\u538B\u7F29").action(wrapAction(async (options) => {
4109
+ const { pluginBuild: pluginBuild2 } = await Promise.resolve().then(() => (init_build2(), build_exports2));
4110
+ await pluginBuild2({ watch: options.watch, minify: options.minify });
4111
+ }, "plugin build"));
4112
+ cli.command("plugin validate", "\u9A8C\u8BC1\u63D2\u4EF6\u914D\u7F6E").option("--fix", "\u81EA\u52A8\u4FEE\u590D").action(wrapAction(async (options) => {
4113
+ const { pluginValidate: pluginValidate2 } = await Promise.resolve().then(() => (init_validate(), validate_exports));
4114
+ await pluginValidate2({ fix: options.fix });
4115
+ }, "plugin validate"));
4116
+ cli.command("plugin publish", "\u53D1\u5E03\u63D2\u4EF6\u5230\u5E02\u573A").option("--scope <scope>", "npm scope").option("--registry <registry>", "\u81EA\u5B9A\u4E49 registry").action(wrapAction(async (options) => {
4117
+ const { pluginPublish: pluginPublish2 } = await Promise.resolve().then(() => (init_publish(), publish_exports));
4118
+ await pluginPublish2({ scope: options.scope, registry: options.registry });
4119
+ }, "plugin publish"));
4120
+ cli.command("theme create <name>", "\u521B\u5EFA\u65B0\u4E3B\u9898").option("-b, --base <base>", "\u57FA\u7840\u4E3B\u9898 (standard|nebula|glass)").option("--css", "\u4F7F\u7528\u7EAF CSS").action(wrapAction(async (name, options) => {
4121
+ const { themeCreate: themeCreate2 } = await Promise.resolve().then(() => (init_create2(), create_exports2));
4122
+ await themeCreate2({
4123
+ name,
4124
+ base: options.base || "standard",
4125
+ css: !!options.css
4126
+ });
4127
+ }, "theme create"));
4128
+ cli.command("scaffold <name>", "\u521B\u5EFA\u65B0\u9879\u76EE\u811A\u624B\u67B6").option("-t, --template <template>", "\u5E94\u7528\u6A21\u677F (full|minimal|empty)").option("--typescript", "\u4F7F\u7528 TypeScript").option("--theme <theme>", "\u4E3B\u9898").action(wrapAction(async (name, options) => {
4129
+ const { scaffold: scaffold2 } = await Promise.resolve().then(() => (init_scaffold(), scaffold_exports));
4130
+ await scaffold2({
4131
+ name,
4132
+ template: options.template || "full",
4133
+ typescript: options.typescript !== false,
4134
+ theme: options.theme || "standard"
4135
+ });
4136
+ }, "scaffold"));
4137
+ cli.command("upgrade [targetVersion]", "\u5347\u7EA7 CLI \u7248\u672C").action(wrapAction(async (targetVersion) => {
4138
+ const { upgrade: upgrade2 } = await Promise.resolve().then(() => (init_upgrade(), upgrade_exports));
4139
+ await upgrade2(targetVersion);
4140
+ }, "upgrade"));
4141
+ cli.command("devtools types", "\u4ECE plugin.json \u751F\u6210 TypeScript \u7C7B\u578B\u5B9A\u4E49").option("-i, --input <file>", "\u8F93\u5165\u6587\u4EF6\u8DEF\u5F84", { default: "src/plugin.json" }).option("-o, --output <file>", "\u8F93\u51FA\u6587\u4EF6\u8DEF\u5F84").option("-t, --type <type>", "\u7C7B\u578B\u751F\u6210\u6A21\u5F0F (full|minimal)", { default: "full" }).action(wrapAction(async (options) => {
4142
+ const { devtoolsTypes: devtoolsTypes2 } = await Promise.resolve().then(() => (init_types(), types_exports));
4143
+ await devtoolsTypes2({
4144
+ input: options.input,
4145
+ output: options.output,
4146
+ type: options.type
4147
+ });
4148
+ }, "devtools types"));
4149
+ cli.help();
2761
4150
  cli.version(package_default.version);
2762
- if (process.argv.length <= 2) {
2763
- cli.outputHelp();
2764
- } else {
2765
- cli.parse();
2766
- }
2767
- var main = async () => {
2768
- if (process.argv.includes("--help") || process.argv.includes("-h") || process.argv.includes("--version") || process.argv.includes("-v")) {
2769
- const latestVersion = await checkForUpdates(package_default.version);
2770
- if (latestVersion) {
2771
- printUpdateNotification(package_default.version, latestVersion);
2772
- }
2773
- }
2774
- };
2775
- main();
4151
+ cli.parse();