refactor(bridge): migrate gravity bridge to pure websocket gateway architecture, deleting legacy local file scanners and dependencies
This commit is contained in:
@@ -13,6 +13,8 @@ import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { WSBridgeClient } from './ws-client';
|
||||
|
||||
let lastFilePermissionTime = 0;
|
||||
|
||||
// ─── Context interface (shared state from extension.ts) ───
|
||||
|
||||
export interface HttpBridgeContext {
|
||||
@@ -127,7 +129,7 @@ export function startHttpBridge(ctx: HttpBridgeContext, sdk: any): Promise<numbe
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
fs.writeFileSync(path.join(ctx.bridgePath, 'dump_html.json'), dumpBody, 'utf-8');
|
||||
} catch(e) {}
|
||||
} catch (e) { }
|
||||
res.writeHead(200); res.end('ok');
|
||||
});
|
||||
return;
|
||||
@@ -140,9 +142,9 @@ export function startHttpBridge(ctx: HttpBridgeContext, sdk: any): Promise<numbe
|
||||
try {
|
||||
const params = JSON.parse(rpcBody);
|
||||
const result = await sdk.ls.rawRPC(params.method, params.args || {});
|
||||
res.writeHead(200, {'Content-Type': 'application/json'});
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(typeof result === 'string' ? result : JSON.stringify(result));
|
||||
} catch(e: any) {
|
||||
} catch (e: any) {
|
||||
res.writeHead(500); res.end(e.message);
|
||||
}
|
||||
});
|
||||
@@ -246,9 +248,6 @@ function _handlePending(req: any, res: any, ctx: HttpBridgeContext) {
|
||||
}
|
||||
|
||||
const rid = data.request_id || Date.now().toString();
|
||||
// Write pending file for Discord bot
|
||||
const pendingDir = path.join(ctx.bridgePath, 'pending');
|
||||
if (!fs.existsSync(pendingDir)) fs.mkdirSync(pendingDir, { recursive: true });
|
||||
const pending: Record<string, any> = {
|
||||
...data,
|
||||
request_id: rid,
|
||||
@@ -265,22 +264,13 @@ function _handlePending(req: any, res: any, ctx: HttpBridgeContext) {
|
||||
if (cmdLower.includes('allow') && !pending.buttons) {
|
||||
// Dedup: skip if another file_permission pending was created within 10s
|
||||
const nowMs = Date.now();
|
||||
try {
|
||||
const existingFiles = fs.readdirSync(pendingDir).filter((f: string) => f.endsWith('.json'));
|
||||
for (const ef of existingFiles) {
|
||||
const existing = JSON.parse(fs.readFileSync(path.join(pendingDir, ef), 'utf-8'));
|
||||
if (existing.step_type === 'file_permission' && existing.status === 'pending'
|
||||
&& existing.project_name === ctx.projectName) {
|
||||
const age = nowMs - (existing.timestamp * 1000);
|
||||
if (age < 10_000 && age >= 0) {
|
||||
ctx.logToFile(`[HTTP] filtered duplicate file_permission (${age}ms old): ${ef}`);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ ok: false, filtered: true, reason: 'dedup_file_permission' }));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch { }
|
||||
if (nowMs - lastFilePermissionTime < 10000) {
|
||||
ctx.logToFile(`[HTTP] filtered duplicate file_permission (${nowMs - lastFilePermissionTime}ms old)`);
|
||||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||||
res.end(JSON.stringify({ ok: false, filtered: true, reason: 'dedup_file_permission' }));
|
||||
return;
|
||||
}
|
||||
lastFilePermissionTime = nowMs;
|
||||
|
||||
pending.buttons = [
|
||||
{ text: 'Allow Once', index: 0 },
|
||||
@@ -292,8 +282,7 @@ function _handlePending(req: any, res: any, ctx: HttpBridgeContext) {
|
||||
const rawDesc = (data.description || data.command || '').replace(/Deny|Allow Once|Allow This Conversation/gi, '').trim();
|
||||
pending.command = `파일 접근 권한${rawDesc ? ': ' + rawDesc : ''}`;
|
||||
}
|
||||
fs.writeFileSync(path.join(pendingDir, `${rid}.json`), JSON.stringify(pending, null, 2));
|
||||
// WS dual-write
|
||||
// WS dispatch
|
||||
if (ctx.wsBridge && ctx.wsBridge.isConnected()) {
|
||||
ctx.wsBridge.sendPending({
|
||||
request_id: rid,
|
||||
|
||||
Reference in New Issue
Block a user