feat: add gateway lock, shell completion, and tailscale serve (Tier 4 features 1-3)
This commit is contained in:
@@ -11,6 +11,7 @@ import type { AuthConfig } from './auth.js';
|
||||
import {
|
||||
parseMessage,
|
||||
makeError,
|
||||
makeResponse,
|
||||
ErrorCode,
|
||||
type OutboundMessage,
|
||||
} from './protocol.js';
|
||||
@@ -39,6 +40,8 @@ export interface GatewayServerConfig {
|
||||
toolExecutor: ToolExecutor;
|
||||
version?: string;
|
||||
auth?: AuthConfig;
|
||||
/** When true, only one WebSocket client can be connected at a time. */
|
||||
lock?: boolean;
|
||||
/** Whether to apply token auth to HTTP requests too (default: true when token is set). */
|
||||
authHttp?: boolean;
|
||||
uiDir?: string;
|
||||
@@ -159,6 +162,15 @@ export class GatewayServer {
|
||||
this.handleConnection(ws, authResult.identity);
|
||||
});
|
||||
|
||||
// Register system.lock handler (needs access to connectionMap)
|
||||
this.router.register('system.lock', async (request) => {
|
||||
return makeResponse(request.id, {
|
||||
locked: this.config.lock ?? false,
|
||||
activeClients: this.connectionMap.size,
|
||||
maxClients: this.config.lock ? 1 : null,
|
||||
});
|
||||
});
|
||||
|
||||
this.httpServer.listen(port, host, () => {
|
||||
console.log(`Gateway server listening on ${host}:${port}`);
|
||||
resolve();
|
||||
@@ -199,6 +211,12 @@ export class GatewayServer {
|
||||
}
|
||||
|
||||
private handleConnection(ws: WebSocket, identity?: string): void {
|
||||
// Gateway lock — reject if another client is already connected
|
||||
if (this.config.lock && this.connectionMap.size > 0) {
|
||||
ws.close(4003, 'Gateway locked — another client is already connected');
|
||||
return;
|
||||
}
|
||||
|
||||
const connectionId = randomUUID();
|
||||
this.sessionBridge.connect(connectionId);
|
||||
this.connectionMap.set(ws, connectionId);
|
||||
|
||||
Reference in New Issue
Block a user