@d5render/cli 0.1.85 → 0.1.87

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/README.md CHANGED
@@ -1,35 +1,35 @@
1
- > 参考 [.skills/devops](.skills/devops) 对项目进行初始化
2
-
3
- > .github/\* 是相关技能的自定义的部分,建议自行放在项目文件夹内,review脚本会自动部署在~/.claude/skills(.claude适配的CLI比较多)内
4
-
5
- # CHANGELOG
6
-
7
- ### 2026-3-18
8
-
9
- 🚩 cli
10
-
11
- - 功能更新
12
- - 报告添加回流功能
13
-
14
- 🚩 skills
15
-
16
- - 多agent审查
17
- - 启动LSP等辅助工具
18
-
19
- ### 2026-1-31
20
-
21
- code-review skill 补充LSP相关语句
22
-
23
- ### 2026-1-16
24
-
25
- 补充安全相关检查
26
-
27
- ### 2026-1-7
28
-
29
- 代码评审 skills 更新
30
-
31
- 使用内置 skills
32
-
33
- ### 2025-12-31
34
-
35
- 基础评审能力上云
1
+ > 参考 [.skills/devops](.skills/devops) 对项目进行初始化
2
+
3
+ > .github/\* 是相关技能的自定义的部分,建议自行放在项目文件夹内,review脚本会自动部署在~/.claude/skills(.claude适配的CLI比较多)内
4
+
5
+ # CHANGELOG
6
+
7
+ ### 2026-3-18
8
+
9
+ 🚩 cli
10
+
11
+ - 功能更新
12
+ - 报告添加回流功能
13
+
14
+ 🚩 skills
15
+
16
+ - 多agent审查
17
+ - 启动LSP等辅助工具
18
+
19
+ ### 2026-1-31
20
+
21
+ code-review skill 补充LSP相关语句
22
+
23
+ ### 2026-1-16
24
+
25
+ 补充安全相关检查
26
+
27
+ ### 2026-1-7
28
+
29
+ 代码评审 skills 更新
30
+
31
+ 使用内置 skills
32
+
33
+ ### 2025-12-31
34
+
35
+ 基础评审能力上云
package/bin/d5cli CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { argv, env, platform } from "node:process";
3
- import { execSync, spawn, spawnSync } from "node:child_process";
3
+ import { execSync, spawn } from "node:child_process";
4
4
  import { createHash } from "node:crypto";
5
5
  import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
6
6
  import { dirname, join } from "node:path";
@@ -8,7 +8,7 @@ import { fileURLToPath } from "node:url";
8
8
 
9
9
  //#region package.json
10
10
  var name$1 = "@d5render/cli";
11
- var version = "0.1.85";
11
+ var version = "0.1.87";
12
12
 
13
13
  //#endregion
14
14
  //#region packages/env.ts
@@ -140,14 +140,14 @@ async function changelog() {
140
140
  const matcheds = matched.split("\n");
141
141
  matcheds.shift();
142
142
  matched = matcheds.join("\n").trim();
143
- if (matched) await dingding("NOTICE", `skills 更新\n\n\n${matched}\n\n\n历史请参考 [线上文档内容.skills文件夹](https://www.npmjs.com/package/@d5render/cli)`);
143
+ if (matched) await dingding("NOTICE CLI更新", `skills 更新\n\n\n${matched}\n\n\n历史请参考 [线上文档内容.skills文件夹](https://www.npmjs.com/package/@d5render/cli)`);
144
144
  }
145
145
  function deploySkills(SKILLS_DIR = ".copilot/skills") {
146
146
  const HOME = env.USERPROFILE ?? env.HOME ?? env.HOMEPATH;
147
147
  if (!HOME) throw new Error("cannot find `USERPROFILE` directory");
148
148
  const dir = join(HOME, `${SKILLS_DIR}/code-review`);
149
149
  mkdirSync(dir, { recursive: true });
150
- console.log("deploy code-review skills..." + VERSION);
150
+ console.log("deploy code-review skills...");
151
151
  const skillRoot = join(RUNTIME_CWD, ".skills/code-review");
152
152
  readdirSync(skillRoot).forEach((file) => copyFileSync(join(skillRoot, file), join(dir, file)));
153
153
  const instructionsRoot = join(RUNTIME_CWD, ".github/instructions");
@@ -208,9 +208,10 @@ const COPILOT_HEADERS = {
208
208
  "Editor-Plugin-Version": "copilot-chat/0.35.0",
209
209
  "Copilot-Integration-Id": "vscode-chat"
210
210
  };
211
- function getOAuthToken() {
211
+ function getOAuthToken(setKey) {
212
212
  const token = env.GITHUB_COPILOT_TOKEN || env.COPILOT_TOKEN || env.GITHUB_TOKEN || env.GH_TOKEN;
213
213
  if (!token) throw new Error("未找到 GitHub Token,请设置 GITHUB_COPILOT_TOKEN / GITHUB_TOKEN / GH_TOKEN 环境变量");
214
+ if (setKey) env[setKey] = token;
214
215
  return token;
215
216
  }
216
217
  /**
@@ -230,8 +231,8 @@ async function exchangeForCopilotToken(oauthToken) {
230
231
  return;
231
232
  }
232
233
  }
233
- async function fetchInternalUsage() {
234
- const oauthToken = getOAuthToken();
234
+ async function fetchInternalUsage(options = {}) {
235
+ const oauthToken = getOAuthToken(options.token);
235
236
  const directRes = await fetch(`${GITHUB_API}/copilot_internal/user`, { headers: {
236
237
  Accept: "application/json",
237
238
  Authorization: `token ${oauthToken}`,
@@ -269,7 +270,7 @@ function formatInternalResult(data) {
269
270
  */
270
271
  async function getCopilotUsage(options = {}) {
271
272
  try {
272
- return formatInternalResult(await fetchInternalUsage());
273
+ return formatInternalResult(await fetchInternalUsage(options));
273
274
  } catch {
274
275
  return null;
275
276
  }
@@ -278,7 +279,6 @@ async function getCopilotUsage(options = {}) {
278
279
  //#endregion
279
280
  //#region review/copilot/deploy.ts
280
281
  const config = join(dirname(fileURLToPath(import.meta.url)), "copilot-mcp.json");
281
- console.log("config:", config);
282
282
  const tools = [
283
283
  "--additional-mcp-config",
284
284
  platform === "win32" ? `"@${config}"` : `@${config}`,
@@ -295,9 +295,9 @@ const tools = [
295
295
  async function deploy() {
296
296
  if (!env.CI) return;
297
297
  await changelog();
298
- execSync("npm i -g @github/copilot@latest --registry=https://registry.npmmirror.com", { stdio: "inherit" });
299
298
  deploySkills();
300
- const token = await getCopilotUsage();
299
+ execSync("npm i -g @github/copilot@latest --registry=https://registry.npmmirror.com", { stdio: "inherit" });
300
+ const token = await getCopilotUsage({ token: "GH_TOKEN" });
301
301
  env["TOKEN_USAGE"] = String(token);
302
302
  console.log("deploy customized config...");
303
303
  writeFileSync(config, JSON.stringify({ mcpServers: { [name]: {
@@ -310,84 +310,47 @@ async function deploy() {
310
310
 
311
311
  //#endregion
312
312
  //#region review/copilot/index.ts
313
- const bind = "copilot";
314
- const verifyPrompt = "Reply with OK only, no other text.";
315
- /** 单引号包裹并转义,用于 shell 内联,避免子进程 env 被改写 */
316
- function shellEscape(val) {
317
- return `'${val.replace(/'/g, "'\\''")}'`;
318
- }
319
- /** 最简 copilot 调用(仅 -p),用于验证登录/env 是否可用 */
320
- function runVerifySync() {
321
- const verifyArgs = ["-p", verifyPrompt];
322
- const opts = {
323
- cwd: env.CI_PROJECT_DIR,
324
- encoding: "utf8"
325
- };
326
- if (platform === "win32") {
327
- const r = spawnSync(bind, verifyArgs, {
328
- ...opts,
329
- shell: true
330
- });
331
- return {
332
- code: r.status ?? -1,
333
- out: r.stdout?.toString() ?? "",
334
- err: r.stderr?.toString() ?? ""
335
- };
336
- }
337
- const token = env.COPILOT_GITHUB_TOKEN || env.GH_TOKEN || env.GITHUB_TOKEN || env.GITHUB_COPILOT_TOKEN;
338
- const r = spawnSync("sh", ["-c", `${token !== void 0 && token !== "" ? `export COPILOT_GITHUB_TOKEN=${shellEscape(token)} GH_TOKEN=${shellEscape(token)} GITHUB_TOKEN=${shellEscape(token)}; ` : ""}exec ${bind} ${verifyArgs.map((a) => shellEscape(a)).join(" ")}`], {
339
- ...opts,
340
- env
341
- });
342
- return {
343
- code: r.status ?? -1,
344
- out: r.stdout?.toString() ?? "",
345
- err: r.stderr?.toString() ?? ""
346
- };
347
- }
313
+ const bin = "copilot";
348
314
  async function cli() {
349
315
  await deploy();
316
+ console.log(NAME, "version:", VERSION);
350
317
  const httpProxy = env.HTTP_PROXY || env.http_proxy || "";
351
318
  const httpsProxy = env.HTTPS_PROXY || env.https_proxy || "";
352
319
  if (httpProxy) env.HTTP_PROXY = httpProxy;
353
320
  if (httpsProxy) env.HTTPS_PROXY = httpsProxy;
354
- console.log("@d5render/cli version:", VERSION);
355
- const verify = runVerifySync();
356
- console.log("copilot verify:", verify.code === 0 ? "OK" : `failed (code ${verify.code})`);
357
- if (verify.out) console.log(verify.out.trim());
358
- if (verify.err) console.error(verify.err.trim());
359
321
  const args = [
360
322
  ...tools,
361
323
  "-p",
362
324
  `"${common_review_prompt.replace(/"/g, "\\\"")}"`
363
325
  ];
364
- const opts = {
326
+ let child;
327
+ if (platform === "win32") child = spawn(bin, args, {
365
328
  cwd: env.CI_PROJECT_DIR,
366
329
  stdio: [
367
330
  "inherit",
368
331
  "pipe",
369
332
  "pipe"
370
- ]
371
- };
372
- let child;
373
- if (platform === "win32") child = spawn(bind, args, {
374
- ...opts,
333
+ ],
375
334
  shell: true
376
335
  });
377
- else {
378
- const token = env.COPILOT_GITHUB_TOKEN || env.GH_TOKEN || env.GITHUB_TOKEN || env.GITHUB_COPILOT_TOKEN;
379
- child = spawn("sh", ["-c", `${token !== void 0 && token !== "" ? `export COPILOT_GITHUB_TOKEN=${shellEscape(token)} GH_TOKEN=${shellEscape(token)} GITHUB_TOKEN=${shellEscape(token)}; ` : ""}exec ${bind} ${args.map((a) => shellEscape(a)).join(" ")}`], {
380
- ...opts,
381
- env
382
- });
383
- }
336
+ else child = spawn("sh", ["-c", `export GH_TOKEN=${shellEscape(env.GH_TOKEN)}; exec ${bin} ${args.map((a) => shellEscape(a)).join(" ")}`], {
337
+ cwd: env.CI_PROJECT_DIR,
338
+ stdio: [
339
+ "inherit",
340
+ "pipe",
341
+ "pipe"
342
+ ]
343
+ });
384
344
  child.stdout.on("data", (chunk) => console.log(String(chunk)));
385
345
  child.stderr.on("data", (chunk) => console.error(String(chunk)));
386
- return new Promise((res, rej) => child.on("close", (code) => getCopilotUsage().then((r) => console.log("本次Token积累使用量:", r)).catch(() => {}).finally(() => {
346
+ return new Promise((res, rej) => child.on("close", (code) => getCopilotUsage().then((res) => console.log("本次Token积累使用量:", res)).catch(() => {}).finally(() => {
387
347
  if (code === 0) res();
388
- else rej(/* @__PURE__ */ new Error(`${bind} exited with code ${code}`));
348
+ else rej(/* @__PURE__ */ new Error(`${bin} exited with code ${code}`));
389
349
  })));
390
350
  }
351
+ function shellEscape(val) {
352
+ return `'${(val || "").replace(/'/g, "'\\''")}'`;
353
+ }
391
354
 
392
355
  //#endregion
393
356
  //#region review/index.ts
@@ -402,7 +365,7 @@ async function codereview() {
402
365
  }
403
366
  await cli();
404
367
  } catch (error) {
405
- await dingding("CRITICAL", "CI ERROR: 未知错误,请自行检查日志");
368
+ await dingding("CRITICAL CI ERROR", "CI ERROR: 未知错误,请自行检查日志");
406
369
  throw error;
407
370
  }
408
371
  }