feat: diff review Discord relay — Accept/Reject all via VS Code commands
This commit is contained in:
@@ -1997,6 +1997,60 @@ function setupMonitor() {
|
|||||||
logToFile(`[RESPONSE-CAPTURE] error: ${re.message.substring(0, 100)}`);
|
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)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
wasRunning = isRunning;
|
wasRunning = isRunning;
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
@@ -2094,7 +2148,23 @@ async function processResponseFile(filePath) {
|
|||||||
// DOM observer: renderer handles clicking via pollResponse
|
// DOM observer: renderer handles clicking via pollResponse
|
||||||
// Step probe/stall: try RPC → VS Code commands → log results
|
// Step probe/stall: try RPC → VS Code commands → log results
|
||||||
const approved = resp.approved;
|
const approved = resp.approved;
|
||||||
if (isDomObserver) {
|
// ── diff_review: Accept all / Reject all via VS Code commands ──
|
||||||
|
if (pendingStepType === 'diff_review') {
|
||||||
|
const btnIdx = resp.button_index ?? -1;
|
||||||
|
const isAccept = btnIdx === 0 || (btnIdx === -1 && approved);
|
||||||
|
const cmd = isAccept
|
||||||
|
? 'antigravity.prioritized.agentAcceptAllInFile'
|
||||||
|
: 'antigravity.prioritized.agentRejectAllInFile';
|
||||||
|
logToFile(`[RESPONSE] diff_review → executing VS Code command: ${cmd} (btnIdx=${btnIdx})`);
|
||||||
|
try {
|
||||||
|
await vscode.commands.executeCommand(cmd);
|
||||||
|
logToFile(`[RESPONSE] diff_review command executed OK`);
|
||||||
|
}
|
||||||
|
catch (cmdErr) {
|
||||||
|
logToFile(`[RESPONSE] diff_review command error: ${cmdErr.message}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (isDomObserver) {
|
||||||
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
|
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
|
||||||
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
|
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
|
||||||
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
|
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1950,6 +1950,58 @@ function setupMonitor() {
|
|||||||
logToFile(`[RESPONSE-CAPTURE] error: ${re.message.substring(0, 100)}`);
|
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: any) => {
|
||||||
|
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: string[] = [];
|
||||||
|
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: any) {
|
||||||
|
logToFile(`[DIFF-REVIEW] error: ${dre.message?.substring(0, 100)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
wasRunning = isRunning;
|
wasRunning = isRunning;
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
if (pollCount <= 5 || pollCount % 20 === 0) {
|
if (pollCount <= 5 || pollCount % 20 === 0) {
|
||||||
@@ -2051,7 +2103,21 @@ async function processResponseFile(filePath: string) {
|
|||||||
|
|
||||||
const approved = resp.approved;
|
const approved = resp.approved;
|
||||||
|
|
||||||
if (isDomObserver) {
|
// ── diff_review: Accept all / Reject all via VS Code commands ──
|
||||||
|
if (pendingStepType === 'diff_review') {
|
||||||
|
const btnIdx = resp.button_index ?? -1;
|
||||||
|
const isAccept = btnIdx === 0 || (btnIdx === -1 && approved);
|
||||||
|
const cmd = isAccept
|
||||||
|
? 'antigravity.prioritized.agentAcceptAllInFile'
|
||||||
|
: 'antigravity.prioritized.agentRejectAllInFile';
|
||||||
|
logToFile(`[RESPONSE] diff_review → executing VS Code command: ${cmd} (btnIdx=${btnIdx})`);
|
||||||
|
try {
|
||||||
|
await vscode.commands.executeCommand(cmd);
|
||||||
|
logToFile(`[RESPONSE] diff_review command executed OK`);
|
||||||
|
} catch (cmdErr: any) {
|
||||||
|
logToFile(`[RESPONSE] diff_review command error: ${cmdErr.message}`);
|
||||||
|
}
|
||||||
|
} else if (isDomObserver) {
|
||||||
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
|
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
|
||||||
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
|
logToFile(`[RESPONSE] dom_observer → tryApprovalStrategies(${approved}, ${activeSessionId.substring(0, 8)}, type=${pendingStepType}, step=${pendingStepIndex})`);
|
||||||
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
|
const strategyResult = await tryApprovalStrategies(approved, activeSessionId, pendingStepType, pendingStepIndex);
|
||||||
@@ -2198,7 +2264,7 @@ function extractToolDescription(stepData: any, sessionTitle: string, stepIndex:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Write a pending approval file matching Bot's ApprovalRequest dataclass. */
|
/** Write a pending approval file matching Bot's ApprovalRequest dataclass. */
|
||||||
function writePendingApproval(data: { conversation_id: string; command: string; description: string; step_type?: string; step_index?: number; source?: string }) {
|
function writePendingApproval(data: { conversation_id: string; command: string; description: string; step_type?: string; step_index?: number; source?: string; buttons?: Array<{text: string; index: number}> }) {
|
||||||
try {
|
try {
|
||||||
const pendingDir = path.join(bridgePath, 'pending');
|
const pendingDir = path.join(bridgePath, 'pending');
|
||||||
if (!fs.existsSync(pendingDir)) { fs.mkdirSync(pendingDir, { recursive: true }); }
|
if (!fs.existsSync(pendingDir)) { fs.mkdirSync(pendingDir, { recursive: true }); }
|
||||||
|
|||||||
6
tmp_test_review.md
Normal file
6
tmp_test_review.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
# Accept All 테스트 파일
|
||||||
|
|
||||||
|
이 파일은 DOM Observer가 Accept all / Reject all 버튼을 감지하는지 테스트하기 위한 임시 파일입니다.
|
||||||
|
|
||||||
|
## 수정 내역
|
||||||
|
- 초기 생성: Accept all 리뷰 바 트리거 테스트
|
||||||
Reference in New Issue
Block a user