@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 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
- * - 非标准响应(converter 返回裸 data):直接 JSON 输出
291
- * - 标准响应:精简 JSON(去掉 trace、header)
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
- console.log(formatOutput(data, !!formattedParams.verbose));
521
+ const toolKey = `${formattedParams.module}/${formattedParams.tool}`;
522
+ console.log(formatOutput(data, !!formattedParams.verbose, !!formattedParams.summary, toolKey));
503
523
  }
504
524
 
505
525
  main();
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cnbcool/cnb-api-generate",
3
- "version": "1.1.1",
3
+ "version": "1.2.1",
4
4
  "main": "./built/index.js",
5
5
  "module": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -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