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