sales-frontend-gemini-cli 0.4.3 → 0.4.4
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/dist/common/helper.cjs +119 -3
- package/dist/common/helper.cjs.map +1 -1
- package/dist/common/helper.d.cts +30 -1
- package/dist/common/helper.d.ts +30 -1
- package/dist/common/helper.js +118 -4
- package/dist/common/helper.js.map +1 -1
- package/dist/pr-review/claude/claude-commander.cjs +10 -3
- package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
- package/dist/pr-review/claude/claude-commander.js +10 -3
- package/dist/pr-review/claude/claude-commander.js.map +1 -1
- package/dist/pr-review/claude/installation-claude.cjs +1 -1
- package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
- package/dist/pr-review/claude/installation-claude.js +1 -1
- package/dist/pr-review/claude/installation-claude.js.map +1 -1
- package/dist/pr-review/codex/codex-commander.cjs +14 -4
- package/dist/pr-review/codex/codex-commander.cjs.map +1 -1
- package/dist/pr-review/codex/codex-commander.d.cts +1 -1
- package/dist/pr-review/codex/codex-commander.d.ts +1 -1
- package/dist/pr-review/codex/codex-commander.js +14 -4
- package/dist/pr-review/codex/codex-commander.js.map +1 -1
- package/dist/pr-review/codex/installation-codex.cjs +1 -1
- package/dist/pr-review/codex/installation-codex.cjs.map +1 -1
- package/dist/pr-review/codex/installation-codex.js +1 -1
- package/dist/pr-review/codex/installation-codex.js.map +1 -1
- package/dist/pr-review/gemini/gemini-commander.cjs +12 -12
- package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
- package/dist/pr-review/gemini/gemini-commander.js +12 -12
- package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
- package/dist/pr-review/gemini/installation-gemini.cjs +1 -1
- package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
- package/dist/pr-review/gemini/installation-gemini.js +1 -1
- package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
- package/dist/pr-review/review-one-by-one.cjs +223 -24
- package/dist/pr-review/review-one-by-one.cjs.map +1 -1
- package/dist/pr-review/review-one-by-one.js +223 -24
- package/dist/pr-review/review-one-by-one.js.map +1 -1
- package/dist/pr-review/review.cjs +220 -26
- package/dist/pr-review/review.cjs.map +1 -1
- package/dist/pr-review/review.js +220 -26
- package/dist/pr-review/review.js.map +1 -1
- package/package.json +1 -1
package/dist/pr-review/review.js
CHANGED
|
@@ -71,6 +71,9 @@ var ignoreList = [
|
|
|
71
71
|
function isTestMode(args4 = process.argv.slice(2)) {
|
|
72
72
|
return args4.includes("--test");
|
|
73
73
|
}
|
|
74
|
+
function shouldStreamAIOutput(args4 = process.argv.slice(2)) {
|
|
75
|
+
return args4.includes("--stream-output");
|
|
76
|
+
}
|
|
74
77
|
function clearTraceMessages() {
|
|
75
78
|
traceMessages.length = 0;
|
|
76
79
|
}
|
|
@@ -240,11 +243,41 @@ async function executeShellCommandWithProgress(command, options = {}) {
|
|
|
240
243
|
return;
|
|
241
244
|
}
|
|
242
245
|
const exitSummary = signal ? `signal=${signal}` : `code=${String(code ?? "unknown")}`;
|
|
243
|
-
|
|
244
|
-
|
|
246
|
+
const failureDetails = {
|
|
247
|
+
code,
|
|
248
|
+
command,
|
|
249
|
+
signal,
|
|
250
|
+
stderr,
|
|
251
|
+
stdout
|
|
252
|
+
};
|
|
253
|
+
reject(createShellCommandExecutionError(failureDetails, exitSummary));
|
|
245
254
|
});
|
|
246
255
|
});
|
|
247
256
|
}
|
|
257
|
+
function getShellCommandFailurePreview(failureDetails) {
|
|
258
|
+
const stderrText = failureDetails.stderr.trim();
|
|
259
|
+
const stdoutText = failureDetails.stdout.trim();
|
|
260
|
+
const combinedOutput = stderrText || stdoutText;
|
|
261
|
+
if (!combinedOutput) {
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
const MAX_PREVIEW_LENGTH = 4e3;
|
|
265
|
+
if (combinedOutput.length <= MAX_PREVIEW_LENGTH) {
|
|
266
|
+
return combinedOutput;
|
|
267
|
+
}
|
|
268
|
+
return combinedOutput.slice(-4e3);
|
|
269
|
+
}
|
|
270
|
+
function createShellCommandExecutionError(failureDetails, exitSummary) {
|
|
271
|
+
const failurePreview = getShellCommandFailurePreview(failureDetails);
|
|
272
|
+
const error = new Error(`\uC258 \uBA85\uB839 \uC2E4\uD589 \uC2E4\uD328 (${exitSummary})${failurePreview ? `
|
|
273
|
+
${failurePreview}` : ""}`);
|
|
274
|
+
error.code = failureDetails.code;
|
|
275
|
+
error.signal = failureDetails.signal;
|
|
276
|
+
error.stdout = failureDetails.stdout;
|
|
277
|
+
error.stderr = failureDetails.stderr;
|
|
278
|
+
error.command = failureDetails.command;
|
|
279
|
+
return error;
|
|
280
|
+
}
|
|
248
281
|
function formatReviewTargetFiles(files, visibleCount = 5) {
|
|
249
282
|
if (files.length === 0) {
|
|
250
283
|
return "(\uC5C6\uC74C)";
|
|
@@ -317,7 +350,7 @@ function serializeError(error) {
|
|
|
317
350
|
}
|
|
318
351
|
if (error && typeof error === "object") {
|
|
319
352
|
const errorLike = error;
|
|
320
|
-
const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs"];
|
|
353
|
+
const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs", "command"];
|
|
321
354
|
extraKeys.forEach((key) => {
|
|
322
355
|
if (errorLike[key] !== void 0) {
|
|
323
356
|
serialized[key] = errorLike[key];
|
|
@@ -423,6 +456,87 @@ ${section.markdown}`).join("\n")}
|
|
|
423
456
|
return "";
|
|
424
457
|
}
|
|
425
458
|
}
|
|
459
|
+
function getExecutionLogSummary(status, title) {
|
|
460
|
+
if (title) {
|
|
461
|
+
return title;
|
|
462
|
+
}
|
|
463
|
+
switch (status) {
|
|
464
|
+
case "success":
|
|
465
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
466
|
+
case "failed":
|
|
467
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
468
|
+
case "partial_failure":
|
|
469
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589\uC740 \uC644\uB8CC\uB418\uC5C8\uC9C0\uB9CC \uC77C\uBD80 \uB2E8\uACC4\uC5D0\uC11C \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
470
|
+
default:
|
|
471
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589\uC774 \uCDE8\uC18C\uB418\uC5C8\uAC70\uB098 \uB9AC\uBDF0 \uB300\uC0C1\uC774 \uC5C6\uC5B4 \uC885\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
function formatExecutionDuration(startedAt, finishedAt) {
|
|
475
|
+
const durationMs = Math.max(0, finishedAt.getTime() - startedAt.getTime());
|
|
476
|
+
if (durationMs < 1e3) {
|
|
477
|
+
return `${durationMs}ms`;
|
|
478
|
+
}
|
|
479
|
+
const durationSeconds = durationMs / 1e3;
|
|
480
|
+
if (durationSeconds < 60) {
|
|
481
|
+
return `${durationSeconds.toFixed(1)}s`;
|
|
482
|
+
}
|
|
483
|
+
const minutes = Math.floor(durationSeconds / 60);
|
|
484
|
+
const seconds = Math.round(durationSeconds % 60);
|
|
485
|
+
return `${minutes}m ${seconds}s`;
|
|
486
|
+
}
|
|
487
|
+
function writeExecutionLog(options = {}) {
|
|
488
|
+
try {
|
|
489
|
+
const startedAt = options.startedAt ?? /* @__PURE__ */ new Date();
|
|
490
|
+
const finishedAt = options.finishedAt ?? /* @__PURE__ */ new Date();
|
|
491
|
+
const status = options.status ?? "success";
|
|
492
|
+
helperTrace("execution-log:write:start", options.scope || "unknown");
|
|
493
|
+
createReportDirectory();
|
|
494
|
+
const reportPath = getAvailableFilePath(REPORT_DIR, `${getNowString(finishedAt)}-execution-log`, ".md");
|
|
495
|
+
const traceSnapshot = options.traceMessages ?? getTraceMessages();
|
|
496
|
+
const extraSections = options.extraSections || [];
|
|
497
|
+
const serializedError = options.error ? serializeError(options.error) : null;
|
|
498
|
+
const report = `# Execution Log
|
|
499
|
+
|
|
500
|
+
- \uC2DC\uC791 \uC2DC\uAC01: ${getHumanReadableNowString(startedAt)}
|
|
501
|
+
- \uC885\uB8CC \uC2DC\uAC01: ${getHumanReadableNowString(finishedAt)}
|
|
502
|
+
- \uC2E4\uD589 \uC2DC\uAC04: ${formatExecutionDuration(startedAt, finishedAt)}
|
|
503
|
+
- \uC0C1\uD0DC: \`${status}\`
|
|
504
|
+
- Scope: \`${options.scope || "unknown"}\`
|
|
505
|
+
- \uC791\uC5C5 \uACBD\uB85C: \`${process.cwd()}\`
|
|
506
|
+
- \uC2E4\uD589 \uC778\uC790: \`${JSON.stringify(options.args ?? process.argv.slice(2))}\`
|
|
507
|
+
- \uC2E4\uD589 \uD658\uACBD: \`${process.platform} ${process.arch} / Node ${process.version}\`
|
|
508
|
+
|
|
509
|
+
## Summary
|
|
510
|
+
|
|
511
|
+
${getExecutionLogSummary(status, options.title)}
|
|
512
|
+
${serializedError ? `
|
|
513
|
+
|
|
514
|
+
## Error
|
|
515
|
+
|
|
516
|
+
\`\`\`json
|
|
517
|
+
${JSON.stringify(serializedError, null, 2)}
|
|
518
|
+
\`\`\`` : ""}
|
|
519
|
+
|
|
520
|
+
## Trace
|
|
521
|
+
|
|
522
|
+
\`\`\`json
|
|
523
|
+
${JSON.stringify(traceSnapshot, null, 2)}
|
|
524
|
+
\`\`\`${extraSections.length ? `
|
|
525
|
+
${extraSections.map((section) => `
|
|
526
|
+
## ${section.heading}
|
|
527
|
+
|
|
528
|
+
${section.markdown}`).join("\n")}
|
|
529
|
+
` : "\n"}
|
|
530
|
+
`;
|
|
531
|
+
fs.writeFileSync(reportPath, report);
|
|
532
|
+
helperTrace("execution-log:write:done", reportPath);
|
|
533
|
+
return reportPath;
|
|
534
|
+
} catch (writeError) {
|
|
535
|
+
console.error("\u26A0\uFE0F \uC2E4\uD589 \uB85C\uADF8 \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
536
|
+
console.error(writeError);
|
|
537
|
+
return "";
|
|
538
|
+
}
|
|
539
|
+
}
|
|
426
540
|
function exitWithError(message, options = {}) {
|
|
427
541
|
const reportPath = writeErrorReport(options.error || new Error(message), {
|
|
428
542
|
...options,
|
|
@@ -810,6 +924,13 @@ var ALLOWED_REASONING_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
|
810
924
|
function shellQuote(value) {
|
|
811
925
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
812
926
|
}
|
|
927
|
+
function toShellOptionToken(value) {
|
|
928
|
+
const SIMPLE_SHELL_TOKEN_PATTERN = /^[A-Za-z0-9._:/=-]+$/;
|
|
929
|
+
if (SIMPLE_SHELL_TOKEN_PATTERN.test(value)) {
|
|
930
|
+
return value;
|
|
931
|
+
}
|
|
932
|
+
return shellQuote(value);
|
|
933
|
+
}
|
|
813
934
|
function getArgValue(flag) {
|
|
814
935
|
const index = args.indexOf(flag);
|
|
815
936
|
if (index === -1 || !args[index + 1]) {
|
|
@@ -889,9 +1010,9 @@ function getAliasFallbacks(primaryAlias) {
|
|
|
889
1010
|
}
|
|
890
1011
|
function buildClaudeExecCommand(options) {
|
|
891
1012
|
const { tempDiffPath: tempDiffPath2, prompt, systemPromptFiles, effort, model, fallbackModel } = options;
|
|
892
|
-
const modelOption = model ? `--model ${
|
|
893
|
-
const fallbackOption = model && fallbackModel ? `--fallback-model ${
|
|
894
|
-
const effortOption = `--effort ${
|
|
1013
|
+
const modelOption = model ? `--model ${toShellOptionToken(model)}` : "";
|
|
1014
|
+
const fallbackOption = model && fallbackModel ? `--fallback-model ${toShellOptionToken(fallbackModel)}` : "";
|
|
1015
|
+
const effortOption = `--effort ${toShellOptionToken(effort)}`;
|
|
895
1016
|
const appendedPromptFiles = systemPromptFiles.map((path3) => `--append-system-prompt-file ${shellQuote(path3)}`).join(" ");
|
|
896
1017
|
return `cat ${shellQuote(tempDiffPath2)} | claude ${[
|
|
897
1018
|
modelOption,
|
|
@@ -1016,12 +1137,22 @@ function printNotice2(message) {
|
|
|
1016
1137
|
console.warn(message);
|
|
1017
1138
|
}
|
|
1018
1139
|
}
|
|
1140
|
+
function normalizeEffort2(level) {
|
|
1141
|
+
if (level === "minimal") {
|
|
1142
|
+
return "low";
|
|
1143
|
+
}
|
|
1144
|
+
return level;
|
|
1145
|
+
}
|
|
1019
1146
|
function resolveReasoningEffort2() {
|
|
1020
1147
|
const customReasoningEffort = getArgValue2("--reasoning-effort");
|
|
1021
1148
|
if (customReasoningEffort) {
|
|
1022
1149
|
if (ALLOWED_REASONING_EFFORTS2.includes(customReasoningEffort)) {
|
|
1023
|
-
|
|
1024
|
-
|
|
1150
|
+
const normalized = normalizeEffort2(customReasoningEffort);
|
|
1151
|
+
trace3("reasoning:custom", `${customReasoningEffort} -> ${normalized}`);
|
|
1152
|
+
if (customReasoningEffort === "minimal") {
|
|
1153
|
+
printNotice2("\u26A0\uFE0F Codex\uB294 minimal\uC774 web_search \uB3C4\uAD6C\uC640 \uCDA9\uB3CC\uD560 \uC218 \uC788\uC5B4 low\uB85C \uB9E4\uD551\uD569\uB2C8\uB2E4.");
|
|
1154
|
+
}
|
|
1155
|
+
return normalized;
|
|
1025
1156
|
}
|
|
1026
1157
|
printNotice2(
|
|
1027
1158
|
`\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS2.join(
|
|
@@ -1030,8 +1161,8 @@ function resolveReasoningEffort2() {
|
|
|
1030
1161
|
);
|
|
1031
1162
|
}
|
|
1032
1163
|
if (args2.includes("--flash")) {
|
|
1033
|
-
trace3("reasoning:flash-default", "
|
|
1034
|
-
return "
|
|
1164
|
+
trace3("reasoning:flash-default", "low");
|
|
1165
|
+
return "low";
|
|
1035
1166
|
}
|
|
1036
1167
|
if (args2.includes("--review")) {
|
|
1037
1168
|
trace3("reasoning:review-default", "high");
|
|
@@ -1226,7 +1357,7 @@ function buildGeminiFileReferenceSection(files) {
|
|
|
1226
1357
|
const existingFiles = files.filter((file) => fs.existsSync(file.path));
|
|
1227
1358
|
return {
|
|
1228
1359
|
count: existingFiles.length,
|
|
1229
|
-
|
|
1360
|
+
items: existingFiles.map((file) => `${file.display} ${toGeminiFileReference(file.path)}`)
|
|
1230
1361
|
};
|
|
1231
1362
|
}
|
|
1232
1363
|
var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
@@ -1245,19 +1376,19 @@ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
|
1245
1376
|
const ruleSection = buildGeminiFileReferenceSection(rules);
|
|
1246
1377
|
trace5("rules:loaded", `count=${ruleSection.count}`);
|
|
1247
1378
|
const reviewFormExists = fs.existsSync(resolvedReviewFormPath);
|
|
1248
|
-
const
|
|
1379
|
+
const reviewFormText = reviewFormExists ? `\uB9AC\uBDF0 \uC591\uC2DD ${toGeminiFileReference(resolvedReviewFormPath)}` : "\uB9AC\uBDF0 \uC591\uC2DD (\uC5C6\uC74C)";
|
|
1249
1380
|
trace5("reviewForm:status", reviewFormExists ? "exists" : "missing");
|
|
1250
1381
|
const reasoningInstruction = getReasoningInstruction(reasoningEffort);
|
|
1251
|
-
const
|
|
1252
|
-
\
|
|
1253
|
-
|
|
1254
|
-
\uB9AC\uBDF0 \
|
|
1255
|
-
${
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
\
|
|
1260
|
-
|
|
1382
|
+
const ruleText = ruleSection.items.join(" ") || "(\uC5C6\uC74C)";
|
|
1383
|
+
const diffText = `\uB9AC\uBDF0 \uB300\uC0C1 diff ${toGeminiFileReference(resolvedTempDiffPath)}`;
|
|
1384
|
+
const prompt = [
|
|
1385
|
+
"\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uC21C\uC11C\uB300\uB85C \uC77D\uACE0 \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.",
|
|
1386
|
+
`\uADDC\uCE59 \uD30C\uC77C: ${ruleText}`,
|
|
1387
|
+
`\uB9AC\uBDF0 \uC591\uC2DD \uD30C\uC77C: ${reviewFormText}`,
|
|
1388
|
+
`\uB9AC\uBDF0 \uB300\uC0C1 diff \uD30C\uC77C: ${diffText}`,
|
|
1389
|
+
"\uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.",
|
|
1390
|
+
`\uCD94\uB860 \uAC15\uB3C4 \uC9C0\uCE68: ${reasoningInstruction}`
|
|
1391
|
+
].join(" ");
|
|
1261
1392
|
trace5("prompt:prepared", `length=${prompt.length}`);
|
|
1262
1393
|
const modelCandidates = toUnique2(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
|
|
1263
1394
|
trace5("model:candidates", modelCandidates.join(", "));
|
|
@@ -1320,8 +1451,10 @@ function checkGeminiCliInstalled() {
|
|
|
1320
1451
|
// src/pr-review/review.ts
|
|
1321
1452
|
async function main() {
|
|
1322
1453
|
const args4 = process.argv.slice(2);
|
|
1454
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
1323
1455
|
clearTraceMessages();
|
|
1324
1456
|
const isTest = isTestMode(args4);
|
|
1457
|
+
const shouldStreamOutput = shouldStreamAIOutput(args4);
|
|
1325
1458
|
const trace7 = createTraceLogger("review", args4);
|
|
1326
1459
|
trace7("main:start", `args=${JSON.stringify(args4)}`);
|
|
1327
1460
|
let command = "";
|
|
@@ -1330,6 +1463,12 @@ async function main() {
|
|
|
1330
1463
|
let service = "";
|
|
1331
1464
|
let selectedCommitSummary = "";
|
|
1332
1465
|
let reviewTargetFiles = [];
|
|
1466
|
+
let executionLogPath = "";
|
|
1467
|
+
let executionStatus = "cancelled";
|
|
1468
|
+
let executionTitle = "\uB9AC\uBDF0 \uC2E4\uD589\uC774 \uCDE8\uC18C\uB418\uC5C8\uAC70\uB098 \uB9AC\uBDF0 \uB300\uC0C1\uC774 \uC5C6\uC5B4 \uC885\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
1469
|
+
let executionError = null;
|
|
1470
|
+
let resultLength = 0;
|
|
1471
|
+
let exitCode = 0;
|
|
1333
1472
|
try {
|
|
1334
1473
|
trace7("service-selection:start");
|
|
1335
1474
|
service = await showSelectionAIService();
|
|
@@ -1353,14 +1492,18 @@ async function main() {
|
|
|
1353
1492
|
}
|
|
1354
1493
|
trace7("review-flow:start");
|
|
1355
1494
|
console.log("\u{1F680} AI Code Review\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4...");
|
|
1495
|
+
if (shouldStreamOutput) {
|
|
1496
|
+
console.log("\u2139\uFE0F AI \uC2E4\uC2DC\uAC04 \uC751\uB2F5 \uD45C\uC2DC \uBAA8\uB4DC\uAC00 \uD65C\uC131\uD654\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
1497
|
+
}
|
|
1356
1498
|
trace7("commit-selection:start");
|
|
1357
1499
|
const selectedCommits = await selectReviewCommits();
|
|
1358
1500
|
trace7("commit-selection:done", `count=${selectedCommits.length}`);
|
|
1359
1501
|
if (selectedCommits.length === 0) {
|
|
1360
1502
|
trace7("commit-selection:empty");
|
|
1503
|
+
executionTitle = "\uC120\uD0DD\uB41C \uCEE4\uBC0B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
1361
1504
|
console.log("\u2139\uFE0F \uC120\uD0DD\uB41C \uCEE4\uBC0B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
1362
1505
|
deleteTempDiff();
|
|
1363
|
-
|
|
1506
|
+
return;
|
|
1364
1507
|
}
|
|
1365
1508
|
selectedCommitSummary = buildSelectedCommitSummary(selectedCommits);
|
|
1366
1509
|
trace7("commit-summary:prepared", selectedCommitSummary);
|
|
@@ -1372,9 +1515,10 @@ async function main() {
|
|
|
1372
1515
|
trace7("git-diff:build:done", `length=${diff.length}`);
|
|
1373
1516
|
if (!diff.trim() && !isTest) {
|
|
1374
1517
|
trace7("empty-diff:exit");
|
|
1518
|
+
executionTitle = "\uC120\uD0DD\uD55C \uCEE4\uBC0B\uC5D0\uC11C \uB9AC\uBDF0 \uB300\uC0C1 \uD30C\uC77C \uBCC0\uACBD\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.";
|
|
1375
1519
|
console.log("\u2139\uFE0F \uC120\uD0DD\uD55C \uCEE4\uBC0B\uC5D0\uC11C \uB9AC\uBDF0 \uB300\uC0C1 \uD30C\uC77C \uBCC0\uACBD\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
1376
1520
|
deleteTempDiff();
|
|
1377
|
-
|
|
1521
|
+
return;
|
|
1378
1522
|
}
|
|
1379
1523
|
const nowStr = getNowString();
|
|
1380
1524
|
trace7("timestamp:created", nowStr);
|
|
@@ -1404,8 +1548,9 @@ async function main() {
|
|
|
1404
1548
|
trace7("command:exec:start");
|
|
1405
1549
|
const result = (await executeShellCommandWithProgress(command, {
|
|
1406
1550
|
progressMessage: `\u23F3 [\uB9AC\uBDF0 \uC9C4\uD589] ${service} | \uB300\uC0C1 ${reviewTargetFiles.length}\uAC1C \uD30C\uC77C`,
|
|
1407
|
-
streamOutput: isTest
|
|
1551
|
+
streamOutput: isTest || shouldStreamOutput
|
|
1408
1552
|
})).stdout;
|
|
1553
|
+
resultLength = result.length;
|
|
1409
1554
|
trace7("command:exec:done", `resultLength=${result.length}`);
|
|
1410
1555
|
trace7("report:write:start");
|
|
1411
1556
|
savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
|
|
@@ -1431,9 +1576,15 @@ ${command}`);
|
|
|
1431
1576
|
deleteTempDiff();
|
|
1432
1577
|
trace7("cleanup-temp-diff:done");
|
|
1433
1578
|
trace7("review-flow:end");
|
|
1579
|
+
executionStatus = "success";
|
|
1580
|
+
executionTitle = "\uB9AC\uBDF0\uAC00 \uC131\uACF5\uC801\uC73C\uB85C \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
1434
1581
|
} catch (error) {
|
|
1435
1582
|
trace7("review-flow:catch", getErrorSummary(error));
|
|
1436
1583
|
let errorReportPath = "";
|
|
1584
|
+
executionStatus = "failed";
|
|
1585
|
+
executionTitle = "\uB9AC\uBDF0 \uC2E4\uD589 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
1586
|
+
executionError = error;
|
|
1587
|
+
exitCode = 1;
|
|
1437
1588
|
trace7("cleanup-temp-diff:start(catch)");
|
|
1438
1589
|
try {
|
|
1439
1590
|
deleteTempDiff();
|
|
@@ -1473,7 +1624,50 @@ ${JSON.stringify(
|
|
|
1473
1624
|
if (errorReportPath) {
|
|
1474
1625
|
console.error(`\u{1F4C4} \uC5D0\uB7EC \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${errorReportPath}`);
|
|
1475
1626
|
}
|
|
1476
|
-
|
|
1627
|
+
} finally {
|
|
1628
|
+
executionLogPath = writeExecutionLog({
|
|
1629
|
+
scope: "review",
|
|
1630
|
+
status: executionStatus,
|
|
1631
|
+
title: executionTitle,
|
|
1632
|
+
args: args4,
|
|
1633
|
+
startedAt,
|
|
1634
|
+
error: executionError,
|
|
1635
|
+
extraSections: [
|
|
1636
|
+
{
|
|
1637
|
+
heading: "Execution Context",
|
|
1638
|
+
markdown: `\`\`\`json
|
|
1639
|
+
${JSON.stringify(
|
|
1640
|
+
{
|
|
1641
|
+
service: service || null,
|
|
1642
|
+
selectedCommitSummary: selectedCommitSummary || null,
|
|
1643
|
+
reviewTargetFiles,
|
|
1644
|
+
command: command || null,
|
|
1645
|
+
tempDiffPath,
|
|
1646
|
+
savedDiffPath: savedDiffPath || null,
|
|
1647
|
+
savedReportPath: savedReportPath || null,
|
|
1648
|
+
shouldStreamOutput,
|
|
1649
|
+
resultLength
|
|
1650
|
+
},
|
|
1651
|
+
null,
|
|
1652
|
+
2
|
|
1653
|
+
)}
|
|
1654
|
+
\`\`\``
|
|
1655
|
+
},
|
|
1656
|
+
{
|
|
1657
|
+
heading: "Generated Command",
|
|
1658
|
+
markdown: command ? `\`\`\`sh
|
|
1659
|
+
${command}
|
|
1660
|
+
\`\`\`` : "(\uC5C6\uC74C)"
|
|
1661
|
+
}
|
|
1662
|
+
]
|
|
1663
|
+
});
|
|
1664
|
+
if (executionLogPath) {
|
|
1665
|
+
const writeLog = executionStatus === "failed" ? console.error : console.log;
|
|
1666
|
+
writeLog(`\u{1F4DD} \uC2E4\uD589 \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${executionLogPath}`);
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
if (exitCode !== 0) {
|
|
1670
|
+
process.exit(exitCode);
|
|
1477
1671
|
}
|
|
1478
1672
|
}
|
|
1479
1673
|
main();
|