@xiaozhi-client/cli 1.9.8-beta.1 → 1.9.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/README.md +1 -1
- package/package.json +6 -2
- package/src/commands/McpCommandHandler.ts +26 -14
- package/src/global.d.ts +0 -4
- package/src/services/DaemonManager.ts +1 -1
- package/src/services/ProcessManager.ts +12 -0
- package/src/services/ServiceManager.ts +2 -2
- package/src/services/__tests__/ServiceManager.test.ts +2 -2
- package/src/types/backend.d.ts +2 -2
- package/tsconfig.json +5 -1
- package/tsup.config.ts +8 -11
- package/vitest.config.ts +2 -4
- /package/src/commands/__tests__/{CommandHandlerFactory.test.ts → command-handler-factory.test.ts} +0 -0
- /package/src/commands/__tests__/{CommandRegistry.test.ts → command-registry.test.ts} +0 -0
- /package/src/commands/__tests__/{ConfigCommandHandler.test.ts → config-command-handler.test.ts} +0 -0
- /package/src/commands/__tests__/{EndpointCommandHandler.test.ts → endpoint-command-handler.test.ts} +0 -0
- /package/src/commands/__tests__/{McpCommandHandler.test.ts → mcp-command-handler.test.ts} +0 -0
- /package/src/commands/__tests__/{ProjectCommandHandler.test.ts → project-command-handler.test.ts} +0 -0
- /package/src/commands/__tests__/{ServiceCommands.integration.test.ts → service-commands.integration.test.ts} +0 -0
- /package/src/utils/__tests__/{FormatUtils.test.ts → format-utils.test.ts} +0 -0
- /package/src/utils/__tests__/{PathUtils.test.ts → path-utils.test.ts} +0 -0
- /package/src/utils/__tests__/{Validation.test.ts → validation.test.ts} +0 -0
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ packages/cli/
|
|
|
49
49
|
|
|
50
50
|
CLI 包通过 external 配置引用 backend 模块:
|
|
51
51
|
|
|
52
|
-
-
|
|
52
|
+
- `@/WebServer` → `dist/backend/WebServer.js` (通过 WebServerLauncher)
|
|
53
53
|
- `@/lib/config/manager` → `dist/backend/lib/config/manager.js`
|
|
54
54
|
|
|
55
55
|
## 导入方式
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xiaozhi-client/cli",
|
|
3
|
-
"version": "1.9.8
|
|
3
|
+
"version": "1.9.8",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,8 +17,12 @@
|
|
|
17
17
|
"xiaozhi-client": "../../dist/cli/index.js"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
+
"chalk": "^5.6.0",
|
|
21
|
+
"cli-table3": "^0.6.5",
|
|
22
|
+
"commander": "^14.0.0",
|
|
20
23
|
"consola": "^3.4.2",
|
|
21
|
-
"
|
|
24
|
+
"ora": "^8.2.0",
|
|
25
|
+
"@xiaozhi-client/config": "1.9.8"
|
|
22
26
|
},
|
|
23
27
|
"devDependencies": {
|
|
24
28
|
"@types/node": "^24.3.0",
|
|
@@ -634,6 +634,30 @@ export class McpCommandHandler extends BaseCommandHandler {
|
|
|
634
634
|
}
|
|
635
635
|
}
|
|
636
636
|
|
|
637
|
+
/**
|
|
638
|
+
* 验证服务是否存在
|
|
639
|
+
* @param serverName 服务名称
|
|
640
|
+
* @param spinner Ora 加载动画实例
|
|
641
|
+
* @returns 服务是否存在
|
|
642
|
+
* @private
|
|
643
|
+
*/
|
|
644
|
+
private validateServerExists(
|
|
645
|
+
serverName: string,
|
|
646
|
+
spinner: ReturnType<typeof ora>
|
|
647
|
+
): boolean {
|
|
648
|
+
const mcpServers = configManager.getMcpServers();
|
|
649
|
+
|
|
650
|
+
if (!mcpServers[serverName]) {
|
|
651
|
+
spinner.fail(`服务 '${serverName}' 不存在`);
|
|
652
|
+
console.log(
|
|
653
|
+
chalk.yellow("💡 提示: 使用 'xiaozhi mcp list' 查看所有可用服务")
|
|
654
|
+
);
|
|
655
|
+
return false;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return true;
|
|
659
|
+
}
|
|
660
|
+
|
|
637
661
|
/**
|
|
638
662
|
* 列出指定服务的工具
|
|
639
663
|
*/
|
|
@@ -641,13 +665,7 @@ export class McpCommandHandler extends BaseCommandHandler {
|
|
|
641
665
|
const spinner = ora(`获取 ${serverName} 服务的工具列表...`).start();
|
|
642
666
|
|
|
643
667
|
try {
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
if (!mcpServers[serverName]) {
|
|
647
|
-
spinner.fail(`服务 '${serverName}' 不存在`);
|
|
648
|
-
console.log(
|
|
649
|
-
chalk.yellow("💡 提示: 使用 'xiaozhi mcp list' 查看所有可用服务")
|
|
650
|
-
);
|
|
668
|
+
if (!this.validateServerExists(serverName, spinner)) {
|
|
651
669
|
return;
|
|
652
670
|
}
|
|
653
671
|
|
|
@@ -729,13 +747,7 @@ export class McpCommandHandler extends BaseCommandHandler {
|
|
|
729
747
|
const spinner = ora(`${action}工具 ${serverName}/${toolName}...`).start();
|
|
730
748
|
|
|
731
749
|
try {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
if (!mcpServers[serverName]) {
|
|
735
|
-
spinner.fail(`服务 '${serverName}' 不存在`);
|
|
736
|
-
console.log(
|
|
737
|
-
chalk.yellow("💡 提示: 使用 'xiaozhi mcp list' 查看所有可用服务")
|
|
738
|
-
);
|
|
750
|
+
if (!this.validateServerExists(serverName, spinner)) {
|
|
739
751
|
return;
|
|
740
752
|
}
|
|
741
753
|
|
package/src/global.d.ts
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import type { ChildProcess } from "node:child_process";
|
|
6
6
|
import { spawn } from "node:child_process";
|
|
7
7
|
import fs from "node:fs";
|
|
8
|
-
import type { WebServer } from "
|
|
8
|
+
import type { WebServer } from "@/WebServer";
|
|
9
9
|
import consola from "consola";
|
|
10
10
|
import { ProcessError, ServiceError } from "../errors/index";
|
|
11
11
|
import type {
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 进程管理服务
|
|
3
|
+
*
|
|
4
|
+
* 负责管理 xiaozhi 服务的进程生命周期,包括:
|
|
5
|
+
* - 进程启动和停止
|
|
6
|
+
* - PID 文件管理
|
|
7
|
+
* - 进程状态查询
|
|
8
|
+
* - 优雅关闭进程
|
|
9
|
+
*
|
|
10
|
+
* @module packages/cli/src/services/ProcessManager
|
|
11
|
+
*/
|
|
12
|
+
|
|
1
13
|
import { FileError, ProcessError } from "../errors/index";
|
|
2
14
|
import type {
|
|
3
15
|
ProcessManager as IProcessManager,
|
|
@@ -264,7 +264,7 @@ export class ServiceManagerImpl implements IServiceManager {
|
|
|
264
264
|
process.exit(0);
|
|
265
265
|
} else {
|
|
266
266
|
// 前台模式 - 直接启动 Web Server
|
|
267
|
-
const { WebServer } = await import("
|
|
267
|
+
const { WebServer } = await import("@/WebServer.js");
|
|
268
268
|
const server = new WebServer(port);
|
|
269
269
|
|
|
270
270
|
// 处理退出信号
|
|
@@ -323,7 +323,7 @@ export class ServiceManagerImpl implements IServiceManager {
|
|
|
323
323
|
* 前台模式启动 WebServer
|
|
324
324
|
*/
|
|
325
325
|
private async startWebServerInForeground(): Promise<void> {
|
|
326
|
-
const { WebServer } = await import("
|
|
326
|
+
const { WebServer } = await import("@/WebServer.js");
|
|
327
327
|
const server = new WebServer();
|
|
328
328
|
|
|
329
329
|
// 处理退出信号
|
|
@@ -40,7 +40,7 @@ const mockMCPServerInstance = {
|
|
|
40
40
|
stop: vi.fn().mockResolvedValue(undefined),
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
vi.mock("
|
|
43
|
+
vi.mock("@/WebServer.js", () => ({
|
|
44
44
|
WebServer: vi.fn().mockImplementation(() => mockWebServerInstance),
|
|
45
45
|
}));
|
|
46
46
|
|
|
@@ -184,7 +184,7 @@ describe("ServiceManagerImpl 服务管理器实现", () => {
|
|
|
184
184
|
);
|
|
185
185
|
|
|
186
186
|
// Mock dynamic import for WebServer
|
|
187
|
-
vi.doMock("
|
|
187
|
+
vi.doMock("@/WebServer.js", () => ({
|
|
188
188
|
WebServer: vi.fn().mockImplementation(() => mockWebServerInstance),
|
|
189
189
|
}));
|
|
190
190
|
});
|
package/src/types/backend.d.ts
CHANGED
|
@@ -39,10 +39,10 @@ declare module "@/lib/config/manager.js" {
|
|
|
39
39
|
export const configManager: any;
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
declare module "
|
|
42
|
+
declare module "@/WebServer" {
|
|
43
43
|
export class WebServer {}
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
-
declare module "
|
|
46
|
+
declare module "@/WebServer.js" {
|
|
47
47
|
export class WebServer {}
|
|
48
48
|
}
|
package/tsconfig.json
CHANGED
|
@@ -7,5 +7,9 @@
|
|
|
7
7
|
},
|
|
8
8
|
"include": ["src/**/*.ts"],
|
|
9
9
|
"exclude": ["node_modules", "dist", "**/*.test.ts"],
|
|
10
|
-
"references": [
|
|
10
|
+
"references": [
|
|
11
|
+
{ "path": "../../apps/backend" },
|
|
12
|
+
{ "path": "../config" },
|
|
13
|
+
{ "path": "../version" }
|
|
14
|
+
]
|
|
11
15
|
}
|
package/tsup.config.ts
CHANGED
|
@@ -66,8 +66,8 @@ export default defineConfig({
|
|
|
66
66
|
"@xiaozhi-client/version",
|
|
67
67
|
"@xiaozhi-client/version.js",
|
|
68
68
|
// Backend 模块(运行时从 dist/backend 读取)
|
|
69
|
-
"
|
|
70
|
-
"
|
|
69
|
+
"@/WebServer",
|
|
70
|
+
"@/WebServer.js",
|
|
71
71
|
],
|
|
72
72
|
outExtension: () => ({
|
|
73
73
|
js: ".js",
|
|
@@ -77,24 +77,21 @@ export default defineConfig({
|
|
|
77
77
|
const filePath = resolve("../../dist/cli/index.js");
|
|
78
78
|
let content = readFileSync(filePath, "utf-8");
|
|
79
79
|
|
|
80
|
-
// 替换
|
|
80
|
+
// 替换 @/* 为指向正确位置的相对路径
|
|
81
81
|
// 注意:@xiaozhi-client/config 现在从 node_modules 解析,不需要替换
|
|
82
82
|
content = content
|
|
83
83
|
.replace(
|
|
84
|
-
/from\s*["']
|
|
84
|
+
/from\s*["']@\/WebServer\.js["']/g,
|
|
85
85
|
'from "../backend/WebServer.js"'
|
|
86
86
|
)
|
|
87
|
+
.replace(/from\s*["']@\/WebServer["']/g, 'from "../backend/WebServer.js"')
|
|
88
|
+
// 替换动态导入中的 @/WebServer.js
|
|
87
89
|
.replace(
|
|
88
|
-
/
|
|
89
|
-
'from "../backend/WebServer.js"'
|
|
90
|
-
)
|
|
91
|
-
// 替换动态导入中的 @root/WebServer.js
|
|
92
|
-
.replace(
|
|
93
|
-
/import\(["']@root\/WebServer\.js["']\)/g,
|
|
90
|
+
/import\(["']@\/WebServer\.js["']\)/g,
|
|
94
91
|
'import("../backend/WebServer.js")'
|
|
95
92
|
)
|
|
96
93
|
.replace(
|
|
97
|
-
/import\(["']
|
|
94
|
+
/import\(["']@\/WebServer["']\)/g,
|
|
98
95
|
'import("../backend/WebServer.js")'
|
|
99
96
|
);
|
|
100
97
|
|
package/vitest.config.ts
CHANGED
|
@@ -54,8 +54,6 @@ export default defineConfig({
|
|
|
54
54
|
// Backend 路径别名(从 packages/cli 向上到项目根目录)
|
|
55
55
|
"@handlers": resolve(__dirname, "../../apps/backend/handlers"),
|
|
56
56
|
"@handlers/*": resolve(__dirname, "../../apps/backend/handlers/*"),
|
|
57
|
-
"@middlewares": resolve(__dirname, "../../apps/backend/middlewares"),
|
|
58
|
-
"@middlewares/*": resolve(__dirname, "../../apps/backend/middlewares/*"),
|
|
59
57
|
"@services": resolve(__dirname, "../../apps/backend/services"),
|
|
60
58
|
"@services/*": resolve(__dirname, "../../apps/backend/services/*"),
|
|
61
59
|
"@errors": resolve(__dirname, "../../apps/backend/errors"),
|
|
@@ -80,8 +78,8 @@ export default defineConfig({
|
|
|
80
78
|
"@types/*": resolve(__dirname, "../../apps/backend/types/*"),
|
|
81
79
|
"@/lib": resolve(__dirname, "../../apps/backend/lib"),
|
|
82
80
|
"@/lib/*": resolve(__dirname, "../../apps/backend/lib/*"),
|
|
83
|
-
"@
|
|
84
|
-
"
|
|
81
|
+
"@": resolve(__dirname, "../../apps/backend"),
|
|
82
|
+
"@/*": resolve(__dirname, "../../apps/backend/*"),
|
|
85
83
|
"@routes": resolve(__dirname, "../../apps/backend/routes"),
|
|
86
84
|
"@routes/*": resolve(__dirname, "../../apps/backend/routes/*"),
|
|
87
85
|
"@constants": resolve(__dirname, "../../apps/backend/constants"),
|
/package/src/commands/__tests__/{CommandHandlerFactory.test.ts → command-handler-factory.test.ts}
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/commands/__tests__/{ConfigCommandHandler.test.ts → config-command-handler.test.ts}
RENAMED
|
File without changes
|
/package/src/commands/__tests__/{EndpointCommandHandler.test.ts → endpoint-command-handler.test.ts}
RENAMED
|
File without changes
|
|
File without changes
|
/package/src/commands/__tests__/{ProjectCommandHandler.test.ts → project-command-handler.test.ts}
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|