sales-frontend-gemini-cli 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/common/helper.cjs +59 -8
- package/dist/common/helper.cjs.map +1 -1
- package/dist/common/helper.d.cts +15 -1
- package/dist/common/helper.d.ts +15 -1
- package/dist/common/helper.js +58 -9
- 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 +31 -5
- package/dist/pr-review/claude/claude-commander.cjs.map +1 -1
- package/dist/pr-review/claude/claude-commander.js +31 -5
- 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 +88 -0
- package/dist/pr-review/codex/codex-commander.cjs.map +1 -0
- package/dist/pr-review/codex/codex-commander.d.cts +12 -0
- package/dist/pr-review/codex/codex-commander.d.ts +12 -0
- package/dist/pr-review/codex/codex-commander.js +80 -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 +28 -5
- package/dist/pr-review/gemini/gemini-commander.cjs.map +1 -1
- package/dist/pr-review/gemini/gemini-commander.js +28 -5
- 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 +265 -36
- package/dist/pr-review/review-one-by-one.cjs.map +1 -1
- package/dist/pr-review/review-one-by-one.js +264 -35
- package/dist/pr-review/review-one-by-one.js.map +1 -1
- package/dist/pr-review/review.cjs +233 -19
- package/dist/pr-review/review.cjs.map +1 -1
- package/dist/pr-review/review.js +233 -19
- 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
package/dist/pr-review/review.js
CHANGED
|
@@ -6,11 +6,11 @@ import readline from 'readline';
|
|
|
6
6
|
import { fileURLToPath } from 'url';
|
|
7
7
|
|
|
8
8
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
var rulesPath = path.resolve(__dirname, "../../src/
|
|
10
|
-
var namingRulesPath = path.resolve(__dirname, "../../src/
|
|
11
|
-
var codingConventionRulesPath = path.resolve(__dirname, "../../src/
|
|
12
|
-
var reviewFormPath = path.resolve(__dirname, "../../src/
|
|
13
|
-
path.resolve(__dirname, "../../src/
|
|
9
|
+
var rulesPath = path.resolve(__dirname, "../../src/common/rules/review-rules.md");
|
|
10
|
+
var namingRulesPath = path.resolve(__dirname, "../../src/common/rules/naming-rule.md");
|
|
11
|
+
var codingConventionRulesPath = path.resolve(__dirname, "../../src/common/rules/coding-convention.md");
|
|
12
|
+
var reviewFormPath = path.resolve(__dirname, "../../src/common/form/review-form.md");
|
|
13
|
+
path.resolve(__dirname, "../../src/common/form/review-form-one-by-one.md");
|
|
14
14
|
var REPORT_DIR = ".review-report";
|
|
15
15
|
var tempDiffPath = "temp_diff.txt";
|
|
16
16
|
var AIServices = ["gemini", "claude", "codex"];
|
|
@@ -28,6 +28,18 @@ var ignoreList = [
|
|
|
28
28
|
".review-report/"
|
|
29
29
|
// 생성되는 리포트 폴더도 제외
|
|
30
30
|
];
|
|
31
|
+
function isTestMode(args4 = process.argv.slice(2)) {
|
|
32
|
+
return args4.includes("--test");
|
|
33
|
+
}
|
|
34
|
+
function createTraceLogger(scope, args4 = process.argv.slice(2)) {
|
|
35
|
+
const enabled = isTestMode(args4);
|
|
36
|
+
return (step, detail) => {
|
|
37
|
+
if (!enabled) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
console.log(`[TRACE][${scope}] ${step}${detail ? ` | ${detail}` : ""}`);
|
|
41
|
+
};
|
|
42
|
+
}
|
|
31
43
|
function getNextFilePath(dir, baseName, extension) {
|
|
32
44
|
let counter = 1;
|
|
33
45
|
while (true) {
|
|
@@ -70,25 +82,60 @@ function getGitDiffFilter() {
|
|
|
70
82
|
return { includeParams, excludeParams };
|
|
71
83
|
}
|
|
72
84
|
function openReport(reportPath) {
|
|
85
|
+
const resolvedPath = path.resolve(reportPath);
|
|
86
|
+
const { platform } = process;
|
|
87
|
+
const openWithChrome = () => {
|
|
88
|
+
if (platform === "darwin") {
|
|
89
|
+
execSync(`open -a "Google Chrome" "${resolvedPath}"`, { stdio: "ignore" });
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
if (platform === "linux") {
|
|
93
|
+
execSync(`google-chrome "${resolvedPath}"`, { stdio: "ignore" });
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
return false;
|
|
97
|
+
};
|
|
98
|
+
const openWithDefaultBrowser = () => {
|
|
99
|
+
if (platform === "darwin") {
|
|
100
|
+
execSync(`open "${resolvedPath}"`, { stdio: "ignore" });
|
|
101
|
+
return true;
|
|
102
|
+
}
|
|
103
|
+
if (platform === "linux") {
|
|
104
|
+
execSync(`xdg-open "${resolvedPath}"`, { stdio: "ignore" });
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
return false;
|
|
108
|
+
};
|
|
109
|
+
try {
|
|
110
|
+
if (openWithChrome()) {
|
|
111
|
+
console.log("\u{1F680} Google Chrome\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
} catch {
|
|
115
|
+
}
|
|
73
116
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
117
|
+
if (openWithDefaultBrowser()) {
|
|
118
|
+
console.log("\u{1F680} \uAE30\uBCF8 \uBE0C\uB77C\uC6B0\uC800\uC5D0\uC11C \uB9AC\uD3EC\uD2B8\uB97C \uC5F4\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
76
121
|
} catch (e) {
|
|
77
122
|
console.error("\u26A0\uFE0F \uBE0C\uB77C\uC6B0\uC800 \uC5F4\uAE30 \uC2E4\uD328:", e);
|
|
123
|
+
return;
|
|
78
124
|
}
|
|
125
|
+
console.error(`\u26A0\uFE0F \uC9C0\uC6D0\uD558\uC9C0 \uC54A\uB294 \uD50C\uB7AB\uD3FC\uC785\uB2C8\uB2E4: ${platform}`);
|
|
79
126
|
}
|
|
80
127
|
function getDiffArgs() {
|
|
81
|
-
const
|
|
82
|
-
const commitIndex =
|
|
128
|
+
const args4 = process.argv.slice(2);
|
|
129
|
+
const commitIndex = args4.indexOf("--commit");
|
|
83
130
|
const { includeParams, excludeParams } = getGitDiffFilter();
|
|
84
131
|
let diffArgs = "";
|
|
85
132
|
if (commitIndex !== -1) {
|
|
86
|
-
const commitHash =
|
|
133
|
+
const commitHash = args4[commitIndex + 1];
|
|
87
134
|
if (!commitHash) {
|
|
88
135
|
console.error("\u274C \uCEE4\uBC0B \uD574\uC2DC\uAC00 \uC81C\uACF5\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.");
|
|
89
136
|
process.exit(1);
|
|
90
137
|
}
|
|
91
|
-
const nextArg =
|
|
138
|
+
const nextArg = args4[commitIndex + 2];
|
|
92
139
|
let n = 0;
|
|
93
140
|
if (nextArg && !nextArg.startsWith("--")) {
|
|
94
141
|
n = parseInt(nextArg, 10);
|
|
@@ -125,7 +172,9 @@ async function showSelectionAIService() {
|
|
|
125
172
|
}
|
|
126
173
|
firstRender = false;
|
|
127
174
|
readline.clearScreenDown(process.stdout);
|
|
128
|
-
process.stdout.write(
|
|
175
|
+
process.stdout.write(
|
|
176
|
+
"\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"
|
|
177
|
+
);
|
|
129
178
|
AIServices.forEach((service, index) => {
|
|
130
179
|
if (index === selectedIndex) {
|
|
131
180
|
process.stdout.write(` \x1B[36m>\x1B[0m \x1B[36m\u25C9\x1B[0m \x1B[1m${service}\x1B[0m
|
|
@@ -171,20 +220,26 @@ async function showSelectionAIService() {
|
|
|
171
220
|
});
|
|
172
221
|
}
|
|
173
222
|
var args = process.argv.slice(2);
|
|
223
|
+
var trace = createTraceLogger("claude-commander", args);
|
|
174
224
|
var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
225
|
+
trace("createClaudeCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
|
|
175
226
|
let modelOption = "";
|
|
176
227
|
if (args.includes("--review")) {
|
|
177
228
|
modelOption = "--model opus";
|
|
229
|
+
trace("model:review", modelOption);
|
|
178
230
|
} else if (args.includes("--flash")) {
|
|
179
231
|
modelOption = "--model haiku";
|
|
232
|
+
trace("model:flash", modelOption);
|
|
180
233
|
} else {
|
|
181
234
|
const modelIndex = args.indexOf("--model");
|
|
182
235
|
if (modelIndex !== -1 && args[modelIndex + 1]) {
|
|
183
236
|
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.");
|
|
184
237
|
modelOption = `--model ${args[modelIndex + 1]}`;
|
|
238
|
+
trace("model:custom", modelOption);
|
|
185
239
|
} else {
|
|
186
240
|
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.");
|
|
187
241
|
modelOption = "--model sonnet";
|
|
242
|
+
trace("model:default", modelOption);
|
|
188
243
|
}
|
|
189
244
|
}
|
|
190
245
|
const rules = [
|
|
@@ -193,50 +248,151 @@ var createClaudeCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
|
193
248
|
{ path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
|
|
194
249
|
];
|
|
195
250
|
const systemPromptFiles = rules.filter((rule) => fs.existsSync(rule.path)).map((rule) => `--append-system-prompt-file ${rule.path}`).join(" ");
|
|
251
|
+
trace(
|
|
252
|
+
"rules:loaded",
|
|
253
|
+
`count=${systemPromptFiles ? systemPromptFiles.split("--append-system-prompt-file").length - 1 : 0}`
|
|
254
|
+
);
|
|
196
255
|
const reviewFormOption = fs.existsSync(reviewFormPath2) ? `--append-system-prompt-file ${reviewFormPath2}` : "";
|
|
256
|
+
trace("reviewForm:status", reviewFormOption ? "exists" : "missing");
|
|
197
257
|
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."`;
|
|
258
|
+
trace("command:created");
|
|
198
259
|
if (args.includes("--test")) {
|
|
199
260
|
const safeCommand = command.replace(/"/g, '\\"');
|
|
261
|
+
trace("test-mode:return-preview");
|
|
200
262
|
return `echo "[TEST MODE] Claude \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
|
|
201
263
|
|
|
202
264
|
\uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
|
|
203
265
|
${safeCommand}"`;
|
|
204
266
|
}
|
|
267
|
+
trace("createClaudeCommand:end");
|
|
205
268
|
return command;
|
|
206
269
|
};
|
|
270
|
+
var trace2 = createTraceLogger("installation-claude");
|
|
207
271
|
function checkClaudeCliInstalled() {
|
|
272
|
+
trace2("checkClaudeCliInstalled:start");
|
|
208
273
|
try {
|
|
274
|
+
trace2("version-check:run", "claude --version");
|
|
209
275
|
execSync("claude --version", { stdio: "ignore" });
|
|
276
|
+
trace2("version-check:ok");
|
|
210
277
|
} catch {
|
|
211
|
-
|
|
278
|
+
trace2("version-check:failed", "install-start");
|
|
279
|
+
console.log(
|
|
280
|
+
"\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"
|
|
281
|
+
);
|
|
212
282
|
try {
|
|
213
283
|
execSync("npm install -g @anthropic-ai/claude-code", { stdio: "inherit" });
|
|
284
|
+
trace2("install:ok", "exit(1) for login");
|
|
214
285
|
console.log("\u2705 claude-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
215
286
|
console.log("\u26A0\uFE0F claude-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
216
287
|
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.');
|
|
217
288
|
process.exit(1);
|
|
218
289
|
} catch (installError) {
|
|
290
|
+
trace2("install:failed");
|
|
219
291
|
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).");
|
|
220
292
|
console.error(installError);
|
|
221
293
|
process.exit(1);
|
|
222
294
|
}
|
|
223
295
|
}
|
|
296
|
+
trace2("checkClaudeCliInstalled:end");
|
|
224
297
|
}
|
|
225
298
|
var args2 = process.argv.slice(2);
|
|
226
|
-
var
|
|
299
|
+
var trace3 = createTraceLogger("codex-commander", args2);
|
|
300
|
+
var createCodexCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
301
|
+
trace3("createCodexCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
|
|
227
302
|
let modelOption = "";
|
|
228
303
|
if (args2.includes("--review")) {
|
|
229
|
-
modelOption = "--model
|
|
304
|
+
modelOption = "--model gpt-5";
|
|
305
|
+
trace3("model:review", modelOption);
|
|
230
306
|
} else if (args2.includes("--flash")) {
|
|
231
|
-
modelOption = "--model
|
|
307
|
+
modelOption = "--model gpt-5-mini";
|
|
308
|
+
trace3("model:flash", modelOption);
|
|
232
309
|
} else {
|
|
233
310
|
const modelIndex = args2.indexOf("--model");
|
|
234
311
|
if (modelIndex !== -1 && args2[modelIndex + 1]) {
|
|
235
312
|
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.");
|
|
236
313
|
modelOption = `--model ${args2[modelIndex + 1]}`;
|
|
314
|
+
trace3("model:custom", modelOption);
|
|
315
|
+
} else {
|
|
316
|
+
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.");
|
|
317
|
+
modelOption = "--model gpt-5-mini";
|
|
318
|
+
trace3("model:default", modelOption);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
const rules = [rulesPath, namingRulesPath, codingConventionRulesPath].filter((filePath) => fs.existsSync(filePath)).map((filePath) => `- ${filePath}`).join("\n");
|
|
322
|
+
const rulesCount = rules ? rules.split("\n").length : 0;
|
|
323
|
+
trace3("rules:loaded", `count=${rulesCount}`);
|
|
324
|
+
const hasReviewForm = fs.existsSync(reviewFormPath2);
|
|
325
|
+
const reviewFormLine = hasReviewForm ? `- ${reviewFormPath2}` : "";
|
|
326
|
+
trace3("reviewForm:status", reviewFormLine ? "exists" : "missing");
|
|
327
|
+
const prompt = `\uC544\uB798 \uD30C\uC77C\uB4E4\uC744 \uCC38\uACE0\uD574\uC11C \uCF54\uB4DC \uB9AC\uBDF0\uB97C \uC9C4\uD589\uD574\uC918.
|
|
328
|
+
\uADDC\uCE59 \uD30C\uC77C:
|
|
329
|
+
${rules || "- (\uC5C6\uC74C)"}
|
|
330
|
+
\uB9AC\uBDF0 \uC591\uC2DD \uD30C\uC77C:
|
|
331
|
+
${reviewFormLine || "- (\uC5C6\uC74C)"}
|
|
332
|
+
\uB9AC\uBDF0 \uB300\uC0C1 diff \uD30C\uC77C:
|
|
333
|
+
- ${tempDiffPath2}
|
|
334
|
+
|
|
335
|
+
\uBC18\uB4DC\uC2DC \uB9AC\uBDF0 \uC591\uC2DD\uC5D0 \uB9DE\uCDB0 \uC791\uC131\uD574\uC918.`;
|
|
336
|
+
const command = `codex exec ${modelOption} "${prompt.replace(/"/g, '\\"')}"`;
|
|
337
|
+
trace3("command:created");
|
|
338
|
+
if (args2.includes("--test")) {
|
|
339
|
+
const safeCommand = command.replace(/"/g, '\\"');
|
|
340
|
+
trace3("test-mode:return-preview");
|
|
341
|
+
return `echo "[TEST MODE] Codex \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
|
|
342
|
+
|
|
343
|
+
\uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
|
|
344
|
+
${safeCommand}"`;
|
|
345
|
+
}
|
|
346
|
+
trace3("createCodexCommand:end");
|
|
347
|
+
return command;
|
|
348
|
+
};
|
|
349
|
+
var trace4 = createTraceLogger("installation-codex");
|
|
350
|
+
function checkCodexCliInstalled() {
|
|
351
|
+
trace4("checkCodexCliInstalled:start");
|
|
352
|
+
try {
|
|
353
|
+
trace4("version-check:run", "codex --version");
|
|
354
|
+
execSync("codex --version", { stdio: "ignore" });
|
|
355
|
+
trace4("version-check:ok");
|
|
356
|
+
} catch {
|
|
357
|
+
trace4("version-check:failed", "install-start");
|
|
358
|
+
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");
|
|
359
|
+
try {
|
|
360
|
+
execSync("npm install -g @openai/codex", { stdio: "inherit" });
|
|
361
|
+
trace4("install:ok", "exit(1) for login");
|
|
362
|
+
console.log("\u2705 codex-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
363
|
+
console.log("\u26A0\uFE0F codex-cli \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
364
|
+
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.');
|
|
365
|
+
process.exit(1);
|
|
366
|
+
} catch (installError) {
|
|
367
|
+
trace4("install:failed");
|
|
368
|
+
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).");
|
|
369
|
+
console.error(installError);
|
|
370
|
+
process.exit(1);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
trace4("checkCodexCliInstalled:end");
|
|
374
|
+
}
|
|
375
|
+
var args3 = process.argv.slice(2);
|
|
376
|
+
var trace5 = createTraceLogger("gemini-commander", args3);
|
|
377
|
+
var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
378
|
+
trace5("createGeminiCommand:start", `tempDiffPath=${tempDiffPath2}, reviewFormPath=${reviewFormPath2}`);
|
|
379
|
+
let modelOption = "";
|
|
380
|
+
if (args3.includes("--review")) {
|
|
381
|
+
modelOption = "--model pro";
|
|
382
|
+
trace5("model:review", modelOption);
|
|
383
|
+
} else if (args3.includes("--flash")) {
|
|
384
|
+
modelOption = "--model flash";
|
|
385
|
+
trace5("model:flash", modelOption);
|
|
386
|
+
} else {
|
|
387
|
+
const modelIndex = args3.indexOf("--model");
|
|
388
|
+
if (modelIndex !== -1 && args3[modelIndex + 1]) {
|
|
389
|
+
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.");
|
|
390
|
+
modelOption = `--model ${args3[modelIndex + 1]}`;
|
|
391
|
+
trace5("model:custom", modelOption);
|
|
237
392
|
} else {
|
|
238
393
|
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.");
|
|
239
394
|
modelOption = "--model flash";
|
|
395
|
+
trace5("model:default", modelOption);
|
|
240
396
|
}
|
|
241
397
|
}
|
|
242
398
|
const rules = [
|
|
@@ -245,68 +401,110 @@ var createGeminiCommand = (tempDiffPath2, reviewFormPath2) => {
|
|
|
245
401
|
{ path: codingConventionRulesPath, display: "\uCF54\uB529 \uCEE8\uBCA4\uC158" }
|
|
246
402
|
];
|
|
247
403
|
const validRules = rules.filter((rule) => fs.existsSync(rule.path)).map((rule) => `@${rule.path}`).join(", ");
|
|
404
|
+
const rulesCount = validRules ? validRules.split(",").length : 0;
|
|
405
|
+
trace5("rules:loaded", `count=${rulesCount}`);
|
|
248
406
|
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. "`;
|
|
249
|
-
|
|
407
|
+
trace5("command:created");
|
|
408
|
+
if (args3.includes("--test")) {
|
|
250
409
|
const safeCommand = command.replace(/"/g, '\\"');
|
|
410
|
+
trace5("test-mode:return-preview");
|
|
251
411
|
return `echo "[TEST MODE] Gemini \uBA85\uB839\uC5B4\uAC00 \uC2E4\uD589\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4.
|
|
252
412
|
|
|
253
413
|
\uC0DD\uC131\uB420 \uBA85\uB839\uC5B4 \uBBF8\uB9AC\uBCF4\uAE30:
|
|
254
414
|
${safeCommand}"`;
|
|
255
415
|
}
|
|
416
|
+
trace5("createGeminiCommand:end");
|
|
256
417
|
return command;
|
|
257
418
|
};
|
|
419
|
+
var trace6 = createTraceLogger("installation-gemini");
|
|
258
420
|
function checkGeminiCliInstalled() {
|
|
421
|
+
trace6("checkGeminiCliInstalled:start");
|
|
259
422
|
try {
|
|
423
|
+
trace6("version-check:run", "gemini --version");
|
|
260
424
|
execSync("gemini --version", { stdio: "ignore" });
|
|
425
|
+
trace6("version-check:ok");
|
|
261
426
|
} catch {
|
|
427
|
+
trace6("version-check:failed", "install-start");
|
|
262
428
|
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");
|
|
263
429
|
try {
|
|
264
430
|
execSync("npm install -g @google/gemini-cli", { stdio: "inherit" });
|
|
431
|
+
trace6("install:ok", "exit(1) for login");
|
|
265
432
|
console.log("\u2705 gemini-cli \uC124\uCE58\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.");
|
|
266
433
|
console.log("\u26A0\uFE0F Gemini API \uC0AC\uC6A9\uC744 \uC704\uD574 \uC778\uC99D\uC774 \uD544\uC694\uD569\uB2C8\uB2E4.");
|
|
267
434
|
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.');
|
|
268
435
|
process.exit(1);
|
|
269
436
|
} catch (installError) {
|
|
437
|
+
trace6("install:failed");
|
|
270
438
|
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).");
|
|
271
439
|
console.error(installError);
|
|
272
440
|
process.exit(1);
|
|
273
441
|
}
|
|
274
442
|
}
|
|
443
|
+
trace6("checkGeminiCliInstalled:end");
|
|
275
444
|
}
|
|
276
445
|
|
|
277
446
|
// src/pr-review/review.ts
|
|
278
447
|
async function main() {
|
|
279
|
-
const
|
|
280
|
-
const isTest =
|
|
448
|
+
const args4 = process.argv.slice(2);
|
|
449
|
+
const isTest = isTestMode(args4);
|
|
450
|
+
const trace7 = createTraceLogger("review", args4);
|
|
451
|
+
trace7("main:start", `args=${JSON.stringify(args4)}`);
|
|
452
|
+
trace7("service-selection:start");
|
|
281
453
|
const service = await showSelectionAIService();
|
|
454
|
+
trace7("service-selection:done", `service=${service}`);
|
|
282
455
|
switch (service) {
|
|
283
456
|
case "gemini":
|
|
457
|
+
trace7("install-check:start", "service=gemini");
|
|
284
458
|
checkGeminiCliInstalled();
|
|
459
|
+
trace7("install-check:done", "service=gemini");
|
|
285
460
|
break;
|
|
286
461
|
case "claude":
|
|
462
|
+
trace7("install-check:start", "service=claude");
|
|
287
463
|
checkClaudeCliInstalled();
|
|
464
|
+
trace7("install-check:done", "service=claude");
|
|
465
|
+
break;
|
|
466
|
+
case "codex":
|
|
467
|
+
trace7("install-check:start", "service=codex");
|
|
468
|
+
checkCodexCliInstalled();
|
|
469
|
+
trace7("install-check:done", "service=codex");
|
|
288
470
|
break;
|
|
289
471
|
}
|
|
290
472
|
try {
|
|
473
|
+
trace7("review-flow:start");
|
|
291
474
|
console.log("\u{1F680} AI Code Review\uB97C \uC2DC\uC791\uD569\uB2C8\uB2E4...");
|
|
292
475
|
const nowStr = getNowString();
|
|
476
|
+
trace7("timestamp:created", nowStr);
|
|
477
|
+
trace7("report-dir:create:start");
|
|
293
478
|
createReportDirectory();
|
|
479
|
+
trace7("report-dir:create:done");
|
|
480
|
+
trace7("diff-args:build:start");
|
|
294
481
|
const diffArgs = getDiffArgs();
|
|
482
|
+
trace7("diff-args:build:done", `diffArgs=${diffArgs || "(default)"}`);
|
|
295
483
|
let diff = "";
|
|
296
484
|
const { includeParams, excludeParams } = getGitDiffFilter();
|
|
485
|
+
trace7("diff-filter:loaded", `include=${includeParams} | exclude=${excludeParams}`);
|
|
297
486
|
try {
|
|
487
|
+
trace7("git-diff:run");
|
|
298
488
|
diff = execSync(`git diff ${diffArgs} -- ${includeParams} ${excludeParams}`).toString();
|
|
489
|
+
trace7("git-diff:done", `length=${diff.length}`);
|
|
299
490
|
} catch {
|
|
491
|
+
trace7("git-diff:error", "fallback-empty-diff");
|
|
300
492
|
}
|
|
301
493
|
if (!diff.trim() && !isTest) {
|
|
494
|
+
trace7("empty-diff:exit");
|
|
302
495
|
console.log("\u2139\uFE0F \uB9AC\uBDF0\uD560 \uBCC0\uACBD \uC0AC\uD56D\uC774 \uC5C6\uC2B5\uB2C8\uB2E4 (Unstaged Empty & HEAD Empty).");
|
|
303
496
|
deleteTempDiff();
|
|
304
497
|
process.exit(0);
|
|
305
498
|
}
|
|
499
|
+
trace7("temp-diff:write:start", tempDiffPath);
|
|
306
500
|
fs.writeFileSync(tempDiffPath, diff);
|
|
501
|
+
trace7("temp-diff:write:done");
|
|
502
|
+
trace7("saved-diff:copy:start");
|
|
307
503
|
const savedDiffPath = getNextFilePath(REPORT_DIR, `${nowStr}-diff`, ".txt");
|
|
308
504
|
fs.copyFileSync(tempDiffPath, savedDiffPath);
|
|
505
|
+
trace7("saved-diff:copy:done", savedDiffPath);
|
|
309
506
|
let command = "";
|
|
507
|
+
trace7("command:create:start", `service=${service}`);
|
|
310
508
|
switch (service) {
|
|
311
509
|
case "gemini":
|
|
312
510
|
command = createGeminiCommand(tempDiffPath, reviewFormPath);
|
|
@@ -315,29 +513,45 @@ async function main() {
|
|
|
315
513
|
command = createClaudeCommand(tempDiffPath, reviewFormPath);
|
|
316
514
|
break;
|
|
317
515
|
case "codex":
|
|
516
|
+
command = createCodexCommand(tempDiffPath, reviewFormPath);
|
|
318
517
|
break;
|
|
319
518
|
}
|
|
519
|
+
trace7("command:create:done");
|
|
520
|
+
trace7("command:exec:start");
|
|
320
521
|
const result = execSync(command).toString();
|
|
522
|
+
trace7("command:exec:done", `resultLength=${result.length}`);
|
|
321
523
|
console.log(result);
|
|
524
|
+
trace7("report:write:start");
|
|
322
525
|
const savedReportPath = getNextFilePath(REPORT_DIR, nowStr, ".md");
|
|
323
526
|
fs.writeFileSync(savedReportPath, result);
|
|
527
|
+
trace7("report:write:done", savedReportPath);
|
|
324
528
|
if (isTest) {
|
|
529
|
+
trace7("test-command:append:start");
|
|
325
530
|
fs.appendFileSync(savedReportPath, `
|
|
326
531
|
|
|
327
532
|
## \uC0AC\uC6A9\uB41C \uBA85\uB839\uC5B4
|
|
328
533
|
|
|
329
534
|
${command}`);
|
|
535
|
+
trace7("test-command:append:done");
|
|
330
536
|
}
|
|
331
537
|
console.log(`
|
|
332
538
|
\u2705 \uB9AC\uBDF0\uAC00 \uC644\uB8CC\uB418\uC5C8\uC2B5\uB2C8\uB2E4.`);
|
|
333
539
|
console.log(`\u{1F4C4} \uB9AC\uD3EC\uD2B8 \uC800\uC7A5 \uC704\uCE58: ${savedReportPath}`);
|
|
334
540
|
console.log(`diff \uC800\uC7A5 \uC704\uCE58: ${savedDiffPath}`);
|
|
541
|
+
trace7("open-report:start");
|
|
335
542
|
openReport(savedReportPath);
|
|
543
|
+
trace7("open-report:done");
|
|
544
|
+
trace7("cleanup-temp-diff:start");
|
|
336
545
|
deleteTempDiff();
|
|
546
|
+
trace7("cleanup-temp-diff:done");
|
|
547
|
+
trace7("review-flow:end");
|
|
337
548
|
} catch (error) {
|
|
549
|
+
trace7("review-flow:catch");
|
|
338
550
|
console.error("\u274C \uB9AC\uBDF0 \uB3C4\uC911 \uC624\uB958\uAC00 \uBC1C\uC0DD\uD588\uC2B5\uB2C8\uB2E4.");
|
|
339
551
|
console.error(error);
|
|
552
|
+
trace7("cleanup-temp-diff:start(catch)");
|
|
340
553
|
deleteTempDiff();
|
|
554
|
+
trace7("cleanup-temp-diff:done(catch)");
|
|
341
555
|
process.exit(1);
|
|
342
556
|
}
|
|
343
557
|
}
|