sales-frontend-gemini-cli 0.4.0 → 0.4.2

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 (45) hide show
  1. package/dist/common/helper.cjs +234 -20
  2. package/dist/common/helper.cjs.map +1 -1
  3. package/dist/common/helper.d.cts +23 -3
  4. package/dist/common/helper.d.ts +23 -3
  5. package/dist/common/helper.js +228 -21
  6. package/dist/common/helper.js.map +1 -1
  7. package/dist/pr-review/claude/claude-commander.cjs +142 -28
  8. package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
  9. package/dist/pr-review/claude/claude-commander.d.cts +7 -8
  10. package/dist/pr-review/claude/claude-commander.d.ts +7 -8
  11. package/dist/pr-review/claude/claude-commander.js +142 -28
  12. package/dist/pr-review/claude/claude-commander.js.map +1 -1
  13. package/dist/pr-review/claude/installation-claude.cjs +178 -8
  14. package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
  15. package/dist/pr-review/claude/installation-claude.js +177 -8
  16. package/dist/pr-review/claude/installation-claude.js.map +1 -1
  17. package/dist/pr-review/codex/codex-commander.cjs +64 -21
  18. package/dist/pr-review/codex/codex-commander.cjs.map +1 -1
  19. package/dist/pr-review/codex/codex-commander.d.cts +8 -3
  20. package/dist/pr-review/codex/codex-commander.d.ts +8 -3
  21. package/dist/pr-review/codex/codex-commander.js +64 -21
  22. package/dist/pr-review/codex/codex-commander.js.map +1 -1
  23. package/dist/pr-review/codex/installation-codex.cjs +178 -8
  24. package/dist/pr-review/codex/installation-codex.cjs.map +1 -1
  25. package/dist/pr-review/codex/installation-codex.js +177 -8
  26. package/dist/pr-review/codex/installation-codex.js.map +1 -1
  27. package/dist/pr-review/gemini/gemini-commander.cjs +122 -21
  28. package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
  29. package/dist/pr-review/gemini/gemini-commander.d.cts +10 -13
  30. package/dist/pr-review/gemini/gemini-commander.d.ts +10 -13
  31. package/dist/pr-review/gemini/gemini-commander.js +122 -21
  32. package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
  33. package/dist/pr-review/gemini/installation-gemini.cjs +178 -8
  34. package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
  35. package/dist/pr-review/gemini/installation-gemini.js +177 -8
  36. package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
  37. package/dist/pr-review/review-one-by-one.cjs +679 -157
  38. package/dist/pr-review/review-one-by-one.cjs.map +1 -1
  39. package/dist/pr-review/review-one-by-one.js +679 -157
  40. package/dist/pr-review/review-one-by-one.js.map +1 -1
  41. package/dist/pr-review/review.cjs +630 -132
  42. package/dist/pr-review/review.cjs.map +1 -1
  43. package/dist/pr-review/review.js +630 -132
  44. package/dist/pr-review/review.js.map +1 -1
  45. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  'use strict';
3
3
 
4
4
  var child_process = require('child_process');
5
- var fs5 = require('fs');
5
+ var fs = require('fs');
6
6
  var util = require('util');
7
7
  var path = require('path');
8
8
  var readline = require('readline');
@@ -11,12 +11,13 @@ 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 fs5__default = /*#__PURE__*/_interopDefault(fs5);
14
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
15
15
  var util__default = /*#__PURE__*/_interopDefault(util);
16
16
  var path__default = /*#__PURE__*/_interopDefault(path);
17
17
  var readline__default = /*#__PURE__*/_interopDefault(readline);
18
18
 
19
19
  var __dirname$1 = path__default.default.dirname(url.fileURLToPath((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('review-one-by-one.cjs', document.baseURI).href))));
20
+ var traceMessages = [];
20
21
  var rulesPath = path__default.default.resolve(__dirname$1, "../../src/common/rules/review-rules.md");
21
22
  var namingRulesPath = path__default.default.resolve(__dirname$1, "../../src/common/rules/naming-rule.md");
22
23
  var codingConventionRulesPath = path__default.default.resolve(__dirname$1, "../../src/common/rules/coding-convention.md");
@@ -42,48 +43,223 @@ var ignoreList = [
42
43
  function isTestMode(args4 = process.argv.slice(2)) {
43
44
  return args4.includes("--test");
44
45
  }
46
+ function clearTraceMessages() {
47
+ traceMessages.length = 0;
48
+ }
49
+ function getTraceMessages() {
50
+ return [...traceMessages];
51
+ }
45
52
  function createTraceLogger(scope, args4 = process.argv.slice(2)) {
46
53
  const enabled = isTestMode(args4);
47
54
  return (step, detail) => {
55
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
56
+ const message = `[${timestamp}][TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ""}`;
57
+ traceMessages.push(message);
48
58
  if (!enabled) {
49
59
  return;
50
60
  }
51
- console.log(`[TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ""}`);
61
+ console.log(message);
62
+ };
63
+ }
64
+ var helperTrace = createTraceLogger("helper");
65
+ function getTimestampParts(now = /* @__PURE__ */ new Date()) {
66
+ return {
67
+ YYYY: now.getFullYear(),
68
+ MM: String(now.getMonth() + 1).padStart(2, "0"),
69
+ DD: String(now.getDate()).padStart(2, "0"),
70
+ HH: String(now.getHours()).padStart(2, "0"),
71
+ mm: String(now.getMinutes()).padStart(2, "0"),
72
+ ss: String(now.getSeconds()).padStart(2, "0")
52
73
  };
53
74
  }
75
+ function getHumanReadableNowString(now = /* @__PURE__ */ new Date()) {
76
+ const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);
77
+ return `${YYYY}-${MM}-${DD} ${HH}:${mm}:${ss}`;
78
+ }
79
+ function stringifyUnknown(value) {
80
+ if (value === void 0 || value === null) {
81
+ return "";
82
+ }
83
+ if (typeof value === "string") {
84
+ return value;
85
+ }
86
+ if (Buffer.isBuffer(value)) {
87
+ return value.toString();
88
+ }
89
+ if (value instanceof Error) {
90
+ return value.stack || value.message;
91
+ }
92
+ return util.inspect(value, { depth: 5, breakLength: 120 });
93
+ }
94
+ function getErrorSummary(error) {
95
+ if (error instanceof Error) {
96
+ return `${error.name}: ${error.message}`;
97
+ }
98
+ return stringifyUnknown(error) || "Unknown error";
99
+ }
100
+ function serializeError(error) {
101
+ const serialized = {
102
+ summary: getErrorSummary(error)
103
+ };
104
+ if (error instanceof Error) {
105
+ serialized.name = error.name;
106
+ serialized.message = error.message;
107
+ serialized.stack = error.stack;
108
+ } else {
109
+ serialized.value = stringifyUnknown(error);
110
+ }
111
+ if (error && typeof error === "object") {
112
+ const errorLike = error;
113
+ const extraKeys = ["code", "errno", "syscall", "path", "cmd", "status", "signal", "spawnargs"];
114
+ extraKeys.forEach((key) => {
115
+ if (errorLike[key] !== void 0) {
116
+ serialized[key] = errorLike[key];
117
+ }
118
+ });
119
+ const stdout = stringifyUnknown(errorLike.stdout);
120
+ if (stdout) {
121
+ serialized.stdout = stdout;
122
+ }
123
+ const stderr = stringifyUnknown(errorLike.stderr);
124
+ if (stderr) {
125
+ serialized.stderr = stderr;
126
+ }
127
+ const cause = stringifyUnknown(errorLike.cause);
128
+ if (cause) {
129
+ serialized.cause = cause;
130
+ }
131
+ }
132
+ return serialized;
133
+ }
54
134
  function getNextFilePath(dir, baseName, extension) {
55
135
  let counter = 1;
56
136
  while (true) {
57
137
  const filePath = path__default.default.join(dir, `${baseName}-${counter}${extension}`);
58
- if (!fs5__default.default.existsSync(filePath)) {
138
+ if (!fs__default.default.existsSync(filePath)) {
59
139
  return filePath;
60
140
  }
61
141
  counter++;
62
142
  }
63
143
  }
144
+ function getAvailableFilePath(dir, baseName, extension) {
145
+ const firstFilePath = path__default.default.join(dir, `${baseName}${extension}`);
146
+ if (!fs__default.default.existsSync(firstFilePath)) {
147
+ return firstFilePath;
148
+ }
149
+ return getNextFilePath(dir, baseName, extension);
150
+ }
64
151
  function deleteFile(filePath) {
65
- if (fs5__default.default.existsSync(filePath)) {
66
- fs5__default.default.unlinkSync(filePath);
152
+ if (fs__default.default.existsSync(filePath)) {
153
+ fs__default.default.unlinkSync(filePath);
67
154
  }
68
155
  }
69
156
  function deleteTempDiff() {
70
157
  deleteFile(tempDiffPath);
71
158
  }
72
159
  function createReportDirectory() {
73
- if (!fs5__default.default.existsSync(REPORT_DIR)) {
74
- fs5__default.default.mkdirSync(REPORT_DIR, { recursive: true });
75
- }
76
- }
77
- function getNowString() {
78
- const now = /* @__PURE__ */ new Date();
79
- const YYYY = now.getFullYear();
80
- const MM = String(now.getMonth() + 1).padStart(2, "0");
81
- const DD = String(now.getDate()).padStart(2, "0");
82
- const HH = String(now.getHours()).padStart(2, "0");
83
- const mm = String(now.getMinutes()).padStart(2, "0");
84
- const ss = String(now.getSeconds()).padStart(2, "0");
160
+ if (!fs__default.default.existsSync(REPORT_DIR)) {
161
+ fs__default.default.mkdirSync(REPORT_DIR, { recursive: true });
162
+ }
163
+ }
164
+ function getNowString(now = /* @__PURE__ */ new Date()) {
165
+ const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);
85
166
  return `${YYYY}-${MM}-${DD}_${HH}-${mm}-${ss}`;
86
167
  }
168
+ function getErrorLogTimestamp(now = /* @__PURE__ */ new Date()) {
169
+ const { YYYY, MM, DD, HH, mm, ss } = getTimestampParts(now);
170
+ return `${YYYY}-${MM}-${DD}-${HH}\uC2DC-${mm}\uBD84-${ss}\uCD08`;
171
+ }
172
+ function writeErrorReport(error, options = {}) {
173
+ try {
174
+ const now = /* @__PURE__ */ new Date();
175
+ helperTrace("error-report:write:start", options.scope || "unknown");
176
+ createReportDirectory();
177
+ const reportPath = getAvailableFilePath(REPORT_DIR, `error-log-${getErrorLogTimestamp(now)}`, ".md");
178
+ const serializedError = serializeError(error);
179
+ const traceSnapshot = options.traceMessages ?? getTraceMessages();
180
+ const extraSections = options.extraSections || [];
181
+ const report = `# Error Log
182
+
183
+ - \uBC1C\uC0DD \uC2DC\uAC01: ${getHumanReadableNowString(now)}
184
+ - Scope: \`${options.scope || "unknown"}\`
185
+ - \uC791\uC5C5 \uACBD\uB85C: \`${process.cwd()}\`
186
+ - \uC2E4\uD589 \uC778\uC790: \`${JSON.stringify(options.args ?? process.argv.slice(2))}\`
187
+ - \uC2E4\uD589 \uD658\uACBD: \`${process.platform} ${process.arch} / Node ${process.version}\`
188
+
189
+ ## Summary
190
+
191
+ ${options.title || serializedError.summary || "Unknown error"}
192
+
193
+ ## Error
194
+
195
+ \`\`\`json
196
+ ${JSON.stringify(serializedError, null, 2)}
197
+ \`\`\`
198
+
199
+ ## Trace
200
+
201
+ \`\`\`json
202
+ ${JSON.stringify(traceSnapshot, null, 2)}
203
+ \`\`\`${extraSections.length ? `
204
+ ${extraSections.map((section) => `
205
+ ## ${section.heading}
206
+
207
+ ${section.markdown}`).join("\n")}
208
+ ` : "\n"}
209
+ `;
210
+ fs__default.default.writeFileSync(reportPath, report);
211
+ helperTrace("error-report:write:done", reportPath);
212
+ return reportPath;
213
+ } catch (writeError) {
214
+ console.error("\u26A0\uFE0F \uC5D0\uB7EC \uB85C\uADF8 \uD30C\uC77C \uC0DD\uC131\uC5D0 \uC2E4\uD328\uD588\uC2B5\uB2C8\uB2E4.");
215
+ console.error(writeError);
216
+ return "";
217
+ }
218
+ }
219
+ function exitWithError(message, options = {}) {
220
+ const reportPath = writeErrorReport(options.error || new Error(message), {
221
+ ...options,
222
+ title: message
223
+ });
224
+ console.error(message);
225
+ if (options.error) {
226
+ console.error(options.error);
227
+ }
228
+ if (reportPath) {
229
+ console.error(`\u{1F4C4} \uC5D0\uB7EC \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${reportPath}`);
230
+ }
231
+ process.exit(1);
232
+ }
233
+ function parseServiceFromArgs(args4 = process.argv.slice(2)) {
234
+ helperTrace("parse-service:start", `args=${JSON.stringify(args4)}`);
235
+ const serviceIndex = args4.indexOf("--service");
236
+ const rawService = serviceIndex !== -1 ? args4[serviceIndex + 1] : "";
237
+ if (!rawService) {
238
+ helperTrace("parse-service:empty");
239
+ return "";
240
+ }
241
+ const normalizedService = rawService.toLowerCase();
242
+ if (AIServices.includes(normalizedService)) {
243
+ helperTrace("parse-service:resolved", normalizedService);
244
+ return normalizedService;
245
+ }
246
+ helperTrace("parse-service:invalid", rawService);
247
+ exitWithError(
248
+ `\u274C \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uC11C\uBE44\uC2A4\uC785\uB2C8\uB2E4: ${rawService}. \uC0AC\uC6A9 \uAC00\uB2A5 \uAC12: ${AIServices.join(", ")} (\uC608: --service codex)`,
249
+ {
250
+ scope: "helper:parseServiceFromArgs",
251
+ args: args4,
252
+ extraSections: [
253
+ {
254
+ heading: "Allowed Services",
255
+ markdown: `\`\`\`json
256
+ ${JSON.stringify(AIServices, null, 2)}
257
+ \`\`\``
258
+ }
259
+ ]
260
+ }
261
+ );
262
+ }
87
263
  function getGitDiffFilter() {
88
264
  const includeExtensions = ["*.ts", "*.tsx", "*.js", "*.jsx"];
89
265
  const excludePatterns = ignoreList.map((item) => `:(exclude)${item}`);
@@ -95,6 +271,7 @@ function getGitDiffFilter() {
95
271
  function openReport(reportPath) {
96
272
  const resolvedPath = path__default.default.resolve(reportPath);
97
273
  const { platform } = process;
274
+ helperTrace("open-report:start", resolvedPath);
98
275
  const openWithChrome = () => {
99
276
  if (platform === "darwin") {
100
277
  child_process.execSync(`open -a "Google Chrome" "${resolvedPath}"`, { stdio: "ignore" });
@@ -119,32 +296,41 @@ function openReport(reportPath) {
119
296
  };
120
297
  try {
121
298
  if (openWithChrome()) {
299
+ helperTrace("open-report:chrome:success", platform);
122
300
  console.log("\u{1F680} Google Chrome\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
123
301
  return;
124
302
  }
125
- } catch {
303
+ } catch (error) {
304
+ helperTrace("open-report:chrome:failed", getErrorSummary(error));
126
305
  }
127
306
  try {
128
307
  if (openWithDefaultBrowser()) {
308
+ helperTrace("open-report:default-browser:success", platform);
129
309
  console.log("\u{1F680} \uAE30\uBCF8 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
130
310
  return;
131
311
  }
132
- } catch (e) {
133
- console.error("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30 \uC2E4\uD328:", e);
312
+ } catch (error) {
313
+ helperTrace("open-report:default-browser:failed", getErrorSummary(error));
314
+ console.error("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30 \uC2E4\uD328:", error);
134
315
  return;
135
316
  }
317
+ helperTrace("open-report:unsupported-platform", platform);
136
318
  console.error(`\u26A0\uFE0F \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD50C\uB7AB\uD3FC\uC785\uB2C8\uB2E4: ${platform}`);
137
319
  }
138
320
  function getDiffArgs() {
139
321
  const args4 = process.argv.slice(2);
140
322
  const commitIndex = args4.indexOf("--commit");
141
323
  const { includeParams, excludeParams } = getGitDiffFilter();
324
+ helperTrace("diff-args:resolve:start", `args=${JSON.stringify(args4)}`);
142
325
  let diffArgs = "";
143
326
  if (commitIndex !== -1) {
144
327
  const commitHash = args4[commitIndex + 1];
145
328
  if (!commitHash) {
146
- console.error("\u274C \uCEE4\uBC0B \uD574\uC2DC\uAC00 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
147
- process.exit(1);
329
+ helperTrace("diff-args:commit-hash-missing");
330
+ exitWithError("\u274C \uCEE4\uBC0B \uD574\uC2DC\uAC00 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.", {
331
+ scope: "helper:getDiffArgs",
332
+ args: args4
333
+ });
148
334
  }
149
335
  const nextArg = args4[commitIndex + 2];
150
336
  let n = 0;
@@ -154,21 +340,37 @@ function getDiffArgs() {
154
340
  n = 0;
155
341
  }
156
342
  }
343
+ helperTrace("diff-args:commit-mode", `${commitHash}~${n + 1} ${commitHash}`);
157
344
  console.log(`\u2139\uFE0F \uCEE4\uBC0B '${commitHash}' ${n > 0 ? ` \uD3EC\uD568 \uCD1D ${n + 1}\uAC1C\uC758 \uCEE4\uBC0B` : ""}\uC744 \uB9AC\uBDF0\uD569\uB2C8\uB2E4...`);
158
345
  diffArgs = `${commitHash}~${n + 1} ${commitHash}`;
159
346
  } else {
160
347
  try {
348
+ helperTrace("diff-args:unstaged-check:start");
161
349
  const check = child_process.execSync(`git diff --name-only -- ${includeParams} ${excludeParams}`).toString();
162
350
  if (!check.trim()) {
351
+ helperTrace("diff-args:unstaged-check:empty", "use HEAD~1 HEAD");
163
352
  console.log("\u2139\uFE0F Unstaged \uBCC0\uACBD\uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4. \uB9C8\uC9C0\uB9C9 \uCEE4\uBC0B(HEAD)\uC744 \uB9AC\uBDF0\uD569\uB2C8\uB2E4...");
164
353
  diffArgs = "HEAD~1 HEAD";
354
+ } else {
355
+ helperTrace("diff-args:unstaged-check:has-changes", `length=${check.length}`);
165
356
  }
166
- } catch {
357
+ } catch (error) {
358
+ helperTrace("diff-args:unstaged-check:failed", getErrorSummary(error));
167
359
  }
168
360
  }
361
+ helperTrace("diff-args:resolve:done", diffArgs || "(default)");
169
362
  return diffArgs;
170
363
  }
171
364
  async function showSelectionAIService() {
365
+ const selectedServiceFromArgs = parseServiceFromArgs();
366
+ if (selectedServiceFromArgs) {
367
+ helperTrace("show-selection:from-args", selectedServiceFromArgs);
368
+ console.log(`
369
+ \u2705 \x1B[32m${selectedServiceFromArgs}\x1B[0m \uC11C\uBE44\uC2A4\uAC00 \uC120\uD0DD\uB418\uC5C8\uC2B5\uB2C8\uB2E4. (--service)
370
+ `);
371
+ return selectedServiceFromArgs;
372
+ }
373
+ helperTrace("show-selection:interactive:start");
172
374
  let selectedIndex = 0;
173
375
  const rl = readline__default.default.createInterface({
174
376
  input: process.stdin,
@@ -182,6 +384,7 @@ async function showSelectionAIService() {
182
384
  readline__default.default.moveCursor(process.stdout, 0, -(AIServices.length + 1));
183
385
  }
184
386
  firstRender = false;
387
+ helperTrace("show-selection:interactive:render", AIServices[selectedIndex] || "unknown");
185
388
  readline__default.default.clearScreenDown(process.stdout);
186
389
  process.stdout.write(
187
390
  "\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"
@@ -201,6 +404,7 @@ async function showSelectionAIService() {
201
404
  const onData = (data) => {
202
405
  const key = data.toString();
203
406
  if (key === "") {
407
+ helperTrace("show-selection:interactive:ctrl-c");
204
408
  process.stdout.write("\x1B[?25h");
205
409
  process.exit(0);
206
410
  }
@@ -221,6 +425,7 @@ async function showSelectionAIService() {
221
425
  `);
222
426
  const result = AIServices[selectedIndex];
223
427
  if (result) {
428
+ helperTrace("show-selection:interactive:confirmed", result);
224
429
  resolve(result);
225
430
  }
226
431
  }
@@ -232,40 +437,150 @@ async function showSelectionAIService() {
232
437
  }
233
438
  var args = process.argv.slice(2);
234
439
  var trace = createTraceLogger("claude-commander", args);
235
- var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
236
- trace("createClaudeCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
237
- let modelOption = "";
238
- if (args.includes("--review")) {
239
- modelOption = "--model opus";
240
- trace("model:review", modelOption);
241
- } else if (args.includes("--flash")) {
242
- modelOption = "--model haiku";
243
- trace("model:flash", modelOption);
244
- } else {
245
- const modelIndex = args.indexOf("--model");
246
- if (modelIndex !== -1 && args[modelIndex + 1]) {
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.");
248
- modelOption = `--model ${args[modelIndex + 1]}`;
249
- trace("model:custom", modelOption);
250
- } else {
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.");
252
- modelOption = "--model sonnet";
253
- trace("model:default", modelOption);
440
+ var ALLOWED_REASONING_EFFORTS = ["minimal", "low", "medium", "high"];
441
+ function shellQuote(value) {
442
+ return `'${value.replace(/'/g, `'\\''`)}'`;
443
+ }
444
+ function getArgValue(flag) {
445
+ const index = args.indexOf(flag);
446
+ if (index === -1 || !args[index + 1]) {
447
+ return "";
448
+ }
449
+ return args[index + 1];
450
+ }
451
+ function toUnique(values) {
452
+ const seen = /* @__PURE__ */ new Set();
453
+ return values.filter((value) => {
454
+ if (!value || seen.has(value)) {
455
+ return false;
456
+ }
457
+ seen.add(value);
458
+ return true;
459
+ });
460
+ }
461
+ function normalizeEffort(level) {
462
+ if (level === "minimal") {
463
+ return "low";
464
+ }
465
+ return level;
466
+ }
467
+ function resolveReasoningEffort() {
468
+ const customReasoningEffort = getArgValue("--reasoning-effort") || getArgValue("--effort");
469
+ if (customReasoningEffort) {
470
+ if (ALLOWED_REASONING_EFFORTS.includes(customReasoningEffort)) {
471
+ const normalized = normalizeEffort(customReasoningEffort);
472
+ trace("reasoning:custom", `${customReasoningEffort} -> ${normalized}`);
473
+ if (customReasoningEffort === "minimal") {
474
+ console.warn("\u26A0\uFE0F Claude\uB294 minimal\uC744 \uC9C1\uC811 \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uC544 low\uB85C \uB9E4\uD551\uD569\uB2C8\uB2E4.");
475
+ }
476
+ return normalized;
254
477
  }
478
+ console.warn(
479
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS.join(
480
+ ", "
481
+ )}`
482
+ );
483
+ }
484
+ if (args.includes("--flash")) {
485
+ trace("reasoning:flash-default", "low");
486
+ return "low";
487
+ }
488
+ if (args.includes("--review")) {
489
+ trace("reasoning:review-default", "high");
490
+ return "high";
491
+ }
492
+ trace("reasoning:default", "medium");
493
+ return "medium";
494
+ }
495
+ function resolvePrimaryAlias() {
496
+ if (args.includes("--review")) {
497
+ trace("model:mode-alias", "opus");
498
+ return "opus";
499
+ }
500
+ if (args.includes("--flash")) {
501
+ trace("model:mode-alias", "haiku");
502
+ return "haiku";
503
+ }
504
+ trace("model:default-alias", "sonnet");
505
+ return "sonnet";
506
+ }
507
+ function getAliasFallbacks(primaryAlias) {
508
+ if (primaryAlias === "opus") {
509
+ return ["opus", "sonnet", "haiku"];
510
+ }
511
+ if (primaryAlias === "haiku") {
512
+ return ["haiku", "sonnet"];
255
513
  }
514
+ return [primaryAlias, "sonnet", "haiku"];
515
+ }
516
+ function buildClaudeExecCommand(options) {
517
+ const { tempDiffPath: tempDiffPath2, prompt, systemPromptFiles, effort, model, fallbackModel } = options;
518
+ const modelOption = model ? `--model ${shellQuote(model)}` : "";
519
+ const fallbackOption = model && fallbackModel ? `--fallback-model ${shellQuote(fallbackModel)}` : "";
520
+ const effortOption = `--effort ${shellQuote(effort)}`;
521
+ const appendedPromptFiles = systemPromptFiles.map((path2) => `--append-system-prompt-file ${shellQuote(path2)}`).join(" ");
522
+ return `cat ${shellQuote(tempDiffPath2)} | claude ${[
523
+ modelOption,
524
+ fallbackOption,
525
+ effortOption,
526
+ appendedPromptFiles,
527
+ "-p",
528
+ shellQuote(prompt)
529
+ ].filter(Boolean).join(" ")}`;
530
+ }
531
+ var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
532
+ trace("createClaudeCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
533
+ const customModel = getArgValue("--model");
534
+ const effort = resolveReasoningEffort();
535
+ const primaryAlias = resolvePrimaryAlias();
536
+ const aliasFallbacks = toUnique(getAliasFallbacks(primaryAlias));
256
537
  const rules = [
257
538
  { path: rulesPath, display: "\uB8F0\uC14B" },
258
539
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
259
540
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
260
541
  ];
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");
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."`;
542
+ const existingRuleFiles = rules.filter((rule) => fs__default.default.existsSync(rule.path)).map((rule) => rule.path);
543
+ trace("rules:loaded", `count=${existingRuleFiles.length}`);
544
+ const reviewFormExists = fs__default.default.existsSync(reviewFormPath2);
545
+ trace("reviewForm:status", reviewFormExists ? "exists" : "missing");
546
+ const systemPromptFiles = reviewFormExists ? [...existingRuleFiles, reviewFormPath2] : existingRuleFiles;
547
+ 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.";
548
+ trace("prompt:prepared", `length=${prompt.length}`);
549
+ trace("system-prompt-files", `count=${systemPromptFiles.length}`);
550
+ const modelCandidates = toUnique(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
551
+ trace("model:candidates", modelCandidates.join(", "));
552
+ trace("command:candidates:count", String(modelCandidates.length + 1));
553
+ if (customModel) {
554
+ console.warn(
555
+ `\u26A0\uFE0F \uCEE4\uC2A4\uD140 \uBAA8\uB378(${customModel})\uC744 \uC6B0\uC120 \uC2DC\uB3C4\uD558\uACE0 \uC2E4\uD328\uD558\uBA74 alias(${aliasFallbacks.join(
556
+ " -> "
557
+ )}) \uBC0F \uAE30\uBCF8 \uBAA8\uB378 \uC21C\uC73C\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
558
+ );
559
+ } else {
560
+ console.warn(
561
+ `\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.`
562
+ );
563
+ }
564
+ const commandCandidates = modelCandidates.map((model, index) => {
565
+ const fallbackModel = modelCandidates[index + 1];
566
+ return buildClaudeExecCommand({
567
+ tempDiffPath: tempDiffPath2,
568
+ prompt,
569
+ systemPromptFiles,
570
+ effort,
571
+ model,
572
+ fallbackModel
573
+ });
574
+ });
575
+ const command = [
576
+ ...commandCandidates,
577
+ buildClaudeExecCommand({
578
+ tempDiffPath: tempDiffPath2,
579
+ prompt,
580
+ systemPromptFiles,
581
+ effort
582
+ })
583
+ ].join(" || ");
269
584
  trace("command:created");
270
585
  if (args.includes("--test")) {
271
586
  const safeCommand = command.replace(/"/g, '\\"');
@@ -275,6 +590,7 @@ var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
275
590
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
276
591
  ${safeCommand}"`;
277
592
  }
593
+ trace("command:mode", "execute");
278
594
  trace("createClaudeCommand:end");
279
595
  return command;
280
596
  };
@@ -285,54 +601,79 @@ function checkClaudeCliInstalled() {
285
601
  trace2("version-check:run", "claude --version");
286
602
  child_process.execSync("claude --version", { stdio: "ignore" });
287
603
  trace2("version-check:ok");
288
- } catch {
289
- trace2("version-check:failed", "install-start");
604
+ } catch (error) {
605
+ trace2("version-check:failed", getErrorSummary(error));
606
+ trace2("install:start", "@anthropic-ai/claude-code");
290
607
  console.log(
291
608
  "\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
609
  );
293
610
  try {
294
611
  child_process.execSync("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
295
- trace2("install:ok", "exit(1) for login");
612
+ trace2("install:ok", "login-required");
296
613
  console.log("\u2705 claude-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
297
614
  console.log("\u26A0\uFE0F claude-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
298
615
  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.');
299
616
  process.exit(1);
300
617
  } catch (installError) {
301
- trace2("install:failed");
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).");
303
- console.error(installError);
304
- process.exit(1);
618
+ trace2("install:failed", getErrorSummary(installError));
619
+ exitWithError("\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).", {
620
+ scope: "installation-claude",
621
+ error: installError
622
+ });
305
623
  }
306
624
  }
307
625
  trace2("checkClaudeCliInstalled:end");
308
626
  }
309
627
  var args2 = process.argv.slice(2);
310
628
  var trace3 = createTraceLogger("codex-commander", args2);
311
- var createCodexCommand = (tempDiffPath2, reviewFormPath2) => {
312
- trace3("createCodexCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
313
- let modelOption = "";
314
- if (args2.includes("--review")) {
315
- modelOption = "--model gpt-5";
316
- trace3("model:review", modelOption);
317
- } else if (args2.includes("--flash")) {
318
- modelOption = "--model gpt-5-mini";
319
- trace3("model:flash", modelOption);
320
- } else {
321
- const modelIndex = args2.indexOf("--model");
322
- if (modelIndex !== -1 && args2[modelIndex + 1]) {
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.");
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);
629
+ var ALLOWED_REASONING_EFFORTS2 = ["minimal", "low", "medium", "high"];
630
+ function shellQuote2(value) {
631
+ return `'${value.replace(/'/g, `'\\''`)}'`;
632
+ }
633
+ function getArgValue2(flag) {
634
+ const index = args2.indexOf(flag);
635
+ if (index === -1 || !args2[index + 1]) {
636
+ return "";
637
+ }
638
+ return args2[index + 1];
639
+ }
640
+ function resolveReasoningEffort2() {
641
+ const customReasoningEffort = getArgValue2("--reasoning-effort");
642
+ if (customReasoningEffort) {
643
+ if (ALLOWED_REASONING_EFFORTS2.includes(customReasoningEffort)) {
644
+ trace3("reasoning:custom", customReasoningEffort);
645
+ return customReasoningEffort;
330
646
  }
647
+ console.warn(
648
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS2.join(
649
+ ", "
650
+ )}`
651
+ );
331
652
  }
332
- const rules = [rulesPath, namingRulesPath, codingConventionRulesPath].filter((filePath) => fs5__default.default.existsSync(filePath)).map((filePath) => `- ${filePath}`).join("\n");
653
+ if (args2.includes("--flash")) {
654
+ trace3("reasoning:flash-default", "minimal");
655
+ return "minimal";
656
+ }
657
+ if (args2.includes("--review")) {
658
+ trace3("reasoning:review-default", "high");
659
+ return "high";
660
+ }
661
+ trace3("reasoning:default", "medium");
662
+ return "medium";
663
+ }
664
+ function buildCodexExecCommand(prompt, reasoningEffort, model) {
665
+ const modelOption = model ? `--model ${shellQuote2(model)}` : "";
666
+ const reasoningOption = `-c ${shellQuote2(`model_reasoning_effort="${reasoningEffort}"`)}`;
667
+ return `codex exec ${[modelOption, reasoningOption, shellQuote2(prompt)].filter(Boolean).join(" ")}`;
668
+ }
669
+ var createCodexCommand = (tempDiffPath2, reviewFormPath2) => {
670
+ trace3("createCodexCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
671
+ const customModel = getArgValue2("--model");
672
+ const reasoningEffort = resolveReasoningEffort2();
673
+ const rules = [rulesPath, namingRulesPath, codingConventionRulesPath].filter((filePath) => fs__default.default.existsSync(filePath)).map((filePath) => `- ${filePath}`).join("\n");
333
674
  const rulesCount = rules ? rules.split("\n").length : 0;
334
675
  trace3("rules:loaded", `count=${rulesCount}`);
335
- const hasReviewForm = fs5__default.default.existsSync(reviewFormPath2);
676
+ const hasReviewForm = fs__default.default.existsSync(reviewFormPath2);
336
677
  const reviewFormLine = hasReviewForm ? `- ${reviewFormPath2}` : "";
337
678
  trace3("reviewForm:status", reviewFormLine ? "exists" : "missing");
338
679
  const prompt = `\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.
@@ -344,7 +685,23 @@ ${reviewFormLine || "- (\uC5C6\uC74C)"}
344
685
  - ${tempDiffPath2}
345
686
 
346
687
  \uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.`;
347
- const command = `codex exec ${modelOption} "${prompt.replace(/"/g, '\\"')}"`;
688
+ trace3("prompt:prepared", `length=${prompt.length}`);
689
+ let command = "";
690
+ if (customModel) {
691
+ 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.");
692
+ trace3("model:custom", customModel);
693
+ command = buildCodexExecCommand(prompt, reasoningEffort, customModel);
694
+ } else {
695
+ const preferredModelAlias = "gpt-5";
696
+ const aliasCommand = buildCodexExecCommand(prompt, reasoningEffort, preferredModelAlias);
697
+ const fallbackCommand = buildCodexExecCommand(prompt, reasoningEffort);
698
+ console.warn(
699
+ `\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.`
700
+ );
701
+ trace3("model:alias-first", preferredModelAlias);
702
+ trace3("model:fallback", "account-default");
703
+ command = `${aliasCommand} || ${fallbackCommand}`;
704
+ }
348
705
  trace3("command:created");
349
706
  if (args2.includes("--test")) {
350
707
  const safeCommand = command.replace(/"/g, '\\"');
@@ -354,6 +711,7 @@ ${reviewFormLine || "- (\uC5C6\uC74C)"}
354
711
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
355
712
  ${safeCommand}"`;
356
713
  }
714
+ trace3("command:mode", "execute");
357
715
  trace3("createCodexCommand:end");
358
716
  return command;
359
717
  };
@@ -364,57 +722,156 @@ function checkCodexCliInstalled() {
364
722
  trace4("version-check:run", "codex --version");
365
723
  child_process.execSync("codex --version", { stdio: "ignore" });
366
724
  trace4("version-check:ok");
367
- } catch {
368
- trace4("version-check:failed", "install-start");
725
+ } catch (error) {
726
+ trace4("version-check:failed", getErrorSummary(error));
727
+ trace4("install:start", "@openai/codex");
369
728
  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
729
  try {
371
730
  child_process.execSync("npm install -g @openai/codex", { stdio: "inherit" });
372
- trace4("install:ok", "exit(1) for login");
731
+ trace4("install:ok", "login-required");
373
732
  console.log("\u2705 codex-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
374
733
  console.log("\u26A0\uFE0F codex-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
375
734
  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
735
  process.exit(1);
377
736
  } 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);
737
+ trace4("install:failed", getErrorSummary(installError));
738
+ exitWithError("\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).", {
739
+ scope: "installation-codex",
740
+ error: installError
741
+ });
382
742
  }
383
743
  }
384
744
  trace4("checkCodexCliInstalled:end");
385
745
  }
386
746
  var args3 = process.argv.slice(2);
387
747
  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);
403
- } else {
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.");
405
- modelOption = "--model flash";
406
- trace5("model:default", modelOption);
748
+ var ALLOWED_REASONING_EFFORTS3 = ["minimal", "low", "medium", "high"];
749
+ function shellQuote3(value) {
750
+ return `'${value.replace(/'/g, `'\\''`)}'`;
751
+ }
752
+ function getArgValue3(flag) {
753
+ const index = args3.indexOf(flag);
754
+ if (index === -1 || !args3[index + 1]) {
755
+ return "";
756
+ }
757
+ return args3[index + 1];
758
+ }
759
+ function toUnique2(values) {
760
+ const seen = /* @__PURE__ */ new Set();
761
+ return values.filter((value) => {
762
+ if (!value || seen.has(value)) {
763
+ return false;
764
+ }
765
+ seen.add(value);
766
+ return true;
767
+ });
768
+ }
769
+ function resolveReasoningEffort3() {
770
+ const customReasoningEffort = getArgValue3("--reasoning-effort");
771
+ if (customReasoningEffort) {
772
+ if (ALLOWED_REASONING_EFFORTS3.includes(customReasoningEffort)) {
773
+ trace5("reasoning:custom", customReasoningEffort);
774
+ return customReasoningEffort;
407
775
  }
776
+ console.warn(
777
+ `\u26A0\uFE0F \uC9C0\uC6D0\uB418\uC9C0 \uC54A\uB294 reasoning effort(${customReasoningEffort})\uC785\uB2C8\uB2E4. allowed: ${ALLOWED_REASONING_EFFORTS3.join(
778
+ ", "
779
+ )}`
780
+ );
781
+ }
782
+ if (args3.includes("--flash")) {
783
+ trace5("reasoning:flash-default", "minimal");
784
+ return "minimal";
785
+ }
786
+ if (args3.includes("--review")) {
787
+ trace5("reasoning:review-default", "high");
788
+ return "high";
789
+ }
790
+ trace5("reasoning:default", "medium");
791
+ return "medium";
792
+ }
793
+ function resolvePrimaryAlias2(reasoningEffort) {
794
+ if (args3.includes("--review")) {
795
+ trace5("model:mode-alias", "pro");
796
+ return "pro";
797
+ }
798
+ if (args3.includes("--flash")) {
799
+ trace5("model:mode-alias", "flash");
800
+ return "flash";
801
+ }
802
+ if (reasoningEffort === "high") {
803
+ trace5("model:reasoning-alias", "pro");
804
+ return "pro";
408
805
  }
806
+ if (reasoningEffort === "minimal" || reasoningEffort === "low") {
807
+ trace5("model:reasoning-alias", "flash");
808
+ return "flash";
809
+ }
810
+ trace5("model:default-alias", "auto");
811
+ return "auto";
812
+ }
813
+ function getAliasFallbacks2(primaryAlias) {
814
+ if (primaryAlias === "pro") {
815
+ return ["pro", "flash", "auto"];
816
+ }
817
+ if (primaryAlias === "flash") {
818
+ return ["flash", "auto", "pro"];
819
+ }
820
+ return [primaryAlias, "auto", "flash", "pro"];
821
+ }
822
+ function getReasoningInstruction(reasoningEffort) {
823
+ if (reasoningEffort === "high") {
824
+ return "high (\uAE4A\uC774 \uC788\uB294 \uBD84\uC11D, \uC7A0\uC7AC\uC801 \uB9AC\uC2A4\uD06C\uAE4C\uC9C0 \uC810\uAC80)";
825
+ }
826
+ if (reasoningEffort === "medium") {
827
+ return "medium (\uADE0\uD615 \uC7A1\uD78C \uBD84\uC11D\uACFC \uD575\uC2EC \uC774\uC288 \uC911\uC2EC)";
828
+ }
829
+ if (reasoningEffort === "low") {
830
+ return "low (\uD575\uC2EC \uACB0\uD568 \uC704\uC8FC\uB85C \uAC04\uACB0\uD558\uAC8C \uBD84\uC11D)";
831
+ }
832
+ return "minimal (\uCE58\uBA85\uB3C4 \uB192\uC740 \uC774\uC288\uB9CC \uB9E4\uC6B0 \uAC04\uACB0\uD558\uAC8C \uBD84\uC11D)";
833
+ }
834
+ function buildGeminiExecCommand(prompt, model) {
835
+ const modelOption = model ? `--model ${shellQuote3(model)}` : "";
836
+ return `gemini ${[modelOption, "-p", shellQuote3(prompt)].filter(Boolean).join(" ")}`;
837
+ }
838
+ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
839
+ trace5("createGeminiCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
840
+ const customModel = getArgValue3("--model");
841
+ const reasoningEffort = resolveReasoningEffort3();
842
+ const primaryAlias = resolvePrimaryAlias2(reasoningEffort);
843
+ const aliasFallbacks = toUnique2(getAliasFallbacks2(primaryAlias));
409
844
  const rules = [
410
845
  { path: rulesPath, display: "\uB8F0\uC14B" },
411
846
  { path: namingRulesPath, display: "\uB124\uC774\uBC0D \uADDC\uCE59" },
412
847
  { path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
413
848
  ];
414
- const validRules = rules.filter((rule) => fs5__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
849
+ const validRules = rules.filter((rule) => fs__default.default.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
415
850
  const rulesCount = validRules ? validRules.split(",").length : 0;
416
851
  trace5("rules:loaded", `count=${rulesCount}`);
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. "`;
852
+ const reviewFormRef = fs__default.default.existsSync(reviewFormPath2) ? `@${reviewFormPath2}` : "(\uC5C6\uC74C)";
853
+ trace5("reviewForm:status", reviewFormRef === "(\uC5C6\uC74C)" ? "missing" : "exists");
854
+ const reasoningInstruction = getReasoningInstruction(reasoningEffort);
855
+ const prompt = `\uB2E4\uC74C \uADDC\uCE59\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C(${validRules || "(\uC5C6\uC74C)"}) \uC774 diff(@${tempDiffPath2})\uB97C \uB9AC\uBDF0\uD574\uC918.
856
+ \uB9AC\uBDF0 \uC591\uC2DD\uC740 ${reviewFormRef} \uC5D0 \uB9DE\uCDB0\uC11C \uC791\uC131\uD574\uC918.
857
+ \uCD94\uB860 \uAC15\uB3C4 \uC9C0\uCE68: ${reasoningInstruction}`;
858
+ trace5("prompt:prepared", `length=${prompt.length}`);
859
+ const modelCandidates = toUnique2(customModel ? [customModel, ...aliasFallbacks] : aliasFallbacks);
860
+ trace5("model:candidates", modelCandidates.join(", "));
861
+ trace5("command:candidates:count", String(modelCandidates.length + 1));
862
+ if (customModel) {
863
+ console.warn(
864
+ `\u26A0\uFE0F \uCEE4\uC2A4\uD140 \uBAA8\uB378(${customModel})\uC744 \uC6B0\uC120 \uC2DC\uB3C4\uD558\uACE0 \uC2E4\uD328\uD558\uBA74 alias(${aliasFallbacks.join(
865
+ " -> "
866
+ )}) \uBC0F \uAE30\uBCF8 \uBAA8\uB378 \uC21C\uC73C\uB85C \uD3F4\uBC31\uD569\uB2C8\uB2E4.`
867
+ );
868
+ } else {
869
+ console.warn(
870
+ `\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.`
871
+ );
872
+ }
873
+ const commandCandidates = modelCandidates.map((model) => buildGeminiExecCommand(prompt, model));
874
+ const command = [...commandCandidates, buildGeminiExecCommand(prompt)].join(" || ");
418
875
  trace5("command:created");
419
876
  if (args3.includes("--test")) {
420
877
  const safeCommand = command.replace(/"/g, '\\"');
@@ -424,6 +881,7 @@ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
424
881
  \uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
425
882
  ${safeCommand}"`;
426
883
  }
884
+ trace5("command:mode", "execute");
427
885
  trace5("createGeminiCommand:end");
428
886
  return command;
429
887
  };
@@ -434,21 +892,23 @@ function checkGeminiCliInstalled() {
434
892
  trace6("version-check:run", "gemini --version");
435
893
  child_process.execSync("gemini --version", { stdio: "ignore" });
436
894
  trace6("version-check:ok");
437
- } catch {
438
- trace6("version-check:failed", "install-start");
895
+ } catch (error) {
896
+ trace6("version-check:failed", getErrorSummary(error));
897
+ trace6("install:start", "@google/gemini-cli");
439
898
  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");
440
899
  try {
441
900
  child_process.execSync("npm install -g @google/gemini-cli", { stdio: "inherit" });
442
- trace6("install:ok", "exit(1) for login");
901
+ trace6("install:ok", "login-required");
443
902
  console.log("\u2705 gemini-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
444
903
  console.log("\u26A0\uFE0F Gemini API \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
445
904
  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.');
446
905
  process.exit(1);
447
906
  } catch (installError) {
448
- trace6("install:failed");
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).");
450
- console.error(installError);
451
- process.exit(1);
907
+ trace6("install:failed", getErrorSummary(installError));
908
+ exitWithError("\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).", {
909
+ scope: "installation-gemini",
910
+ error: installError
911
+ });
452
912
  }
453
913
  }
454
914
  trace6("checkGeminiCliInstalled:end");
@@ -458,30 +918,34 @@ function checkGeminiCliInstalled() {
458
918
  var execAsync = util__default.default.promisify(child_process.exec);
459
919
  async function main() {
460
920
  const args4 = process.argv.slice(2);
921
+ clearTraceMessages();
461
922
  const isTest = isTestMode(args4);
462
923
  const trace7 = createTraceLogger("review-one-by-one", args4);
463
924
  trace7("main:start", `args=${JSON.stringify(args4)}`);
464
- trace7("service-selection:start");
465
- const service = await showSelectionAIService();
466
- trace7("service-selection:done", `service=${service}`);
467
- switch (service) {
468
- case "gemini":
469
- trace7("install-check:start", "service=gemini");
470
- checkGeminiCliInstalled();
471
- trace7("install-check:done", "service=gemini");
472
- break;
473
- case "claude":
474
- trace7("install-check:start", "service=claude");
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");
482
- break;
483
- }
925
+ let service = "";
926
+ let savedDiffPath = "";
927
+ let savedReportPath = "";
484
928
  try {
929
+ trace7("service-selection:start");
930
+ service = await showSelectionAIService();
931
+ trace7("service-selection:done", `service=${service}`);
932
+ switch (service) {
933
+ case "gemini":
934
+ trace7("install-check:start", "service=gemini");
935
+ checkGeminiCliInstalled();
936
+ trace7("install-check:done", "service=gemini");
937
+ break;
938
+ case "claude":
939
+ trace7("install-check:start", "service=claude");
940
+ checkClaudeCliInstalled();
941
+ trace7("install-check:done", "service=claude");
942
+ break;
943
+ case "codex":
944
+ trace7("install-check:start", "service=codex");
945
+ checkCodexCliInstalled();
946
+ trace7("install-check:done", "service=codex");
947
+ break;
948
+ }
485
949
  trace7("review-flow:start");
486
950
  console.log("\u{1F680} AI Code Review\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4...");
487
951
  trace7("report-dir:create:start");
@@ -489,6 +953,7 @@ async function main() {
489
953
  trace7("report-dir:create:done");
490
954
  const { includeParams, excludeParams } = getGitDiffFilter();
491
955
  trace7("diff-filter:loaded", `include=${includeParams} | exclude=${excludeParams}`);
956
+ trace7("diff-args:build:start");
492
957
  const diffArgs = getDiffArgs();
493
958
  trace7("diff-args:build:done", `diffArgs=${diffArgs || "(default)"}`);
494
959
  const filesCommand = `git diff --name-only ${diffArgs} -- ${includeParams} ${excludeParams}`;
@@ -508,26 +973,26 @@ async function main() {
508
973
  trace7("full-diff:done", `length=${fullDiff.length}`);
509
974
  trace7("timestamp:created", nowStr);
510
975
  trace7("temp-diff:write:start", tempDiffPath);
511
- fs5__default.default.writeFileSync(tempDiffPath, fullDiff);
976
+ fs__default.default.writeFileSync(tempDiffPath, fullDiff);
512
977
  trace7("temp-diff:write:done");
513
978
  trace7("saved-diff:copy:start");
514
- const savedDiffPath = getNextFilePath(REPORT_DIR, `${nowStr}-diff`, ".txt");
515
- fs5__default.default.copyFileSync(tempDiffPath, savedDiffPath);
979
+ savedDiffPath = getNextFilePath(REPORT_DIR, `${nowStr}-diff`, ".txt");
980
+ fs__default.default.copyFileSync(tempDiffPath, savedDiffPath);
516
981
  trace7("saved-diff:copy:done", savedDiffPath);
517
- const savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
982
+ savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
518
983
  trace7("saved-report:path", savedReportPath);
519
984
  const promises = fileList.map(async (file) => {
985
+ const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
986
+ let command = "";
520
987
  try {
521
988
  trace7("file-review:start", file);
522
989
  console.log(`\u{1F50D} Reviewing: ${file}...`);
523
990
  trace7("file-diff:run", file);
524
991
  const fileDiff = child_process.execSync(`git diff ${diffArgs} -- "${file}"`).toString();
525
992
  trace7("file-diff:done", `${file} | length=${fileDiff.length}`);
526
- const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
527
993
  trace7("file-temp-diff:write:start", tempOneFileDiffPath);
528
- fs5__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
994
+ fs__default.default.writeFileSync(tempOneFileDiffPath, fileDiff);
529
995
  trace7("file-temp-diff:write:done", tempOneFileDiffPath);
530
- let command = "";
531
996
  trace7("file-command:create:start", file);
532
997
  switch (service) {
533
998
  case "gemini":
@@ -540,7 +1005,7 @@ async function main() {
540
1005
  command = createCodexCommand(tempOneFileDiffPath, reviewFormOneByOnePath);
541
1006
  break;
542
1007
  }
543
- trace7("file-command:create:done", file);
1008
+ trace7("file-command:create:done", `${file} | commandLength=${command.length}`);
544
1009
  trace7("file-command:exec:start", file);
545
1010
  const { stdout } = await execAsync(command, { maxBuffer: 1024 * 1024 * 20 });
546
1011
  const result = stdout.toString();
@@ -554,11 +1019,11 @@ ${result}
554
1019
  `;
555
1020
  console.log(tempReport);
556
1021
  trace7("file-report:append:start", file);
557
- fs5__default.default.appendFileSync(savedReportPath, tempReport);
1022
+ fs__default.default.appendFileSync(savedReportPath, tempReport);
558
1023
  trace7("file-report:append:done", file);
559
1024
  if (isTest) {
560
1025
  trace7("file-test-command:append:start", file);
561
- fs5__default.default.appendFileSync(savedReportPath, `
1026
+ fs__default.default.appendFileSync(savedReportPath, `
562
1027
 
563
1028
  ## \uC0AC\uC6A9\uB41C \uBA85\uB839\uC5B4
564
1029
 
@@ -567,26 +1032,51 @@ ${command}`);
567
1032
  }
568
1033
  trace7("file-review:end", file);
569
1034
  } catch (err) {
570
- trace7("file-review:catch", file);
1035
+ trace7("file-review:catch", `${file} | ${getErrorSummary(err)}`);
1036
+ const errorLogPath = writeErrorReport(err, {
1037
+ scope: "review-one-by-one:file",
1038
+ args: args4,
1039
+ extraSections: [
1040
+ {
1041
+ heading: "Execution Context",
1042
+ markdown: `\`\`\`json
1043
+ ${JSON.stringify(
1044
+ {
1045
+ service,
1046
+ file,
1047
+ command: command || null,
1048
+ tempOneFileDiffPath,
1049
+ savedDiffPath: savedDiffPath || null,
1050
+ savedReportPath: savedReportPath || null
1051
+ },
1052
+ null,
1053
+ 2
1054
+ )}
1055
+ \`\`\``
1056
+ }
1057
+ ]
1058
+ });
571
1059
  console.error(`\u274C Error reviewing file ${file}:`, err);
1060
+ if (errorLogPath) {
1061
+ console.error(`\u{1F4C4} \uC5D0\uB7EC \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${errorLogPath}`);
1062
+ }
572
1063
  const errorReport = `### File: ${file}
573
1064
  \u274C Review Failed
574
1065
  \`\`\`
575
- ${err}
1066
+ ${getErrorSummary(err)}
576
1067
  \`\`\`
577
1068
 
578
1069
  `;
579
- fs5__default.default.appendFileSync(savedReportPath, errorReport);
1070
+ fs__default.default.appendFileSync(savedReportPath, errorReport);
580
1071
  try {
581
- const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
582
- if (fs5__default.default.existsSync(tempOneFileDiffPath)) {
1072
+ if (fs__default.default.existsSync(tempOneFileDiffPath)) {
583
1073
  trace7("file-temp-diff:delete:start(catch)", tempOneFileDiffPath);
584
1074
  deleteFile(tempOneFileDiffPath);
585
1075
  trace7("file-temp-diff:delete:done(catch)", tempOneFileDiffPath);
586
1076
  }
587
- } catch (e) {
588
- trace7("file-temp-diff:delete:failed(catch)", file);
589
- console.error(`\u274C Error deleting temp file for ${file}:`, e);
1077
+ } catch (cleanupError) {
1078
+ trace7("file-temp-diff:delete:failed(catch)", `${file} | ${getErrorSummary(cleanupError)}`);
1079
+ console.error(`\u274C Error deleting temp file for ${file}:`, cleanupError);
590
1080
  }
591
1081
  }
592
1082
  });
@@ -605,12 +1095,44 @@ ${err}
605
1095
  trace7("cleanup-temp-diff:done");
606
1096
  trace7("review-flow:end");
607
1097
  } catch (error) {
608
- trace7("review-flow:catch");
1098
+ trace7("review-flow:catch", getErrorSummary(error));
1099
+ let errorReportPath = "";
1100
+ trace7("cleanup-temp-diff:start(catch)");
1101
+ try {
1102
+ deleteTempDiff();
1103
+ trace7("cleanup-temp-diff:done(catch)");
1104
+ } catch (cleanupError) {
1105
+ trace7("cleanup-temp-diff:failed(catch)", getErrorSummary(cleanupError));
1106
+ console.error("\u26A0\uFE0F \uC784\uC2DC diff \uC815\uB9AC \uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.");
1107
+ console.error(cleanupError);
1108
+ }
1109
+ trace7("error-report:prepare", `service=${service || "unknown"}`);
1110
+ errorReportPath = writeErrorReport(error, {
1111
+ scope: "review-one-by-one",
1112
+ args: args4,
1113
+ extraSections: [
1114
+ {
1115
+ heading: "Execution Context",
1116
+ markdown: `\`\`\`json
1117
+ ${JSON.stringify(
1118
+ {
1119
+ service: service || null,
1120
+ tempDiffPath,
1121
+ savedDiffPath: savedDiffPath || null,
1122
+ savedReportPath: savedReportPath || null
1123
+ },
1124
+ null,
1125
+ 2
1126
+ )}
1127
+ \`\`\``
1128
+ }
1129
+ ]
1130
+ });
609
1131
  console.error("\u274C \uB9AC\uBDF0 \uB3C4\uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.");
610
1132
  console.error(error);
611
- trace7("cleanup-temp-diff:start(catch)");
612
- deleteTempDiff();
613
- trace7("cleanup-temp-diff:done(catch)");
1133
+ if (errorReportPath) {
1134
+ console.error(`\u{1F4C4} \uC5D0\uB7EC \uB85C\uADF8 \uC800\uC7A5 \uC704\uCE58: ${errorReportPath}`);
1135
+ }
614
1136
  process.exit(1);
615
1137
  }
616
1138
  }