sales-frontend-gemini-cli 0.3.1 → 0.4.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 (77) hide show
  1. package/dist/common/helper.cjs +54 -3
  2. package/dist/common/helper.cjs.map +1 -1
  3. package/dist/common/helper.d.cts +15 -1
  4. package/dist/common/helper.d.ts +15 -1
  5. package/dist/common/helper.js +53 -4
  6. package/dist/common/helper.js.map +1 -1
  7. package/dist/{pr-review/gemini → etc}/installation-gcloud.cjs +1 -1
  8. package/dist/etc/installation-gcloud.cjs.map +1 -0
  9. package/dist/{pr-review/gemini → etc}/installation-gcloud.js +1 -1
  10. package/dist/etc/installation-gcloud.js.map +1 -0
  11. package/dist/{pr-review/gemini → etc}/interactive-version/index.cjs +2 -2
  12. package/dist/etc/interactive-version/index.cjs.map +1 -0
  13. package/dist/{pr-review/gemini → etc}/interactive-version/index.js +2 -2
  14. package/dist/etc/interactive-version/index.js.map +1 -0
  15. package/dist/{pr-review/gemini → etc}/login.cjs +1 -1
  16. package/dist/etc/login.cjs.map +1 -0
  17. package/dist/{pr-review/gemini → etc}/login.js +1 -1
  18. package/dist/etc/login.js.map +1 -0
  19. package/dist/{pr-review/gemini → etc}/vertex-version/index.cjs +1 -1
  20. package/dist/etc/vertex-version/index.cjs.map +1 -0
  21. package/dist/{pr-review/gemini → etc}/vertex-version/index.js +1 -1
  22. package/dist/etc/vertex-version/index.js.map +1 -0
  23. package/dist/pr-review/claude/claude-commander.cjs +26 -0
  24. package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
  25. package/dist/pr-review/claude/claude-commander.js +26 -0
  26. package/dist/pr-review/claude/claude-commander.js.map +1 -1
  27. package/dist/pr-review/claude/installation-claude.cjs +38 -1
  28. package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
  29. package/dist/pr-review/claude/installation-claude.js +33 -1
  30. package/dist/pr-review/claude/installation-claude.js.map +1 -1
  31. package/dist/pr-review/codex/codex-commander.cjs +88 -0
  32. package/dist/pr-review/codex/codex-commander.cjs.map +1 -0
  33. package/dist/pr-review/codex/codex-commander.d.cts +12 -0
  34. package/dist/pr-review/codex/codex-commander.d.ts +12 -0
  35. package/dist/pr-review/codex/codex-commander.js +80 -0
  36. package/dist/pr-review/codex/codex-commander.js.map +1 -0
  37. package/dist/pr-review/codex/installation-codex.cjs +62 -0
  38. package/dist/pr-review/codex/installation-codex.cjs.map +1 -0
  39. package/dist/pr-review/codex/installation-codex.d.cts +3 -0
  40. package/dist/pr-review/codex/installation-codex.d.ts +3 -0
  41. package/dist/pr-review/codex/installation-codex.js +55 -0
  42. package/dist/pr-review/codex/installation-codex.js.map +1 -0
  43. package/dist/pr-review/gemini/gemini-commander.cjs +23 -0
  44. package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
  45. package/dist/pr-review/gemini/gemini-commander.js +23 -0
  46. package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
  47. package/dist/pr-review/gemini/installation-gemini.cjs +35 -0
  48. package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
  49. package/dist/pr-review/gemini/installation-gemini.js +30 -0
  50. package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
  51. package/dist/pr-review/review-one-by-one.cjs +260 -31
  52. package/dist/pr-review/review-one-by-one.cjs.map +1 -1
  53. package/dist/pr-review/review-one-by-one.js +259 -30
  54. package/dist/pr-review/review-one-by-one.js.map +1 -1
  55. package/dist/pr-review/review.cjs +228 -14
  56. package/dist/pr-review/review.cjs.map +1 -1
  57. package/dist/pr-review/review.js +228 -14
  58. package/dist/pr-review/review.js.map +1 -1
  59. package/package.json +1 -1
  60. package/src/common/form/review-form.md +1 -1
  61. package/src/common/rules/review-rules.md +2 -0
  62. package/dist/pr-review/gemini/installation-gcloud.cjs.map +0 -1
  63. package/dist/pr-review/gemini/installation-gcloud.js.map +0 -1
  64. package/dist/pr-review/gemini/interactive-version/index.cjs.map +0 -1
  65. package/dist/pr-review/gemini/interactive-version/index.js.map +0 -1
  66. package/dist/pr-review/gemini/login.cjs.map +0 -1
  67. package/dist/pr-review/gemini/login.js.map +0 -1
  68. package/dist/pr-review/gemini/vertex-version/index.cjs.map +0 -1
  69. package/dist/pr-review/gemini/vertex-version/index.js.map +0 -1
  70. /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.cts +0 -0
  71. /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.ts +0 -0
  72. /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.cts +0 -0
  73. /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.ts +0 -0
  74. /package/dist/{pr-review/gemini → etc}/login.d.cts +0 -0
  75. /package/dist/{pr-review/gemini → etc}/login.d.ts +0 -0
  76. /package/dist/{pr-review/gemini → etc}/vertex-version/index.d.cts +0 -0
  77. /package/dist/{pr-review/gemini → etc}/vertex-version/index.d.ts +0 -0
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var child_process = require('child_process');
5
- var fs4 = require('fs');
5
+ var fs5 = require('fs');
6
6
  var util = require('util');
7
7
  var path = require('path');
8
8
  var readline = require('readline');
@@ -11,7 +11,7 @@ var url = require('url');
11
11
  var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
12
12
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
13
13
 
14
- var fs4__default = /*#__PURE__*/_interopDefault(fs4);
14
+ var fs5__default = /*#__PURE__*/_interopDefault(fs5);
15
15
  var util__default = /*#__PURE__*/_interopDefault(util);
16
16
  var path__default = /*#__PURE__*/_interopDefault(path);
17
17
  var readline__default = /*#__PURE__*/_interopDefault(readline);
@@ -39,27 +39,39 @@ var ignoreList = [
39
39
  ".review-report/"
40
40
  // 생성되는 리포트 폴더도 제외
41
41
  ];
42
+ function isTestMode(args4 = process.argv.slice(2)) {
43
+ return args4.includes("--test");
44
+ }
45
+ function createTraceLogger(scope, args4 = process.argv.slice(2)) {
46
+ const enabled = isTestMode(args4);
47
+ return (step, detail) => {
48
+ if (!enabled) {
49
+ return;
50
+ }
51
+ console.log(`[TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ""}`);
52
+ };
53
+ }
42
54
  function getNextFilePath(dir, baseName, extension) {
43
55
  let counter = 1;
44
56
  while (true) {
45
57
  const filePath = path__default.default.join(dir, `${baseName}-${counter}${extension}`);
46
- if (!fs4__default.default.existsSync(filePath)) {
58
+ if (!fs5__default.default.existsSync(filePath)) {
47
59
  return filePath;
48
60
  }
49
61
  counter++;
50
62
  }
51
63
  }
52
64
  function deleteFile(filePath) {
53
- if (fs4__default.default.existsSync(filePath)) {
54
- fs4__default.default.unlinkSync(filePath);
65
+ if (fs5__default.default.existsSync(filePath)) {
66
+ fs5__default.default.unlinkSync(filePath);
55
67
  }
56
68
  }
57
69
  function deleteTempDiff() {
58
70
  deleteFile(tempDiffPath);
59
71
  }
60
72
  function createReportDirectory() {
61
- if (!fs4__default.default.existsSync(REPORT_DIR)) {
62
- fs4__default.default.mkdirSync(REPORT_DIR, { recursive: true });
73
+ if (!fs5__default.default.existsSync(REPORT_DIR)) {
74
+ fs5__default.default.mkdirSync(REPORT_DIR, { recursive: true });
63
75
  }
64
76
  }
65
77
  function getNowString() {
@@ -81,25 +93,60 @@ function getGitDiffFilter() {
81
93
  return { includeParams, excludeParams };
82
94
  }
83
95
  function openReport(reportPath) {
96
+ const resolvedPath = path__default.default.resolve(reportPath);
97
+ const { platform } = process;
98
+ const openWithChrome = () => {
99
+ if (platform === "darwin") {
100
+ child_process.execSync(`open -a "Google Chrome" "${resolvedPath}"`, { stdio: "ignore" });
101
+ return true;
102
+ }
103
+ if (platform === "linux") {
104
+ child_process.execSync(`google-chrome "${resolvedPath}"`, { stdio: "ignore" });
105
+ return true;
106
+ }
107
+ return false;
108
+ };
109
+ const openWithDefaultBrowser = () => {
110
+ if (platform === "darwin") {
111
+ child_process.execSync(`open "${resolvedPath}"`, { stdio: "ignore" });
112
+ return true;
113
+ }
114
+ if (platform === "linux") {
115
+ child_process.execSync(`xdg-open "${resolvedPath}"`, { stdio: "ignore" });
116
+ return true;
117
+ }
118
+ return false;
119
+ };
120
+ try {
121
+ if (openWithChrome()) {
122
+ console.log("\u{1F680} Google Chrome\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
123
+ return;
124
+ }
125
+ } catch {
126
+ }
84
127
  try {
85
- child_process.execSync(`open -a "Google Chrome" "${path__default.default.resolve(reportPath)}"`);
86
- console.log(`\u{1F680} \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.`);
128
+ if (openWithDefaultBrowser()) {
129
+ console.log("\u{1F680} \uAE30\uBCF8 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
130
+ return;
131
+ }
87
132
  } catch (e) {
88
133
  console.error("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30 \uC2E4\uD328:", e);
134
+ return;
89
135
  }
136
+ console.error(`\u26A0\uFE0F \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD50C\uB7AB\uD3FC\uC785\uB2C8\uB2E4: ${platform}`);
90
137
  }
91
138
  function getDiffArgs() {
92
- const args3 = process.argv.slice(2);
93
- const commitIndex = args3.indexOf("--commit");
139
+ const args4 = process.argv.slice(2);
140
+ const commitIndex = args4.indexOf("--commit");
94
141
  const { includeParams, excludeParams } = getGitDiffFilter();
95
142
  let diffArgs = "";
96
143
  if (commitIndex !== -1) {
97
- const commitHash = args3[commitIndex + 1];
144
+ const commitHash = args4[commitIndex + 1];
98
145
  if (!commitHash) {
99
146
  console.error("\u274C \uCEE4\uBC0B \uD574\uC2DC\uAC00 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
100
147
  process.exit(1);
101
148
  }
102
- const nextArg = args3[commitIndex + 2];
149
+ const nextArg = args4[commitIndex + 2];
103
150
  let n = 0;
104
151
  if (nextArg && !nextArg.startsWith("--")) {
105
152
  n = parseInt(nextArg, 10);
@@ -136,7 +183,9 @@ async function showSelectionAIService() {
136
183
  }
137
184
  firstRender = false;
138
185
  readline__default.default.clearScreenDown(process.stdout);
139
- process.stdout.write("\u{1F916} AI \uC11C\uBE44\uC2A4\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\x1B[33m\u2191\u2193 \uBC29\uD5A5\uD0A4\x1B[0m \uC774\uB3D9, \x1B[33mEnter\x1B[0m \uC120\uD0DD):\n");
186
+ process.stdout.write(
187
+ "\u{1F916} AI \uC11C\uBE44\uC2A4\uB97C \uC120\uD0DD\uD574\uC8FC\uC138\uC694 (\x1B[33m\u2191\u2193 \uBC29\uD5A5\uD0A4\x1B[0m \uC774\uB3D9, \x1B[33mEnter\x1B[0m \uC120\uD0DD):\n"
188
+ );
140
189
  AIServices.forEach((service, index) => {
141
190
  if (index === selectedIndex) {
142
191
  process.stdout.write(` \x1B[36m>\x1B[0m \x1B[36m\u25C9\x1B[0m \x1B[1m${service}\x1B[0m
@@ -182,20 +231,26 @@ async function showSelectionAIService() {
182
231
  });
183
232
  }
184
233
  var args = process.argv.slice(2);
234
+ var trace = createTraceLogger("claude-commander", args);
185
235
  var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
236
+ trace("createClaudeCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
186
237
  let modelOption = "";
187
238
  if (args.includes("--review")) {
188
239
  modelOption = "--model opus";
240
+ trace("model:review", modelOption);
189
241
  } else if (args.includes("--flash")) {
190
242
  modelOption = "--model haiku";
243
+ trace("model:flash", modelOption);
191
244
  } else {
192
245
  const modelIndex = args.indexOf("--model");
193
246
  if (modelIndex !== -1 && args[modelIndex + 1]) {
194
247
  console.warn("\u26A0\uFE0F \uC9C0\uC815\uD55C \uBAA8\uB378\uC774 \uC5C6\uB294 \uACBD\uC6B0, \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD558\uB2C8 \uC8FC\uC758\uD558\uC138\uC694.");
195
248
  modelOption = `--model ${args[modelIndex + 1]}`;
249
+ trace("model:custom", modelOption);
196
250
  } else {
197
251
  console.warn("\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uAE30\uBCF8 \uBAA8\uB378\uC778 sonnet\uC744 \uC0AC\uC6A9\uD569\uB2C8\uB2E4.");
198
252
  modelOption = "--model sonnet";
253
+ trace("model:default", modelOption);
199
254
  }
200
255
  }
201
256
  const rules = [
@@ -203,51 +258,152 @@ var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
203
258
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
204
259
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
205
260
  ];
206
- const systemPromptFiles = rules.filter((rule) => fs4__default.default.existsSync(rule.path)).map((rule) => `--append-system-prompt-file ${rule.path}`).join(" ");
207
- const reviewFormOption = fs4__default.default.existsSync(reviewFormPath2) ? `--append-system-prompt-file ${reviewFormPath2}` : "";
261
+ const systemPromptFiles = rules.filter((rule) => fs5__default.default.existsSync(rule.path)).map((rule) => `--append-system-prompt-file ${rule.path}`).join(" ");
262
+ trace(
263
+ "rules:loaded",
264
+ `count=${systemPromptFiles ? systemPromptFiles.split("--append-system-prompt-file").length - 1 : 0}`
265
+ );
266
+ const reviewFormOption = fs5__default.default.existsSync(reviewFormPath2) ? `--append-system-prompt-file ${reviewFormPath2}` : "";
267
+ trace("reviewForm:status", reviewFormOption ? "exists" : "missing");
208
268
  const command = `cat ${tempDiffPath2} | claude ${modelOption} ${systemPromptFiles} ${reviewFormOption} -p "\uC704 \uADDC\uCE59\uB4E4\uC744 \uCC38\uACE0\uD558\uC5EC \uC774 diff\uB97C \uCF54\uB4DC\uB9AC\uBDF0\uD574\uC918. \uB9AC\uBDF0\uC591\uC2DD\uC5D0 \uB9DE\uCDB0\uC11C \uC791\uC131\uD574\uC918."`;
269
+ trace("command:created");
209
270
  if (args.includes("--test")) {
210
271
  const safeCommand = command.replace(/"/g, '\\"');
272
+ trace("test-mode:return-preview");
211
273
  return `echo "[TEST MODE] Claude \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
212
274
 
213
275
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
214
276
  ${safeCommand}"`;
215
277
  }
278
+ trace("createClaudeCommand:end");
216
279
  return command;
217
280
  };
281
+ var trace2 = createTraceLogger("installation-claude");
218
282
  function checkClaudeCliInstalled() {
283
+ trace2("checkClaudeCliInstalled:start");
219
284
  try {
285
+ trace2("version-check:run", "claude --version");
220
286
  child_process.execSync("claude --version", { stdio: "ignore" });
287
+ trace2("version-check:ok");
221
288
  } catch {
222
- console.log("\u2139\uFE0F claude-cli\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uB97C \uC9C4\uD589\uD569\uB2C8\uB2E4... npm install -g @anthropic-ai/claude-code");
289
+ trace2("version-check:failed", "install-start");
290
+ console.log(
291
+ "\u2139\uFE0F claude-cli\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uB97C \uC9C4\uD589\uD569\uB2C8\uB2E4... npm install -g @anthropic-ai/claude-code"
292
+ );
223
293
  try {
224
294
  child_process.execSync("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
295
+ trace2("install:ok", "exit(1) for login");
225
296
  console.log("\u2705 claude-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
226
297
  console.log("\u26A0\uFE0F claude-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
227
298
  console.log(' \uD130\uBBF8\uB110\uC5D0\uC11C "claude" \uB97C \uC785\uB825\uD558\uC5EC \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC744 \uC644\uB8CC\uD55C \uD6C4, \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.');
228
299
  process.exit(1);
229
300
  } catch (installError) {
301
+ trace2("install:failed");
230
302
  console.error("\u274C claude-cli \uC124\uCE58 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uAD8C\uD55C \uBB38\uC81C\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4 (sudo \uD544\uC694).");
231
303
  console.error(installError);
232
304
  process.exit(1);
233
305
  }
234
306
  }
307
+ trace2("checkClaudeCliInstalled:end");
235
308
  }
236
309
  var args2 = process.argv.slice(2);
237
- var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
310
+ var trace3 = createTraceLogger("codex-commander", args2);
311
+ var createCodexCommand = (tempDiffPath2, reviewFormPath2) => {
312
+ trace3("createCodexCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
238
313
  let modelOption = "";
239
314
  if (args2.includes("--review")) {
240
- modelOption = "--model pro";
315
+ modelOption = "--model gpt-5";
316
+ trace3("model:review", modelOption);
241
317
  } else if (args2.includes("--flash")) {
242
- modelOption = "--model flash";
318
+ modelOption = "--model gpt-5-mini";
319
+ trace3("model:flash", modelOption);
243
320
  } else {
244
321
  const modelIndex = args2.indexOf("--model");
245
322
  if (modelIndex !== -1 && args2[modelIndex + 1]) {
246
323
  console.warn("\u26A0\uFE0F \uC9C0\uC815\uD55C \uBAA8\uB378\uC774 \uC5C6\uB294 \uACBD\uC6B0, \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD558\uB2C8 \uC8FC\uC758\uD558\uC138\uC694.");
247
324
  modelOption = `--model ${args2[modelIndex + 1]}`;
325
+ trace3("model:custom", modelOption);
326
+ } else {
327
+ console.warn("\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uAE30\uBCF8 \uBAA8\uB378\uC778 gpt-5-mini\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.");
328
+ modelOption = "--model gpt-5-mini";
329
+ trace3("model:default", modelOption);
330
+ }
331
+ }
332
+ const rules = [rulesPath, namingRulesPath, codingConventionRulesPath].filter((filePath) => fs5__default.default.existsSync(filePath)).map((filePath) => `- ${filePath}`).join("\n");
333
+ const rulesCount = rules ? rules.split("\n").length : 0;
334
+ trace3("rules:loaded", `count=${rulesCount}`);
335
+ const hasReviewForm = fs5__default.default.existsSync(reviewFormPath2);
336
+ const reviewFormLine = hasReviewForm ? `- ${reviewFormPath2}` : "";
337
+ trace3("reviewForm:status", reviewFormLine ? "exists" : "missing");
338
+ const prompt = `\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.
339
+ \uADDC\uCE59 \uD30C\uC77C:
340
+ ${rules || "- (\uC5C6\uC74C)"}
341
+ \uB9AC\uBDF0 \uC591\uC2DD \uD30C\uC77C:
342
+ ${reviewFormLine || "- (\uC5C6\uC74C)"}
343
+ \uB9AC\uBDF0 \uB300\uC0C1 diff \uD30C\uC77C:
344
+ - ${tempDiffPath2}
345
+
346
+ \uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.`;
347
+ const command = `codex exec ${modelOption} "${prompt.replace(/"/g, '\\"')}"`;
348
+ trace3("command:created");
349
+ if (args2.includes("--test")) {
350
+ const safeCommand = command.replace(/"/g, '\\"');
351
+ trace3("test-mode:return-preview");
352
+ return `echo "[TEST MODE] Codex \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
353
+
354
+ \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
355
+ ${safeCommand}"`;
356
+ }
357
+ trace3("createCodexCommand:end");
358
+ return command;
359
+ };
360
+ var trace4 = createTraceLogger("installation-codex");
361
+ function checkCodexCliInstalled() {
362
+ trace4("checkCodexCliInstalled:start");
363
+ try {
364
+ trace4("version-check:run", "codex --version");
365
+ child_process.execSync("codex --version", { stdio: "ignore" });
366
+ trace4("version-check:ok");
367
+ } catch {
368
+ trace4("version-check:failed", "install-start");
369
+ console.log("\u2139\uFE0F codex-cli\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uB97C \uC9C4\uD589\uD569\uB2C8\uB2E4... npm install -g @openai/codex");
370
+ try {
371
+ child_process.execSync("npm install -g @openai/codex", { stdio: "inherit" });
372
+ trace4("install:ok", "exit(1) for login");
373
+ console.log("\u2705 codex-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
374
+ console.log("\u26A0\uFE0F codex-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
375
+ console.log(' \uD130\uBBF8\uB110\uC5D0\uC11C "codex login" \uC744 \uC785\uB825\uD558\uC5EC \uB85C\uADF8\uC778\uC744 \uC644\uB8CC\uD55C \uD6C4, \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.');
376
+ process.exit(1);
377
+ } catch (installError) {
378
+ trace4("install:failed");
379
+ console.error("\u274C codex-cli \uC124\uCE58 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uAD8C\uD55C \uBB38\uC81C\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4 (sudo \uD544\uC694).");
380
+ console.error(installError);
381
+ process.exit(1);
382
+ }
383
+ }
384
+ trace4("checkCodexCliInstalled:end");
385
+ }
386
+ var args3 = process.argv.slice(2);
387
+ var trace5 = createTraceLogger("gemini-commander", args3);
388
+ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
389
+ trace5("createGeminiCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
390
+ let modelOption = "";
391
+ if (args3.includes("--review")) {
392
+ modelOption = "--model pro";
393
+ trace5("model:review", modelOption);
394
+ } else if (args3.includes("--flash")) {
395
+ modelOption = "--model flash";
396
+ trace5("model:flash", modelOption);
397
+ } else {
398
+ const modelIndex = args3.indexOf("--model");
399
+ if (modelIndex !== -1 && args3[modelIndex + 1]) {
400
+ console.warn("\u26A0\uFE0F \uC9C0\uC815\uD55C \uBAA8\uB378\uC774 \uC5C6\uB294 \uACBD\uC6B0, \uC5D0\uB7EC\uAC00 \uBC1C\uC0DD\uD558\uB2C8 \uC8FC\uC758\uD558\uC138\uC694.");
401
+ modelOption = `--model ${args3[modelIndex + 1]}`;
402
+ trace5("model:custom", modelOption);
248
403
  } else {
249
404
  console.warn("\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uAE30\uBCF8 \uBAA8\uB378\uC778 gemini-flash\uB97C \uC0AC\uC6A9\uD569\uB2C8\uB2E4.");
250
405
  modelOption = "--model flash";
406
+ trace5("model:default", modelOption);
251
407
  }
252
408
  }
253
409
  const rules = [
@@ -255,76 +411,124 @@ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
255
411
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
256
412
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
257
413
  ];
258
- const validRules = rules.filter((rule) => fs4__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
414
+ const validRules = rules.filter((rule) => fs5__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
415
+ const rulesCount = validRules ? validRules.split(",").length : 0;
416
+ trace5("rules:loaded", `count=${rulesCount}`);
259
417
  const command = `gemini ${modelOption} -p "\uB2E4\uC74C \uADDC\uCE59\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C(${validRules}) \uC774 diff(@${tempDiffPath2})\uB97C \uB9AC\uBDF0\uD574\uC918. \uB9AC\uBDF0\uC591\uC2DD\uC740 @${reviewFormPath2} \uC5D0 \uB9DE\uCDB0\uC11C \uC791\uC131\uD574\uC918. "`;
260
- if (args2.includes("--test")) {
418
+ trace5("command:created");
419
+ if (args3.includes("--test")) {
261
420
  const safeCommand = command.replace(/"/g, '\\"');
421
+ trace5("test-mode:return-preview");
262
422
  return `echo "[TEST MODE] Gemini \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
263
423
 
264
424
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
265
425
  ${safeCommand}"`;
266
426
  }
427
+ trace5("createGeminiCommand:end");
267
428
  return command;
268
429
  };
430
+ var trace6 = createTraceLogger("installation-gemini");
269
431
  function checkGeminiCliInstalled() {
432
+ trace6("checkGeminiCliInstalled:start");
270
433
  try {
434
+ trace6("version-check:run", "gemini --version");
271
435
  child_process.execSync("gemini --version", { stdio: "ignore" });
436
+ trace6("version-check:ok");
272
437
  } catch {
438
+ trace6("version-check:failed", "install-start");
273
439
  console.log("\u2139\uFE0F gemini-cli\uAC00 \uC124\uCE58\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4. \uC124\uCE58\uB97C \uC9C4\uD589\uD569\uB2C8\uB2E4... npm install -g @google/gemini-cli");
274
440
  try {
275
441
  child_process.execSync("npm install -g @google/gemini-cli", { stdio: "inherit" });
442
+ trace6("install:ok", "exit(1) for login");
276
443
  console.log("\u2705 gemini-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
277
444
  console.log("\u26A0\uFE0F Gemini API \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
278
445
  console.log(' \uD130\uBBF8\uB110\uC5D0\uC11C "gemini" \uB97C \uC785\uB825\uD558\uC5EC \uBE0C\uB77C\uC6B0\uC800 \uB85C\uADF8\uC778\uC744 \uC644\uB8CC\uD55C \uD6C4, \uB2E4\uC2DC \uC2DC\uB3C4\uD574\uC8FC\uC138\uC694.');
279
446
  process.exit(1);
280
447
  } catch (installError) {
448
+ trace6("install:failed");
281
449
  console.error("\u274C gemini-cli \uC124\uCE58 \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4. \uAD8C\uD55C \uBB38\uC81C\uC77C \uC218 \uC788\uC2B5\uB2C8\uB2E4 (sudo \uD544\uC694).");
282
450
  console.error(installError);
283
451
  process.exit(1);
284
452
  }
285
453
  }
454
+ trace6("checkGeminiCliInstalled:end");
286
455
  }
287
456
 
288
457
  // src/pr-review/review-one-by-one.ts
289
458
  var execAsync = util__default.default.promisify(child_process.exec);
290
459
  async function main() {
291
- const args3 = process.argv.slice(2);
292
- const isTest = args3.includes("--test");
460
+ const args4 = process.argv.slice(2);
461
+ const isTest = isTestMode(args4);
462
+ const trace7 = createTraceLogger("review-one-by-one", args4);
463
+ trace7("main:start", `args=${JSON.stringify(args4)}`);
464
+ trace7("service-selection:start");
293
465
  const service = await showSelectionAIService();
466
+ trace7("service-selection:done", `service=${service}`);
294
467
  switch (service) {
295
468
  case "gemini":
469
+ trace7("install-check:start", "service=gemini");
296
470
  checkGeminiCliInstalled();
471
+ trace7("install-check:done", "service=gemini");
297
472
  break;
298
473
  case "claude":
474
+ trace7("install-check:start", "service=claude");
299
475
  checkClaudeCliInstalled();
476
+ trace7("install-check:done", "service=claude");
477
+ break;
478
+ case "codex":
479
+ trace7("install-check:start", "service=codex");
480
+ checkCodexCliInstalled();
481
+ trace7("install-check:done", "service=codex");
300
482
  break;
301
483
  }
302
484
  try {
485
+ trace7("review-flow:start");
303
486
  console.log("\u{1F680} AI Code Review\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4...");
487
+ trace7("report-dir:create:start");
304
488
  createReportDirectory();
489
+ trace7("report-dir:create:done");
305
490
  const { includeParams, excludeParams } = getGitDiffFilter();
491
+ trace7("diff-filter:loaded", `include=${includeParams} | exclude=${excludeParams}`);
306
492
  const diffArgs = getDiffArgs();
493
+ trace7("diff-args:build:done", `diffArgs=${diffArgs || "(default)"}`);
307
494
  const filesCommand = `git diff --name-only ${diffArgs} -- ${includeParams} ${excludeParams}`;
495
+ trace7("files-command:run", filesCommand);
308
496
  const fileList = child_process.execSync(filesCommand).toString().split("\n").filter(Boolean);
497
+ trace7("files-command:done", `fileCount=${fileList.length}`);
309
498
  if (fileList.length === 0) {
499
+ trace7("empty-file-list:exit");
310
500
  console.log("\u2139\uFE0F \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
311
501
  deleteTempDiff();
312
502
  process.exit(0);
313
503
  }
314
504
  const fullDiffCommand = `git diff ${diffArgs} -- ${includeParams} ${excludeParams}`;
505
+ trace7("full-diff:run");
315
506
  const fullDiff = child_process.execSync(fullDiffCommand).toString();
316
507
  const nowStr = getNowString();
317
- fs4__default.default.writeFileSync(tempDiffPath, fullDiff);
508
+ trace7("full-diff:done", `length=${fullDiff.length}`);
509
+ trace7("timestamp:created", nowStr);
510
+ trace7("temp-diff:write:start", tempDiffPath);
511
+ fs5__default.default.writeFileSync(tempDiffPath, fullDiff);
512
+ trace7("temp-diff:write:done");
513
+ trace7("saved-diff:copy:start");
318
514
  const savedDiffPath = getNextFilePath(REPORT_DIR, `${nowStr}-diff`, ".txt");
319
- fs4__default.default.copyFileSync(tempDiffPath, savedDiffPath);
515
+ fs5__default.default.copyFileSync(tempDiffPath, savedDiffPath);
516
+ trace7("saved-diff:copy:done", savedDiffPath);
320
517
  const savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
518
+ trace7("saved-report:path", savedReportPath);
321
519
  const promises = fileList.map(async (file) => {
322
520
  try {
521
+ trace7("file-review:start", file);
323
522
  console.log(`\u{1F50D} Reviewing: ${file}...`);
523
+ trace7("file-diff:run", file);
324
524
  const fileDiff = child_process.execSync(`git diff ${diffArgs} -- "${file}"`).toString();
525
+ trace7("file-diff:done", `${file} | length=${fileDiff.length}`);
325
526
  const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
326
- fs4__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
527
+ trace7("file-temp-diff:write:start", tempOneFileDiffPath);
528
+ fs5__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
529
+ trace7("file-temp-diff:write:done", tempOneFileDiffPath);
327
530
  let command = "";
531
+ trace7("file-command:create:start", file);
328
532
  switch (service) {
329
533
  case "gemini":
330
534
  command = createGeminiCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
@@ -333,25 +537,37 @@ async function main() {
333
537
  command = createClaudeCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
334
538
  break;
335
539
  case "codex":
540
+ command = createCodexCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
336
541
  break;
337
542
  }
543
+ trace7("file-command:create:done", file);
544
+ trace7("file-command:exec:start", file);
338
545
  const { stdout } = await execAsync(command, { maxBuffer: 1024 * 1024 * 20 });
339
546
  const result = stdout.toString();
547
+ trace7("file-command:exec:done", `${file} | resultLength=${result.length}`);
548
+ trace7("file-temp-diff:delete:start", tempOneFileDiffPath);
340
549
  deleteFile(tempOneFileDiffPath);
550
+ trace7("file-temp-diff:delete:done", tempOneFileDiffPath);
341
551
  const tempReport = `### File: ${file}
342
552
  ${result}
343
553
 
344
554
  `;
345
555
  console.log(tempReport);
346
- fs4__default.default.appendFileSync(savedReportPath, tempReport);
556
+ trace7("file-report:append:start", file);
557
+ fs5__default.default.appendFileSync(savedReportPath, tempReport);
558
+ trace7("file-report:append:done", file);
347
559
  if (isTest) {
348
- fs4__default.default.appendFileSync(savedReportPath, `
560
+ trace7("file-test-command:append:start", file);
561
+ fs5__default.default.appendFileSync(savedReportPath, `
349
562
 
350
563
  ## \uC0AC\uC6A9\uB41C \uBA85\uB839\uC5B4
351
564
 
352
565
  ${command}`);
566
+ trace7("file-test-command:append:done", file);
353
567
  }
568
+ trace7("file-review:end", file);
354
569
  } catch (err) {
570
+ trace7("file-review:catch", file);
355
571
  console.error(`\u274C Error reviewing file ${file}:`, err);
356
572
  const errorReport = `### File: ${file}
357
573
  \u274C Review Failed
@@ -360,28 +576,41 @@ ${err}
360
576
  \`\`\`
361
577
 
362
578
  `;
363
- fs4__default.default.appendFileSync(savedReportPath, errorReport);
579
+ fs5__default.default.appendFileSync(savedReportPath, errorReport);
364
580
  try {
365
581
  const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
366
- if (fs4__default.default.existsSync(tempOneFileDiffPath)) {
582
+ if (fs5__default.default.existsSync(tempOneFileDiffPath)) {
583
+ trace7("file-temp-diff:delete:start(catch)", tempOneFileDiffPath);
367
584
  deleteFile(tempOneFileDiffPath);
585
+ trace7("file-temp-diff:delete:done(catch)", tempOneFileDiffPath);
368
586
  }
369
587
  } catch (e) {
588
+ trace7("file-temp-diff:delete:failed(catch)", file);
370
589
  console.error(`\u274C Error deleting temp file for ${file}:`, e);
371
590
  }
372
591
  }
373
592
  });
593
+ trace7("parallel-review:await-start");
374
594
  await Promise.all(promises);
595
+ trace7("parallel-review:await-done");
375
596
  console.log(`
376
597
  \u2705 \uB9AC\uBDF0\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`);
377
598
  console.log(`\u{1F4C4} \uB9AC\uD3EC\uD2B8 \uC800\uC7A5 \uC704\uCE58: ${savedReportPath}`);
378
599
  console.log(`diff \uC800\uC7A5 \uC704\uCE58: ${savedDiffPath}`);
600
+ trace7("open-report:start");
379
601
  openReport(savedReportPath);
602
+ trace7("open-report:done");
603
+ trace7("cleanup-temp-diff:start");
380
604
  deleteTempDiff();
605
+ trace7("cleanup-temp-diff:done");
606
+ trace7("review-flow:end");
381
607
  } catch (error) {
608
+ trace7("review-flow:catch");
382
609
  console.error("\u274C \uB9AC\uBDF0 \uB3C4\uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.");
383
610
  console.error(error);
611
+ trace7("cleanup-temp-diff:start(catch)");
384
612
  deleteTempDiff();
613
+ trace7("cleanup-temp-diff:done(catch)");
385
614
  process.exit(1);
386
615
  }
387
616
  }