@d5render/cli 0.0.91 → 0.1.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/.github/instructions/review.instructions.md +43 -0
- package/.github/instructions/severity.instructions.md +34 -0
- package/.skills/review/SKILL.md +9 -0
- package/.skills/review/version +1 -0
- package/CHANGELOG.md +9 -0
- package/README.md +44 -0
- package/bin/CHANGELOG.md +4 -0
- package/bin/copilot.js +418 -434
- package/bin/d5cli +273 -99
- package/package.json +13 -10
- package/copilot.config.js +0 -68
package/bin/copilot.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import process$1 from "node:process";
|
|
1
|
+
import process$1, { argv } from "node:process";
|
|
2
2
|
import { dirname, join } from "node:path";
|
|
3
3
|
import { fileURLToPath } from "node:url";
|
|
4
4
|
|
|
@@ -326,16 +326,16 @@ const makeIssue = (params) => {
|
|
|
326
326
|
path: fullPath,
|
|
327
327
|
message: issueData.message
|
|
328
328
|
};
|
|
329
|
-
let errorMessage
|
|
329
|
+
let errorMessage = "";
|
|
330
330
|
const maps = errorMaps.filter((m) => !!m).slice().reverse();
|
|
331
|
-
for (const map of maps) errorMessage
|
|
331
|
+
for (const map of maps) errorMessage = map(fullIssue, {
|
|
332
332
|
data,
|
|
333
|
-
defaultError: errorMessage
|
|
333
|
+
defaultError: errorMessage
|
|
334
334
|
}).message;
|
|
335
335
|
return {
|
|
336
336
|
...issueData,
|
|
337
337
|
path: fullPath,
|
|
338
|
-
message: errorMessage
|
|
338
|
+
message: errorMessage
|
|
339
339
|
};
|
|
340
340
|
};
|
|
341
341
|
function addIssueToContext(ctx, issueData) {
|
|
@@ -3631,7 +3631,7 @@ var $ZodEncodeError = class extends Error {
|
|
|
3631
3631
|
}
|
|
3632
3632
|
};
|
|
3633
3633
|
const globalConfig = {};
|
|
3634
|
-
function config
|
|
3634
|
+
function config(newConfig) {
|
|
3635
3635
|
if (newConfig) Object.assign(globalConfig, newConfig);
|
|
3636
3636
|
return globalConfig;
|
|
3637
3637
|
}
|
|
@@ -3924,12 +3924,12 @@ function prefixIssues(path, issues) {
|
|
|
3924
3924
|
function unwrapMessage(message) {
|
|
3925
3925
|
return typeof message === "string" ? message : message?.message;
|
|
3926
3926
|
}
|
|
3927
|
-
function finalizeIssue(iss, ctx, config$
|
|
3927
|
+
function finalizeIssue(iss, ctx, config$1) {
|
|
3928
3928
|
const full = {
|
|
3929
3929
|
...iss,
|
|
3930
3930
|
path: iss.path ?? []
|
|
3931
3931
|
};
|
|
3932
|
-
if (!iss.message) full.message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config$
|
|
3932
|
+
if (!iss.message) full.message = unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config$1.customError?.(iss)) ?? unwrapMessage(config$1.localeError?.(iss)) ?? "Invalid input";
|
|
3933
3933
|
delete full.inst;
|
|
3934
3934
|
delete full.continue;
|
|
3935
3935
|
if (!ctx?.reportInput) delete full.input;
|
|
@@ -4019,7 +4019,7 @@ const _parse = (_Err) => (schema, value, _ctx, _params) => {
|
|
|
4019
4019
|
}, ctx);
|
|
4020
4020
|
if (result instanceof Promise) throw new $ZodAsyncError();
|
|
4021
4021
|
if (result.issues.length) {
|
|
4022
|
-
const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
4022
|
+
const e = new (_params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
4023
4023
|
captureStackTrace(e, _params?.callee);
|
|
4024
4024
|
throw e;
|
|
4025
4025
|
}
|
|
@@ -4034,7 +4034,7 @@ const _parseAsync = (_Err) => async (schema, value, _ctx, params) => {
|
|
|
4034
4034
|
}, ctx);
|
|
4035
4035
|
if (result instanceof Promise) result = await result;
|
|
4036
4036
|
if (result.issues.length) {
|
|
4037
|
-
const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
4037
|
+
const e = new (params?.Err ?? _Err)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())));
|
|
4038
4038
|
captureStackTrace(e, params?.callee);
|
|
4039
4039
|
throw e;
|
|
4040
4040
|
}
|
|
@@ -4053,7 +4053,7 @@ const _safeParse = (_Err) => (schema, value, _ctx) => {
|
|
|
4053
4053
|
if (result instanceof Promise) throw new $ZodAsyncError();
|
|
4054
4054
|
return result.issues.length ? {
|
|
4055
4055
|
success: false,
|
|
4056
|
-
error: new (_Err ?? $ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
4056
|
+
error: new (_Err ?? $ZodError)(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
|
|
4057
4057
|
} : {
|
|
4058
4058
|
success: true,
|
|
4059
4059
|
data: result.value
|
|
@@ -4069,7 +4069,7 @@ const _safeParseAsync = (_Err) => async (schema, value, _ctx) => {
|
|
|
4069
4069
|
if (result instanceof Promise) result = await result;
|
|
4070
4070
|
return result.issues.length ? {
|
|
4071
4071
|
success: false,
|
|
4072
|
-
error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
4072
|
+
error: new _Err(result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
|
|
4073
4073
|
} : {
|
|
4074
4074
|
success: true,
|
|
4075
4075
|
data: result.value
|
|
@@ -5216,7 +5216,7 @@ function handleUnionResults(results, final, inst, ctx) {
|
|
|
5216
5216
|
code: "invalid_union",
|
|
5217
5217
|
input: final.value,
|
|
5218
5218
|
inst,
|
|
5219
|
-
errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
5219
|
+
errors: results.map((result) => result.issues.map((iss) => finalizeIssue(iss, ctx, config())))
|
|
5220
5220
|
});
|
|
5221
5221
|
return final;
|
|
5222
5222
|
}
|
|
@@ -5451,7 +5451,7 @@ const $ZodRecord = /* @__PURE__ */ $constructor("$ZodRecord", (inst, def$30) =>
|
|
|
5451
5451
|
payload.issues.push({
|
|
5452
5452
|
code: "invalid_key",
|
|
5453
5453
|
origin: "record",
|
|
5454
|
-
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
5454
|
+
issues: keyResult.issues.map((iss) => finalizeIssue(iss, ctx, config())),
|
|
5455
5455
|
input: key,
|
|
5456
5456
|
path: [key],
|
|
5457
5457
|
inst
|
|
@@ -5637,7 +5637,7 @@ const $ZodCatch = /* @__PURE__ */ $constructor("$ZodCatch", (inst, def$30) => {
|
|
|
5637
5637
|
if (result$1.issues.length) {
|
|
5638
5638
|
payload.value = def$30.catchValue({
|
|
5639
5639
|
...payload,
|
|
5640
|
-
error: { issues: result$1.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
5640
|
+
error: { issues: result$1.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
|
|
5641
5641
|
input: payload.value
|
|
5642
5642
|
});
|
|
5643
5643
|
payload.issues = [];
|
|
@@ -5648,7 +5648,7 @@ const $ZodCatch = /* @__PURE__ */ $constructor("$ZodCatch", (inst, def$30) => {
|
|
|
5648
5648
|
if (result.issues.length) {
|
|
5649
5649
|
payload.value = def$30.catchValue({
|
|
5650
5650
|
...payload,
|
|
5651
|
-
error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config
|
|
5651
|
+
error: { issues: result.issues.map((iss) => finalizeIssue(iss, ctx, config())) },
|
|
5652
5652
|
input: payload.value
|
|
5653
5653
|
});
|
|
5654
5654
|
payload.issues = [];
|
|
@@ -8839,21 +8839,21 @@ const ServerResultSchema = union([
|
|
|
8839
8839
|
CreateTaskResultSchema
|
|
8840
8840
|
]);
|
|
8841
8841
|
var McpError = class McpError extends Error {
|
|
8842
|
-
constructor(code, message, data) {
|
|
8843
|
-
super(`MCP error ${code}: ${message}`);
|
|
8844
|
-
this.code = code;
|
|
8842
|
+
constructor(code$1, message, data) {
|
|
8843
|
+
super(`MCP error ${code$1}: ${message}`);
|
|
8844
|
+
this.code = code$1;
|
|
8845
8845
|
this.data = data;
|
|
8846
8846
|
this.name = "McpError";
|
|
8847
8847
|
}
|
|
8848
8848
|
/**
|
|
8849
8849
|
* Factory method to create the appropriate error type based on the error code and data
|
|
8850
8850
|
*/
|
|
8851
|
-
static fromError(code, message, data) {
|
|
8852
|
-
if (code === ErrorCode.UrlElicitationRequired && data) {
|
|
8851
|
+
static fromError(code$1, message, data) {
|
|
8852
|
+
if (code$1 === ErrorCode.UrlElicitationRequired && data) {
|
|
8853
8853
|
const errorData = data;
|
|
8854
8854
|
if (errorData.elicitations) return new UrlElicitationRequiredError(errorData.elicitations, message);
|
|
8855
8855
|
}
|
|
8856
|
-
return new McpError(code, message, data);
|
|
8856
|
+
return new McpError(code$1, message, data);
|
|
8857
8857
|
}
|
|
8858
8858
|
};
|
|
8859
8859
|
/**
|
|
@@ -8951,16 +8951,16 @@ const getRefs = (options) => {
|
|
|
8951
8951
|
|
|
8952
8952
|
//#endregion
|
|
8953
8953
|
//#region node_modules/.pnpm/zod-to-json-schema@3.25.0_zod@4.1.13/node_modules/zod-to-json-schema/dist/esm/errorMessages.js
|
|
8954
|
-
function addErrorMessage(res, key, errorMessage
|
|
8954
|
+
function addErrorMessage(res, key, errorMessage, refs) {
|
|
8955
8955
|
if (!refs?.errorMessages) return;
|
|
8956
|
-
if (errorMessage
|
|
8956
|
+
if (errorMessage) res.errorMessage = {
|
|
8957
8957
|
...res.errorMessage,
|
|
8958
|
-
[key]: errorMessage
|
|
8958
|
+
[key]: errorMessage
|
|
8959
8959
|
};
|
|
8960
8960
|
}
|
|
8961
|
-
function setResponseValueAndErrors(res, key, value, errorMessage
|
|
8961
|
+
function setResponseValueAndErrors(res, key, value, errorMessage, refs) {
|
|
8962
8962
|
res[key] = value;
|
|
8963
|
-
addErrorMessage(res, key, errorMessage
|
|
8963
|
+
addErrorMessage(res, key, errorMessage, refs);
|
|
8964
8964
|
}
|
|
8965
8965
|
|
|
8966
8966
|
//#endregion
|
|
@@ -10076,8 +10076,8 @@ var Protocol = class {
|
|
|
10076
10076
|
this._requestResolvers.delete(requestId);
|
|
10077
10077
|
if (queuedMessage.type === "response") resolver(message);
|
|
10078
10078
|
else {
|
|
10079
|
-
const errorMessage
|
|
10080
|
-
resolver(new McpError(errorMessage
|
|
10079
|
+
const errorMessage = message;
|
|
10080
|
+
resolver(new McpError(errorMessage.error.code, errorMessage.error.message, errorMessage.error.data));
|
|
10081
10081
|
}
|
|
10082
10082
|
} else {
|
|
10083
10083
|
const messageType = queuedMessage.type === "response" ? "Response" : "Error";
|
|
@@ -10914,9 +10914,9 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10914
10914
|
};
|
|
10915
10915
|
exports.Name = Name;
|
|
10916
10916
|
var _Code = class extends _CodeOrName {
|
|
10917
|
-
constructor(code) {
|
|
10917
|
+
constructor(code$1) {
|
|
10918
10918
|
super();
|
|
10919
|
-
this._items = typeof code === "string" ? [code] : code;
|
|
10919
|
+
this._items = typeof code$1 === "string" ? [code$1] : code$1;
|
|
10920
10920
|
}
|
|
10921
10921
|
toString() {
|
|
10922
10922
|
return this.str;
|
|
@@ -10941,13 +10941,13 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10941
10941
|
exports._Code = _Code;
|
|
10942
10942
|
exports.nil = new _Code("");
|
|
10943
10943
|
function _(strs, ...args) {
|
|
10944
|
-
const code = [strs[0]];
|
|
10944
|
+
const code$1 = [strs[0]];
|
|
10945
10945
|
let i = 0;
|
|
10946
10946
|
while (i < args.length) {
|
|
10947
|
-
addCodeArg(code, args[i]);
|
|
10948
|
-
code.push(strs[++i]);
|
|
10947
|
+
addCodeArg(code$1, args[i]);
|
|
10948
|
+
code$1.push(strs[++i]);
|
|
10949
10949
|
}
|
|
10950
|
-
return new _Code(code);
|
|
10950
|
+
return new _Code(code$1);
|
|
10951
10951
|
}
|
|
10952
10952
|
exports._ = _;
|
|
10953
10953
|
const plus = new _Code("+");
|
|
@@ -10963,10 +10963,10 @@ var require_code$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
10963
10963
|
return new _Code(expr);
|
|
10964
10964
|
}
|
|
10965
10965
|
exports.str = str;
|
|
10966
|
-
function addCodeArg(code, arg) {
|
|
10967
|
-
if (arg instanceof _Code) code.push(...arg._items);
|
|
10968
|
-
else if (arg instanceof Name) code.push(arg);
|
|
10969
|
-
else code.push(interpolate(arg));
|
|
10966
|
+
function addCodeArg(code$1, arg) {
|
|
10967
|
+
if (arg instanceof _Code) code$1.push(...arg._items);
|
|
10968
|
+
else if (arg instanceof Name) code$1.push(arg);
|
|
10969
|
+
else code$1.push(interpolate(arg));
|
|
10970
10970
|
}
|
|
10971
10971
|
exports.addCodeArg = addCodeArg;
|
|
10972
10972
|
function optimize(expr) {
|
|
@@ -11139,7 +11139,7 @@ var require_scope = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11139
11139
|
}, usedValues, getCode);
|
|
11140
11140
|
}
|
|
11141
11141
|
_reduceValues(values, valueCode, usedValues = {}, getCode) {
|
|
11142
|
-
let code = code_1$12.nil;
|
|
11142
|
+
let code$1 = code_1$12.nil;
|
|
11143
11143
|
for (const prefix in values) {
|
|
11144
11144
|
const vs = values[prefix];
|
|
11145
11145
|
if (!vs) continue;
|
|
@@ -11150,13 +11150,13 @@ var require_scope = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11150
11150
|
let c = valueCode(name$1);
|
|
11151
11151
|
if (c) {
|
|
11152
11152
|
const def$30 = this.opts.es5 ? exports.varKinds.var : exports.varKinds.const;
|
|
11153
|
-
code = (0, code_1$12._)`${code}${def$30} ${name$1} = ${c};${this.opts._n}`;
|
|
11154
|
-
} else if (c = getCode === null || getCode === void 0 ? void 0 : getCode(name$1)) code = (0, code_1$12._)`${code}${c}${this.opts._n}`;
|
|
11153
|
+
code$1 = (0, code_1$12._)`${code$1}${def$30} ${name$1} = ${c};${this.opts._n}`;
|
|
11154
|
+
} else if (c = getCode === null || getCode === void 0 ? void 0 : getCode(name$1)) code$1 = (0, code_1$12._)`${code$1}${c}${this.opts._n}`;
|
|
11155
11155
|
else throw new ValueError(name$1);
|
|
11156
11156
|
nameSet.set(name$1, UsedValueState.Completed);
|
|
11157
11157
|
});
|
|
11158
11158
|
}
|
|
11159
|
-
return code;
|
|
11159
|
+
return code$1;
|
|
11160
11160
|
}
|
|
11161
11161
|
};
|
|
11162
11162
|
exports.ValueScope = ValueScope;
|
|
@@ -11345,9 +11345,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11345
11345
|
}
|
|
11346
11346
|
};
|
|
11347
11347
|
var AnyCode = class extends Node {
|
|
11348
|
-
constructor(code) {
|
|
11348
|
+
constructor(code$1) {
|
|
11349
11349
|
super();
|
|
11350
|
-
this.code = code;
|
|
11350
|
+
this.code = code$1;
|
|
11351
11351
|
}
|
|
11352
11352
|
render({ _n }) {
|
|
11353
11353
|
return `${this.code};` + _n;
|
|
@@ -11369,7 +11369,7 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11369
11369
|
this.nodes = nodes;
|
|
11370
11370
|
}
|
|
11371
11371
|
render(opts) {
|
|
11372
|
-
return this.nodes.reduce((code, n) => code + n.render(opts), "");
|
|
11372
|
+
return this.nodes.reduce((code$1, n) => code$1 + n.render(opts), "");
|
|
11373
11373
|
}
|
|
11374
11374
|
optimizeNodes() {
|
|
11375
11375
|
const { nodes } = this;
|
|
@@ -11411,9 +11411,9 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11411
11411
|
this.condition = condition;
|
|
11412
11412
|
}
|
|
11413
11413
|
render(opts) {
|
|
11414
|
-
let code = `if(${this.condition})` + super.render(opts);
|
|
11415
|
-
if (this.else) code += "else " + this.else.render(opts);
|
|
11416
|
-
return code;
|
|
11414
|
+
let code$1 = `if(${this.condition})` + super.render(opts);
|
|
11415
|
+
if (this.else) code$1 += "else " + this.else.render(opts);
|
|
11416
|
+
return code$1;
|
|
11417
11417
|
}
|
|
11418
11418
|
optimizeNodes() {
|
|
11419
11419
|
super.optimizeNodes();
|
|
@@ -11523,10 +11523,10 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11523
11523
|
Return.kind = "return";
|
|
11524
11524
|
var Try = class extends BlockNode {
|
|
11525
11525
|
render(opts) {
|
|
11526
|
-
let code = "try" + super.render(opts);
|
|
11527
|
-
if (this.catch) code += this.catch.render(opts);
|
|
11528
|
-
if (this.finally) code += this.finally.render(opts);
|
|
11529
|
-
return code;
|
|
11526
|
+
let code$1 = "try" + super.render(opts);
|
|
11527
|
+
if (this.catch) code$1 += this.catch.render(opts);
|
|
11528
|
+
if (this.finally) code$1 += this.finally.render(opts);
|
|
11529
|
+
return code$1;
|
|
11530
11530
|
}
|
|
11531
11531
|
optimizeNodes() {
|
|
11532
11532
|
var _a$1, _b;
|
|
@@ -11628,17 +11628,17 @@ var require_codegen = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
11628
11628
|
return this;
|
|
11629
11629
|
}
|
|
11630
11630
|
object(...keyValues) {
|
|
11631
|
-
const code = ["{"];
|
|
11631
|
+
const code$1 = ["{"];
|
|
11632
11632
|
for (const [key, value] of keyValues) {
|
|
11633
|
-
if (code.length > 1) code.push(",");
|
|
11634
|
-
code.push(key);
|
|
11633
|
+
if (code$1.length > 1) code$1.push(",");
|
|
11634
|
+
code$1.push(key);
|
|
11635
11635
|
if (key !== value || this.opts.es5) {
|
|
11636
|
-
code.push(":");
|
|
11637
|
-
(0, code_1$11.addCodeArg)(code, value);
|
|
11636
|
+
code$1.push(":");
|
|
11637
|
+
(0, code_1$11.addCodeArg)(code$1, value);
|
|
11638
11638
|
}
|
|
11639
11639
|
}
|
|
11640
|
-
code.push("}");
|
|
11641
|
-
return new code_1$11._Code(code);
|
|
11640
|
+
code$1.push("}");
|
|
11641
|
+
return new code_1$11._Code(code$1);
|
|
11642
11642
|
}
|
|
11643
11643
|
if(condition, thenBody, elseBody) {
|
|
11644
11644
|
this._blockNode(new If(condition));
|
|
@@ -13640,18 +13640,18 @@ var require_utils = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
|
13640
13640
|
*/
|
|
13641
13641
|
function stringArrayToHexStripped(input) {
|
|
13642
13642
|
let acc = "";
|
|
13643
|
-
let code = 0;
|
|
13643
|
+
let code$1 = 0;
|
|
13644
13644
|
let i = 0;
|
|
13645
13645
|
for (i = 0; i < input.length; i++) {
|
|
13646
|
-
code = input[i].charCodeAt(0);
|
|
13647
|
-
if (code === 48) continue;
|
|
13648
|
-
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) return "";
|
|
13646
|
+
code$1 = input[i].charCodeAt(0);
|
|
13647
|
+
if (code$1 === 48) continue;
|
|
13648
|
+
if (!(code$1 >= 48 && code$1 <= 57 || code$1 >= 65 && code$1 <= 70 || code$1 >= 97 && code$1 <= 102)) return "";
|
|
13649
13649
|
acc += input[i];
|
|
13650
13650
|
break;
|
|
13651
13651
|
}
|
|
13652
13652
|
for (i += 1; i < input.length; i++) {
|
|
13653
|
-
code = input[i].charCodeAt(0);
|
|
13654
|
-
if (!(code >= 48 && code <= 57 || code >= 65 && code <= 70 || code >= 97 && code <= 102)) return "";
|
|
13653
|
+
code$1 = input[i].charCodeAt(0);
|
|
13654
|
+
if (!(code$1 >= 48 && code$1 <= 57 || code$1 >= 65 && code$1 <= 70 || code$1 >= 97 && code$1 <= 102)) return "";
|
|
13655
13655
|
acc += input[i];
|
|
13656
13656
|
}
|
|
13657
13657
|
return acc;
|
|
@@ -16332,11 +16332,11 @@ var require_format$1 = /* @__PURE__ */ __commonJSMin(((exports) => {
|
|
|
16332
16332
|
}
|
|
16333
16333
|
}
|
|
16334
16334
|
function getFormat(fmtDef$1) {
|
|
16335
|
-
const code = fmtDef$1 instanceof RegExp ? (0, codegen_1$4.regexpCode)(fmtDef$1) : opts.code.formats ? (0, codegen_1$4._)`${opts.code.formats}${(0, codegen_1$4.getProperty)(schema)}` : void 0;
|
|
16335
|
+
const code$1 = fmtDef$1 instanceof RegExp ? (0, codegen_1$4.regexpCode)(fmtDef$1) : opts.code.formats ? (0, codegen_1$4._)`${opts.code.formats}${(0, codegen_1$4.getProperty)(schema)}` : void 0;
|
|
16336
16336
|
const fmt = gen.scopeValue("formats", {
|
|
16337
16337
|
key: schema,
|
|
16338
16338
|
ref: fmtDef$1,
|
|
16339
|
-
code
|
|
16339
|
+
code: code$1
|
|
16340
16340
|
});
|
|
16341
16341
|
if (typeof fmtDef$1 == "object" && !(fmtDef$1 instanceof RegExp)) return [
|
|
16342
16342
|
fmtDef$1.type || "string",
|
|
@@ -17379,23 +17379,23 @@ var Server = class extends Protocol {
|
|
|
17379
17379
|
const wrappedHandler = async (request, extra) => {
|
|
17380
17380
|
const validatedRequest = safeParse(CallToolRequestSchema, request);
|
|
17381
17381
|
if (!validatedRequest.success) {
|
|
17382
|
-
const errorMessage
|
|
17383
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage
|
|
17382
|
+
const errorMessage = validatedRequest.error instanceof Error ? validatedRequest.error.message : String(validatedRequest.error);
|
|
17383
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call request: ${errorMessage}`);
|
|
17384
17384
|
}
|
|
17385
17385
|
const { params } = validatedRequest.data;
|
|
17386
17386
|
const result = await Promise.resolve(handler(request, extra));
|
|
17387
17387
|
if (params.task) {
|
|
17388
17388
|
const taskValidationResult = safeParse(CreateTaskResultSchema, result);
|
|
17389
17389
|
if (!taskValidationResult.success) {
|
|
17390
|
-
const errorMessage
|
|
17391
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage
|
|
17390
|
+
const errorMessage = taskValidationResult.error instanceof Error ? taskValidationResult.error.message : String(taskValidationResult.error);
|
|
17391
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid task creation result: ${errorMessage}`);
|
|
17392
17392
|
}
|
|
17393
17393
|
return taskValidationResult.data;
|
|
17394
17394
|
}
|
|
17395
17395
|
const validationResult = safeParse(CallToolResultSchema, result);
|
|
17396
17396
|
if (!validationResult.success) {
|
|
17397
|
-
const errorMessage
|
|
17398
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage
|
|
17397
|
+
const errorMessage = validationResult.error instanceof Error ? validationResult.error.message : String(validationResult.error);
|
|
17398
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid tools/call result: ${errorMessage}`);
|
|
17399
17399
|
}
|
|
17400
17400
|
return validationResult.data;
|
|
17401
17401
|
};
|
|
@@ -17750,13 +17750,13 @@ var ExperimentalMcpServerTasks = class {
|
|
|
17750
17750
|
constructor(_mcpServer) {
|
|
17751
17751
|
this._mcpServer = _mcpServer;
|
|
17752
17752
|
}
|
|
17753
|
-
registerToolTask(name$1, config$
|
|
17753
|
+
registerToolTask(name$1, config$1, handler) {
|
|
17754
17754
|
const execution = {
|
|
17755
17755
|
taskSupport: "required",
|
|
17756
|
-
...config$
|
|
17756
|
+
...config$1.execution
|
|
17757
17757
|
};
|
|
17758
17758
|
if (execution.taskSupport === "forbidden") throw new Error(`Cannot register task-based tool '${name$1}' with taskSupport 'forbidden'. Use registerTool() instead.`);
|
|
17759
|
-
return this._mcpServer._createRegisteredTool(name$1, config$
|
|
17759
|
+
return this._mcpServer._createRegisteredTool(name$1, config$1.title, config$1.description, config$1.inputSchema, config$1.outputSchema, config$1.annotations, execution, config$1._meta, handler);
|
|
17760
17760
|
}
|
|
17761
17761
|
};
|
|
17762
17762
|
|
|
@@ -17866,11 +17866,11 @@ var McpServer = class {
|
|
|
17866
17866
|
* @param errorMessage - The error message.
|
|
17867
17867
|
* @returns The tool error result.
|
|
17868
17868
|
*/
|
|
17869
|
-
createToolError(errorMessage
|
|
17869
|
+
createToolError(errorMessage) {
|
|
17870
17870
|
return {
|
|
17871
17871
|
content: [{
|
|
17872
17872
|
type: "text",
|
|
17873
|
-
text: errorMessage
|
|
17873
|
+
text: errorMessage
|
|
17874
17874
|
}],
|
|
17875
17875
|
isError: true
|
|
17876
17876
|
};
|
|
@@ -17883,8 +17883,8 @@ var McpServer = class {
|
|
|
17883
17883
|
const inputObj = normalizeObjectSchema(tool.inputSchema);
|
|
17884
17884
|
const parseResult = await safeParseAsync(inputObj !== null && inputObj !== void 0 ? inputObj : tool.inputSchema, args);
|
|
17885
17885
|
if (!parseResult.success) {
|
|
17886
|
-
const errorMessage
|
|
17887
|
-
throw new McpError(ErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage
|
|
17886
|
+
const errorMessage = getParseErrorMessage("error" in parseResult ? parseResult.error : "Unknown error");
|
|
17887
|
+
throw new McpError(ErrorCode.InvalidParams, `Input validation error: Invalid arguments for tool ${toolName}: ${errorMessage}`);
|
|
17888
17888
|
}
|
|
17889
17889
|
return parseResult.data;
|
|
17890
17890
|
}
|
|
@@ -17898,8 +17898,8 @@ var McpServer = class {
|
|
|
17898
17898
|
if (!result.structuredContent) throw new McpError(ErrorCode.InvalidParams, `Output validation error: Tool ${toolName} has an output schema but no structured content was provided`);
|
|
17899
17899
|
const parseResult = await safeParseAsync(normalizeObjectSchema(tool.outputSchema), result.structuredContent);
|
|
17900
17900
|
if (!parseResult.success) {
|
|
17901
|
-
const errorMessage
|
|
17902
|
-
throw new McpError(ErrorCode.InvalidParams, `Output validation error: Invalid structured content for tool ${toolName}: ${errorMessage
|
|
17901
|
+
const errorMessage = getParseErrorMessage("error" in parseResult ? parseResult.error : "Unknown error");
|
|
17902
|
+
throw new McpError(ErrorCode.InvalidParams, `Output validation error: Invalid structured content for tool ${toolName}: ${errorMessage}`);
|
|
17903
17903
|
}
|
|
17904
17904
|
}
|
|
17905
17905
|
/**
|
|
@@ -18058,8 +18058,8 @@ var McpServer = class {
|
|
|
18058
18058
|
if (prompt.argsSchema) {
|
|
18059
18059
|
const parseResult = await safeParseAsync(normalizeObjectSchema(prompt.argsSchema), request.params.arguments);
|
|
18060
18060
|
if (!parseResult.success) {
|
|
18061
|
-
const errorMessage
|
|
18062
|
-
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for prompt ${request.params.name}: ${errorMessage
|
|
18061
|
+
const errorMessage = getParseErrorMessage("error" in parseResult ? parseResult.error : "Unknown error");
|
|
18062
|
+
throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for prompt ${request.params.name}: ${errorMessage}`);
|
|
18063
18063
|
}
|
|
18064
18064
|
const args = parseResult.data;
|
|
18065
18065
|
const cb = prompt.callback;
|
|
@@ -18090,16 +18090,16 @@ var McpServer = class {
|
|
|
18090
18090
|
return registeredResourceTemplate;
|
|
18091
18091
|
}
|
|
18092
18092
|
}
|
|
18093
|
-
registerResource(name$1, uriOrTemplate, config$
|
|
18093
|
+
registerResource(name$1, uriOrTemplate, config$1, readCallback) {
|
|
18094
18094
|
if (typeof uriOrTemplate === "string") {
|
|
18095
18095
|
if (this._registeredResources[uriOrTemplate]) throw new Error(`Resource ${uriOrTemplate} is already registered`);
|
|
18096
|
-
const registeredResource = this._createRegisteredResource(name$1, config$
|
|
18096
|
+
const registeredResource = this._createRegisteredResource(name$1, config$1.title, uriOrTemplate, config$1, readCallback);
|
|
18097
18097
|
this.setResourceRequestHandlers();
|
|
18098
18098
|
this.sendResourceListChanged();
|
|
18099
18099
|
return registeredResource;
|
|
18100
18100
|
} else {
|
|
18101
18101
|
if (this._registeredResourceTemplates[name$1]) throw new Error(`Resource template ${name$1} is already registered`);
|
|
18102
|
-
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name$1, config$
|
|
18102
|
+
const registeredResourceTemplate = this._createRegisteredResourceTemplate(name$1, config$1.title, uriOrTemplate, config$1, readCallback);
|
|
18103
18103
|
this.setResourceRequestHandlers();
|
|
18104
18104
|
this.sendResourceListChanged();
|
|
18105
18105
|
return registeredResourceTemplate;
|
|
@@ -18242,9 +18242,9 @@ var McpServer = class {
|
|
|
18242
18242
|
/**
|
|
18243
18243
|
* Registers a tool with a config object and callback.
|
|
18244
18244
|
*/
|
|
18245
|
-
registerTool(name$1, config$
|
|
18245
|
+
registerTool(name$1, config$1, cb) {
|
|
18246
18246
|
if (this._registeredTools[name$1]) throw new Error(`Tool ${name$1} is already registered`);
|
|
18247
|
-
const { title, description, inputSchema, outputSchema, annotations, _meta } = config$
|
|
18247
|
+
const { title, description, inputSchema, outputSchema, annotations, _meta } = config$1;
|
|
18248
18248
|
return this._createRegisteredTool(name$1, title, description, inputSchema, outputSchema, annotations, { taskSupport: "forbidden" }, _meta, cb);
|
|
18249
18249
|
}
|
|
18250
18250
|
prompt(name$1, ...rest) {
|
|
@@ -18262,9 +18262,9 @@ var McpServer = class {
|
|
|
18262
18262
|
/**
|
|
18263
18263
|
* Registers a prompt with a config object and callback.
|
|
18264
18264
|
*/
|
|
18265
|
-
registerPrompt(name$1, config$
|
|
18265
|
+
registerPrompt(name$1, config$1, cb) {
|
|
18266
18266
|
if (this._registeredPrompts[name$1]) throw new Error(`Prompt ${name$1} is already registered`);
|
|
18267
|
-
const { title, description, argsSchema } = config$
|
|
18267
|
+
const { title, description, argsSchema } = config$1;
|
|
18268
18268
|
const registeredPrompt = this._createRegisteredPrompt(name$1, title, description, argsSchema, cb);
|
|
18269
18269
|
this.setPromptRequestHandlers();
|
|
18270
18270
|
this.sendPromptListChanged();
|
|
@@ -18469,20 +18469,14 @@ var StdioServerTransport = class {
|
|
|
18469
18469
|
};
|
|
18470
18470
|
|
|
18471
18471
|
//#endregion
|
|
18472
|
-
//#region copilot
|
|
18472
|
+
//#region copilot/server/config.ts
|
|
18473
18473
|
const name = "d5_mcp_review_builtin";
|
|
18474
18474
|
const report = "report";
|
|
18475
18475
|
const getHash = "getHash";
|
|
18476
|
-
const errorMessage = "error: call mcp " + name;
|
|
18477
18476
|
const noMandatory = "dont't call under non-mandatory conditions";
|
|
18478
|
-
const file =
|
|
18479
|
-
const
|
|
18480
|
-
const
|
|
18481
|
-
let envJson = {};
|
|
18482
|
-
if (envArg) envJson = JSON.parse(envArg.replace("--customizenv=", ""));
|
|
18483
|
-
function toEnv(key, defaultValue = void 0) {
|
|
18484
|
-
return envJson[key] || process.env[key] || defaultValue;
|
|
18485
|
-
}
|
|
18477
|
+
const file = "./copilot.js";
|
|
18478
|
+
const serveFile = join(dirname(fileURLToPath(import.meta.url)), file);
|
|
18479
|
+
const envJson = buildEnv();
|
|
18486
18480
|
const envUsed = {
|
|
18487
18481
|
CI_SERVER_URL: toEnv("CI_SERVER_URL"),
|
|
18488
18482
|
CI_PROJECT_PATH: toEnv("CI_PROJECT_PATH"),
|
|
@@ -18490,8 +18484,6 @@ const envUsed = {
|
|
|
18490
18484
|
CI_PROJECT_NAME: toEnv("CI_PROJECT_NAME"),
|
|
18491
18485
|
CI_COMMIT_SHA: toEnv("CI_COMMIT_SHA"),
|
|
18492
18486
|
CI_COMMIT_BEFORE_SHA: toEnv("CI_COMMIT_BEFORE_SHA"),
|
|
18493
|
-
CI_COMMIT_AUTHOR: toEnv("CI_COMMIT_AUTHOR"),
|
|
18494
|
-
CI_COMMIT_AUTHOR_EMAIL: toEnv("CI_COMMIT_AUTHOR_EMAIL"),
|
|
18495
18487
|
CI_MERGE_REQUEST_IID: toEnv("CI_MERGE_REQUEST_IID"),
|
|
18496
18488
|
CI_MERGE_REQUEST_TITLE: toEnv("CI_MERGE_REQUEST_TITLE"),
|
|
18497
18489
|
CI_MERGE_REQUEST_DESCRIPTION: toEnv("CI_MERGE_REQUEST_DESCRIPTION"),
|
|
@@ -18503,21 +18495,33 @@ const envUsed = {
|
|
|
18503
18495
|
JIRA_USERNAME: toEnv("JIRA_USERNAME"),
|
|
18504
18496
|
JIRA_PASSWORD: toEnv("JIRA_PASSWORD")
|
|
18505
18497
|
};
|
|
18506
|
-
const
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
|
|
18498
|
+
const tools = [
|
|
18499
|
+
"--additional-mcp-config",
|
|
18500
|
+
JSON.stringify({ mcpServers: { [name]: {
|
|
18501
|
+
type: "local",
|
|
18502
|
+
command: "node",
|
|
18503
|
+
args: [serveFile, `--customizenv=${JSON.stringify(envUsed)}`],
|
|
18504
|
+
tools: ["*"]
|
|
18505
|
+
} } }),
|
|
18506
|
+
"--allow-all-tools",
|
|
18507
|
+
"--deny-tool",
|
|
18508
|
+
"write",
|
|
18509
|
+
"--deny-tool",
|
|
18510
|
+
"github-mcp-server"
|
|
18511
|
+
];
|
|
18512
|
+
function toEnv(key, defaultValue) {
|
|
18513
|
+
return envJson[key] || process.env[key] || defaultValue;
|
|
18514
|
+
}
|
|
18515
|
+
function buildEnv() {
|
|
18516
|
+
const envArg = argv.find((arg) => arg.startsWith("--customizenv="));
|
|
18517
|
+
let envJson$1 = {};
|
|
18518
|
+
if (envArg) envJson$1 = JSON.parse(envArg.replace("--customizenv=", ""));
|
|
18519
|
+
return envJson$1;
|
|
18520
|
+
}
|
|
18512
18521
|
|
|
18513
18522
|
//#endregion
|
|
18514
|
-
//#region packages/gitlab/
|
|
18515
|
-
|
|
18516
|
-
const canireviewSchema = {
|
|
18517
|
-
hash: string().describe("commit hash"),
|
|
18518
|
-
B: string().describe("the commit directions logged by `git log --format=%B -n 1 <hash>`")
|
|
18519
|
-
};
|
|
18520
|
-
function commonHeaders$1() {
|
|
18523
|
+
//#region packages/gitlab/url.ts
|
|
18524
|
+
function buildHeaders() {
|
|
18521
18525
|
const headers = new Headers();
|
|
18522
18526
|
headers.set("Content-Type", "application/json");
|
|
18523
18527
|
const { GITLAB_TOKEN = "" } = envUsed;
|
|
@@ -18525,123 +18529,48 @@ function commonHeaders$1() {
|
|
|
18525
18529
|
else headers.set("Authorization", `Bearer ${GITLAB_TOKEN}`);
|
|
18526
18530
|
return headers;
|
|
18527
18531
|
}
|
|
18528
|
-
const
|
|
18532
|
+
const pipelineMerge = () => {
|
|
18529
18533
|
const { CI_MERGE_REQUEST_IID, CI_PROJECT_ID, CI_SERVER_URL } = envUsed;
|
|
18530
18534
|
if (CI_MERGE_REQUEST_IID && CI_PROJECT_ID && CI_SERVER_URL) return `${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/merge_requests/${CI_MERGE_REQUEST_IID}`;
|
|
18531
18535
|
};
|
|
18532
|
-
const
|
|
18536
|
+
const visitCommit = () => {
|
|
18533
18537
|
const { CI_PROJECT_PATH, CI_SERVER_URL } = envUsed;
|
|
18534
18538
|
if (CI_PROJECT_PATH && CI_SERVER_URL) return `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/commit`;
|
|
18535
18539
|
};
|
|
18536
|
-
|
|
18540
|
+
function visitPipeline(mid) {
|
|
18541
|
+
const { CI_SERVER_URL, CI_PROJECT_PATH, CI_MERGE_REQUEST_IID = mid, CI_COMMIT_SHA } = envUsed;
|
|
18542
|
+
if (!CI_SERVER_URL || !CI_PROJECT_PATH) return {};
|
|
18543
|
+
if (CI_MERGE_REQUEST_IID) return {
|
|
18544
|
+
url: `${CI_SERVER_URL}/${CI_PROJECT_PATH}/-/merge_requests/${CI_MERGE_REQUEST_IID}`,
|
|
18545
|
+
type: "merge_request"
|
|
18546
|
+
};
|
|
18547
|
+
if (CI_COMMIT_SHA) return {
|
|
18548
|
+
url: `${visitCommit()}/${CI_COMMIT_SHA}`,
|
|
18549
|
+
type: "commit"
|
|
18550
|
+
};
|
|
18551
|
+
return {};
|
|
18552
|
+
}
|
|
18553
|
+
const commits = () => {
|
|
18537
18554
|
const { CI_PROJECT_ID, CI_SERVER_URL } = envUsed;
|
|
18538
18555
|
if (CI_PROJECT_ID && CI_SERVER_URL) return `${CI_SERVER_URL}/api/v4/projects/${CI_PROJECT_ID}/repository/commits`;
|
|
18539
18556
|
};
|
|
18540
18557
|
|
|
18541
|
-
//#endregion
|
|
18542
|
-
//#region packages/gitlab/comments.ts
|
|
18543
|
-
const lastComment = { value: {} };
|
|
18544
|
-
const postComments = (report$1) => {
|
|
18545
|
-
const url = commonMergeURL();
|
|
18546
|
-
const { title = "代码审查报告", summary, severityIssues = [], mainRisks = [], nextActions = [] } = report$1;
|
|
18547
|
-
if (severityIssues.length === 0) return Promise.resolve({ content: [{
|
|
18548
|
-
type: "text",
|
|
18549
|
-
text: "✅ GitLab MCP Report 执行完成,无问题"
|
|
18550
|
-
}] });
|
|
18551
|
-
let message = `## 📖 ${title}\n`;
|
|
18552
|
-
if (summary) message += `> ${summary}\n\n`;
|
|
18553
|
-
const commitTasks = [];
|
|
18554
|
-
const commitsURL = commonCommitURl();
|
|
18555
|
-
const filesMap = /* @__PURE__ */ new Map();
|
|
18556
|
-
const commits = /* @__PURE__ */ new Set();
|
|
18557
|
-
for (const issue$1 of severityIssues) {
|
|
18558
|
-
const { file: file$1 = "", severity = "NON", commitSha = "", line: line$1 = "", details = [], suggestions = [], codeExample = "" } = issue$1;
|
|
18559
|
-
const usedSha = commitSha || "NON";
|
|
18560
|
-
const usedFile = file$1 || "NON";
|
|
18561
|
-
const list = filesMap.get(usedFile) || [];
|
|
18562
|
-
list.push(issue$1);
|
|
18563
|
-
filesMap.set(usedFile, list);
|
|
18564
|
-
commits.add(usedSha);
|
|
18565
|
-
if (commitsURL && commitSha) {
|
|
18566
|
-
const lines = line$1.split(",").map((line$2) => {
|
|
18567
|
-
const str$1 = line$2.trim().split("-");
|
|
18568
|
-
const num = Number.parseInt(str$1[str$1.length - 1], 10);
|
|
18569
|
-
return Number.isNaN(num) ? void 0 : num;
|
|
18570
|
-
}).filter((v) => v !== void 0);
|
|
18571
|
-
if (file$1) commitTasks.push(() => fetch(`${commitsURL}/${commitSha}/comments`, {
|
|
18572
|
-
method: "POST",
|
|
18573
|
-
headers: commonHeaders$1(),
|
|
18574
|
-
body: JSON.stringify({
|
|
18575
|
-
note: `**${severity}:** ${file$1}\n\n**问题:**\n\n - ${details.join("\n - ")}\n\n-------\n\n**修正建议:**\n - ${suggestions.join("\n - ")}${codeExample ? `\n------\n\n**代码示例:**\n${toCode(codeExample)}\n` : ""}`,
|
|
18576
|
-
path: file$1,
|
|
18577
|
-
line: lines.length > 0 ? lines[lines.length - 1] : void 0,
|
|
18578
|
-
line_type: "new"
|
|
18579
|
-
})
|
|
18580
|
-
}));
|
|
18581
|
-
}
|
|
18582
|
-
}
|
|
18583
|
-
if (mainRisks.length > 0) message += "\n**📋 主要风险**\n - " + mainRisks.join("\n - ");
|
|
18584
|
-
const linkBase = commonCommitPage();
|
|
18585
|
-
message += `\n### 🐛 问题列表`;
|
|
18586
|
-
const cms = [...commits].map((v) => {
|
|
18587
|
-
if (v === "NON") return;
|
|
18588
|
-
return `[${v.slice(0, 8)}](${linkBase}/${v})`;
|
|
18589
|
-
}).filter((v) => v !== void 0);
|
|
18590
|
-
if (cms.length > 0) message += `\n-----\n> 含问题的commits:${cms.join(",")}\n\n`;
|
|
18591
|
-
for (const [file$1, issues] of filesMap) {
|
|
18592
|
-
message += `\n-----\n\n#### 文件: ${file$1}`;
|
|
18593
|
-
for (const issue$1 of issues) {
|
|
18594
|
-
const { severity = "NON", line: line$1 = "NON", title: title$1 = "NON", details = [], suggestions = [], codeExample = "" } = issue$1;
|
|
18595
|
-
message += `\n\n**${severity}** | ${line$1} | ${title$1}`;
|
|
18596
|
-
message += `\n- 详情:\n - ${details.join("\n - ")}`;
|
|
18597
|
-
message += `\n- 建议:\n - ${suggestions.join("\n - ")}`;
|
|
18598
|
-
if (codeExample) message += `\n${toCode(codeExample)}\n`;
|
|
18599
|
-
}
|
|
18600
|
-
}
|
|
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
|
-
}] });
|
|
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) => {
|
|
18611
|
-
lastComment.value = res;
|
|
18612
|
-
return { content: [{
|
|
18613
|
-
type: "text",
|
|
18614
|
-
text: "✅ GitLab 代码审查报告已发布。"
|
|
18615
|
-
}] };
|
|
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
|
-
}));
|
|
18623
|
-
};
|
|
18624
|
-
function toCode(code) {
|
|
18625
|
-
const ct = code.trim();
|
|
18626
|
-
return ct.startsWith("```") && ct.endsWith("```") ? code : `\`\`\`\n${code}\n\`\`\``;
|
|
18627
|
-
}
|
|
18628
|
-
|
|
18629
18558
|
//#endregion
|
|
18630
18559
|
//#region packages/gitlab/commit.ts
|
|
18631
18560
|
const getCommits = () => {
|
|
18632
18561
|
const { CI_COMMIT_SHA, CI_COMMIT_BEFORE_SHA } = envUsed;
|
|
18633
|
-
const url =
|
|
18634
|
-
if (url) return fetch(`${url}/commits`, { headers:
|
|
18562
|
+
const url = pipelineMerge();
|
|
18563
|
+
if (url) return fetch(`${url}/commits`, { headers: buildHeaders() }).then((res) => {
|
|
18635
18564
|
if (!res.ok) throw new Error("");
|
|
18636
18565
|
return res.json();
|
|
18637
|
-
}).then((commits) => ({ content: [{
|
|
18566
|
+
}).then((commits$1) => ({ content: [{
|
|
18638
18567
|
type: "text",
|
|
18639
18568
|
description: "commits from `merge pipeline`",
|
|
18640
|
-
text: `${commits.map((commit) => commit.id).join(",")}, the above review is from \`merge pipeline\` commits.`
|
|
18569
|
+
text: `${commits$1.map((commit) => commit.id).join(",")}, the above review is from \`merge pipeline\` commits.`
|
|
18641
18570
|
}] })).catch((error$1) => ({
|
|
18642
18571
|
content: [{
|
|
18643
18572
|
type: "text",
|
|
18644
|
-
text:
|
|
18573
|
+
text: "error" + error$1.message ? ", reason: " + error$1.message || "请求GitLab API失败" : ""
|
|
18645
18574
|
}],
|
|
18646
18575
|
isError: true
|
|
18647
18576
|
}));
|
|
@@ -18668,15 +18597,23 @@ const getMergeInfomation = () => {
|
|
|
18668
18597
|
return {
|
|
18669
18598
|
content: [{
|
|
18670
18599
|
type: "text",
|
|
18671
|
-
text: ""
|
|
18600
|
+
text: "error"
|
|
18672
18601
|
}],
|
|
18673
18602
|
isError: true
|
|
18674
18603
|
};
|
|
18675
18604
|
};
|
|
18676
18605
|
|
|
18677
18606
|
//#endregion
|
|
18678
|
-
//#region packages/gitlab/
|
|
18679
|
-
|
|
18607
|
+
//#region packages/gitlab/schema.ts
|
|
18608
|
+
const canireview = "can-i-review";
|
|
18609
|
+
const canireviewSchema = {
|
|
18610
|
+
hash: string().describe("commit hash"),
|
|
18611
|
+
B: string().describe("the commit directions logged by `git log --format=%B -n 1 <hash>`")
|
|
18612
|
+
};
|
|
18613
|
+
|
|
18614
|
+
//#endregion
|
|
18615
|
+
//#region packages/gitlab/index.ts
|
|
18616
|
+
function install(server$1) {
|
|
18680
18617
|
server$1.registerTool(getHash, { description: noMandatory }, getCommits);
|
|
18681
18618
|
server$1.registerTool(canireview, {
|
|
18682
18619
|
inputSchema: canireviewSchema,
|
|
@@ -18689,222 +18626,7 @@ function installGitlab(server$1) {
|
|
|
18689
18626
|
}
|
|
18690
18627
|
|
|
18691
18628
|
//#endregion
|
|
18692
|
-
//#region packages/
|
|
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
|
-
|
|
18735
|
-
//#endregion
|
|
18736
|
-
//#region packages/builtin/dingding.ts
|
|
18737
|
-
const postComments$1 = (report$1) => {
|
|
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;
|
|
18739
|
-
if (!DINGTALK_WEBHOOK) return { content: [{
|
|
18740
|
-
type: "text",
|
|
18741
|
-
text: "✅ 无 DingDing Webhook 配置,跳过推送。"
|
|
18742
|
-
}] };
|
|
18743
|
-
const { title = "代码审查报告", mainRisks = [], relatedJIRAs = [], severityIssues = [] } = report$1;
|
|
18744
|
-
if (severityIssues.length === 0) return { content: [{
|
|
18745
|
-
type: "text",
|
|
18746
|
-
text: "✅ 无问题,跳过DingDing推送。"
|
|
18747
|
-
}] };
|
|
18748
|
-
let { url, type } = commonURL();
|
|
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}>` : ""}`;
|
|
18750
|
-
if (type) {
|
|
18751
|
-
const { value = {} } = lastComment;
|
|
18752
|
-
let { id: note = "" } = value || {};
|
|
18753
|
-
note = note ? `#note_${note}` : "";
|
|
18754
|
-
message += `${type === "merge_request" ? `
|
|
18755
|
-
|
|
18756
|
-
**合并**:[${CI_MERGE_REQUEST_IID}](${url}${note})` : `
|
|
18757
|
-
|
|
18758
|
-
**提交**:[${CI_COMMIT_SHA?.slice(0, 8)}](${url})`}`;
|
|
18759
|
-
}
|
|
18760
|
-
const issuesMap = /* @__PURE__ */ new Map(), commitsMap = /* @__PURE__ */ new Map();
|
|
18761
|
-
for (const element of severityIssues) {
|
|
18762
|
-
const { severity = "NON", commitSha = "NON" } = element;
|
|
18763
|
-
const list = issuesMap.get(severity) || [];
|
|
18764
|
-
list.push(element);
|
|
18765
|
-
issuesMap.set(severity, list);
|
|
18766
|
-
commitsMap.set(commitSha, element);
|
|
18767
|
-
}
|
|
18768
|
-
const linkBase = commonCommitPage();
|
|
18769
|
-
message += `\n> 含问题的commits:${[...commitsMap.keys()].map((v) => `[${v.slice(0, 8)}](${linkBase}/${v})`).join(", ")}\n\n-----\n`;
|
|
18770
|
-
message += "\n#### 🐛 问题列表\n";
|
|
18771
|
-
let bugLength = 0, maxBugLength = 5;
|
|
18772
|
-
for (const [severity, issues] of issuesMap) {
|
|
18773
|
-
if (bugLength > maxBugLength) break;
|
|
18774
|
-
message += `\n\n**${severity}**`;
|
|
18775
|
-
for (const issue$1 of issues) {
|
|
18776
|
-
if (bugLength > maxBugLength) {
|
|
18777
|
-
message += `\n\n\n...以及其他 ${severityIssues.length - bugLength} 个问题,[详见报告](${url})`;
|
|
18778
|
-
break;
|
|
18779
|
-
}
|
|
18780
|
-
const { title: title$1 = "NON", commitSha = "", file: file$1 = "NON", line: line$1 = "NON" } = issue$1;
|
|
18781
|
-
const shortSha = (commitSha || "").slice(0, 8);
|
|
18782
|
-
const commitLink = linkBase && commitSha ? `${linkBase}/${commitSha}` : void 0;
|
|
18783
|
-
message += `\n- ${commitLink ? `[${shortSha}](${commitLink}) ` : shortSha}: ${title$1}\n\n - file: ${file$1}\n\n - line: ${line$1}`;
|
|
18784
|
-
bugLength++;
|
|
18785
|
-
}
|
|
18786
|
-
}
|
|
18787
|
-
message += "\n\n\n\n#### 🚩 提交列表";
|
|
18788
|
-
let hashLength = 0;
|
|
18789
|
-
for (const [_$1, issue$1] of commitsMap) {
|
|
18790
|
-
if (hashLength > 9) {
|
|
18791
|
-
message += `\n...以及其他 ${commitsMap.size - hashLength} 个提交,[详见报告](${url})`;
|
|
18792
|
-
break;
|
|
18793
|
-
}
|
|
18794
|
-
const { commitTitle = "NON", commitSha = "" } = issue$1;
|
|
18795
|
-
const shortSha = (commitSha || "").slice(0, 8);
|
|
18796
|
-
const commitLink = linkBase && commitSha ? `${linkBase}/${commitSha}` : void 0;
|
|
18797
|
-
message += `\n\n${commitLink ? `[${shortSha}](${commitLink})` : `${shortSha}`}: ${commitTitle}`;
|
|
18798
|
-
hashLength++;
|
|
18799
|
-
}
|
|
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")}`;
|
|
18801
|
-
return fetch(DINGTALK_WEBHOOK, {
|
|
18802
|
-
method: "POST",
|
|
18803
|
-
headers: { "Content-Type": "application/json" },
|
|
18804
|
-
body: JSON.stringify({
|
|
18805
|
-
msgtype: "markdown",
|
|
18806
|
-
markdown: {
|
|
18807
|
-
title,
|
|
18808
|
-
text: message
|
|
18809
|
-
},
|
|
18810
|
-
at: {
|
|
18811
|
-
atMobiles: ["17856104313"],
|
|
18812
|
-
isAtAll: false
|
|
18813
|
-
}
|
|
18814
|
-
})
|
|
18815
|
-
}).then((response) => {
|
|
18816
|
-
if (!response.ok) throw new Error("");
|
|
18817
|
-
return response.json();
|
|
18818
|
-
}).then((res) => {
|
|
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
|
-
}] };
|
|
18827
|
-
throw new Error("Post comments to DingTalk with error code:" + res.errcode + ", message: " + res.errmsg);
|
|
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
|
-
}));
|
|
18835
|
-
};
|
|
18836
|
-
|
|
18837
|
-
//#endregion
|
|
18838
|
-
//#region packages/builtin/prompt.ts
|
|
18839
|
-
const getPrompt = () => ({ content: [{
|
|
18840
|
-
type: "text",
|
|
18841
|
-
description: "default review suggestions",
|
|
18842
|
-
text: `1. **MUST** Take the file as the review target:
|
|
18843
|
-
- The focus of this review is on the content involved in the diff but the evaluation dimensions need to be based on the file content.
|
|
18844
|
-
- When the diff in the discrepancy report differs from the document content, the diff is only used as a line number reference.
|
|
18845
|
-
- The actual content that needs to be reviewed should be **based on the document content**.
|
|
18846
|
-
2. Establish context by **reading relevant files**, files that are **imported/used by** the diff files or are **structurally neighboring** them (e.g., related configuration or test files).
|
|
18847
|
-
3. **Ensure the relationship diagram of the diff is complete:**
|
|
18848
|
-
- After establishing the context, analyze the complete context of the difference code to ensure a relatively complete code relationship diagram can be built.
|
|
18849
|
-
- If the content is incomplete, supplement the context and rebuild the relationship diagram.
|
|
18850
|
-
4. Read the commit message as the basic understanding of the current change
|
|
18851
|
-
5. Determine technology the repository belongs, draw upon your understanding of that technology, provide recommendations on cutting-edge technologies and best practices:
|
|
18852
|
-
- **Consult the workspace introduction** yourself.
|
|
18853
|
-
- Consult cutting-edge industry documentation yourself.
|
|
18854
|
-
6. **Execute as many relevant commands as possible to enrich your context.**
|
|
18855
|
-
7. **Prioritize Analysis Focus**:
|
|
18856
|
-
- For all collected code, meticulously trace the logic to uncover functional bugs and correctness issues.
|
|
18857
|
-
- Pay attention to the **correctness** of the analytical logic, the **efficiency** of the code, and its **long-term maintainability**.
|
|
18858
|
-
- Concentrate your deepest analysis on the application code (non-test files).
|
|
18859
|
-
- Actively consider edge cases, off-by-one errors, race conditions, and improper null/error handling.
|
|
18860
|
-
- **focusing on major errors**, identify potential bugs, architectural impact, security vulnerabilities, performance bottlenecks, and clarity issues.
|
|
18861
|
-
8. **Maintain skepticism but verify carefully**:
|
|
18862
|
-
- Gather as much context as possible for the code you suspect, raise questions only after **ensuring you have a sufficient understanding** of the business logic.
|
|
18863
|
-
- If doubts persist even after establishing a complete context, lower the severity rating of the issue.
|
|
18864
|
-
9. **Further summary report:**
|
|
18865
|
-
- **Tone/Content:** **DO NOT** add comments that:
|
|
18866
|
-
- Tell the user to "check," "confirm," "verify," or "ensure" something.
|
|
18867
|
-
- Explain what the code change does or validate its purpose.
|
|
18868
|
-
- Explain the code to the author (they are assumed to know their own code).
|
|
18869
|
-
- Comment on missing trailing newlines or other purely stylistic issues that do not affect code execution or readability in a meaningful way.
|
|
18870
|
-
- **Technical Detail:**
|
|
18871
|
-
- Pay **meticulous attention to line numbers and indentation** in code suggestions; they **must** be correct and match the surrounding code.
|
|
18872
|
-
- **NEVER** comment on license headers, copyright headers, or anything related to future dates/versions (e.g., "this date is in the future").
|
|
18873
|
-
- **NEVER** comment on the presence or absence of comments in the code.
|
|
18874
|
-
- **Formatting/Structure:**
|
|
18875
|
-
- Keep the **change summary** concise (aim for a single sentence).
|
|
18876
|
-
- Keep **comment bodies concise** and focused on a single issue.
|
|
18877
|
-
- When similar issues occur frequently, please review the code to determine if it meets the change objectives.`
|
|
18878
|
-
}] });
|
|
18879
|
-
|
|
18880
|
-
//#endregion
|
|
18881
|
-
//#region packages/builtin/server.ts
|
|
18882
|
-
function install(server$1) {
|
|
18883
|
-
installGitlab(server$1);
|
|
18884
|
-
server$1.registerTool("default_review_requirements", { description: "default review suggestions" }, getPrompt);
|
|
18885
|
-
server$1.registerTool(report, {
|
|
18886
|
-
description: noMandatory,
|
|
18887
|
-
inputSchema: reportSchema
|
|
18888
|
-
}, async (...args) => {
|
|
18889
|
-
const git = await postComments(...args);
|
|
18890
|
-
const ding = await postComments$1(...args);
|
|
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
|
-
};
|
|
18898
|
-
return { content: [{
|
|
18899
|
-
type: "text",
|
|
18900
|
-
text: args[0]?.summary || ""
|
|
18901
|
-
}] };
|
|
18902
|
-
});
|
|
18903
|
-
}
|
|
18904
|
-
|
|
18905
|
-
//#endregion
|
|
18906
|
-
//#region packages/jira/config.ts
|
|
18907
|
-
const jiraSchema = { key: string().describe("JIRA task number such as `FUS-123`") };
|
|
18629
|
+
//#region packages/jira/url.ts
|
|
18908
18630
|
function commonHeaders() {
|
|
18909
18631
|
const headers = new Headers();
|
|
18910
18632
|
headers.set("Accept", "application/json");
|
|
@@ -18954,7 +18676,11 @@ const getIssue = (request) => {
|
|
|
18954
18676
|
};
|
|
18955
18677
|
|
|
18956
18678
|
//#endregion
|
|
18957
|
-
//#region packages/jira/
|
|
18679
|
+
//#region packages/jira/schema.ts
|
|
18680
|
+
const jiraSchema = { key: string().describe("JIRA task number such as `FUS-123`") };
|
|
18681
|
+
|
|
18682
|
+
//#endregion
|
|
18683
|
+
//#region packages/jira/index.ts
|
|
18958
18684
|
function install$1(server$1) {
|
|
18959
18685
|
server$1.registerTool("get_jira_context", {
|
|
18960
18686
|
title: "get jira context",
|
|
@@ -18964,13 +18690,271 @@ function install$1(server$1) {
|
|
|
18964
18690
|
}
|
|
18965
18691
|
|
|
18966
18692
|
//#endregion
|
|
18967
|
-
//#region packages/
|
|
18693
|
+
//#region packages/message/props.ts
|
|
18694
|
+
const one = "If it can be explained in one sentence, then passing in one entry is sufficient.";
|
|
18695
|
+
const code = {
|
|
18696
|
+
file: string().optional().describe("The file path where the issue is found"),
|
|
18697
|
+
line: string().optional().describe("Line number, e.g., '1-345' pr '205' or '17,35', **must** provide the line of final file"),
|
|
18698
|
+
codeExample: string().optional().describe(`Code modification suggestions, recommended to use code in diff format, like: \`\`\`
|
|
18699
|
+
while (condition) {
|
|
18700
|
+
unchanged line;
|
|
18701
|
+
- remove this;
|
|
18702
|
+
+ replace it with this;
|
|
18703
|
+
+ and this;
|
|
18704
|
+
but keep this the same;
|
|
18705
|
+
}\`\`\`.`)
|
|
18706
|
+
};
|
|
18707
|
+
const reportSchema = {
|
|
18708
|
+
title: string().describe("Please describe the problem in the shortest possible way."),
|
|
18709
|
+
summary: array(string().describe(one)).optional().describe("Regarding the description of the current review, please summarize the main logic of the submission as concisely as possible."),
|
|
18710
|
+
issues: array(object({
|
|
18711
|
+
severity: string().optional().describe("Bug severity levels, such as CRITICAL, HIGH, MEDIUM, LOW."),
|
|
18712
|
+
commitAuthor: string().optional().describe("The commit author associated with the issue"),
|
|
18713
|
+
commitSha: string().optional().describe("The commit SHA associated with the issue"),
|
|
18714
|
+
commitTitle: string().optional().describe("The commit title associated with the issue"),
|
|
18715
|
+
title: string().optional().describe("A short title for the issue"),
|
|
18716
|
+
details: array(string()).optional().describe("Details about the issue"),
|
|
18717
|
+
suggestions: array(string()).optional().describe("Improvement suggestion"),
|
|
18718
|
+
...code
|
|
18719
|
+
})).optional().describe("List all bugs, order by 'severity' from heaviest to lightest."),
|
|
18720
|
+
jiras: array(object({
|
|
18721
|
+
key: string().describe("JIRA issue key, e.g., 'FUS-123'"),
|
|
18722
|
+
summary: string().describe("Summary of the JIRA issue")
|
|
18723
|
+
}).describe("Related JIRA issues")).optional().describe("List of related JIRA issues"),
|
|
18724
|
+
risks: array(string().describe(one).describe("A short summary of the risk")).optional().describe("After summarizing all the bugs, identify the main risks that could potentially impact the business."),
|
|
18725
|
+
suggestions: array(object({
|
|
18726
|
+
details: array(string().describe(one)).describe("Improvement suggestion"),
|
|
18727
|
+
example: object(code).optional().describe("Pass in when you feel it is necessary to provide code.")
|
|
18728
|
+
})).optional().describe("After summarizing all the issues, other code snippets that deserve correction.")
|
|
18729
|
+
};
|
|
18730
|
+
|
|
18731
|
+
//#endregion
|
|
18732
|
+
//#region packages/message/dingding.ts
|
|
18733
|
+
function send(title, text) {
|
|
18734
|
+
if (!envUsed.DINGTALK_WEBHOOK) return Promise.reject(/* @__PURE__ */ new Error("non DINGTALK_WEBHOOK"));
|
|
18735
|
+
const urls = envUsed.DINGTALK_WEBHOOK.split(",");
|
|
18736
|
+
return Promise.all(urls.map((url) => fetch(url, {
|
|
18737
|
+
method: "POST",
|
|
18738
|
+
headers: { "Content-Type": "application/json" },
|
|
18739
|
+
body: JSON.stringify({
|
|
18740
|
+
msgtype: "markdown",
|
|
18741
|
+
markdown: {
|
|
18742
|
+
title,
|
|
18743
|
+
text
|
|
18744
|
+
},
|
|
18745
|
+
at: {
|
|
18746
|
+
atMobiles: ["17856104313"],
|
|
18747
|
+
isAtAll: false
|
|
18748
|
+
}
|
|
18749
|
+
})
|
|
18750
|
+
})));
|
|
18751
|
+
}
|
|
18752
|
+
|
|
18753
|
+
//#endregion
|
|
18754
|
+
//#region packages/message/report.ts
|
|
18755
|
+
const lastComment = { value: {} };
|
|
18756
|
+
const schemaGitlabPipeline = "gitlab_pipeline";
|
|
18757
|
+
const schemaGitlabCommit = "gitlab_commit";
|
|
18758
|
+
const schemaDingdingTalk = "dingding_talk";
|
|
18759
|
+
function distReports(input) {
|
|
18760
|
+
const gitlabReport = {
|
|
18761
|
+
title: schemaGitlabPipeline,
|
|
18762
|
+
report: [() => Promise.resolve(void 0)]
|
|
18763
|
+
};
|
|
18764
|
+
const gitlabCommitReport = {
|
|
18765
|
+
title: schemaGitlabCommit,
|
|
18766
|
+
report: [() => Promise.resolve(void 0)]
|
|
18767
|
+
};
|
|
18768
|
+
const dingdingReport = {
|
|
18769
|
+
title: schemaDingdingTalk,
|
|
18770
|
+
report: [() => Promise.resolve(void 0)]
|
|
18771
|
+
};
|
|
18772
|
+
const { title = "代码审查报告", summary = [], issues = [], jiras = [], risks = [], suggestions = [] } = input;
|
|
18773
|
+
const result = [
|
|
18774
|
+
gitlabCommitReport,
|
|
18775
|
+
gitlabReport,
|
|
18776
|
+
dingdingReport
|
|
18777
|
+
];
|
|
18778
|
+
if (issues.length === 0 && suggestions.length === 0) {
|
|
18779
|
+
gitlabReport.report = [];
|
|
18780
|
+
gitlabCommitReport.report = [];
|
|
18781
|
+
dingdingReport.report = [];
|
|
18782
|
+
return result;
|
|
18783
|
+
}
|
|
18784
|
+
const { CI_PROJECT_NAME = "", CI_COMMIT_SHA = "", JIRA_BASE_URL, CI_MERGE_REQUEST_IID, DINGTALK_WEBHOOK } = envUsed;
|
|
18785
|
+
const fileMap = /* @__PURE__ */ new Map();
|
|
18786
|
+
const severityMap = /* @__PURE__ */ new Map();
|
|
18787
|
+
const commitsSet = /* @__PURE__ */ new Set();
|
|
18788
|
+
const commitsMap = /* @__PURE__ */ new Map();
|
|
18789
|
+
const commitComments = [];
|
|
18790
|
+
const mergeURL = pipelineMerge();
|
|
18791
|
+
const linkBase = visitCommit();
|
|
18792
|
+
const commitsURL = commits();
|
|
18793
|
+
for (const issue$1 of issues) {
|
|
18794
|
+
const { file: file$1 = "NON", commitSha = "", severity = "NON", commitSha: NCommitSha = "NON" } = issue$1;
|
|
18795
|
+
const fileList = fileMap.get(file$1) || [], issueList = severityMap.get(severity) || [];
|
|
18796
|
+
fileList.push(issue$1);
|
|
18797
|
+
fileMap.set(file$1, fileList);
|
|
18798
|
+
issueList.push(issue$1);
|
|
18799
|
+
severityMap.set(severity, issueList);
|
|
18800
|
+
if (commitSha) commitsSet.add(commitSha);
|
|
18801
|
+
commitsMap.set(NCommitSha, issue$1);
|
|
18802
|
+
distCommitComments(issue$1);
|
|
18803
|
+
}
|
|
18804
|
+
let gitlabReportMessage = `## 📖 ${title}\n`;
|
|
18805
|
+
if (summary && summary.length > 0) gitlabReportMessage += `> ${summary.join(" \n> ")}\n\n`;
|
|
18806
|
+
if (risks.length > 0) gitlabReportMessage += "\n**📋 主要风险**\n - " + risks.join("\n - ");
|
|
18807
|
+
gitlabReportMessage += `\n### 🐛 问题列表`;
|
|
18808
|
+
const cms = [...commitsSet].map((v) => `[${v.slice(0, 8)}](${linkBase}/${v})`);
|
|
18809
|
+
if (cms.length > 0) gitlabReportMessage += `\n-----\n> 含问题的commits:${cms.join(",")}\n\n`;
|
|
18810
|
+
function distCommitComments({ file: file$1, commitSha, severity = "NON", line: line$1 = "", details = [], suggestions: suggestions$1 = [], codeExample = "" }) {
|
|
18811
|
+
if (commitSha && file$1) {
|
|
18812
|
+
const lines = line$1.split(",").map((line$2) => {
|
|
18813
|
+
const str$1 = line$2.trim().split("-");
|
|
18814
|
+
const num = Number.parseInt(str$1[str$1.length - 1], 10);
|
|
18815
|
+
return Number.isNaN(num) ? void 0 : num;
|
|
18816
|
+
}).filter((v) => v !== void 0);
|
|
18817
|
+
commitComments.push({
|
|
18818
|
+
sha: commitSha,
|
|
18819
|
+
file: file$1,
|
|
18820
|
+
line: lines.length > 0 ? lines[lines.length - 1] : void 0,
|
|
18821
|
+
note: `**${severity}:** ${file$1}\n\n**问题:**\n\n - ${details.join("\n - ")}\n\n-------\n\n**修正建议:**\n - ${suggestions$1.join("\n - ")}${codeExample ? `\n------\n\n**代码示例:**\n${toCode(codeExample)}\n` : ""}`
|
|
18822
|
+
});
|
|
18823
|
+
}
|
|
18824
|
+
}
|
|
18825
|
+
for (const [file$1, fileIssues] of fileMap) {
|
|
18826
|
+
gitlabReportMessage += `\n-----\n\n#### 文件: ${file$1}`;
|
|
18827
|
+
for (const issue$1 of fileIssues) {
|
|
18828
|
+
const { severity = "NON", line: line$1 = "NON", title: issueTitle = "NON", details = [], suggestions: issueSuggestions = [], codeExample = "" } = issue$1;
|
|
18829
|
+
gitlabReportMessage += `\n\n**${severity}** | ${line$1} | ${issueTitle}`;
|
|
18830
|
+
gitlabReportMessage += `\n- 详情:\n - ${details.join("\n - ")}`;
|
|
18831
|
+
gitlabReportMessage += `\n- 建议:\n - ${issueSuggestions.join("\n - ")}`;
|
|
18832
|
+
if (codeExample) gitlabReportMessage += `\n${toCode(codeExample)}\n`;
|
|
18833
|
+
}
|
|
18834
|
+
}
|
|
18835
|
+
if (suggestions.length > 0) {
|
|
18836
|
+
gitlabReportMessage += "\n\n### 📈 其他建议\n\n-----\n";
|
|
18837
|
+
let withNoFile = "", withFile = "";
|
|
18838
|
+
for (const suggestion of suggestions) {
|
|
18839
|
+
const { details = [], example } = suggestion;
|
|
18840
|
+
const { file: file$1 = "", line: line$1 = "", codeExample = "" } = example || {};
|
|
18841
|
+
if (file$1) {
|
|
18842
|
+
withFile += `\n-----\n\n#### 文件: ${file$1}`;
|
|
18843
|
+
if (line$1) withFile += `\n- 行数:${line$1}`;
|
|
18844
|
+
withFile += `\n- 详情:\n - ${details.join("\n - ")}`;
|
|
18845
|
+
if (codeExample) withFile += `\n${toCode(codeExample)}\n`;
|
|
18846
|
+
} else withNoFile += `\n - ${details.join("\n - ")}`;
|
|
18847
|
+
}
|
|
18848
|
+
gitlabReportMessage += withNoFile + withFile;
|
|
18849
|
+
}
|
|
18850
|
+
let dingdingReportMessage = "";
|
|
18851
|
+
if (DINGTALK_WEBHOOK) {
|
|
18852
|
+
dingdingReportMessage = `### 📖 ${title}\n\n**共计**:${issues.length}个问题\n\n${risks.length > 0 ? "**主要风险**:\n\n" + risks.join("\n\n") + "\n\n" : "\n\n"}-----\n\n**项目名**:${CI_PROJECT_NAME}`;
|
|
18853
|
+
const { url, type } = visitPipeline();
|
|
18854
|
+
if (type) {
|
|
18855
|
+
const { value = {} } = lastComment;
|
|
18856
|
+
let { id: note = "" } = value || {};
|
|
18857
|
+
note = note ? `#note_${note}` : "";
|
|
18858
|
+
dingdingReportMessage += `${type === "merge_request" ? `
|
|
18859
|
+
|
|
18860
|
+
**合并**:[${CI_MERGE_REQUEST_IID}](${url}${note})` : `
|
|
18861
|
+
|
|
18862
|
+
**提交**:[${CI_COMMIT_SHA.slice(0, 8)}](${url})`}`;
|
|
18863
|
+
}
|
|
18864
|
+
dingdingReportMessage += `\n\n含问题的commits:${[...commitsMap.keys()].map((v) => `[${v.slice(0, 8)}](${linkBase}/${v})`).join(", ")}\n\n-----\n`;
|
|
18865
|
+
dingdingReportMessage += "\n#### 🐞 问题列表\n";
|
|
18866
|
+
let bugLength = 0;
|
|
18867
|
+
const maxBugLength = 5;
|
|
18868
|
+
for (const [severity, severityIssues] of severityMap) {
|
|
18869
|
+
if (bugLength > maxBugLength) break;
|
|
18870
|
+
dingdingReportMessage += `\n\n**${severity}**`;
|
|
18871
|
+
for (const issue$1 of severityIssues) {
|
|
18872
|
+
if (bugLength > maxBugLength) {
|
|
18873
|
+
dingdingReportMessage += `\n\n\n...以及其他 ${issues.length - bugLength} 个问题,[详见报告](${url})`;
|
|
18874
|
+
break;
|
|
18875
|
+
}
|
|
18876
|
+
const { title: issueTitle = "NON", commitSha = "", file: file$1 = "NON", line: line$1 = "NON", commitAuthor = "" } = issue$1;
|
|
18877
|
+
const shortSha = (commitSha || "").slice(0, 8);
|
|
18878
|
+
const commitLink = linkBase && commitSha ? `${linkBase}/${commitSha}` : void 0;
|
|
18879
|
+
dingdingReportMessage += `\n- ${issueTitle}\n\n - hash: ${commitLink ? `[${shortSha}](${commitLink}) ` : shortSha}\n\n - author: ${commitAuthor}\n\n - file: ${file$1}\n\n - line: ${line$1}`;
|
|
18880
|
+
bugLength++;
|
|
18881
|
+
}
|
|
18882
|
+
}
|
|
18883
|
+
if (jiras.length > 0) dingdingReportMessage += `\n\n\n\n#### 🔗 关联 JIRA\n ${jiras.map((v) => `[${v.key}](${JIRA_BASE_URL}/browse/${v.key}): ${v.summary}`).join("\n\n")}`;
|
|
18884
|
+
}
|
|
18885
|
+
gitlabCommitReport.report = commitsURL ? commitComments.map(({ sha, file: file$1, line: line$1, note }) => () => fetch(`${commitsURL}/${sha}/comments`, {
|
|
18886
|
+
method: "POST",
|
|
18887
|
+
headers: buildHeaders(),
|
|
18888
|
+
body: JSON.stringify({
|
|
18889
|
+
note,
|
|
18890
|
+
path: file$1,
|
|
18891
|
+
line: line$1,
|
|
18892
|
+
line_type: "new"
|
|
18893
|
+
})
|
|
18894
|
+
})) : [];
|
|
18895
|
+
gitlabReport.report = mergeURL ? [() => fetch(mergeURL + `/notes`, {
|
|
18896
|
+
method: "POST",
|
|
18897
|
+
headers: buildHeaders(),
|
|
18898
|
+
body: JSON.stringify({ body: gitlabReportMessage })
|
|
18899
|
+
}).then((res) => res.json()).then((res) => {
|
|
18900
|
+
lastComment.value = res;
|
|
18901
|
+
})] : CI_COMMIT_SHA ? [() => fetch(`${commitsURL}/${CI_COMMIT_SHA}/comments`, {
|
|
18902
|
+
method: "POST",
|
|
18903
|
+
headers: buildHeaders(),
|
|
18904
|
+
body: JSON.stringify({
|
|
18905
|
+
note: gitlabReportMessage,
|
|
18906
|
+
line_type: "new"
|
|
18907
|
+
})
|
|
18908
|
+
}).then((res) => res.json()).then((res) => {
|
|
18909
|
+
lastComment.value = res;
|
|
18910
|
+
})] : [() => Promise.reject(/* @__PURE__ */ new Error("⚠️ 当前为 push 事件,无合并请求,无法在 GitLab 中发布报告。报告内容已生成但未发布。"))];
|
|
18911
|
+
dingdingReport.report = DINGTALK_WEBHOOK ? [() => send(title, dingdingReportMessage).then((response) => {
|
|
18912
|
+
if (!response.ok) throw new Error(response.statusText);
|
|
18913
|
+
return response.json();
|
|
18914
|
+
}).then((res) => {
|
|
18915
|
+
if (res.errcode === 0) return;
|
|
18916
|
+
if (res.errcode === 31e4) return;
|
|
18917
|
+
throw new Error("Post comments to DingTalk with error code:" + res.errcode + ", message: " + res.errmsg);
|
|
18918
|
+
})] : [];
|
|
18919
|
+
return result;
|
|
18920
|
+
}
|
|
18921
|
+
async function runReport(input) {
|
|
18922
|
+
let results = [];
|
|
18923
|
+
for (const item of input) results.push(await Promise.all(item.report.map((task) => task())).then(() => item).catch((error$2) => ({
|
|
18924
|
+
title: item.title,
|
|
18925
|
+
error: error$2.message || "未知错误"
|
|
18926
|
+
})));
|
|
18927
|
+
const error$1 = results.find((v) => v.error);
|
|
18928
|
+
return error$1 ? error$1.error : "✅ GitLab MCP Report 执行完成,无问题";
|
|
18929
|
+
}
|
|
18930
|
+
function toCode(code$1) {
|
|
18931
|
+
const ct = code$1.trim();
|
|
18932
|
+
return ct.startsWith("```") && ct.endsWith("```") ? code$1 : `\`\`\`\n${code$1}\n\`\`\``;
|
|
18933
|
+
}
|
|
18934
|
+
|
|
18935
|
+
//#endregion
|
|
18936
|
+
//#region packages/message/index.ts
|
|
18937
|
+
function install$2(server$1) {
|
|
18938
|
+
server$1.registerTool(report, {
|
|
18939
|
+
description: noMandatory,
|
|
18940
|
+
inputSchema: reportSchema
|
|
18941
|
+
}, async (input) => {
|
|
18942
|
+
return { content: [{
|
|
18943
|
+
type: "text",
|
|
18944
|
+
text: await runReport(distReports(input))
|
|
18945
|
+
}] };
|
|
18946
|
+
});
|
|
18947
|
+
}
|
|
18948
|
+
|
|
18949
|
+
//#endregion
|
|
18950
|
+
//#region copilot/server/index.ts
|
|
18968
18951
|
const server = new McpServer({
|
|
18969
18952
|
name,
|
|
18970
18953
|
version: "1.0.0"
|
|
18971
18954
|
});
|
|
18972
18955
|
install(server);
|
|
18973
18956
|
install$1(server);
|
|
18957
|
+
install$2(server);
|
|
18974
18958
|
server.connect(new StdioServerTransport());
|
|
18975
18959
|
|
|
18976
18960
|
//#endregion
|