feat(gateway): allow webchat port override
This commit is contained in:
@@ -214,6 +214,10 @@ Examples:
|
|||||||
.command("gateway")
|
.command("gateway")
|
||||||
.description("Run the WebSocket Gateway")
|
.description("Run the WebSocket Gateway")
|
||||||
.option("--port <port>", "Port for the gateway WebSocket", "18789")
|
.option("--port <port>", "Port for the gateway WebSocket", "18789")
|
||||||
|
.option(
|
||||||
|
"--webchat-port <port>",
|
||||||
|
"Port for the loopback WebChat HTTP server (default 18788)",
|
||||||
|
)
|
||||||
.option(
|
.option(
|
||||||
"--token <token>",
|
"--token <token>",
|
||||||
"Shared token required in hello.auth.token (default: CLAWDIS_GATEWAY_TOKEN env if set)",
|
"Shared token required in hello.auth.token (default: CLAWDIS_GATEWAY_TOKEN env if set)",
|
||||||
@@ -231,6 +235,13 @@ Examples:
|
|||||||
defaultRuntime.error("Invalid port");
|
defaultRuntime.error("Invalid port");
|
||||||
defaultRuntime.exit(1);
|
defaultRuntime.exit(1);
|
||||||
}
|
}
|
||||||
|
const webchatPort = opts.webchatPort
|
||||||
|
? Number.parseInt(String(opts.webchatPort), 10)
|
||||||
|
: undefined;
|
||||||
|
if (webchatPort !== undefined && (Number.isNaN(webchatPort) || webchatPort <= 0)) {
|
||||||
|
defaultRuntime.error("Invalid webchat port");
|
||||||
|
defaultRuntime.exit(1);
|
||||||
|
}
|
||||||
if (opts.force) {
|
if (opts.force) {
|
||||||
try {
|
try {
|
||||||
const killed = forceFreePort(port);
|
const killed = forceFreePort(port);
|
||||||
@@ -256,7 +267,7 @@ Examples:
|
|||||||
process.env.CLAWDIS_GATEWAY_TOKEN = String(opts.token);
|
process.env.CLAWDIS_GATEWAY_TOKEN = String(opts.token);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
await startGatewayServer(port);
|
await startGatewayServer(port, { webchatPort });
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err instanceof GatewayLockError) {
|
if (err instanceof GatewayLockError) {
|
||||||
defaultRuntime.error(`Gateway failed to start: ${err.message}`);
|
defaultRuntime.error(`Gateway failed to start: ${err.message}`);
|
||||||
|
|||||||
@@ -22,6 +22,12 @@ export type HealthSummary = {
|
|||||||
web: {
|
web: {
|
||||||
linked: boolean;
|
linked: boolean;
|
||||||
authAgeMs: number | null;
|
authAgeMs: number | null;
|
||||||
|
connect?: {
|
||||||
|
ok: boolean;
|
||||||
|
status?: number | null;
|
||||||
|
error?: string | null;
|
||||||
|
elapsedMs?: number | null;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
telegram: {
|
telegram: {
|
||||||
configured: boolean;
|
configured: boolean;
|
||||||
|
|||||||
@@ -236,7 +236,7 @@ function formatError(err: unknown): string {
|
|||||||
async function refreshHealthSnapshot(opts?: { probe?: boolean }) {
|
async function refreshHealthSnapshot(opts?: { probe?: boolean }) {
|
||||||
if (!healthRefresh) {
|
if (!healthRefresh) {
|
||||||
healthRefresh = (async () => {
|
healthRefresh = (async () => {
|
||||||
const snap = await getHealthSnapshot(undefined, opts);
|
const snap = await getHealthSnapshot(undefined);
|
||||||
healthCache = snap;
|
healthCache = snap;
|
||||||
healthVersion += 1;
|
healthVersion += 1;
|
||||||
if (broadcastHealthUpdate) {
|
if (broadcastHealthUpdate) {
|
||||||
@@ -251,7 +251,10 @@ async function refreshHealthSnapshot(opts?: { probe?: boolean }) {
|
|||||||
return healthRefresh;
|
return healthRefresh;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
export async function startGatewayServer(
|
||||||
|
port = 18789,
|
||||||
|
opts?: { webchatPort?: number },
|
||||||
|
): Promise<GatewayServer> {
|
||||||
const releaseLock = await acquireGatewayLock().catch((err) => {
|
const releaseLock = await acquireGatewayLock().catch((err) => {
|
||||||
// Bubble known lock errors so callers can present a nice message.
|
// Bubble known lock errors so callers can present a nice message.
|
||||||
if (err instanceof GatewayLockError) throw err;
|
if (err instanceof GatewayLockError) throw err;
|
||||||
@@ -1146,7 +1149,7 @@ export async function startGatewayServer(port = 18789): Promise<GatewayServer> {
|
|||||||
defaultRuntime.log(`gateway log file: ${getResolvedLoggerSettings().file}`);
|
defaultRuntime.log(`gateway log file: ${getResolvedLoggerSettings().file}`);
|
||||||
|
|
||||||
// Start loopback WebChat server (unless disabled via config).
|
// Start loopback WebChat server (unless disabled via config).
|
||||||
void ensureWebChatServerFromConfig()
|
void ensureWebChatServerFromConfig(opts?.webchatPort)
|
||||||
.then((webchat) => {
|
.then((webchat) => {
|
||||||
if (webchat) {
|
if (webchat) {
|
||||||
defaultRuntime.log(
|
defaultRuntime.log(
|
||||||
|
|||||||
@@ -160,10 +160,12 @@ export async function __broadcastGatewayEventForTests() {
|
|||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function ensureWebChatServerFromConfig() {
|
export async function ensureWebChatServerFromConfig(
|
||||||
|
overridePort?: number,
|
||||||
|
) {
|
||||||
const cfg = loadConfig();
|
const cfg = loadConfig();
|
||||||
if (cfg.webchat?.enabled === false) return null;
|
if (cfg.webchat?.enabled === false) return null;
|
||||||
const port = cfg.webchat?.port ?? WEBCHAT_DEFAULT_PORT;
|
const port = overridePort ?? cfg.webchat?.port ?? WEBCHAT_DEFAULT_PORT;
|
||||||
try {
|
try {
|
||||||
return await startWebChatServer(port);
|
return await startWebChatServer(port);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
|
|||||||
Reference in New Issue
Block a user