fix: restore hidden gateway-daemon alias

This commit is contained in:
Peter Steinberger
2026-01-08 19:54:20 +00:00
parent 28e3e51335
commit 04e0e10411
2 changed files with 284 additions and 249 deletions

View File

@@ -20,6 +20,7 @@
- Onboarding: QuickStart jumps straight into provider selection with Telegram preselected when unset.
- Onboarding: QuickStart auto-installs the Gateway daemon with Node (no runtime picker).
- Daemon runtime: remove Bun from selection options.
- CLI: restore hidden `gateway-daemon` alias for legacy launchd configs.
## 2026.1.8

View File

@@ -37,6 +37,25 @@ type GatewayRpcOpts = {
expectFinal?: boolean;
};
type GatewayRunOpts = {
port?: unknown;
bind?: unknown;
token?: unknown;
auth?: unknown;
password?: unknown;
tailscale?: unknown;
tailscaleResetOnExit?: boolean;
allowUnconfigured?: boolean;
force?: boolean;
verbose?: boolean;
wsLog?: unknown;
compact?: boolean;
};
type GatewayRunParams = {
legacyTokenEnv?: boolean;
};
const gatewayLog = createSubsystemLogger("gateway");
type GatewayRunSignalAction = "stop" | "restart";
@@ -246,67 +265,30 @@ const callGatewayCli = async (
}),
);
export function registerGatewayCli(program: Command) {
const gateway = program
.command("gateway")
.description("Run the WebSocket Gateway")
.option("--port <port>", "Port for the gateway WebSocket")
.option(
"--bind <mode>",
'Bind mode ("loopback"|"tailnet"|"lan"|"auto"). Defaults to config gateway.bind (or loopback).',
)
.option(
"--token <token>",
"Shared token required in connect.params.auth.token (default: CLAWDBOT_GATEWAY_TOKEN env if set)",
)
.option("--auth <mode>", 'Gateway auth mode ("token"|"password")')
.option("--password <password>", "Password for auth mode=password")
.option(
"--tailscale <mode>",
'Tailscale exposure mode ("off"|"serve"|"funnel")',
)
.option(
"--tailscale-reset-on-exit",
"Reset Tailscale serve/funnel configuration on shutdown",
false,
)
.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 <style>",
'WebSocket log style ("auto"|"full"|"compact")',
"auto",
)
.option("--compact", 'Alias for "--ws-log compact"', false)
.action(async (opts) => {
async function runGatewayCommand(
opts: GatewayRunOpts,
params: GatewayRunParams = {},
) {
if (params.legacyTokenEnv) {
const legacyToken = process.env.CLAWDIS_GATEWAY_TOKEN;
if (legacyToken && !process.env.CLAWDBOT_GATEWAY_TOKEN) {
process.env.CLAWDBOT_GATEWAY_TOKEN = legacyToken;
}
}
setVerbose(Boolean(opts.verbose));
const wsLogRaw = (opts.compact ? "compact" : opts.wsLog) as
| string
| undefined;
const wsLogStyle: GatewayWsLogStyle =
wsLogRaw === "compact"
? "compact"
: wsLogRaw === "full"
? "full"
: "auto";
wsLogRaw === "compact" ? "compact" : wsLogRaw === "full" ? "full" : "auto";
if (
wsLogRaw !== undefined &&
wsLogRaw !== "auto" &&
wsLogRaw !== "compact" &&
wsLogRaw !== "full"
) {
defaultRuntime.error(
'Invalid --ws-log (use "auto", "full", "compact")',
);
defaultRuntime.error('Invalid --ws-log (use "auto", "full", "compact")');
defaultRuntime.exit(1);
}
setGatewayWsLogStyle(wsLogStyle);
@@ -344,9 +326,7 @@ export function registerGatewayCli(program: Command) {
);
}
if (waitedMs > 0) {
gatewayLog.info(
`force: waited ${waitedMs}ms for port ${port} to free`,
);
gatewayLog.info(`force: waited ${waitedMs}ms for port ${port} to free`);
}
}
} catch (err) {
@@ -360,9 +340,7 @@ export function registerGatewayCli(program: Command) {
}
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
const authMode: GatewayAuthMode | null =
authModeRaw === "token" || authModeRaw === "password"
? authModeRaw
: null;
authModeRaw === "token" || authModeRaw === "password" ? authModeRaw : null;
if (authModeRaw && !authMode) {
defaultRuntime.error('Invalid --auth (use "token" or "password")');
defaultRuntime.exit(1);
@@ -376,9 +354,7 @@ export function registerGatewayCli(program: Command) {
? tailscaleRaw
: null;
if (tailscaleRaw && !tailscaleMode) {
defaultRuntime.error(
'Invalid --tailscale (use "off", "serve", or "funnel")',
);
defaultRuntime.error('Invalid --tailscale (use "off", "serve", or "funnel")');
defaultRuntime.exit(1);
return;
}
@@ -491,9 +467,7 @@ export function registerGatewayCli(program: Command) {
? {
mode: authMode ?? undefined,
token: opts.token ? String(opts.token) : undefined,
password: opts.password
? String(opts.password)
: undefined,
password: opts.password ? String(opts.password) : undefined,
}
: undefined,
tailscale:
@@ -533,7 +507,67 @@ export function registerGatewayCli(program: Command) {
defaultRuntime.error(`Gateway failed to start: ${String(err)}`);
defaultRuntime.exit(1);
}
}
function addGatewayRunCommand(
cmd: Command,
params: GatewayRunParams = {},
): Command {
return cmd
.option("--port <port>", "Port for the gateway WebSocket")
.option(
"--bind <mode>",
'Bind mode ("loopback"|"tailnet"|"lan"|"auto"). Defaults to config gateway.bind (or loopback).',
)
.option(
"--token <token>",
"Shared token required in connect.params.auth.token (default: CLAWDBOT_GATEWAY_TOKEN env if set)",
)
.option("--auth <mode>", 'Gateway auth mode ("token"|"password")')
.option("--password <password>", "Password for auth mode=password")
.option(
"--tailscale <mode>",
'Tailscale exposure mode ("off"|"serve"|"funnel")',
)
.option(
"--tailscale-reset-on-exit",
"Reset Tailscale serve/funnel configuration on shutdown",
false,
)
.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 <style>",
'WebSocket log style ("auto"|"full"|"compact")',
"auto",
)
.option("--compact", 'Alias for "--ws-log compact"', false)
.action(async (opts) => {
await runGatewayCommand(opts, params);
});
}
export function registerGatewayCli(program: Command) {
const gateway = addGatewayRunCommand(
program.command("gateway").description("Run the WebSocket Gateway"),
);
// Back-compat: legacy launchd plists used gateway-daemon; keep hidden alias.
addGatewayRunCommand(
program
.command("gateway-daemon", { hidden: true })
.description("Run the WebSocket Gateway as a long-lived daemon"),
{ legacyTokenEnv: true },
);
gatewayCallOpts(
gateway