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