ms-vite-plugin 1.1.2 → 1.1.4

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.
Files changed (94) hide show
  1. package/dist/build.js +6 -0
  2. package/dist/cli.js +91 -1
  3. package/dist/mcp/device-config.d.ts +55 -0
  4. package/dist/mcp/device-config.js +183 -0
  5. package/dist/mcp/docs-service.d.ts +65 -0
  6. package/dist/mcp/docs-service.js +168 -0
  7. package/dist/mcp/project.d.ts +16 -0
  8. package/dist/mcp/project.js +74 -0
  9. package/dist/mcp/tools.d.ts +18 -0
  10. package/dist/mcp/tools.js +825 -0
  11. package/dist/mcp/types.d.ts +32 -0
  12. package/dist/mcp/types.js +11 -0
  13. package/dist/mcp-server.d.ts +2 -0
  14. package/dist/mcp-server.js +86 -0
  15. package/dist/project.d.ts +89 -0
  16. package/dist/project.js +306 -0
  17. package/dist/version.d.ts +12 -0
  18. package/dist/version.js +63 -0
  19. package/docs/api/action.md +922 -0
  20. package/docs/api/appleocr.md +229 -0
  21. package/docs/api/config.md +122 -0
  22. package/docs/api/cryptoUtils.md +232 -0
  23. package/docs/api/device.md +374 -0
  24. package/docs/api/file.md +516 -0
  25. package/docs/api/global.md +617 -0
  26. package/docs/api/hid.md +1032 -0
  27. package/docs/api/hotUpdate.md +166 -0
  28. package/docs/api/http.md +548 -0
  29. package/docs/api/image.md +907 -0
  30. package/docs/api/ime.md +290 -0
  31. package/docs/api/logger.md +324 -0
  32. package/docs/api/media.md +248 -0
  33. package/docs/api/mysql.md +441 -0
  34. package/docs/api/netCard.md +200 -0
  35. package/docs/api/node.md +353 -0
  36. package/docs/api/paddleocr.md +246 -0
  37. package/docs/api/pip.md +242 -0
  38. package/docs/api/system.md +572 -0
  39. package/docs/api/thread.md +269 -0
  40. package/docs/api/tomatoocr.md +425 -0
  41. package/docs/api/tts.md +334 -0
  42. package/docs/api/ui.md +947 -0
  43. package/docs/api/utils.md +265 -0
  44. package/docs/api/yolo.md +310 -0
  45. package/docs/apicn/action.md +919 -0
  46. package/docs/apicn/appleocr.md +233 -0
  47. package/docs/apicn/config.md +120 -0
  48. package/docs/apicn/device.md +385 -0
  49. package/docs/apicn/file.md +511 -0
  50. package/docs/apicn/global.md +613 -0
  51. package/docs/apicn/hid.md +1033 -0
  52. package/docs/apicn/hotUpdate.md +170 -0
  53. package/docs/apicn/http.md +672 -0
  54. package/docs/apicn/image.md +924 -0
  55. package/docs/apicn/ime.md +290 -0
  56. package/docs/apicn/logger.md +332 -0
  57. package/docs/apicn/media.md +252 -0
  58. package/docs/apicn/mysql.md +445 -0
  59. package/docs/apicn/netCard.md +200 -0
  60. package/docs/apicn/node.md +362 -0
  61. package/docs/apicn/paddleocr.md +255 -0
  62. package/docs/apicn/pip.md +242 -0
  63. package/docs/apicn/system.md +575 -0
  64. package/docs/apicn/thread.md +269 -0
  65. package/docs/apicn/tts.md +338 -0
  66. package/docs/apicn/ui.md +933 -0
  67. package/docs/apicn/utils.md +265 -0
  68. package/docs/apicn/yolo.md +314 -0
  69. package/docs/apipython/action.md +901 -0
  70. package/docs/apipython/appleocr.md +226 -0
  71. package/docs/apipython/config.md +126 -0
  72. package/docs/apipython/cryptoUtils.md +246 -0
  73. package/docs/apipython/device.md +365 -0
  74. package/docs/apipython/file.md +476 -0
  75. package/docs/apipython/g.md +154 -0
  76. package/docs/apipython/hid.md +1059 -0
  77. package/docs/apipython/hotUpdate.md +154 -0
  78. package/docs/apipython/image.md +938 -0
  79. package/docs/apipython/ime.md +306 -0
  80. package/docs/apipython/logger.md +330 -0
  81. package/docs/apipython/media.md +221 -0
  82. package/docs/apipython/mysql.md +432 -0
  83. package/docs/apipython/netCard.md +219 -0
  84. package/docs/apipython/node.md +331 -0
  85. package/docs/apipython/overview.md +66 -0
  86. package/docs/apipython/paddleocr.md +211 -0
  87. package/docs/apipython/pip.md +231 -0
  88. package/docs/apipython/system.md +458 -0
  89. package/docs/apipython/tomatoocr.md +444 -0
  90. package/docs/apipython/tts.md +331 -0
  91. package/docs/apipython/ui.md +949 -0
  92. package/docs/apipython/utils.md +284 -0
  93. package/docs/apipython/yolo.md +281 -0
  94. package/package.json +8 -4
package/dist/build.js CHANGED
@@ -43,6 +43,12 @@ const fsExtra = __importStar(require("fs-extra"));
43
43
  const os = __importStar(require("os"));
44
44
  const path = __importStar(require("path"));
45
45
  const vite_plugin_bundle_obfuscator_1 = __importDefault(require("vite-plugin-bundle-obfuscator"));
46
+ /**
47
+ * 压缩目录
48
+ * @param source 源目录路径
49
+ * @param out 输出文件路径
50
+ * @returns 压缩完成后的 Promise
51
+ */
46
52
  async function zipDirectory(source, out) {
47
53
  const archive = (0, archiver_1.default)("zip", { zlib: { level: 9 } });
48
54
  const stream = fsExtra.createWriteStream(out);
package/dist/cli.js CHANGED
@@ -42,6 +42,7 @@ const fsExtra = __importStar(require("fs-extra"));
42
42
  const project_1 = require("./project");
43
43
  const packager_1 = require("./packager");
44
44
  const ws_manager_1 = require("./ws-manager");
45
+ const version_1 = require("./version");
45
46
  /**
46
47
  * WS 状态持久化文件路径(用于跨进程查询 ws-status)
47
48
  */
@@ -183,6 +184,70 @@ async function stopCommand(options) {
183
184
  process.exit(1);
184
185
  }
185
186
  }
187
+ /**
188
+ * screenshot 命令处理函数
189
+ * @param options 命令选项
190
+ * @returns 请求完成后退出
191
+ * @example
192
+ * ms screenshot --ip 192.168.1.100 --port 9800 --output ./screen.jpg
193
+ */
194
+ async function screenshotCommand(options) {
195
+ try {
196
+ await ensureValidKuaiJSProject(process.cwd());
197
+ const format = options.format ?? "file";
198
+ if (format === "base64") {
199
+ const base64 = await (0, project_1.getScreenshotBase64OnDevice)(options);
200
+ console.log(base64);
201
+ return;
202
+ }
203
+ const image = await (0, project_1.getScreenshotOnDevice)(options);
204
+ const outputPath = options.output?.trim()
205
+ ? path.resolve(options.output.trim())
206
+ : path.resolve(process.cwd(), "screenshot.jpg");
207
+ await fsExtra.ensureDir(path.dirname(outputPath));
208
+ await fsExtra.writeFile(outputPath, image);
209
+ console.log(`✅ 截图成功: ${outputPath} (${image.length} bytes)`);
210
+ }
211
+ catch (error) {
212
+ console.error("❌ 截图失败:", error instanceof Error ? error.message : error);
213
+ process.exit(1);
214
+ }
215
+ }
216
+ /**
217
+ * source 命令处理函数
218
+ * @param options 命令选项
219
+ * @returns 请求完成后退出
220
+ * @example
221
+ * ms source --ip 192.168.1.100 --port 9800 --max-depth 50 --timeout 120
222
+ */
223
+ async function sourceCommand(options) {
224
+ try {
225
+ await ensureValidKuaiJSProject(process.cwd());
226
+ const maxDepthText = (options.maxDepth ?? "50").trim();
227
+ const timeoutText = (options.timeout ?? "120").trim();
228
+ const maxDepth = Number.parseInt(maxDepthText, 10);
229
+ const timeout = Number.parseInt(timeoutText, 10);
230
+ if (!Number.isInteger(maxDepth) || maxDepth < 1) {
231
+ throw new Error(`无效 max-depth: ${maxDepthText}`);
232
+ }
233
+ if (!Number.isInteger(timeout) || timeout < 1) {
234
+ throw new Error(`无效 timeout: ${timeoutText}`);
235
+ }
236
+ const source = await (0, project_1.getSourceOnDevice)(options, maxDepth, timeout);
237
+ if (options.output?.trim()) {
238
+ const outputPath = path.resolve(options.output.trim());
239
+ await fsExtra.ensureDir(path.dirname(outputPath));
240
+ await fsExtra.writeFile(outputPath, source, "utf8");
241
+ console.log(`✅ 节点已保存: ${outputPath}`);
242
+ return;
243
+ }
244
+ console.log(source);
245
+ }
246
+ catch (error) {
247
+ console.error("❌ 获取节点失败:", error instanceof Error ? error.message : error);
248
+ process.exit(1);
249
+ }
250
+ }
186
251
  /**
187
252
  * ws-start 命令处理函数
188
253
  * @param options 命令选项
@@ -365,7 +430,7 @@ function renderDetailedCommandHelp() {
365
430
  return lines.join("\n");
366
431
  }
367
432
  // 配置 CLI 程序
368
- commander_1.program.name("ms-cli").description("快点JS 构建工具").version("1.1.2");
433
+ commander_1.program.name("ms-cli").description("快点JS 构建工具").version(version_1.PACKAGE_VERSION);
369
434
  commander_1.program.addHelpText("after", renderDetailedCommandHelp);
370
435
  // 构建命令
371
436
  commander_1.program
@@ -408,6 +473,31 @@ commander_1.program
408
473
  .option("--ws-port <wsPort>", "WS 服务端口", "31111")
409
474
  .option("--ws-wait-ms <wsWaitMs>", "WS 等待设备连接时间(毫秒)", "30000")
410
475
  .action(stopCommand);
476
+ // 截图命令
477
+ commander_1.program
478
+ .command("screenshot")
479
+ .description("获取设备截图(JPG)")
480
+ .option("-i, --ip <ip>", "设备 IP 地址(transport=http 时必填)")
481
+ .option("--port <port>", "设备端口", "9800")
482
+ .option("-t, --transport <transport>", "传输方式: http|ws", "http")
483
+ .option("--ws-port <wsPort>", "WS 服务端口", "31111")
484
+ .option("--ws-wait-ms <wsWaitMs>", "WS 等待设备连接时间(毫秒)", "30000")
485
+ .option("--format <format>", "返回格式: file|base64", "file")
486
+ .option("--output <output>", "截图输出文件路径(format=file 时生效)")
487
+ .action(screenshotCommand);
488
+ // 节点命令
489
+ commander_1.program
490
+ .command("source")
491
+ .description("获取设备当前页面节点 XML")
492
+ .option("-i, --ip <ip>", "设备 IP 地址(transport=http 时必填)")
493
+ .option("--port <port>", "设备端口", "9800")
494
+ .option("-t, --transport <transport>", "传输方式: http|ws", "http")
495
+ .option("--ws-port <wsPort>", "WS 服务端口", "31111")
496
+ .option("--ws-wait-ms <wsWaitMs>", "WS 等待设备连接时间(毫秒)", "30000")
497
+ .option("--max-depth <maxDepth>", "节点最大深度", "50")
498
+ .option("--timeout <timeout>", "节点抓取超时秒数", "120")
499
+ .option("--output <output>", "节点 XML 输出文件路径(可选)")
500
+ .action(sourceCommand);
411
501
  // WS 服务启动命令
412
502
  commander_1.program
413
503
  .command("ws-start")
@@ -0,0 +1,55 @@
1
+ import type { DeviceConfig } from "./types";
2
+ /**
3
+ * 默认设备端口
4
+ */
5
+ export declare const DEFAULT_DEVICE_PORT = 9800;
6
+ /**
7
+ * 设备连接配置持久化文件
8
+ * - 使用系统临时目录,避免污染项目源码目录
9
+ * - 文件名包含 pid/时间戳/随机串,确保并发窗口与多次启动互不冲突
10
+ */
11
+ export declare const DEVICE_CONFIG_FILE: string;
12
+ /**
13
+ * 将端口标准化为字符串(内部沿用 DeviceCliOptions 字符串端口)
14
+ * @param port 端口号
15
+ * @returns 返回标准端口字符串
16
+ * @example
17
+ * const textPort = normalizePort(9800)
18
+ */
19
+ export declare function normalizePort(port: number): string;
20
+ /**
21
+ * 读取已保存的设备配置
22
+ * @returns 若存在有效配置则返回配置对象,否则返回 null
23
+ * @example
24
+ * const cfg = await readDeviceConfig()
25
+ */
26
+ export declare function readDeviceConfig(): Promise<DeviceConfig | null>;
27
+ /**
28
+ * 保存设备配置
29
+ * @param config 需要保存的设备配置
30
+ * @returns 保存完成后返回 Promise<void>
31
+ * @example
32
+ * await writeDeviceConfig({ ip: "192.168.1.100", port: 9800, updatedAt: Date.now() })
33
+ */
34
+ export declare function writeDeviceConfig(config: DeviceConfig): Promise<void>;
35
+ /**
36
+ * 构建并保存设备配置
37
+ * @param ip 设备 IP
38
+ * @param port 设备端口(可选)
39
+ * @returns 返回保存后的设备配置
40
+ * @example
41
+ * const cfg = await setDeviceConfig("192.168.1.100", 9800)
42
+ */
43
+ export declare function setDeviceConfig(ip: string, port?: number): Promise<DeviceConfig>;
44
+ /**
45
+ * 获取最终生效的设备配置
46
+ * - 若调用参数携带 ip,则优先使用调用参数并落盘
47
+ * - 若只传 port,则复用已保存 ip,并更新 port 后落盘
48
+ * - 若都不传,则读取已保存配置
49
+ * @param ip 调用参数中的设备 ip(可选)
50
+ * @param port 调用参数中的设备端口(可选)
51
+ * @returns 返回可直接用于请求设备的配置
52
+ * @example
53
+ * const target = await resolveDeviceConfig(undefined, undefined)
54
+ */
55
+ export declare function resolveDeviceConfig(ip?: string, port?: number): Promise<DeviceConfig>;
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEVICE_CONFIG_FILE = exports.DEFAULT_DEVICE_PORT = void 0;
37
+ exports.normalizePort = normalizePort;
38
+ exports.readDeviceConfig = readDeviceConfig;
39
+ exports.writeDeviceConfig = writeDeviceConfig;
40
+ exports.setDeviceConfig = setDeviceConfig;
41
+ exports.resolveDeviceConfig = resolveDeviceConfig;
42
+ const fsExtra = __importStar(require("fs-extra"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ /**
46
+ * 默认设备端口
47
+ */
48
+ exports.DEFAULT_DEVICE_PORT = 9800;
49
+ /**
50
+ * 设备连接配置持久化文件
51
+ * - 使用系统临时目录,避免污染项目源码目录
52
+ * - 文件名包含 pid/时间戳/随机串,确保并发窗口与多次启动互不冲突
53
+ */
54
+ exports.DEVICE_CONFIG_FILE = path.join(os.tmpdir(), `ms-cli-mcp-device-${process.pid}-${Date.now()}-${Math.random()
55
+ .toString(36)
56
+ .slice(2, 10)}.json`);
57
+ /**
58
+ * 将端口标准化为字符串(内部沿用 DeviceCliOptions 字符串端口)
59
+ * @param port 端口号
60
+ * @returns 返回标准端口字符串
61
+ * @example
62
+ * const textPort = normalizePort(9800)
63
+ */
64
+ function normalizePort(port) {
65
+ return String(port);
66
+ }
67
+ /**
68
+ * 校验并标准化 IP 字符串
69
+ * @param ip 原始 ip 输入
70
+ * @returns 返回去空格后的 ip
71
+ * @example
72
+ * const normalizedIp = normalizeIp(" 192.168.1.100 ")
73
+ */
74
+ function normalizeIp(ip) {
75
+ const normalizedIp = ip.trim();
76
+ if (!normalizedIp) {
77
+ throw new Error("设备 IP 不能为空");
78
+ }
79
+ return normalizedIp;
80
+ }
81
+ /**
82
+ * 校验并标准化端口
83
+ * @param port 原始端口(可选)
84
+ * @returns 返回有效端口,默认 9800
85
+ * @example
86
+ * const normalizedPort = normalizeDevicePort(undefined)
87
+ */
88
+ function normalizeDevicePort(port) {
89
+ const targetPort = port ?? exports.DEFAULT_DEVICE_PORT;
90
+ if (!Number.isInteger(targetPort) || targetPort < 1 || targetPort > 65535) {
91
+ throw new Error(`无效设备端口: ${String(port)}`);
92
+ }
93
+ return targetPort;
94
+ }
95
+ /**
96
+ * 读取已保存的设备配置
97
+ * @returns 若存在有效配置则返回配置对象,否则返回 null
98
+ * @example
99
+ * const cfg = await readDeviceConfig()
100
+ */
101
+ async function readDeviceConfig() {
102
+ try {
103
+ if (!(await fsExtra.pathExists(exports.DEVICE_CONFIG_FILE))) {
104
+ return null;
105
+ }
106
+ const data = (await fsExtra.readJSON(exports.DEVICE_CONFIG_FILE));
107
+ const ip = typeof data.ip === "string" ? data.ip.trim() : "";
108
+ const port = typeof data.port === "number" ? data.port : Number.parseInt(String(data.port), 10);
109
+ if (!ip || !Number.isInteger(port) || port < 1 || port > 65535) {
110
+ return null;
111
+ }
112
+ return {
113
+ ip,
114
+ port,
115
+ updatedAt: typeof data.updatedAt === "number" && Number.isFinite(data.updatedAt)
116
+ ? data.updatedAt
117
+ : Date.now(),
118
+ };
119
+ }
120
+ catch {
121
+ return null;
122
+ }
123
+ }
124
+ /**
125
+ * 保存设备配置
126
+ * @param config 需要保存的设备配置
127
+ * @returns 保存完成后返回 Promise<void>
128
+ * @example
129
+ * await writeDeviceConfig({ ip: "192.168.1.100", port: 9800, updatedAt: Date.now() })
130
+ */
131
+ async function writeDeviceConfig(config) {
132
+ await fsExtra.writeJSON(exports.DEVICE_CONFIG_FILE, config, { spaces: 2 });
133
+ }
134
+ /**
135
+ * 构建并保存设备配置
136
+ * @param ip 设备 IP
137
+ * @param port 设备端口(可选)
138
+ * @returns 返回保存后的设备配置
139
+ * @example
140
+ * const cfg = await setDeviceConfig("192.168.1.100", 9800)
141
+ */
142
+ async function setDeviceConfig(ip, port) {
143
+ const config = {
144
+ ip: normalizeIp(ip),
145
+ port: normalizeDevicePort(port),
146
+ updatedAt: Date.now(),
147
+ };
148
+ await writeDeviceConfig(config);
149
+ return config;
150
+ }
151
+ /**
152
+ * 获取最终生效的设备配置
153
+ * - 若调用参数携带 ip,则优先使用调用参数并落盘
154
+ * - 若只传 port,则复用已保存 ip,并更新 port 后落盘
155
+ * - 若都不传,则读取已保存配置
156
+ * @param ip 调用参数中的设备 ip(可选)
157
+ * @param port 调用参数中的设备端口(可选)
158
+ * @returns 返回可直接用于请求设备的配置
159
+ * @example
160
+ * const target = await resolveDeviceConfig(undefined, undefined)
161
+ */
162
+ async function resolveDeviceConfig(ip, port) {
163
+ const savedConfig = await readDeviceConfig();
164
+ if (ip !== undefined) {
165
+ return setDeviceConfig(ip, port);
166
+ }
167
+ if (port !== undefined) {
168
+ if (!savedConfig) {
169
+ throw new Error("尚未配置设备 IP。请先调用 set_device 设置 ip,或在本次 run 调用里传入 ip。");
170
+ }
171
+ const nextConfig = {
172
+ ip: savedConfig.ip,
173
+ port: normalizeDevicePort(port),
174
+ updatedAt: Date.now(),
175
+ };
176
+ await writeDeviceConfig(nextConfig);
177
+ return nextConfig;
178
+ }
179
+ if (savedConfig) {
180
+ return savedConfig;
181
+ }
182
+ throw new Error("未找到可用设备配置。请先调用 set_device 设置 ip,或在 run/run_ui/stop 调用里传入 ip。");
183
+ }
@@ -0,0 +1,65 @@
1
+ import type { ApiDocItem, ApiDocsLanguage } from "./types";
2
+ /**
3
+ * 获取当前文档语言
4
+ * @returns 返回当前语言
5
+ * @example
6
+ * const language = getCurrentDocsLanguage()
7
+ */
8
+ export declare function getCurrentDocsLanguage(): ApiDocsLanguage;
9
+ /**
10
+ * 设置当前文档语言
11
+ * @param language 目标语言
12
+ * @returns 设置后的语言
13
+ * @example
14
+ * const language = setCurrentDocsLanguage("python")
15
+ */
16
+ export declare function setCurrentDocsLanguage(language: ApiDocsLanguage): ApiDocsLanguage;
17
+ /**
18
+ * 根据可选入参解析实际使用的文档语言
19
+ * @param language 工具调用时传入的语言(可选)
20
+ * @returns 返回最终生效的语言
21
+ * @example
22
+ * const activeLanguage = resolveDocsLanguage(undefined)
23
+ */
24
+ export declare function resolveDocsLanguage(language?: ApiDocsLanguage): ApiDocsLanguage;
25
+ /**
26
+ * 获取 docs 根目录
27
+ * @returns 返回 docs 目录绝对路径
28
+ * @example
29
+ * const docsRoot = getDocsRootDir()
30
+ */
31
+ export declare function getDocsRootDir(): string;
32
+ /**
33
+ * 获取某语言对应的文档目录
34
+ * @param language 文档语言
35
+ * @returns 返回文档目录绝对路径
36
+ * @example
37
+ * const dir = getDocsDirByLanguage("js_zh")
38
+ */
39
+ export declare function getDocsDirByLanguage(language: ApiDocsLanguage): string;
40
+ /**
41
+ * 读取指定语言的 API 文档列表
42
+ * @param language 文档语言
43
+ * @returns 返回文档条目数组(按 slug 升序)
44
+ * @example
45
+ * const docs = await getApiDocsByLanguage("python")
46
+ */
47
+ export declare function getApiDocsByLanguage(language: ApiDocsLanguage): Promise<ApiDocItem[]>;
48
+ /**
49
+ * 对文档按查询词打分,用于检索排序
50
+ * @param doc 文档条目
51
+ * @param normalizedQuery 已转小写的查询词
52
+ * @returns 分数,0 表示不命中
53
+ * @example
54
+ * const score = scoreApiDoc(doc, "click")
55
+ */
56
+ export declare function scoreApiDoc(doc: ApiDocItem, normalizedQuery: string): number;
57
+ /**
58
+ * 生成文档 URI(用于资源与文本返回)
59
+ * @param language 文档语言
60
+ * @param slug 文档分类
61
+ * @returns 返回 MCP 资源 URI 字符串
62
+ * @example
63
+ * const uri = getDocUri("js_zh", "device")
64
+ */
65
+ export declare function getDocUri(language: ApiDocsLanguage, slug: string): string;
@@ -0,0 +1,168 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getCurrentDocsLanguage = getCurrentDocsLanguage;
37
+ exports.setCurrentDocsLanguage = setCurrentDocsLanguage;
38
+ exports.resolveDocsLanguage = resolveDocsLanguage;
39
+ exports.getDocsRootDir = getDocsRootDir;
40
+ exports.getDocsDirByLanguage = getDocsDirByLanguage;
41
+ exports.getApiDocsByLanguage = getApiDocsByLanguage;
42
+ exports.scoreApiDoc = scoreApiDoc;
43
+ exports.getDocUri = getDocUri;
44
+ const fsExtra = __importStar(require("fs-extra"));
45
+ const path = __importStar(require("path"));
46
+ /**
47
+ * 当前 MCP 进程默认文档语言
48
+ */
49
+ let currentDocsLanguage = "js_zh";
50
+ /**
51
+ * 获取当前文档语言
52
+ * @returns 返回当前语言
53
+ * @example
54
+ * const language = getCurrentDocsLanguage()
55
+ */
56
+ function getCurrentDocsLanguage() {
57
+ return currentDocsLanguage;
58
+ }
59
+ /**
60
+ * 设置当前文档语言
61
+ * @param language 目标语言
62
+ * @returns 设置后的语言
63
+ * @example
64
+ * const language = setCurrentDocsLanguage("python")
65
+ */
66
+ function setCurrentDocsLanguage(language) {
67
+ currentDocsLanguage = language;
68
+ return currentDocsLanguage;
69
+ }
70
+ /**
71
+ * 根据可选入参解析实际使用的文档语言
72
+ * @param language 工具调用时传入的语言(可选)
73
+ * @returns 返回最终生效的语言
74
+ * @example
75
+ * const activeLanguage = resolveDocsLanguage(undefined)
76
+ */
77
+ function resolveDocsLanguage(language) {
78
+ return language ?? currentDocsLanguage;
79
+ }
80
+ /**
81
+ * 获取 docs 根目录
82
+ * @returns 返回 docs 目录绝对路径
83
+ * @example
84
+ * const docsRoot = getDocsRootDir()
85
+ */
86
+ function getDocsRootDir() {
87
+ return path.resolve(__dirname, "..", "..", "docs");
88
+ }
89
+ /**
90
+ * 获取某语言对应的文档目录
91
+ * @param language 文档语言
92
+ * @returns 返回文档目录绝对路径
93
+ * @example
94
+ * const dir = getDocsDirByLanguage("js_zh")
95
+ */
96
+ function getDocsDirByLanguage(language) {
97
+ if (language === "js") {
98
+ return path.join(getDocsRootDir(), "api");
99
+ }
100
+ if (language === "js_zh") {
101
+ return path.join(getDocsRootDir(), "apicn");
102
+ }
103
+ return path.join(getDocsRootDir(), "apipython");
104
+ }
105
+ /**
106
+ * 读取指定语言的 API 文档列表
107
+ * @param language 文档语言
108
+ * @returns 返回文档条目数组(按 slug 升序)
109
+ * @example
110
+ * const docs = await getApiDocsByLanguage("python")
111
+ */
112
+ async function getApiDocsByLanguage(language) {
113
+ const docsDir = getDocsDirByLanguage(language);
114
+ if (!(await fsExtra.pathExists(docsDir))) {
115
+ throw new Error(`文档目录不存在: ${docsDir}`);
116
+ }
117
+ const fileNames = await fsExtra.readdir(docsDir);
118
+ const mdFiles = fileNames
119
+ .filter((name) => name.toLowerCase().endsWith(".md"))
120
+ .sort();
121
+ const docs = [];
122
+ for (const fileName of mdFiles) {
123
+ const filePath = path.join(docsDir, fileName);
124
+ const content = await fsExtra.readFile(filePath, "utf8");
125
+ const slug = path.basename(fileName, ".md");
126
+ const titleMatch = content.match(/^#\s+(.+)$/m);
127
+ const title = titleMatch?.[1]?.trim() || slug;
128
+ docs.push({
129
+ slug,
130
+ title,
131
+ content,
132
+ filePath,
133
+ });
134
+ }
135
+ return docs;
136
+ }
137
+ /**
138
+ * 对文档按查询词打分,用于检索排序
139
+ * @param doc 文档条目
140
+ * @param normalizedQuery 已转小写的查询词
141
+ * @returns 分数,0 表示不命中
142
+ * @example
143
+ * const score = scoreApiDoc(doc, "click")
144
+ */
145
+ function scoreApiDoc(doc, normalizedQuery) {
146
+ let score = 0;
147
+ if (doc.title.toLowerCase().includes(normalizedQuery)) {
148
+ score += 50;
149
+ }
150
+ if (doc.slug.toLowerCase().includes(normalizedQuery)) {
151
+ score += 40;
152
+ }
153
+ if (doc.content.toLowerCase().includes(normalizedQuery)) {
154
+ score += 10;
155
+ }
156
+ return score;
157
+ }
158
+ /**
159
+ * 生成文档 URI(用于资源与文本返回)
160
+ * @param language 文档语言
161
+ * @param slug 文档分类
162
+ * @returns 返回 MCP 资源 URI 字符串
163
+ * @example
164
+ * const uri = getDocUri("js_zh", "device")
165
+ */
166
+ function getDocUri(language, slug) {
167
+ return `kuaijs://docs/${language}/${slug}`;
168
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 检查工作目录是否为有效的 KuaiJS 项目
3
+ * @param workspacePath 工作目录路径
4
+ * @returns 若目录包含 package.json 与 scripts 目录则返回 true,否则返回 false
5
+ * @example
6
+ * const ok = await isValidKuaiJSProject(process.cwd())
7
+ */
8
+ export declare function isValidKuaiJSProject(workspacePath: string): Promise<boolean>;
9
+ /**
10
+ * 校验当前目录是否是可执行构建/运行的 KuaiJS 项目
11
+ * @param workspacePath 待校验目录
12
+ * @returns 校验通过时返回 Promise<void>,失败时抛出异常
13
+ * @example
14
+ * await ensureValidKuaiJSProject("/Users/demo/project")
15
+ */
16
+ export declare function ensureValidKuaiJSProject(workspacePath: string): Promise<void>;