From d8eac80b2f7ce9d9a03164247c29b430deb8e263 Mon Sep 17 00:00:00 2001 From: Variet Worker Date: Wed, 18 Mar 2026 07:16:17 +0900 Subject: [PATCH] =?UTF-8?q?fix(ext):=20!stop=20CancelCascadeInvocation=20R?= =?UTF-8?q?PC=20=E2=80=94=20AG=20=EB=B9=A8=EA=B0=84=E2=96=A0=20=EB=8F=99?= =?UTF-8?q?=EC=9D=BC=20=EB=A9=94=EC=BB=A4=EB=8B=88=EC=A6=98=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20#task-411?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .agents/references/known-issues.md | 10 +- docs/devlog/2026-03-18.md | 3 +- extension/out/extension.js | 4 +- extension/out/extension.js.map | 2 +- extension/src/command-handler.ts | 53 +- extension/src/extension.ts | 1269 ++++++++++++++-------------- 6 files changed, 685 insertions(+), 656 deletions(-) diff --git a/.agents/references/known-issues.md b/.agents/references/known-issues.md index 50d4a3e..6c3437e 100644 --- a/.agents/references/known-issues.md +++ b/.agents/references/known-issues.md @@ -43,12 +43,10 @@ ### [2026-03-11] rejectAgentStep — AG 미등록 VS Code 커맨드 - **증상**: `/stop` 및 거부 시 `antigravity.agent.rejectAgentStep` → `command not found` - **원인**: AG IDE가 이 커맨드를 런타임에 등록하지 않음 (상수 정의만 존재) -- **해결** (2026-03-18): `command-handler.ts`의 `!stop` 핸들러를 `sdk.cascade.cancelCurrentTask()`로 교체. - WS 경로는 이미 SDK 사용 중이었으므로 file-based 경로만 수정. - - `CancelCascadeInvocation` gRPC 메서드도 사용 가능 (cascade_id 필요) - - **E2E 검증 필요** — AG 가동 중 `!stop` 명령 테스트 -- **주의**: `sdk.cascade.rejectStep()`은 여전히 내부적으로 `rejectAgentStep` 커맨드를 호출할 수 있음. - 단일 step 거부보다 `cancelCurrentTask()`(전체 중단)가 더 안정적. +- **해결** (2026-03-18): `_cancelCurrentCascade()` 헬퍼 추가 — `sdk.titles.getActiveCascadeId()` → `ls.cancelCascade(cascadeId)` (CancelCascadeInvocation RPC). + AG의 빨간색 ■ 버튼과 동일한 메커니즘. rawRPC fallback 포함. + - ~~`sdk.cascade.cancelCurrentTask()` — SDK에 존재하지 않는 메서드, 무시됨~~ +- **주의**: `getActiveCascadeId()`가 null이면 취소 불가 — 로그로 확인 필요 - **Vikunja**: #411 --- diff --git a/docs/devlog/2026-03-18.md b/docs/devlog/2026-03-18.md index 22a0415..819be5e 100644 --- a/docs/devlog/2026-03-18.md +++ b/docs/devlog/2026-03-18.md @@ -4,4 +4,5 @@ |---|------|------|------|------| | 001 | 06:09~06:26 | known-issues 정리/아카이빙 + Collector 폐기 마킹 + 문서 보강 (architecture, tech-stack, conventions) | `881a424` | ✅ | | 002 | 06:33~06:50 | Hub/WS 단위 테스트 45개 작성 (연결 관리, pending_owners, 라우팅, 인증) | `ac803d4` | ✅ | -| 003 | 06:50~07:00 | rejectAgentStep 대안 조사 — CancelCascadeInvocation RPC 발견 | `bcca706` | 🔧 | +| 003 | 06:50~07:05 | !stop 핸들러 SDK cancelCurrentTask() 교체 + VSIX 재빌드/설치 | `759dab5` | ✅ | +| 004 | 07:03~07:15 | !stop 재수정 — cancelCurrentTask→CancelCascadeInvocation RPC (AG 빨간■ 동일) + VSIX 설치 | `8d5940b` | ✅ | diff --git a/extension/out/extension.js b/extension/out/extension.js index 076eddd..3df9055 100644 --- a/extension/out/extension.js +++ b/extension/out/extension.js @@ -435,7 +435,7 @@ async function activate(context) { onCommand: (data) => { logToFile(`[WS-CMD] ${data.text?.substring(0, 50)}`); (0, command_handler_1.handleWSCommand)({ - bridgePath, projectName, sdk, autoApproveEnabled, logToFile, + bridgePath, projectName, sdk, ls: sdk?.ls, autoApproveEnabled, logToFile, onAutoApproveChanged: (enabled) => { autoApproveEnabled = enabled; }, recentDiscordSentTexts, }, data); @@ -558,7 +558,7 @@ async function activate(context) { } // Watch commands directory (0, command_handler_1.watchCommandsDir)({ - bridgePath, projectName, sdk, autoApproveEnabled, logToFile, + bridgePath, projectName, sdk, ls: sdk?.ls, autoApproveEnabled, logToFile, onAutoApproveChanged: (enabled) => { autoApproveEnabled = enabled; }, recentDiscordSentTexts, }); diff --git a/extension/out/extension.js.map b/extension/out/extension.js.map index d49f992..3006d76 100644 --- a/extension/out/extension.js.map +++ b/extension/out/extension.js.map @@ -1 +1 @@ -{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"extension.js","sourceRoot":"","sources":["../src/extension.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/extension/src/command-handler.ts b/extension/src/command-handler.ts index 8348c38..ca9ee30 100644 --- a/extension/src/command-handler.ts +++ b/extension/src/command-handler.ts @@ -17,6 +17,8 @@ export interface CommandHandlerContext { bridgePath: string; projectName: string; sdk: any; + /** LSBridge instance for direct LS RPC calls (cancelCascade, etc.) */ + ls: any; autoApproveEnabled: boolean; logToFile: (msg: string) => void; /** Called when auto-approve is toggled; extension.ts updates its own state */ @@ -93,9 +95,7 @@ export function handleWSCommand(ctx: CommandHandlerContext, data: { text?: strin if (text === '!stop') { ctx.logToFile('[WS-CMD] !stop — cancelling AG task'); - if (ctx.sdk) { - try { ctx.sdk.cascade.cancelCurrentTask(); } catch { } - } + _cancelCurrentCascade(ctx); return; } @@ -122,6 +122,42 @@ export function handleWSCommand(ctx: CommandHandlerContext, data: { text?: strin // ─── Private ─── +/** + * Cancel the currently active cascade via CancelCascadeInvocation RPC. + * This is the same mechanism AG's native red ■ stop button uses. + */ +async function _cancelCurrentCascade(ctx: CommandHandlerContext) { + // 1. Get the active cascade ID from SDK titles manager + const cascadeId = ctx.sdk?.titles?.getActiveCascadeId?.(); + if (!cascadeId) { + ctx.logToFile('[STOP] No active cascade to cancel (getActiveCascadeId returned null)'); + return; + } + + ctx.logToFile(`[STOP] Cancelling cascade: ${cascadeId.substring(0, 12)}...`); + + // 2. Use LSBridge.cancelCascade() → CancelCascadeInvocation RPC + if (ctx.ls) { + try { + await ctx.ls.cancelCascade(cascadeId); + ctx.logToFile(`[STOP] ✅ CancelCascadeInvocation sent for ${cascadeId.substring(0, 12)}`); + return; + } catch (e: any) { + ctx.logToFile(`[STOP] LSBridge cancelCascade failed: ${e.message}`); + } + } + + // 3. Fallback: try rawRPC directly via sdk.ls + if (ctx.sdk?.ls?.rawRPC) { + try { + await ctx.sdk.ls.rawRPC('CancelCascadeInvocation', { cascadeId }); + ctx.logToFile(`[STOP] ✅ rawRPC CancelCascadeInvocation sent for ${cascadeId.substring(0, 12)}`); + } catch (e: any) { + ctx.logToFile(`[STOP] rawRPC fallback also failed: ${e.message}`); + } + } +} + function _processCommandFile(filePath: string, ctx: CommandHandlerContext) { try { const content = fs.readFileSync(filePath, 'utf-8'); @@ -158,15 +194,8 @@ function _processCommandFile(filePath: string, ctx: CommandHandlerContext) { console.log(`Gravity Bridge: approve_terminal error: ${e.message}`) ); } else if (text === '!stop') { - // Cancel current operation — use SDK (rejectAgentStep is NOT a registered VS Code command) - if (ctx.sdk) { - try { - ctx.sdk.cascade.cancelCurrentTask(); - console.log('Gravity Bridge: ✅ stop sent via SDK'); - } catch (e: any) { - console.log(`Gravity Bridge: stop error: ${e.message}`); - } - } + // Cancel current operation — use CancelCascadeInvocation RPC (same as AG's red ■ button) + _cancelCurrentCascade(ctx); } else if (text.startsWith('!auto')) { // Auto-approve mode toggle let enabled: boolean; diff --git a/extension/src/extension.ts b/extension/src/extension.ts index 4c7c968..2fbe548 100644 --- a/extension/src/extension.ts +++ b/extension/src/extension.ts @@ -1,634 +1,635 @@ -/** - * Gravity Bridge — VS Code Extension (SDK Edition) - * - * Uses antigravity-sdk for: - * - Real-time step/conversation monitoring via EventMonitor - * - Full conversation content via LSBridge.getConversation() - * - Message sending via CascadeManager.sendPrompt() - * - Accept/Reject via CascadeManager.acceptStep()/rejectStep() - * - * Communication with Discord via file-based bridge protocol. - */ - -import * as vscode from 'vscode'; -import * as fs from 'fs'; -import * as path from 'path'; -import * as os from 'os'; -import * as cp from 'child_process'; -import { WSBridgeClient, WSResponseData, WSCommandData } from './ws-client'; -import { initStepProbe, BridgeContext, writePendingApproval, tryApprovalStrategies, writeRegistration, getApprovalContext, resetPendingState, handleDiffReviewResponse } from './step-probe'; -import { startHttpBridge, getDeterministicPort, HttpBridgeContext } from './http-bridge'; -import { setupApprovalObserver } from './html-patcher'; -import { watchCommandsDir, handleWSCommand, disposeCommandsWatcher, CommandHandlerContext } from './command-handler'; - -// ─── File-based logging (AI can read directly) ─── -function logToFile(msg: string) { - const ts = new Date().toISOString().replace('T', ' ').substring(0, 19); - // Include projectName prefix so shared log can distinguish which extension instance logged - const prefix = projectName ? `[${projectName}]` : ''; - const line = `${ts} ${prefix} ${msg}`; - console.log(`Gravity Bridge: ${prefix} ${msg}`); - try { - if (!bridgePath) return; - const logFile = path.join(bridgePath, 'extension.log'); - fs.appendFileSync(logFile, line + '\n', 'utf-8'); - } catch (e: any) { - console.error(`Gravity Bridge LOG WRITE FAIL: ${e.message}`); - } -} - -// antigravity-sdk embedded locally (src/sdk/) -let AntigravitySDK: any; -let sdk: any; - -let statusBar: vscode.StatusBarItem; -let bridgePath: string; -let projectName: string; -let workspaceUri: string = ''; // filesystem path of the workspace folder (for session filtering) -let isActive = false; -let autoApproveEnabled = false; // toggled via !auto from Discord -let watcher: fs.FSWatcher | null = null; -let wsBridge: WSBridgeClient | null = null; // WebSocket Hub connection - -const sentPendingIds = new Set(); -// Memory-based dedup: tracks recently created pending step_indexes to prevent -// regeneration after pending file deletion (by Collector/Bot response cycle). -// Map = `${conversationId}:${stepIndex}` → creation timestamp -const recentPendingSteps = new Map(); -const PENDING_MEMORY_TTL_MS = 60_000; // 60 seconds memory retention -// In-memory cache for diff_review metadata (survives pending file deletion by Collector). -// Map -const diffReviewMetadata = new Map(); - -// ─── Project Detection ─── - -function detectProjectName(): string { - const config = vscode.workspace.getConfiguration('gravityBridge'); - const configName = config.get('projectName'); - if (configName) { return configName; } - - const folders = vscode.workspace.workspaceFolders; - if (folders && folders.length > 0) { - const cwd = folders[0].uri.fsPath; - try { - const remoteUrl = cp.execSync('git remote get-url origin', { - cwd, encoding: 'utf-8', timeout: 3000 - }).trim(); - const match = remoteUrl.match(/\/([^\/]+?)(?:\.git)?$/); - if (match && match[1]) { - return match[1].toLowerCase().replace(/[\s\-]+/g, '_'); - } - } catch { } - return path.basename(cwd).toLowerCase().replace(/[\s\-]+/g, '_'); - } - return 'default'; -} - -// ─── Bridge File I/O ─── - -function ensureBridgeDir() { - const dirs = ['', 'response', 'commands', 'chat_snapshots']; - for (const d of dirs) { - const p = path.join(bridgePath, d); - if (!fs.existsSync(p)) { fs.mkdirSync(p, { recursive: true }); } - } -} - -// Module-level activeSessionId so writeChatSnapshot can register sessions lazily -let activeSessionId = ''; -let activeTrajectoryId = ''; -// Track recently sent Discord→AG texts to avoid echo relay -const recentDiscordSentTexts: Map = new Map(); - -function writeChatSnapshot(text: string) { - try { - // WS route (preferred) — skip file write to prevent duplicate Discord delivery - if (wsBridge && wsBridge.isConnected()) { - wsBridge.sendChat({ - content: text, - conversation_id: activeSessionId, - project_name: projectName, - }); - logToFile(`[SNAPSHOT-WS] sent (${text.length} chars)`); - if (activeSessionId) { writeRegistration(activeSessionId); } - return; - } - // File route (fallback — only when WS is NOT connected) - const snapshotDir = path.join(bridgePath, 'chat_snapshots'); - if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); } - const id = Date.now().toString(); - const data = { - id, - project_name: projectName, - content: text, - timestamp: Date.now() / 1000, - }; - const filePath = path.join(snapshotDir, `${id}.json`); - fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8'); - console.log(`Gravity Bridge: chat snapshot written (${text.length} chars) → ${id}.json`); - logToFile(`[SNAPSHOT] written ${id}.json (${text.length} chars)`); - logToFile(`[SNAPSHOT] content: ${text.substring(0, 200)}`); - // Lazily register session → project mapping (correct because projectName is per-window) - if (activeSessionId) { writeRegistration(activeSessionId); } - } catch (e: any) { - console.log(`Gravity Bridge: snapshot write error: ${e.message}`); - } -} - -function writeChatSnapshotWithFiles(text: string, files: Array<{name: string, content: string}>) { - try { - // WS route (preferred) — skip file write to prevent duplicate Discord delivery - if (wsBridge && wsBridge.isConnected()) { - wsBridge.sendChat({ - content: text, - attached_files: files, - conversation_id: activeSessionId, - project_name: projectName, - }); - logToFile(`[SNAPSHOT-WS] sent with ${files.length} files (${text.length} chars)`); - if (activeSessionId) { writeRegistration(activeSessionId); } - return; - } - // File route (fallback — only when WS is NOT connected) - const snapshotDir = path.join(bridgePath, 'chat_snapshots'); - if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); } - const id = Date.now().toString(); - const data = { - id, - project_name: projectName, - content: text, - attached_files: files, - timestamp: Date.now() / 1000, - }; - const filePath = path.join(snapshotDir, `${id}.json`); - fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8'); - logToFile(`[SNAPSHOT] written ${id}.json (${text.length} chars, ${files.length} files)`); - if (activeSessionId) { writeRegistration(activeSessionId); } - } catch (e: any) { - console.log(`Gravity Bridge: snapshot+files write error: ${e.message}`); - } -} - - -// ─── Command handling extracted to ./command-handler.ts ─── - -// ─── SDK Integration ─── - -async function initSDK(context: vscode.ExtensionContext): Promise { - try { - const sdkModule = require('./sdk/index'); - AntigravitySDK = sdkModule.AntigravitySDK; - } catch (err: any) { - console.log(`Gravity Bridge: antigravity-sdk load failed: ${err.message}`); - return false; - } - - try { - sdk = new AntigravitySDK(context); - await sdk.initialize(); - console.log('Gravity Bridge: ✅ SDK initialized'); - - // ── FIX: SDK's _findLSProcess() uses case-sensitive String.includes() ── - // workspace_id in LS process has 'Desktop' (capital D), but SDK hint - // generates 'desktop' (lowercase) → match fails → connects to WRONG LS. - // Re-discover the correct LS using case-insensitive workspace_id matching. - await fixLSConnection(); - - return true; - } catch (err: any) { - console.log(`Gravity Bridge: SDK init failed: ${err.message}`); - return false; - } -} - -/** - * Fix SDK's LS connection by finding the correct language_server process - * for this workspace using case-insensitive matching. - * - * SDK bug: _findLSProcess() compares workspaceHint via JS String.includes() - * which is case-sensitive. workspace_id in process args has original casing - * (e.g., file_c_3A_Users_Certes_Desktop_variet_agent) but SDK hint is - * lowercased (desktop_variet_agent) → no match → falls back to first LS - * found (wrong workspace). - */ -async function fixLSConnection(): Promise { - if (!sdk?.ls) return; - try { - const folders = vscode.workspace.workspaceFolders; - if (!folders || folders.length === 0) return; - - // Generate the workspace hint the same way SDK does, but we'll match case-insensitively - const folder = folders[0].uri.fsPath; - const parts = folder.replace(/\\/g, '/').split('/'); - const hint = parts.slice(-2).join('_').replace(/[-.\s]/g, '_').toLowerCase(); - - if (!hint) return; - - // Find all language_server processes with csrf_token - const { exec } = cp; - const { promisify } = require('util'); - const execAsync = promisify(exec); - - let output: string; - try { - const psScript = `Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'language_server' -and $_.CommandLine -match 'csrf_token' } | ForEach-Object { $_.ProcessId.ToString() + '|' + $_.CommandLine }`; - const encoded = Buffer.from(psScript, 'utf16le').toString('base64'); - const result = await execAsync( - `powershell.exe -NoProfile -EncodedCommand ${encoded}`, - { encoding: 'utf8', timeout: 15000, windowsHide: true } - ); - output = result.stdout; - } catch { - return; // Can't discover processes — leave SDK's choice - } - - const lines = output.split('\n').filter((l: string) => l.trim().length > 0); - if (lines.length <= 1) return; // Only one LS — no ambiguity - - // Find the line whose workspace_id matches our workspace (case-insensitive) - let matchedLine: string | null = null; - for (const line of lines) { - const lower = line.toLowerCase(); - // Match workspace_id arg against our hint - const wsMatch = line.match(/--workspace_id[= ](\S+)/i); - if (wsMatch) { - const wsid = wsMatch[1].toLowerCase(); - if (wsid.includes(hint)) { - matchedLine = line; - break; - } - } - } - - if (!matchedLine) { - logToFile(`[LS-FIX] No LS process matched hint="${hint}" (${lines.length} processes)`); - return; - } - - // Extract port and csrf_token from matched line - const csrfMatch = matchedLine.match(/--csrf_token[= ](\S+)/); - const extPortMatch = matchedLine.match(/--extension_server_port[= ](\d+)/); - const pidMatch = matchedLine.split('|')[0]?.trim(); - - if (!csrfMatch || !extPortMatch) { - logToFile(`[LS-FIX] Matched LS but missing csrf/port args`); - return; - } - - const csrfToken = csrfMatch[1]; - const extPort = parseInt(extPortMatch[1], 10); - const pid = parseInt(pidMatch || '0', 10); - - // Check if SDK already connected to this LS - if (sdk.ls.port === extPort) { - logToFile(`[LS-FIX] SDK already on correct LS port=${extPort}`); - return; - } - - // Find ConnectRPC port via netstat (same as SDK logic) - let netstatOutput: string; - try { - const result = await execAsync( - `netstat -aon | findstr "LISTENING" | findstr "${pid}"`, - { encoding: 'utf8', timeout: 5000, windowsHide: true } - ); - netstatOutput = result.stdout; - } catch { - // Netstat failed — try extension_server_port as fallback - logToFile(`[LS-FIX] netstat failed, using ext_port=${extPort} for PID=${pid}`); - sdk.ls.setConnection(extPort, csrfToken, false); - logToFile(`[LS-FIX] ✅ Reconnected to correct LS: port=${extPort} hint="${hint}" PID=${pid}`); - return; - } - - const portMatches = netstatOutput.matchAll(/127\.0\.0\.1:(\d+)/g); - const ports: number[] = []; - for (const m of portMatches) { - const p = parseInt(m[1], 10); - if (p !== extPort && !ports.includes(p)) { - ports.push(p); - } - } - - // Try each port — prefer HTTPS, fall back to HTTP - const httpModule = require('http'); - const httpsModule = require('https'); - - for (const useTls of [true, false]) { - const mod = useTls ? httpsModule : httpModule; - const proto = useTls ? 'https' : 'http'; - for (const port of ports) { - try { - const ok = await new Promise((resolve) => { - const req = mod.request( - `${proto}://127.0.0.1:${port}/exa.language_server_pb.LanguageServerService/GetUserStatus`, - { - method: 'POST', - headers: { 'Content-Type': 'application/json', 'Content-Length': 2 }, - rejectUnauthorized: false, - timeout: 2000, - }, - (res: any) => resolve(res.statusCode === 200 || res.statusCode === 401) - ); - req.on('error', () => resolve(false)); - req.on('timeout', () => { req.destroy(); resolve(false); }); - req.write('{}'); - req.end(); - }); - - if (ok) { - sdk.ls.setConnection(port, csrfToken, useTls); - logToFile(`[LS-FIX] ✅ Reconnected to correct LS: port=${port} ${proto} hint="${hint}" PID=${pid}`); - return; - } - } catch { /* try next */ } - } - } - - // Last resort: use extension_server_port - sdk.ls.setConnection(extPort, csrfToken, false); - logToFile(`[LS-FIX] ✅ Reconnected via ext_port=${extPort} hint="${hint}" PID=${pid}`); - } catch (err: any) { - logToFile(`[LS-FIX] error: ${err.message}`); - } -} - -// ─── Approval Observer + Product.json Checksums extracted to ./html-patcher.ts ─── - -// ─── HTTP Bridge Server extracted to ./http-bridge.ts ─── - -// Shared state for HTTP bridge context (module-level, referenced by BridgeContext too) -let sessionStalled = false; -let lastPendingStepIndex = -1; -let stallProbed = false; -let sawRunningAfterPending = true; - -// ─── Step Probe, Response Watcher, Approval Strategies → extracted to ./step-probe.ts ─── - - -export async function activate(context: vscode.ExtensionContext) { - console.log('Gravity Bridge: activating...'); - - // Project detection - projectName = detectProjectName(); - // Store workspace folder path for session filtering (prevents cross-window session grabbing) - const folders = vscode.workspace.workspaceFolders; - workspaceUri = folders && folders.length > 0 ? folders[0].uri.fsPath : ''; - console.log(`Gravity Bridge: project "${projectName}" workspace="${workspaceUri}"`); - - // Bridge path - const config = vscode.workspace.getConfiguration('gravityBridge'); - const configPath = config.get('bridgePath'); - bridgePath = configPath || path.join(os.homedir(), '.gemini', 'antigravity', 'bridge'); - ensureBridgeDir(); - console.log(`Gravity Bridge: bridge path: ${bridgePath}`); - - // ── WebSocket Hub Connection ── - const hubUrl = process.env.GRAVITY_HUB_URL || config.get('hubUrl') || ''; - const regCode = process.env.GRAVITY_REGISTRATION_CODE || config.get('registrationCode') || ''; - const pcName = os.hostname(); - if (hubUrl) { - wsBridge = new WSBridgeClient(hubUrl, regCode, projectName, pcName, { - onResponse: (data: WSResponseData) => { - logToFile(`[WS-RESPONSE] ${data.request_id?.substring(0, 12)} approved=${data.approved} step_type=${data.step_type || '(none)'}`); - const approved = data.approved ?? true; - const stepType = data.step_type || ''; - - // ── diff_review: Accept all / Reject all (REGRESSION FIX) ── - // Previously only handled in processResponseFile (file-bridge path). - // WS path was missing this logic entirely, causing Accept All to fail. - if (stepType === 'diff_review') { - logToFile(`[WS-RESPONSE] diff_review detected — routing to handleDiffReviewResponse`); - handleDiffReviewResponse({ - request_id: data.request_id, - approved, - button_index: data.button_index, - step_type: stepType, - }) - .then(result => { - logToFile(`[WS-RESPONSE] diff_review result: ${result}`); - resetPendingState(); - }) - .catch(err => logToFile(`[WS-RESPONSE] diff_review error: ${err.message}`)); - return; - } - - // Normal approval — tryApprovalStrategies - const approvalCtx = getApprovalContext(); - logToFile(`[WS-RESPONSE] Triggering approval: approved=${approved} session=${approvalCtx.sessionId.substring(0, 8)} stepType=${stepType} stepIndex=${approvalCtx.stepIndex}`); - tryApprovalStrategies(approved, approvalCtx.sessionId, stepType, approvalCtx.stepIndex) - .then(result => { - logToFile(`[WS-RESPONSE] Approval result: ${result}`); - resetPendingState(); - }) - .catch(err => logToFile(`[WS-RESPONSE] Approval error: ${err.message}`)); - }, - onCommand: (data: WSCommandData) => { - logToFile(`[WS-CMD] ${data.text?.substring(0, 50)}`); - handleWSCommand({ - bridgePath, projectName, sdk, autoApproveEnabled, logToFile, - onAutoApproveChanged: (enabled: boolean) => { autoApproveEnabled = enabled; }, - recentDiscordSentTexts, - }, data); - }, - onInstanceUpdate: (count, instances) => { - logToFile(`[WS-INSTANCE] ${count} active instances`); - }, - onConnected: (connId, instanceNum, token) => { - logToFile(`[WS] Connected: ${connId} instance=#${instanceNum}`); - statusBar.text = '$(check) Bridge WS'; - statusBar.tooltip = `Gravity Bridge: ${projectName} (WS #${instanceNum})`; - }, - onDisconnected: () => { - logToFile('[WS] Disconnected — using file fallback'); - statusBar.text = '$(warning) Bridge (WS ↓)'; - }, - onError: (err) => { - logToFile(`[WS-ERR] ${err}`); - }, - }, logToFile); - wsBridge.connect(); - logToFile(`[WS] Hub connection initiated: ${hubUrl}`); - } else { - logToFile('[WS] No GRAVITY_HUB_URL — WebSocket disabled, using file bridge only'); - } - - // ── Multi-project: no lock file, each project uses project_name-based filtering ── - // (active_project.lock removed — was blocking concurrent multi-project usage) - logToFile(`[INIT] project="${projectName}" pid=${process.pid} — multi-project mode (no lock)`); - - // Status bar - statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100); - statusBar.text = '$(sync~spin) Bridge'; - statusBar.tooltip = `Gravity Bridge: ${projectName}`; - statusBar.show(); - context.subscriptions.push(statusBar); - - // Initialize SDK - const sdkReady = await initSDK(context); - - if (sdkReady) { - // ── Command Discovery Diagnostic ── - // Enumerate ALL antigravity.* commands to find correct approval command names - try { - const allCmds = await vscode.commands.getCommands(true); - const agCmds = allCmds.filter((c: string) => c.startsWith('antigravity.')); - logToFile(`[CMD-DISCOVERY] Total antigravity.* commands: ${agCmds.length}`); - // Log approval-related commands specifically - const approvalKeywords = ['accept', 'reject', 'approve', 'terminal', 'agent', 'cascade', 'step', 'run', 'command.']; - const relevantCmds = agCmds.filter((c: string) => - approvalKeywords.some(kw => c.toLowerCase().includes(kw)) - ); - logToFile(`[CMD-DISCOVERY] Approval-related commands (${relevantCmds.length}):`); - for (const cmd of relevantCmds) { - logToFile(`[CMD-DISCOVERY] → ${cmd}`); - } - // Also dump ALL commands for full reference - logToFile(`[CMD-DISCOVERY] ALL antigravity.* commands:`); - for (const cmd of agCmds) { - logToFile(`[CMD-DISCOVERY] ${cmd}`); - } - } catch (e: any) { - logToFile(`[CMD-DISCOVERY] error: ${e.message}`); - } - - // Initialize step probe (polling + response watcher) - initStepProbe({ - bridgePath, - projectName, - sdk, - wsBridge, - autoApproveEnabled, - activeSessionId, - sessionStalled, - lastPendingStepIndex, - stallProbed, - sawRunningAfterPending, - setClickTrigger: (action: 'approve' | 'reject') => { - const { setClickTrigger: setTrigger } = require('./http-bridge'); - setTrigger(action); - }, - logToFile, - workspaceUri, - diffReviewMetadata: new Map(), - recentDiscordSentTexts, - writeChatSnapshot, - writeChatSnapshotWithFiles, - } as BridgeContext); - // Start HTTP bridge, then setup observer - const httpBridgeCtx: HttpBridgeContext = { - bridgePath, projectName, activeSessionId, wsBridge, - sessionStalled, lastPendingStepIndex, logToFile, - }; - const bridgePort = await startHttpBridge(httpBridgeCtx, sdk); - if (bridgePort) { - await setupApprovalObserver(sdk, bridgePort, logToFile); - } else { - logToFile('[OBSERVER] HTTP bridge failed — skipping observer setup'); - } - statusBar.text = '$(check) Bridge'; - statusBar.tooltip = `Gravity Bridge: ${projectName} (POLL + Observer active)`; - - // Register SDK-powered commands - context.subscriptions.push( - vscode.commands.registerCommand('gravityBridge.approve', async () => { - try { - await sdk.cascade.acceptStep(); - vscode.window.showInformationMessage('Gravity Bridge: Step approved'); - } catch (e: any) { - vscode.window.showErrorMessage(`Approve failed: ${e.message}`); - } - }), - vscode.commands.registerCommand('gravityBridge.reject', async () => { - try { - await sdk.cascade.rejectStep(); - vscode.window.showInformationMessage('Gravity Bridge: Step rejected'); - } catch (e: any) { - vscode.window.showErrorMessage(`Reject failed: ${e.message}`); - } - }) - ); - } else { - statusBar.text = '$(warning) Bridge (no SDK)'; - console.log('Gravity Bridge: SDK not available, file-based mode only'); - } - - // Watch commands directory - watchCommandsDir({ - bridgePath, projectName, sdk, autoApproveEnabled, logToFile, - onAutoApproveChanged: (enabled: boolean) => { autoApproveEnabled = enabled; }, - recentDiscordSentTexts, - }); - - // Response watcher is now initialized by initStepProbe() above - // Register basic commands - context.subscriptions.push( - vscode.commands.registerCommand('gravityBridge.start', () => { - isActive = true; - statusBar.text = sdkReady ? '$(check) Bridge SDK' : '$(sync~spin) Bridge'; - vscode.window.showInformationMessage(`Gravity Bridge started for "${projectName}"`); - }), - vscode.commands.registerCommand('gravityBridge.stop', () => { - isActive = false; - // SDK monitor is disabled, no need to stop - statusBar.text = '$(circle-slash) Bridge OFF'; - vscode.window.showInformationMessage('Gravity Bridge stopped'); - }), - vscode.commands.registerCommand('gravityBridge.connect', async () => { - if (!sdk) { - vscode.window.showErrorMessage('SDK not initialized'); - return; - } - try { - const sessions = await sdk.cascade.getSessions(); - const items = sessions.map((s: any) => ({ - label: s.title || 'Untitled', - description: `step ${s.stepCount} • ${s.id?.substring(0, 8)}`, - sessionId: s.id, - })); - const pick = await vscode.window.showQuickPick(items, { - placeHolder: 'Select a conversation to connect' - }); - if (pick) { - await sdk.cascade.focusSession((pick as any).sessionId); - vscode.window.showInformationMessage(`Connected to: ${(pick as any).label}`); - } - } catch (e: any) { - vscode.window.showErrorMessage(`Connect failed: ${e.message}`); - } - }) - ); - - // Cleanup - context.subscriptions.push({ - dispose: () => { - if (sdk) { try { sdk.dispose(); } catch { } } - if (watcher) { watcher.close(); } - disposeCommandsWatcher(); - } - }); - - console.log('Gravity Bridge: ✅ activated'); - isActive = true; -} - -export function deactivate() { - // Disconnect WebSocket - if (wsBridge) { - wsBridge.disconnect(); - wsBridge = null; - } - // Clean up stale lock file if it exists (legacy cleanup) - try { - const lockFile = path.join(bridgePath, 'active_project.lock'); - if (fs.existsSync(lockFile)) { - const lockData = JSON.parse(fs.readFileSync(lockFile, 'utf-8')); - if (lockData.pid === process.pid) { - fs.unlinkSync(lockFile); - } - } - } catch { } - if (sdk) { - try { sdk.dispose(); } catch { } - } -} +/** + * Gravity Bridge — VS Code Extension (SDK Edition) + * + * Uses antigravity-sdk for: + * - Real-time step/conversation monitoring via EventMonitor + * - Full conversation content via LSBridge.getConversation() + * - Message sending via CascadeManager.sendPrompt() + * - Accept/Reject via CascadeManager.acceptStep()/rejectStep() + * + * Communication with Discord via file-based bridge protocol. + */ + +import * as vscode from 'vscode'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as os from 'os'; +import * as cp from 'child_process'; +import { WSBridgeClient, WSResponseData, WSCommandData } from './ws-client'; +import { initStepProbe, BridgeContext, writePendingApproval, tryApprovalStrategies, writeRegistration, getApprovalContext, resetPendingState, handleDiffReviewResponse } from './step-probe'; +import { startHttpBridge, getDeterministicPort, HttpBridgeContext } from './http-bridge'; +import { setupApprovalObserver } from './html-patcher'; +import { watchCommandsDir, handleWSCommand, disposeCommandsWatcher, CommandHandlerContext } from './command-handler'; + +// ─── File-based logging (AI can read directly) ─── +function logToFile(msg: string) { + const ts = new Date().toISOString().replace('T', ' ').substring(0, 19); + // Include projectName prefix so shared log can distinguish which extension instance logged + const prefix = projectName ? `[${projectName}]` : ''; + const line = `${ts} ${prefix} ${msg}`; + console.log(`Gravity Bridge: ${prefix} ${msg}`); + try { + if (!bridgePath) return; + const logFile = path.join(bridgePath, 'extension.log'); + fs.appendFileSync(logFile, line + '\n', 'utf-8'); + } catch (e: any) { + console.error(`Gravity Bridge LOG WRITE FAIL: ${e.message}`); + } +} + +// antigravity-sdk embedded locally (src/sdk/) +let AntigravitySDK: any; +let sdk: any; + +let statusBar: vscode.StatusBarItem; +let bridgePath: string; +let projectName: string; +let workspaceUri: string = ''; // filesystem path of the workspace folder (for session filtering) +let isActive = false; +let autoApproveEnabled = false; // toggled via !auto from Discord +let watcher: fs.FSWatcher | null = null; +let wsBridge: WSBridgeClient | null = null; // WebSocket Hub connection + +const sentPendingIds = new Set(); +// Memory-based dedup: tracks recently created pending step_indexes to prevent +// regeneration after pending file deletion (by Collector/Bot response cycle). +// Map = `${conversationId}:${stepIndex}` → creation timestamp +const recentPendingSteps = new Map(); +const PENDING_MEMORY_TTL_MS = 60_000; // 60 seconds memory retention +// In-memory cache for diff_review metadata (survives pending file deletion by Collector). +// Map +const diffReviewMetadata = new Map(); + +// ─── Project Detection ─── + +function detectProjectName(): string { + const config = vscode.workspace.getConfiguration('gravityBridge'); + const configName = config.get('projectName'); + if (configName) { return configName; } + + const folders = vscode.workspace.workspaceFolders; + if (folders && folders.length > 0) { + const cwd = folders[0].uri.fsPath; + try { + const remoteUrl = cp.execSync('git remote get-url origin', { + cwd, encoding: 'utf-8', timeout: 3000 + }).trim(); + const match = remoteUrl.match(/\/([^\/]+?)(?:\.git)?$/); + if (match && match[1]) { + return match[1].toLowerCase().replace(/[\s\-]+/g, '_'); + } + } catch { } + return path.basename(cwd).toLowerCase().replace(/[\s\-]+/g, '_'); + } + return 'default'; +} + +// ─── Bridge File I/O ─── + +function ensureBridgeDir() { + const dirs = ['', 'response', 'commands', 'chat_snapshots']; + for (const d of dirs) { + const p = path.join(bridgePath, d); + if (!fs.existsSync(p)) { fs.mkdirSync(p, { recursive: true }); } + } +} + +// Module-level activeSessionId so writeChatSnapshot can register sessions lazily +let activeSessionId = ''; +let activeTrajectoryId = ''; +// Track recently sent Discord→AG texts to avoid echo relay +const recentDiscordSentTexts: Map = new Map(); + +function writeChatSnapshot(text: string) { + try { + // WS route (preferred) — skip file write to prevent duplicate Discord delivery + if (wsBridge && wsBridge.isConnected()) { + wsBridge.sendChat({ + content: text, + conversation_id: activeSessionId, + project_name: projectName, + }); + logToFile(`[SNAPSHOT-WS] sent (${text.length} chars)`); + if (activeSessionId) { writeRegistration(activeSessionId); } + return; + } + // File route (fallback — only when WS is NOT connected) + const snapshotDir = path.join(bridgePath, 'chat_snapshots'); + if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); } + const id = Date.now().toString(); + const data = { + id, + project_name: projectName, + content: text, + timestamp: Date.now() / 1000, + }; + const filePath = path.join(snapshotDir, `${id}.json`); + fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8'); + console.log(`Gravity Bridge: chat snapshot written (${text.length} chars) → ${id}.json`); + logToFile(`[SNAPSHOT] written ${id}.json (${text.length} chars)`); + logToFile(`[SNAPSHOT] content: ${text.substring(0, 200)}`); + // Lazily register session → project mapping (correct because projectName is per-window) + if (activeSessionId) { writeRegistration(activeSessionId); } + } catch (e: any) { + console.log(`Gravity Bridge: snapshot write error: ${e.message}`); + } +} + +function writeChatSnapshotWithFiles(text: string, files: Array<{ name: string, content: string }>) { + try { + // WS route (preferred) — skip file write to prevent duplicate Discord delivery + if (wsBridge && wsBridge.isConnected()) { + wsBridge.sendChat({ + content: text, + attached_files: files, + conversation_id: activeSessionId, + project_name: projectName, + }); + logToFile(`[SNAPSHOT-WS] sent with ${files.length} files (${text.length} chars)`); + if (activeSessionId) { writeRegistration(activeSessionId); } + return; + } + // File route (fallback — only when WS is NOT connected) + const snapshotDir = path.join(bridgePath, 'chat_snapshots'); + if (!fs.existsSync(snapshotDir)) { fs.mkdirSync(snapshotDir, { recursive: true }); } + const id = Date.now().toString(); + const data = { + id, + project_name: projectName, + content: text, + attached_files: files, + timestamp: Date.now() / 1000, + }; + const filePath = path.join(snapshotDir, `${id}.json`); + fs.writeFileSync(filePath, JSON.stringify(data, null, 2), 'utf-8'); + logToFile(`[SNAPSHOT] written ${id}.json (${text.length} chars, ${files.length} files)`); + if (activeSessionId) { writeRegistration(activeSessionId); } + } catch (e: any) { + console.log(`Gravity Bridge: snapshot+files write error: ${e.message}`); + } +} + + +// ─── Command handling extracted to ./command-handler.ts ─── + +// ─── SDK Integration ─── + +async function initSDK(context: vscode.ExtensionContext): Promise { + try { + const sdkModule = require('./sdk/index'); + AntigravitySDK = sdkModule.AntigravitySDK; + } catch (err: any) { + console.log(`Gravity Bridge: antigravity-sdk load failed: ${err.message}`); + return false; + } + + try { + sdk = new AntigravitySDK(context); + await sdk.initialize(); + console.log('Gravity Bridge: ✅ SDK initialized'); + + // ── FIX: SDK's _findLSProcess() uses case-sensitive String.includes() ── + // workspace_id in LS process has 'Desktop' (capital D), but SDK hint + // generates 'desktop' (lowercase) → match fails → connects to WRONG LS. + // Re-discover the correct LS using case-insensitive workspace_id matching. + await fixLSConnection(); + + return true; + } catch (err: any) { + console.log(`Gravity Bridge: SDK init failed: ${err.message}`); + return false; + } +} + +/** + * Fix SDK's LS connection by finding the correct language_server process + * for this workspace using case-insensitive matching. + * + * SDK bug: _findLSProcess() compares workspaceHint via JS String.includes() + * which is case-sensitive. workspace_id in process args has original casing + * (e.g., file_c_3A_Users_Certes_Desktop_variet_agent) but SDK hint is + * lowercased (desktop_variet_agent) → no match → falls back to first LS + * found (wrong workspace). + */ +async function fixLSConnection(): Promise { + if (!sdk?.ls) return; + try { + const folders = vscode.workspace.workspaceFolders; + if (!folders || folders.length === 0) return; + + // Generate the workspace hint the same way SDK does, but we'll match case-insensitively + const folder = folders[0].uri.fsPath; + const parts = folder.replace(/\\/g, '/').split('/'); + const hint = parts.slice(-2).join('_').replace(/[-.\s]/g, '_').toLowerCase(); + + if (!hint) return; + + // Find all language_server processes with csrf_token + const { exec } = cp; + const { promisify } = require('util'); + const execAsync = promisify(exec); + + let output: string; + try { + const psScript = `Get-CimInstance Win32_Process | Where-Object { $_.CommandLine -match 'language_server' -and $_.CommandLine -match 'csrf_token' } | ForEach-Object { $_.ProcessId.ToString() + '|' + $_.CommandLine }`; + const encoded = Buffer.from(psScript, 'utf16le').toString('base64'); + const result = await execAsync( + `powershell.exe -NoProfile -EncodedCommand ${encoded}`, + { encoding: 'utf8', timeout: 15000, windowsHide: true } + ); + output = result.stdout; + } catch { + return; // Can't discover processes — leave SDK's choice + } + + const lines = output.split('\n').filter((l: string) => l.trim().length > 0); + if (lines.length <= 1) return; // Only one LS — no ambiguity + + // Find the line whose workspace_id matches our workspace (case-insensitive) + let matchedLine: string | null = null; + for (const line of lines) { + const lower = line.toLowerCase(); + // Match workspace_id arg against our hint + const wsMatch = line.match(/--workspace_id[= ](\S+)/i); + if (wsMatch) { + const wsid = wsMatch[1].toLowerCase(); + if (wsid.includes(hint)) { + matchedLine = line; + break; + } + } + } + + if (!matchedLine) { + logToFile(`[LS-FIX] No LS process matched hint="${hint}" (${lines.length} processes)`); + return; + } + + // Extract port and csrf_token from matched line + const csrfMatch = matchedLine.match(/--csrf_token[= ](\S+)/); + const extPortMatch = matchedLine.match(/--extension_server_port[= ](\d+)/); + const pidMatch = matchedLine.split('|')[0]?.trim(); + + if (!csrfMatch || !extPortMatch) { + logToFile(`[LS-FIX] Matched LS but missing csrf/port args`); + return; + } + + const csrfToken = csrfMatch[1]; + const extPort = parseInt(extPortMatch[1], 10); + const pid = parseInt(pidMatch || '0', 10); + + // Check if SDK already connected to this LS + if (sdk.ls.port === extPort) { + logToFile(`[LS-FIX] SDK already on correct LS port=${extPort}`); + return; + } + + // Find ConnectRPC port via netstat (same as SDK logic) + let netstatOutput: string; + try { + const result = await execAsync( + `netstat -aon | findstr "LISTENING" | findstr "${pid}"`, + { encoding: 'utf8', timeout: 5000, windowsHide: true } + ); + netstatOutput = result.stdout; + } catch { + // Netstat failed — try extension_server_port as fallback + logToFile(`[LS-FIX] netstat failed, using ext_port=${extPort} for PID=${pid}`); + sdk.ls.setConnection(extPort, csrfToken, false); + logToFile(`[LS-FIX] ✅ Reconnected to correct LS: port=${extPort} hint="${hint}" PID=${pid}`); + return; + } + + const portMatches = netstatOutput.matchAll(/127\.0\.0\.1:(\d+)/g); + const ports: number[] = []; + for (const m of portMatches) { + const p = parseInt(m[1], 10); + if (p !== extPort && !ports.includes(p)) { + ports.push(p); + } + } + + // Try each port — prefer HTTPS, fall back to HTTP + const httpModule = require('http'); + const httpsModule = require('https'); + + for (const useTls of [true, false]) { + const mod = useTls ? httpsModule : httpModule; + const proto = useTls ? 'https' : 'http'; + for (const port of ports) { + try { + const ok = await new Promise((resolve) => { + const req = mod.request( + `${proto}://127.0.0.1:${port}/exa.language_server_pb.LanguageServerService/GetUserStatus`, + { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'Content-Length': 2 }, + rejectUnauthorized: false, + timeout: 2000, + }, + (res: any) => resolve(res.statusCode === 200 || res.statusCode === 401) + ); + req.on('error', () => resolve(false)); + req.on('timeout', () => { req.destroy(); resolve(false); }); + req.write('{}'); + req.end(); + }); + + if (ok) { + sdk.ls.setConnection(port, csrfToken, useTls); + logToFile(`[LS-FIX] ✅ Reconnected to correct LS: port=${port} ${proto} hint="${hint}" PID=${pid}`); + return; + } + } catch { /* try next */ } + } + } + + // Last resort: use extension_server_port + sdk.ls.setConnection(extPort, csrfToken, false); + logToFile(`[LS-FIX] ✅ Reconnected via ext_port=${extPort} hint="${hint}" PID=${pid}`); + } catch (err: any) { + logToFile(`[LS-FIX] error: ${err.message}`); + } +} + +// ─── Approval Observer + Product.json Checksums extracted to ./html-patcher.ts ─── + +// ─── HTTP Bridge Server extracted to ./http-bridge.ts ─── + +// Shared state for HTTP bridge context (module-level, referenced by BridgeContext too) +let sessionStalled = false; +let lastPendingStepIndex = -1; +let stallProbed = false; +let sawRunningAfterPending = true; + +// ─── Step Probe, Response Watcher, Approval Strategies → extracted to ./step-probe.ts ─── + + + +export async function activate(context: vscode.ExtensionContext) { + console.log('Gravity Bridge: activating...'); + + // Project detection + projectName = detectProjectName(); + // Store workspace folder path for session filtering (prevents cross-window session grabbing) + const folders = vscode.workspace.workspaceFolders; + workspaceUri = folders && folders.length > 0 ? folders[0].uri.fsPath : ''; + console.log(`Gravity Bridge: project "${projectName}" workspace="${workspaceUri}"`); + + // Bridge path + const config = vscode.workspace.getConfiguration('gravityBridge'); + const configPath = config.get('bridgePath'); + bridgePath = configPath || path.join(os.homedir(), '.gemini', 'antigravity', 'bridge'); + ensureBridgeDir(); + console.log(`Gravity Bridge: bridge path: ${bridgePath}`); + + // ── WebSocket Hub Connection ── + const hubUrl = process.env.GRAVITY_HUB_URL || config.get('hubUrl') || ''; + const regCode = process.env.GRAVITY_REGISTRATION_CODE || config.get('registrationCode') || ''; + const pcName = os.hostname(); + if (hubUrl) { + wsBridge = new WSBridgeClient(hubUrl, regCode, projectName, pcName, { + onResponse: (data: WSResponseData) => { + logToFile(`[WS-RESPONSE] ${data.request_id?.substring(0, 12)} approved=${data.approved} step_type=${data.step_type || '(none)'}`); + const approved = data.approved ?? true; + const stepType = data.step_type || ''; + + // ── diff_review: Accept all / Reject all (REGRESSION FIX) ── + // Previously only handled in processResponseFile (file-bridge path). + // WS path was missing this logic entirely, causing Accept All to fail. + if (stepType === 'diff_review') { + logToFile(`[WS-RESPONSE] diff_review detected — routing to handleDiffReviewResponse`); + handleDiffReviewResponse({ + request_id: data.request_id, + approved, + button_index: data.button_index, + step_type: stepType, + }) + .then(result => { + logToFile(`[WS-RESPONSE] diff_review result: ${result}`); + resetPendingState(); + }) + .catch(err => logToFile(`[WS-RESPONSE] diff_review error: ${err.message}`)); + return; + } + + // Normal approval — tryApprovalStrategies + const approvalCtx = getApprovalContext(); + logToFile(`[WS-RESPONSE] Triggering approval: approved=${approved} session=${approvalCtx.sessionId.substring(0, 8)} stepType=${stepType} stepIndex=${approvalCtx.stepIndex}`); + tryApprovalStrategies(approved, approvalCtx.sessionId, stepType, approvalCtx.stepIndex) + .then(result => { + logToFile(`[WS-RESPONSE] Approval result: ${result}`); + resetPendingState(); + }) + .catch(err => logToFile(`[WS-RESPONSE] Approval error: ${err.message}`)); + }, + onCommand: (data: WSCommandData) => { + logToFile(`[WS-CMD] ${data.text?.substring(0, 50)}`); + handleWSCommand({ + bridgePath, projectName, sdk, ls: sdk?.ls, autoApproveEnabled, logToFile, + onAutoApproveChanged: (enabled: boolean) => { autoApproveEnabled = enabled; }, + recentDiscordSentTexts, + }, data); + }, + onInstanceUpdate: (count, instances) => { + logToFile(`[WS-INSTANCE] ${count} active instances`); + }, + onConnected: (connId, instanceNum, token) => { + logToFile(`[WS] Connected: ${connId} instance=#${instanceNum}`); + statusBar.text = '$(check) Bridge WS'; + statusBar.tooltip = `Gravity Bridge: ${projectName} (WS #${instanceNum})`; + }, + onDisconnected: () => { + logToFile('[WS] Disconnected — using file fallback'); + statusBar.text = '$(warning) Bridge (WS ↓)'; + }, + onError: (err) => { + logToFile(`[WS-ERR] ${err}`); + }, + }, logToFile); + wsBridge.connect(); + logToFile(`[WS] Hub connection initiated: ${hubUrl}`); + } else { + logToFile('[WS] No GRAVITY_HUB_URL — WebSocket disabled, using file bridge only'); + } + + // ── Multi-project: no lock file, each project uses project_name-based filtering ── + // (active_project.lock removed — was blocking concurrent multi-project usage) + logToFile(`[INIT] project="${projectName}" pid=${process.pid} — multi-project mode (no lock)`); + + // Status bar + statusBar = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 100); + statusBar.text = '$(sync~spin) Bridge'; + statusBar.tooltip = `Gravity Bridge: ${projectName}`; + statusBar.show(); + context.subscriptions.push(statusBar); + + // Initialize SDK + const sdkReady = await initSDK(context); + + if (sdkReady) { + // ── Command Discovery Diagnostic ── + // Enumerate ALL antigravity.* commands to find correct approval command names + try { + const allCmds = await vscode.commands.getCommands(true); + const agCmds = allCmds.filter((c: string) => c.startsWith('antigravity.')); + logToFile(`[CMD-DISCOVERY] Total antigravity.* commands: ${agCmds.length}`); + // Log approval-related commands specifically + const approvalKeywords = ['accept', 'reject', 'approve', 'terminal', 'agent', 'cascade', 'step', 'run', 'command.']; + const relevantCmds = agCmds.filter((c: string) => + approvalKeywords.some(kw => c.toLowerCase().includes(kw)) + ); + logToFile(`[CMD-DISCOVERY] Approval-related commands (${relevantCmds.length}):`); + for (const cmd of relevantCmds) { + logToFile(`[CMD-DISCOVERY] → ${cmd}`); + } + // Also dump ALL commands for full reference + logToFile(`[CMD-DISCOVERY] ALL antigravity.* commands:`); + for (const cmd of agCmds) { + logToFile(`[CMD-DISCOVERY] ${cmd}`); + } + } catch (e: any) { + logToFile(`[CMD-DISCOVERY] error: ${e.message}`); + } + + // Initialize step probe (polling + response watcher) + initStepProbe({ + bridgePath, + projectName, + sdk, + wsBridge, + autoApproveEnabled, + activeSessionId, + sessionStalled, + lastPendingStepIndex, + stallProbed, + sawRunningAfterPending, + setClickTrigger: (action: 'approve' | 'reject') => { + const { setClickTrigger: setTrigger } = require('./http-bridge'); + setTrigger(action); + }, + logToFile, + workspaceUri, + diffReviewMetadata: new Map(), + recentDiscordSentTexts, + writeChatSnapshot, + writeChatSnapshotWithFiles, + } as BridgeContext); + // Start HTTP bridge, then setup observer + const httpBridgeCtx: HttpBridgeContext = { + bridgePath, projectName, activeSessionId, wsBridge, + sessionStalled, lastPendingStepIndex, logToFile, + }; + const bridgePort = await startHttpBridge(httpBridgeCtx, sdk); + if (bridgePort) { + await setupApprovalObserver(sdk, bridgePort, logToFile); + } else { + logToFile('[OBSERVER] HTTP bridge failed — skipping observer setup'); + } + statusBar.text = '$(check) Bridge'; + statusBar.tooltip = `Gravity Bridge: ${projectName} (POLL + Observer active)`; + + // Register SDK-powered commands + context.subscriptions.push( + vscode.commands.registerCommand('gravityBridge.approve', async () => { + try { + await sdk.cascade.acceptStep(); + vscode.window.showInformationMessage('Gravity Bridge: Step approved'); + } catch (e: any) { + vscode.window.showErrorMessage(`Approve failed: ${e.message}`); + } + }), + vscode.commands.registerCommand('gravityBridge.reject', async () => { + try { + await sdk.cascade.rejectStep(); + vscode.window.showInformationMessage('Gravity Bridge: Step rejected'); + } catch (e: any) { + vscode.window.showErrorMessage(`Reject failed: ${e.message}`); + } + }) + ); + } else { + statusBar.text = '$(warning) Bridge (no SDK)'; + console.log('Gravity Bridge: SDK not available, file-based mode only'); + } + + // Watch commands directory + watchCommandsDir({ + bridgePath, projectName, sdk, ls: sdk?.ls, autoApproveEnabled, logToFile, + onAutoApproveChanged: (enabled: boolean) => { autoApproveEnabled = enabled; }, + recentDiscordSentTexts, + }); + + // Response watcher is now initialized by initStepProbe() above + // Register basic commands + context.subscriptions.push( + vscode.commands.registerCommand('gravityBridge.start', () => { + isActive = true; + statusBar.text = sdkReady ? '$(check) Bridge SDK' : '$(sync~spin) Bridge'; + vscode.window.showInformationMessage(`Gravity Bridge started for "${projectName}"`); + }), + vscode.commands.registerCommand('gravityBridge.stop', () => { + isActive = false; + // SDK monitor is disabled, no need to stop + statusBar.text = '$(circle-slash) Bridge OFF'; + vscode.window.showInformationMessage('Gravity Bridge stopped'); + }), + vscode.commands.registerCommand('gravityBridge.connect', async () => { + if (!sdk) { + vscode.window.showErrorMessage('SDK not initialized'); + return; + } + try { + const sessions = await sdk.cascade.getSessions(); + const items = sessions.map((s: any) => ({ + label: s.title || 'Untitled', + description: `step ${s.stepCount} • ${s.id?.substring(0, 8)}`, + sessionId: s.id, + })); + const pick = await vscode.window.showQuickPick(items, { + placeHolder: 'Select a conversation to connect' + }); + if (pick) { + await sdk.cascade.focusSession((pick as any).sessionId); + vscode.window.showInformationMessage(`Connected to: ${(pick as any).label}`); + } + } catch (e: any) { + vscode.window.showErrorMessage(`Connect failed: ${e.message}`); + } + }) + ); + + // Cleanup + context.subscriptions.push({ + dispose: () => { + if (sdk) { try { sdk.dispose(); } catch { } } + if (watcher) { watcher.close(); } + disposeCommandsWatcher(); + } + }); + + console.log('Gravity Bridge: ✅ activated'); + isActive = true; +} + +export function deactivate() { + // Disconnect WebSocket + if (wsBridge) { + wsBridge.disconnect(); + wsBridge = null; + } + // Clean up stale lock file if it exists (legacy cleanup) + try { + const lockFile = path.join(bridgePath, 'active_project.lock'); + if (fs.existsSync(lockFile)) { + const lockData = JSON.parse(fs.readFileSync(lockFile, 'utf-8')); + if (lockData.pid === process.pid) { + fs.unlinkSync(lockFile); + } + } + } catch { } + if (sdk) { + try { sdk.dispose(); } catch { } + } +}