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.
Files changed (43) hide show
  1. package/dist/common/helper.cjs +227 -20
  2. package/dist/common/helper.cjs.map +1 -1
  3. package/dist/common/helper.d.cts +30 -1
  4. package/dist/common/helper.d.ts +30 -1
  5. package/dist/common/helper.js +226 -21
  6. package/dist/common/helper.js.map +1 -1
  7. package/dist/common/types.d.cts +3 -1
  8. package/dist/common/types.d.ts +3 -1
  9. package/dist/pr-review/claude/claude-commander.cjs +10 -3
  10. package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
  11. package/dist/pr-review/claude/claude-commander.js +10 -3
  12. package/dist/pr-review/claude/claude-commander.js.map +1 -1
  13. package/dist/pr-review/claude/installation-claude.cjs +1 -1
  14. package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
  15. package/dist/pr-review/claude/installation-claude.js +1 -1
  16. package/dist/pr-review/claude/installation-claude.js.map +1 -1
  17. package/dist/pr-review/codex/codex-commander.cjs +14 -4
  18. package/dist/pr-review/codex/codex-commander.cjs.map +1 -1
  19. package/dist/pr-review/codex/codex-commander.d.cts +1 -1
  20. package/dist/pr-review/codex/codex-commander.d.ts +1 -1
  21. package/dist/pr-review/codex/codex-commander.js +14 -4
  22. package/dist/pr-review/codex/codex-commander.js.map +1 -1
  23. package/dist/pr-review/codex/installation-codex.cjs +1 -1
  24. package/dist/pr-review/codex/installation-codex.cjs.map +1 -1
  25. package/dist/pr-review/codex/installation-codex.js +1 -1
  26. package/dist/pr-review/codex/installation-codex.js.map +1 -1
  27. package/dist/pr-review/gemini/gemini-commander.cjs +12 -12
  28. package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
  29. package/dist/pr-review/gemini/gemini-commander.js +12 -12
  30. package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
  31. package/dist/pr-review/gemini/installation-gemini.cjs +1 -1
  32. package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
  33. package/dist/pr-review/gemini/installation-gemini.js +1 -1
  34. package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
  35. package/dist/pr-review/review-one-by-one.cjs +296 -42
  36. package/dist/pr-review/review-one-by-one.cjs.map +1 -1
  37. package/dist/pr-review/review-one-by-one.js +296 -42
  38. package/dist/pr-review/review-one-by-one.js.map +1 -1
  39. package/dist/pr-review/review.cjs +327 -42
  40. package/dist/pr-review/review.cjs.map +1 -1
  41. package/dist/pr-review/review.js +327 -42
  42. package/dist/pr-review/review.js.map +1 -1
  43. package/package.json +1 -1
@@ -80,6 +80,9 @@ var ignoreList = [
80
80
  function isTestMode(args = process.argv.slice(2)) {
81
81
  return args.includes("--test");
82
82
  }
83
+ function shouldStreamAIOutput(args = process.argv.slice(2)) {
84
+ return args.includes("--stream-output");
85
+ }
83
86
  function clearTraceMessages() {
84
87
  traceMessages.length = 0;
85
88
  }
@@ -206,15 +209,51 @@ function runGitCommand(args, options = {}) {
206
209
  throw error;
207
210
  }
208
211
  }
212
+ function resolveShellLaunchConfig() {
213
+ const candidates = [];
214
+ const seen = /* @__PURE__ */ new Set();
215
+ const appendCandidate = (executable, shellArgs) => {
216
+ const normalizedExecutable = executable?.trim();
217
+ if (!normalizedExecutable) {
218
+ return;
219
+ }
220
+ if (path__default.default.isAbsolute(normalizedExecutable) && !fs__default.default.existsSync(normalizedExecutable)) {
221
+ return;
222
+ }
223
+ const key = `${normalizedExecutable}::${shellArgs.join("\0")}`;
224
+ if (seen.has(key)) {
225
+ return;
226
+ }
227
+ seen.add(key);
228
+ candidates.push({
229
+ executable: normalizedExecutable,
230
+ shellArgs
231
+ });
232
+ };
233
+ const shellFromEnv = process.env.SHELL?.trim();
234
+ const envShellName = shellFromEnv ? path__default.default.basename(shellFromEnv) : "";
235
+ if (["bash", "zsh", "ksh"].includes(envShellName)) {
236
+ appendCandidate(shellFromEnv, ["-lc"]);
237
+ }
238
+ ["/bin/bash", "/usr/bin/bash", "bash", "/bin/zsh", "/usr/bin/zsh", "zsh"].forEach((shellPath) => {
239
+ appendCandidate(shellPath, ["-lc"]);
240
+ });
241
+ ["/bin/sh", "/usr/bin/sh", "sh"].forEach((shellPath) => {
242
+ appendCandidate(shellPath, ["-c"]);
243
+ });
244
+ return candidates[0] || { executable: "sh", shellArgs: ["-c"] };
245
+ }
209
246
  async function executeShellCommandWithProgress(command, options = {}) {
210
247
  const { progressIntervalMs = 1e4, progressMessage = "\u23F3 \uBA85\uB839\uC744 \uC2E4\uD589\uD558\uB294 \uC911\uC785\uB2C8\uB2E4...", streamOutput = false } = options;
211
248
  const { spawn } = await import('child_process');
249
+ const shellLaunchConfig = resolveShellLaunchConfig();
212
250
  return new Promise((resolve, reject) => {
213
251
  let stdout = "";
214
252
  let stderr = "";
215
253
  const startedAt = Date.now();
216
254
  console.log(progressMessage);
217
- const child = spawn("/bin/zsh", ["-lc", command], {
255
+ helperTrace("shell-command:launcher", `${shellLaunchConfig.executable} ${shellLaunchConfig.shellArgs.join(" ")}`);
256
+ const child = spawn(shellLaunchConfig.executable, [...shellLaunchConfig.shellArgs, command], {
218
257
  stdio: ["ignore", "pipe", "pipe"]
219
258
  });
220
259
  const progressTimer = setInterval(() => {
@@ -249,11 +288,41 @@ async function executeShellCommandWithProgress(command, options = {}) {
249
288
  return;
250
289
  }
251
290
  const exitSummary = signal ? `signal=${signal}` : `code=${String(code ?? "unknown")}`;
252
- reject(new Error(`\uC258 \uBA85\uB839 \uC2E4\uD589 \uC2E4\uD328 (${exitSummary})${stderr.trim() ? `
253
- ${stderr.trim()}` : ""}`));
291
+ const failureDetails = {
292
+ code,
293
+ command,
294
+ signal,
295
+ stderr,
296
+ stdout
297
+ };
298
+ reject(createShellCommandExecutionError(failureDetails, exitSummary));
254
299
  });
255
300
  });
256
301
  }
302
+ function getShellCommandFailurePreview(failureDetails) {
303
+ const stderrText = failureDetails.stderr.trim();
304
+ const stdoutText = failureDetails.stdout.trim();
305
+ const combinedOutput = stderrText || stdoutText;
306
+ if (!combinedOutput) {
307
+ return "";
308
+ }
309
+ const MAX_PREVIEW_LENGTH = 4e3;
310
+ if (combinedOutput.length <= MAX_PREVIEW_LENGTH) {
311
+ return combinedOutput;
312
+ }
313
+ return combinedOutput.slice(-4e3);
314
+ }
315
+ function createShellCommandExecutionError(failureDetails, exitSummary) {
316
+ const failurePreview = getShellCommandFailurePreview(failureDetails);
317
+ const error = new Error(`\uC258 \uBA85\uB839 \uC2E4\uD589 \uC2E4\uD328 (${exitSummary})${failurePreview ? `
318
+ ${failurePreview}` : ""}`);
319
+ error.code = failureDetails.code;
320
+ error.signal = failureDetails.signal;
321
+ error.stdout = failureDetails.stdout;
322
+ error.stderr = failureDetails.stderr;
323
+ error.command = failureDetails.command;
324
+ return error;
325
+ }
257
326
  function formatReviewTargetFiles(files, visibleCount = 5) {
258
327
  if (files.length === 0) {
259
328
  return "(\uC5C6\uC74C)";
@@ -326,7 +395,7 @@ function serializeError(error) {
326
395
  }
327
396
  if (error && typeof error === "object") {
328
397
  const errorLike = error;
329
- const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs"];
398
+ const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs", "command"];
330
399
  extraKeys.forEach((key) => {
331
400
  if (errorLike[key] !== void 0) {
332
401
  serialized[key] = errorLike[key];
@@ -432,6 +501,87 @@ ${section.markdown}`).join("\n")}
432
501
  return "";
433
502
  }
434
503
  }
504
+ function getExecutionLogSummary(status, title) {
505
+ if (title) {
506
+ return title;
507
+ }
508
+ switch (status) {
509
+ case "success":
510
+ return "\uB9AC\uBDF0 \uC2E4\uD589\uC774 \uC131\uACF5\uC801\uC73C\uB85C \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.";
511
+ case "failed":
512
+ return "\uB9AC\uBDF0 \uC2E4\uD589 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.";
513
+ case "partial_failure":
514
+ 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.";
515
+ default:
516
+ 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.";
517
+ }
518
+ }
519
+ function formatExecutionDuration(startedAt, finishedAt) {
520
+ const durationMs = Math.max(0, finishedAt.getTime() - startedAt.getTime());
521
+ if (durationMs < 1e3) {
522
+ return `${durationMs}ms`;
523
+ }
524
+ const durationSeconds = durationMs / 1e3;
525
+ if (durationSeconds < 60) {
526
+ return `${durationSeconds.toFixed(1)}s`;
527
+ }
528
+ const minutes = Math.floor(durationSeconds / 60);
529
+ const seconds = Math.round(durationSeconds % 60);
530
+ return `${minutes}m ${seconds}s`;
531
+ }
532
+ function writeExecutionLog(options = {}) {
533
+ try {
534
+ const startedAt = options.startedAt ?? /* @__PURE__ */ new Date();
535
+ const finishedAt = options.finishedAt ?? /* @__PURE__ */ new Date();
536
+ const status = options.status ?? "success";
537
+ helperTrace("execution-log:write:start", options.scope || "unknown");
538
+ createReportDirectory();
539
+ const reportPath = getAvailableFilePath(REPORT_DIR, `${getNowString(finishedAt)}-execution-log`, ".md");
540
+ const traceSnapshot = options.traceMessages ?? getTraceMessages();
541
+ const extraSections = options.extraSections || [];
542
+ const serializedError = options.error ? serializeError(options.error) : null;
543
+ const report = `# Execution Log
544
+
545
+ - \uC2DC\uC791 \uC2DC\uAC01: ${getHumanReadableNowString(startedAt)}
546
+ - \uC885\uB8CC \uC2DC\uAC01: ${getHumanReadableNowString(finishedAt)}
547
+ - \uC2E4\uD589 \uC2DC\uAC04: ${formatExecutionDuration(startedAt, finishedAt)}
548
+ - \uC0C1\uD0DC: \`${status}\`
549
+ - Scope: \`${options.scope || "unknown"}\`
550
+ - \uC791\uC5C5 \uACBD\uB85C: \`${process.cwd()}\`
551
+ - \uC2E4\uD589 \uC778\uC790: \`${JSON.stringify(options.args ?? process.argv.slice(2))}\`
552
+ - \uC2E4\uD589 \uD658\uACBD: \`${process.platform} ${process.arch} / Node ${process.version}\`
553
+
554
+ ## Summary
555
+
556
+ ${getExecutionLogSummary(status, options.title)}
557
+ ${serializedError ? `
558
+
559
+ ## Error
560
+
561
+ \`\`\`json
562
+ ${JSON.stringify(serializedError, null, 2)}
563
+ \`\`\`` : ""}
564
+
565
+ ## Trace
566
+
567
+ \`\`\`json
568
+ ${JSON.stringify(traceSnapshot, null, 2)}
569
+ \`\`\`${extraSections.length ? `
570
+ ${extraSections.map((section) => `
571
+ ## ${section.heading}
572
+
573
+ ${section.markdown}`).join("\n")}
574
+ ` : "\n"}
575
+ `;
576
+ fs__default.default.writeFileSync(reportPath, report);
577
+ helperTrace("execution-log:write:done", reportPath);
578
+ return reportPath;
579
+ } catch (writeError) {
580
+ console.error("\u26A0\uFE0F \uC2E4\uD589 \uB85C\uADF8 \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
581
+ console.error(writeError);
582
+ return "";
583
+ }
584
+ }
435
585
  function exitWithError(message, options = {}) {
436
586
  const reportPath = writeErrorReport(options.error || new Error(message), {
437
587
  ...options,
@@ -489,6 +639,62 @@ function truncateCommitSubject(subject) {
489
639
  }
490
640
  return `${subject.slice(0, 69)}...`;
491
641
  }
642
+ function formatReviewTargetFileCount(fileCount) {
643
+ return fileCount === 0 ? "\uBCC0\uACBD \uC5C6\uC74C" : `${fileCount}\uAC1C \uD30C\uC77C`;
644
+ }
645
+ function buildReviewTargetSectionTitle(target) {
646
+ return target.kind === "commit" ? `${target.hash} ${target.subject}` : `${target.hash} | ${target.subject}`;
647
+ }
648
+ function buildReviewTargetSummaryLine(target) {
649
+ if (target.kind === "commit") {
650
+ return `- ${target.hash} | ${target.subject} | ${target.author} | ${target.relativeDate}`;
651
+ }
652
+ return `- ${target.hash} | ${target.subject}`;
653
+ }
654
+ function buildReviewTargetDiffArgs(target, filePath) {
655
+ const reviewPathspecArgs = getReviewPathspecArgs();
656
+ if (target.kind === "commit") {
657
+ return filePath ? ["show", "--stat", "--patch", "--format=", target.hash, "--", filePath] : ["show", "--stat", "--patch", "--format=", target.hash, "--", ...reviewPathspecArgs];
658
+ }
659
+ const diffArgs = ["diff"];
660
+ if (target.kind === "staged") {
661
+ diffArgs.push("--cached");
662
+ }
663
+ diffArgs.push("--stat", "--patch", "--");
664
+ return filePath ? [...diffArgs, filePath] : [...diffArgs, ...reviewPathspecArgs];
665
+ }
666
+ function buildReviewTargetFileArgs(target) {
667
+ const reviewPathspecArgs = getReviewPathspecArgs();
668
+ if (target.kind === "commit") {
669
+ return ["show", "--pretty=format:", "--name-only", target.hash, "--", ...reviewPathspecArgs];
670
+ }
671
+ const diffArgs = ["diff"];
672
+ if (target.kind === "staged") {
673
+ diffArgs.push("--cached");
674
+ }
675
+ return [...diffArgs, "--name-only", "--", ...reviewPathspecArgs];
676
+ }
677
+ function getReviewTargetFiles(target) {
678
+ const output = runGitCommand(buildReviewTargetFileArgs(target), {
679
+ allowFailure: true
680
+ });
681
+ return output.split("\n").map((line) => line.trim()).filter(Boolean);
682
+ }
683
+ function createWorkingTreeReviewOption(kind) {
684
+ const files = getReviewTargetFiles({
685
+ hash: kind,
686
+ kind});
687
+ const subject = kind === "unstaged" ? "\uC544\uC9C1 git add \uD558\uC9C0 \uC54A\uC740 \uBCC0\uACBD\uC0AC\uD56D" : "git add \uB41C \uBCC0\uACBD\uC0AC\uD56D";
688
+ return {
689
+ author: "",
690
+ description: `${subject} | ${formatReviewTargetFileCount(files.length)}`,
691
+ hash: kind,
692
+ kind,
693
+ label: kind,
694
+ relativeDate: "",
695
+ subject
696
+ };
697
+ }
492
698
  function getRecentCommitOptions() {
493
699
  const output = runGitCommand(
494
700
  ["log", `-${COMMIT_FETCH_LIMIT}`, "--date=relative", "--pretty=format:%h%x09%an%x09%ar%x09%s"],
@@ -504,62 +710,61 @@ function getRecentCommitOptions() {
504
710
  author,
505
711
  description: `${author} | ${relativeDate}`,
506
712
  hash,
713
+ kind: "commit",
507
714
  label: `${hash} | ${truncateCommitSubject(subject)}`,
508
715
  relativeDate,
509
716
  subject
510
717
  };
511
718
  });
512
719
  }
720
+ function getReviewTargetOptions() {
721
+ return [createWorkingTreeReviewOption("unstaged"), createWorkingTreeReviewOption("staged"), ...getRecentCommitOptions()];
722
+ }
513
723
  function buildSelectedCommitSummary(commits) {
514
- return commits.map((commit) => `- ${commit.hash} | ${commit.subject} | ${commit.author} | ${commit.relativeDate}`).join("\n");
724
+ return commits.map((commit) => buildReviewTargetSummaryLine(commit)).join("\n");
515
725
  }
516
726
  function getReviewPathspecArgs() {
517
727
  const { includePatterns, excludePatterns } = getGitDiffPathspecs();
518
728
  return [...includePatterns, ...excludePatterns];
519
729
  }
520
730
  function buildSelectedCommitDiff(commits) {
521
- const reviewPathspecArgs = getReviewPathspecArgs();
522
731
  const sections = commits.map((commit) => {
523
- const diff = runGitCommand(["show", "--stat", "--patch", "--format=", commit.hash, "--", ...reviewPathspecArgs], {
732
+ const diff = runGitCommand(buildReviewTargetDiffArgs(commit), {
524
733
  allowFailure: true,
525
734
  trimOutput: false
526
735
  }).trim();
527
736
  if (!diff) {
528
737
  return "";
529
738
  }
530
- return [`## ${commit.hash} ${commit.subject}`, diff].join("\n\n");
739
+ return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join("\n\n");
531
740
  }).filter(Boolean).join("\n\n");
532
741
  if (!sections) {
533
742
  return "";
534
743
  }
535
- return ["# \uC120\uD0DD\uD55C \uCEE4\uBC0B", buildSelectedCommitSummary(commits), "", "# \uB9AC\uBDF0 \uB300\uC0C1 diff", sections].join("\n");
744
+ return ["# \uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1", buildSelectedCommitSummary(commits), "", "# \uB9AC\uBDF0 \uB300\uC0C1 diff", sections].join("\n");
536
745
  }
537
746
  function getSelectedCommitFiles(commits) {
538
- const reviewPathspecArgs = getReviewPathspecArgs();
539
747
  const files = /* @__PURE__ */ new Set();
540
748
  commits.forEach((commit) => {
541
- const output = runGitCommand(["show", "--pretty=format:", "--name-only", commit.hash, "--", ...reviewPathspecArgs], {
542
- allowFailure: true
543
- });
544
- output.split("\n").map((line) => line.trim()).filter(Boolean).forEach((filePath) => files.add(filePath));
749
+ getReviewTargetFiles(commit).forEach((filePath) => files.add(filePath));
545
750
  });
546
751
  return [...files];
547
752
  }
548
753
  function buildSelectedFileDiff(commits, filePath) {
549
754
  const sections = commits.map((commit) => {
550
- const diff = runGitCommand(["show", "--stat", "--patch", "--format=", commit.hash, "--", filePath], {
755
+ const diff = runGitCommand(buildReviewTargetDiffArgs(commit, filePath), {
551
756
  allowFailure: true,
552
757
  trimOutput: false
553
758
  }).trim();
554
759
  if (!diff) {
555
760
  return "";
556
761
  }
557
- return [`## ${commit.hash} ${commit.subject}`, diff].join("\n\n");
762
+ return [`## ${buildReviewTargetSectionTitle(commit)}`, diff].join("\n\n");
558
763
  }).filter(Boolean).join("\n\n");
559
764
  if (!sections) {
560
765
  return "";
561
766
  }
562
- return ["# \uC120\uD0DD\uD55C \uCEE4\uBC0B", buildSelectedCommitSummary(commits), "", `# \uD30C\uC77C: ${filePath}`, sections].join("\n\n");
767
+ return ["# \uC120\uD0DD\uD55C \uB9AC\uBDF0 \uB300\uC0C1", buildSelectedCommitSummary(commits), "", `# \uD30C\uC77C: ${filePath}`, sections].join("\n\n");
563
768
  }
564
769
  function openReport(reportPath) {
565
770
  const resolvedPath = path__default.default.resolve(reportPath);
@@ -745,13 +950,13 @@ async function showMultiSelect(question, options, windowSize = COMMIT_SELECTION_
745
950
  });
746
951
  }
747
952
  async function selectReviewCommits() {
748
- const commits = getRecentCommitOptions();
953
+ const commits = getReviewTargetOptions();
749
954
  if (commits.length === 0) {
750
- console.log("\u2139\uFE0F \uB9AC\uBDF0\uD560 \uCD5C\uADFC \uCEE4\uBC0B\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
955
+ console.log("\u2139\uFE0F \uB9AC\uBDF0\uD560 \uB300\uC0C1\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
751
956
  return [];
752
957
  }
753
958
  return showMultiSelect(
754
- "\uB9AC\uBDF0\uD560 \uCEE4\uBC0B\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.",
959
+ "\uB9AC\uBDF0\uD560 \uB300\uC0C1\uC744 \uC120\uD0DD\uD574\uC8FC\uC138\uC694.",
755
960
  commits.map((commit) => ({
756
961
  description: commit.description,
757
962
  label: commit.label,
@@ -882,9 +1087,11 @@ exports.reviewFormPath = reviewFormPath;
882
1087
  exports.rulesPath = rulesPath;
883
1088
  exports.selectAIService = selectAIService;
884
1089
  exports.selectReviewCommits = selectReviewCommits;
1090
+ exports.shouldStreamAIOutput = shouldStreamAIOutput;
885
1091
  exports.showMultiSelect = showMultiSelect;
886
1092
  exports.showSelectionAIService = showSelectionAIService;
887
1093
  exports.tempDiffPath = tempDiffPath;
888
1094
  exports.writeErrorReport = writeErrorReport;
1095
+ exports.writeExecutionLog = writeExecutionLog;
889
1096
  //# sourceMappingURL=helper.cjs.map
890
1097
  //# sourceMappingURL=helper.cjs.map