fix: diff review uses cumulative file tracking instead of IDLE-time step scan

This commit is contained in:
2026-03-10 14:44:16 +09:00
parent f8f9ce8f5f
commit 8fbf6bf6b7
3 changed files with 69 additions and 105 deletions

View File

@@ -1457,6 +1457,7 @@ function setupMonitor() {
let lastRelayedTaskText = ''; // dedup TASK_BOUNDARY relay
let wasRunning = false; // track RUNNING→IDLE transition for response capture
let lastUserInputStepIdx = -1; // track user input for response matching
let pendingModifiedFiles = []; // accumulate modified files during RUNNING
let lastResponseCaptureStep = -1; // dedup: don't capture same response twice
setInterval(async () => {
pollCount++;
@@ -1546,6 +1547,21 @@ function setupMonitor() {
const actualIdx = rtOffset + ri;
if (actualIdx <= lastResponseCaptureStep)
continue;
// Track file write steps for diff review
if (s?.metadata?.toolCall?.argumentsJson) {
try {
const tcArgs = JSON.parse(s.metadata.toolCall.argumentsJson);
const tf = tcArgs.TargetFile || tcArgs.target_file || '';
if (tf) {
const bn = tf.split(/[\\/]/).pop() || tf;
if (!pendingModifiedFiles.includes(bn)) {
pendingModifiedFiles.push(bn);
logToFile(`[DIFF-TRACK] + ${bn} (step ${actualIdx})`);
}
}
}
catch { }
}
if (sType.includes('PLANNER_RESPONSE') && s?.status?.includes('DONE')) {
const pr = s?.plannerResponse;
if (pr) {
@@ -2009,59 +2025,24 @@ function setupMonitor() {
logToFile(`[RESPONSE-CAPTURE] error: ${re.message.substring(0, 100)}`);
}
}
// ── Diff review detection: if session just went IDLE and file writes happened ──
if (wasRunning && !isRunning && sdk) {
try {
const drOffset = Math.max(0, currentCount - 10);
const drResp = await sdk.ls.rawRPC('GetCascadeTrajectorySteps', {
cascadeId: bestSessionId,
stepOffset: drOffset,
verbosity: 1,
});
if (drResp?.steps?.length > 0) {
const fileWriteSteps = drResp.steps.filter((s) => {
const t = s?.type || '';
return t.includes('WRITE_TO_FILE') || t.includes('REPLACE_FILE') || t.includes('MULTI_REPLACE');
});
if (fileWriteSteps.length > 0) {
// Extract modified file names
const modifiedFiles = [];
for (const fw of fileWriteSteps) {
try {
const args = JSON.parse(fw?.metadata?.toolCall?.argumentsJson || '{}');
const f = args.TargetFile || args.target_file || '';
if (f) {
const basename = f.split(/[\\/]/).pop() || f;
if (!modifiedFiles.includes(basename))
modifiedFiles.push(basename);
}
}
catch { }
}
const fileList = modifiedFiles.length > 0
? modifiedFiles.slice(0, 5).join(', ')
: `${fileWriteSteps.length}개 파일`;
logToFile(`[DIFF-REVIEW] ${fileWriteSteps.length} file write steps detected, files: ${fileList}`);
writeChatSnapshot(`📝 **코드 리뷰 대기**\n\n수정된 파일: ${fileList}\n\nAG에서 Accept all / Reject all로 확인해주세요.`);
// Create pending for Discord approval
writePendingApproval({
conversation_id: activeSessionId,
command: `코드 리뷰: ${fileList}`,
description: `${fileWriteSteps.length}개 파일이 수정되었습니다`,
step_type: 'diff_review',
step_index: currentCount,
source: 'diff_review_detect',
buttons: [
{ text: 'Accept all', index: 0 },
{ text: 'Reject all', index: 1 },
],
});
}
}
}
catch (dre) {
logToFile(`[DIFF-REVIEW] error: ${dre.message?.substring(0, 100)}`);
}
// ── Diff review detection: if session just went IDLE and files were modified ──
if (wasRunning && !isRunning && pendingModifiedFiles.length > 0) {
const fileList = pendingModifiedFiles.slice(0, 5).join(', ');
logToFile(`[DIFF-REVIEW] IDLE with ${pendingModifiedFiles.length} modified files: ${fileList}`);
writeChatSnapshot(`📝 **코드 리뷰 대기**\n\n수정된 파일: ${fileList}\n\nAG에서 Accept all / Reject all로 확인해주세요.`);
writePendingApproval({
conversation_id: activeSessionId,
command: `코드 리뷰: ${fileList}`,
description: `${pendingModifiedFiles.length}개 파일이 수정되었습니다`,
step_type: 'diff_review',
step_index: currentCount,
source: 'diff_review_detect',
buttons: [
{ text: 'Accept all', index: 0 },
{ text: 'Reject all', index: 1 },
],
});
pendingModifiedFiles = []; // reset after notification
}
wasRunning = isRunning;
}

File diff suppressed because one or more lines are too long