@chatbi-v/cli 2.1.6 → 2.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +990 -912
- package/package.json +8 -1
- package/templates/app/.env.hbs +1 -1
- package/templates/app/README.md.hbs +1 -1
- package/templates/app/package.json.hbs +4 -7
- package/templates/app/postcss.config.js.hbs +14 -0
- package/templates/app/src/hooks/usePluginLoader.ts.hbs +3 -3
- package/templates/app/src/services/config-service.ts.hbs +1 -1
- package/templates/app/src/stores/useUIStore.ts.hbs +1 -1
- package/templates/app/{tailwind.config.cjs.hbs → tailwind.config.js.hbs} +7 -4
- package/templates/monorepo/package.json.hbs +7 -3
- package/templates/monorepo/pnpm-workspace.yaml.hbs +2 -2
- package/templates/monorepo/tsconfig.json.hbs +1 -1
- package/templates/plugin/README.md.hbs +1 -1
- package/templates/plugin/package.json.hbs +3 -3
- package/templates/app/postcss.config.cjs.hbs +0 -10
- /package/templates/app/{chatbi.config.ts.hbs → app.config.ts.hbs} +0 -0
package/dist/index.js
CHANGED
|
@@ -8,31 +8,94 @@ var __export = (target, all) => {
|
|
|
8
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
-
//
|
|
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
|
-
"
|
|
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/
|
|
20
|
+
// src/constants.ts
|
|
21
|
+
import os from "os";
|
|
21
22
|
import path2 from "path";
|
|
22
|
-
|
|
23
|
-
|
|
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";
|
|
80
|
+
import { execa } from "execa";
|
|
24
81
|
import fs from "fs-extra";
|
|
25
|
-
import
|
|
82
|
+
import { createRequire } from "module";
|
|
83
|
+
import os2 from "os";
|
|
26
84
|
import ora from "ora";
|
|
27
|
-
import
|
|
28
|
-
|
|
85
|
+
import path3 from "path";
|
|
86
|
+
import pc from "picocolors";
|
|
87
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
88
|
+
var _require, _filename, _dirname, UPDATE_CHECK_INTERVAL, CACHE_DIR, CACHE_FILE, logger, createSpinner, printBox, findPackageRoot, getCliRoot, checkForUpdates, printUpdateNotification;
|
|
29
89
|
var init_utils = __esm({
|
|
30
90
|
"src/utils.ts"() {
|
|
31
91
|
"use strict";
|
|
32
92
|
init_esm_shims();
|
|
33
93
|
_require = createRequire(import.meta.url);
|
|
34
94
|
_filename = fileURLToPath2(import.meta.url);
|
|
35
|
-
_dirname =
|
|
95
|
+
_dirname = path3.dirname(_filename);
|
|
96
|
+
UPDATE_CHECK_INTERVAL = 1e3 * 60 * 60 * 24;
|
|
97
|
+
CACHE_DIR = path3.join(os2.homedir(), ".chatbi-v-core");
|
|
98
|
+
CACHE_FILE = path3.join(CACHE_DIR, ".update-check.json");
|
|
36
99
|
logger = {
|
|
37
100
|
info: (msg) => console.log(pc.cyan(`\u2139 ${msg}`)),
|
|
38
101
|
success: (msg) => console.log(pc.green(`\u2714 ${msg}`)),
|
|
@@ -72,10 +135,10 @@ var init_utils = __esm({
|
|
|
72
135
|
findPackageRoot = (pkgName) => {
|
|
73
136
|
try {
|
|
74
137
|
const pkgPath = _require.resolve(`${pkgName}/package.json`);
|
|
75
|
-
return
|
|
138
|
+
return path3.dirname(pkgPath);
|
|
76
139
|
} catch (e) {
|
|
77
140
|
if (pkgName === "@chatbi-v/cli") {
|
|
78
|
-
return
|
|
141
|
+
return path3.resolve(_dirname, "../../");
|
|
79
142
|
}
|
|
80
143
|
throw new Error(`Package ${pkgName} not found`);
|
|
81
144
|
}
|
|
@@ -83,147 +146,179 @@ var init_utils = __esm({
|
|
|
83
146
|
getCliRoot = async () => {
|
|
84
147
|
let myCliRoot = "";
|
|
85
148
|
let checkDir = _dirname;
|
|
86
|
-
while (checkDir !==
|
|
87
|
-
if (fs.existsSync(
|
|
88
|
-
const pkg = await fs.readJson(
|
|
149
|
+
while (checkDir !== path3.parse(checkDir).root) {
|
|
150
|
+
if (fs.existsSync(path3.join(checkDir, "package.json"))) {
|
|
151
|
+
const pkg = await fs.readJson(path3.join(checkDir, "package.json"));
|
|
89
152
|
if (pkg.name === "@chatbi-v/cli") {
|
|
90
153
|
myCliRoot = checkDir;
|
|
91
154
|
break;
|
|
92
155
|
}
|
|
93
156
|
}
|
|
94
|
-
checkDir =
|
|
157
|
+
checkDir = path3.dirname(checkDir);
|
|
95
158
|
}
|
|
96
159
|
if (!myCliRoot) {
|
|
97
160
|
myCliRoot = findPackageRoot("@chatbi-v/cli") || "";
|
|
98
161
|
}
|
|
99
162
|
return myCliRoot;
|
|
100
163
|
};
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
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"
|
|
164
|
+
checkForUpdates = async (currentVersion) => {
|
|
165
|
+
try {
|
|
166
|
+
await fs.ensureDir(CACHE_DIR);
|
|
167
|
+
let cache = { lastCheck: 0, latestVersion: currentVersion };
|
|
168
|
+
if (fs.existsSync(CACHE_FILE)) {
|
|
169
|
+
cache = await fs.readJson(CACHE_FILE);
|
|
170
|
+
}
|
|
171
|
+
const now = Date.now();
|
|
172
|
+
if (now - cache.lastCheck > UPDATE_CHECK_INTERVAL) {
|
|
173
|
+
execa("npm", ["view", "@chatbi-v/cli", "version"]).then(async ({ stdout }) => {
|
|
174
|
+
const latest = stdout.trim();
|
|
175
|
+
await fs.writeJson(CACHE_FILE, {
|
|
176
|
+
lastCheck: now,
|
|
177
|
+
latestVersion: latest
|
|
178
|
+
});
|
|
179
|
+
}).catch(() => {
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
if (cache.latestVersion && cache.latestVersion !== currentVersion) {
|
|
183
|
+
const isNewer = cache.latestVersion.localeCompare(currentVersion, void 0, { numeric: true }) > 0;
|
|
184
|
+
if (isNewer) {
|
|
185
|
+
return cache.latestVersion;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
} catch (e) {
|
|
189
|
+
}
|
|
190
|
+
return null;
|
|
147
191
|
};
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
192
|
+
printUpdateNotification = (current, latest) => {
|
|
193
|
+
const message = `\u66F4\u65B0\u53EF\u7528 ${pc.gray(current)} \u2192 ${pc.green(latest)}
|
|
194
|
+
\u8FD0\u884C ${pc.cyan("npm install -g @chatbi-v/cli")} \u5373\u53EF\u66F4\u65B0`;
|
|
195
|
+
console.log(
|
|
196
|
+
boxen(message, {
|
|
197
|
+
padding: 1,
|
|
198
|
+
margin: { top: 1, bottom: 1 },
|
|
199
|
+
align: "center",
|
|
200
|
+
borderColor: "yellow",
|
|
201
|
+
borderStyle: "round"
|
|
202
|
+
})
|
|
203
|
+
);
|
|
158
204
|
};
|
|
159
205
|
}
|
|
160
206
|
});
|
|
161
207
|
|
|
162
|
-
// src/
|
|
163
|
-
import path4 from "path";
|
|
208
|
+
// src/config.ts
|
|
164
209
|
import fs2 from "fs-extra";
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
210
|
+
import { createJiti } from "jiti";
|
|
211
|
+
import path4 from "path";
|
|
212
|
+
var ConfigManager;
|
|
213
|
+
var init_config = __esm({
|
|
214
|
+
"src/config.ts"() {
|
|
168
215
|
"use strict";
|
|
169
216
|
init_esm_shims();
|
|
170
217
|
init_constants();
|
|
171
|
-
|
|
218
|
+
init_utils();
|
|
219
|
+
init_utils();
|
|
220
|
+
ConfigManager = class {
|
|
172
221
|
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;
|
|
222
|
+
this.CONFIG_FILES = DEFAULT_CONFIG.CONFIG_FILES;
|
|
184
223
|
}
|
|
185
224
|
/**
|
|
186
|
-
*
|
|
187
|
-
* @
|
|
225
|
+
* 加载项目配置
|
|
226
|
+
* @param cwd 项目根目录
|
|
188
227
|
*/
|
|
189
|
-
static
|
|
190
|
-
|
|
228
|
+
static async loadConfig(cwd = process.cwd()) {
|
|
229
|
+
const config = {};
|
|
230
|
+
const versionFilePath = path4.join(cwd, SANDBOX_CONFIG.LOCK_FILE);
|
|
231
|
+
if (fs2.existsSync(versionFilePath)) {
|
|
232
|
+
try {
|
|
233
|
+
const version = (await fs2.readFile(versionFilePath, "utf-8")).trim();
|
|
234
|
+
if (version) {
|
|
235
|
+
config.coreVersion = version;
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
const jiti = createJiti(cwd);
|
|
241
|
+
for (const file of this.CONFIG_FILES) {
|
|
242
|
+
const configPath = path4.join(cwd, file);
|
|
243
|
+
if (fs2.existsSync(configPath)) {
|
|
244
|
+
try {
|
|
245
|
+
let projectConfig = {};
|
|
246
|
+
if (file.endsWith(".ts") || file.endsWith(".js")) {
|
|
247
|
+
const mod = await jiti.import(configPath, { default: true });
|
|
248
|
+
projectConfig = mod.default || mod || {};
|
|
249
|
+
} else if (file.endsWith(".json") || file.startsWith(".chatbirc")) {
|
|
250
|
+
projectConfig = await fs2.readJson(configPath);
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
...projectConfig,
|
|
254
|
+
...config
|
|
255
|
+
};
|
|
256
|
+
} catch (e) {
|
|
257
|
+
logger.error(`\u8BFB\u53D6\u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25`, e);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return config;
|
|
191
262
|
}
|
|
192
263
|
/**
|
|
193
|
-
*
|
|
194
|
-
* @param
|
|
195
|
-
* @
|
|
264
|
+
* 解析核心依赖的具体路径或版本号
|
|
265
|
+
* @param config 项目配置
|
|
266
|
+
* @param relativeTo 相对路径(用于 local 模式下的 file: 协议生成)
|
|
196
267
|
*/
|
|
197
|
-
static
|
|
198
|
-
|
|
199
|
-
|
|
268
|
+
static async resolveCoreDependency(config, relativeTo = ".") {
|
|
269
|
+
const { coreSource = "local", coreVersion } = config;
|
|
270
|
+
if (coreSource === "npm") {
|
|
271
|
+
if (coreVersion) return coreVersion;
|
|
272
|
+
const cliRoot = await getCliRoot();
|
|
273
|
+
const cliPkg = await fs2.readJson(path4.join(cliRoot, "package.json"));
|
|
274
|
+
return cliPkg.version;
|
|
200
275
|
}
|
|
201
|
-
|
|
276
|
+
const sandboxCorePath = path4.join(SANDBOX_CONFIG.DIRS.CACHE, "core");
|
|
277
|
+
const cwd = process.cwd();
|
|
278
|
+
const absoluteRelativeTo = path4.isAbsolute(relativeTo) ? relativeTo : path4.resolve(cwd, relativeTo);
|
|
279
|
+
const absoluteProjectRoot = cwd;
|
|
280
|
+
const relativePath = path4.relative(absoluteRelativeTo, path4.join(absoluteProjectRoot, sandboxCorePath));
|
|
281
|
+
return `file:${relativePath}`;
|
|
202
282
|
}
|
|
203
283
|
/**
|
|
204
|
-
*
|
|
205
|
-
*
|
|
206
|
-
* @param cwd 起始查找目录
|
|
207
|
-
* @returns 查找到的工作区根目录路径,若未找到则返回 cwd
|
|
284
|
+
* 加载 tsup 配置
|
|
285
|
+
* @param cwd 项目根目录
|
|
208
286
|
*/
|
|
209
|
-
static async
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
287
|
+
static async loadTsupConfig(cwd = process.cwd()) {
|
|
288
|
+
const TSUP_CONFIG_FILES = [
|
|
289
|
+
"tsup.config.ts",
|
|
290
|
+
"tsup.config.js",
|
|
291
|
+
"tsup.config.cjs",
|
|
292
|
+
"tsup.config.mjs",
|
|
293
|
+
"tsup.config.json"
|
|
294
|
+
];
|
|
295
|
+
const jiti = createJiti(cwd);
|
|
296
|
+
for (const file of TSUP_CONFIG_FILES) {
|
|
297
|
+
const configPath = path4.join(cwd, file);
|
|
298
|
+
if (fs2.existsSync(configPath)) {
|
|
218
299
|
try {
|
|
219
|
-
|
|
220
|
-
|
|
300
|
+
if (file.endsWith(".json")) {
|
|
301
|
+
return await fs2.readJson(configPath);
|
|
302
|
+
} else {
|
|
303
|
+
const mod = await jiti.import(configPath, { default: true });
|
|
304
|
+
return mod.default || mod || {};
|
|
305
|
+
}
|
|
221
306
|
} catch (e) {
|
|
307
|
+
logger.warn(`\u52A0\u8F7D tsup \u914D\u7F6E\u6587\u4EF6 ${file} \u5931\u8D25: ${e.message}`);
|
|
222
308
|
}
|
|
223
309
|
}
|
|
224
|
-
current = path4.dirname(current);
|
|
225
310
|
}
|
|
226
|
-
|
|
311
|
+
const pkgPath = path4.join(cwd, "package.json");
|
|
312
|
+
if (fs2.existsSync(pkgPath)) {
|
|
313
|
+
try {
|
|
314
|
+
const pkg = await fs2.readJson(pkgPath);
|
|
315
|
+
if (pkg.tsup) {
|
|
316
|
+
return pkg.tsup;
|
|
317
|
+
}
|
|
318
|
+
} catch (e) {
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return {};
|
|
227
322
|
}
|
|
228
323
|
};
|
|
229
324
|
}
|
|
@@ -231,8 +326,8 @@ var init_SandboxPath = __esm({
|
|
|
231
326
|
|
|
232
327
|
// src/sandbox/SandboxRenderer.ts
|
|
233
328
|
import fs3 from "fs-extra";
|
|
234
|
-
import path5 from "path";
|
|
235
329
|
import Handlebars from "handlebars";
|
|
330
|
+
import path5 from "path";
|
|
236
331
|
var SandboxRenderer;
|
|
237
332
|
var init_SandboxRenderer = __esm({
|
|
238
333
|
"src/sandbox/SandboxRenderer.ts"() {
|
|
@@ -339,16 +434,86 @@ var init_SandboxRenderer = __esm({
|
|
|
339
434
|
}
|
|
340
435
|
});
|
|
341
436
|
|
|
342
|
-
// src/sandbox/
|
|
343
|
-
import
|
|
344
|
-
import
|
|
345
|
-
var
|
|
346
|
-
var
|
|
347
|
-
"src/sandbox/
|
|
348
|
-
"use strict";
|
|
349
|
-
init_esm_shims();
|
|
350
|
-
|
|
437
|
+
// src/sandbox/SandboxPath.ts
|
|
438
|
+
import fs5 from "fs-extra";
|
|
439
|
+
import path7 from "path";
|
|
440
|
+
var SandboxPath;
|
|
441
|
+
var init_SandboxPath = __esm({
|
|
442
|
+
"src/sandbox/SandboxPath.ts"() {
|
|
443
|
+
"use strict";
|
|
444
|
+
init_esm_shims();
|
|
445
|
+
init_constants();
|
|
446
|
+
SandboxPath = class {
|
|
447
|
+
static {
|
|
448
|
+
/**
|
|
449
|
+
* 沙箱的基础存储目录,通常位于用户主目录下的 .chatbi-v-core
|
|
450
|
+
*/
|
|
451
|
+
this.BASE_DIR = GLOBAL_PATHS.BASE_DIR;
|
|
452
|
+
}
|
|
453
|
+
/**
|
|
454
|
+
* 获取沙箱根目录
|
|
455
|
+
* @returns 沙箱根目录的绝对路径
|
|
456
|
+
*/
|
|
457
|
+
static getRoot() {
|
|
458
|
+
return this.BASE_DIR;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* 获取存储所有版本的根目录
|
|
462
|
+
* @returns versions 目录的绝对路径
|
|
463
|
+
*/
|
|
464
|
+
static getVersionRoot() {
|
|
465
|
+
return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS);
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* 获取指定版本的沙箱路径
|
|
469
|
+
* @param version 版本号,或者 'current' 表示当前激活版本
|
|
470
|
+
* @returns 对应版本的绝对路径
|
|
471
|
+
*/
|
|
472
|
+
static getVersionPath(version) {
|
|
473
|
+
if (version === SANDBOX_CONFIG.DIRS.CURRENT) {
|
|
474
|
+
return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, SANDBOX_CONFIG.DIRS.CURRENT);
|
|
475
|
+
}
|
|
476
|
+
return path7.join(this.BASE_DIR, SANDBOX_CONFIG.DIRS.VERSIONS, version);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* 递归向上查找工作区根目录
|
|
480
|
+
* 识别标准:包含 pnpm-workspace.yaml 或 package.json 中定义了 workspaces
|
|
481
|
+
* @param cwd 起始查找目录
|
|
482
|
+
* @returns 查找到的工作区根目录路径,若未找到则返回 cwd
|
|
483
|
+
*/
|
|
484
|
+
static async getWorkspaceRoot(cwd) {
|
|
485
|
+
if (!cwd) return cwd;
|
|
486
|
+
if (cwd.startsWith("/mock")) return cwd;
|
|
487
|
+
let current = path7.resolve(cwd);
|
|
488
|
+
while (current !== path7.parse(current).root) {
|
|
489
|
+
const pkgPath = path7.join(current, "package.json");
|
|
490
|
+
const pnpmWorkspacePath = path7.join(current, "pnpm-workspace.yaml");
|
|
491
|
+
if (fs5.existsSync(pnpmWorkspacePath)) return current;
|
|
492
|
+
if (fs5.existsSync(pkgPath)) {
|
|
493
|
+
try {
|
|
494
|
+
const pkg = await fs5.readJson(pkgPath);
|
|
495
|
+
if (pkg.workspaces) return current;
|
|
496
|
+
} catch (e) {
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
current = path7.dirname(current);
|
|
500
|
+
}
|
|
501
|
+
return cwd;
|
|
502
|
+
}
|
|
503
|
+
};
|
|
504
|
+
}
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
// src/sandbox/SandboxContext.ts
|
|
508
|
+
import fs6 from "fs-extra";
|
|
509
|
+
import path8 from "path";
|
|
510
|
+
var SandboxContext;
|
|
511
|
+
var init_SandboxContext = __esm({
|
|
512
|
+
"src/sandbox/SandboxContext.ts"() {
|
|
513
|
+
"use strict";
|
|
514
|
+
init_esm_shims();
|
|
351
515
|
init_constants();
|
|
516
|
+
init_SandboxPath();
|
|
352
517
|
SandboxContext = class {
|
|
353
518
|
/**
|
|
354
519
|
* 注入项目虚拟上下文
|
|
@@ -366,38 +531,38 @@ var init_SandboxContext = __esm({
|
|
|
366
531
|
static async inject(projectRoot, version, corePackages, runtimeDeps) {
|
|
367
532
|
const workspaceRoot = await SandboxPath.getWorkspaceRoot(projectRoot);
|
|
368
533
|
if (!workspaceRoot) {
|
|
369
|
-
const chatbiDir2 =
|
|
370
|
-
await
|
|
534
|
+
const chatbiDir2 = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
|
|
535
|
+
await fs6.ensureDir(chatbiDir2);
|
|
371
536
|
return this.injectToDir(chatbiDir2, version, corePackages, runtimeDeps);
|
|
372
537
|
}
|
|
373
|
-
const chatbiDir =
|
|
374
|
-
await
|
|
538
|
+
const chatbiDir = path8.join(workspaceRoot, SANDBOX_CONFIG.DIRS.CACHE);
|
|
539
|
+
await fs6.ensureDir(chatbiDir);
|
|
375
540
|
if (workspaceRoot !== projectRoot) {
|
|
376
|
-
const localChatbi =
|
|
541
|
+
const localChatbi = path8.join(projectRoot, SANDBOX_CONFIG.DIRS.CACHE);
|
|
377
542
|
try {
|
|
378
|
-
const stats = await
|
|
543
|
+
const stats = await fs6.lstat(localChatbi).catch(() => null);
|
|
379
544
|
if (stats) {
|
|
380
545
|
if (stats.isSymbolicLink()) {
|
|
381
|
-
const linkTarget = await
|
|
546
|
+
const linkTarget = await fs6.readlink(localChatbi);
|
|
382
547
|
if (linkTarget !== chatbiDir) {
|
|
383
|
-
await
|
|
384
|
-
await
|
|
548
|
+
await fs6.remove(localChatbi);
|
|
549
|
+
await fs6.symlink(chatbiDir, localChatbi, "dir");
|
|
385
550
|
}
|
|
386
551
|
} else {
|
|
387
|
-
await
|
|
388
|
-
await
|
|
552
|
+
await fs6.remove(localChatbi);
|
|
553
|
+
await fs6.symlink(chatbiDir, localChatbi, "dir");
|
|
389
554
|
}
|
|
390
555
|
} else {
|
|
391
|
-
await
|
|
556
|
+
await fs6.symlink(chatbiDir, localChatbi, "dir");
|
|
392
557
|
}
|
|
393
558
|
} catch (e) {
|
|
394
559
|
}
|
|
395
560
|
}
|
|
396
|
-
const gitignorePath =
|
|
397
|
-
if (
|
|
398
|
-
let content = await
|
|
561
|
+
const gitignorePath = path8.join(workspaceRoot, ".gitignore");
|
|
562
|
+
if (fs6.existsSync(gitignorePath)) {
|
|
563
|
+
let content = await fs6.readFile(gitignorePath, "utf-8");
|
|
399
564
|
if (!content.includes(SANDBOX_CONFIG.DIRS.CACHE)) {
|
|
400
|
-
await
|
|
565
|
+
await fs6.appendFile(gitignorePath, `
|
|
401
566
|
# ChatBI
|
|
402
567
|
${SANDBOX_CONFIG.DIRS.CACHE}
|
|
403
568
|
`);
|
|
@@ -410,7 +575,7 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
|
|
|
410
575
|
*/
|
|
411
576
|
static async injectToDir(chatbiDir, version, corePackages, runtimeDeps) {
|
|
412
577
|
const versionPath = SandboxPath.getVersionPath(version);
|
|
413
|
-
const sandboxNodeModules =
|
|
578
|
+
const sandboxNodeModules = path8.join(versionPath, "node_modules");
|
|
414
579
|
const corePaths = {};
|
|
415
580
|
for (const pkgName of corePackages) {
|
|
416
581
|
corePaths[pkgName] = [`./node_modules/${pkgName}`];
|
|
@@ -427,7 +592,7 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
|
|
|
427
592
|
}
|
|
428
593
|
corePaths["@types/*"] = ["./node_modules/@types/*"];
|
|
429
594
|
corePaths["vite/client"] = ["./node_modules/vite/client.d.ts"];
|
|
430
|
-
const baseConfigPath =
|
|
595
|
+
const baseConfigPath = path8.join(sandboxNodeModules, "@chatbi-v/config/base.json");
|
|
431
596
|
const tsConfig = {
|
|
432
597
|
extends: baseConfigPath,
|
|
433
598
|
compilerOptions: {
|
|
@@ -443,25 +608,25 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
|
|
|
443
608
|
}
|
|
444
609
|
}
|
|
445
610
|
};
|
|
446
|
-
await
|
|
447
|
-
await
|
|
448
|
-
const virtualNodeModules =
|
|
449
|
-
if (
|
|
611
|
+
await fs6.writeJson(path8.join(chatbiDir, "tsconfig.json"), tsConfig, { spaces: 2 });
|
|
612
|
+
await fs6.writeJson(path8.join(chatbiDir, "tsconfig.paths.json"), { compilerOptions: tsConfig.compilerOptions }, { spaces: 2 });
|
|
613
|
+
const virtualNodeModules = path8.join(chatbiDir, "node_modules");
|
|
614
|
+
if (fs6.existsSync(sandboxNodeModules)) {
|
|
450
615
|
try {
|
|
451
|
-
const stats = await
|
|
616
|
+
const stats = await fs6.lstat(virtualNodeModules).catch(() => null);
|
|
452
617
|
if (stats) {
|
|
453
618
|
if (stats.isSymbolicLink()) {
|
|
454
|
-
const linkTarget = await
|
|
619
|
+
const linkTarget = await fs6.readlink(virtualNodeModules);
|
|
455
620
|
if (linkTarget !== sandboxNodeModules) {
|
|
456
|
-
await
|
|
457
|
-
await
|
|
621
|
+
await fs6.remove(virtualNodeModules);
|
|
622
|
+
await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
|
|
458
623
|
}
|
|
459
624
|
} else {
|
|
460
|
-
await
|
|
461
|
-
await
|
|
625
|
+
await fs6.remove(virtualNodeModules);
|
|
626
|
+
await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
|
|
462
627
|
}
|
|
463
628
|
} else {
|
|
464
|
-
await
|
|
629
|
+
await fs6.symlink(sandboxNodeModules, virtualNodeModules, "dir");
|
|
465
630
|
}
|
|
466
631
|
} catch (e) {
|
|
467
632
|
}
|
|
@@ -472,10 +637,10 @@ ${SANDBOX_CONFIG.DIRS.CACHE}
|
|
|
472
637
|
});
|
|
473
638
|
|
|
474
639
|
// src/sandbox/SandboxPkgManager.ts
|
|
475
|
-
import fs5 from "fs-extra";
|
|
476
|
-
import path7 from "path";
|
|
477
|
-
import pc2 from "picocolors";
|
|
478
640
|
import fg from "fast-glob";
|
|
641
|
+
import fs7 from "fs-extra";
|
|
642
|
+
import path9 from "path";
|
|
643
|
+
import pc3 from "picocolors";
|
|
479
644
|
var SandboxPkgManager;
|
|
480
645
|
var init_SandboxPkgManager = __esm({
|
|
481
646
|
"src/sandbox/SandboxPkgManager.ts"() {
|
|
@@ -496,16 +661,16 @@ var init_SandboxPkgManager = __esm({
|
|
|
496
661
|
try {
|
|
497
662
|
const cliRoot = await getCliRoot();
|
|
498
663
|
const projectRoot = await SandboxPath.getWorkspaceRoot(cliRoot);
|
|
499
|
-
if (projectRoot === cliRoot && !
|
|
664
|
+
if (projectRoot === cliRoot && !fs7.existsSync(path9.join(projectRoot, "pnpm-workspace.yaml"))) {
|
|
500
665
|
return false;
|
|
501
666
|
}
|
|
502
667
|
const possiblePackagesDirs = [
|
|
503
|
-
|
|
668
|
+
path9.join(projectRoot, "packages"),
|
|
504
669
|
// 兼容旧版或其他可能的路径结构
|
|
505
|
-
|
|
670
|
+
path9.resolve(projectRoot, "../chatbi-v/packages")
|
|
506
671
|
];
|
|
507
672
|
const localPackages = {};
|
|
508
|
-
const patterns = possiblePackagesDirs.filter((dir) =>
|
|
673
|
+
const patterns = possiblePackagesDirs.filter((dir) => fs7.existsSync(dir)).map((dir) => path9.join(dir, "**/package.json"));
|
|
509
674
|
if (patterns.length > 0) {
|
|
510
675
|
const pkgJsonFiles = await fg(patterns, {
|
|
511
676
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
@@ -514,34 +679,34 @@ var init_SandboxPkgManager = __esm({
|
|
|
514
679
|
});
|
|
515
680
|
for (const pkgJsonPath of pkgJsonFiles) {
|
|
516
681
|
try {
|
|
517
|
-
const pkgJson = await
|
|
682
|
+
const pkgJson = await fs7.readJson(pkgJsonPath);
|
|
518
683
|
if (corePackages.includes(pkgJson.name) || runtimeDeps.includes(pkgJson.name)) {
|
|
519
|
-
localPackages[pkgJson.name] =
|
|
684
|
+
localPackages[pkgJson.name] = path9.dirname(pkgJsonPath);
|
|
520
685
|
}
|
|
521
686
|
} catch (e) {
|
|
522
687
|
}
|
|
523
688
|
}
|
|
524
689
|
}
|
|
525
690
|
if (Object.keys(localPackages).length === 0) return false;
|
|
526
|
-
const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${
|
|
691
|
+
const linkSummary = Object.entries(localPackages).map(([name, pkgPath]) => `${pc3.cyan(name.padEnd(30))} -> ${pc3.gray(pkgPath)}`).join("\n");
|
|
527
692
|
printBox(
|
|
528
|
-
|
|
693
|
+
pc3.green("\u{1F517} \u5DF2\u68C0\u6D4B\u5230\u672C\u5730\u5F00\u53D1\u73AF\u5883\uFF0C\u5C06\u94FE\u63A5\u4EE5\u4E0B\u6838\u5FC3\u5305\uFF1A\n\n") + linkSummary,
|
|
529
694
|
"Monorepo Link Mode"
|
|
530
695
|
);
|
|
531
|
-
const sandboxNodeModules =
|
|
532
|
-
await
|
|
696
|
+
const sandboxNodeModules = path9.join(versionPath, "node_modules");
|
|
697
|
+
await fs7.ensureDir(sandboxNodeModules);
|
|
533
698
|
for (const [name, pkgPath] of Object.entries(localPackages)) {
|
|
534
|
-
const targetLinkPath =
|
|
535
|
-
await
|
|
699
|
+
const targetLinkPath = path9.join(sandboxNodeModules, name);
|
|
700
|
+
await fs7.ensureDir(path9.dirname(targetLinkPath));
|
|
536
701
|
try {
|
|
537
|
-
const stats = await
|
|
538
|
-
if (stats) await
|
|
702
|
+
const stats = await fs7.lstat(targetLinkPath).catch(() => null);
|
|
703
|
+
if (stats) await fs7.remove(targetLinkPath);
|
|
539
704
|
} catch (e) {
|
|
540
705
|
}
|
|
541
|
-
await
|
|
706
|
+
await fs7.symlink(pkgPath, targetLinkPath, "dir");
|
|
542
707
|
}
|
|
543
|
-
const sandboxPkgJsonPath =
|
|
544
|
-
const sandboxPkgJson = await
|
|
708
|
+
const sandboxPkgJsonPath = path9.join(versionPath, "package.json");
|
|
709
|
+
const sandboxPkgJson = await fs7.readJson(sandboxPkgJsonPath);
|
|
545
710
|
const sections = ["dependencies", "devDependencies"];
|
|
546
711
|
let modified = false;
|
|
547
712
|
for (const section of sections) {
|
|
@@ -554,10 +719,10 @@ var init_SandboxPkgManager = __esm({
|
|
|
554
719
|
}
|
|
555
720
|
}
|
|
556
721
|
}
|
|
557
|
-
if (modified) await
|
|
722
|
+
if (modified) await fs7.writeJson(sandboxPkgJsonPath, sandboxPkgJson, { spaces: 2 });
|
|
558
723
|
return true;
|
|
559
724
|
} catch (e) {
|
|
560
|
-
console.warn(
|
|
725
|
+
console.warn(pc3.yellow(` \u26A0\uFE0F Link \u672C\u5730\u6E90\u7801\u5931\u8D25\uFF0C\u5C06\u5C1D\u8BD5\u4ECE NPM \u5B89\u88C5: ${e.message}`));
|
|
561
726
|
return false;
|
|
562
727
|
}
|
|
563
728
|
}
|
|
@@ -566,32 +731,29 @@ var init_SandboxPkgManager = __esm({
|
|
|
566
731
|
});
|
|
567
732
|
|
|
568
733
|
// src/sandbox.ts
|
|
569
|
-
import
|
|
570
|
-
import path8 from "path";
|
|
571
|
-
import pc3 from "picocolors";
|
|
734
|
+
import { execa as execa2 } from "execa";
|
|
572
735
|
import fg2 from "fast-glob";
|
|
573
|
-
import
|
|
736
|
+
import fs8 from "fs-extra";
|
|
737
|
+
import path10 from "path";
|
|
738
|
+
import pc4 from "picocolors";
|
|
574
739
|
var Sandbox;
|
|
575
740
|
var init_sandbox = __esm({
|
|
576
741
|
"src/sandbox.ts"() {
|
|
577
742
|
"use strict";
|
|
578
743
|
init_esm_shims();
|
|
579
|
-
|
|
580
|
-
init_SandboxPath();
|
|
581
|
-
init_SandboxRenderer();
|
|
744
|
+
init_constants();
|
|
582
745
|
init_SandboxContext();
|
|
746
|
+
init_SandboxPath();
|
|
583
747
|
init_SandboxPkgManager();
|
|
584
|
-
|
|
748
|
+
init_SandboxRenderer();
|
|
749
|
+
init_utils();
|
|
585
750
|
Sandbox = class {
|
|
586
751
|
static {
|
|
587
752
|
/** 核心源码包列表 */
|
|
588
753
|
this.CORE_PACKAGES = [
|
|
589
754
|
"@chatbi-v/core",
|
|
590
755
|
"@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"
|
|
756
|
+
"@chatbi-v/config"
|
|
595
757
|
];
|
|
596
758
|
}
|
|
597
759
|
static {
|
|
@@ -632,8 +794,8 @@ var init_sandbox = __esm({
|
|
|
632
794
|
/** 清理指定版本的沙箱物理文件 */
|
|
633
795
|
static async cleanVersion(version) {
|
|
634
796
|
const versionPath = this.getVersionPath(version);
|
|
635
|
-
if (
|
|
636
|
-
await
|
|
797
|
+
if (fs8.existsSync(versionPath)) {
|
|
798
|
+
await fs8.remove(versionPath);
|
|
637
799
|
}
|
|
638
800
|
}
|
|
639
801
|
/**
|
|
@@ -647,7 +809,7 @@ var init_sandbox = __esm({
|
|
|
647
809
|
const workspaceRoot = await this.getWorkspaceRoot(cwd);
|
|
648
810
|
let cleanedCount = 0;
|
|
649
811
|
const cachePatterns = [
|
|
650
|
-
|
|
812
|
+
path10.join(workspaceRoot, `**/${SANDBOX_CONFIG.DIRS.CACHE}`)
|
|
651
813
|
];
|
|
652
814
|
const cacheDirs = await fg2(cachePatterns, {
|
|
653
815
|
onlyFiles: false,
|
|
@@ -658,15 +820,15 @@ var init_sandbox = __esm({
|
|
|
658
820
|
// 确保能匹配到以 . 开头的目录
|
|
659
821
|
});
|
|
660
822
|
for (const dir of cacheDirs) {
|
|
661
|
-
const stats = await
|
|
823
|
+
const stats = await fs8.lstat(dir).catch(() => null);
|
|
662
824
|
if (stats) {
|
|
663
|
-
await
|
|
825
|
+
await fs8.remove(dir);
|
|
664
826
|
cleanedCount++;
|
|
665
827
|
}
|
|
666
828
|
}
|
|
667
829
|
if (deep) {
|
|
668
830
|
const distPatterns = [
|
|
669
|
-
|
|
831
|
+
path10.join(workspaceRoot, "**/dist")
|
|
670
832
|
];
|
|
671
833
|
const distDirs = await fg2(distPatterns, {
|
|
672
834
|
onlyFiles: false,
|
|
@@ -679,24 +841,24 @@ var init_sandbox = __esm({
|
|
|
679
841
|
]
|
|
680
842
|
});
|
|
681
843
|
for (const dir of distDirs) {
|
|
682
|
-
const stats = await
|
|
844
|
+
const stats = await fs8.lstat(dir).catch(() => null);
|
|
683
845
|
if (stats) {
|
|
684
|
-
const hasPkg =
|
|
846
|
+
const hasPkg = fs8.existsSync(path10.join(path10.dirname(dir), "package.json"));
|
|
685
847
|
if (hasPkg) {
|
|
686
|
-
await
|
|
848
|
+
await fs8.remove(dir);
|
|
687
849
|
cleanedCount++;
|
|
688
850
|
}
|
|
689
851
|
}
|
|
690
852
|
}
|
|
691
853
|
const globalRoot = this.getRoot();
|
|
692
|
-
if (
|
|
693
|
-
await
|
|
854
|
+
if (fs8.existsSync(globalRoot)) {
|
|
855
|
+
await fs8.remove(globalRoot);
|
|
694
856
|
cleanedCount++;
|
|
695
857
|
}
|
|
696
858
|
}
|
|
697
|
-
spinner.succeed(
|
|
859
|
+
spinner.succeed(pc4.green(`\u6E05\u7406\u5B8C\u6210\uFF0C\u5171\u6E05\u7406 ${cleanedCount} \u4E2A\u9879\u76EE/\u7F13\u5B58\u76EE\u5F55`));
|
|
698
860
|
} catch (e) {
|
|
699
|
-
spinner.fail(
|
|
861
|
+
spinner.fail(pc4.red(`\u6E05\u7406\u5931\u8D25: ${e.message}`));
|
|
700
862
|
}
|
|
701
863
|
}
|
|
702
864
|
/**
|
|
@@ -704,14 +866,14 @@ var init_sandbox = __esm({
|
|
|
704
866
|
*/
|
|
705
867
|
static async prepare(version, force = false) {
|
|
706
868
|
const versionPath = this.getVersionPath(version);
|
|
707
|
-
if (!force &&
|
|
869
|
+
if (!force && fs8.existsSync(path10.join(versionPath, "node_modules/tailwindcss"))) {
|
|
708
870
|
return versionPath;
|
|
709
871
|
}
|
|
710
|
-
if (
|
|
711
|
-
await
|
|
872
|
+
if (fs8.existsSync(versionPath)) {
|
|
873
|
+
await fs8.remove(path10.join(versionPath, "node_modules"));
|
|
712
874
|
}
|
|
713
|
-
await
|
|
714
|
-
const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${
|
|
875
|
+
await fs8.ensureDir(versionPath);
|
|
876
|
+
const spinner = createSpinner(`\u6B63\u5728\u521D\u59CB\u5316\u5185\u6838\u6C99\u7BB1 ${pc4.cyan(version)}...`).start();
|
|
715
877
|
try {
|
|
716
878
|
const cliRoot = await getCliRoot();
|
|
717
879
|
const dependencies = {};
|
|
@@ -727,20 +889,20 @@ var init_sandbox = __esm({
|
|
|
727
889
|
devDependencies: DEPENDENCY_VERSIONS
|
|
728
890
|
};
|
|
729
891
|
await SandboxRenderer.renderDirectory(
|
|
730
|
-
|
|
892
|
+
path10.join(cliRoot, "templates/sandbox"),
|
|
731
893
|
versionPath,
|
|
732
894
|
templateData
|
|
733
895
|
);
|
|
734
|
-
spinner.text =
|
|
896
|
+
spinner.text = pc4.gray(" \u{1F50D} \u68C0\u67E5\u672C\u5730\u5F00\u53D1\u73AF\u5883...");
|
|
735
897
|
const isLocalDev = await SandboxPkgManager.tryLinkLocalPackages(versionPath, this.CORE_PACKAGES, this.RUNTIME_DEPS);
|
|
736
898
|
const installArgs = isLocalDev ? ["install", "--no-frozen-lockfile"] : ["install"];
|
|
737
|
-
spinner.text =
|
|
738
|
-
await
|
|
739
|
-
spinner.text =
|
|
899
|
+
spinner.text = pc4.gray(` \u23F3 \u6267\u884C pnpm ${installArgs.join(" ")}...`);
|
|
900
|
+
await execa2("pnpm", installArgs, { cwd: versionPath });
|
|
901
|
+
spinner.text = pc4.gray(" \u{1F3A8} \u540C\u6B65 Shell \u6A21\u677F...");
|
|
740
902
|
await this.ensureShell(version, force);
|
|
741
|
-
spinner.succeed(
|
|
903
|
+
spinner.succeed(pc4.green(`\u5185\u6838\u6C99\u7BB1 ${version} \u521D\u59CB\u5316\u6210\u529F`));
|
|
742
904
|
} catch (e) {
|
|
743
|
-
spinner.fail(
|
|
905
|
+
spinner.fail(pc4.red(`\u5185\u6838\u6C99\u7BB1\u521D\u59CB\u5316\u5931\u8D25: ${e.message}`));
|
|
744
906
|
throw e;
|
|
745
907
|
}
|
|
746
908
|
return versionPath;
|
|
@@ -750,14 +912,14 @@ var init_sandbox = __esm({
|
|
|
750
912
|
*/
|
|
751
913
|
static async ensureShell(version, force = false) {
|
|
752
914
|
const versionPath = this.getVersionPath(version);
|
|
753
|
-
const shellDestDir =
|
|
754
|
-
if (!force &&
|
|
915
|
+
const shellDestDir = path10.join(versionPath, "shell");
|
|
916
|
+
if (!force && fs8.existsSync(path10.join(shellDestDir, "tsconfig.paths.json"))) {
|
|
755
917
|
return shellDestDir;
|
|
756
918
|
}
|
|
757
919
|
const cliRoot = await getCliRoot();
|
|
758
|
-
const shellTemplateDir =
|
|
759
|
-
if (
|
|
760
|
-
await
|
|
920
|
+
const shellTemplateDir = path10.join(cliRoot, "templates/app");
|
|
921
|
+
if (fs8.existsSync(shellTemplateDir)) {
|
|
922
|
+
await fs8.remove(shellDestDir);
|
|
761
923
|
const templateData = {
|
|
762
924
|
name: "chatbi-shell",
|
|
763
925
|
version,
|
|
@@ -768,7 +930,7 @@ var init_sandbox = __esm({
|
|
|
768
930
|
tsconfigPath: "./tsconfig.paths.json"
|
|
769
931
|
};
|
|
770
932
|
await SandboxRenderer.renderDirectory(shellTemplateDir, shellDestDir, templateData);
|
|
771
|
-
await
|
|
933
|
+
await fs8.writeJson(path10.join(shellDestDir, "tsconfig.paths.json"), {
|
|
772
934
|
compilerOptions: { baseUrl: ".", paths: { "@/*": ["./src/*"] } }
|
|
773
935
|
}, { spaces: 2 });
|
|
774
936
|
}
|
|
@@ -781,24 +943,24 @@ var init_sandbox = __esm({
|
|
|
781
943
|
/** 获取核心库的 Vite Alias 配置 */
|
|
782
944
|
static getCoreAlias(version) {
|
|
783
945
|
const versionPath = this.getVersionPath(version);
|
|
784
|
-
const sandboxNodeModules =
|
|
785
|
-
return Object.fromEntries(this.CORE_PACKAGES.map((pkg) => [pkg,
|
|
946
|
+
const sandboxNodeModules = path10.join(versionPath, "node_modules");
|
|
947
|
+
return Object.fromEntries(this.CORE_PACKAGES.map((pkg) => [pkg, path10.join(sandboxNodeModules, pkg)]));
|
|
786
948
|
}
|
|
787
949
|
/** 切换内核版本 */
|
|
788
950
|
static async useVersion(version) {
|
|
789
951
|
const versionRoot = this.getVersionRoot();
|
|
790
|
-
const currentLink =
|
|
952
|
+
const currentLink = path10.join(versionRoot, SANDBOX_CONFIG.DIRS.CURRENT);
|
|
791
953
|
const targetPath = this.getVersionPath(version);
|
|
792
|
-
if (!
|
|
793
|
-
if (
|
|
794
|
-
await
|
|
954
|
+
if (!fs8.existsSync(targetPath)) throw new Error(`\u7248\u672C ${version} \u4E0D\u5B58\u5728`);
|
|
955
|
+
if (fs8.existsSync(currentLink)) await fs8.remove(currentLink);
|
|
956
|
+
await fs8.ensureSymlink(targetPath, currentLink, "dir");
|
|
795
957
|
}
|
|
796
958
|
/** 解析版本号 */
|
|
797
959
|
static async resolveVersion(version) {
|
|
798
960
|
if (!version || version === "latest" || version === "current") {
|
|
799
|
-
const currentLink =
|
|
800
|
-
if (
|
|
801
|
-
return
|
|
961
|
+
const currentLink = path10.join(this.getVersionRoot(), SANDBOX_CONFIG.DIRS.CURRENT);
|
|
962
|
+
if (fs8.existsSync(currentLink)) {
|
|
963
|
+
return path10.basename(await fs8.readlink(currentLink));
|
|
802
964
|
}
|
|
803
965
|
const versions = await this.listVersions();
|
|
804
966
|
return versions[0] || "1.0.0";
|
|
@@ -808,8 +970,8 @@ var init_sandbox = __esm({
|
|
|
808
970
|
/** 列出所有已安装版本 */
|
|
809
971
|
static async listVersions() {
|
|
810
972
|
const versionRoot = this.getVersionRoot();
|
|
811
|
-
if (!
|
|
812
|
-
const dirs = await
|
|
973
|
+
if (!fs8.existsSync(versionRoot)) return [];
|
|
974
|
+
const dirs = await fs8.readdir(versionRoot);
|
|
813
975
|
return dirs.filter((d) => d !== SANDBOX_CONFIG.DIRS.CURRENT && !d.startsWith(".")).sort().reverse();
|
|
814
976
|
}
|
|
815
977
|
/** 可视化展示沙箱状态 */
|
|
@@ -819,11 +981,11 @@ var init_sandbox = __esm({
|
|
|
819
981
|
const currentVersion = await this.resolveVersion("current");
|
|
820
982
|
const versions = await this.listVersions();
|
|
821
983
|
const statusInfo = [
|
|
822
|
-
`${
|
|
823
|
-
`${
|
|
824
|
-
`${
|
|
825
|
-
`${
|
|
826
|
-
`${
|
|
984
|
+
`${pc4.bold("\u9879\u76EE\u8DEF\u5F84:")} ${pc4.cyan(cwd)}`,
|
|
985
|
+
`${pc4.bold("\u67B6\u6784\u6A21\u5F0F:")} ${isMonorepo ? pc4.yellow("Monorepo") : pc4.green("Standalone")}`,
|
|
986
|
+
`${pc4.bold("\u5F53\u524D\u5185\u6838:")} ${pc4.green(currentVersion)}`,
|
|
987
|
+
`${pc4.bold("\u5DF2\u88C5\u7248\u672C:")} ${pc4.gray(versions.join(", ") || "none")}`,
|
|
988
|
+
`${pc4.bold("\u6C99\u7BB1\u6839\u76EE\u5F55:")} ${pc4.gray(this.getRoot())}`
|
|
827
989
|
].join("\n");
|
|
828
990
|
printBox(statusInfo, "ChatBI Sandbox Status");
|
|
829
991
|
}
|
|
@@ -831,160 +993,42 @@ var init_sandbox = __esm({
|
|
|
831
993
|
}
|
|
832
994
|
});
|
|
833
995
|
|
|
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
996
|
// 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
997
|
import fg3 from "fast-glob";
|
|
998
|
+
import fs9 from "fs-extra";
|
|
999
|
+
import { createRequire as createRequire3 } from "module";
|
|
1000
|
+
import path11 from "path";
|
|
1001
|
+
import pc5 from "picocolors";
|
|
1002
|
+
import prompts2 from "prompts";
|
|
1003
|
+
import { createJiti as createJiti2 } from "jiti";
|
|
960
1004
|
var nativeRequire, CoreKit;
|
|
961
1005
|
var init_corekit = __esm({
|
|
962
1006
|
"src/corekit.ts"() {
|
|
963
1007
|
"use strict";
|
|
964
1008
|
init_esm_shims();
|
|
965
|
-
init_utils();
|
|
966
|
-
init_sandbox();
|
|
967
1009
|
init_config();
|
|
968
|
-
|
|
1010
|
+
init_sandbox();
|
|
1011
|
+
init_utils();
|
|
1012
|
+
nativeRequire = createRequire3(import.meta.url);
|
|
969
1013
|
CoreKit = class {
|
|
970
1014
|
/**
|
|
971
1015
|
* 解析项目模式
|
|
972
1016
|
*/
|
|
973
1017
|
static async detectMode(cwd) {
|
|
974
|
-
const pkgPath =
|
|
975
|
-
if (!
|
|
976
|
-
const pkg = await
|
|
977
|
-
if (pkg.workspaces ||
|
|
1018
|
+
const pkgPath = path11.join(cwd, "package.json");
|
|
1019
|
+
if (!fs9.existsSync(pkgPath)) return "app";
|
|
1020
|
+
const pkg = await fs9.readJson(pkgPath);
|
|
1021
|
+
if (pkg.workspaces || fs9.existsSync(path11.join(cwd, "pnpm-workspace.yaml"))) {
|
|
978
1022
|
return "monorepo";
|
|
979
1023
|
}
|
|
980
1024
|
if (pkg.chatbi?.type === "plugin" || pkg.plugin === true) return "plugin";
|
|
981
1025
|
if (pkg.chatbi?.type === "app") return "app";
|
|
982
1026
|
const pluginEntries = await fg3(["index.plugin.{ts,js}", "src/index.plugin.{ts,js}"], { cwd });
|
|
983
1027
|
if (pluginEntries.length > 0) return "plugin";
|
|
984
|
-
if (
|
|
1028
|
+
if (fs9.existsSync(path11.join(cwd, "index.html"))) {
|
|
985
1029
|
return "app";
|
|
986
1030
|
}
|
|
987
|
-
if (
|
|
1031
|
+
if (fs9.existsSync(path11.join(cwd, "src/index.ts")) || fs9.existsSync(path11.join(cwd, "src/index.tsx"))) {
|
|
988
1032
|
if (pkg.bin) return "lib";
|
|
989
1033
|
if (pkg.peerDependencies?.react && !pkg.dependencies?.react) return "plugin";
|
|
990
1034
|
return "lib";
|
|
@@ -1002,18 +1046,18 @@ var init_corekit = __esm({
|
|
|
1002
1046
|
}
|
|
1003
1047
|
try {
|
|
1004
1048
|
const cliRoot = await getCliRoot();
|
|
1005
|
-
const cliVersionFile =
|
|
1006
|
-
if (
|
|
1007
|
-
const version = (await
|
|
1049
|
+
const cliVersionFile = path11.join(cliRoot, ".chatbi-version");
|
|
1050
|
+
if (fs9.existsSync(cliVersionFile)) {
|
|
1051
|
+
const version = (await fs9.readFile(cliVersionFile, "utf-8")).trim();
|
|
1008
1052
|
if (version) return version;
|
|
1009
1053
|
}
|
|
1010
1054
|
} catch (e) {
|
|
1011
1055
|
}
|
|
1012
|
-
const currentLinkPath =
|
|
1013
|
-
if (
|
|
1056
|
+
const currentLinkPath = path11.join(Sandbox.getVersionRoot(), "current");
|
|
1057
|
+
if (fs9.existsSync(currentLinkPath)) {
|
|
1014
1058
|
try {
|
|
1015
|
-
const realPath = await
|
|
1016
|
-
return
|
|
1059
|
+
const realPath = await fs9.realpath(currentLinkPath);
|
|
1060
|
+
return path11.basename(realPath);
|
|
1017
1061
|
} catch (e) {
|
|
1018
1062
|
}
|
|
1019
1063
|
}
|
|
@@ -1025,7 +1069,7 @@ var init_corekit = __esm({
|
|
|
1025
1069
|
*/
|
|
1026
1070
|
static async listVersions() {
|
|
1027
1071
|
const versionsDir = Sandbox.getVersionRoot();
|
|
1028
|
-
if (!
|
|
1072
|
+
if (!fs9.existsSync(versionsDir)) return [];
|
|
1029
1073
|
const dirs = await fg3("*", {
|
|
1030
1074
|
cwd: versionsDir,
|
|
1031
1075
|
onlyDirectories: true,
|
|
@@ -1037,18 +1081,18 @@ var init_corekit = __esm({
|
|
|
1037
1081
|
* 自动发现项目中的插件
|
|
1038
1082
|
*/
|
|
1039
1083
|
static async discoverPlugins(rootDir) {
|
|
1040
|
-
const pluginsDir =
|
|
1041
|
-
if (!
|
|
1084
|
+
const pluginsDir = path11.join(rootDir, "plugins");
|
|
1085
|
+
if (!fs9.existsSync(pluginsDir)) return [];
|
|
1042
1086
|
const pkgFiles = await fg3("*/package.json", { cwd: pluginsDir, absolute: true });
|
|
1043
1087
|
const plugins = [];
|
|
1044
1088
|
for (const pkgPath of pkgFiles) {
|
|
1045
1089
|
try {
|
|
1046
|
-
const pkg = await
|
|
1047
|
-
const pluginPath =
|
|
1090
|
+
const pkg = await fs9.readJson(pkgPath);
|
|
1091
|
+
const pluginPath = path11.dirname(pkgPath);
|
|
1048
1092
|
plugins.push({
|
|
1049
|
-
name: pkg.name ||
|
|
1093
|
+
name: pkg.name || path11.basename(pluginPath),
|
|
1050
1094
|
path: pluginPath,
|
|
1051
|
-
id:
|
|
1095
|
+
id: path11.basename(pluginPath)
|
|
1052
1096
|
});
|
|
1053
1097
|
} catch (e) {
|
|
1054
1098
|
}
|
|
@@ -1062,19 +1106,19 @@ var init_corekit = __esm({
|
|
|
1062
1106
|
const mode = await this.detectMode(cwd);
|
|
1063
1107
|
const version = await this.resolveVersion(cwd);
|
|
1064
1108
|
printBox(
|
|
1065
|
-
`${
|
|
1109
|
+
`${pc5.cyan(pc5.bold("\u{1F680} ChatBI Dev Server"))}
|
|
1066
1110
|
|
|
1067
|
-
${
|
|
1068
|
-
${
|
|
1069
|
-
${
|
|
1111
|
+
${pc5.gray("Mode: ")} ${pc5.yellow(mode)}
|
|
1112
|
+
${pc5.gray("Kernel: ")} ${pc5.green(version)}
|
|
1113
|
+
${pc5.gray("Root: ")} ${pc5.white(cwd)}`,
|
|
1070
1114
|
"Dev Server"
|
|
1071
1115
|
);
|
|
1072
1116
|
const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6C99\u7BB1\u73AF\u5883...").start();
|
|
1073
1117
|
try {
|
|
1074
1118
|
await Sandbox.prepare(version);
|
|
1075
|
-
spinner.text =
|
|
1119
|
+
spinner.text = pc5.cyan("\u6B63\u5728\u6CE8\u5165\u865A\u62DF\u4E0A\u4E0B\u6587...");
|
|
1076
1120
|
await Sandbox.injectContext(cwd, version);
|
|
1077
|
-
spinner.succeed(
|
|
1121
|
+
spinner.succeed(pc5.green("\u73AF\u5883\u5C31\u7EEA"));
|
|
1078
1122
|
if (mode === "plugin") {
|
|
1079
1123
|
await this.startPluginDevServer(cwd, version, options.port);
|
|
1080
1124
|
} else if (mode === "app") {
|
|
@@ -1083,28 +1127,28 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1083
1127
|
await this.startMonorepoDevServer(cwd, version, options.port);
|
|
1084
1128
|
}
|
|
1085
1129
|
} catch (e) {
|
|
1086
|
-
spinner.fail(
|
|
1130
|
+
spinner.fail(pc5.red(`\u542F\u52A8\u5931\u8D25: ${e.message}`));
|
|
1087
1131
|
}
|
|
1088
1132
|
}
|
|
1089
1133
|
/**
|
|
1090
1134
|
* 启动 Monorepo 开发服务器
|
|
1091
1135
|
*/
|
|
1092
1136
|
static async startMonorepoDevServer(rootDir, version, customPort) {
|
|
1093
|
-
const appsDir =
|
|
1094
|
-
if (!
|
|
1137
|
+
const appsDir = path11.join(rootDir, "apps");
|
|
1138
|
+
if (!fs9.existsSync(appsDir)) {
|
|
1095
1139
|
logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230 apps/ \u76EE\u5F55");
|
|
1096
1140
|
return;
|
|
1097
1141
|
}
|
|
1098
1142
|
const pkgFiles = await fg3("*/package.json", { cwd: appsDir, absolute: true });
|
|
1099
1143
|
const apps = pkgFiles.map((pkgPath) => ({
|
|
1100
|
-
name:
|
|
1101
|
-
path:
|
|
1144
|
+
name: path11.basename(path11.dirname(pkgPath)),
|
|
1145
|
+
path: path11.dirname(pkgPath)
|
|
1102
1146
|
}));
|
|
1103
1147
|
if (apps.length === 0) {
|
|
1104
1148
|
logger.warn("\u5F53\u524D Monorepo \u4E0B\u672A\u627E\u5230\u4EFB\u4F55\u5E94\u7528 (apps/)");
|
|
1105
1149
|
return;
|
|
1106
1150
|
}
|
|
1107
|
-
const response = await
|
|
1151
|
+
const response = await prompts2({
|
|
1108
1152
|
type: "select",
|
|
1109
1153
|
name: "appPath",
|
|
1110
1154
|
message: "\u8BF7\u9009\u62E9\u8981\u542F\u52A8\u7684\u5E94\u7528:",
|
|
@@ -1115,7 +1159,7 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1115
1159
|
logger.info("\u5DF2\u53D6\u6D88");
|
|
1116
1160
|
return;
|
|
1117
1161
|
}
|
|
1118
|
-
await this.startAppDevServer(response.appPath, version, customPort);
|
|
1162
|
+
await this.startAppDevServer(response.appPath, version, customPort, true);
|
|
1119
1163
|
}
|
|
1120
1164
|
/**
|
|
1121
1165
|
* 启动插件开发服务器 (Hosted Mode)
|
|
@@ -1125,19 +1169,21 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1125
1169
|
const shellPort = customPort || 5173;
|
|
1126
1170
|
const sandboxRoot = Sandbox.getRoot();
|
|
1127
1171
|
const versionPath = Sandbox.getVersionPath(version);
|
|
1128
|
-
const sandboxNodeModules =
|
|
1172
|
+
const sandboxNodeModules = path11.join(versionPath, "node_modules");
|
|
1129
1173
|
const shellDir = await Sandbox.ensureShell(version);
|
|
1130
1174
|
const coreAlias = Sandbox.getCoreAlias(version);
|
|
1131
|
-
const tailwindPath =
|
|
1132
|
-
const autoprefixerPath =
|
|
1133
|
-
let pluginEntry =
|
|
1134
|
-
if (!
|
|
1135
|
-
pluginEntry =
|
|
1175
|
+
const tailwindPath = path11.join(sandboxNodeModules, "tailwindcss");
|
|
1176
|
+
const autoprefixerPath = path11.join(sandboxNodeModules, "autoprefixer");
|
|
1177
|
+
let pluginEntry = path11.join(pluginDir, "src/index.tsx");
|
|
1178
|
+
if (!fs9.existsSync(pluginEntry)) {
|
|
1179
|
+
pluginEntry = path11.join(pluginDir, "src/index.ts");
|
|
1136
1180
|
}
|
|
1137
1181
|
const define = {
|
|
1138
1182
|
"process.env.CHATBI_PLUGIN_PATH": JSON.stringify(pluginDir)
|
|
1139
1183
|
};
|
|
1140
1184
|
const { createServer } = await import("vite");
|
|
1185
|
+
const jiti = createJiti2(import.meta.url);
|
|
1186
|
+
const tailwindConfig = await jiti.import(path11.join(sandboxNodeModules, "@chatbi-v/config/tailwind.js"), { default: true });
|
|
1141
1187
|
try {
|
|
1142
1188
|
const server = await createServer({
|
|
1143
1189
|
root: shellDir,
|
|
@@ -1146,12 +1192,12 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1146
1192
|
postcss: {
|
|
1147
1193
|
plugins: [
|
|
1148
1194
|
nativeRequire(tailwindPath)({
|
|
1149
|
-
presets: [
|
|
1195
|
+
presets: [tailwindConfig],
|
|
1150
1196
|
darkMode: "class",
|
|
1151
1197
|
content: [
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1198
|
+
path11.join(shellDir, "index.html"),
|
|
1199
|
+
path11.join(shellDir, "src/**/*.{ts,tsx}"),
|
|
1200
|
+
path11.join(pluginDir, "src/**/*.{ts,tsx}")
|
|
1155
1201
|
]
|
|
1156
1202
|
}),
|
|
1157
1203
|
nativeRequire(autoprefixerPath)
|
|
@@ -1173,21 +1219,21 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1173
1219
|
allow: [
|
|
1174
1220
|
sandboxRoot,
|
|
1175
1221
|
pluginDir,
|
|
1176
|
-
|
|
1222
|
+
path11.resolve(pluginDir, "../../")
|
|
1177
1223
|
]
|
|
1178
1224
|
}
|
|
1179
1225
|
},
|
|
1180
1226
|
resolve: {
|
|
1181
1227
|
alias: {
|
|
1182
1228
|
...coreAlias,
|
|
1183
|
-
"react":
|
|
1184
|
-
"react-dom":
|
|
1185
|
-
"@":
|
|
1229
|
+
"react": path11.join(sandboxNodeModules, "react"),
|
|
1230
|
+
"react-dom": path11.join(sandboxNodeModules, "react-dom"),
|
|
1231
|
+
"@": path11.join(shellDir, "src"),
|
|
1186
1232
|
// 关键:将虚拟模块指向用户插件
|
|
1187
1233
|
"virtual:user-plugin": pluginEntry,
|
|
1188
1234
|
// 防止 glob 报错,提供空的映射
|
|
1189
|
-
"@chatbi-plugins":
|
|
1190
|
-
"@chatbi-apps":
|
|
1235
|
+
"@chatbi-plugins": path11.join(shellDir, "empty"),
|
|
1236
|
+
"@chatbi-apps": path11.join(shellDir, "empty")
|
|
1191
1237
|
}
|
|
1192
1238
|
},
|
|
1193
1239
|
define
|
|
@@ -1195,9 +1241,9 @@ ${pc4.gray("Root: ")} ${pc4.white(cwd)}`,
|
|
|
1195
1241
|
await server.listen();
|
|
1196
1242
|
const localUrl = `http://localhost:${shellPort}/`;
|
|
1197
1243
|
printBox(
|
|
1198
|
-
`${
|
|
1244
|
+
`${pc5.green(pc5.bold("\u2705 \u6258\u7BA1\u5F0F Shell \u5DF2\u542F\u52A8"))}
|
|
1199
1245
|
|
|
1200
|
-
${
|
|
1246
|
+
${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
|
|
1201
1247
|
"Shell Success"
|
|
1202
1248
|
);
|
|
1203
1249
|
} catch (e) {
|
|
@@ -1207,12 +1253,16 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
|
|
|
1207
1253
|
/**
|
|
1208
1254
|
* 启动应用开发服务器 (Integrated Mode)
|
|
1209
1255
|
*/
|
|
1210
|
-
static async startAppDevServer(appDir, version, customPort) {
|
|
1256
|
+
static async startAppDevServer(appDir, version, customPort, isMonorepo = false) {
|
|
1211
1257
|
logger.info("\u6B63\u5728\u542F\u52A8\u5E94\u7528...");
|
|
1212
1258
|
const versionPath = Sandbox.getVersionPath(version);
|
|
1213
|
-
const sandboxNodeModules =
|
|
1214
|
-
const
|
|
1215
|
-
const
|
|
1259
|
+
const sandboxNodeModules = path11.join(versionPath, "node_modules");
|
|
1260
|
+
const pkgPath = path11.join(appDir, "package.json");
|
|
1261
|
+
const pkg = await fs9.readJson(pkgPath).catch(() => ({}));
|
|
1262
|
+
const hasCoreDep = pkg.dependencies?.["@chatbi-v/core"] || pkg.devDependencies?.["@chatbi-v/core"];
|
|
1263
|
+
const shouldUseSandboxAlias = !(isMonorepo && hasCoreDep);
|
|
1264
|
+
const coreAlias = shouldUseSandboxAlias ? Sandbox.getCoreAlias(version) : {};
|
|
1265
|
+
const { createServer, loadConfigFromFile, searchForWorkspaceRoot } = await import("vite");
|
|
1216
1266
|
try {
|
|
1217
1267
|
const configContext = { command: "serve", mode: "development" };
|
|
1218
1268
|
const userConfig = await loadConfigFromFile(configContext, void 0, appDir).catch(() => null);
|
|
@@ -1224,9 +1274,12 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
|
|
|
1224
1274
|
alias: {
|
|
1225
1275
|
...coreAlias,
|
|
1226
1276
|
// 补充常用的基础依赖映射,防止用户 vite.config.ts 中的插件找不到依赖
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1277
|
+
// 只有在需要使用沙箱时才注入 React Alias
|
|
1278
|
+
...shouldUseSandboxAlias ? {
|
|
1279
|
+
"react": path11.join(sandboxNodeModules, "react"),
|
|
1280
|
+
"react-dom": path11.join(sandboxNodeModules, "react-dom"),
|
|
1281
|
+
"@vitejs/plugin-react": path11.join(sandboxNodeModules, "@vitejs/plugin-react")
|
|
1282
|
+
} : {}
|
|
1230
1283
|
}
|
|
1231
1284
|
},
|
|
1232
1285
|
server: {
|
|
@@ -1242,6 +1295,7 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
|
|
|
1242
1295
|
},
|
|
1243
1296
|
fs: {
|
|
1244
1297
|
allow: [
|
|
1298
|
+
searchForWorkspaceRoot(appDir),
|
|
1245
1299
|
Sandbox.getRoot(),
|
|
1246
1300
|
appDir,
|
|
1247
1301
|
// 允许访问沙箱中的所有依赖
|
|
@@ -1253,9 +1307,9 @@ ${pc4.white("Local: ")} ${pc4.cyan(pc4.underline(localUrl))}`,
|
|
|
1253
1307
|
await server.listen();
|
|
1254
1308
|
const localUrl = `http://localhost:${server.config.server.port}/`;
|
|
1255
1309
|
printBox(
|
|
1256
|
-
`${
|
|
1310
|
+
`${pc5.green(pc5.bold("\u2705 \u5E94\u7528\u5DF2\u6210\u529F\u542F\u52A8"))}
|
|
1257
1311
|
|
|
1258
|
-
${
|
|
1312
|
+
${pc5.white("Local: ")} ${pc5.cyan(pc5.underline(localUrl))}`,
|
|
1259
1313
|
"App Success"
|
|
1260
1314
|
);
|
|
1261
1315
|
} catch (e) {
|
|
@@ -1271,19 +1325,19 @@ var build_exports = {};
|
|
|
1271
1325
|
__export(build_exports, {
|
|
1272
1326
|
build: () => build
|
|
1273
1327
|
});
|
|
1274
|
-
import { execa as
|
|
1275
|
-
import
|
|
1276
|
-
import
|
|
1277
|
-
import
|
|
1328
|
+
import { execa as execa3 } from "execa";
|
|
1329
|
+
import fs10 from "fs-extra";
|
|
1330
|
+
import path12 from "path";
|
|
1331
|
+
import pc6 from "picocolors";
|
|
1278
1332
|
import { build as tsupBuild } from "tsup";
|
|
1279
1333
|
async function build(options) {
|
|
1280
1334
|
const cwd = process.cwd();
|
|
1281
|
-
const pkgPath =
|
|
1282
|
-
if (!
|
|
1335
|
+
const pkgPath = path12.join(cwd, "package.json");
|
|
1336
|
+
if (!fs10.existsSync(pkgPath)) {
|
|
1283
1337
|
logger.error(`\u5728 ${cwd} \u4E2D\u672A\u627E\u5230 package.json`);
|
|
1284
1338
|
return;
|
|
1285
1339
|
}
|
|
1286
|
-
const pkg = await
|
|
1340
|
+
const pkg = await fs10.readJson(pkgPath);
|
|
1287
1341
|
if (options.force) {
|
|
1288
1342
|
const spinnerClean = createSpinner("\u6B63\u5728\u6E05\u7406\u7F13\u5B58\u73AF\u5883...").start();
|
|
1289
1343
|
try {
|
|
@@ -1295,24 +1349,24 @@ async function build(options) {
|
|
|
1295
1349
|
}
|
|
1296
1350
|
}
|
|
1297
1351
|
const version = await CoreKit.resolveVersion(cwd);
|
|
1298
|
-
logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${
|
|
1352
|
+
logger.info(`\u6B63\u5728\u6784\u5EFA\u9879\u76EE: ${pc6.bold(pkg.name || "unnamed")} (\u5185\u6838\u7248\u672C: ${version})
|
|
1299
1353
|
`);
|
|
1300
1354
|
const spinner = createSpinner("\u6B63\u5728\u51C6\u5907\u6784\u5EFA\u73AF\u5883...").start();
|
|
1301
1355
|
spinner.text = "\u6B63\u5728\u540C\u6B65\u6C99\u7BB1\u5185\u6838...";
|
|
1302
1356
|
await Sandbox.prepare(version, options.force);
|
|
1303
|
-
if (pkg.workspaces ||
|
|
1357
|
+
if (pkg.workspaces || fs10.existsSync(path12.join(cwd, "pnpm-workspace.yaml"))) {
|
|
1304
1358
|
spinner.text = "\u68C0\u6D4B\u5230 Monorepo\uFF0C\u6B63\u5728\u521D\u59CB\u5316\u6839\u76EE\u5F55\u4E0A\u4E0B\u6587...";
|
|
1305
1359
|
await Sandbox.injectContext(cwd, version);
|
|
1306
1360
|
spinner.text = "\u6B63\u5728\u540C\u6B65\u5B50\u5305\u4E0A\u4E0B\u6587...";
|
|
1307
1361
|
const subDirs = ["apps", "plugins", "packages"];
|
|
1308
1362
|
for (const dir of subDirs) {
|
|
1309
|
-
const dirPath =
|
|
1310
|
-
if (
|
|
1311
|
-
const entries = await
|
|
1363
|
+
const dirPath = path12.join(cwd, dir);
|
|
1364
|
+
if (fs10.existsSync(dirPath)) {
|
|
1365
|
+
const entries = await fs10.readdir(dirPath, { withFileTypes: true });
|
|
1312
1366
|
for (const entry2 of entries) {
|
|
1313
1367
|
if (entry2.isDirectory()) {
|
|
1314
|
-
const subPkgPath =
|
|
1315
|
-
if (
|
|
1368
|
+
const subPkgPath = path12.join(dirPath, entry2.name);
|
|
1369
|
+
if (fs10.existsSync(path12.join(subPkgPath, "package.json"))) {
|
|
1316
1370
|
await Sandbox.injectContext(subPkgPath, version);
|
|
1317
1371
|
}
|
|
1318
1372
|
}
|
|
@@ -1326,12 +1380,12 @@ async function build(options) {
|
|
|
1326
1380
|
if (pkg.scripts && pkg.scripts.build && !process.env.CHATBI_CLI_INTERNAL) {
|
|
1327
1381
|
const buildScript = pkg.scripts.build;
|
|
1328
1382
|
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: ${
|
|
1383
|
+
logger.info(`\u68C0\u6D4B\u5230\u81EA\u5B9A\u4E49 build \u811A\u672C\uFF0C\u6B63\u5728\u6267\u884C: ${pc6.cyan("npm run build")}`);
|
|
1330
1384
|
const args = ["run", "build"];
|
|
1331
1385
|
if (options.watch) {
|
|
1332
1386
|
args.push("--", "--watch");
|
|
1333
1387
|
}
|
|
1334
|
-
await
|
|
1388
|
+
await execa3("npm", args, {
|
|
1335
1389
|
stdio: "inherit",
|
|
1336
1390
|
env: { ...process.env, CHATBI_CLI_INTERNAL: "true" }
|
|
1337
1391
|
});
|
|
@@ -1341,7 +1395,7 @@ async function build(options) {
|
|
|
1341
1395
|
const mode = await CoreKit.detectMode(cwd);
|
|
1342
1396
|
if (mode === "monorepo") {
|
|
1343
1397
|
logger.info("\u68C0\u6D4B\u5230 Monorepo \u9879\u76EE\uFF0C\u6B63\u5728\u9012\u5F52\u6784\u5EFA\u5B50\u5305...");
|
|
1344
|
-
await
|
|
1398
|
+
await execa3("pnpm", ["-r", "build"], { stdio: "inherit", cwd });
|
|
1345
1399
|
return;
|
|
1346
1400
|
}
|
|
1347
1401
|
if (mode === "app") {
|
|
@@ -1350,7 +1404,7 @@ async function build(options) {
|
|
|
1350
1404
|
const coreAlias = Sandbox.getCoreAlias(version);
|
|
1351
1405
|
await viteBuild({
|
|
1352
1406
|
root: cwd,
|
|
1353
|
-
configFile:
|
|
1407
|
+
configFile: fs10.existsSync(path12.join(cwd, "vite.config.ts")) ? void 0 : false,
|
|
1354
1408
|
resolve: {
|
|
1355
1409
|
alias: {
|
|
1356
1410
|
...coreAlias
|
|
@@ -1374,16 +1428,16 @@ async function build(options) {
|
|
|
1374
1428
|
});
|
|
1375
1429
|
if (!options.watch) {
|
|
1376
1430
|
printBox(
|
|
1377
|
-
|
|
1431
|
+
pc6.green(pc6.bold("\u2728 \u5E94\u7528\u6784\u5EFA\u6210\u529F!")) + "\n\n" + pc6.white("\u4EA7\u7269\u76EE\u5F55: ") + pc6.cyan("dist"),
|
|
1378
1432
|
"Build Success"
|
|
1379
1433
|
);
|
|
1380
1434
|
}
|
|
1381
1435
|
return;
|
|
1382
1436
|
}
|
|
1383
1437
|
let entry = ["src/index.ts"];
|
|
1384
|
-
if (
|
|
1438
|
+
if (fs10.existsSync(path12.join(cwd, "src/index.tsx"))) {
|
|
1385
1439
|
entry = ["src/index.tsx"];
|
|
1386
|
-
} else if (!
|
|
1440
|
+
} else if (!fs10.existsSync(path12.join(cwd, "src/index.ts"))) {
|
|
1387
1441
|
logger.error("\u672A\u627E\u5230\u5165\u53E3\u6587\u4EF6\u3002\u671F\u671B src/index.ts \u6216 src/index.tsx");
|
|
1388
1442
|
return;
|
|
1389
1443
|
}
|
|
@@ -1393,10 +1447,10 @@ async function build(options) {
|
|
|
1393
1447
|
logger.info(`\u5DF2\u52A0\u8F7D\u672C\u5730\u6784\u5EFA\u914D\u7F6E`);
|
|
1394
1448
|
}
|
|
1395
1449
|
if (!options.watch) {
|
|
1396
|
-
await
|
|
1397
|
-
const tsbuildinfo =
|
|
1398
|
-
if (
|
|
1399
|
-
await
|
|
1450
|
+
await fs10.remove(path12.join(cwd, "dist"));
|
|
1451
|
+
const tsbuildinfo = path12.join(cwd, "tsconfig.tsbuildinfo");
|
|
1452
|
+
if (fs10.existsSync(tsbuildinfo)) {
|
|
1453
|
+
await fs10.remove(tsbuildinfo);
|
|
1400
1454
|
}
|
|
1401
1455
|
}
|
|
1402
1456
|
if (isPlugin) {
|
|
@@ -1486,31 +1540,31 @@ async function build(options) {
|
|
|
1486
1540
|
if (!options.watch) {
|
|
1487
1541
|
const dtsSpinner = createSpinner("\u6B63\u5728\u751F\u6210\u7C7B\u578B\u5B9A\u4E49...").start();
|
|
1488
1542
|
try {
|
|
1489
|
-
const localTsc =
|
|
1490
|
-
const sandboxTsc =
|
|
1543
|
+
const localTsc = path12.join(cwd, "node_modules/.bin/tsc");
|
|
1544
|
+
const sandboxTsc = path12.join(Sandbox.getVersionPath(version), "node_modules/.bin/tsc");
|
|
1491
1545
|
let tscBin = "tsc";
|
|
1492
|
-
if (
|
|
1546
|
+
if (fs10.existsSync(localTsc)) {
|
|
1493
1547
|
tscBin = localTsc;
|
|
1494
|
-
} else if (
|
|
1548
|
+
} else if (fs10.existsSync(sandboxTsc)) {
|
|
1495
1549
|
tscBin = sandboxTsc;
|
|
1496
1550
|
} else {
|
|
1497
|
-
if (
|
|
1498
|
-
await
|
|
1551
|
+
if (fs10.existsSync(path12.join(cwd, "pnpm-lock.yaml"))) {
|
|
1552
|
+
await execa3("pnpm", ["exec", "tsc", "--build", "tsconfig.json"]);
|
|
1499
1553
|
dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
|
|
1500
1554
|
} else {
|
|
1501
|
-
await
|
|
1555
|
+
await execa3("npx", ["-p", "typescript", "tsc", "--build", "tsconfig.json"]);
|
|
1502
1556
|
dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
|
|
1503
1557
|
}
|
|
1504
1558
|
}
|
|
1505
1559
|
if (tscBin !== "tsc") {
|
|
1506
|
-
await
|
|
1560
|
+
await execa3(tscBin, ["--build", "tsconfig.json"]);
|
|
1507
1561
|
dtsSpinner.succeed("\u7C7B\u578B\u5B9A\u4E49\u751F\u6210\u5B8C\u6210");
|
|
1508
1562
|
}
|
|
1509
1563
|
} catch (e) {
|
|
1510
1564
|
dtsSpinner.warn("\u7C7B\u578B\u751F\u6210\u5931\u8D25\uFF0C\u8BF7\u68C0\u67E5\u9879\u76EE\u4E2D\u7684 tsconfig.json \u914D\u7F6E");
|
|
1511
1565
|
}
|
|
1512
1566
|
printBox(
|
|
1513
|
-
|
|
1567
|
+
pc6.green(pc6.bold("\u2728 \u6784\u5EFA\u5B8C\u6210!")) + "\n\n" + pc6.white("\u4EA7\u7269\u76EE\u5F55: ") + pc6.cyan("dist") + "\n" + pc6.white("\u6784\u5EFA\u6A21\u5F0F: ") + pc6.cyan(isPlugin ? "Plugin" : "Library"),
|
|
1514
1568
|
"Build Success"
|
|
1515
1569
|
);
|
|
1516
1570
|
}
|
|
@@ -1519,9 +1573,9 @@ var init_build = __esm({
|
|
|
1519
1573
|
"src/commands/build.ts"() {
|
|
1520
1574
|
"use strict";
|
|
1521
1575
|
init_esm_shims();
|
|
1522
|
-
init_sandbox();
|
|
1523
|
-
init_corekit();
|
|
1524
1576
|
init_config();
|
|
1577
|
+
init_corekit();
|
|
1578
|
+
init_sandbox();
|
|
1525
1579
|
init_utils();
|
|
1526
1580
|
}
|
|
1527
1581
|
});
|
|
@@ -1531,17 +1585,17 @@ var sync_exports = {};
|
|
|
1531
1585
|
__export(sync_exports, {
|
|
1532
1586
|
sync: () => sync
|
|
1533
1587
|
});
|
|
1534
|
-
import
|
|
1535
|
-
import
|
|
1536
|
-
import
|
|
1588
|
+
import fs11 from "fs-extra";
|
|
1589
|
+
import path13 from "path";
|
|
1590
|
+
import pc8 from "picocolors";
|
|
1537
1591
|
async function sync(options = {}) {
|
|
1538
1592
|
const cwd = options.cwd || process.cwd();
|
|
1539
|
-
const pkgPath =
|
|
1540
|
-
if (!
|
|
1593
|
+
const pkgPath = path13.join(cwd, "package.json");
|
|
1594
|
+
if (!fs11.existsSync(pkgPath)) {
|
|
1541
1595
|
logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728\u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u3002");
|
|
1542
1596
|
return;
|
|
1543
1597
|
}
|
|
1544
|
-
const pkg = await
|
|
1598
|
+
const pkg = await fs11.readJson(pkgPath);
|
|
1545
1599
|
let version = options.version;
|
|
1546
1600
|
if (!version) {
|
|
1547
1601
|
version = await CoreKit.resolveVersion(cwd);
|
|
@@ -1556,8 +1610,8 @@ async function sync(options = {}) {
|
|
|
1556
1610
|
await Sandbox.prepare(version, options.force);
|
|
1557
1611
|
mainSpinner.text = "\u6B63\u5728\u751F\u6210\u865A\u62DF\u4E0A\u4E0B\u6587...";
|
|
1558
1612
|
if (options.version) {
|
|
1559
|
-
const versionFilePath =
|
|
1560
|
-
await
|
|
1613
|
+
const versionFilePath = path13.join(cwd, ".chatbi-version");
|
|
1614
|
+
await fs11.writeFile(versionFilePath, version, "utf-8");
|
|
1561
1615
|
}
|
|
1562
1616
|
await Sandbox.injectContext(cwd, version);
|
|
1563
1617
|
let modified = false;
|
|
@@ -1579,19 +1633,19 @@ async function sync(options = {}) {
|
|
|
1579
1633
|
if (modified) {
|
|
1580
1634
|
pkg.dependencies = deps;
|
|
1581
1635
|
pkg.devDependencies = devDeps;
|
|
1582
|
-
await
|
|
1636
|
+
await fs11.writeJson(pkgPath, pkg, { spaces: 2 });
|
|
1583
1637
|
mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210 (\u4F9D\u8D56\u5DF2\u4F18\u5316)");
|
|
1584
1638
|
} else {
|
|
1585
1639
|
mainSpinner.succeed("\u5185\u6838\u540C\u6B65\u5B8C\u6210");
|
|
1586
1640
|
}
|
|
1587
1641
|
if (!options.silent) {
|
|
1588
1642
|
printBox(
|
|
1589
|
-
`${
|
|
1643
|
+
`${pc8.green(pc8.bold("\u2728 \u5185\u6838\u540C\u6B65\u6210\u529F!"))}
|
|
1590
1644
|
|
|
1591
|
-
${
|
|
1592
|
-
${
|
|
1645
|
+
${pc8.white("\u5F53\u524D\u7248\u672C: ")} ${pc8.cyan(version)}
|
|
1646
|
+
${pc8.white("\u6C99\u7BB1\u8DEF\u5F84: ")} ${pc8.gray(Sandbox.getVersionPath(version))}
|
|
1593
1647
|
|
|
1594
|
-
${
|
|
1648
|
+
${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
1649
|
"Sync Success"
|
|
1596
1650
|
);
|
|
1597
1651
|
}
|
|
@@ -1600,24 +1654,68 @@ var init_sync = __esm({
|
|
|
1600
1654
|
"src/commands/sync.ts"() {
|
|
1601
1655
|
"use strict";
|
|
1602
1656
|
init_esm_shims();
|
|
1603
|
-
init_utils();
|
|
1604
|
-
init_sandbox();
|
|
1605
1657
|
init_corekit();
|
|
1658
|
+
init_sandbox();
|
|
1659
|
+
init_utils();
|
|
1606
1660
|
}
|
|
1607
1661
|
});
|
|
1608
1662
|
|
|
1609
|
-
// src/commands/
|
|
1610
|
-
var
|
|
1611
|
-
__export(
|
|
1612
|
-
|
|
1663
|
+
// src/commands/fetch.ts
|
|
1664
|
+
var fetch_exports = {};
|
|
1665
|
+
__export(fetch_exports, {
|
|
1666
|
+
fetch: () => fetch
|
|
1613
1667
|
});
|
|
1614
|
-
import
|
|
1615
|
-
import
|
|
1616
|
-
import
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1668
|
+
import { execa as execa4 } from "execa";
|
|
1669
|
+
import path15 from "path";
|
|
1670
|
+
import pc10 from "picocolors";
|
|
1671
|
+
async function fetch(version, options = {}) {
|
|
1672
|
+
const fetchSpinner = createSpinner(`\u6B63\u5728\u83B7\u53D6\u5185\u6838\u7248\u672C ${pc10.cyan(version)}...`).start();
|
|
1673
|
+
const versionPath = await Sandbox.prepare(version, true);
|
|
1674
|
+
fetchSpinner.succeed(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u83B7\u53D6\u6210\u529F`);
|
|
1675
|
+
if (options.pack) {
|
|
1676
|
+
const packSpinner = createSpinner("\u6B63\u5728\u6253\u5305\u79BB\u7EBF\u8D44\u6E90...").start();
|
|
1677
|
+
const tgzName = `chatbi-core-${version}.tgz`;
|
|
1678
|
+
const tgzPath = path15.resolve(process.cwd(), tgzName);
|
|
1679
|
+
await execa4("tar", [
|
|
1680
|
+
"-czf",
|
|
1681
|
+
tgzPath,
|
|
1682
|
+
"-C",
|
|
1683
|
+
path15.dirname(versionPath),
|
|
1684
|
+
path15.basename(versionPath)
|
|
1685
|
+
]);
|
|
1686
|
+
packSpinner.succeed("\u79BB\u7EBF\u8D44\u6E90\u6253\u5305\u5B8C\u6210");
|
|
1687
|
+
printBox(
|
|
1688
|
+
`${pc10.green(pc10.bold("\u2728 \u79BB\u7EBF\u5305\u5DF2\u751F\u6210!"))}
|
|
1689
|
+
|
|
1690
|
+
${pc10.white("\u6587\u4EF6\u8DEF\u5F84: ")} ${pc10.cyan(tgzPath)}
|
|
1691
|
+
${pc10.white("\u5B89\u88C5\u547D\u4EE4: ")} ${pc10.gray(`chatbi install ${tgzName}`)}`,
|
|
1692
|
+
"Pack Success"
|
|
1693
|
+
);
|
|
1694
|
+
} else {
|
|
1695
|
+
logger.success(`\u5185\u6838\u7248\u672C ${pc10.cyan(version)} \u5DF2\u51C6\u5907\u5C31\u7EEA\u3002`);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1698
|
+
var init_fetch = __esm({
|
|
1699
|
+
"src/commands/fetch.ts"() {
|
|
1700
|
+
"use strict";
|
|
1701
|
+
init_esm_shims();
|
|
1702
|
+
init_sandbox();
|
|
1703
|
+
init_utils();
|
|
1704
|
+
}
|
|
1705
|
+
});
|
|
1706
|
+
|
|
1707
|
+
// src/commands/init.ts
|
|
1708
|
+
var init_exports = {};
|
|
1709
|
+
__export(init_exports, {
|
|
1710
|
+
init: () => init
|
|
1711
|
+
});
|
|
1712
|
+
import fs14 from "fs-extra";
|
|
1713
|
+
import path17 from "path";
|
|
1714
|
+
import pc12 from "picocolors";
|
|
1715
|
+
import prompts4 from "prompts";
|
|
1716
|
+
async function init(options) {
|
|
1717
|
+
let { name, pluginType = "business", theme = DEFAULT_CONFIG.THEME, projectType, includeApp, includePlugin, cwd } = options;
|
|
1718
|
+
const response = await prompts4([
|
|
1621
1719
|
// ... (prompts remain the same)
|
|
1622
1720
|
{
|
|
1623
1721
|
type: name ? null : "text",
|
|
@@ -1687,32 +1785,32 @@ async function init(options) {
|
|
|
1687
1785
|
const isAppIncluded = finalIncludeApp;
|
|
1688
1786
|
const isPluginIncluded = finalIncludePlugin;
|
|
1689
1787
|
const rootDir = cwd || process.cwd();
|
|
1690
|
-
const targetDir =
|
|
1691
|
-
if (
|
|
1788
|
+
const targetDir = path17.resolve(rootDir, name);
|
|
1789
|
+
if (fs14.existsSync(targetDir)) {
|
|
1692
1790
|
logger.error(`\u76EE\u5F55 ${name} \u5DF2\u5B58\u5728\u3002`);
|
|
1693
1791
|
return;
|
|
1694
1792
|
}
|
|
1695
|
-
logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${
|
|
1696
|
-
logger.info(
|
|
1793
|
+
logger.info(`\u6B63\u5728\u521D\u59CB\u5316\u9879\u76EE: ${pc12.bold(name)}...`);
|
|
1794
|
+
logger.info(pc12.gray(`\u7C7B\u578B: ${projectType} | \u4E3B\u9898: ${theme || "N/A"}`));
|
|
1697
1795
|
console.log("");
|
|
1698
1796
|
try {
|
|
1699
1797
|
const myCliRoot = await getCliRoot();
|
|
1700
|
-
const cliPkg = await
|
|
1798
|
+
const cliPkg = await fs14.readJson(path17.join(myCliRoot, "package.json"));
|
|
1701
1799
|
const cliVersion = cliPkg.version;
|
|
1702
1800
|
const config = { coreSource: "npm" };
|
|
1703
|
-
const kernelVersionFile =
|
|
1704
|
-
if (
|
|
1705
|
-
config.coreVersion = (await
|
|
1801
|
+
const kernelVersionFile = path17.join(myCliRoot, SANDBOX_CONFIG.LOCK_FILE);
|
|
1802
|
+
if (fs14.existsSync(kernelVersionFile)) {
|
|
1803
|
+
config.coreVersion = (await fs14.readFile(kernelVersionFile, "utf-8")).trim();
|
|
1706
1804
|
}
|
|
1707
1805
|
const kernelVersion = await ConfigManager.resolveCoreDependency(config);
|
|
1708
1806
|
const renderTemplate = async (templateName, destDir, extraData = {}) => {
|
|
1709
|
-
const srcDir =
|
|
1710
|
-
if (!
|
|
1807
|
+
const srcDir = path17.join(myCliRoot, "templates", templateName);
|
|
1808
|
+
if (!fs14.existsSync(srcDir)) {
|
|
1711
1809
|
throw new Error(`\u627E\u4E0D\u5230\u6A21\u677F: ${templateName}\uFF0C\u8BF7\u68C0\u67E5\u8DEF\u5F84 ${srcDir} \u662F\u5426\u6B63\u786E\u3002`);
|
|
1712
1810
|
}
|
|
1713
|
-
await
|
|
1811
|
+
await fs14.ensureDir(destDir);
|
|
1714
1812
|
const templateData = {
|
|
1715
|
-
name:
|
|
1813
|
+
name: path17.basename(destDir),
|
|
1716
1814
|
projectName: name,
|
|
1717
1815
|
// Original project name from CLI argument
|
|
1718
1816
|
projectTitle: name.split("-").map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join(" "),
|
|
@@ -1740,12 +1838,12 @@ async function init(options) {
|
|
|
1740
1838
|
await renderTemplate("monorepo", targetDir, { name });
|
|
1741
1839
|
if (isAppIncluded) {
|
|
1742
1840
|
spinner.text = "\u6B63\u5728\u751F\u6210 Host App...";
|
|
1743
|
-
const appDir =
|
|
1841
|
+
const appDir = path17.join(targetDir, "apps", "main");
|
|
1744
1842
|
await renderTemplate("app", appDir, { name: "@chatbi-v/main" });
|
|
1745
1843
|
}
|
|
1746
1844
|
if (isPluginIncluded) {
|
|
1747
1845
|
spinner.text = "\u6B63\u5728\u751F\u6210 Demo Plugin...";
|
|
1748
|
-
const pluginDir =
|
|
1846
|
+
const pluginDir = path17.join(targetDir, "plugins", "plugin-demo");
|
|
1749
1847
|
await renderTemplate("plugin", pluginDir, {
|
|
1750
1848
|
name: "@chatbi-v/plugin-demo",
|
|
1751
1849
|
pluginId: "demo",
|
|
@@ -1787,15 +1885,15 @@ async function init(options) {
|
|
|
1787
1885
|
const cliConfig = {
|
|
1788
1886
|
coreVersion: kernelVersion
|
|
1789
1887
|
};
|
|
1790
|
-
await
|
|
1888
|
+
await fs14.writeJson(path17.join(targetDir, "chatbi.config.json"), cliConfig, { spaces: 2 });
|
|
1791
1889
|
configSpinner.succeed("\u9879\u76EE\u914D\u7F6E\u751F\u6210\u5B8C\u6210");
|
|
1792
1890
|
printBox(
|
|
1793
|
-
`${
|
|
1891
|
+
`${pc12.green(pc12.bold("\u2728 \u9879\u76EE\u5DF2\u6210\u529F\u521B\u5EFA!"))}
|
|
1794
1892
|
|
|
1795
|
-
${
|
|
1796
|
-
${
|
|
1797
|
-
${
|
|
1798
|
-
${
|
|
1893
|
+
${pc12.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
|
|
1894
|
+
${pc12.cyan(` cd ${name}`)}
|
|
1895
|
+
${pc12.cyan(" pnpm install")}
|
|
1896
|
+
${pc12.cyan(" pnpm dev")}`,
|
|
1799
1897
|
"Success"
|
|
1800
1898
|
);
|
|
1801
1899
|
} catch (error) {
|
|
@@ -1807,55 +1905,11 @@ var init_init = __esm({
|
|
|
1807
1905
|
"src/commands/init.ts"() {
|
|
1808
1906
|
"use strict";
|
|
1809
1907
|
init_esm_shims();
|
|
1810
|
-
init_utils();
|
|
1811
|
-
init_sync();
|
|
1812
|
-
init_constants();
|
|
1813
1908
|
init_config();
|
|
1909
|
+
init_constants();
|
|
1814
1910
|
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
1911
|
init_utils();
|
|
1912
|
+
init_sync();
|
|
1859
1913
|
}
|
|
1860
1914
|
});
|
|
1861
1915
|
|
|
@@ -1864,14 +1918,14 @@ var bench_exports = {};
|
|
|
1864
1918
|
__export(bench_exports, {
|
|
1865
1919
|
bench: () => bench
|
|
1866
1920
|
});
|
|
1867
|
-
import pc15 from "picocolors";
|
|
1868
1921
|
import fs17 from "fs-extra";
|
|
1922
|
+
import os3 from "os";
|
|
1869
1923
|
import path20 from "path";
|
|
1870
|
-
import
|
|
1924
|
+
import pc15 from "picocolors";
|
|
1871
1925
|
async function bench() {
|
|
1872
1926
|
logger.info("\u6B63\u5728\u542F\u52A8 CLI \u6027\u80FD\u57FA\u51C6\u6D4B\u8BD5...");
|
|
1873
1927
|
const results = [];
|
|
1874
|
-
const tmpDir = path20.join(
|
|
1928
|
+
const tmpDir = path20.join(os3.tmpdir(), `chatbi-bench-${Date.now()}`);
|
|
1875
1929
|
await fs17.ensureDir(tmpDir);
|
|
1876
1930
|
try {
|
|
1877
1931
|
const initSpinner = createSpinner("\u6B63\u5728\u6D4B\u8BD5: \u521D\u59CB\u5316\u63D2\u4EF6\u9879\u76EE (init)...").start();
|
|
@@ -1934,54 +1988,104 @@ var init_bench = __esm({
|
|
|
1934
1988
|
|
|
1935
1989
|
// src/index.ts
|
|
1936
1990
|
init_esm_shims();
|
|
1937
|
-
|
|
1991
|
+
import boxen2 from "boxen";
|
|
1938
1992
|
import cac from "cac";
|
|
1939
|
-
import pc16 from "picocolors";
|
|
1940
1993
|
import figlet from "figlet";
|
|
1941
1994
|
import gradient from "gradient-string";
|
|
1942
|
-
import
|
|
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
|
-
}
|
|
1995
|
+
import pc16 from "picocolors";
|
|
1951
1996
|
|
|
1952
|
-
//
|
|
1953
|
-
|
|
1997
|
+
// package.json
|
|
1998
|
+
var package_default = {
|
|
1999
|
+
name: "@chatbi-v/cli",
|
|
2000
|
+
version: "2.1.8",
|
|
2001
|
+
description: "Standardized CLI tooling for ChatBI Monorepo",
|
|
2002
|
+
type: "module",
|
|
2003
|
+
main: "dist/index.js",
|
|
2004
|
+
module: "dist/index.js",
|
|
2005
|
+
types: "dist/index.d.ts",
|
|
2006
|
+
exports: {
|
|
2007
|
+
".": {
|
|
2008
|
+
types: "./dist/index.d.ts",
|
|
2009
|
+
import: "./dist/index.js"
|
|
2010
|
+
},
|
|
2011
|
+
"./package.json": "./package.json"
|
|
2012
|
+
},
|
|
2013
|
+
bin: {
|
|
2014
|
+
"chatbi-cli": "./bin/chatbi-cli.js"
|
|
2015
|
+
},
|
|
2016
|
+
files: [
|
|
2017
|
+
"dist",
|
|
2018
|
+
"bin",
|
|
2019
|
+
"templates"
|
|
2020
|
+
],
|
|
2021
|
+
publishConfig: {
|
|
2022
|
+
access: "public"
|
|
2023
|
+
},
|
|
2024
|
+
scripts: {
|
|
2025
|
+
build: "tsup",
|
|
2026
|
+
dev: "tsup --watch",
|
|
2027
|
+
test: "vitest"
|
|
2028
|
+
},
|
|
2029
|
+
dependencies: {
|
|
2030
|
+
boxen: "^8.0.1",
|
|
2031
|
+
cac: "^6.7.14",
|
|
2032
|
+
execa: "^8.0.1",
|
|
2033
|
+
"fast-glob": "^3.3.3",
|
|
2034
|
+
figlet: "^1.9.4",
|
|
2035
|
+
"fs-extra": "^11.2.0",
|
|
2036
|
+
"gradient-string": "^3.0.0",
|
|
2037
|
+
handlebars: "^4.7.8",
|
|
2038
|
+
jiti: "^2.6.1",
|
|
2039
|
+
ora: "^7.0.1",
|
|
2040
|
+
picocolors: "^1.0.0",
|
|
2041
|
+
prompts: "^2.4.2",
|
|
2042
|
+
tsup: "^8.5.1",
|
|
2043
|
+
typescript: "^5.0.0",
|
|
2044
|
+
vite: "^5.4.21"
|
|
2045
|
+
},
|
|
2046
|
+
devDependencies: {
|
|
2047
|
+
"@types/boxen": "^3.0.5",
|
|
2048
|
+
"@types/figlet": "^1.7.0",
|
|
2049
|
+
"@types/fs-extra": "^11.0.0",
|
|
2050
|
+
"@types/gradient-string": "^1.1.6",
|
|
2051
|
+
"@types/node": "^20.0.0",
|
|
2052
|
+
"@types/prompts": "^2.4.9",
|
|
2053
|
+
"@vitest/coverage-v8": "1.6.1",
|
|
2054
|
+
tsup: "^8.5.1",
|
|
2055
|
+
vitest: "^1.0.0"
|
|
2056
|
+
}
|
|
2057
|
+
};
|
|
1954
2058
|
|
|
1955
2059
|
// src/commands/add.ts
|
|
1956
2060
|
init_esm_shims();
|
|
1957
|
-
init_utils();
|
|
1958
2061
|
init_config();
|
|
1959
2062
|
init_constants();
|
|
1960
2063
|
init_SandboxRenderer();
|
|
1961
|
-
|
|
1962
|
-
import
|
|
1963
|
-
import
|
|
1964
|
-
import
|
|
1965
|
-
import
|
|
2064
|
+
init_utils();
|
|
2065
|
+
import fs4 from "fs-extra";
|
|
2066
|
+
import { createRequire as createRequire2 } from "module";
|
|
2067
|
+
import path6 from "path";
|
|
2068
|
+
import pc2 from "picocolors";
|
|
2069
|
+
import prompts from "prompts";
|
|
1966
2070
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
1967
|
-
var _require2 =
|
|
2071
|
+
var _require2 = createRequire2(import.meta.url);
|
|
1968
2072
|
var _filename2 = fileURLToPath3(import.meta.url);
|
|
1969
|
-
var _dirname2 =
|
|
2073
|
+
var _dirname2 = path6.dirname(_filename2);
|
|
1970
2074
|
async function add(options) {
|
|
1971
2075
|
let { name, type, displayName, description } = options;
|
|
1972
2076
|
const cwd = process.cwd();
|
|
1973
|
-
const pkgPath =
|
|
1974
|
-
if (!
|
|
2077
|
+
const pkgPath = path6.join(cwd, "package.json");
|
|
2078
|
+
if (!fs4.existsSync(pkgPath)) {
|
|
1975
2079
|
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
2080
|
return;
|
|
1977
2081
|
}
|
|
1978
|
-
const pkg = await
|
|
2082
|
+
const pkg = await fs4.readJson(pkgPath);
|
|
1979
2083
|
const isMonorepo = pkg.workspaces && (pkg.workspaces.includes("plugins/*") || pkg.workspaces.packages?.includes("plugins/*"));
|
|
1980
2084
|
if (!isMonorepo) {
|
|
1981
2085
|
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
2086
|
process.exit(1);
|
|
1983
2087
|
}
|
|
1984
|
-
const response = await
|
|
2088
|
+
const response = await prompts([
|
|
1985
2089
|
{
|
|
1986
2090
|
type: name ? null : "text",
|
|
1987
2091
|
name: "pluginName",
|
|
@@ -2026,12 +2130,12 @@ async function add(options) {
|
|
|
2026
2130
|
cleanName = cleanName.replace(/-plugin$/, "");
|
|
2027
2131
|
}
|
|
2028
2132
|
const folderName = cleanName.startsWith("plugin-") ? cleanName : `plugin-${cleanName}`;
|
|
2029
|
-
const pluginDir =
|
|
2030
|
-
if (
|
|
2133
|
+
const pluginDir = path6.resolve(cwd, "plugins", folderName);
|
|
2134
|
+
if (fs4.existsSync(pluginDir)) {
|
|
2031
2135
|
logger.error(`\u63D2\u4EF6\u76EE\u5F55 ${folderName} \u5DF2\u5B58\u5728\u3002`);
|
|
2032
2136
|
return;
|
|
2033
2137
|
}
|
|
2034
|
-
const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${
|
|
2138
|
+
const spinner = createSpinner(`\u6B63\u5728\u6DFB\u52A0\u65B0\u63D2\u4EF6: ${pc2.bold(name)}...`).start();
|
|
2035
2139
|
const targetDir = pluginDir;
|
|
2036
2140
|
spinner.text = "\u6B63\u5728\u52A0\u8F7D\u914D\u7F6E...";
|
|
2037
2141
|
const config = await ConfigManager.loadConfig(cwd);
|
|
@@ -2057,199 +2161,95 @@ async function add(options) {
|
|
|
2057
2161
|
tsconfigPath: `../../${SANDBOX_CONFIG.DIRS.CACHE}/tsconfig.json`
|
|
2058
2162
|
};
|
|
2059
2163
|
const myCliRoot = await getCliRoot();
|
|
2060
|
-
let templateDir = myCliRoot ?
|
|
2164
|
+
let templateDir = myCliRoot ? path6.join(myCliRoot, "templates/plugin") : "";
|
|
2061
2165
|
if (process.env.NODE_ENV === "test" && !templateDir) {
|
|
2062
2166
|
templateDir = "/mock/templates/plugin";
|
|
2063
2167
|
}
|
|
2064
2168
|
if (process.env.NODE_ENV === "test") {
|
|
2065
|
-
spinner.succeed(`\u63D2\u4EF6 ${
|
|
2066
|
-
console.log(`\u63D2\u4EF6 ${
|
|
2169
|
+
spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
|
|
2170
|
+
console.log(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
|
|
2067
2171
|
console.log("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!");
|
|
2068
2172
|
return;
|
|
2069
2173
|
}
|
|
2070
|
-
if (!templateDir || !
|
|
2174
|
+
if (!templateDir || !fs4.existsSync(templateDir)) {
|
|
2071
2175
|
spinner.fail("\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F");
|
|
2072
2176
|
throw new Error(`\u627E\u4E0D\u5230\u63D2\u4EF6\u6A21\u677F: ${templateDir || "undefined"}`);
|
|
2073
2177
|
}
|
|
2074
2178
|
spinner.text = "\u6B63\u5728\u751F\u6210\u63D2\u4EF6\u6587\u4EF6...";
|
|
2075
2179
|
await SandboxRenderer.renderDirectory(templateDir, targetDir, data);
|
|
2076
|
-
spinner.succeed(`\u63D2\u4EF6 ${
|
|
2180
|
+
spinner.succeed(`\u63D2\u4EF6 ${pc2.bold(name)} \u6DFB\u52A0\u6210\u529F\uFF01`);
|
|
2077
2181
|
printBox(
|
|
2078
|
-
`${
|
|
2182
|
+
`${pc2.green(pc2.bold("\u2728 \u63D2\u4EF6\u521B\u5EFA\u6210\u529F!"))}
|
|
2079
2183
|
|
|
2080
|
-
${
|
|
2081
|
-
${
|
|
2082
|
-
${
|
|
2184
|
+
${pc2.white("\u9879\u76EE\u8DEF\u5F84: ")} ${pc2.cyan(`plugins/${folderName}`)}
|
|
2185
|
+
${pc2.white("\u63D2\u4EF6 ID: ")} ${pc2.cyan(cleanName)}
|
|
2186
|
+
${pc2.white("\u63D2\u4EF6\u7C7B\u578B: ")} ${pc2.cyan(type)}
|
|
2083
2187
|
|
|
2084
|
-
${
|
|
2085
|
-
${
|
|
2188
|
+
${pc2.white("\u63A5\u4E0B\u6765\u4F60\u53EF\u4EE5:")}
|
|
2189
|
+
${pc2.cyan(" pnpm dev")} \u542F\u52A8\u5F00\u53D1\u73AF\u5883\u67E5\u770B\u6548\u679C`,
|
|
2086
2190
|
"Plugin Created"
|
|
2087
2191
|
);
|
|
2088
2192
|
}
|
|
2089
2193
|
|
|
2090
|
-
// src/
|
|
2194
|
+
// src/index.ts
|
|
2195
|
+
init_build();
|
|
2196
|
+
|
|
2197
|
+
// src/commands/clean.ts
|
|
2198
|
+
init_esm_shims();
|
|
2199
|
+
init_sandbox();
|
|
2200
|
+
async function clean(options) {
|
|
2201
|
+
const cwd = process.cwd();
|
|
2202
|
+
await Sandbox.clean(cwd, options.deep);
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2205
|
+
// src/commands/dev.ts
|
|
2206
|
+
init_esm_shims();
|
|
2207
|
+
init_corekit();
|
|
2208
|
+
async function dev(options = {}) {
|
|
2209
|
+
const cwd = process.cwd();
|
|
2210
|
+
await CoreKit.startDev(cwd, options);
|
|
2211
|
+
}
|
|
2212
|
+
|
|
2213
|
+
// src/commands/discover.ts
|
|
2091
2214
|
init_esm_shims();
|
|
2215
|
+
init_corekit();
|
|
2092
2216
|
init_utils();
|
|
2093
|
-
import
|
|
2094
|
-
|
|
2095
|
-
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;
|
|
2217
|
+
import pc7 from "picocolors";
|
|
2218
|
+
async function discover() {
|
|
2100
2219
|
const cwd = process.cwd();
|
|
2101
|
-
const
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
{
|
|
2108
|
-
|
|
2109
|
-
|
|
2110
|
-
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
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;
|
|
2220
|
+
const spinner = createSpinner("\u6B63\u5728\u626B\u63CF\u9879\u76EE\u4E2D\u7684\u63D2\u4EF6...").start();
|
|
2221
|
+
const plugins = await CoreKit.discoverPlugins(cwd);
|
|
2222
|
+
if (plugins.length === 0) {
|
|
2223
|
+
spinner.warn("\u672A\u53D1\u73B0\u4EFB\u4F55\u63D2\u4EF6");
|
|
2224
|
+
logger.info(pc7.gray("\u8BF7\u786E\u4FDD\u63D2\u4EF6\u4F4D\u4E8E plugins/ \u76EE\u5F55\u4E0B\uFF0C\u4E14\u5305\u542B package.json\u3002"));
|
|
2225
|
+
} else {
|
|
2226
|
+
spinner.succeed(`\u53D1\u73B0\u4E86 ${pc7.cyan(plugins.length)} \u4E2A\u63D2\u4EF6`);
|
|
2227
|
+
const pluginList = plugins.map((p) => `- ${pc7.bold(p.name)} ${pc7.gray(`(${p.id})`)}
|
|
2228
|
+
${pc7.gray(p.path)}`).join("\n\n");
|
|
2229
|
+
printBox(
|
|
2230
|
+
`${pc7.green(pc7.bold("\u2728 \u63D2\u4EF6\u626B\u63CF\u7ED3\u679C"))}
|
|
2231
|
+
|
|
2232
|
+
${pluginList}`,
|
|
2233
|
+
"Plugin Discovery"
|
|
2234
|
+
);
|
|
2140
2235
|
}
|
|
2141
|
-
|
|
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();
|
|
2236
|
+
}
|
|
2237
2237
|
|
|
2238
2238
|
// src/commands/doctor.ts
|
|
2239
2239
|
init_esm_shims();
|
|
2240
|
-
init_utils();
|
|
2241
|
-
init_sandbox();
|
|
2242
2240
|
init_corekit();
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
import pc10 from "picocolors";
|
|
2241
|
+
init_sandbox();
|
|
2242
|
+
init_utils();
|
|
2246
2243
|
import glob from "fast-glob";
|
|
2244
|
+
import fs12 from "fs-extra";
|
|
2245
|
+
import path14 from "path";
|
|
2246
|
+
import pc9 from "picocolors";
|
|
2247
2247
|
async function doctor(options = {}) {
|
|
2248
2248
|
logger.info("\u6B63\u5728\u8BCA\u65AD\u9879\u76EE\u5065\u5EB7\u72B6\u51B5...\n");
|
|
2249
2249
|
const cwd = process.cwd();
|
|
2250
2250
|
let hasIssues = false;
|
|
2251
2251
|
const issues = [];
|
|
2252
|
-
logger.info(
|
|
2252
|
+
logger.info(pc9.bold("Step 1: \u68C0\u67E5\u57FA\u7840\u73AF\u5883..."));
|
|
2253
2253
|
const nodeVersion = process.version;
|
|
2254
2254
|
if (parseInt(nodeVersion.slice(1).split(".")[0]) < 18) {
|
|
2255
2255
|
logger.error(`Node.js \u7248\u672C\u592A\u4F4E: ${nodeVersion} (\u8981\u6C42 >=18)`);
|
|
@@ -2259,47 +2259,47 @@ async function doctor(options = {}) {
|
|
|
2259
2259
|
logger.success(`Node.js \u7248\u672C: ${nodeVersion}`);
|
|
2260
2260
|
}
|
|
2261
2261
|
try {
|
|
2262
|
-
const { execa:
|
|
2263
|
-
const { stdout: pnpmVer } = await
|
|
2262
|
+
const { execa: execa7 } = await import("execa");
|
|
2263
|
+
const { stdout: pnpmVer } = await execa7("pnpm", ["-v"]);
|
|
2264
2264
|
logger.success(`pnpm \u7248\u672C: ${pnpmVer}`);
|
|
2265
2265
|
} catch (e) {
|
|
2266
2266
|
logger.warn("\u672A\u68C0\u6D4B\u5230 pnpm\uFF0C\u5EFA\u8BAE\u5B89\u88C5\u4EE5\u83B7\u5F97\u6700\u4F73\u4F53\u9A8C");
|
|
2267
2267
|
}
|
|
2268
|
-
logger.info(
|
|
2268
|
+
logger.info(pc9.bold("\nStep 2: \u68C0\u67E5\u5185\u6838\u6C99\u7BB1\u73AF\u5883..."));
|
|
2269
2269
|
const version = await CoreKit.resolveVersion(cwd);
|
|
2270
2270
|
const versionPath = Sandbox.getVersionPath(version);
|
|
2271
|
-
if (!
|
|
2271
|
+
if (!fs12.existsSync(versionPath)) {
|
|
2272
2272
|
logger.error(`\u5185\u6838\u6C99\u7BB1\u7248\u672C ${version} \u5C1A\u672A\u5B89\u88C5`);
|
|
2273
|
-
console.log(
|
|
2273
|
+
console.log(pc9.gray(` \u5EFA\u8BAE\u8FD0\u884C 'chatbi sync' \u6216 'chatbi use ${version}' \u8FDB\u884C\u5B89\u88C5\u3002`));
|
|
2274
2274
|
hasIssues = true;
|
|
2275
2275
|
issues.push(`\u5185\u6838\u6C99\u7BB1\u672A\u5B89\u88C5 (${version})`);
|
|
2276
2276
|
} else {
|
|
2277
2277
|
logger.success(`\u5185\u6838\u6C99\u7BB1\u5C31\u7EEA (\u7248\u672C: ${version})`);
|
|
2278
|
-
const sandboxNm =
|
|
2279
|
-
if (!
|
|
2278
|
+
const sandboxNm = path14.join(versionPath, "node_modules");
|
|
2279
|
+
if (!fs12.existsSync(sandboxNm)) {
|
|
2280
2280
|
logger.warn("\u6C99\u7BB1\u4F9D\u8D56\u672A\u5B89\u88C5\uFF0C\u5C06\u5BFC\u81F4\u6784\u5EFA\u5931\u8D25");
|
|
2281
2281
|
hasIssues = true;
|
|
2282
2282
|
issues.push("\u6C99\u7BB1\u4F9D\u8D56\u7F3A\u5931");
|
|
2283
2283
|
}
|
|
2284
2284
|
const missingDeps = [];
|
|
2285
2285
|
for (const dep of Sandbox.CORE_PACKAGES) {
|
|
2286
|
-
if (!
|
|
2286
|
+
if (!fs12.existsSync(path14.join(sandboxNm, dep))) {
|
|
2287
2287
|
missingDeps.push(dep);
|
|
2288
2288
|
}
|
|
2289
2289
|
}
|
|
2290
2290
|
if (missingDeps.length > 0) {
|
|
2291
2291
|
}
|
|
2292
2292
|
}
|
|
2293
|
-
logger.info(
|
|
2294
|
-
const chatbiDir =
|
|
2295
|
-
if (!
|
|
2293
|
+
logger.info(pc9.bold("\nStep 3: \u68C0\u67E5\u865A\u62DF\u4F9D\u8D56\u6620\u5C04..."));
|
|
2294
|
+
const chatbiDir = path14.join(cwd, ".chatbi");
|
|
2295
|
+
if (!fs12.existsSync(chatbiDir)) {
|
|
2296
2296
|
logger.warn("\u672A\u53D1\u73B0\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E (.chatbi \u76EE\u5F55)");
|
|
2297
2297
|
hasIssues = true;
|
|
2298
2298
|
issues.push("\u7F3A\u5931 .chatbi \u76EE\u5F55");
|
|
2299
2299
|
} else {
|
|
2300
|
-
const pathsJson =
|
|
2301
|
-
const aliasJson =
|
|
2302
|
-
if (!
|
|
2300
|
+
const pathsJson = path14.join(chatbiDir, "tsconfig.paths.json");
|
|
2301
|
+
const aliasJson = path14.join(chatbiDir, "vite.alias.json");
|
|
2302
|
+
if (!fs12.existsSync(pathsJson) || !fs12.existsSync(aliasJson)) {
|
|
2303
2303
|
logger.warn("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B8C\u6574");
|
|
2304
2304
|
hasIssues = true;
|
|
2305
2305
|
issues.push("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u4E0D\u5B8C\u6574");
|
|
@@ -2307,10 +2307,10 @@ async function doctor(options = {}) {
|
|
|
2307
2307
|
logger.success("\u865A\u62DF\u4F9D\u8D56\u914D\u7F6E\u5DF2\u751F\u6210");
|
|
2308
2308
|
}
|
|
2309
2309
|
}
|
|
2310
|
-
const tsConfigPath =
|
|
2311
|
-
if (
|
|
2310
|
+
const tsConfigPath = path14.join(cwd, "tsconfig.json");
|
|
2311
|
+
if (fs12.existsSync(tsConfigPath)) {
|
|
2312
2312
|
try {
|
|
2313
|
-
const tsConfig = await
|
|
2313
|
+
const tsConfig = await fs12.readJson(tsConfigPath);
|
|
2314
2314
|
const extendsPath = tsConfig.extends;
|
|
2315
2315
|
const expectedPaths = ["./.chatbi/tsconfig.paths.json", ".chatbi/tsconfig.paths.json"];
|
|
2316
2316
|
let hasExtend = false;
|
|
@@ -2330,14 +2330,14 @@ async function doctor(options = {}) {
|
|
|
2330
2330
|
logger.error("\u89E3\u6790 tsconfig.json \u5931\u8D25");
|
|
2331
2331
|
}
|
|
2332
2332
|
}
|
|
2333
|
-
const viteConfigPath =
|
|
2334
|
-
if (
|
|
2335
|
-
const content = await
|
|
2333
|
+
const viteConfigPath = path14.join(cwd, "vite.config.ts");
|
|
2334
|
+
if (fs12.existsSync(viteConfigPath)) {
|
|
2335
|
+
const content = await fs12.readFile(viteConfigPath, "utf-8");
|
|
2336
2336
|
if (!content.includes("vite.alias.json")) {
|
|
2337
2337
|
logger.warn("vite.config.ts \u53EF\u80FD\u672A\u52A0\u8F7D\u865A\u62DF\u522B\u540D\u914D\u7F6E");
|
|
2338
2338
|
}
|
|
2339
2339
|
}
|
|
2340
|
-
logger.info(
|
|
2340
|
+
logger.info(pc9.bold("\nStep 4: \u626B\u63CF\u4EE3\u7801\u89C4\u5219..."));
|
|
2341
2341
|
const rules = [
|
|
2342
2342
|
{
|
|
2343
2343
|
id: "plugin-lifecycle-init",
|
|
@@ -2357,7 +2357,7 @@ async function doctor(options = {}) {
|
|
|
2357
2357
|
if (files.length > 0) {
|
|
2358
2358
|
const scanSpinner = createSpinner(`\u6B63\u5728\u626B\u63CF ${files.length} \u4E2A\u6587\u4EF6...`).start();
|
|
2359
2359
|
for (const file of files) {
|
|
2360
|
-
const content = await
|
|
2360
|
+
const content = await fs12.readFile(file, "utf-8");
|
|
2361
2361
|
for (const rule of rules) {
|
|
2362
2362
|
if (rule.pattern.test(content)) {
|
|
2363
2363
|
codeIssues.push({
|
|
@@ -2373,7 +2373,7 @@ async function doctor(options = {}) {
|
|
|
2373
2373
|
scanSpinner.fail(`\u53D1\u73B0 ${codeIssues.length} \u4E2A\u4EE3\u7801\u89C4\u8303\u95EE\u9898`);
|
|
2374
2374
|
hasIssues = true;
|
|
2375
2375
|
codeIssues.forEach((issue) => {
|
|
2376
|
-
const relativePath =
|
|
2376
|
+
const relativePath = path14.relative(cwd, issue.file);
|
|
2377
2377
|
issues.push(`\u4EE3\u7801\u89C4\u8303 [${issue.ruleId}]: ${relativePath}`);
|
|
2378
2378
|
});
|
|
2379
2379
|
} else {
|
|
@@ -2382,26 +2382,26 @@ async function doctor(options = {}) {
|
|
|
2382
2382
|
}
|
|
2383
2383
|
if (!hasIssues) {
|
|
2384
2384
|
printBox(
|
|
2385
|
-
|
|
2385
|
+
pc9.green(pc9.bold("\u2728 \u8BCA\u65AD\u5B8C\u6210\uFF1A\u9879\u76EE\u4E00\u5207\u6B63\u5E38\uFF01")),
|
|
2386
2386
|
"Doctor Report"
|
|
2387
2387
|
);
|
|
2388
2388
|
} else {
|
|
2389
|
-
const issueList = issues.map((i) =>
|
|
2389
|
+
const issueList = issues.map((i) => pc9.red(`\u2022 ${i}`)).join("\n");
|
|
2390
2390
|
printBox(
|
|
2391
|
-
`${
|
|
2391
|
+
`${pc9.yellow(pc9.bold("\u26A0\uFE0F \u8BCA\u65AD\u5B8C\u6210\uFF1A\u53D1\u73B0\u4EE5\u4E0B\u95EE\u9898"))}
|
|
2392
2392
|
|
|
2393
2393
|
${issueList}
|
|
2394
2394
|
|
|
2395
|
-
${
|
|
2395
|
+
${pc9.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
|
|
2396
2396
|
"Doctor Report"
|
|
2397
2397
|
);
|
|
2398
2398
|
if (options.fix) {
|
|
2399
2399
|
if (codeIssues.length > 0) {
|
|
2400
2400
|
const fixSpinner = createSpinner("\u6B63\u5728\u4FEE\u590D\u4EE3\u7801\u89C4\u8303\u95EE\u9898...").start();
|
|
2401
2401
|
for (const issue of codeIssues) {
|
|
2402
|
-
const content = await
|
|
2402
|
+
const content = await fs12.readFile(issue.file, "utf-8");
|
|
2403
2403
|
const newContent = issue.rule.fix(content);
|
|
2404
|
-
await
|
|
2404
|
+
await fs12.writeFile(issue.file, newContent);
|
|
2405
2405
|
}
|
|
2406
2406
|
fixSpinner.succeed("\u4EE3\u7801\u4FEE\u590D\u5B8C\u6210");
|
|
2407
2407
|
}
|
|
@@ -2413,28 +2413,198 @@ ${pc10.cyan("\u5EFA\u8BAE\u6839\u636E\u63D0\u793A\u8FDB\u884C\u4FEE\u590D")}`,
|
|
|
2413
2413
|
}
|
|
2414
2414
|
}
|
|
2415
2415
|
|
|
2416
|
-
// src/
|
|
2416
|
+
// src/index.ts
|
|
2417
|
+
init_fetch();
|
|
2418
|
+
|
|
2419
|
+
// src/commands/gl.ts
|
|
2417
2420
|
init_esm_shims();
|
|
2418
|
-
init_corekit();
|
|
2419
2421
|
init_utils();
|
|
2422
|
+
import { execa as execa5 } from "execa";
|
|
2423
|
+
import fs13 from "fs-extra";
|
|
2424
|
+
import path16 from "path";
|
|
2420
2425
|
import pc11 from "picocolors";
|
|
2421
|
-
|
|
2426
|
+
import prompts3 from "prompts";
|
|
2427
|
+
async function gl(options) {
|
|
2428
|
+
const { type: initialType, prompt: initialPrompt } = options;
|
|
2422
2429
|
const cwd = process.cwd();
|
|
2423
|
-
const
|
|
2424
|
-
|
|
2425
|
-
|
|
2426
|
-
|
|
2427
|
-
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2430
|
+
const pkgPath = path16.join(cwd, "package.json");
|
|
2431
|
+
if (!fs13.existsSync(pkgPath)) {
|
|
2432
|
+
logger.error("\u672A\u627E\u5230 package.json\u3002\u8BF7\u5728 ChatBI-V \u9879\u76EE\u6839\u76EE\u5F55\u4E0B\u8FD0\u884C\u6B64\u547D\u4EE4\u3002");
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
const response = await prompts3([
|
|
2436
|
+
{
|
|
2437
|
+
type: initialType ? null : "select",
|
|
2438
|
+
name: "genType",
|
|
2439
|
+
message: "\u8BF7\u9009\u62E9 AI \u811A\u624B\u67B6\u6307\u4EE4:",
|
|
2440
|
+
choices: [
|
|
2441
|
+
{ title: "\u{1F916} smart", value: "smart", description: "\u667A\u80FD\u51B3\u7B56 (\u6839\u636E\u9700\u6C42\u81EA\u52A8\u9009\u62E9\u5DE5\u5177)" },
|
|
2442
|
+
{ title: "\u{1F50C} plugin", value: "plugin", description: "\u751F\u6210\u65B0\u63D2\u4EF6" },
|
|
2443
|
+
{ title: "\u{1F9E9} component", value: "component", description: "\u751F\u6210\u4E1A\u52A1\u7EC4\u4EF6" },
|
|
2444
|
+
{ title: "\u{1F4E1} api", value: "api", description: "\u751F\u6210 API \u5B9A\u4E49\u4E0E\u8BF7\u6C42\u51FD\u6570" },
|
|
2445
|
+
{ title: "\u{1F3AD} mock", value: "mock", description: "\u751F\u6210 Mock \u6D4B\u8BD5\u6570\u636E" },
|
|
2446
|
+
{ title: "\u{1F6E0}\uFE0F util", value: "util", description: "\u751F\u6210\u5DE5\u5177\u51FD\u6570" },
|
|
2447
|
+
{ title: "\u{1F4C4} doc", value: "doc", description: "\u751F\u6210\u9879\u76EE\u6587\u6863" },
|
|
2448
|
+
{ title: "\u2728 chat", value: "chat", description: "\u81EA\u7531\u5BF9\u8BDD" }
|
|
2449
|
+
],
|
|
2450
|
+
initial: 0
|
|
2451
|
+
},
|
|
2452
|
+
{
|
|
2453
|
+
type: (prev, values) => initialPrompt || values.genType === "chat" ? null : "text",
|
|
2454
|
+
name: "userPrompt",
|
|
2455
|
+
message: "\u8BF7\u8F93\u5165\u8BE6\u7EC6\u9700\u6C42\u63CF\u8FF0:",
|
|
2456
|
+
initial: initialPrompt || ""
|
|
2457
|
+
}
|
|
2458
|
+
], {
|
|
2459
|
+
onCancel: () => {
|
|
2460
|
+
logger.warn("\u5DF2\u53D6\u6D88 AI \u751F\u6210");
|
|
2461
|
+
process.exit(0);
|
|
2462
|
+
}
|
|
2463
|
+
});
|
|
2464
|
+
const genType = initialType || response.genType;
|
|
2465
|
+
const userPrompt = initialPrompt || response.userPrompt;
|
|
2466
|
+
if (!userPrompt && genType !== "chat") {
|
|
2467
|
+
logger.error("\u9700\u6C42\u63CF\u8FF0\u4E0D\u80FD\u4E3A\u7A7A\u3002");
|
|
2468
|
+
return;
|
|
2469
|
+
}
|
|
2470
|
+
logger.info(`\u6B63\u5728\u547C\u53EB AI \u5F15\u64CE [\u6A21\u5F0F: ${pc11.bold(genType)}]...`);
|
|
2471
|
+
const toolsContext = `
|
|
2472
|
+
[Available Tools & Capabilities]
|
|
2473
|
+
- Tool: plugin -> For creating new feature modules. Requires: name, type (business|system).
|
|
2474
|
+
- Tool: component -> For UI elements. Tech: AntD5, Tailwind.
|
|
2475
|
+
- Tool: api -> For network requests. Structure: src/api/[name].ts, uses shared request util, defines TS interfaces.
|
|
2476
|
+
- Tool: mock -> For dev data. Structure: mock/[name].ts, follows Mock.js or MSW format.
|
|
2477
|
+
- Tool: util -> For pure functions. Structure: src/utils/[name].ts, requires unit tests.
|
|
2478
|
+
- Tool: doc -> For documentation. Format: Markdown, structure: docs/[type]/[name].md.
|
|
2434
2479
|
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2480
|
+
[Tool Functions Implementation Details]
|
|
2481
|
+
- API Function: Should include request method, URL, params/data types, and response type. Use '@chatbi-v/core/request'.
|
|
2482
|
+
- Mock Function: Should provide realistic data based on API definition.
|
|
2483
|
+
- Plugin Function: Should follow the Micro-Kernel architecture, registering to 'pluginManager'.
|
|
2484
|
+
|
|
2485
|
+
[Requirement Slots / Missing Info]
|
|
2486
|
+
If the user's request is ambiguous or missing key information, you MUST output: "SLOT_REQUIRED: [Field Name] | [Question to User]".
|
|
2487
|
+
`.trim();
|
|
2488
|
+
const templatesContext = `
|
|
2489
|
+
[Project Templates Structure]
|
|
2490
|
+
- Plugin: class extends Plugin, metadata: { id, name, version, type, routes, extensions }.
|
|
2491
|
+
- API: export const fetchData = (params: T) => request.get<R>('/url', { params }).
|
|
2492
|
+
- Mock: export default { 'GET /api/test': { code: 200, data: {} } }.
|
|
2493
|
+
- UI: React 18, Ant Design 5, Tailwind CSS 3.
|
|
2494
|
+
`.trim();
|
|
2495
|
+
const systemContext = `[Context: ChatBI-V System | Dir: ${cwd} | Tech: React18, AntD5, Tailwind, Micro-Kernel]
|
|
2496
|
+
${toolsContext}
|
|
2497
|
+
${templatesContext}
|
|
2498
|
+
|
|
2499
|
+
[Decision Logic]
|
|
2500
|
+
If genType is 'smart', you must first decide which tool is most appropriate.
|
|
2501
|
+
If the requirement is clear, proceed with generation.
|
|
2502
|
+
If not, use the SLOT_REQUIRED format.`.trim();
|
|
2503
|
+
const finalPrompt = userPrompt ? `${systemContext}
|
|
2504
|
+
|
|
2505
|
+
[User Request]: ${userPrompt}` : systemContext;
|
|
2506
|
+
const geminiCmd = genType === "smart" ? "chat" : genType;
|
|
2507
|
+
const spinner = createSpinner("AI \u5F15\u64CE\u6B63\u5728\u601D\u8003\u4E2D... (\u53EF\u80FD\u9700\u8981\u51E0\u5341\u79D2\uFF0C\u8BF7\u8010\u5FC3\u7B49\u5F85)");
|
|
2508
|
+
let currentPrompt = finalPrompt;
|
|
2509
|
+
let retry = true;
|
|
2510
|
+
while (retry) {
|
|
2511
|
+
spinner.start();
|
|
2512
|
+
try {
|
|
2513
|
+
const { stdout } = await execa5("gemini", [geminiCmd, currentPrompt], {
|
|
2514
|
+
stdio: "pipe"
|
|
2515
|
+
});
|
|
2516
|
+
spinner.stop();
|
|
2517
|
+
if (stdout.includes("SLOT_REQUIRED:")) {
|
|
2518
|
+
const slots = [];
|
|
2519
|
+
const lines = stdout.split("\n");
|
|
2520
|
+
for (const line of lines) {
|
|
2521
|
+
if (line.includes("SLOT_REQUIRED:")) {
|
|
2522
|
+
const match = line.match(/SLOT_REQUIRED:\s*([^|]+)\|\s*(.+)/);
|
|
2523
|
+
if (match) {
|
|
2524
|
+
slots.push({
|
|
2525
|
+
type: "text",
|
|
2526
|
+
name: match[1].trim(),
|
|
2527
|
+
message: match[2].trim()
|
|
2528
|
+
});
|
|
2529
|
+
}
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
if (slots.length > 0) {
|
|
2533
|
+
logger.info(pc11.yellow("\n\u{1F4DD} AI \u9700\u8981\u66F4\u591A\u4FE1\u606F\u4EE5\u7EE7\u7EED:"));
|
|
2534
|
+
const answers = await prompts3(slots, {
|
|
2535
|
+
onCancel: () => process.exit(0)
|
|
2536
|
+
});
|
|
2537
|
+
const answerContext = Object.entries(answers).map(([k, v]) => `[${k}]: ${v}`).join("\n");
|
|
2538
|
+
currentPrompt += `
|
|
2539
|
+
|
|
2540
|
+
[User Answers]:
|
|
2541
|
+
${answerContext}
|
|
2542
|
+
|
|
2543
|
+
Please proceed with generation based on these answers.`;
|
|
2544
|
+
logger.info("\u6B63\u5728\u6839\u636E\u60A8\u7684\u53CD\u9988\u91CD\u65B0\u547C\u53EB AI...");
|
|
2545
|
+
continue;
|
|
2546
|
+
}
|
|
2547
|
+
}
|
|
2548
|
+
console.log("\n" + stdout);
|
|
2549
|
+
retry = false;
|
|
2550
|
+
logger.success(`AI \u547D\u4EE4 [gemini ${geminiCmd}] \u6267\u884C\u5B8C\u6BD5!`);
|
|
2551
|
+
} catch (error) {
|
|
2552
|
+
spinner.stop();
|
|
2553
|
+
if (error.code === "ENOENT") {
|
|
2554
|
+
logger.error("\u672A\u5728\u7CFB\u7EDF\u4E2D\u627E\u5230 `gemini-cli` \u547D\u4EE4\u3002");
|
|
2555
|
+
logger.info(pc11.yellow("\u8BF7\u786E\u4FDD\u5DF2\u5B89\u88C5 gemini-cli \u5E76\u5C06\u5176\u6DFB\u52A0\u5230\u7CFB\u7EDF PATH \u4E2D\u3002"));
|
|
2556
|
+
} else {
|
|
2557
|
+
logger.error(`AI \u751F\u6210\u8FC7\u7A0B\u4E2D\u51FA\u9519: ${error.message}`);
|
|
2558
|
+
}
|
|
2559
|
+
throw error;
|
|
2560
|
+
}
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
|
|
2564
|
+
// src/index.ts
|
|
2565
|
+
init_init();
|
|
2566
|
+
|
|
2567
|
+
// src/commands/install.ts
|
|
2568
|
+
init_esm_shims();
|
|
2569
|
+
init_sandbox();
|
|
2570
|
+
init_utils();
|
|
2571
|
+
import { execa as execa6 } from "execa";
|
|
2572
|
+
import fs15 from "fs-extra";
|
|
2573
|
+
import path18 from "path";
|
|
2574
|
+
import pc13 from "picocolors";
|
|
2575
|
+
async function install(target) {
|
|
2576
|
+
if (target.endsWith(".tgz") && fs15.existsSync(target)) {
|
|
2577
|
+
const spinner = createSpinner(`\u6B63\u5728\u5B89\u88C5\u672C\u5730\u79BB\u7EBF\u5305: ${pc13.bold(target)}...`).start();
|
|
2578
|
+
try {
|
|
2579
|
+
const tgzPath = path18.resolve(target);
|
|
2580
|
+
const match = path18.basename(target).match(/chatbi-core-(.+)\.tgz/);
|
|
2581
|
+
let version = "unknown";
|
|
2582
|
+
if (match) {
|
|
2583
|
+
version = match[1];
|
|
2584
|
+
}
|
|
2585
|
+
if (version === "unknown") {
|
|
2586
|
+
spinner.warn("\u65E0\u6CD5\u4ECE\u6587\u4EF6\u540D\u8BC6\u522B\u7248\u672C\uFF0C\u5C06\u4F7F\u7528\u5F53\u524D\u65F6\u95F4\u6233\u4F5C\u4E3A\u7248\u672C\u53F7");
|
|
2587
|
+
version = `local-${Date.now()}`;
|
|
2588
|
+
}
|
|
2589
|
+
const versionRoot = Sandbox.getVersionRoot();
|
|
2590
|
+
await fs15.ensureDir(versionRoot);
|
|
2591
|
+
spinner.text = "\u6B63\u5728\u89E3\u538B\u6587\u4EF6...";
|
|
2592
|
+
await execa6("tar", ["-xzf", tgzPath, "-C", versionRoot]);
|
|
2593
|
+
spinner.succeed(`\u672C\u5730\u5305\u5DF2\u5B89\u88C5\u81F3\u6C99\u7BB1: ${version}`);
|
|
2594
|
+
spinner.text = "\u6B63\u5728\u51C6\u5907\u5185\u6838\u73AF\u5883...";
|
|
2595
|
+
await Sandbox.prepare(version);
|
|
2596
|
+
spinner.succeed("\u5185\u6838\u73AF\u5883\u5C31\u7EEA");
|
|
2597
|
+
printBox(
|
|
2598
|
+
pc13.green(pc13.bold("\u2728 \u672C\u5730\u5185\u6838\u5B89\u88C5\u6210\u529F!")) + "\n\n" + pc13.white("\u7248\u672C: ") + pc13.cyan(version) + "\n" + pc13.white("\u8DEF\u5F84: ") + pc13.gray(Sandbox.getVersionPath(version)),
|
|
2599
|
+
"Install Success"
|
|
2600
|
+
);
|
|
2601
|
+
} catch (e) {
|
|
2602
|
+
spinner.fail("\u5B89\u88C5\u5931\u8D25");
|
|
2603
|
+
throw e;
|
|
2604
|
+
}
|
|
2605
|
+
} else {
|
|
2606
|
+
const { fetch: fetch2 } = await Promise.resolve().then(() => (init_fetch(), fetch_exports));
|
|
2607
|
+
await fetch2(target);
|
|
2438
2608
|
}
|
|
2439
2609
|
}
|
|
2440
2610
|
|
|
@@ -2443,7 +2613,7 @@ init_esm_shims();
|
|
|
2443
2613
|
init_corekit();
|
|
2444
2614
|
init_sandbox();
|
|
2445
2615
|
init_utils();
|
|
2446
|
-
import
|
|
2616
|
+
import pc14 from "picocolors";
|
|
2447
2617
|
async function ls() {
|
|
2448
2618
|
const versions = await CoreKit.listVersions();
|
|
2449
2619
|
const currentVersion = await CoreKit.resolveVersion(process.cwd());
|
|
@@ -2457,36 +2627,39 @@ async function ls() {
|
|
|
2457
2627
|
const isProjectCurrent = v === currentVersion;
|
|
2458
2628
|
let prefix = " ";
|
|
2459
2629
|
if (isProjectCurrent) {
|
|
2460
|
-
prefix =
|
|
2630
|
+
prefix = pc14.green(" *");
|
|
2461
2631
|
} else if (isGlobalCurrent) {
|
|
2462
|
-
prefix =
|
|
2632
|
+
prefix = pc14.blue(" >");
|
|
2463
2633
|
}
|
|
2464
2634
|
let suffix = "";
|
|
2465
2635
|
if (isProjectCurrent && isGlobalCurrent) {
|
|
2466
|
-
suffix =
|
|
2636
|
+
suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE & \u5168\u5C40)");
|
|
2467
2637
|
} else if (isProjectCurrent) {
|
|
2468
|
-
suffix =
|
|
2638
|
+
suffix = pc14.gray(" (\u5F53\u524D\u9879\u76EE)");
|
|
2469
2639
|
} else if (isGlobalCurrent) {
|
|
2470
|
-
suffix =
|
|
2640
|
+
suffix = pc14.gray(" (\u5168\u5C40)");
|
|
2471
2641
|
}
|
|
2472
|
-
return `${prefix} ${
|
|
2642
|
+
return `${prefix} ${pc14.white(v)}${suffix}`;
|
|
2473
2643
|
}).join("\n");
|
|
2474
2644
|
printBox(
|
|
2475
|
-
list +
|
|
2645
|
+
list + pc14.gray("\n\n\u63D0\u793A: * \u5F53\u524D\u9879\u76EE\u4F7F\u7528, > \u5168\u5C40\u9ED8\u8BA4\u4F7F\u7528"),
|
|
2476
2646
|
"Kernel Versions"
|
|
2477
2647
|
);
|
|
2478
2648
|
}
|
|
2479
2649
|
await Sandbox.visualizeStatus(process.cwd());
|
|
2480
2650
|
}
|
|
2481
2651
|
|
|
2652
|
+
// src/index.ts
|
|
2653
|
+
init_sync();
|
|
2654
|
+
|
|
2482
2655
|
// src/commands/use.ts
|
|
2483
2656
|
init_esm_shims();
|
|
2484
|
-
init_sandbox();
|
|
2485
2657
|
init_corekit();
|
|
2486
|
-
|
|
2658
|
+
init_sandbox();
|
|
2487
2659
|
init_utils();
|
|
2488
|
-
|
|
2489
|
-
import
|
|
2660
|
+
init_sync();
|
|
2661
|
+
import fs16 from "fs-extra";
|
|
2662
|
+
import path19 from "path";
|
|
2490
2663
|
async function use(version, options = {}) {
|
|
2491
2664
|
const versions = await CoreKit.listVersions();
|
|
2492
2665
|
if (!versions.includes(version)) {
|
|
@@ -2498,123 +2671,13 @@ async function use(version, options = {}) {
|
|
|
2498
2671
|
logger.success(`\u5DF2\u5207\u6362\u5168\u5C40\u5185\u6838\u7248\u672C\u81F3: ${version}`);
|
|
2499
2672
|
} else {
|
|
2500
2673
|
const cwd = process.cwd();
|
|
2501
|
-
const versionFilePath =
|
|
2502
|
-
await
|
|
2674
|
+
const versionFilePath = path19.join(cwd, ".chatbi-version");
|
|
2675
|
+
await fs16.writeFile(versionFilePath, version, "utf-8");
|
|
2503
2676
|
logger.success(`\u5DF2\u5207\u6362\u5F53\u524D\u9879\u76EE\u5185\u6838\u7248\u672C\u4E3A: ${version}`);
|
|
2504
2677
|
}
|
|
2505
2678
|
await sync({ version, force: false });
|
|
2506
2679
|
}
|
|
2507
2680
|
|
|
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
2681
|
// src/index.ts
|
|
2619
2682
|
init_utils();
|
|
2620
2683
|
var cli = cac("chatbi-cli");
|
|
@@ -2634,12 +2697,18 @@ var showHeader = () => {
|
|
|
2634
2697
|
};
|
|
2635
2698
|
var wrapAction = (action, commandName) => {
|
|
2636
2699
|
return async (...args) => {
|
|
2700
|
+
const updateCheckPromise = checkForUpdates(package_default.version);
|
|
2637
2701
|
showHeader();
|
|
2638
2702
|
try {
|
|
2639
2703
|
await action(...args);
|
|
2640
2704
|
} catch (e) {
|
|
2641
2705
|
logger.error(`${commandName} \u6267\u884C\u5931\u8D25`, e);
|
|
2642
2706
|
process.exit(1);
|
|
2707
|
+
} finally {
|
|
2708
|
+
const latestVersion = await updateCheckPromise;
|
|
2709
|
+
if (latestVersion) {
|
|
2710
|
+
printUpdateNotification(package_default.version, latestVersion);
|
|
2711
|
+
}
|
|
2643
2712
|
}
|
|
2644
2713
|
};
|
|
2645
2714
|
};
|
|
@@ -2695,3 +2764,12 @@ if (process.argv.length <= 2) {
|
|
|
2695
2764
|
} else {
|
|
2696
2765
|
cli.parse();
|
|
2697
2766
|
}
|
|
2767
|
+
var main = async () => {
|
|
2768
|
+
if (process.argv.includes("--help") || process.argv.includes("-h") || process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
2769
|
+
const latestVersion = await checkForUpdates(package_default.version);
|
|
2770
|
+
if (latestVersion) {
|
|
2771
|
+
printUpdateNotification(package_default.version, latestVersion);
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
};
|
|
2775
|
+
main();
|