sales-frontend-gemini-cli 0.3.1 → 0.4.1

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 (81) hide show
  1. package/dist/common/helper.cjs +77 -6
  2. package/dist/common/helper.cjs.map +1 -1
  3. package/dist/common/helper.d.cts +16 -2
  4. package/dist/common/helper.d.ts +16 -2
  5. package/dist/common/helper.js +76 -7
  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 +150 -17
  24. package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
  25. package/dist/pr-review/claude/claude-commander.d.cts +7 -8
  26. package/dist/pr-review/claude/claude-commander.d.ts +7 -8
  27. package/dist/pr-review/claude/claude-commander.js +150 -17
  28. package/dist/pr-review/claude/claude-commander.js.map +1 -1
  29. package/dist/pr-review/claude/installation-claude.cjs +38 -1
  30. package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
  31. package/dist/pr-review/claude/installation-claude.js +33 -1
  32. package/dist/pr-review/claude/installation-claude.js.map +1 -1
  33. package/dist/pr-review/codex/codex-commander.cjs +126 -0
  34. package/dist/pr-review/codex/codex-commander.cjs.map +1 -0
  35. package/dist/pr-review/codex/codex-commander.d.cts +17 -0
  36. package/dist/pr-review/codex/codex-commander.d.ts +17 -0
  37. package/dist/pr-review/codex/codex-commander.js +118 -0
  38. package/dist/pr-review/codex/codex-commander.js.map +1 -0
  39. package/dist/pr-review/codex/installation-codex.cjs +62 -0
  40. package/dist/pr-review/codex/installation-codex.cjs.map +1 -0
  41. package/dist/pr-review/codex/installation-codex.d.cts +3 -0
  42. package/dist/pr-review/codex/installation-codex.d.ts +3 -0
  43. package/dist/pr-review/codex/installation-codex.js +55 -0
  44. package/dist/pr-review/codex/installation-codex.js.map +1 -0
  45. package/dist/pr-review/gemini/gemini-commander.cjs +133 -15
  46. package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
  47. package/dist/pr-review/gemini/gemini-commander.d.cts +10 -13
  48. package/dist/pr-review/gemini/gemini-commander.d.ts +10 -13
  49. package/dist/pr-review/gemini/gemini-commander.js +133 -15
  50. package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
  51. package/dist/pr-review/gemini/installation-gemini.cjs +35 -0
  52. package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
  53. package/dist/pr-review/gemini/installation-gemini.js +30 -0
  54. package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
  55. package/dist/pr-review/review-one-by-one.cjs +547 -56
  56. package/dist/pr-review/review-one-by-one.cjs.map +1 -1
  57. package/dist/pr-review/review-one-by-one.js +546 -55
  58. package/dist/pr-review/review-one-by-one.js.map +1 -1
  59. package/dist/pr-review/review.cjs +517 -41
  60. package/dist/pr-review/review.cjs.map +1 -1
  61. package/dist/pr-review/review.js +517 -41
  62. package/dist/pr-review/review.js.map +1 -1
  63. package/package.json +1 -1
  64. package/src/common/form/review-form.md +1 -1
  65. package/src/common/rules/review-rules.md +2 -0
  66. package/dist/pr-review/gemini/installation-gcloud.cjs.map +0 -1
  67. package/dist/pr-review/gemini/installation-gcloud.js.map +0 -1
  68. package/dist/pr-review/gemini/interactive-version/index.cjs.map +0 -1
  69. package/dist/pr-review/gemini/interactive-version/index.js.map +0 -1
  70. package/dist/pr-review/gemini/login.cjs.map +0 -1
  71. package/dist/pr-review/gemini/login.js.map +0 -1
  72. package/dist/pr-review/gemini/vertex-version/index.cjs.map +0 -1
  73. package/dist/pr-review/gemini/vertex-version/index.js.map +0 -1
  74. /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.cts +0 -0
  75. /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.ts +0 -0
  76. /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.cts +0 -0
  77. /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.ts +0 -0
  78. /package/dist/{pr-review/gemini → etc}/login.d.cts +0 -0
  79. /package/dist/{pr-review/gemini → etc}/login.d.ts +0 -0
  80. /package/dist/{pr-review/gemini → etc}/vertex-version/index.d.cts +0 -0
  81. /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,54 @@ var ignoreList = [
39
39
  ".review-report/"
40
40
  // 생성되는 리포트 폴더도 제외
41
41
  ];
42
+ function parseServiceFromArgs(args4 = process.argv.slice(2)) {
43
+ const serviceIndex = args4.indexOf("--service");
44
+ const rawService = serviceIndex !== -1 ? args4[serviceIndex + 1] : "";
45
+ if (!rawService) {
46
+ return "";
47
+ }
48
+ const normalizedService = rawService.toLowerCase();
49
+ if (AIServices.includes(normalizedService)) {
50
+ return normalizedService;
51
+ }
52
+ console.error(
53
+ `\u274C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC11C\uBE44\uC2A4\uC785\uB2C8\uB2E4: ${rawService}. \uC0AC\uC6A9 \uAC00\uB2A5 \uAC12: ${AIServices.join(", ")} (\uC608: --service codex)`
54
+ );
55
+ process.exit(1);
56
+ }
57
+ function isTestMode(args4 = process.argv.slice(2)) {
58
+ return args4.includes("--test");
59
+ }
60
+ function createTraceLogger(scope, args4 = process.argv.slice(2)) {
61
+ const enabled = isTestMode(args4);
62
+ return (step, detail) => {
63
+ if (!enabled) {
64
+ return;
65
+ }
66
+ console.log(`[TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ""}`);
67
+ };
68
+ }
42
69
  function getNextFilePath(dir, baseName, extension) {
43
70
  let counter = 1;
44
71
  while (true) {
45
72
  const filePath = path__default.default.join(dir, `${baseName}-${counter}${extension}`);
46
- if (!fs4__default.default.existsSync(filePath)) {
73
+ if (!fs5__default.default.existsSync(filePath)) {
47
74
  return filePath;
48
75
  }
49
76
  counter++;
50
77
  }
51
78
  }
52
79
  function deleteFile(filePath) {
53
- if (fs4__default.default.existsSync(filePath)) {
54
- fs4__default.default.unlinkSync(filePath);
80
+ if (fs5__default.default.existsSync(filePath)) {
81
+ fs5__default.default.unlinkSync(filePath);
55
82
  }
56
83
  }
57
84
  function deleteTempDiff() {
58
85
  deleteFile(tempDiffPath);
59
86
  }
60
87
  function createReportDirectory() {
61
- if (!fs4__default.default.existsSync(REPORT_DIR)) {
62
- fs4__default.default.mkdirSync(REPORT_DIR, { recursive: true });
88
+ if (!fs5__default.default.existsSync(REPORT_DIR)) {
89
+ fs5__default.default.mkdirSync(REPORT_DIR, { recursive: true });
63
90
  }
64
91
  }
65
92
  function getNowString() {
@@ -81,25 +108,60 @@ function getGitDiffFilter() {
81
108
  return { includeParams, excludeParams };
82
109
  }
83
110
  function openReport(reportPath) {
111
+ const resolvedPath = path__default.default.resolve(reportPath);
112
+ const { platform } = process;
113
+ const openWithChrome = () => {
114
+ if (platform === "darwin") {
115
+ child_process.execSync(`open -a "Google Chrome" "${resolvedPath}"`, { stdio: "ignore" });
116
+ return true;
117
+ }
118
+ if (platform === "linux") {
119
+ child_process.execSync(`google-chrome "${resolvedPath}"`, { stdio: "ignore" });
120
+ return true;
121
+ }
122
+ return false;
123
+ };
124
+ const openWithDefaultBrowser = () => {
125
+ if (platform === "darwin") {
126
+ child_process.execSync(`open "${resolvedPath}"`, { stdio: "ignore" });
127
+ return true;
128
+ }
129
+ if (platform === "linux") {
130
+ child_process.execSync(`xdg-open "${resolvedPath}"`, { stdio: "ignore" });
131
+ return true;
132
+ }
133
+ return false;
134
+ };
84
135
  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.`);
136
+ if (openWithChrome()) {
137
+ console.log("\u{1F680} Google Chrome\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
138
+ return;
139
+ }
140
+ } catch {
141
+ }
142
+ try {
143
+ if (openWithDefaultBrowser()) {
144
+ console.log("\u{1F680} \uAE30\uBCF8 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
145
+ return;
146
+ }
87
147
  } catch (e) {
88
148
  console.error("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30 \uC2E4\uD328:", e);
149
+ return;
89
150
  }
151
+ console.error(`\u26A0\uFE0F \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD50C\uB7AB\uD3FC\uC785\uB2C8\uB2E4: ${platform}`);
90
152
  }
91
153
  function getDiffArgs() {
92
- const args3 = process.argv.slice(2);
93
- const commitIndex = args3.indexOf("--commit");
154
+ const args4 = process.argv.slice(2);
155
+ const commitIndex = args4.indexOf("--commit");
94
156
  const { includeParams, excludeParams } = getGitDiffFilter();
95
157
  let diffArgs = "";
96
158
  if (commitIndex !== -1) {
97
- const commitHash = args3[commitIndex + 1];
159
+ const commitHash = args4[commitIndex + 1];
98
160
  if (!commitHash) {
99
161
  console.error("\u274C \uCEE4\uBC0B \uD574\uC2DC\uAC00 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
100
162
  process.exit(1);
101
163
  }
102
- const nextArg = args3[commitIndex + 2];
164
+ const nextArg = args4[commitIndex + 2];
103
165
  let n = 0;
104
166
  if (nextArg && !nextArg.startsWith("--")) {
105
167
  n = parseInt(nextArg, 10);
@@ -122,6 +184,13 @@ function getDiffArgs() {
122
184
  return diffArgs;
123
185
  }
124
186
  async function showSelectionAIService() {
187
+ const selectedServiceFromArgs = parseServiceFromArgs();
188
+ if (selectedServiceFromArgs) {
189
+ console.log(`
190
+ \u2705 \x1B[32m${selectedServiceFromArgs}\x1B[0m \uC11C\uBE44\uC2A4\uAC00 \uC120\uD0DD\uB418\uC5C8\uC2B5\uB2C8\uB2E4. (--service)
191
+ `);
192
+ return selectedServiceFromArgs;
193
+ }
125
194
  let selectedIndex = 0;
126
195
  const rl = readline__default.default.createInterface({
127
196
  input: process.stdin,
@@ -136,7 +205,9 @@ async function showSelectionAIService() {
136
205
  }
137
206
  firstRender = false;
138
207
  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");
208
+ process.stdout.write(
209
+ "\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"
210
+ );
140
211
  AIServices.forEach((service, index) => {
141
212
  if (index === selectedIndex) {
142
213
  process.stdout.write(` \x1B[36m>\x1B[0m \x1B[36m\u25C9\x1B[0m \x1B[1m${service}\x1B[0m
@@ -182,149 +253,544 @@ async function showSelectionAIService() {
182
253
  });
183
254
  }
184
255
  var args = process.argv.slice(2);
185
- var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
186
- let modelOption = "";
187
- if (args.includes("--review")) {
188
- modelOption = "--model opus";
189
- } else if (args.includes("--flash")) {
190
- modelOption = "--model haiku";
191
- } else {
192
- const modelIndex = args.indexOf("--model");
193
- if (modelIndex !== -1 && args[modelIndex + 1]) {
194
- 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
- modelOption = `--model ${args[modelIndex + 1]}`;
196
- } else {
197
- 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
- modelOption = "--model sonnet";
256
+ var trace = createTraceLogger("claude-commander", args);
257
+ var ALLOWED_REASONING_EFFORTS = ["minimal", "low", "medium", "high"];
258
+ function shellQuote(value) {
259
+ return `'${value.replace(/'/g, `'\\''`)}'`;
260
+ }
261
+ function getArgValue(flag) {
262
+ const index = args.indexOf(flag);
263
+ if (index === -1 || !args[index + 1]) {
264
+ return "";
265
+ }
266
+ return args[index + 1];
267
+ }
268
+ function toUnique(values) {
269
+ const seen = /* @__PURE__ */ new Set();
270
+ return values.filter((value) => {
271
+ if (!value || seen.has(value)) {
272
+ return false;
199
273
  }
274
+ seen.add(value);
275
+ return true;
276
+ });
277
+ }
278
+ function normalizeEffort(level) {
279
+ if (level === "minimal") {
280
+ return "low";
281
+ }
282
+ return level;
283
+ }
284
+ function resolveReasoningEffort() {
285
+ const customReasoningEffort = getArgValue("--reasoning-effort") || getArgValue("--effort");
286
+ if (customReasoningEffort) {
287
+ if (ALLOWED_REASONING_EFFORTS.includes(customReasoningEffort)) {
288
+ const normalized = normalizeEffort(customReasoningEffort);
289
+ trace("reasoning:custom", `${customReasoningEffort} -> ${normalized}`);
290
+ if (customReasoningEffort === "minimal") {
291
+ console.warn("\u26A0\uFE0F Claude\uB294 minimal\uC744 \uC9C1\uC811 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC544 low\uB85C \uB9E4\uD551\uD569\uB2C8\uB2E4.");
292
+ }
293
+ return normalized;
294
+ }
295
+ console.warn(
296
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS.join(
297
+ ", "
298
+ )}`
299
+ );
300
+ }
301
+ if (args.includes("--flash")) {
302
+ trace("reasoning:flash-default", "low");
303
+ return "low";
200
304
  }
305
+ if (args.includes("--review")) {
306
+ trace("reasoning:review-default", "high");
307
+ return "high";
308
+ }
309
+ trace("reasoning:default", "medium");
310
+ return "medium";
311
+ }
312
+ function resolvePrimaryAlias() {
313
+ if (args.includes("--review")) {
314
+ trace("model:mode-alias", "opus");
315
+ return "opus";
316
+ }
317
+ if (args.includes("--flash")) {
318
+ trace("model:mode-alias", "haiku");
319
+ return "haiku";
320
+ }
321
+ trace("model:default-alias", "sonnet");
322
+ return "sonnet";
323
+ }
324
+ function getAliasFallbacks(primaryAlias) {
325
+ if (primaryAlias === "opus") {
326
+ return ["opus", "sonnet", "haiku"];
327
+ }
328
+ if (primaryAlias === "haiku") {
329
+ return ["haiku", "sonnet"];
330
+ }
331
+ return [primaryAlias, "sonnet", "haiku"];
332
+ }
333
+ function buildClaudeExecCommand(options) {
334
+ const { tempDiffPath: tempDiffPath2, prompt, systemPromptFiles, effort, model, fallbackModel } = options;
335
+ const modelOption = model ? `--model ${shellQuote(model)}` : "";
336
+ const fallbackOption = model && fallbackModel ? `--fallback-model ${shellQuote(fallbackModel)}` : "";
337
+ const effortOption = `--effort ${shellQuote(effort)}`;
338
+ const appendedPromptFiles = systemPromptFiles.map((path2) => `--append-system-prompt-file ${shellQuote(path2)}`).join(" ");
339
+ return `cat ${shellQuote(tempDiffPath2)} | claude ${[
340
+ modelOption,
341
+ fallbackOption,
342
+ effortOption,
343
+ appendedPromptFiles,
344
+ "-p",
345
+ shellQuote(prompt)
346
+ ].filter(Boolean).join(" ")}`;
347
+ }
348
+ var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
349
+ trace("createClaudeCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
350
+ const customModel = getArgValue("--model");
351
+ const effort = resolveReasoningEffort();
352
+ const primaryAlias = resolvePrimaryAlias();
353
+ const aliasFallbacks = toUnique(getAliasFallbacks(primaryAlias));
201
354
  const rules = [
202
355
  { path: rulesPath, display: "\uB8F0\uC14B" },
203
356
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
204
357
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
205
358
  ];
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}` : "";
208
- 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."`;
359
+ const existingRuleFiles = rules.filter((rule) => fs5__default.default.existsSync(rule.path)).map((rule) => rule.path);
360
+ trace("rules:loaded", `count=${existingRuleFiles.length}`);
361
+ const reviewFormExists = fs5__default.default.existsSync(reviewFormPath2);
362
+ trace("reviewForm:status", reviewFormExists ? "exists" : "missing");
363
+ const systemPromptFiles = reviewFormExists ? [...existingRuleFiles, reviewFormPath2] : existingRuleFiles;
364
+ const prompt = "\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.";
365
+ const modelCandidates = toUnique(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
366
+ trace("model:candidates", modelCandidates.join(", "));
367
+ if (customModel) {
368
+ console.warn(
369
+ `\u26A0\uFE0F \uCEE4\uC2A4\uD140 \uBAA8\uB378(${customModel})\uC744 \uC6B0\uC120 \uC2DC\uB3C4\uD558\uACE0 \uC2E4\uD328\uD558\uBA74 alias(${aliasFallbacks.join(
370
+ " -> "
371
+ )}) \uBC0F \uAE30\uBCF8 \uBAA8\uB378 \uC21C\uC73C\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
372
+ );
373
+ } else {
374
+ console.warn(
375
+ `\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. alias(${aliasFallbacks.join(" -> ")})\uB97C \uC21C\uCC28 \uC2DC\uB3C4\uD558\uACE0 \uB9C8\uC9C0\uB9C9\uC5D0 \uAE30\uBCF8 \uBAA8\uB378\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
376
+ );
377
+ }
378
+ const commandCandidates = modelCandidates.map((model, index) => {
379
+ const fallbackModel = modelCandidates[index + 1];
380
+ return buildClaudeExecCommand({
381
+ tempDiffPath: tempDiffPath2,
382
+ prompt,
383
+ systemPromptFiles,
384
+ effort,
385
+ model,
386
+ fallbackModel
387
+ });
388
+ });
389
+ const command = [
390
+ ...commandCandidates,
391
+ buildClaudeExecCommand({
392
+ tempDiffPath: tempDiffPath2,
393
+ prompt,
394
+ systemPromptFiles,
395
+ effort
396
+ })
397
+ ].join(" || ");
398
+ trace("command:created");
209
399
  if (args.includes("--test")) {
210
400
  const safeCommand = command.replace(/"/g, '\\"');
401
+ trace("test-mode:return-preview");
211
402
  return `echo "[TEST MODE] Claude \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
212
403
 
213
404
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
214
405
  ${safeCommand}"`;
215
406
  }
407
+ trace("createClaudeCommand:end");
216
408
  return command;
217
409
  };
410
+ var trace2 = createTraceLogger("installation-claude");
218
411
  function checkClaudeCliInstalled() {
412
+ trace2("checkClaudeCliInstalled:start");
219
413
  try {
414
+ trace2("version-check:run", "claude --version");
220
415
  child_process.execSync("claude --version", { stdio: "ignore" });
416
+ trace2("version-check:ok");
221
417
  } 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");
418
+ trace2("version-check:failed", "install-start");
419
+ console.log(
420
+ "\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"
421
+ );
223
422
  try {
224
423
  child_process.execSync("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
424
+ trace2("install:ok", "exit(1) for login");
225
425
  console.log("\u2705 claude-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
226
426
  console.log("\u26A0\uFE0F claude-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
227
427
  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
428
  process.exit(1);
229
429
  } catch (installError) {
430
+ trace2("install:failed");
230
431
  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
432
  console.error(installError);
232
433
  process.exit(1);
233
434
  }
234
435
  }
436
+ trace2("checkClaudeCliInstalled:end");
235
437
  }
236
438
  var args2 = process.argv.slice(2);
237
- var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
238
- let modelOption = "";
439
+ var trace3 = createTraceLogger("codex-commander", args2);
440
+ var ALLOWED_REASONING_EFFORTS2 = ["minimal", "low", "medium", "high"];
441
+ function shellQuote2(value) {
442
+ return `'${value.replace(/'/g, `'\\''`)}'`;
443
+ }
444
+ function getArgValue2(flag) {
445
+ const index = args2.indexOf(flag);
446
+ if (index === -1 || !args2[index + 1]) {
447
+ return "";
448
+ }
449
+ return args2[index + 1];
450
+ }
451
+ function resolveReasoningEffort2() {
452
+ const customReasoningEffort = getArgValue2("--reasoning-effort");
453
+ if (customReasoningEffort) {
454
+ if (ALLOWED_REASONING_EFFORTS2.includes(customReasoningEffort)) {
455
+ trace3("reasoning:custom", customReasoningEffort);
456
+ return customReasoningEffort;
457
+ }
458
+ console.warn(
459
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS2.join(
460
+ ", "
461
+ )}`
462
+ );
463
+ }
464
+ if (args2.includes("--flash")) {
465
+ trace3("reasoning:flash-default", "minimal");
466
+ return "minimal";
467
+ }
239
468
  if (args2.includes("--review")) {
240
- modelOption = "--model pro";
241
- } else if (args2.includes("--flash")) {
242
- modelOption = "--model flash";
469
+ trace3("reasoning:review-default", "high");
470
+ return "high";
471
+ }
472
+ trace3("reasoning:default", "medium");
473
+ return "medium";
474
+ }
475
+ function buildCodexExecCommand(prompt, reasoningEffort, model) {
476
+ const modelOption = model ? `--model ${shellQuote2(model)}` : "";
477
+ const reasoningOption = `-c ${shellQuote2(`model_reasoning_effort="${reasoningEffort}"`)}`;
478
+ return `codex exec ${[modelOption, reasoningOption, shellQuote2(prompt)].filter(Boolean).join(" ")}`;
479
+ }
480
+ var createCodexCommand = (tempDiffPath2, reviewFormPath2) => {
481
+ trace3("createCodexCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
482
+ const customModel = getArgValue2("--model");
483
+ const reasoningEffort = resolveReasoningEffort2();
484
+ const rules = [rulesPath, namingRulesPath, codingConventionRulesPath].filter((filePath) => fs5__default.default.existsSync(filePath)).map((filePath) => `- ${filePath}`).join("\n");
485
+ const rulesCount = rules ? rules.split("\n").length : 0;
486
+ trace3("rules:loaded", `count=${rulesCount}`);
487
+ const hasReviewForm = fs5__default.default.existsSync(reviewFormPath2);
488
+ const reviewFormLine = hasReviewForm ? `- ${reviewFormPath2}` : "";
489
+ trace3("reviewForm:status", reviewFormLine ? "exists" : "missing");
490
+ const prompt = `\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.
491
+ \uADDC\uCE59 \uD30C\uC77C:
492
+ ${rules || "- (\uC5C6\uC74C)"}
493
+ \uB9AC\uBDF0 \uC591\uC2DD \uD30C\uC77C:
494
+ ${reviewFormLine || "- (\uC5C6\uC74C)"}
495
+ \uB9AC\uBDF0 \uB300\uC0C1 diff \uD30C\uC77C:
496
+ - ${tempDiffPath2}
497
+
498
+ \uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.`;
499
+ let command = "";
500
+ if (customModel) {
501
+ 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.");
502
+ trace3("model:custom", customModel);
503
+ command = buildCodexExecCommand(prompt, reasoningEffort, customModel);
243
504
  } else {
244
- const modelIndex = args2.indexOf("--model");
245
- if (modelIndex !== -1 && args2[modelIndex + 1]) {
246
- 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
- modelOption = `--model ${args2[modelIndex + 1]}`;
248
- } else {
249
- 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
- modelOption = "--model flash";
505
+ const preferredModelAlias = "gpt-5";
506
+ const aliasCommand = buildCodexExecCommand(prompt, reasoningEffort, preferredModelAlias);
507
+ const fallbackCommand = buildCodexExecCommand(prompt, reasoningEffort);
508
+ console.warn(
509
+ `\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. alias(${preferredModelAlias})\uB97C \uC6B0\uC120 \uC2DC\uB3C4\uD558\uACE0 \uC2E4\uD328\uD558\uBA74 \uACC4\uC815 \uAE30\uBCF8 \uBAA8\uB378\uB85C \uC790\uB3D9 \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
510
+ );
511
+ trace3("model:alias-first", preferredModelAlias);
512
+ trace3("model:fallback", "account-default");
513
+ command = `${aliasCommand} || ${fallbackCommand}`;
514
+ }
515
+ trace3("command:created");
516
+ if (args2.includes("--test")) {
517
+ const safeCommand = command.replace(/"/g, '\\"');
518
+ trace3("test-mode:return-preview");
519
+ return `echo "[TEST MODE] Codex \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
520
+
521
+ \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
522
+ ${safeCommand}"`;
523
+ }
524
+ trace3("createCodexCommand:end");
525
+ return command;
526
+ };
527
+ var trace4 = createTraceLogger("installation-codex");
528
+ function checkCodexCliInstalled() {
529
+ trace4("checkCodexCliInstalled:start");
530
+ try {
531
+ trace4("version-check:run", "codex --version");
532
+ child_process.execSync("codex --version", { stdio: "ignore" });
533
+ trace4("version-check:ok");
534
+ } catch {
535
+ trace4("version-check:failed", "install-start");
536
+ 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");
537
+ try {
538
+ child_process.execSync("npm install -g @openai/codex", { stdio: "inherit" });
539
+ trace4("install:ok", "exit(1) for login");
540
+ console.log("\u2705 codex-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
541
+ console.log("\u26A0\uFE0F codex-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
542
+ 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.');
543
+ process.exit(1);
544
+ } catch (installError) {
545
+ trace4("install:failed");
546
+ 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).");
547
+ console.error(installError);
548
+ process.exit(1);
251
549
  }
252
550
  }
551
+ trace4("checkCodexCliInstalled:end");
552
+ }
553
+ var args3 = process.argv.slice(2);
554
+ var trace5 = createTraceLogger("gemini-commander", args3);
555
+ var ALLOWED_REASONING_EFFORTS3 = ["minimal", "low", "medium", "high"];
556
+ function shellQuote3(value) {
557
+ return `'${value.replace(/'/g, `'\\''`)}'`;
558
+ }
559
+ function getArgValue3(flag) {
560
+ const index = args3.indexOf(flag);
561
+ if (index === -1 || !args3[index + 1]) {
562
+ return "";
563
+ }
564
+ return args3[index + 1];
565
+ }
566
+ function toUnique2(values) {
567
+ const seen = /* @__PURE__ */ new Set();
568
+ return values.filter((value) => {
569
+ if (!value || seen.has(value)) {
570
+ return false;
571
+ }
572
+ seen.add(value);
573
+ return true;
574
+ });
575
+ }
576
+ function resolveReasoningEffort3() {
577
+ const customReasoningEffort = getArgValue3("--reasoning-effort");
578
+ if (customReasoningEffort) {
579
+ if (ALLOWED_REASONING_EFFORTS3.includes(customReasoningEffort)) {
580
+ trace5("reasoning:custom", customReasoningEffort);
581
+ return customReasoningEffort;
582
+ }
583
+ console.warn(
584
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS3.join(
585
+ ", "
586
+ )}`
587
+ );
588
+ }
589
+ if (args3.includes("--flash")) {
590
+ trace5("reasoning:flash-default", "minimal");
591
+ return "minimal";
592
+ }
593
+ if (args3.includes("--review")) {
594
+ trace5("reasoning:review-default", "high");
595
+ return "high";
596
+ }
597
+ trace5("reasoning:default", "medium");
598
+ return "medium";
599
+ }
600
+ function resolvePrimaryAlias2(reasoningEffort) {
601
+ if (args3.includes("--review")) {
602
+ trace5("model:mode-alias", "pro");
603
+ return "pro";
604
+ }
605
+ if (args3.includes("--flash")) {
606
+ trace5("model:mode-alias", "flash");
607
+ return "flash";
608
+ }
609
+ if (reasoningEffort === "high") {
610
+ trace5("model:reasoning-alias", "pro");
611
+ return "pro";
612
+ }
613
+ if (reasoningEffort === "minimal" || reasoningEffort === "low") {
614
+ trace5("model:reasoning-alias", "flash");
615
+ return "flash";
616
+ }
617
+ trace5("model:default-alias", "auto");
618
+ return "auto";
619
+ }
620
+ function getAliasFallbacks2(primaryAlias) {
621
+ if (primaryAlias === "pro") {
622
+ return ["pro", "flash", "auto"];
623
+ }
624
+ if (primaryAlias === "flash") {
625
+ return ["flash", "auto", "pro"];
626
+ }
627
+ return [primaryAlias, "auto", "flash", "pro"];
628
+ }
629
+ function getReasoningInstruction(reasoningEffort) {
630
+ if (reasoningEffort === "high") {
631
+ return "high (\uAE4A\uC774 \uC788\uB294 \uBD84\uC11D, \uC7A0\uC7AC\uC801 \uB9AC\uC2A4\uD06C\uAE4C\uC9C0 \uC810\uAC80)";
632
+ }
633
+ if (reasoningEffort === "medium") {
634
+ return "medium (\uADE0\uD615 \uC7A1\uD78C \uBD84\uC11D\uACFC \uD575\uC2EC \uC774\uC288 \uC911\uC2EC)";
635
+ }
636
+ if (reasoningEffort === "low") {
637
+ return "low (\uD575\uC2EC \uACB0\uD568 \uC704\uC8FC\uB85C \uAC04\uACB0\uD558\uAC8C \uBD84\uC11D)";
638
+ }
639
+ return "minimal (\uCE58\uBA85\uB3C4 \uB192\uC740 \uC774\uC288\uB9CC \uB9E4\uC6B0 \uAC04\uACB0\uD558\uAC8C \uBD84\uC11D)";
640
+ }
641
+ function buildGeminiExecCommand(prompt, model) {
642
+ const modelOption = model ? `--model ${shellQuote3(model)}` : "";
643
+ return `gemini ${[modelOption, "-p", shellQuote3(prompt)].filter(Boolean).join(" ")}`;
644
+ }
645
+ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
646
+ trace5("createGeminiCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
647
+ const customModel = getArgValue3("--model");
648
+ const reasoningEffort = resolveReasoningEffort3();
649
+ const primaryAlias = resolvePrimaryAlias2(reasoningEffort);
650
+ const aliasFallbacks = toUnique2(getAliasFallbacks2(primaryAlias));
253
651
  const rules = [
254
652
  { path: rulesPath, display: "\uB8F0\uC14B" },
255
653
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
256
654
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
257
655
  ];
258
- const validRules = rules.filter((rule) => fs4__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
259
- 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")) {
656
+ const validRules = rules.filter((rule) => fs5__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
657
+ const rulesCount = validRules ? validRules.split(",").length : 0;
658
+ trace5("rules:loaded", `count=${rulesCount}`);
659
+ const reviewFormRef = fs5__default.default.existsSync(reviewFormPath2) ? `@${reviewFormPath2}` : "(\uC5C6\uC74C)";
660
+ trace5("reviewForm:status", reviewFormRef === "(\uC5C6\uC74C)" ? "missing" : "exists");
661
+ const reasoningInstruction = getReasoningInstruction(reasoningEffort);
662
+ const prompt = `\uB2E4\uC74C \uADDC\uCE59\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C(${validRules || "(\uC5C6\uC74C)"}) \uC774 diff(@${tempDiffPath2})\uB97C \uB9AC\uBDF0\uD574\uC918.
663
+ \uB9AC\uBDF0 \uC591\uC2DD\uC740 ${reviewFormRef} \uC5D0 \uB9DE\uCDB0\uC11C \uC791\uC131\uD574\uC918.
664
+ \uCD94\uB860 \uAC15\uB3C4 \uC9C0\uCE68: ${reasoningInstruction}`;
665
+ const modelCandidates = toUnique2(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
666
+ trace5("model:candidates", modelCandidates.join(", "));
667
+ if (customModel) {
668
+ console.warn(
669
+ `\u26A0\uFE0F \uCEE4\uC2A4\uD140 \uBAA8\uB378(${customModel})\uC744 \uC6B0\uC120 \uC2DC\uB3C4\uD558\uACE0 \uC2E4\uD328\uD558\uBA74 alias(${aliasFallbacks.join(
670
+ " -> "
671
+ )}) \uBC0F \uAE30\uBCF8 \uBAA8\uB378 \uC21C\uC73C\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
672
+ );
673
+ } else {
674
+ console.warn(
675
+ `\u26A0\uFE0F \uBAA8\uB378\uC774 \uC9C0\uC815\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. alias(${aliasFallbacks.join(" -> ")})\uB97C \uC21C\uCC28 \uC2DC\uB3C4\uD558\uACE0 \uB9C8\uC9C0\uB9C9\uC5D0 \uAE30\uBCF8 \uBAA8\uB378\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
676
+ );
677
+ }
678
+ const commandCandidates = modelCandidates.map((model) => buildGeminiExecCommand(prompt, model));
679
+ const command = [...commandCandidates, buildGeminiExecCommand(prompt)].join(" || ");
680
+ trace5("command:created");
681
+ if (args3.includes("--test")) {
261
682
  const safeCommand = command.replace(/"/g, '\\"');
683
+ trace5("test-mode:return-preview");
262
684
  return `echo "[TEST MODE] Gemini \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
263
685
 
264
686
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
265
687
  ${safeCommand}"`;
266
688
  }
689
+ trace5("createGeminiCommand:end");
267
690
  return command;
268
691
  };
692
+ var trace6 = createTraceLogger("installation-gemini");
269
693
  function checkGeminiCliInstalled() {
694
+ trace6("checkGeminiCliInstalled:start");
270
695
  try {
696
+ trace6("version-check:run", "gemini --version");
271
697
  child_process.execSync("gemini --version", { stdio: "ignore" });
698
+ trace6("version-check:ok");
272
699
  } catch {
700
+ trace6("version-check:failed", "install-start");
273
701
  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
702
  try {
275
703
  child_process.execSync("npm install -g @google/gemini-cli", { stdio: "inherit" });
704
+ trace6("install:ok", "exit(1) for login");
276
705
  console.log("\u2705 gemini-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
277
706
  console.log("\u26A0\uFE0F Gemini API \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
278
707
  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
708
  process.exit(1);
280
709
  } catch (installError) {
710
+ trace6("install:failed");
281
711
  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
712
  console.error(installError);
283
713
  process.exit(1);
284
714
  }
285
715
  }
716
+ trace6("checkGeminiCliInstalled:end");
286
717
  }
287
718
 
288
719
  // src/pr-review/review-one-by-one.ts
289
720
  var execAsync = util__default.default.promisify(child_process.exec);
290
721
  async function main() {
291
- const args3 = process.argv.slice(2);
292
- const isTest = args3.includes("--test");
722
+ const args4 = process.argv.slice(2);
723
+ const isTest = isTestMode(args4);
724
+ const trace7 = createTraceLogger("review-one-by-one", args4);
725
+ trace7("main:start", `args=${JSON.stringify(args4)}`);
726
+ trace7("service-selection:start");
293
727
  const service = await showSelectionAIService();
728
+ trace7("service-selection:done", `service=${service}`);
294
729
  switch (service) {
295
730
  case "gemini":
731
+ trace7("install-check:start", "service=gemini");
296
732
  checkGeminiCliInstalled();
733
+ trace7("install-check:done", "service=gemini");
297
734
  break;
298
735
  case "claude":
736
+ trace7("install-check:start", "service=claude");
299
737
  checkClaudeCliInstalled();
738
+ trace7("install-check:done", "service=claude");
739
+ break;
740
+ case "codex":
741
+ trace7("install-check:start", "service=codex");
742
+ checkCodexCliInstalled();
743
+ trace7("install-check:done", "service=codex");
300
744
  break;
301
745
  }
302
746
  try {
747
+ trace7("review-flow:start");
303
748
  console.log("\u{1F680} AI Code Review\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4...");
749
+ trace7("report-dir:create:start");
304
750
  createReportDirectory();
751
+ trace7("report-dir:create:done");
305
752
  const { includeParams, excludeParams } = getGitDiffFilter();
753
+ trace7("diff-filter:loaded", `include=${includeParams} | exclude=${excludeParams}`);
306
754
  const diffArgs = getDiffArgs();
755
+ trace7("diff-args:build:done", `diffArgs=${diffArgs || "(default)"}`);
307
756
  const filesCommand = `git diff --name-only ${diffArgs} -- ${includeParams} ${excludeParams}`;
757
+ trace7("files-command:run", filesCommand);
308
758
  const fileList = child_process.execSync(filesCommand).toString().split("\n").filter(Boolean);
759
+ trace7("files-command:done", `fileCount=${fileList.length}`);
309
760
  if (fileList.length === 0) {
761
+ trace7("empty-file-list:exit");
310
762
  console.log("\u2139\uFE0F \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4.");
311
763
  deleteTempDiff();
312
764
  process.exit(0);
313
765
  }
314
766
  const fullDiffCommand = `git diff ${diffArgs} -- ${includeParams} ${excludeParams}`;
767
+ trace7("full-diff:run");
315
768
  const fullDiff = child_process.execSync(fullDiffCommand).toString();
316
769
  const nowStr = getNowString();
317
- fs4__default.default.writeFileSync(tempDiffPath, fullDiff);
770
+ trace7("full-diff:done", `length=${fullDiff.length}`);
771
+ trace7("timestamp:created", nowStr);
772
+ trace7("temp-diff:write:start", tempDiffPath);
773
+ fs5__default.default.writeFileSync(tempDiffPath, fullDiff);
774
+ trace7("temp-diff:write:done");
775
+ trace7("saved-diff:copy:start");
318
776
  const savedDiffPath = getNextFilePath(REPORT_DIR, `${nowStr}-diff`, ".txt");
319
- fs4__default.default.copyFileSync(tempDiffPath, savedDiffPath);
777
+ fs5__default.default.copyFileSync(tempDiffPath, savedDiffPath);
778
+ trace7("saved-diff:copy:done", savedDiffPath);
320
779
  const savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
780
+ trace7("saved-report:path", savedReportPath);
321
781
  const promises = fileList.map(async (file) => {
322
782
  try {
783
+ trace7("file-review:start", file);
323
784
  console.log(`\u{1F50D} Reviewing: ${file}...`);
785
+ trace7("file-diff:run", file);
324
786
  const fileDiff = child_process.execSync(`git diff ${diffArgs} -- "${file}"`).toString();
787
+ trace7("file-diff:done", `${file} | length=${fileDiff.length}`);
325
788
  const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
326
- fs4__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
789
+ trace7("file-temp-diff:write:start", tempOneFileDiffPath);
790
+ fs5__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
791
+ trace7("file-temp-diff:write:done", tempOneFileDiffPath);
327
792
  let command = "";
793
+ trace7("file-command:create:start", file);
328
794
  switch (service) {
329
795
  case "gemini":
330
796
  command = createGeminiCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
@@ -333,25 +799,37 @@ async function main() {
333
799
  command = createClaudeCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
334
800
  break;
335
801
  case "codex":
802
+ command = createCodexCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
336
803
  break;
337
804
  }
805
+ trace7("file-command:create:done", file);
806
+ trace7("file-command:exec:start", file);
338
807
  const { stdout } = await execAsync(command, { maxBuffer: 1024 * 1024 * 20 });
339
808
  const result = stdout.toString();
809
+ trace7("file-command:exec:done", `${file} | resultLength=${result.length}`);
810
+ trace7("file-temp-diff:delete:start", tempOneFileDiffPath);
340
811
  deleteFile(tempOneFileDiffPath);
812
+ trace7("file-temp-diff:delete:done", tempOneFileDiffPath);
341
813
  const tempReport = `### File: ${file}
342
814
  ${result}
343
815
 
344
816
  `;
345
817
  console.log(tempReport);
346
- fs4__default.default.appendFileSync(savedReportPath, tempReport);
818
+ trace7("file-report:append:start", file);
819
+ fs5__default.default.appendFileSync(savedReportPath, tempReport);
820
+ trace7("file-report:append:done", file);
347
821
  if (isTest) {
348
- fs4__default.default.appendFileSync(savedReportPath, `
822
+ trace7("file-test-command:append:start", file);
823
+ fs5__default.default.appendFileSync(savedReportPath, `
349
824
 
350
825
  ## \uC0AC\uC6A9\uB41C \uBA85\uB839\uC5B4
351
826
 
352
827
  ${command}`);
828
+ trace7("file-test-command:append:done", file);
353
829
  }
830
+ trace7("file-review:end", file);
354
831
  } catch (err) {
832
+ trace7("file-review:catch", file);
355
833
  console.error(`\u274C Error reviewing file ${file}:`, err);
356
834
  const errorReport = `### File: ${file}
357
835
  \u274C Review Failed
@@ -360,28 +838,41 @@ ${err}
360
838
  \`\`\`
361
839
 
362
840
  `;
363
- fs4__default.default.appendFileSync(savedReportPath, errorReport);
841
+ fs5__default.default.appendFileSync(savedReportPath, errorReport);
364
842
  try {
365
843
  const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
366
- if (fs4__default.default.existsSync(tempOneFileDiffPath)) {
844
+ if (fs5__default.default.existsSync(tempOneFileDiffPath)) {
845
+ trace7("file-temp-diff:delete:start(catch)", tempOneFileDiffPath);
367
846
  deleteFile(tempOneFileDiffPath);
847
+ trace7("file-temp-diff:delete:done(catch)", tempOneFileDiffPath);
368
848
  }
369
849
  } catch (e) {
850
+ trace7("file-temp-diff:delete:failed(catch)", file);
370
851
  console.error(`\u274C Error deleting temp file for ${file}:`, e);
371
852
  }
372
853
  }
373
854
  });
855
+ trace7("parallel-review:await-start");
374
856
  await Promise.all(promises);
857
+ trace7("parallel-review:await-done");
375
858
  console.log(`
376
859
  \u2705 \uB9AC\uBDF0\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`);
377
860
  console.log(`\u{1F4C4} \uB9AC\uD3EC\uD2B8 \uC800\uC7A5 \uC704\uCE58: ${savedReportPath}`);
378
861
  console.log(`diff \uC800\uC7A5 \uC704\uCE58: ${savedDiffPath}`);
862
+ trace7("open-report:start");
379
863
  openReport(savedReportPath);
864
+ trace7("open-report:done");
865
+ trace7("cleanup-temp-diff:start");
380
866
  deleteTempDiff();
867
+ trace7("cleanup-temp-diff:done");
868
+ trace7("review-flow:end");
381
869
  } catch (error) {
870
+ trace7("review-flow:catch");
382
871
  console.error("\u274C \uB9AC\uBDF0 \uB3C4\uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.");
383
872
  console.error(error);
873
+ trace7("cleanup-temp-diff:start(catch)");
384
874
  deleteTempDiff();
875
+ trace7("cleanup-temp-diff:done(catch)");
385
876
  process.exit(1);
386
877
  }
387
878
  }