fix(extension): v0.5.4 신호 감지 3중 버그 수정 — 세션 전환 즉시 probe, reviewAbsoluteUris 필드, stepIndex uint32 clamp + permission 매핑

This commit is contained in:
Variet Worker
2026-03-21 17:50:45 +09:00
parent f4ded343c7
commit a72c522ab5
6 changed files with 55 additions and 10 deletions

View File

@@ -1,12 +1,12 @@
{
"name": "gravity-bridge",
"version": "0.4.3",
"version": "0.5.4",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "gravity-bridge",
"version": "0.4.3",
"version": "0.5.4",
"dependencies": {
"ws": "^8.19.0"
},

View File

@@ -2,7 +2,7 @@
"name": "gravity-bridge",
"displayName": "Gravity Bridge",
"description": "Antigravity ↔ Discord 브리지 연동 확장",
"version": "0.5.2",
"version": "0.5.4",
"publisher": "variet",
"engines": {
"vscode": "^1.100.0"
@@ -85,4 +85,4 @@
"dependencies": {
"ws": "^8.19.0"
}
}
}

View File

@@ -313,7 +313,7 @@ async function processResponseFile(filePath: string) {
*/
export async function tryApprovalStrategies(approved: boolean, sessionId: string, stepType: string = '', stepIndex: number = -1): Promise<string> {
const action = approved ? 'APPROVE' : 'REJECT';
const effectiveStepIndex = stepIndex >= 0 ? stepIndex : ctx.lastPendingStepIndex;
const effectiveStepIndex = Math.max(0, stepIndex >= 0 ? stepIndex : ctx.lastPendingStepIndex);
ctx.logToFile(`[APPROVAL] Starting ${action} strategies for session ${sessionId.substring(0, 8)} stepType=${stepType} stepIndex=${effectiveStepIndex}`);
// ── Dynamic Command Discovery (log what's available during WAITING state) ──
@@ -388,6 +388,10 @@ export async function tryApprovalStrategies(approved: boolean, sessionId: string
interactionPayload = { filePermission: { allow: true, scope } };
} else if (typeLower.includes('elicitation')) {
interactionPayload = { elicitation: {} };
} else if (typeLower === 'permission' || typeLower.includes('permission')) {
// DOM observer 'permission' type: browser_subagent Allow/Deny dialog
// Try runExtensionCode first (most common for JS execution permission)
interactionPayload = { runExtensionCode: { confirm: true } };
} else {
// Default: try run_command (most common)
interactionPayload = { runCommand: { confirm: true } };

View File

@@ -258,6 +258,8 @@ function setupMonitor() {
const currentTitle = (bestSession.summary || 'Untitled').substring(0, 50);
const isRunning = String(bestSession.status || '').includes('RUNNING');
const currentModTime = bestSession.lastModifiedTime || (bestSession as any).lastModifiedTimestamp || (bestSession as any).modifiedTime || '';
// Session changed?
if (bestSessionId !== ctx.activeSessionId) {
ctx.activeSessionId = bestSessionId;
@@ -270,6 +272,14 @@ function setupMonitor() {
lastResponseCaptureStep = currentCount; // don't re-relay old responses
ctx.lastPendingStepIndex = -1;
ctx.stallProbed = false;
ctx.sawRunningAfterPending = true; // prevent stale auto_resolve from previous session
consecutiveIdleCount = 0;
lastModTime = currentModTime; // use currentModTime → prevents THINKING branch on first poll
// Reset transition/diff state from previous session (regression guard for fall-through)
wasRunning = isRunning;
pendingModifiedFiles = [];
pendingModifiedFilePaths = [];
pendingEditStepIndices = [];
// Don't register here — registration happens lazily in ctx.writeChatSnapshot/writePendingApproval
// to avoid race conditions between multiple extension instances
// Dump session keys + trajectoryMetadata on session change
@@ -280,7 +290,9 @@ function setupMonitor() {
ctx.logToFile(`[SESSION-INIT] trajectoryMetadata=${JSON.stringify(trajMeta).substring(0, 500)}`);
}
console.log(`Gravity Bridge: [POLL#${pollCount}] session: ${ctx.activeSessionId.substring(0, 8)} "${currentTitle}" steps=${currentCount} ${isRunning ? 'RUNNING' : 'idle'}`);
return;
// Fall through to WAITING detection — immediate probe on session change.
// Previously, `return` here caused 20-25s delay before first WAITING
// detection (confirmed via extension.log). Now we immediately check.
}
const delta = currentCount - lastKnownStepCount;
@@ -356,10 +368,15 @@ function setupMonitor() {
// ── STALL-BASED approval detection with step probe ──
const currentModTime = bestSession.lastModifiedTime || (bestSession as any).lastModifiedTimestamp || (bestSession as any).modifiedTime || '';
const modTimeChanged = currentModTime !== lastModTime;
const isStall = isRunning && delta === 0;
// Session-change immediate probe: bypass stall debounce on first poll
// Without this, consecutiveIdleCount=0 prevents probe condition (>=1)
if (isStall && consecutiveIdleCount === 0 && !ctx.stallProbed && !modTimeChanged) {
consecutiveIdleCount = 1; // force probe condition satisfied
}
// Log modTime on stalls for debugging
if (isStall && consecutiveIdleCount < 8) {
ctx.logToFile(`[STALL-DBG] idle=${consecutiveIdleCount} modTime='${currentModTime}' changed=${modTimeChanged}`);
@@ -661,9 +678,9 @@ function setupMonitor() {
}
// ── PathsToReview: read and relay referenced artifact files ──
const pathsToReview: string[] = notifyData.pathsToReview
|| notifyData.paths_to_review
|| notifyData.filePaths
// AG field name is `reviewAbsoluteUris` (confirmed via extension.log NOTIFY-STEP keys)
const pathsToReview: string[] = notifyData.reviewAbsoluteUris
|| notifyData.pathsToReview
|| [];
if (pathsToReview.length > 0) {
ctx.logToFile(`[NOTIFY-STEP] PathsToReview: ${pathsToReview.length} files`);