@chatbi-v/cli 2.1.6 → 2.1.7

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,23 +8,81 @@ var __export = (target, all) => {
8
8
  __defProp(target, name, { get: all[name], enumerable: true });
9
9
  };
10
10
 
11
- // ../../../chatbi-v/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_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.6_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
- "../../../chatbi-v/node_modules/.pnpm/tsup@8.5.1_jiti@2.6.1_postcss@8.5.6_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.6_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/utils.ts
20
+ // src/constants.ts
21
+ import os from "os";
21
22
  import path2 from "path";
22
- import { createRequire } from "module";
23
- import { fileURLToPath as fileURLToPath2 } from "url";
23
+ var SANDBOX_CONFIG, GLOBAL_PATHS, DEPENDENCY_VERSIONS, DEFAULT_CONFIG;
24
+ var init_constants = __esm({
25
+ "src/constants.ts"() {
26
+ "use strict";
27
+ 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"
36
+ },
37
+ /** 关键标识文件 */
38
+ LOCK_FILE: ".chatbi-version"
39
+ };
40
+ GLOBAL_PATHS = {
41
+ /** 沙箱根路径 */
42
+ BASE_DIR: path2.join(os.homedir(), SANDBOX_CONFIG.BASE_NAME),
43
+ /** Monorepo 扫描目录 */
44
+ MONOREPO_ROOTS: ["apps", "plugins", "packages"]
45
+ };
46
+ DEPENDENCY_VERSIONS = {
47
+ // 基础框架
48
+ "react": "^18.3.1",
49
+ "react-dom": "^18.3.1",
50
+ "antd": "^5.20.0",
51
+ // 构建工具
52
+ "vite": "^5.0.8",
53
+ "typescript": "^5.3.3",
54
+ "tailwindcss": "^3.4.1",
55
+ "autoprefixer": "^10.4.17",
56
+ "postcss": "^8.4.35",
57
+ "less": "^4.2.0",
58
+ // 类型定义
59
+ "@types/react": "^18.3.1",
60
+ "@types/react-dom": "^18.3.1",
61
+ "@types/node": "^20.11.20",
62
+ "@vitejs/plugin-react": "^4.2.1"
63
+ };
64
+ DEFAULT_CONFIG = {
65
+ /** 支持的配置文件名 */
66
+ CONFIG_FILES: [
67
+ "chatbi.config.ts",
68
+ "chatbi.config.js",
69
+ "chatbi.config.json",
70
+ ".chatbirc"
71
+ ],
72
+ /** 默认 UI 主题 */
73
+ THEME: "standard"
74
+ };
75
+ }
76
+ });
77
+
78
+ // src/utils.ts
79
+ import boxen from "boxen";
24
80
  import fs from "fs-extra";
25
- import pc from "picocolors";
81
+ import { createRequire } from "module";
26
82
  import ora from "ora";
27
- import boxen from "boxen";
83
+ import path3 from "path";
84
+ import pc from "picocolors";
85
+ import { fileURLToPath as fileURLToPath2 } from "url";
28
86
  var _require, _filename, _dirname, logger, createSpinner, printBox, findPackageRoot, getCliRoot;
29
87
  var init_utils = __esm({
30
88
  "src/utils.ts"() {
@@ -32,7 +90,7 @@ var init_utils = __esm({
32
90
  init_esm_shims();
33
91
  _require = createRequire(import.meta.url);
34
92
  _filename = fileURLToPath2(import.meta.url);
35
- _dirname = path2.dirname(_filename);
93
+ _dirname = path3.dirname(_filename);
36
94
  logger = {
37
95
  info: (msg) => console.log(pc.cyan(`\u2139 ${msg}`)),
38
96
  success: (msg) => console.log(pc.green(`\u2714 ${msg}`)),
@@ -72,10 +130,10 @@ var init_utils = __esm({
72
130
  findPackageRoot = (pkgName) => {
73
131
  try {
74
132
  const pkgPath = _require.resolve(`${pkgName}/package.json`);
75
- return path2.dirname(pkgPath);
133
+ return path3.dirname(pkgPath);
76
134
  } catch (e) {
77
135
  if (pkgName === "@chatbi-v/cli") {
78
- return path2.resolve(_dirname, "../../");
136
+ return path3.resolve(_dirname, "../../");
79
137
  }
80
138
  throw new Error(`Package ${pkgName} not found`);
81
139
  }
@@ -83,15 +141,15 @@ var init_utils = __esm({
83
141
  getCliRoot = async () => {
84
142
  let myCliRoot = "";
85
143
  let checkDir = _dirname;
86
- while (checkDir !== path2.parse(checkDir).root) {
87
- if (fs.existsSync(path2.join(checkDir, "package.json"))) {
88
- const pkg = await fs.readJson(path2.join(checkDir, "package.json"));
144
+ while (checkDir !== path3.parse(checkDir).root) {
145
+ if (fs.existsSync(path3.join(checkDir, "package.json"))) {
146
+ const pkg = await fs.readJson(path3.join(checkDir, "package.json"));
89
147
  if (pkg.name === "@chatbi-v/cli") {
90
148
  myCliRoot = checkDir;
91
149
  break;
92
150
  }
93
151
  }
94
- checkDir = path2.dirname(checkDir);
152
+ checkDir = path3.dirname(checkDir);
95
153
  }
96
154
  if (!myCliRoot) {
97
155
  myCliRoot = findPackageRoot("@chatbi-v/cli") || "";
@@ -101,129 +159,120 @@ var init_utils = __esm({
101
159
  }
102
160
  });
103
161
 
104
- // src/constants.ts
105
- import path3 from "path";
106
- import os from "os";
107
- var SANDBOX_CONFIG, GLOBAL_PATHS, DEPENDENCY_VERSIONS, DEFAULT_CONFIG;
108
- var init_constants = __esm({
109
- "src/constants.ts"() {
110
- "use strict";
111
- init_esm_shims();
112
- SANDBOX_CONFIG = {
113
- /** 用户主目录下的沙箱根目录名 */
114
- BASE_NAME: ".chatbi-v-core",
115
- /** 内部子目录结构 */
116
- DIRS: {
117
- VERSIONS: "versions",
118
- CURRENT: "current",
119
- CACHE: ".chatbi"
120
- },
121
- /** 关键标识文件 */
122
- LOCK_FILE: ".chatbi-version"
123
- };
124
- GLOBAL_PATHS = {
125
- /** 沙箱根路径 */
126
- BASE_DIR: path3.join(os.homedir(), SANDBOX_CONFIG.BASE_NAME),
127
- /** Monorepo 扫描目录 */
128
- MONOREPO_ROOTS: ["apps", "plugins", "packages"]
129
- };
130
- DEPENDENCY_VERSIONS = {
131
- // 基础框架
132
- "react": "^18.3.1",
133
- "react-dom": "^18.3.1",
134
- "antd": "^5.20.0",
135
- // 构建工具
136
- "vite": "^5.0.8",
137
- "typescript": "^5.3.3",
138
- "tailwindcss": "^3.4.1",
139
- "autoprefixer": "^10.4.17",
140
- "postcss": "^8.4.35",
141
- "less": "^4.2.0",
142
- // 类型定义
143
- "@types/react": "^18.3.1",
144
- "@types/react-dom": "^18.3.1",
145
- "@types/node": "^20.11.20",
146
- "@vitejs/plugin-react": "^4.2.1"
147
- };
148
- DEFAULT_CONFIG = {
149
- /** 支持的配置文件名 */
150
- CONFIG_FILES: [
151
- "chatbi.config.ts",
152
- "chatbi.config.js",
153
- "chatbi.config.json",
154
- ".chatbirc"
155
- ],
156
- /** 默认 UI 主题 */
157
- THEME: "standard"
158
- };
159
- }
160
- });
161
-
162
- // src/sandbox/SandboxPath.ts
163
- import path4 from "path";
162
+ // src/config.ts
164
163
  import fs2 from "fs-extra";
165
- var SandboxPath;
166
- var init_SandboxPath = __esm({
167
- "src/sandbox/SandboxPath.ts"() {
164
+ import { createJiti } from "jiti";
165
+ import path4 from "path";
166
+ var ConfigManager;
167
+ var init_config = __esm({
168
+ "src/config.ts"() {
168
169
  "use strict";
169
170
  init_esm_shims();
170
171
  init_constants();
171
- SandboxPath = class {
172
+ init_utils();
173
+ init_utils();
174
+ ConfigManager = class {
172
175
  static {
173
- /**
174
- * 沙箱的基础存储目录,通常位于用户主目录下的 .chatbi-v-core
175
- */
176
- this.BASE_DIR = GLOBAL_PATHS.BASE_DIR;
177
- }
178
- /**
179
- * 获取沙箱根目录
180
- * @returns 沙箱根目录的绝对路径
181
- */
182
- static getRoot() {
183
- return this.BASE_DIR;
176
+ this.CONFIG_FILES = DEFAULT_CONFIG.CONFIG_FILES;
184
177
  }
185
178
  /**
186
- * 获取存储所有版本的根目录
187
- * @returns versions 目录的绝对路径
179
+ * 加载项目配置
180
+ * @param cwd 项目根目录
188
181
  */
189
- static getVersionRoot() {
190
- return path4.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS);
182
+ static async loadConfig(cwd = process.cwd()) {
183
+ const config = {};
184
+ const versionFilePath = path4.join(cwd, SANDBOX_CONFIG.LOCK_FILE);
185
+ if (fs2.existsSync(versionFilePath)) {
186
+ try {
187
+ const version = (await fs2.readFile(versionFilePath, "utf-8")).trim();
188
+ if (version) {
189
+ config.coreVersion = version;
190
+ }
191
+ } catch (e) {
192
+ }
193
+ }
194
+ const jiti = createJiti(cwd);
195
+ for (const file of this.CONFIG_FILES) {
196
+ const configPath = path4.join(cwd, file);
197
+ if (fs2.existsSync(configPath)) {
198
+ try {
199
+ let projectConfig = {};
200
+ if (file.endsWith(".ts") || file.endsWith(".js")) {
201
+ const mod = await jiti.import(configPath, { default: true });
202
+ projectConfig = mod.default || mod || {};
203
+ } else if (file.endsWith(".json") || file.startsWith(".chatbirc")) {
204
+ projectConfig = await fs2.readJson(configPath);
205
+ }
206
+ return {
207
+ ...projectConfig,
208
+ ...config
209
+ };
210
+ } catch (e) {
211
+ logger.error(`\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25`, e);
212
+ }
213
+ }
214
+ }
215
+ return config;
191
216
  }
192
217
  /**
193
- * 获取指定版本的沙箱路径
194
- * @param version 版本号,或者 'current' 表示当前激活版本
195
- * @returns 对应版本的绝对路径
218
+ * 解析核心依赖的具体路径或版本号
219
+ * @param config 项目配置
220
+ * @param relativeTo 相对路径(用于 local 模式下的 file: 协议生成)
196
221
  */
197
- static getVersionPath(version) {
198
- if (version === SANDBOX_CONFIG.DIRS.CURRENT) {
199
- return path4.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, SANDBOX_CONFIG.DIRS.CURRENT);
222
+ static async resolveCoreDependency(config, relativeTo = ".") {
223
+ const { coreSource = "local", coreVersion } = config;
224
+ if (coreSource === "npm") {
225
+ if (coreVersion) return coreVersion;
226
+ const cliRoot = await getCliRoot();
227
+ const cliPkg = await fs2.readJson(path4.join(cliRoot, "package.json"));
228
+ return cliPkg.version;
200
229
  }
201
- return path4.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, version);
230
+ const sandboxCorePath = path4.join(SANDBOX_CONFIG.DIRS.CACHE, "core");
231
+ const cwd = process.cwd();
232
+ const absoluteRelativeTo = path4.isAbsolute(relativeTo) ? relativeTo : path4.resolve(cwd, relativeTo);
233
+ const absoluteProjectRoot = cwd;
234
+ const relativePath = path4.relative(absoluteRelativeTo, path4.join(absoluteProjectRoot, sandboxCorePath));
235
+ return `file:${relativePath}`;
202
236
  }
203
237
  /**
204
- * 递归向上查找工作区根目录
205
- * 识别标准:包含 pnpm-workspace.yaml 或 package.json 中定义了 workspaces
206
- * @param cwd 起始查找目录
207
- * @returns 查找到的工作区根目录路径,若未找到则返回 cwd
238
+ * 加载 tsup 配置
239
+ * @param cwd 项目根目录
208
240
  */
209
- static async getWorkspaceRoot(cwd) {
210
- if (!cwd) return cwd;
211
- if (cwd.startsWith("/mock")) return cwd;
212
- let current = path4.resolve(cwd);
213
- while (current !== path4.parse(current).root) {
214
- const pkgPath = path4.join(current, "package.json");
215
- const pnpmWorkspacePath = path4.join(current, "pnpm-workspace.yaml");
216
- if (fs2.existsSync(pnpmWorkspacePath)) return current;
217
- if (fs2.existsSync(pkgPath)) {
241
+ static async loadTsupConfig(cwd = process.cwd()) {
242
+ const TSUP_CONFIG_FILES = [
243
+ "tsup.config.ts",
244
+ "tsup.config.js",
245
+ "tsup.config.cjs",
246
+ "tsup.config.mjs",
247
+ "tsup.config.json"
248
+ ];
249
+ const jiti = createJiti(cwd);
250
+ for (const file of TSUP_CONFIG_FILES) {
251
+ const configPath = path4.join(cwd, file);
252
+ if (fs2.existsSync(configPath)) {
218
253
  try {
219
- const pkg = await fs2.readJson(pkgPath);
220
- if (pkg.workspaces) return current;
254
+ if (file.endsWith(".json")) {
255
+ return await fs2.readJson(configPath);
256
+ } else {
257
+ const mod = await jiti.import(configPath, { default: true });
258
+ return mod.default || mod || {};
259
+ }
221
260
  } catch (e) {
261
+ logger.warn(`\u52A0\u8F7D tsup \u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25: ${e.message}`);
222
262
  }
223
263
  }
224
- current = path4.dirname(current);
225
264
  }
226
- return cwd;
265
+ const pkgPath = path4.join(cwd, "package.json");
266
+ if (fs2.existsSync(pkgPath)) {
267
+ try {
268
+ const pkg = await fs2.readJson(pkgPath);
269
+ if (pkg.tsup) {
270
+ return pkg.tsup;
271
+ }
272
+ } catch (e) {
273
+ }
274
+ }
275
+ return {};
227
276
  }
228
277
  };
229
278
  }
@@ -231,8 +280,8 @@ var init_SandboxPath = __esm({
231
280
 
232
281
  // src/sandbox/SandboxRenderer.ts
233
282
  import fs3 from "fs-extra";
234
- import path5 from "path";
235
283
  import Handlebars from "handlebars";
284
+ import path5 from "path";
236
285
  var SandboxRenderer;
237
286
  var init_SandboxRenderer = __esm({
238
287
  "src/sandbox/SandboxRenderer.ts"() {
@@ -339,21 +388,91 @@ var init_SandboxRenderer = __esm({
339
388
  }
340
389
  });
341
390
 
342
- // src/sandbox/SandboxContext.ts
343
- import fs4 from "fs-extra";
344
- import path6 from "path";
345
- var SandboxContext;
346
- var init_SandboxContext = __esm({
347
- "src/sandbox/SandboxContext.ts"() {
391
+ // src/sandbox/SandboxPath.ts
392
+ import fs5 from "fs-extra";
393
+ import path7 from "path";
394
+ var SandboxPath;
395
+ var init_SandboxPath = __esm({
396
+ "src/sandbox/SandboxPath.ts"() {
348
397
  "use strict";
349
398
  init_esm_shims();
350
- init_SandboxPath();
351
399
  init_constants();
352
- SandboxContext = class {
353
- /**
354
- * 注入项目虚拟上下文
355
- * 包括:
356
- * 1. 确定集中式 .chatbi 存放位置并处理子包软链
400
+ SandboxPath = class {
401
+ static {
402
+ /**
403
+ * 沙箱的基础存储目录,通常位于用户主目录下的 .chatbi-v-core
404
+ */
405
+ this.BASE_DIR = GLOBAL_PATHS.BASE_DIR;
406
+ }
407
+ /**
408
+ * 获取沙箱根目录
409
+ * @returns 沙箱根目录的绝对路径
410
+ */
411
+ static getRoot() {
412
+ return this.BASE_DIR;
413
+ }
414
+ /**
415
+ * 获取存储所有版本的根目录
416
+ * @returns versions 目录的绝对路径
417
+ */
418
+ static getVersionRoot() {
419
+ return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS);
420
+ }
421
+ /**
422
+ * 获取指定版本的沙箱路径
423
+ * @param version 版本号,或者 'current' 表示当前激活版本
424
+ * @returns 对应版本的绝对路径
425
+ */
426
+ static getVersionPath(version) {
427
+ if (version === SANDBOX_CONFIG.DIRS.CURRENT) {
428
+ return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, SANDBOX_CONFIG.DIRS.CURRENT);
429
+ }
430
+ return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, version);
431
+ }
432
+ /**
433
+ * 递归向上查找工作区根目录
434
+ * 识别标准:包含 pnpm-workspace.yaml 或 package.json 中定义了 workspaces
435
+ * @param cwd 起始查找目录
436
+ * @returns 查找到的工作区根目录路径,若未找到则返回 cwd
437
+ */
438
+ static async getWorkspaceRoot(cwd) {
439
+ if (!cwd) return cwd;
440
+ if (cwd.startsWith("/mock")) return cwd;
441
+ let current = path7.resolve(cwd);
442
+ while (current !== path7.parse(current).root) {
443
+ const pkgPath = path7.join(current, "package.json");
444
+ const pnpmWorkspacePath = path7.join(current, "pnpm-workspace.yaml");
445
+ if (fs5.existsSync(pnpmWorkspacePath)) return current;
446
+ if (fs5.existsSync(pkgPath)) {
447
+ try {
448
+ const pkg = await fs5.readJson(pkgPath);
449
+ if (pkg.workspaces) return current;
450
+ } catch (e) {
451
+ }
452
+ }
453
+ current = path7.dirname(current);
454
+ }
455
+ return cwd;
456
+ }
457
+ };
458
+ }
459
+ });
460
+
461
+ // src/sandbox/SandboxContext.ts
462
+ import fs6 from "fs-extra";
463
+ import path8 from "path";
464
+ var SandboxContext;
465
+ var init_SandboxContext = __esm({
466
+ "src/sandbox/SandboxContext.ts"() {
467
+ "use strict";
468
+ init_esm_shims();
469
+ init_constants();
470
+ init_SandboxPath();
471
+ SandboxContext = class {
472
+ /**
473
+ * 注入项目虚拟上下文
474
+ * 包括:
475
+ * 1. 确定集中式 .chatbi 存放位置并处理子包软链
357
476
  * 2. 生成适配沙箱的 tsconfig.json (配置路径别名)
358
477
  * 3. 软链接沙箱的 node_modules 到项目 .chatbi 目录下
359
478
  * 4. 确保 .chatbi 被加入 .gitignore
@@ -366,38 +485,38 @@ var init_SandboxContext = __esm({
366
485
  static async inject(projectRoot, version, corePackages, runtimeDeps) {
367
486
  const workspaceRoot = await SandboxPath.getWorkspaceRoot(projectRoot);
368
487
  if (!workspaceRoot) {
369
- const chatbiDir2 = path6.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
370
- await fs4.ensureDir(chatbiDir2);
488
+ const chatbiDir2 = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
489
+ await fs6.ensureDir(chatbiDir2);
371
490
  return this.injectToDir(chatbiDir2, version, corePackages, runtimeDeps);
372
491
  }
373
- const chatbiDir = path6.join(workspaceRoot, SANDBOX_CONFIG.DIRS.CACHE);
374
- await fs4.ensureDir(chatbiDir);
492
+ const chatbiDir = path8.join(workspaceRoot, SANDBOX_CONFIG.DIRS.CACHE);
493
+ await fs6.ensureDir(chatbiDir);
375
494
  if (workspaceRoot !== projectRoot) {
376
- const localChatbi = path6.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
495
+ const localChatbi = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
377
496
  try {
378
- const stats = await fs4.lstat(localChatbi).catch(() => null);
497
+ const stats = await fs6.lstat(localChatbi).catch(() => null);
379
498
  if (stats) {
380
499
  if (stats.isSymbolicLink()) {
381
- const linkTarget = await fs4.readlink(localChatbi);
500
+ const linkTarget = await fs6.readlink(localChatbi);
382
501
  if (linkTarget !== chatbiDir) {
383
- await fs4.remove(localChatbi);
384
- await fs4.symlink(chatbiDir, localChatbi, "dir");
502
+ await fs6.remove(localChatbi);
503
+ await fs6.symlink(chatbiDir, localChatbi, "dir");
385
504
  }
386
505
  } else {
387
- await fs4.remove(localChatbi);
388
- await fs4.symlink(chatbiDir, localChatbi, "dir");
506
+ await fs6.remove(localChatbi);
507
+ await fs6.symlink(chatbiDir, localChatbi, "dir");
389
508
  }
390
509
  } else {
391
- await fs4.symlink(chatbiDir, localChatbi, "dir");
510
+ await fs6.symlink(chatbiDir, localChatbi, "dir");
392
511
  }
393
512
  } catch (e) {
394
513
  }
395
514
  }
396
- const gitignorePath = path6.join(workspaceRoot, ".gitignore");
397
- if (fs4.existsSync(gitignorePath)) {
398
- let content = await fs4.readFile(gitignorePath, "utf-8");
515
+ const gitignorePath = path8.join(workspaceRoot, ".gitignore");
516
+ if (fs6.existsSync(gitignorePath)) {
517
+ let content = await fs6.readFile(gitignorePath, "utf-8");
399
518
  if (!content.includes(SANDBOX_CONFIG.DIRS.CACHE)) {
400
- await fs4.appendFile(gitignorePath, `
519
+ await fs6.appendFile(gitignorePath, `
401
520
  # ChatBI
402
521
  ${SANDBOX_CONFIG.DIRS.CACHE}
403
522
  `);
@@ -410,7 +529,7 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
410
529
  */
411
530
  static async injectToDir(chatbiDir, version, corePackages, runtimeDeps) {
412
531
  const versionPath = SandboxPath.getVersionPath(version);
413
- const sandboxNodeModules = path6.join(versionPath, "node_modules");
532
+ const sandboxNodeModules = path8.join(versionPath, "node_modules");
414
533
  const corePaths = {};
415
534
  for (const pkgName of corePackages) {
416
535
  corePaths[pkgName] = [`./node_modules/${pkgName}`];
@@ -427,7 +546,7 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
427
546
  }
428
547
  corePaths["@types/*"] = ["./node_modules/@types/*"];
429
548
  corePaths["vite/client"] = ["./node_modules/vite/client.d.ts"];
430
- const baseConfigPath = path6.join(sandboxNodeModules, "@chatbi-v/config/base.json");
549
+ const baseConfigPath = path8.join(sandboxNodeModules, "@chatbi-v/config/base.json");
431
550
  const tsConfig = {
432
551
  extends: baseConfigPath,
433
552
  compilerOptions: {
@@ -443,25 +562,25 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
443
562
  }
444
563
  }
445
564
  };
446
- await fs4.writeJson(path6.join(chatbiDir, "tsconfig.json"), tsConfig, { spaces: 2 });
447
- await fs4.writeJson(path6.join(chatbiDir, "tsconfig.paths.json"), { compilerOptions: tsConfig.compilerOptions }, { spaces: 2 });
448
- const virtualNodeModules = path6.join(chatbiDir, "node_modules");
449
- if (fs4.existsSync(sandboxNodeModules)) {
565
+ await fs6.writeJson(path8.join(chatbiDir, "tsconfig.json"), tsConfig, { spaces: 2 });
566
+ await fs6.writeJson(path8.join(chatbiDir, "tsconfig.paths.json"), { compilerOptions: tsConfig.compilerOptions }, { spaces: 2 });
567
+ const virtualNodeModules = path8.join(chatbiDir, "node_modules");
568
+ if (fs6.existsSync(sandboxNodeModules)) {
450
569
  try {
451
- const stats = await fs4.lstat(virtualNodeModules).catch(() => null);
570
+ const stats = await fs6.lstat(virtualNodeModules).catch(() => null);
452
571
  if (stats) {
453
572
  if (stats.isSymbolicLink()) {
454
- const linkTarget = await fs4.readlink(virtualNodeModules);
573
+ const linkTarget = await fs6.readlink(virtualNodeModules);
455
574
  if (linkTarget !== sandboxNodeModules) {
456
- await fs4.remove(virtualNodeModules);
457
- await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
575
+ await fs6.remove(virtualNodeModules);
576
+ await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
458
577
  }
459
578
  } else {
460
- await fs4.remove(virtualNodeModules);
461
- await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
579
+ await fs6.remove(virtualNodeModules);
580
+ await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
462
581
  }
463
582
  } else {
464
- await fs4.symlink(sandboxNodeModules, virtualNodeModules, "dir");
583
+ await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
465
584
  }
466
585
  } catch (e) {
467
586
  }
@@ -472,10 +591,10 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
472
591
  });
473
592
 
474
593
  // src/sandbox/SandboxPkgManager.ts
475
- import fs5 from "fs-extra";
476
- import path7 from "path";
477
- import pc2 from "picocolors";
478
594
  import fg from "fast-glob";
595
+ import fs7 from "fs-extra";
596
+ import path9 from "path";
597
+ import pc3 from "picocolors";
479
598
  var SandboxPkgManager;
480
599
  var init_SandboxPkgManager = __esm({
481
600
  "src/sandbox/SandboxPkgManager.ts"() {
@@ -496,16 +615,16 @@ var init_SandboxPkgManager = __esm({
496
615
  try {
497
616
  const cliRoot = await getCliRoot();
498
617
  const projectRoot = await SandboxPath.getWorkspaceRoot(cliRoot);
499
- if (projectRoot === cliRoot && !fs5.existsSync(path7.join(projectRoot, "pnpm-workspace.yaml"))) {
618
+ if (projectRoot === cliRoot && !fs7.existsSync(path9.join(projectRoot, "pnpm-workspace.yaml"))) {
500
619
  return false;
501
620
  }
502
621
  const possiblePackagesDirs = [
503
- path7.join(projectRoot, "packages"),
622
+ path9.join(projectRoot, "packages"),
504
623
  // 兼容旧版或其他可能的路径结构
505
- path7.resolve(projectRoot, "../chatbi-v/packages")
624
+ path9.resolve(projectRoot, "../chatbi-v/packages")
506
625
  ];
507
626
  const localPackages = {};
508
- const patterns = possiblePackagesDirs.filter((dir) => fs5.existsSync(dir)).map((dir) => path7.join(dir, "**/package.json"));
627
+ const patterns = possiblePackagesDirs.filter((dir) => fs7.existsSync(dir)).map((dir) => path9.join(dir, "**/package.json"));
509
628
  if (patterns.length > 0) {
510
629
  const pkgJsonFiles = await fg(patterns, {
511
630
  ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
@@ -514,34 +633,34 @@ var init_SandboxPkgManager = __esm({
514
633
  });
515
634
  for (const pkgJsonPath of pkgJsonFiles) {
516
635
  try {
517
- const pkgJson = await fs5.readJson(pkgJsonPath);
636
+ const pkgJson = await fs7.readJson(pkgJsonPath);
518
637
  if (corePackages.includes(pkgJson.name) || runtimeDeps.includes(pkgJson.name)) {
519
- localPackages[pkgJson.name] = path7.dirname(pkgJsonPath);
638
+ localPackages[pkgJson.name] = path9.dirname(pkgJsonPath);
520
639
  }
521
640
  } catch (e) {
522
641
  }
523
642
  }
524
643
  }
525
644
  if (Object.keys(localPackages).length === 0) return false;
526
- const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${pc2.cyan(name.padEnd(30))} -> ${pc2.gray(pkgPath)}`).join("\n");
645
+ const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${pc3.cyan(name.padEnd(30))} -> ${pc3.gray(pkgPath)}`).join("\n");
527
646
  printBox(
528
- 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,
647
+ 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,
529
648
  "Monorepo Link Mode"
530
649
  );
531
- const sandboxNodeModules = path7.join(versionPath, "node_modules");
532
- await fs5.ensureDir(sandboxNodeModules);
650
+ const sandboxNodeModules = path9.join(versionPath, "node_modules");
651
+ await fs7.ensureDir(sandboxNodeModules);
533
652
  for (const [name, pkgPath] of Object.entries(localPackages)) {
534
- const targetLinkPath = path7.join(sandboxNodeModules, name);
535
- await fs5.ensureDir(path7.dirname(targetLinkPath));
653
+ const targetLinkPath = path9.join(sandboxNodeModules, name);
654
+ await fs7.ensureDir(path9.dirname(targetLinkPath));
536
655
  try {
537
- const stats = await fs5.lstat(targetLinkPath).catch(() => null);
538
- if (stats) await fs5.remove(targetLinkPath);
656
+ const stats = await fs7.lstat(targetLinkPath).catch(() => null);
657
+ if (stats) await fs7.remove(targetLinkPath);
539
658
  } catch (e) {
540
659
  }
541
- await fs5.symlink(pkgPath, targetLinkPath, "dir");
660
+ await fs7.symlink(pkgPath, targetLinkPath, "dir");
542
661
  }
543
- const sandboxPkgJsonPath = path7.join(versionPath, "package.json");
544
- const sandboxPkgJson = await fs5.readJson(sandboxPkgJsonPath);
662
+ const sandboxPkgJsonPath = path9.join(versionPath, "package.json");
663
+ const sandboxPkgJson = await fs7.readJson(sandboxPkgJsonPath);
545
664
  const sections = ["dependencies", "devDependencies"];
546
665
  let modified = false;
547
666
  for (const section of sections) {
@@ -554,10 +673,10 @@ var init_SandboxPkgManager = __esm({
554
673
  }
555
674
  }
556
675
  }
557
- if (modified) await fs5.writeJson(sandboxPkgJsonPath, sandboxPkgJson, { spaces: 2 });
676
+ if (modified) await fs7.writeJson(sandboxPkgJsonPath, sandboxPkgJson, { spaces: 2 });
558
677
  return true;
559
678
  } catch (e) {
560
- console.warn(pc2.yellow(` \u26A0\uFE0F Link \u672C\u5730\u6E90\u7801\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4ECE NPM \u5B89\u88C5: ${e.message}`));
679
+ console.warn(pc3.yellow(` \u26A0\uFE0F Link \u672C\u5730\u6E90\u7801\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4ECE NPM \u5B89\u88C5: ${e.message}`));
561
680
  return false;
562
681
  }
563
682
  }
@@ -566,32 +685,29 @@ var init_SandboxPkgManager = __esm({
566
685
  });
567
686
 
568
687
  // src/sandbox.ts
569
- import fs6 from "fs-extra";
570
- import path8 from "path";
571
- import pc3 from "picocolors";
572
- import fg2 from "fast-glob";
573
688
  import { execa } from "execa";
689
+ import fg2 from "fast-glob";
690
+ import fs8 from "fs-extra";
691
+ import path10 from "path";
692
+ import pc4 from "picocolors";
574
693
  var Sandbox;
575
694
  var init_sandbox = __esm({
576
695
  "src/sandbox.ts"() {
577
696
  "use strict";
578
697
  init_esm_shims();
579
- init_utils();
580
- init_SandboxPath();
581
- init_SandboxRenderer();
698
+ init_constants();
582
699
  init_SandboxContext();
700
+ init_SandboxPath();
583
701
  init_SandboxPkgManager();
584
- init_constants();
702
+ init_SandboxRenderer();
703
+ init_utils();
585
704
  Sandbox = class {
586
705
  static {
587
706
  /** 核心源码包列表 */
588
707
  this.CORE_PACKAGES = [
589
708
  "@chatbi-v/core",
590
709
  "@chatbi-v/mocks",
591
- "@chatbi-v/config",
592
- "@chatbi-v/plugin-theme-manager",
593
- "@chatbi-v/plugin-layout-transform",
594
- "@chatbi-v/plugin-system-monitor"
710
+ "@chatbi-v/config"
595
711
  ];
596
712
  }
597
713
  static {
@@ -632,8 +748,8 @@ var init_sandbox = __esm({
632
748
  /** 清理指定版本的沙箱物理文件 */
633
749
  static async cleanVersion(version) {
634
750
  const versionPath = this.getVersionPath(version);
635
- if (fs6.existsSync(versionPath)) {
636
- await fs6.remove(versionPath);
751
+ if (fs8.existsSync(versionPath)) {
752
+ await fs8.remove(versionPath);
637
753
  }
638
754
  }
639
755
  /**
@@ -647,7 +763,7 @@ var init_sandbox = __esm({
647
763
  const workspaceRoot = await this.getWorkspaceRoot(cwd);
648
764
  let cleanedCount = 0;
649
765
  const cachePatterns = [
650
- path8.join(workspaceRoot, `**/${SANDBOX_CONFIG.DIRS.CACHE}`)
766
+ path10.join(workspaceRoot, `**/${SANDBOX_CONFIG.DIRS.CACHE}`)
651
767
  ];
652
768
  const cacheDirs = await fg2(cachePatterns, {
653
769
  onlyFiles: false,
@@ -658,15 +774,15 @@ var init_sandbox = __esm({
658
774
  // 确保能匹配到以 . 开头的目录
659
775
  });
660
776
  for (const dir of cacheDirs) {
661
- const stats = await fs6.lstat(dir).catch(() => null);
777
+ const stats = await fs8.lstat(dir).catch(() => null);
662
778
  if (stats) {
663
- await fs6.remove(dir);
779
+ await fs8.remove(dir);
664
780
  cleanedCount++;
665
781
  }
666
782
  }
667
783
  if (deep) {
668
784
  const distPatterns = [
669
- path8.join(workspaceRoot, "**/dist")
785
+ path10.join(workspaceRoot, "**/dist")
670
786
  ];
671
787
  const distDirs = await fg2(distPatterns, {
672
788
  onlyFiles: false,
@@ -679,24 +795,24 @@ var init_sandbox = __esm({
679
795
  ]
680
796
  });
681
797
  for (const dir of distDirs) {
682
- const stats = await fs6.lstat(dir).catch(() => null);
798
+ const stats = await fs8.lstat(dir).catch(() => null);
683
799
  if (stats) {
684
- const hasPkg = fs6.existsSync(path8.join(path8.dirname(dir), "package.json"));
800
+ const hasPkg = fs8.existsSync(path10.join(path10.dirname(dir), "package.json"));
685
801
  if (hasPkg) {
686
- await fs6.remove(dir);
802
+ await fs8.remove(dir);
687
803
  cleanedCount++;
688
804
  }
689
805
  }
690
806
  }
691
807
  const globalRoot = this.getRoot();
692
- if (fs6.existsSync(globalRoot)) {
693
- await fs6.remove(globalRoot);
808
+ if (fs8.existsSync(globalRoot)) {
809
+ await fs8.remove(globalRoot);
694
810
  cleanedCount++;
695
811
  }
696
812
  }
697
- spinner.succeed(pc3.green(`\u6E05\u7406\u5B8C\u6210\uFF0C\u5171\u6E05\u7406 ${cleanedCount} \u4E2A\u9879\u76EE/\u7F13\u5B58\u76EE\u5F55`));
813
+ spinner.succeed(pc4.green(`\u6E05\u7406\u5B8C\u6210\uFF0C\u5171\u6E05\u7406 ${cleanedCount} \u4E2A\u9879\u76EE/\u7F13\u5B58\u76EE\u5F55`));
698
814
  } catch (e) {
699
- spinner.fail(pc3.red(`\u6E05\u7406\u5931\u8D25: ${e.message}`));
815
+ spinner.fail(pc4.red(`\u6E05\u7406\u5931\u8D25: ${e.message}`));
700
816
  }
701
817
  }
702
818
  /**
@@ -704,14 +820,14 @@ var init_sandbox = __esm({
704
820
  */
705
821
  static async prepare(version, force = false) {
706
822
  const versionPath = this.getVersionPath(version);
707
- if (!force && fs6.existsSync(path8.join(versionPath, "node_modules/tailwindcss"))) {
823
+ if (!force && fs8.existsSync(path10.join(versionPath, "node_modules/tailwindcss"))) {
708
824
  return versionPath;
709
825
  }
710
- if (fs6.existsSync(versionPath)) {
711
- await fs6.remove(path8.join(versionPath, "node_modules"));
826
+ if (fs8.existsSync(versionPath)) {
827
+ await fs8.remove(path10.join(versionPath, "node_modules"));
712
828
  }
713
- await fs6.ensureDir(versionPath);
714
- const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${pc3.cyan(version)}...`).start();
829
+ await fs8.ensureDir(versionPath);
830
+ const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${pc4.cyan(version)}...`).start();
715
831
  try {
716
832
  const cliRoot = await getCliRoot();
717
833
  const dependencies = {};
@@ -727,20 +843,20 @@ var init_sandbox = __esm({
727
843
  devDependencies: DEPENDENCY_VERSIONS
728
844
  };
729
845
  await SandboxRenderer.renderDirectory(
730
- path8.join(cliRoot, "templates/sandbox"),
846
+ path10.join(cliRoot, "templates/sandbox"),
731
847
  versionPath,
732
848
  templateData
733
849
  );
734
- spinner.text = pc3.gray(" \u{1F50D} \u68C0\u67E5\u672C\u5730\u5F00\u53D1\u73AF\u5883...");
850
+ spinner.text = pc4.gray(" \u{1F50D} \u68C0\u67E5\u672C\u5730\u5F00\u53D1\u73AF\u5883...");
735
851
  const isLocalDev = await SandboxPkgManager.tryLinkLocalPackages(versionPath, this.CORE_PACKAGES, this.RUNTIME_DEPS);
736
852
  const installArgs = isLocalDev ? ["install", "--no-frozen-lockfile"] : ["install"];
737
- spinner.text = pc3.gray(` \u23F3 \u6267\u884C pnpm ${installArgs.join(" ")}...`);
853
+ spinner.text = pc4.gray(` \u23F3 \u6267\u884C pnpm ${installArgs.join(" ")}...`);
738
854
  await execa("pnpm", installArgs, { cwd: versionPath });
739
- spinner.text = pc3.gray(" \u{1F3A8} \u540C\u6B65 Shell \u6A21\u677F...");
855
+ spinner.text = pc4.gray(" \u{1F3A8} \u540C\u6B65 Shell \u6A21\u677F...");
740
856
  await this.ensureShell(version, force);
741
- spinner.succeed(pc3.green(`\u5185\u6838\u6C99\u7BB1 ${version} \u521D\u59CB\u5316\u6210\u529F`));
857
+ spinner.succeed(pc4.green(`\u5185\u6838\u6C99\u7BB1 ${version} \u521D\u59CB\u5316\u6210\u529F`));
742
858
  } catch (e) {
743
- spinner.fail(pc3.red(`\u5185\u6838\u6C99\u7BB1\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`));
859
+ spinner.fail(pc4.red(`\u5185\u6838\u6C99\u7BB1\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`));
744
860
  throw e;
745
861
  }
746
862
  return versionPath;
@@ -750,14 +866,14 @@ var init_sandbox = __esm({
750
866
  */
751
867
  static async ensureShell(version, force = false) {
752
868
  const versionPath = this.getVersionPath(version);
753
- const shellDestDir = path8.join(versionPath, "shell");
754
- if (!force && fs6.existsSync(path8.join(shellDestDir, "tsconfig.paths.json"))) {
869
+ const shellDestDir = path10.join(versionPath, "shell");
870
+ if (!force && fs8.existsSync(path10.join(shellDestDir, "tsconfig.paths.json"))) {
755
871
  return shellDestDir;
756
872
  }
757
873
  const cliRoot = await getCliRoot();
758
- const shellTemplateDir = path8.join(cliRoot, "templates/app");
759
- if (fs6.existsSync(shellTemplateDir)) {
760
- await fs6.remove(shellDestDir);
874
+ const shellTemplateDir = path10.join(cliRoot, "templates/app");
875
+ if (fs8.existsSync(shellTemplateDir)) {
876
+ await fs8.remove(shellDestDir);
761
877
  const templateData = {
762
878
  name: "chatbi-shell",
763
879
  version,
@@ -768,7 +884,7 @@ var init_sandbox = __esm({
768
884
  tsconfigPath: "./tsconfig.paths.json"
769
885
  };
770
886
  await SandboxRenderer.renderDirectory(shellTemplateDir, shellDestDir, templateData);
771
- await fs6.writeJson(path8.join(shellDestDir, "tsconfig.paths.json"), {
887
+ await fs8.writeJson(path10.join(shellDestDir, "tsconfig.paths.json"), {
772
888
  compilerOptions: { baseUrl: ".", paths: { "@/*": ["./src/*"] } }
773
889
  }, { spaces: 2 });
774
890
  }
@@ -781,24 +897,24 @@ var init_sandbox = __esm({
781
897
  /** 获取核心库的 Vite Alias 配置 */
782
898
  static getCoreAlias(version) {
783
899
  const versionPath = this.getVersionPath(version);
784
- const sandboxNodeModules = path8.join(versionPath, "node_modules");
785
- return Object.fromEntries(this.CORE_PACKAGES.map((pkg) => [pkg, path8.join(sandboxNodeModules, pkg)]));
900
+ const sandboxNodeModules = path10.join(versionPath, "node_modules");
901
+ return Object.fromEntries(this.CORE_PACKAGES.map((pkg) => [pkg, path10.join(sandboxNodeModules, pkg)]));
786
902
  }
787
903
  /** 切换内核版本 */
788
904
  static async useVersion(version) {
789
905
  const versionRoot = this.getVersionRoot();
790
- const currentLink = path8.join(versionRoot, SANDBOX_CONFIG.DIRS.CURRENT);
906
+ const currentLink = path10.join(versionRoot, SANDBOX_CONFIG.DIRS.CURRENT);
791
907
  const targetPath = this.getVersionPath(version);
792
- if (!fs6.existsSync(targetPath)) throw new Error(`\u7248\u672C ${version} \u4E0D\u5B58\u5728`);
793
- if (fs6.existsSync(currentLink)) await fs6.remove(currentLink);
794
- await fs6.ensureSymlink(targetPath, currentLink, "dir");
908
+ if (!fs8.existsSync(targetPath)) throw new Error(`\u7248\u672C ${version} \u4E0D\u5B58\u5728`);
909
+ if (fs8.existsSync(currentLink)) await fs8.remove(currentLink);
910
+ await fs8.ensureSymlink(targetPath, currentLink, "dir");
795
911
  }
796
912
  /** 解析版本号 */
797
913
  static async resolveVersion(version) {
798
914
  if (!version || version === "latest" || version === "current") {
799
- const currentLink = path8.join(this.getVersionRoot(), SANDBOX_CONFIG.DIRS.CURRENT);
800
- if (fs6.existsSync(currentLink)) {
801
- return path8.basename(await fs6.readlink(currentLink));
915
+ const currentLink = path10.join(this.getVersionRoot(), SANDBOX_CONFIG.DIRS.CURRENT);
916
+ if (fs8.existsSync(currentLink)) {
917
+ return path10.basename(await fs8.readlink(currentLink));
802
918
  }
803
919
  const versions = await this.listVersions();
804
920
  return versions[0] || "1.0.0";
@@ -808,8 +924,8 @@ var init_sandbox = __esm({
808
924
  /** 列出所有已安装版本 */
809
925
  static async listVersions() {
810
926
  const versionRoot = this.getVersionRoot();
811
- if (!fs6.existsSync(versionRoot)) return [];
812
- const dirs = await fs6.readdir(versionRoot);
927
+ if (!fs8.existsSync(versionRoot)) return [];
928
+ const dirs = await fs8.readdir(versionRoot);
813
929
  return dirs.filter((d) => d !== SANDBOX_CONFIG.DIRS.CURRENT && !d.startsWith(".")).sort().reverse();
814
930
  }
815
931
  /** 可视化展示沙箱状态 */
@@ -819,11 +935,11 @@ var init_sandbox = __esm({
819
935
  const currentVersion = await this.resolveVersion("current");
820
936
  const versions = await this.listVersions();
821
937
  const statusInfo = [
822
- `${pc3.bold("\u9879\u76EE\u8DEF\u5F84:")} ${pc3.cyan(cwd)}`,
823
- `${pc3.bold("\u67B6\u6784\u6A21\u5F0F:")} ${isMonorepo ? pc3.yellow("Monorepo") : pc3.green("Standalone")}`,
824
- `${pc3.bold("\u5F53\u524D\u5185\u6838:")} ${pc3.green(currentVersion)}`,
825
- `${pc3.bold("\u5DF2\u88C5\u7248\u672C:")} ${pc3.gray(versions.join(", ") || "none")}`,
826
- `${pc3.bold("\u6C99\u7BB1\u6839\u76EE\u5F55:")} ${pc3.gray(this.getRoot())}`
938
+ `${pc4.bold("\u9879\u76EE\u8DEF\u5F84:")} ${pc4.cyan(cwd)}`,
939
+ `${pc4.bold("\u67B6\u6784\u6A21\u5F0F:")} ${isMonorepo ? pc4.yellow("Monorepo") : pc4.green("Standalone")}`,
940
+ `${pc4.bold("\u5F53\u524D\u5185\u6838:")} ${pc4.green(currentVersion)}`,
941
+ `${pc4.bold("\u5DF2\u88C5\u7248\u672C:")} ${pc4.gray(versions.join(", ") || "none")}`,
942
+ `${pc4.bold("\u6C99\u7BB1\u6839\u76EE\u5F55:")} ${pc4.gray(this.getRoot())}`
827
943
  ].join("\n");
828
944
  printBox(statusInfo, "ChatBI Sandbox Status");
829
945
  }
@@ -831,160 +947,42 @@ var init_sandbox = __esm({
831
947
  }
832
948
  });
833
949
 
834
- // src/config.ts
835
- import fs7 from "fs-extra";
836
- import path9 from "path";
837
- import { createJiti } from "jiti";
838
- var ConfigManager;
839
- var init_config = __esm({
840
- "src/config.ts"() {
841
- "use strict";
842
- init_esm_shims();
843
- init_utils();
844
- init_constants();
845
- init_utils();
846
- ConfigManager = class {
847
- static {
848
- this.CONFIG_FILES = DEFAULT_CONFIG.CONFIG_FILES;
849
- }
850
- /**
851
- * 加载项目配置
852
- * @param cwd 项目根目录
853
- */
854
- static async loadConfig(cwd = process.cwd()) {
855
- const config = {};
856
- const versionFilePath = path9.join(cwd, SANDBOX_CONFIG.LOCK_FILE);
857
- if (fs7.existsSync(versionFilePath)) {
858
- try {
859
- const version = (await fs7.readFile(versionFilePath, "utf-8")).trim();
860
- if (version) {
861
- config.coreVersion = version;
862
- }
863
- } catch (e) {
864
- }
865
- }
866
- const jiti = createJiti(cwd);
867
- for (const file of this.CONFIG_FILES) {
868
- const configPath = path9.join(cwd, file);
869
- if (fs7.existsSync(configPath)) {
870
- try {
871
- let projectConfig = {};
872
- if (file.endsWith(".ts") || file.endsWith(".js")) {
873
- const mod = await jiti.import(configPath, { default: true });
874
- projectConfig = mod.default || mod || {};
875
- } else if (file.endsWith(".json") || file.startsWith(".chatbirc")) {
876
- projectConfig = await fs7.readJson(configPath);
877
- }
878
- return {
879
- ...projectConfig,
880
- ...config
881
- };
882
- } catch (e) {
883
- logger.error(`\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25`, e);
884
- }
885
- }
886
- }
887
- return config;
888
- }
889
- /**
890
- * 解析核心依赖的具体路径或版本号
891
- * @param config 项目配置
892
- * @param relativeTo 相对路径(用于 local 模式下的 file: 协议生成)
893
- */
894
- static async resolveCoreDependency(config, relativeTo = ".") {
895
- const { coreSource = "local", coreVersion } = config;
896
- if (coreSource === "npm") {
897
- if (coreVersion) return coreVersion;
898
- const cliRoot = await getCliRoot();
899
- const cliPkg = await fs7.readJson(path9.join(cliRoot, "package.json"));
900
- return cliPkg.version;
901
- }
902
- const sandboxCorePath = path9.join(SANDBOX_CONFIG.DIRS.CACHE, "core");
903
- const cwd = process.cwd();
904
- const absoluteRelativeTo = path9.isAbsolute(relativeTo) ? relativeTo : path9.resolve(cwd, relativeTo);
905
- const absoluteProjectRoot = cwd;
906
- const relativePath = path9.relative(absoluteRelativeTo, path9.join(absoluteProjectRoot, sandboxCorePath));
907
- return `file:${relativePath}`;
908
- }
909
- /**
910
- * 加载 tsup 配置
911
- * @param cwd 项目根目录
912
- */
913
- static async loadTsupConfig(cwd = process.cwd()) {
914
- const TSUP_CONFIG_FILES = [
915
- "tsup.config.ts",
916
- "tsup.config.js",
917
- "tsup.config.cjs",
918
- "tsup.config.mjs",
919
- "tsup.config.json"
920
- ];
921
- const jiti = createJiti(cwd);
922
- for (const file of TSUP_CONFIG_FILES) {
923
- const configPath = path9.join(cwd, file);
924
- if (fs7.existsSync(configPath)) {
925
- try {
926
- if (file.endsWith(".json")) {
927
- return await fs7.readJson(configPath);
928
- } else {
929
- const mod = await jiti.import(configPath, { default: true });
930
- return mod.default || mod || {};
931
- }
932
- } catch (e) {
933
- logger.warn(`\u52A0\u8F7D tsup \u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25: ${e.message}`);
934
- }
935
- }
936
- }
937
- const pkgPath = path9.join(cwd, "package.json");
938
- if (fs7.existsSync(pkgPath)) {
939
- try {
940
- const pkg = await fs7.readJson(pkgPath);
941
- if (pkg.tsup) {
942
- return pkg.tsup;
943
- }
944
- } catch (e) {
945
- }
946
- }
947
- return {};
948
- }
949
- };
950
- }
951
- });
952
-
953
950
  // src/corekit.ts
954
- import { createRequire as createRequire2 } from "module";
955
- import path10 from "path";
956
- import fs8 from "fs-extra";
957
- import pc4 from "picocolors";
958
- import prompts from "prompts";
959
951
  import fg3 from "fast-glob";
952
+ import fs9 from "fs-extra";
953
+ import { createRequire as createRequire3 } from "module";
954
+ import path11 from "path";
955
+ import pc5 from "picocolors";
956
+ import prompts2 from "prompts";
957
+ import { createJiti as createJiti2 } from "jiti";
960
958
  var nativeRequire, CoreKit;
961
959
  var init_corekit = __esm({
962
960
  "src/corekit.ts"() {
963
961
  "use strict";
964
962
  init_esm_shims();
965
- init_utils();
966
- init_sandbox();
967
963
  init_config();
968
- nativeRequire = createRequire2(import.meta.url);
964
+ init_sandbox();
965
+ init_utils();
966
+ nativeRequire = createRequire3(import.meta.url);
969
967
  CoreKit = class {
970
968
  /**
971
969
  * 解析项目模式
972
970
  */
973
971
  static async detectMode(cwd) {
974
- const pkgPath = path10.join(cwd, "package.json");
975
- if (!fs8.existsSync(pkgPath)) return "app";
976
- const pkg = await fs8.readJson(pkgPath);
977
- if (pkg.workspaces || fs8.existsSync(path10.join(cwd, "pnpm-workspace.yaml"))) {
972
+ const pkgPath = path11.join(cwd, "package.json");
973
+ if (!fs9.existsSync(pkgPath)) return "app";
974
+ const pkg = await fs9.readJson(pkgPath);
975
+ if (pkg.workspaces || fs9.existsSync(path11.join(cwd, "pnpm-workspace.yaml"))) {
978
976
  return "monorepo";
979
977
  }
980
978
  if (pkg.chatbi?.type === "plugin" || pkg.plugin === true) return "plugin";
981
979
  if (pkg.chatbi?.type === "app") return "app";
982
980
  const pluginEntries = await fg3(["index.plugin.{ts,js}", "src/index.plugin.{ts,js}"], { cwd });
983
981
  if (pluginEntries.length > 0) return "plugin";
984
- if (fs8.existsSync(path10.join(cwd, "index.html"))) {
982
+ if (fs9.existsSync(path11.join(cwd, "index.html"))) {
985
983
  return "app";
986
984
  }
987
- if (fs8.existsSync(path10.join(cwd, "src/index.ts")) || fs8.existsSync(path10.join(cwd, "src/index.tsx"))) {
985
+ if (fs9.existsSync(path11.join(cwd, "src/index.ts")) || fs9.existsSync(path11.join(cwd, "src/index.tsx"))) {
988
986
  if (pkg.bin) return "lib";
989
987
  if (pkg.peerDependencies?.react && !pkg.dependencies?.react) return "plugin";
990
988
  return "lib";
@@ -1002,18 +1000,18 @@ var init_corekit = __esm({
1002
1000
  }
1003
1001
  try {
1004
1002
  const cliRoot = await getCliRoot();
1005
- const cliVersionFile = path10.join(cliRoot, ".chatbi-version");
1006
- if (fs8.existsSync(cliVersionFile)) {
1007
- const version = (await fs8.readFile(cliVersionFile, "utf-8")).trim();
1003
+ const cliVersionFile = path11.join(cliRoot, ".chatbi-version");
1004
+ if (fs9.existsSync(cliVersionFile)) {
1005
+ const version = (await fs9.readFile(cliVersionFile, "utf-8")).trim();
1008
1006
  if (version) return version;
1009
1007
  }
1010
1008
  } catch (e) {
1011
1009
  }
1012
- const currentLinkPath = path10.join(Sandbox.getVersionRoot(), "current");
1013
- if (fs8.existsSync(currentLinkPath)) {
1010
+ const currentLinkPath = path11.join(Sandbox.getVersionRoot(), "current");
1011
+ if (fs9.existsSync(currentLinkPath)) {
1014
1012
  try {
1015
- const realPath = await fs8.realpath(currentLinkPath);
1016
- return path10.basename(realPath);
1013
+ const realPath = await fs9.realpath(currentLinkPath);
1014
+ return path11.basename(realPath);
1017
1015
  } catch (e) {
1018
1016
  }
1019
1017
  }
@@ -1025,7 +1023,7 @@ var init_corekit = __esm({
1025
1023
  */
1026
1024
  static async listVersions() {
1027
1025
  const versionsDir = Sandbox.getVersionRoot();
1028
- if (!fs8.existsSync(versionsDir)) return [];
1026
+ if (!fs9.existsSync(versionsDir)) return [];
1029
1027
  const dirs = await fg3("*", {
1030
1028
  cwd: versionsDir,
1031
1029
  onlyDirectories: true,
@@ -1037,18 +1035,18 @@ var init_corekit = __esm({
1037
1035
  * 自动发现项目中的插件
1038
1036
  */
1039
1037
  static async discoverPlugins(rootDir) {
1040
- const pluginsDir = path10.join(rootDir, "plugins");
1041
- if (!fs8.existsSync(pluginsDir)) return [];
1038
+ const pluginsDir = path11.join(rootDir, "plugins");
1039
+ if (!fs9.existsSync(pluginsDir)) return [];
1042
1040
  const pkgFiles = await fg3("*/package.json", { cwd: pluginsDir, absolute: true });
1043
1041
  const plugins = [];
1044
1042
  for (const pkgPath of pkgFiles) {
1045
1043
  try {
1046
- const pkg = await fs8.readJson(pkgPath);
1047
- const pluginPath = path10.dirname(pkgPath);
1044
+ const pkg = await fs9.readJson(pkgPath);
1045
+ const pluginPath = path11.dirname(pkgPath);
1048
1046
  plugins.push({
1049
- name: pkg.name || path10.basename(pluginPath),
1047
+ name: pkg.name || path11.basename(pluginPath),
1050
1048
  path: pluginPath,
1051
- id: path10.basename(pluginPath)
1049
+ id: path11.basename(pluginPath)
1052
1050
  });
1053
1051
  } catch (e) {
1054
1052
  }
@@ -1062,19 +1060,19 @@ var init_corekit = __esm({
1062
1060
  const mode = await this.detectMode(cwd);
1063
1061
  const version = await this.resolveVersion(cwd);
1064
1062
  printBox(
1065
- `${pc4.cyan(pc4.bold("\u{1F680} ChatBI Dev Server"))}
1063
+ `${pc5.cyan(pc5.bold("\u{1F680} ChatBI Dev Server"))}
1066
1064
 
1067
- ${pc4.gray("Mode: ")} ${pc4.yellow(mode)}
1068
- ${pc4.gray("Kernel: ")} ${pc4.green(version)}
1069
- ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1065
+ ${pc5.gray("Mode: ")} ${pc5.yellow(mode)}
1066
+ ${pc5.gray("Kernel: ")} ${pc5.green(version)}
1067
+ ${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
1070
1068
  "Dev Server"
1071
1069
  );
1072
1070
  const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6C99\u7BB1\u73AF\u5883...").start();
1073
1071
  try {
1074
1072
  await Sandbox.prepare(version);
1075
- spinner.text = pc4.cyan("\u6B63\u5728\u6CE8\u5165\u865A\u62DF\u4E0A\u4E0B\u6587...");
1073
+ spinner.text = pc5.cyan("\u6B63\u5728\u6CE8\u5165\u865A\u62DF\u4E0A\u4E0B\u6587...");
1076
1074
  await Sandbox.injectContext(cwd, version);
1077
- spinner.succeed(pc4.green("\u73AF\u5883\u5C31\u7EEA"));
1075
+ spinner.succeed(pc5.green("\u73AF\u5883\u5C31\u7EEA"));
1078
1076
  if (mode === "plugin") {
1079
1077
  await this.startPluginDevServer(cwd, version, options.port);
1080
1078
  } else if (mode === "app") {
@@ -1083,28 +1081,28 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1083
1081
  await this.startMonorepoDevServer(cwd, version, options.port);
1084
1082
  }
1085
1083
  } catch (e) {
1086
- spinner.fail(pc4.red(`\u542F\u52A8\u5931\u8D25: ${e.message}`));
1084
+ spinner.fail(pc5.red(`\u542F\u52A8\u5931\u8D25: ${e.message}`));
1087
1085
  }
1088
1086
  }
1089
1087
  /**
1090
1088
  * 启动 Monorepo 开发服务器
1091
1089
  */
1092
1090
  static async startMonorepoDevServer(rootDir, version, customPort) {
1093
- const appsDir = path10.join(rootDir, "apps");
1094
- if (!fs8.existsSync(appsDir)) {
1091
+ const appsDir = path11.join(rootDir, "apps");
1092
+ if (!fs9.existsSync(appsDir)) {
1095
1093
  logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230 apps/ \u76EE\u5F55");
1096
1094
  return;
1097
1095
  }
1098
1096
  const pkgFiles = await fg3("*/package.json", { cwd: appsDir, absolute: true });
1099
1097
  const apps = pkgFiles.map((pkgPath) => ({
1100
- name: path10.basename(path10.dirname(pkgPath)),
1101
- path: path10.dirname(pkgPath)
1098
+ name: path11.basename(path11.dirname(pkgPath)),
1099
+ path: path11.dirname(pkgPath)
1102
1100
  }));
1103
1101
  if (apps.length === 0) {
1104
1102
  logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230\u4EFB\u4F55\u5E94\u7528 (apps/)");
1105
1103
  return;
1106
1104
  }
1107
- const response = await prompts({
1105
+ const response = await prompts2({
1108
1106
  type: "select",
1109
1107
  name: "appPath",
1110
1108
  message: "\u8BF7\u9009\u62E9\u8981\u542F\u52A8\u7684\u5E94\u7528:",
@@ -1125,19 +1123,21 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1125
1123
  const shellPort = customPort || 5173;
1126
1124
  const sandboxRoot = Sandbox.getRoot();
1127
1125
  const versionPath = Sandbox.getVersionPath(version);
1128
- const sandboxNodeModules = path10.join(versionPath, "node_modules");
1126
+ const sandboxNodeModules = path11.join(versionPath, "node_modules");
1129
1127
  const shellDir = await Sandbox.ensureShell(version);
1130
1128
  const coreAlias = Sandbox.getCoreAlias(version);
1131
- const tailwindPath = path10.join(sandboxNodeModules, "tailwindcss");
1132
- const autoprefixerPath = path10.join(sandboxNodeModules, "autoprefixer");
1133
- let pluginEntry = path10.join(pluginDir, "src/index.tsx");
1134
- if (!fs8.existsSync(pluginEntry)) {
1135
- pluginEntry = path10.join(pluginDir, "src/index.ts");
1129
+ const tailwindPath = path11.join(sandboxNodeModules, "tailwindcss");
1130
+ const autoprefixerPath = path11.join(sandboxNodeModules, "autoprefixer");
1131
+ let pluginEntry = path11.join(pluginDir, "src/index.tsx");
1132
+ if (!fs9.existsSync(pluginEntry)) {
1133
+ pluginEntry = path11.join(pluginDir, "src/index.ts");
1136
1134
  }
1137
1135
  const define = {
1138
1136
  "process.env.CHATBI_PLUGIN_PATH": JSON.stringify(pluginDir)
1139
1137
  };
1140
1138
  const { createServer } = await import("vite");
1139
+ const jiti = createJiti2(import.meta.url);
1140
+ const tailwindConfig = await jiti.import(path11.join(sandboxNodeModules, "@chatbi-v/config/tailwind.js"), { default: true });
1141
1141
  try {
1142
1142
  const server = await createServer({
1143
1143
  root: shellDir,
@@ -1146,12 +1146,12 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1146
1146
  postcss: {
1147
1147
  plugins: [
1148
1148
  nativeRequire(tailwindPath)({
1149
- presets: [nativeRequire(path10.join(sandboxNodeModules, "@chatbi-v/config/tailwind.js"))],
1149
+ presets: [tailwindConfig],
1150
1150
  darkMode: "class",
1151
1151
  content: [
1152
- path10.join(shellDir, "index.html"),
1153
- path10.join(shellDir, "src/**/*.{ts,tsx}"),
1154
- path10.join(pluginDir, "src/**/*.{ts,tsx}")
1152
+ path11.join(shellDir, "index.html"),
1153
+ path11.join(shellDir, "src/**/*.{ts,tsx}"),
1154
+ path11.join(pluginDir, "src/**/*.{ts,tsx}")
1155
1155
  ]
1156
1156
  }),
1157
1157
  nativeRequire(autoprefixerPath)
@@ -1173,21 +1173,21 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1173
1173
  allow: [
1174
1174
  sandboxRoot,
1175
1175
  pluginDir,
1176
- path10.resolve(pluginDir, "../../")
1176
+ path11.resolve(pluginDir, "../../")
1177
1177
  ]
1178
1178
  }
1179
1179
  },
1180
1180
  resolve: {
1181
1181
  alias: {
1182
1182
  ...coreAlias,
1183
- "react": path10.join(sandboxNodeModules, "react"),
1184
- "react-dom": path10.join(sandboxNodeModules, "react-dom"),
1185
- "@": path10.join(shellDir, "src"),
1183
+ "react": path11.join(sandboxNodeModules, "react"),
1184
+ "react-dom": path11.join(sandboxNodeModules, "react-dom"),
1185
+ "@": path11.join(shellDir, "src"),
1186
1186
  // 关键:将虚拟模块指向用户插件
1187
1187
  "virtual:user-plugin": pluginEntry,
1188
1188
  // 防止 glob 报错,提供空的映射
1189
- "@chatbi-plugins": path10.join(shellDir, "empty"),
1190
- "@chatbi-apps": path10.join(shellDir, "empty")
1189
+ "@chatbi-plugins": path11.join(shellDir, "empty"),
1190
+ "@chatbi-apps": path11.join(shellDir, "empty")
1191
1191
  }
1192
1192
  },
1193
1193
  define
@@ -1195,9 +1195,9 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
1195
1195
  await server.listen();
1196
1196
  const localUrl = `http://localhost:${shellPort}/`;
1197
1197
  printBox(
1198
- `${pc4.green(pc4.bold("\u2705 \u6258\u7BA1\u5F0F Shell \u5DF2\u542F\u52A8"))}
1198
+ `${pc5.green(pc5.bold("\u2705 \u6258\u7BA1\u5F0F Shell \u5DF2\u542F\u52A8"))}
1199
1199
 
1200
- ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1200
+ ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1201
1201
  "Shell Success"
1202
1202
  );
1203
1203
  } catch (e) {
@@ -1210,7 +1210,7 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1210
1210
  static async startAppDevServer(appDir, version, customPort) {
1211
1211
  logger.info("\u6B63\u5728\u542F\u52A8\u5E94\u7528...");
1212
1212
  const versionPath = Sandbox.getVersionPath(version);
1213
- const sandboxNodeModules = path10.join(versionPath, "node_modules");
1213
+ const sandboxNodeModules = path11.join(versionPath, "node_modules");
1214
1214
  const coreAlias = Sandbox.getCoreAlias(version);
1215
1215
  const { createServer, loadConfigFromFile } = await import("vite");
1216
1216
  try {
@@ -1224,9 +1224,9 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1224
1224
  alias: {
1225
1225
  ...coreAlias,
1226
1226
  // 补充常用的基础依赖映射,防止用户 vite.config.ts 中的插件找不到依赖
1227
- "react": path10.join(sandboxNodeModules, "react"),
1228
- "react-dom": path10.join(sandboxNodeModules, "react-dom"),
1229
- "@vitejs/plugin-react": path10.join(sandboxNodeModules, "@vitejs/plugin-react")
1227
+ "react": path11.join(sandboxNodeModules, "react"),
1228
+ "react-dom": path11.join(sandboxNodeModules, "react-dom"),
1229
+ "@vitejs/plugin-react": path11.join(sandboxNodeModules, "@vitejs/plugin-react")
1230
1230
  }
1231
1231
  },
1232
1232
  server: {
@@ -1253,9 +1253,9 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1253
1253
  await server.listen();
1254
1254
  const localUrl = `http://localhost:${server.config.server.port}/`;
1255
1255
  printBox(
1256
- `${pc4.green(pc4.bold("\u2705 \u5E94\u7528\u5DF2\u6210\u529F\u542F\u52A8"))}
1256
+ `${pc5.green(pc5.bold("\u2705 \u5E94\u7528\u5DF2\u6210\u529F\u542F\u52A8"))}
1257
1257
 
1258
- ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
1258
+ ${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
1259
1259
  "App Success"
1260
1260
  );
1261
1261
  } catch (e) {
@@ -1272,18 +1272,18 @@ __export(build_exports, {
1272
1272
  build: () => build
1273
1273
  });
1274
1274
  import { execa as execa2 } from "execa";
1275
- import fs9 from "fs-extra";
1276
- import path11 from "path";
1277
- import pc5 from "picocolors";
1275
+ import fs10 from "fs-extra";
1276
+ import path12 from "path";
1277
+ import pc6 from "picocolors";
1278
1278
  import { build as tsupBuild } from "tsup";
1279
1279
  async function build(options) {
1280
1280
  const cwd = process.cwd();
1281
- const pkgPath = path11.join(cwd, "package.json");
1282
- if (!fs9.existsSync(pkgPath)) {
1281
+ const pkgPath = path12.join(cwd, "package.json");
1282
+ if (!fs10.existsSync(pkgPath)) {
1283
1283
  logger.error(`\u5728 ${cwd} \u4E2D\u672A\u627E\u5230 package.json`);
1284
1284
  return;
1285
1285
  }
1286
- const pkg = await fs9.readJson(pkgPath);
1286
+ const pkg = await fs10.readJson(pkgPath);
1287
1287
  if (options.force) {
1288
1288
  const spinnerClean = createSpinner("\u6B63\u5728\u6E05\u7406\u7F13\u5B58\u73AF\u5883...").start();
1289
1289
  try {
@@ -1295,24 +1295,24 @@ async function build(options) {
1295
1295
  }
1296
1296
  }
1297
1297
  const version = await CoreKit.resolveVersion(cwd);
1298
- logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${pc5.bold(pkg.name || "unnamed")} (\u5185\u6838\u7248\u672C: ${version})
1298
+ logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${pc6.bold(pkg.name || "unnamed")} (\u5185\u6838\u7248\u672C: ${version})
1299
1299
  `);
1300
1300
  const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6784\u5EFA\u73AF\u5883...").start();
1301
1301
  spinner.text = "\u6B63\u5728\u540C\u6B65\u6C99\u7BB1\u5185\u6838...";
1302
1302
  await Sandbox.prepare(version, options.force);
1303
- if (pkg.workspaces || fs9.existsSync(path11.join(cwd, "pnpm-workspace.yaml"))) {
1303
+ if (pkg.workspaces || fs10.existsSync(path12.join(cwd, "pnpm-workspace.yaml"))) {
1304
1304
  spinner.text = "\u68C0\u6D4B\u5230 Monorepo\uFF0C\u6B63\u5728\u521D\u59CB\u5316\u6839\u76EE\u5F55\u4E0A\u4E0B\u6587...";
1305
1305
  await Sandbox.injectContext(cwd, version);
1306
1306
  spinner.text = "\u6B63\u5728\u540C\u6B65\u5B50\u5305\u4E0A\u4E0B\u6587...";
1307
1307
  const subDirs = ["apps", "plugins", "packages"];
1308
1308
  for (const dir of subDirs) {
1309
- const dirPath = path11.join(cwd, dir);
1310
- if (fs9.existsSync(dirPath)) {
1311
- const entries = await fs9.readdir(dirPath, { withFileTypes: true });
1309
+ const dirPath = path12.join(cwd, dir);
1310
+ if (fs10.existsSync(dirPath)) {
1311
+ const entries = await fs10.readdir(dirPath, { withFileTypes: true });
1312
1312
  for (const entry2 of entries) {
1313
1313
  if (entry2.isDirectory()) {
1314
- const subPkgPath = path11.join(dirPath, entry2.name);
1315
- if (fs9.existsSync(path11.join(subPkgPath, "package.json"))) {
1314
+ const subPkgPath = path12.join(dirPath, entry2.name);
1315
+ if (fs10.existsSync(path12.join(subPkgPath, "package.json"))) {
1316
1316
  await Sandbox.injectContext(subPkgPath, version);
1317
1317
  }
1318
1318
  }
@@ -1326,7 +1326,7 @@ async function build(options) {
1326
1326
  if (pkg.scripts && pkg.scripts.build && !process.env.CHATBI_CLI_INTERNAL) {
1327
1327
  const buildScript = pkg.scripts.build;
1328
1328
  if (!buildScript.includes("chatbi-cli build") && !buildScript.includes("chatbi build")) {
1329
- logger.info(`\u68C0\u6D4B\u5230\u81EA\u5B9A\u4E49 build \u811A\u672C\uFF0C\u6B63\u5728\u6267\u884C: ${pc5.cyan("npm run build")}`);
1329
+ logger.info(`\u68C0\u6D4B\u5230\u81EA\u5B9A\u4E49 build \u811A\u672C\uFF0C\u6B63\u5728\u6267\u884C: ${pc6.cyan("npm run build")}`);
1330
1330
  const args = ["run", "build"];
1331
1331
  if (options.watch) {
1332
1332
  args.push("--", "--watch");
@@ -1350,7 +1350,7 @@ async function build(options) {
1350
1350
  const coreAlias = Sandbox.getCoreAlias(version);
1351
1351
  await viteBuild({
1352
1352
  root: cwd,
1353
- configFile: fs9.existsSync(path11.join(cwd, "vite.config.ts")) ? void 0 : false,
1353
+ configFile: fs10.existsSync(path12.join(cwd, "vite.config.ts")) ? void 0 : false,
1354
1354
  resolve: {
1355
1355
  alias: {
1356
1356
  ...coreAlias
@@ -1374,16 +1374,16 @@ async function build(options) {
1374
1374
  });
1375
1375
  if (!options.watch) {
1376
1376
  printBox(
1377
- pc5.green(pc5.bold("\u2728 \u5E94\u7528\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc5.white("\u4EA7\u7269\u76EE\u5F55: ") + pc5.cyan("dist"),
1377
+ pc6.green(pc6.bold("\u2728 \u5E94\u7528\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc6.white("\u4EA7\u7269\u76EE\u5F55: ") + pc6.cyan("dist"),
1378
1378
  "Build Success"
1379
1379
  );
1380
1380
  }
1381
1381
  return;
1382
1382
  }
1383
1383
  let entry = ["src/index.ts"];
1384
- if (fs9.existsSync(path11.join(cwd, "src/index.tsx"))) {
1384
+ if (fs10.existsSync(path12.join(cwd, "src/index.tsx"))) {
1385
1385
  entry = ["src/index.tsx"];
1386
- } else if (!fs9.existsSync(path11.join(cwd, "src/index.ts"))) {
1386
+ } else if (!fs10.existsSync(path12.join(cwd, "src/index.ts"))) {
1387
1387
  logger.error("\u672A\u627E\u5230\u5165\u53E3\u6587\u4EF6\u3002\u671F\u671B src/index.ts \u6216 src/index.tsx");
1388
1388
  return;
1389
1389
  }
@@ -1393,10 +1393,10 @@ async function build(options) {
1393
1393
  logger.info(`\u5DF2\u52A0\u8F7D\u672C\u5730\u6784\u5EFA\u914D\u7F6E`);
1394
1394
  }
1395
1395
  if (!options.watch) {
1396
- await fs9.remove(path11.join(cwd, "dist"));
1397
- const tsbuildinfo = path11.join(cwd, "tsconfig.tsbuildinfo");
1398
- if (fs9.existsSync(tsbuildinfo)) {
1399
- await fs9.remove(tsbuildinfo);
1396
+ await fs10.remove(path12.join(cwd, "dist"));
1397
+ const tsbuildinfo = path12.join(cwd, "tsconfig.tsbuildinfo");
1398
+ if (fs10.existsSync(tsbuildinfo)) {
1399
+ await fs10.remove(tsbuildinfo);
1400
1400
  }
1401
1401
  }
1402
1402
  if (isPlugin) {
@@ -1486,15 +1486,15 @@ async function build(options) {
1486
1486
  if (!options.watch) {
1487
1487
  const dtsSpinner = createSpinner("\u6B63\u5728\u751F\u6210\u7C7B\u578B\u5B9A\u4E49...").start();
1488
1488
  try {
1489
- const localTsc = path11.join(cwd, "node_modules/.bin/tsc");
1490
- const sandboxTsc = path11.join(Sandbox.getVersionPath(version), "node_modules/.bin/tsc");
1489
+ const localTsc = path12.join(cwd, "node_modules/.bin/tsc");
1490
+ const sandboxTsc = path12.join(Sandbox.getVersionPath(version), "node_modules/.bin/tsc");
1491
1491
  let tscBin = "tsc";
1492
- if (fs9.existsSync(localTsc)) {
1492
+ if (fs10.existsSync(localTsc)) {
1493
1493
  tscBin = localTsc;
1494
- } else if (fs9.existsSync(sandboxTsc)) {
1494
+ } else if (fs10.existsSync(sandboxTsc)) {
1495
1495
  tscBin = sandboxTsc;
1496
1496
  } else {
1497
- if (fs9.existsSync(path11.join(cwd, "pnpm-lock.yaml"))) {
1497
+ if (fs10.existsSync(path12.join(cwd, "pnpm-lock.yaml"))) {
1498
1498
  await execa2("pnpm", ["exec", "tsc", "--build", "tsconfig.json"]);
1499
1499
  dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
1500
1500
  } else {
@@ -1510,7 +1510,7 @@ async function build(options) {
1510
1510
  dtsSpinner.warn("\u7C7B\u578B\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u4E2D\u7684 tsconfig.json \u914D\u7F6E");
1511
1511
  }
1512
1512
  printBox(
1513
- 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"),
1513
+ 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"),
1514
1514
  "Build Success"
1515
1515
  );
1516
1516
  }
@@ -1519,9 +1519,9 @@ var init_build = __esm({
1519
1519
  "src/commands/build.ts"() {
1520
1520
  "use strict";
1521
1521
  init_esm_shims();
1522
- init_sandbox();
1523
- init_corekit();
1524
1522
  init_config();
1523
+ init_corekit();
1524
+ init_sandbox();
1525
1525
  init_utils();
1526
1526
  }
1527
1527
  });
@@ -1531,17 +1531,17 @@ var sync_exports = {};
1531
1531
  __export(sync_exports, {
1532
1532
  sync: () => sync
1533
1533
  });
1534
- import fs10 from "fs-extra";
1535
- import path12 from "path";
1536
- import pc6 from "picocolors";
1534
+ import fs11 from "fs-extra";
1535
+ import path13 from "path";
1536
+ import pc8 from "picocolors";
1537
1537
  async function sync(options = {}) {
1538
1538
  const cwd = options.cwd || process.cwd();
1539
- const pkgPath = path12.join(cwd, "package.json");
1540
- if (!fs10.existsSync(pkgPath)) {
1539
+ const pkgPath = path13.join(cwd, "package.json");
1540
+ if (!fs11.existsSync(pkgPath)) {
1541
1541
  logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u3002");
1542
1542
  return;
1543
1543
  }
1544
- const pkg = await fs10.readJson(pkgPath);
1544
+ const pkg = await fs11.readJson(pkgPath);
1545
1545
  let version = options.version;
1546
1546
  if (!version) {
1547
1547
  version = await CoreKit.resolveVersion(cwd);
@@ -1556,8 +1556,8 @@ async function sync(options = {}) {
1556
1556
  await Sandbox.prepare(version, options.force);
1557
1557
  mainSpinner.text = "\u6B63\u5728\u751F\u6210\u865A\u62DF\u4E0A\u4E0B\u6587...";
1558
1558
  if (options.version) {
1559
- const versionFilePath = path12.join(cwd, ".chatbi-version");
1560
- await fs10.writeFile(versionFilePath, version, "utf-8");
1559
+ const versionFilePath = path13.join(cwd, ".chatbi-version");
1560
+ await fs11.writeFile(versionFilePath, version, "utf-8");
1561
1561
  }
1562
1562
  await Sandbox.injectContext(cwd, version);
1563
1563
  let modified = false;
@@ -1579,19 +1579,19 @@ async function sync(options = {}) {
1579
1579
  if (modified) {
1580
1580
  pkg.dependencies = deps;
1581
1581
  pkg.devDependencies = devDeps;
1582
- await fs10.writeJson(pkgPath, pkg, { spaces: 2 });
1582
+ await fs11.writeJson(pkgPath, pkg, { spaces: 2 });
1583
1583
  mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210 (\u4F9D\u8D56\u5DF2\u4F18\u5316)");
1584
1584
  } else {
1585
1585
  mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210");
1586
1586
  }
1587
1587
  if (!options.silent) {
1588
1588
  printBox(
1589
- `${pc6.green(pc6.bold("\u2728 \u5185\u6838\u540C\u6B65\u6210\u529F!"))}
1589
+ `${pc8.green(pc8.bold("\u2728 \u5185\u6838\u540C\u6B65\u6210\u529F!"))}
1590
1590
 
1591
- ${pc6.white("\u5F53\u524D\u7248\u672C: ")} ${pc6.cyan(version)}
1592
- ${pc6.white("\u6C99\u7BB1\u8DEF\u5F84: ")} ${pc6.gray(Sandbox.getVersionPath(version))}
1591
+ ${pc8.white("\u5F53\u524D\u7248\u672C: ")} ${pc8.cyan(version)}
1592
+ ${pc8.white("\u6C99\u7BB1\u8DEF\u5F84: ")} ${pc8.gray(Sandbox.getVersionPath(version))}
1593
1593
 
1594
- ${pc6.white("\u63D0\u793A: ")} \u9879\u76EE\u73B0\u5728\u901A\u8FC7\u865A\u62DF\u522B\u540D\u5F15\u7528\u6838\u5FC3\u5305\uFF0C\u65E0\u9700\u663E\u5F0F\u5B89\u88C5\u4F9D\u8D56\u3002`,
1594
+ ${pc8.white("\u63D0\u793A: ")} \u9879\u76EE\u73B0\u5728\u901A\u8FC7\u865A\u62DF\u522B\u540D\u5F15\u7528\u6838\u5FC3\u5305\uFF0C\u65E0\u9700\u663E\u5F0F\u5B89\u88C5\u4F9D\u8D56\u3002`,
1595
1595
  "Sync Success"
1596
1596
  );
1597
1597
  }
@@ -1600,31 +1600,75 @@ var init_sync = __esm({
1600
1600
  "src/commands/sync.ts"() {
1601
1601
  "use strict";
1602
1602
  init_esm_shims();
1603
- init_utils();
1604
- init_sandbox();
1605
1603
  init_corekit();
1604
+ init_sandbox();
1605
+ init_utils();
1606
1606
  }
1607
1607
  });
1608
1608
 
1609
- // src/commands/init.ts
1610
- var init_exports = {};
1611
- __export(init_exports, {
1612
- init: () => init
1609
+ // src/commands/fetch.ts
1610
+ var fetch_exports = {};
1611
+ __export(fetch_exports, {
1612
+ fetch: () => fetch
1613
1613
  });
1614
- import fs11 from "fs-extra";
1615
- import path13 from "path";
1616
- import pc7 from "picocolors";
1617
- import prompts2 from "prompts";
1618
- async function init(options) {
1619
- let { name, pluginType = "business", theme = DEFAULT_CONFIG.THEME, projectType, includeApp, includePlugin, cwd } = options;
1620
- const response = await prompts2([
1621
- // ... (prompts remain the same)
1622
- {
1623
- type: name ? null : "text",
1624
- name: "projectName",
1625
- message: "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0:",
1626
- initial: "my-chatbi-workspace"
1627
- },
1614
+ import { execa as execa3 } from "execa";
1615
+ import path15 from "path";
1616
+ import pc10 from "picocolors";
1617
+ async function fetch(version, options = {}) {
1618
+ const fetchSpinner = createSpinner(`\u6B63\u5728\u83B7\u53D6\u5185\u6838\u7248\u672C ${pc10.cyan(version)}...`).start();
1619
+ const versionPath = await Sandbox.prepare(version, true);
1620
+ fetchSpinner.succeed(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u83B7\u53D6\u6210\u529F`);
1621
+ if (options.pack) {
1622
+ const packSpinner = createSpinner("\u6B63\u5728\u6253\u5305\u79BB\u7EBF\u8D44\u6E90...").start();
1623
+ const tgzName = `chatbi-core-${version}.tgz`;
1624
+ const tgzPath = path15.resolve(process.cwd(), tgzName);
1625
+ await execa3("tar", [
1626
+ "-czf",
1627
+ tgzPath,
1628
+ "-C",
1629
+ path15.dirname(versionPath),
1630
+ path15.basename(versionPath)
1631
+ ]);
1632
+ packSpinner.succeed("\u79BB\u7EBF\u8D44\u6E90\u6253\u5305\u5B8C\u6210");
1633
+ printBox(
1634
+ `${pc10.green(pc10.bold("\u2728 \u79BB\u7EBF\u5305\u5DF2\u751F\u6210!"))}
1635
+
1636
+ ${pc10.white("\u6587\u4EF6\u8DEF\u5F84: ")} ${pc10.cyan(tgzPath)}
1637
+ ${pc10.white("\u5B89\u88C5\u547D\u4EE4: ")} ${pc10.gray(`chatbi install ${tgzName}`)}`,
1638
+ "Pack Success"
1639
+ );
1640
+ } else {
1641
+ logger.success(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002`);
1642
+ }
1643
+ }
1644
+ var init_fetch = __esm({
1645
+ "src/commands/fetch.ts"() {
1646
+ "use strict";
1647
+ init_esm_shims();
1648
+ init_sandbox();
1649
+ init_utils();
1650
+ }
1651
+ });
1652
+
1653
+ // src/commands/init.ts
1654
+ var init_exports = {};
1655
+ __export(init_exports, {
1656
+ init: () => init
1657
+ });
1658
+ import fs14 from "fs-extra";
1659
+ import path17 from "path";
1660
+ import pc12 from "picocolors";
1661
+ import prompts4 from "prompts";
1662
+ async function init(options) {
1663
+ let { name, pluginType = "business", theme = DEFAULT_CONFIG.THEME, projectType, includeApp, includePlugin, cwd } = options;
1664
+ const response = await prompts4([
1665
+ // ... (prompts remain the same)
1666
+ {
1667
+ type: name ? null : "text",
1668
+ name: "projectName",
1669
+ message: "\u8BF7\u8F93\u5165\u9879\u76EE\u540D\u79F0:",
1670
+ initial: "my-chatbi-workspace"
1671
+ },
1628
1672
  {
1629
1673
  type: projectType ? null : "select",
1630
1674
  name: "projectType",
@@ -1687,32 +1731,32 @@ async function init(options) {
1687
1731
  const isAppIncluded = finalIncludeApp;
1688
1732
  const isPluginIncluded = finalIncludePlugin;
1689
1733
  const rootDir = cwd || process.cwd();
1690
- const targetDir = path13.resolve(rootDir, name);
1691
- if (fs11.existsSync(targetDir)) {
1734
+ const targetDir = path17.resolve(rootDir, name);
1735
+ if (fs14.existsSync(targetDir)) {
1692
1736
  logger.error(`\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728\u3002`);
1693
1737
  return;
1694
1738
  }
1695
- logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${pc7.bold(name)}...`);
1696
- logger.info(pc7.gray(`\u7C7B\u578B: ${projectType} | \u4E3B\u9898: ${theme || "N/A"}`));
1739
+ logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${pc12.bold(name)}...`);
1740
+ logger.info(pc12.gray(`\u7C7B\u578B: ${projectType} | \u4E3B\u9898: ${theme || "N/A"}`));
1697
1741
  console.log("");
1698
1742
  try {
1699
1743
  const myCliRoot = await getCliRoot();
1700
- const cliPkg = await fs11.readJson(path13.join(myCliRoot, "package.json"));
1744
+ const cliPkg = await fs14.readJson(path17.join(myCliRoot, "package.json"));
1701
1745
  const cliVersion = cliPkg.version;
1702
1746
  const config = { coreSource: "npm" };
1703
- const kernelVersionFile = path13.join(myCliRoot, SANDBOX_CONFIG.LOCK_FILE);
1704
- if (fs11.existsSync(kernelVersionFile)) {
1705
- config.coreVersion = (await fs11.readFile(kernelVersionFile, "utf-8")).trim();
1747
+ const kernelVersionFile = path17.join(myCliRoot, SANDBOX_CONFIG.LOCK_FILE);
1748
+ if (fs14.existsSync(kernelVersionFile)) {
1749
+ config.coreVersion = (await fs14.readFile(kernelVersionFile, "utf-8")).trim();
1706
1750
  }
1707
1751
  const kernelVersion = await ConfigManager.resolveCoreDependency(config);
1708
1752
  const renderTemplate = async (templateName, destDir, extraData = {}) => {
1709
- const srcDir = path13.join(myCliRoot, "templates", templateName);
1710
- if (!fs11.existsSync(srcDir)) {
1753
+ const srcDir = path17.join(myCliRoot, "templates", templateName);
1754
+ if (!fs14.existsSync(srcDir)) {
1711
1755
  throw new Error(`\u627E\u4E0D\u5230\u6A21\u677F: ${templateName}\uFF0C\u8BF7\u68C0\u67E5\u8DEF\u5F84 ${srcDir} \u662F\u5426\u6B63\u786E\u3002`);
1712
1756
  }
1713
- await fs11.ensureDir(destDir);
1757
+ await fs14.ensureDir(destDir);
1714
1758
  const templateData = {
1715
- name: path13.basename(destDir),
1759
+ name: path17.basename(destDir),
1716
1760
  projectName: name,
1717
1761
  // Original project name from CLI argument
1718
1762
  projectTitle: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" "),
@@ -1740,12 +1784,12 @@ async function init(options) {
1740
1784
  await renderTemplate("monorepo", targetDir, { name });
1741
1785
  if (isAppIncluded) {
1742
1786
  spinner.text = "\u6B63\u5728\u751F\u6210 Host App...";
1743
- const appDir = path13.join(targetDir, "apps", "main");
1787
+ const appDir = path17.join(targetDir, "apps", "main");
1744
1788
  await renderTemplate("app", appDir, { name: "@chatbi-v/main" });
1745
1789
  }
1746
1790
  if (isPluginIncluded) {
1747
1791
  spinner.text = "\u6B63\u5728\u751F\u6210 Demo Plugin...";
1748
- const pluginDir = path13.join(targetDir, "plugins", "plugin-demo");
1792
+ const pluginDir = path17.join(targetDir, "plugins", "plugin-demo");
1749
1793
  await renderTemplate("plugin", pluginDir, {
1750
1794
  name: "@chatbi-v/plugin-demo",
1751
1795
  pluginId: "demo",
@@ -1787,15 +1831,15 @@ async function init(options) {
1787
1831
  const cliConfig = {
1788
1832
  coreVersion: kernelVersion
1789
1833
  };
1790
- await fs11.writeJson(path13.join(targetDir, "chatbi.config.json"), cliConfig, { spaces: 2 });
1834
+ await fs14.writeJson(path17.join(targetDir, "chatbi.config.json"), cliConfig, { spaces: 2 });
1791
1835
  configSpinner.succeed("\u9879\u76EE\u914D\u7F6E\u751F\u6210\u5B8C\u6210");
1792
1836
  printBox(
1793
- `${pc7.green(pc7.bold("\u2728 \u9879\u76EE\u5DF2\u6210\u529F\u521B\u5EFA!"))}
1837
+ `${pc12.green(pc12.bold("\u2728 \u9879\u76EE\u5DF2\u6210\u529F\u521B\u5EFA!"))}
1794
1838
 
1795
- ${pc7.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
1796
- ${pc7.cyan(` cd ${name}`)}
1797
- ${pc7.cyan(" pnpm install")}
1798
- ${pc7.cyan(" pnpm dev")}`,
1839
+ ${pc12.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
1840
+ ${pc12.cyan(` cd ${name}`)}
1841
+ ${pc12.cyan(" pnpm install")}
1842
+ ${pc12.cyan(" pnpm dev")}`,
1799
1843
  "Success"
1800
1844
  );
1801
1845
  } catch (error) {
@@ -1807,55 +1851,11 @@ var init_init = __esm({
1807
1851
  "src/commands/init.ts"() {
1808
1852
  "use strict";
1809
1853
  init_esm_shims();
1810
- init_utils();
1811
- init_sync();
1812
- init_constants();
1813
1854
  init_config();
1855
+ init_constants();
1814
1856
  init_SandboxRenderer();
1815
- }
1816
- });
1817
-
1818
- // src/commands/fetch.ts
1819
- var fetch_exports = {};
1820
- __export(fetch_exports, {
1821
- fetch: () => fetch
1822
- });
1823
- import path18 from "path";
1824
- import pc13 from "picocolors";
1825
- import { execa as execa4 } from "execa";
1826
- async function fetch(version, options = {}) {
1827
- const fetchSpinner = createSpinner(`\u6B63\u5728\u83B7\u53D6\u5185\u6838\u7248\u672C ${pc13.cyan(version)}...`).start();
1828
- const versionPath = await Sandbox.prepare(version, true);
1829
- fetchSpinner.succeed(`\u5185\u6838\u7248\u672C ${pc13.cyan(version)} \u83B7\u53D6\u6210\u529F`);
1830
- if (options.pack) {
1831
- const packSpinner = createSpinner("\u6B63\u5728\u6253\u5305\u79BB\u7EBF\u8D44\u6E90...").start();
1832
- const tgzName = `chatbi-core-${version}.tgz`;
1833
- const tgzPath = path18.resolve(process.cwd(), tgzName);
1834
- await execa4("tar", [
1835
- "-czf",
1836
- tgzPath,
1837
- "-C",
1838
- path18.dirname(versionPath),
1839
- path18.basename(versionPath)
1840
- ]);
1841
- packSpinner.succeed("\u79BB\u7EBF\u8D44\u6E90\u6253\u5305\u5B8C\u6210");
1842
- printBox(
1843
- `${pc13.green(pc13.bold("\u2728 \u79BB\u7EBF\u5305\u5DF2\u751F\u6210!"))}
1844
-
1845
- ${pc13.white("\u6587\u4EF6\u8DEF\u5F84: ")} ${pc13.cyan(tgzPath)}
1846
- ${pc13.white("\u5B89\u88C5\u547D\u4EE4: ")} ${pc13.gray(`chatbi install ${tgzName}`)}`,
1847
- "Pack Success"
1848
- );
1849
- } else {
1850
- logger.success(`\u5185\u6838\u7248\u672C ${pc13.cyan(version)} \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002`);
1851
- }
1852
- }
1853
- var init_fetch = __esm({
1854
- "src/commands/fetch.ts"() {
1855
- "use strict";
1856
- init_esm_shims();
1857
- init_sandbox();
1858
1857
  init_utils();
1858
+ init_sync();
1859
1859
  }
1860
1860
  });
1861
1861
 
@@ -1864,10 +1864,10 @@ var bench_exports = {};
1864
1864
  __export(bench_exports, {
1865
1865
  bench: () => bench
1866
1866
  });
1867
- import pc15 from "picocolors";
1868
1867
  import fs17 from "fs-extra";
1869
- import path20 from "path";
1870
1868
  import os2 from "os";
1869
+ import path20 from "path";
1870
+ import pc15 from "picocolors";
1871
1871
  async function bench() {
1872
1872
  logger.info("\u6B63\u5728\u542F\u52A8 CLI \u6027\u80FD\u57FA\u51C6\u6D4B\u8BD5...");
1873
1873
  const results = [];
@@ -1934,54 +1934,101 @@ var init_bench = __esm({
1934
1934
 
1935
1935
  // src/index.ts
1936
1936
  init_esm_shims();
1937
- init_build();
1937
+ import boxen2 from "boxen";
1938
1938
  import cac from "cac";
1939
- import pc16 from "picocolors";
1940
1939
  import figlet from "figlet";
1941
1940
  import gradient from "gradient-string";
1942
- import boxen2 from "boxen";
1943
-
1944
- // src/commands/dev.ts
1945
- init_esm_shims();
1946
- init_corekit();
1947
- async function dev(options = {}) {
1948
- const cwd = process.cwd();
1949
- await CoreKit.startDev(cwd, options);
1950
- }
1941
+ import pc16 from "picocolors";
1951
1942
 
1952
- // src/index.ts
1953
- init_init();
1943
+ // package.json
1944
+ var package_default = {
1945
+ name: "@chatbi-v/cli",
1946
+ version: "2.1.7",
1947
+ description: "Standardized CLI tooling for ChatBI Monorepo",
1948
+ type: "module",
1949
+ main: "dist/index.js",
1950
+ module: "dist/index.js",
1951
+ types: "dist/index.d.ts",
1952
+ exports: {
1953
+ ".": "./dist/index.js",
1954
+ "./package.json": "./package.json"
1955
+ },
1956
+ bin: {
1957
+ "chatbi-cli": "./bin/chatbi-cli.js"
1958
+ },
1959
+ files: [
1960
+ "dist",
1961
+ "bin",
1962
+ "templates"
1963
+ ],
1964
+ publishConfig: {
1965
+ access: "public"
1966
+ },
1967
+ scripts: {
1968
+ build: "tsup",
1969
+ dev: "tsup --watch",
1970
+ test: "vitest"
1971
+ },
1972
+ dependencies: {
1973
+ boxen: "^8.0.1",
1974
+ cac: "^6.7.14",
1975
+ execa: "^8.0.1",
1976
+ "fast-glob": "^3.3.3",
1977
+ figlet: "^1.9.4",
1978
+ "fs-extra": "^11.2.0",
1979
+ "gradient-string": "^3.0.0",
1980
+ handlebars: "^4.7.8",
1981
+ jiti: "^2.6.1",
1982
+ ora: "^7.0.1",
1983
+ picocolors: "^1.0.0",
1984
+ prompts: "^2.4.2",
1985
+ tsup: "^8.5.1",
1986
+ typescript: "^5.0.0",
1987
+ vite: "^5.4.21"
1988
+ },
1989
+ devDependencies: {
1990
+ "@types/boxen": "^3.0.5",
1991
+ "@types/figlet": "^1.7.0",
1992
+ "@types/fs-extra": "^11.0.0",
1993
+ "@types/gradient-string": "^1.1.6",
1994
+ "@types/node": "^20.0.0",
1995
+ "@types/prompts": "^2.4.9",
1996
+ "@vitest/coverage-v8": "1.6.1",
1997
+ tsup: "^8.5.1",
1998
+ vitest: "^1.0.0"
1999
+ }
2000
+ };
1954
2001
 
1955
2002
  // src/commands/add.ts
1956
2003
  init_esm_shims();
1957
- init_utils();
1958
2004
  init_config();
1959
2005
  init_constants();
1960
2006
  init_SandboxRenderer();
1961
- import fs12 from "fs-extra";
1962
- import path14 from "path";
1963
- import pc8 from "picocolors";
1964
- import prompts3 from "prompts";
1965
- import { createRequire as createRequire3 } from "module";
2007
+ init_utils();
2008
+ import fs4 from "fs-extra";
2009
+ import { createRequire as createRequire2 } from "module";
2010
+ import path6 from "path";
2011
+ import pc2 from "picocolors";
2012
+ import prompts from "prompts";
1966
2013
  import { fileURLToPath as fileURLToPath3 } from "url";
1967
- var _require2 = createRequire3(import.meta.url);
2014
+ var _require2 = createRequire2(import.meta.url);
1968
2015
  var _filename2 = fileURLToPath3(import.meta.url);
1969
- var _dirname2 = path14.dirname(_filename2);
2016
+ var _dirname2 = path6.dirname(_filename2);
1970
2017
  async function add(options) {
1971
2018
  let { name, type, displayName, description } = options;
1972
2019
  const cwd = process.cwd();
1973
- const pkgPath = path14.join(cwd, "package.json");
1974
- if (!fs12.existsSync(pkgPath)) {
2020
+ const pkgPath = path6.join(cwd, "package.json");
2021
+ if (!fs4.existsSync(pkgPath)) {
1975
2022
  logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
1976
2023
  return;
1977
2024
  }
1978
- const pkg = await fs12.readJson(pkgPath);
2025
+ const pkg = await fs4.readJson(pkgPath);
1979
2026
  const isMonorepo = pkg.workspaces && (pkg.workspaces.includes("plugins/*") || pkg.workspaces.packages?.includes("plugins/*"));
1980
2027
  if (!isMonorepo) {
1981
2028
  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)");
1982
2029
  process.exit(1);
1983
2030
  }
1984
- const response = await prompts3([
2031
+ const response = await prompts([
1985
2032
  {
1986
2033
  type: name ? null : "text",
1987
2034
  name: "pluginName",
@@ -2026,12 +2073,12 @@ async function add(options) {
2026
2073
  cleanName = cleanName.replace(/-plugin$/, "");
2027
2074
  }
2028
2075
  const folderName = cleanName.startsWith("plugin-") ? cleanName : `plugin-${cleanName}`;
2029
- const pluginDir = path14.resolve(cwd, "plugins", folderName);
2030
- if (fs12.existsSync(pluginDir)) {
2076
+ const pluginDir = path6.resolve(cwd, "plugins", folderName);
2077
+ if (fs4.existsSync(pluginDir)) {
2031
2078
  logger.error(`\u63D2\u4EF6\u76EE\u5F55 ${folderName} \u5DF2\u5B58\u5728\u3002`);
2032
2079
  return;
2033
2080
  }
2034
- const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${pc8.bold(name)}...`).start();
2081
+ const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${pc2.bold(name)}...`).start();
2035
2082
  const targetDir = pluginDir;
2036
2083
  spinner.text = "\u6B63\u5728\u52A0\u8F7D\u914D\u7F6E...";
2037
2084
  const config = await ConfigManager.loadConfig(cwd);
@@ -2057,206 +2104,102 @@ async function add(options) {
2057
2104
  tsconfigPath: `../../${SANDBOX_CONFIG.DIRS.CACHE}/tsconfig.json`
2058
2105
  };
2059
2106
  const myCliRoot = await getCliRoot();
2060
- let templateDir = myCliRoot ? path14.join(myCliRoot, "templates/plugin") : "";
2107
+ let templateDir = myCliRoot ? path6.join(myCliRoot, "templates/plugin") : "";
2061
2108
  if (process.env.NODE_ENV === "test" && !templateDir) {
2062
2109
  templateDir = "/mock/templates/plugin";
2063
2110
  }
2064
2111
  if (process.env.NODE_ENV === "test") {
2065
- spinner.succeed(`\u63D2\u4EF6 ${pc8.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2066
- console.log(`\u63D2\u4EF6 ${pc8.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2112
+ spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2113
+ console.log(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2067
2114
  console.log("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!");
2068
2115
  return;
2069
2116
  }
2070
- if (!templateDir || !fs12.existsSync(templateDir)) {
2117
+ if (!templateDir || !fs4.existsSync(templateDir)) {
2071
2118
  spinner.fail("\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F");
2072
2119
  throw new Error(`\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F: ${templateDir || "undefined"}`);
2073
2120
  }
2074
2121
  spinner.text = "\u6B63\u5728\u751F\u6210\u63D2\u4EF6\u6587\u4EF6...";
2075
2122
  await SandboxRenderer.renderDirectory(templateDir, targetDir, data);
2076
- spinner.succeed(`\u63D2\u4EF6 ${pc8.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2123
+ spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
2077
2124
  printBox(
2078
- `${pc8.green(pc8.bold("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!"))}
2125
+ `${pc2.green(pc2.bold("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!"))}
2079
2126
 
2080
- ${pc8.white("\u9879\u76EE\u8DEF\u5F84: ")} ${pc8.cyan(`plugins/${folderName}`)}
2081
- ${pc8.white("\u63D2\u4EF6 ID: ")} ${pc8.cyan(cleanName)}
2082
- ${pc8.white("\u63D2\u4EF6\u7C7B\u578B: ")} ${pc8.cyan(type)}
2127
+ ${pc2.white("\u9879\u76EE\u8DEF\u5F84: ")} ${pc2.cyan(`plugins/${folderName}`)}
2128
+ ${pc2.white("\u63D2\u4EF6 ID: ")} ${pc2.cyan(cleanName)}
2129
+ ${pc2.white("\u63D2\u4EF6\u7C7B\u578B: ")} ${pc2.cyan(type)}
2083
2130
 
2084
- ${pc8.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
2085
- ${pc8.cyan(" pnpm dev")} \u542F\u52A8\u5F00\u53D1\u73AF\u5883\u67E5\u770B\u6548\u679C`,
2131
+ ${pc2.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
2132
+ ${pc2.cyan(" pnpm dev")} \u542F\u52A8\u5F00\u53D1\u73AF\u5883\u67E5\u770B\u6548\u679C`,
2086
2133
  "Plugin Created"
2087
2134
  );
2088
2135
  }
2089
2136
 
2090
- // src/commands/gl.ts
2137
+ // src/index.ts
2138
+ init_build();
2139
+
2140
+ // src/commands/clean.ts
2141
+ init_esm_shims();
2142
+ init_sandbox();
2143
+ async function clean(options) {
2144
+ const cwd = process.cwd();
2145
+ await Sandbox.clean(cwd, options.deep);
2146
+ }
2147
+
2148
+ // src/commands/dev.ts
2149
+ init_esm_shims();
2150
+ init_corekit();
2151
+ async function dev(options = {}) {
2152
+ const cwd = process.cwd();
2153
+ await CoreKit.startDev(cwd, options);
2154
+ }
2155
+
2156
+ // src/commands/discover.ts
2091
2157
  init_esm_shims();
2158
+ init_corekit();
2092
2159
  init_utils();
2093
- import fs13 from "fs-extra";
2094
- import path15 from "path";
2160
+ import pc7 from "picocolors";
2161
+ async function discover() {
2162
+ const cwd = process.cwd();
2163
+ const spinner = createSpinner("\u6B63\u5728\u626B\u63CF\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6...").start();
2164
+ const plugins = await CoreKit.discoverPlugins(cwd);
2165
+ if (plugins.length === 0) {
2166
+ spinner.warn("\u672A\u53D1\u73B0\u4EFB\u4F55\u63D2\u4EF6");
2167
+ logger.info(pc7.gray("\u8BF7\u786E\u4FDD\u63D2\u4EF6\u4F4D\u4E8E plugins/ \u76EE\u5F55\u4E0B\uFF0C\u4E14\u5305\u542B package.json\u3002"));
2168
+ } else {
2169
+ spinner.succeed(`\u53D1\u73B0\u4E86 ${pc7.cyan(plugins.length)} \u4E2A\u63D2\u4EF6`);
2170
+ const pluginList = plugins.map((p) => `- ${pc7.bold(p.name)} ${pc7.gray(`(${p.id})`)}
2171
+ ${pc7.gray(p.path)}`).join("\n\n");
2172
+ printBox(
2173
+ `${pc7.green(pc7.bold("\u2728 \u63D2\u4EF6\u626B\u63CF\u7ED3\u679C"))}
2174
+
2175
+ ${pluginList}`,
2176
+ "Plugin Discovery"
2177
+ );
2178
+ }
2179
+ }
2180
+
2181
+ // src/commands/doctor.ts
2182
+ init_esm_shims();
2183
+ init_corekit();
2184
+ init_sandbox();
2185
+ init_utils();
2186
+ import glob from "fast-glob";
2187
+ import fs12 from "fs-extra";
2188
+ import path14 from "path";
2095
2189
  import pc9 from "picocolors";
2096
- import prompts4 from "prompts";
2097
- import { execa as execa3 } from "execa";
2098
- async function gl(options) {
2099
- const { type: initialType, prompt: initialPrompt } = options;
2190
+ async function doctor(options = {}) {
2191
+ logger.info("\u6B63\u5728\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5...\n");
2100
2192
  const cwd = process.cwd();
2101
- const pkgPath = path15.join(cwd, "package.json");
2102
- if (!fs13.existsSync(pkgPath)) {
2103
- logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
2104
- return;
2105
- }
2106
- const response = await prompts4([
2107
- {
2108
- type: initialType ? null : "select",
2109
- name: "genType",
2110
- message: "\u8BF7\u9009\u62E9 AI \u811A\u624B\u67B6\u6307\u4EE4:",
2111
- choices: [
2112
- { title: "\u{1F916} smart", value: "smart", description: "\u667A\u80FD\u51B3\u7B56 (\u6839\u636E\u9700\u6C42\u81EA\u52A8\u9009\u62E9\u5DE5\u5177)" },
2113
- { title: "\u{1F50C} plugin", value: "plugin", description: "\u751F\u6210\u65B0\u63D2\u4EF6" },
2114
- { title: "\u{1F9E9} component", value: "component", description: "\u751F\u6210\u4E1A\u52A1\u7EC4\u4EF6" },
2115
- { title: "\u{1F4E1} api", value: "api", description: "\u751F\u6210 API \u5B9A\u4E49\u4E0E\u8BF7\u6C42\u51FD\u6570" },
2116
- { title: "\u{1F3AD} mock", value: "mock", description: "\u751F\u6210 Mock \u6D4B\u8BD5\u6570\u636E" },
2117
- { title: "\u{1F6E0}\uFE0F util", value: "util", description: "\u751F\u6210\u5DE5\u5177\u51FD\u6570" },
2118
- { title: "\u{1F4C4} doc", value: "doc", description: "\u751F\u6210\u9879\u76EE\u6587\u6863" },
2119
- { title: "\u2728 chat", value: "chat", description: "\u81EA\u7531\u5BF9\u8BDD" }
2120
- ],
2121
- initial: 0
2122
- },
2123
- {
2124
- type: (prev, values) => initialPrompt || values.genType === "chat" ? null : "text",
2125
- name: "userPrompt",
2126
- message: "\u8BF7\u8F93\u5165\u8BE6\u7EC6\u9700\u6C42\u63CF\u8FF0:",
2127
- initial: initialPrompt || ""
2128
- }
2129
- ], {
2130
- onCancel: () => {
2131
- logger.warn("\u5DF2\u53D6\u6D88 AI \u751F\u6210");
2132
- process.exit(0);
2133
- }
2134
- });
2135
- const genType = initialType || response.genType;
2136
- const userPrompt = initialPrompt || response.userPrompt;
2137
- if (!userPrompt && genType !== "chat") {
2138
- logger.error("\u9700\u6C42\u63CF\u8FF0\u4E0D\u80FD\u4E3A\u7A7A\u3002");
2139
- return;
2140
- }
2141
- logger.info(`\u6B63\u5728\u547C\u53EB AI \u5F15\u64CE [\u6A21\u5F0F: ${pc9.bold(genType)}]...`);
2142
- const toolsContext = `
2143
- [Available Tools & Capabilities]
2144
- - Tool: plugin -> For creating new feature modules. Requires: name, type (business|system).
2145
- - Tool: component -> For UI elements. Tech: AntD5, Tailwind.
2146
- - Tool: api -> For network requests. Structure: src/api/[name].ts, uses shared request util, defines TS interfaces.
2147
- - Tool: mock -> For dev data. Structure: mock/[name].ts, follows Mock.js or MSW format.
2148
- - Tool: util -> For pure functions. Structure: src/utils/[name].ts, requires unit tests.
2149
- - Tool: doc -> For documentation. Format: Markdown, structure: docs/[type]/[name].md.
2150
-
2151
- [Tool Functions Implementation Details]
2152
- - API Function: Should include request method, URL, params/data types, and response type. Use '@chatbi-v/core/request'.
2153
- - Mock Function: Should provide realistic data based on API definition.
2154
- - Plugin Function: Should follow the Micro-Kernel architecture, registering to 'pluginManager'.
2155
-
2156
- [Requirement Slots / Missing Info]
2157
- If the user's request is ambiguous or missing key information, you MUST output: "SLOT_REQUIRED: [Field Name] | [Question to User]".
2158
- `.trim();
2159
- const templatesContext = `
2160
- [Project Templates Structure]
2161
- - Plugin: class extends Plugin, metadata: { id, name, version, type, routes, extensions }.
2162
- - API: export const fetchData = (params: T) => request.get<R>('/url', { params }).
2163
- - Mock: export default { 'GET /api/test': { code: 200, data: {} } }.
2164
- - UI: React 18, Ant Design 5, Tailwind CSS 3.
2165
- `.trim();
2166
- const systemContext = `[Context: ChatBI-V System | Dir: ${cwd} | Tech: React18, AntD5, Tailwind, Micro-Kernel]
2167
- ${toolsContext}
2168
- ${templatesContext}
2169
-
2170
- [Decision Logic]
2171
- If genType is 'smart', you must first decide which tool is most appropriate.
2172
- If the requirement is clear, proceed with generation.
2173
- If not, use the SLOT_REQUIRED format.`.trim();
2174
- const finalPrompt = userPrompt ? `${systemContext}
2175
-
2176
- [User Request]: ${userPrompt}` : systemContext;
2177
- const geminiCmd = genType === "smart" ? "chat" : genType;
2178
- const spinner = createSpinner("AI \u5F15\u64CE\u6B63\u5728\u601D\u8003\u4E2D... (\u53EF\u80FD\u9700\u8981\u51E0\u5341\u79D2\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85)");
2179
- let currentPrompt = finalPrompt;
2180
- let retry = true;
2181
- while (retry) {
2182
- spinner.start();
2183
- try {
2184
- const { stdout } = await execa3("gemini", [geminiCmd, currentPrompt], {
2185
- stdio: "pipe"
2186
- });
2187
- spinner.stop();
2188
- if (stdout.includes("SLOT_REQUIRED:")) {
2189
- const slots = [];
2190
- const lines = stdout.split("\n");
2191
- for (const line of lines) {
2192
- if (line.includes("SLOT_REQUIRED:")) {
2193
- const match = line.match(/SLOT_REQUIRED:\s*([^|]+)\|\s*(.+)/);
2194
- if (match) {
2195
- slots.push({
2196
- type: "text",
2197
- name: match[1].trim(),
2198
- message: match[2].trim()
2199
- });
2200
- }
2201
- }
2202
- }
2203
- if (slots.length > 0) {
2204
- logger.info(pc9.yellow("\n\u{1F4DD} AI \u9700\u8981\u66F4\u591A\u4FE1\u606F\u4EE5\u7EE7\u7EED:"));
2205
- const answers = await prompts4(slots, {
2206
- onCancel: () => process.exit(0)
2207
- });
2208
- const answerContext = Object.entries(answers).map(([k, v]) => `[${k}]: ${v}`).join("\n");
2209
- currentPrompt += `
2210
-
2211
- [User Answers]:
2212
- ${answerContext}
2213
-
2214
- Please proceed with generation based on these answers.`;
2215
- logger.info("\u6B63\u5728\u6839\u636E\u60A8\u7684\u53CD\u9988\u91CD\u65B0\u547C\u53EB AI...");
2216
- continue;
2217
- }
2218
- }
2219
- console.log("\n" + stdout);
2220
- retry = false;
2221
- logger.success(`AI \u547D\u4EE4 [gemini ${geminiCmd}] \u6267\u884C\u5B8C\u6BD5!`);
2222
- } catch (error) {
2223
- spinner.stop();
2224
- if (error.code === "ENOENT") {
2225
- logger.error("\u672A\u5728\u7CFB\u7EDF\u4E2D\u627E\u5230 `gemini-cli` \u547D\u4EE4\u3002");
2226
- logger.info(pc9.yellow("\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 gemini-cli \u5E76\u5C06\u5176\u6DFB\u52A0\u5230\u7CFB\u7EDF PATH \u4E2D\u3002"));
2227
- } else {
2228
- logger.error(`AI \u751F\u6210\u8FC7\u7A0B\u4E2D\u51FA\u9519: ${error.message}`);
2229
- }
2230
- throw error;
2231
- }
2232
- }
2233
- }
2234
-
2235
- // src/index.ts
2236
- init_sync();
2237
-
2238
- // src/commands/doctor.ts
2239
- init_esm_shims();
2240
- init_utils();
2241
- init_sandbox();
2242
- init_corekit();
2243
- import fs14 from "fs-extra";
2244
- import path16 from "path";
2245
- import pc10 from "picocolors";
2246
- import glob from "fast-glob";
2247
- async function doctor(options = {}) {
2248
- logger.info("\u6B63\u5728\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5...\n");
2249
- const cwd = process.cwd();
2250
- let hasIssues = false;
2251
- const issues = [];
2252
- logger.info(pc10.bold("Step 1: \u68C0\u67E5\u57FA\u7840\u73AF\u5883..."));
2253
- const nodeVersion = process.version;
2254
- if (parseInt(nodeVersion.slice(1).split(".")[0]) < 18) {
2255
- logger.error(`Node.js \u7248\u672C\u592A\u4F4E: ${nodeVersion} (\u8981\u6C42 >=18)`);
2256
- hasIssues = true;
2257
- issues.push(`Node.js \u7248\u672C\u8FC7\u4F4E (${nodeVersion})`);
2258
- } else {
2259
- logger.success(`Node.js \u7248\u672C: ${nodeVersion}`);
2193
+ let hasIssues = false;
2194
+ const issues = [];
2195
+ logger.info(pc9.bold("Step 1: \u68C0\u67E5\u57FA\u7840\u73AF\u5883..."));
2196
+ const nodeVersion = process.version;
2197
+ if (parseInt(nodeVersion.slice(1).split(".")[0]) < 18) {
2198
+ logger.error(`Node.js \u7248\u672C\u592A\u4F4E: ${nodeVersion} (\u8981\u6C42 >=18)`);
2199
+ hasIssues = true;
2200
+ issues.push(`Node.js \u7248\u672C\u8FC7\u4F4E (${nodeVersion})`);
2201
+ } else {
2202
+ logger.success(`Node.js \u7248\u672C: ${nodeVersion}`);
2260
2203
  }
2261
2204
  try {
2262
2205
  const { execa: execa6 } = await import("execa");
@@ -2265,41 +2208,41 @@ async function doctor(options = {}) {
2265
2208
  } catch (e) {
2266
2209
  logger.warn("\u672A\u68C0\u6D4B\u5230 pnpm\uFF0C\u5EFA\u8BAE\u5B89\u88C5\u4EE5\u83B7\u5F97\u6700\u4F73\u4F53\u9A8C");
2267
2210
  }
2268
- logger.info(pc10.bold("\nStep 2: \u68C0\u67E5\u5185\u6838\u6C99\u7BB1\u73AF\u5883..."));
2211
+ logger.info(pc9.bold("\nStep 2: \u68C0\u67E5\u5185\u6838\u6C99\u7BB1\u73AF\u5883..."));
2269
2212
  const version = await CoreKit.resolveVersion(cwd);
2270
2213
  const versionPath = Sandbox.getVersionPath(version);
2271
- if (!fs14.existsSync(versionPath)) {
2214
+ if (!fs12.existsSync(versionPath)) {
2272
2215
  logger.error(`\u5185\u6838\u6C99\u7BB1\u7248\u672C ${version} \u5C1A\u672A\u5B89\u88C5`);
2273
- console.log(pc10.gray(` \u5EFA\u8BAE\u8FD0\u884C 'chatbi sync' \u6216 'chatbi use ${version}' \u8FDB\u884C\u5B89\u88C5\u3002`));
2216
+ console.log(pc9.gray(` \u5EFA\u8BAE\u8FD0\u884C 'chatbi sync' \u6216 'chatbi use ${version}' \u8FDB\u884C\u5B89\u88C5\u3002`));
2274
2217
  hasIssues = true;
2275
2218
  issues.push(`\u5185\u6838\u6C99\u7BB1\u672A\u5B89\u88C5 (${version})`);
2276
2219
  } else {
2277
2220
  logger.success(`\u5185\u6838\u6C99\u7BB1\u5C31\u7EEA (\u7248\u672C: ${version})`);
2278
- const sandboxNm = path16.join(versionPath, "node_modules");
2279
- if (!fs14.existsSync(sandboxNm)) {
2221
+ const sandboxNm = path14.join(versionPath, "node_modules");
2222
+ if (!fs12.existsSync(sandboxNm)) {
2280
2223
  logger.warn("\u6C99\u7BB1\u4F9D\u8D56\u672A\u5B89\u88C5\uFF0C\u5C06\u5BFC\u81F4\u6784\u5EFA\u5931\u8D25");
2281
2224
  hasIssues = true;
2282
2225
  issues.push("\u6C99\u7BB1\u4F9D\u8D56\u7F3A\u5931");
2283
2226
  }
2284
2227
  const missingDeps = [];
2285
2228
  for (const dep of Sandbox.CORE_PACKAGES) {
2286
- if (!fs14.existsSync(path16.join(sandboxNm, dep))) {
2229
+ if (!fs12.existsSync(path14.join(sandboxNm, dep))) {
2287
2230
  missingDeps.push(dep);
2288
2231
  }
2289
2232
  }
2290
2233
  if (missingDeps.length > 0) {
2291
2234
  }
2292
2235
  }
2293
- logger.info(pc10.bold("\nStep 3: \u68C0\u67E5\u865A\u62DF\u4F9D\u8D56\u6620\u5C04..."));
2294
- const chatbiDir = path16.join(cwd, ".chatbi");
2295
- if (!fs14.existsSync(chatbiDir)) {
2236
+ logger.info(pc9.bold("\nStep 3: \u68C0\u67E5\u865A\u62DF\u4F9D\u8D56\u6620\u5C04..."));
2237
+ const chatbiDir = path14.join(cwd, ".chatbi");
2238
+ if (!fs12.existsSync(chatbiDir)) {
2296
2239
  logger.warn("\u672A\u53D1\u73B0\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E (.chatbi \u76EE\u5F55)");
2297
2240
  hasIssues = true;
2298
2241
  issues.push("\u7F3A\u5931 .chatbi \u76EE\u5F55");
2299
2242
  } else {
2300
- const pathsJson = path16.join(chatbiDir, "tsconfig.paths.json");
2301
- const aliasJson = path16.join(chatbiDir, "vite.alias.json");
2302
- if (!fs14.existsSync(pathsJson) || !fs14.existsSync(aliasJson)) {
2243
+ const pathsJson = path14.join(chatbiDir, "tsconfig.paths.json");
2244
+ const aliasJson = path14.join(chatbiDir, "vite.alias.json");
2245
+ if (!fs12.existsSync(pathsJson) || !fs12.existsSync(aliasJson)) {
2303
2246
  logger.warn("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B8C\u6574");
2304
2247
  hasIssues = true;
2305
2248
  issues.push("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u4E0D\u5B8C\u6574");
@@ -2307,10 +2250,10 @@ async function doctor(options = {}) {
2307
2250
  logger.success("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u5DF2\u751F\u6210");
2308
2251
  }
2309
2252
  }
2310
- const tsConfigPath = path16.join(cwd, "tsconfig.json");
2311
- if (fs14.existsSync(tsConfigPath)) {
2253
+ const tsConfigPath = path14.join(cwd, "tsconfig.json");
2254
+ if (fs12.existsSync(tsConfigPath)) {
2312
2255
  try {
2313
- const tsConfig = await fs14.readJson(tsConfigPath);
2256
+ const tsConfig = await fs12.readJson(tsConfigPath);
2314
2257
  const extendsPath = tsConfig.extends;
2315
2258
  const expectedPaths = ["./.chatbi/tsconfig.paths.json", ".chatbi/tsconfig.paths.json"];
2316
2259
  let hasExtend = false;
@@ -2330,14 +2273,14 @@ async function doctor(options = {}) {
2330
2273
  logger.error("\u89E3\u6790 tsconfig.json \u5931\u8D25");
2331
2274
  }
2332
2275
  }
2333
- const viteConfigPath = path16.join(cwd, "vite.config.ts");
2334
- if (fs14.existsSync(viteConfigPath)) {
2335
- const content = await fs14.readFile(viteConfigPath, "utf-8");
2276
+ const viteConfigPath = path14.join(cwd, "vite.config.ts");
2277
+ if (fs12.existsSync(viteConfigPath)) {
2278
+ const content = await fs12.readFile(viteConfigPath, "utf-8");
2336
2279
  if (!content.includes("vite.alias.json")) {
2337
2280
  logger.warn("vite.config.ts \u53EF\u80FD\u672A\u52A0\u8F7D\u865A\u62DF\u522B\u540D\u914D\u7F6E");
2338
2281
  }
2339
2282
  }
2340
- logger.info(pc10.bold("\nStep 4: \u626B\u63CF\u4EE3\u7801\u89C4\u5219..."));
2283
+ logger.info(pc9.bold("\nStep 4: \u626B\u63CF\u4EE3\u7801\u89C4\u5219..."));
2341
2284
  const rules = [
2342
2285
  {
2343
2286
  id: "plugin-lifecycle-init",
@@ -2357,7 +2300,7 @@ async function doctor(options = {}) {
2357
2300
  if (files.length > 0) {
2358
2301
  const scanSpinner = createSpinner(`\u6B63\u5728\u626B\u63CF ${files.length} \u4E2A\u6587\u4EF6...`).start();
2359
2302
  for (const file of files) {
2360
- const content = await fs14.readFile(file, "utf-8");
2303
+ const content = await fs12.readFile(file, "utf-8");
2361
2304
  for (const rule of rules) {
2362
2305
  if (rule.pattern.test(content)) {
2363
2306
  codeIssues.push({
@@ -2373,7 +2316,7 @@ async function doctor(options = {}) {
2373
2316
  scanSpinner.fail(`\u53D1\u73B0 ${codeIssues.length} \u4E2A\u4EE3\u7801\u89C4\u8303\u95EE\u9898`);
2374
2317
  hasIssues = true;
2375
2318
  codeIssues.forEach((issue) => {
2376
- const relativePath = path16.relative(cwd, issue.file);
2319
+ const relativePath = path14.relative(cwd, issue.file);
2377
2320
  issues.push(`\u4EE3\u7801\u89C4\u8303 [${issue.ruleId}]: ${relativePath}`);
2378
2321
  });
2379
2322
  } else {
@@ -2382,26 +2325,26 @@ async function doctor(options = {}) {
2382
2325
  }
2383
2326
  if (!hasIssues) {
2384
2327
  printBox(
2385
- pc10.green(pc10.bold("\u2728 \u8BCA\u65AD\u5B8C\u6210\uFF1A\u9879\u76EE\u4E00\u5207\u6B63\u5E38\uFF01")),
2328
+ pc9.green(pc9.bold("\u2728 \u8BCA\u65AD\u5B8C\u6210\uFF1A\u9879\u76EE\u4E00\u5207\u6B63\u5E38\uFF01")),
2386
2329
  "Doctor Report"
2387
2330
  );
2388
2331
  } else {
2389
- const issueList = issues.map((i) => pc10.red(`\u2022 ${i}`)).join("\n");
2332
+ const issueList = issues.map((i) => pc9.red(`\u2022 ${i}`)).join("\n");
2390
2333
  printBox(
2391
- `${pc10.yellow(pc10.bold("\u26A0\uFE0F \u8BCA\u65AD\u5B8C\u6210\uFF1A\u53D1\u73B0\u4EE5\u4E0B\u95EE\u9898"))}
2334
+ `${pc9.yellow(pc9.bold("\u26A0\uFE0F \u8BCA\u65AD\u5B8C\u6210\uFF1A\u53D1\u73B0\u4EE5\u4E0B\u95EE\u9898"))}
2392
2335
 
2393
2336
  ${issueList}
2394
2337
 
2395
- ${pc10.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
2338
+ ${pc9.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
2396
2339
  "Doctor Report"
2397
2340
  );
2398
2341
  if (options.fix) {
2399
2342
  if (codeIssues.length > 0) {
2400
2343
  const fixSpinner = createSpinner("\u6B63\u5728\u4FEE\u590D\u4EE3\u7801\u89C4\u8303\u95EE\u9898...").start();
2401
2344
  for (const issue of codeIssues) {
2402
- const content = await fs14.readFile(issue.file, "utf-8");
2345
+ const content = await fs12.readFile(issue.file, "utf-8");
2403
2346
  const newContent = issue.rule.fix(content);
2404
- await fs14.writeFile(issue.file, newContent);
2347
+ await fs12.writeFile(issue.file, newContent);
2405
2348
  }
2406
2349
  fixSpinner.succeed("\u4EE3\u7801\u4FEE\u590D\u5B8C\u6210");
2407
2350
  }
@@ -2413,28 +2356,198 @@ ${pc10.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
2413
2356
  }
2414
2357
  }
2415
2358
 
2416
- // src/commands/discover.ts
2359
+ // src/index.ts
2360
+ init_fetch();
2361
+
2362
+ // src/commands/gl.ts
2417
2363
  init_esm_shims();
2418
- init_corekit();
2419
2364
  init_utils();
2365
+ import { execa as execa4 } from "execa";
2366
+ import fs13 from "fs-extra";
2367
+ import path16 from "path";
2420
2368
  import pc11 from "picocolors";
2421
- async function discover() {
2369
+ import prompts3 from "prompts";
2370
+ async function gl(options) {
2371
+ const { type: initialType, prompt: initialPrompt } = options;
2422
2372
  const cwd = process.cwd();
2423
- const spinner = createSpinner("\u6B63\u5728\u626B\u63CF\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6...").start();
2424
- const plugins = await CoreKit.discoverPlugins(cwd);
2425
- if (plugins.length === 0) {
2426
- spinner.warn("\u672A\u53D1\u73B0\u4EFB\u4F55\u63D2\u4EF6");
2427
- logger.info(pc11.gray("\u8BF7\u786E\u4FDD\u63D2\u4EF6\u4F4D\u4E8E plugins/ \u76EE\u5F55\u4E0B\uFF0C\u4E14\u5305\u542B package.json\u3002"));
2428
- } else {
2429
- spinner.succeed(`\u53D1\u73B0\u4E86 ${pc11.cyan(plugins.length)} \u4E2A\u63D2\u4EF6`);
2430
- const pluginList = plugins.map((p) => `- ${pc11.bold(p.name)} ${pc11.gray(`(${p.id})`)}
2431
- ${pc11.gray(p.path)}`).join("\n\n");
2432
- printBox(
2433
- `${pc11.green(pc11.bold("\u2728 \u63D2\u4EF6\u626B\u63CF\u7ED3\u679C"))}
2373
+ const pkgPath = path16.join(cwd, "package.json");
2374
+ if (!fs13.existsSync(pkgPath)) {
2375
+ logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
2376
+ return;
2377
+ }
2378
+ const response = await prompts3([
2379
+ {
2380
+ type: initialType ? null : "select",
2381
+ name: "genType",
2382
+ message: "\u8BF7\u9009\u62E9 AI \u811A\u624B\u67B6\u6307\u4EE4:",
2383
+ choices: [
2384
+ { title: "\u{1F916} smart", value: "smart", description: "\u667A\u80FD\u51B3\u7B56 (\u6839\u636E\u9700\u6C42\u81EA\u52A8\u9009\u62E9\u5DE5\u5177)" },
2385
+ { title: "\u{1F50C} plugin", value: "plugin", description: "\u751F\u6210\u65B0\u63D2\u4EF6" },
2386
+ { title: "\u{1F9E9} component", value: "component", description: "\u751F\u6210\u4E1A\u52A1\u7EC4\u4EF6" },
2387
+ { title: "\u{1F4E1} api", value: "api", description: "\u751F\u6210 API \u5B9A\u4E49\u4E0E\u8BF7\u6C42\u51FD\u6570" },
2388
+ { title: "\u{1F3AD} mock", value: "mock", description: "\u751F\u6210 Mock \u6D4B\u8BD5\u6570\u636E" },
2389
+ { title: "\u{1F6E0}\uFE0F util", value: "util", description: "\u751F\u6210\u5DE5\u5177\u51FD\u6570" },
2390
+ { title: "\u{1F4C4} doc", value: "doc", description: "\u751F\u6210\u9879\u76EE\u6587\u6863" },
2391
+ { title: "\u2728 chat", value: "chat", description: "\u81EA\u7531\u5BF9\u8BDD" }
2392
+ ],
2393
+ initial: 0
2394
+ },
2395
+ {
2396
+ type: (prev, values) => initialPrompt || values.genType === "chat" ? null : "text",
2397
+ name: "userPrompt",
2398
+ message: "\u8BF7\u8F93\u5165\u8BE6\u7EC6\u9700\u6C42\u63CF\u8FF0:",
2399
+ initial: initialPrompt || ""
2400
+ }
2401
+ ], {
2402
+ onCancel: () => {
2403
+ logger.warn("\u5DF2\u53D6\u6D88 AI \u751F\u6210");
2404
+ process.exit(0);
2405
+ }
2406
+ });
2407
+ const genType = initialType || response.genType;
2408
+ const userPrompt = initialPrompt || response.userPrompt;
2409
+ if (!userPrompt && genType !== "chat") {
2410
+ logger.error("\u9700\u6C42\u63CF\u8FF0\u4E0D\u80FD\u4E3A\u7A7A\u3002");
2411
+ return;
2412
+ }
2413
+ logger.info(`\u6B63\u5728\u547C\u53EB AI \u5F15\u64CE [\u6A21\u5F0F: ${pc11.bold(genType)}]...`);
2414
+ const toolsContext = `
2415
+ [Available Tools & Capabilities]
2416
+ - Tool: plugin -> For creating new feature modules. Requires: name, type (business|system).
2417
+ - Tool: component -> For UI elements. Tech: AntD5, Tailwind.
2418
+ - Tool: api -> For network requests. Structure: src/api/[name].ts, uses shared request util, defines TS interfaces.
2419
+ - Tool: mock -> For dev data. Structure: mock/[name].ts, follows Mock.js or MSW format.
2420
+ - Tool: util -> For pure functions. Structure: src/utils/[name].ts, requires unit tests.
2421
+ - Tool: doc -> For documentation. Format: Markdown, structure: docs/[type]/[name].md.
2434
2422
 
2435
- ${pluginList}`,
2436
- "Plugin Discovery"
2437
- );
2423
+ [Tool Functions Implementation Details]
2424
+ - API Function: Should include request method, URL, params/data types, and response type. Use '@chatbi-v/core/request'.
2425
+ - Mock Function: Should provide realistic data based on API definition.
2426
+ - Plugin Function: Should follow the Micro-Kernel architecture, registering to 'pluginManager'.
2427
+
2428
+ [Requirement Slots / Missing Info]
2429
+ If the user's request is ambiguous or missing key information, you MUST output: "SLOT_REQUIRED: [Field Name] | [Question to User]".
2430
+ `.trim();
2431
+ const templatesContext = `
2432
+ [Project Templates Structure]
2433
+ - Plugin: class extends Plugin, metadata: { id, name, version, type, routes, extensions }.
2434
+ - API: export const fetchData = (params: T) => request.get<R>('/url', { params }).
2435
+ - Mock: export default { 'GET /api/test': { code: 200, data: {} } }.
2436
+ - UI: React 18, Ant Design 5, Tailwind CSS 3.
2437
+ `.trim();
2438
+ const systemContext = `[Context: ChatBI-V System | Dir: ${cwd} | Tech: React18, AntD5, Tailwind, Micro-Kernel]
2439
+ ${toolsContext}
2440
+ ${templatesContext}
2441
+
2442
+ [Decision Logic]
2443
+ If genType is 'smart', you must first decide which tool is most appropriate.
2444
+ If the requirement is clear, proceed with generation.
2445
+ If not, use the SLOT_REQUIRED format.`.trim();
2446
+ const finalPrompt = userPrompt ? `${systemContext}
2447
+
2448
+ [User Request]: ${userPrompt}` : systemContext;
2449
+ const geminiCmd = genType === "smart" ? "chat" : genType;
2450
+ const spinner = createSpinner("AI \u5F15\u64CE\u6B63\u5728\u601D\u8003\u4E2D... (\u53EF\u80FD\u9700\u8981\u51E0\u5341\u79D2\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85)");
2451
+ let currentPrompt = finalPrompt;
2452
+ let retry = true;
2453
+ while (retry) {
2454
+ spinner.start();
2455
+ try {
2456
+ const { stdout } = await execa4("gemini", [geminiCmd, currentPrompt], {
2457
+ stdio: "pipe"
2458
+ });
2459
+ spinner.stop();
2460
+ if (stdout.includes("SLOT_REQUIRED:")) {
2461
+ const slots = [];
2462
+ const lines = stdout.split("\n");
2463
+ for (const line of lines) {
2464
+ if (line.includes("SLOT_REQUIRED:")) {
2465
+ const match = line.match(/SLOT_REQUIRED:\s*([^|]+)\|\s*(.+)/);
2466
+ if (match) {
2467
+ slots.push({
2468
+ type: "text",
2469
+ name: match[1].trim(),
2470
+ message: match[2].trim()
2471
+ });
2472
+ }
2473
+ }
2474
+ }
2475
+ if (slots.length > 0) {
2476
+ logger.info(pc11.yellow("\n\u{1F4DD} AI \u9700\u8981\u66F4\u591A\u4FE1\u606F\u4EE5\u7EE7\u7EED:"));
2477
+ const answers = await prompts3(slots, {
2478
+ onCancel: () => process.exit(0)
2479
+ });
2480
+ const answerContext = Object.entries(answers).map(([k, v]) => `[${k}]: ${v}`).join("\n");
2481
+ currentPrompt += `
2482
+
2483
+ [User Answers]:
2484
+ ${answerContext}
2485
+
2486
+ Please proceed with generation based on these answers.`;
2487
+ logger.info("\u6B63\u5728\u6839\u636E\u60A8\u7684\u53CD\u9988\u91CD\u65B0\u547C\u53EB AI...");
2488
+ continue;
2489
+ }
2490
+ }
2491
+ console.log("\n" + stdout);
2492
+ retry = false;
2493
+ logger.success(`AI \u547D\u4EE4 [gemini ${geminiCmd}] \u6267\u884C\u5B8C\u6BD5!`);
2494
+ } catch (error) {
2495
+ spinner.stop();
2496
+ if (error.code === "ENOENT") {
2497
+ logger.error("\u672A\u5728\u7CFB\u7EDF\u4E2D\u627E\u5230 `gemini-cli` \u547D\u4EE4\u3002");
2498
+ logger.info(pc11.yellow("\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 gemini-cli \u5E76\u5C06\u5176\u6DFB\u52A0\u5230\u7CFB\u7EDF PATH \u4E2D\u3002"));
2499
+ } else {
2500
+ logger.error(`AI \u751F\u6210\u8FC7\u7A0B\u4E2D\u51FA\u9519: ${error.message}`);
2501
+ }
2502
+ throw error;
2503
+ }
2504
+ }
2505
+ }
2506
+
2507
+ // src/index.ts
2508
+ init_init();
2509
+
2510
+ // src/commands/install.ts
2511
+ init_esm_shims();
2512
+ init_sandbox();
2513
+ init_utils();
2514
+ import { execa as execa5 } from "execa";
2515
+ import fs15 from "fs-extra";
2516
+ import path18 from "path";
2517
+ import pc13 from "picocolors";
2518
+ async function install(target) {
2519
+ if (target.endsWith(".tgz") && fs15.existsSync(target)) {
2520
+ const spinner = createSpinner(`\u6B63\u5728\u5B89\u88C5\u672C\u5730\u79BB\u7EBF\u5305: ${pc13.bold(target)}...`).start();
2521
+ try {
2522
+ const tgzPath = path18.resolve(target);
2523
+ const match = path18.basename(target).match(/chatbi-core-(.+)\.tgz/);
2524
+ let version = "unknown";
2525
+ if (match) {
2526
+ version = match[1];
2527
+ }
2528
+ if (version === "unknown") {
2529
+ 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");
2530
+ version = `local-${Date.now()}`;
2531
+ }
2532
+ const versionRoot = Sandbox.getVersionRoot();
2533
+ await fs15.ensureDir(versionRoot);
2534
+ spinner.text = "\u6B63\u5728\u89E3\u538B\u6587\u4EF6...";
2535
+ await execa5("tar", ["-xzf", tgzPath, "-C", versionRoot]);
2536
+ spinner.succeed(`\u672C\u5730\u5305\u5DF2\u5B89\u88C5\u81F3\u6C99\u7BB1: ${version}`);
2537
+ spinner.text = "\u6B63\u5728\u51C6\u5907\u5185\u6838\u73AF\u5883...";
2538
+ await Sandbox.prepare(version);
2539
+ spinner.succeed("\u5185\u6838\u73AF\u5883\u5C31\u7EEA");
2540
+ printBox(
2541
+ 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)),
2542
+ "Install Success"
2543
+ );
2544
+ } catch (e) {
2545
+ spinner.fail("\u5B89\u88C5\u5931\u8D25");
2546
+ throw e;
2547
+ }
2548
+ } else {
2549
+ const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
2550
+ await fetch2(target);
2438
2551
  }
2439
2552
  }
2440
2553
 
@@ -2443,7 +2556,7 @@ init_esm_shims();
2443
2556
  init_corekit();
2444
2557
  init_sandbox();
2445
2558
  init_utils();
2446
- import pc12 from "picocolors";
2559
+ import pc14 from "picocolors";
2447
2560
  async function ls() {
2448
2561
  const versions = await CoreKit.listVersions();
2449
2562
  const currentVersion = await CoreKit.resolveVersion(process.cwd());
@@ -2457,36 +2570,39 @@ async function ls() {
2457
2570
  const isProjectCurrent = v === currentVersion;
2458
2571
  let prefix = " ";
2459
2572
  if (isProjectCurrent) {
2460
- prefix = pc12.green(" *");
2573
+ prefix = pc14.green(" *");
2461
2574
  } else if (isGlobalCurrent) {
2462
- prefix = pc12.blue(" >");
2575
+ prefix = pc14.blue(" >");
2463
2576
  }
2464
2577
  let suffix = "";
2465
2578
  if (isProjectCurrent && isGlobalCurrent) {
2466
- suffix = pc12.gray(" (\u5F53\u524D\u9879\u76EE & \u5168\u5C40)");
2579
+ suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE & \u5168\u5C40)");
2467
2580
  } else if (isProjectCurrent) {
2468
- suffix = pc12.gray(" (\u5F53\u524D\u9879\u76EE)");
2581
+ suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE)");
2469
2582
  } else if (isGlobalCurrent) {
2470
- suffix = pc12.gray(" (\u5168\u5C40)");
2583
+ suffix = pc14.gray(" (\u5168\u5C40)");
2471
2584
  }
2472
- return `${prefix} ${pc12.white(v)}${suffix}`;
2585
+ return `${prefix} ${pc14.white(v)}${suffix}`;
2473
2586
  }).join("\n");
2474
2587
  printBox(
2475
- list + pc12.gray("\n\n\u63D0\u793A: * \u5F53\u524D\u9879\u76EE\u4F7F\u7528, > \u5168\u5C40\u9ED8\u8BA4\u4F7F\u7528"),
2588
+ list + pc14.gray("\n\n\u63D0\u793A: * \u5F53\u524D\u9879\u76EE\u4F7F\u7528, > \u5168\u5C40\u9ED8\u8BA4\u4F7F\u7528"),
2476
2589
  "Kernel Versions"
2477
2590
  );
2478
2591
  }
2479
2592
  await Sandbox.visualizeStatus(process.cwd());
2480
2593
  }
2481
2594
 
2595
+ // src/index.ts
2596
+ init_sync();
2597
+
2482
2598
  // src/commands/use.ts
2483
2599
  init_esm_shims();
2484
- init_sandbox();
2485
2600
  init_corekit();
2486
- init_sync();
2601
+ init_sandbox();
2487
2602
  init_utils();
2488
- import fs15 from "fs-extra";
2489
- import path17 from "path";
2603
+ init_sync();
2604
+ import fs16 from "fs-extra";
2605
+ import path19 from "path";
2490
2606
  async function use(version, options = {}) {
2491
2607
  const versions = await CoreKit.listVersions();
2492
2608
  if (!versions.includes(version)) {
@@ -2498,123 +2614,13 @@ async function use(version, options = {}) {
2498
2614
  logger.success(`\u5DF2\u5207\u6362\u5168\u5C40\u5185\u6838\u7248\u672C\u81F3: ${version}`);
2499
2615
  } else {
2500
2616
  const cwd = process.cwd();
2501
- const versionFilePath = path17.join(cwd, ".chatbi-version");
2502
- await fs15.writeFile(versionFilePath, version, "utf-8");
2617
+ const versionFilePath = path19.join(cwd, ".chatbi-version");
2618
+ await fs16.writeFile(versionFilePath, version, "utf-8");
2503
2619
  logger.success(`\u5DF2\u5207\u6362\u5F53\u524D\u9879\u76EE\u5185\u6838\u7248\u672C\u4E3A: ${version}`);
2504
2620
  }
2505
2621
  await sync({ version, force: false });
2506
2622
  }
2507
2623
 
2508
- // src/index.ts
2509
- init_fetch();
2510
-
2511
- // src/commands/install.ts
2512
- init_esm_shims();
2513
- init_sandbox();
2514
- init_utils();
2515
- import fs16 from "fs-extra";
2516
- import path19 from "path";
2517
- import pc14 from "picocolors";
2518
- import { execa as execa5 } from "execa";
2519
- async function install(target) {
2520
- if (target.endsWith(".tgz") && fs16.existsSync(target)) {
2521
- const spinner = createSpinner(`\u6B63\u5728\u5B89\u88C5\u672C\u5730\u79BB\u7EBF\u5305: ${pc14.bold(target)}...`).start();
2522
- try {
2523
- const tgzPath = path19.resolve(target);
2524
- const match = path19.basename(target).match(/chatbi-core-(.+)\.tgz/);
2525
- let version = "unknown";
2526
- if (match) {
2527
- version = match[1];
2528
- }
2529
- if (version === "unknown") {
2530
- 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");
2531
- version = `local-${Date.now()}`;
2532
- }
2533
- const versionRoot = Sandbox.getVersionRoot();
2534
- await fs16.ensureDir(versionRoot);
2535
- spinner.text = "\u6B63\u5728\u89E3\u538B\u6587\u4EF6...";
2536
- await execa5("tar", ["-xzf", tgzPath, "-C", versionRoot]);
2537
- spinner.succeed(`\u672C\u5730\u5305\u5DF2\u5B89\u88C5\u81F3\u6C99\u7BB1: ${version}`);
2538
- spinner.text = "\u6B63\u5728\u51C6\u5907\u5185\u6838\u73AF\u5883...";
2539
- await Sandbox.prepare(version);
2540
- spinner.succeed("\u5185\u6838\u73AF\u5883\u5C31\u7EEA");
2541
- printBox(
2542
- pc14.green(pc14.bold("\u2728 \u672C\u5730\u5185\u6838\u5B89\u88C5\u6210\u529F!")) + "\n\n" + pc14.white("\u7248\u672C: ") + pc14.cyan(version) + "\n" + pc14.white("\u8DEF\u5F84: ") + pc14.gray(Sandbox.getVersionPath(version)),
2543
- "Install Success"
2544
- );
2545
- } catch (e) {
2546
- spinner.fail("\u5B89\u88C5\u5931\u8D25");
2547
- throw e;
2548
- }
2549
- } else {
2550
- const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
2551
- await fetch2(target);
2552
- }
2553
- }
2554
-
2555
- // src/commands/clean.ts
2556
- init_esm_shims();
2557
- init_sandbox();
2558
- async function clean(options) {
2559
- const cwd = process.cwd();
2560
- await Sandbox.clean(cwd, options.deep);
2561
- }
2562
-
2563
- // package.json
2564
- var package_default = {
2565
- name: "@chatbi-v/cli",
2566
- version: "2.1.6",
2567
- description: "Standardized CLI tooling for ChatBI Monorepo",
2568
- type: "module",
2569
- main: "dist/index.js",
2570
- module: "dist/index.js",
2571
- types: "dist/index.d.ts",
2572
- bin: {
2573
- "chatbi-cli": "./bin/chatbi-cli.js"
2574
- },
2575
- files: [
2576
- "dist",
2577
- "bin",
2578
- "templates"
2579
- ],
2580
- publishConfig: {
2581
- access: "public"
2582
- },
2583
- scripts: {
2584
- build: "tsup",
2585
- dev: "tsup --watch",
2586
- test: "vitest"
2587
- },
2588
- dependencies: {
2589
- boxen: "^8.0.1",
2590
- cac: "^6.7.14",
2591
- execa: "^8.0.1",
2592
- "fast-glob": "^3.3.3",
2593
- figlet: "^1.9.4",
2594
- "fs-extra": "^11.2.0",
2595
- "gradient-string": "^3.0.0",
2596
- handlebars: "^4.7.8",
2597
- jiti: "^2.6.1",
2598
- ora: "^7.0.1",
2599
- picocolors: "^1.0.0",
2600
- prompts: "^2.4.2",
2601
- tsup: "^8.5.1",
2602
- typescript: "^5.0.0",
2603
- vite: "^5.4.21"
2604
- },
2605
- devDependencies: {
2606
- "@types/boxen": "^3.0.5",
2607
- "@types/figlet": "^1.7.0",
2608
- "@types/fs-extra": "^11.0.0",
2609
- "@types/gradient-string": "^1.1.6",
2610
- "@types/node": "^20.0.0",
2611
- "@types/prompts": "^2.4.9",
2612
- "@vitest/coverage-v8": "1.6.1",
2613
- tsup: "^8.5.1",
2614
- vitest: "^1.0.0"
2615
- }
2616
- };
2617
-
2618
2624
  // src/index.ts
2619
2625
  init_utils();
2620
2626
  var cli = cac("chatbi-cli");