@cnbcool/cnb-cli 1.1.1 → 1.2.1
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/package.json +2 -2
- package/skills/cnb-api/scripts/core/flat-options.json +8909 -0
- package/skills/cnb-api/scripts/core/index.js +33 -455
- package/skills/cnb-api/scripts/core/key-mapping.json +538 -0
- package/skills/cnb-api/scripts/core/lib/execute-action.js +97 -0
- package/skills/cnb-api/scripts/core/lib/extra-help.js +20 -0
- package/skills/cnb-api/scripts/core/lib/flat-options-data.js +16 -0
- package/skills/cnb-api/scripts/core/lib/format-output.js +85 -0
- package/skills/cnb-api/scripts/core/lib/format-params.js +219 -0
- package/skills/cnb-api/scripts/core/lib/help-data.js +15 -0
- package/skills/cnb-api/scripts/core/lib/key-mapping-data.js +16 -0
- package/skills/cnb-api/scripts/core/lib/parsers.js +126 -0
- package/skills/cnb-api/scripts/core/lib/print-json.js +15 -0
- package/skills/cnb-api/scripts/core/lib/register-fallback.js +15 -0
- package/skills/cnb-api/scripts/core/lib/register-modules.js +117 -0
- package/skills/cnb-api/scripts/core/lib/summary-extractors.js +181 -0
- package/skills/cnb-api/scripts/core/lib/trim-summary.js +17 -0
- package/skills/cnb-api/scripts/core/shortcuts.js +13 -188
- package/skills/cnb-api/scripts/core/utils/build-nested-field-map.js +35 -0
- package/skills/cnb-api/scripts/core/utils/flat-key-from-segments.js +14 -0
- package/skills/cnb-api/scripts/core/utils/match-array-object-field.js +25 -0
- package/skills/cnb-api/scripts/core/utils/restore-original-keys.js +24 -0
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.summarizeResponse = summarizeResponse;
|
|
7
|
+
/**
|
|
8
|
+
* 摘要输出
|
|
9
|
+
* 对返回数据量大的快捷命令,默认只输出核心字段,减少 token 消耗
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* 摘要提取器配置
|
|
14
|
+
* key: "module/tool",value: 摘要提取函数
|
|
15
|
+
* - 对象响应:直接对 data 应用提取函数
|
|
16
|
+
* - 数组响应:对 data 中每个元素应用提取函数
|
|
17
|
+
*/
|
|
18
|
+
const SUMMARY_EXTRACTORS = {
|
|
19
|
+
// Issue 详情摘要:保留标题、状态、标签和正文
|
|
20
|
+
// 过滤: number, state_reason, assignees, author, created_at, updated_at 等
|
|
21
|
+
'issues/get-issue': item => ({
|
|
22
|
+
title: item.title,
|
|
23
|
+
state: item.state,
|
|
24
|
+
labels: item.labels?.map?.(l => l.name).filter(Boolean) || [],
|
|
25
|
+
body: item.body
|
|
26
|
+
}),
|
|
27
|
+
// Issue 更新摘要:只保留状态变更结果
|
|
28
|
+
// 过滤: title, body, labels, assignees, author, created_at, updated_at 等
|
|
29
|
+
'issues/update-issue': item => ({
|
|
30
|
+
number: item.number,
|
|
31
|
+
state: item.state,
|
|
32
|
+
state_reason: item.state_reason
|
|
33
|
+
}),
|
|
34
|
+
// Issue 评论列表摘要:只保留作者用户名、内容和创建时间
|
|
35
|
+
// 过滤: author 完整对象(avatar/email/freeze/is_npc/nickname), reactions, updated_at
|
|
36
|
+
'issues/list-issue-comments': item => ({
|
|
37
|
+
id: item.id,
|
|
38
|
+
author: item.author?.username,
|
|
39
|
+
body: item.body,
|
|
40
|
+
created_at: item.created_at
|
|
41
|
+
}),
|
|
42
|
+
// Issue 发表评论摘要:只保留评论 ID 和创建时间(body 已在请求中传入,无需重复)
|
|
43
|
+
// 过滤: body(请求已传入), author 完整对象(avatar/email/freeze/is_npc/nickname/username), reactions, updated_at
|
|
44
|
+
'issues/post-issue-comment': item => ({
|
|
45
|
+
id: item.id,
|
|
46
|
+
created_at: item.created_at
|
|
47
|
+
}),
|
|
48
|
+
// Issue 标签列表摘要:保留名称、颜色和描述
|
|
49
|
+
// 过滤: id
|
|
50
|
+
'issues/list-issue-labels': item => ({
|
|
51
|
+
name: item.name,
|
|
52
|
+
color: item.color,
|
|
53
|
+
description: item.description
|
|
54
|
+
}),
|
|
55
|
+
// Issue 添加标签摘要:只保留 ID 和颜色(name 已在请求中传入,无需重复)
|
|
56
|
+
// 过滤: name(请求已传入), description
|
|
57
|
+
'issues/post-issue-labels': item => ({
|
|
58
|
+
id: item.id,
|
|
59
|
+
color: item.color
|
|
60
|
+
}),
|
|
61
|
+
// Issue 处理人列表摘要:保留用户名和昵称
|
|
62
|
+
// 过滤: avatar, email, freeze, is_npc
|
|
63
|
+
'issues/list-issue-assignees': item => ({
|
|
64
|
+
username: item.username,
|
|
65
|
+
nickname: item.nickname
|
|
66
|
+
}),
|
|
67
|
+
// Issue 添加处理人摘要:保留处理人用户名和昵称列表
|
|
68
|
+
// 过滤: assignees 中每个用户的 avatar/email/freeze/is_npc,以及 issue 其他字段
|
|
69
|
+
'issues/post-issue-assignees': item => ({
|
|
70
|
+
number: item.number,
|
|
71
|
+
assignees: item.assignees?.map?.(a => ({
|
|
72
|
+
username: a.username,
|
|
73
|
+
nickname: a.nickname
|
|
74
|
+
})).filter(a => a.username) || []
|
|
75
|
+
}),
|
|
76
|
+
// PR 详情摘要:保留标题、状态、标签、正文和分支信息
|
|
77
|
+
// 过滤: number, author, assignees, reviewers, created_at, updated_at, base/head 完整对象等
|
|
78
|
+
'pulls/get-pull': item => ({
|
|
79
|
+
title: item.title,
|
|
80
|
+
state: item.state,
|
|
81
|
+
labels: item.labels?.map?.(l => l.name).filter(Boolean) || [],
|
|
82
|
+
base: item.base?.ref,
|
|
83
|
+
head: item.head?.ref,
|
|
84
|
+
body: item.body
|
|
85
|
+
}),
|
|
86
|
+
// PR 文件列表摘要:保留文件名、sha、变更状态和增删行数
|
|
87
|
+
// 过滤: patch, blob_url, raw_url, contents_url, previous_filename
|
|
88
|
+
'pulls/list-pull-files': item => ({
|
|
89
|
+
filename: item.filename,
|
|
90
|
+
sha: item.sha,
|
|
91
|
+
status: item.status,
|
|
92
|
+
additions: item.additions,
|
|
93
|
+
deletions: item.deletions
|
|
94
|
+
}),
|
|
95
|
+
// PR 提交列表摘要:只保留 sha 前 8 位和 commit message
|
|
96
|
+
// 过滤: sha 完整值, commit 完整对象(author/committer/tree/verification), parents, url 等
|
|
97
|
+
'pulls/list-pull-commits': item => ({
|
|
98
|
+
sha: typeof item.sha === 'string' ? item.sha.substring(0, 8) : item.sha,
|
|
99
|
+
message: item.commit?.message
|
|
100
|
+
}),
|
|
101
|
+
// PR 评论列表摘要:保留作者用户名和昵称、内容和创建时间
|
|
102
|
+
// 过滤: author 完整对象(avatar/email/freeze/is_npc), reactions, updated_at
|
|
103
|
+
'pulls/list-pull-comments': item => ({
|
|
104
|
+
id: item.id,
|
|
105
|
+
author: item.author?.username,
|
|
106
|
+
nickname: item.author?.nickname,
|
|
107
|
+
body: item.body,
|
|
108
|
+
created_at: item.created_at
|
|
109
|
+
}),
|
|
110
|
+
// PR 发表评论摘要:只保留评论 ID 和创建时间(body 已在请求中传入,无需重复)
|
|
111
|
+
// 过滤: body(请求已传入), author 完整对象(avatar/email/freeze/is_npc/nickname/username), reactions, updated_at
|
|
112
|
+
'pulls/post-pull-comment': item => ({
|
|
113
|
+
id: item.id,
|
|
114
|
+
created_at: item.created_at
|
|
115
|
+
}),
|
|
116
|
+
// PR 标签列表摘要:保留 ID、名称、颜色和描述
|
|
117
|
+
// 过滤: 无
|
|
118
|
+
'pulls/list-pull-labels': item => ({
|
|
119
|
+
id: item.id,
|
|
120
|
+
name: item.name,
|
|
121
|
+
color: item.color,
|
|
122
|
+
description: item.description
|
|
123
|
+
}),
|
|
124
|
+
// PR 添加标签摘要:只保留 ID 和颜色(name 已在请求中传入,无需重复)
|
|
125
|
+
// 过滤: name(请求已传入), description
|
|
126
|
+
'pulls/post-pull-labels': item => ({
|
|
127
|
+
id: item.id,
|
|
128
|
+
color: item.color
|
|
129
|
+
}),
|
|
130
|
+
// PR CI 状态摘要:保留整体状态和各检查项的核心信息(sha 截断为前 8 位)
|
|
131
|
+
// 过滤: sha 完整值, statuses 中每项的 target_url/created_at/updated_at
|
|
132
|
+
'pulls/list-pull-commit-statuses': item => ({
|
|
133
|
+
sha: typeof item.sha === 'string' ? item.sha.substring(0, 8) : item.sha,
|
|
134
|
+
state: item.state,
|
|
135
|
+
statuses: item.statuses?.map?.(s => ({
|
|
136
|
+
context: s.context,
|
|
137
|
+
state: s.state,
|
|
138
|
+
description: s.description
|
|
139
|
+
})) || []
|
|
140
|
+
}),
|
|
141
|
+
// PR 评审列表摘要:保留作者用户名和昵称、状态和内容
|
|
142
|
+
// 过滤: author 完整对象(avatar/email/freeze/is_npc), created_at, updated_at
|
|
143
|
+
'pulls/list-pull-reviews': item => ({
|
|
144
|
+
id: item.id,
|
|
145
|
+
author: item.author?.username,
|
|
146
|
+
nickname: item.author?.nickname,
|
|
147
|
+
state: item.state,
|
|
148
|
+
body: item.body
|
|
149
|
+
}),
|
|
150
|
+
// PR 处理人列表摘要:保留用户名和昵称
|
|
151
|
+
// 过滤: avatar, email, freeze, is_npc
|
|
152
|
+
'pulls/list-pull-assignees': item => ({
|
|
153
|
+
username: item.username,
|
|
154
|
+
nickname: item.nickname
|
|
155
|
+
}),
|
|
156
|
+
// PR 添加处理人摘要:保留处理人用户名和昵称列表
|
|
157
|
+
// 过滤: assignees 中每个用户的 avatar/email/freeze/is_npc,以及 PR 其他字段
|
|
158
|
+
'pulls/post-pull-assignees': item => ({
|
|
159
|
+
number: item.number,
|
|
160
|
+
assignees: item.assignees?.map?.(a => ({
|
|
161
|
+
username: a.username,
|
|
162
|
+
nickname: a.nickname
|
|
163
|
+
})).filter(a => a.username) || []
|
|
164
|
+
})
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* 对响应数据应用摘要提取(如果当前 tool 配置了摘要提取器)
|
|
169
|
+
* @param data 原始 data(对象或数组)
|
|
170
|
+
* @param toolKey 当前 tool 标识,格式为 "module/tool"
|
|
171
|
+
* @returns 摘要后的 data,如果无匹配提取器则返回 null
|
|
172
|
+
*/
|
|
173
|
+
function summarizeResponse(data, toolKey) {
|
|
174
|
+
const extractor = SUMMARY_EXTRACTORS[toolKey];
|
|
175
|
+
if (!extractor) return null;
|
|
176
|
+
if (data == null) return data;
|
|
177
|
+
if (Array.isArray(data)) {
|
|
178
|
+
return data.map(extractor);
|
|
179
|
+
}
|
|
180
|
+
return extractor(data);
|
|
181
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.trimSummary = trimSummary;
|
|
7
|
+
/**
|
|
8
|
+
* 去除 summary 中的英文部分(保留中文句号前的内容)
|
|
9
|
+
*/
|
|
10
|
+
function trimSummary(summary) {
|
|
11
|
+
if (!summary) return '';
|
|
12
|
+
// 匹配中文句号"。"后面跟英文的模式,只保留中文部分
|
|
13
|
+
const match = summary.match(/^(.*?[\u4e00-\u9fff].*?)[。.]\s*[A-Z]/);
|
|
14
|
+
if (match) return match[1];
|
|
15
|
+
// 没有匹配到则返回原文
|
|
16
|
+
return summary;
|
|
17
|
+
}
|
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
+
exports.PR_SHORTCUTS = exports.ISSUE_SHORTCUTS = void 0;
|
|
6
7
|
exports.detectEventContext = detectEventContext;
|
|
7
8
|
exports.resolveShortcut = resolveShortcut;
|
|
8
9
|
exports.showShort = showShort;
|
|
9
|
-
exports.summarizeResponse = summarizeResponse;
|
|
10
10
|
/**
|
|
11
11
|
* 快捷命令模块
|
|
12
12
|
*
|
|
@@ -41,7 +41,7 @@ function getPRNumber() {
|
|
|
41
41
|
// 快捷命令定义
|
|
42
42
|
// ============================================================
|
|
43
43
|
|
|
44
|
-
const ISSUE_SHORTCUTS = [{
|
|
44
|
+
const ISSUE_SHORTCUTS = exports.ISSUE_SHORTCUTS = [{
|
|
45
45
|
shortName: 'get',
|
|
46
46
|
realTool: 'get-issue',
|
|
47
47
|
description: '获取详情'
|
|
@@ -53,7 +53,7 @@ const ISSUE_SHORTCUTS = [{
|
|
|
53
53
|
shortName: 'comment',
|
|
54
54
|
realTool: 'post-issue-comment',
|
|
55
55
|
description: '评论',
|
|
56
|
-
dataTip: "--
|
|
56
|
+
dataTip: "--body 内容"
|
|
57
57
|
}, {
|
|
58
58
|
shortName: 'close',
|
|
59
59
|
realTool: 'update-issue',
|
|
@@ -78,7 +78,7 @@ const ISSUE_SHORTCUTS = [{
|
|
|
78
78
|
shortName: 'add-labels',
|
|
79
79
|
realTool: 'post-issue-labels',
|
|
80
80
|
description: '添加标签',
|
|
81
|
-
dataTip: "--
|
|
81
|
+
dataTip: "--labels bug --labels feature"
|
|
82
82
|
}, {
|
|
83
83
|
shortName: 'list-assignees',
|
|
84
84
|
realTool: 'list-issue-assignees',
|
|
@@ -87,21 +87,21 @@ const ISSUE_SHORTCUTS = [{
|
|
|
87
87
|
shortName: 'add-assignees',
|
|
88
88
|
realTool: 'post-issue-assignees',
|
|
89
89
|
description: '添加处理人',
|
|
90
|
-
dataTip: "--
|
|
90
|
+
dataTip: "--assignees username"
|
|
91
91
|
}, {
|
|
92
92
|
shortName: 'upload-file',
|
|
93
93
|
realTool: 'post-issue-file-asset-upload-url',
|
|
94
94
|
description: '上传文件',
|
|
95
95
|
upload: true,
|
|
96
|
-
dataTip: "--
|
|
96
|
+
dataTip: "--file 文件路径"
|
|
97
97
|
}, {
|
|
98
98
|
shortName: 'upload-image',
|
|
99
99
|
realTool: 'post-issue-image-asset-upload-url',
|
|
100
100
|
description: '上传图片',
|
|
101
101
|
upload: true,
|
|
102
|
-
dataTip: "--
|
|
102
|
+
dataTip: "--file 图片路径"
|
|
103
103
|
}];
|
|
104
|
-
const PR_SHORTCUTS = [{
|
|
104
|
+
const PR_SHORTCUTS = exports.PR_SHORTCUTS = [{
|
|
105
105
|
shortName: 'get',
|
|
106
106
|
realTool: 'get-pull',
|
|
107
107
|
description: '获取详情'
|
|
@@ -121,7 +121,7 @@ const PR_SHORTCUTS = [{
|
|
|
121
121
|
shortName: 'comment',
|
|
122
122
|
realTool: 'post-pull-comment',
|
|
123
123
|
description: '评论',
|
|
124
|
-
dataTip: "--
|
|
124
|
+
dataTip: "--body 内容"
|
|
125
125
|
}, {
|
|
126
126
|
shortName: 'list-labels',
|
|
127
127
|
realTool: 'list-pull-labels',
|
|
@@ -130,7 +130,7 @@ const PR_SHORTCUTS = [{
|
|
|
130
130
|
shortName: 'add-labels',
|
|
131
131
|
realTool: 'post-pull-labels',
|
|
132
132
|
description: '添加标签',
|
|
133
|
-
dataTip: "--
|
|
133
|
+
dataTip: "--labels ready --labels approved"
|
|
134
134
|
}, {
|
|
135
135
|
shortName: 'check-status',
|
|
136
136
|
realTool: 'list-pull-commit-statuses',
|
|
@@ -149,14 +149,14 @@ const PR_SHORTCUTS = [{
|
|
|
149
149
|
description: '上传文件',
|
|
150
150
|
repoOnly: true,
|
|
151
151
|
upload: true,
|
|
152
|
-
dataTip: "--
|
|
152
|
+
dataTip: "--file 文件路径"
|
|
153
153
|
}, {
|
|
154
154
|
shortName: 'upload-image',
|
|
155
155
|
realTool: 'upload-imgs',
|
|
156
156
|
description: '上传图片',
|
|
157
157
|
repoOnly: true,
|
|
158
158
|
upload: true,
|
|
159
|
-
dataTip: "--
|
|
159
|
+
dataTip: "--file 图片路径"
|
|
160
160
|
}];
|
|
161
161
|
|
|
162
162
|
// ============================================================
|
|
@@ -234,7 +234,7 @@ ${prList}
|
|
|
234
234
|
CNB_ISSUE_IID - Issue 编号(Issue 相关快捷命令)
|
|
235
235
|
CNB_PULL_REQUEST_IID - PR 编号(PR 相关快捷命令)
|
|
236
236
|
|
|
237
|
-
默认只输出摘要信息,添加 --
|
|
237
|
+
默认只输出摘要信息,添加 --v 可输出全部信息
|
|
238
238
|
`);
|
|
239
239
|
}
|
|
240
240
|
}
|
|
@@ -273,179 +273,4 @@ function resolveShortcut(moduleName, toolName) {
|
|
|
273
273
|
autoData: matched.autoData || null,
|
|
274
274
|
upload: !!matched.upload
|
|
275
275
|
};
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
// ============================================================
|
|
279
|
-
// 摘要输出
|
|
280
|
-
// 对返回数据量大的快捷命令,默认只输出核心字段,减少 token 消耗
|
|
281
|
-
// ============================================================
|
|
282
|
-
|
|
283
|
-
/**
|
|
284
|
-
* 摘要提取器配置
|
|
285
|
-
* key: "module/tool",value: 摘要提取函数
|
|
286
|
-
* - 对象响应:直接对 data 应用提取函数
|
|
287
|
-
* - 数组响应:对 data 中每个元素应用提取函数
|
|
288
|
-
*/
|
|
289
|
-
const SUMMARY_EXTRACTORS = {
|
|
290
|
-
// Issue 详情摘要:保留标题、状态、标签和正文
|
|
291
|
-
// 过滤: number, state_reason, assignees, author, created_at, updated_at 等
|
|
292
|
-
'issues/get-issue': item => ({
|
|
293
|
-
title: item.title,
|
|
294
|
-
state: item.state,
|
|
295
|
-
labels: item.labels?.map?.(l => l.name).filter(Boolean) || [],
|
|
296
|
-
body: item.body
|
|
297
|
-
}),
|
|
298
|
-
// Issue 更新摘要:只保留状态变更结果
|
|
299
|
-
// 过滤: title, body, labels, assignees, author, created_at, updated_at 等
|
|
300
|
-
'issues/update-issue': item => ({
|
|
301
|
-
number: item.number,
|
|
302
|
-
state: item.state,
|
|
303
|
-
state_reason: item.state_reason
|
|
304
|
-
}),
|
|
305
|
-
// Issue 评论列表摘要:只保留作者用户名、内容和创建时间
|
|
306
|
-
// 过滤: author 完整对象(avatar/email/freeze/is_npc/nickname), reactions, updated_at
|
|
307
|
-
'issues/list-issue-comments': item => ({
|
|
308
|
-
id: item.id,
|
|
309
|
-
author: item.author?.username,
|
|
310
|
-
body: item.body,
|
|
311
|
-
created_at: item.created_at
|
|
312
|
-
}),
|
|
313
|
-
// Issue 发表评论摘要:只保留评论 ID 和创建时间(body 已在请求中传入,无需重复)
|
|
314
|
-
// 过滤: body(请求已传入), author 完整对象(avatar/email/freeze/is_npc/nickname/username), reactions, updated_at
|
|
315
|
-
'issues/post-issue-comment': item => ({
|
|
316
|
-
id: item.id,
|
|
317
|
-
created_at: item.created_at
|
|
318
|
-
}),
|
|
319
|
-
// Issue 标签列表摘要:保留名称、颜色和描述
|
|
320
|
-
// 过滤: id
|
|
321
|
-
'issues/list-issue-labels': item => ({
|
|
322
|
-
name: item.name,
|
|
323
|
-
color: item.color,
|
|
324
|
-
description: item.description
|
|
325
|
-
}),
|
|
326
|
-
// Issue 添加标签摘要:只保留 ID 和颜色(name 已在请求中传入,无需重复)
|
|
327
|
-
// 过滤: name(请求已传入), description
|
|
328
|
-
'issues/post-issue-labels': item => ({
|
|
329
|
-
id: item.id,
|
|
330
|
-
color: item.color
|
|
331
|
-
}),
|
|
332
|
-
// Issue 处理人列表摘要:保留用户名和昵称
|
|
333
|
-
// 过滤: avatar, email, freeze, is_npc
|
|
334
|
-
'issues/list-issue-assignees': item => ({
|
|
335
|
-
username: item.username,
|
|
336
|
-
nickname: item.nickname
|
|
337
|
-
}),
|
|
338
|
-
// Issue 添加处理人摘要:保留处理人用户名和昵称列表
|
|
339
|
-
// 过滤: assignees 中每个用户的 avatar/email/freeze/is_npc,以及 issue 其他字段
|
|
340
|
-
'issues/post-issue-assignees': item => ({
|
|
341
|
-
number: item.number,
|
|
342
|
-
assignees: item.assignees?.map?.(a => ({
|
|
343
|
-
username: a.username,
|
|
344
|
-
nickname: a.nickname
|
|
345
|
-
})).filter(a => a.username) || []
|
|
346
|
-
}),
|
|
347
|
-
// PR 详情摘要:保留标题、状态、标签、正文和分支信息
|
|
348
|
-
// 过滤: number, author, assignees, reviewers, created_at, updated_at, base/head 完整对象等
|
|
349
|
-
'pulls/get-pull': item => ({
|
|
350
|
-
title: item.title,
|
|
351
|
-
state: item.state,
|
|
352
|
-
labels: item.labels?.map?.(l => l.name).filter(Boolean) || [],
|
|
353
|
-
base: item.base?.ref,
|
|
354
|
-
head: item.head?.ref,
|
|
355
|
-
body: item.body
|
|
356
|
-
}),
|
|
357
|
-
// PR 文件列表摘要:保留文件名、sha、变更状态和增删行数
|
|
358
|
-
// 过滤: patch, blob_url, raw_url, contents_url, previous_filename
|
|
359
|
-
'pulls/list-pull-files': item => ({
|
|
360
|
-
filename: item.filename,
|
|
361
|
-
sha: item.sha,
|
|
362
|
-
status: item.status,
|
|
363
|
-
additions: item.additions,
|
|
364
|
-
deletions: item.deletions
|
|
365
|
-
}),
|
|
366
|
-
// PR 提交列表摘要:只保留 sha 前 8 位和 commit message
|
|
367
|
-
// 过滤: sha 完整值, commit 完整对象(author/committer/tree/verification), parents, url 等
|
|
368
|
-
'pulls/list-pull-commits': item => ({
|
|
369
|
-
sha: typeof item.sha === 'string' ? item.sha.substring(0, 8) : item.sha,
|
|
370
|
-
message: item.commit?.message
|
|
371
|
-
}),
|
|
372
|
-
// PR 评论列表摘要:保留作者用户名和昵称、内容和创建时间
|
|
373
|
-
// 过滤: author 完整对象(avatar/email/freeze/is_npc), reactions, updated_at
|
|
374
|
-
'pulls/list-pull-comments': item => ({
|
|
375
|
-
id: item.id,
|
|
376
|
-
author: item.author?.username,
|
|
377
|
-
nickname: item.author?.nickname,
|
|
378
|
-
body: item.body,
|
|
379
|
-
created_at: item.created_at
|
|
380
|
-
}),
|
|
381
|
-
// PR 发表评论摘要:只保留评论 ID 和创建时间(body 已在请求中传入,无需重复)
|
|
382
|
-
// 过滤: body(请求已传入), author 完整对象(avatar/email/freeze/is_npc/nickname/username), reactions, updated_at
|
|
383
|
-
'pulls/post-pull-comment': item => ({
|
|
384
|
-
id: item.id,
|
|
385
|
-
created_at: item.created_at
|
|
386
|
-
}),
|
|
387
|
-
// PR 标签列表摘要:保留 ID、名称、颜色和描述
|
|
388
|
-
// 过滤: 无
|
|
389
|
-
'pulls/list-pull-labels': item => ({
|
|
390
|
-
id: item.id,
|
|
391
|
-
name: item.name,
|
|
392
|
-
color: item.color,
|
|
393
|
-
description: item.description
|
|
394
|
-
}),
|
|
395
|
-
// PR 添加标签摘要:只保留 ID 和颜色(name 已在请求中传入,无需重复)
|
|
396
|
-
// 过滤: name(请求已传入), description
|
|
397
|
-
'pulls/post-pull-labels': item => ({
|
|
398
|
-
id: item.id,
|
|
399
|
-
color: item.color
|
|
400
|
-
}),
|
|
401
|
-
// PR CI 状态摘要:保留整体状态和各检查项的核心信息(sha 截断为前 8 位)
|
|
402
|
-
// 过滤: sha 完整值, statuses 中每项的 target_url/created_at/updated_at
|
|
403
|
-
'pulls/list-pull-commit-statuses': item => ({
|
|
404
|
-
sha: typeof item.sha === 'string' ? item.sha.substring(0, 8) : item.sha,
|
|
405
|
-
state: item.state,
|
|
406
|
-
statuses: item.statuses?.map?.(s => ({
|
|
407
|
-
context: s.context,
|
|
408
|
-
state: s.state,
|
|
409
|
-
description: s.description
|
|
410
|
-
})) || []
|
|
411
|
-
}),
|
|
412
|
-
// PR 评审列表摘要:保留作者用户名和昵称、状态和内容
|
|
413
|
-
// 过滤: author 完整对象(avatar/email/freeze/is_npc), created_at, updated_at
|
|
414
|
-
'pulls/list-pull-reviews': item => ({
|
|
415
|
-
id: item.id,
|
|
416
|
-
author: item.author?.username,
|
|
417
|
-
nickname: item.author?.nickname,
|
|
418
|
-
state: item.state,
|
|
419
|
-
body: item.body
|
|
420
|
-
}),
|
|
421
|
-
// PR 处理人列表摘要:保留用户名和昵称
|
|
422
|
-
// 过滤: avatar, email, freeze, is_npc
|
|
423
|
-
'pulls/list-pull-assignees': item => ({
|
|
424
|
-
username: item.username,
|
|
425
|
-
nickname: item.nickname
|
|
426
|
-
}),
|
|
427
|
-
// PR 添加处理人摘要:保留处理人用户名和昵称列表
|
|
428
|
-
// 过滤: assignees 中每个用户的 avatar/email/freeze/is_npc,以及 PR 其他字段
|
|
429
|
-
'pulls/post-pull-assignees': item => ({
|
|
430
|
-
number: item.number,
|
|
431
|
-
assignees: item.assignees?.map?.(a => ({
|
|
432
|
-
username: a.username,
|
|
433
|
-
nickname: a.nickname
|
|
434
|
-
})).filter(a => a.username) || []
|
|
435
|
-
})
|
|
436
|
-
};
|
|
437
|
-
|
|
438
|
-
/**
|
|
439
|
-
* 对响应数据应用摘要提取(如果当前 tool 配置了摘要提取器)
|
|
440
|
-
* @param data 原始 data(对象或数组)
|
|
441
|
-
* @param toolKey 当前 tool 标识,格式为 "module/tool"
|
|
442
|
-
* @returns 摘要后的 data,如果无匹配提取器则返回 null
|
|
443
|
-
*/
|
|
444
|
-
function summarizeResponse(data, toolKey) {
|
|
445
|
-
const extractor = SUMMARY_EXTRACTORS[toolKey];
|
|
446
|
-
if (!extractor) return null;
|
|
447
|
-
if (Array.isArray(data)) {
|
|
448
|
-
return data.map(extractor);
|
|
449
|
-
}
|
|
450
|
-
return extractor(data);
|
|
451
276
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.buildNestedFieldMap = buildNestedFieldMap;
|
|
7
|
+
/**
|
|
8
|
+
* 递归遍历嵌套对象的 schema,生成所有叶子节点的 flat key 映射
|
|
9
|
+
* @param props 当前层级的 properties
|
|
10
|
+
* @param prefix 当前层级的 CLI flat key 前缀(用 @ 连接),如 "testBody"
|
|
11
|
+
* @param pathKeys 当前层级的 schema 路径数组,如 ["testBody"]
|
|
12
|
+
* @returns Map<flatKey, NestedFieldMapping>
|
|
13
|
+
*/
|
|
14
|
+
function buildNestedFieldMap(props, prefix, pathKeys) {
|
|
15
|
+
const map = new Map();
|
|
16
|
+
for (const [subKey, subProp] of Object.entries(props)) {
|
|
17
|
+
const flatKey = `${prefix}@${subKey}`;
|
|
18
|
+
const currentPath = [...pathKeys, subKey];
|
|
19
|
+
if (subProp.type === 'object' && subProp.properties && Object.keys(subProp.properties).length > 0) {
|
|
20
|
+
// 嵌套对象:继续递归
|
|
21
|
+
const subMap = buildNestedFieldMap(subProp.properties, flatKey, currentPath);
|
|
22
|
+
for (const [k, v] of subMap) {
|
|
23
|
+
map.set(k, v);
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
// 叶子节点:注册 flat key
|
|
27
|
+
const camelKey = flatKey;
|
|
28
|
+
map.set(camelKey, {
|
|
29
|
+
pathKeys: currentPath,
|
|
30
|
+
leafSchema: subProp
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return map;
|
|
35
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.flatKeyFromSegments = flatKeyFromSegments;
|
|
7
|
+
/**
|
|
8
|
+
* 生成 CLI flat key:按 '@' 连接层级
|
|
9
|
+
* 例如 "testBody@critical_count@id"
|
|
10
|
+
* Commander 不会对 '@' 做 camelCase 转换,所以 key 保持原样
|
|
11
|
+
*/
|
|
12
|
+
function flatKeyFromSegments(str) {
|
|
13
|
+
return str;
|
|
14
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.matchArrayObjectField = matchArrayObjectField;
|
|
7
|
+
/**
|
|
8
|
+
* 检测是否为 array<object> 展开字段(格式:bodyArrayKey@subPropName)
|
|
9
|
+
* Commander 不会对 '@' 做 camelCase,所以直接匹配原始 key
|
|
10
|
+
*/
|
|
11
|
+
function matchArrayObjectField(camelKey, bodyProps) {
|
|
12
|
+
for (const [rootKey, rootProp] of Object.entries(bodyProps)) {
|
|
13
|
+
if (rootProp.type !== 'array' || !rootProp.items?.properties) continue;
|
|
14
|
+
for (const subKey of Object.keys(rootProp.items.properties)) {
|
|
15
|
+
const flatKey = `${rootKey}@${subKey}`;
|
|
16
|
+
if (flatKey === camelKey) {
|
|
17
|
+
return {
|
|
18
|
+
arrayKey: rootKey,
|
|
19
|
+
subKey
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.restoreOriginalKeys = restoreOriginalKeys;
|
|
7
|
+
var _keyMappingData = require("../lib/key-mapping-data");
|
|
8
|
+
/**
|
|
9
|
+
* 将 CLI 传入的带 '-' 的参数名还原为原始的 '_' 或 '@' 参数名
|
|
10
|
+
* 通过 key-mapping.json 中的映射表进行查找还原
|
|
11
|
+
*/
|
|
12
|
+
function restoreOriginalKeys(params) {
|
|
13
|
+
const moduleName = params.module;
|
|
14
|
+
const toolName = params.tool;
|
|
15
|
+
if (!moduleName || !toolName) return params;
|
|
16
|
+
const toolMapping = _keyMappingData.keyMappingData[moduleName]?.[toolName];
|
|
17
|
+
if (!toolMapping) return params;
|
|
18
|
+
const restored = {};
|
|
19
|
+
for (const [key, value] of Object.entries(params)) {
|
|
20
|
+
const originalKey = toolMapping[key];
|
|
21
|
+
restored[originalKey || key] = value;
|
|
22
|
+
}
|
|
23
|
+
return restored;
|
|
24
|
+
}
|