fix(extension): diff_review use agentAcceptAllInFile instead of dead RPC strategies (v0.3.15)
This commit is contained in:
@@ -2625,123 +2625,88 @@ async function processResponseFile(filePath) {
|
||||
logToFile(`[RESPONSE] diff_review → ${isAccept ? 'ACCEPT' : 'REJECT'} (btnIdx=${btnIdx})`);
|
||||
let diffReviewDone = false;
|
||||
const targetSession = sessionId || activeSessionId;
|
||||
let modifiedFiles = []; // shared between Strategy 1 and 2
|
||||
// ── Strategy 1: acknowledgeCodeActionStep RPC (correct AG LS method) ──
|
||||
// Discovered via AG source reverse-engineering: the internal LS method is
|
||||
// `acknowledgeCodeActionStep` (proto ID 167), NOT `AcknowledgeCascadeCodeEdit`.
|
||||
// Accept all button → fireEvent({type:"accept-all-in-file"}) → submitCodeAcknowledgement → acknowledgeCodeActionStep
|
||||
if (sdk) {
|
||||
try {
|
||||
// Get tracked step indices from in-memory cache FIRST (pending file may be deleted by Collector)
|
||||
const trackedSteps = [];
|
||||
const memMeta = diffReviewMetadata.get(resp.request_id);
|
||||
if (memMeta) {
|
||||
trackedSteps.push(...memMeta.edit_step_indices);
|
||||
modifiedFiles = memMeta.modified_files;
|
||||
diffReviewMetadata.delete(resp.request_id); // cleanup
|
||||
logToFile(`[DIFF-REVIEW-RPC] loaded from memory: steps=[${trackedSteps.join(',')}] files=${modifiedFiles.length}`);
|
||||
}
|
||||
else {
|
||||
// Fallback: try pending file (may already be deleted)
|
||||
const pendingDir = path.join(bridgePath, 'pending');
|
||||
try {
|
||||
const pendingFile = path.join(pendingDir, `${resp.request_id}.json`);
|
||||
if (fs.existsSync(pendingFile)) {
|
||||
const pd = JSON.parse(fs.readFileSync(pendingFile, 'utf-8'));
|
||||
if (pd.edit_step_indices)
|
||||
trackedSteps.push(...pd.edit_step_indices);
|
||||
if (pd.modified_files)
|
||||
modifiedFiles = pd.modified_files;
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
// If no tracked steps, use the step_index from the pending
|
||||
if (trackedSteps.length === 0 && pendingStepIndex > 0) {
|
||||
trackedSteps.push(pendingStepIndex);
|
||||
}
|
||||
logToFile(`[DIFF-REVIEW-RPC] acknowledgeCodeActionStep(session=${targetSession.substring(0, 8)}, accept=${isAccept}, steps=[${trackedSteps.join(',')}])`);
|
||||
// Strategy 1a: VS Code command (most reliable — same path as UI button)
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.prioritized.submitCodeAcknowledgement');
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ submitCodeAcknowledgement command OK`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (cmdErr) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] submitCodeAcknowledgement command error: ${cmdErr.message?.substring(0, 200)}`);
|
||||
}
|
||||
// Strategy 1b: Direct LS RPC with correct method name
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const ackResult = await sdk.ls.rawRPC('acknowledgeCodeActionStep', {
|
||||
cascadeId: targetSession,
|
||||
accept: isAccept,
|
||||
...(trackedSteps.length > 0 ? { stepIndices: trackedSteps } : {}),
|
||||
});
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ acknowledgeCodeActionStep: ${JSON.stringify(ackResult).substring(0, 300)}`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (rpcErr1) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] acknowledgeCodeActionStep error: ${rpcErr1.message?.substring(0, 200)}`);
|
||||
}
|
||||
}
|
||||
// Strategy 1c: Legacy method name (fallback)
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const ackLegacy = await sdk.ls.rawRPC('AcknowledgeCascadeCodeEdit', {
|
||||
cascadeId: targetSession,
|
||||
accept: isAccept,
|
||||
...(trackedSteps.length > 0 ? { stepIndices: trackedSteps } : {}),
|
||||
});
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ AcknowledgeCascadeCodeEdit (legacy): ${JSON.stringify(ackLegacy).substring(0, 300)}`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (rpcErr2) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] AcknowledgeCascadeCodeEdit (legacy) error: ${rpcErr2.message?.substring(0, 200)}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (outerErr) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] ❌ outer error: ${outerErr.message?.substring(0, 200)}`);
|
||||
}
|
||||
let modifiedFiles = [];
|
||||
// Load tracked step indices and modified files from memory cache or pending file
|
||||
const trackedSteps = [];
|
||||
const memMeta = diffReviewMetadata.get(resp.request_id);
|
||||
if (memMeta) {
|
||||
trackedSteps.push(...memMeta.edit_step_indices);
|
||||
modifiedFiles = memMeta.modified_files;
|
||||
diffReviewMetadata.delete(resp.request_id);
|
||||
logToFile(`[DIFF-REVIEW] loaded from memory: steps=[${trackedSteps.join(',')}] files=${modifiedFiles.length}`);
|
||||
}
|
||||
// ── Strategy 2: Open review panel + focus file + VS Code command ──
|
||||
if (!diffReviewDone) {
|
||||
else {
|
||||
try {
|
||||
// Step 2a: Open the Review Changes panel
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.openReviewChanges');
|
||||
logToFile(`[DIFF-REVIEW-CMD] openReviewChanges OK`);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
const pf = path.join(bridgePath, 'pending', `${resp.request_id}.json`);
|
||||
if (fs.existsSync(pf)) {
|
||||
const pd = JSON.parse(fs.readFileSync(pf, 'utf-8'));
|
||||
if (pd.edit_step_indices)
|
||||
trackedSteps.push(...pd.edit_step_indices);
|
||||
if (pd.modified_files)
|
||||
modifiedFiles = pd.modified_files;
|
||||
}
|
||||
catch { }
|
||||
// Step 2b: Use modifiedFiles from Strategy 1 (already loaded from memory/file above)
|
||||
// Step 2c: Open and focus each modified file, then execute
|
||||
if (modifiedFiles.length > 0) {
|
||||
for (const filePath of modifiedFiles) {
|
||||
try {
|
||||
const uri = vscode.Uri.file(filePath);
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc, { preview: false });
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW-CMD] ${cmd} on ${filePath.split(/[\\/]/).pop()} OK`);
|
||||
}
|
||||
catch (e) {
|
||||
logToFile(`[DIFF-REVIEW-CMD] per-file error on ${filePath}: ${e.message?.substring(0, 80)}`);
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
if (trackedSteps.length === 0 && pendingStepIndex > 0) {
|
||||
trackedSteps.push(pendingStepIndex);
|
||||
}
|
||||
// ── Strategy 1: VS Code command (confirmed registered at runtime) ──
|
||||
// agentAcceptAllInFile / agentRejectAllInFile are the ONLY working diff_review
|
||||
// commands. RPC methods (acknowledgeCodeActionStep → 404, AcknowledgeCascadeCodeEdit
|
||||
// → no-op {}, submitCodeAcknowledgement → not registered) are all dead ends.
|
||||
// The command requires the diff review file to be focused in the editor.
|
||||
try {
|
||||
// First, open the Review Changes panel to ensure diff UI is active
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.openReviewChanges');
|
||||
logToFile(`[DIFF-REVIEW] openReviewChanges OK`);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
}
|
||||
catch { }
|
||||
if (modifiedFiles.length > 0) {
|
||||
// Focus each modified file and execute accept/reject
|
||||
for (const fp of modifiedFiles) {
|
||||
try {
|
||||
const uri = vscode.Uri.file(fp);
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc, { preview: false });
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${cmd} on ${fp.split(/[\\/]/).pop()} OK`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (e) {
|
||||
logToFile(`[DIFF-REVIEW] per-file error on ${fp}: ${e.message?.substring(0, 80)}`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No file list — just execute command (best effort)
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW-CMD] ${cmd} executed (no file list)`);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// No file list — just execute command (best effort on currently focused file)
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${cmd} executed (no file list)`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (cmdErr) {
|
||||
logToFile(`[DIFF-REVIEW-CMD] error: ${cmdErr.message}`);
|
||||
}
|
||||
catch (cmdErr) {
|
||||
logToFile(`[DIFF-REVIEW] Strategy 1 command error: ${cmdErr.message?.substring(0, 200)}`);
|
||||
}
|
||||
// ── Strategy 2: Try individual hunk accept/reject as fallback ──
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const hunkCmd = isAccept
|
||||
? 'antigravity.prioritized.agentAcceptFocusedHunk'
|
||||
: 'antigravity.prioritized.agentRejectFocusedHunk';
|
||||
await vscode.commands.executeCommand(hunkCmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${hunkCmd} fallback OK`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
catch (hunkErr) {
|
||||
logToFile(`[DIFF-REVIEW] hunk fallback error: ${hunkErr.message?.substring(0, 100)}`);
|
||||
}
|
||||
}
|
||||
if (!diffReviewDone) {
|
||||
logToFile(`[DIFF-REVIEW] ❌ ALL strategies failed for rid=${resp.request_id}`);
|
||||
}
|
||||
}
|
||||
else if (isDomObserver) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@
|
||||
"name": "gravity-bridge",
|
||||
"displayName": "Gravity Bridge",
|
||||
"description": "Antigravity ↔ Discord 브리지 연동 확장",
|
||||
"version": "0.3.14",
|
||||
"version": "0.3.15",
|
||||
"publisher": "variet",
|
||||
"engines": {
|
||||
"vscode": "^1.100.0"
|
||||
|
||||
@@ -2595,120 +2595,84 @@ async function processResponseFile(filePath: string) {
|
||||
|
||||
let diffReviewDone = false;
|
||||
const targetSession = sessionId || activeSessionId;
|
||||
let modifiedFiles: string[] = []; // shared between Strategy 1 and 2
|
||||
let modifiedFiles: string[] = [];
|
||||
|
||||
// ── Strategy 1: acknowledgeCodeActionStep RPC (correct AG LS method) ──
|
||||
// Discovered via AG source reverse-engineering: the internal LS method is
|
||||
// `acknowledgeCodeActionStep` (proto ID 167), NOT `AcknowledgeCascadeCodeEdit`.
|
||||
// Accept all button → fireEvent({type:"accept-all-in-file"}) → submitCodeAcknowledgement → acknowledgeCodeActionStep
|
||||
if (sdk) {
|
||||
// Load tracked step indices and modified files from memory cache or pending file
|
||||
const trackedSteps: number[] = [];
|
||||
const memMeta = diffReviewMetadata.get(resp.request_id);
|
||||
if (memMeta) {
|
||||
trackedSteps.push(...memMeta.edit_step_indices);
|
||||
modifiedFiles = memMeta.modified_files;
|
||||
diffReviewMetadata.delete(resp.request_id);
|
||||
logToFile(`[DIFF-REVIEW] loaded from memory: steps=[${trackedSteps.join(',')}] files=${modifiedFiles.length}`);
|
||||
} else {
|
||||
try {
|
||||
// Get tracked step indices from in-memory cache FIRST (pending file may be deleted by Collector)
|
||||
const trackedSteps: number[] = [];
|
||||
const memMeta = diffReviewMetadata.get(resp.request_id);
|
||||
if (memMeta) {
|
||||
trackedSteps.push(...memMeta.edit_step_indices);
|
||||
modifiedFiles = memMeta.modified_files;
|
||||
diffReviewMetadata.delete(resp.request_id); // cleanup
|
||||
logToFile(`[DIFF-REVIEW-RPC] loaded from memory: steps=[${trackedSteps.join(',')}] files=${modifiedFiles.length}`);
|
||||
} else {
|
||||
// Fallback: try pending file (may already be deleted)
|
||||
const pendingDir = path.join(bridgePath, 'pending');
|
||||
const pf = path.join(bridgePath, 'pending', `${resp.request_id}.json`);
|
||||
if (fs.existsSync(pf)) {
|
||||
const pd = JSON.parse(fs.readFileSync(pf, 'utf-8'));
|
||||
if (pd.edit_step_indices) trackedSteps.push(...pd.edit_step_indices);
|
||||
if (pd.modified_files) modifiedFiles = pd.modified_files;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
if (trackedSteps.length === 0 && pendingStepIndex > 0) {
|
||||
trackedSteps.push(pendingStepIndex);
|
||||
}
|
||||
|
||||
// ── Strategy 1: VS Code command (confirmed registered at runtime) ──
|
||||
// agentAcceptAllInFile / agentRejectAllInFile are the ONLY working diff_review
|
||||
// commands. RPC methods (acknowledgeCodeActionStep → 404, AcknowledgeCascadeCodeEdit
|
||||
// → no-op {}, submitCodeAcknowledgement → not registered) are all dead ends.
|
||||
// The command requires the diff review file to be focused in the editor.
|
||||
try {
|
||||
// First, open the Review Changes panel to ensure diff UI is active
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.openReviewChanges');
|
||||
logToFile(`[DIFF-REVIEW] openReviewChanges OK`);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
} catch { }
|
||||
|
||||
if (modifiedFiles.length > 0) {
|
||||
// Focus each modified file and execute accept/reject
|
||||
for (const fp of modifiedFiles) {
|
||||
try {
|
||||
const pendingFile = path.join(pendingDir, `${resp.request_id}.json`);
|
||||
if (fs.existsSync(pendingFile)) {
|
||||
const pd = JSON.parse(fs.readFileSync(pendingFile, 'utf-8'));
|
||||
if (pd.edit_step_indices) trackedSteps.push(...pd.edit_step_indices);
|
||||
if (pd.modified_files) modifiedFiles = pd.modified_files;
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
// If no tracked steps, use the step_index from the pending
|
||||
if (trackedSteps.length === 0 && pendingStepIndex > 0) {
|
||||
trackedSteps.push(pendingStepIndex);
|
||||
}
|
||||
|
||||
logToFile(`[DIFF-REVIEW-RPC] acknowledgeCodeActionStep(session=${targetSession.substring(0, 8)}, accept=${isAccept}, steps=[${trackedSteps.join(',')}])`);
|
||||
|
||||
// Strategy 1a: VS Code command (most reliable — same path as UI button)
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.prioritized.submitCodeAcknowledgement');
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ submitCodeAcknowledgement command OK`);
|
||||
diffReviewDone = true;
|
||||
} catch (cmdErr: any) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] submitCodeAcknowledgement command error: ${cmdErr.message?.substring(0, 200)}`);
|
||||
}
|
||||
|
||||
// Strategy 1b: Direct LS RPC with correct method name
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const ackResult = await sdk.ls.rawRPC('acknowledgeCodeActionStep', {
|
||||
cascadeId: targetSession,
|
||||
accept: isAccept,
|
||||
...(trackedSteps.length > 0 ? { stepIndices: trackedSteps } : {}),
|
||||
});
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ acknowledgeCodeActionStep: ${JSON.stringify(ackResult).substring(0, 300)}`);
|
||||
const uri = vscode.Uri.file(fp);
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc, { preview: false });
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${cmd} on ${fp.split(/[\\/]/).pop()} OK`);
|
||||
diffReviewDone = true;
|
||||
} catch (rpcErr1: any) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] acknowledgeCodeActionStep error: ${rpcErr1.message?.substring(0, 200)}`);
|
||||
} catch (e: any) {
|
||||
logToFile(`[DIFF-REVIEW] per-file error on ${fp}: ${e.message?.substring(0, 80)}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No file list — just execute command (best effort on currently focused file)
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${cmd} executed (no file list)`);
|
||||
diffReviewDone = true;
|
||||
}
|
||||
} catch (cmdErr: any) {
|
||||
logToFile(`[DIFF-REVIEW] Strategy 1 command error: ${cmdErr.message?.substring(0, 200)}`);
|
||||
}
|
||||
|
||||
// Strategy 1c: Legacy method name (fallback)
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const ackLegacy = await sdk.ls.rawRPC('AcknowledgeCascadeCodeEdit', {
|
||||
cascadeId: targetSession,
|
||||
accept: isAccept,
|
||||
...(trackedSteps.length > 0 ? { stepIndices: trackedSteps } : {}),
|
||||
});
|
||||
logToFile(`[DIFF-REVIEW-RPC] ✅ AcknowledgeCascadeCodeEdit (legacy): ${JSON.stringify(ackLegacy).substring(0, 300)}`);
|
||||
diffReviewDone = true;
|
||||
} catch (rpcErr2: any) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] AcknowledgeCascadeCodeEdit (legacy) error: ${rpcErr2.message?.substring(0, 200)}`);
|
||||
}
|
||||
}
|
||||
} catch (outerErr: any) {
|
||||
logToFile(`[DIFF-REVIEW-RPC] ❌ outer error: ${outerErr.message?.substring(0, 200)}`);
|
||||
// ── Strategy 2: Try individual hunk accept/reject as fallback ──
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
const hunkCmd = isAccept
|
||||
? 'antigravity.prioritized.agentAcceptFocusedHunk'
|
||||
: 'antigravity.prioritized.agentRejectFocusedHunk';
|
||||
await vscode.commands.executeCommand(hunkCmd);
|
||||
logToFile(`[DIFF-REVIEW] ✅ ${hunkCmd} fallback OK`);
|
||||
diffReviewDone = true;
|
||||
} catch (hunkErr: any) {
|
||||
logToFile(`[DIFF-REVIEW] hunk fallback error: ${hunkErr.message?.substring(0, 100)}`);
|
||||
}
|
||||
}
|
||||
|
||||
// ── Strategy 2: Open review panel + focus file + VS Code command ──
|
||||
if (!diffReviewDone) {
|
||||
try {
|
||||
// Step 2a: Open the Review Changes panel
|
||||
try {
|
||||
await vscode.commands.executeCommand('antigravity.openReviewChanges');
|
||||
logToFile(`[DIFF-REVIEW-CMD] openReviewChanges OK`);
|
||||
await new Promise(r => setTimeout(r, 500));
|
||||
} catch { }
|
||||
|
||||
// Step 2b: Use modifiedFiles from Strategy 1 (already loaded from memory/file above)
|
||||
|
||||
// Step 2c: Open and focus each modified file, then execute
|
||||
if (modifiedFiles.length > 0) {
|
||||
for (const filePath of modifiedFiles) {
|
||||
try {
|
||||
const uri = vscode.Uri.file(filePath);
|
||||
const doc = await vscode.workspace.openTextDocument(uri);
|
||||
await vscode.window.showTextDocument(doc, { preview: false });
|
||||
await new Promise(r => setTimeout(r, 300));
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW-CMD] ${cmd} on ${filePath.split(/[\\/]/).pop()} OK`);
|
||||
} catch (e: any) {
|
||||
logToFile(`[DIFF-REVIEW-CMD] per-file error on ${filePath}: ${e.message?.substring(0, 80)}`);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// No file list — just execute command (best effort)
|
||||
await vscode.commands.executeCommand(cmd);
|
||||
logToFile(`[DIFF-REVIEW-CMD] ${cmd} executed (no file list)`);
|
||||
}
|
||||
diffReviewDone = true;
|
||||
} catch (cmdErr: any) {
|
||||
logToFile(`[DIFF-REVIEW-CMD] error: ${cmdErr.message}`);
|
||||
}
|
||||
logToFile(`[DIFF-REVIEW] ❌ ALL strategies failed for rid=${resp.request_id}`);
|
||||
}
|
||||
} else if (isDomObserver) {
|
||||
// DOM observer path: ALSO try RPC strategies (renderer click is unreliable)
|
||||
|
||||
Reference in New Issue
Block a user