@vibebrowser/mcp 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -85
- package/dist/cli.js +7 -9
- package/dist/cli.js.map +1 -1
- package/dist/connection.d.ts +32 -12
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +153 -74
- package/dist/connection.js.map +1 -1
- package/dist/index.js +3 -23
- package/dist/index.js.map +1 -1
- package/dist/relay-daemon.d.ts +8 -0
- package/dist/relay-daemon.d.ts.map +1 -0
- package/dist/relay-daemon.js +13 -0
- package/dist/relay-daemon.js.map +1 -0
- package/dist/relay.d.ts +86 -0
- package/dist/relay.d.ts.map +1 -0
- package/dist/relay.js +381 -0
- package/dist/relay.js.map +1 -0
- package/dist/server.js +11 -16
- package/dist/server.js.map +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +2 -5
- package/dist/types.js.map +1 -1
- package/package.json +21 -8
package/dist/connection.js
CHANGED
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
|
-
* Vibe MCP Server -
|
|
2
|
+
* Vibe MCP Server - Relay Connection
|
|
4
3
|
*
|
|
5
|
-
*
|
|
4
|
+
* Connects to the relay server as a WebSocket client.
|
|
5
|
+
* The relay handles the actual extension connection.
|
|
6
6
|
*/
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
import WebSocket from 'ws';
|
|
8
|
+
import { EventEmitter } from 'events';
|
|
9
|
+
import { spawn } from 'child_process';
|
|
10
|
+
import { dirname, join } from 'path';
|
|
11
|
+
import { isRelayRunning, AGENT_PORT } from './relay.js';
|
|
12
12
|
const NO_CONNECTION_MESSAGE = `No connection to Vibe extension. Please:
|
|
13
13
|
1. Install the Vibe AI Browser extension from https://vibebrowser.app
|
|
14
14
|
2. Click the Vibe extension icon in Chrome
|
|
15
|
-
3.
|
|
15
|
+
3. Enable "MCP External Control" in Settings`;
|
|
16
|
+
const RELAY_CONNECT_TIMEOUT = 10000;
|
|
17
|
+
const RELAY_RECONNECT_DELAY = 2000;
|
|
16
18
|
/**
|
|
17
|
-
*
|
|
19
|
+
* Relay connection manager
|
|
20
|
+
*
|
|
21
|
+
* Connects to the relay server instead of directly to the extension.
|
|
18
22
|
*/
|
|
19
|
-
class ExtensionConnection extends
|
|
20
|
-
wss = null;
|
|
23
|
+
export class ExtensionConnection extends EventEmitter {
|
|
21
24
|
ws = null;
|
|
22
25
|
status = 'disconnected';
|
|
23
26
|
pendingRequests = new Map();
|
|
@@ -26,27 +29,108 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
26
29
|
debug;
|
|
27
30
|
tools = [];
|
|
28
31
|
reconnectTimer = null;
|
|
29
|
-
|
|
32
|
+
extensionConnected = false;
|
|
33
|
+
constructor(port = AGENT_PORT, debug = false) {
|
|
30
34
|
super();
|
|
31
35
|
this.port = port;
|
|
32
36
|
this.debug = debug;
|
|
33
37
|
}
|
|
34
38
|
/**
|
|
35
|
-
* Start
|
|
39
|
+
* Start connection to relay server
|
|
40
|
+
* Spawns relay daemon if not already running
|
|
36
41
|
*/
|
|
37
42
|
async start() {
|
|
43
|
+
// Check if relay is already running
|
|
44
|
+
if (!isRelayRunning()) {
|
|
45
|
+
this.log('Starting relay daemon...');
|
|
46
|
+
await this.spawnRelay();
|
|
47
|
+
// Wait for relay to start
|
|
48
|
+
await this.waitForRelay();
|
|
49
|
+
}
|
|
50
|
+
// Connect to relay
|
|
51
|
+
await this.connectToRelay();
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Spawn relay daemon as detached process
|
|
55
|
+
*/
|
|
56
|
+
async spawnRelay() {
|
|
57
|
+
// Use __dirname equivalent for ESM
|
|
58
|
+
const relayScript = join(dirname(new URL(import.meta.url).pathname), 'relay-daemon.js');
|
|
59
|
+
const child = spawn(process.execPath, [relayScript, this.debug ? '--debug' : ''], {
|
|
60
|
+
detached: true,
|
|
61
|
+
stdio: 'ignore',
|
|
62
|
+
});
|
|
63
|
+
child.unref();
|
|
64
|
+
this.log('Relay daemon spawned');
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Wait for relay to become available
|
|
68
|
+
*/
|
|
69
|
+
async waitForRelay() {
|
|
70
|
+
const startTime = Date.now();
|
|
71
|
+
while (Date.now() - startTime < RELAY_CONNECT_TIMEOUT) {
|
|
72
|
+
try {
|
|
73
|
+
// Try to connect
|
|
74
|
+
await new Promise((resolve, reject) => {
|
|
75
|
+
const ws = new WebSocket(`ws://127.0.0.1:${AGENT_PORT}`);
|
|
76
|
+
const timeout = setTimeout(() => {
|
|
77
|
+
ws.close();
|
|
78
|
+
reject(new Error('Timeout'));
|
|
79
|
+
}, 1000);
|
|
80
|
+
ws.on('open', () => {
|
|
81
|
+
clearTimeout(timeout);
|
|
82
|
+
ws.close();
|
|
83
|
+
resolve();
|
|
84
|
+
});
|
|
85
|
+
ws.on('error', () => {
|
|
86
|
+
clearTimeout(timeout);
|
|
87
|
+
reject(new Error('Connection failed'));
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
this.log('Relay is ready');
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Relay not ready yet, wait and retry
|
|
95
|
+
await new Promise(r => setTimeout(r, 200));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
throw new Error('Relay failed to start within timeout');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Connect to the relay server
|
|
102
|
+
*/
|
|
103
|
+
async connectToRelay() {
|
|
38
104
|
return new Promise((resolve, reject) => {
|
|
105
|
+
const url = `ws://127.0.0.1:${AGENT_PORT}`;
|
|
106
|
+
this.log(`Connecting to relay at ${url}...`);
|
|
39
107
|
try {
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
this.log(
|
|
108
|
+
this.ws = new WebSocket(url);
|
|
109
|
+
this.ws.on('open', () => {
|
|
110
|
+
this.log('Connected to relay');
|
|
111
|
+
this.status = 'connected';
|
|
112
|
+
this.emit('connected');
|
|
43
113
|
resolve();
|
|
44
114
|
});
|
|
45
|
-
this.
|
|
46
|
-
|
|
115
|
+
this.ws.on('message', (data) => {
|
|
116
|
+
try {
|
|
117
|
+
const message = JSON.parse(data.toString());
|
|
118
|
+
this.handleMessage(message);
|
|
119
|
+
}
|
|
120
|
+
catch (error) {
|
|
121
|
+
this.log(`Failed to parse message: ${error}`);
|
|
122
|
+
}
|
|
47
123
|
});
|
|
48
|
-
this.
|
|
49
|
-
this.log(
|
|
124
|
+
this.ws.on('close', () => {
|
|
125
|
+
this.log('Disconnected from relay');
|
|
126
|
+
this.ws = null;
|
|
127
|
+
this.status = 'disconnected';
|
|
128
|
+
this.emit('disconnected');
|
|
129
|
+
// Schedule reconnect
|
|
130
|
+
this.scheduleReconnect();
|
|
131
|
+
});
|
|
132
|
+
this.ws.on('error', (error) => {
|
|
133
|
+
this.log(`WebSocket error: ${error.message}`);
|
|
50
134
|
reject(error);
|
|
51
135
|
});
|
|
52
136
|
}
|
|
@@ -56,7 +140,25 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
56
140
|
});
|
|
57
141
|
}
|
|
58
142
|
/**
|
|
59
|
-
*
|
|
143
|
+
* Schedule reconnection attempt
|
|
144
|
+
*/
|
|
145
|
+
scheduleReconnect() {
|
|
146
|
+
if (this.reconnectTimer) {
|
|
147
|
+
clearTimeout(this.reconnectTimer);
|
|
148
|
+
}
|
|
149
|
+
this.reconnectTimer = setTimeout(async () => {
|
|
150
|
+
this.log('Attempting to reconnect to relay...');
|
|
151
|
+
try {
|
|
152
|
+
await this.connectToRelay();
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
this.log(`Reconnect failed: ${error}`);
|
|
156
|
+
this.scheduleReconnect();
|
|
157
|
+
}
|
|
158
|
+
}, RELAY_RECONNECT_DELAY);
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Stop the connection
|
|
60
162
|
*/
|
|
61
163
|
async stop() {
|
|
62
164
|
if (this.reconnectTimer) {
|
|
@@ -66,64 +168,32 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
66
168
|
// Reject all pending requests
|
|
67
169
|
for (const [id, request] of this.pendingRequests) {
|
|
68
170
|
clearTimeout(request.timeout);
|
|
69
|
-
request.reject(new Error('
|
|
171
|
+
request.reject(new Error('Connection closed'));
|
|
70
172
|
}
|
|
71
173
|
this.pendingRequests.clear();
|
|
72
174
|
if (this.ws) {
|
|
73
175
|
this.ws.close();
|
|
74
176
|
this.ws = null;
|
|
75
177
|
}
|
|
76
|
-
|
|
77
|
-
return new Promise((resolve) => {
|
|
78
|
-
this.wss.close(() => {
|
|
79
|
-
this.wss = null;
|
|
80
|
-
this.status = 'disconnected';
|
|
81
|
-
resolve();
|
|
82
|
-
});
|
|
83
|
-
});
|
|
84
|
-
}
|
|
178
|
+
this.status = 'disconnected';
|
|
85
179
|
}
|
|
86
180
|
/**
|
|
87
|
-
* Handle
|
|
88
|
-
*/
|
|
89
|
-
handleConnection(ws) {
|
|
90
|
-
this.log('Extension connected');
|
|
91
|
-
// Close previous connection if any
|
|
92
|
-
if (this.ws) {
|
|
93
|
-
this.ws.close();
|
|
94
|
-
}
|
|
95
|
-
this.ws = ws;
|
|
96
|
-
this.status = 'connected';
|
|
97
|
-
this.emit('connected');
|
|
98
|
-
ws.on('message', (data) => {
|
|
99
|
-
try {
|
|
100
|
-
const message = JSON.parse(data.toString());
|
|
101
|
-
this.handleMessage(message);
|
|
102
|
-
}
|
|
103
|
-
catch (error) {
|
|
104
|
-
this.log(`Failed to parse message: ${error}`);
|
|
105
|
-
}
|
|
106
|
-
});
|
|
107
|
-
ws.on('close', () => {
|
|
108
|
-
this.log('Extension disconnected');
|
|
109
|
-
this.ws = null;
|
|
110
|
-
this.status = 'disconnected';
|
|
111
|
-
this.tools = [];
|
|
112
|
-
this.emit('disconnected');
|
|
113
|
-
});
|
|
114
|
-
ws.on('error', (error) => {
|
|
115
|
-
this.log(`WebSocket error: ${error.message}`);
|
|
116
|
-
});
|
|
117
|
-
// Request available tools
|
|
118
|
-
this.refreshTools().catch((error) => {
|
|
119
|
-
this.log(`Failed to get tools: ${error.message}`);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Handle message from extension
|
|
181
|
+
* Handle message from relay
|
|
124
182
|
*/
|
|
125
183
|
handleMessage(message) {
|
|
126
184
|
this.log(`Received: ${message.type}`);
|
|
185
|
+
// Handle extension status updates
|
|
186
|
+
if (message.type === 'extension_status') {
|
|
187
|
+
this.extensionConnected = message.connected ?? false;
|
|
188
|
+
this.emit('extension_status', this.extensionConnected);
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
if (message.type === 'extension_disconnected') {
|
|
192
|
+
this.extensionConnected = false;
|
|
193
|
+
this.tools = [];
|
|
194
|
+
this.emit('extension_disconnected');
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
127
197
|
// Handle responses to pending requests
|
|
128
198
|
if (message.requestId) {
|
|
129
199
|
const pending = this.pendingRequests.get(message.requestId);
|
|
@@ -143,21 +213,25 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
143
213
|
switch (message.type) {
|
|
144
214
|
case 'tools_list':
|
|
145
215
|
this.tools = message.data;
|
|
216
|
+
this.extensionConnected = true;
|
|
146
217
|
this.emit('tools_updated', this.tools);
|
|
147
218
|
break;
|
|
148
219
|
case 'snapshot':
|
|
149
220
|
this.emit('snapshot', message.data);
|
|
150
221
|
break;
|
|
151
222
|
case 'error':
|
|
152
|
-
this.log(`
|
|
223
|
+
this.log(`Error: ${message.error}`);
|
|
153
224
|
break;
|
|
154
225
|
}
|
|
155
226
|
}
|
|
156
227
|
/**
|
|
157
|
-
* Send a message to the extension and wait for response
|
|
228
|
+
* Send a message to the extension via relay and wait for response
|
|
158
229
|
*/
|
|
159
230
|
async sendRequest(type, data, timeoutMs = 30000) {
|
|
160
231
|
if (!this.ws || this.status !== 'connected') {
|
|
232
|
+
throw new Error('Not connected to relay');
|
|
233
|
+
}
|
|
234
|
+
if (!this.extensionConnected) {
|
|
161
235
|
throw new Error(NO_CONNECTION_MESSAGE);
|
|
162
236
|
}
|
|
163
237
|
const requestId = `req_${++this.requestIdCounter}`;
|
|
@@ -203,10 +277,10 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
203
277
|
return this.sendRequest('get_snapshot');
|
|
204
278
|
}
|
|
205
279
|
/**
|
|
206
|
-
* Check if extension is connected
|
|
280
|
+
* Check if extension is connected (via relay)
|
|
207
281
|
*/
|
|
208
282
|
isConnected() {
|
|
209
|
-
return this.status === 'connected';
|
|
283
|
+
return this.status === 'connected' && this.extensionConnected;
|
|
210
284
|
}
|
|
211
285
|
/**
|
|
212
286
|
* Get connection status
|
|
@@ -214,6 +288,12 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
214
288
|
getStatus() {
|
|
215
289
|
return this.status;
|
|
216
290
|
}
|
|
291
|
+
/**
|
|
292
|
+
* Check if extension is connected to relay
|
|
293
|
+
*/
|
|
294
|
+
isExtensionConnected() {
|
|
295
|
+
return this.extensionConnected;
|
|
296
|
+
}
|
|
217
297
|
/**
|
|
218
298
|
* Log message if debug is enabled
|
|
219
299
|
*/
|
|
@@ -223,5 +303,4 @@ class ExtensionConnection extends events_1.EventEmitter {
|
|
|
223
303
|
}
|
|
224
304
|
}
|
|
225
305
|
}
|
|
226
|
-
exports.ExtensionConnection = ExtensionConnection;
|
|
227
306
|
//# sourceMappingURL=connection.js.map
|
package/dist/connection.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,27 +1,7 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Vibe MCP Server - Main Exports
|
|
4
3
|
*/
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
-
}
|
|
11
|
-
Object.defineProperty(o, k2, desc);
|
|
12
|
-
}) : (function(o, m, k, k2) {
|
|
13
|
-
if (k2 === undefined) k2 = k;
|
|
14
|
-
o[k2] = m[k];
|
|
15
|
-
}));
|
|
16
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
17
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
18
|
-
};
|
|
19
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.ExtensionConnection = exports.createServer = exports.VibeMcpServer = void 0;
|
|
21
|
-
var server_js_1 = require("./server.js");
|
|
22
|
-
Object.defineProperty(exports, "VibeMcpServer", { enumerable: true, get: function () { return server_js_1.VibeMcpServer; } });
|
|
23
|
-
Object.defineProperty(exports, "createServer", { enumerable: true, get: function () { return server_js_1.createServer; } });
|
|
24
|
-
var connection_js_1 = require("./connection.js");
|
|
25
|
-
Object.defineProperty(exports, "ExtensionConnection", { enumerable: true, get: function () { return connection_js_1.ExtensionConnection; } });
|
|
26
|
-
__exportStar(require("./types.js"), exports);
|
|
4
|
+
export { VibeMcpServer, createServer } from './server.js';
|
|
5
|
+
export { ExtensionConnection } from './connection.js';
|
|
6
|
+
export * from './types.js';
|
|
27
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,cAAc,YAAY,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-daemon.d.ts","sourceRoot":"","sources":["../src/relay-daemon.ts"],"names":[],"mappings":";AACA;;;;GAIG"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Vibe MCP Relay Daemon Entry Point
|
|
4
|
+
*
|
|
5
|
+
* This script is spawned as a detached daemon process.
|
|
6
|
+
*/
|
|
7
|
+
import { startRelayDaemon } from './relay.js';
|
|
8
|
+
const debug = process.argv.includes('--debug');
|
|
9
|
+
startRelayDaemon(debug).catch((error) => {
|
|
10
|
+
console.error(`[relay] Fatal error: ${error.message}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
});
|
|
13
|
+
//# sourceMappingURL=relay-daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay-daemon.js","sourceRoot":"","sources":["../src/relay-daemon.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;AAC/C,gBAAgB,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IACtC,OAAO,CAAC,KAAK,CAAC,wBAAwB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/relay.d.ts
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vibe MCP Relay Server
|
|
3
|
+
*
|
|
4
|
+
* Daemon that multiplexes multiple MCP agents to a single browser extension.
|
|
5
|
+
* - Listens on port 19989 for extension connection (one client)
|
|
6
|
+
* - Listens on port 19988 for MCP agent connections (multiple clients)
|
|
7
|
+
* - Routes tool calls from agents to extension, responses back to agents
|
|
8
|
+
*/
|
|
9
|
+
import { EventEmitter } from 'events';
|
|
10
|
+
export declare const EXTENSION_PORT = 19989;
|
|
11
|
+
export declare const AGENT_PORT = 19988;
|
|
12
|
+
/**
|
|
13
|
+
* Vibe MCP Relay Server
|
|
14
|
+
*/
|
|
15
|
+
export declare class RelayServer extends EventEmitter {
|
|
16
|
+
private extensionWss;
|
|
17
|
+
private agentWss;
|
|
18
|
+
private extensionWs;
|
|
19
|
+
private agents;
|
|
20
|
+
private pendingRequests;
|
|
21
|
+
private tools;
|
|
22
|
+
private requestIdCounter;
|
|
23
|
+
private debug;
|
|
24
|
+
constructor(debug?: boolean);
|
|
25
|
+
/**
|
|
26
|
+
* Start the relay server
|
|
27
|
+
*/
|
|
28
|
+
start(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Start WebSocket server for extension connection
|
|
31
|
+
*/
|
|
32
|
+
private startExtensionServer;
|
|
33
|
+
/**
|
|
34
|
+
* Start WebSocket server for agent connections
|
|
35
|
+
*/
|
|
36
|
+
private startAgentServer;
|
|
37
|
+
/**
|
|
38
|
+
* Handle extension connection
|
|
39
|
+
*/
|
|
40
|
+
private handleExtensionConnection;
|
|
41
|
+
/**
|
|
42
|
+
* Handle agent connection
|
|
43
|
+
*/
|
|
44
|
+
private handleAgentConnection;
|
|
45
|
+
/**
|
|
46
|
+
* Handle message from extension
|
|
47
|
+
*/
|
|
48
|
+
private handleExtensionMessage;
|
|
49
|
+
/**
|
|
50
|
+
* Handle message from an agent
|
|
51
|
+
*/
|
|
52
|
+
private handleAgentMessage;
|
|
53
|
+
/**
|
|
54
|
+
* Request tools list from extension
|
|
55
|
+
*/
|
|
56
|
+
private requestToolsFromExtension;
|
|
57
|
+
/**
|
|
58
|
+
* Broadcast message to all connected agents
|
|
59
|
+
*/
|
|
60
|
+
private broadcastToAgents;
|
|
61
|
+
/**
|
|
62
|
+
* Shutdown the relay server
|
|
63
|
+
*/
|
|
64
|
+
private shutdown;
|
|
65
|
+
/**
|
|
66
|
+
* Log message
|
|
67
|
+
*/
|
|
68
|
+
private log;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Check if relay is already running
|
|
72
|
+
*/
|
|
73
|
+
export declare function isRelayRunning(): boolean;
|
|
74
|
+
/**
|
|
75
|
+
* Get relay PID if running
|
|
76
|
+
*/
|
|
77
|
+
export declare function getRelayPid(): number | null;
|
|
78
|
+
/**
|
|
79
|
+
* Start relay as a detached daemon
|
|
80
|
+
*/
|
|
81
|
+
export declare function spawnRelayDaemon(debug?: boolean): void;
|
|
82
|
+
/**
|
|
83
|
+
* Main entry point for relay daemon
|
|
84
|
+
*/
|
|
85
|
+
export declare function startRelayDaemon(debug?: boolean): Promise<void>;
|
|
86
|
+
//# sourceMappingURL=relay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relay.d.ts","sourceRoot":"","sources":["../src/relay.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAGtC,eAAO,MAAM,cAAc,QAAQ,CAAC;AACpC,eAAO,MAAM,UAAU,QAAQ,CAAC;AA8ChC;;GAEG;AACH,qBAAa,WAAY,SAAQ,YAAY;IAC3C,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,MAAM,CAA2C;IACzD,OAAO,CAAC,eAAe,CAA0C;IACjE,OAAO,CAAC,KAAK,CAAiB;IAC9B,OAAO,CAAC,gBAAgB,CAAK;IAC7B,OAAO,CAAC,KAAK,CAAU;gBAEX,KAAK,GAAE,OAAe;IAKlC;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAqB5B;;OAEG;YACW,oBAAoB;IAoBlC;;OAEG;YACW,gBAAgB;IAoB9B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAoCjC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiD7B;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiC9B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAgC1B;;OAEG;IACH,OAAO,CAAC,yBAAyB;IAUjC;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;OAEG;YACW,QAAQ;IA0CtB;;OAEG;IACH,OAAO,CAAC,GAAG;CAgBZ;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,OAAO,CAmBxC;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,MAAM,GAAG,IAAI,CAY3C;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,GAAE,OAAe,GAAG,IAAI,CAe7D;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,KAAK,GAAE,OAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CAM5E"}
|