@d5render/cli 0.0.69 → 0.0.83
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/LICENSE +21 -21
- package/{dist → bin}/copilot.js +6 -2
- package/{standalone.js → bin/d5cli} +81 -74
- package/copilot.config.js +68 -68
- package/package.json +9 -8
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2025 D5 Techs
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 D5 Techs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/{dist → bin}/copilot.js
RENAMED
|
@@ -18475,7 +18475,7 @@ const report = "report";
|
|
|
18475
18475
|
const getHash = "getHash";
|
|
18476
18476
|
const errorMessage = "error: call mcp " + name;
|
|
18477
18477
|
const noMandatory = "dont't call under non-mandatory conditions";
|
|
18478
|
-
const file = join(dirname(fileURLToPath(import.meta.url)), "
|
|
18478
|
+
const file = join(dirname(fileURLToPath(import.meta.url)), "bin/copilot.js");
|
|
18479
18479
|
const { argv } = process;
|
|
18480
18480
|
const envArg = argv.find((arg) => arg.startsWith("--customizenv="));
|
|
18481
18481
|
let envJson = {};
|
|
@@ -18599,6 +18599,10 @@ const postComments = (report$1) => {
|
|
|
18599
18599
|
}
|
|
18600
18600
|
}
|
|
18601
18601
|
if (nextActions.length > 0) message += "\n\n### 📈 其他建议\n\n-----\n - " + nextActions.join("\n - ");
|
|
18602
|
+
if (!url) return Promise.resolve({ content: [{
|
|
18603
|
+
type: "text",
|
|
18604
|
+
text: "⚠️ 当前为 push 事件,无合并请求,无法在 GitLab 中发布报告。报告内容已生成但未发布。"
|
|
18605
|
+
}] });
|
|
18602
18606
|
return Promise.allSettled(commitTasks.map((task) => task())).then(() => fetch(url + `/notes`, {
|
|
18603
18607
|
method: "POST",
|
|
18604
18608
|
headers: commonHeaders$1(),
|
|
@@ -18612,7 +18616,7 @@ const postComments = (report$1) => {
|
|
|
18612
18616
|
}).catch((error$1) => ({
|
|
18613
18617
|
content: [{
|
|
18614
18618
|
type: "text",
|
|
18615
|
-
text: errorMessage +
|
|
18619
|
+
text: errorMessage + `-report, reason: ${error$1.message || error$1.reason || "未知错误"}`
|
|
18616
18620
|
}],
|
|
18617
18621
|
isError: true
|
|
18618
18622
|
}));
|
|
@@ -1,74 +1,81 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
|
|
41
|
-
.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
execSync("npm
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
console.error(error);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync, spawn } from "node:child_process";
|
|
4
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
5
|
+
import { join } from "node:path";
|
|
6
|
+
import { env, exit, platform } from "node:process";
|
|
7
|
+
import { errorMessage, getHash, name, report, tools } from "../copilot.config.js";
|
|
8
|
+
|
|
9
|
+
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
|
+
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
|
+
|
|
12
|
+
// TODO: 只支持保护分支触发
|
|
13
|
+
install();
|
|
14
|
+
const copilot = spawn("node", [findCopilopt(), "--stream", "off", ...tools, "-p", prompt], {
|
|
15
|
+
cwd: env.CI_PROJECT_DIR,
|
|
16
|
+
...(platform === "win32" && { windowsHide: true }),
|
|
17
|
+
});
|
|
18
|
+
let hasError = false;
|
|
19
|
+
const errorRegex = new RegExp(errorMessage, "i");
|
|
20
|
+
copilot.stdout.on("data", (data) => {
|
|
21
|
+
const str = String(data);
|
|
22
|
+
console.log(str);
|
|
23
|
+
|
|
24
|
+
if (errorRegex.test(str)) hasError = true;
|
|
25
|
+
});
|
|
26
|
+
copilot.stderr.on("data", (data) => console.error(String(data)));
|
|
27
|
+
copilot.on("close", () => {
|
|
28
|
+
if (hasError) exit(1);
|
|
29
|
+
else exit(0);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function install() {
|
|
33
|
+
if (!env.CI) return;
|
|
34
|
+
console.log("install dependencies...");
|
|
35
|
+
try {
|
|
36
|
+
const local = execSync("npm list @github/copilot -g --depth=0 --json").toString();
|
|
37
|
+
const localInfo = JSON.parse(local);
|
|
38
|
+
const localVersion = localInfo.dependencies ? localInfo.dependencies?.["@github/copilot"]?.version : null;
|
|
39
|
+
const remoteVersion = execSync("npm view @github/copilot version --registry=https://registry.npmmirror.com")
|
|
40
|
+
.toString()
|
|
41
|
+
.trim();
|
|
42
|
+
if (localVersion !== remoteVersion) {
|
|
43
|
+
execSync("npm uninstall -g @github/copilot --force");
|
|
44
|
+
execSync("npm install -g @github/copilot --registry=https://registry.npmmirror.com", {
|
|
45
|
+
stdio: "inherit",
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
} catch (error) {
|
|
49
|
+
console.error("install dependencies error");
|
|
50
|
+
console.error(error);
|
|
51
|
+
if (error.status === 1 && error.stdout) {
|
|
52
|
+
execSync("npm install -g @github/copilot --registry=https://registry.npmmirror.com", {
|
|
53
|
+
stdio: "inherit",
|
|
54
|
+
});
|
|
55
|
+
console.log("install dependencies success");
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function findCopilopt() {
|
|
60
|
+
let copilot = execSync("npm list @github/copilot -g -p").toString().trim();
|
|
61
|
+
if (!copilot) {
|
|
62
|
+
try {
|
|
63
|
+
const pathEnv = env.PATH || env.Path || "";
|
|
64
|
+
const pathSeparator = platform === "win32" ? ";" : ":";
|
|
65
|
+
const npm = pathEnv.split(pathSeparator).find((p) => p.includes("npm"));
|
|
66
|
+
if (npm) copilot = join(npm, "node_modules", "@github", "copilot");
|
|
67
|
+
} catch {}
|
|
68
|
+
}
|
|
69
|
+
const pkg = join(copilot, "package.json");
|
|
70
|
+
if (!existsSync(pkg)) throw new Error("找不到 copilot 包");
|
|
71
|
+
const copilotPackage = JSON.parse(readFileSync(pkg, "utf8"));
|
|
72
|
+
// return join(copilot, copilotPackage.bin.copilot);
|
|
73
|
+
// 兼容 bin 字段可能是字符串或对象的情况
|
|
74
|
+
const binPath =
|
|
75
|
+
typeof copilotPackage.bin === "string"
|
|
76
|
+
? copilotPackage.bin
|
|
77
|
+
: copilotPackage.bin?.copilot || copilotPackage.bin?.["@github/copilot"];
|
|
78
|
+
if (!binPath) throw new Error("找不到 copilot 可执行文件路径");
|
|
79
|
+
console.log(join(copilot, binPath), "copilot 已经被发现");
|
|
80
|
+
return join(copilot, binPath);
|
|
81
|
+
}
|
package/copilot.config.js
CHANGED
|
@@ -1,68 +1,68 @@
|
|
|
1
|
-
import { dirname, join } from "node:path";
|
|
2
|
-
import { fileURLToPath } from "node:url";
|
|
3
|
-
|
|
4
|
-
export const name = "d5_mcp_review_builtin";
|
|
5
|
-
export const report = "report";
|
|
6
|
-
export const getPrompt = "default_review_requirements";
|
|
7
|
-
export const getHash = "getHash";
|
|
8
|
-
|
|
9
|
-
export const errorMessage = "error: call mcp " + name;
|
|
10
|
-
export const noMandatory = "dont't call under non-mandatory conditions";
|
|
11
|
-
|
|
12
|
-
export const file = join(dirname(fileURLToPath(import.meta.url)), "
|
|
13
|
-
|
|
14
|
-
const { argv } = process;
|
|
15
|
-
const envArg = argv.find((arg) => arg.startsWith("--customizenv="));
|
|
16
|
-
let envJson = {};
|
|
17
|
-
if (envArg) envJson = JSON.parse(envArg.replace("--customizenv=", ""));
|
|
18
|
-
function toEnv(key, defaultValue = undefined) {
|
|
19
|
-
return envJson[key] || process.env[key] || defaultValue;
|
|
20
|
-
}
|
|
21
|
-
// 辣鸡: https://github.com/modelcontextprotocol/typescript-sdk/issues/259
|
|
22
|
-
export const envUsed = {
|
|
23
|
-
CI_SERVER_URL: toEnv("CI_SERVER_URL"),
|
|
24
|
-
CI_PROJECT_PATH: toEnv("CI_PROJECT_PATH"),
|
|
25
|
-
CI_PROJECT_ID: toEnv("CI_PROJECT_ID"),
|
|
26
|
-
CI_PROJECT_NAME: toEnv("CI_PROJECT_NAME"),
|
|
27
|
-
|
|
28
|
-
CI_COMMIT_SHA: toEnv("CI_COMMIT_SHA"),
|
|
29
|
-
CI_COMMIT_BEFORE_SHA: toEnv("CI_COMMIT_BEFORE_SHA"),
|
|
30
|
-
|
|
31
|
-
CI_COMMIT_AUTHOR: toEnv("CI_COMMIT_AUTHOR"),
|
|
32
|
-
CI_COMMIT_AUTHOR_EMAIL: toEnv("CI_COMMIT_AUTHOR_EMAIL"),
|
|
33
|
-
|
|
34
|
-
CI_MERGE_REQUEST_IID: toEnv("CI_MERGE_REQUEST_IID"),
|
|
35
|
-
CI_MERGE_REQUEST_TITLE: toEnv("CI_MERGE_REQUEST_TITLE"),
|
|
36
|
-
CI_MERGE_REQUEST_DESCRIPTION: toEnv("CI_MERGE_REQUEST_DESCRIPTION"),
|
|
37
|
-
|
|
38
|
-
JIRA_BASE_URL: toEnv("JIRA_BASE_URL", "http://jira.d5techs.com.cn"),
|
|
39
|
-
|
|
40
|
-
DINGTALK_WEBHOOK: toEnv("DINGTALK_WEBHOOK"),
|
|
41
|
-
GITLAB_TOKEN: toEnv("GITLAB_TOKEN"),
|
|
42
|
-
JIRA_PAT: toEnv("JIRA_PAT"),
|
|
43
|
-
JIRA_COOKIE: toEnv("JIRA_COOKIE"),
|
|
44
|
-
|
|
45
|
-
JIRA_USERNAME: toEnv("JIRA_USERNAME"),
|
|
46
|
-
JIRA_PASSWORD: toEnv("JIRA_PASSWORD")
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const config = JSON.stringify({
|
|
50
|
-
mcpServers: {
|
|
51
|
-
[name]: {
|
|
52
|
-
type: "local",
|
|
53
|
-
command: "node",
|
|
54
|
-
args: [file, `--customizenv=${JSON.stringify(envUsed)}`],
|
|
55
|
-
tools: ["*"]
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
});
|
|
59
|
-
export const tools = [
|
|
60
|
-
"--additional-mcp-config",
|
|
61
|
-
config,
|
|
62
|
-
"--allow-all-tools",
|
|
63
|
-
"--resume",
|
|
64
|
-
"--deny-tool",
|
|
65
|
-
"write",
|
|
66
|
-
"--deny-tool",
|
|
67
|
-
"github-mcp-server"
|
|
68
|
-
];
|
|
1
|
+
import { dirname, join } from "node:path";
|
|
2
|
+
import { fileURLToPath } from "node:url";
|
|
3
|
+
|
|
4
|
+
export const name = "d5_mcp_review_builtin";
|
|
5
|
+
export const report = "report";
|
|
6
|
+
export const getPrompt = "default_review_requirements";
|
|
7
|
+
export const getHash = "getHash";
|
|
8
|
+
|
|
9
|
+
export const errorMessage = "error: call mcp " + name;
|
|
10
|
+
export const noMandatory = "dont't call under non-mandatory conditions";
|
|
11
|
+
|
|
12
|
+
export const file = join(dirname(fileURLToPath(import.meta.url)), "bin/copilot.js");
|
|
13
|
+
|
|
14
|
+
const { argv } = process;
|
|
15
|
+
const envArg = argv.find((arg) => arg.startsWith("--customizenv="));
|
|
16
|
+
let envJson = {};
|
|
17
|
+
if (envArg) envJson = JSON.parse(envArg.replace("--customizenv=", ""));
|
|
18
|
+
function toEnv(key, defaultValue = undefined) {
|
|
19
|
+
return envJson[key] || process.env[key] || defaultValue;
|
|
20
|
+
}
|
|
21
|
+
// 辣鸡: https://github.com/modelcontextprotocol/typescript-sdk/issues/259
|
|
22
|
+
export const envUsed = {
|
|
23
|
+
CI_SERVER_URL: toEnv("CI_SERVER_URL"),
|
|
24
|
+
CI_PROJECT_PATH: toEnv("CI_PROJECT_PATH"),
|
|
25
|
+
CI_PROJECT_ID: toEnv("CI_PROJECT_ID"),
|
|
26
|
+
CI_PROJECT_NAME: toEnv("CI_PROJECT_NAME"),
|
|
27
|
+
|
|
28
|
+
CI_COMMIT_SHA: toEnv("CI_COMMIT_SHA"),
|
|
29
|
+
CI_COMMIT_BEFORE_SHA: toEnv("CI_COMMIT_BEFORE_SHA"),
|
|
30
|
+
|
|
31
|
+
CI_COMMIT_AUTHOR: toEnv("CI_COMMIT_AUTHOR"),
|
|
32
|
+
CI_COMMIT_AUTHOR_EMAIL: toEnv("CI_COMMIT_AUTHOR_EMAIL"),
|
|
33
|
+
|
|
34
|
+
CI_MERGE_REQUEST_IID: toEnv("CI_MERGE_REQUEST_IID"),
|
|
35
|
+
CI_MERGE_REQUEST_TITLE: toEnv("CI_MERGE_REQUEST_TITLE"),
|
|
36
|
+
CI_MERGE_REQUEST_DESCRIPTION: toEnv("CI_MERGE_REQUEST_DESCRIPTION"),
|
|
37
|
+
|
|
38
|
+
JIRA_BASE_URL: toEnv("JIRA_BASE_URL", "http://jira.d5techs.com.cn"),
|
|
39
|
+
|
|
40
|
+
DINGTALK_WEBHOOK: toEnv("DINGTALK_WEBHOOK"),
|
|
41
|
+
GITLAB_TOKEN: toEnv("GITLAB_TOKEN"),
|
|
42
|
+
JIRA_PAT: toEnv("JIRA_PAT"),
|
|
43
|
+
JIRA_COOKIE: toEnv("JIRA_COOKIE"),
|
|
44
|
+
|
|
45
|
+
JIRA_USERNAME: toEnv("JIRA_USERNAME"),
|
|
46
|
+
JIRA_PASSWORD: toEnv("JIRA_PASSWORD")
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const config = JSON.stringify({
|
|
50
|
+
mcpServers: {
|
|
51
|
+
[name]: {
|
|
52
|
+
type: "local",
|
|
53
|
+
command: "node",
|
|
54
|
+
args: [file, `--customizenv=${JSON.stringify(envUsed)}`],
|
|
55
|
+
tools: ["*"]
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
export const tools = [
|
|
60
|
+
"--additional-mcp-config",
|
|
61
|
+
config,
|
|
62
|
+
"--allow-all-tools",
|
|
63
|
+
"--resume",
|
|
64
|
+
"--deny-tool",
|
|
65
|
+
"write",
|
|
66
|
+
"--deny-tool",
|
|
67
|
+
"github-mcp-server"
|
|
68
|
+
];
|
package/package.json
CHANGED
|
@@ -3,27 +3,28 @@
|
|
|
3
3
|
"type": "module",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "jasirou",
|
|
6
|
-
"main": "./
|
|
7
|
-
"version": "0.0.
|
|
6
|
+
"main": "./bin/d5cli",
|
|
7
|
+
"version": "0.0.83",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@modelcontextprotocol/sdk": "^1.24.3",
|
|
10
10
|
"@types/node": "22.18.1",
|
|
11
11
|
"@types/vscode": "^1.88.0",
|
|
12
12
|
"@vscode/vsce": "^3.2.2",
|
|
13
|
+
"oxfmt": "^0.21.0",
|
|
14
|
+
"oxlint": "^1.36.0",
|
|
13
15
|
"rolldown": "^1.0.0-beta.53",
|
|
14
16
|
"zod": "^4.1.13"
|
|
15
17
|
},
|
|
16
18
|
"files": [
|
|
17
|
-
"
|
|
18
|
-
"./copilot.config.js"
|
|
19
|
-
"./standalone.js"
|
|
19
|
+
"bin",
|
|
20
|
+
"./copilot.config.js"
|
|
20
21
|
],
|
|
21
22
|
"bin": {
|
|
22
|
-
"d5cli": "
|
|
23
|
+
"d5cli": "bin/d5cli"
|
|
23
24
|
},
|
|
24
25
|
"scripts": {
|
|
25
26
|
"build:copilot": "rolldown -c packages/copilot/rolldown.config.ts",
|
|
26
|
-
"
|
|
27
|
-
"release": "node ./
|
|
27
|
+
"setup": "node ./setup.js",
|
|
28
|
+
"release": "node ./setup.js publish"
|
|
28
29
|
}
|
|
29
30
|
}
|