@d5render/cli 0.0.90 → 0.0.91
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/bin/copilot.js +96 -136
- package/bin/d5cli +20 -2
- package/package.json +1 -1
package/bin/copilot.js
CHANGED
|
@@ -14797,10 +14797,10 @@ var require_core$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
14797
14797
|
Ajv$2.ValidationError = validation_error_1$1.default;
|
|
14798
14798
|
Ajv$2.MissingRefError = ref_error_1$3.default;
|
|
14799
14799
|
exports.default = Ajv$2;
|
|
14800
|
-
function checkOptions(checkOpts, options, msg, log
|
|
14800
|
+
function checkOptions(checkOpts, options, msg, log = "error") {
|
|
14801
14801
|
for (const key in checkOpts) {
|
|
14802
14802
|
const opt = key;
|
|
14803
|
-
if (opt in options) this.logger[log
|
|
14803
|
+
if (opt in options) this.logger[log](`${msg}: option ${key}. ${checkOpts[opt]}`);
|
|
14804
14804
|
}
|
|
14805
14805
|
}
|
|
14806
14806
|
function getSchEnv(keyRef) {
|
|
@@ -18510,53 +18510,6 @@ const config = JSON.stringify({ mcpServers: { [name]: {
|
|
|
18510
18510
|
tools: ["*"]
|
|
18511
18511
|
} } });
|
|
18512
18512
|
|
|
18513
|
-
//#endregion
|
|
18514
|
-
//#region packages/builtin/config.ts
|
|
18515
|
-
function log(message) {
|
|
18516
|
-
process.stderr.write(`[LOG] ${message}\n`);
|
|
18517
|
-
}
|
|
18518
|
-
const reportSchema = {
|
|
18519
|
-
title: string().optional().describe("The title of the report"),
|
|
18520
|
-
summary: string().optional().describe("Overall summary of the changes"),
|
|
18521
|
-
relatedJIRAs: array(object({
|
|
18522
|
-
key: string().describe("JIRA issue key, e.g., 'FUS-123'"),
|
|
18523
|
-
summary: string().describe("Summary of the JIRA issue")
|
|
18524
|
-
}).describe("Related JIRA issues")).optional().describe("List of related JIRA issues"),
|
|
18525
|
-
severityIssues: array(object({
|
|
18526
|
-
severity: string().optional().describe("Bug severity levels, such as CRITICAL, HIGH, MEDIUM, LOW."),
|
|
18527
|
-
commitSha: string().optional().describe("The commit SHA associated with the issue"),
|
|
18528
|
-
commitTitle: string().optional().describe("The commit title associated with the issue"),
|
|
18529
|
-
file: string().optional().describe("The file path where the issue is found"),
|
|
18530
|
-
line: string().optional().describe("Line number, e.g., '1-345' pr '205' or '17,35', **must** provide the line of final file"),
|
|
18531
|
-
title: string().optional().describe("A short title for the issue"),
|
|
18532
|
-
details: array(string()).optional().describe("Details about the issue"),
|
|
18533
|
-
suggestions: array(string()).optional().describe("Improvement suggestion"),
|
|
18534
|
-
codeExample: string().optional().describe(`Code modification suggestions, recommended to use code in diff format, like: \`\`\`
|
|
18535
|
-
while (condition) {
|
|
18536
|
-
unchanged line;
|
|
18537
|
-
- remove this;
|
|
18538
|
-
+ replace it with this;
|
|
18539
|
-
+ and this;
|
|
18540
|
-
but keep this the same;
|
|
18541
|
-
}\`\`\`.`)
|
|
18542
|
-
})).optional().describe("List all bugs, Please order by 'severity' sort them from heaviest to lightest."),
|
|
18543
|
-
mainRisks: array(string().describe("Main risk item")).optional().describe("List of main risks"),
|
|
18544
|
-
nextActions: array(string().describe("Description of the action item")).optional().describe("List suggestions for improvement")
|
|
18545
|
-
};
|
|
18546
|
-
function commonURL() {
|
|
18547
|
-
const { CI_SERVER_URL, CI_PROJECT_PATH, CI_MERGE_REQUEST_IID, CI_COMMIT_SHA } = envUsed;
|
|
18548
|
-
if (!CI_SERVER_URL || !CI_PROJECT_PATH) return {};
|
|
18549
|
-
if (CI_MERGE_REQUEST_IID) return {
|
|
18550
|
-
url: `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/merge_requests/${CI_MERGE_REQUEST_IID}`,
|
|
18551
|
-
type: "merge_request"
|
|
18552
|
-
};
|
|
18553
|
-
if (CI_COMMIT_SHA) return {
|
|
18554
|
-
url: `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/commit/${CI_COMMIT_SHA}`,
|
|
18555
|
-
type: "commit"
|
|
18556
|
-
};
|
|
18557
|
-
return {};
|
|
18558
|
-
}
|
|
18559
|
-
|
|
18560
18513
|
//#endregion
|
|
18561
18514
|
//#region packages/gitlab/config.ts
|
|
18562
18515
|
const canireview = "can-i-review";
|
|
@@ -18591,13 +18544,10 @@ const lastComment = { value: {} };
|
|
|
18591
18544
|
const postComments = (report$1) => {
|
|
18592
18545
|
const url = commonMergeURL();
|
|
18593
18546
|
const { title = "代码审查报告", summary, severityIssues = [], mainRisks = [], nextActions = [] } = report$1;
|
|
18594
|
-
if (severityIssues.length === 0) {
|
|
18595
|
-
|
|
18596
|
-
|
|
18597
|
-
|
|
18598
|
-
text: "✅ GitLab MCP Report 执行完成,无问题"
|
|
18599
|
-
}] });
|
|
18600
|
-
}
|
|
18547
|
+
if (severityIssues.length === 0) return Promise.resolve({ content: [{
|
|
18548
|
+
type: "text",
|
|
18549
|
+
text: "✅ GitLab MCP Report 执行完成,无问题"
|
|
18550
|
+
}] });
|
|
18601
18551
|
let message = `## 📖 ${title}\n`;
|
|
18602
18552
|
if (summary) message += `> ${summary}\n\n`;
|
|
18603
18553
|
const commitTasks = [];
|
|
@@ -18649,40 +18599,27 @@ const postComments = (report$1) => {
|
|
|
18649
18599
|
}
|
|
18650
18600
|
}
|
|
18651
18601
|
if (nextActions.length > 0) message += "\n\n### 📈 其他建议\n\n-----\n - " + nextActions.join("\n - ");
|
|
18652
|
-
if (!url) {
|
|
18653
|
-
|
|
18654
|
-
|
|
18655
|
-
|
|
18656
|
-
|
|
18657
|
-
|
|
18658
|
-
|
|
18659
|
-
|
|
18660
|
-
|
|
18661
|
-
const successCount = results.filter((r) => r.status === "fulfilled").length;
|
|
18662
|
-
const failCount = results.filter((r) => r.status === "rejected").length;
|
|
18663
|
-
if (commitTasks.length > 0) log(`GitLab: 行内评论完成 - 成功: ${successCount}, 失败: ${failCount}`);
|
|
18664
|
-
return fetch(url + `/notes`, {
|
|
18665
|
-
method: "POST",
|
|
18666
|
-
headers: commonHeaders$1(),
|
|
18667
|
-
body: JSON.stringify({ body: message })
|
|
18668
|
-
});
|
|
18669
|
-
}).then((res) => res.json()).then((res) => {
|
|
18602
|
+
if (!url) return Promise.resolve({ content: [{
|
|
18603
|
+
type: "text",
|
|
18604
|
+
text: "⚠️ 当前为 push 事件,无合并请求,无法在 GitLab 中发布报告。报告内容已生成但未发布。"
|
|
18605
|
+
}] });
|
|
18606
|
+
return Promise.allSettled(commitTasks.map((task) => task())).then(() => fetch(url + `/notes`, {
|
|
18607
|
+
method: "POST",
|
|
18608
|
+
headers: commonHeaders$1(),
|
|
18609
|
+
body: JSON.stringify({ body: message })
|
|
18610
|
+
})).then((res) => res.json()).then((res) => {
|
|
18670
18611
|
lastComment.value = res;
|
|
18671
|
-
log(`GitLab: 总结报告已发布`);
|
|
18672
18612
|
return { content: [{
|
|
18673
18613
|
type: "text",
|
|
18674
18614
|
text: "✅ GitLab 代码审查报告已发布。"
|
|
18675
18615
|
}] };
|
|
18676
|
-
}).catch((error$1) => {
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
isError: true
|
|
18684
|
-
};
|
|
18685
|
-
});
|
|
18616
|
+
}).catch((error$1) => ({
|
|
18617
|
+
content: [{
|
|
18618
|
+
type: "text",
|
|
18619
|
+
text: errorMessage + `-report, reason: ${error$1.message || error$1.reason || "未知错误"}`
|
|
18620
|
+
}],
|
|
18621
|
+
isError: true
|
|
18622
|
+
}));
|
|
18686
18623
|
};
|
|
18687
18624
|
function toCode(code) {
|
|
18688
18625
|
const ct = code.trim();
|
|
@@ -18751,25 +18688,63 @@ function installGitlab(server$1) {
|
|
|
18751
18688
|
}, getMergeInfomation);
|
|
18752
18689
|
}
|
|
18753
18690
|
|
|
18691
|
+
//#endregion
|
|
18692
|
+
//#region packages/builtin/config.ts
|
|
18693
|
+
const reportSchema = {
|
|
18694
|
+
title: string().optional().describe("The title of the report"),
|
|
18695
|
+
summary: string().optional().describe("Overall summary of the changes"),
|
|
18696
|
+
relatedJIRAs: array(object({
|
|
18697
|
+
key: string().describe("JIRA issue key, e.g., 'FUS-123'"),
|
|
18698
|
+
summary: string().describe("Summary of the JIRA issue")
|
|
18699
|
+
}).describe("Related JIRA issues")).optional().describe("List of related JIRA issues"),
|
|
18700
|
+
severityIssues: array(object({
|
|
18701
|
+
severity: string().optional().describe("Bug severity levels, such as CRITICAL, HIGH, MEDIUM, LOW."),
|
|
18702
|
+
commitSha: string().optional().describe("The commit SHA associated with the issue"),
|
|
18703
|
+
commitTitle: string().optional().describe("The commit title associated with the issue"),
|
|
18704
|
+
file: string().optional().describe("The file path where the issue is found"),
|
|
18705
|
+
line: string().optional().describe("Line number, e.g., '1-345' pr '205' or '17,35', **must** provide the line of final file"),
|
|
18706
|
+
title: string().optional().describe("A short title for the issue"),
|
|
18707
|
+
details: array(string()).optional().describe("Details about the issue"),
|
|
18708
|
+
suggestions: array(string()).optional().describe("Improvement suggestion"),
|
|
18709
|
+
codeExample: string().optional().describe(`Code modification suggestions, recommended to use code in diff format, like: \`\`\`
|
|
18710
|
+
while (condition) {
|
|
18711
|
+
unchanged line;
|
|
18712
|
+
- remove this;
|
|
18713
|
+
+ replace it with this;
|
|
18714
|
+
+ and this;
|
|
18715
|
+
but keep this the same;
|
|
18716
|
+
}\`\`\`.`)
|
|
18717
|
+
})).optional().describe("List all bugs, Please order by 'severity' sort them from heaviest to lightest."),
|
|
18718
|
+
mainRisks: array(string().describe("Main risk item")).optional().describe("List of main risks"),
|
|
18719
|
+
nextActions: array(string().describe("Description of the action item")).optional().describe("List suggestions for improvement")
|
|
18720
|
+
};
|
|
18721
|
+
function commonURL() {
|
|
18722
|
+
const { CI_SERVER_URL, CI_PROJECT_PATH, CI_MERGE_REQUEST_IID, CI_COMMIT_SHA } = envUsed;
|
|
18723
|
+
if (!CI_SERVER_URL || !CI_PROJECT_PATH) return {};
|
|
18724
|
+
if (CI_MERGE_REQUEST_IID) return {
|
|
18725
|
+
url: `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/merge_requests/${CI_MERGE_REQUEST_IID}`,
|
|
18726
|
+
type: "merge_request"
|
|
18727
|
+
};
|
|
18728
|
+
if (CI_COMMIT_SHA) return {
|
|
18729
|
+
url: `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/commit/${CI_COMMIT_SHA}`,
|
|
18730
|
+
type: "commit"
|
|
18731
|
+
};
|
|
18732
|
+
return {};
|
|
18733
|
+
}
|
|
18734
|
+
|
|
18754
18735
|
//#endregion
|
|
18755
18736
|
//#region packages/builtin/dingding.ts
|
|
18756
18737
|
const postComments$1 = (report$1) => {
|
|
18757
18738
|
const { CI_PROJECT_NAME = "", CI_COMMIT_SHA = "", CI_COMMIT_AUTHOR = "", CI_COMMIT_AUTHOR_EMAIL = "", JIRA_BASE_URL, CI_MERGE_REQUEST_IID, DINGTALK_WEBHOOK } = envUsed;
|
|
18758
|
-
if (!DINGTALK_WEBHOOK) {
|
|
18759
|
-
|
|
18760
|
-
|
|
18761
|
-
|
|
18762
|
-
text: "✅ 无 DingDing Webhook 配置,跳过推送。"
|
|
18763
|
-
}] };
|
|
18764
|
-
}
|
|
18739
|
+
if (!DINGTALK_WEBHOOK) return { content: [{
|
|
18740
|
+
type: "text",
|
|
18741
|
+
text: "✅ 无 DingDing Webhook 配置,跳过推送。"
|
|
18742
|
+
}] };
|
|
18765
18743
|
const { title = "代码审查报告", mainRisks = [], relatedJIRAs = [], severityIssues = [] } = report$1;
|
|
18766
|
-
if (severityIssues.length === 0) {
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
|
|
18770
|
-
text: "✅ 无问题,跳过DingDing推送。"
|
|
18771
|
-
}] };
|
|
18772
|
-
}
|
|
18744
|
+
if (severityIssues.length === 0) return { content: [{
|
|
18745
|
+
type: "text",
|
|
18746
|
+
text: "✅ 无问题,跳过DingDing推送。"
|
|
18747
|
+
}] };
|
|
18773
18748
|
let { url, type } = commonURL();
|
|
18774
18749
|
let message = `### 📖 ${title}\n\n**共计**:${severityIssues.length}个问题\n\n${mainRisks.length >= 0 ? "**主要风险**:\n\n" + mainRisks.join("\n\n") + "\n\n" : "\n\n"}-----\n\n**项目名**:${CI_PROJECT_NAME}\n\n**作者**:${CI_COMMIT_AUTHOR}${CI_COMMIT_AUTHOR_EMAIL ? ` <${CI_COMMIT_AUTHOR_EMAIL}>` : ""}`;
|
|
18775
18750
|
if (type) {
|
|
@@ -18823,7 +18798,6 @@ const postComments$1 = (report$1) => {
|
|
|
18823
18798
|
hashLength++;
|
|
18824
18799
|
}
|
|
18825
18800
|
if (relatedJIRAs.length > 0) message += `\n\n\n\n#### 🔗 关联 JIRA\n ${relatedJIRAs.map((v) => `[${v.key}](${JIRA_BASE_URL}/browse/${v.key}): ${v.summary}`).join("\n\n")}`;
|
|
18826
|
-
log(`钉钉: 开始推送 - 问题数: ${severityIssues.length}, 项目: ${CI_PROJECT_NAME}`);
|
|
18827
18801
|
return fetch(DINGTALK_WEBHOOK, {
|
|
18828
18802
|
method: "POST",
|
|
18829
18803
|
headers: { "Content-Type": "application/json" },
|
|
@@ -18842,31 +18816,22 @@ const postComments$1 = (report$1) => {
|
|
|
18842
18816
|
if (!response.ok) throw new Error("");
|
|
18843
18817
|
return response.json();
|
|
18844
18818
|
}).then((res) => {
|
|
18845
|
-
if (res.errcode === 0) {
|
|
18846
|
-
|
|
18847
|
-
|
|
18848
|
-
|
|
18849
|
-
|
|
18850
|
-
|
|
18851
|
-
|
|
18852
|
-
|
|
18853
|
-
log("钉钉: 推送成功,但被关键词拦截");
|
|
18854
|
-
return { content: [{
|
|
18855
|
-
type: "text",
|
|
18856
|
-
text: "✅ DingDing 代码审查报告已推送,但被屏蔽关键词拦截。"
|
|
18857
|
-
}] };
|
|
18858
|
-
}
|
|
18819
|
+
if (res.errcode === 0) return { content: [{
|
|
18820
|
+
type: "text",
|
|
18821
|
+
text: "✅ DingDing 代码审查报告已推送。"
|
|
18822
|
+
}] };
|
|
18823
|
+
if (res.errcode === 31e4) return { content: [{
|
|
18824
|
+
type: "text",
|
|
18825
|
+
text: "✅ DingDing 代码审查报告已推送,但被屏蔽关键词拦截。"
|
|
18826
|
+
}] };
|
|
18859
18827
|
throw new Error("Post comments to DingTalk with error code:" + res.errcode + ", message: " + res.errmsg);
|
|
18860
|
-
}).catch((error$1) => {
|
|
18861
|
-
|
|
18862
|
-
|
|
18863
|
-
|
|
18864
|
-
|
|
18865
|
-
|
|
18866
|
-
|
|
18867
|
-
isError: true
|
|
18868
|
-
};
|
|
18869
|
-
});
|
|
18828
|
+
}).catch((error$1) => ({
|
|
18829
|
+
content: [{
|
|
18830
|
+
type: "text",
|
|
18831
|
+
text: errorMessage + "-dingding, reason: " + (error$1.message || "Post comments to DingTalk failed")
|
|
18832
|
+
}],
|
|
18833
|
+
isError: true
|
|
18834
|
+
}));
|
|
18870
18835
|
};
|
|
18871
18836
|
|
|
18872
18837
|
//#endregion
|
|
@@ -18921,20 +18886,15 @@ function install(server$1) {
|
|
|
18921
18886
|
description: noMandatory,
|
|
18922
18887
|
inputSchema: reportSchema
|
|
18923
18888
|
}, async (...args) => {
|
|
18924
|
-
log(`报告提交开始 - 问题数: ${args[0]?.severityIssues?.length || 0}`);
|
|
18925
18889
|
const git = await postComments(...args);
|
|
18926
18890
|
const ding = await postComments$1(...args);
|
|
18927
|
-
if (git.isError || ding.isError) {
|
|
18928
|
-
|
|
18929
|
-
|
|
18930
|
-
content: [
|
|
18931
|
-
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
isError: true
|
|
18935
|
-
};
|
|
18936
|
-
}
|
|
18937
|
-
log(`报告提交成功 - GitLab: 已发布, 钉钉: 已推送`);
|
|
18891
|
+
if (git.isError || ding.isError) return {
|
|
18892
|
+
content: [{
|
|
18893
|
+
type: "text",
|
|
18894
|
+
text: [...git.isError ? git.content : [], ...ding.isError ? ding.content : []].map((c) => c.text).join(", ")
|
|
18895
|
+
}],
|
|
18896
|
+
isError: true
|
|
18897
|
+
};
|
|
18938
18898
|
return { content: [{
|
|
18939
18899
|
type: "text",
|
|
18940
18900
|
text: args[0]?.summary || ""
|
package/bin/d5cli
CHANGED
|
@@ -2,10 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
import { execSync, spawn } from "node:child_process";
|
|
4
4
|
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
-
import { join } from "node:path";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
6
|
import { env, exit, platform } from "node:process";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
7
8
|
import { errorMessage, getHash, name, report, tools } from "../copilot.config.js";
|
|
8
9
|
|
|
10
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
+
|
|
9
12
|
const prompt = `call the mcp tool '${name}-${getHash}' to load review commits, if the task encounters an error, throw that, otherwise, you can decide for yourself which tools to use to enrich context and determine whether a specific commit needs to be reviewed.
|
|
10
13
|
Then, use chinese as default language to organize the report into JSON format and call the mcp tool '${name}-${report}', please ignore error encountered when calling this and report title should not contain words such as MCP or "中文".`;
|
|
11
14
|
|
|
@@ -76,6 +79,21 @@ function findCopilopt() {
|
|
|
76
79
|
? copilotPackage.bin
|
|
77
80
|
: copilotPackage.bin?.copilot || copilotPackage.bin?.["@github/copilot"];
|
|
78
81
|
if (!binPath) throw new Error("找不到 copilot 可执行文件路径");
|
|
79
|
-
|
|
82
|
+
const copilotVersion = copilotPackage.version || "未知版本";
|
|
83
|
+
|
|
84
|
+
// 读取 d5cli 的版本
|
|
85
|
+
const d5cliPkg = join(__dirname, "..", "package.json");
|
|
86
|
+
let d5cliVersion = "未知版本";
|
|
87
|
+
if (existsSync(d5cliPkg)) {
|
|
88
|
+
try {
|
|
89
|
+
const d5cliPackage = JSON.parse(readFileSync(d5cliPkg, "utf8"));
|
|
90
|
+
d5cliVersion = d5cliPackage.version || "未知版本";
|
|
91
|
+
} catch {}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
console.log(
|
|
95
|
+
join(copilot, binPath),
|
|
96
|
+
`copilot 已经被发现,copilot 版本: ${copilotVersion}, d5cli 版本: ${d5cliVersion}`
|
|
97
|
+
);
|
|
80
98
|
return join(copilot, binPath);
|
|
81
99
|
}
|