sales-frontend-gemini-cli 0.4.3 → 0.5.0
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 +227 -20
- 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 +226 -21
- package/dist/common/helper.js.map +1 -1
- package/dist/common/types.d.cts +3 -1
- package/dist/common/types.d.ts +3 -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 +296 -42
- package/dist/pr-review/review-one-by-one.cjs.map +1 -1
- package/dist/pr-review/review-one-by-one.js +296 -42
- package/dist/pr-review/review-one-by-one.js.map +1 -1
- package/dist/pr-review/review.cjs +327 -42
- package/dist/pr-review/review.cjs.map +1 -1
- package/dist/pr-review/review.js +327 -42
- package/dist/pr-review/review.js.map +1 -1
- package/package.json +1 -1
|
@@ -269,7 +269,7 @@ function serializeError(error) {
|
|
|
269
269
|
}
|
|
270
270
|
if (error && typeof error === "object") {
|
|
271
271
|
const errorLike = error;
|
|
272
|
-
const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs"];
|
|
272
|
+
const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs", "command"];
|
|
273
273
|
extraKeys.forEach((key) => {
|
|
274
274
|
if (errorLike[key] !== void 0) {
|
|
275
275
|
serialized[key] = errorLike[key];
|
|
@@ -375,6 +375,87 @@ ${section.markdown}`).join("\n")}
|
|
|
375
375
|
return "";
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
|
+
function getExecutionLogSummary(status, title) {
|
|
379
|
+
if (title) {
|
|
380
|
+
return title;
|
|
381
|
+
}
|
|
382
|
+
switch (status) {
|
|
383
|
+
case "success":
|
|
384
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
385
|
+
case "failed":
|
|
386
|
+
return "\uB9AC\uBDF0 \uC2E4\uD589 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
387
|
+
case "partial_failure":
|
|
388
|
+
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.";
|
|
389
|
+
default:
|
|
390
|
+
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.";
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function formatExecutionDuration(startedAt, finishedAt) {
|
|
394
|
+
const durationMs = Math.max(0, finishedAt.getTime() - startedAt.getTime());
|
|
395
|
+
if (durationMs < 1e3) {
|
|
396
|
+
return `${durationMs}ms`;
|
|
397
|
+
}
|
|
398
|
+
const durationSeconds = durationMs / 1e3;
|
|
399
|
+
if (durationSeconds < 60) {
|
|
400
|
+
return `${durationSeconds.toFixed(1)}s`;
|
|
401
|
+
}
|
|
402
|
+
const minutes = Math.floor(durationSeconds / 60);
|
|
403
|
+
const seconds = Math.round(durationSeconds % 60);
|
|
404
|
+
return `${minutes}m ${seconds}s`;
|
|
405
|
+
}
|
|
406
|
+
function writeExecutionLog(options = {}) {
|
|
407
|
+
try {
|
|
408
|
+
const startedAt = options.startedAt ?? /* @__PURE__ */ new Date();
|
|
409
|
+
const finishedAt = options.finishedAt ?? /* @__PURE__ */ new Date();
|
|
410
|
+
const status = options.status ?? "success";
|
|
411
|
+
helperTrace("execution-log:write:start", options.scope || "unknown");
|
|
412
|
+
createReportDirectory();
|
|
413
|
+
const reportPath = getAvailableFilePath(REPORT_DIR, `${getNowString(finishedAt)}-execution-log`, ".md");
|
|
414
|
+
const traceSnapshot = options.traceMessages ?? getTraceMessages();
|
|
415
|
+
const extraSections = options.extraSections || [];
|
|
416
|
+
const serializedError = options.error ? serializeError(options.error) : null;
|
|
417
|
+
const report = `# Execution Log
|
|
418
|
+
|
|
419
|
+
- \uC2DC\uC791 \uC2DC\uAC01: ${getHumanReadableNowString(startedAt)}
|
|
420
|
+
- \uC885\uB8CC \uC2DC\uAC01: ${getHumanReadableNowString(finishedAt)}
|
|
421
|
+
- \uC2E4\uD589 \uC2DC\uAC04: ${formatExecutionDuration(startedAt, finishedAt)}
|
|
422
|
+
- \uC0C1\uD0DC: \`${status}\`
|
|
423
|
+
- Scope: \`${options.scope || "unknown"}\`
|
|
424
|
+
- \uC791\uC5C5 \uACBD\uB85C: \`${process.cwd()}\`
|
|
425
|
+
- \uC2E4\uD589 \uC778\uC790: \`${JSON.stringify(options.args ?? process.argv.slice(2))}\`
|
|
426
|
+
- \uC2E4\uD589 \uD658\uACBD: \`${process.platform} ${process.arch} / Node ${process.version}\`
|
|
427
|
+
|
|
428
|
+
## Summary
|
|
429
|
+
|
|
430
|
+
${getExecutionLogSummary(status, options.title)}
|
|
431
|
+
${serializedError ? `
|
|
432
|
+
|
|
433
|
+
## Error
|
|
434
|
+
|
|
435
|
+
\`\`\`json
|
|
436
|
+
${JSON.stringify(serializedError, null, 2)}
|
|
437
|
+
\`\`\`` : ""}
|
|
438
|
+
|
|
439
|
+
## Trace
|
|
440
|
+
|
|
441
|
+
\`\`\`json
|
|
442
|
+
${JSON.stringify(traceSnapshot, null, 2)}
|
|
443
|
+
\`\`\`${extraSections.length ? `
|
|
444
|
+
${extraSections.map((section) => `
|
|
445
|
+
## ${section.heading}
|
|
446
|
+
|
|
447
|
+
${section.markdown}`).join("\n")}
|
|
448
|
+
` : "\n"}
|
|
449
|
+
`;
|
|
450
|
+
fs.writeFileSync(reportPath, report);
|
|
451
|
+
helperTrace("execution-log:write:done", reportPath);
|
|
452
|
+
return reportPath;
|
|
453
|
+
} catch (writeError) {
|
|
454
|
+
console.error("\u26A0\uFE0F \uC2E4\uD589 \uB85C\uADF8 \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
|
|
455
|
+
console.error(writeError);
|
|
456
|
+
return "";
|
|
457
|
+
}
|
|
458
|
+
}
|
|
378
459
|
function exitWithError(message, options = {}) {
|
|
379
460
|
const reportPath = writeErrorReport(options.error || new Error(message), {
|
|
380
461
|
...options,
|
|
@@ -425,6 +506,62 @@ function truncateCommitSubject(subject) {
|
|
|
425
506
|
}
|
|
426
507
|
return `${subject.slice(0, 69)}...`;
|
|
427
508
|
}
|
|
509
|
+
function formatReviewTargetFileCount(fileCount) {
|
|
510
|
+
return fileCount === 0 ? "\uBCC0\uACBD \uC5C6\uC74C" : `${fileCount}\uAC1C \uD30C\uC77C`;
|
|
511
|
+
}
|
|
512
|
+
function buildReviewTargetSectionTitle(target) {
|
|
513
|
+
return target.kind === "commit" ? `${target.hash} ${target.subject}` : `${target.hash} | ${target.subject}`;
|
|
514
|
+
}
|
|
515
|
+
function buildReviewTargetSummaryLine(target) {
|
|
516
|
+
if (target.kind === "commit") {
|
|
517
|
+
return `- ${target.hash} | ${target.subject} | ${target.author} | ${target.relativeDate}`;
|
|
518
|
+
}
|
|
519
|
+
return `- ${target.hash} | ${target.subject}`;
|
|
520
|
+
}
|
|
521
|
+
function buildReviewTargetDiffArgs(target, filePath) {
|
|
522
|
+
const reviewPathspecArgs = getReviewPathspecArgs();
|
|
523
|
+
if (target.kind === "commit") {
|
|
524
|
+
return filePath ? ["show", "--stat", "--patch", "--format=", target.hash, "--", filePath] : ["show", "--stat", "--patch", "--format=", target.hash, "--", ...reviewPathspecArgs];
|
|
525
|
+
}
|
|
526
|
+
const diffArgs = ["diff"];
|
|
527
|
+
if (target.kind === "staged") {
|
|
528
|
+
diffArgs.push("--cached");
|
|
529
|
+
}
|
|
530
|
+
diffArgs.push("--stat", "--patch", "--");
|
|
531
|
+
return filePath ? [...diffArgs, filePath] : [...diffArgs, ...reviewPathspecArgs];
|
|
532
|
+
}
|
|
533
|
+
function buildReviewTargetFileArgs(target) {
|
|
534
|
+
const reviewPathspecArgs = getReviewPathspecArgs();
|
|
535
|
+
if (target.kind === "commit") {
|
|
536
|
+
return ["show", "--pretty=format:", "--name-only", target.hash, "--", ...reviewPathspecArgs];
|
|
537
|
+
}
|
|
538
|
+
const diffArgs = ["diff"];
|
|
539
|
+
if (target.kind === "staged") {
|
|
540
|
+
diffArgs.push("--cached");
|
|
541
|
+
}
|
|
542
|
+
return [...diffArgs, "--name-only", "--", ...reviewPathspecArgs];
|
|
543
|
+
}
|
|
544
|
+
function getReviewTargetFiles(target) {
|
|
545
|
+
const output = runGitCommand(buildReviewTargetFileArgs(target), {
|
|
546
|
+
allowFailure: true
|
|
547
|
+
});
|
|
548
|
+
return output.split("\n").map((line) => line.trim()).filter(Boolean);
|
|
549
|
+
}
|
|
550
|
+
function createWorkingTreeReviewOption(kind) {
|
|
551
|
+
const files = getReviewTargetFiles({
|
|
552
|
+
hash: kind,
|
|
553
|
+
kind});
|
|
554
|
+
const subject = kind === "unstaged" ? "\uC544\uC9C1 git add \uD558\uC9C0 \uC54A\uC740 \uBCC0\uACBD\uC0AC\uD56D" : "git add \uB41C \uBCC0\uACBD\uC0AC\uD56D";
|
|
555
|
+
return {
|
|
556
|
+
author: "",
|
|
557
|
+
description: `${subject} | ${formatReviewTargetFileCount(files.length)}`,
|
|
558
|
+
hash: kind,
|
|
559
|
+
kind,
|
|
560
|
+
label: kind,
|
|
561
|
+
relativeDate: "",
|
|
562
|
+
subject
|
|
563
|
+
};
|
|
564
|
+
}
|
|
428
565
|
function getRecentCommitOptions() {
|
|
429
566
|
const output = runGitCommand(
|
|
430
567
|
["log", `-${COMMIT_FETCH_LIMIT}`, "--date=relative", "--pretty=format:%h%x09%an%x09%ar%x09%s"],
|
|
@@ -440,62 +577,61 @@ function getRecentCommitOptions() {
|
|
|
440
577
|
author,
|
|
441
578
|
description: `${author} | ${relativeDate}`,
|
|
442
579
|
hash,
|
|
580
|
+
kind: "commit",
|
|
443
581
|
label: `${hash} | ${truncateCommitSubject(subject)}`,
|
|
444
582
|
relativeDate,
|
|
445
583
|
subject
|
|
446
584
|
};
|
|
447
585
|
});
|
|
448
586
|
}
|
|
587
|
+
function getReviewTargetOptions() {
|
|
588
|
+
return [createWorkingTreeReviewOption("unstaged"), createWorkingTreeReviewOption("staged"), ...getRecentCommitOptions()];
|
|
589
|
+
}
|
|
449
590
|
function buildSelectedCommitSummary(commits) {
|
|
450
|
-
return commits.map((commit) =>
|
|
591
|
+
return commits.map((commit) => buildReviewTargetSummaryLine(commit)).join("\n");
|
|
451
592
|
}
|
|
452
593
|
function getReviewPathspecArgs() {
|
|
453
594
|
const { includePatterns, excludePatterns } = getGitDiffPathspecs();
|
|
454
595
|
return [...includePatterns, ...excludePatterns];
|
|
455
596
|
}
|
|
456
597
|
function buildSelectedCommitDiff(commits) {
|
|
457
|
-
const reviewPathspecArgs = getReviewPathspecArgs();
|
|
458
598
|
const sections = commits.map((commit) => {
|
|
459
|
-
const diff = runGitCommand(
|
|
599
|
+
const diff = runGitCommand(buildReviewTargetDiffArgs(commit), {
|
|
460
600
|
allowFailure: true,
|
|
461
601
|
trimOutput: false
|
|
462
602
|
}).trim();
|
|
463
603
|
if (!diff) {
|
|
464
604
|
return "";
|
|
465
605
|
}
|
|
466
|
-
return [`## ${commit
|
|
606
|
+
return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join("\n\n");
|
|
467
607
|
}).filter(Boolean).join("\n\n");
|
|
468
608
|
if (!sections) {
|
|
469
609
|
return "";
|
|
470
610
|
}
|
|
471
|
-
return ["# \uC120\uD0DD\uD55C \
|
|
611
|
+
return ["# \uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1", buildSelectedCommitSummary(commits), "", "# \uB9AC\uBDF0 \uB300\uC0C1 diff", sections].join("\n");
|
|
472
612
|
}
|
|
473
613
|
function getSelectedCommitFiles(commits) {
|
|
474
|
-
const reviewPathspecArgs = getReviewPathspecArgs();
|
|
475
614
|
const files = /* @__PURE__ */ new Set();
|
|
476
615
|
commits.forEach((commit) => {
|
|
477
|
-
|
|
478
|
-
allowFailure: true
|
|
479
|
-
});
|
|
480
|
-
output.split("\n").map((line) => line.trim()).filter(Boolean).forEach((filePath) => files.add(filePath));
|
|
616
|
+
getReviewTargetFiles(commit).forEach((filePath) => files.add(filePath));
|
|
481
617
|
});
|
|
482
618
|
return [...files];
|
|
483
619
|
}
|
|
484
620
|
function buildSelectedFileDiff(commits, filePath) {
|
|
485
621
|
const sections = commits.map((commit) => {
|
|
486
|
-
const diff = runGitCommand(
|
|
622
|
+
const diff = runGitCommand(buildReviewTargetDiffArgs(commit, filePath), {
|
|
487
623
|
allowFailure: true,
|
|
488
624
|
trimOutput: false
|
|
489
625
|
}).trim();
|
|
490
626
|
if (!diff) {
|
|
491
627
|
return "";
|
|
492
628
|
}
|
|
493
|
-
return [`## ${commit
|
|
629
|
+
return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join("\n\n");
|
|
494
630
|
}).filter(Boolean).join("\n\n");
|
|
495
631
|
if (!sections) {
|
|
496
632
|
return "";
|
|
497
633
|
}
|
|
498
|
-
return ["# \uC120\uD0DD\uD55C \
|
|
634
|
+
return ["# \uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1", buildSelectedCommitSummary(commits), "", `# \uD30C\uC77C: ${filePath}`, sections].join("\n\n");
|
|
499
635
|
}
|
|
500
636
|
function openReport(reportPath) {
|
|
501
637
|
const resolvedPath = path.resolve(reportPath);
|
|
@@ -681,13 +817,13 @@ async function showMultiSelect(question, options, windowSize = COMMIT_SELECTION_
|
|
|
681
817
|
});
|
|
682
818
|
}
|
|
683
819
|
async function selectReviewCommits() {
|
|
684
|
-
const commits =
|
|
820
|
+
const commits = getReviewTargetOptions();
|
|
685
821
|
if (commits.length === 0) {
|
|
686
|
-
console.log("\u2139\uFE0F \uB9AC\uBDF0\uD560 \
|
|
822
|
+
console.log("\u2139\uFE0F \uB9AC\uBDF0\uD560 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
687
823
|
return [];
|
|
688
824
|
}
|
|
689
825
|
return showMultiSelect(
|
|
690
|
-
"\uB9AC\uBDF0\uD560 \
|
|
826
|
+
"\uB9AC\uBDF0\uD560 \uB300\uC0C1\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.",
|
|
691
827
|
commits.map((commit) => ({
|
|
692
828
|
description: commit.description,
|
|
693
829
|
label: commit.label,
|
|
@@ -778,6 +914,13 @@ var ALLOWED_REASONING_EFFORTS = ["minimal", "low", "medium", "high"];
|
|
|
778
914
|
function shellQuote(value) {
|
|
779
915
|
return `'${value.replace(/'/g, `'\\''`)}'`;
|
|
780
916
|
}
|
|
917
|
+
function toShellOptionToken(value) {
|
|
918
|
+
const SIMPLE_SHELL_TOKEN_PATTERN = /^[A-Za-z0-9._:/=-]+$/;
|
|
919
|
+
if (SIMPLE_SHELL_TOKEN_PATTERN.test(value)) {
|
|
920
|
+
return value;
|
|
921
|
+
}
|
|
922
|
+
return shellQuote(value);
|
|
923
|
+
}
|
|
781
924
|
function getArgValue(flag) {
|
|
782
925
|
const index = args.indexOf(flag);
|
|
783
926
|
if (index === -1 || !args[index + 1]) {
|
|
@@ -857,9 +1000,9 @@ function getAliasFallbacks(primaryAlias) {
|
|
|
857
1000
|
}
|
|
858
1001
|
function buildClaudeExecCommand(options) {
|
|
859
1002
|
const { tempDiffPath: tempDiffPath2, prompt, systemPromptFiles, effort, model, fallbackModel } = options;
|
|
860
|
-
const modelOption = model ? `--model ${
|
|
861
|
-
const fallbackOption = model && fallbackModel ? `--fallback-model ${
|
|
862
|
-
const effortOption = `--effort ${
|
|
1003
|
+
const modelOption = model ? `--model ${toShellOptionToken(model)}` : "";
|
|
1004
|
+
const fallbackOption = model && fallbackModel ? `--fallback-model ${toShellOptionToken(fallbackModel)}` : "";
|
|
1005
|
+
const effortOption = `--effort ${toShellOptionToken(effort)}`;
|
|
863
1006
|
const appendedPromptFiles = systemPromptFiles.map((path3) => `--append-system-prompt-file ${shellQuote(path3)}`).join(" ");
|
|
864
1007
|
return `cat ${shellQuote(tempDiffPath2)} | claude ${[
|
|
865
1008
|
modelOption,
|
|
@@ -984,12 +1127,22 @@ function printNotice2(message) {
|
|
|
984
1127
|
console.warn(message);
|
|
985
1128
|
}
|
|
986
1129
|
}
|
|
1130
|
+
function normalizeEffort2(level) {
|
|
1131
|
+
if (level === "minimal") {
|
|
1132
|
+
return "low";
|
|
1133
|
+
}
|
|
1134
|
+
return level;
|
|
1135
|
+
}
|
|
987
1136
|
function resolveReasoningEffort2() {
|
|
988
1137
|
const customReasoningEffort = getArgValue2("--reasoning-effort");
|
|
989
1138
|
if (customReasoningEffort) {
|
|
990
1139
|
if (ALLOWED_REASONING_EFFORTS2.includes(customReasoningEffort)) {
|
|
991
|
-
|
|
992
|
-
|
|
1140
|
+
const normalized = normalizeEffort2(customReasoningEffort);
|
|
1141
|
+
trace3("reasoning:custom", `${customReasoningEffort} -> ${normalized}`);
|
|
1142
|
+
if (customReasoningEffort === "minimal") {
|
|
1143
|
+
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.");
|
|
1144
|
+
}
|
|
1145
|
+
return normalized;
|
|
993
1146
|
}
|
|
994
1147
|
printNotice2(
|
|
995
1148
|
`\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS2.join(
|
|
@@ -998,8 +1151,8 @@ function resolveReasoningEffort2() {
|
|
|
998
1151
|
);
|
|
999
1152
|
}
|
|
1000
1153
|
if (args2.includes("--flash")) {
|
|
1001
|
-
trace3("reasoning:flash-default", "
|
|
1002
|
-
return "
|
|
1154
|
+
trace3("reasoning:flash-default", "low");
|
|
1155
|
+
return "low";
|
|
1003
1156
|
}
|
|
1004
1157
|
if (args2.includes("--review")) {
|
|
1005
1158
|
trace3("reasoning:review-default", "high");
|
|
@@ -1194,7 +1347,7 @@ function buildGeminiFileReferenceSection(files) {
|
|
|
1194
1347
|
const existingFiles = files.filter((file) => fs.existsSync(file.path));
|
|
1195
1348
|
return {
|
|
1196
1349
|
count: existingFiles.length,
|
|
1197
|
-
|
|
1350
|
+
items: existingFiles.map((file) => `${file.display} ${toGeminiFileReference(file.path)}`)
|
|
1198
1351
|
};
|
|
1199
1352
|
}
|
|
1200
1353
|
var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
@@ -1213,19 +1366,19 @@ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
|
1213
1366
|
const ruleSection = buildGeminiFileReferenceSection(rules);
|
|
1214
1367
|
trace5("rules:loaded", `count=${ruleSection.count}`);
|
|
1215
1368
|
const reviewFormExists = fs.existsSync(resolvedReviewFormPath);
|
|
1216
|
-
const
|
|
1369
|
+
const reviewFormText = reviewFormExists ? `\uB9AC\uBDF0 \uC591\uC2DD ${toGeminiFileReference(resolvedReviewFormPath)}` : "\uB9AC\uBDF0 \uC591\uC2DD (\uC5C6\uC74C)";
|
|
1217
1370
|
trace5("reviewForm:status", reviewFormExists ? "exists" : "missing");
|
|
1218
1371
|
const reasoningInstruction = getReasoningInstruction(reasoningEffort);
|
|
1219
|
-
const
|
|
1220
|
-
\
|
|
1221
|
-
|
|
1222
|
-
\uB9AC\uBDF0 \
|
|
1223
|
-
${
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
\
|
|
1228
|
-
|
|
1372
|
+
const ruleText = ruleSection.items.join(" ") || "(\uC5C6\uC74C)";
|
|
1373
|
+
const diffText = `\uB9AC\uBDF0 \uB300\uC0C1 diff ${toGeminiFileReference(resolvedTempDiffPath)}`;
|
|
1374
|
+
const prompt = [
|
|
1375
|
+
"\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uC21C\uC11C\uB300\uB85C \uC77D\uACE0 \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.",
|
|
1376
|
+
`\uADDC\uCE59 \uD30C\uC77C: ${ruleText}`,
|
|
1377
|
+
`\uB9AC\uBDF0 \uC591\uC2DD \uD30C\uC77C: ${reviewFormText}`,
|
|
1378
|
+
`\uB9AC\uBDF0 \uB300\uC0C1 diff \uD30C\uC77C: ${diffText}`,
|
|
1379
|
+
"\uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.",
|
|
1380
|
+
`\uCD94\uB860 \uAC15\uB3C4 \uC9C0\uCE68: ${reasoningInstruction}`
|
|
1381
|
+
].join(" ");
|
|
1229
1382
|
trace5("prompt:prepared", `length=${prompt.length}`);
|
|
1230
1383
|
const modelCandidates = toUnique2(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
|
|
1231
1384
|
trace5("model:candidates", modelCandidates.join(", "));
|
|
@@ -1289,6 +1442,7 @@ function checkGeminiCliInstalled() {
|
|
|
1289
1442
|
var execAsync = util.promisify(exec);
|
|
1290
1443
|
async function main() {
|
|
1291
1444
|
const args4 = process.argv.slice(2);
|
|
1445
|
+
const startedAt = /* @__PURE__ */ new Date();
|
|
1292
1446
|
clearTraceMessages();
|
|
1293
1447
|
const isTest = isTestMode(args4);
|
|
1294
1448
|
const trace7 = createTraceLogger("review-one-by-one", args4);
|
|
@@ -1297,6 +1451,13 @@ async function main() {
|
|
|
1297
1451
|
let savedDiffPath = "";
|
|
1298
1452
|
let savedReportPath = "";
|
|
1299
1453
|
let selectedCommitSummary = "";
|
|
1454
|
+
let fileList = [];
|
|
1455
|
+
let executionLogPath = "";
|
|
1456
|
+
let executionStatus = "cancelled";
|
|
1457
|
+
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.";
|
|
1458
|
+
let executionError = null;
|
|
1459
|
+
let exitCode = 0;
|
|
1460
|
+
const fileExecutionLogs = [];
|
|
1300
1461
|
try {
|
|
1301
1462
|
trace7("service-selection:start");
|
|
1302
1463
|
service = await showSelectionAIService();
|
|
@@ -1325,22 +1486,24 @@ async function main() {
|
|
|
1325
1486
|
trace7("commit-selection:done", `count=${selectedCommits.length}`);
|
|
1326
1487
|
if (selectedCommits.length === 0) {
|
|
1327
1488
|
trace7("commit-selection:empty");
|
|
1328
|
-
|
|
1489
|
+
executionTitle = "\uC120\uD0DD\uB41C \uB9AC\uBDF0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.";
|
|
1490
|
+
console.log("\u2139\uFE0F \uC120\uD0DD\uB41C \uB9AC\uBDF0 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
|
|
1329
1491
|
deleteTempDiff();
|
|
1330
|
-
|
|
1492
|
+
return;
|
|
1331
1493
|
}
|
|
1332
1494
|
selectedCommitSummary = buildSelectedCommitSummary(selectedCommits);
|
|
1333
1495
|
trace7("commit-summary:prepared", selectedCommitSummary);
|
|
1334
1496
|
console.log("\u23F3 \uC120\uD0DD\uD55C \uCEE4\uBC0B\uC758 \uD30C\uC77C \uBAA9\uB85D\uACFC diff\uB97C \uC815\uB9AC\uD558\uB294 \uC911\uC785\uB2C8\uB2E4...");
|
|
1335
1497
|
trace7("files-command:run");
|
|
1336
|
-
|
|
1498
|
+
fileList = getSelectedCommitFiles(selectedCommits);
|
|
1337
1499
|
trace7("files-command:done", `fileCount=${fileList.length}`);
|
|
1338
1500
|
console.log(`\u{1F4C2} \uB9AC\uBDF0 \uB300\uC0C1 \uD30C\uC77C(${fileList.length}\uAC1C): ${formatReviewTargetFiles(fileList)}`);
|
|
1339
1501
|
if (fileList.length === 0) {
|
|
1340
1502
|
trace7("empty-file-list:exit");
|
|
1341
|
-
|
|
1503
|
+
executionTitle = "\uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1\uC5D0\uC11C \uB9AC\uBDF0\uD560 \uBCC0\uACBD\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.";
|
|
1504
|
+
console.log("\u2139\uFE0F \uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1\uC5D0\uC11C \uB9AC\uBDF0\uD560 \uBCC0\uACBD\uC744 \uCC3E\uC9C0 \uBABB\uD588\uC2B5\uB2C8\uB2E4.");
|
|
1342
1505
|
deleteTempDiff();
|
|
1343
|
-
|
|
1506
|
+
return;
|
|
1344
1507
|
}
|
|
1345
1508
|
trace7("report-dir:create:start");
|
|
1346
1509
|
createReportDirectory();
|
|
@@ -1370,6 +1533,15 @@ async function main() {
|
|
|
1370
1533
|
trace7("file-diff:build:done", `${file} | length=${fileDiff.length}`);
|
|
1371
1534
|
if (!fileDiff.trim()) {
|
|
1372
1535
|
trace7("file-diff:empty", file);
|
|
1536
|
+
fileExecutionLogs.push({
|
|
1537
|
+
command: null,
|
|
1538
|
+
errorSummary: null,
|
|
1539
|
+
file,
|
|
1540
|
+
index,
|
|
1541
|
+
resultLength: 0,
|
|
1542
|
+
status: "skipped",
|
|
1543
|
+
tempOneFileDiffPath
|
|
1544
|
+
});
|
|
1373
1545
|
return;
|
|
1374
1546
|
}
|
|
1375
1547
|
trace7("file-temp-diff:write:start", tempOneFileDiffPath);
|
|
@@ -1412,9 +1584,27 @@ ${result}
|
|
|
1412
1584
|
${command}`);
|
|
1413
1585
|
trace7("file-test-command:append:done", file);
|
|
1414
1586
|
}
|
|
1587
|
+
fileExecutionLogs.push({
|
|
1588
|
+
command,
|
|
1589
|
+
errorSummary: null,
|
|
1590
|
+
file,
|
|
1591
|
+
index,
|
|
1592
|
+
resultLength: result.length,
|
|
1593
|
+
status: "success",
|
|
1594
|
+
tempOneFileDiffPath
|
|
1595
|
+
});
|
|
1415
1596
|
trace7("file-review:end", file);
|
|
1416
1597
|
} catch (err) {
|
|
1417
1598
|
trace7("file-review:catch", `${file} | ${getErrorSummary(err)}`);
|
|
1599
|
+
fileExecutionLogs.push({
|
|
1600
|
+
command: command || null,
|
|
1601
|
+
errorSummary: getErrorSummary(err),
|
|
1602
|
+
file,
|
|
1603
|
+
index,
|
|
1604
|
+
resultLength: 0,
|
|
1605
|
+
status: "failed",
|
|
1606
|
+
tempOneFileDiffPath
|
|
1607
|
+
});
|
|
1418
1608
|
const errorLogPath = writeErrorReport(err, {
|
|
1419
1609
|
scope: "review-one-by-one:file",
|
|
1420
1610
|
args: args4,
|
|
@@ -1466,6 +1656,15 @@ ${getErrorSummary(err)}
|
|
|
1466
1656
|
trace7("parallel-review:await-start");
|
|
1467
1657
|
await Promise.all(promises);
|
|
1468
1658
|
trace7("parallel-review:await-done");
|
|
1659
|
+
const failedFileCount = fileExecutionLogs.filter((log) => log.status === "failed").length;
|
|
1660
|
+
const successfulFileCount = fileExecutionLogs.filter((log) => log.status === "success").length;
|
|
1661
|
+
if (failedFileCount > 0) {
|
|
1662
|
+
executionStatus = "partial_failure";
|
|
1663
|
+
executionTitle = `\uD30C\uC77C\uBCC4 \uB9AC\uBDF0 \uC911 \uC77C\uBD80\uAC00 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4. (\uC131\uACF5 ${successfulFileCount}\uAC74 / \uC2E4\uD328 ${failedFileCount}\uAC74)`;
|
|
1664
|
+
} else {
|
|
1665
|
+
executionStatus = "success";
|
|
1666
|
+
executionTitle = "\uD30C\uC77C\uBCC4 \uB9AC\uBDF0\uAC00 \uC131\uACF5\uC801\uC73C\uB85C \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
|
|
1667
|
+
}
|
|
1469
1668
|
console.log(`
|
|
1470
1669
|
\u2705 \uB9AC\uBDF0\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`);
|
|
1471
1670
|
console.log(`\u{1F4C4} \uB9AC\uD3EC\uD2B8 \uC800\uC7A5 \uC704\uCE58: ${savedReportPath}`);
|
|
@@ -1480,6 +1679,10 @@ ${getErrorSummary(err)}
|
|
|
1480
1679
|
} catch (error) {
|
|
1481
1680
|
trace7("review-flow:catch", getErrorSummary(error));
|
|
1482
1681
|
let errorReportPath = "";
|
|
1682
|
+
executionStatus = "failed";
|
|
1683
|
+
executionTitle = "\uD30C\uC77C\uBCC4 \uB9AC\uBDF0 \uC2E4\uD589 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
|
|
1684
|
+
executionError = error;
|
|
1685
|
+
exitCode = 1;
|
|
1483
1686
|
trace7("cleanup-temp-diff:start(catch)");
|
|
1484
1687
|
try {
|
|
1485
1688
|
deleteTempDiff();
|
|
@@ -1517,7 +1720,58 @@ ${JSON.stringify(
|
|
|
1517
1720
|
if (errorReportPath) {
|
|
1518
1721
|
console.error(`\u{1F4C4} \uC5D0\uB7EC \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${errorReportPath}`);
|
|
1519
1722
|
}
|
|
1520
|
-
|
|
1723
|
+
} finally {
|
|
1724
|
+
executionLogPath = writeExecutionLog({
|
|
1725
|
+
scope: "review-one-by-one",
|
|
1726
|
+
status: executionStatus,
|
|
1727
|
+
title: executionTitle,
|
|
1728
|
+
args: args4,
|
|
1729
|
+
startedAt,
|
|
1730
|
+
error: executionError,
|
|
1731
|
+
extraSections: [
|
|
1732
|
+
{
|
|
1733
|
+
heading: "Execution Context",
|
|
1734
|
+
markdown: `\`\`\`json
|
|
1735
|
+
${JSON.stringify(
|
|
1736
|
+
{
|
|
1737
|
+
service: service || null,
|
|
1738
|
+
selectedCommitSummary: selectedCommitSummary || null,
|
|
1739
|
+
fileList,
|
|
1740
|
+
tempDiffPath,
|
|
1741
|
+
savedDiffPath: savedDiffPath || null,
|
|
1742
|
+
savedReportPath: savedReportPath || null
|
|
1743
|
+
},
|
|
1744
|
+
null,
|
|
1745
|
+
2
|
|
1746
|
+
)}
|
|
1747
|
+
\`\`\``
|
|
1748
|
+
},
|
|
1749
|
+
{
|
|
1750
|
+
heading: "Generated Commands",
|
|
1751
|
+
markdown: `\`\`\`json
|
|
1752
|
+
${JSON.stringify(
|
|
1753
|
+
fileExecutionLogs.slice().sort((left, right) => left.index - right.index).map((log) => ({
|
|
1754
|
+
file: log.file,
|
|
1755
|
+
status: log.status,
|
|
1756
|
+
resultLength: log.resultLength,
|
|
1757
|
+
errorSummary: log.errorSummary,
|
|
1758
|
+
tempOneFileDiffPath: log.tempOneFileDiffPath,
|
|
1759
|
+
command: log.command
|
|
1760
|
+
})),
|
|
1761
|
+
null,
|
|
1762
|
+
2
|
|
1763
|
+
)}
|
|
1764
|
+
\`\`\``
|
|
1765
|
+
}
|
|
1766
|
+
]
|
|
1767
|
+
});
|
|
1768
|
+
if (executionLogPath) {
|
|
1769
|
+
const writeLog = executionStatus === "failed" ? console.error : console.log;
|
|
1770
|
+
writeLog(`\u{1F4DD} \uC2E4\uD589 \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${executionLogPath}`);
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
if (exitCode !== 0) {
|
|
1774
|
+
process.exit(exitCode);
|
|
1521
1775
|
}
|
|
1522
1776
|
}
|
|
1523
1777
|
main();
|