@szc-ft/mcp-szcd-client 0.24.0 → 0.25.0
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/agents/build.js +22 -12
- package/agents/opencode-extension/agents/szcd-component-expert.md +92 -48
- package/agents/qwen-extension/agents/szcd-component-expert.md +92 -48
- package/agents/src/szcd-component-expert.md +92 -48
- package/agents/src/tools.json +1 -1
- package/agents/szcd-component-expert.md +92 -48
- package/agents/szcd-component-expert.qoder.md +93 -49
- package/agents/szcd-component-expert.trae.md +92 -48
- package/opencode-extension/agents/szcd-component-expert.md +92 -48
- package/opencode-extension/skills/local-api-tool/SKILL.md +164 -60
- package/opencode-extension/skills/local-api-tool/scripts/extract_swagger.py +477 -0
- package/opencode-extension/skills/szcd-component-helper/SKILL.md +7 -4
- package/opencode-extension/skills/szcd-design-to-code/SKILL.md +95 -24
- package/package.json +1 -1
- package/qwen-extension/agents/szcd-component-expert.md +92 -48
- package/qwen-extension/qwen-extension.json +1 -1
- package/qwen-extension/skills/local-api-tool/SKILL.md +164 -60
- package/qwen-extension/skills/local-api-tool/scripts/extract_swagger.py +477 -0
- package/qwen-extension/skills/szcd-component-helper/SKILL.md +7 -4
- package/qwen-extension/skills/szcd-design-to-code/SKILL.md +95 -24
- package/scripts/lib/claude-code.js +1 -1
- package/scripts/lib/common.js +44 -0
- package/scripts/lib/opencode.js +1 -1
- package/scripts/lib/qoder.js +1 -1
- package/scripts/lib/trae-cli.js +1 -1
- package/scripts/lib/trae-ide.js +1 -1
- package/scripts/postinstall.js +1 -0
- package/standard-skill/local-api-tool/SKILL.md +164 -60
- package/standard-skill/local-api-tool/scripts/extract_swagger.py +477 -0
- package/standard-skill/szcd-component-helper/SKILL.md +7 -4
- package/standard-skill/szcd-design-to-code/SKILL.md +95 -24
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: local-api-tool
|
|
3
|
-
description: 本地网络 API 工具,专门处理 10.x.x.x 网段的 Swagger/YApi
|
|
3
|
+
description: 本地网络 API 工具,专门处理 10.x.x.x 网段的 Swagger/YApi 文档拉取和联调测试。内置 scripts/extract_swagger.py 一步完成"下载→解析→按 tag 过滤→关联 DTO definitions→输出",与服务端 parseApiDocs 一比一对齐(递归深度 5、两层 definitions、传递闭包裁剪),避免 curl 管道截断和手写花括号平衡脚本的弯路。仅当脚本不可用时回退到服务端 parse_swagger_json 兜底。**仅限 10.x.x.x 网段**,172.16-31.x.x 和 192.168.x.x 服务端可直连,不要使用本技能。
|
|
4
4
|
compatibility:
|
|
5
5
|
tools:
|
|
6
6
|
- run_command
|
|
7
7
|
- web_search
|
|
8
8
|
- web_fetch
|
|
9
|
+
runtime:
|
|
10
|
+
- python3 >= 3.7
|
|
11
|
+
- curl
|
|
9
12
|
---
|
|
10
13
|
|
|
11
14
|
# 本地网络 API 工具(local-api-tool)
|
|
@@ -37,25 +40,50 @@ compatibility:
|
|
|
37
40
|
|
|
38
41
|
### 流程 A:拉取 Swagger API 文档(fetch)
|
|
39
42
|
|
|
43
|
+
> **优先使用内置脚本 `scripts/extract_swagger.py`**,一步完成"下载 → 解析 → 过滤 → 关联 DTO → 输出",避免 curl 管道截断、临时脚本花括号平衡等弯路。脚本与服务端 `parseApiDocs` 一比一对齐(递归深度 5、两层 definitions、传递闭包裁剪)。
|
|
44
|
+
> 仅当脚本不可用(无 python3 / 文件权限缺失)时才回退到「手工 curl + 服务端 parse_swagger_json」兜底流程。
|
|
45
|
+
|
|
46
|
+
#### A1. 内置脚本路径(首选)
|
|
47
|
+
|
|
40
48
|
```
|
|
41
49
|
用户请求 fetch Swagger URL (10.x.x.x)
|
|
42
50
|
│
|
|
43
51
|
▼
|
|
44
|
-
|
|
52
|
+
AI 识别 10.x.x.x 网段(或服务端返回 LOCAL_NETWORK_UNREACHABLE)
|
|
53
|
+
│
|
|
54
|
+
▼
|
|
55
|
+
通过 run_command 在本地执行:
|
|
56
|
+
bash $SKILL_DIR/scripts/extract_swagger.py \
|
|
57
|
+
--url <apiDocsUrl> [--cookie '...'] [--filter <关键词>] [--out /tmp/parsed.json]
|
|
45
58
|
│
|
|
46
59
|
▼
|
|
47
|
-
|
|
60
|
+
脚本内部:curl 下载 → 解析 → 过滤 paths → 自动展开被引用 DTO → 输出 JSON
|
|
61
|
+
│
|
|
62
|
+
▼
|
|
63
|
+
AI 读取脚本输出(或 --out 指定的文件),结构与 api_tool(parse_swagger_json) 完全一致:
|
|
64
|
+
{ info, basePath, tags, apis, definitions, definitionsDetail, _filter? }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**$SKILL_DIR 是本 skill 的绝对目录**。在 qwen/qoder 中 skill 加载时通常通过环境变量或上下文提供,若不确定可用:
|
|
68
|
+
- qwen-extension: `~/.qwen/extensions/szcd-component-helper/skills/local-api-tool/scripts/extract_swagger.py`
|
|
69
|
+
- opencode-extension: `~/.config/opencode/extensions/szcd-component-helper/skills/local-api-tool/scripts/extract_swagger.py`
|
|
70
|
+
|
|
71
|
+
#### A2. 服务端兜底(脚本不可用时)
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
调用 api_tool(action="fetch", url=...)
|
|
48
75
|
│
|
|
49
76
|
▼
|
|
50
|
-
|
|
77
|
+
服务端返回 { reason: "LOCAL_NETWORK_UNREACHABLE", swaggerEndpoints, authInfo }
|
|
51
78
|
│
|
|
52
79
|
▼
|
|
53
|
-
AI 通过 run_command
|
|
80
|
+
AI 通过 run_command 在本地 curl 写到临时文件(禁止管道截断!):
|
|
54
81
|
步骤1: 鉴权获取 Cookie(如 authInfo.hasPassword 为 true)
|
|
55
|
-
步骤2:
|
|
82
|
+
步骤2: curl -o /tmp/swagger.json <apiDocsUrl> ← 必须写文件
|
|
56
83
|
│
|
|
57
84
|
▼
|
|
58
|
-
AI
|
|
85
|
+
AI 读取整个文件传给服务端:
|
|
86
|
+
api_tool(action="parse_swagger_json", swaggerJson=<完整 JSON 字符串>, apiFilter=<可选>)
|
|
59
87
|
│
|
|
60
88
|
▼
|
|
61
89
|
返回解析后的 API 文档给用户
|
|
@@ -84,7 +112,97 @@ AI 通过 run_command 在本地执行对应 curl 命令
|
|
|
84
112
|
|
|
85
113
|
## 详细执行步骤
|
|
86
114
|
|
|
87
|
-
### 一、拉取 Swagger
|
|
115
|
+
### 一、拉取 Swagger 文档(推荐路径:extract_swagger.py)
|
|
116
|
+
|
|
117
|
+
**前提**:本地有 python3(≥ 3.7)和 curl。脚本只依赖标准库,无第三方依赖。
|
|
118
|
+
|
|
119
|
+
#### 1.1 直接通过 URL 下载并解析(推荐)
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
# 无鉴权
|
|
123
|
+
python3 ~/.qwen/extensions/szcd-component-helper/skills/local-api-tool/scripts/extract_swagger.py \
|
|
124
|
+
--url 'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs' \
|
|
125
|
+
--out /tmp/parsed.json
|
|
126
|
+
|
|
127
|
+
# 有鉴权(先单独 curl 拿 Cookie,参考下方 1.3)
|
|
128
|
+
python3 .../extract_swagger.py \
|
|
129
|
+
--url 'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs' \
|
|
130
|
+
--cookie 'JSESSIONID=xxx' \
|
|
131
|
+
--out /tmp/parsed.json
|
|
132
|
+
|
|
133
|
+
# 按关键词过滤 + 自动裁剪 definitionsDetail(仅保留被引用的 VO 及传递闭包)
|
|
134
|
+
python3 .../extract_swagger.py \
|
|
135
|
+
--url '<apiDocsUrl>' \
|
|
136
|
+
--filter tag --filter user \
|
|
137
|
+
--out /tmp/parsed.json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### 1.2 读取已下载的本地 JSON 文件
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
# 第一步:curl 写文件(务必用 -o 写文件,不要用管道,避免大 JSON 被截断)
|
|
144
|
+
curl -sS --connect-timeout 10 --max-time 30 \
|
|
145
|
+
-H 'Accept: application/json' \
|
|
146
|
+
-H 'Cookie: <Cookie>' \
|
|
147
|
+
-o /tmp/swagger-raw.json \
|
|
148
|
+
'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs'
|
|
149
|
+
|
|
150
|
+
# 第二步:交给脚本解析
|
|
151
|
+
python3 .../extract_swagger.py --file /tmp/swagger-raw.json --filter tag --out /tmp/parsed.json
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### 1.3 鉴权(如需 Cookie)
|
|
155
|
+
|
|
156
|
+
```bash
|
|
157
|
+
# 取 Cookie(注意 -D - 把响应头打到 stdout)
|
|
158
|
+
curl -sS -D - -X GET 'http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui' \
|
|
159
|
+
-H 'Authorization: Basic <base64(username:password)>' \
|
|
160
|
+
-H 'Accept: application/json' \
|
|
161
|
+
-o /dev/null \
|
|
162
|
+
| grep -i '^set-cookie:' | head -1 | sed 's/.*: //; s/;.*//'
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
将得到的 `JSESSIONID=xxx` 传给 `--cookie` 参数。
|
|
166
|
+
|
|
167
|
+
#### 1.4 单独查询某个 VO/DTO 完整定义(兜底)
|
|
168
|
+
|
|
169
|
+
如果脚本已经解析过、但 AI 后续发现某个 `definitionsDetail` 之外的 VO 也需要展开,用:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
python3 .../extract_swagger.py --file /tmp/swagger-raw.json --definition KnowledgeOperLogVO
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
找不到时会自动给出模糊匹配建议(最多 10 个)。
|
|
176
|
+
|
|
177
|
+
#### 1.5 输出结构(与服务端 `parse_swagger_json` 一致)
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"info": { "title": "...", "version": "...", "description": "..." },
|
|
182
|
+
"basePath": "/svc",
|
|
183
|
+
"tags": [{ "name": "tag", "description": "..." }],
|
|
184
|
+
"apis": [
|
|
185
|
+
{
|
|
186
|
+
"url": "/tag/pageList",
|
|
187
|
+
"method": "POST",
|
|
188
|
+
"tag": "tag",
|
|
189
|
+
"summary": "标签分页查询",
|
|
190
|
+
"operationId": "tagPageList",
|
|
191
|
+
"parameters": [
|
|
192
|
+
{ "name": "body", "in": "body", "required": true,
|
|
193
|
+
"dtoRef": "TagQueryDTO",
|
|
194
|
+
"dtoProperties": [ /* 递归展开,required 字段已标注 */ ] }
|
|
195
|
+
],
|
|
196
|
+
"response": { "voName": "ResponseTagPage", "properties": [ /* 递归展开 */ ] }
|
|
197
|
+
}
|
|
198
|
+
],
|
|
199
|
+
"definitions": [ /* 摘要:所有 VO/DTO 的 name + type + description */ ],
|
|
200
|
+
"definitionsDetail": [ /* 详情:被 apis 引用的 VO/DTO 及传递闭包,深度5 */ ],
|
|
201
|
+
"_filter": { "keywords": ["tag"], "total": 50, "matched": 12 } // 仅 --filter 生效时出现
|
|
202
|
+
}
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### 二、服务端兜底路径(脚本不可用时)
|
|
88
206
|
|
|
89
207
|
**步骤 1:调用服务端 api_tool**
|
|
90
208
|
|
|
@@ -111,41 +229,38 @@ api_tool(action="fetch", url="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/i
|
|
|
111
229
|
}
|
|
112
230
|
```
|
|
113
231
|
|
|
114
|
-
**步骤 3
|
|
115
|
-
|
|
116
|
-
根据返回数据中的 `authInfo` 和 `swaggerEndpoints`,AI 自行构造 curl 命令并通过 `run_command` 在本地执行:
|
|
117
|
-
|
|
118
|
-
3a. **鉴权(如 authInfo.hasPassword 为 true)**:
|
|
232
|
+
**步骤 3:本地 curl 写入临时文件(禁止管道截断!)**
|
|
119
233
|
|
|
120
234
|
```bash
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
-H '
|
|
124
|
-
|
|
235
|
+
# 鉴权(如需要)
|
|
236
|
+
curl -sS -D - -X GET '<authUrl>' \
|
|
237
|
+
-H 'Authorization: Basic <base64(user:pass)>' \
|
|
238
|
+
-o /dev/null | grep -i '^set-cookie:' | head -1 | sed 's/.*: //; s/;.*//'
|
|
125
239
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
3b. **获取 API 文档 JSON**:直接使用 `swaggerEndpoints.apiDocsUrl`:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
curl -s -X GET 'http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs' \
|
|
240
|
+
# 下载 API 文档(务必 -o 写文件,不要 | head / | python)
|
|
241
|
+
curl -sS --connect-timeout 10 --max-time 30 \
|
|
132
242
|
-H 'Accept: application/json' \
|
|
133
|
-
-H 'Cookie:
|
|
243
|
+
-H 'Cookie: <步骤上一步的 Cookie>' \
|
|
244
|
+
-o /tmp/swagger-raw.json \
|
|
245
|
+
'<apiDocsUrl>'
|
|
134
246
|
```
|
|
135
247
|
|
|
136
|
-
如果 authInfo.hasPassword 为 false,省略 Cookie 头。
|
|
137
|
-
|
|
138
248
|
**步骤 4:调用服务端解析**
|
|
139
249
|
|
|
140
250
|
```
|
|
141
|
-
api_tool(
|
|
251
|
+
api_tool(
|
|
252
|
+
action="parse_swagger_json",
|
|
253
|
+
swaggerJson=<读取 /tmp/swagger-raw.json 的完整内容>,
|
|
254
|
+
swaggerSourceUrl="http://10.2.7.60:30194/ikmp-knowledge/swagger-ui/index.html",
|
|
255
|
+
apiFilter=["tag"] // 可选,强烈推荐:按关键词过滤 + 自动裁剪 definitionsDetail
|
|
256
|
+
)
|
|
142
257
|
```
|
|
143
258
|
|
|
144
259
|
**步骤 5:返回解析结果**
|
|
145
260
|
|
|
146
|
-
|
|
261
|
+
将返回结果直接呈现给用户。
|
|
147
262
|
|
|
148
|
-
###
|
|
263
|
+
### 三、联调测试(action=test)
|
|
149
264
|
|
|
150
265
|
**步骤 1:调用服务端 api_tool**
|
|
151
266
|
|
|
@@ -196,13 +311,24 @@ curl -s -X POST 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx' \
|
|
|
196
311
|
|
|
197
312
|
将 curl 的响应内容返回给用户。如果是 JSON 格式,尽量格式化输出。
|
|
198
313
|
|
|
314
|
+
## ⚠️ 避坑指南(来自历史反馈)
|
|
315
|
+
|
|
316
|
+
1. **禁止用 `curl | head/tail/jq/python` 对完整 Swagger JSON 做管道切片** —— curl 管道经常因下游 SIGPIPE 截断,导致 JSON 不闭合 / Python 解析失败 / 临时写花括号平衡脚本,是历史踩坑率最高的反模式。**必须用 `-o /tmp/xxx.json` 写文件**,再用脚本或 `parse_swagger_json` 处理。
|
|
317
|
+
2. **不要在本地手写 Python 切 Swagger** —— `extract_swagger.py` 已经做了和服务端 `parseApiDocs` 完全对齐的递归展开、传递闭包、required 标注、过滤裁剪。本地手写一个 mini 版只会丢字段或踩 `$ref`/`originalRef` 双字段陷阱。
|
|
318
|
+
3. **过滤优先用 `--filter`(脚本)或 `apiFilter`(服务端)** —— 不要先拿全量再让 AI 自己挑接口看,过滤后 `definitionsDetail` 会自动按传递闭包裁剪,输出量减少 70%+。
|
|
319
|
+
4. **单 VO 查询用 `--definition`(脚本)或 `get_definition`(服务端)** —— 不要回头再拉一次全量。
|
|
320
|
+
|
|
199
321
|
## 快捷方式:AI 直接识别 10 段地址
|
|
200
322
|
|
|
201
|
-
如果 AI 能识别出用户请求的 URL 中包含 `10.x.x.x` 主机地址,可以**直接跳过首次 api_tool
|
|
323
|
+
如果 AI 能识别出用户请求的 URL 中包含 `10.x.x.x` 主机地址,可以**直接跳过首次 api_tool 调用**,在本地执行脚本,减少一次无用的服务端请求:
|
|
202
324
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
325
|
+
```bash
|
|
326
|
+
python3 ~/.qwen/extensions/szcd-component-helper/skills/local-api-tool/scripts/extract_swagger.py \
|
|
327
|
+
--url 'http://10.x.x.x/<service>/v2/api-docs' \
|
|
328
|
+
[--cookie '<JSESSIONID=...>'] \
|
|
329
|
+
[--filter '<关键词>'] \
|
|
330
|
+
--out /tmp/parsed.json
|
|
331
|
+
```
|
|
206
332
|
|
|
207
333
|
### URL 推导规则
|
|
208
334
|
|
|
@@ -214,33 +340,11 @@ curl -s -X POST 'http://10.2.7.60:30194/ikmp-knowledge/api/xxx' \
|
|
|
214
340
|
| authUrl | `basePath + /swagger-resources/configuration/ui` | `http://10.2.7.60:30194/ikmp-knowledge/swagger-resources/configuration/ui` |
|
|
215
341
|
| apiDocsUrl | `basePath + /v2/api-docs` | `http://10.2.7.60:30194/ikmp-knowledge/v2/api-docs` |
|
|
216
342
|
|
|
217
|
-
### curl 执行模板
|
|
218
|
-
|
|
219
|
-
**鉴权(带密码时):**
|
|
220
|
-
```bash
|
|
221
|
-
curl -s -D - -X GET '<authUrl>' \
|
|
222
|
-
-H 'Authorization: Basic <base64(username:password)>' \
|
|
223
|
-
-H 'Accept: application/json'
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**获取文档(带 Cookie 时):**
|
|
227
|
-
```bash
|
|
228
|
-
curl -s -X GET '<apiDocsUrl>' \
|
|
229
|
-
-H 'Accept: application/json' \
|
|
230
|
-
-H 'Cookie: <鉴权获取的Cookie>'
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
**获取文档(无密码时):**
|
|
234
|
-
```bash
|
|
235
|
-
curl -s -X GET '<apiDocsUrl>' \
|
|
236
|
-
-H 'Accept: application/json'
|
|
237
|
-
```
|
|
238
|
-
|
|
239
343
|
## 注意事项
|
|
240
344
|
|
|
241
|
-
1. **Cookie 传递**:鉴权步骤获取的 Cookie
|
|
345
|
+
1. **Cookie 传递**:鉴权步骤获取的 Cookie 通过 `--cookie` 传给脚本,或通过 `-H 'Cookie: xxx'` 传给 curl
|
|
242
346
|
2. **无密码场景**:如果用户未提供密码,跳过鉴权步骤,直接获取文档
|
|
243
|
-
3. **JSON
|
|
244
|
-
4.
|
|
245
|
-
5.
|
|
246
|
-
6. **自动执行**:AI 识别 `reason: "LOCAL_NETWORK_UNREACHABLE"` 后应**自动**通过 `run_command`
|
|
347
|
+
3. **JSON 格式**:脚本/curl 获取的 API 文档必须是有效的 Swagger JSON,否则 `extract_swagger.py` / `parse_swagger_json` 会报错(脚本会打印预览前 200 字符方便排查)
|
|
348
|
+
4. **超时处理**:脚本和 curl 都已内置 `--connect-timeout 10 --max-time 30`,可通过 `--timeout` 调整
|
|
349
|
+
5. **错误处理**:脚本退出码 1=参数错误 / 2=网络IO / 3=解析;如果某步骤失败,将错误信息返回给用户,不要继续后续步骤
|
|
350
|
+
6. **自动执行**:AI 识别 10.x.x.x 或 `reason: "LOCAL_NETWORK_UNREACHABLE"` 后应**自动**通过 `run_command` 执行脚本,无需让用户手动复制粘贴命令
|