smart-commit-copilot-cli 0.1.12 → 0.1.14
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/CHANGELOG.md +35 -0
- package/README.md +90 -10
- package/docs/configuration.md +93 -17
- package/docs/contracts.md +106 -2
- package/docs/getting-started.md +18 -1
- package/docs/integrations.md +2 -0
- package/docs/publish.md +1 -1
- package/docs/release-checklist.md +1 -1
- package/docs/releases/0.1.13-draft.md +63 -0
- package/docs/releases/0.1.14-draft.md +94 -0
- package/docs/releases/0.1.8-draft.md +3 -3
- package/docs/verification.md +7 -0
- package/examples/config/smart-commit.json +19 -5
- package/out/cli.js +7 -1
- package/out/cli.js.map +1 -1
- package/out/cliApp.js +102 -8
- package/out/cliApp.js.map +1 -1
- package/out/commands/bridge.js +3 -3
- package/out/commands/bridge.js.map +1 -1
- package/out/commands/commitMessage.js +239 -0
- package/out/commands/commitMessage.js.map +1 -0
- package/out/commands/pullRequest.js +3 -3
- package/out/commands/pullRequest.js.map +1 -1
- package/out/commands/pullRequestReview.js +220 -0
- package/out/commands/pullRequestReview.js.map +1 -0
- package/out/commands/report.js +96 -18
- package/out/commands/report.js.map +1 -1
- package/out/config/cliArgs.js +96 -21
- package/out/config/cliArgs.js.map +1 -1
- package/out/config/env.js +68 -28
- package/out/config/env.js.map +1 -1
- package/out/config/file.js +456 -11
- package/out/config/file.js.map +1 -1
- package/out/config/index.js +5 -1
- package/out/config/index.js.map +1 -1
- package/out/config/legacySmartCommit.js +120 -14
- package/out/config/legacySmartCommit.js.map +1 -1
- package/out/config/merge.js +27 -11
- package/out/config/merge.js.map +1 -1
- package/out/config/schema.js +57 -7
- package/out/config/schema.js.map +1 -1
- package/out/contracts.js +244 -11
- package/out/contracts.js.map +1 -1
- package/out/git.js +101 -0
- package/out/git.js.map +1 -1
- package/out/localization.js +106 -0
- package/out/localization.js.map +1 -0
- package/out/passHistory/index.js +1 -1
- package/out/passHistory/index.js.map +1 -1
- package/out/pullRequest/api.js +39 -26
- package/out/pullRequest/api.js.map +1 -1
- package/out/pullRequest/config.js +36 -2
- package/out/pullRequest/config.js.map +1 -1
- package/out/pullRequest/index.js +6 -0
- package/out/pullRequest/index.js.map +1 -1
- package/out/pullRequest/mergeGate.js +34 -0
- package/out/pullRequest/mergeGate.js.map +1 -0
- package/out/pullRequest/platform.js +13 -0
- package/out/pullRequest/platform.js.map +1 -1
- package/out/pullRequest/reviewApi.js +424 -0
- package/out/pullRequest/reviewApi.js.map +1 -0
- package/out/pullRequest/reviewComment.js +176 -0
- package/out/pullRequest/reviewComment.js.map +1 -0
- package/out/pullRequest/reviewGate.js +43 -0
- package/out/pullRequest/reviewGate.js.map +1 -0
- package/out/pullRequest/reviewWorkflow.js +313 -0
- package/out/pullRequest/reviewWorkflow.js.map +1 -0
- package/out/pullRequest/urlParser.js +135 -0
- package/out/pullRequest/urlParser.js.map +1 -0
- package/out/pullRequest/workflow.js +17 -4
- package/out/pullRequest/workflow.js.map +1 -1
- package/out/renderOutput.js +59 -0
- package/out/renderOutput.js.map +1 -1
- package/out/reporting/aggregate.js +1 -1
- package/out/reporting/aggregate.js.map +1 -1
- package/out/reporting/index.js +2 -2
- package/out/reporting/index.js.map +1 -1
- package/out/reporting/render.js +5 -1
- package/out/reporting/render.js.map +1 -1
- package/out/reporting/timeWindow.js +52 -2
- package/out/reporting/timeWindow.js.map +1 -1
- package/out/reporting/types.js.map +1 -1
- package/out/review/chunkAggregate.js +53 -0
- package/out/review/chunkAggregate.js.map +1 -0
- package/out/review/detailLocator.js +19 -12
- package/out/review/detailLocator.js.map +1 -1
- package/out/review/diffReviewRunner.js +191 -0
- package/out/review/diffReviewRunner.js.map +1 -0
- package/out/review/index.js +12 -45
- package/out/review/index.js.map +1 -1
- package/out/review/mockProvider.js +55 -44
- package/out/review/mockProvider.js.map +1 -1
- package/out/review/openaiProvider.js +31 -20
- package/out/review/openaiProvider.js.map +1 -1
- package/out/review/parser.js +39 -2
- package/out/review/parser.js.map +1 -1
- package/out/review/prompt.js +180 -8
- package/out/review/prompt.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.shouldPublishInlineComments = shouldPublishInlineComments;
|
|
4
|
+
exports.shouldPublishSummaryComment = shouldPublishSummaryComment;
|
|
5
|
+
/**
|
|
6
|
+
* Decides whether inline review comments should be published for the current run.
|
|
7
|
+
*
|
|
8
|
+
* Inline comments are disabled entirely when no comment severities are configured
|
|
9
|
+
* (an empty array means "never add inline comments"), and are skipped after a passing
|
|
10
|
+
* review when pullRequestReview.skipCommentOnPass is enabled. When the review does not pass,
|
|
11
|
+
* inline comments are always published (subject to the severity filter).
|
|
12
|
+
*/
|
|
13
|
+
function shouldPublishInlineComments(config, passed, onLog) {
|
|
14
|
+
if (config.commentSeverities.length === 0) {
|
|
15
|
+
onLog?.("[PR][REVIEW][INFO] Inline comments disabled: pullRequestReview.commentSeverities is empty ([]).");
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
if (passed && config.skipCommentOnPass) {
|
|
19
|
+
onLog?.("[PR][REVIEW][INFO] Inline comments skipped: review passed and pullRequestReview.skipCommentOnPass is true.");
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Decides whether the summary comment should be published for the current run.
|
|
26
|
+
*
|
|
27
|
+
* The summary comment is disabled entirely when no summary severities are configured
|
|
28
|
+
* (an empty array means "never add the summary"), and is skipped after a passing review
|
|
29
|
+
* when pullRequestReview.skipSummaryOnPass is enabled. When the review does not pass, the
|
|
30
|
+
* summary comment is always published.
|
|
31
|
+
*/
|
|
32
|
+
function shouldPublishSummaryComment(config, passed, onLog) {
|
|
33
|
+
if (config.summarySeverities.length === 0) {
|
|
34
|
+
onLog?.("[PR][REVIEW][INFO] Summary comment disabled: pullRequestReview.summarySeverities is empty ([]).");
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (passed && config.skipSummaryOnPass) {
|
|
38
|
+
onLog?.("[PR][REVIEW][INFO] Summary comment skipped: review passed and pullRequestReview.skipSummaryOnPass is true.");
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
return true;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=reviewGate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewGate.js","sourceRoot":"","sources":["../../src/pullRequest/reviewGate.ts"],"names":[],"mappings":";;AAYA,kEAgBC;AAUD,kEAgBC;AAlDD;;;;;;;GAOG;AACH,SAAgB,2BAA2B,CACzC,MAAmC,EACnC,MAAe,EACf,KAAiC;IAEjC,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,KAAK,EAAE,CAAC,iGAAiG,CAAC,CAAC;QAC3G,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACvC,KAAK,EAAE,CACL,4GAA4G,CAC7G,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,SAAgB,2BAA2B,CACzC,MAAmC,EACnC,MAAe,EACf,KAAiC;IAEjC,IAAI,MAAM,CAAC,iBAAiB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1C,KAAK,EAAE,CAAC,iGAAiG,CAAC,CAAC;QAC3G,OAAO,KAAK,CAAC;IACf,CAAC;IACD,IAAI,MAAM,IAAI,MAAM,CAAC,iBAAiB,EAAE,CAAC;QACvC,KAAK,EAAE,CACL,4GAA4G,CAC7G,CAAC;QACF,OAAO,KAAK,CAAC;IACf,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reviewPullRequest = reviewPullRequest;
|
|
4
|
+
const localization_1 = require("../localization");
|
|
5
|
+
const review_1 = require("../review");
|
|
6
|
+
const parser_1 = require("../review/parser");
|
|
7
|
+
const config_1 = require("./config");
|
|
8
|
+
const mergeGate_1 = require("./mergeGate");
|
|
9
|
+
const reviewGate_1 = require("./reviewGate");
|
|
10
|
+
const reviewComment_1 = require("./reviewComment");
|
|
11
|
+
const reviewApi_1 = require("./reviewApi");
|
|
12
|
+
const urlParser_1 = require("./urlParser");
|
|
13
|
+
async function reviewPullRequest(input) {
|
|
14
|
+
(0, config_1.validatePullRequestReviewConfig)(input.config);
|
|
15
|
+
const reviewConfig = input.config.pullRequestReview;
|
|
16
|
+
const parsed = (0, urlParser_1.parsePullRequestUrl)(input.url, input.config.pullRequest.provider, input.config.pullRequest.apiBaseUrl);
|
|
17
|
+
const platform = parsed.platform;
|
|
18
|
+
const itemLabel = platform.kind === "github" ? "pull request" : "merge request";
|
|
19
|
+
input.onLog?.(`[PR][REVIEW][INFO] Target: ${platform.kind} ${platform.projectPath} #${parsed.number} (${platform.htmlBaseUrl}).`);
|
|
20
|
+
const apiInput = {
|
|
21
|
+
platform,
|
|
22
|
+
number: parsed.number,
|
|
23
|
+
authToken: input.config.pullRequest.authToken,
|
|
24
|
+
timeoutMs: input.config.connection.requestTimeoutMs,
|
|
25
|
+
signal: input.signal
|
|
26
|
+
};
|
|
27
|
+
input.onProgress?.("Identifying the authenticated user...");
|
|
28
|
+
const currentUser = await (0, reviewApi_1.getCurrentUser)(apiInput);
|
|
29
|
+
input.onLog?.(`[PR][REVIEW][INFO] Authenticated as: ${currentUser || "(unknown)"}.`);
|
|
30
|
+
input.onProgress?.(`Loading ${itemLabel} details...`);
|
|
31
|
+
const details = await (0, reviewApi_1.getPullRequestDetails)(apiInput);
|
|
32
|
+
if (details.isMerged) {
|
|
33
|
+
throw new Error(`The ${itemLabel} #${parsed.number} is already merged; review was skipped.`);
|
|
34
|
+
}
|
|
35
|
+
if (!details.isOpen) {
|
|
36
|
+
throw new Error(`The ${itemLabel} #${parsed.number} is not open (state: ${details.state || "unknown"}); review was skipped.`);
|
|
37
|
+
}
|
|
38
|
+
logPullRequestDetails(input, details);
|
|
39
|
+
input.onProgress?.(`Loading ${itemLabel} diff...`);
|
|
40
|
+
const diff = await (0, reviewApi_1.getPullRequestDiff)(apiInput);
|
|
41
|
+
if (!diff.trim()) {
|
|
42
|
+
throw new Error(`No diff content was found for ${itemLabel} #${parsed.number}.`);
|
|
43
|
+
}
|
|
44
|
+
input.onLog?.(`[PR][REVIEW][INFO] Diff loaded: ${diff.length} chars.`);
|
|
45
|
+
input.onProgress?.("Reviewing the diff with the model...");
|
|
46
|
+
const result = await (0, review_1.runReviewExecution)({
|
|
47
|
+
repositoryPath: input.repositoryPath,
|
|
48
|
+
commitMessage: `Reviewing ${itemLabel} #${parsed.number}: ${details.title || "(no title)"}`,
|
|
49
|
+
diff,
|
|
50
|
+
changedFiles: [],
|
|
51
|
+
reviewLanguage: input.config.review.language,
|
|
52
|
+
threshold: reviewConfig.threshold,
|
|
53
|
+
skillPromptTuning: reviewConfig.skillPromptTuning || undefined,
|
|
54
|
+
maxDiffChars: input.config.review.maxDiffChars,
|
|
55
|
+
inlineAnchoring: true
|
|
56
|
+
}, {
|
|
57
|
+
config: input.config,
|
|
58
|
+
provider: input.provider,
|
|
59
|
+
onLog: input.onLog
|
|
60
|
+
});
|
|
61
|
+
const reviewMode = result.reviewMode ?? "single";
|
|
62
|
+
const summarySource = result.summarySource ?? "direct";
|
|
63
|
+
const passed = result.decision === "pass";
|
|
64
|
+
logReviewOutcome(input, result, reviewConfig.threshold, passed, {
|
|
65
|
+
reviewMode,
|
|
66
|
+
chunkCount: result.chunkCount,
|
|
67
|
+
summarySource
|
|
68
|
+
});
|
|
69
|
+
const warnings = [];
|
|
70
|
+
if (input.dryRun) {
|
|
71
|
+
input.onLog?.("[PR][REVIEW][INFO] Dry-run enabled: provider comments, approve, and merge actions were skipped.");
|
|
72
|
+
return {
|
|
73
|
+
platform: platform.kind,
|
|
74
|
+
number: parsed.number,
|
|
75
|
+
title: details.title,
|
|
76
|
+
webUrl: details.webUrl,
|
|
77
|
+
isDraft: details.isDraft,
|
|
78
|
+
score: result.score,
|
|
79
|
+
threshold: reviewConfig.threshold,
|
|
80
|
+
passed,
|
|
81
|
+
reviewMode,
|
|
82
|
+
chunkCount: result.chunkCount,
|
|
83
|
+
summarySource,
|
|
84
|
+
result,
|
|
85
|
+
summaryCommentAction: "skipped",
|
|
86
|
+
inlineCommentAction: "skipped",
|
|
87
|
+
inlinePosted: 0,
|
|
88
|
+
inlineSkipped: 0,
|
|
89
|
+
inlineFailed: 0,
|
|
90
|
+
inlineUnanchored: 0,
|
|
91
|
+
approve: { attempted: false, performed: false, detail: "skipped (dry-run)" },
|
|
92
|
+
merge: { attempted: false, performed: false, detail: "skipped (dry-run)" },
|
|
93
|
+
warnings
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
let inlineStats = { posted: 0, skipped: 0, failed: 0, unanchored: 0 };
|
|
97
|
+
let inlineCommentAction = "skipped";
|
|
98
|
+
if ((0, reviewGate_1.shouldPublishInlineComments)(reviewConfig, passed, input.onLog)) {
|
|
99
|
+
input.onProgress?.("Publishing inline comments...");
|
|
100
|
+
inlineStats = await publishInlineComments(input, apiInput, details, result, warnings);
|
|
101
|
+
inlineCommentAction = "published";
|
|
102
|
+
}
|
|
103
|
+
input.onProgress?.("Evaluating approve and merge actions...");
|
|
104
|
+
const approve = await runApproveStep(input, apiInput, details, currentUser, passed, warnings);
|
|
105
|
+
const merge = await runMergeStep(input, apiInput, details, currentUser, passed, approve, warnings);
|
|
106
|
+
let summaryCommentAction = "skipped";
|
|
107
|
+
if ((0, reviewGate_1.shouldPublishSummaryComment)(reviewConfig, passed, input.onLog)) {
|
|
108
|
+
input.onProgress?.("Publishing the summary comment...");
|
|
109
|
+
summaryCommentAction = await upsertSummaryComment(input, apiInput, result, passed, approve, merge, warnings);
|
|
110
|
+
}
|
|
111
|
+
for (const warning of warnings) {
|
|
112
|
+
input.onLog?.(`[PR][REVIEW][WARN] ${warning}`);
|
|
113
|
+
}
|
|
114
|
+
return {
|
|
115
|
+
platform: platform.kind,
|
|
116
|
+
number: parsed.number,
|
|
117
|
+
title: details.title,
|
|
118
|
+
webUrl: details.webUrl,
|
|
119
|
+
isDraft: details.isDraft,
|
|
120
|
+
score: result.score,
|
|
121
|
+
threshold: reviewConfig.threshold,
|
|
122
|
+
passed,
|
|
123
|
+
reviewMode,
|
|
124
|
+
chunkCount: result.chunkCount,
|
|
125
|
+
summarySource,
|
|
126
|
+
result,
|
|
127
|
+
summaryCommentAction,
|
|
128
|
+
inlineCommentAction,
|
|
129
|
+
inlinePosted: inlineStats.posted,
|
|
130
|
+
inlineSkipped: inlineStats.skipped,
|
|
131
|
+
inlineFailed: inlineStats.failed,
|
|
132
|
+
inlineUnanchored: inlineStats.unanchored,
|
|
133
|
+
approve,
|
|
134
|
+
merge,
|
|
135
|
+
warnings
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
async function publishInlineComments(input, apiInput, details, result, warnings) {
|
|
139
|
+
const stats = { posted: 0, skipped: 0, failed: 0, unanchored: 0 };
|
|
140
|
+
const severityMatched = (0, reviewComment_1.filterDetailsBySeverities)(result.details, input.config.pullRequestReview.commentSeverities);
|
|
141
|
+
const inlineDetails = severityMatched.filter((detail) => Boolean(detail.filePath) && detail.lineNumber !== undefined);
|
|
142
|
+
stats.unanchored = severityMatched.length - inlineDetails.length;
|
|
143
|
+
if (severityMatched.length === 0) {
|
|
144
|
+
input.onLog?.(`[PR][REVIEW][INFO] No findings matched the configured inline-comment severities (${input.config.pullRequestReview.commentSeverities.join(", ") || "none"}).`);
|
|
145
|
+
return stats;
|
|
146
|
+
}
|
|
147
|
+
if (inlineDetails.length === 0) {
|
|
148
|
+
input.onLog?.(`[PR][REVIEW][INFO] ${(0, localization_1.formatUnanchoredFindingsAllInSummaryLog)(stats.unanchored, input.config.review.language)}`);
|
|
149
|
+
return stats;
|
|
150
|
+
}
|
|
151
|
+
let existingBodies = [];
|
|
152
|
+
try {
|
|
153
|
+
existingBodies = await (0, reviewApi_1.listInlineCommentBodies)(apiInput);
|
|
154
|
+
}
|
|
155
|
+
catch (error) {
|
|
156
|
+
warnings.push(`Failed to list existing inline comments for deduplication: ${describeError(error)}`);
|
|
157
|
+
}
|
|
158
|
+
const seenMarkers = new Set();
|
|
159
|
+
for (const detail of inlineDetails) {
|
|
160
|
+
const { marker, body } = (0, reviewComment_1.buildInlineCommentBody)(detail);
|
|
161
|
+
if (seenMarkers.has(marker) || existingBodies.some((existing) => existing.includes(marker))) {
|
|
162
|
+
stats.skipped += 1;
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
seenMarkers.add(marker);
|
|
166
|
+
try {
|
|
167
|
+
await (0, reviewApi_1.createInlineComment)(apiInput, details, {
|
|
168
|
+
path: detail.filePath,
|
|
169
|
+
line: detail.lineNumber,
|
|
170
|
+
body
|
|
171
|
+
});
|
|
172
|
+
stats.posted += 1;
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
stats.failed += 1;
|
|
176
|
+
warnings.push(`Failed to publish an inline comment on ${detail.filePath}:${detail.lineNumber}: ${describeError(error)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
input.onLog?.(`[PR][REVIEW][INFO] Inline comments: posted=${stats.posted}, skipped=${stats.skipped}, failed=${stats.failed}, unanchored=${stats.unanchored}.`);
|
|
180
|
+
if (stats.unanchored > 0) {
|
|
181
|
+
input.onLog?.(`[PR][REVIEW][INFO] ${(0, localization_1.formatUnanchoredFindingsAdditionalInSummaryLog)(stats.unanchored, input.config.review.language)}`);
|
|
182
|
+
}
|
|
183
|
+
return stats;
|
|
184
|
+
}
|
|
185
|
+
async function runApproveStep(input, apiInput, details, currentUser, passed, warnings) {
|
|
186
|
+
if (!passed) {
|
|
187
|
+
return { attempted: false, performed: false, detail: "skipped (review did not pass)" };
|
|
188
|
+
}
|
|
189
|
+
if (!input.config.pullRequestReview.autoApprove) {
|
|
190
|
+
return { attempted: false, performed: false, detail: "skipped (auto approve disabled)" };
|
|
191
|
+
}
|
|
192
|
+
if (apiInput.platform.kind === "github" &&
|
|
193
|
+
currentUser &&
|
|
194
|
+
details.authorUsername.toLowerCase() === currentUser.toLowerCase()) {
|
|
195
|
+
const detail = "skipped (GitHub does not allow approving your own pull request)";
|
|
196
|
+
warnings.push("Approve skipped: GitHub does not allow approving your own pull request.");
|
|
197
|
+
return { attempted: false, performed: false, detail };
|
|
198
|
+
}
|
|
199
|
+
if ((0, reviewApi_1.hasPullRequestApprovalFromUser)(details, currentUser)) {
|
|
200
|
+
input.onLog?.("[PR][REVIEW][INFO] Approve: skipped because the authenticated user already approved.");
|
|
201
|
+
return { attempted: false, performed: true, detail: "skipped (already approved)" };
|
|
202
|
+
}
|
|
203
|
+
try {
|
|
204
|
+
await (0, reviewApi_1.approvePullRequest)(apiInput);
|
|
205
|
+
input.onLog?.("[PR][REVIEW][INFO] Approve: done.");
|
|
206
|
+
return { attempted: true, performed: true, detail: "approved" };
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
warnings.push(`Approve failed: ${describeError(error)}`);
|
|
210
|
+
return { attempted: true, performed: false, detail: `failed (${describeError(error)})` };
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
async function runMergeStep(input, apiInput, details, currentUser, passed, approve, warnings) {
|
|
214
|
+
void approve;
|
|
215
|
+
if (!passed) {
|
|
216
|
+
return { attempted: false, performed: false, detail: "skipped (review did not pass)" };
|
|
217
|
+
}
|
|
218
|
+
if (!input.config.pullRequestReview.autoMerge) {
|
|
219
|
+
return { attempted: false, performed: false, detail: "skipped (auto merge disabled)" };
|
|
220
|
+
}
|
|
221
|
+
const gate = (0, mergeGate_1.evaluateMergeGate)({
|
|
222
|
+
currentUser,
|
|
223
|
+
assignees: details.assignees,
|
|
224
|
+
reviewers: details.reviewers
|
|
225
|
+
});
|
|
226
|
+
input.onLog?.(`[PR][REVIEW][INFO] Merge gate: assignee check ${gate.assigneeCheckPassed ? "passed" : "failed"}, reviewer check ${gate.reviewerCheckPassed ? "passed" : "failed"}.`);
|
|
227
|
+
for (const reason of gate.reasons) {
|
|
228
|
+
input.onLog?.(`[PR][REVIEW][INFO] ${reason}`);
|
|
229
|
+
}
|
|
230
|
+
if (!gate.allowed) {
|
|
231
|
+
const detail = `not merged (${gate.reasons.join(" ") || "merge conditions not met"})`;
|
|
232
|
+
return { attempted: false, performed: false, detail };
|
|
233
|
+
}
|
|
234
|
+
try {
|
|
235
|
+
const mergeResult = await (0, reviewApi_1.mergePullRequest)(apiInput);
|
|
236
|
+
input.onLog?.(`[PR][REVIEW][INFO] Merge: ${mergeResult.merged ? "done" : "not merged"}.`);
|
|
237
|
+
return {
|
|
238
|
+
attempted: true,
|
|
239
|
+
performed: mergeResult.merged,
|
|
240
|
+
detail: mergeResult.merged ? "merged" : `not merged${mergeResult.message ? ` (${mergeResult.message})` : ""}`
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
warnings.push(`Merge failed: ${describeError(error)}`);
|
|
245
|
+
return { attempted: true, performed: false, detail: `failed (${describeError(error)})` };
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
async function upsertSummaryComment(input, apiInput, result, passed, approve, merge, warnings) {
|
|
249
|
+
const body = (0, reviewComment_1.buildSummaryCommentBody)({
|
|
250
|
+
result,
|
|
251
|
+
threshold: input.config.pullRequestReview.threshold,
|
|
252
|
+
passed,
|
|
253
|
+
summarySeverities: input.config.pullRequestReview.summarySeverities,
|
|
254
|
+
actions: {
|
|
255
|
+
approve: approve.detail,
|
|
256
|
+
merge: merge.detail
|
|
257
|
+
},
|
|
258
|
+
generatedAt: (0, reviewComment_1.formatReviewTimestamp)()
|
|
259
|
+
});
|
|
260
|
+
let existing = [];
|
|
261
|
+
try {
|
|
262
|
+
existing = await (0, reviewApi_1.listSmartCommitReviewComments)(apiInput, reviewComment_1.PULL_REQUEST_REVIEW_SUMMARY_MARKER);
|
|
263
|
+
}
|
|
264
|
+
catch (error) {
|
|
265
|
+
warnings.push(`Failed to look up an existing summary comment: ${describeError(error)}`);
|
|
266
|
+
}
|
|
267
|
+
if (existing.length > 0) {
|
|
268
|
+
await (0, reviewApi_1.updateSummaryComment)(apiInput, existing[0].id, body);
|
|
269
|
+
input.onLog?.("[PR][REVIEW][INFO] Summary comment: updated.");
|
|
270
|
+
return "updated";
|
|
271
|
+
}
|
|
272
|
+
await (0, reviewApi_1.createSummaryComment)(apiInput, body);
|
|
273
|
+
input.onLog?.("[PR][REVIEW][INFO] Summary comment: created.");
|
|
274
|
+
return "created";
|
|
275
|
+
}
|
|
276
|
+
function logPullRequestDetails(input, details) {
|
|
277
|
+
input.onLog?.(`[PR][REVIEW][INFO] State: ${details.state}${details.isDraft ? " (draft)" : ""}, title: ${details.title || "(no title)"}.`);
|
|
278
|
+
input.onLog?.(`[PR][REVIEW][INFO] Author: ${details.authorUsername || "(unknown)"}.`);
|
|
279
|
+
input.onLog?.(`[PR][REVIEW][INFO] Assignees: ${formatList(details.assignees)}.`);
|
|
280
|
+
input.onLog?.(`[PR][REVIEW][INFO] Reviewers: ${details.reviewers.length > 0
|
|
281
|
+
? details.reviewers
|
|
282
|
+
.map((reviewer) => `${reviewer.username}${reviewer.approved ? " (approved)" : ""}`)
|
|
283
|
+
.join(", ")
|
|
284
|
+
: "none"}.`);
|
|
285
|
+
}
|
|
286
|
+
function logReviewOutcome(input, result, threshold, passed, review) {
|
|
287
|
+
input.onLog?.(`[PR][REVIEW][RESULT] Score: ${result.score === null ? "N/A" : result.score}/10 (threshold ${threshold}) -> ${passed ? "PASSED" : "NOT PASSED"}.`);
|
|
288
|
+
input.onLog?.(`[PR][REVIEW][RESULT] Review mode: ${review.reviewMode}${review.chunkCount ? ` (${review.chunkCount} chunks)` : ""}, summary source: ${review.summarySource}.`);
|
|
289
|
+
input.onLog?.(`[PR][REVIEW][RESULT] Summary: ${result.summary}`);
|
|
290
|
+
const counts = (0, parser_1.countReviewDetailsBySeverity)(result.details);
|
|
291
|
+
input.onLog?.(`[PR][REVIEW][RESULT] Issues by severity: P0=${counts.P0}, P1=${counts.P1}, P2=${counts.P2}, P3=${counts.P3}, OTHER=${counts.OTHER}.`);
|
|
292
|
+
if (result.details.length === 0) {
|
|
293
|
+
input.onLog?.("[PR][REVIEW][RESULT] Issues: none");
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
for (const detail of result.details) {
|
|
297
|
+
input.onLog?.(`[PR][REVIEW][RESULT] ${formatDetailLogLine(detail)}`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function formatDetailLogLine(detail) {
|
|
301
|
+
const severity = detail.severity === "OTHER" ? "" : `${detail.severity} `;
|
|
302
|
+
const location = detail.filePath
|
|
303
|
+
? `[${detail.filePath}${detail.lineNumber === undefined ? "" : `:${detail.lineNumber}`}] `
|
|
304
|
+
: "";
|
|
305
|
+
return `${severity}${location}${detail.message}`.trim();
|
|
306
|
+
}
|
|
307
|
+
function formatList(values) {
|
|
308
|
+
return values.length > 0 ? values.join(", ") : "none";
|
|
309
|
+
}
|
|
310
|
+
function describeError(error) {
|
|
311
|
+
return error instanceof Error ? error.message : String(error);
|
|
312
|
+
}
|
|
313
|
+
//# sourceMappingURL=reviewWorkflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviewWorkflow.js","sourceRoot":"","sources":["../../src/pullRequest/reviewWorkflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.parsePullRequestUrl = parsePullRequestUrl;
|
|
4
|
+
const platform_1 = require("./platform");
|
|
5
|
+
function parsePullRequestUrl(rawUrl, provider = "auto", configuredApiBaseUrl = "") {
|
|
6
|
+
const trimmed = rawUrl.trim();
|
|
7
|
+
if (!trimmed) {
|
|
8
|
+
throw new Error("PR/MR URL is empty.");
|
|
9
|
+
}
|
|
10
|
+
let url;
|
|
11
|
+
try {
|
|
12
|
+
url = new URL(trimmed);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16
|
+
throw new Error(`Unsupported PR/MR URL format: ${message}`);
|
|
17
|
+
}
|
|
18
|
+
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
19
|
+
throw new Error("PR/MR URL must use the http or https protocol.");
|
|
20
|
+
}
|
|
21
|
+
const host = url.host;
|
|
22
|
+
const segments = url.pathname
|
|
23
|
+
.split("/")
|
|
24
|
+
.map((segment) => segment.trim())
|
|
25
|
+
.filter((segment) => segment.length > 0)
|
|
26
|
+
.map((segment) => decodeSegment(segment));
|
|
27
|
+
const githubMatch = extractGitHubPullRequest(segments);
|
|
28
|
+
if (githubMatch) {
|
|
29
|
+
return {
|
|
30
|
+
platform: (0, platform_1.buildPullRequestPlatform)({
|
|
31
|
+
kind: "github",
|
|
32
|
+
host,
|
|
33
|
+
owner: githubMatch.owner,
|
|
34
|
+
repository: githubMatch.repository,
|
|
35
|
+
projectPath: `${githubMatch.owner}/${githubMatch.repository}`,
|
|
36
|
+
configuredApiBaseUrl
|
|
37
|
+
}),
|
|
38
|
+
number: githubMatch.number
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const gitlabMatch = extractGitLabMergeRequest(segments);
|
|
42
|
+
if (gitlabMatch) {
|
|
43
|
+
const [owner, repository] = splitOwnerAndRepository(gitlabMatch.projectPath);
|
|
44
|
+
return {
|
|
45
|
+
platform: (0, platform_1.buildPullRequestPlatform)({
|
|
46
|
+
kind: "gitlab",
|
|
47
|
+
host,
|
|
48
|
+
owner,
|
|
49
|
+
repository,
|
|
50
|
+
projectPath: gitlabMatch.projectPath,
|
|
51
|
+
configuredApiBaseUrl
|
|
52
|
+
}),
|
|
53
|
+
number: gitlabMatch.number
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const hintedKind = resolveProviderHint(provider, host);
|
|
57
|
+
throw new Error(`Unsupported PR/MR URL: ${trimmed}. Expected a GitHub pull request URL such as https://github.com/owner/repo/pull/123 or a GitLab merge request URL such as https://gitlab.com/group/project/-/merge_requests/12.${hintedKind ? "" : " For private deployments, also set pullRequest.provider."}`);
|
|
58
|
+
}
|
|
59
|
+
function extractGitHubPullRequest(segments) {
|
|
60
|
+
const pullIndex = segments.findIndex((segment) => segment === "pull" || segment === "pulls");
|
|
61
|
+
if (pullIndex < 2) {
|
|
62
|
+
return undefined;
|
|
63
|
+
}
|
|
64
|
+
const number = parsePositiveInteger(segments[pullIndex + 1]);
|
|
65
|
+
if (number === undefined) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
const owner = segments[0];
|
|
69
|
+
const repository = stripGitSuffix(segments[1]);
|
|
70
|
+
if (!owner || !repository) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
return { owner, repository, number };
|
|
74
|
+
}
|
|
75
|
+
function extractGitLabMergeRequest(segments) {
|
|
76
|
+
const mergeRequestIndex = segments.findIndex((segment) => segment === "merge_requests");
|
|
77
|
+
if (mergeRequestIndex < 1) {
|
|
78
|
+
return undefined;
|
|
79
|
+
}
|
|
80
|
+
const number = parsePositiveInteger(segments[mergeRequestIndex + 1]);
|
|
81
|
+
if (number === undefined) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
let projectSegments = segments.slice(0, mergeRequestIndex);
|
|
85
|
+
if (projectSegments[projectSegments.length - 1] === "-") {
|
|
86
|
+
projectSegments = projectSegments.slice(0, -1);
|
|
87
|
+
}
|
|
88
|
+
if (projectSegments.length < 2) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
const projectPath = projectSegments.map(stripGitSuffix).join("/");
|
|
92
|
+
return { projectPath, number };
|
|
93
|
+
}
|
|
94
|
+
function splitOwnerAndRepository(projectPath) {
|
|
95
|
+
const parts = projectPath.split("/").filter((part) => part.length > 0);
|
|
96
|
+
if (parts.length < 2) {
|
|
97
|
+
throw new Error(`GitLab merge request URL must contain at least a group and project: ${projectPath}`);
|
|
98
|
+
}
|
|
99
|
+
return [parts[0], parts[parts.length - 1]];
|
|
100
|
+
}
|
|
101
|
+
function resolveProviderHint(provider, host) {
|
|
102
|
+
if (provider === "github" || provider === "gitlab") {
|
|
103
|
+
return provider;
|
|
104
|
+
}
|
|
105
|
+
const normalizedHost = host.toLowerCase();
|
|
106
|
+
if (normalizedHost === "github.com") {
|
|
107
|
+
return "github";
|
|
108
|
+
}
|
|
109
|
+
if (normalizedHost === "gitlab.com") {
|
|
110
|
+
return "gitlab";
|
|
111
|
+
}
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
function parsePositiveInteger(value) {
|
|
115
|
+
if (!value) {
|
|
116
|
+
return undefined;
|
|
117
|
+
}
|
|
118
|
+
if (!/^\d+$/.test(value)) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
121
|
+
const parsed = Number(value);
|
|
122
|
+
return Number.isInteger(parsed) && parsed > 0 ? parsed : undefined;
|
|
123
|
+
}
|
|
124
|
+
function stripGitSuffix(value) {
|
|
125
|
+
return value.replace(/\.git$/i, "");
|
|
126
|
+
}
|
|
127
|
+
function decodeSegment(segment) {
|
|
128
|
+
try {
|
|
129
|
+
return decodeURIComponent(segment);
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
return segment;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=urlParser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"urlParser.js","sourceRoot":"","sources":["../../src/pullRequest/urlParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -41,7 +41,7 @@ const config_1 = require("./config");
|
|
|
41
41
|
const contentService_1 = require("./contentService");
|
|
42
42
|
const platform_1 = require("./platform");
|
|
43
43
|
async function createPullRequestFromCurrentBranch(input) {
|
|
44
|
-
const pullRequestConfig = input.pullRequestConfig ?? input.config
|
|
44
|
+
const pullRequestConfig = input.pullRequestConfig ?? (0, config_1.resolvePullRequestCreationConfig)(input.config);
|
|
45
45
|
(0, config_1.validatePullRequestCreationConfig)(pullRequestConfig);
|
|
46
46
|
const sourceBranch = await (0, git_1.getCurrentBranch)(input.repositoryPath);
|
|
47
47
|
if (!sourceBranch || sourceBranch === "HEAD") {
|
|
@@ -49,10 +49,10 @@ async function createPullRequestFromCurrentBranch(input) {
|
|
|
49
49
|
}
|
|
50
50
|
const targetBranch = pullRequestConfig.targetBranch.trim();
|
|
51
51
|
if (sourceBranch === targetBranch) {
|
|
52
|
-
throw new Error("Current branch is the same as
|
|
52
|
+
throw new Error("Current branch is the same as pullRequestCreation.targetBranch; PR/MR creation was skipped.");
|
|
53
53
|
}
|
|
54
54
|
if (matchesAnyBranchPattern(sourceBranch, pullRequestConfig.skipBranches)) {
|
|
55
|
-
throw new Error(`Current branch ${sourceBranch} is blocked by
|
|
55
|
+
throw new Error(`Current branch ${sourceBranch} is blocked by pullRequestCreation.skipBranches.`);
|
|
56
56
|
}
|
|
57
57
|
const upstream = await (0, git_1.getCurrentBranchUpstream)(input.repositoryPath);
|
|
58
58
|
const remoteUrl = await (0, git_1.getRemoteUrl)(input.repositoryPath, upstream.remote);
|
|
@@ -89,7 +89,7 @@ async function createPullRequestFromCurrentBranch(input) {
|
|
|
89
89
|
throw new Error(`No branch diff found between ${targetBranch} and ${sourceBranch}.`);
|
|
90
90
|
}
|
|
91
91
|
const limitedDiff = (0, git_1.limitDiff)(comparison.fullDiff, pullRequestConfig.maxDiffChars, "[Diff truncated by smart-commit-cli for PR/MR creation]");
|
|
92
|
-
const
|
|
92
|
+
const generatedContent = await (0, contentService_1.generatePullRequestContent)({
|
|
93
93
|
client: input.client,
|
|
94
94
|
llmResponseCorrectionRetryCount: input.config.connection.llmResponseCorrectionRetryCount,
|
|
95
95
|
repositoryName: path.basename(input.repositoryPath),
|
|
@@ -106,6 +106,10 @@ async function createPullRequestFromCurrentBranch(input) {
|
|
|
106
106
|
descriptionPrompt: pullRequestConfig.descriptionPrompt,
|
|
107
107
|
onRetryableError: (error) => input.onInfo?.(`[PR][WARN] Generated PR/MR content did not match protocol: ${error.issues.join("; ")}`)
|
|
108
108
|
});
|
|
109
|
+
const content = {
|
|
110
|
+
...generatedContent,
|
|
111
|
+
title: resolvePullRequestTitle(comparison, generatedContent.title, pullRequestConfig.titlePrompt)
|
|
112
|
+
};
|
|
109
113
|
if (input.dryRun) {
|
|
110
114
|
return {
|
|
111
115
|
status: "ready",
|
|
@@ -139,6 +143,15 @@ async function createPullRequestFromCurrentBranch(input) {
|
|
|
139
143
|
function matchesAnyBranchPattern(branch, patterns) {
|
|
140
144
|
return patterns.some((pattern) => matchesBranchPattern(branch, pattern));
|
|
141
145
|
}
|
|
146
|
+
function resolvePullRequestTitle(comparison, generatedTitle, titlePrompt) {
|
|
147
|
+
if (titlePrompt.trim()) {
|
|
148
|
+
return generatedTitle;
|
|
149
|
+
}
|
|
150
|
+
if (comparison.commits.length !== 1) {
|
|
151
|
+
return generatedTitle;
|
|
152
|
+
}
|
|
153
|
+
return comparison.commits[0].subject.trim() || generatedTitle;
|
|
154
|
+
}
|
|
142
155
|
function matchesBranchPattern(branch, pattern) {
|
|
143
156
|
const trimmed = pattern.trim();
|
|
144
157
|
if (!trimmed) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/pullRequest/workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"workflow.js","sourceRoot":"","sources":["../../src/pullRequest/workflow.ts"],"names":[],"mappings":"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"}
|