@cnbcool/cnb-api-generate 2.17.3 → 2.18.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.
@@ -42,7 +42,6 @@ const babel = __importStar(require("@babel/core"));
42
42
  const fs = __importStar(require("fs"));
43
43
  const path = __importStar(require("path"));
44
44
  const debug_1 = __importDefault(require("debug"));
45
- const skills_1 = require("../../constants/skills");
46
45
  const logger = (0, debug_1.default)('csg:babel');
47
46
  function transformTsToJs(tsCode, filename) {
48
47
  return babel.transformSync(tsCode, {
@@ -55,7 +54,7 @@ function transformTsToJs(tsCode, filename) {
55
54
  [
56
55
  'transform-define',
57
56
  {
58
- 'process.env.CNB_CLI_CMD': process.env.CNB_CLI_CMD || skills_1.CNB_CLI_PROD_CMD,
57
+ 'process.env.CNB_CLI_CMD': process.env.CNB_CLI_CMD || 'cnb',
59
58
  },
60
59
  ],
61
60
  ],
@@ -8,8 +8,6 @@ const debug_1 = __importDefault(require("debug"));
8
8
  const path_1 = __importDefault(require("path"));
9
9
  const fs_1 = __importDefault(require("fs"));
10
10
  const get_skills_codegen_target_1 = require("../utils/get-skills-codegen-target");
11
- const get_config_1 = require("../utils/get-config");
12
- const skills_1 = require("../constants/skills");
13
11
  const render_quick_commands_md_1 = require("./render-quick-commands-md");
14
12
  const logger = (0, debug_1.default)('csg:skills');
15
13
  async function generateSkillMd(
@@ -24,17 +22,13 @@ _requestMap, quickCommandsByModule) {
24
22
  const SKILL_MD = path_1.default.join(skillMDTempateDir, 'SKILL.md');
25
23
  const targetSkillMD = path_1.default.join(skillMDDir, 'SKILL.md');
26
24
  const skillMDContent = fs_1.default.readFileSync(SKILL_MD, 'utf8');
27
- const config = (0, get_config_1.getConfig)();
28
- const cliCmd = config.skillsDev ? skills_1.CNB_CLI_DEV_CMD : skills_1.CNB_CLI_PROD_CMD;
29
- // 仅替换两类占位符:
30
- // - <$QUICK_COMMANDS$>:配置驱动的快捷命令清单(标题/使用约定写在模板里即可)
31
- // - <$CNB_CLI_CMD$> :CLI 命令前缀
32
- const quickCommandsMd = (0, render_quick_commands_md_1.renderQuickCommandsMarkdown)(quickCommandsByModule, cliCmd);
25
+ // 仅替换 <$QUICK_COMMANDS$>:配置驱动的快捷命令清单。
26
+ // 模板正文、渲染出的快捷命令前缀都写死 `cnb`(skillsDev 只影响产物运行时的 CNB_CLI_CMD),
27
+ // 不在这里传 CLI 前缀,避免同一份 SKILL.md 出现两种命令写法。
28
+ const quickCommandsMd = (0, render_quick_commands_md_1.renderQuickCommandsMarkdown)(quickCommandsByModule);
33
29
  const total = Object.values(quickCommandsByModule).reduce((n, arr) => n + arr.length, 0);
34
30
  logger(`quick commands rendered: ${Object.keys(quickCommandsByModule).length} modules, ${total} commands`);
35
- const newSkillMDContent = skillMDContent
36
- .replaceAll('<$QUICK_COMMANDS$>', quickCommandsMd)
37
- .replaceAll('<$CNB_CLI_CMD$>', cliCmd);
31
+ const newSkillMDContent = skillMDContent.replaceAll('<$QUICK_COMMANDS$>', quickCommandsMd);
38
32
  fs_1.default.writeFileSync(targetSkillMD, newSkillMDContent);
39
33
  logger(`generate ${SKILL_MD} to ${targetSkillMD}`);
40
34
  }
@@ -9,10 +9,11 @@ exports.renderQuickCommandsMarkdown = renderQuickCommandsMarkdown;
9
9
  *
10
10
  * 渲染规则:
11
11
  * - 每个模块先输出 `<moduleName>:` 标题行
12
- * - 每条命令渲染为 ``- `<cliCmd> <module> <shortName>[ <dataTip>]` — <description>`` 的列表项
12
+ * - 每条命令渲染为 ``- `cnb <module> <shortName>[ <dataTip>]` — <description>`` 的列表项。
13
+ * 前缀固定为 `cnb`,与模板正文写法一致,不跟随 skillsDev 切换
13
14
  * - 没有任何模块/命令时返回空字符串(让模板里的占位符消失)
14
15
  */
15
- function renderQuickCommandsMarkdown(byModule, cliCmd) {
16
+ function renderQuickCommandsMarkdown(byModule) {
16
17
  const moduleNames = Object.keys(byModule);
17
18
  if (!moduleNames.length)
18
19
  return '';
@@ -25,7 +26,7 @@ function renderQuickCommandsMarkdown(byModule, cliCmd) {
25
26
  lines.push(`${moduleName}:`);
26
27
  for (const cmd of items) {
27
28
  const dataPart = cmd.dataTip ? ` ${cmd.dataTip}` : '';
28
- const cmdLine = `${cliCmd} ${moduleName} ${cmd.shortName}${dataPart}`;
29
+ const cmdLine = `cnb ${moduleName} ${cmd.shortName}${dataPart}`;
29
30
  lines.push(`- \`${cmdLine}\` — ${cmd.description}`);
30
31
  }
31
32
  lines.push('');
@@ -9,7 +9,6 @@ const fs_1 = __importDefault(require("fs"));
9
9
  const lodash_1 = __importDefault(require("lodash"));
10
10
  const constants_1 = require("../constants");
11
11
  const is_skills_1 = require("./is-skills");
12
- const skills_1 = require("../constants/skills");
13
12
  const defaultConfig = {
14
13
  printeReduxAction: true,
15
14
  requestDependencyMap: {
@@ -61,8 +60,8 @@ function getConfig() {
61
60
  : {});
62
61
  if (globalConfig && !process.env.CNB_CLI_CMD) {
63
62
  process.env.CNB_CLI_CMD = globalConfig.skillsDev
64
- ? skills_1.CNB_CLI_DEV_CMD
65
- : skills_1.CNB_CLI_PROD_CMD;
63
+ ? 'node scripts/core/index.js'
64
+ : 'cnb';
66
65
  }
67
66
  return globalConfig;
68
67
  }
@@ -5,6 +5,7 @@ import { diagnoseBuild } from './build-diagnostics';
5
5
  import { analyzeBuildTiming } from './build-timing';
6
6
  import { formatParams } from './format-params';
7
7
  import { formatOutput } from './format-output';
8
+ import { applyExitCode } from './exit-code';
8
9
  import { buildToolParams } from './build-tool-params';
9
10
  import { skillsList } from './skills-list';
10
11
  // @ts-ignore
@@ -103,6 +104,8 @@ export async function executeAction(
103
104
  data = await handleUpload(shortcut, opts.file, toolFunction, pathParams);
104
105
  }
105
106
 
107
+ // 统一退出码策略:非 2xx 置非零退出码(见 lib/exit-code.ts)
108
+ applyExitCode(data);
106
109
  console.log(formatOutput(data, isVerbose, !isVerbose, `${shortcut.module}/${shortcut.tool}`));
107
110
  return;
108
111
  }
@@ -148,5 +151,7 @@ export async function executeAction(
148
151
  const toolKey = `${formattedParams.module}/${formattedParams.tool}`;
149
152
  const isVerbose = !!formattedParams.verbose;
150
153
  const isSummary = shortcut ? !isVerbose : false;
154
+ // 统一退出码策略:所有 API 响应都经此出口,非 2xx 置非零退出码
155
+ applyExitCode(data);
151
156
  console.log(formatOutput(data, isVerbose, isSummary, toolKey));
152
157
  }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * 统一退出码策略(见 cnb/skills/cnb-skill#458)
3
+ *
4
+ * 现状:`cnb` 的退出码只区分「命令名拼错」「未登录」两类失败,
5
+ * HTTP 4xx/5xx 一律 exit 0 —— 失败只体现在 stdout 的 `status:` 字段里。
6
+ * 对自动化(含 AI Agent)来说「退出码 0」就是成功信号,
7
+ * `cnb pulls submit-review` 在权限不足 / 编号写错时返回 4xx + exit 0,
8
+ * 看起来像已生效。
9
+ *
10
+ * 策略(本文件只做这一件事):HTTP 非 2xx 响应置非零退出码。
11
+ * 用 `process.exitCode` 而非 `process.exit()`:让已排队的 stdout 正常 flush,
12
+ * 输出内容不被截断,进程在事件循环结束后以非零码退出。
13
+ */
14
+
15
+ /** 退出码:与既有失败路径区分,便于脚本定位失败类型 */
16
+ export const EXIT_CODE_HTTP_ERROR = 1;
17
+
18
+ /**
19
+ * 从响应对象中解析 HTTP 状态码。
20
+ * 兼容 responseConverter 可能返回的裸 data(无 status 字段)。
21
+ */
22
+ export function getResponseStatus(response: any): number | undefined {
23
+ if (response && typeof response === 'object' && typeof response.status === 'number') {
24
+ return response.status;
25
+ }
26
+ return undefined;
27
+ }
28
+
29
+ /** 是否为 HTTP 成功响应(2xx) */
30
+ export function isHttpSuccess(status: number | undefined): boolean {
31
+ return typeof status === 'number' && status >= 200 && status < 300;
32
+ }
33
+
34
+ /**
35
+ * 按统一策略处理一次 API 调用结果:
36
+ * - 非 2xx 响应把退出码置为 1(不抛错,输出照旧)。
37
+ * - 拿不到 status(converter 返回的裸 data)时不误判失败。
38
+ *
39
+ * @param response 响应对象(含 status)
40
+ * @returns 该响应的 HTTP 状态码(无则 undefined)
41
+ */
42
+ export function applyExitCode(response: any): number | undefined {
43
+ const status = getResponseStatus(response);
44
+
45
+ if (status !== undefined && !isHttpSuccess(status)) {
46
+ process.exitCode = EXIT_CODE_HTTP_ERROR;
47
+ }
48
+
49
+ return status;
50
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cnbcool/cnb-api-generate",
3
- "version": "2.17.3",
3
+ "version": "2.18.0",
4
4
  "main": "./built/index.js",
5
5
  "module": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -11,26 +11,37 @@ description: CNB 平台交互命令,支持代码仓库、Issue、PR、CI、制
11
11
 
12
12
  ## 使用约定
13
13
 
14
- - **编号自识别**:Issue/PR 编号自动从环境变量识别,无需额外传递。
15
- - **可显式覆盖**:`--repo <组织/仓库>` 与 `--number <编号>` 均为可选参数。
16
- 不传时沿用环境变量(即当前仓库的当前 Issue/PR);传入时覆盖环境变量,
17
- 可用于跨仓库或跨编号场景,例如 `cnb pulls get --repo x/y --number 97`、
18
- `cnb issues get --number 68`。两个参数相互独立,可只传其中一个。
19
14
  - **默认摘要省流**:默认精简输出,加 `--verbose` 输出完整数据。
20
15
  - **多行用单引号**:bash 参数为多行文本时用单引号,降低命令注入风险。
21
- - **提及不召唤**:评论中直接 @npc 会召唤 npc;仅提及不召唤时,用反引号包裹 `@npc`。
22
- NPC 的触发条件见 `cnb-npc-search`,单独 `@仓库名` 不会触发。
23
16
 
24
- ## 取正文里的图片与附件
17
+ ## issue 访问
25
18
 
26
- 评论正文里的图片、附件 URL,一律用 `get-imgs` / `get-files` 取回,URL 从 `list-comments` 原文取:
19
+ 编号同 `--repo` 一样默认从环境变量识别,无需传递;用 `--repo <组织/仓库>`、`--number <编号>`
20
+ 可覆盖,例:`cnb issues get --number 68`。
27
21
 
28
- - **参数取 URL 的尾段,且必须含数字 ID 段**:图片取 `/imgs/<issues|pulls>/` 之后的**完整尾段**,
29
- 附件取 `/files/<issues|pulls>/` 之后的完整尾段;尾段首位的数字 ID 段不能省,漏掉会返回 `404 Resource not found`:
30
- - 原文 `.../-/imgs/issues/2101868753481326592/Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png`
31
- - 正确 `2101868753481326592/Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png` ✅
32
- - 漏 ID `Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png` ❌ `404`
33
- - **CLI 内置鉴权**:手写 `Authorization: Bearer` 或 `token` 都不被识别,只会拿到 400
22
+ - `cnb issues get-imgs --img-path 图片路径` — 取正文里的图片
23
+ - `cnb issues get-files --file-path 附件路径` — 取正文里的附件
24
+
25
+ `--img-path` / `--file-path` 取 URL 的**完整尾段**,首位数字 ID 段不能省,漏掉返回 `404`:
26
+
27
+ - 原文 `.../-/imgs/issues/2101868753481326592/Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png`
28
+ - 正确 `2101868753481326592/Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png` ✅
29
+ - 漏 ID `Lma2nfHjnchalMtHZcq4OA/6d7ab033-xxxx.png` ❌ `404`
30
+
31
+ 鉴权由 `@cnbcool/cnb-cli`(命令 `cnb`)内置,执行命令即带登录态,
32
+ `get-imgs` / `get-files` 无需自己传鉴权头。
33
+
34
+ ## pull 访问
35
+
36
+ 编号同 `--repo` 一样默认从环境变量识别,无需传递;用 `--repo <组织/仓库>`、`--number <编号>`
37
+ 可覆盖,例:`cnb pulls get --repo x/y --number 97`。
38
+
39
+ - `cnb pulls get-imgs --img-path 图片路径` — 取正文里的图片
40
+ - `cnb pulls get-files --file-path 附件路径` — 取正文里的附件
41
+
42
+ `--img-path` / `--file-path` 与 issue 同规则:取 URL 的**完整尾段**,首位数字 ID 段不能省,
43
+ 漏掉返回 `404`(原文形如 `.../-/imgs/pulls/<数字 ID>/<key>/<file>`)。
44
+ 鉴权同样由 `cnb` 命令内置的登录态提供,无需自己传鉴权头。
34
45
 
35
46
  ## 常用链接
36
47
 
@@ -40,6 +51,6 @@ description: CNB 平台交互命令,支持代码仓库、Issue、PR、CI、制
40
51
 
41
52
  ## 更多 API
42
53
 
43
- 1. `<$CNB_CLI_CMD$> --help` 查看所有模块
44
- 2. `<$CNB_CLI_CMD$> <module> --help` 查看模块下的工具列表
45
- 3. `<$CNB_CLI_CMD$> <module> <tool> --help` 查看工具参数
54
+ 1. `cnb --help` 查看所有模块
55
+ 2. `cnb <module> --help` 查看模块下的工具列表
56
+ 3. `cnb <module> <tool> --help` 查看工具参数
@@ -1,5 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.CNB_CLI_PROD_CMD = exports.CNB_CLI_DEV_CMD = void 0;
4
- exports.CNB_CLI_DEV_CMD = 'node scripts/core/index.js';
5
- exports.CNB_CLI_PROD_CMD = 'cnb';