chore: migrate to oxlint and oxfmt

Co-authored-by: Christoph Nakazawa <christoph.pojer@gmail.com>
This commit is contained in:
Peter Steinberger
2026-01-14 14:31:43 +00:00
parent 912ebffc63
commit c379191f80
1480 changed files with 28608 additions and 43547 deletions

View File

@@ -38,9 +38,7 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
defaultRuntime.exit(1);
return;
}
const runtimeRaw = opts.runtime
? String(opts.runtime)
: DEFAULT_GATEWAY_DAEMON_RUNTIME;
const runtimeRaw = opts.runtime ? String(opts.runtime) : DEFAULT_GATEWAY_DAEMON_RUNTIME;
if (!isGatewayDaemonRuntime(runtimeRaw)) {
defaultRuntime.error('Invalid --runtime (use "node" or "bun")');
defaultRuntime.exit(1);
@@ -66,19 +64,17 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
}
const devMode =
process.argv[1]?.includes(`${path.sep}src${path.sep}`) &&
process.argv[1]?.endsWith(".ts");
process.argv[1]?.includes(`${path.sep}src${path.sep}`) && process.argv[1]?.endsWith(".ts");
const nodePath = await resolvePreferredNodePath({
env: process.env,
runtime: runtimeRaw,
});
const { programArguments, workingDirectory } =
await resolveGatewayProgramArguments({
port,
dev: devMode,
runtime: runtimeRaw,
nodePath,
});
const { programArguments, workingDirectory } = await resolveGatewayProgramArguments({
port,
dev: devMode,
runtime: runtimeRaw,
nodePath,
});
if (runtimeRaw === "node") {
const systemNode = await resolveSystemNodeInfo({ env: process.env });
const warning = renderSystemNodeWarning(systemNode, programArguments[0]);
@@ -87,14 +83,9 @@ export async function runDaemonInstall(opts: DaemonInstallOptions) {
const environment = buildServiceEnvironment({
env: process.env,
port,
token:
opts.token ||
cfg.gateway?.auth?.token ||
process.env.CLAWDBOT_GATEWAY_TOKEN,
token: opts.token || cfg.gateway?.auth?.token || process.env.CLAWDBOT_GATEWAY_TOKEN,
launchdLabel:
process.platform === "darwin"
? resolveGatewayLaunchAgentLabel(profile)
: undefined,
process.platform === "darwin" ? resolveGatewayLaunchAgentLabel(profile) : undefined,
});
try {

View File

@@ -1,8 +1,5 @@
import { callGateway } from "../../gateway/call.js";
import {
GATEWAY_CLIENT_MODES,
GATEWAY_CLIENT_NAMES,
} from "../../utils/message-channel.js";
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES } from "../../utils/message-channel.js";
import { withProgress } from "../progress.js";
export async function probeGatewayStatus(opts: {

View File

@@ -17,20 +17,13 @@ export function registerDaemonCli(program: Command) {
.description("Manage the Gateway daemon service (launchd/systemd/schtasks)")
.addHelpText(
"after",
() =>
`\n${theme.muted("Docs:")} ${formatDocsLink(
"/gateway",
"docs.clawd.bot/gateway",
)}\n`,
() => `\n${theme.muted("Docs:")} ${formatDocsLink("/gateway", "docs.clawd.bot/gateway")}\n`,
);
daemon
.command("status")
.description("Show daemon install status + probe the Gateway")
.option(
"--url <url>",
"Gateway WebSocket URL (defaults to config/remote/local)",
)
.option("--url <url>", "Gateway WebSocket URL (defaults to config/remote/local)")
.option("--token <token>", "Gateway token (if required)")
.option("--password <password>", "Gateway password (password auth)")
.option("--timeout <ms>", "Timeout in ms", "10000")

View File

@@ -20,9 +20,7 @@ export function parsePort(raw: unknown): number | null {
return parsed;
}
export function parsePortFromArgs(
programArguments: string[] | undefined,
): number | null {
export function parsePortFromArgs(programArguments: string[] | undefined): number | null {
if (!programArguments?.length) return null;
for (let i = 0; i < programArguments.length; i += 1) {
const arg = programArguments[i];
@@ -51,9 +49,7 @@ export function pickProbeHostForBind(
return "127.0.0.1";
}
export function safeDaemonEnv(
env: Record<string, string> | undefined,
): string[] {
export function safeDaemonEnv(env: Record<string, string> | undefined): string[] {
if (!env) return [];
const allow = [
"CLAWDBOT_PROFILE",
@@ -138,9 +134,7 @@ export function renderRuntimeHints(
hints.push(`Launchd stderr (if installed): ${logs.stderrPath}`);
} else if (process.platform === "linux") {
const unit = resolveGatewaySystemdServiceName(env.CLAWDBOT_PROFILE);
hints.push(
`Logs: journalctl --user -u ${unit}.service -n 200 --no-pager`,
);
hints.push(`Logs: journalctl --user -u ${unit}.service -n 200 --no-pager`);
} else if (process.platform === "win32") {
const task = resolveGatewayWindowsTaskName(env.CLAWDBOT_PROFILE);
hints.push(`Logs: schtasks /Query /TN "${task}" /V /FO LIST`);
@@ -149,18 +143,13 @@ export function renderRuntimeHints(
return hints;
}
export function renderGatewayServiceStartHints(
env: NodeJS.ProcessEnv = process.env,
): string[] {
export function renderGatewayServiceStartHints(env: NodeJS.ProcessEnv = process.env): string[] {
const base = ["clawdbot daemon install", "clawdbot gateway"];
const profile = env.CLAWDBOT_PROFILE;
switch (process.platform) {
case "darwin": {
const label = resolveGatewayLaunchAgentLabel(profile);
return [
...base,
`launchctl bootstrap gui/$UID ~/Library/LaunchAgents/${label}.plist`,
];
return [...base, `launchctl bootstrap gui/$UID ~/Library/LaunchAgents/${label}.plist`];
}
case "linux": {
const unit = resolveGatewaySystemdServiceName(profile);

View File

@@ -4,10 +4,7 @@ import {
resolveGatewayPort,
resolveStateDir,
} from "../../config/config.js";
import type {
BridgeBindMode,
GatewayControlUiConfig,
} from "../../config/types.js";
import type { BridgeBindMode, GatewayControlUiConfig } from "../../config/types.js";
import { readLastGatewayErrorLine } from "../../daemon/diagnostics.js";
import type { FindExtraGatewayServicesOptions } from "../../daemon/inspect.js";
import { findExtraGatewayServices } from "../../daemon/inspect.js";
@@ -24,11 +21,7 @@ import {
} from "../../infra/ports.js";
import { pickPrimaryTailnetIPv4 } from "../../infra/tailnet.js";
import { probeGatewayStatus } from "./probe.js";
import {
normalizeListenerAddress,
parsePortFromArgs,
pickProbeHostForBind,
} from "./shared.js";
import { normalizeListenerAddress, parsePortFromArgs, pickProbeHostForBind } from "./shared.js";
import type { GatewayRpcOpts } from "./types.js";
type ConfigSummary = {
@@ -104,10 +97,7 @@ export type DaemonStatus = {
extraServices: Array<{ label: string; detail: string; scope: string }>;
};
function shouldReportPortUsage(
status: PortUsageStatus | undefined,
rpcOk?: boolean,
) {
function shouldReportPortUsage(status: PortUsageStatus | undefined, rpcOk?: boolean) {
if (status !== "busy") return false;
if (rpcOk === true) return false;
return true;
@@ -142,10 +132,7 @@ export async function gatherDaemonStatus(
...(serviceEnv ?? undefined),
} satisfies Record<string, string | undefined>;
const cliConfigPath = resolveConfigPath(
process.env,
resolveStateDir(process.env),
);
const cliConfigPath = resolveConfigPath(process.env, resolveStateDir(process.env));
const daemonConfigPath = resolveConfigPath(
mergedDaemonEnv as NodeJS.ProcessEnv,
resolveStateDir(mergedDaemonEnv as NodeJS.ProcessEnv),
@@ -175,16 +162,13 @@ export async function gatherDaemonStatus(
path: daemonSnapshot?.path ?? daemonConfigPath,
exists: daemonSnapshot?.exists ?? false,
valid: daemonSnapshot?.valid ?? true,
...(daemonSnapshot?.issues?.length
? { issues: daemonSnapshot.issues }
: {}),
...(daemonSnapshot?.issues?.length ? { issues: daemonSnapshot.issues } : {}),
controlUi: daemonCfg.gateway?.controlUi,
};
const configMismatch = cliConfigSummary.path !== daemonConfigSummary.path;
const portFromArgs = parsePortFromArgs(command?.programArguments);
const daemonPort =
portFromArgs ?? resolveGatewayPort(daemonCfg, mergedDaemonEnv);
const daemonPort = portFromArgs ?? resolveGatewayPort(daemonCfg, mergedDaemonEnv);
const portSource: GatewayStatusSummary["portSource"] = portFromArgs
? "service args"
: "env/config";
@@ -199,9 +183,7 @@ export async function gatherDaemonStatus(
const tailnetIPv4 = pickPrimaryTailnetIPv4();
const probeHost = pickProbeHostForBind(bindMode, tailnetIPv4, customBindHost);
const probeUrlOverride =
typeof opts.rpc.url === "string" && opts.rpc.url.trim().length > 0
? opts.rpc.url.trim()
: null;
typeof opts.rpc.url === "string" && opts.rpc.url.trim().length > 0 ? opts.rpc.url.trim() : null;
const probeUrl = probeUrlOverride ?? `ws://${probeHost}:${daemonPort}`;
const probeNote =
!probeUrlOverride && bindMode === "lan"
@@ -241,8 +223,7 @@ export async function gatherDaemonStatus(
).catch(() => []);
const timeoutMsRaw = Number.parseInt(String(opts.rpc.timeout ?? "10000"), 10);
const timeoutMs =
Number.isFinite(timeoutMsRaw) && timeoutMsRaw > 0 ? timeoutMsRaw : 10_000;
const timeoutMs = Number.isFinite(timeoutMsRaw) && timeoutMsRaw > 0 ? timeoutMsRaw : 10_000;
const rpc = opts.probe
? await probeGatewayStatus({
@@ -262,15 +243,8 @@ export async function gatherDaemonStatus(
: undefined;
let lastError: string | undefined;
if (
loaded &&
runtime?.status === "running" &&
portStatus &&
portStatus.status !== "busy"
) {
lastError =
(await readLastGatewayErrorLine(mergedDaemonEnv as NodeJS.ProcessEnv)) ??
undefined;
if (loaded && runtime?.status === "running" && portStatus && portStatus.status !== "busy") {
lastError = (await readLastGatewayErrorLine(mergedDaemonEnv as NodeJS.ProcessEnv)) ?? undefined;
}
return {
@@ -306,12 +280,8 @@ export async function gatherDaemonStatus(
};
}
export function renderPortDiagnosticsForCli(
status: DaemonStatus,
rpcOk?: boolean,
): string[] {
if (!status.port || !shouldReportPortUsage(status.port.status, rpcOk))
return [];
export function renderPortDiagnosticsForCli(status: DaemonStatus, rpcOk?: boolean): string[] {
if (!status.port || !shouldReportPortUsage(status.port.status, rpcOk)) return [];
return formatPortDiagnostics({
port: status.port.port,
status: status.port.status,

View File

@@ -8,21 +8,14 @@ import { resolveGatewayLogPaths } from "../../daemon/launchd.js";
import { getResolvedLoggerSettings } from "../../logging.js";
import { defaultRuntime } from "../../runtime.js";
import { colorize, isRich, theme } from "../../terminal/theme.js";
import {
formatRuntimeStatus,
renderRuntimeHints,
safeDaemonEnv,
} from "./shared.js";
import { formatRuntimeStatus, renderRuntimeHints, safeDaemonEnv } from "./shared.js";
import {
type DaemonStatus,
renderPortDiagnosticsForCli,
resolvePortListeningAddresses,
} from "./status.gather.js";
export function printDaemonStatus(
status: DaemonStatus,
opts: { json: boolean },
) {
export function printDaemonStatus(status: DaemonStatus, opts: { json: boolean }) {
if (opts.json) {
defaultRuntime.log(JSON.stringify(status, null, 2));
return;
@@ -41,9 +34,7 @@ export function printDaemonStatus(
const serviceStatus = service.loaded
? okText(service.loadedText)
: warnText(service.notLoadedText);
defaultRuntime.log(
`${label("Service:")} ${accent(service.label)} (${serviceStatus})`,
);
defaultRuntime.log(`${label("Service:")} ${accent(service.label)} (${serviceStatus})`);
try {
const logFile = getResolvedLoggerSettings().file;
defaultRuntime.log(`${label("File logs:")} ${infoText(logFile)}`);
@@ -56,14 +47,10 @@ export function printDaemonStatus(
);
}
if (service.command?.sourcePath) {
defaultRuntime.log(
`${label("Service file:")} ${infoText(service.command.sourcePath)}`,
);
defaultRuntime.log(`${label("Service file:")} ${infoText(service.command.sourcePath)}`);
}
if (service.command?.workingDirectory) {
defaultRuntime.log(
`${label("Working dir:")} ${infoText(service.command.workingDirectory)}`,
);
defaultRuntime.log(`${label("Working dir:")} ${infoText(service.command.workingDirectory)}`);
}
const daemonEnvLines = safeDaemonEnv(service.command?.environment);
if (daemonEnvLines.length > 0) {
@@ -72,19 +59,13 @@ export function printDaemonStatus(
spacer();
if (service.configAudit?.issues.length) {
defaultRuntime.error(
warnText("Service config looks out of date or non-standard."),
);
defaultRuntime.error(warnText("Service config looks out of date or non-standard."));
for (const issue of service.configAudit.issues) {
const detail = issue.detail ? ` (${issue.detail})` : "";
defaultRuntime.error(
`${warnText("Service config issue:")} ${issue.message}${detail}`,
);
defaultRuntime.error(`${warnText("Service config issue:")} ${issue.message}${detail}`);
}
defaultRuntime.error(
warnText(
'Recommendation: run "clawdbot doctor" (or "clawdbot doctor --repair").',
),
warnText('Recommendation: run "clawdbot doctor" (or "clawdbot doctor --repair").'),
);
}
@@ -129,9 +110,7 @@ export function printDaemonStatus(
defaultRuntime.log(
`${label("Gateway:")} bind=${infoText(status.gateway.bindMode)} (${infoText(bindHost)}), port=${infoText(String(status.gateway.port))} (${infoText(status.gateway.portSource)})`,
);
defaultRuntime.log(
`${label("Probe target:")} ${infoText(status.gateway.probeUrl)}`,
);
defaultRuntime.log(`${label("Probe target:")} ${infoText(status.gateway.probeUrl)}`);
const controlUiEnabled = status.config?.daemon?.controlUi?.enabled ?? true;
if (!controlUiEnabled) {
defaultRuntime.log(`${label("Dashboard:")} ${warnText("disabled")}`);
@@ -145,9 +124,7 @@ export function printDaemonStatus(
defaultRuntime.log(`${label("Dashboard:")} ${infoText(links.httpUrl)}`);
}
if (status.gateway.probeNote) {
defaultRuntime.log(
`${label("Probe note:")} ${infoText(status.gateway.probeNote)}`,
);
defaultRuntime.log(`${label("Probe note:")} ${infoText(status.gateway.probeNote)}`);
}
spacer();
}
@@ -163,21 +140,12 @@ export function printDaemonStatus(
: runtimeStatus === "unknown"
? theme.muted
: theme.warn;
defaultRuntime.log(
`${label("Runtime:")} ${colorize(rich, runtimeColor, runtimeLine)}`,
);
defaultRuntime.log(`${label("Runtime:")} ${colorize(rich, runtimeColor, runtimeLine)}`);
}
if (
rpc &&
!rpc.ok &&
service.loaded &&
service.runtime?.status === "running"
) {
if (rpc && !rpc.ok && service.loaded && service.runtime?.status === "running") {
defaultRuntime.log(
warnText(
"Warm-up: launch agents can take a few seconds. Try again shortly.",
),
warnText("Warm-up: launch agents can take a few seconds. Try again shortly."),
);
}
if (rpc) {
@@ -203,9 +171,7 @@ export function printDaemonStatus(
}
} else if (service.loaded && service.runtime?.status === "stopped") {
defaultRuntime.error(
errorText(
"Service is loaded but not running (likely exited immediately).",
),
errorText("Service is loaded but not running (likely exited immediately)."),
);
for (const hint of renderRuntimeHints(
service.runtime,
@@ -217,8 +183,7 @@ export function printDaemonStatus(
}
if (service.runtime?.cachedLabel) {
const env = (service.command?.environment ??
process.env) as NodeJS.ProcessEnv;
const env = (service.command?.environment ?? process.env) as NodeJS.ProcessEnv;
const labelValue = resolveGatewayLaunchAgentLabel(env.CLAWDBOT_PROFILE);
defaultRuntime.error(
errorText(
@@ -236,9 +201,7 @@ export function printDaemonStatus(
if (status.port) {
const addrs = resolvePortListeningAddresses(status);
if (addrs.length > 0) {
defaultRuntime.log(
`${label("Listening:")} ${infoText(addrs.join(", "))}`,
);
defaultRuntime.log(`${label("Listening:")} ${infoText(addrs.join(", "))}`);
}
}
@@ -255,23 +218,16 @@ export function printDaemonStatus(
status.port.status !== "busy"
) {
defaultRuntime.error(
errorText(
`Gateway port ${status.port.port} is not listening (service appears running).`,
),
errorText(`Gateway port ${status.port.port} is not listening (service appears running).`),
);
if (status.lastError) {
defaultRuntime.error(
`${errorText("Last gateway error:")} ${status.lastError}`,
);
defaultRuntime.error(`${errorText("Last gateway error:")} ${status.lastError}`);
}
if (process.platform === "linux") {
const env = (service.command?.environment ??
process.env) as NodeJS.ProcessEnv;
const env = (service.command?.environment ?? process.env) as NodeJS.ProcessEnv;
const unit = resolveGatewaySystemdServiceName(env.CLAWDBOT_PROFILE);
defaultRuntime.error(
errorText(
`Logs: journalctl --user -u ${unit}.service -n 200 --no-pager`,
),
errorText(`Logs: journalctl --user -u ${unit}.service -n 200 --no-pager`),
);
} else if (process.platform === "darwin") {
const logs = resolveGatewayLogPaths(
@@ -293,13 +249,9 @@ export function printDaemonStatus(
}
if (extraServices.length > 0) {
defaultRuntime.error(
errorText("Other gateway-like services detected (best effort):"),
);
defaultRuntime.error(errorText("Other gateway-like services detected (best effort):"));
for (const svc of extraServices) {
defaultRuntime.error(
`- ${errorText(svc.label)} (${svc.scope}, ${svc.detail})`,
);
defaultRuntime.error(`- ${errorText(svc.label)} (${svc.scope}, ${svc.detail})`);
}
for (const hint of renderGatewayServiceCleanupHints()) {
defaultRuntime.error(`${errorText("Cleanup hint:")} ${hint}`);
@@ -322,7 +274,5 @@ export function printDaemonStatus(
}
defaultRuntime.log(`${label("Troubles:")} run clawdbot status`);
defaultRuntime.log(
`${label("Troubleshooting:")} https://docs.clawd.bot/troubleshooting`,
);
defaultRuntime.log(`${label("Troubleshooting:")} https://docs.clawd.bot/troubleshooting`);
}

View File

@@ -14,9 +14,7 @@ export async function runDaemonStatus(opts: DaemonStatusOptions) {
printDaemonStatus(status, { json: Boolean(opts.json) });
} catch (err) {
const rich = isRich();
defaultRuntime.error(
colorize(rich, theme.error, `Daemon status failed: ${String(err)}`),
);
defaultRuntime.error(colorize(rich, theme.error, `Daemon status failed: ${String(err)}`));
defaultRuntime.exit(1);
}
}