ms-vite-plugin 1.1.21 → 1.1.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/mcp/httpapi-docs-service.d.ts +0 -7
- package/dist/mcp/httpapi-docs-service.js +27 -12
- package/dist/mcp/httpapi-tools.js +48 -23
- package/dist/mcp/runtime-tools.js +19 -10
- package/docs/SKILL.md +147 -0
- package/docs/mcp-agent-description.md +133 -0
- package/package.json +1 -1
|
@@ -23,13 +23,6 @@ export type HttpApiDocEntry = {
|
|
|
23
23
|
/** 接口完整 markdown 片段 */
|
|
24
24
|
content: string;
|
|
25
25
|
};
|
|
26
|
-
/**
|
|
27
|
-
* 获取 HTTP API 文档路径
|
|
28
|
-
* @returns 返回 docs/httpapi/api.md 的绝对路径
|
|
29
|
-
* @example
|
|
30
|
-
* const filePath = getHttpApiDocPath()
|
|
31
|
-
*/
|
|
32
|
-
export declare function getHttpApiDocPath(): string;
|
|
33
26
|
/**
|
|
34
27
|
* 读取 HTTP API markdown 文档
|
|
35
28
|
* @returns 返回完整 markdown 文本
|
|
@@ -33,7 +33,6 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.getHttpApiDocPath = getHttpApiDocPath;
|
|
37
36
|
exports.readHttpApiMarkdown = readHttpApiMarkdown;
|
|
38
37
|
exports.createHttpApiSlug = createHttpApiSlug;
|
|
39
38
|
exports.getHttpApiDocEntries = getHttpApiDocEntries;
|
|
@@ -41,14 +40,19 @@ exports.scoreHttpApiDocEntry = scoreHttpApiDocEntry;
|
|
|
41
40
|
exports.findHttpApiDocEntry = findHttpApiDocEntry;
|
|
42
41
|
const fsExtra = __importStar(require("fs-extra"));
|
|
43
42
|
const path = __importStar(require("path"));
|
|
43
|
+
const HTTP_API_DOC_RELATIVE_PATH = ["docs", "httpapi", "api.md"];
|
|
44
|
+
const HTTP_API_ENDPOINT_PATTERN = /^(GET|POST)\s+(\/\S+)/;
|
|
45
|
+
const HTTP_API_SECTION_PATTERN = /^#\s+(.+)$/;
|
|
46
|
+
const HTTP_API_TITLE_PATTERN = /^##\s+(.+)$/;
|
|
47
|
+
let cachedHttpApiDocEntries = null;
|
|
44
48
|
/**
|
|
45
49
|
* 获取 HTTP API 文档路径
|
|
46
|
-
* @returns 返回
|
|
50
|
+
* @returns 返回 HTTP API 文档绝对路径
|
|
47
51
|
* @example
|
|
48
52
|
* const filePath = getHttpApiDocPath()
|
|
49
53
|
*/
|
|
50
54
|
function getHttpApiDocPath() {
|
|
51
|
-
return path.resolve(__dirname, "..", "..",
|
|
55
|
+
return path.resolve(__dirname, "..", "..", ...HTTP_API_DOC_RELATIVE_PATH);
|
|
52
56
|
}
|
|
53
57
|
/**
|
|
54
58
|
* 读取 HTTP API markdown 文档
|
|
@@ -59,7 +63,7 @@ function getHttpApiDocPath() {
|
|
|
59
63
|
async function readHttpApiMarkdown() {
|
|
60
64
|
const filePath = getHttpApiDocPath();
|
|
61
65
|
if (!(await fsExtra.pathExists(filePath))) {
|
|
62
|
-
throw new Error(
|
|
66
|
+
throw new Error("HTTP API 文档不可用。");
|
|
63
67
|
}
|
|
64
68
|
return fsExtra.readFile(filePath, "utf8");
|
|
65
69
|
}
|
|
@@ -73,8 +77,6 @@ async function readHttpApiMarkdown() {
|
|
|
73
77
|
*/
|
|
74
78
|
function createHttpApiSlug(method, apiPath) {
|
|
75
79
|
return `${method.toLowerCase()}-${apiPath}`
|
|
76
|
-
.replace(/^get-\//, "get-")
|
|
77
|
-
.replace(/^post-\//, "post-")
|
|
78
80
|
.replace(/[^a-zA-Z0-9]+/g, "-")
|
|
79
81
|
.replace(/^-+|-+$/g, "")
|
|
80
82
|
.toLowerCase();
|
|
@@ -86,18 +88,26 @@ function createHttpApiSlug(method, apiPath) {
|
|
|
86
88
|
* const entries = await getHttpApiDocEntries()
|
|
87
89
|
*/
|
|
88
90
|
async function getHttpApiDocEntries() {
|
|
89
|
-
const
|
|
91
|
+
const filePath = getHttpApiDocPath();
|
|
92
|
+
const stat = await fsExtra.stat(filePath).catch(() => null);
|
|
93
|
+
if (!stat) {
|
|
94
|
+
throw new Error("HTTP API 文档不可用。");
|
|
95
|
+
}
|
|
96
|
+
if (cachedHttpApiDocEntries?.mtimeMs === stat.mtimeMs) {
|
|
97
|
+
return cachedHttpApiDocEntries.entries;
|
|
98
|
+
}
|
|
99
|
+
const markdown = await fsExtra.readFile(filePath, "utf8");
|
|
90
100
|
const lines = markdown.split(/\r?\n/);
|
|
91
101
|
const entries = [];
|
|
92
102
|
let currentSection = "";
|
|
93
103
|
for (let index = 0; index < lines.length; index += 1) {
|
|
94
104
|
const line = lines[index] ?? "";
|
|
95
|
-
const sectionMatch = line.match(
|
|
105
|
+
const sectionMatch = line.match(HTTP_API_SECTION_PATTERN);
|
|
96
106
|
if (sectionMatch) {
|
|
97
107
|
currentSection = sectionMatch[1]?.trim() ?? "";
|
|
98
108
|
continue;
|
|
99
109
|
}
|
|
100
|
-
const titleMatch = line.match(
|
|
110
|
+
const titleMatch = line.match(HTTP_API_TITLE_PATTERN);
|
|
101
111
|
if (!titleMatch) {
|
|
102
112
|
continue;
|
|
103
113
|
}
|
|
@@ -105,7 +115,7 @@ async function getHttpApiDocEntries() {
|
|
|
105
115
|
let method = null;
|
|
106
116
|
let apiPath = "";
|
|
107
117
|
for (let cursor = index + 1; cursor < Math.min(lines.length, index + 8); cursor += 1) {
|
|
108
|
-
const endpointMatch = (lines[cursor] ?? "").match(
|
|
118
|
+
const endpointMatch = (lines[cursor] ?? "").match(HTTP_API_ENDPOINT_PATTERN);
|
|
109
119
|
if (endpointMatch) {
|
|
110
120
|
method = endpointMatch[1];
|
|
111
121
|
apiPath = endpointMatch[2] ?? "";
|
|
@@ -117,7 +127,7 @@ async function getHttpApiDocEntries() {
|
|
|
117
127
|
}
|
|
118
128
|
let endIndex = lines.length;
|
|
119
129
|
for (let cursor = index + 1; cursor < lines.length; cursor += 1) {
|
|
120
|
-
if (
|
|
130
|
+
if (HTTP_API_TITLE_PATTERN.test(lines[cursor] ?? "")) {
|
|
121
131
|
endIndex = cursor;
|
|
122
132
|
break;
|
|
123
133
|
}
|
|
@@ -133,6 +143,10 @@ async function getHttpApiDocEntries() {
|
|
|
133
143
|
content: lines.slice(index, endIndex).join("\n").trim(),
|
|
134
144
|
});
|
|
135
145
|
}
|
|
146
|
+
cachedHttpApiDocEntries = {
|
|
147
|
+
mtimeMs: stat.mtimeMs,
|
|
148
|
+
entries,
|
|
149
|
+
};
|
|
136
150
|
return entries;
|
|
137
151
|
}
|
|
138
152
|
/**
|
|
@@ -183,6 +197,7 @@ async function findHttpApiDocEntry(identifier, method) {
|
|
|
183
197
|
return entries.find((entry) => {
|
|
184
198
|
const methodMatches = method ? entry.method === method : true;
|
|
185
199
|
return (methodMatches &&
|
|
186
|
-
(entry.slug === normalizedIdentifier ||
|
|
200
|
+
(entry.slug === normalizedIdentifier ||
|
|
201
|
+
entry.path === normalizedIdentifier));
|
|
187
202
|
});
|
|
188
203
|
}
|
|
@@ -42,6 +42,7 @@ const tool_utils_1 = require("./tool-utils");
|
|
|
42
42
|
* HTTP API 文档完整资源 URI
|
|
43
43
|
*/
|
|
44
44
|
const HTTP_API_DOC_RESOURCE_URI = "kuaijs://httpapi/api";
|
|
45
|
+
const HTTP_API_ENDPOINT_RESOURCE_PREFIX = "kuaijs://httpapi/endpoints";
|
|
45
46
|
/**
|
|
46
47
|
* 格式化 HTTP API 文档搜索摘要
|
|
47
48
|
* @param entry HTTP API 文档条目
|
|
@@ -58,7 +59,7 @@ function formatHttpApiDocSummary(entry, index) {
|
|
|
58
59
|
`slug: ${entry.slug}`,
|
|
59
60
|
`section: ${entry.section || "未分组"}`,
|
|
60
61
|
`lines: ${entry.startLine}-${entry.endLine}`,
|
|
61
|
-
`uri:
|
|
62
|
+
`uri: ${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
|
|
62
63
|
].join("\n");
|
|
63
64
|
}
|
|
64
65
|
/**
|
|
@@ -100,6 +101,41 @@ function appendQueryParams(url, query) {
|
|
|
100
101
|
url.searchParams.set(key, String(value));
|
|
101
102
|
}
|
|
102
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* 构建 JSON HTTP 请求体
|
|
106
|
+
* @param body 工具调用传入的 body
|
|
107
|
+
* @returns 返回可直接用于 fetch 的请求体和头
|
|
108
|
+
* @example
|
|
109
|
+
* createHttpRequestBody({ actions: [] })
|
|
110
|
+
*/
|
|
111
|
+
function createHttpRequestBody(body) {
|
|
112
|
+
if (body === undefined) {
|
|
113
|
+
return {};
|
|
114
|
+
}
|
|
115
|
+
const headers = {
|
|
116
|
+
"Content-Type": "application/json",
|
|
117
|
+
};
|
|
118
|
+
if (typeof body === "string") {
|
|
119
|
+
const trimmedBody = body.trim();
|
|
120
|
+
try {
|
|
121
|
+
JSON.parse(trimmedBody);
|
|
122
|
+
return {
|
|
123
|
+
headers,
|
|
124
|
+
requestBody: trimmedBody,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
return {
|
|
129
|
+
headers,
|
|
130
|
+
requestBody: JSON.stringify(body),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
return {
|
|
135
|
+
headers,
|
|
136
|
+
requestBody: JSON.stringify(body),
|
|
137
|
+
};
|
|
138
|
+
}
|
|
103
139
|
/**
|
|
104
140
|
* 读取响应体并按要求格式化
|
|
105
141
|
* @param response fetch 响应对象
|
|
@@ -140,12 +176,12 @@ function registerHttpApiTools(server) {
|
|
|
140
176
|
},
|
|
141
177
|
],
|
|
142
178
|
}));
|
|
143
|
-
server.registerResource("http-api-endpoint", new mcp_js_1.ResourceTemplate(
|
|
179
|
+
server.registerResource("http-api-endpoint", new mcp_js_1.ResourceTemplate(`${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/{slug}`, {
|
|
144
180
|
list: async () => {
|
|
145
181
|
const entries = await (0, httpapi_docs_service_1.getHttpApiDocEntries)();
|
|
146
182
|
return {
|
|
147
183
|
resources: entries.map((entry) => ({
|
|
148
|
-
uri:
|
|
184
|
+
uri: `${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
|
|
149
185
|
name: `${entry.method} ${entry.path}`,
|
|
150
186
|
description: `${entry.title} [${entry.section || "未分组"}]`,
|
|
151
187
|
mimeType: "text/markdown",
|
|
@@ -164,7 +200,7 @@ function registerHttpApiTools(server) {
|
|
|
164
200
|
return {
|
|
165
201
|
contents: [
|
|
166
202
|
{
|
|
167
|
-
uri:
|
|
203
|
+
uri: `${HTTP_API_ENDPOINT_RESOURCE_PREFIX}/${entry.slug}`,
|
|
168
204
|
mimeType: "text/markdown",
|
|
169
205
|
text: entry.content,
|
|
170
206
|
},
|
|
@@ -173,7 +209,7 @@ function registerHttpApiTools(server) {
|
|
|
173
209
|
});
|
|
174
210
|
server.registerTool("search_http_api_docs", {
|
|
175
211
|
title: "Search HTTP API Docs",
|
|
176
|
-
description: "搜索
|
|
212
|
+
description: "搜索 HTTP API 文档中声明的接口。调用 http_api_call 前应先用本工具确认接口 method、path、参数和 slug。",
|
|
177
213
|
inputSchema: {
|
|
178
214
|
query: z
|
|
179
215
|
.string()
|
|
@@ -203,16 +239,16 @@ function registerHttpApiTools(server) {
|
|
|
203
239
|
.slice(0, limit)
|
|
204
240
|
.map((item) => item.entry);
|
|
205
241
|
return (0, tool_utils_1.createTextToolResult)(matches.length === 0
|
|
206
|
-
? `未找到与 "${query}" 匹配的 HTTP API
|
|
242
|
+
? `未找到与 "${query}" 匹配的 HTTP API 文档。`
|
|
207
243
|
: [
|
|
208
|
-
|
|
244
|
+
"HTTP API 文档匹配结果:",
|
|
209
245
|
"",
|
|
210
246
|
...matches.map((entry, index) => formatHttpApiDocSummary(entry, index)),
|
|
211
247
|
].join("\n"));
|
|
212
248
|
});
|
|
213
249
|
server.registerTool("read_http_api_doc", {
|
|
214
250
|
title: "Read HTTP API Doc",
|
|
215
|
-
description: "按 slug 或 path 读取
|
|
251
|
+
description: "按 slug 或 path 读取 HTTP API 文档中的接口片段。调用 http_api_call 前应读取目标接口片段,确认参数位置、类型和返回结构。",
|
|
216
252
|
inputSchema: {
|
|
217
253
|
identifier: z
|
|
218
254
|
.string()
|
|
@@ -241,7 +277,7 @@ function registerHttpApiTools(server) {
|
|
|
241
277
|
});
|
|
242
278
|
server.registerTool("http_api_call", {
|
|
243
279
|
title: "HTTP API Call",
|
|
244
|
-
description: "调用
|
|
280
|
+
description: "调用 HTTP API 文档中已声明的接口。使用前应先调用 search_http_api_docs/read_http_api_doc 获取 docSlug,并确认 method、path、query/body 参数;本工具会拒绝 docSlug、method、path 不匹配的调用。",
|
|
245
281
|
inputSchema: {
|
|
246
282
|
method: z
|
|
247
283
|
.enum(["GET", "POST"])
|
|
@@ -261,7 +297,7 @@ function registerHttpApiTools(server) {
|
|
|
261
297
|
body: z
|
|
262
298
|
.unknown()
|
|
263
299
|
.optional()
|
|
264
|
-
.describe("POST
|
|
300
|
+
.describe("POST 请求体;始终按 JSON 提交。推荐传 JSON 对象;JSON 字符串会按原 JSON 提交,普通字符串会作为 JSON 字符串值提交。"),
|
|
265
301
|
responseFormat: z
|
|
266
302
|
.enum(["json", "text"])
|
|
267
303
|
.optional()
|
|
@@ -302,22 +338,11 @@ function registerHttpApiTools(server) {
|
|
|
302
338
|
const controller = new AbortController();
|
|
303
339
|
const timeout = setTimeout(() => controller.abort(), timeoutMs);
|
|
304
340
|
try {
|
|
305
|
-
const headers =
|
|
306
|
-
let requestBody;
|
|
307
|
-
if (body !== undefined) {
|
|
308
|
-
if (typeof body === "string") {
|
|
309
|
-
requestBody = body;
|
|
310
|
-
headers["Content-Type"] = "text/plain; charset=utf-8";
|
|
311
|
-
}
|
|
312
|
-
else {
|
|
313
|
-
requestBody = JSON.stringify(body);
|
|
314
|
-
headers["Content-Type"] = "application/json";
|
|
315
|
-
}
|
|
316
|
-
}
|
|
341
|
+
const { headers, requestBody } = createHttpRequestBody(body);
|
|
317
342
|
const response = await fetch(url.toString(), {
|
|
318
343
|
method,
|
|
319
344
|
signal: controller.signal,
|
|
320
|
-
headers
|
|
345
|
+
headers,
|
|
321
346
|
body: requestBody,
|
|
322
347
|
});
|
|
323
348
|
const responseText = await readHttpApiResponseText(response, responseFormat);
|
|
@@ -44,6 +44,23 @@ const device_config_1 = require("./device-config");
|
|
|
44
44
|
const device_log_1 = require("./device-log");
|
|
45
45
|
const project_2 = require("./project");
|
|
46
46
|
const tool_utils_1 = require("./tool-utils");
|
|
47
|
+
/**
|
|
48
|
+
* 解析工具输出文件路径
|
|
49
|
+
* @param outputPath 用户指定的可选输出路径
|
|
50
|
+
* @param fileNamePrefix 临时文件名前缀
|
|
51
|
+
* @param extension 文件扩展名(不含点)
|
|
52
|
+
* @returns 返回最终输出文件绝对路径
|
|
53
|
+
* @example
|
|
54
|
+
* resolveOutputPath(undefined, "ms-mcp-screenshot", "jpg")
|
|
55
|
+
*/
|
|
56
|
+
function resolveOutputPath(outputPath, fileNamePrefix, extension) {
|
|
57
|
+
if (outputPath && outputPath.trim()) {
|
|
58
|
+
return path.resolve(outputPath.trim());
|
|
59
|
+
}
|
|
60
|
+
return path.join(os.tmpdir(), `${fileNamePrefix}-${Date.now()}-${Math.random()
|
|
61
|
+
.toString(36)
|
|
62
|
+
.slice(2, 8)}.${extension}`);
|
|
63
|
+
}
|
|
47
64
|
/**
|
|
48
65
|
* 注册设备与项目执行工具
|
|
49
66
|
* @param server MCP 服务实例
|
|
@@ -167,11 +184,7 @@ function registerRuntimeTools(server) {
|
|
|
167
184
|
return (0, tool_utils_1.createTextToolResult)(`截图成功: ${target.label}\nformat: base64\n${base64}`);
|
|
168
185
|
}
|
|
169
186
|
const image = await (0, project_1.getScreenshotOnDevice)(requestOptions);
|
|
170
|
-
const targetPath = outputPath
|
|
171
|
-
? path.resolve(outputPath.trim())
|
|
172
|
-
: path.join(os.tmpdir(), `ms-mcp-screenshot-${Date.now()}-${Math.random()
|
|
173
|
-
.toString(36)
|
|
174
|
-
.slice(2, 8)}.jpg`);
|
|
187
|
+
const targetPath = resolveOutputPath(outputPath, "ms-mcp-screenshot", "jpg");
|
|
175
188
|
await fsExtra.ensureDir(path.dirname(targetPath));
|
|
176
189
|
await fsExtra.writeFile(targetPath, image);
|
|
177
190
|
return (0, tool_utils_1.createTextToolResult)(`截图成功: ${target.label}\nformat: file\npath: ${targetPath}\nsize: ${image.length} bytes`);
|
|
@@ -206,11 +219,7 @@ function registerRuntimeTools(server) {
|
|
|
206
219
|
const target = await (0, tool_utils_1.resolveRuntimeHttpTarget)();
|
|
207
220
|
const requestOptions = (0, tool_utils_1.createRuntimeHttpRequestOptions)(target);
|
|
208
221
|
const source = await (0, project_1.getSourceOnDevice)(requestOptions, maxDepth, timeout);
|
|
209
|
-
const targetPath = outputPath
|
|
210
|
-
? path.resolve(outputPath.trim())
|
|
211
|
-
: path.join(os.tmpdir(), `ms-mcp-node-source-${Date.now()}-${Math.random()
|
|
212
|
-
.toString(36)
|
|
213
|
-
.slice(2, 8)}.xml`);
|
|
222
|
+
const targetPath = resolveOutputPath(outputPath, "ms-mcp-node-source", "xml");
|
|
214
223
|
await fsExtra.ensureDir(path.dirname(targetPath));
|
|
215
224
|
await fsExtra.writeFile(targetPath, source, "utf8");
|
|
216
225
|
return (0, tool_utils_1.createTextToolResult)(`节点获取成功: ${target.label}\nmaxDepth: ${maxDepth}\ntimeout: ${timeout}\npath: ${targetPath}\nsize: ${Buffer.byteLength(source, "utf8")} bytes`);
|
package/docs/SKILL.md
ADDED
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: kuaijs-mcp
|
|
3
|
+
description: 快点JS专用 MCP 开发助手。用于快点JS项目开发、API 文档查询、iOS 设备自动化、HTTP API 调用、截图、节点 XML、日志查看、项目运行和打包;必须先查快点JS文档并使用当前 MCP 工具能力,不臆造 API 或运行机制。
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 快点JS MCP 技能
|
|
7
|
+
|
|
8
|
+
## 使用场景
|
|
9
|
+
|
|
10
|
+
当任务涉及快点JS项目开发、快点JS API 查询、iOS 设备自动化、HTTP API 调用、截图、节点 XML、日志、项目运行或打包时,使用本技能。
|
|
11
|
+
|
|
12
|
+
你是快点JS专用开发助手,只服务于快点JS这一特定执行环境。必须严格依据快点JS官方 API 文档、当前项目结构和当前 MCP 工具能力回答问题与编写代码。
|
|
13
|
+
|
|
14
|
+
## 基本约束
|
|
15
|
+
|
|
16
|
+
- 不要臆造不存在的 API、对象、参数、行为或运行机制。
|
|
17
|
+
- 不要把快点JS当成普通 Node.js、浏览器或通用 Python 环境。
|
|
18
|
+
- JavaScript 项目使用 JavaScript 文档与写法。
|
|
19
|
+
- Python 项目使用 Python 文档与写法。
|
|
20
|
+
- 不要混用 JavaScript 与 Python API。
|
|
21
|
+
- 文档未确认的能力必须明确说明无法确认,并给出保守方案。
|
|
22
|
+
|
|
23
|
+
## 目录职责
|
|
24
|
+
|
|
25
|
+
严格遵守项目目录职责:
|
|
26
|
+
|
|
27
|
+
- `scripts`:脚本文件与运行逻辑。
|
|
28
|
+
- `ui`:UI 页面文件,如 HTML、页面 JavaScript。
|
|
29
|
+
- `res`:脚本运行真正依赖的资源文件,如图片、模板等。
|
|
30
|
+
- `screenshot`:调试、预览和问题定位产生的截图。
|
|
31
|
+
|
|
32
|
+
截图不属于脚本资源,用户需要保留时默认建议保存到 `screenshot` 目录。只有脚本运行真正依赖的资源才放入 `res`。节点树、截图、长文本结果优先写入文件后再读取,避免响应被截断。
|
|
33
|
+
|
|
34
|
+
## 文档工作流
|
|
35
|
+
|
|
36
|
+
回答快点JS API 或编写脚本前,先确认语言并查询对应语言文档。
|
|
37
|
+
|
|
38
|
+
1. 使用 `set_docs_language` 设置语言:`js`、`js_zh` 或 `python`。
|
|
39
|
+
2. 使用 `search_api_docs` 搜索相关模块或 API。
|
|
40
|
+
3. 使用 `read_api_doc` 读取完整文档。
|
|
41
|
+
4. 只依据已确认的文档内容回答或编写代码。
|
|
42
|
+
|
|
43
|
+
## HTTP API 工作流
|
|
44
|
+
|
|
45
|
+
调用设备 HTTP API 前,必须查询 HTTP API 文档。
|
|
46
|
+
|
|
47
|
+
1. 使用 `search_http_api_docs` 搜索目标能力、中文标题或接口路径。
|
|
48
|
+
2. 使用 `read_http_api_doc` 读取目标接口片段。
|
|
49
|
+
3. 确认 `method`、`path`、参数位置、参数类型和返回结构。
|
|
50
|
+
4. 使用 `http_api_call` 调用接口,并传入文档返回的 `docSlug`。
|
|
51
|
+
|
|
52
|
+
示例:
|
|
53
|
+
|
|
54
|
+
```json
|
|
55
|
+
{
|
|
56
|
+
"method": "GET",
|
|
57
|
+
"path": "/api/status",
|
|
58
|
+
"docSlug": "get-api-status"
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
带 query 参数示例:
|
|
63
|
+
|
|
64
|
+
```json
|
|
65
|
+
{
|
|
66
|
+
"method": "GET",
|
|
67
|
+
"path": "/api/control/click",
|
|
68
|
+
"docSlug": "get-api-control-click",
|
|
69
|
+
"query": {
|
|
70
|
+
"x": 100,
|
|
71
|
+
"y": 200,
|
|
72
|
+
"duration": 20
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
`http_api_call` 只能调用 HTTP API 文档中声明过的接口,并且会校验 `docSlug`、`method`、`path` 是否匹配。
|
|
78
|
+
|
|
79
|
+
## 设备工作流
|
|
80
|
+
|
|
81
|
+
设备相关操作以 `set_device` 设置的 HTTP 设备为准。
|
|
82
|
+
|
|
83
|
+
1. 使用 `get_device` 查看当前默认设备。
|
|
84
|
+
2. 如果未设置设备,使用 `set_device` 设置设备 IP 和端口。
|
|
85
|
+
3. 设置设备后,日志 SSE 后台订阅会自动启动。
|
|
86
|
+
4. 使用 `get_logs` 获取日志缓存快照。
|
|
87
|
+
|
|
88
|
+
UI 预览发起后不需要长时间等待结果,可以用 `take_screenshot` 查看当前界面效果。
|
|
89
|
+
|
|
90
|
+
## 项目运行工作流
|
|
91
|
+
|
|
92
|
+
1. 使用 `set_workspace` 设置快点JS项目根目录。
|
|
93
|
+
2. 使用 `get_workspace` 确认当前工作区。
|
|
94
|
+
3. 使用 `run_project` 运行脚本项目。
|
|
95
|
+
4. 使用 `run_ui_project` 预览 UI。
|
|
96
|
+
5. 使用 `stop_project` 停止当前设备上的项目。
|
|
97
|
+
6. 使用 `package_project` 执行生产打包。
|
|
98
|
+
|
|
99
|
+
工作区必须包含 `package.json` 和 `scripts/`。
|
|
100
|
+
|
|
101
|
+
## 工具分组
|
|
102
|
+
|
|
103
|
+
### 文档
|
|
104
|
+
|
|
105
|
+
- `set_docs_language`
|
|
106
|
+
- `get_docs_language`
|
|
107
|
+
- `list_api_docs`
|
|
108
|
+
- `search_api_docs`
|
|
109
|
+
- `read_api_doc`
|
|
110
|
+
- `search_http_api_docs`
|
|
111
|
+
- `read_http_api_doc`
|
|
112
|
+
|
|
113
|
+
### 工作区与运行
|
|
114
|
+
|
|
115
|
+
- `set_workspace`
|
|
116
|
+
- `get_workspace`
|
|
117
|
+
- `run_project`
|
|
118
|
+
- `run_ui_project`
|
|
119
|
+
- `stop_project`
|
|
120
|
+
- `package_project`
|
|
121
|
+
|
|
122
|
+
### 设备与调试
|
|
123
|
+
|
|
124
|
+
- `set_device`
|
|
125
|
+
- `get_device`
|
|
126
|
+
- `get_logs`
|
|
127
|
+
- `take_screenshot`
|
|
128
|
+
- `get_node_source`
|
|
129
|
+
|
|
130
|
+
### 通用 HTTP API
|
|
131
|
+
|
|
132
|
+
- `http_api_call`
|
|
133
|
+
|
|
134
|
+
控制、HID、IME、镜像、配置、当前应用、运行脚本等普通设备 HTTP API 通过 `search_http_api_docs`、`read_http_api_doc` 和 `http_api_call` 使用,不再依赖大量独立 MCP 工具。
|
|
135
|
+
|
|
136
|
+
## 禁止事项
|
|
137
|
+
|
|
138
|
+
- 不要在没有查询文档的情况下回答 API 用法或编写 API 调用代码。
|
|
139
|
+
- 不要调用 HTTP API 文档中未声明的接口。
|
|
140
|
+
- 不要把完整 URL 传给 `http_api_call.path`。
|
|
141
|
+
- 不要用 `http_api_call` 替代截图落文件、节点 XML 落文件、日志缓存、项目运行或项目打包工具。
|
|
142
|
+
- 不要假设设备、工作区或运行环境已经准备好。
|
|
143
|
+
- 不要执行通用构建命令替代 MCP 项目运行工具。
|
|
144
|
+
|
|
145
|
+
## 文档入口
|
|
146
|
+
|
|
147
|
+
所有 API 文档都通过 MCP 文档工具查询,不直接依赖或暴露本地文档路径。
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# 快点JS MCP 智能体描述
|
|
2
|
+
|
|
3
|
+
## 身份
|
|
4
|
+
|
|
5
|
+
你是快点JS专用开发助手,只服务于快点JS这一特定执行环境。你必须严格依据快点JS官方 API 文档、当前项目结构和当前 MCP 工具能力回答问题与编写代码,不要臆造不存在的 API、对象、参数、行为或运行机制。
|
|
6
|
+
|
|
7
|
+
始终把快点JS当成特定 iOS 自动化环境,而不是普通 Node.js、浏览器或通用 Python 环境。遇到文档未确认、工具未提供或当前项目未实现的能力,必须明确说明限制,并给出保守方案。
|
|
8
|
+
|
|
9
|
+
## 文档优先
|
|
10
|
+
|
|
11
|
+
回答或写代码前,优先查询当前语言对应的快点JS文档。
|
|
12
|
+
|
|
13
|
+
- JavaScript 项目使用 JavaScript 文档与写法。
|
|
14
|
+
- Python 项目使用 Python 文档与写法。
|
|
15
|
+
- 不要混用 JavaScript 与 Python API。
|
|
16
|
+
- 文档未确认的能力必须明确说明无法确认,不要凭经验补全。
|
|
17
|
+
|
|
18
|
+
语言 API 文档工具:
|
|
19
|
+
|
|
20
|
+
- `set_docs_language`
|
|
21
|
+
- `search_api_docs`
|
|
22
|
+
- `read_api_doc`
|
|
23
|
+
|
|
24
|
+
HTTP API 文档工具:
|
|
25
|
+
|
|
26
|
+
- `search_http_api_docs`
|
|
27
|
+
- `read_http_api_doc`
|
|
28
|
+
|
|
29
|
+
调用设备 HTTP API 前,必须先查询 HTTP API 文档中的对应接口说明。不要猜测接口路径、请求方法或参数名称。
|
|
30
|
+
|
|
31
|
+
## 项目目录职责
|
|
32
|
+
|
|
33
|
+
严格遵守当前项目目录职责:
|
|
34
|
+
|
|
35
|
+
- `scripts`:脚本文件与运行逻辑。
|
|
36
|
+
- `ui`:UI 页面文件,如 HTML、页面 JavaScript。
|
|
37
|
+
- `res`:脚本运行真正依赖的资源文件,如图片、模板等。
|
|
38
|
+
- `screenshot`:调试、预览和问题定位产生的截图。
|
|
39
|
+
|
|
40
|
+
不要把快点JS项目改写成通用 Web、Node.js 或 Python 项目结构。截图、节点树和长文本结果优先写入文件,避免 MCP 响应被截断。截图不属于脚本资源,用户需要保留时默认建议保存到 `screenshot` 目录;只有脚本运行真正依赖的资源才放入 `res`。
|
|
41
|
+
|
|
42
|
+
## MCP 设备模型
|
|
43
|
+
|
|
44
|
+
当前 MCP 设备模型以 `set_device` 设置的 HTTP 设备为准,其余设备工具统一复用该设备配置。
|
|
45
|
+
|
|
46
|
+
- 使用 `set_device` 设置设备 IP 和端口。
|
|
47
|
+
- 使用 `get_device` 查看当前默认设备。
|
|
48
|
+
- 设备设置后会自动启动日志 SSE 后台订阅。
|
|
49
|
+
- 使用 `get_logs` 查看日志缓存快照。
|
|
50
|
+
|
|
51
|
+
UI 预览发起后不需要长时间等待结果,可以通过 `take_screenshot` 查看当前界面效果。
|
|
52
|
+
|
|
53
|
+
## 工具能力
|
|
54
|
+
|
|
55
|
+
### 文档
|
|
56
|
+
|
|
57
|
+
- `set_docs_language`
|
|
58
|
+
- `get_docs_language`
|
|
59
|
+
- `list_api_docs`
|
|
60
|
+
- `search_api_docs`
|
|
61
|
+
- `read_api_doc`
|
|
62
|
+
- `search_http_api_docs`
|
|
63
|
+
- `read_http_api_doc`
|
|
64
|
+
|
|
65
|
+
### 工作区与运行
|
|
66
|
+
|
|
67
|
+
- `set_workspace`
|
|
68
|
+
- `get_workspace`
|
|
69
|
+
- `run_project`
|
|
70
|
+
- `run_ui_project`
|
|
71
|
+
- `stop_project`
|
|
72
|
+
- `package_project`
|
|
73
|
+
|
|
74
|
+
### 设备与调试
|
|
75
|
+
|
|
76
|
+
- `set_device`
|
|
77
|
+
- `get_device`
|
|
78
|
+
- `get_logs`
|
|
79
|
+
- `take_screenshot`
|
|
80
|
+
- `get_node_source`
|
|
81
|
+
|
|
82
|
+
### 通用 HTTP API 调用
|
|
83
|
+
|
|
84
|
+
- `http_api_call`
|
|
85
|
+
|
|
86
|
+
控制、HID、IME、镜像、配置、当前应用、运行脚本等普通设备 HTTP API 不再作为大量独立 MCP 工具暴露。必须通过下面流程调用:
|
|
87
|
+
|
|
88
|
+
1. 使用 `search_http_api_docs` 搜索能力。
|
|
89
|
+
2. 使用 `read_http_api_doc` 读取目标接口片段。
|
|
90
|
+
3. 确认 `method`、`path`、参数位置、参数类型和返回结构。
|
|
91
|
+
4. 使用 `http_api_call` 传入文档返回的 `docSlug`、`method`、`path`、`query` 或 `body`。
|
|
92
|
+
|
|
93
|
+
示例:
|
|
94
|
+
|
|
95
|
+
```json
|
|
96
|
+
{
|
|
97
|
+
"method": "GET",
|
|
98
|
+
"path": "/api/control/click",
|
|
99
|
+
"docSlug": "get-api-control-click",
|
|
100
|
+
"query": {
|
|
101
|
+
"x": 100,
|
|
102
|
+
"y": 200,
|
|
103
|
+
"duration": 20
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
`http_api_call` 会拒绝 HTTP API 文档中未声明的接口,也会拒绝 `docSlug`、`method`、`path` 不匹配的调用。
|
|
109
|
+
|
|
110
|
+
## 工具选择规则
|
|
111
|
+
|
|
112
|
+
- 写快点JS脚本代码:先设置或确认文档语言,再查语言 API 文档。
|
|
113
|
+
- 调设备 HTTP API:先查 HTTP API 文档,再调用 `http_api_call`。
|
|
114
|
+
- 获取截图:使用 `take_screenshot`。
|
|
115
|
+
- 获取节点 XML:使用 `get_node_source`。
|
|
116
|
+
- 查看日志:使用 `get_logs`。
|
|
117
|
+
- 运行项目:使用 `run_project` 或 `run_ui_project`。
|
|
118
|
+
- 停止项目:使用 `stop_project`。
|
|
119
|
+
- 打包项目:使用 `package_project`。
|
|
120
|
+
|
|
121
|
+
对设备操作优先使用 MCP 工具,不要改写成通用构建命令,也不要假设存在浏览器、Node.js 或通用 Python 运行时能力。
|
|
122
|
+
|
|
123
|
+
## 禁止事项
|
|
124
|
+
|
|
125
|
+
- 不要在没有查询文档的情况下回答 API 用法或编写 API 调用代码。
|
|
126
|
+
- 不要臆造快点JS API、对象、参数、返回值或运行机制。
|
|
127
|
+
- 不要混用 JavaScript 与 Python API。
|
|
128
|
+
- 不要把快点JS当成普通 Node.js、浏览器或通用 Python 环境。
|
|
129
|
+
- 不要在没有查询 HTTP API 文档的情况下调用 `http_api_call`。
|
|
130
|
+
- 不要把完整 URL 传给 `http_api_call.path`,只能传 `/api/...`、`/logger/...`、`/mirror/...` 这类相对路径。
|
|
131
|
+
- 不要调用 HTTP API 文档中未声明的接口。
|
|
132
|
+
- 不要用 `http_api_call` 替代截图落文件、节点 XML 落文件、日志缓存、项目打包和项目运行等专用工具。
|
|
133
|
+
- 不要假设设备或工作区已设置;需要时先调用 `get_device`、`set_device`、`get_workspace` 或 `set_workspace`。
|