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.
- package/dist/common/helper.cjs +77 -6
- package/dist/common/helper.cjs.map +1 -1
- package/dist/common/helper.d.cts +16 -2
- package/dist/common/helper.d.ts +16 -2
- package/dist/common/helper.js +76 -7
- package/dist/common/helper.js.map +1 -1
- package/dist/{pr-review/gemini → etc}/installation-gcloud.cjs +1 -1
- package/dist/etc/installation-gcloud.cjs.map +1 -0
- package/dist/{pr-review/gemini → etc}/installation-gcloud.js +1 -1
- package/dist/etc/installation-gcloud.js.map +1 -0
- package/dist/{pr-review/gemini → etc}/interactive-version/index.cjs +2 -2
- package/dist/etc/interactive-version/index.cjs.map +1 -0
- package/dist/{pr-review/gemini → etc}/interactive-version/index.js +2 -2
- package/dist/etc/interactive-version/index.js.map +1 -0
- package/dist/{pr-review/gemini → etc}/login.cjs +1 -1
- package/dist/etc/login.cjs.map +1 -0
- package/dist/{pr-review/gemini → etc}/login.js +1 -1
- package/dist/etc/login.js.map +1 -0
- package/dist/{pr-review/gemini → etc}/vertex-version/index.cjs +1 -1
- package/dist/etc/vertex-version/index.cjs.map +1 -0
- package/dist/{pr-review/gemini → etc}/vertex-version/index.js +1 -1
- package/dist/etc/vertex-version/index.js.map +1 -0
- package/dist/pr-review/claude/claude-commander.cjs +150 -17
- package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
- package/dist/pr-review/claude/claude-commander.d.cts +7 -8
- package/dist/pr-review/claude/claude-commander.d.ts +7 -8
- package/dist/pr-review/claude/claude-commander.js +150 -17
- package/dist/pr-review/claude/claude-commander.js.map +1 -1
- package/dist/pr-review/claude/installation-claude.cjs +38 -1
- package/dist/pr-review/claude/installation-claude.cjs.map +1 -1
- package/dist/pr-review/claude/installation-claude.js +33 -1
- package/dist/pr-review/claude/installation-claude.js.map +1 -1
- package/dist/pr-review/codex/codex-commander.cjs +126 -0
- package/dist/pr-review/codex/codex-commander.cjs.map +1 -0
- package/dist/pr-review/codex/codex-commander.d.cts +17 -0
- package/dist/pr-review/codex/codex-commander.d.ts +17 -0
- package/dist/pr-review/codex/codex-commander.js +118 -0
- package/dist/pr-review/codex/codex-commander.js.map +1 -0
- package/dist/pr-review/codex/installation-codex.cjs +62 -0
- package/dist/pr-review/codex/installation-codex.cjs.map +1 -0
- package/dist/pr-review/codex/installation-codex.d.cts +3 -0
- package/dist/pr-review/codex/installation-codex.d.ts +3 -0
- package/dist/pr-review/codex/installation-codex.js +55 -0
- package/dist/pr-review/codex/installation-codex.js.map +1 -0
- package/dist/pr-review/gemini/gemini-commander.cjs +133 -15
- package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
- package/dist/pr-review/gemini/gemini-commander.d.cts +10 -13
- package/dist/pr-review/gemini/gemini-commander.d.ts +10 -13
- package/dist/pr-review/gemini/gemini-commander.js +133 -15
- package/dist/pr-review/gemini/gemini-commander.js.map +1 -1
- package/dist/pr-review/gemini/installation-gemini.cjs +35 -0
- package/dist/pr-review/gemini/installation-gemini.cjs.map +1 -1
- package/dist/pr-review/gemini/installation-gemini.js +30 -0
- package/dist/pr-review/gemini/installation-gemini.js.map +1 -1
- package/dist/pr-review/review-one-by-one.cjs +547 -56
- package/dist/pr-review/review-one-by-one.cjs.map +1 -1
- package/dist/pr-review/review-one-by-one.js +546 -55
- package/dist/pr-review/review-one-by-one.js.map +1 -1
- package/dist/pr-review/review.cjs +517 -41
- package/dist/pr-review/review.cjs.map +1 -1
- package/dist/pr-review/review.js +517 -41
- package/dist/pr-review/review.js.map +1 -1
- package/package.json +1 -1
- package/src/common/form/review-form.md +1 -1
- package/src/common/rules/review-rules.md +2 -0
- package/dist/pr-review/gemini/installation-gcloud.cjs.map +0 -1
- package/dist/pr-review/gemini/installation-gcloud.js.map +0 -1
- package/dist/pr-review/gemini/interactive-version/index.cjs.map +0 -1
- package/dist/pr-review/gemini/interactive-version/index.js.map +0 -1
- package/dist/pr-review/gemini/login.cjs.map +0 -1
- package/dist/pr-review/gemini/login.js.map +0 -1
- package/dist/pr-review/gemini/vertex-version/index.cjs.map +0 -1
- package/dist/pr-review/gemini/vertex-version/index.js.map +0 -1
- /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.cts +0 -0
- /package/dist/{pr-review/gemini → etc}/installation-gcloud.d.ts +0 -0
- /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.cts +0 -0
- /package/dist/{pr-review/gemini → etc}/interactive-version/index.d.ts +0 -0
- /package/dist/{pr-review/gemini → etc}/login.d.cts +0 -0
- /package/dist/{pr-review/gemini → etc}/login.d.ts +0 -0
- /package/dist/{pr-review/gemini → etc}/vertex-version/index.d.cts +0 -0
- /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
|
|
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
|
|
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 (!
|
|
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 (
|
|
54
|
-
|
|
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 (!
|
|
62
|
-
|
|
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
|
-
|
|
86
|
-
|
|
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
|
|
93
|
-
const commitIndex =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
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
|
|
207
|
-
|
|
208
|
-
const
|
|
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
|
-
|
|
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
|
|
238
|
-
|
|
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
|
-
|
|
241
|
-
|
|
242
|
-
|
|
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
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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) =>
|
|
259
|
-
const
|
|
260
|
-
|
|
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
|
|
292
|
-
const isTest =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
841
|
+
fs5__default.default.appendFileSync(savedReportPath, errorReport);
|
|
364
842
|
try {
|
|
365
843
|
const tempOneFileDiffPath = `temp_diff_${file.replace(/\//g, "_")}.txt`;
|
|
366
|
-
if (
|
|
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
|
}
|