import fs from "node:fs"; import type { Command } from "commander"; import { CONFIG_PATH_CLAWDIS, loadConfig } from "../config/config.js"; import { callGateway, randomIdempotencyKey } from "../gateway/call.js"; import { startGatewayServer } from "../gateway/server.js"; import { type GatewayWsLogStyle, setGatewayWsLogStyle, } from "../gateway/ws-logging.js"; import { info, setVerbose } from "../globals.js"; import { GatewayLockError } from "../infra/gateway-lock.js"; import { defaultRuntime } from "../runtime.js"; import { createDefaultDeps } from "./deps.js"; import { forceFreePortAndWait } from "./ports.js"; type GatewayRpcOpts = { url?: string; token?: string; timeout?: string; expectFinal?: boolean; }; const gatewayCallOpts = (cmd: Command) => cmd .option("--url ", "Gateway WebSocket URL", "ws://127.0.0.1:18789") .option("--token ", "Gateway token (if required)") .option("--timeout ", "Timeout in ms", "10000") .option("--expect-final", "Wait for final response (agent)", false); const callGatewayCli = async ( method: string, opts: GatewayRpcOpts, params?: unknown, ) => callGateway({ url: opts.url, token: opts.token, method, params, expectFinal: Boolean(opts.expectFinal), timeoutMs: Number(opts.timeout ?? 10_000), clientName: "cli", mode: "cli", }); export function registerGatewayCli(program: Command) { const gateway = program .command("gateway") .description("Run the WebSocket Gateway") .option("--port ", "Port for the gateway WebSocket", "18789") .option( "--bind ", 'Bind mode ("loopback"|"tailnet"|"lan"|"auto"). Defaults to config gateway.bind (or loopback).', ) .option( "--token ", "Shared token required in connect.params.auth.token (default: CLAWDIS_GATEWAY_TOKEN env if set)", ) .option( "--allow-unconfigured", "Allow gateway start without gateway.mode=local in config", false, ) .option( "--force", "Kill any existing listener on the target port before starting", false, ) .option("--verbose", "Verbose logging to stdout/stderr", false) .option( "--ws-log