xiaozhi-client 0.0.1 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  小智 AI 客户端,目前主要用于 MCP 的对接
4
4
 
5
- ![效果图](./docs/preview.png)
5
+ ![效果图](./docs/images/preview.png)
6
6
 
7
7
  ## 安装和使用
8
8
 
@@ -91,6 +91,64 @@ xiaozhi restart
91
91
  - Commander.js (CLI 框架)
92
92
  - Chalk (终端颜色)
93
93
  - Ora (加载动画)
94
+ - Biome (代码格式化和检查)
95
+ - Vitest (单元测试)
96
+
97
+ ### 代码质量
98
+
99
+ 项目使用完整的 CI/CD 流程确保代码质量:
100
+
101
+ #### 测试
102
+
103
+ ```bash
104
+ # 运行所有测试
105
+ pnpm run test
106
+
107
+ # 运行测试并生成覆盖率报告
108
+ pnpm run test:coverage
109
+
110
+ # 监听模式运行测试
111
+ pnpm run test:watch
112
+
113
+ # 运行测试UI界面
114
+ pnpm run test:ui
115
+ ```
116
+
117
+ #### 代码检查和格式化
118
+
119
+ ```bash
120
+ # 运行Biome代码检查(CI模式)
121
+ pnpm run ci
122
+
123
+ # 格式化代码
124
+ pnpm run format
125
+
126
+ # 检查格式(不修改文件)
127
+ pnpm run format:check
128
+
129
+ # 运行lint检查
130
+ pnpm run lint:check
131
+
132
+ # 运行lint并自动修复
133
+ pnpm run lint
134
+
135
+ # TypeScript类型检查
136
+ pnpm run type-check
137
+ ```
138
+
139
+ #### CI/CD 流程
140
+
141
+ 每次向 main 分支提交 PR 时,会自动运行以下检查:
142
+
143
+ 1. **TypeScript 类型检查** - 确保没有类型错误
144
+ 2. **Biome 代码检查** - 确保代码格式和质量符合规范
145
+ 3. **单元测试** - 运行所有测试用例并生成覆盖率报告
146
+ 4. **覆盖率检查** - 确保测试覆盖率不低于配置的阈值
147
+ 5. **构建验证** - 确保项目能够正确构建
148
+ 6. **产物验证** - 验证所有必要的构建产物都已生成
149
+ 7. **CLI 可执行性测试** - 确保 CLI 工具可以正常执行
150
+
151
+ 只有所有检查都通过,PR 才能被合并到 main 分支。
94
152
 
95
153
  ### 打包特性
96
154
 
package/dist/cli.cjs CHANGED
@@ -1,452 +1,7 @@
1
1
  #!/usr/bin/env node
2
- "use strict";
3
- var __create = Object.create;
4
- var __defProp = Object.defineProperty;
5
- var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
- var __getOwnPropNames = Object.getOwnPropertyNames;
7
- var __getProtoOf = Object.getPrototypeOf;
8
- var __hasOwnProp = Object.prototype.hasOwnProperty;
9
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
10
- var __copyProps = (to, from, except, desc) => {
11
- if (from && typeof from === "object" || typeof from === "function") {
12
- for (let key of __getOwnPropNames(from))
13
- if (!__hasOwnProp.call(to, key) && key !== except)
14
- __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
- }
16
- return to;
17
- };
18
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
19
- // If the importer is in node compatibility mode or this is not an ESM
20
- // file that has been converted to a CommonJS file using a Babel-
21
- // compatible transform (i.e. "__esModule" has not been set), then set
22
- // "default" to the CommonJS "module.exports" for node compatibility.
23
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
24
- mod
25
- ));
26
- var import_commander = require("commander");
27
- var import_chalk = __toESM(require("chalk"));
28
- var import_ora = __toESM(require("ora"));
29
- var import_child_process = require("child_process");
30
- var import_fs = __toESM(require("fs"));
31
- var import_path = __toESM(require("path"));
32
- var import_os = __toESM(require("os"));
33
- var import_configManager = require("./configManager.cjs");
34
- const program = new import_commander.Command();
35
- const VERSION = "0.0.1";
36
- const SERVICE_NAME = "xiaozhi-mcp-service";
37
- const PID_FILE = import_path.default.join(import_os.default.tmpdir(), `${SERVICE_NAME}.pid`);
38
- const LOG_FILE = import_path.default.join(import_os.default.tmpdir(), `${SERVICE_NAME}.log`);
39
- function getServiceStatus() {
40
- try {
41
- if (!import_fs.default.existsSync(PID_FILE)) {
42
- return { running: false };
43
- }
44
- const pidContent = import_fs.default.readFileSync(PID_FILE, "utf8").trim();
45
- const [pidStr, startTime, mode] = pidContent.split("|");
46
- const pid = parseInt(pidStr);
47
- if (isNaN(pid)) {
48
- import_fs.default.unlinkSync(PID_FILE);
49
- return { running: false };
50
- }
51
- try {
52
- process.kill(pid, 0);
53
- const start = parseInt(startTime);
54
- const uptime = formatUptime(Date.now() - start);
55
- return {
56
- running: true,
57
- pid,
58
- uptime,
59
- mode: mode || "foreground"
60
- };
61
- } catch (error) {
62
- import_fs.default.unlinkSync(PID_FILE);
63
- return { running: false };
64
- }
65
- } catch (error) {
66
- return { running: false };
67
- }
68
- }
69
- __name(getServiceStatus, "getServiceStatus");
70
- function formatUptime(ms) {
71
- const seconds = Math.floor(ms / 1e3);
72
- const minutes = Math.floor(seconds / 60);
73
- const hours = Math.floor(minutes / 60);
74
- const days = Math.floor(hours / 24);
75
- if (days > 0) {
76
- return `${days}\u5929 ${hours % 24}\u5C0F\u65F6 ${minutes % 60}\u5206\u949F`;
77
- } else if (hours > 0) {
78
- return `${hours}\u5C0F\u65F6 ${minutes % 60}\u5206\u949F`;
79
- } else if (minutes > 0) {
80
- return `${minutes}\u5206\u949F ${seconds % 60}\u79D2`;
81
- } else {
82
- return `${seconds}\u79D2`;
83
- }
84
- }
85
- __name(formatUptime, "formatUptime");
86
- function savePidInfo(pid, mode) {
87
- const pidInfo = `${pid}|${Date.now()}|${mode}`;
88
- import_fs.default.writeFileSync(PID_FILE, pidInfo);
89
- }
90
- __name(savePidInfo, "savePidInfo");
91
- function cleanupPidFile() {
92
- try {
93
- if (import_fs.default.existsSync(PID_FILE)) {
94
- import_fs.default.unlinkSync(PID_FILE);
95
- }
96
- } catch (error) {
97
- }
98
- }
99
- __name(cleanupPidFile, "cleanupPidFile");
100
- function checkEnvironment() {
101
- if (!import_configManager.configManager.configExists()) {
102
- console.error(import_chalk.default.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"));
103
- console.log(import_chalk.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));
104
- return false;
105
- }
106
- try {
107
- const endpoint = import_configManager.configManager.getMcpEndpoint();
108
- if (!endpoint || endpoint.includes("<\u8BF7\u586B\u5199")) {
109
- console.error(import_chalk.default.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E"));
110
- console.log(import_chalk.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9'));
111
- return false;
112
- }
113
- return true;
114
- } catch (error) {
115
- console.error(import_chalk.default.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${error instanceof Error ? error.message : String(error)}`));
116
- console.log(import_chalk.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E'));
117
- return false;
118
- }
119
- }
120
- __name(checkEnvironment, "checkEnvironment");
121
- function getServiceCommand() {
122
- const scriptDir = __dirname;
123
- let distDir;
124
- if (scriptDir.includes("js-demo/dist")) {
125
- distDir = scriptDir;
126
- } else {
127
- const possiblePaths = [
128
- import_path.default.join(scriptDir, "..", "js-demo", "dist"),
129
- import_path.default.join(scriptDir, "..", "..", "js-demo", "dist"),
130
- import_path.default.join(scriptDir, "..", "..", "..", "js-demo", "dist"),
131
- import_path.default.join(process.cwd(), "js-demo", "dist"),
132
- import_path.default.join(process.cwd(), "dist")
133
- ];
134
- distDir = possiblePaths.find(
135
- (p) => import_fs.default.existsSync(import_path.default.join(p, "mcpPipe.cjs")) && import_fs.default.existsSync(import_path.default.join(p, "mcpServerProxy.cjs"))
136
- ) || scriptDir;
137
- }
138
- return {
139
- command: "node",
140
- args: ["mcpPipe.cjs", "mcpServerProxy.cjs"],
141
- cwd: distDir
142
- };
143
- }
144
- __name(getServiceCommand, "getServiceCommand");
145
- async function startService(daemon = false) {
146
- const spinner = (0, import_ora.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();
147
- try {
148
- const status = getServiceStatus();
149
- if (status.running) {
150
- spinner.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${status.pid})`);
151
- return;
152
- }
153
- spinner.text = "\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...";
154
- if (!checkEnvironment()) {
155
- spinner.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");
156
- return;
157
- }
158
- const { command, args, cwd } = getServiceCommand();
159
- spinner.text = `\u542F\u52A8\u670D\u52A1 (${daemon ? "\u540E\u53F0\u6A21\u5F0F" : "\u524D\u53F0\u6A21\u5F0F"})...`;
160
- if (daemon) {
161
- const child = (0, import_child_process.spawn)(command, args, {
162
- cwd,
163
- detached: true,
164
- stdio: ["ignore", "pipe", "pipe"],
165
- env: { ...process.env }
166
- });
167
- savePidInfo(child.pid, "daemon");
168
- const logStream = import_fs.default.createWriteStream(LOG_FILE, { flags: "a" });
169
- child.stdout?.pipe(logStream);
170
- child.stderr?.pipe(logStream);
171
- child.unref();
172
- spinner.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${child.pid})`);
173
- console.log(import_chalk.default.gray(`\u65E5\u5FD7\u6587\u4EF6: ${LOG_FILE}`));
174
- console.log(import_chalk.default.gray(`\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7`));
175
- } else {
176
- spinner.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");
177
- const child = (0, import_child_process.spawn)(command, args, {
178
- cwd,
179
- stdio: "inherit",
180
- env: { ...process.env }
181
- });
182
- savePidInfo(child.pid, "foreground");
183
- child.on("exit", (code, signal) => {
184
- cleanupPidFile();
185
- if (code !== 0) {
186
- console.log(import_chalk.default.red(`
187
- \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${code}, \u4FE1\u53F7: ${signal})`));
188
- } else {
189
- console.log(import_chalk.default.green("\n\u670D\u52A1\u5DF2\u505C\u6B62"));
190
- }
191
- });
192
- process.on("SIGINT", () => {
193
- console.log(import_chalk.default.yellow("\n\u6B63\u5728\u505C\u6B62\u670D\u52A1..."));
194
- child.kill("SIGTERM");
195
- });
196
- process.on("SIGTERM", () => {
197
- child.kill("SIGTERM");
198
- });
199
- }
200
- } catch (error) {
201
- spinner.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
202
- }
203
- }
204
- __name(startService, "startService");
205
- async function stopService() {
206
- const spinner = (0, import_ora.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();
207
- try {
208
- const status = getServiceStatus();
209
- if (!status.running) {
210
- spinner.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");
211
- return;
212
- }
213
- spinner.text = `\u505C\u6B62\u670D\u52A1 (PID: ${status.pid})...`;
214
- try {
215
- process.kill(status.pid, "SIGTERM");
216
- let attempts = 0;
217
- const maxAttempts = 30;
218
- while (attempts < maxAttempts) {
219
- await new Promise((resolve) => setTimeout(resolve, 100));
220
- try {
221
- process.kill(status.pid, 0);
222
- attempts++;
223
- } catch {
224
- break;
225
- }
226
- }
227
- try {
228
- process.kill(status.pid, 0);
229
- spinner.text = "\u5F3A\u5236\u505C\u6B62\u670D\u52A1...";
230
- process.kill(status.pid, "SIGKILL");
231
- await new Promise((resolve) => setTimeout(resolve, 500));
232
- } catch {
233
- }
234
- cleanupPidFile();
235
- spinner.succeed("\u670D\u52A1\u5DF2\u505C\u6B62");
236
- } catch (error) {
237
- cleanupPidFile();
238
- spinner.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
239
- }
240
- } catch (error) {
241
- spinner.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
242
- }
243
- }
244
- __name(stopService, "stopService");
245
- async function checkStatus() {
246
- const spinner = (0, import_ora.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();
247
- try {
248
- const status = getServiceStatus();
249
- if (status.running) {
250
- spinner.succeed("\u670D\u52A1\u72B6\u6001");
251
- console.log(import_chalk.default.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C"));
252
- console.log(import_chalk.default.gray(` PID: ${status.pid}`));
253
- console.log(import_chalk.default.gray(` \u8FD0\u884C\u65F6\u95F4: ${status.uptime}`));
254
- console.log(import_chalk.default.gray(` \u8FD0\u884C\u6A21\u5F0F: ${status.mode === "daemon" ? "\u540E\u53F0\u6A21\u5F0F" : "\u524D\u53F0\u6A21\u5F0F"}`));
255
- if (status.mode === "daemon") {
256
- console.log(import_chalk.default.gray(` \u65E5\u5FD7\u6587\u4EF6: ${LOG_FILE}`));
257
- }
258
- } else {
259
- spinner.succeed("\u670D\u52A1\u72B6\u6001");
260
- console.log(import_chalk.default.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C"));
261
- }
262
- } catch (error) {
263
- spinner.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
264
- }
265
- }
266
- __name(checkStatus, "checkStatus");
267
- async function attachService() {
268
- const spinner = (0, import_ora.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();
269
- try {
270
- const status = getServiceStatus();
271
- if (!status.running) {
272
- spinner.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");
273
- return;
274
- }
275
- if (status.mode !== "daemon") {
276
- spinner.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");
277
- return;
278
- }
279
- spinner.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1...");
280
- console.log(import_chalk.default.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${status.pid})`));
281
- console.log(import_chalk.default.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09"));
282
- console.log(import_chalk.default.gray("=".repeat(50)));
283
- if (import_fs.default.existsSync(LOG_FILE)) {
284
- const { spawn: spawn2 } = await import("child_process");
285
- const tail = spawn2("tail", ["-f", LOG_FILE], { stdio: "inherit" });
286
- process.on("SIGINT", () => {
287
- console.log(import_chalk.default.yellow("\n\u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C"));
288
- tail.kill();
289
- process.exit(0);
290
- });
291
- tail.on("exit", () => {
292
- process.exit(0);
293
- });
294
- } else {
295
- console.log(import_chalk.default.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"));
296
- }
297
- } catch (error) {
298
- spinner.fail(`\u8FDE\u63A5\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
299
- }
300
- }
301
- __name(attachService, "attachService");
302
- async function restartService(daemon = false) {
303
- console.log(import_chalk.default.blue("\u{1F504} \u91CD\u542F\u670D\u52A1..."));
304
- await stopService();
305
- await new Promise((resolve) => setTimeout(resolve, 1e3));
306
- await startService(daemon);
307
- }
308
- __name(restartService, "restartService");
309
- function showVersion() {
310
- console.log(import_chalk.default.blue(`xiaozhi v${VERSION}`));
311
- }
312
- __name(showVersion, "showVersion");
313
- function showDetailedInfo() {
314
- console.log(import_chalk.default.blue(`xiaozhi v${VERSION}`));
315
- console.log(import_chalk.default.gray("MCP Calculator Service CLI Tool"));
316
- console.log(import_chalk.default.gray("Built with Node.js and TypeScript"));
317
- console.log(import_chalk.default.gray(`Node.js: ${process.version}`));
318
- console.log(import_chalk.default.gray(`Platform: ${process.platform} ${process.arch}`));
319
- }
320
- __name(showDetailedInfo, "showDetailedInfo");
321
- async function initConfig() {
322
- const spinner = (0, import_ora.default)("\u521D\u59CB\u5316\u914D\u7F6E...").start();
323
- try {
324
- if (import_configManager.configManager.configExists()) {
325
- spinner.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728");
326
- console.log(import_chalk.default.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 config.json \u6587\u4EF6"));
327
- return;
328
- }
329
- import_configManager.configManager.initConfig();
330
- spinner.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F");
331
- console.log(import_chalk.default.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: config.json"));
332
- console.log(import_chalk.default.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:"));
333
- console.log(import_chalk.default.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${import_configManager.configManager.getConfigPath()}`));
334
- console.log(import_chalk.default.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:"));
335
- console.log(import_chalk.default.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"));
336
- } catch (error) {
337
- spinner.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
338
- }
339
- }
340
- __name(initConfig, "initConfig");
341
- async function configCommand(key, value) {
342
- const spinner = (0, import_ora.default)("\u66F4\u65B0\u914D\u7F6E...").start();
343
- try {
344
- if (!import_configManager.configManager.configExists()) {
345
- spinner.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728");
346
- console.log(import_chalk.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));
347
- return;
348
- }
349
- if (!value) {
350
- spinner.text = "\u8BFB\u53D6\u914D\u7F6E...";
351
- const config = import_configManager.configManager.getConfig();
352
- switch (key) {
353
- case "mcpEndpoint":
354
- spinner.succeed("\u914D\u7F6E\u4FE1\u606F");
355
- console.log(import_chalk.default.green(`MCP \u7AEF\u70B9: ${config.mcpEndpoint}`));
356
- break;
357
- case "mcpServers":
358
- spinner.succeed("\u914D\u7F6E\u4FE1\u606F");
359
- console.log(import_chalk.default.green("MCP \u670D\u52A1:"));
360
- for (const [name, serverConfig] of Object.entries(config.mcpServers)) {
361
- console.log(import_chalk.default.gray(` ${name}: ${serverConfig.command} ${serverConfig.args.join(" ")}`));
362
- }
363
- break;
364
- default:
365
- spinner.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${key}`);
366
- console.log(import_chalk.default.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers"));
367
- return;
368
- }
369
- } else {
370
- switch (key) {
371
- case "mcpEndpoint":
372
- import_configManager.configManager.updateMcpEndpoint(value);
373
- spinner.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${value}`);
374
- break;
375
- default:
376
- spinner.fail(`\u914D\u7F6E\u9879 ${key} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`);
377
- console.log(import_chalk.default.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint"));
378
- return;
379
- }
380
- }
381
- } catch (error) {
382
- spinner.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${error instanceof Error ? error.message : String(error)}`);
383
- }
384
- }
385
- __name(configCommand, "configCommand");
386
- function showHelp() {
387
- console.log(import_chalk.default.blue.bold("xiaozhi - MCP Calculator Service CLI"));
388
- console.log();
389
- console.log(import_chalk.default.yellow("\u4F7F\u7528\u65B9\u6CD5:"));
390
- console.log(" xiaozhi <command> [options]");
391
- console.log();
392
- console.log(import_chalk.default.yellow("\u547D\u4EE4:"));
393
- console.log(" init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6");
394
- console.log(" config <key> [value] \u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E");
395
- console.log(" start [--daemon] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)");
396
- console.log(" stop \u505C\u6B62\u670D\u52A1");
397
- console.log(" status \u68C0\u67E5\u670D\u52A1\u72B6\u6001");
398
- console.log(" attach \u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7");
399
- console.log(" restart [--daemon] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)");
400
- console.log();
401
- console.log(import_chalk.default.yellow("\u9009\u9879:"));
402
- console.log(" -v, --version \u663E\u793A\u7248\u672C\u4FE1\u606F");
403
- console.log(" -V \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F");
404
- console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F");
405
- console.log();
406
- console.log(import_chalk.default.yellow("\u914D\u7F6E\u793A\u4F8B:"));
407
- console.log(" xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E");
408
- console.log(" xiaozhi config mcpEndpoint # \u67E5\u770B MCP \u7AEF\u70B9");
409
- console.log(" xiaozhi config mcpEndpoint wss://... # \u8BBE\u7F6E MCP \u7AEF\u70B9");
410
- console.log();
411
- console.log(import_chalk.default.yellow("\u670D\u52A1\u793A\u4F8B:"));
412
- console.log(" xiaozhi start # \u524D\u53F0\u542F\u52A8\u670D\u52A1");
413
- console.log(" xiaozhi start --daemon # \u540E\u53F0\u542F\u52A8\u670D\u52A1");
414
- console.log(" xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001");
415
- console.log(" xiaozhi attach # \u67E5\u770B\u540E\u53F0\u670D\u52A1\u65E5\u5FD7");
416
- console.log(" xiaozhi stop # \u505C\u6B62\u670D\u52A1");
417
- }
418
- __name(showHelp, "showHelp");
419
- program.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(VERSION, "-v, --version", "\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help", "\u663E\u793A\u5E2E\u52A9\u4FE1\u606F");
420
- program.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async () => {
421
- await initConfig();
422
- });
423
- program.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async (key, value) => {
424
- await configCommand(key, value);
425
- });
426
- program.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon", "\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async (options) => {
427
- await startService(options.daemon);
428
- });
429
- program.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async () => {
430
- await stopService();
431
- });
432
- program.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async () => {
433
- await checkStatus();
434
- });
435
- program.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async () => {
436
- await attachService();
437
- });
438
- program.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon", "\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async (options) => {
439
- await restartService(options.daemon);
440
- });
441
- program.option("-V", "\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action((options) => {
442
- if (options.V) {
443
- showDetailedInfo();
444
- process.exit(0);
445
- }
446
- });
447
- if (process.argv.length <= 2) {
448
- showHelp();
449
- process.exit(0);
450
- }
451
- program.parse(process.argv);
2
+ "use strict";var G=Object.create;var v=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var R=Object.getPrototypeOf,A=Object.prototype.hasOwnProperty;var l=(o,e)=>v(o,"name",{value:e,configurable:!0});var V=(o,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of O(e))!A.call(o,s)&&s!==n&&v(o,s,{get:()=>e[s],enumerable:!(i=F(e,s))||i.enumerable});return o};var u=(o,e,n)=>(n=o!=null?G(R(o)):{},V(e||!o||!o.__esModule?v(n,"default",{value:o,enumerable:!0}):n,o));var b=require("node:child_process"),a=u(require("node:fs")),I=u(require("node:os")),g=u(require("node:path")),t=u(require("chalk")),N=require("commander"),f=u(require("ora")),d=require("./configManager.cjs"),h=require("./mcpCommands.cjs");const p=new N.Command,z="0.0.1",E="xiaozhi-mcp-service",y=g.default.join(I.default.tmpdir(),`${E}.pid`),x=g.default.join(I.default.tmpdir(),`${E}.log`);function $(){try{if(!a.default.existsSync(y))return{running:!1};const o=a.default.readFileSync(y,"utf8").trim(),[e,n,i]=o.split("|"),s=Number.parseInt(e);if(Number.isNaN(s))return a.default.unlinkSync(y),{running:!1};try{process.kill(s,0);const c=Number.parseInt(n),r=H(Date.now()-c);return{running:!0,pid:s,uptime:r,mode:i||"foreground"}}catch{return a.default.unlinkSync(y),{running:!1}}}catch{return{running:!1}}}l($,"getServiceStatus");function H(o){const e=Math.floor(o/1e3),n=Math.floor(e/60),i=Math.floor(n/60),s=Math.floor(i/24);return s>0?`${s}\u5929 ${i%24}\u5C0F\u65F6 ${n%60}\u5206\u949F`:i>0?`${i}\u5C0F\u65F6 ${n%60}\u5206\u949F`:n>0?`${n}\u5206\u949F ${e%60}\u79D2`:`${e}\u79D2`}l(H,"formatUptime");function M(o,e){const n=`${o}|${Date.now()}|${e}`;a.default.writeFileSync(y,n)}l(M,"savePidInfo");function P(){try{a.default.existsSync(y)&&a.default.unlinkSync(y)}catch{}}l(P,"cleanupPidFile");function B(){if(!d.configManager.configExists())return console.error(t.default.red("\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728")),console.log(t.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E')),!1;try{const o=d.configManager.getMcpEndpoint();return!o||o.includes("<\u8BF7\u586B\u5199")?(console.error(t.default.red("\u274C \u9519\u8BEF: MCP \u7AEF\u70B9\u672A\u914D\u7F6E")),console.log(t.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi config mcpEndpoint <your-endpoint-url>" \u8BBE\u7F6E\u7AEF\u70B9')),!1):!0}catch(o){return console.error(t.default.red(`\u274C \u9519\u8BEF: \u914D\u7F6E\u6587\u4EF6\u65E0\u6548 - ${o instanceof Error?o.message:String(o)}`)),console.log(t.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u8FD0\u884C "xiaozhi init" \u91CD\u65B0\u521D\u59CB\u5316\u914D\u7F6E')),!1}}l(B,"checkEnvironment");function U(){const o=__dirname;let e;return o.includes("js-demo/dist")?e=o:e=[g.default.join(o,"..","js-demo","dist"),g.default.join(o,"..","..","js-demo","dist"),g.default.join(o,"..","..","..","js-demo","dist"),g.default.join(process.cwd(),"js-demo","dist"),g.default.join(process.cwd(),"dist")].find(i=>a.default.existsSync(g.default.join(i,"mcpPipe.cjs"))&&a.default.existsSync(g.default.join(i,"mcpServerProxy.cjs")))||o,{command:"node",args:["mcpPipe.cjs","mcpServerProxy.cjs"],cwd:e}}l(U,"getServiceCommand");async function T(o=!1){const e=(0,f.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{const n=$();if(n.running){e.fail(`\u670D\u52A1\u5DF2\u7ECF\u5728\u8FD0\u884C (PID: ${n.pid})`);return}if(e.text="\u68C0\u67E5\u73AF\u5883\u914D\u7F6E...",!B()){e.fail("\u73AF\u5883\u914D\u7F6E\u68C0\u67E5\u5931\u8D25");return}const{command:i,args:s,cwd:c}=U();if(e.text=`\u542F\u52A8\u670D\u52A1 (${o?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"})...`,o){const r=(0,b.spawn)(i,s,{cwd:c,detached:!0,stdio:["ignore","pipe","pipe"],env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});M(r.pid,"daemon");const m=a.default.createWriteStream(x,{flags:"a"});r.stdout?.pipe(m),r.stderr?.pipe(m),r.unref(),e.succeed(`\u670D\u52A1\u5DF2\u5728\u540E\u53F0\u542F\u52A8 (PID: ${r.pid})`),console.log(t.default.gray(`\u65E5\u5FD7\u6587\u4EF6: ${x}`)),console.log(t.default.gray("\u4F7F\u7528 'xiaozhi attach' \u53EF\u4EE5\u67E5\u770B\u5B9E\u65F6\u65E5\u5FD7"))}else{e.succeed("\u670D\u52A1\u542F\u52A8\u4E2D...");const r=(0,b.spawn)(i,s,{cwd:c,stdio:"inherit",env:{...process.env,XIAOZHI_CONFIG_DIR:process.cwd()}});M(r.pid,"foreground"),r.on("exit",(m,w)=>{P(),console.log(m!==0?t.default.red(`
3
+ \u670D\u52A1\u5F02\u5E38\u9000\u51FA (\u4EE3\u7801: ${m}, \u4FE1\u53F7: ${w})`):t.default.green(`
4
+ \u670D\u52A1\u5DF2\u505C\u6B62`))}),process.on("SIGINT",()=>{console.log(t.default.yellow(`
5
+ \u6B63\u5728\u505C\u6B62\u670D\u52A1...`)),r.kill("SIGTERM")}),process.on("SIGTERM",()=>{r.kill("SIGTERM")})}}catch(n){e.fail(`\u542F\u52A8\u670D\u52A1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}l(T,"startService");async function k(){const o=(0,f.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{const e=$();if(!e.running){o.warn("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}o.text=`\u505C\u6B62\u670D\u52A1 (PID: ${e.pid})...`;try{process.kill(e.pid,"SIGTERM");let n=0;const i=30;for(;n<i;){await new Promise(s=>setTimeout(s,100));try{process.kill(e.pid,0),n++}catch{break}}try{process.kill(e.pid,0),o.text="\u5F3A\u5236\u505C\u6B62\u670D\u52A1...",process.kill(e.pid,"SIGKILL"),await new Promise(s=>setTimeout(s,500))}catch{}P(),o.succeed("\u670D\u52A1\u5DF2\u505C\u6B62")}catch(n){P(),o.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${n instanceof Error?n.message:String(n)}`)}}catch(e){o.fail(`\u505C\u6B62\u670D\u52A1\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}l(k,"stopService");async function X(){const o=(0,f.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{const e=$();e.running?(o.succeed("\u670D\u52A1\u72B6\u6001"),console.log(t.default.green("\u2705 \u670D\u52A1\u6B63\u5728\u8FD0\u884C")),console.log(t.default.gray(` PID: ${e.pid}`)),console.log(t.default.gray(` \u8FD0\u884C\u65F6\u95F4: ${e.uptime}`)),console.log(t.default.gray(` \u8FD0\u884C\u6A21\u5F0F: ${e.mode==="daemon"?"\u540E\u53F0\u6A21\u5F0F":"\u524D\u53F0\u6A21\u5F0F"}`)),e.mode==="daemon"&&console.log(t.default.gray(` \u65E5\u5FD7\u6587\u4EF6: ${x}`))):(o.succeed("\u670D\u52A1\u72B6\u6001"),console.log(t.default.red("\u274C \u670D\u52A1\u672A\u8FD0\u884C")))}catch(e){o.fail(`\u68C0\u67E5\u72B6\u6001\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}l(X,"checkStatus");async function Z(){const o=(0,f.default)("\u68C0\u67E5\u670D\u52A1\u72B6\u6001...").start();try{const e=$();if(!e.running){o.fail("\u670D\u52A1\u672A\u5728\u8FD0\u884C");return}if(e.mode!=="daemon"){o.fail("\u670D\u52A1\u4E0D\u662F\u5728\u540E\u53F0\u6A21\u5F0F\u8FD0\u884C");return}if(o.succeed("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1..."),console.log(t.default.green(`\u5DF2\u8FDE\u63A5\u5230\u670D\u52A1 (PID: ${e.pid})`)),console.log(t.default.gray("\u6309 Ctrl+C \u53EF\u4EE5\u65AD\u5F00\u8FDE\u63A5\uFF08\u4E0D\u4F1A\u505C\u6B62\u670D\u52A1\uFF09")),console.log(t.default.gray("=".repeat(50))),a.default.existsSync(x)){const{spawn:n}=await import("node:child_process"),i=n("tail",["-f",x],{stdio:"inherit"});process.on("SIGINT",()=>{console.log(t.default.yellow(`
6
+ \u65AD\u5F00\u8FDE\u63A5\uFF0C\u670D\u52A1\u7EE7\u7EED\u5728\u540E\u53F0\u8FD0\u884C`)),i.kill(),process.exit(0)}),i.on("exit",()=>{process.exit(0)})}else console.log(t.default.yellow("\u65E5\u5FD7\u6587\u4EF6\u4E0D\u5B58\u5728"))}catch(e){o.fail(`\u8FDE\u63A5\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}l(Z,"attachService");async function J(o=!1){console.log(t.default.blue("\u{1F504} \u91CD\u542F\u670D\u52A1...")),await k(),await new Promise(e=>setTimeout(e,1e3)),await T(o)}l(J,"restartService");function K(){console.log(t.default.blue(`xiaozhi v${z}`)),console.log(t.default.gray("MCP Calculator Service CLI Tool")),console.log(t.default.gray("Built with Node.js and TypeScript")),console.log(t.default.gray(`Node.js: ${process.version}`)),console.log(t.default.gray(`Platform: ${process.platform} ${process.arch}`))}l(K,"showDetailedInfo");async function W(){const o=(0,f.default)("\u521D\u59CB\u5316\u914D\u7F6E...").start();try{if(d.configManager.configExists()){o.warn("\u914D\u7F6E\u6587\u4EF6\u5DF2\u5B58\u5728"),console.log(t.default.yellow("\u5982\u9700\u91CD\u65B0\u521D\u59CB\u5316\uFF0C\u8BF7\u5148\u5220\u9664\u73B0\u6709\u7684 xiaozhi.config.json \u6587\u4EF6"));return}d.configManager.initConfig(),o.succeed("\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u6210\u529F"),console.log(t.default.green("\u2705 \u914D\u7F6E\u6587\u4EF6\u5DF2\u521B\u5EFA: xiaozhi.config.json")),console.log(t.default.yellow("\u{1F4DD} \u8BF7\u7F16\u8F91\u914D\u7F6E\u6587\u4EF6\u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9:")),console.log(t.default.gray(` \u914D\u7F6E\u6587\u4EF6\u8DEF\u5F84: ${d.configManager.getConfigPath()}`)),console.log(t.default.yellow("\u{1F4A1} \u6216\u8005\u4F7F\u7528\u547D\u4EE4\u8BBE\u7F6E:")),console.log(t.default.gray(" xiaozhi config mcpEndpoint <your-endpoint-url>"))}catch(e){o.fail(`\u521D\u59CB\u5316\u914D\u7F6E\u5931\u8D25: ${e instanceof Error?e.message:String(e)}`)}}l(W,"initConfig");function Y(){const o=__dirname,n=[g.default.join(o,"..","templates"),g.default.join(o,"templates"),g.default.join(o,"..","..","templates")].find(i=>a.default.existsSync(i));return n?a.default.readdirSync(n).filter(i=>{const s=g.default.join(n,i);return a.default.statSync(s).isDirectory()}):[]}l(Y,"getAvailableTemplates");function D(o,e){const n=o.length,i=e.length,s=Array(n+1).fill(null).map(()=>Array(i+1).fill(0));for(let r=0;r<=n;r++)s[r][0]=r;for(let r=0;r<=i;r++)s[0][r]=r;for(let r=1;r<=n;r++)for(let m=1;m<=i;m++)o[r-1]===e[m-1]?s[r][m]=s[r-1][m-1]:s[r][m]=Math.min(s[r-1][m]+1,s[r][m-1]+1,s[r-1][m-1]+1);const c=Math.max(n,i);return c===0?1:(c-s[n][i])/c}l(D,"calculateSimilarity");function q(o,e){if(e.length===0)return null;let n=e[0],i=D(o.toLowerCase(),n.toLowerCase());for(const s of e.slice(1)){const c=D(o.toLowerCase(),s.toLowerCase());c>i&&(i=c,n=s)}return i>.5?n:null}l(q,"findSimilarTemplate");async function Q(o){if(!process.stdin.isTTY)return console.log("n (\u975E\u4EA4\u4E92\u5F0F\u73AF\u5883)"),!1;const e=await import("node:readline");return new Promise(n=>{process.stdout.write(o);const i=e.createInterface({input:process.stdin,output:process.stdout}),s=l(c=>{const r=c.trim().toLowerCase();r==="y"||r==="yes"?(i.close(),n(!0)):r==="n"||r==="no"||r===""?(i.close(),n(!1)):process.stdout.write("\u8BF7\u8F93\u5165 y \u6216 n: ")},"handleInput");i.on("line",s),i.on("SIGINT",()=>{i.close(),n(!1)})})}l(Q,"askUserConfirmation");function oo(o){const e={mcpEndpoint:"<\u8BF7\u586B\u5199\u4F60\u7684\u63A5\u5165\u70B9\u5730\u5740\uFF08\u83B7\u53D6\u5730\u5740\u5728 xiaozhi.me\uFF09>",mcpServers:{}},n=g.default.join(o,"xiaozhi.config.json");a.default.writeFileSync(n,JSON.stringify(e,null,2),"utf8")}l(oo,"createBasicConfig");async function eo(o,e){const n=(0,f.default)("\u521D\u59CB\u5316\u9879\u76EE...").start();try{const i=g.default.join(process.cwd(),o);if(a.default.existsSync(i)){n.fail(`\u76EE\u5F55 "${o}" \u5DF2\u5B58\u5728`),console.log(t.default.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u9009\u62E9\u4E0D\u540C\u7684\u9879\u76EE\u540D\u79F0\u6216\u5220\u9664\u73B0\u6709\u76EE\u5F55"));return}if(e.template){n.text="\u68C0\u67E5\u6A21\u677F...";const s=Y();if(s.length===0){n.fail("\u627E\u4E0D\u5230 templates \u76EE\u5F55"),console.log(t.default.yellow("\u{1F4A1} \u63D0\u793A: \u8BF7\u786E\u4FDD xiaozhi-client \u6B63\u786E\u5B89\u88C5"));return}if(!s.includes(e.template)){n.fail(`\u6A21\u677F "${e.template}" \u4E0D\u5B58\u5728`);const S=q(e.template,s);if(S)if(console.log(t.default.yellow(`\u{1F4A1} \u4F60\u662F\u60F3\u4F7F\u7528\u6A21\u677F "${S}" \u5417\uFF1F`)),await Q(t.default.cyan("\u786E\u8BA4\u4F7F\u7528\u6B64\u6A21\u677F\uFF1F(y/n): ")))e.template=S;else{console.log(t.default.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(const _ of s)console.log(t.default.gray(` - ${_}`));return}else{console.log(t.default.yellow("\u53EF\u7528\u7684\u6A21\u677F:"));for(const j of s)console.log(t.default.gray(` - ${j}`));return}}const c=__dirname,m=[g.default.join(c,"..","templates"),g.default.join(c,"templates"),g.default.join(c,"..","..","templates")].find(S=>a.default.existsSync(S)),w=g.default.join(m,e.template);n.text=`\u4ECE\u6A21\u677F "${e.template}" \u521B\u5EFA\u9879\u76EE "${o}"...`,L(w,i,["node_modules",".pnpm-debug.log","pnpm-lock.yaml"]),n.succeed(`\u9879\u76EE "${o}" \u521B\u5EFA\u6210\u529F`),console.log(t.default.green("\u2705 \u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(t.default.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(t.default.gray(` cd ${o}`)),console.log(t.default.gray(" pnpm install # \u5B89\u88C5\u4F9D\u8D56")),console.log(t.default.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9")),console.log(t.default.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1"))}else n.text=`\u521B\u5EFA\u57FA\u672C\u9879\u76EE "${o}"...`,a.default.mkdirSync(i,{recursive:!0}),oo(i),n.succeed(`\u9879\u76EE "${o}" \u521B\u5EFA\u6210\u529F`),console.log(t.default.green("\u2705 \u57FA\u672C\u9879\u76EE\u521B\u5EFA\u5B8C\u6210!")),console.log(t.default.yellow("\u{1F4DD} \u63A5\u4E0B\u6765\u7684\u6B65\u9AA4:")),console.log(t.default.gray(` cd ${o}`)),console.log(t.default.gray(" # \u7F16\u8F91 xiaozhi.config.json \u8BBE\u7F6E\u4F60\u7684 MCP \u7AEF\u70B9\u548C\u670D\u52A1")),console.log(t.default.gray(" xiaozhi start # \u542F\u52A8\u670D\u52A1")),console.log(t.default.yellow("\u{1F4A1} \u63D0\u793A: \u4F7F\u7528 --template \u9009\u9879\u53EF\u4EE5\u4ECE\u6A21\u677F\u521B\u5EFA\u9879\u76EE"))}catch(i){n.fail(`\u521B\u5EFA\u9879\u76EE\u5931\u8D25: ${i instanceof Error?i.message:String(i)}`)}}l(eo,"createProject");function L(o,e,n=[]){a.default.existsSync(e)||a.default.mkdirSync(e,{recursive:!0});const i=a.default.readdirSync(o);for(const s of i){if(n.some(w=>s.includes(w)))continue;const c=g.default.join(o,s),r=g.default.join(e,s);a.default.statSync(c).isDirectory()?L(c,r,n):a.default.copyFileSync(c,r)}}l(L,"copyDirectory");async function no(o,e){const n=(0,f.default)("\u66F4\u65B0\u914D\u7F6E...").start();try{if(!d.configManager.configExists()){n.fail("\u914D\u7F6E\u6587\u4EF6\u4E0D\u5B58\u5728"),console.log(t.default.yellow('\u{1F4A1} \u63D0\u793A: \u8BF7\u5148\u8FD0\u884C "xiaozhi init" \u521D\u59CB\u5316\u914D\u7F6E'));return}if(e)switch(o){case"mcpEndpoint":d.configManager.updateMcpEndpoint(e),n.succeed(`MCP \u7AEF\u70B9\u5DF2\u66F4\u65B0\u4E3A: ${e}`);break;default:n.fail(`\u914D\u7F6E\u9879 ${o} \u4E0D\u652F\u6301\u901A\u8FC7\u547D\u4EE4\u884C\u8BBE\u7F6E`),console.log(t.default.yellow("\u652F\u6301\u8BBE\u7F6E\u7684\u914D\u7F6E\u9879: mcpEndpoint"));return}else{n.text="\u8BFB\u53D6\u914D\u7F6E...";const i=d.configManager.getConfig();switch(o){case"mcpEndpoint":n.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(t.default.green(`MCP \u7AEF\u70B9: ${i.mcpEndpoint}`));break;case"mcpServers":n.succeed("\u914D\u7F6E\u4FE1\u606F"),console.log(t.default.green("MCP \u670D\u52A1:"));for(const[s,c]of Object.entries(i.mcpServers))console.log(t.default.gray(` ${s}: ${c.command} ${c.args.join(" ")}`));break;default:n.fail(`\u672A\u77E5\u7684\u914D\u7F6E\u9879: ${o}`),console.log(t.default.yellow("\u652F\u6301\u7684\u914D\u7F6E\u9879: mcpEndpoint, mcpServers"));return}}}catch(i){n.fail(`\u914D\u7F6E\u64CD\u4F5C\u5931\u8D25: ${i instanceof Error?i.message:String(i)}`)}}l(no,"configCommand");function to(){console.log(t.default.blue.bold("xiaozhi - MCP Calculator Service CLI")),console.log(),console.log(t.default.yellow("\u4F7F\u7528\u65B9\u6CD5:")),console.log(" xiaozhi <command> [options]"),console.log(),console.log(t.default.yellow("\u547D\u4EE4:")),console.log(" create <projectName> \u521B\u5EFA\u9879\u76EE"),console.log(" init \u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6"),console.log(" config <key> [value] \u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E"),console.log(" start [--daemon] \u542F\u52A8\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),console.log(" stop \u505C\u6B62\u670D\u52A1"),console.log(" status \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" attach \u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7"),console.log(" restart [--daemon] \u91CD\u542F\u670D\u52A1 (--daemon \u540E\u53F0\u8FD0\u884C)"),console.log(),console.log(t.default.yellow("\u9009\u9879:")),console.log(" -v, --version \u663E\u793A\u7248\u672C\u4FE1\u606F"),console.log(" -V \u663E\u793A\u8BE6\u7EC6\u4FE1\u606F"),console.log(" -h, --help \u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),console.log(" -t, --template <name> \u6307\u5B9A\u6A21\u677F\u540D\u79F0\uFF08\u7528\u4E8E create \u547D\u4EE4\uFF09"),console.log(),console.log(t.default.yellow("\u9879\u76EE\u793A\u4F8B:")),console.log(" xiaozhi create my-app # \u521B\u5EFA\u57FA\u672C\u9879\u76EE"),console.log(" xiaozhi create my-app -t hello-world # \u4F7F\u7528 hello-world \u6A21\u677F"),console.log(" xiaozhi create my-app --template hello-world # \u540C\u4E0A\uFF0C\u5B8C\u6574\u9009\u9879\u540D"),console.log(),console.log(t.default.yellow("\u914D\u7F6E\u793A\u4F8B:")),console.log(" xiaozhi init # \u521D\u59CB\u5316\u914D\u7F6E"),console.log(" xiaozhi config mcpEndpoint # \u67E5\u770B MCP \u7AEF\u70B9"),console.log(" xiaozhi config mcpEndpoint wss://... # \u8BBE\u7F6E MCP \u7AEF\u70B9"),console.log(),console.log(t.default.yellow("\u670D\u52A1\u793A\u4F8B:")),console.log(" xiaozhi start # \u524D\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi start --daemon # \u540E\u53F0\u542F\u52A8\u670D\u52A1"),console.log(" xiaozhi status # \u68C0\u67E5\u670D\u52A1\u72B6\u6001"),console.log(" xiaozhi attach # \u67E5\u770B\u540E\u53F0\u670D\u52A1\u65E5\u5FD7"),console.log(" xiaozhi stop # \u505C\u6B62\u670D\u52A1"),console.log(),console.log(t.default.yellow("MCP \u7BA1\u7406\u793A\u4F8B:")),console.log(" xiaozhi mcp list # \u5217\u51FA\u6240\u6709 MCP \u670D\u52A1"),console.log(" xiaozhi mcp list --tools # \u5217\u51FA\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp server <name> # \u5217\u51FA\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> enable # \u542F\u7528\u5DE5\u5177"),console.log(" xiaozhi mcp tool <server> <tool> disable # \u7981\u7528\u5DE5\u5177")}l(to,"showHelp"),p.name("xiaozhi").description("MCP Calculator Service CLI Tool").version(z,"-v, --version","\u663E\u793A\u7248\u672C\u4FE1\u606F").helpOption("-h, --help","\u663E\u793A\u5E2E\u52A9\u4FE1\u606F"),p.command("create <projectName>").description("\u521B\u5EFA\u9879\u76EE").option("-t, --template <templateName>","\u4F7F\u7528\u6307\u5B9A\u6A21\u677F\u521B\u5EFA\u9879\u76EE").action(async(o,e)=>{await eo(o,e)}),p.command("init").description("\u521D\u59CB\u5316\u914D\u7F6E\u6587\u4EF6").action(async()=>{await W()}),p.command("config <key> [value]").description("\u67E5\u770B\u6216\u8BBE\u7F6E\u914D\u7F6E").action(async(o,e)=>{await no(o,e)}),p.command("start").description("\u542F\u52A8\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async o=>{await T(o.daemon)}),p.command("stop").description("\u505C\u6B62\u670D\u52A1").action(async()=>{await k()}),p.command("status").description("\u68C0\u67E5\u670D\u52A1\u72B6\u6001").action(async()=>{await X()}),p.command("attach").description("\u8FDE\u63A5\u5230\u540E\u53F0\u670D\u52A1\u67E5\u770B\u65E5\u5FD7").action(async()=>{await Z()}),p.command("restart").description("\u91CD\u542F\u670D\u52A1").option("-d, --daemon","\u5728\u540E\u53F0\u8FD0\u884C\u670D\u52A1").action(async o=>{await J(o.daemon)});const C=p.command("mcp").description("MCP \u670D\u52A1\u548C\u5DE5\u5177\u7BA1\u7406");C.command("list").description("\u5217\u51FA MCP \u670D\u52A1").option("--tools","\u663E\u793A\u6240\u6709\u670D\u52A1\u7684\u5DE5\u5177\u5217\u8868").action(async o=>{await(0,h.listMcpServers)(o)}),C.command("server <serverName>").description("\u7BA1\u7406\u6307\u5B9A\u7684 MCP \u670D\u52A1").action(async o=>{await(0,h.listServerTools)(o)}),C.command("tool <serverName> <toolName> <action>").description("\u542F\u7528\u6216\u7981\u7528\u6307\u5B9A\u670D\u52A1\u7684\u5DE5\u5177").action(async(o,e,n)=>{n!=="enable"&&n!=="disable"&&(console.error(t.default.red("\u9519\u8BEF: \u64CD\u4F5C\u5FC5\u987B\u662F 'enable' \u6216 'disable'")),process.exit(1)),await(0,h.setToolEnabled)(o,e,n==="enable")}),p.option("-V","\u663E\u793A\u8BE6\u7EC6\u4FE1\u606F").action(o=>{o.V&&(K(),process.exit(0))}),process.argv.length<=2&&(to(),process.exit(0)),p.parse(process.argv);
452
7
  //# sourceMappingURL=cli.cjs.map