diff --git a/scripts/release-check.ts b/scripts/release-check.ts index 6c44d51e58e..f54b65cb859 100755 --- a/scripts/release-check.ts +++ b/scripts/release-check.ts @@ -456,7 +456,8 @@ export function collectForbiddenPackPaths(paths: Iterable): string[] { return [...paths] .filter( (path) => - forbiddenPrefixes.some((prefix) => path.startsWith(prefix)) || /node_modules\//.test(path), + forbiddenPrefixes.some((prefix) => path.startsWith(prefix)) || + path.includes("node_modules/"), ) .toSorted((left, right) => left.localeCompare(right)); } diff --git a/scripts/tsdown-build.mjs b/scripts/tsdown-build.mjs index 30e36273514..7a5ccdc4944 100644 --- a/scripts/tsdown-build.mjs +++ b/scripts/tsdown-build.mjs @@ -13,7 +13,7 @@ import { const logLevel = process.env.OPENCLAW_BUILD_VERBOSE ? "info" : "warn"; const extraArgs = process.argv.slice(2); -const INEFFECTIVE_DYNAMIC_IMPORT_RE = /\[INEFFECTIVE_DYNAMIC_IMPORT\]/; +const INEFFECTIVE_DYNAMIC_IMPORT_MARKER = "[INEFFECTIVE_DYNAMIC_IMPORT]"; const UNRESOLVED_IMPORT_RE = /\[UNRESOLVED_IMPORT\]/; const ANSI_ESCAPE_RE = new RegExp(String.raw`\u001B\[[0-9;]*m`, "g"); const HASHED_ROOT_JS_RE = /^(?.+)-[A-Za-z0-9_-]+\.js$/u; @@ -170,7 +170,7 @@ export function createTsdownOutputScanner(params = {}) { return { append(chunk) { const text = Buffer.isBuffer(chunk) ? chunk.toString("utf8") : String(chunk); - if (INEFFECTIVE_DYNAMIC_IMPORT_RE.test(text)) { + if (text.includes(INEFFECTIVE_DYNAMIC_IMPORT_MARKER)) { hasIneffectiveDynamicImport = true; } scanLines(text); diff --git a/src/agents/auth-profiles.getsoonestcooldownexpiry.test.ts b/src/agents/auth-profiles.getsoonestcooldownexpiry.test.ts index d2add044a82..98653bc89fc 100644 --- a/src/agents/auth-profiles.getsoonestcooldownexpiry.test.ts +++ b/src/agents/auth-profiles.getsoonestcooldownexpiry.test.ts @@ -44,7 +44,7 @@ describe("getSoonestCooldownExpiry", () => { cooldownUntil: Infinity, }, "openai:p3": { - disabledUntil: NaN, + disabledUntil: Number.NaN, }, "openai:p4": { cooldownUntil: 1_700_000_005_000, diff --git a/src/agents/auth-profiles/oauth.fallback-to-main-agent.test.ts b/src/agents/auth-profiles/oauth.fallback-to-main-agent.test.ts index 3e4ba5e429d..aea165dbcb0 100644 --- a/src/agents/auth-profiles/oauth.fallback-to-main-agent.test.ts +++ b/src/agents/auth-profiles/oauth.fallback-to-main-agent.test.ts @@ -249,7 +249,7 @@ describe("resolveApiKeyForProfile fallback to main agent", () => { profileId, access: "secondary-stale", refresh: "secondary-refresh", - expires: NaN, + expires: Number.NaN, }), ); diff --git a/src/agents/auth-profiles/usage.test.ts b/src/agents/auth-profiles/usage.test.ts index da98eb6f05d..e7e53320d33 100644 --- a/src/agents/auth-profiles/usage.test.ts +++ b/src/agents/auth-profiles/usage.test.ts @@ -521,7 +521,7 @@ describe("clearExpiredCooldowns", () => { it("ignores NaN and Infinity cooldown values", () => { const store = makeStore({ "anthropic:default": { - cooldownUntil: NaN, + cooldownUntil: Number.NaN, errorCount: 2, }, "openai:default": { diff --git a/src/agents/date-time.ts b/src/agents/date-time.ts index 6b64bf7b181..b1ea6df0f22 100644 --- a/src/agents/date-time.ts +++ b/src/agents/date-time.ts @@ -181,7 +181,7 @@ export function formatUserTime( if (!map.weekday || !map.year || !map.month || !map.day || !map.hour || !map.minute) { return undefined; } - const dayNum = parseInt(map.day, 10); + const dayNum = Number.parseInt(map.day, 10); const suffix = ordinalSuffix(dayNum); const timePart = use24Hour ? `${map.hour}:${map.minute}` diff --git a/src/agents/model-fallback.probe.test.ts b/src/agents/model-fallback.probe.test.ts index a9e8a878233..d7b359e10bd 100644 --- a/src/agents/model-fallback.probe.test.ts +++ b/src/agents/model-fallback.probe.test.ts @@ -539,7 +539,7 @@ describe("runWithModelFallback – probe logic", () => { it("handles NaN soonest safely (treats as probe-worthy)", async () => { const cfg = makeCfg(); - mockedGetSoonestCooldownExpiry.mockReturnValue(NaN); + mockedGetSoonestCooldownExpiry.mockReturnValue(Number.NaN); const run = vi.fn().mockResolvedValue("ok-nan"); diff --git a/src/agents/pi-bundle-lsp-runtime.ts b/src/agents/pi-bundle-lsp-runtime.ts index 5203884efe5..1e5e8d34274 100644 --- a/src/agents/pi-bundle-lsp-runtime.ts +++ b/src/agents/pi-bundle-lsp-runtime.ts @@ -66,7 +66,7 @@ function parseLspMessages(buffer: string): { messages: unknown[]; remaining: str continue; } - const contentLength = parseInt(match[1], 10); + const contentLength = Number.parseInt(match[1], 10); const bodyStart = headerEnd + 4; const bodyEnd = bodyStart + contentLength; diff --git a/src/agents/pi-embedded-runner.compaction-safety-timeout.test.ts b/src/agents/pi-embedded-runner.compaction-safety-timeout.test.ts index 4cedf36bed9..de1447a68b1 100644 --- a/src/agents/pi-embedded-runner.compaction-safety-timeout.test.ts +++ b/src/agents/pi-embedded-runner.compaction-safety-timeout.test.ts @@ -146,7 +146,7 @@ describe("resolveCompactionTimeoutMs", () => { it("returns default for NaN", () => { expect( resolveCompactionTimeoutMs({ - agents: { defaults: { compaction: { timeoutSeconds: NaN } } }, + agents: { defaults: { compaction: { timeoutSeconds: Number.NaN } } }, }), ).toBe(EMBEDDED_COMPACTION_TIMEOUT_MS); }); diff --git a/src/agents/pi-embedded-runner/openrouter-model-capabilities.ts b/src/agents/pi-embedded-runner/openrouter-model-capabilities.ts index cf55454ee1c..f2a1b2f1458 100644 --- a/src/agents/pi-embedded-runner/openrouter-model-capabilities.ts +++ b/src/agents/pi-embedded-runner/openrouter-model-capabilities.ts @@ -171,10 +171,10 @@ function parseModel(model: OpenRouterApiModel): OpenRouterModelCapabilities { model.max_output_tokens ?? 8192, cost: { - input: parseFloat(model.pricing?.prompt || "0") * 1_000_000, - output: parseFloat(model.pricing?.completion || "0") * 1_000_000, - cacheRead: parseFloat(model.pricing?.input_cache_read || "0") * 1_000_000, - cacheWrite: parseFloat(model.pricing?.input_cache_write || "0") * 1_000_000, + input: Number.parseFloat(model.pricing?.prompt || "0") * 1_000_000, + output: Number.parseFloat(model.pricing?.completion || "0") * 1_000_000, + cacheRead: Number.parseFloat(model.pricing?.input_cache_read || "0") * 1_000_000, + cacheWrite: Number.parseFloat(model.pricing?.input_cache_write || "0") * 1_000_000, }, }; } diff --git a/src/agents/pi-tools.before-tool-call.ts b/src/agents/pi-tools.before-tool-call.ts index e29ff2c0814..f8440195f1b 100644 --- a/src/agents/pi-tools.before-tool-call.ts +++ b/src/agents/pi-tools.before-tool-call.ts @@ -163,22 +163,21 @@ export async function runBeforeToolCallHook(args: { blocked: true, reason: loopResult.message, }; - } else { - const warningKey = loopResult.warningKey ?? `${loopResult.detector}:${toolName}`; - if (shouldEmitLoopWarning(sessionState, warningKey, loopResult.count)) { - log.warn(`Loop warning for ${toolName}: ${loopResult.message}`); - logToolLoopAction({ - sessionKey: args.ctx.sessionKey, - sessionId: args.ctx?.agentId, - toolName, - level: "warning", - action: "warn", - detector: loopResult.detector, - count: loopResult.count, - message: loopResult.message, - pairedToolName: loopResult.pairedToolName, - }); - } + } + const warningKey = loopResult.warningKey ?? `${loopResult.detector}:${toolName}`; + if (shouldEmitLoopWarning(sessionState, warningKey, loopResult.count)) { + log.warn(`Loop warning for ${toolName}: ${loopResult.message}`); + logToolLoopAction({ + sessionKey: args.ctx.sessionKey, + sessionId: args.ctx?.agentId, + toolName, + level: "warning", + action: "warn", + detector: loopResult.detector, + count: loopResult.count, + message: loopResult.message, + pairedToolName: loopResult.pairedToolName, + }); } } diff --git a/src/agents/provider-transport-fetch.ts b/src/agents/provider-transport-fetch.ts index 69466edfa75..815f703de63 100644 --- a/src/agents/provider-transport-fetch.ts +++ b/src/agents/provider-transport-fetch.ts @@ -13,7 +13,7 @@ const DEFAULT_MAX_SDK_RETRY_WAIT_SECONDS = 60; function parseRetryAfterSeconds(headers: Headers): number | undefined { const retryAfterMs = headers.get("retry-after-ms"); if (retryAfterMs) { - const milliseconds = parseFloat(retryAfterMs); + const milliseconds = Number.parseFloat(retryAfterMs); if (Number.isFinite(milliseconds) && milliseconds >= 0) { return milliseconds / 1000; } @@ -24,7 +24,7 @@ function parseRetryAfterSeconds(headers: Headers): number | undefined { return undefined; } - const seconds = parseFloat(retryAfter); + const seconds = Number.parseFloat(retryAfter); if (Number.isFinite(seconds) && seconds >= 0) { return seconds; } @@ -47,7 +47,7 @@ function resolveMaxSdkRetryWaitSeconds(): number | undefined { return undefined; } - const seconds = parseFloat(raw); + const seconds = Number.parseFloat(raw); if (Number.isFinite(seconds) && seconds > 0) { return seconds; } diff --git a/src/agents/subagent-registry.ts b/src/agents/subagent-registry.ts index a21be5b4266..cf6047bb567 100644 --- a/src/agents/subagent-registry.ts +++ b/src/agents/subagent-registry.ts @@ -156,7 +156,7 @@ let sweepInProgress = false; let listenerStarted = false; let listenerStop: (() => void) | null = null; // Use var to avoid TDZ when init runs across circular imports during bootstrap. -var restoreAttempted = false; +let restoreAttempted = false; const ORPHAN_RECOVERY_DEBOUNCE_MS = 1_000; let lastOrphanRecoveryScheduleAt = 0; const SUBAGENT_ANNOUNCE_TIMEOUT_MS = 120_000; diff --git a/src/agents/tools/web-search-provider-common.ts b/src/agents/tools/web-search-provider-common.ts index 17da3943a04..60c083666b0 100644 --- a/src/agents/tools/web-search-provider-common.ts +++ b/src/agents/tools/web-search-provider-common.ts @@ -193,7 +193,7 @@ export function isoToPerplexityDate(iso: string): string | undefined { return undefined; } const [, year, month, day] = match; - return `${parseInt(month, 10)}/${parseInt(day, 10)}/${year}`; + return `${Number.parseInt(month, 10)}/${Number.parseInt(day, 10)}/${year}`; } export function normalizeToIsoDate(value: string): string | undefined { diff --git a/src/auto-reply/reply/streaming-directives.ts b/src/auto-reply/reply/streaming-directives.ts index 5ac7bd44913..3a7f1bc235f 100644 --- a/src/auto-reply/reply/streaming-directives.ts +++ b/src/auto-reply/reply/streaming-directives.ts @@ -42,7 +42,7 @@ export const splitTrailingDirective = ( // 1. Unclosed `[[…` reply/audio directive tail. const openIndex = text.lastIndexOf("[["); - if (openIndex >= 0 && text.indexOf("]]", openIndex + 2) < 0) { + if (openIndex >= 0 && !text.includes("]]", openIndex + 2)) { if (openIndex < bufferStart) { bufferStart = openIndex; } diff --git a/src/channels/allow-from.ts b/src/channels/allow-from.ts index 6a517145755..a7d44b44ab2 100644 --- a/src/channels/allow-from.ts +++ b/src/channels/allow-from.ts @@ -28,7 +28,7 @@ export function resolveGroupAllowFromSources(params: { export function firstDefined(...values: Array) { for (const value of values) { - if (typeof value !== "undefined") { + if (value !== undefined) { return value; } } diff --git a/src/channels/plugins/setup-promotion-helpers.ts b/src/channels/plugins/setup-promotion-helpers.ts index 21912bf2ccd..15ce34151ab 100644 --- a/src/channels/plugins/setup-promotion-helpers.ts +++ b/src/channels/plugins/setup-promotion-helpers.ts @@ -98,9 +98,9 @@ export function resolveSingleAccountKeysToMove(params: { channelKey: string; channel: Record; }): string[] { - const hasNamedAccounts = - Object.keys((params.channel.accounts as Record) ?? {}).filter(Boolean).length > - 0; + const hasNamedAccounts = Object.keys( + (params.channel.accounts as Record) ?? {}, + ).some(Boolean); const entries = Object.entries(params.channel) .filter( ([key, value]) => diff --git a/src/cli/command-secret-resolution.coverage.test.ts b/src/cli/command-secret-resolution.coverage.test.ts index c815c6ccd4b..9da2c0f322b 100644 --- a/src/cli/command-secret-resolution.coverage.test.ts +++ b/src/cli/command-secret-resolution.coverage.test.ts @@ -17,7 +17,7 @@ const SECRET_TARGET_CALLSITES = [ function hasSupportedTargetIdsWiring(source: string): boolean { return ( - /resolveAgentRuntimeConfig\(/.test(source) || + source.includes("resolveAgentRuntimeConfig(") || /targetIds:\s*get[A-Za-z0-9_]+\(\)/m.test(source) || /targetIds:\s*getAgentRuntimeCommandSecretTargetIds\(/m.test(source) || /targetIds:\s*scopedTargets\.targetIds/m.test(source) || @@ -27,15 +27,15 @@ function hasSupportedTargetIdsWiring(source: string): boolean { function hasSupportedSecretResolutionWiring(source: string): boolean { return ( - /resolveAgentRuntimeConfig\(/.test(source) || - /resolveCommandConfigWithSecrets\(/.test(source) || - /resolveCommandSecretRefsViaGateway\(/.test(source) || - /collectStatusScanOverview\(/.test(source) + source.includes("resolveAgentRuntimeConfig(") || + source.includes("resolveCommandConfigWithSecrets(") || + source.includes("resolveCommandSecretRefsViaGateway(") || + source.includes("collectStatusScanOverview(") ); } function usesDelegatedStatusOverviewFlow(source: string): boolean { - return /collectStatusScanOverview\(/.test(source); + return source.includes("collectStatusScanOverview("); } describe("command secret resolution coverage", () => { diff --git a/src/cli/cron-cli/shared.ts b/src/cli/cron-cli/shared.ts index ec2664a380a..0d10567e90c 100644 --- a/src/cli/cron-cli/shared.ts +++ b/src/cli/cron-cli/shared.ts @@ -170,7 +170,7 @@ const truncate = (value: string, width: number) => { const formatIsoMinute = (iso: string) => { const parsed = parseAbsoluteTimeMs(iso); - const d = new Date(parsed ?? NaN); + const d = new Date(parsed ?? Number.NaN); if (Number.isNaN(d.getTime())) { return "-"; } diff --git a/src/cli/node-cli/daemon.ts b/src/cli/node-cli/daemon.ts index 53c84f508b9..7f85b9ce2ff 100644 --- a/src/cli/node-cli/daemon.ts +++ b/src/cli/node-cli/daemon.ts @@ -94,7 +94,7 @@ export async function runNodeDaemonInstall(opts: NodeDaemonInstallOptions) { const config = await loadNodeHostConfig(); const { host, port } = resolveNodeDefaults(opts, config); - if (!Number.isFinite(port ?? NaN) || (port ?? 0) <= 0) { + if (!Number.isFinite(port ?? Number.NaN) || (port ?? 0) <= 0) { fail("Invalid port"); return; } diff --git a/src/cli/program/route-specs.ts b/src/cli/program/route-specs.ts index 7fc1ca34da8..512a3ed11b6 100644 --- a/src/cli/program/route-specs.ts +++ b/src/cli/program/route-specs.ts @@ -8,7 +8,7 @@ import { } from "./routed-command-definitions.js"; export type RouteSpec = { - match: (path: string[]) => boolean; + matches: (path: string[]) => boolean; loadPlugins?: boolean | ((argv: string[]) => boolean); run: (argv: string[]) => Promise; }; @@ -25,7 +25,7 @@ function createParsedRoute(params: { definition: AnyRoutedCommandDefinition; }): RouteSpec { return { - match: (path) => + matches: (path) => matchesCommandPath(path, params.entry.commandPath, { exact: params.entry.exact }), loadPlugins: params.entry.route?.preloadPlugins ? createCommandLoadPlugins(params.entry.commandPath) diff --git a/src/cli/program/routes.ts b/src/cli/program/routes.ts index 5239df898f6..487115372c5 100644 --- a/src/cli/program/routes.ts +++ b/src/cli/program/routes.ts @@ -4,7 +4,7 @@ export type { RouteSpec } from "./route-specs.js"; export function findRoutedCommand(path: string[]): RouteSpec | null { for (const route of routedCommands) { - if (route.match(path)) { + if (route.matches(path)) { return route; } } diff --git a/src/commands/agent.test.ts b/src/commands/agent.test.ts index 609986caefa..5e21768ab03 100644 --- a/src/commands/agent.test.ts +++ b/src/commands/agent.test.ts @@ -178,7 +178,7 @@ vi.mock("../config/sessions/transcript-resolve.runtime.js", () => { return lastSlash >= 0 ? filePath.slice(0, lastSlash) : "."; }; const joinPath = (...parts: string[]): string => { - const separator = parts.find((part) => part.includes("\\")) ? "\\" : "/"; + const separator = parts.some((part) => part.includes("\\")) ? "\\" : "/"; return parts .map((part, index) => index === 0 ? part.replace(/[\\/]+$/u, "") : part.replace(/^[\\/]+|[\\/]+$/gu, ""), diff --git a/src/commands/doctor-config-flow.test.ts b/src/commands/doctor-config-flow.test.ts index aea2acb9e0a..cda4300d0d1 100644 --- a/src/commands/doctor-config-flow.test.ts +++ b/src/commands/doctor-config-flow.test.ts @@ -551,7 +551,7 @@ vi.mock("../channels/plugins/setup-promotion-helpers.js", () => { channel.accounts && typeof channel.accounts === "object" && !Array.isArray(channel.accounts) ? (channel.accounts as Record) : {}; - const hasNamedAccounts = Object.keys(accounts).filter(Boolean).length > 0; + const hasNamedAccounts = Object.keys(accounts).some(Boolean); const allowedNamedKeys = namedAccountPromotionKeys[channelKey]; return Object.entries(channel) .filter(([key, value]) => { diff --git a/src/config/redact-snapshot.ts b/src/config/redact-snapshot.ts index 4a362bd9919..f50d8d5eb76 100644 --- a/src/config/redact-snapshot.ts +++ b/src/config/redact-snapshot.ts @@ -19,9 +19,8 @@ const ENV_VAR_PLACEHOLDER_PATTERN = /^\$\{[^}]*\}$/; function isSensitivePath(path: string): boolean { if (path.endsWith("[]")) { return isSensitiveConfigPath(path.slice(0, -2)); - } else { - return isSensitiveConfigPath(path); } + return isSensitiveConfigPath(path); } function isEnvVarPlaceholder(value: string): boolean { @@ -146,9 +145,8 @@ function redactObject(obj: unknown, hints?: ConfigUiHints): unknown { return lookup.has("") ? redactObjectWithLookup(obj, lookup, "", [], hints) : redactObjectGuessing(obj, "", [], hints); - } else { - return redactObjectGuessing(obj, "", []); } + return redactObjectGuessing(obj, "", []); } /** diff --git a/src/cron/schedule.test.ts b/src/cron/schedule.test.ts index 1b4a09744b1..62ac2a647a8 100644 --- a/src/cron/schedule.test.ts +++ b/src/cron/schedule.test.ts @@ -210,7 +210,7 @@ describe("coerceFiniteScheduleNumber", () => { it("returns undefined for invalid inputs", () => { expect(coerceFiniteScheduleNumber("")).toBeUndefined(); expect(coerceFiniteScheduleNumber("abc")).toBeUndefined(); - expect(coerceFiniteScheduleNumber(NaN)).toBeUndefined(); + expect(coerceFiniteScheduleNumber(Number.NaN)).toBeUndefined(); expect(coerceFiniteScheduleNumber(Infinity)).toBeUndefined(); expect(coerceFiniteScheduleNumber(null)).toBeUndefined(); expect(coerceFiniteScheduleNumber(undefined)).toBeUndefined(); diff --git a/src/gateway/server-discovery-runtime.ts b/src/gateway/server-discovery-runtime.ts index eaf7c964f48..31b26270542 100644 --- a/src/gateway/server-discovery-runtime.ts +++ b/src/gateway/server-discovery-runtime.ts @@ -34,7 +34,7 @@ export async function startGatewayDiscovery(params: { ? await resolveTailnetDnsHint({ enabled: tailscaleEnabled }) : undefined; const sshPortEnv = mdnsMinimal ? undefined : process.env.OPENCLAW_SSH_PORT?.trim(); - const sshPortParsed = sshPortEnv ? Number.parseInt(sshPortEnv, 10) : NaN; + const sshPortParsed = sshPortEnv ? Number.parseInt(sshPortEnv, 10) : Number.NaN; const sshPort = Number.isFinite(sshPortParsed) && sshPortParsed > 0 ? sshPortParsed : undefined; const cliPath = mdnsMinimal ? undefined : resolveBonjourCliPath(); diff --git a/src/gateway/server-methods/agent-timestamp.ts b/src/gateway/server-methods/agent-timestamp.ts index eb13d12cf14..0039f12be4c 100644 --- a/src/gateway/server-methods/agent-timestamp.ts +++ b/src/gateway/server-methods/agent-timestamp.ts @@ -6,7 +6,7 @@ import { formatZonedTimestamp } from "../../infra/format-time/format-datetime.ts * Cron jobs inject "Current time: ..." into their messages. * Skip injection for those. */ -const CRON_TIME_PATTERN = /Current time: /; +const CRON_TIME_MARKER = "Current time: "; /** * Matches a leading `[... YYYY-MM-DD HH:MM ...]` envelope — either from @@ -49,7 +49,7 @@ export function injectTimestamp(message: string, opts?: TimestampInjectionOption } // Already has a cron-injected timestamp - if (CRON_TIME_PATTERN.test(message)) { + if (message.includes(CRON_TIME_MARKER)) { return message; } diff --git a/src/gateway/server-reload-handlers.ts b/src/gateway/server-reload-handlers.ts index 919710aa790..630639f6a87 100644 --- a/src/gateway/server-reload-handlers.ts +++ b/src/gateway/server-reload-handlers.ts @@ -278,15 +278,14 @@ export function createGatewayReloadHandlers(params: GatewayReloadHandlerParams) }, }); return true; - } else { - // No active operations or pending replies, restart immediately - params.logReload.warn(`config change requires gateway restart (${reasons})`); - const emitted = emitGatewayRestart(); - if (!emitted) { - params.logReload.info("gateway restart already scheduled; skipping duplicate signal"); - } - return true; } + // No active operations or pending replies, restart immediately + params.logReload.warn(`config change requires gateway restart (${reasons})`); + const emitted = emitGatewayRestart(); + if (!emitted) { + params.logReload.info("gateway restart already scheduled; skipping duplicate signal"); + } + return true; }; return { applyHotReload, requestGatewayRestart }; diff --git a/src/gateway/test-helpers.openai-mock.ts b/src/gateway/test-helpers.openai-mock.ts index 163b2638181..279c46fbd87 100644 --- a/src/gateway/test-helpers.openai-mock.ts +++ b/src/gateway/test-helpers.openai-mock.ts @@ -218,7 +218,7 @@ export function installOpenAiResponsesMock(params?: { baseUrl?: string }) { if (isResponsesRequest(url)) { const bodyText = - typeof (init as { body?: unknown } | undefined)?.body !== "undefined" + (init as { body?: unknown } | undefined)?.body !== undefined ? decodeBodyText((init as { body?: unknown }).body) : input instanceof Request ? await input.clone().text() diff --git a/src/infra/format-time/format-time.test.ts b/src/infra/format-time/format-time.test.ts index 75f8c8b649b..bea87370f4d 100644 --- a/src/infra/format-time/format-time.test.ts +++ b/src/infra/format-time/format-time.test.ts @@ -91,7 +91,7 @@ describe("format-duration", () => { { input: 1000, expected: "1s" }, { input: 1500, expected: "1.5s" }, { input: 1234, expected: "1.23s" }, - { input: NaN, expected: "unknown" }, + { input: Number.NaN, expected: "unknown" }, { input: Infinity, expected: "unknown" }, ])("formats precise duration for %j", ({ input, expected }) => { expect(formatDurationPrecise(input)).toBe(expected); @@ -105,7 +105,7 @@ describe("format-duration", () => { { input: 1000, options: { decimals: 0 }, expected: "1s" }, { input: 2000, options: { unit: "seconds" as const }, expected: "2 seconds" }, { input: -1500, options: { decimals: 1 }, expected: "0s" }, - { input: NaN, options: undefined, expected: "unknown" }, + { input: Number.NaN, options: undefined, expected: "unknown" }, { input: Infinity, options: undefined, expected: "unknown" }, ])("formats seconds duration for %j", ({ input, options, expected }) => { expect(formatDurationSeconds(input, options)).toBe(expected); diff --git a/src/infra/ports-inspect.ts b/src/infra/ports-inspect.ts index 14d973f66f7..6789f99ed93 100644 --- a/src/infra/ports-inspect.ts +++ b/src/infra/ports-inspect.ts @@ -219,7 +219,7 @@ function parseNetstatListeners(output: string, port: number): PortListener[] { continue; } const pidRaw = parts.at(-1); - const pid = pidRaw ? Number.parseInt(pidRaw, 10) : NaN; + const pid = pidRaw ? Number.parseInt(pidRaw, 10) : Number.NaN; const localAddr = parts[1]; const listener: PortListener = {}; if (Number.isFinite(pid)) { diff --git a/src/infra/provider-usage.fetch.codex.ts b/src/infra/provider-usage.fetch.codex.ts index b7ad369a671..b640b7bf5a5 100644 --- a/src/infra/provider-usage.fetch.codex.ts +++ b/src/infra/provider-usage.fetch.codex.ts @@ -110,7 +110,7 @@ export async function fetchCodexUsage( const balance = typeof data.credits.balance === "number" ? data.credits.balance - : parseFloat(data.credits.balance) || 0; + : Number.parseFloat(data.credits.balance) || 0; plan = plan ? `${plan} ($${balance.toFixed(2)})` : `$${balance.toFixed(2)}`; } diff --git a/src/logging/diagnostic-stability.ts b/src/logging/diagnostic-stability.ts index 1965159b589..b0a1ca59fad 100644 --- a/src/logging/diagnostic-stability.ts +++ b/src/logging/diagnostic-stability.ts @@ -380,7 +380,7 @@ function parseOptionalNonNegativeInteger(value: unknown, field: string): number return undefined; } const parsed = - typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN; + typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN; if (!Number.isInteger(parsed) || parsed < 0) { throw new Error(`${field} must be a non-negative integer`); } diff --git a/src/plugin-sdk/core.ts b/src/plugin-sdk/core.ts index 80c325606fd..61000fb1285 100644 --- a/src/plugin-sdk/core.ts +++ b/src/plugin-sdk/core.ts @@ -243,7 +243,7 @@ export type ChannelOutboundSessionRouteParams = Parameters< NonNullable >[0]; -var cachedSdkChatChannelMeta: +let cachedSdkChatChannelMeta: | { cacheKey: string; metaById: ReturnType; diff --git a/src/plugins/command-registration.ts b/src/plugins/command-registration.ts index 45101a5c431..7a6e3f63762 100644 --- a/src/plugins/command-registration.ts +++ b/src/plugins/command-registration.ts @@ -22,7 +22,7 @@ import type { OpenClawPluginCommandDefinition } from "./types.js"; * output chunk, so any module-level const/let would be uninitialized when * first accessed during plugin registration. */ -var reservedCommands: Set | undefined; +let reservedCommands: Set | undefined; export type CommandRegistrationResult = { ok: boolean; diff --git a/src/security/skill-scanner.ts b/src/security/skill-scanner.ts index 45a57c2711c..2e2ffd14d2b 100644 --- a/src/security/skill-scanner.ts +++ b/src/security/skill-scanner.ts @@ -241,7 +241,7 @@ export function scanSource(source: string, filePath: string): SkillScanFinding[] // Special handling for suspicious-network: check port if (rule.ruleId === "suspicious-network") { - const port = parseInt(match[1], 10); + const port = Number.parseInt(match[1], 10); if (STANDARD_PORTS.has(port)) { continue; } diff --git a/src/tui/tui-command-handlers.ts b/src/tui/tui-command-handlers.ts index a714be8996e..8be0ae6b41d 100644 --- a/src/tui/tui-command-handlers.ts +++ b/src/tui/tui-command-handlers.ts @@ -497,7 +497,7 @@ export function createCommandHandlers(context: CommandHandlerContext) { chatLog.addSystem(`elevated failed: ${String(err)}`); } break; - case "activation": + case "activation": { if (!args) { chatLog.addSystem("usage: /activation "); break; @@ -519,6 +519,7 @@ export function createCommandHandlers(context: CommandHandlerContext) { chatLog.addSystem(`activation failed: ${String(err)}`); } break; + } case "new": try { // Clear token counts immediately to avoid stale display (#1523) diff --git a/src/utils/usage-format.ts b/src/utils/usage-format.ts index b805bd60567..b26504b9fe2 100644 --- a/src/utils/usage-format.ts +++ b/src/utils/usage-format.ts @@ -144,7 +144,7 @@ function normalizeTieredPricing(raw: RawPricingTier[] | undefined): PricingTier[ if (!Array.isArray(range) || range.length < 1) { continue; } - const start = typeof range[0] === "number" ? range[0] : NaN; + const start = typeof range[0] === "number" ? range[0] : Number.NaN; if (!Number.isFinite(start)) { continue; } diff --git a/ui/src/ui/chat/context-notice.ts b/ui/src/ui/chat/context-notice.ts index 79fd05bba5f..89a8528997a 100644 --- a/ui/src/ui/chat/context-notice.ts +++ b/ui/src/ui/chat/context-notice.ts @@ -7,7 +7,11 @@ function parseHexRgb(hex: string): [number, number, number] | null { if (!/^[0-9a-fA-F]{6}$/.test(h)) { return null; } - return [parseInt(h.slice(0, 2), 16), parseInt(h.slice(2, 4), 16), parseInt(h.slice(4, 6), 16)]; + return [ + Number.parseInt(h.slice(0, 2), 16), + Number.parseInt(h.slice(2, 4), 16), + Number.parseInt(h.slice(4, 6), 16), + ]; } let cachedThemeNoticeColors: { diff --git a/ui/src/ui/views/usage-render-overview.ts b/ui/src/ui/views/usage-render-overview.ts index b62981ce43e..42e0ac7331d 100644 --- a/ui/src/ui/views/usage-render-overview.ts +++ b/ui/src/ui/views/usage-render-overview.ts @@ -219,7 +219,8 @@ function renderDailyChartCompact( const isSelected = selectedDays.includes(d.date); const label = formatDayLabel(d.date); // Shorter label for many days (just day number) - const shortLabel = daily.length > 20 ? String(parseInt(d.date.slice(8), 10)) : label; + const shortLabel = + daily.length > 20 ? String(Number.parseInt(d.date.slice(8), 10)) : label; const labelClass = daily.length > 20 ? "daily-bar-label daily-bar-label--compact" : "daily-bar-label"; const segments =