xiaozhi-client 0.0.1 → 1.0.2

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
@@ -1,68 +1,82 @@
1
1
  # Xiaozhi Client
2
2
 
3
+ [![npm version](https://badge.fury.io/js/xiaozhi-client.svg)](https://badge.fury.io/js/xiaozhi-client)
4
+ [![codecov](https://codecov.io/gh/shenjingnan/xiaozhi-client/branch/main/graph/badge.svg)](https://codecov.io/gh/shenjingnan/xiaozhi-client)
5
+ [![CI](https://github.com/shenjingnan/xiaozhi-client/workflows/Release/badge.svg)](https://github.com/shenjingnan/xiaozhi-client/actions)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
3
8
  小智 AI 客户端,目前主要用于 MCP 的对接
4
9
 
5
- ![效果图](./docs/preview.png)
10
+ ![效果图](https://raw.githubusercontent.com/shenjingnan/xiaozhi-client/main/docs/images/preview.png)
11
+
12
+ ## 功能特性
6
13
 
7
- ## 安装和使用
14
+ - 支持 小智(xiaozhi.me) 官方服务器接入点
15
+ - 支持 自定义 MCP 服务
16
+ - 支持 使用标准 MCP 配置方式多个 MCP Server
17
+ - 支持 聚合多个 MCP Server
18
+ - 支持 动态控制 MCP Server 提供的工具
19
+ - 支持 通过模板创建
20
+ - 支持 后台运行
8
21
 
9
- ### 开发环境
22
+ ## 快速上手
10
23
 
11
- 1. 克隆项目:
24
+ ### 全局安装 xiaozhi-client 命令行工具
12
25
 
13
26
  ```bash
14
- git clone <repository-url>
15
- cd xiaozhi-client
16
- ```
27
+ ## 安装
28
+ npm i -g xiaozhi-client
17
29
 
18
- 2. 安装依赖:
30
+ ## 创建项目
31
+ xiaozhi create my-app --template hello-world
19
32
 
20
- ```bash
33
+ ## 进入项目
34
+ cd my-app
35
+
36
+ ## 安装依赖(主要是示例代码中mcp服务所使用的依赖)
21
37
  pnpm install
22
- ```
23
38
 
24
- 3. 构建项目:
39
+ # 修改 xiaozhi.config.json 中的 mcpEndpoint 为你的接入点地址(需要自行前往xiaozhi.me获取)
40
+ # 小智AI配置MCP接入点使用说明:https://ccnphfhqs21z.feishu.cn/wiki/HiPEwZ37XiitnwktX13cEM5KnSb
25
41
 
26
- ```bash
27
- pnpm run build
42
+ ## 运行
43
+ xiaozhi start
28
44
  ```
29
45
 
30
- 4. 本地安装(用于开发测试):
46
+ ### 通过 npx 直接运行
31
47
 
32
48
  ```bash
33
- npm link
34
- ```
49
+ # 创建项目
50
+ npx -y xiaozhi-client create --template hello-world
35
51
 
36
- 现在你可以在任何地方使用 `xiaozhi` 命令了。
52
+ # 进入项目目录
53
+ cd hello-world
37
54
 
38
- ### 生产环境
39
-
40
- 项目使用 tsup 打包成单个可执行的 JavaScript 文件,所有依赖都被正确处理。
55
+ # 安装依赖
56
+ pnpm install
41
57
 
42
- 构建后的文件位于 `dist/cli.js`,这是一个完整的可执行文件,包含:
58
+ # 修改 xiaozhi.config.json 中的 mcpEndpoint 为你的接入点地址(需要自行前往xiaozhi.me获取)
59
+ # 小智AI配置MCP接入点使用说明:https://ccnphfhqs21z.feishu.cn/wiki/HiPEwZ37XiitnwktX13cEM5KnSb
43
60
 
44
- - 正确的 shebang (`#!/usr/bin/env node`)
45
- - 所有必要的代码(除了外部依赖)
46
- - 可执行权限
61
+ # 启动服务
62
+ npx -y xiaozhi-client start
63
+ ```
47
64
 
48
- ### 可用命令
65
+ ## 可用命令
49
66
 
50
67
  ```bash
51
68
  # 查看帮助
52
69
  xiaozhi --help
53
70
 
54
- # 配置端点
55
- xiaozhi set-config xiaozhi.endpoint=wss://your-endpoint
56
-
57
- # 查看配置
58
- xiaozhi get-config
59
-
60
71
  # 启动服务
61
72
  xiaozhi start
62
73
 
63
74
  # 后台启动服务
64
75
  xiaozhi start --daemon
65
76
 
77
+ # 将后台服务转到前台运行
78
+ xiaozhi attach
79
+
66
80
  # 查看服务状态
67
81
  xiaozhi status
68
82
 
@@ -71,31 +85,16 @@ xiaozhi stop
71
85
 
72
86
  # 重启服务
73
87
  xiaozhi restart
74
- ```
75
-
76
- ## 开发
77
-
78
- ### 构建脚本
79
88
 
80
- - `pnpm run build` - 使用 tsup 构建项目(推荐)
81
- - `pnpm run build:tsc` - 使用 TypeScript 编译器构建(备用)
82
- - `pnpm run clean` - 清理构建文件
83
- - `pnpm run dev` - 开发模式(监听文件变化)
84
- - `pnpm run type-check` - 仅进行类型检查
85
- - `pnpm run start` - 编译并启动服务
89
+ # 列出所有使用的mcp服务
90
+ xiaozhi mcp list
86
91
 
87
- ### 技术栈
88
-
89
- - TypeScript
90
- - tsup (打包工具)
91
- - Commander.js (CLI 框架)
92
- - Chalk (终端颜色)
93
- - Ora (加载动画)
92
+ # 列出所有mcp所提供的tools
93
+ xiaozhi mcp --tools
94
+ ```
94
95
 
95
- ### 打包特性
96
+ ## 路线图
96
97
 
97
- - 使用 tsup 进行快速打包
98
- - 自动处理 shebang 重复问题
99
- - 自动添加可执行权限
100
- - 支持 ES 模块
101
- - 生成 source maps 和类型定义文件
98
+ - 支持 通过 SSE 类型的 MCP Server
99
+ - 支持 直接使用 [modelscope](https://www.modelscope.cn/mcp) 中托管的 MCP 服务
100
+ - 支持 通过使用网页进行 MCP 配置
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