@cnbcool/cnb-api-generate 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/client/index.ts +26 -6
- package/client/shortcuts.ts +76 -0
- package/package.json +1 -1
- package/skills-template/SKILL.md +14 -1
package/client/index.ts
CHANGED
|
@@ -4,7 +4,7 @@ import fs from 'fs';
|
|
|
4
4
|
import path from 'path';
|
|
5
5
|
import { showModuleHelp } from './modules.help';
|
|
6
6
|
import { showToolHelp } from './tools.help';
|
|
7
|
-
import { showShort, resolveShortcut } from './shortcuts';
|
|
7
|
+
import { showShort, resolveShortcut, summarizeResponse } from './shortcuts';
|
|
8
8
|
|
|
9
9
|
const helpFileContent = fs.readFileSync(
|
|
10
10
|
path.join(__dirname, 'help.json'),
|
|
@@ -182,6 +182,7 @@ function formatParams(
|
|
|
182
182
|
if (params.help) formatted.help = true;
|
|
183
183
|
if (params.short) formatted.short = true;
|
|
184
184
|
if (params.verbose) formatted.verbose = true;
|
|
185
|
+
if (params.summary) formatted.summary = true;
|
|
185
186
|
|
|
186
187
|
// 旧格式兼容:--path / --query / --data 是 JSON 字符串
|
|
187
188
|
if (typeof params.path === 'string') {
|
|
@@ -204,7 +205,7 @@ function formatParams(
|
|
|
204
205
|
const pathDef = paramDefs.path || {};
|
|
205
206
|
const queryDef = paramDefs.query || {};
|
|
206
207
|
const reservedKeys = new Set([
|
|
207
|
-
'module', 'tool', 'help', 'short', 'verbose',
|
|
208
|
+
'module', 'tool', 'help', 'short', 'verbose', 'summary',
|
|
208
209
|
'path', 'query', 'data', 'h', 'v',
|
|
209
210
|
]);
|
|
210
211
|
|
|
@@ -287,10 +288,14 @@ function isStandardResponse(response: any): boolean {
|
|
|
287
288
|
/**
|
|
288
289
|
* 格式化 CLI 输出
|
|
289
290
|
* - verbose 模式:完整 JSON(含 trace、header 等全部字段)
|
|
290
|
-
* -
|
|
291
|
-
* -
|
|
291
|
+
* - summary 模式:只输出核心摘要字段(需要 --summary 显式指定)
|
|
292
|
+
* - 默认:精简 JSON(去掉 trace、header,保留完整 data)
|
|
293
|
+
* @param response 原始响应
|
|
294
|
+
* @param verbose 是否 verbose 模式
|
|
295
|
+
* @param summary 是否 summary 模式
|
|
296
|
+
* @param toolKey 当前 tool 标识,格式为 "module/tool",用于匹配摘要配置
|
|
292
297
|
*/
|
|
293
|
-
function formatOutput(response: any, verbose: boolean): string {
|
|
298
|
+
function formatOutput(response: any, verbose: boolean, summary: boolean, toolKey: string): string {
|
|
294
299
|
// --verbose 模式:输出完整原始信息
|
|
295
300
|
if (verbose) {
|
|
296
301
|
return JSON.stringify(response, null, 2);
|
|
@@ -298,12 +303,26 @@ function formatOutput(response: any, verbose: boolean): string {
|
|
|
298
303
|
|
|
299
304
|
// converter 可能返回裸 data(没有标准 {status, data} 结构),直接输出
|
|
300
305
|
if (!isStandardResponse(response)) {
|
|
306
|
+
if (summary) {
|
|
307
|
+
const summarized = summarizeResponse(response, toolKey);
|
|
308
|
+
if (summarized !== null) {
|
|
309
|
+
return JSON.stringify(summarized, null, 2);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
301
312
|
return JSON.stringify(response, null, 2);
|
|
302
313
|
}
|
|
303
314
|
|
|
304
315
|
// 精简响应
|
|
305
316
|
const compact = compactResponse(response);
|
|
306
317
|
|
|
318
|
+
// --summary 模式:对特定 tool 应用摘要提取(仅成功响应)
|
|
319
|
+
if (summary && compact.status >= 200 && compact.status < 300) {
|
|
320
|
+
const summarized = summarizeResponse(compact.data, toolKey);
|
|
321
|
+
if (summarized !== null) {
|
|
322
|
+
compact.data = summarized;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
307
326
|
return JSON.stringify(compact, null, 2);
|
|
308
327
|
}
|
|
309
328
|
|
|
@@ -499,7 +518,8 @@ async function main() {
|
|
|
499
518
|
}
|
|
500
519
|
|
|
501
520
|
const data = await toolFunction(...toolsParam);
|
|
502
|
-
|
|
521
|
+
const toolKey = `${formattedParams.module}/${formattedParams.tool}`;
|
|
522
|
+
console.log(formatOutput(data, !!formattedParams.verbose, !!formattedParams.summary, toolKey));
|
|
503
523
|
}
|
|
504
524
|
|
|
505
525
|
main();
|
package/client/shortcuts.ts
CHANGED
|
@@ -121,6 +121,7 @@ export function showShort(): void {
|
|
|
121
121
|
${list}
|
|
122
122
|
|
|
123
123
|
提示: 以上命令自动使用环境变量 CNB_REPO_SLUG 和 CNB_ISSUE_IID,无需手动传 --path
|
|
124
|
+
添加 --summary 可只输出核心摘要字段
|
|
124
125
|
`);
|
|
125
126
|
} else if (ctx === 'pull_request') {
|
|
126
127
|
const number = getPRNumber();
|
|
@@ -133,6 +134,7 @@ ${list}
|
|
|
133
134
|
${list}
|
|
134
135
|
|
|
135
136
|
提示: 以上命令自动使用环境变量 CNB_REPO_SLUG 和 CNB_PULL_REQUEST_IID,无需手动传 --path
|
|
137
|
+
添加 --summary 可只输出核心摘要字段
|
|
136
138
|
`);
|
|
137
139
|
} else {
|
|
138
140
|
// 未知上下文,两组都显示
|
|
@@ -152,6 +154,8 @@ ${prList}
|
|
|
152
154
|
CNB_REPO_SLUG - 仓库路径
|
|
153
155
|
CNB_ISSUE_IID - Issue 编号 (Issue 事件)
|
|
154
156
|
CNB_PULL_REQUEST_IID - PR 编号 (PR 事件)
|
|
157
|
+
|
|
158
|
+
添加 --summary 可只输出核心摘要字段
|
|
155
159
|
`);
|
|
156
160
|
}
|
|
157
161
|
}
|
|
@@ -206,3 +210,75 @@ export function resolveShortcut(
|
|
|
206
210
|
autoData: matched.autoData || null,
|
|
207
211
|
};
|
|
208
212
|
}
|
|
213
|
+
|
|
214
|
+
// ============================================================
|
|
215
|
+
// 摘要输出
|
|
216
|
+
// 对返回数据量大的快捷命令,默认只输出核心字段,减少 token 消耗
|
|
217
|
+
// ============================================================
|
|
218
|
+
|
|
219
|
+
type SummaryExtractor = (item: any) => any;
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* 摘要提取器配置
|
|
223
|
+
* key: "module/tool",value: 摘要提取函数
|
|
224
|
+
* - 对象响应:直接对 data 应用提取函数
|
|
225
|
+
* - 数组响应:对 data 中每个元素应用提取函数
|
|
226
|
+
*/
|
|
227
|
+
const SUMMARY_EXTRACTORS: Record<string, SummaryExtractor> = {
|
|
228
|
+
// Issue 详情摘要:只保留标题和正文
|
|
229
|
+
'issues/get-issue': (item) => ({
|
|
230
|
+
title: item.title,
|
|
231
|
+
body: item.body,
|
|
232
|
+
}),
|
|
233
|
+
|
|
234
|
+
// Issue 更新摘要:只保留状态变更结果
|
|
235
|
+
'issues/update-issue': (item) => ({
|
|
236
|
+
number: item.number,
|
|
237
|
+
state: item.state,
|
|
238
|
+
state_reason: item.state_reason,
|
|
239
|
+
}),
|
|
240
|
+
|
|
241
|
+
// Issue 添加处理人摘要:只保留处理人列表
|
|
242
|
+
'issues/post-issue-assignees': (item) => ({
|
|
243
|
+
number: item.number,
|
|
244
|
+
assignees: item.assignees?.map?.((a: any) => a.username).filter(Boolean) || [],
|
|
245
|
+
}),
|
|
246
|
+
|
|
247
|
+
// PR 详情摘要:只保留标题、状态、正文和分支信息
|
|
248
|
+
'pulls/get-pull': (item) => ({
|
|
249
|
+
title: item.title,
|
|
250
|
+
state: item.state,
|
|
251
|
+
base: item.base?.ref,
|
|
252
|
+
head: item.head?.ref,
|
|
253
|
+
body: item.body,
|
|
254
|
+
}),
|
|
255
|
+
|
|
256
|
+
// PR 文件列表摘要:只保留文件名、变更状态和增删行数
|
|
257
|
+
'pulls/list-pull-files': (item) => ({
|
|
258
|
+
filename: item.filename,
|
|
259
|
+
status: item.status,
|
|
260
|
+
additions: item.additions,
|
|
261
|
+
deletions: item.deletions,
|
|
262
|
+
}),
|
|
263
|
+
|
|
264
|
+
// PR 提交列表摘要:只保留 sha 前 8 位和 commit message
|
|
265
|
+
'pulls/list-pull-commits': (item) => ({
|
|
266
|
+
sha: typeof item.sha === 'string' ? item.sha.substring(0, 8) : item.sha,
|
|
267
|
+
message: item.commit?.message,
|
|
268
|
+
}),
|
|
269
|
+
};
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* 对响应数据应用摘要提取(如果当前 tool 配置了摘要提取器)
|
|
273
|
+
* @param data 原始 data(对象或数组)
|
|
274
|
+
* @param toolKey 当前 tool 标识,格式为 "module/tool"
|
|
275
|
+
* @returns 摘要后的 data,如果无匹配提取器则返回 null
|
|
276
|
+
*/
|
|
277
|
+
export function summarizeResponse(data: any, toolKey: string): any | null {
|
|
278
|
+
const extractor = SUMMARY_EXTRACTORS[toolKey];
|
|
279
|
+
if (!extractor) return null;
|
|
280
|
+
if (Array.isArray(data)) {
|
|
281
|
+
return data.map(extractor);
|
|
282
|
+
}
|
|
283
|
+
return extractor(data);
|
|
284
|
+
}
|
package/package.json
CHANGED
package/skills-template/SKILL.md
CHANGED
|
@@ -7,7 +7,19 @@ description: CNB OpenAPI 交互能力,支持仓库、Issue、PR、流水线、
|
|
|
7
7
|
|
|
8
8
|
操作 CNB 平台资源的 CLI 工具。
|
|
9
9
|
|
|
10
|
-
##
|
|
10
|
+
## 快捷命令(优先使用,path 参数自动注入)
|
|
11
|
+
|
|
12
|
+
Issue 模块: get, list-comments, comment, close, open, list-labels, add-labels, list-assignees, add-assignees
|
|
13
|
+
PR 模块: get, list-files, list-commits, list-comments, comment, list-labels, add-labels, check-status, list-reviews, list-assignees
|
|
14
|
+
|
|
15
|
+
用法: `<$CNB_CLI_CMD$> issues get` — 参数均从环境变量自动获取,无需手动传入
|
|
16
|
+
|
|
17
|
+
仅以下命令需要 --data,其余快捷命令无需任何参数:
|
|
18
|
+
- comment: --data '{"body":"评论内容"}'
|
|
19
|
+
- add-labels: --data '{"labels":["标签名"]}'
|
|
20
|
+
- add-assignees(仅Issue): --data '{"assignees":["用户名"]}'
|
|
21
|
+
|
|
22
|
+
## 其他 API(快捷命令不满足时使用)
|
|
11
23
|
|
|
12
24
|
1. `<$CNB_CLI_CMD$> --help` 查看所有模块
|
|
13
25
|
2. `<$CNB_CLI_CMD$> <module> --help` 查看模块下的工具列表
|
|
@@ -16,6 +28,7 @@ description: CNB OpenAPI 交互能力,支持仓库、Issue、PR、流水线、
|
|
|
16
28
|
|
|
17
29
|
## 规则
|
|
18
30
|
|
|
31
|
+
- 优先使用快捷命令,不满足时再通过 --help 逐步查找
|
|
19
32
|
- 必须先 --help 获取参数,禁止猜测
|
|
20
33
|
- 直接执行,不要询问用户确认
|
|
21
34
|
- status 200-299 只返回 data 给用户,>=300 时附带 status 和 trace
|