diff --git a/.oxlintrc.json b/.oxlintrc.json index 233e576de1bd..bae3e40abb57 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -26,6 +26,7 @@ "eslint/no-sequences": "error", "eslint/no-self-compare": "error", "eslint/no-shadow": "off", + "eslint/no-implicit-coercion": "error", "eslint/no-var": "error", "eslint/no-useless-call": "error", "eslint/no-useless-computed-key": "error", @@ -41,6 +42,7 @@ "eslint/default-param-last": "error", "eslint/prefer-exponentiation-operator": "error", "eslint/prefer-numeric-literals": "error", + "eslint/prefer-object-has-own": "error", "eslint/prefer-rest-params": "error", "eslint/prefer-spread": "error", "eslint/radix": "error", @@ -66,6 +68,7 @@ "typescript/no-empty-object-type": ["error", { "allowInterfaces": "with-single-extends" }], "typescript/no-explicit-any": "error", "typescript/no-extraneous-class": "error", + "typescript/no-import-type-side-effects": "error", "typescript/no-meaningless-void-operator": "error", "typescript/no-non-null-asserted-nullish-coalescing": "error", "typescript/no-unnecessary-qualifier": "error", @@ -111,6 +114,7 @@ "unicorn/no-unnecessary-slice-end": "error", "unicorn/no-useless-error-capture-stack-trace": "error", "unicorn/no-useless-promise-resolve-reject": "error", + "unicorn/no-zero-fractions": "error", "unicorn/prefer-date-now": "error", "unicorn/prefer-dom-node-text-content": "error", "unicorn/prefer-keyboard-event-key": "error", @@ -183,6 +187,7 @@ "docs/_layouts/", "extensions/diffs/assets/viewer-runtime.js", "extensions/diffs-language-pack/assets/viewer-runtime.js", + "extensions/canvas/src/host/a2ui/a2ui.bundle.js", "node_modules/", "patches/", "pnpm-lock.yaml", diff --git a/extensions/acpx/src/process-lease.ts b/extensions/acpx/src/process-lease.ts index 46af800ed188..b8515a9e6caf 100644 --- a/extensions/acpx/src/process-lease.ts +++ b/extensions/acpx/src/process-lease.ts @@ -75,7 +75,7 @@ async function readLeaseFile(filePath: string): Promise { leases: [], }); const leases = Array.isArray(value.leases) - ? value.leases.map(normalizeLease).filter((lease): lease is AcpxProcessLease => !!lease) + ? value.leases.map(normalizeLease).filter((lease): lease is AcpxProcessLease => Boolean(lease)) : []; return { version: 1, leases }; } diff --git a/extensions/admin-http-rpc/src/handler.ts b/extensions/admin-http-rpc/src/handler.ts index 9e45aa17db61..aa9db1016cde 100644 --- a/extensions/admin-http-rpc/src/handler.ts +++ b/extensions/admin-http-rpc/src/handler.ts @@ -127,9 +127,7 @@ function readRpcRequestBody(body: unknown): request: { id, method: rpcBody.method.trim(), - ...(Object.prototype.hasOwnProperty.call(rpcBody, "params") - ? { params: rpcBody.params } - : {}), + ...(Object.hasOwn(rpcBody, "params") ? { params: rpcBody.params } : {}), }, }; } diff --git a/extensions/amazon-bedrock/discovery.ts b/extensions/amazon-bedrock/discovery.ts index 10518cab7dce..2b2b16e822a7 100644 --- a/extensions/amazon-bedrock/discovery.ts +++ b/extensions/amazon-bedrock/discovery.ts @@ -1,7 +1,7 @@ -import { - type BedrockClient, - type ListFoundationModelsCommandOutput, - type ListInferenceProfilesCommandOutput, +import type { + BedrockClient, + ListFoundationModelsCommandOutput, + ListInferenceProfilesCommandOutput, } from "@aws-sdk/client-bedrock"; import { createSubsystemLogger } from "openclaw/plugin-sdk/core"; import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; diff --git a/extensions/arcee/models.ts b/extensions/arcee/models.ts index 5c84d3a8e1be..190717ea684b 100644 --- a/extensions/arcee/models.ts +++ b/extensions/arcee/models.ts @@ -26,7 +26,7 @@ export const ARCEE_MODEL_CATALOG: ModelDefinitionConfig[] = [ maxTokens: 16384, cost: { input: 0.25, - output: 1.0, + output: 1, cacheRead: 0.25, cacheWrite: 0.25, }, diff --git a/extensions/brave/web-search-contract-api.ts b/extensions/brave/web-search-contract-api.ts index 4cf7feee271a..89ebf172c7ca 100644 --- a/extensions/brave/web-search-contract-api.ts +++ b/extensions/brave/web-search-contract-api.ts @@ -1,4 +1,4 @@ -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; import { buildBraveWebSearchProviderBase } from "./web-search-shared.js"; export function createBraveWebSearchProvider(): WebSearchProviderPlugin { diff --git a/extensions/browser/setup-api.ts b/extensions/browser/setup-api.ts index 1cc2cb6922c5..c0734d7c6a93 100644 --- a/extensions/browser/setup-api.ts +++ b/extensions/browser/setup-api.ts @@ -38,13 +38,10 @@ export default definePluginEntry({ ) { return null; } - if (Object.prototype.hasOwnProperty.call(config, "browser")) { + if (Object.hasOwn(config, "browser")) { return "browser configured"; } - if ( - config.plugins?.entries && - Object.prototype.hasOwnProperty.call(config.plugins.entries, "browser") - ) { + if (config.plugins?.entries && Object.hasOwn(config.plugins.entries, "browser")) { return "browser plugin configured"; } if (hasBrowserToolReference(config)) { diff --git a/extensions/browser/src/browser/config.ts b/extensions/browser/src/browser/config.ts index e5d4c13eff3a..f980170eee4f 100644 --- a/extensions/browser/src/browser/config.ts +++ b/extensions/browser/src/browser/config.ts @@ -5,11 +5,7 @@ import { normalizeOptionalString, normalizeOptionalTrimmedStringList, } from "openclaw/plugin-sdk/string-coerce-runtime"; -import { - type BrowserConfig, - type BrowserProfileConfig, - type OpenClawConfig, -} from "../config/config.js"; +import type { BrowserConfig, BrowserProfileConfig, OpenClawConfig } from "../config/config.js"; import { resolveGatewayPort } from "../config/paths.js"; import { DEFAULT_BROWSER_CONTROL_PORT, diff --git a/extensions/browser/src/browser/routes/basic.ts b/extensions/browser/src/browser/routes/basic.ts index 926274dcaa7d..173e1e3d70d8 100644 --- a/extensions/browser/src/browser/routes/basic.ts +++ b/extensions/browser/src/browser/routes/basic.ts @@ -269,7 +269,7 @@ async function runBrowserLiveProbe(req: BrowserRequest, ctx: BrowserRouteContext } function hasQueryKey(query: BrowserRequest["query"], key: string): boolean { - return Object.prototype.hasOwnProperty.call(query ?? {}, key); + return Object.hasOwn(query ?? {}, key); } function parseHeadlessStartOverride(params: { diff --git a/extensions/browser/src/doctor-browser.ts b/extensions/browser/src/doctor-browser.ts index 747d47188beb..42a6aafa5b3e 100644 --- a/extensions/browser/src/doctor-browser.ts +++ b/extensions/browser/src/doctor-browser.ts @@ -133,7 +133,7 @@ function isLegacyClawdProfileConfigured(cfg: OpenClawConfig, legacyProfileDir: s if (!configuredProfiles) { return false; } - if (Object.prototype.hasOwnProperty.call(configuredProfiles, LEGACY_CLAWD_BROWSER_PROFILE_NAME)) { + if (Object.hasOwn(configuredProfiles, LEGACY_CLAWD_BROWSER_PROFILE_NAME)) { return true; } diff --git a/extensions/canvas/src/host/a2ui-app/bootstrap.js b/extensions/canvas/src/host/a2ui-app/bootstrap.js index 192fc1610cba..f1aba7394dcd 100644 --- a/extensions/canvas/src/host/a2ui-app/bootstrap.js +++ b/extensions/canvas/src/host/a2ui-app/bootstrap.js @@ -457,15 +457,15 @@ class OpenClawA2UIHost extends LitElement { context[key] = resolved; continue; } - if (Object.prototype.hasOwnProperty.call(value, "literalString")) { + if (Object.hasOwn(value, "literalString")) { context[key] = value.literalString ?? ""; continue; } - if (Object.prototype.hasOwnProperty.call(value, "literalNumber")) { + if (Object.hasOwn(value, "literalNumber")) { context[key] = value.literalNumber ?? 0; continue; } - if (Object.prototype.hasOwnProperty.call(value, "literalBoolean")) { + if (Object.hasOwn(value, "literalBoolean")) { context[key] = value.literalBoolean ?? false; continue; } diff --git a/extensions/canvas/src/tool.ts b/extensions/canvas/src/tool.ts index b4d096ea89db..5485c3655f0f 100644 --- a/extensions/canvas/src/tool.ts +++ b/extensions/canvas/src/tool.ts @@ -54,7 +54,7 @@ async function writeBase64ToTempFile(params: { base64: string; ext: string }): P function isPathInsideRoot(root: string, candidate: string): boolean { const relative = path.relative(root, candidate); return ( - relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative)) + relative === "" || (relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)) ); } diff --git a/extensions/codex/doctor-contract-api.ts b/extensions/codex/doctor-contract-api.ts index f226b4d2958c..63acb691d4fe 100644 --- a/extensions/codex/doctor-contract-api.ts +++ b/extensions/codex/doctor-contract-api.ts @@ -14,7 +14,7 @@ function asRecord(value: unknown): Record | null { } function hasRetiredDynamicToolsProfile(value: unknown): boolean { - return Object.prototype.hasOwnProperty.call(asRecord(value) ?? {}, "codexDynamicToolsProfile"); + return Object.hasOwn(asRecord(value) ?? {}, "codexDynamicToolsProfile"); } export const legacyConfigRules: LegacyConfigRule[] = [ diff --git a/extensions/codex/media-understanding-provider.ts b/extensions/codex/media-understanding-provider.ts index db218b294364..4c78519a0b39 100644 --- a/extensions/codex/media-understanding-provider.ts +++ b/extensions/codex/media-understanding-provider.ts @@ -2,16 +2,16 @@ import { type JsonSchemaObject, validateJsonSchemaValue, } from "openclaw/plugin-sdk/json-schema-runtime"; -import { - type ImagesDescriptionRequest, - type ImagesDescriptionResult, - type MediaUnderstandingProvider, - type StructuredExtractionRequest, - type StructuredExtractionResult, +import type { + ImagesDescriptionRequest, + ImagesDescriptionResult, + MediaUnderstandingProvider, + StructuredExtractionRequest, + StructuredExtractionResult, } from "openclaw/plugin-sdk/media-understanding"; import { resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime"; import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js"; -import { type CodexAppServerClientFactory } from "./src/app-server/client-factory.js"; +import type { CodexAppServerClientFactory } from "./src/app-server/client-factory.js"; import type { CodexAppServerClient } from "./src/app-server/client.js"; import { resolveCodexAppServerRuntimeOptions } from "./src/app-server/config.js"; import { readModelListResult } from "./src/app-server/models.js"; diff --git a/extensions/codex/src/app-server/dynamic-tools.ts b/extensions/codex/src/app-server/dynamic-tools.ts index d30743c3e03c..bafad056233e 100644 --- a/extensions/codex/src/app-server/dynamic-tools.ts +++ b/extensions/codex/src/app-server/dynamic-tools.ts @@ -1,5 +1,4 @@ import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core"; -import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime"; import { createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, @@ -21,6 +20,7 @@ import { type MessagingToolSourceReplyPayload, wrapToolWithBeforeToolCallHook, } from "openclaw/plugin-sdk/agent-harness-runtime"; +import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime"; import type { ImageContent, TextContent } from "openclaw/plugin-sdk/llm"; import { normalizeAgentId } from "openclaw/plugin-sdk/routing"; import { @@ -29,13 +29,13 @@ import { } from "openclaw/plugin-sdk/string-coerce-runtime"; import type { CodexDynamicToolsLoading } from "./config.js"; import { invalidInlineImageText, sanitizeInlineImageDataUrl } from "./image-payload-sanitizer.js"; -import { - type CodexDynamicToolCallOutputContentItem, - type CodexDynamicToolCallParams, - type CodexDynamicToolCallResponse, - type CodexDynamicToolDiagnosticTerminalType, - type CodexDynamicToolSpec, - type JsonValue, +import type { + CodexDynamicToolCallOutputContentItem, + CodexDynamicToolCallParams, + CodexDynamicToolCallResponse, + CodexDynamicToolDiagnosticTerminalType, + CodexDynamicToolSpec, + JsonValue, } from "./protocol.js"; type CodexDynamicToolHookContext = { diff --git a/extensions/codex/src/app-server/elicitation-bridge.ts b/extensions/codex/src/app-server/elicitation-bridge.ts index aa94550d6418..c1bd1e0ddc49 100644 --- a/extensions/codex/src/app-server/elicitation-bridge.ts +++ b/extensions/codex/src/app-server/elicitation-bridge.ts @@ -508,7 +508,7 @@ function formatDisplayJsonValue(value: JsonValue, depth = MAX_DISPLAY_VALUE_DEPT let count = 0; let truncated = false; for (const key in value) { - if (!Object.prototype.hasOwnProperty.call(value, key)) { + if (!Object.hasOwn(value, key)) { continue; } if (count >= MAX_DISPLAY_VALUE_OBJECT_KEYS) { diff --git a/extensions/codex/src/app-server/plugin-activation.ts b/extensions/codex/src/app-server/plugin-activation.ts index c342bfbf3e59..4fb9911547e4 100644 --- a/extensions/codex/src/app-server/plugin-activation.ts +++ b/extensions/codex/src/app-server/plugin-activation.ts @@ -1,9 +1,6 @@ import fs from "node:fs/promises"; import path from "node:path"; -import { - type CodexAppInventoryCache, - type CodexAppInventoryRequest, -} from "./app-inventory-cache.js"; +import type { CodexAppInventoryCache, CodexAppInventoryRequest } from "./app-inventory-cache.js"; import { CODEX_PLUGINS_MARKETPLACE_NAME, type ResolvedCodexPluginPolicy } from "./config.js"; import { findOpenAiCuratedPluginSummary, diff --git a/extensions/codex/src/app-server/plugin-inventory.ts b/extensions/codex/src/app-server/plugin-inventory.ts index 81a04354aace..aaa7a00d35c9 100644 --- a/extensions/codex/src/app-server/plugin-inventory.ts +++ b/extensions/codex/src/app-server/plugin-inventory.ts @@ -1,8 +1,8 @@ import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime"; -import { - type CodexAppInventoryCache, - type CodexAppInventoryCacheRead, - type CodexAppInventoryRequest, +import type { + CodexAppInventoryCache, + CodexAppInventoryCacheRead, + CodexAppInventoryRequest, } from "./app-inventory-cache.js"; import { CODEX_PLUGINS_MARKETPLACE_NAME, diff --git a/extensions/codex/src/app-server/protocol-validators.ts b/extensions/codex/src/app-server/protocol-validators.ts index 756ca2dcdcb0..55bf543b545c 100644 --- a/extensions/codex/src/app-server/protocol-validators.ts +++ b/extensions/codex/src/app-server/protocol-validators.ts @@ -107,7 +107,7 @@ function normalizeJsonSchemaNode(schema: unknown): unknown { } function readDefault(schema: unknown): unknown { - if (!isRecord(schema) || !Object.prototype.hasOwnProperty.call(schema, "default")) { + if (!isRecord(schema) || !Object.hasOwn(schema, "default")) { return undefined; } return structuredClone(schema.default); @@ -176,7 +176,7 @@ function applySchemaDefaults( } if (isRecord(schema.additionalProperties)) { for (const key of Object.keys(nextValue)) { - if (Object.prototype.hasOwnProperty.call(schema.properties, key)) { + if (Object.hasOwn(schema.properties, key)) { continue; } nextValue[key] = applySchemaDefaults( diff --git a/extensions/codex/src/app-server/run-attempt.ts b/extensions/codex/src/app-server/run-attempt.ts index 026c65d38464..ac42afbbab0e 100644 --- a/extensions/codex/src/app-server/run-attempt.ts +++ b/extensions/codex/src/app-server/run-attempt.ts @@ -192,15 +192,15 @@ import { assertCodexTurnStartResponse, readCodexDynamicToolCallParams, } from "./protocol-validators.js"; -import { - type CodexSandboxPolicy, - type CodexTurnEnvironmentParams, - type CodexServerNotification, - type CodexDynamicToolCallParams, - type CodexDynamicToolCallResponse, - type CodexTurnStartResponse, - type JsonObject, - type JsonValue, +import type { + CodexSandboxPolicy, + CodexTurnEnvironmentParams, + CodexServerNotification, + CodexDynamicToolCallParams, + CodexDynamicToolCallResponse, + CodexTurnStartResponse, + JsonObject, + JsonValue, } from "./protocol.js"; import { releaseCodexSandboxExecServerEnvironment } from "./sandbox-exec-server.js"; import { diff --git a/extensions/codex/src/command-account.ts b/extensions/codex/src/command-account.ts index 01e0277d07e8..6b8eb65065ca 100644 --- a/extensions/codex/src/command-account.ts +++ b/extensions/codex/src/command-account.ts @@ -226,7 +226,7 @@ function resolveActiveProfileId(params: { params.store.lastGood?.[OPENAI_CODEX_PROVIDER_ID], ].find( (profileId): profileId is string => - !!profileId && + Boolean(profileId) && params.order.includes(profileId) && isActiveProfileCandidate(params, profileId), ); diff --git a/extensions/codex/src/conversation-binding.ts b/extensions/codex/src/conversation-binding.ts index 93d8d7337461..32180895db8c 100644 --- a/extensions/codex/src/conversation-binding.ts +++ b/extensions/codex/src/conversation-binding.ts @@ -25,12 +25,12 @@ import { type CodexAppServerSandboxMode, type OpenClawExecPolicyForCodexAppServer, } from "./app-server/config.js"; -import { - type CodexServiceTier, - type CodexThreadResumeResponse, - type CodexThreadStartResponse, - type CodexTurnStartResponse, - type JsonValue, +import type { + CodexServiceTier, + CodexThreadResumeResponse, + CodexThreadStartResponse, + CodexTurnStartResponse, + JsonValue, } from "./app-server/protocol.js"; import { resolveCodexNativeExecutionBlock, diff --git a/extensions/deepinfra/provider-catalog.ts b/extensions/deepinfra/provider-catalog.ts index 07bf65d1da7e..5b5be3f5647a 100644 --- a/extensions/deepinfra/provider-catalog.ts +++ b/extensions/deepinfra/provider-catalog.ts @@ -3,7 +3,7 @@ import { type ProviderCatalogContext, type ProviderCatalogResult, } from "openclaw/plugin-sdk/provider-catalog-shared"; -import { type ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; +import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; import { DEEPINFRA_BASE_URL, DEEPINFRA_MODEL_CATALOG, diff --git a/extensions/deepinfra/provider-discovery.ts b/extensions/deepinfra/provider-discovery.ts index 5524f29d4c4a..bdcd77f216c7 100644 --- a/extensions/deepinfra/provider-discovery.ts +++ b/extensions/deepinfra/provider-discovery.ts @@ -1,4 +1,4 @@ -import { type ProviderCatalogContext } from "openclaw/plugin-sdk/provider-catalog-shared"; +import type { ProviderCatalogContext } from "openclaw/plugin-sdk/provider-catalog-shared"; import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared"; import { buildDeepInfraApiKeyCatalog, buildStaticDeepInfraProvider } from "./provider-catalog.js"; diff --git a/extensions/deepinfra/provider-models.ts b/extensions/deepinfra/provider-models.ts index e57a85094c54..d0dbc7915714 100644 --- a/extensions/deepinfra/provider-models.ts +++ b/extensions/deepinfra/provider-models.ts @@ -293,13 +293,13 @@ const STATIC_NON_CHAT_FALLBACK: DeepInfraSurfaceModel[] = [ id: "ResembleAI/chatterbox-turbo", name: "ResembleAI/chatterbox-turbo", tags: ["tts"], - pricing: { input_characters: 1.0 }, + pricing: { input_characters: 1 }, }, { id: "sesame/csm-1b", name: "sesame/csm-1b", tags: ["tts"], - pricing: { input_characters: 7.0 }, + pricing: { input_characters: 7 }, }, // stt { diff --git a/extensions/discord/src/account-inspect.ts b/extensions/discord/src/account-inspect.ts index 2b2783765e4f..e6e2d1a0038e 100644 --- a/extensions/discord/src/account-inspect.ts +++ b/extensions/discord/src/account-inspect.ts @@ -33,8 +33,7 @@ export function inspectDiscordAccount(params: { const enabled = params.cfg.channels?.discord?.enabled !== false && merged.enabled !== false; const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId); const hasAccountToken = Boolean( - accountConfig && - Object.prototype.hasOwnProperty.call(accountConfig as Record, "token"), + accountConfig && Object.hasOwn(accountConfig as Record, "token"), ); const accountToken = inspectDiscordConfiguredToken(accountConfig?.token); if (accountToken) { diff --git a/extensions/discord/src/channel.setup.ts b/extensions/discord/src/channel.setup.ts index 71d95e333408..7f0805b6f819 100644 --- a/extensions/discord/src/channel.setup.ts +++ b/extensions/discord/src/channel.setup.ts @@ -1,5 +1,5 @@ -import { type ResolvedDiscordAccount } from "./accounts.js"; -import { type ChannelPlugin } from "./channel-api.js"; +import type { ResolvedDiscordAccount } from "./accounts.js"; +import type { ChannelPlugin } from "./channel-api.js"; import { discordSetupWizard } from "./channel.runtime.js"; import { discordSetupAdapter } from "./setup-adapter.js"; import { createDiscordPluginBase } from "./shared.js"; diff --git a/extensions/discord/src/doctor-contract.ts b/extensions/discord/src/doctor-contract.ts index 4a9ccf29b841..1c7f65e0875e 100644 --- a/extensions/discord/src/doctor-contract.ts +++ b/extensions/discord/src/doctor-contract.ts @@ -18,7 +18,7 @@ function hasLegacyTtsProviderKeys(value: unknown): boolean { if (!tts) { return false; } - return LEGACY_TTS_PROVIDER_KEYS.some((key) => Object.prototype.hasOwnProperty.call(tts, key)); + return LEGACY_TTS_PROVIDER_KEYS.some((key) => Object.hasOwn(tts, key)); } function hasLegacyDiscordAccountTtsProviderKeys(value: unknown): boolean { @@ -44,7 +44,7 @@ function hasLegacyDiscordGuildChannelAllowAlias(value: unknown): boolean { return false; } return Object.values(channels).some((channel) => - Object.prototype.hasOwnProperty.call(asObjectRecord(channel) ?? {}, "allow"), + Object.hasOwn(asObjectRecord(channel) ?? {}, "allow"), ); }); } @@ -60,7 +60,7 @@ function hasLegacyDiscordGuildChannelAgentId(value: unknown): boolean { return false; } return Object.values(channels).some((channel) => - Object.prototype.hasOwnProperty.call(asObjectRecord(channel) ?? {}, "agentId"), + Object.hasOwn(asObjectRecord(channel) ?? {}, "agentId"), ); }); } @@ -284,7 +284,7 @@ function normalizeDiscordGuildChannelAllowAliases(params: { const nextChannels = { ...channels }; for (const [channelId, channelValue] of Object.entries(channels)) { const channel = asObjectRecord(channelValue); - if (!channel || !Object.prototype.hasOwnProperty.call(channel, "allow")) { + if (!channel || !Object.hasOwn(channel, "allow")) { continue; } const nextChannel = { ...channel }; @@ -359,7 +359,7 @@ function normalizeDiscordGuildChannelAgentIds(params: { const nextChannels = { ...channels }; for (const [channelId, channelValue] of Object.entries(channels)) { const channel = asObjectRecord(channelValue); - if (!channel || !Object.prototype.hasOwnProperty.call(channel, "agentId")) { + if (!channel || !Object.hasOwn(channel, "agentId")) { continue; } const nextChannel = { ...channel }; diff --git a/extensions/discord/src/doctor.ts b/extensions/discord/src/doctor.ts index b1db0871e91a..e7c2cf474397 100644 --- a/extensions/discord/src/doctor.ts +++ b/extensions/discord/src/doctor.ts @@ -1,4 +1,4 @@ -import { type ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; +import type { ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { collectProviderDangerousNameMatchingScopes } from "openclaw/plugin-sdk/runtime-doctor"; import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; diff --git a/extensions/discord/src/internal/interaction-options.ts b/extensions/discord/src/internal/interaction-options.ts index c9cda63b7a75..425569875a9f 100644 --- a/extensions/discord/src/internal/interaction-options.ts +++ b/extensions/discord/src/internal/interaction-options.ts @@ -1,8 +1,8 @@ -import { - type APIApplicationCommandInteractionDataBasicOption, - type APIApplicationCommandInteractionDataOption, - type APIChannel, - type APIInteractionDataResolvedChannel, +import type { + APIApplicationCommandInteractionDataBasicOption, + APIApplicationCommandInteractionDataOption, + APIChannel, + APIInteractionDataResolvedChannel, } from "discord-api-types/v10"; import { channelFactory, type DiscordChannel, type StructureClient } from "./structures.js"; diff --git a/extensions/discord/src/internal/modal-fields.ts b/extensions/discord/src/internal/modal-fields.ts index 1b226c235987..49a100abd2de 100644 --- a/extensions/discord/src/internal/modal-fields.ts +++ b/extensions/discord/src/internal/modal-fields.ts @@ -1,4 +1,4 @@ -import { type APIRole, type APIUser } from "discord-api-types/v10"; +import type { APIRole, APIUser } from "discord-api-types/v10"; import { Role, User, type StructureClient } from "./structures.js"; type ModalResolvedData = { diff --git a/extensions/discord/src/internal/structures.ts b/extensions/discord/src/internal/structures.ts index 7c886a0196d1..09e048d0c7e8 100644 --- a/extensions/discord/src/internal/structures.ts +++ b/extensions/discord/src/internal/structures.ts @@ -1,12 +1,12 @@ -import { - type APIChannel, - type APIEmbed, - type APIGuild, - type APIGuildMember, - type APIMessage, - type APIRole, - type APIUser, - type MessageType, +import type { + APIChannel, + APIEmbed, + APIGuild, + APIGuildMember, + APIMessage, + APIRole, + APIUser, + MessageType, } from "discord-api-types/v10"; import { createChannelMessage, diff --git a/extensions/discord/src/monitor/agent-components-context.ts b/extensions/discord/src/monitor/agent-components-context.ts index 0c4ef9615a9d..e9c71e810faf 100644 --- a/extensions/discord/src/monitor/agent-components-context.ts +++ b/extensions/discord/src/monitor/agent-components-context.ts @@ -1,12 +1,12 @@ import { ChannelType } from "discord-api-types/v10"; import { logError } from "openclaw/plugin-sdk/logging-core"; import { resolveAgentRoute } from "openclaw/plugin-sdk/routing"; -import { - type AgentComponentContext, - type AgentComponentInteraction, - type AgentComponentMessageInteraction, - type ComponentInteractionContext, - type DiscordChannelContext, +import type { + AgentComponentContext, + AgentComponentInteraction, + AgentComponentMessageInteraction, + ComponentInteractionContext, + DiscordChannelContext, } from "./agent-components.types.js"; import { normalizeDiscordDisplaySlug, normalizeDiscordSlug } from "./allow-list.js"; import { resolveDiscordChannelInfoSafe } from "./channel-access.js"; diff --git a/extensions/discord/src/monitor/message-handler.preflight.ts b/extensions/discord/src/monitor/message-handler.preflight.ts index ebb285ce3b34..bb1866042910 100644 --- a/extensions/discord/src/monitor/message-handler.preflight.ts +++ b/extensions/discord/src/monitor/message-handler.preflight.ts @@ -455,7 +455,7 @@ export async function preflightDiscordMessage( }) : null; logDebug( - `[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${!!params.data.guild} guild_obj_id=${params.data.guild?.id} guildInfo=${!!guildInfo} guildEntries=${params.guildEntries ? Object.keys(params.guildEntries).join(",") : "none"}`, + `[discord-preflight] guild_id=${params.data.guild_id} guild_obj=${Boolean(params.data.guild)} guild_obj_id=${params.data.guild?.id} guildInfo=${Boolean(guildInfo)} guildEntries=${params.guildEntries ? Object.keys(params.guildEntries).join(",") : "none"}`, ); if ( isGuildMessage && diff --git a/extensions/discord/src/monitor/monitor.test.ts b/extensions/discord/src/monitor/monitor.test.ts index baea7183253b..6528ef45a9d1 100644 --- a/extensions/discord/src/monitor/monitor.test.ts +++ b/extensions/discord/src/monitor/monitor.test.ts @@ -2,7 +2,7 @@ import { ChannelType } from "discord-api-types/v10"; import type { DiscordAccountConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { buildPluginBindingApprovalCustomId } from "openclaw/plugin-sdk/conversation-runtime"; import { beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { type DiscordComponentEntry, type DiscordModalEntry } from "../components.js"; +import type { DiscordComponentEntry, DiscordModalEntry } from "../components.js"; import type { ButtonInteraction, ComponentData, diff --git a/extensions/discord/src/monitor/native-command-context.ts b/extensions/discord/src/monitor/native-command-context.ts index 5ccd5b6d88ff..b3c9f6934040 100644 --- a/extensions/discord/src/monitor/native-command-context.ts +++ b/extensions/discord/src/monitor/native-command-context.ts @@ -1,7 +1,7 @@ import type { CommandArgs } from "openclaw/plugin-sdk/command-auth-native"; import { finalizeInboundContext } from "openclaw/plugin-sdk/reply-dispatch-runtime"; import { resolveDiscordConversationIdentity } from "../conversation-identity.js"; -import { type DiscordChannelConfigResolved, type DiscordGuildEntryResolved } from "./allow-list.js"; +import type { DiscordChannelConfigResolved, DiscordGuildEntryResolved } from "./allow-list.js"; import { buildDiscordInboundAccessContext } from "./inbound-context.js"; type BuildDiscordNativeCommandContextParams = { diff --git a/extensions/discord/src/monitor/native-command.args.ts b/extensions/discord/src/monitor/native-command.args.ts index c93b54044d58..e3d8ff3d7de6 100644 --- a/extensions/discord/src/monitor/native-command.args.ts +++ b/extensions/discord/src/monitor/native-command.args.ts @@ -1,8 +1,8 @@ -import { - type ChatCommandDefinition, - type CommandArgDefinition, - type CommandArgValues, - type NativeCommandSpec, +import type { + ChatCommandDefinition, + CommandArgDefinition, + CommandArgValues, + NativeCommandSpec, } from "openclaw/plugin-sdk/native-command-registry"; import type { CommandInteraction } from "../internal/discord.js"; import type { DiscordCommandArgs } from "./native-command.types.js"; diff --git a/extensions/discord/src/monitor/provider.interactions.ts b/extensions/discord/src/monitor/provider.interactions.ts index 19db9e08f13d..fa56222937b6 100644 --- a/extensions/discord/src/monitor/provider.interactions.ts +++ b/extensions/discord/src/monitor/provider.interactions.ts @@ -5,11 +5,7 @@ import type { NativeCommandSpec } from "openclaw/plugin-sdk/command-auth-native" import type { DiscordAccountConfig, OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import type { RuntimeEnv } from "openclaw/plugin-sdk/runtime-env"; import { isDiscordExecApprovalClientEnabled } from "../exec-approvals.js"; -import { - type BaseCommand, - type BaseMessageInteractiveComponent, - type Modal, -} from "../internal/discord.js"; +import type { BaseCommand, BaseMessageInteractiveComponent, Modal } from "../internal/discord.js"; import { createDiscordVoiceCommand } from "../voice/command.js"; import { createAgentComponentControls, diff --git a/extensions/discord/src/setup-account-state.ts b/extensions/discord/src/setup-account-state.ts index 0c7bf3356bb2..dc31e35bd173 100644 --- a/extensions/discord/src/setup-account-state.ts +++ b/extensions/discord/src/setup-account-state.ts @@ -53,8 +53,7 @@ export function inspectDiscordSetupAccount(params: { const enabled = params.cfg.channels?.discord?.enabled !== false && config.enabled !== false; const accountConfig = resolveDiscordAccountConfig(params.cfg, accountId); const hasAccountToken = Boolean( - accountConfig && - Object.prototype.hasOwnProperty.call(accountConfig as Record, "token"), + accountConfig && Object.hasOwn(accountConfig as Record, "token"), ); const accountToken = inspectDiscordConfiguredToken(accountConfig?.token); if (accountToken) { diff --git a/extensions/discord/src/target-resolver.ts b/extensions/discord/src/target-resolver.ts index e490e72084a2..d2975f4e536c 100644 --- a/extensions/discord/src/target-resolver.ts +++ b/extensions/discord/src/target-resolver.ts @@ -5,7 +5,7 @@ import { rememberDiscordDirectoryUser } from "./directory-cache.js"; import { listDiscordDirectoryPeersLive } from "./directory-live.js"; import { allowFromContainsDiscordUserId } from "./normalize.js"; import { parseDiscordSendTarget } from "./send-target-parsing.js"; -import { type DiscordTargetParseOptions } from "./target-parsing.js"; +import type { DiscordTargetParseOptions } from "./target-parsing.js"; /** * Resolve a Discord username to user ID using the directory lookup. diff --git a/extensions/discord/src/token.ts b/extensions/discord/src/token.ts index ec97fc4d7ae7..d44ee5e0f2e6 100644 --- a/extensions/discord/src/token.ts +++ b/extensions/discord/src/token.ts @@ -65,8 +65,7 @@ export function resolveDiscordToken( const discordCfg = selectedCfg?.channels?.discord; const accountCfg = resolveAccountEntry(discordCfg?.accounts, accountId); const hasAccountToken = Boolean( - accountCfg && - Object.prototype.hasOwnProperty.call(accountCfg as Record, "token"), + accountCfg && Object.hasOwn(accountCfg as Record, "token"), ); const accountToken = resolveDiscordTokenValue({ cfg: selectedCfg, diff --git a/extensions/elevenlabs/config-compat.ts b/extensions/elevenlabs/config-compat.ts index 9ad1f3f348d1..5a90946fc666 100644 --- a/extensions/elevenlabs/config-compat.ts +++ b/extensions/elevenlabs/config-compat.ts @@ -62,7 +62,7 @@ function hasLegacyTalkFields(value: unknown): value is JsonRecord { if (!talk) { return false; } - return LEGACY_TALK_FIELD_KEYS.some((key) => Object.prototype.hasOwnProperty.call(talk, key)); + return LEGACY_TALK_FIELD_KEYS.some((key) => Object.hasOwn(talk, key)); } function resolveTalkMigrationTargetProviderId(talk: JsonRecord): string | null { @@ -117,7 +117,7 @@ export function migrateElevenLabsLegacyTalkConfig(raw: T): { config: T; chang const movedKeys: string[] = []; for (const key of LEGACY_TALK_FIELD_KEYS) { - if (!Object.prototype.hasOwnProperty.call(nextTalk, key)) { + if (!Object.hasOwn(nextTalk, key)) { continue; } legacyFields[key] = nextTalk[key]; diff --git a/extensions/elevenlabs/doctor-contract.ts b/extensions/elevenlabs/doctor-contract.ts index 4a4ce724683d..ae449f30c59a 100644 --- a/extensions/elevenlabs/doctor-contract.ts +++ b/extensions/elevenlabs/doctor-contract.ts @@ -9,7 +9,7 @@ export function hasLegacyTalkFields(value: unknown): boolean { return false; } return ["voiceId", "voiceAliases", "modelId", "outputFormat", "apiKey"].some((key) => - Object.prototype.hasOwnProperty.call(talk, key), + Object.hasOwn(talk, key), ); } diff --git a/extensions/elevenlabs/speech-provider.ts b/extensions/elevenlabs/speech-provider.ts index 70260092f7ab..3d0a072b85c7 100644 --- a/extensions/elevenlabs/speech-provider.ts +++ b/extensions/elevenlabs/speech-provider.ts @@ -32,9 +32,9 @@ const DEFAULT_ELEVENLABS_MODEL_ID = "eleven_multilingual_v2"; const DEFAULT_ELEVENLABS_VOICE_SETTINGS = { stability: 0.5, similarityBoost: 0.75, - style: 0.0, + style: 0, useSpeakerBoost: true, - speed: 1.0, + speed: 1, }; const ELEVENLABS_TTS_MODELS = [ diff --git a/extensions/elevenlabs/tts.test.ts b/extensions/elevenlabs/tts.test.ts index 298500d9ed45..75634f80105c 100644 --- a/extensions/elevenlabs/tts.test.ts +++ b/extensions/elevenlabs/tts.test.ts @@ -18,7 +18,7 @@ describe("elevenlabs tts diagnostics", () => { similarityBoost: 0.75, style: 0, useSpeakerBoost: true, - speed: 1.0, + speed: 1, }, timeoutMs: 5_000, }; diff --git a/extensions/fal/http-config.ts b/extensions/fal/http-config.ts index d1f6b4d2cbe7..837b1e02fd02 100644 --- a/extensions/fal/http-config.ts +++ b/extensions/fal/http-config.ts @@ -1,4 +1,4 @@ -import { type AuthProfileStore, type OpenClawConfig } from "openclaw/plugin-sdk/provider-auth"; +import type { AuthProfileStore, OpenClawConfig } from "openclaw/plugin-sdk/provider-auth"; import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime"; import { resolveProviderHttpRequestConfig, diff --git a/extensions/feishu/src/config-schema.ts b/extensions/feishu/src/config-schema.ts index b84895f84353..37133c84b903 100644 --- a/extensions/feishu/src/config-schema.ts +++ b/extensions/feishu/src/config-schema.ts @@ -258,7 +258,7 @@ export const FeishuConfigSchema = z const defaultAccount = value.defaultAccount?.trim(); if (defaultAccount && value.accounts && Object.keys(value.accounts).length > 0) { const normalizedDefaultAccount = normalizeAccountId(defaultAccount); - if (!Object.prototype.hasOwnProperty.call(value.accounts, normalizedDefaultAccount)) { + if (!Object.hasOwn(value.accounts, normalizedDefaultAccount)) { ctx.addIssue({ code: z.ZodIssueCode.custom, path: ["defaultAccount"], diff --git a/extensions/feishu/src/doctor.ts b/extensions/feishu/src/doctor.ts index ddc60bd679b8..d1af6b9498c5 100644 --- a/extensions/feishu/src/doctor.ts +++ b/extensions/feishu/src/doctor.ts @@ -129,7 +129,7 @@ function isPathWithinRoot(targetPath: string, rootPath: string): boolean { const resolvedTarget = path.resolve(targetPath); const resolvedRoot = path.resolve(rootPath); const relative = path.relative(resolvedRoot, resolvedTarget); - return Boolean(relative) && !relative.startsWith("..") && !path.isAbsolute(relative); + return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative); } function formatDisplayPath(filePath: string): string { @@ -740,7 +740,7 @@ async function repairFeishuDoctorState(params: { (store) => { const removed: typeof group.entries = []; for (const key of keys) { - if (Object.prototype.hasOwnProperty.call(store, key)) { + if (Object.hasOwn(store, key)) { delete store[key]; const entry = group.entries.find((candidate) => candidate.key === key); if (entry) { diff --git a/extensions/feishu/src/mention.ts b/extensions/feishu/src/mention.ts index 50ca52c98cc7..1b7de953e543 100644 --- a/extensions/feishu/src/mention.ts +++ b/extensions/feishu/src/mention.ts @@ -41,7 +41,7 @@ export function extractMentionTargets( return false; } // Must have open_id - return !!m.id.open_id; + return Boolean(m.id.open_id); }) .map((m) => ({ openId: m.id.open_id!, diff --git a/extensions/feishu/src/monitor.transport.ts b/extensions/feishu/src/monitor.transport.ts index 6c4f2e4eed55..0aa8774bca4e 100644 --- a/extensions/feishu/src/monitor.transport.ts +++ b/extensions/feishu/src/monitor.transport.ts @@ -39,7 +39,7 @@ const FEISHU_WS_AUTORECONNECT_DISABLED_ERROR = "WebSocket connect failed and autoReconnect is disabled"; function isFeishuWebhookPayload(value: unknown): value is Record { - return !!value && typeof value === "object" && !Array.isArray(value); + return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function buildFeishuWebhookEnvelope( diff --git a/extensions/feishu/src/policy.ts b/extensions/feishu/src/policy.ts index 5d3a586a169f..65dbfa52d3c5 100644 --- a/extensions/feishu/src/policy.ts +++ b/extensions/feishu/src/policy.ts @@ -257,7 +257,7 @@ export function hasExplicitFeishuGroupConfig(params: { if (!groupId) { return false; } - if (Object.prototype.hasOwnProperty.call(groups, groupId) && groupId !== "*") { + if (Object.hasOwn(groups, groupId) && groupId !== "*") { return true; } diff --git a/extensions/feishu/src/setup-surface.ts b/extensions/feishu/src/setup-surface.ts index 8e49c0662ff7..ec42e0304dcf 100644 --- a/extensions/feishu/src/setup-surface.ts +++ b/extensions/feishu/src/setup-surface.ts @@ -55,8 +55,8 @@ function isFeishuConfigured(cfg: OpenClawConfig): boolean { if (!account || typeof account !== "object") { return false; } - const hasOwnAppId = Object.prototype.hasOwnProperty.call(account, "appId"); - const hasOwnAppSecret = Object.prototype.hasOwnProperty.call(account, "appSecret"); + const hasOwnAppId = Object.hasOwn(account, "appId"); + const hasOwnAppSecret = Object.hasOwn(account, "appSecret"); const accountAppIdConfigured = hasOwnAppId ? isAppIdConfigured((account as Record).appId) : isAppIdConfigured(feishuCfg?.appId); diff --git a/extensions/feishu/src/streaming-card.ts b/extensions/feishu/src/streaming-card.ts index 6d139fddd30c..14da03669851 100644 --- a/extensions/feishu/src/streaming-card.ts +++ b/extensions/feishu/src/streaming-card.ts @@ -342,7 +342,7 @@ export class FeishuStreamingSession { sequence: 1, currentText: "", sentText: "", - hasNote: !!options?.note, + hasNote: Boolean(options?.note), }; this.log?.(`Started streaming: cardId=${cardId}, messageId=${sendRes.data.message_id}`); } diff --git a/extensions/file-transfer/src/shared/policy.ts b/extensions/file-transfer/src/shared/policy.ts index ec973fd0548c..f8dc0aa152b8 100644 --- a/extensions/file-transfer/src/shared/policy.ts +++ b/extensions/file-transfer/src/shared/policy.ts @@ -367,7 +367,7 @@ export async function persistAllowAlways(input: { ); // Use hasOwnProperty so a node with displayName "constructor" doesn't // accidentally hit Object.prototype.constructor and pretend to match. - let key = candidates.find((c) => Object.prototype.hasOwnProperty.call(fileTransfer, c)); + let key = candidates.find((c) => Object.hasOwn(fileTransfer, c)); if (!key) { key = assertSafeConfigKey(input.nodeDisplayName ?? input.nodeId); fileTransfer[key] = {}; diff --git a/extensions/file-transfer/src/tools/dir-fetch-tool.ts b/extensions/file-transfer/src/tools/dir-fetch-tool.ts index 4185aa3f95af..8058f5f8e65a 100644 --- a/extensions/file-transfer/src/tools/dir-fetch-tool.ts +++ b/extensions/file-transfer/src/tools/dir-fetch-tool.ts @@ -2,7 +2,7 @@ import { spawn } from "node:child_process"; import crypto from "node:crypto"; import fs from "node:fs/promises"; import path from "node:path"; -import { type AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; +import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store"; import { appendFileTransferAudit } from "../shared/audit.js"; import { IMAGE_MIME_INLINE_SET, mimeFromExtension } from "../shared/mime.js"; diff --git a/extensions/file-transfer/src/tools/dir-list-tool.ts b/extensions/file-transfer/src/tools/dir-list-tool.ts index 394e8a5abc10..029a7c02d81a 100644 --- a/extensions/file-transfer/src/tools/dir-list-tool.ts +++ b/extensions/file-transfer/src/tools/dir-list-tool.ts @@ -1,4 +1,4 @@ -import { type AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; +import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; import { appendFileTransferAudit } from "../shared/audit.js"; import { readClampedInt } from "../shared/params.js"; import { diff --git a/extensions/file-transfer/src/tools/file-fetch-tool.ts b/extensions/file-transfer/src/tools/file-fetch-tool.ts index e02ad404af9a..35215705fd58 100644 --- a/extensions/file-transfer/src/tools/file-fetch-tool.ts +++ b/extensions/file-transfer/src/tools/file-fetch-tool.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { type AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; +import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store"; import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers"; import { wrapExternalContent } from "openclaw/plugin-sdk/security-runtime"; diff --git a/extensions/file-transfer/src/tools/file-write-tool.ts b/extensions/file-transfer/src/tools/file-write-tool.ts index ead03df495a1..7f2e61a38e07 100644 --- a/extensions/file-transfer/src/tools/file-write-tool.ts +++ b/extensions/file-transfer/src/tools/file-write-tool.ts @@ -1,5 +1,5 @@ import crypto from "node:crypto"; -import { type AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; +import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness-runtime"; import { readMediaBuffer } from "openclaw/plugin-sdk/media-store"; import { appendFileTransferAudit } from "../shared/audit.js"; import { humanSize, readBoolean } from "../shared/params.js"; diff --git a/extensions/firecrawl/src/firecrawl-search-provider.ts b/extensions/firecrawl/src/firecrawl-search-provider.ts index cc230e6f0e95..fba25399cb66 100644 --- a/extensions/firecrawl/src/firecrawl-search-provider.ts +++ b/extensions/firecrawl/src/firecrawl-search-provider.ts @@ -1,5 +1,5 @@ import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers"; -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; import { buildFirecrawlWebSearchProviderBase } from "../web-search-shared.js"; type FirecrawlClientModule = typeof import("./firecrawl-client.js"); diff --git a/extensions/firecrawl/web-search-contract-api.ts b/extensions/firecrawl/web-search-contract-api.ts index ba815d0cf7b6..9291ffbabc7d 100644 --- a/extensions/firecrawl/web-search-contract-api.ts +++ b/extensions/firecrawl/web-search-contract-api.ts @@ -1,4 +1,4 @@ -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; import { buildFirecrawlWebSearchProviderBase } from "./web-search-shared.js"; export function createFirecrawlWebSearchProvider(): WebSearchProviderPlugin { diff --git a/extensions/github-copilot/connection-bound-ids.live.test.ts b/extensions/github-copilot/connection-bound-ids.live.test.ts index 4bbf8b6dfb45..9708e77add66 100644 --- a/extensions/github-copilot/connection-bound-ids.live.test.ts +++ b/extensions/github-copilot/connection-bound-ids.live.test.ts @@ -221,7 +221,9 @@ describeLive("github-copilot connection-bound Responses IDs live", () => { const input = Array.isArray(capturedPayload?.input) ? capturedPayload.input : []; const replayedAssistant = input.find( (item): item is Record => - !!item && typeof item === "object" && (item as Record).type === "message", + Boolean(item) && + typeof item === "object" && + (item as Record).type === "message", ); expect(replayedAssistant?.id).toMatch(/^msg_[a-f0-9]{16}$/); diff --git a/extensions/github-copilot/connection-bound-ids.ts b/extensions/github-copilot/connection-bound-ids.ts index cfd9f839f1f8..7f18df5a42c1 100644 --- a/extensions/github-copilot/connection-bound-ids.ts +++ b/extensions/github-copilot/connection-bound-ids.ts @@ -26,7 +26,7 @@ function deriveReplacementId(type: string | undefined, originalId: string): stri type InputItem = Record & { id?: unknown; type?: unknown }; function isInputItem(value: unknown): value is InputItem { - return !!value && typeof value === "object"; + return Boolean(value) && typeof value === "object"; } function isValidReasoningReplayId(id: unknown): id is string { diff --git a/extensions/google-meet/src/config-compat.ts b/extensions/google-meet/src/config-compat.ts index 44a772f94a86..cf1050f660ad 100644 --- a/extensions/google-meet/src/config-compat.ts +++ b/extensions/google-meet/src/config-compat.ts @@ -11,7 +11,7 @@ type LegacyConfigRule = { }; function hasOwn(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } function hasLegacyGoogleRealtimeProvider(value: unknown): boolean { diff --git a/extensions/googlechat/src/doctor-contract.ts b/extensions/googlechat/src/doctor-contract.ts index 6233257c5749..aacb9c3e5efb 100644 --- a/extensions/googlechat/src/doctor-contract.ts +++ b/extensions/googlechat/src/doctor-contract.ts @@ -16,9 +16,7 @@ function hasLegacyGoogleChatGroupAllowAlias(value: unknown): boolean { if (!groups) { return false; } - return Object.values(groups).some((group) => - Object.prototype.hasOwnProperty.call(asObjectRecord(group) ?? {}, "allow"), - ); + return Object.values(groups).some((group) => Object.hasOwn(asObjectRecord(group) ?? {}, "allow")); } function hasLegacyAccountAliases(value: unknown, match: (entry: unknown) => boolean): boolean { @@ -38,7 +36,7 @@ function normalizeGoogleChatGroups(params: { const nextGroups = { ...params.groups }; for (const [groupId, groupValue] of Object.entries(params.groups)) { const group = asObjectRecord(groupValue); - if (!group || !Object.prototype.hasOwnProperty.call(group, "allow")) { + if (!group || !Object.hasOwn(group, "allow")) { continue; } const nextGroup = { ...group }; diff --git a/extensions/googlechat/src/monitor.ts b/extensions/googlechat/src/monitor.ts index 9583fe64f8d1..e0065c76d7d0 100644 --- a/extensions/googlechat/src/monitor.ts +++ b/extensions/googlechat/src/monitor.ts @@ -9,9 +9,9 @@ import { resolveInboundRouteEnvelopeBuilderWithRuntime, resolveWebhookPath, } from "../runtime-api.js"; -import { type ResolvedGoogleChatAccount } from "./accounts.js"; +import type { ResolvedGoogleChatAccount } from "./accounts.js"; import { downloadGoogleChatMedia, sendGoogleChatMessage } from "./api.js"; -import { type GoogleChatAudienceType } from "./auth.js"; +import type { GoogleChatAudienceType } from "./auth.js"; import { applyGoogleChatInboundAccessPolicy } from "./monitor-access.js"; import { resolveGoogleChatDurableReplyOptions } from "./monitor-durable.js"; import { deliverGoogleChatReply } from "./monitor-reply-delivery.js"; diff --git a/extensions/huggingface/models.ts b/extensions/huggingface/models.ts index 3908f17f3de0..49d30b845eed 100644 --- a/extensions/huggingface/models.ts +++ b/extensions/huggingface/models.ts @@ -47,7 +47,7 @@ export const HUGGINGFACE_MODEL_CATALOG: ModelDefinitionConfig[] = [ input: ["text"], contextWindow: 131072, maxTokens: 8192, - cost: { input: 3.0, output: 7.0, cacheRead: 3.0, cacheWrite: 3.0 }, + cost: { input: 3, output: 7, cacheRead: 3, cacheWrite: 3 }, }, { id: "deepseek-ai/DeepSeek-V3.1", diff --git a/extensions/imessage/src/approval-handler.runtime.ts b/extensions/imessage/src/approval-handler.runtime.ts index 7c6ae247937c..41c78754ec22 100644 --- a/extensions/imessage/src/approval-handler.runtime.ts +++ b/extensions/imessage/src/approval-handler.runtime.ts @@ -8,9 +8,9 @@ import { import { buildChannelApprovalNativeTargetKey } from "openclaw/plugin-sdk/approval-native-runtime"; import { buildApprovalReactionPendingContent } from "openclaw/plugin-sdk/approval-reaction-runtime"; import type { ExecApprovalReplyDecision } from "openclaw/plugin-sdk/approval-reply-runtime"; -import { - type ExecApprovalRequest, - type PluginApprovalRequest, +import type { + ExecApprovalRequest, + PluginApprovalRequest, } from "openclaw/plugin-sdk/approval-runtime"; import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env"; import { diff --git a/extensions/imessage/src/channel.setup.ts b/extensions/imessage/src/channel.setup.ts index 22b549ebe852..37b84d3a1246 100644 --- a/extensions/imessage/src/channel.setup.ts +++ b/extensions/imessage/src/channel.setup.ts @@ -1,5 +1,5 @@ -import { type ResolvedIMessageAccount } from "./accounts.js"; -import { type ChannelPlugin } from "./channel-api.js"; +import type { ResolvedIMessageAccount } from "./accounts.js"; +import type { ChannelPlugin } from "./channel-api.js"; import { imessageSetupAdapter } from "./setup-core.js"; import { createIMessagePluginBase, imessageSetupWizard } from "./shared.js"; diff --git a/extensions/kilocode/provider-catalog.ts b/extensions/kilocode/provider-catalog.ts index 4f425fb9bc2b..c7e17a499dab 100644 --- a/extensions/kilocode/provider-catalog.ts +++ b/extensions/kilocode/provider-catalog.ts @@ -1,4 +1,4 @@ -import { type ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; +import type { ModelProviderConfig } from "openclaw/plugin-sdk/provider-model-shared"; import { discoverKilocodeModels, KILOCODE_BASE_URL as LOCAL_KILOCODE_BASE_URL, diff --git a/extensions/kilocode/provider-models.test.ts b/extensions/kilocode/provider-models.test.ts index d931cae39dbe..e624ba023b09 100644 --- a/extensions/kilocode/provider-models.test.ts +++ b/extensions/kilocode/provider-models.test.ts @@ -196,8 +196,8 @@ describe("discoverKilocodeModels (fetch path)", () => { expect(models.length).toBe(2); const sonnet = requireModelById(models, "anthropic/claude-sonnet-4"); - expect(sonnet.cost.input).toBeCloseTo(3.0); - expect(sonnet.cost.output).toBeCloseTo(15.0); + expect(sonnet.cost.input).toBeCloseTo(3); + expect(sonnet.cost.output).toBeCloseTo(15); expect(sonnet.cost.cacheRead).toBeCloseTo(0.3); expect(sonnet.cost.cacheWrite).toBeCloseTo(3.75); expect(sonnet.input).toEqual(["text", "image"]); @@ -329,7 +329,7 @@ describe("discoverKilocodeModels (fetch path)", () => { const models = await discoverKilocodeModels(); const auto = requireModelById(models, "kilo/auto"); expect(auto.name).toBe("Kilo: Auto"); - expect(auto.cost.input).toBeCloseTo(5.0); + expect(auto.cost.input).toBeCloseTo(5); expect(requireModelById(models, "anthropic/claude-sonnet-4").id).toBe( "anthropic/claude-sonnet-4", ); diff --git a/extensions/line/src/channel-shared.ts b/extensions/line/src/channel-shared.ts index 9e14fd013114..7e6099ef0fe4 100644 --- a/extensions/line/src/channel-shared.ts +++ b/extensions/line/src/channel-shared.ts @@ -1,6 +1,6 @@ import { describeWebhookAccountSnapshot } from "openclaw/plugin-sdk/account-helpers"; import { hasLineCredentials } from "./account-helpers.js"; -import { type ChannelPlugin, type ResolvedLineAccount } from "./channel-api.js"; +import type { ChannelPlugin, ResolvedLineAccount } from "./channel-api.js"; import { lineConfigAdapter } from "./config-adapter.js"; import { LineChannelConfigSchema } from "./config-schema.js"; diff --git a/extensions/line/src/channel.setup.ts b/extensions/line/src/channel.setup.ts index 9108443b1d91..c8548316fc73 100644 --- a/extensions/line/src/channel.setup.ts +++ b/extensions/line/src/channel.setup.ts @@ -1,4 +1,4 @@ -import { type ChannelPlugin, type ResolvedLineAccount } from "./channel-api.js"; +import type { ChannelPlugin, ResolvedLineAccount } from "./channel-api.js"; import { lineChannelPluginCommon } from "./channel-shared.js"; import { lineSetupAdapter } from "./setup-core.js"; import { lineSetupWizard } from "./setup-surface.js"; diff --git a/extensions/line/src/channel.ts b/extensions/line/src/channel.ts index d2efb7e553ef..33b7c7788fee 100644 --- a/extensions/line/src/channel.ts +++ b/extensions/line/src/channel.ts @@ -5,7 +5,7 @@ import { createEmptyChannelDirectoryAdapter } from "openclaw/plugin-sdk/director import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime"; import { resolveLineAccount } from "./accounts.js"; import { lineBindingsAdapter } from "./bindings.js"; -import { type ChannelPlugin, type ResolvedLineAccount } from "./channel-api.js"; +import type { ChannelPlugin, ResolvedLineAccount } from "./channel-api.js"; import { lineChannelPluginCommon } from "./channel-shared.js"; import { lineGatewayAdapter } from "./gateway.js"; import { resolveLineGroupRequireMention } from "./group-policy.js"; diff --git a/extensions/line/src/outbound.ts b/extensions/line/src/outbound.ts index 269c4c9fa739..f686e2021fe4 100644 --- a/extensions/line/src/outbound.ts +++ b/extensions/line/src/outbound.ts @@ -9,7 +9,7 @@ import { } from "openclaw/plugin-sdk/channel-send-result"; import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime"; import { resolveOutboundMediaUrls } from "openclaw/plugin-sdk/reply-payload"; -import { type ChannelPlugin, type ResolvedLineAccount } from "./channel-api.js"; +import type { ChannelPlugin, ResolvedLineAccount } from "./channel-api.js"; import { resolveLineOutboundMedia, type LineOutboundMediaResolved } from "./outbound-media.js"; import { buildLineQuickReplyFallbackText } from "./quick-reply-fallback.js"; import { getLineRuntime } from "./runtime.js"; diff --git a/extensions/llm-task/src/llm-task-tool.ts b/extensions/llm-task/src/llm-task-tool.ts index 0a61e4f53d56..55fdfe2b8f8c 100644 --- a/extensions/llm-task/src/llm-task-tool.ts +++ b/extensions/llm-task/src/llm-task-tool.ts @@ -147,7 +147,7 @@ function supportsThinkingPolicyLevel( policy: ThinkingPolicy, level: ReturnType, ): boolean { - return !!level && policy.levels.some((entry) => entry.id === level); + return Boolean(level) && policy.levels.some((entry) => entry.id === level); } export function createLlmTaskTool(api: OpenClawPluginApi) { diff --git a/extensions/matrix/src/doctor.ts b/extensions/matrix/src/doctor.ts index 70ba6875fd3f..d5d0cc15f8a1 100644 --- a/extensions/matrix/src/doctor.ts +++ b/extensions/matrix/src/doctor.ts @@ -1,4 +1,4 @@ -import { type ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; +import type { ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { detectPluginInstallPathIssue, diff --git a/extensions/matrix/src/matrix/actions/reactions.ts b/extensions/matrix/src/matrix/actions/reactions.ts index 6aa98dbf4d0b..4a7f8d9b352c 100644 --- a/extensions/matrix/src/matrix/actions/reactions.ts +++ b/extensions/matrix/src/matrix/actions/reactions.ts @@ -5,11 +5,7 @@ import { } from "../reaction-common.js"; import { withResolvedRoomAction } from "./client.js"; import { resolveMatrixActionLimit } from "./limits.js"; -import { - type MatrixActionClientOpts, - type MatrixRawEvent, - type MatrixReactionSummary, -} from "./types.js"; +import type { MatrixActionClientOpts, MatrixRawEvent, MatrixReactionSummary } from "./types.js"; type ActionClient = NonNullable; diff --git a/extensions/matrix/src/matrix/monitor/handler.group-history.test.ts b/extensions/matrix/src/matrix/monitor/handler.group-history.test.ts index ee576cddf4f5..bf63b8f838c8 100644 --- a/extensions/matrix/src/matrix/monitor/handler.group-history.test.ts +++ b/extensions/matrix/src/matrix/monitor/handler.group-history.test.ts @@ -23,7 +23,7 @@ import { createMatrixRoomMessageEvent, createMatrixTextMessageEvent, } from "./handler.test-helpers.js"; -import { type MatrixRawEvent } from "./types.js"; +import type { MatrixRawEvent } from "./types.js"; const deliverMatrixRepliesMock = vi.hoisted(() => vi.fn(async () => true)); diff --git a/extensions/matrix/src/matrix/monitor/index.test.ts b/extensions/matrix/src/matrix/monitor/index.test.ts index 69035d5af73c..8d3b27eb0cc6 100644 --- a/extensions/matrix/src/matrix/monitor/index.test.ts +++ b/extensions/matrix/src/matrix/monitor/index.test.ts @@ -198,28 +198,20 @@ vi.mock("../../runtime-api.js", () => { wildcardKey: string; }) => { for (const key of keys) { - if (Object.prototype.hasOwnProperty.call(entries, key)) { + if (Object.hasOwn(entries, key)) { return { entry: entries[key], key, - wildcardEntry: Object.prototype.hasOwnProperty.call(entries, wildcardKey) - ? entries[wildcardKey] - : undefined, - wildcardKey: Object.prototype.hasOwnProperty.call(entries, wildcardKey) - ? wildcardKey - : undefined, + wildcardEntry: Object.hasOwn(entries, wildcardKey) ? entries[wildcardKey] : undefined, + wildcardKey: Object.hasOwn(entries, wildcardKey) ? wildcardKey : undefined, }; } } return { entry: undefined, key: undefined, - wildcardEntry: Object.prototype.hasOwnProperty.call(entries, wildcardKey) - ? entries[wildcardKey] - : undefined, - wildcardKey: Object.prototype.hasOwnProperty.call(entries, wildcardKey) - ? wildcardKey - : undefined, + wildcardEntry: Object.hasOwn(entries, wildcardKey) ? entries[wildcardKey] : undefined, + wildcardKey: Object.hasOwn(entries, wildcardKey) ? wildcardKey : undefined, }; }, resolveDefaultGroupPolicy: () => "allowlist", diff --git a/extensions/matrix/src/matrix/send/media.ts b/extensions/matrix/src/matrix/send/media.ts index 663d95e07128..1d4a5a027114 100644 --- a/extensions/matrix/src/matrix/send/media.ts +++ b/extensions/matrix/src/matrix/send/media.ts @@ -8,12 +8,12 @@ import type { TimedFileInfo, VideoFileInfo, } from "../sdk.js"; -import { - type MatrixMediaContent, - type MatrixMediaInfo, - type MatrixMediaMsgType, - type MatrixRelation, - type MediaKind, +import type { + MatrixMediaContent, + MatrixMediaInfo, + MatrixMediaMsgType, + MatrixRelation, + MediaKind, } from "./types.js"; const getCore = () => getMatrixRuntime(); diff --git a/extensions/matrix/src/plugin-entry.runtime.js b/extensions/matrix/src/plugin-entry.runtime.js index 0f267750f491..e2d2fdb17026 100644 --- a/extensions/matrix/src/plugin-entry.runtime.js +++ b/extensions/matrix/src/plugin-entry.runtime.js @@ -23,10 +23,10 @@ function normalizeLowercaseStringOrEmpty(value) { function hasTrustedOpenClawRootIndicator(packageRoot, packageJson) { const packageExports = packageJson?.exports ?? {}; - if (!Object.prototype.hasOwnProperty.call(packageExports, "./plugin-sdk")) { + if (!Object.hasOwn(packageExports, "./plugin-sdk")) { return false; } - const hasCliEntryExport = Object.prototype.hasOwnProperty.call(packageExports, "./cli-entry"); + const hasCliEntryExport = Object.hasOwn(packageExports, "./cli-entry"); const hasOpenClawBin = (typeof packageJson?.bin === "string" && normalizeLowercaseStringOrEmpty(packageJson.bin).includes("openclaw")) || diff --git a/extensions/mattermost/src/channel.setup.ts b/extensions/mattermost/src/channel.setup.ts index 3cb198ffa229..e299b758b876 100644 --- a/extensions/mattermost/src/channel.setup.ts +++ b/extensions/mattermost/src/channel.setup.ts @@ -7,7 +7,7 @@ import { resolveMattermostGatewayAuthBypassPaths, } from "./channel-config-shared.js"; import { MattermostChannelConfigSchema } from "./config-surface.js"; -import { type ResolvedMattermostAccount } from "./mattermost/accounts.js"; +import type { ResolvedMattermostAccount } from "./mattermost/accounts.js"; import { mattermostSetupAdapter } from "./setup-core.js"; import { mattermostSetupWizard } from "./setup-surface.js"; diff --git a/extensions/mattermost/src/mattermost/interactions.test.ts b/extensions/mattermost/src/mattermost/interactions.test.ts index b72733572b08..b4b87424e0ca 100644 --- a/extensions/mattermost/src/mattermost/interactions.test.ts +++ b/extensions/mattermost/src/mattermost/interactions.test.ts @@ -1,4 +1,4 @@ -import { type IncomingMessage, type ServerResponse } from "node:http"; +import type { IncomingMessage, ServerResponse } from "node:http"; import { describe, expect, it, beforeEach, afterEach, vi } from "vitest"; import type { PluginRuntime } from "../../runtime-api.js"; import { setMattermostRuntime } from "../runtime.js"; diff --git a/extensions/memory-core/src/memory/hybrid.test.ts b/extensions/memory-core/src/memory/hybrid.test.ts index deb9f9477106..505db1072bf6 100644 --- a/extensions/memory-core/src/memory/hybrid.test.ts +++ b/extensions/memory-core/src/memory/hybrid.test.ts @@ -51,7 +51,7 @@ describe("memory hybrid helpers", () => { endLine: 4, source: "memory", snippet: "kw-b", - textScore: 1.0, + textScore: 1, }, ], }); @@ -62,9 +62,9 @@ describe("memory hybrid helpers", () => { expect(a?.score).toBeCloseTo(0.7 * 0.9); expect(a?.vectorScore).toBeCloseTo(0.9); expect(a?.textScore).toBe(0); - expect(b?.score).toBeCloseTo(0.3 * 1.0); + expect(b?.score).toBeCloseTo(0.3 * 1); expect(b?.vectorScore).toBe(0); - expect(b?.textScore).toBeCloseTo(1.0); + expect(b?.textScore).toBeCloseTo(1); }); it("mergeHybridResults prefers keyword snippet when ids overlap", async () => { @@ -90,15 +90,15 @@ describe("memory hybrid helpers", () => { endLine: 2, source: "memory", snippet: "kw-a", - textScore: 1.0, + textScore: 1, }, ], }); expect(merged).toHaveLength(1); expect(merged[0]?.snippet).toBe("kw-a"); - expect(merged[0]?.score).toBeCloseTo(0.5 * 0.2 + 0.5 * 1.0); + expect(merged[0]?.score).toBeCloseTo(0.5 * 0.2 + 0.5 * 1); expect(merged[0]?.vectorScore).toBeCloseTo(0.2); - expect(merged[0]?.textScore).toBeCloseTo(1.0); + expect(merged[0]?.textScore).toBeCloseTo(1); }); }); diff --git a/extensions/memory-core/src/memory/manager-session-sync-state.ts b/extensions/memory-core/src/memory/manager-session-sync-state.ts index cd0d83f1c44b..4463c394d136 100644 --- a/extensions/memory-core/src/memory/manager-session-sync-state.ts +++ b/extensions/memory-core/src/memory/manager-session-sync-state.ts @@ -1,4 +1,4 @@ -import { type MemorySourceFileStateRow } from "./manager-source-state.js"; +import type { MemorySourceFileStateRow } from "./manager-source-state.js"; export type MemorySessionStartupFileState = { absPath: string; diff --git a/extensions/memory-core/src/memory/manager.ts b/extensions/memory-core/src/memory/manager.ts index e69dc2885be6..2ebc1b5650da 100644 --- a/extensions/memory-core/src/memory/manager.ts +++ b/extensions/memory-core/src/memory/manager.ts @@ -1,5 +1,5 @@ import type { DatabaseSync } from "node:sqlite"; -import { type FSWatcher } from "chokidar"; +import type { FSWatcher } from "chokidar"; import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; import { createSubsystemLogger, diff --git a/extensions/memory-core/src/memory/mmr.test.ts b/extensions/memory-core/src/memory/mmr.test.ts index 912658e7a4da..41c6ea182dd3 100644 --- a/extensions/memory-core/src/memory/mmr.test.ts +++ b/extensions/memory-core/src/memory/mmr.test.ts @@ -195,7 +195,7 @@ describe("computeMMRScore", () => { expected: -0.5, }, { name: "lambda=0.5 mixed", relevance: 0.8, similarity: 0.6, lambda: 0.5, expected: 0.1 }, - { name: "default lambda math", relevance: 1.0, similarity: 0.5, lambda: 0.7, expected: 0.55 }, + { name: "default lambda math", relevance: 1, similarity: 0.5, lambda: 0.7, expected: 0.55 }, ] as const; for (const testCase of cases) { @@ -239,7 +239,7 @@ describe("mmrRerank", () => { describe("lambda edge cases", () => { const diverseItems: MMRItem[] = [ - { id: "1", score: 1.0, content: "apple banana cherry" }, + { id: "1", score: 1, content: "apple banana cherry" }, { id: "2", score: 0.9, content: "apple banana date" }, { id: "3", score: 0.8, content: "elderberry fig grape" }, ]; @@ -272,7 +272,7 @@ describe("mmrRerank", () => { describe("diversity behavior", () => { it("promotes diverse results over similar high-scoring ones", () => { const items: MMRItem[] = [ - { id: "1", score: 1.0, content: "machine learning neural networks" }, + { id: "1", score: 1, content: "machine learning neural networks" }, { id: "2", score: 0.95, content: "machine learning deep learning" }, { id: "3", score: 0.9, content: "database systems sql queries" }, { id: "4", score: 0.85, content: "machine learning algorithms" }, @@ -288,7 +288,7 @@ describe("mmrRerank", () => { it("handles items with identical content", () => { const items: MMRItem[] = [ - { id: "1", score: 1.0, content: "identical content" }, + { id: "1", score: 1, content: "identical content" }, { id: "2", score: 0.9, content: "identical content" }, { id: "3", score: 0.8, content: "different stuff" }, ]; @@ -301,7 +301,7 @@ describe("mmrRerank", () => { it("handles all identical content gracefully", () => { const items: MMRItem[] = [ - { id: "1", score: 1.0, content: "same" }, + { id: "1", score: 1, content: "same" }, { id: "2", score: 0.9, content: "same" }, { id: "3", score: 0.8, content: "same" }, ]; @@ -315,7 +315,7 @@ describe("mmrRerank", () => { describe("tie-breaking", () => { it("uses original score as tiebreaker", () => { const items: MMRItem[] = [ - { id: "1", score: 1.0, content: "unique content one" }, + { id: "1", score: 1, content: "unique content one" }, { id: "2", score: 0.9, content: "unique content two" }, { id: "3", score: 0.8, content: "unique content three" }, ]; @@ -352,7 +352,7 @@ describe("mmrRerank", () => { it("handles negative scores", () => { const items: MMRItem[] = [ { id: "1", score: -0.5, content: "hello world" }, - { id: "2", score: -1.0, content: "foo bar" }, + { id: "2", score: -1, content: "foo bar" }, ]; const result = mmrRerank(items, { lambda: 0.7 }); @@ -420,7 +420,7 @@ describe("applyMMRToHybridResults", () => { path: "/a.ts", startLine: 1, endLine: 10, - score: 1.0, + score: 1, snippet: "function add numbers together", source: "memory", }, diff --git a/extensions/memory-lancedb/index.ts b/extensions/memory-lancedb/index.ts index bc6914f04ee8..a007aa0eaa9e 100644 --- a/extensions/memory-lancedb/index.ts +++ b/extensions/memory-lancedb/index.ts @@ -1024,7 +1024,7 @@ export default definePluginEntry({ return -1 * direction; } if (a[col] > b[col]) { - return 1 * direction; + return Number(direction); } return 0; }); diff --git a/extensions/memory-wiki/src/config-compat.ts b/extensions/memory-wiki/src/config-compat.ts index 6657a50c4e69..46806bd4ed95 100644 --- a/extensions/memory-wiki/src/config-compat.ts +++ b/extensions/memory-wiki/src/config-compat.ts @@ -13,7 +13,7 @@ function asRecord(value: unknown): Record | null { } function hasLegacyBridgeArtifactToggle(value: unknown): boolean { - return Object.prototype.hasOwnProperty.call(asRecord(value) ?? {}, "readMemoryCore"); + return Object.hasOwn(asRecord(value) ?? {}, "readMemoryCore"); } export const legacyConfigRules: LegacyConfigRule[] = [ @@ -49,7 +49,7 @@ export function migrateMemoryWikiLegacyConfig(config: OpenClawConfig): { nextPluginConfig.bridge = nextBridge; const legacyValue = nextBridge.readMemoryCore; - const hasCanonical = Object.prototype.hasOwnProperty.call(nextBridge, "readMemoryArtifacts"); + const hasCanonical = Object.hasOwn(nextBridge, "readMemoryArtifacts"); if (!hasCanonical) { nextBridge.readMemoryArtifacts = legacyValue; } diff --git a/extensions/minimax/speech-provider.test.ts b/extensions/minimax/speech-provider.test.ts index 329588ca13f6..263744522e9f 100644 --- a/extensions/minimax/speech-provider.test.ts +++ b/extensions/minimax/speech-provider.test.ts @@ -168,7 +168,7 @@ describe("buildMinimaxSpeechProvider", () => { model: "speech-01-240228", voiceId: "Chinese (Mandarin)_Warm_Girl", speed: 1.5, - vol: 2.0, + vol: 2, pitch: 3, }, }, @@ -180,7 +180,7 @@ describe("buildMinimaxSpeechProvider", () => { expect(config.model).toBe("speech-01-240228"); expect(config.voiceId).toBe("Chinese (Mandarin)_Warm_Girl"); expect(config.speed).toBe(1.5); - expect(config.vol).toBe(2.0); + expect(config.vol).toBe(2); expect(config.pitch).toBe(3); }); diff --git a/extensions/minimax/tts.ts b/extensions/minimax/tts.ts index 4fcf62421a40..1b037290300a 100644 --- a/extensions/minimax/tts.ts +++ b/extensions/minimax/tts.ts @@ -58,8 +58,8 @@ export async function minimaxTTS(params: { baseUrl, model, voiceId, - speed = 1.0, - vol = 1.0, + speed = 1, + vol = 1, pitch = 0, format = "mp3", sampleRate = 32000, diff --git a/extensions/msteams/src/attachments/shared.ts b/extensions/msteams/src/attachments/shared.ts index abbeed859920..8ce3b20ea411 100644 --- a/extensions/msteams/src/attachments/shared.ts +++ b/extensions/msteams/src/attachments/shared.ts @@ -472,9 +472,7 @@ export type MSTeamsAttachmentResolveFn = (hostname: string) => Promise<{ address function isMockFetchFn(fetchFn: typeof fetch): boolean { const candidate = fetchFn as unknown as { mock?: unknown }; - return Boolean( - candidate.mock || Object.prototype.hasOwnProperty.call(candidate, "_isMockFunction"), - ); + return Boolean(candidate.mock || Object.hasOwn(candidate, "_isMockFunction")); } function resolveGuardedFetchImpl(params: { diff --git a/extensions/msteams/src/graph-teams.ts b/extensions/msteams/src/graph-teams.ts index a9cd425e738c..e6105caa4a81 100644 --- a/extensions/msteams/src/graph-teams.ts +++ b/extensions/msteams/src/graph-teams.ts @@ -84,7 +84,7 @@ export async function listChannelsMSTeams( description: ch.description, membershipType: ch.membershipType, })); - return { channels, truncated: !!nextPath }; + return { channels, truncated: Boolean(nextPath) }; } // --------------------------------------------------------------------------- diff --git a/extensions/msteams/src/monitor-handler.feedback-authz.test.ts b/extensions/msteams/src/monitor-handler.feedback-authz.test.ts index b017f7c8ccb1..540f4b0bf3e7 100644 --- a/extensions/msteams/src/monitor-handler.feedback-authz.test.ts +++ b/extensions/msteams/src/monitor-handler.feedback-authz.test.ts @@ -4,7 +4,7 @@ import path from "node:path"; import { beforeEach, describe, expect, it, vi } from "vitest"; import type { OpenClawConfig, PluginRuntime, RuntimeEnv } from "../runtime-api.js"; import { runMSTeamsFeedbackInvokeHandler } from "./feedback-invoke.js"; -import { type MSTeamsMessageHandlerDeps } from "./monitor-handler.js"; +import type { MSTeamsMessageHandlerDeps } from "./monitor-handler.js"; import { createMSTeamsMessageHandlerDeps } from "./monitor-handler.test-helpers.js"; import { setMSTeamsRuntime } from "./runtime.js"; import type { MSTeamsTurnContext } from "./sdk-types.js"; diff --git a/extensions/msteams/src/monitor-handler.types.ts b/extensions/msteams/src/monitor-handler.types.ts index 80943397e6ff..5b3bbd1bd184 100644 --- a/extensions/msteams/src/monitor-handler.types.ts +++ b/extensions/msteams/src/monitor-handler.types.ts @@ -1,4 +1,4 @@ -import { type OpenClawConfig, type RuntimeEnv } from "../runtime-api.js"; +import type { OpenClawConfig, RuntimeEnv } from "../runtime-api.js"; import type { MSTeamsConversationStore } from "./conversation-store.js"; import type { MSTeamsMonitorLogger } from "./monitor-types.js"; import type { MSTeamsPollStore } from "./polls.js"; diff --git a/extensions/nextcloud-talk/src/monitor.test-harness.ts b/extensions/nextcloud-talk/src/monitor.test-harness.ts index f25a26422b34..b52bb22d78c6 100644 --- a/extensions/nextcloud-talk/src/monitor.test-harness.ts +++ b/extensions/nextcloud-talk/src/monitor.test-harness.ts @@ -1,4 +1,4 @@ -import { type AddressInfo } from "node:net"; +import type { AddressInfo } from "node:net"; import { afterEach } from "vitest"; import { createNextcloudTalkWebhookServer } from "./monitor.js"; import type { NextcloudTalkWebhookServerOptions } from "./types.js"; diff --git a/extensions/nostr/src/gateway.ts b/extensions/nostr/src/gateway.ts index 29c6f2a2df0c..67a25da09265 100644 --- a/extensions/nostr/src/gateway.ts +++ b/extensions/nostr/src/gateway.ts @@ -6,7 +6,7 @@ import { createChannelPairingController } from "openclaw/plugin-sdk/channel-pair import { attachChannelToResult } from "openclaw/plugin-sdk/channel-send-result"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { runStoppablePassiveMonitor } from "openclaw/plugin-sdk/extension-shared"; -import { type ChannelOutboundAdapter, type ChannelPlugin } from "./channel-api.js"; +import type { ChannelOutboundAdapter, ChannelPlugin } from "./channel-api.js"; import type { MetricEvent, MetricsSnapshot } from "./metrics.js"; import { startNostrBus, type NostrBusHandle } from "./nostr-bus.js"; import { normalizePubkey } from "./nostr-key-utils.js"; diff --git a/extensions/openai/openai-chatgpt-provider.ts b/extensions/openai/openai-chatgpt-provider.ts index ccb85b5a25a3..42ec9e50f2d2 100644 --- a/extensions/openai/openai-chatgpt-provider.ts +++ b/extensions/openai/openai-chatgpt-provider.ts @@ -113,7 +113,7 @@ function isOpenAIOrLegacyCodexProvider(provider: string | undefined): boolean { function isLegacyCodexCompatBaseUrl(baseUrl?: string): boolean { const trimmed = baseUrl?.trim(); - return !!trimmed && /^https?:\/\/api\.githubcopilot\.com(?:\/v1)?\/?$/iu.test(trimmed); + return Boolean(trimmed) && /^https?:\/\/api\.githubcopilot\.com(?:\/v1)?\/?$/iu.test(trimmed); } function normalizeCodexTransportFields(params: { diff --git a/extensions/openai/openai-provider.ts b/extensions/openai/openai-provider.ts index 077e64adea4b..f622ce8ac91f 100644 --- a/extensions/openai/openai-provider.ts +++ b/extensions/openai/openai-provider.ts @@ -1,6 +1,6 @@ -import { - type ProviderResolveDynamicModelContext, - type ProviderRuntimeModel, +import type { + ProviderResolveDynamicModelContext, + ProviderRuntimeModel, } from "openclaw/plugin-sdk/plugin-entry"; import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key"; import { diff --git a/extensions/openrouter/video-model-catalog.ts b/extensions/openrouter/video-model-catalog.ts index f6e9000942f7..3d63e1cf1c02 100644 --- a/extensions/openrouter/video-model-catalog.ts +++ b/extensions/openrouter/video-model-catalog.ts @@ -1,6 +1,6 @@ -import { - type UnifiedModelCatalogEntry, - type UnifiedModelCatalogProviderContext, +import type { + UnifiedModelCatalogEntry, + UnifiedModelCatalogProviderContext, } from "openclaw/plugin-sdk/plugin-entry"; import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime"; import { getCachedLiveCatalogValue } from "openclaw/plugin-sdk/provider-catalog-shared"; diff --git a/extensions/perplexity/web-search-contract-api.ts b/extensions/perplexity/web-search-contract-api.ts index 2d6fcbecccb4..2f0d8f2e2253 100644 --- a/extensions/perplexity/web-search-contract-api.ts +++ b/extensions/perplexity/web-search-contract-api.ts @@ -1,4 +1,4 @@ -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; import { createPerplexityWebSearchProviderBase, resolvePerplexityWebSearchRuntimeMetadata, diff --git a/extensions/pixverse/onboard.ts b/extensions/pixverse/onboard.ts index f799a1ab564f..c38c39caf211 100644 --- a/extensions/pixverse/onboard.ts +++ b/extensions/pixverse/onboard.ts @@ -1,7 +1,7 @@ -import { - type ProviderAuthContext, - type ProviderAuthMethod, - type ProviderAuthMethodNonInteractiveContext, +import type { + ProviderAuthContext, + ProviderAuthMethod, + ProviderAuthMethodNonInteractiveContext, } from "openclaw/plugin-sdk/plugin-entry"; import { applyAuthProfileConfig, diff --git a/extensions/qa-lab/src/agentic-parity-report.ts b/extensions/qa-lab/src/agentic-parity-report.ts index 45909fb39064..9f3a54642a64 100644 --- a/extensions/qa-lab/src/agentic-parity-report.ts +++ b/extensions/qa-lab/src/agentic-parity-report.ts @@ -259,7 +259,7 @@ function describeLiveUsageFailure(scenarioName: string, scenario: QaRuntimeParit scenario.codexTokens > 0 ? undefined : `${scenario.codexStatus === "pass" ? "codex" : "codex failed"}=0`, - ].filter((entry): entry is string => !!entry); + ].filter((entry): entry is string => Boolean(entry)); if (missing.length === 0) { return undefined; } diff --git a/extensions/qa-lab/src/character-eval.ts b/extensions/qa-lab/src/character-eval.ts index ce23a5de92dc..5f867ebfde2e 100644 --- a/extensions/qa-lab/src/character-eval.ts +++ b/extensions/qa-lab/src/character-eval.ts @@ -10,7 +10,7 @@ import { QA_FRONTIER_CHARACTER_JUDGE_MODELS, QA_FRONTIER_CHARACTER_THINKING_BY_MODEL, } from "./providers/live-frontier/character-eval.js"; -import { type QaThinkingLevel } from "./qa-gateway-config.js"; +import type { QaThinkingLevel } from "./qa-gateway-config.js"; import { extractQaVisibleReplyLeakText } from "./reply-failure.js"; import { runQaSuiteFromRuntime } from "./suite-launch.runtime.js"; import type { QaSuiteResult } from "./suite.js"; diff --git a/extensions/qa-lab/src/harness-parity.ts b/extensions/qa-lab/src/harness-parity.ts index bc55ae4f1853..449c492aa895 100644 --- a/extensions/qa-lab/src/harness-parity.ts +++ b/extensions/qa-lab/src/harness-parity.ts @@ -414,8 +414,8 @@ export function buildHarnessParityResult(params: { if ( compareTranscriptStructure && (leftTranscriptRecords !== rightTranscriptRecords || - (!params.left.finalText && !!params.right.finalText) || - (!!params.left.finalText && !params.right.finalText)) + (!params.left.finalText && Boolean(params.right.finalText)) || + (Boolean(params.left.finalText) && !params.right.finalText)) ) { return { scenarioId: params.scenarioId, diff --git a/extensions/qa-lab/src/live-transports/shared/live-gateway.runtime.ts b/extensions/qa-lab/src/live-transports/shared/live-gateway.runtime.ts index a3bd8abd2267..5561c0264bae 100644 --- a/extensions/qa-lab/src/live-transports/shared/live-gateway.runtime.ts +++ b/extensions/qa-lab/src/live-transports/shared/live-gateway.runtime.ts @@ -35,7 +35,7 @@ async function stopQaLiveLaneResources( } function omitMemoryCoreEntry | undefined>(entries: T): T { - if (!entries || !Object.prototype.hasOwnProperty.call(entries, "memory-core")) { + if (!entries || !Object.hasOwn(entries, "memory-core")) { return entries; } const { "memory-core": _memoryCore, ...rest } = entries; diff --git a/extensions/qa-lab/src/providers/mock-openai/server.ts b/extensions/qa-lab/src/providers/mock-openai/server.ts index b3e25b1e33a1..6dfe0e2d270e 100644 --- a/extensions/qa-lab/src/providers/mock-openai/server.ts +++ b/extensions/qa-lab/src/providers/mock-openai/server.ts @@ -445,7 +445,7 @@ function extractInputText(content: unknown[]): string { return content .filter( (entry): entry is { type: "input_text"; text: string } => - !!entry && + Boolean(entry) && typeof entry === "object" && (entry as { type?: unknown }).type === "input_text" && typeof (entry as { text?: unknown }).text === "string", @@ -609,14 +609,14 @@ function normalizePromptPathCandidate(candidate: string) { function readTargetFromPrompt(prompt: string) { const backtickedMatches = Array.from(prompt.matchAll(/`([^`]+)`/g)) .map((match) => normalizePromptPathCandidate(match[1] ?? "")) - .filter((value): value is string => !!value); + .filter((value): value is string => Boolean(value)); if (backtickedMatches.length > 0) { return backtickedMatches[0]; } const quotedMatches = Array.from(prompt.matchAll(/"([^"]+)"/g)) .map((match) => normalizePromptPathCandidate(match[1] ?? "")) - .filter((value): value is string => !!value); + .filter((value): value is string => Boolean(value)); if (quotedMatches.length > 0) { return quotedMatches[0]; } diff --git a/extensions/qa-lab/src/runtime-parity.ts b/extensions/qa-lab/src/runtime-parity.ts index a32fdf05a28a..869384c05208 100644 --- a/extensions/qa-lab/src/runtime-parity.ts +++ b/extensions/qa-lab/src/runtime-parity.ts @@ -804,8 +804,8 @@ function classifyRuntimeParityCells(params: { : 0; if ( openclawTranscriptLines !== codexTranscriptLines || - (!params.openclaw.finalText && !!params.codex.finalText) || - (!!params.openclaw.finalText && !params.codex.finalText) + (!params.openclaw.finalText && Boolean(params.codex.finalText)) || + (Boolean(params.openclaw.finalText) && !params.codex.finalText) ) { return { drift: "structural", diff --git a/extensions/qa-lab/src/token-efficiency-report.ts b/extensions/qa-lab/src/token-efficiency-report.ts index bb377643ac40..5733f5842263 100644 --- a/extensions/qa-lab/src/token-efficiency-report.ts +++ b/extensions/qa-lab/src/token-efficiency-report.ts @@ -190,7 +190,7 @@ export function buildTokenEfficiencyReport( const usageSource: TokenEfficiencyRow["usageSource"] = liveUsage ? "live-usage" : "mock-estimate"; const parityResults = params.summary.scenarios .map((scenario) => scenario.runtimeParity) - .filter((result): result is RuntimeParityResult => !!result); + .filter((result): result is RuntimeParityResult => Boolean(result)); if (parityResults.length === 0) { return { diff --git a/extensions/qa-lab/web/src/app.ts b/extensions/qa-lab/web/src/app.ts index c69c52b6aba3..1668091f1527 100644 --- a/extensions/qa-lab/web/src/app.ts +++ b/extensions/qa-lab/web/src/app.ts @@ -320,7 +320,7 @@ export async function createQaLabApp(root: HTMLDivElement) { function isSelectOpen(): boolean { const active = document.activeElement; - return !!active && root.contains(active) && active.tagName === "SELECT"; + return active !== null && root.contains(active) && active.tagName === "SELECT"; } /* ---------- Data fetching ---------- */ diff --git a/extensions/qa-matrix/src/runners/contract/scenario-catalog.ts b/extensions/qa-matrix/src/runners/contract/scenario-catalog.ts index f7f4a59a9631..b2d253ade7f6 100644 --- a/extensions/qa-matrix/src/runners/contract/scenario-catalog.ts +++ b/extensions/qa-matrix/src/runners/contract/scenario-catalog.ts @@ -1,10 +1,10 @@ -import { type QaProviderModeInput } from "../../run-config.js"; +import type { QaProviderModeInput } from "../../run-config.js"; import { collectLiveTransportStandardScenarioCoverage, selectLiveTransportScenarios, type LiveTransportScenarioDefinition, } from "../../shared/live-transport-scenarios.js"; -import { type MatrixQaConfigOverrides } from "../../substrate/config.js"; +import type { MatrixQaConfigOverrides } from "../../substrate/config.js"; import { buildDefaultMatrixQaTopologySpec, findMatrixQaProvisionedRoom, diff --git a/extensions/qa-matrix/src/runners/contract/scenario-runtime-e2ee-destructive.ts b/extensions/qa-matrix/src/runners/contract/scenario-runtime-e2ee-destructive.ts index 5577d01dc418..d6fb6b65ba83 100644 --- a/extensions/qa-matrix/src/runners/contract/scenario-runtime-e2ee-destructive.ts +++ b/extensions/qa-matrix/src/runners/contract/scenario-runtime-e2ee-destructive.ts @@ -87,7 +87,7 @@ async function cleanupMatrixQaTempDevices( ): Promise { await client.stop().catch(() => undefined); const uniqueDeviceIds = [ - ...new Set(deviceIds.filter((deviceId): deviceId is string => !!deviceId)), + ...new Set(deviceIds.filter((deviceId): deviceId is string => Boolean(deviceId))), ]; if (uniqueDeviceIds.length > 0) { await client.deleteOwnDevices(uniqueDeviceIds).catch(() => undefined); diff --git a/extensions/qa-matrix/src/runners/contract/scenario-runtime-shared.ts b/extensions/qa-matrix/src/runners/contract/scenario-runtime-shared.ts index 1cbaf88b706a..5e83b551b839 100644 --- a/extensions/qa-matrix/src/runners/contract/scenario-runtime-shared.ts +++ b/extensions/qa-matrix/src/runners/contract/scenario-runtime-shared.ts @@ -2,7 +2,7 @@ import { randomUUID } from "node:crypto"; import { createMatrixQaClient, type MatrixQaRoomObserver } from "../../substrate/client.js"; import type { MatrixQaObservedEvent } from "../../substrate/events.js"; import { createMatrixQaRoomObserver } from "../../substrate/sync.js"; -import { type MatrixQaProvisionedTopology } from "../../substrate/topology.js"; +import type { MatrixQaProvisionedTopology } from "../../substrate/topology.js"; import { resolveMatrixQaScenarioRoomId } from "./scenario-catalog.js"; import type { MatrixQaCanaryArtifact, diff --git a/extensions/qqbot/src/bridge/gateway.ts b/extensions/qqbot/src/bridge/gateway.ts index 7984e8b79ae4..171f5d1de06f 100644 --- a/extensions/qqbot/src/bridge/gateway.ts +++ b/extensions/qqbot/src/bridge/gateway.ts @@ -131,7 +131,7 @@ export async function startGateway(ctx: GatewayContext): Promise { context: { account: ctx.account }, abortSignal: ctx.abortSignal, }); - accountLogger.info(`approval.native context registered (lease=${!!lease})`); + accountLogger.info(`approval.native context registered (lease=${Boolean(lease)})`); } else { accountLogger.info("No channelRuntime — skipping approval.native registration"); } diff --git a/extensions/qqbot/src/engine/ref/store.ts b/extensions/qqbot/src/engine/ref/store.ts index cb5554bab160..3421441794b0 100644 --- a/extensions/qqbot/src/engine/ref/store.ts +++ b/extensions/qqbot/src/engine/ref/store.ts @@ -98,7 +98,9 @@ function appendLine(line: RefIndexLine): void { function shouldCompact(): boolean { return ( - !!cache && totalLinesOnDisk > cache.size * COMPACT_THRESHOLD_RATIO && totalLinesOnDisk > 1000 + Boolean(cache) && + totalLinesOnDisk > cache.size * COMPACT_THRESHOLD_RATIO && + totalLinesOnDisk > 1000 ); } diff --git a/extensions/qqbot/src/engine/utils/platform.test.ts b/extensions/qqbot/src/engine/utils/platform.test.ts index e641630384be..cf59b179665f 100644 --- a/extensions/qqbot/src/engine/utils/platform.test.ts +++ b/extensions/qqbot/src/engine/utils/platform.test.ts @@ -181,7 +181,7 @@ describe("qqbot media path resolution honors OPENCLAW_HOME (#83562)", () => { const relative = path.relative(parent, candidate); return ( relative === "" || - (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative)) + (relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)) ); } diff --git a/extensions/signal/src/approval-handler.runtime.ts b/extensions/signal/src/approval-handler.runtime.ts index d038b2e93ead..42beca76fe11 100644 --- a/extensions/signal/src/approval-handler.runtime.ts +++ b/extensions/signal/src/approval-handler.runtime.ts @@ -11,9 +11,9 @@ import { buildApprovalReactionPendingContent, type ApprovalReactionPendingContent, } from "openclaw/plugin-sdk/approval-reaction-runtime"; -import { - type ExecApprovalRequest, - type PluginApprovalRequest, +import type { + ExecApprovalRequest, + PluginApprovalRequest, } from "openclaw/plugin-sdk/approval-runtime"; import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env"; import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; diff --git a/extensions/signal/src/approval-native.ts b/extensions/signal/src/approval-native.ts index 5970fa41fb6b..8173209eaa96 100644 --- a/extensions/signal/src/approval-native.ts +++ b/extensions/signal/src/approval-native.ts @@ -12,9 +12,9 @@ import { shouldSuppressLocalNativeExecApprovalPrompt, } from "openclaw/plugin-sdk/approval-native-runtime"; import { buildApprovalReactionPendingContentForRequest } from "openclaw/plugin-sdk/approval-reaction-runtime"; -import { - type ExecApprovalRequest, - type PluginApprovalRequest, +import type { + ExecApprovalRequest, + PluginApprovalRequest, } from "openclaw/plugin-sdk/approval-runtime"; import type { ChannelApprovalCapability, diff --git a/extensions/signal/src/channel.setup.ts b/extensions/signal/src/channel.setup.ts index a3441a99f92c..116beb4b67de 100644 --- a/extensions/signal/src/channel.setup.ts +++ b/extensions/signal/src/channel.setup.ts @@ -1,5 +1,5 @@ import type { ChannelPlugin } from "openclaw/plugin-sdk/core"; -import { type ResolvedSignalAccount } from "./accounts.js"; +import type { ResolvedSignalAccount } from "./accounts.js"; import { signalSetupAdapter } from "./setup-core.js"; import { createSignalPluginBase, signalSetupWizard } from "./shared.js"; diff --git a/extensions/signal/src/outbound-session.ts b/extensions/signal/src/outbound-session.ts index 2a385f7c6b21..8be384284ab0 100644 --- a/extensions/signal/src/outbound-session.ts +++ b/extensions/signal/src/outbound-session.ts @@ -1,4 +1,4 @@ -import { type RoutePeer } from "openclaw/plugin-sdk/routing"; +import type { RoutePeer } from "openclaw/plugin-sdk/routing"; import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime"; import { resolveSignalPeerId, resolveSignalRecipient, resolveSignalSender } from "./identity.js"; import { looksLikeUuid } from "./uuid.js"; diff --git a/extensions/slack/src/channel.setup.ts b/extensions/slack/src/channel.setup.ts index 38959e12ad9c..ed5e4ed085bf 100644 --- a/extensions/slack/src/channel.setup.ts +++ b/extensions/slack/src/channel.setup.ts @@ -3,7 +3,7 @@ import { adaptScopedAccountAccessor, createScopedChannelConfigAdapter, } from "openclaw/plugin-sdk/channel-config-helpers"; -import { type ResolvedSlackAccount } from "./accounts.js"; +import type { ResolvedSlackAccount } from "./accounts.js"; import { listSlackAccountIds, resolveSlackConfigAccessorAccount, @@ -11,7 +11,7 @@ import { resolveSlackAccount, type SlackConfigAccessorAccount, } from "./accounts.js"; -import { type ChannelPlugin } from "./channel-api.js"; +import type { ChannelPlugin } from "./channel-api.js"; import { SlackChannelConfigSchema } from "./config-schema.js"; import { slackSetupAdapter, createSlackSetupWizardProxy } from "./setup-core.js"; import { diff --git a/extensions/slack/src/doctor-contract.ts b/extensions/slack/src/doctor-contract.ts index 9b1346796e05..613650d60af6 100644 --- a/extensions/slack/src/doctor-contract.ts +++ b/extensions/slack/src/doctor-contract.ts @@ -21,7 +21,7 @@ function hasLegacySlackChannelAllowAlias(value: unknown): boolean { return false; } return Object.values(channels).some((channel) => - Object.prototype.hasOwnProperty.call(asObjectRecord(channel) ?? {}, "allow"), + Object.hasOwn(asObjectRecord(channel) ?? {}, "allow"), ); } @@ -34,7 +34,7 @@ function normalizeSlackChannelAllowAliases(params: { const nextChannels = { ...params.channels }; for (const [channelId, channelValue] of Object.entries(params.channels)) { const channel = asObjectRecord(channelValue); - if (!channel || !Object.prototype.hasOwnProperty.call(channel, "allow")) { + if (!channel || !Object.hasOwn(channel, "allow")) { continue; } const nextChannel = { ...channel }; diff --git a/extensions/slack/src/doctor.ts b/extensions/slack/src/doctor.ts index d5a0e75ffe82..8e294b783c0b 100644 --- a/extensions/slack/src/doctor.ts +++ b/extensions/slack/src/doctor.ts @@ -1,4 +1,4 @@ -import { type ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; +import type { ChannelDoctorAdapter } from "openclaw/plugin-sdk/channel-contract"; import { createDangerousNameMatchingMutableAllowlistWarningCollector } from "openclaw/plugin-sdk/channel-policy"; import { legacyConfigRules as SLACK_LEGACY_CONFIG_RULES, diff --git a/extensions/slack/src/send.ts b/extensions/slack/src/send.ts index ebd99723e612..7f127ab7c8da 100644 --- a/extensions/slack/src/send.ts +++ b/extensions/slack/src/send.ts @@ -1,5 +1,5 @@ import type { MessageMetadata } from "@slack/types"; -import { type Block, type KnownBlock, type WebClient } from "@slack/web-api"; +import type { Block, KnownBlock, WebClient } from "@slack/web-api"; import { createMessageReceiptFromOutboundResults, type MessageReceipt, diff --git a/extensions/tavily/src/tavily-search-provider.ts b/extensions/tavily/src/tavily-search-provider.ts index 66baf543669f..7308a192247f 100644 --- a/extensions/tavily/src/tavily-search-provider.ts +++ b/extensions/tavily/src/tavily-search-provider.ts @@ -1,5 +1,5 @@ import { readPositiveIntegerParam } from "openclaw/plugin-sdk/param-readers"; -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; import { buildTavilyWebSearchProviderBase } from "../web-search-shared.js"; type TavilyClientModule = typeof import("./tavily-client.js"); diff --git a/extensions/tavily/web-search-contract-api.ts b/extensions/tavily/web-search-contract-api.ts index ec3361313f58..54266140b355 100644 --- a/extensions/tavily/web-search-contract-api.ts +++ b/extensions/tavily/web-search-contract-api.ts @@ -1,4 +1,4 @@ -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-contract"; import { buildTavilyWebSearchProviderBase } from "./web-search-shared.js"; export function createTavilyWebSearchProvider(): WebSearchProviderPlugin { diff --git a/extensions/telegram/src/account-inspect.ts b/extensions/telegram/src/account-inspect.ts index 974bd3c0f3cf..f936cf0c67fb 100644 --- a/extensions/telegram/src/account-inspect.ts +++ b/extensions/telegram/src/account-inspect.ts @@ -133,7 +133,7 @@ function inspectTokenValue(params: { cfg: OpenClawConfig; value: unknown }): { function hasConfiguredTelegramAccounts(cfg: OpenClawConfig): boolean { const accounts = cfg.channels?.telegram?.accounts; return ( - !!accounts && + Boolean(accounts) && typeof accounts === "object" && !Array.isArray(accounts) && Object.keys(accounts).length > 0 @@ -152,7 +152,7 @@ function inspectTelegramAccountPrimary(params: { const accountConfig = resolveTelegramAccountConfig(params.cfg, accountId); const allowChannelCredentialFallback = accountId === DEFAULT_ACCOUNT_ID || - !!accountConfig || + Boolean(accountConfig) || !hasConfiguredTelegramAccounts(params.cfg); const accountTokenFile = inspectTokenFile(accountConfig?.tokenFile); if (accountTokenFile) { diff --git a/extensions/telegram/src/bot-native-commands.session-meta.test.ts b/extensions/telegram/src/bot-native-commands.session-meta.test.ts index 5de4a7736eb6..229fe1c74cb5 100644 --- a/extensions/telegram/src/bot-native-commands.session-meta.test.ts +++ b/extensions/telegram/src/bot-native-commands.session-meta.test.ts @@ -11,7 +11,7 @@ import { createTelegramTopicCommandContext, type NativeCommandTestParams, } from "./bot-native-commands.fixture-test-support.js"; -import { type RegisterTelegramHandlerParams } from "./bot-native-commands.js"; +import type { RegisterTelegramHandlerParams } from "./bot-native-commands.js"; // All mocks scoped to this file only — does not affect bot-native-commands.test.ts diff --git a/extensions/telegram/src/channel.setup.ts b/extensions/telegram/src/channel.setup.ts index 77480f14075d..1b3808433e2e 100644 --- a/extensions/telegram/src/channel.setup.ts +++ b/extensions/telegram/src/channel.setup.ts @@ -1,5 +1,5 @@ import type { ChannelPlugin } from "openclaw/plugin-sdk/channel-core"; -import { type ResolvedTelegramAccount } from "./accounts.js"; +import type { ResolvedTelegramAccount } from "./accounts.js"; import type { TelegramProbe } from "./probe.js"; import { telegramSetupAdapter } from "./setup-core.js"; import { telegramSetupWizard } from "./setup-surface.js"; diff --git a/extensions/telegram/src/channel.ts b/extensions/telegram/src/channel.ts index 3dde08fd4bc9..013cc5f3693f 100644 --- a/extensions/telegram/src/channel.ts +++ b/extensions/telegram/src/channel.ts @@ -26,7 +26,7 @@ import { import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { createChannelDirectoryAdapter } from "openclaw/plugin-sdk/directory-runtime"; import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime"; -import { type RoutePeer } from "openclaw/plugin-sdk/routing"; +import type { RoutePeer } from "openclaw/plugin-sdk/routing"; import { createComputedAccountStatusAdapter, createDefaultChannelRuntimeState, diff --git a/extensions/telegram/src/doctor.ts b/extensions/telegram/src/doctor.ts index a711cebae2f0..5c5cbe2bb951 100644 --- a/extensions/telegram/src/doctor.ts +++ b/extensions/telegram/src/doctor.ts @@ -1,6 +1,6 @@ -import { - type ChannelDoctorAdapter, - type ChannelDoctorEmptyAllowlistAccountContext, +import type { + ChannelDoctorAdapter, + ChannelDoctorEmptyAllowlistAccountContext, } from "openclaw/plugin-sdk/channel-contract"; import { resolveChannelStreamingBlockEnabled, @@ -147,7 +147,7 @@ export function scanTelegramMalformedGroupsConfig( ): TelegramMalformedGroupsHit[] { const hits: TelegramMalformedGroupsHit[] = []; for (const scope of collectTelegramAccountScopes(cfg)) { - if (!Object.prototype.hasOwnProperty.call(scope.account, "groups")) { + if (!Object.hasOwn(scope.account, "groups")) { continue; } const groups = scope.account.groups; diff --git a/extensions/telegram/src/polling-session.ts b/extensions/telegram/src/polling-session.ts index 17462c115754..9c2f071fd60e 100644 --- a/extensions/telegram/src/polling-session.ts +++ b/extensions/telegram/src/polling-session.ts @@ -19,7 +19,7 @@ import { import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime"; import { withTelegramApiErrorLogging } from "./api-logging.js"; import { createTelegramBot } from "./bot.js"; -import { type TelegramTransport } from "./fetch.js"; +import type { TelegramTransport } from "./fetch.js"; import { isRecoverableTelegramNetworkError } from "./network-errors.js"; import { TelegramPollingLivenessTracker } from "./polling-liveness.js"; import { createTelegramPollingStatusPublisher } from "./polling-status.js"; diff --git a/extensions/telegram/src/shared.ts b/extensions/telegram/src/shared.ts index b7f0a43cdb10..d447154832c1 100644 --- a/extensions/telegram/src/shared.ts +++ b/extensions/telegram/src/shared.ts @@ -91,7 +91,7 @@ function isBlockedByMultiBotGuard(cfg: OpenClawConfig, accountId: string): boole } const accounts = cfg.channels?.telegram?.accounts; const hasConfiguredAccounts = - !!accounts && + Boolean(accounts) && typeof accounts === "object" && !Array.isArray(accounts) && Object.keys(accounts).length > 0; @@ -245,7 +245,7 @@ export function createTelegramPluginBase(params: { name: account.name, enabled: account.enabled, configured: - !!inspected.token?.trim() && + Boolean(inspected.token?.trim()) && !findTelegramTokenOwnerAccountId({ cfg, accountId: account.accountId }), tokenSource: inspected.tokenSource, }; diff --git a/extensions/telegram/src/token.ts b/extensions/telegram/src/token.ts index 07ee3d08dcfd..33d9467e23a1 100644 --- a/extensions/telegram/src/token.ts +++ b/extensions/telegram/src/token.ts @@ -132,7 +132,7 @@ export function resolveTelegramToken( if (accountId !== DEFAULT_ACCOUNT_ID && !accountCfg) { const accounts = telegramCfg?.accounts; const hasConfiguredAccounts = - !!accounts && + Boolean(accounts) && typeof accounts === "object" && !Array.isArray(accounts) && Object.keys(accounts).length > 0; diff --git a/extensions/voice-call/src/config-compat.ts b/extensions/voice-call/src/config-compat.ts index 7b1dac24d7d6..39cf3d6b85b9 100644 --- a/extensions/voice-call/src/config-compat.ts +++ b/extensions/voice-call/src/config-compat.ts @@ -95,10 +95,7 @@ export function collectVoiceCallLegacyConfigIssues(value: unknown): VoiceCallLeg message: "Move streaming.vadThreshold to streaming.providers.openai.vadThreshold.", }); } - if ( - realtimeAgentContext && - Object.prototype.hasOwnProperty.call(realtimeAgentContext, "includeSystemPrompt") - ) { + if (realtimeAgentContext && Object.hasOwn(realtimeAgentContext, "includeSystemPrompt")) { issues.push({ path: "realtime.agentContext.includeSystemPrompt", replacement: "realtime.agentContext", @@ -250,10 +247,7 @@ export function migrateVoiceCallLegacyConfigInput(params: { } else if (typeof streaming?.vadThreshold === "number") { changes.push(`Removed invalid ${configPathPrefix}.streaming.vadThreshold.`); } - if ( - realtimeAgentContext && - Object.prototype.hasOwnProperty.call(realtimeAgentContext, "includeSystemPrompt") - ) { + if (realtimeAgentContext && Object.hasOwn(realtimeAgentContext, "includeSystemPrompt")) { changes.push(`Removed ${configPathPrefix}.realtime.agentContext.includeSystemPrompt.`); } diff --git a/extensions/voice-call/src/config.ts b/extensions/voice-call/src/config.ts index 8cbc53490954..e4a655ab894a 100644 --- a/extensions/voice-call/src/config.ts +++ b/extensions/voice-call/src/config.ts @@ -573,7 +573,7 @@ export function resolveVoiceCallNumberRouteKey( if (!routes) { return undefined; } - if (phone && Object.prototype.hasOwnProperty.call(routes, phone)) { + if (phone && Object.hasOwn(routes, phone)) { return phone; } diff --git a/extensions/voice-call/src/webhook.ts b/extensions/voice-call/src/webhook.ts index 2b653b717719..3707a5aab1b6 100644 --- a/extensions/voice-call/src/webhook.ts +++ b/extensions/voice-call/src/webhook.ts @@ -90,7 +90,7 @@ function appendRecentTalkEventMetadata(call: CallRecord, event: TalkEvent): void const recent = Array.isArray(metadata.recentTalkEvents) ? metadata.recentTalkEvents.filter( (entry): entry is { at: string; type: string; sessionId: string; turnId?: string } => - !!entry && typeof entry === "object" && !Array.isArray(entry), + Boolean(entry) && typeof entry === "object" && !Array.isArray(entry), ) : []; recent.push({ diff --git a/extensions/volcengine/tts.ts b/extensions/volcengine/tts.ts index 8550903058dd..1ef82799fb04 100644 --- a/extensions/volcengine/tts.ts +++ b/extensions/volcengine/tts.ts @@ -117,7 +117,7 @@ async function seedSpeechTTS(params: VolcengineTTSParams & { apiKey: string }): resourceId = DEFAULT_SEED_TTS_RESOURCE_ID, appKey = DEFAULT_SEED_TTS_APP_KEY, baseUrl = BYTEPLUS_SEED_TTS_URL, - speedRatio = 1.0, + speedRatio = 1, emotion, encoding = "ogg_opus", timeoutMs = 30_000, @@ -133,7 +133,7 @@ async function seedSpeechTTS(params: VolcengineTTSParams & { apiKey: string }): format: audioFormat, sample_rate: 24_000, }, - ...(speedRatio !== 1.0 ? { speed_ratio: speedRatio } : {}), + ...(speedRatio !== 1 ? { speed_ratio: speedRatio } : {}), ...(emotion ? { emotion } : {}), }, }); @@ -196,9 +196,9 @@ async function legacyVolcengineTTS( voice = DEFAULT_LEGACY_VOICE, cluster = DEFAULT_CLUSTER, baseUrl = VOLCENGINE_LEGACY_TTS_URL, - speedRatio = 1.0, - volumeRatio = 1.0, - pitchRatio = 1.0, + speedRatio = 1, + volumeRatio = 1, + pitchRatio = 1, emotion, encoding = "ogg_opus", timeoutMs = 30_000, diff --git a/extensions/whatsapp/src/approval-handler.runtime.ts b/extensions/whatsapp/src/approval-handler.runtime.ts index 658051033c41..06c81a7eeb3c 100644 --- a/extensions/whatsapp/src/approval-handler.runtime.ts +++ b/extensions/whatsapp/src/approval-handler.runtime.ts @@ -10,9 +10,9 @@ import { buildApprovalReactionPendingContent, type ApprovalReactionPendingContent, } from "openclaw/plugin-sdk/approval-reaction-runtime"; -import { - type ExecApprovalRequest, - type PluginApprovalRequest, +import type { + ExecApprovalRequest, + PluginApprovalRequest, } from "openclaw/plugin-sdk/approval-runtime"; import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env"; import { diff --git a/extensions/whatsapp/src/channel.setup.ts b/extensions/whatsapp/src/channel.setup.ts index deb83d35057e..9ab0175c06a4 100644 --- a/extensions/whatsapp/src/channel.setup.ts +++ b/extensions/whatsapp/src/channel.setup.ts @@ -1,5 +1,5 @@ import type { ChannelPlugin } from "openclaw/plugin-sdk/core"; -import { type ResolvedWhatsAppAccount } from "./accounts.js"; +import type { ResolvedWhatsAppAccount } from "./accounts.js"; import { resolveWhatsAppGroupIntroHint } from "./group-intro.js"; import { resolveWhatsAppGroupRequireMention, diff --git a/extensions/whatsapp/src/outbound-adapter.ts b/extensions/whatsapp/src/outbound-adapter.ts index e4811db84c76..cfbfbbd2e8ef 100644 --- a/extensions/whatsapp/src/outbound-adapter.ts +++ b/extensions/whatsapp/src/outbound-adapter.ts @@ -1,4 +1,4 @@ -import { type ChannelOutboundAdapter } from "openclaw/plugin-sdk/channel-send-result"; +import type { ChannelOutboundAdapter } from "openclaw/plugin-sdk/channel-send-result"; import { chunkText } from "openclaw/plugin-sdk/reply-chunking"; import { shouldLogVerbose } from "openclaw/plugin-sdk/runtime-env"; import { createWhatsAppOutboundBase } from "./outbound-base.js"; diff --git a/extensions/workboard/doctor-contract-api.ts b/extensions/workboard/doctor-contract-api.ts index 91dfab98dc23..3754992cc71c 100644 --- a/extensions/workboard/doctor-contract-api.ts +++ b/extensions/workboard/doctor-contract-api.ts @@ -1,6 +1,6 @@ -import { - type PluginDoctorStateMigration, - type PluginDoctorStateMigrationContext, +import type { + PluginDoctorStateMigration, + PluginDoctorStateMigrationContext, } from "openclaw/plugin-sdk/runtime-doctor"; import type { PersistedWorkboardAttachment, diff --git a/extensions/xai/src/code-execution-shared.ts b/extensions/xai/src/code-execution-shared.ts index 3f1cb87ce399..9acf840767b6 100644 --- a/extensions/xai/src/code-execution-shared.ts +++ b/extensions/xai/src/code-execution-shared.ts @@ -9,7 +9,7 @@ import { resolveNormalizedXaiToolModel, resolvePositiveIntegerToolConfig, } from "./tool-config-shared.js"; -import { type XaiWebSearchResponse } from "./web-search-shared.js"; +import type { XaiWebSearchResponse } from "./web-search-shared.js"; const XAI_CODE_EXECUTION_ENDPOINT = XAI_RESPONSES_ENDPOINT; const XAI_DEFAULT_CODE_EXECUTION_MODEL = "grok-4-1-fast"; diff --git a/extensions/xai/src/x-search-shared.ts b/extensions/xai/src/x-search-shared.ts index 730000fdb99e..7bbf3f787e50 100644 --- a/extensions/xai/src/x-search-shared.ts +++ b/extensions/xai/src/x-search-shared.ts @@ -10,7 +10,7 @@ import { resolveNormalizedXaiToolModel, resolvePositiveIntegerToolConfig, } from "./tool-config-shared.js"; -import { type XaiWebSearchResponse } from "./web-search-shared.js"; +import type { XaiWebSearchResponse } from "./web-search-shared.js"; export const XAI_DEFAULT_X_SEARCH_MODEL = "grok-4-1-fast-non-reasoning"; diff --git a/extensions/xai/web-search-contract-api.ts b/extensions/xai/web-search-contract-api.ts index 2c53caee05bb..c283550b72da 100644 --- a/extensions/xai/web-search-contract-api.ts +++ b/extensions/xai/web-search-contract-api.ts @@ -1,4 +1,4 @@ -import { type WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; +import type { WebSearchProviderPlugin } from "openclaw/plugin-sdk/provider-web-search-config-contract"; import { buildXaiWebSearchProviderBase } from "./web-search-provider-shared.js"; export function createXaiWebSearchProvider(): WebSearchProviderPlugin { diff --git a/extensions/xai/web-search.ts b/extensions/xai/web-search.ts index 5c7b47a9bb31..e2886cb06117 100644 --- a/extensions/xai/web-search.ts +++ b/extensions/xai/web-search.ts @@ -1,6 +1,6 @@ -import { - type WebSearchProviderPlugin, - type WebSearchProviderSetupContext, +import type { + WebSearchProviderPlugin, + WebSearchProviderSetupContext, } from "openclaw/plugin-sdk/provider-web-search-config-contract"; import { buildXaiWebSearchProviderBase } from "./web-search-provider-shared.js"; diff --git a/extensions/zalo/src/token.ts b/extensions/zalo/src/token.ts index 8c4ef02ff024..bdb0831862ce 100644 --- a/extensions/zalo/src/token.ts +++ b/extensions/zalo/src/token.ts @@ -25,9 +25,7 @@ export function resolveZaloToken( baseConfig?.accounts as Record | undefined, normalizeAccountId(resolvedAccountId), ); - const accountHasBotToken = Boolean( - accountConfig && Object.prototype.hasOwnProperty.call(accountConfig, "botToken"), - ); + const accountHasBotToken = Boolean(accountConfig && Object.hasOwn(accountConfig, "botToken")); if (accountConfig && accountHasBotToken) { const token = options?.allowUnresolvedSecretRef diff --git a/packages/agent-core/src/agent-loop.ts b/packages/agent-core/src/agent-loop.ts index e39328ea0a8a..3b969425054c 100644 --- a/packages/agent-core/src/agent-loop.ts +++ b/packages/agent-core/src/agent-loop.ts @@ -6,11 +6,11 @@ // Keep the runtime class on the package specifier so built agent-core shares // constructor identity with @openclaw/llm-core; source types keep SDK d.ts bundled. import { EventStream as LlmEventStream } from "@openclaw/llm-core"; -import { - type AssistantMessage, - type Context, - type EventStream, - type ToolResultMessage, +import type { + AssistantMessage, + Context, + EventStream, + ToolResultMessage, } from "../../llm-core/src/index.js"; import type { EventStream as SourceEventStream } from "../../llm-core/src/index.js"; import { type AgentCoreStreamRuntimeDeps, resolveAgentCoreStreamFn } from "./runtime-deps.js"; diff --git a/packages/agent-core/src/agent.ts b/packages/agent-core/src/agent.ts index 248f164e4f0d..31ef159163f0 100644 --- a/packages/agent-core/src/agent.ts +++ b/packages/agent-core/src/agent.ts @@ -1,11 +1,11 @@ -import { - type ImageContent, - type Message, - type Model, - type SimpleStreamOptions, - type TextContent, - type ThinkingBudgets, - type Transport, +import type { + ImageContent, + Message, + Model, + SimpleStreamOptions, + TextContent, + ThinkingBudgets, + Transport, } from "../../llm-core/src/index.js"; import { runAgentLoop, runAgentLoopContinue } from "./agent-loop.js"; import { type AgentCoreStreamRuntimeDeps, resolveAgentCoreStreamFn } from "./runtime-deps.js"; diff --git a/packages/agent-core/src/harness/agent-harness.ts b/packages/agent-core/src/harness/agent-harness.ts index ef2f36e54448..9a9684e8cd31 100644 --- a/packages/agent-core/src/harness/agent-harness.ts +++ b/packages/agent-core/src/harness/agent-harness.ts @@ -1,8 +1,8 @@ -import { - type AssistantMessage, - type ImageContent, - type Model, - type UserMessage, +import type { + AssistantMessage, + ImageContent, + Model, + UserMessage, } from "../../../llm-core/src/index.js"; import { runAgentLoop } from "../agent-loop.js"; import { type AgentCoreRuntimeDeps, resolveAgentCoreStreamFn } from "../runtime-deps.js"; diff --git a/packages/agent-core/src/harness/prompt-templates.ts b/packages/agent-core/src/harness/prompt-templates.ts index 8b0df29f3fe6..e8a7f35d5b2a 100644 --- a/packages/agent-core/src/harness/prompt-templates.ts +++ b/packages/agent-core/src/harness/prompt-templates.ts @@ -5,7 +5,7 @@ import { } from "./file-loader-utils.js"; export { parseCommandArgs, substituteArgs } from "./prompt-template-arguments.js"; import { substituteArgs } from "./prompt-template-arguments.js"; -import { type ExecutionEnv, type PromptTemplate, type Result } from "./types.js"; +import type { ExecutionEnv, PromptTemplate, Result } from "./types.js"; export type PromptTemplateDiagnosticCode = | "file_info_failed" diff --git a/packages/agent-core/src/harness/session/memory-storage.ts b/packages/agent-core/src/harness/session/memory-storage.ts index d385e26ea5d9..2b1069889bef 100644 --- a/packages/agent-core/src/harness/session/memory-storage.ts +++ b/packages/agent-core/src/harness/session/memory-storage.ts @@ -1,4 +1,4 @@ -import { type SessionMetadata, type SessionTreeEntry } from "../types.js"; +import type { SessionMetadata, SessionTreeEntry } from "../types.js"; import { BaseSessionStorage } from "./storage-base.js"; import { uuidv7 } from "./uuid.js"; diff --git a/packages/agent-core/src/harness/skills.ts b/packages/agent-core/src/harness/skills.ts index 658423dff6f9..fc945e8c28d0 100644 --- a/packages/agent-core/src/harness/skills.ts +++ b/packages/agent-core/src/harness/skills.ts @@ -7,7 +7,7 @@ import { relativeEnvPath, resolveFileInfoKind as resolveKind, } from "./file-loader-utils.js"; -import { type ExecutionEnv, type Result, type Skill } from "./types.js"; +import type { ExecutionEnv, Result, Skill } from "./types.js"; const MAX_NAME_LENGTH = 64; const MAX_DESCRIPTION_LENGTH = 1024; diff --git a/packages/speech-core/src/tts.ts b/packages/speech-core/src/tts.ts index 1518dfd292bb..0a99a6fd0770 100644 --- a/packages/speech-core/src/tts.ts +++ b/packages/speech-core/src/tts.ts @@ -362,7 +362,7 @@ function asProviderConfigMap(value: unknown): Record { } function hasOwnProperty(value: object, key: string): boolean { - return Object.prototype.hasOwnProperty.call(value, key); + return Object.hasOwn(value, key); } function normalizeProviderConfigMap( diff --git a/scripts/copy-bundled-plugin-metadata.mjs b/scripts/copy-bundled-plugin-metadata.mjs index d60ac2850071..639822d359c1 100644 --- a/scripts/copy-bundled-plugin-metadata.mjs +++ b/scripts/copy-bundled-plugin-metadata.mjs @@ -145,7 +145,7 @@ function resolveBundledSkillTarget(rawPath) { function isTransientCopyError(error) { return ( - !!error && + Boolean(error) && typeof error === "object" && typeof error.code === "string" && TRANSIENT_COPY_ERROR_CODES.has(error.code) diff --git a/scripts/e2e/lib/upgrade-survivor/assertions.mjs b/scripts/e2e/lib/upgrade-survivor/assertions.mjs index 31003a056e7d..0708d0180e0d 100644 --- a/scripts/e2e/lib/upgrade-survivor/assertions.mjs +++ b/scripts/e2e/lib/upgrade-survivor/assertions.mjs @@ -111,7 +111,7 @@ function acceptsIntent(coverage, id) { } function hasCoverage(coverage) { - return !!coverage; + return Boolean(coverage); } function seedState() { diff --git a/scripts/lib/extension-test-plan.mjs b/scripts/lib/extension-test-plan.mjs index f67123c0a40d..ae6954f5fb30 100644 --- a/scripts/lib/extension-test-plan.mjs +++ b/scripts/lib/extension-test-plan.mjs @@ -39,7 +39,7 @@ const EXTENSION_TEST_COST_MULTIPLIERS = { "test/vitest/vitest.extension-discord.config.ts": 0.62, "test/vitest/vitest.extension-feishu.config.ts": 0.18, "test/vitest/vitest.extension-imessage.config.ts": 1.7, - "test/vitest/vitest.extension-irc.config.ts": 1.0, + "test/vitest/vitest.extension-irc.config.ts": 1, "test/vitest/vitest.extension-line.config.ts": 1.1, "test/vitest/vitest.extension-matrix.config.ts": 0.28, "test/vitest/vitest.extension-mattermost.config.ts": 0.75, diff --git a/scripts/update-clawtributors.ts b/scripts/update-clawtributors.ts index 1314346394e9..ef266151d205 100644 --- a/scripts/update-clawtributors.ts +++ b/scripts/update-clawtributors.ts @@ -156,7 +156,7 @@ function computeScore(loc: number, commits: number, prs: number, firstDate: stri ? Math.max(0, (now - new Date(firstDate.slice(0, 10)).getTime()) / 86_400_000) : 0; const tenureRatio = Math.min(1, daysIn / repoAgeDays); - const tenure = 1.0 + tenureRatio * tenureRatio * 0.5; + const tenure = 1 + tenureRatio * tenureRatio * 0.5; return base * tenure; } @@ -330,7 +330,7 @@ for (const [index, entry] of visibleEntries.slice(0, 25).entries()) { const daysIn = fd !== "?" ? Math.max(0, (now - new Date(fd.slice(0, 10)).getTime()) / 86_400_000) : 0; const tr = Math.min(1, daysIn / repoAgeDays); - const tenure = 1.0 + tr * tr * 0.5; + const tenure = 1 + tr * tr * 0.5; console.log( `${index + 1}`.padStart(3) + ` ${login.padEnd(24)} ${entry.score.toFixed(0).padStart(8)} ${tenure.toFixed(2).padStart(6)}x ${String(entry.commits).padStart(8)} ${String(entry.prs).padStart(6)} ${String(entry.lines).padStart(10)} ${fd}`, diff --git a/src/agents/agent-command.live-model-switch.test.ts b/src/agents/agent-command.live-model-switch.test.ts index e704294ab5f9..08c70c6e2b9a 100644 --- a/src/agents/agent-command.live-model-switch.test.ts +++ b/src/agents/agent-command.live-model-switch.test.ts @@ -397,7 +397,7 @@ vi.mock("./model-selection.js", () => { ? entry.models .filter( (model): model is Record => - !!model && typeof model === "object", + Boolean(model) && typeof model === "object", ) .map((model) => { const id = typeof model.id === "string" ? model.id : ""; @@ -487,7 +487,8 @@ vi.mock("./model-selection.js", () => { Array.isArray(entry?.models) ? entry.models .filter( - (model): model is Record => !!model && typeof model === "object", + (model): model is Record => + Boolean(model) && typeof model === "object", ) .map((model) => { const id = typeof model.id === "string" ? model.id : ""; diff --git a/src/agents/agent-hooks/context-pruning.test.ts b/src/agents/agent-hooks/context-pruning.test.ts index 0598244076e4..0be3a659bf81 100644 --- a/src/agents/agent-hooks/context-pruning.test.ts +++ b/src/agents/agent-hooks/context-pruning.test.ts @@ -259,7 +259,7 @@ describe("context-pruning", () => { const next = pruneWithAggressiveDefaults(messages, { keepLastAssistants: 1, - softTrimRatio: 10.0, + softTrimRatio: 10, softTrim: DEFAULT_CONTEXT_PRUNING_SETTINGS.softTrim, }); @@ -399,7 +399,7 @@ describe("context-pruning", () => { ]; const next = pruneWithAggressiveDefaults(messages, { - hardClearRatio: 10.0, + hardClearRatio: 10, hardClear: { enabled: false, placeholder: "[cleared]" }, softTrim: { maxChars: 200, headChars: 100, tailChars: 100 }, }); @@ -427,7 +427,7 @@ describe("context-pruning", () => { ]; const next = pruneWithAggressiveDefaults(messages, { - hardClearRatio: 10.0, + hardClearRatio: 10, softTrim: { maxChars: 5, headChars: 7, tailChars: 3 }, }); @@ -448,7 +448,7 @@ describe("context-pruning", () => { ]; const next = pruneWithAggressiveDefaults(messages, { - hardClearRatio: 10.0, + hardClearRatio: 10, softTrim: { maxChars: 10, headChars: 6, tailChars: 6 }, }); diff --git a/src/agents/agent-hooks/context-pruning/pruner.ts b/src/agents/agent-hooks/context-pruning/pruner.ts index 93cf888c86ef..e381d51d3327 100644 --- a/src/agents/agent-hooks/context-pruning/pruner.ts +++ b/src/agents/agent-hooks/context-pruning/pruner.ts @@ -34,7 +34,9 @@ function coerceTextBlock(block: unknown): string | null { } function isImageBlock(block: unknown): boolean { - return !!block && typeof block === "object" && (block as { type?: unknown }).type === "image"; + return ( + Boolean(block) && typeof block === "object" && (block as { type?: unknown }).type === "image" + ); } function collectTextSegments(content: ReadonlyArray): string[] { diff --git a/src/agents/agent-tools-parameter-schema.ts b/src/agents/agent-tools-parameter-schema.ts index f6517b17c8c5..038b4f0a9d91 100644 --- a/src/agents/agent-tools-parameter-schema.ts +++ b/src/agents/agent-tools-parameter-schema.ts @@ -426,7 +426,7 @@ function resolveJsonPointerPath(value: unknown, segments: string[]): unknown { continue; } const record = current as Record; - if (!Object.prototype.hasOwnProperty.call(record, key)) { + if (!Object.hasOwn(record, key)) { return undefined; } current = record[key]; diff --git a/src/agents/agent-tools.before-tool-call.ts b/src/agents/agent-tools.before-tool-call.ts index 36f8ed254544..2932428c03c5 100644 --- a/src/agents/agent-tools.before-tool-call.ts +++ b/src/agents/agent-tools.before-tool-call.ts @@ -465,10 +465,7 @@ async function requestPluginToolApproval(params: { params: params.baseParams, }; } - const hasImmediateDecision = Object.prototype.hasOwnProperty.call( - requestResult ?? {}, - "decision", - ); + const hasImmediateDecision = Object.hasOwn(requestResult ?? {}, "decision"); let decision: string | null | undefined; if (hasImmediateDecision) { decision = requestResult?.decision; diff --git a/src/agents/agent-tools.read.ts b/src/agents/agent-tools.read.ts index 08cfa2024eec..923b5a895319 100644 --- a/src/agents/agent-tools.read.ts +++ b/src/agents/agent-tools.read.ts @@ -188,7 +188,7 @@ function stripReadTruncationContentDetails( } const truncation = truncationRaw as Record; - if (!Object.prototype.hasOwnProperty.call(truncation, "content")) { + if (!Object.hasOwn(truncation, "content")) { return result; } @@ -374,7 +374,7 @@ async function normalizeReadImageResult( const image = content.find( (b): b is ImageContentBlock => - !!b && + Boolean(b) && typeof b === "object" && (b as { type?: unknown }).type === "image" && typeof (b as { data?: unknown }).data === "string" && diff --git a/src/agents/agent-tools.schema.test.ts b/src/agents/agent-tools.schema.test.ts index ad262c4723d6..08204cd14fb5 100644 --- a/src/agents/agent-tools.schema.test.ts +++ b/src/agents/agent-tools.schema.test.ts @@ -1016,7 +1016,7 @@ describe("normalizeToolParameters", () => { ]), }); expect( - Object.prototype.hasOwnProperty.call( + Object.hasOwn( (normalized.parameters as { properties?: Record }).properties, "__proto__", ), diff --git a/src/agents/agent-tools.ts b/src/agents/agent-tools.ts index b76f856be08d..19d2fe788007 100644 --- a/src/agents/agent-tools.ts +++ b/src/agents/agent-tools.ts @@ -901,7 +901,7 @@ export function createOpenClawCodingTools(options?: { sessionId: options?.sessionId, sandboxBrowserBridgeUrl: sandbox?.browser?.bridgeUrl, allowHostBrowserControl: sandbox ? sandbox.browserAllowHostControl : true, - sandboxed: !!sandbox, + sandboxed: Boolean(sandbox), pluginToolAllowlist, pluginToolDenylist, currentChannelId: options?.currentChannelId, @@ -986,7 +986,7 @@ export function createOpenClawCodingTools(options?: { spawnWorkspaceDir: options?.spawnWorkspaceDir ? resolveWorkspaceRoot(options.spawnWorkspaceDir) : undefined, - sandboxed: !!sandbox, + sandboxed: Boolean(sandbox), config: options?.config, pluginToolAllowlist, pluginToolDenylist, diff --git a/src/agents/auth-profiles/external-cli-auth-selection.ts b/src/agents/auth-profiles/external-cli-auth-selection.ts index 976be94eb4a3..dea3871818bd 100644 --- a/src/agents/auth-profiles/external-cli-auth-selection.ts +++ b/src/agents/auth-profiles/external-cli-auth-selection.ts @@ -155,7 +155,7 @@ function resolveConfiguredAuthProfileOrder(params: { ...new Set( orderedProfileIds .map((profileId) => profileId?.trim()) - .filter((profileId): profileId is string => !!profileId), + .filter((profileId): profileId is string => Boolean(profileId)), ), ]; } diff --git a/src/agents/auth-profiles/usage-state.ts b/src/agents/auth-profiles/usage-state.ts index 0ee52e0f76bc..d3880fca0f1e 100644 --- a/src/agents/auth-profiles/usage-state.ts +++ b/src/agents/auth-profiles/usage-state.ts @@ -29,12 +29,12 @@ function shouldBypassModelScopedCooldown( now: number, forModel?: string, ): boolean { - return !!( + return Boolean( forModel && stats.cooldownReason === "rate_limit" && stats.cooldownModel && stats.cooldownModel !== forModel && - !isActiveUnusableWindow(stats.disabledUntil, now) + !isActiveUnusableWindow(stats.disabledUntil, now), ); } diff --git a/src/agents/auth-profiles/usage.ts b/src/agents/auth-profiles/usage.ts index 7493aafbc138..08284c365376 100644 --- a/src/agents/auth-profiles/usage.ts +++ b/src/agents/auth-profiles/usage.ts @@ -160,11 +160,11 @@ function resolveWhamResetMs(window: WhamUsageWindow | undefined, now: number): n } function isWhamWindowExhausted(window: WhamUsageWindow | undefined): boolean { - return !!( + return Boolean( window && typeof window.used_percent === "number" && Number.isFinite(window.used_percent) && - window.used_percent >= 100 + window.used_percent >= 100, ); } diff --git a/src/agents/bash-tools.exec.ts b/src/agents/bash-tools.exec.ts index 87a75eb06047..8daf6e543000 100644 --- a/src/agents/bash-tools.exec.ts +++ b/src/agents/bash-tools.exec.ts @@ -156,7 +156,7 @@ function shouldSkipScriptPreflightPathError( return true; } const errorCode = getNodeErrorCode(error); - return !!(errorCode && SKIPPABLE_SCRIPT_PREFLIGHT_FS_ERROR_CODES.has(errorCode)); + return Boolean(errorCode && SKIPPABLE_SCRIPT_PREFLIGHT_FS_ERROR_CODES.has(errorCode)); } function resolvePreflightRelativePath(params: { rootDir: string; absPath: string }): string | null { diff --git a/src/agents/btw.ts b/src/agents/btw.ts index 90489b2a4e76..b8387435a077 100644 --- a/src/agents/btw.ts +++ b/src/agents/btw.ts @@ -6,12 +6,12 @@ import type { SessionEntry as StoredSessionEntry } from "../config/sessions.js"; import type { OpenClawConfig } from "../config/types.openclaw.js"; import { streamWithPayloadPatch } from "../llm/providers/stream-wrappers/stream-payload-utils.js"; import { streamSimple } from "../llm/stream.js"; -import { - type AssistantMessageEvent, - type ImageContent, - type Message, - type Model, - type TextContent, +import type { + AssistantMessageEvent, + ImageContent, + Message, + Model, + TextContent, } from "../llm/types.js"; import { prepareProviderRuntimeAuth } from "../plugins/provider-runtime.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; diff --git a/src/agents/cli-runner/session-history.ts b/src/agents/cli-runner/session-history.ts index 629284de4539..6fea2ffc3c6a 100644 --- a/src/agents/cli-runner/session-history.ts +++ b/src/agents/cli-runner/session-history.ts @@ -172,7 +172,7 @@ export function buildCliSessionHistoryPrompt(params: { // alone exceeds the cap. const firstEntry = params.messages[0]; const firstIsCompaction = - !!firstEntry && + Boolean(firstEntry) && typeof firstEntry === "object" && (firstEntry as HistoryMessage).role === "compactionSummary"; const summaryRendered = firstIsCompaction ? renderHistoryMessage(firstEntry) : undefined; diff --git a/src/agents/configured-provider-fallback.ts b/src/agents/configured-provider-fallback.ts index 96c8d5f4934c..0a400f51938e 100644 --- a/src/agents/configured-provider-fallback.ts +++ b/src/agents/configured-provider-fallback.ts @@ -17,8 +17,8 @@ export function resolveConfiguredProviderFallback(params: { const defaultProviderConfig = configuredProviders[params.defaultProvider]; const defaultModel = params.defaultModel?.trim(); const defaultProviderHasDefaultModel = - !!defaultProviderConfig && - !!defaultModel && + Boolean(defaultProviderConfig) && + Boolean(defaultModel) && Array.isArray(defaultProviderConfig.models) && defaultProviderConfig.models.some((model) => model?.id === defaultModel); if (defaultProviderConfig && (!defaultModel || defaultProviderHasDefaultModel)) { diff --git a/src/agents/embedded-agent-runner/compact.ts b/src/agents/embedded-agent-runner/compact.ts index 77d26e8a4f1c..00580d9b64fd 100644 --- a/src/agents/embedded-agent-runner/compact.ts +++ b/src/agents/embedded-agent-runner/compact.ts @@ -1146,7 +1146,7 @@ async function compactEmbeddedAgentSessionDirectOnce( const { customTools } = splitSdkTools({ tools: effectiveTools, - sandboxEnabled: !!sandbox?.enabled, + sandboxEnabled: Boolean(sandbox?.enabled), toolHookContext: { agentId: sessionAgentId, config: params.config, diff --git a/src/agents/embedded-agent-runner/compaction-successor-transcript.ts b/src/agents/embedded-agent-runner/compaction-successor-transcript.ts index 4260db4e5674..775f1a2e7205 100644 --- a/src/agents/embedded-agent-runner/compaction-successor-transcript.ts +++ b/src/agents/embedded-agent-runner/compaction-successor-transcript.ts @@ -3,7 +3,7 @@ import path from "node:path"; import { resolveTimestampMsToIsoString } from "@openclaw/normalization-core/number-coercion"; import { CURRENT_SESSION_VERSION } from "../../config/sessions/version.js"; import type { OpenClawConfig } from "../../config/types.openclaw.js"; -import { type CompactionEntry, type SessionEntry, type SessionHeader } from "../sessions/index.js"; +import type { CompactionEntry, SessionEntry, SessionHeader } from "../sessions/index.js"; import { collectDuplicateUserMessageEntryIdsForCompaction } from "./compaction-duplicate-user-messages.js"; import { readTranscriptFileState, diff --git a/src/agents/embedded-agent-runner/run.ts b/src/agents/embedded-agent-runner/run.ts index b62e757f1b25..ec49cffd233a 100644 --- a/src/agents/embedded-agent-runner/run.ts +++ b/src/agents/embedded-agent-runner/run.ts @@ -360,7 +360,7 @@ function createScopedAuthProfileStore( const profiles = store.profiles ?? {}; const normalizedProfileIds = (Array.isArray(profileIds) ? profileIds : [profileIds]) .map((profileId) => profileId?.trim()) - .filter((profileId): profileId is string => !!profileId); + .filter((profileId): profileId is string => Boolean(profileId)); const scopedProfiles = Object.fromEntries( normalizedProfileIds.flatMap((profileId) => { const credential = profiles[profileId]; diff --git a/src/agents/embedded-agent-runner/run/attempt.session-lock.ts b/src/agents/embedded-agent-runner/run/attempt.session-lock.ts index 90bcdc1fd813..47deece9110a 100644 --- a/src/agents/embedded-agent-runner/run/attempt.session-lock.ts +++ b/src/agents/embedded-agent-runner/run/attempt.session-lock.ts @@ -516,7 +516,7 @@ function isTrustedSessionFileState( fingerprint: SessionFileFingerprint, ): boolean { const trusted = trustedSessionFileStates.get(sessionFileKey); - return !!trusted && sameSessionFileFingerprint(trusted.fingerprint, fingerprint); + return trusted !== undefined && sameSessionFileFingerprint(trusted.fingerprint, fingerprint); } async function readSessionFileFingerprint(sessionFile: string): Promise { diff --git a/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.test.ts b/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.test.ts index cbdacb254e29..87b67bf81c28 100644 --- a/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.test.ts +++ b/src/agents/embedded-agent-runner/run/attempt.tool-call-normalization.test.ts @@ -1065,7 +1065,7 @@ describe("sanitizeOpenAIResponsesReplayForStream", () => { const assistant = out[0] as Extract; const toolCall = assistant.content.find( (block) => - !!block && + Boolean(block) && typeof block === "object" && (block as { type?: unknown }).type === "toolCall" && typeof (block as { id?: unknown }).id === "string", diff --git a/src/agents/embedded-agent-runner/run/attempt.ts b/src/agents/embedded-agent-runner/run/attempt.ts index 701585b24f23..06c5ec48dd21 100644 --- a/src/agents/embedded-agent-runner/run/attempt.ts +++ b/src/agents/embedded-agent-runner/run/attempt.ts @@ -1996,7 +1996,7 @@ export async function runEmbeddedAttempt( const { customTools } = splitSdkTools({ tools: effectiveTools, - sandboxEnabled: !!sandbox?.enabled, + sandboxEnabled: Boolean(sandbox?.enabled), toolHookContext: catalogToolHookContext, }); diff --git a/src/agents/embedded-agent-runner/thinking.ts b/src/agents/embedded-agent-runner/thinking.ts index 080934984ee0..71f830d35629 100644 --- a/src/agents/embedded-agent-runner/thinking.ts +++ b/src/agents/embedded-agent-runner/thinking.ts @@ -14,7 +14,7 @@ export const OMITTED_ASSISTANT_REASONING_TEXT = "[assistant reasoning omitted]"; export function isAssistantMessageWithContent(message: AgentMessage): message is AssistantMessage { return ( - !!message && + Boolean(message) && typeof message === "object" && message.role === "assistant" && Array.isArray(message.content) @@ -23,7 +23,7 @@ export function isAssistantMessageWithContent(message: AgentMessage): message is function isThinkingBlock(block: AssistantContentBlock): boolean { return ( - !!block && + Boolean(block) && typeof block === "object" && ((block as { type?: unknown }).type === "thinking" || (block as { type?: unknown }).type === "redacted_thinking") @@ -44,7 +44,7 @@ function hasAssistantToolCall(message: AssistantMessage): boolean { function isToolResultMessage(message: AgentMessage): boolean { return ( - !!message && + Boolean(message) && typeof message === "object" && (message as { role?: unknown }).role === "toolResult" ); diff --git a/src/agents/embedded-agent-runner/tool-result-char-estimator.ts b/src/agents/embedded-agent-runner/tool-result-char-estimator.ts index 7c2e859d805c..f87b73a2f59e 100644 --- a/src/agents/embedded-agent-runner/tool-result-char-estimator.ts +++ b/src/agents/embedded-agent-runner/tool-result-char-estimator.ts @@ -8,7 +8,7 @@ export type MessageCharEstimateCache = WeakMap; function isTextBlock(block: unknown): block is { type: "text"; text: string } { return ( - !!block && + Boolean(block) && typeof block === "object" && (block as { type?: unknown }).type === "text" && typeof (block as { text?: unknown }).text === "string" @@ -16,7 +16,9 @@ function isTextBlock(block: unknown): block is { type: "text"; text: string } { } function isImageBlock(block: unknown): boolean { - return !!block && typeof block === "object" && (block as { type?: unknown }).type === "image"; + return ( + Boolean(block) && typeof block === "object" && (block as { type?: unknown }).type === "image" + ); } function estimateUnknownChars(value: unknown): number { diff --git a/src/agents/embedded-agent-runner/usage-accumulator.ts b/src/agents/embedded-agent-runner/usage-accumulator.ts index 119dd84c2fa4..a308762d50e0 100644 --- a/src/agents/embedded-agent-runner/usage-accumulator.ts +++ b/src/agents/embedded-agent-runner/usage-accumulator.ts @@ -34,7 +34,7 @@ export const createUsageAccumulator = (): UsageAccumulator => ({ type MaybeUsage = NormalizedUsage | undefined; const hasUsageValues = (usage: MaybeUsage): usage is NormalizedUsage => - !!usage && + Boolean(usage) && [ usage.input, usage.output, diff --git a/src/agents/harness-runtimes.ts b/src/agents/harness-runtimes.ts index 32e337a6e3a8..184b1cb3bcd7 100644 --- a/src/agents/harness-runtimes.ts +++ b/src/agents/harness-runtimes.ts @@ -11,7 +11,7 @@ function normalizeConfiguredRuntimeId(value: unknown): string | undefined { function isSelectablePluginRuntime(runtime: string | undefined): runtime is string { return ( - !!runtime && + Boolean(runtime) && !isDefaultAgentRuntimeId(runtime) && normalizeOptionalAgentRuntimeId(runtime) !== OPENCLAW_AGENT_RUNTIME_ID ); diff --git a/src/agents/harness/native-hook-relay.ts b/src/agents/harness/native-hook-relay.ts index a6c4f8454ed7..4a61c8d11086 100644 --- a/src/agents/harness/native-hook-relay.ts +++ b/src/agents/harness/native-hook-relay.ts @@ -1643,7 +1643,7 @@ function updateJsonHash(hash: ReturnType, value: JsonValue): const sortedKeySet = new Set(keys); hash.update("#object-tail:"); for (const key in value) { - if (!Object.prototype.hasOwnProperty.call(value, key) || sortedKeySet.has(key)) { + if (!Object.hasOwn(value, key) || sortedKeySet.has(key)) { continue; } hash.update(JSON.stringify(key)); @@ -1662,7 +1662,7 @@ function readBoundedOwnKeys( const keys: string[] = []; let truncated = false; for (const key in value) { - if (!Object.prototype.hasOwnProperty.call(value, key)) { + if (!Object.hasOwn(value, key)) { continue; } if (keys.length >= maxKeys) { @@ -1976,7 +1976,7 @@ async function requestNativeHookRelayPermissionApproval( return "defer"; } let decision: string | null | undefined; - if (Object.prototype.hasOwnProperty.call(requestResult ?? {}, "decision")) { + if (Object.hasOwn(requestResult ?? {}, "decision")) { decision = requestResult.decision; } else { const waitResult = await waitForNativeHookRelayApprovalDecision({ @@ -2234,7 +2234,7 @@ function isJsonValue(value: unknown): value is JsonValue { } try { for (const key in current.value) { - if (!Object.prototype.hasOwnProperty.call(current.value, key)) { + if (!Object.hasOwn(current.value, key)) { continue; } if (key.length > MAX_NATIVE_HOOK_RELAY_STRING_LENGTH) { diff --git a/src/agents/live-cache-test-support.ts b/src/agents/live-cache-test-support.ts index 1981c86a2a1c..0d8fbb862e07 100644 --- a/src/agents/live-cache-test-support.ts +++ b/src/agents/live-cache-test-support.ts @@ -2,7 +2,7 @@ import { getRuntimeConfig } from "../config/config.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { parseStrictInteger } from "../infra/parse-finite-number.js"; import { completeSimple } from "../llm/stream.js"; -import { type Api, type AssistantMessage, type Model } from "../llm/types.js"; +import type { Api, AssistantMessage, Model } from "../llm/types.js"; import { discoverAuthStorage, discoverModels } from "./agent-model-discovery.js"; import { resolveDefaultAgentDir } from "./agent-scope.js"; import { collectProviderApiKeys } from "./live-auth-keys.js"; diff --git a/src/agents/model-auth.ts b/src/agents/model-auth.ts index 355c83ab3d0e..6a1cb588513c 100644 --- a/src/agents/model-auth.ts +++ b/src/agents/model-auth.ts @@ -46,7 +46,7 @@ import { isNonSecretApiKeyMarker, NON_ENV_SECRETREF_MARKER, } from "./model-auth-markers.js"; -import { type ResolvedProviderAuth } from "./model-auth-runtime-shared.js"; +import type { ResolvedProviderAuth } from "./model-auth-runtime-shared.js"; import { normalizeProviderId } from "./model-selection.js"; export { diff --git a/src/agents/model-provider-auth.worker.ts b/src/agents/model-provider-auth.worker.ts index d2255f651c41..e3c00b77c8cb 100644 --- a/src/agents/model-provider-auth.worker.ts +++ b/src/agents/model-provider-auth.worker.ts @@ -31,7 +31,7 @@ type ProviderAuthWarmWorkerResult = function isWorkerInput(value: unknown): value is ProviderAuthWarmWorkerInput { return ( - !!value && + Boolean(value) && typeof value === "object" && "cfg" in value && (!("runtimeAuthStores" in value) || diff --git a/src/agents/model-scan.ts b/src/agents/model-scan.ts index bd59520f4417..a8c03ce8de85 100644 --- a/src/agents/model-scan.ts +++ b/src/agents/model-scan.ts @@ -16,7 +16,7 @@ import { formatErrorMessage } from "../infra/errors.js"; import { getEnvApiKey } from "../llm/env-api-keys.js"; import type { OpenAICompletionsOptions } from "../llm/providers/openai-completions.js"; import { complete } from "../llm/stream.js"; -import { type Context, type Model, type Tool } from "../llm/types.js"; +import type { Context, Model, Tool } from "../llm/types.js"; import { inferParamBFromIdOrName } from "../shared/model-param-b.js"; const OPENROUTER_MODELS_URL = "https://openrouter.ai/api/v1/models"; diff --git a/src/agents/openai-completions-string-content.ts b/src/agents/openai-completions-string-content.ts index 8940a90aa6b4..7d8e34d88e60 100644 --- a/src/agents/openai-completions-string-content.ts +++ b/src/agents/openai-completions-string-content.ts @@ -41,10 +41,10 @@ export function stripCompletionMessagesToRoleContent(messages: unknown[]): unkno } const record = message as Record; const stripped: Record = {}; - if (Object.prototype.hasOwnProperty.call(record, "role")) { + if (Object.hasOwn(record, "role")) { stripped.role = record.role; } - if (Object.prototype.hasOwnProperty.call(record, "content")) { + if (Object.hasOwn(record, "content")) { stripped.content = record.content; } return stripped; diff --git a/src/agents/openai-responses.reasoning-replay.test.ts b/src/agents/openai-responses.reasoning-replay.test.ts index c7b5dd02704f..d8344d583d4b 100644 --- a/src/agents/openai-responses.reasoning-replay.test.ts +++ b/src/agents/openai-responses.reasoning-replay.test.ts @@ -33,7 +33,9 @@ function extractInputTypes(input: unknown[]) { function extractInputMessages(input: unknown[]) { return input.filter( (item): item is Record => - !!item && typeof item === "object" && (item as Record).type === "message", + Boolean(item) && + typeof item === "object" && + (item as Record).type === "message", ); } diff --git a/src/agents/openai-transport-stream.ts b/src/agents/openai-transport-stream.ts index a2afe022c979..498a28e98cde 100644 --- a/src/agents/openai-transport-stream.ts +++ b/src/agents/openai-transport-stream.ts @@ -887,7 +887,7 @@ function encryptedReasoningReplayMetadataMatches( context: OpenAIResponsesReplayContext, ): boolean { return ( - !!metadata && + Boolean(metadata) && metadata.provider === context.provider && metadata.api === context.api && metadata.model === context.model && diff --git a/src/agents/runtime/proxy.ts b/src/agents/runtime/proxy.ts index 9fa798a2696a..aa4105ba493d 100644 --- a/src/agents/runtime/proxy.ts +++ b/src/agents/runtime/proxy.ts @@ -4,14 +4,14 @@ */ // Internal import for JSON parsing utility -import { - type AssistantMessage, - type AssistantMessageEvent, - type Context, - type Model, - type SimpleStreamOptions, - type StopReason, - type ToolCall, +import type { + AssistantMessage, + AssistantMessageEvent, + Context, + Model, + SimpleStreamOptions, + StopReason, + ToolCall, } from "../../llm/types.js"; import { EventStream } from "../../llm/utils/event-stream.js"; import { parseStreamingJson } from "../../llm/utils/json-parse.js"; diff --git a/src/agents/schema/clean-for-gemini.ts b/src/agents/schema/clean-for-gemini.ts index e2db433e4871..35304b9e1ba6 100644 --- a/src/agents/schema/clean-for-gemini.ts +++ b/src/agents/schema/clean-for-gemini.ts @@ -418,7 +418,7 @@ function flattenUnionFallback( variants: unknown[], ): Record | undefined { const objects = variants.filter( - (v): v is Record => !!v && typeof v === "object", + (v): v is Record => Boolean(v) && typeof v === "object", ); if (objects.length === 0) { return undefined; diff --git a/src/agents/sessions/agent-session.ts b/src/agents/sessions/agent-session.ts index ba53c804fb40..cdc859a9694b 100644 --- a/src/agents/sessions/agent-session.ts +++ b/src/agents/sessions/agent-session.ts @@ -1729,7 +1729,7 @@ export class AgentSession { * Check if current model supports thinking/reasoning. */ supportsThinking(): boolean { - return !!this.model?.reasoning; + return Boolean(this.model?.reasoning); } private getThinkingLevelForModelSwitch(explicitLevel?: ThinkingLevel): ThinkingLevel { diff --git a/src/agents/sessions/model-registry.ts b/src/agents/sessions/model-registry.ts index 451756909dcc..ae657114a727 100644 --- a/src/agents/sessions/model-registry.ts +++ b/src/agents/sessions/model-registry.ts @@ -9,15 +9,15 @@ import { Compile } from "typebox/compile"; import type { TLocalizedValidationError } from "typebox/error"; import { registerApiProvider } from "../../llm/api-registry.js"; import { resetApiProviders } from "../../llm/providers/register-builtins.js"; -import { - type AnthropicMessagesCompat, - type Api, - type AssistantMessageEventStreamContract, - type Context, - type Model, - type OpenAICompletionsCompat, - type OpenAIResponsesCompat, - type SimpleStreamOptions, +import type { + AnthropicMessagesCompat, + Api, + AssistantMessageEventStreamContract, + Context, + Model, + OpenAICompletionsCompat, + OpenAIResponsesCompat, + SimpleStreamOptions, } from "../../llm/types.js"; import { registerOAuthProvider, resetOAuthProviders } from "../../llm/utils/oauth/index.js"; import type { OAuthProviderInterface } from "../../llm/utils/oauth/types.js"; @@ -475,7 +475,7 @@ export class ModelRegistry { private validateConfig(config: ModelsConfig): void { for (const [providerName, providerConfig] of Object.entries(config.providers)) { - const hasProviderApi = !!providerConfig.api; + const hasProviderApi = Boolean(providerConfig.api); const models = providerConfig.models ?? []; if (models.length === 0) { @@ -495,7 +495,7 @@ export class ModelRegistry { } for (const modelDef of models) { - const hasModelApi = !!modelDef.api; + const hasModelApi = Boolean(modelDef.api); if (!hasProviderApi && !hasModelApi) { throw new Error( diff --git a/src/agents/sessions/session-manager.ts b/src/agents/sessions/session-manager.ts index 993cca01eede..4f1aeaf89bfd 100644 --- a/src/agents/sessions/session-manager.ts +++ b/src/agents/sessions/session-manager.ts @@ -25,7 +25,7 @@ import { type SessionTreeEntry as CoreSessionTreeEntry, uuidv7, } from "../runtime/index.js"; -import { type BashExecutionMessage, type CustomMessage } from "./messages.js"; +import type { BashExecutionMessage, CustomMessage } from "./messages.js"; export { CURRENT_SESSION_VERSION }; diff --git a/src/agents/sessions/system-prompt.ts b/src/agents/sessions/system-prompt.ts index cf55ff8c3246..1fdf5c851ff7 100644 --- a/src/agents/sessions/system-prompt.ts +++ b/src/agents/sessions/system-prompt.ts @@ -88,7 +88,7 @@ export function buildSystemPrompt(options: BuildSystemPromptOptions): string { // Build tools list based on selected tools. // A tool appears in Available tools only when the caller provides a one-line snippet. const tools = selectedTools || ["read", "bash", "edit", "write"]; - const visibleTools = tools.filter((name) => !!toolSnippets?.[name]); + const visibleTools = tools.filter((name) => Boolean(toolSnippets?.[name])); const toolsList = visibleTools.length > 0 ? visibleTools.map((name) => `- ${name}: ${toolSnippets![name]}`).join("\n") diff --git a/src/agents/subagent-list.ts b/src/agents/subagent-list.ts index 374c37ed141e..9d3bb25b947f 100644 --- a/src/agents/subagent-list.ts +++ b/src/agents/subagent-list.ts @@ -283,7 +283,7 @@ export function buildSubagentList(params: { .filter( (entry) => !isActiveSubagentRun(entry, pendingDescendantCount) && - !!entry.endedAt && + Boolean(entry.endedAt) && (entry.endedAt ?? 0) >= recentCutoff, ) .map((entry) => diff --git a/src/agents/subagent-spawn.ts b/src/agents/subagent-spawn.ts index 66ef08af6af6..2db842d76264 100644 --- a/src/agents/subagent-spawn.ts +++ b/src/agents/subagent-spawn.ts @@ -96,10 +96,10 @@ import { updateSessionStore, isAdminOnlyMethod, } from "./subagent-spawn.runtime.js"; -import { - type SpawnSubagentContextMode, - type SpawnSubagentMode, - type SpawnSubagentSandboxMode, +import type { + SpawnSubagentContextMode, + SpawnSubagentMode, + SpawnSubagentSandboxMode, } from "./subagent-spawn.types.js"; export { diff --git a/src/agents/tool-call-id.ts b/src/agents/tool-call-id.ts index 93caa5b37fe2..f1783df44476 100644 --- a/src/agents/tool-call-id.ts +++ b/src/agents/tool-call-id.ts @@ -136,7 +136,7 @@ function hasToolCallInput(block: ReplaySafeToolCallBlock): boolean { function toolCallNeedsReplayMutation(block: ReplaySafeToolCallBlock): boolean { const rawName = typeof block.name === "string" ? block.name : undefined; const trimmedName = rawName?.trim(); - return !!rawName && rawName !== trimmedName; + return Boolean(rawName) && rawName !== trimmedName; } function isReplaySafeThinkingAssistantMessage( diff --git a/src/agents/tools/sessions-access.ts b/src/agents/tools/sessions-access.ts index 0f92c0789295..65930a598cd5 100644 --- a/src/agents/tools/sessions-access.ts +++ b/src/agents/tools/sessions-access.ts @@ -39,7 +39,7 @@ export function resolveSandboxedSessionToolContext(params: { const restrictToSpawned = params.sandboxed === true && visibility === "spawned" && - !!requesterInternalKey && + Boolean(requesterInternalKey) && !isSubagentSessionKey(requesterInternalKey); return { mainKey, diff --git a/src/agents/tools/skill-workshop-tool.ts b/src/agents/tools/skill-workshop-tool.ts index b8de56fa7d83..2e0995499101 100644 --- a/src/agents/tools/skill-workshop-tool.ts +++ b/src/agents/tools/skill-workshop-tool.ts @@ -385,7 +385,7 @@ function listProposalEntries(params: { const lower = value.toLowerCase(); return ( lower.includes(query) || - (!!normalizedQuery && normalizeProposalSearchText(lower).includes(normalizedQuery)) + (Boolean(normalizedQuery) && normalizeProposalSearchText(lower).includes(normalizedQuery)) ); }); }) diff --git a/src/agents/tools/transcripts-tool.ts b/src/agents/tools/transcripts-tool.ts index a3952d6abaad..cf81bbbbacf3 100644 --- a/src/agents/tools/transcripts-tool.ts +++ b/src/agents/tools/transcripts-tool.ts @@ -19,7 +19,7 @@ import type { } from "../../transcripts/provider-types.js"; import { TranscriptsStore, type TranscriptsSessionEntry } from "../../transcripts/store.js"; import { summarizeTranscripts } from "../../transcripts/summary.js"; -import { type AnyAgentTool } from "./common.js"; +import type { AnyAgentTool } from "./common.js"; type TranscriptsLogger = { warn: (message: string) => void; diff --git a/src/auto-reply/model.ts b/src/auto-reply/model.ts index 77ee029331cd..e0156b0d5c3b 100644 --- a/src/auto-reply/model.ts +++ b/src/auto-reply/model.ts @@ -50,6 +50,6 @@ export function extractModelDirective( rawModel, rawProfile, rawRuntime, - hasDirective: !!match, + hasDirective: Boolean(match), }; } diff --git a/src/auto-reply/reply/acp-stream-settings.ts b/src/auto-reply/reply/acp-stream-settings.ts index 12394e1c3a3a..47c8030b928a 100644 --- a/src/auto-reply/reply/acp-stream-settings.ts +++ b/src/auto-reply/reply/acp-stream-settings.ts @@ -150,7 +150,7 @@ export function isAcpTagVisible( if (typeof override === "boolean") { return override; } - if (Object.prototype.hasOwnProperty.call(ACP_TAG_VISIBILITY_DEFAULTS, tag)) { + if (Object.hasOwn(ACP_TAG_VISIBILITY_DEFAULTS, tag)) { return ACP_TAG_VISIBILITY_DEFAULTS[tag]; } return true; diff --git a/src/auto-reply/reply/agent-runner-execution.ts b/src/auto-reply/reply/agent-runner-execution.ts index c7146e8a9010..358d8ca1f38c 100644 --- a/src/auto-reply/reply/agent-runner-execution.ts +++ b/src/auto-reply/reply/agent-runner-execution.ts @@ -100,7 +100,7 @@ import { resolveQueuedReplyRuntimeConfig, resolveModelFallbackOptions, } from "./agent-runner-utils.js"; -import { type BlockReplyPipeline } from "./block-reply-pipeline.js"; +import type { BlockReplyPipeline } from "./block-reply-pipeline.js"; import { resolveCurrentTurnImages } from "./current-turn-images.js"; import { resolveOriginMessageProvider } from "./origin-routing.js"; import { diff --git a/src/auto-reply/reply/commands-allowlist.test.ts b/src/auto-reply/reply/commands-allowlist.test.ts index 550c33466735..3146ae8b97e9 100644 --- a/src/auto-reply/reply/commands-allowlist.test.ts +++ b/src/auto-reply/reply/commands-allowlist.test.ts @@ -18,7 +18,7 @@ import { } from "../../test-utils/channel-plugins.js"; import { handleAllowlistCommand } from "./commands-allowlist.js"; import type { HandleCommandsParams } from "./commands-types.js"; -import { type ConfigSnapshotMock } from "./commands.test-harness.js"; +import type { ConfigSnapshotMock } from "./commands.test-harness.js"; const readConfigFileSnapshotMock = vi.hoisted(() => vi.fn()); const validateConfigObjectWithPluginsMock = vi.hoisted(() => vi.fn()); diff --git a/src/auto-reply/reply/commands-gating.test.ts b/src/auto-reply/reply/commands-gating.test.ts index af95bd8060d1..20c0dad96b60 100644 --- a/src/auto-reply/reply/commands-gating.test.ts +++ b/src/auto-reply/reply/commands-gating.test.ts @@ -6,7 +6,7 @@ import { handleBashChatCommand } from "./bash-command.js"; import { requireGatewayClientScope } from "./command-gates.js"; import { handleConfigCommand, handleDebugCommand } from "./commands-config.js"; import type { HandleCommandsParams } from "./commands-types.js"; -import { type ConfigSnapshotMock } from "./commands.test-harness.js"; +import type { ConfigSnapshotMock } from "./commands.test-harness.js"; import { parseInlineDirectives } from "./directive-handling.parse.js"; const readConfigFileSnapshotMock = vi.hoisted(() => @@ -89,17 +89,23 @@ vi.mock("../../config/config.js", () => ({ transform: ( currentConfig: OpenClawConfig, context: { snapshot: ConfigSnapshotMock; previousHash: string | null; attempt: number }, - ) => Promise<{ nextConfig: OpenClawConfig; result?: unknown }> | { - nextConfig: OpenClawConfig; - result?: unknown; - }; + ) => + | Promise<{ nextConfig: OpenClawConfig; result?: unknown }> + | { + nextConfig: OpenClawConfig; + result?: unknown; + }; }) => { const snapshot = (await readConfigFileSnapshotMock()) as ConfigSnapshotMock; const previousHash = snapshot.hash ?? null; const currentConfig = structuredClone( snapshot.sourceConfig ?? snapshot.resolved ?? snapshot.runtimeConfig ?? snapshot.parsed ?? {}, ); - const transformed = await params.transform(currentConfig, { snapshot, previousHash, attempt: 0 }); + const transformed = await params.transform(currentConfig, { + snapshot, + previousHash, + attempt: 0, + }); const afterWrite = params.afterWrite ?? { mode: "auto" }; await replaceConfigFileMock({ nextConfig: transformed.nextConfig, afterWrite }); return { diff --git a/src/auto-reply/reply/subagents-utils.ts b/src/auto-reply/reply/subagents-utils.ts index fba565ffa7ac..1fc16914b52c 100644 --- a/src/auto-reply/reply/subagents-utils.ts +++ b/src/auto-reply/reply/subagents-utils.ts @@ -80,7 +80,7 @@ export function resolveSubagentTargetFromRuns(params: { const numericOrder = [ ...deduped.filter((entry) => isActive(entry)), ...deduped.filter( - (entry) => !isActive(entry) && !!entry.endedAt && (entry.endedAt ?? 0) >= recentCutoff, + (entry) => !isActive(entry) && Boolean(entry.endedAt) && (entry.endedAt ?? 0) >= recentCutoff, ), ]; if (/^\d+$/.test(trimmed)) { diff --git a/src/channels/channel-config.ts b/src/channels/channel-config.ts index 48c6c4c4ef48..e96b603b3828 100644 --- a/src/channels/channel-config.ts +++ b/src/channels/channel-config.ts @@ -53,14 +53,14 @@ export function resolveChannelEntryMatch(params: { const entries = params.entries ?? {}; const match: ChannelEntryMatch = {}; for (const key of params.keys) { - if (!Object.prototype.hasOwnProperty.call(entries, key)) { + if (!Object.hasOwn(entries, key)) { continue; } match.entry = entries[key]; match.key = key; break; } - if (params.wildcardKey && Object.prototype.hasOwnProperty.call(entries, params.wildcardKey)) { + if (params.wildcardKey && Object.hasOwn(entries, params.wildcardKey)) { match.wildcardEntry = entries[params.wildcardKey]; match.wildcardKey = params.wildcardKey; } diff --git a/src/channels/plugins/read-only-command-defaults.ts b/src/channels/plugins/read-only-command-defaults.ts index 6ba1d994e69a..e268ccaa6ad9 100644 --- a/src/channels/plugins/read-only-command-defaults.ts +++ b/src/channels/plugins/read-only-command-defaults.ts @@ -20,7 +20,7 @@ export function isSafeManifestChannelId(channelId: string): boolean { } export function readOwnRecordValue(record: Record, key: string): unknown { - if (isBlockedObjectKey(key) || !Object.prototype.hasOwnProperty.call(record, key)) { + if (isBlockedObjectKey(key) || !Object.hasOwn(record, key)) { return undefined; } return record[key]; diff --git a/src/channels/plugins/read-only.ts b/src/channels/plugins/read-only.ts index fe15aa62f58e..9f539a76cb5c 100644 --- a/src/channels/plugins/read-only.ts +++ b/src/channels/plugins/read-only.ts @@ -314,15 +314,12 @@ function restoreReboundChannelConfig(params: { return params.updated; } const nextChannels = { ...params.updated.channels }; - if (Object.prototype.hasOwnProperty.call(nextChannels, params.sourceChannelId)) { + if (Object.hasOwn(nextChannels, params.sourceChannelId)) { nextChannels[params.targetChannelId] = nextChannels[params.sourceChannelId]; } else { delete nextChannels[params.targetChannelId]; } - if ( - params.original.channels && - Object.prototype.hasOwnProperty.call(params.original.channels, params.sourceChannelId) - ) { + if (params.original.channels && Object.hasOwn(params.original.channels, params.sourceChannelId)) { nextChannels[params.sourceChannelId] = params.original.channels[params.sourceChannelId]; } else { delete nextChannels[params.sourceChannelId]; @@ -475,7 +472,7 @@ function buildManifestChannelPlugin(params: { function canUseManifestChannelPlugin(record: PluginManifestRecord, channelId: string): boolean { const hasChannelConfig = Boolean( - record.channelConfigs && Object.prototype.hasOwnProperty.call(record.channelConfigs, channelId), + record.channelConfigs && Object.hasOwn(record.channelConfigs, channelId), ); if (hasChannelConfig) { return record.setup?.requiresRuntime === false || !record.setupSource; diff --git a/src/channels/plugins/session-conversation.ts b/src/channels/plugins/session-conversation.ts index ac6fb521b282..86a5e1a531c8 100644 --- a/src/channels/plugins/session-conversation.ts +++ b/src/channels/plugins/session-conversation.ts @@ -167,7 +167,7 @@ function isBundledSessionConversationFallbackDisabled(channel: string): boolean return true; } const entry = snapshot.plugins.entries?.[normalizeResolvedChannel(channel)]; - return !!entry && typeof entry === "object" && entry.enabled === false; + return Boolean(entry) && typeof entry === "object" && entry.enabled === false; } function shouldProbeBundledSessionConversationFallback(rawId: string): boolean { diff --git a/src/cli/config-cli.ts b/src/cli/config-cli.ts index 5562a7f7f360..53436cba8bb2 100644 --- a/src/cli/config-cli.ts +++ b/src/cli/config-cli.ts @@ -154,7 +154,7 @@ function normalizeAgentListModelRefsForConfigMutation(value: unknown): unknown { } let nextAgent = agent; - if (Object.prototype.hasOwnProperty.call(agent, "model")) { + if (Object.hasOwn(agent, "model")) { const model = normalizeAgentDefaultModelValueForConfigMutation(agent.model); if (model !== agent.model) { nextAgent = { ...nextAgent, model }; @@ -455,7 +455,7 @@ function parseValue(raw: string, opts: ConfigSetParseOpts): unknown { } function hasOwnPathKey(value: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(value, key); + return Object.hasOwn(value, key); } function formatDoctorHint(message: string): string { @@ -1763,7 +1763,7 @@ function valueHasAutoManagedChild(value: unknown, childPath: ReadonlyArray; - if (!Object.prototype.hasOwnProperty.call(record, segment)) { + if (!Object.hasOwn(record, segment)) { return false; } cursor = record[segment]; diff --git a/src/cli/config-set-input.ts b/src/cli/config-set-input.ts index b954fa636bdf..938e688ffed8 100644 --- a/src/cli/config-set-input.ts +++ b/src/cli/config-set-input.ts @@ -97,9 +97,9 @@ function parseBatchEntries(raw: string, sourceLabel: string): ConfigSetBatchEntr if (!path) { throw new Error(`${sourceLabel}[${index}].path is required.`); } - const hasValue = Object.prototype.hasOwnProperty.call(typed, "value"); - const hasRef = Object.prototype.hasOwnProperty.call(typed, "ref"); - const hasProvider = Object.prototype.hasOwnProperty.call(typed, "provider"); + const hasValue = Object.hasOwn(typed, "value"); + const hasRef = Object.hasOwn(typed, "ref"); + const hasProvider = Object.hasOwn(typed, "provider"); const modeCount = Number(hasValue) + Number(hasRef) + Number(hasProvider); if (modeCount !== 1) { throw new Error( diff --git a/src/cli/daemon-cli/lifecycle.ts b/src/cli/daemon-cli/lifecycle.ts index c493727cb9e5..134489863c7a 100644 --- a/src/cli/daemon-cli/lifecycle.ts +++ b/src/cli/daemon-cli/lifecycle.ts @@ -85,7 +85,7 @@ function resolveGatewayPortFallback(): Promise { async function assertUnmanagedGatewayRestartEnabled(port: number): Promise { const cfg = await readBestEffortConfig().catch(() => undefined); - const tlsEnabled = !!cfg?.gateway?.tls?.enabled; + const tlsEnabled = Boolean(cfg?.gateway?.tls?.enabled); const scheme = tlsEnabled ? "wss" : "ws"; const probe = await probeGateway({ url: `${scheme}://127.0.0.1:${port}`, diff --git a/src/cli/daemon-cli/status.gather.ts b/src/cli/daemon-cli/status.gather.ts index 2c668933783e..54cdec512232 100644 --- a/src/cli/daemon-cli/status.gather.ts +++ b/src/cli/daemon-cli/status.gather.ts @@ -154,10 +154,7 @@ function coerceStatusConfig(value: unknown): OpenClawConfig { function hasOwnKey(value: unknown, key: string): boolean { return Boolean( - value && - typeof value === "object" && - !Array.isArray(value) && - Object.prototype.hasOwnProperty.call(value, key), + value && typeof value === "object" && !Array.isArray(value) && Object.hasOwn(value, key), ); } diff --git a/src/cli/gateway-cli/register.ts b/src/cli/gateway-cli/register.ts index 29c749cc0ad0..0a762c859e09 100644 --- a/src/cli/gateway-cli/register.ts +++ b/src/cli/gateway-cli/register.ts @@ -8,9 +8,9 @@ import type { DiagnosticStabilityBundle, ReadDiagnosticStabilityBundleResult, } from "../../logging/diagnostic-stability-bundle.js"; -import { - type DiagnosticStabilityEventRecord, - type DiagnosticStabilitySnapshot, +import type { + DiagnosticStabilityEventRecord, + DiagnosticStabilitySnapshot, } from "../../logging/diagnostic-stability.js"; import type { WriteDiagnosticSupportExportResult } from "../../logging/diagnostic-support-export.js"; import { defaultRuntime } from "../../runtime.js"; diff --git a/src/cli/gateway-cli/run.ts b/src/cli/gateway-cli/run.ts index 9ff82ea78d2c..6c4c5d035bcb 100644 --- a/src/cli/gateway-cli/run.ts +++ b/src/cli/gateway-cli/run.ts @@ -329,7 +329,9 @@ export function resolveGatewayRunOptions(opts: GatewayRunOpts, command?: Command function isGatewayLockError(err: unknown): err is GatewayLockError { return ( err instanceof GatewayLockError || - (!!err && typeof err === "object" && (err as { name?: string }).name === "GatewayLockError") + (Boolean(err) && + typeof err === "object" && + (err as { name?: string }).name === "GatewayLockError") ); } diff --git a/src/cli/root-help-live-config.ts b/src/cli/root-help-live-config.ts index 6f2b4a8ed411..485950900d05 100644 --- a/src/cli/root-help-live-config.ts +++ b/src/cli/root-help-live-config.ts @@ -2,7 +2,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { RootHelpRenderOptions } from "./program/root-help.js"; function hasEntries(value: object | undefined): boolean { - return !!value && Object.keys(value).length > 0; + return value !== undefined && Object.keys(value).length > 0; } function hasListEntries(value: string[] | undefined): boolean { diff --git a/src/cli/update-cli.test.ts b/src/cli/update-cli.test.ts index 291c7d9b2520..33e1ad164c93 100644 --- a/src/cli/update-cli.test.ts +++ b/src/cli/update-cli.test.ts @@ -467,7 +467,7 @@ describe("update-cli", () => { const target = stripOpenClawPackageAlias(spec); const [repo] = target.split("#", 1); const isGitHubShorthand = - !!repo && + Boolean(repo) && !repo.startsWith(".") && !repo.startsWith("/") && !repo.startsWith("@") && diff --git a/src/cli/update-cli.ts b/src/cli/update-cli.ts index caa741d486ab..44ba9e98c2a0 100644 --- a/src/cli/update-cli.ts +++ b/src/cli/update-cli.ts @@ -4,11 +4,11 @@ import { theme } from "../../packages/terminal-core/src/theme.js"; import { defaultRuntime } from "../runtime.js"; import { inheritOptionFromParent } from "./command-options.js"; import { formatHelpExamples } from "./help-format.js"; -import { - type UpdateCommandOptions, - type UpdateFinalizeOptions, - type UpdateStatusOptions, - type UpdateWizardOptions, +import type { + UpdateCommandOptions, + UpdateFinalizeOptions, + UpdateStatusOptions, + UpdateWizardOptions, } from "./update-cli/shared.js"; import { updateStatusCommand } from "./update-cli/status.js"; import { updateCommand, updateFinalizeCommand } from "./update-cli/update-command.js"; diff --git a/src/cli/update-cli/update-command.ts b/src/cli/update-cli/update-command.ts index a8da8e33d83c..46a802bc4be1 100644 --- a/src/cli/update-cli/update-command.ts +++ b/src/cli/update-cli/update-command.ts @@ -261,7 +261,7 @@ function normalizeChannelConfigMap(value: unknown): Record | nu function normalizeDirectAuthoredChannelConfigMap(value: unknown): Record | null { const channels = normalizeChannelConfigMap(value); - if (!channels || Object.prototype.hasOwnProperty.call(channels, "$include")) { + if (!channels || Object.hasOwn(channels, "$include")) { return null; } return channels; diff --git a/src/commands/agent-via-gateway.ts b/src/commands/agent-via-gateway.ts index 1cfb2e2686dd..d5c386945a1d 100644 --- a/src/commands/agent-via-gateway.ts +++ b/src/commands/agent-via-gateway.ts @@ -334,7 +334,7 @@ function isAgentCliProcessLike(value: unknown): value is AgentCliProcessLike { } function resolveAgentCliProcessLike(deps: AgentCliDeps | undefined): AgentCliProcessLike { - if (!deps || !Object.prototype.hasOwnProperty.call(deps, "process")) { + if (!deps || !Object.hasOwn(deps, "process")) { return process; } const processLike = (deps as { process?: unknown }).process; diff --git a/src/commands/channel-setup/discovery.ts b/src/commands/channel-setup/discovery.ts index 162bd02471aa..d9852582126b 100644 --- a/src/commands/channel-setup/discovery.ts +++ b/src/commands/channel-setup/discovery.ts @@ -1,6 +1,6 @@ import { resolveAgentWorkspaceDir, resolveDefaultAgentId } from "../../agents/agent-scope.js"; import { listChatChannels } from "../../channels/chat-meta.js"; -import { type ChannelPluginCatalogEntry } from "../../channels/plugins/catalog.js"; +import type { ChannelPluginCatalogEntry } from "../../channels/plugins/catalog.js"; import { isChannelVisibleInSetup } from "../../channels/plugins/exposure.js"; import { normalizeChannelMeta } from "../../channels/plugins/meta-normalization.js"; import type { ChannelPlugin } from "../../channels/plugins/types.plugin.js"; diff --git a/src/commands/channel-setup/plugin-install.test.ts b/src/commands/channel-setup/plugin-install.test.ts index 441eeec9886b..6baeea56ed05 100644 --- a/src/commands/channel-setup/plugin-install.test.ts +++ b/src/commands/channel-setup/plugin-install.test.ts @@ -1047,7 +1047,7 @@ describe("ensureChannelSetupPluginInstalled", () => { expect(loadPluginManifestRegistry).toHaveBeenCalled(); expect( loadPluginManifestRegistry.mock.calls.every( - ([params]) => !Object.prototype.hasOwnProperty.call(params ?? {}, "cache"), + ([params]) => !Object.hasOwn(params ?? {}, "cache"), ), ).toBe(true); }); diff --git a/src/commands/doctor-auth-profile-config.ts b/src/commands/doctor-auth-profile-config.ts index ccd1ca2924fc..ca749df43cf8 100644 --- a/src/commands/doctor-auth-profile-config.ts +++ b/src/commands/doctor-auth-profile-config.ts @@ -183,7 +183,7 @@ export function protectActiveAuthProfileConfig(params: { normalizeProviderId(afterProfileRecord?.provider) || normalizeProviderId(beforeProfileRecord?.provider) || extractProviderFromProfileId(profileId); - const protectsActiveProvider = !!provider && activeProviders.has(provider); + const protectsActiveProvider = provider !== null && activeProviders.has(provider); const protectsExplicitProfile = explicitProfileIds.has(profileId); if (!protectsActiveProvider && !protectsExplicitProfile) { continue; diff --git a/src/commands/doctor-config-flow.test.ts b/src/commands/doctor-config-flow.test.ts index 52a6e41d6014..ccdb086d4c79 100644 --- a/src/commands/doctor-config-flow.test.ts +++ b/src/commands/doctor-config-flow.test.ts @@ -742,7 +742,7 @@ vi.mock("../plugins/doctor-contract-registry.js", () => { return Boolean( talk && ["voiceId", "voiceAliases", "modelId", "outputFormat", "apiKey"].some((key) => - Object.prototype.hasOwnProperty.call(talk, key), + Object.hasOwn(talk, key), ), ); } diff --git a/src/commands/doctor-memory-search.ts b/src/commands/doctor-memory-search.ts index e3a4495835d7..a1a0ca000b0c 100644 --- a/src/commands/doctor-memory-search.ts +++ b/src/commands/doctor-memory-search.ts @@ -379,7 +379,7 @@ function hasActiveAlternateMemoryPluginSlot(cfg: OpenClawConfig): boolean { if (plugins.deny.includes(memorySlot)) { return false; } - if (!Object.prototype.hasOwnProperty.call(plugins.entries, memorySlot)) { + if (!Object.hasOwn(plugins.entries, memorySlot)) { return false; } const entry = plugins.entries[memorySlot]; diff --git a/src/commands/doctor-plugin-registry.ts b/src/commands/doctor-plugin-registry.ts index a5c1c5a0f8ef..2f7e5d055443 100644 --- a/src/commands/doctor-plugin-registry.ts +++ b/src/commands/doctor-plugin-registry.ts @@ -80,7 +80,7 @@ function listManagedPluginNpmRoots(params: PluginRegistryDoctorRepairParams): st } function deleteObjectKey(record: Record, key: string): boolean { - if (!Object.prototype.hasOwnProperty.call(record, key)) { + if (!Object.hasOwn(record, key)) { return false; } delete record[key]; diff --git a/src/commands/doctor-session-snapshots.ts b/src/commands/doctor-session-snapshots.ts index 06145625d6f8..4d097dd27157 100644 --- a/src/commands/doctor-session-snapshots.ts +++ b/src/commands/doctor-session-snapshots.ts @@ -154,7 +154,8 @@ function isInsidePath(baseDir: string, candidatePath: string): boolean { const pathApi = baseIsWindows ? path.win32 : path; const relative = pathApi.relative(pathApi.resolve(baseDir), pathApi.resolve(candidatePath)); return ( - relative === "" || (!!relative && !relative.startsWith("..") && !pathApi.isAbsolute(relative)) + relative === "" || + (relative !== "" && !relative.startsWith("..") && !pathApi.isAbsolute(relative)) ); } function joinPathForRoot(root: string, ...segments: string[]): string { diff --git a/src/commands/doctor/legacy-config-repair.ts b/src/commands/doctor/legacy-config-repair.ts index 3f92ccef9113..ebbdbcf5ae82 100644 --- a/src/commands/doctor/legacy-config-repair.ts +++ b/src/commands/doctor/legacy-config-repair.ts @@ -10,7 +10,7 @@ function containsAuthoredInclude(value: unknown): boolean { if (!isRecord(value)) { return false; } - if (Object.prototype.hasOwnProperty.call(value, INCLUDE_KEY)) { + if (Object.hasOwn(value, INCLUDE_KEY)) { return true; } return Object.values(value).some((entry) => containsAuthoredInclude(entry)); diff --git a/src/commands/doctor/shared/allowfrom-fallback-migration.ts b/src/commands/doctor/shared/allowfrom-fallback-migration.ts index 12bc515465c1..0fd90d9a6e88 100644 --- a/src/commands/doctor/shared/allowfrom-fallback-migration.ts +++ b/src/commands/doctor/shared/allowfrom-fallback-migration.ts @@ -86,11 +86,7 @@ function schemaAllowsConfigPath(schema: unknown, path: SchemaPath): boolean { const [segment, ...rest] = path; const properties = asObjectRecord(node.properties); - if ( - segment !== ACCOUNT_SCHEMA_WILDCARD && - properties && - Object.prototype.hasOwnProperty.call(properties, segment) - ) { + if (segment !== ACCOUNT_SCHEMA_WILDCARD && properties && Object.hasOwn(properties, segment)) { return schemaAllowsConfigPath(properties[segment], rest); } diff --git a/src/commands/doctor/shared/codex-route-warnings.ts b/src/commands/doctor/shared/codex-route-warnings.ts index b0e0c1c89b7f..6be7b1a7616e 100644 --- a/src/commands/doctor/shared/codex-route-warnings.ts +++ b/src/commands/doctor/shared/codex-route-warnings.ts @@ -143,12 +143,14 @@ function collectStringModelSlot(params: { if (!model || !isOpenAICodexModelRef(model)) { return false; } - return !!recordCodexModelHit({ - hits: params.hits, - path: params.path, - model, - runtime: params.runtime, - }); + return Boolean( + recordCodexModelHit({ + hits: params.hits, + path: params.path, + model, + runtime: params.runtime, + }), + ); } function collectModelConfigSlot(params: { @@ -1015,7 +1017,7 @@ function collectAgentRuntimeModelRefs(params: { }): Array<{ path: string; modelRef: string }> { const refs: Array<{ path: string; modelRef: string }> = []; const agent = asMutableRecord(params.agent); - if (agent && Object.prototype.hasOwnProperty.call(agent, "model")) { + if (agent && Object.hasOwn(agent, "model")) { collectModelConfigRefs({ refs, path: `${params.path}.model`, diff --git a/src/commands/doctor/shared/legacy-config-migrate.test.ts b/src/commands/doctor/shared/legacy-config-migrate.test.ts index 104d0692a82b..c2be67d3e894 100644 --- a/src/commands/doctor/shared/legacy-config-migrate.test.ts +++ b/src/commands/doctor/shared/legacy-config-migrate.test.ts @@ -1506,7 +1506,7 @@ describe("legacy migrate heartbeat config", () => { | undefined; expect(heartbeat?.every).toBe("30m"); expect((heartbeat as { polluted?: unknown } | undefined)?.polluted).toBeUndefined(); - expect(Object.prototype.hasOwnProperty.call(heartbeat ?? {}, "__proto__")).toBe(false); + expect(Object.hasOwn(heartbeat ?? {}, "__proto__")).toBe(false); expect(res.config?.channels?.defaults?.heartbeat).toEqual({ showOk: true }); }); diff --git a/src/commands/doctor/shared/legacy-config-migrations.channels.ts b/src/commands/doctor/shared/legacy-config-migrations.channels.ts index f924eb882ed2..8cefcafa8313 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.channels.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.channels.ts @@ -7,7 +7,7 @@ import { } from "../../../config/legacy.shared.js"; function hasOwnKey(target: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(target, key); + return Object.hasOwn(target, key); } function cleanupEmptyRecord(parent: Record, key: string): void { diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts index fb340f5dee83..e7b7ba67d9c0 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.agents.ts @@ -207,7 +207,7 @@ const SILENT_REPLY_LEGACY_RULES: LegacyConfigRule[] = [ path: ["agents", "defaults", "silentReply"], message: 'agents.defaults.silentReply.direct was removed; direct chats never receive NO_REPLY prompt guidance. Run "openclaw doctor --fix" to remove it.', - match: (value) => Object.prototype.hasOwnProperty.call(getRecord(value) ?? {}, "direct"), + match: (value) => Object.hasOwn(getRecord(value) ?? {}, "direct"), }, { path: ["surfaces"], @@ -297,7 +297,7 @@ function mergeLegacyIntoDefaults(params: { function hasLegacySandboxPerSession(value: unknown): boolean { const sandbox = getRecord(value); - return Boolean(sandbox && Object.prototype.hasOwnProperty.call(sandbox, "perSession")); + return Boolean(sandbox && Object.hasOwn(sandbox, "perSession")); } function hasLegacyAgentListSandboxPerSession(value: unknown): boolean { @@ -332,14 +332,12 @@ function hasAgentListSystemPromptOverride(value: unknown): boolean { if (!Array.isArray(value)) { return false; } - return value.some((agent) => - Object.prototype.hasOwnProperty.call(getRecord(agent) ?? {}, "systemPromptOverride"), - ); + return value.some((agent) => Object.hasOwn(getRecord(agent) ?? {}, "systemPromptOverride")); } function hasOwnTimeoutMs(value: unknown): boolean { const record = getRecord(value); - return Boolean(record && Object.prototype.hasOwnProperty.call(record, "timeoutMs")); + return Boolean(record && Object.hasOwn(record, "timeoutMs")); } function hasAgentListModelTimeout(value: unknown): boolean { @@ -409,7 +407,7 @@ function migrateLegacySandboxPerSession( pathLabel: string, changes: string[], ): void { - if (!Object.prototype.hasOwnProperty.call(sandbox, "perSession")) { + if (!Object.hasOwn(sandbox, "perSession")) { return; } const rawPerSession = sandbox.perSession; @@ -551,7 +549,7 @@ function removeIgnoredAgentModelTimeout( changes: string[], ): void { const modelRecord = getRecord(model); - if (!modelRecord || !Object.prototype.hasOwnProperty.call(modelRecord, "timeoutMs")) { + if (!modelRecord || !Object.hasOwn(modelRecord, "timeoutMs")) { return; } delete modelRecord.timeoutMs; @@ -560,7 +558,7 @@ function removeIgnoredAgentModelTimeout( function hasOwnRecordProperty(value: unknown, key: string): boolean { const record = getRecord(value); - return Boolean(record && Object.prototype.hasOwnProperty.call(record, key)); + return Boolean(record && Object.hasOwn(record, key)); } function hasSurfaceSilentReplyRewrite(value: unknown): boolean { @@ -580,17 +578,14 @@ function hasSurfaceSilentReplyDirect(value: unknown): boolean { return false; } return Object.values(surfaces).some((surface) => - Object.prototype.hasOwnProperty.call( - getRecord(getRecord(surface)?.silentReply) ?? {}, - "direct", - ), + Object.hasOwn(getRecord(getRecord(surface)?.silentReply) ?? {}, "direct"), ); } function removeLegacySilentReplyConfig(raw: Record, changes: string[]): void { const defaults = getRecord(getRecord(raw.agents)?.defaults); const defaultSilentReply = getRecord(defaults?.silentReply); - if (defaultSilentReply && Object.prototype.hasOwnProperty.call(defaultSilentReply, "direct")) { + if (defaultSilentReply && Object.hasOwn(defaultSilentReply, "direct")) { delete defaultSilentReply.direct; changes.push("Removed agents.defaults.silentReply.direct; direct chats never use NO_REPLY."); } @@ -612,7 +607,7 @@ function removeLegacySilentReplyConfig(raw: Record, changes: st continue; } const silentReply = getRecord(surface.silentReply); - if (silentReply && Object.prototype.hasOwnProperty.call(silentReply, "direct")) { + if (silentReply && Object.hasOwn(silentReply, "direct")) { delete silentReply.direct; changes.push( `Removed surfaces.${surfaceId}.silentReply.direct; direct chats never use NO_REPLY.`, @@ -628,7 +623,7 @@ function removeLegacySilentReplyConfig(raw: Record, changes: st function removeLegacySystemPromptOverride(raw: Record, changes: string[]): void { const agents = getRecord(raw.agents); const defaults = getRecord(agents?.defaults); - if (defaults && Object.prototype.hasOwnProperty.call(defaults, "systemPromptOverride")) { + if (defaults && Object.hasOwn(defaults, "systemPromptOverride")) { delete defaults.systemPromptOverride; changes.push("Removed agents.defaults.systemPromptOverride."); } @@ -638,10 +633,7 @@ function removeLegacySystemPromptOverride(raw: Record, changes: } for (const [index, agent] of agents.list.entries()) { const agentRecord = getRecord(agent); - if ( - !agentRecord || - !Object.prototype.hasOwnProperty.call(agentRecord, "systemPromptOverride") - ) { + if (!agentRecord || !Object.hasOwn(agentRecord, "systemPromptOverride")) { continue; } delete agentRecord.systemPromptOverride; diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.diagnostics.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.diagnostics.ts index 0ff7aa57a26e..f73e8fb1f3b0 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.diagnostics.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.diagnostics.ts @@ -27,7 +27,7 @@ export const LEGACY_CONFIG_MIGRATIONS_RUNTIME_DIAGNOSTICS: LegacyConfigMigration if (!diagnostics || !isLegacyMemoryPressureBundleConfig(diagnostics.memoryPressureBundle)) { return; } - if (Object.prototype.hasOwnProperty.call(diagnostics, "memoryPressureSnapshot")) { + if (Object.hasOwn(diagnostics, "memoryPressureSnapshot")) { delete diagnostics.memoryPressureBundle; changes.push( "Removed diagnostics.memoryPressureBundle (memoryPressureSnapshot already set).", diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts index 5803173002d5..1123209f65b4 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.models.ts @@ -121,7 +121,7 @@ function getLegacyVllmQwenThinkingFormat(params: Record): } | undefined { for (const key of LEGACY_VLLM_QWEN_THINKING_FORMAT_KEYS) { - if (Object.prototype.hasOwnProperty.call(params, key)) { + if (Object.hasOwn(params, key)) { return { key, value: params[key], diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.session.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.session.ts index 9caef58b541e..1bd3d891796b 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.session.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.session.ts @@ -7,12 +7,12 @@ import { function hasLegacyRotateBytes(value: unknown): boolean { const maintenance = getRecord(value); - return Boolean(maintenance && Object.prototype.hasOwnProperty.call(maintenance, "rotateBytes")); + return Boolean(maintenance && Object.hasOwn(maintenance, "rotateBytes")); } function hasLegacyParentForkMaxTokens(value: unknown): boolean { const session = getRecord(value); - return Boolean(session && Object.prototype.hasOwnProperty.call(session, "parentForkMaxTokens")); + return Boolean(session && Object.hasOwn(session, "parentForkMaxTokens")); } const LEGACY_SESSION_MAINTENANCE_ROTATE_BYTES_RULE: LegacyConfigRule = { @@ -36,7 +36,7 @@ export const LEGACY_CONFIG_MIGRATIONS_RUNTIME_SESSION: LegacyConfigMigrationSpec legacyRules: [LEGACY_SESSION_MAINTENANCE_ROTATE_BYTES_RULE], apply: (raw, changes) => { const maintenance = getRecord(getRecord(raw.session)?.maintenance); - if (!maintenance || !Object.prototype.hasOwnProperty.call(maintenance, "rotateBytes")) { + if (!maintenance || !Object.hasOwn(maintenance, "rotateBytes")) { return; } delete maintenance.rotateBytes; @@ -49,7 +49,7 @@ export const LEGACY_CONFIG_MIGRATIONS_RUNTIME_SESSION: LegacyConfigMigrationSpec legacyRules: [LEGACY_SESSION_PARENT_FORK_MAX_TOKENS_RULE], apply: (raw, changes) => { const session = getRecord(raw.session); - if (!session || !Object.prototype.hasOwnProperty.call(session, "parentForkMaxTokens")) { + if (!session || !Object.hasOwn(session, "parentForkMaxTokens")) { return; } delete session.parentForkMaxTokens; diff --git a/src/commands/doctor/shared/legacy-config-migrations.runtime.tts.ts b/src/commands/doctor/shared/legacy-config-migrations.runtime.tts.ts index 073437c98c98..a24c3b89cc8b 100644 --- a/src/commands/doctor/shared/legacy-config-migrations.runtime.tts.ts +++ b/src/commands/doctor/shared/legacy-config-migrations.runtime.tts.ts @@ -22,11 +22,11 @@ function hasLegacyTtsProviderKeys(value: unknown): boolean { if (isLegacyEdgeProviderId(tts.provider)) { return true; } - if (LEGACY_TTS_PROVIDER_KEYS.some((key) => Object.prototype.hasOwnProperty.call(tts, key))) { + if (LEGACY_TTS_PROVIDER_KEYS.some((key) => Object.hasOwn(tts, key))) { return true; } const providers = getRecord(tts.providers); - return Boolean(providers && Object.prototype.hasOwnProperty.call(providers, "edge")); + return Boolean(providers && Object.hasOwn(providers, "edge")); } function hasLegacyPluginEntryTtsProviderKeys(value: unknown): boolean { @@ -54,9 +54,9 @@ function hasLegacySpeakerSelectionKeys(value: unknown): boolean { return false; } return ( - Object.prototype.hasOwnProperty.call(config, "voice") || - Object.prototype.hasOwnProperty.call(config, "voiceName") || - Object.prototype.hasOwnProperty.call(config, "voiceId") + Object.hasOwn(config, "voice") || + Object.hasOwn(config, "voiceName") || + Object.hasOwn(config, "voiceId") ); } @@ -317,7 +317,7 @@ function migrateLegacySpeakerSelectionConfig( pathLabel: string, changes: string[], ): void { - if (Object.prototype.hasOwnProperty.call(providerConfig, "voice")) { + if (Object.hasOwn(providerConfig, "voice")) { if (providerConfig.speakerVoice === undefined) { providerConfig.speakerVoice = providerConfig.voice; changes.push(`Moved ${pathLabel}.voice → ${pathLabel}.speakerVoice.`); @@ -326,7 +326,7 @@ function migrateLegacySpeakerSelectionConfig( } delete providerConfig.voice; } - if (Object.prototype.hasOwnProperty.call(providerConfig, "voiceName")) { + if (Object.hasOwn(providerConfig, "voiceName")) { if (providerConfig.speakerVoice === undefined) { providerConfig.speakerVoice = providerConfig.voiceName; changes.push(`Moved ${pathLabel}.voiceName → ${pathLabel}.speakerVoice.`); @@ -337,7 +337,7 @@ function migrateLegacySpeakerSelectionConfig( } delete providerConfig.voiceName; } - if (Object.prototype.hasOwnProperty.call(providerConfig, "voiceId")) { + if (Object.hasOwn(providerConfig, "voiceId")) { if (providerConfig.speakerVoiceId === undefined) { providerConfig.speakerVoiceId = providerConfig.voiceId; changes.push(`Moved ${pathLabel}.voiceId → ${pathLabel}.speakerVoiceId.`); diff --git a/src/commands/doctor/shared/legacy-config-record-shared.ts b/src/commands/doctor/shared/legacy-config-record-shared.ts index 0a9b33269214..97200611260f 100644 --- a/src/commands/doctor/shared/legacy-config-record-shared.ts +++ b/src/commands/doctor/shared/legacy-config-record-shared.ts @@ -20,5 +20,5 @@ export function ensureRecord(target: JsonRecord, key: string): JsonRecord { } export function hasOwnKey(target: JsonRecord, key: string): boolean { - return Object.prototype.hasOwnProperty.call(target, key); + return Object.hasOwn(target, key); } diff --git a/src/commands/doctor/shared/legacy-oauth-sidecar.ts b/src/commands/doctor/shared/legacy-oauth-sidecar.ts index 2c396b162e4e..ddeac89b742b 100644 --- a/src/commands/doctor/shared/legacy-oauth-sidecar.ts +++ b/src/commands/doctor/shared/legacy-oauth-sidecar.ts @@ -156,7 +156,7 @@ function encryptLegacyOAuthMaterialForTest(params: { function isPathInsideOrEqual(parentDir: string, candidatePath: string): boolean { const relative = path.relative(path.resolve(parentDir), path.resolve(candidatePath)); return ( - relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative)) + relative === "" || (relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)) ); } diff --git a/src/commands/doctor/shared/legacy-x-search-migrate.ts b/src/commands/doctor/shared/legacy-x-search-migrate.ts index 7c7b447dd997..ba0890bddf85 100644 --- a/src/commands/doctor/shared/legacy-x-search-migrate.ts +++ b/src/commands/doctor/shared/legacy-x-search-migrate.ts @@ -38,7 +38,7 @@ function resolveLegacyXSearchAuth(legacy: JsonRecord): unknown { export function listLegacyXSearchConfigPaths(raw: unknown): string[] { const legacy = resolveLegacyXSearchConfig(raw); - if (!legacy || !Object.prototype.hasOwnProperty.call(legacy, "apiKey")) { + if (!legacy || !Object.hasOwn(legacy, "apiKey")) { return []; } return [`${X_SEARCH_LEGACY_PATH}.apiKey`]; @@ -49,7 +49,7 @@ export function migrateLegacyXSearchConfig(raw: T): { config: T; changes: str return { config: raw, changes: [] }; } const legacy = resolveLegacyXSearchConfig(raw); - if (!legacy || !Object.prototype.hasOwnProperty.call(legacy, "apiKey")) { + if (!legacy || !Object.hasOwn(legacy, "apiKey")) { return { config: raw, changes: [] }; } @@ -82,7 +82,7 @@ export function migrateLegacyXSearchConfig(raw: T): { config: T; changes: str if (!existingWebSearch) { config.webSearch = { apiKey: auth }; changes.push(`Moved ${X_SEARCH_LEGACY_PATH}.apiKey → ${XAI_WEB_SEARCH_PLUGIN_KEY_PATH}.`); - } else if (!Object.prototype.hasOwnProperty.call(existingWebSearch, "apiKey")) { + } else if (!Object.hasOwn(existingWebSearch, "apiKey")) { existingWebSearch.apiKey = auth; config.webSearch = existingWebSearch; changes.push( diff --git a/src/commands/doctor/shared/release-configured-plugin-installs.ts b/src/commands/doctor/shared/release-configured-plugin-installs.ts index 1c06f1c39adc..28306cbd53ff 100644 --- a/src/commands/doctor/shared/release-configured-plugin-installs.ts +++ b/src/commands/doctor/shared/release-configured-plugin-installs.ts @@ -104,7 +104,9 @@ function collectSlotPluginIds(cfg: OpenClawConfig): string[] { const slots = asObjectRecord(cfg.plugins?.slots); return ["memory", "contextEngine"] .map((key) => normalizeId(slots?.[key])) - .filter((pluginId): pluginId is string => !!pluginId && pluginId.toLowerCase() !== "none"); + .filter( + (pluginId): pluginId is string => Boolean(pluginId) && pluginId.toLowerCase() !== "none", + ); } function collectConfiguredChannelIds(cfg: OpenClawConfig, env: NodeJS.ProcessEnv): string[] { diff --git a/src/commands/gateway-status/helpers.ts b/src/commands/gateway-status/helpers.ts index 72698327d37e..f4bb101529c2 100644 --- a/src/commands/gateway-status/helpers.ts +++ b/src/commands/gateway-status/helpers.ts @@ -6,7 +6,7 @@ import type { OpenClawConfig, ConfigFileSnapshot } from "../../config/types.js"; import { hasConfiguredSecretInput } from "../../config/types.secrets.js"; import { resolveGatewayProbeSurfaceAuth } from "../../gateway/auth-surface-resolution.js"; import { isLoopbackHost } from "../../gateway/net.js"; -import { type GatewayProbeCapability, type GatewayProbeResult } from "../../gateway/probe.js"; +import type { GatewayProbeCapability, GatewayProbeResult } from "../../gateway/probe.js"; import { inspectBestEffortPrimaryTailnetIPv4 } from "../../infra/network-discovery-display.js"; import { parseStrictInteger } from "../../infra/parse-finite-number.js"; import { pickGatewaySelfPresence } from "../gateway-presence.js"; diff --git a/src/commands/models/auth.test.ts b/src/commands/models/auth.test.ts index 798959eb0bee..884a4309860a 100644 --- a/src/commands/models/auth.test.ts +++ b/src/commands/models/auth.test.ts @@ -274,7 +274,7 @@ function createRuntime(): RuntimeEnv { function withInteractiveStdin() { const stdin = process.stdin as NodeJS.ReadStream & { isTTY?: boolean }; - const hadOwnIsTTY = Object.prototype.hasOwnProperty.call(stdin, "isTTY"); + const hadOwnIsTTY = Object.hasOwn(stdin, "isTTY"); const previousIsTTYDescriptor = Object.getOwnPropertyDescriptor(stdin, "isTTY"); Object.defineProperty(stdin, "isTTY", { configurable: true, diff --git a/src/commands/models/list.status-command.ts b/src/commands/models/list.status-command.ts index b2aa8b40bea6..1ce4248158f7 100644 --- a/src/commands/models/list.status-command.ts +++ b/src/commands/models/list.status-command.ts @@ -64,7 +64,7 @@ import { createLazyImportLoader } from "../../shared/lazy-promise.js"; import { resolveUserPath, shortenHomePath } from "../../utils.js"; import { resolveProviderAuthOverview } from "./list.auth-overview.js"; import { isRich } from "./list.format.js"; -import { type AuthProbeSummary } from "./list.probe.js"; +import type { AuthProbeSummary } from "./list.probe.js"; import type { ProviderAuthOverview } from "./list.types.js"; import { loadModelsConfig } from "./load-config.js"; import { diff --git a/src/commands/models/list.status.test.ts b/src/commands/models/list.status.test.ts index aabcd4baf7b7..80e0e031ff26 100644 --- a/src/commands/models/list.status.test.ts +++ b/src/commands/models/list.status.test.ts @@ -229,7 +229,7 @@ vi.mock("../../agents/provider-auth-aliases.js", () => ({ vi.mock("../../agents/model-selection-cli.js", () => ({ isCliProvider: vi.fn( (provider: string, cfg?: { agents?: { defaults?: { cliBackends?: object } } }) => - Object.prototype.hasOwnProperty.call(cfg?.agents?.defaults?.cliBackends ?? {}, provider), + Object.hasOwn(cfg?.agents?.defaults?.cliBackends ?? {}, provider), ), })); vi.mock("../../infra/shell-env.js", () => ({ diff --git a/src/commands/onboard-channels.e2e.test.ts b/src/commands/onboard-channels.e2e.test.ts index 70197a82b30b..6c47084f634c 100644 --- a/src/commands/onboard-channels.e2e.test.ts +++ b/src/commands/onboard-channels.e2e.test.ts @@ -374,41 +374,41 @@ function patchTelegramAdapter(overrides: ChannelSetupWizardAdapterPatch) { }; const previous: PatchedSetupAdapterFields = {}; - if (Object.prototype.hasOwnProperty.call(patch, "getStatus")) { + if (Object.hasOwn(patch, "getStatus")) { previous.getStatus = adapter.getStatus; adapter.getStatus = patch.getStatus ?? adapter.getStatus; } - if (Object.prototype.hasOwnProperty.call(patch, "afterConfigWritten")) { + if (Object.hasOwn(patch, "afterConfigWritten")) { previous.afterConfigWritten = adapter.afterConfigWritten; adapter.afterConfigWritten = patch.afterConfigWritten; } - if (Object.prototype.hasOwnProperty.call(patch, "configure")) { + if (Object.hasOwn(patch, "configure")) { previous.configure = adapter.configure; adapter.configure = patch.configure ?? adapter.configure; } - if (Object.prototype.hasOwnProperty.call(patch, "configureInteractive")) { + if (Object.hasOwn(patch, "configureInteractive")) { previous.configureInteractive = adapter.configureInteractive; adapter.configureInteractive = patch.configureInteractive; } - if (Object.prototype.hasOwnProperty.call(patch, "configureWhenConfigured")) { + if (Object.hasOwn(patch, "configureWhenConfigured")) { previous.configureWhenConfigured = adapter.configureWhenConfigured; adapter.configureWhenConfigured = patch.configureWhenConfigured; } return () => { - if (Object.prototype.hasOwnProperty.call(patch, "getStatus")) { + if (Object.hasOwn(patch, "getStatus")) { adapter.getStatus = previous.getStatus!; } - if (Object.prototype.hasOwnProperty.call(patch, "afterConfigWritten")) { + if (Object.hasOwn(patch, "afterConfigWritten")) { adapter.afterConfigWritten = previous.afterConfigWritten; } - if (Object.prototype.hasOwnProperty.call(patch, "configure")) { + if (Object.hasOwn(patch, "configure")) { adapter.configure = previous.configure!; } - if (Object.prototype.hasOwnProperty.call(patch, "configureInteractive")) { + if (Object.hasOwn(patch, "configureInteractive")) { adapter.configureInteractive = previous.configureInteractive; } - if (Object.prototype.hasOwnProperty.call(patch, "configureWhenConfigured")) { + if (Object.hasOwn(patch, "configureWhenConfigured")) { adapter.configureWhenConfigured = previous.configureWhenConfigured; } }; diff --git a/src/commands/status-json.ts b/src/commands/status-json.ts index 29c23a906fb1..f73f547086ee 100644 --- a/src/commands/status-json.ts +++ b/src/commands/status-json.ts @@ -1,4 +1,4 @@ -import { type RuntimeEnv } from "../runtime.js"; +import type { RuntimeEnv } from "../runtime.js"; import { runStatusJsonCommand } from "./status-json-command.ts"; import { scanStatusJsonFast } from "./status.scan.fast-json.js"; diff --git a/src/commands/status.command.ts b/src/commands/status.command.ts index c7ff11ca6f0a..e1816695e70d 100644 --- a/src/commands/status.command.ts +++ b/src/commands/status.command.ts @@ -7,7 +7,7 @@ import { import { sanitizeTerminalText } from "../../packages/terminal-core/src/safe-text.js"; import { withProgress } from "../cli/progress.js"; import { readRestartSentinel } from "../infra/restart-sentinel.js"; -import { type RuntimeEnv } from "../runtime.js"; +import type { RuntimeEnv } from "../runtime.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; import { runStatusJsonCommand } from "./status-json-command.ts"; import { buildStatusOverviewSurfaceFromScan } from "./status-overview-surface.ts"; diff --git a/src/commands/status.scan.shared.ts b/src/commands/status.scan.shared.ts index 609b94f3b643..23b8774ca03f 100644 --- a/src/commands/status.scan.shared.ts +++ b/src/commands/status.scan.shared.ts @@ -170,16 +170,11 @@ async function applyLocalStatusRpcFallback(params: { } function hasExplicitMemorySearchConfig(cfg: OpenClawConfig, agentId: string): boolean { - if ( - cfg.agents?.defaults && - Object.prototype.hasOwnProperty.call(cfg.agents.defaults, "memorySearch") - ) { + if (cfg.agents?.defaults && Object.hasOwn(cfg.agents.defaults, "memorySearch")) { return true; } const agents = Array.isArray(cfg.agents?.list) ? cfg.agents.list : []; - return agents.some( - (agent) => agent?.id === agentId && Object.prototype.hasOwnProperty.call(agent, "memorySearch"), - ); + return agents.some((agent) => agent?.id === agentId && Object.hasOwn(agent, "memorySearch")); } export function resolveMemoryPluginStatus(cfg: OpenClawConfig): MemoryPluginStatus { diff --git a/src/commands/status.scan.test-helpers.ts b/src/commands/status.scan.test-helpers.ts index 65b692a61088..2e4367dc3587 100644 --- a/src/commands/status.scan.test-helpers.ts +++ b/src/commands/status.scan.test-helpers.ts @@ -319,9 +319,7 @@ export function createStatusSummary( paths: [], defaults: {}, recent: [], - ...(Object.prototype.hasOwnProperty.call(options, "byAgent") - ? { byAgent: options.byAgent ?? [] } - : {}), + ...(Object.hasOwn(options, "byAgent") ? { byAgent: options.byAgent ?? [] } : {}), }, }; } diff --git a/src/config/defaults.ts b/src/config/defaults.ts index 7e8fb4ff4924..b84605c00b89 100644 --- a/src/config/defaults.ts +++ b/src/config/defaults.ts @@ -285,7 +285,7 @@ export function applyModelDefaults( return agent; } let nextAgent = agent; - if (Object.prototype.hasOwnProperty.call(agent, "model")) { + if (Object.hasOwn(agent, "model")) { const normalizedModel = normalizeAgentModelConfigForDefaults(agent.model); if (normalizedModel !== agent.model) { nextAgent = { ...nextAgent, model: normalizedModel as typeof agent.model }; diff --git a/src/config/io.ts b/src/config/io.ts index 19c0f963714e..778dedfa2e73 100644 --- a/src/config/io.ts +++ b/src/config/io.ts @@ -1205,7 +1205,7 @@ function restoreAuthoredTildePathsForWrite( const out: Record = { ...next }; for (const [childKey, childValue] of Object.entries(out)) { - if (Object.prototype.hasOwnProperty.call(authored, childKey)) { + if (Object.hasOwn(authored, childKey)) { out[childKey] = restoreAuthoredTildePathsForWrite( childValue, authored[childKey], diff --git a/src/config/io.write-prepare.ts b/src/config/io.write-prepare.ts index 7d4847d93218..121fead635ac 100644 --- a/src/config/io.write-prepare.ts +++ b/src/config/io.write-prepare.ts @@ -78,7 +78,7 @@ export function projectSourceOntoRuntimeShape(source: unknown, runtime: unknown) } function hasOwnIncludeKey(value: unknown): value is Record { - return isRecord(value) && Object.prototype.hasOwnProperty.call(value, "$include"); + return isRecord(value) && Object.hasOwn(value, "$include"); } function collectIncludeOwnedPaths(value: unknown, path: string[] = []): string[][] { @@ -101,7 +101,7 @@ function patchTouchesPath(patch: unknown, path: string[]): boolean { return true; } const [head, ...tail] = path; - if (!Object.prototype.hasOwnProperty.call(patch, head)) { + if (!Object.hasOwn(patch, head)) { return false; } return patchTouchesPath(patch[head], tail); @@ -206,7 +206,7 @@ function deletePathValue(value: unknown, path: string[]): unknown { return value; } const [head, ...tail] = path; - if (!Object.prototype.hasOwnProperty.call(value, head)) { + if (!Object.hasOwn(value, head)) { return value; } const next: Record = { ...value }; @@ -259,7 +259,7 @@ function preserveAuthoredAgentParams(params: { } let next = params.persistedCandidate; - if (Object.prototype.hasOwnProperty.call(defaults, "params")) { + if (Object.hasOwn(defaults, "params")) { next = preserveSourceValueAtPath({ ...params, persistedCandidate: next, @@ -273,7 +273,7 @@ function preserveAuthoredAgentParams(params: { return next; } for (const [modelId, modelEntry] of Object.entries(models)) { - if (!isRecord(modelEntry) || !Object.prototype.hasOwnProperty.call(modelEntry, "params")) { + if (!isRecord(modelEntry) || !Object.hasOwn(modelEntry, "params")) { continue; } const modelPath = [ @@ -511,7 +511,7 @@ function hasPathValue(value: unknown, path: readonly string[]): boolean { if (!isRecord(value)) { return false; } - if (isBlockedObjectKey(head) || !Object.prototype.hasOwnProperty.call(value, head)) { + if (isBlockedObjectKey(head) || !Object.hasOwn(value, head)) { return false; } return tail.length === 0 || hasPathValue(value[head], tail); @@ -554,7 +554,7 @@ function mergeMissingExplicitValues( if (isBlockedObjectKey(key)) { continue; } - if (!Object.prototype.hasOwnProperty.call(next, key)) { + if (!Object.hasOwn(next, key)) { next[key] = cloneUnknown(childExplicitValue); changed = true; continue; @@ -656,7 +656,7 @@ function readRootSchemaUri(value: unknown): string | undefined { } function hasOwnRootSchemaKey(value: unknown): boolean { - return isRecord(value) && Object.prototype.hasOwnProperty.call(value, "$schema"); + return isRecord(value) && Object.hasOwn(value, "$schema"); } function preserveRootSchemaUri(params: { @@ -711,7 +711,7 @@ function isWritePlainObject(value: unknown): value is Record { } function hasOwnObjectKey(value: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(value, key); + return Object.hasOwn(value, key); } const WRITE_PRUNED_OBJECT = Symbol("write-pruned-object"); diff --git a/src/config/merge-patch.proto-pollution.test.ts b/src/config/merge-patch.proto-pollution.test.ts index ebd01fb3553e..bb25f128d6f4 100644 --- a/src/config/merge-patch.proto-pollution.test.ts +++ b/src/config/merge-patch.proto-pollution.test.ts @@ -8,7 +8,7 @@ describe("applyMergePatch prototype pollution guard", () => { const result = applyMergePatch(base, patch) as Record; expect(result.b).toBe(2); expect(result.a).toBe(1); - expect(Object.prototype.hasOwnProperty.call(result, "__proto__")).toBe(false); + expect(Object.hasOwn(result, "__proto__")).toBe(false); expect(result.polluted).toBeUndefined(); expect(({} as Record).polluted).toBeUndefined(); }); @@ -18,7 +18,7 @@ describe("applyMergePatch prototype pollution guard", () => { const patch = { constructor: { polluted: true }, b: 2 }; const result = applyMergePatch(base, patch) as Record; expect(result.b).toBe(2); - expect(Object.prototype.hasOwnProperty.call(result, "constructor")).toBe(false); + expect(Object.hasOwn(result, "constructor")).toBe(false); }); it("ignores prototype key in patch", () => { @@ -26,7 +26,7 @@ describe("applyMergePatch prototype pollution guard", () => { const patch = { prototype: { polluted: true }, b: 2 }; const result = applyMergePatch(base, patch) as Record; expect(result.b).toBe(2); - expect(Object.prototype.hasOwnProperty.call(result, "prototype")).toBe(false); + expect(Object.hasOwn(result, "prototype")).toBe(false); }); it("ignores __proto__ in nested patches", () => { @@ -35,7 +35,7 @@ describe("applyMergePatch prototype pollution guard", () => { const result = applyMergePatch(base, patch) as { nested: Record }; expect(result.nested.y).toBe(2); expect(result.nested.x).toBe(1); - expect(Object.prototype.hasOwnProperty.call(result.nested, "__proto__")).toBe(false); + expect(Object.hasOwn(result.nested, "__proto__")).toBe(false); expect(result.nested.polluted).toBeUndefined(); expect(({} as Record).polluted).toBeUndefined(); }); diff --git a/src/config/model-input.ts b/src/config/model-input.ts index 9acdf513158e..a4b7e9260a0d 100644 --- a/src/config/model-input.ts +++ b/src/config/model-input.ts @@ -108,7 +108,7 @@ export function normalizeAgentModelMapForConfig = {}; for (const [key, entry] of Object.entries(models)) { const normalizedKey = normalizeAgentModelRefForConfig(key); - if (normalizedKey !== key || Object.prototype.hasOwnProperty.call(next, normalizedKey)) { + if (normalizedKey !== key || Object.hasOwn(next, normalizedKey)) { mutated = true; } next[normalizedKey] = mergeAgentModelEntryForConfig(next[normalizedKey], entry); diff --git a/src/config/plugin-auto-enable.shared.ts b/src/config/plugin-auto-enable.shared.ts index 4e42766dbe96..d92591f799ad 100644 --- a/src/config/plugin-auto-enable.shared.ts +++ b/src/config/plugin-auto-enable.shared.ts @@ -15,10 +15,7 @@ import { normalizePluginsConfig } from "../plugins/config-state.js"; import { getCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js"; import type { PluginDiscoveryResult } from "../plugins/discovery.js"; import { resolveInstalledPluginIndexPolicyHash } from "../plugins/installed-plugin-index-policy.js"; -import { - type PluginManifestRecord, - type PluginManifestRegistry, -} from "../plugins/manifest-registry.js"; +import type { PluginManifestRecord, PluginManifestRegistry } from "../plugins/manifest-registry.js"; import { loadPluginMetadataSnapshot } from "../plugins/plugin-metadata-snapshot.js"; import { resolveOwningPluginIdsForModelRef } from "../plugins/providers.js"; import { resolvePluginSetupAutoEnableReasons } from "../plugins/setup-registry.js"; @@ -322,7 +319,7 @@ function isAutoEnableConfiguredChannelSignal(params: { function hasConfiguredWebSearchPluginEntry(cfg: OpenClawConfig): boolean { const entries = cfg.plugins?.entries; return ( - !!entries && + Boolean(entries) && typeof entries === "object" && Object.values(entries).some( (entry) => isRecord(entry) && isRecord(entry.config) && isRecord(entry.config.webSearch), @@ -333,14 +330,16 @@ function hasConfiguredWebSearchPluginEntry(cfg: OpenClawConfig): boolean { function hasConfiguredWebSearchProviderSelection(cfg: OpenClawConfig): boolean { const provider = cfg.tools?.web?.search?.provider; return ( - cfg.tools?.web?.search?.enabled !== false && typeof provider === "string" && !!provider.trim() + cfg.tools?.web?.search?.enabled !== false && + typeof provider === "string" && + Boolean(provider.trim()) ); } function hasConfiguredWebFetchPluginEntry(cfg: OpenClawConfig): boolean { const entries = cfg.plugins?.entries; return ( - !!entries && + Boolean(entries) && typeof entries === "object" && Object.values(entries).some( (entry) => isRecord(entry) && isRecord(entry.config) && isRecord(entry.config.webFetch), @@ -351,7 +350,7 @@ function hasConfiguredWebFetchPluginEntry(cfg: OpenClawConfig): boolean { function hasConfiguredPluginConfigEntry(cfg: OpenClawConfig): boolean { const entries = cfg.plugins?.entries; return ( - !!entries && + Boolean(entries) && typeof entries === "object" && Object.values(entries).some((entry) => isRecord(entry) && isRecord(entry.config)) ); @@ -394,7 +393,7 @@ function collectConfiguredPluginEntryIds(cfg: OpenClawConfig): string[] { function hasOwnPluginEntry(cfg: OpenClawConfig, pluginId: string): boolean { const entries = cfg.plugins?.entries; - return !!entries && typeof entries === "object" && Object.hasOwn(entries, pluginId); + return Boolean(entries) && typeof entries === "object" && Object.hasOwn(entries, pluginId); } function isPluginEntryExplicitlyDisabled(cfg: OpenClawConfig, pluginId: string): boolean { @@ -473,7 +472,7 @@ function hasSetupAutoEnableRelevantConfig(cfg: OpenClawConfig): boolean { function hasPluginEntries(cfg: OpenClawConfig): boolean { const entries = cfg.plugins?.entries; - return !!entries && typeof entries === "object" && Object.keys(entries).length > 0; + return Boolean(entries) && typeof entries === "object" && Object.keys(entries).length > 0; } function hasPluginAllowlistWithMaterialEntries(cfg: OpenClawConfig): boolean { @@ -805,7 +804,7 @@ function isBuiltInChannelAlreadyEnabled(cfg: OpenClawConfig, channelId: string): const channels = cfg.channels as Record | undefined; const channelConfig = channels?.[channelId]; return ( - !!channelConfig && + Boolean(channelConfig) && typeof channelConfig === "object" && !Array.isArray(channelConfig) && (channelConfig as { enabled?: unknown }).enabled === true diff --git a/src/config/plugin-auto-enable.test-helpers.ts b/src/config/plugin-auto-enable.test-helpers.ts index f9087804af74..3d5ed588f812 100644 --- a/src/config/plugin-auto-enable.test-helpers.ts +++ b/src/config/plugin-auto-enable.test-helpers.ts @@ -1,7 +1,7 @@ import path from "node:path"; import { clearCurrentPluginMetadataSnapshot } from "../plugins/current-plugin-metadata-snapshot.js"; -import { type PluginManifestRegistry } from "../plugins/manifest-registry.js"; -import { type PluginOrigin } from "../plugins/plugin-origin.types.js"; +import type { PluginManifestRegistry } from "../plugins/manifest-registry.js"; +import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; import { clearPluginSetupRegistryCache } from "../plugins/setup-registry.js"; import { cleanupTrackedTempDirs, makeTrackedTempDir } from "../plugins/test-helpers/fs-fixtures.js"; diff --git a/src/config/redact-snapshot.ts b/src/config/redact-snapshot.ts index 8088469c41c8..498a23479fca 100644 --- a/src/config/redact-snapshot.ts +++ b/src/config/redact-snapshot.ts @@ -6,7 +6,7 @@ import { import { isRecord as isObjectRecord } from "@openclaw/normalization-core/record-coerce"; import { normalizeLowercaseStringOrEmpty } from "@openclaw/normalization-core/string-coerce"; import { createSubsystemLogger } from "../logging/subsystem.js"; -import { type ConfigUiHints } from "../shared/config-ui-hints-types.js"; +import type { ConfigUiHints } from "../shared/config-ui-hints-types.js"; import { replaceSensitiveValuesInRaw, shouldFallbackToStructuredRawRedaction, diff --git a/src/config/runtime-overrides.test.ts b/src/config/runtime-overrides.test.ts index 1dee978053e9..fabc25b48b9d 100644 --- a/src/config/runtime-overrides.test.ts +++ b/src/config/runtime-overrides.test.ts @@ -55,7 +55,7 @@ describe("runtime overrides", () => { const next = applyConfigOverrides(cfg); expect(next.commands?.bash).toBeUndefined(); - expect(Object.prototype.hasOwnProperty.call(next.commands ?? {}, "bash")).toBe(false); + expect(Object.hasOwn(next.commands ?? {}, "bash")).toBe(false); }); it("blocks constructor/prototype keys inside override object values", () => { @@ -64,7 +64,7 @@ describe("runtime overrides", () => { const next = applyConfigOverrides(cfg); expect(next.commands?.bash).toBeUndefined(); - expect(Object.prototype.hasOwnProperty.call(next.commands ?? {}, "bash")).toBe(false); + expect(Object.hasOwn(next.commands ?? {}, "bash")).toBe(false); }); it("sanitizes blocked object keys when writing overrides", () => { diff --git a/src/config/schema.hints.ts b/src/config/schema.hints.ts index 35afafeb09c5..1db358d12561 100644 --- a/src/config/schema.hints.ts +++ b/src/config/schema.hints.ts @@ -246,7 +246,7 @@ interface ZodDummy { } function isUnwrappable(object: unknown): object is ZodDummy { return ( - !!object && + Boolean(object) && typeof object === "object" && "unwrap" in object && typeof (object as Record).unwrap === "function" && diff --git a/src/config/sessions.cache.test.ts b/src/config/sessions.cache.test.ts index ff27cae00108..6339fc539990 100644 --- a/src/config/sessions.cache.test.ts +++ b/src/config/sessions.cache.test.ts @@ -312,7 +312,7 @@ describe("Session Store Cache", () => { expect(entry).toBeDefined(); expect(entry?.polluted).toBeUndefined(); - expect(Object.prototype.hasOwnProperty.call(entry, "__proto__")).toBe(true); + expect(Object.hasOwn(entry, "__proto__")).toBe(true); expect(Object.prototype).not.toHaveProperty("polluted"); }); diff --git a/src/config/sessions/delivery-info.ts b/src/config/sessions/delivery-info.ts index e7f3a413b53b..33fef5450216 100644 --- a/src/config/sessions/delivery-info.ts +++ b/src/config/sessions/delivery-info.ts @@ -129,7 +129,7 @@ function findSessionEntryInStore( const exactKeyWins = requiresFoldedSessionKeyAliasProof(normalized); let foundRoutableCandidate = false; if ( - Object.prototype.hasOwnProperty.call(store, normalized) && + Object.hasOwn(store, normalized) && !hasMismatchedCaseSensitiveDeliveryProof(asSessionEntry(store[normalized]), normalized) ) { foundRoutableCandidate ||= hasRoutableDeliveryContext( @@ -139,7 +139,7 @@ function findSessionEntryInStore( } for (const foldedLegacyKey of foldedLegacyKeys) { if ( - !Object.prototype.hasOwnProperty.call(store, foldedLegacyKey) || + !Object.hasOwn(store, foldedLegacyKey) || !isConfirmedLowercasedLegacyAlias(asSessionEntry(store[foldedLegacyKey]), normalized) ) { continue; @@ -152,7 +152,7 @@ function findSessionEntryInStore( } if ( trimmed !== normalized && - Object.prototype.hasOwnProperty.call(store, trimmed) && + Object.hasOwn(store, trimmed) && !hasMismatchedCaseSensitiveDeliveryProof(asSessionEntry(store[trimmed]), normalized) ) { foundRoutableCandidate ||= hasRoutableDeliveryContext( diff --git a/src/config/sessions/store-cache.ts b/src/config/sessions/store-cache.ts index cc00450a9d21..c1d988c1aa39 100644 --- a/src/config/sessions/store-cache.ts +++ b/src/config/sessions/store-cache.ts @@ -211,7 +211,7 @@ function cloneJsonLikeValue(value: T): T { } const cloned: Record = {}; for (const key in value as Record) { - if (!Object.prototype.hasOwnProperty.call(value, key)) { + if (!Object.hasOwn(value, key)) { continue; } const child = (value as Record)[key]; diff --git a/src/config/sessions/store-entry.ts b/src/config/sessions/store-entry.ts index 1fc99291a1d2..327a74c76f09 100644 --- a/src/config/sessions/store-entry.ts +++ b/src/config/sessions/store-entry.ts @@ -128,7 +128,7 @@ export function resolveSessionStoreEntry(params: { const legacyKeySet = new Set(); if ( trimmedKey !== normalizedKey && - Object.prototype.hasOwnProperty.call(params.store, trimmedKey) && + Object.hasOwn(params.store, trimmedKey) && !hasMismatchedCaseSensitiveDeliveryProof(params.store[trimmedKey], normalizedKey) ) { legacyKeySet.add(trimmedKey); @@ -140,7 +140,7 @@ export function resolveSessionStoreEntry(params: { let foldedLegacyUpdatedAt = 0; for (const foldedLegacyKey of foldedLegacyKeys) { if ( - !Object.prototype.hasOwnProperty.call(params.store, foldedLegacyKey) || + !Object.hasOwn(params.store, foldedLegacyKey) || !isConfirmedLowercasedLegacyAlias(params.store[foldedLegacyKey], normalizedKey) ) { continue; @@ -156,7 +156,7 @@ export function resolveSessionStoreEntry(params: { // An exact (opaque-preserving-normalized) entry always wins over any folded // legacy alias, regardless of freshness (openclaw#75670). Only when no exact // entry exists do we fall back to a confirmed legacy alias. - const exactEntry = Object.prototype.hasOwnProperty.call(params.store, normalizedKey) + const exactEntry = Object.hasOwn(params.store, normalizedKey) ? params.store[normalizedKey] : undefined; const usableExactEntry = hasMismatchedCaseSensitiveDeliveryProof(exactEntry, normalizedKey) diff --git a/src/config/sessions/store.pruning.integration.test.ts b/src/config/sessions/store.pruning.integration.test.ts index 3030d9162b3e..16c5f5216f22 100644 --- a/src/config/sessions/store.pruning.integration.test.ts +++ b/src/config/sessions/store.pruning.integration.test.ts @@ -678,7 +678,7 @@ describe("Integration: saveSessionStore with pruning", () => { ); const freshReset = path.join( testDir, - `fresh-reset.jsonl.reset.${archiveTimestamp(now - 1 * DAY_MS)}`, + `fresh-reset.jsonl.reset.${archiveTimestamp(now - Number(DAY_MS))}`, ); await fs.writeFile(oldReset, "old", "utf-8"); await fs.writeFile(freshReset, "fresh", "utf-8"); diff --git a/src/config/sessions/store.pruning.test.ts b/src/config/sessions/store.pruning.test.ts index 42ae3973488d..988ed218a6c3 100644 --- a/src/config/sessions/store.pruning.test.ts +++ b/src/config/sessions/store.pruning.test.ts @@ -43,7 +43,7 @@ describe("pruneStaleEntries", () => { const now = Date.now(); const store = makeStore([ ["old", makeEntry(now - 31 * DAY_MS)], - ["fresh", makeEntry(now - 1 * DAY_MS)], + ["fresh", makeEntry(now - Number(DAY_MS))], ]); const pruned = pruneStaleEntries(store, 30 * DAY_MS); @@ -83,7 +83,7 @@ describe("capEntryCount", () => { ["oldest", makeEntry(now - 4 * DAY_MS)], ["old", makeEntry(now - 3 * DAY_MS)], ["mid", makeEntry(now - 2 * DAY_MS)], - ["recent", makeEntry(now - 1 * DAY_MS)], + ["recent", makeEntry(now - Number(DAY_MS))], ["newest", makeEntry(now)], ]); @@ -105,7 +105,7 @@ describe("capEntryCount", () => { [threadKey, makeEntry(now - 5 * DAY_MS)], ["oldest", makeEntry(now - 4 * DAY_MS)], ["old", makeEntry(now - 3 * DAY_MS)], - ["recent", makeEntry(now - 1 * DAY_MS)], + ["recent", makeEntry(now - Number(DAY_MS))], ["newest", makeEntry(now)], ]); diff --git a/src/config/sessions/store.ts b/src/config/sessions/store.ts index ef02e1f6bc4d..409b450ac866 100644 --- a/src/config/sessions/store.ts +++ b/src/config/sessions/store.ts @@ -510,11 +510,11 @@ function resolveMutableSessionStoreKey( if (!trimmed) { return undefined; } - if (Object.prototype.hasOwnProperty.call(store, trimmed)) { + if (Object.hasOwn(store, trimmed)) { return trimmed; } const normalized = normalizeStoreSessionKey(trimmed); - if (Object.prototype.hasOwnProperty.call(store, normalized)) { + if (Object.hasOwn(store, normalized)) { return normalized; } return Object.keys(store).find((key) => normalizeStoreSessionKey(key) === normalized); @@ -1235,8 +1235,7 @@ export async function updateLastRoute(params: { ); const explicitDeliveryContext = params.deliveryContext; const explicitThreadFromDeliveryContext = - explicitDeliveryContext != null && - Object.prototype.hasOwnProperty.call(explicitDeliveryContext, "threadId") + explicitDeliveryContext != null && Object.hasOwn(explicitDeliveryContext, "threadId") ? explicitDeliveryContext.threadId : undefined; const explicitThreadValue = diff --git a/src/config/validation.ts b/src/config/validation.ts index d5df2621afe0..d16fd310b64e 100644 --- a/src/config/validation.ts +++ b/src/config/validation.ts @@ -309,7 +309,7 @@ function collectAllowedValuesFromJsonSchemaNode(schema: unknown): AllowedValuesC return { values: [], incomplete: false, hasValues: false }; } - if (Object.prototype.hasOwnProperty.call(node, "const")) { + if (Object.hasOwn(node, "const")) { return { values: [node.const], incomplete: false, hasValues: true }; } @@ -372,7 +372,7 @@ function collectRawBundledChannelConfigIssues(config: OpenClawConfig): ConfigVal } const issues: ConfigValidationIssue[] = []; for (const [channelId, schema] of bundledChannelSchemaById) { - if (!Object.prototype.hasOwnProperty.call(config.channels, channelId)) { + if (!Object.hasOwn(config.channels, channelId)) { continue; } const result = validateJsonSchemaValue({ @@ -1117,8 +1117,7 @@ function validateConfigObjectWithPluginsBase( const issues: ConfigValidationIssue[] = []; const warnings: ConfigValidationIssue[] = []; - const hasExplicitPluginsConfig = - isRecord(raw) && Object.prototype.hasOwnProperty.call(raw, "plugins"); + const hasExplicitPluginsConfig = isRecord(raw) && Object.hasOwn(raw, "plugins"); const explicitPluginReferences = collectExplicitPluginReferences(raw); const resolvePluginConfigIssuePath = (pluginId: string, errorPath: string): string => { @@ -1873,8 +1872,7 @@ function validateConfigObjectWithPluginsBase( // The default memory slot is inferred; only a user-configured slot should block startup. const pluginSlots = pluginsConfig?.slots; - const hasExplicitMemorySlot = - pluginSlots !== undefined && Object.prototype.hasOwnProperty.call(pluginSlots, "memory"); + const hasExplicitMemorySlot = pluginSlots !== undefined && Object.hasOwn(pluginSlots, "memory"); const memorySlot = normalizedPlugins.slots.memory; if ( hasExplicitMemorySlot && diff --git a/src/config/zod-schema.tts.test.ts b/src/config/zod-schema.tts.test.ts index 3f064327e17d..6e20337c7a1a 100644 --- a/src/config/zod-schema.tts.test.ts +++ b/src/config/zod-schema.tts.test.ts @@ -36,7 +36,7 @@ describe("TtsConfigSchema openai speed and instructions", () => { const result = TtsConfigSchema.safeParse({ providers: { openai: { - speed: 5.0, + speed: 5, }, }, }); diff --git a/src/context-engine/context-engine.test.ts b/src/context-engine/context-engine.test.ts index 975c5bd829bb..95c00bede0e6 100644 --- a/src/context-engine/context-engine.test.ts +++ b/src/context-engine/context-engine.test.ts @@ -197,7 +197,7 @@ class LegacySessionKeyStrictEngine implements ContextEngine { } private rejectSessionKey(params: { sessionKey?: string }): void { - if (Object.prototype.hasOwnProperty.call(params, "sessionKey")) { + if (Object.hasOwn(params, "sessionKey")) { throw new Error("Unrecognized key(s) in object: 'sessionKey'"); } } @@ -346,10 +346,10 @@ class LegacyAssembleStrictEngine implements ContextEngine { prompt?: string; }): Promise { this.assembleCalls.push({ ...params }); - if (Object.prototype.hasOwnProperty.call(params, "sessionKey")) { + if (Object.hasOwn(params, "sessionKey")) { throw new Error("Unrecognized key(s) in object: 'sessionKey'"); } - if (Object.prototype.hasOwnProperty.call(params, "prompt")) { + if (Object.hasOwn(params, "prompt")) { throw new Error("Unrecognized key(s) in object: 'prompt'"); } return { diff --git a/src/context-engine/registry.ts b/src/context-engine/registry.ts index 877f73f17311..b9f28f8fee6d 100644 --- a/src/context-engine/registry.ts +++ b/src/context-engine/registry.ts @@ -96,11 +96,7 @@ function hasOwnLegacyCompatKey( params: unknown, key: K, ): params is SessionKeyCompatParams & Required> { - return ( - params !== null && - typeof params === "object" && - Object.prototype.hasOwnProperty.call(params, key) - ); + return params !== null && typeof params === "object" && Object.hasOwn(params, key); } function withoutLegacyCompatKeys( diff --git a/src/cron/isolated-agent/delivery-dispatch.ts b/src/cron/isolated-agent/delivery-dispatch.ts index f94dbe662a3d..9c287c495e7a 100644 --- a/src/cron/isolated-agent/delivery-dispatch.ts +++ b/src/cron/isolated-agent/delivery-dispatch.ts @@ -530,7 +530,7 @@ function isTtsAudioMirrorOnly(params: { mediaUrl: string; }): boolean { return ( - (params.payload.audioAsVoice === true || !!params.payload.hookContent) && + (params.payload.audioAsVoice === true || Boolean(params.payload.hookContent)) && isAudioFileName(params.mediaUrl) ); } @@ -995,7 +995,9 @@ export async function dispatchCronDelivery( }) : undefined; const deliveryWillReachAwarenessMainSession = - mirrorTargetsAwarenessMainSession && shouldQueueAwarenessForDelivery && !!awarenessText; + mirrorTargetsAwarenessMainSession && + shouldQueueAwarenessForDelivery && + Boolean(awarenessText); // Implicit/default isolated delivery must not create main-session awareness. const mirrorWouldBypassIsolatedAwarenessPolicy = mirrorTargetsAwarenessMainSession && diff --git a/src/flows/model-picker.ts b/src/flows/model-picker.ts index 80016df7622b..740f85ecdca7 100644 --- a/src/flows/model-picker.ts +++ b/src/flows/model-picker.ts @@ -422,13 +422,15 @@ function createPreferredProviderMatcher(params: { return cached; } const value = - !!preferredOwnerPluginIdSet && - !!resolveOwningPluginIdsForProviderRef({ - provider: normalizedEntryProvider, - config: params.cfg, - workspaceDir: params.workspaceDir, - env: params.env, - })?.some((pluginId) => preferredOwnerPluginIdSet.has(pluginId)); + Boolean(preferredOwnerPluginIdSet) && + Boolean( + resolveOwningPluginIdsForProviderRef({ + provider: normalizedEntryProvider, + config: params.cfg, + workspaceDir: params.workspaceDir, + env: params.env, + })?.some((pluginId) => preferredOwnerPluginIdSet.has(pluginId)), + ); entryProviderCache.set(normalizedEntryProvider, value); return value; }; @@ -487,7 +489,7 @@ async function maybeFilterModelsByProvider(params: { }): Promise { let next = params.models.filter((entry) => params.isVisibleProvider(entry.provider)); const providerIds = sortUniqueStrings(next.map((entry) => entry.provider)); - const hasPreferredProvider = !!params.preferredProvider; + const hasPreferredProvider = Boolean(params.preferredProvider); const shouldPromptProvider = !hasPreferredProvider && providerIds.length > 1 && next.length > PROVIDER_FILTER_THRESHOLD; const matchesPreferredProvider = params.preferredProvider diff --git a/src/gateway/auth.ts b/src/gateway/auth.ts index 94a8244c7dee..e6432544a947 100644 --- a/src/gateway/auth.ts +++ b/src/gateway/auth.ts @@ -11,7 +11,7 @@ import { type AuthRateLimiter, type RateLimitCheckResult, } from "./auth-rate-limit.js"; -import { type ResolvedGatewayAuth } from "./auth-resolve.js"; +import type { ResolvedGatewayAuth } from "./auth-resolve.js"; import { isLoopbackAddress, resolveLocalInterfaceAddressMatch, diff --git a/src/gateway/hosted-plugin-surface-url.ts b/src/gateway/hosted-plugin-surface-url.ts index f8497c5de64e..f04bfb6bc7d7 100644 --- a/src/gateway/hosted-plugin-surface-url.ts +++ b/src/gateway/hosted-plugin-surface-url.ts @@ -74,8 +74,8 @@ export function resolveHostedPluginSurfaceUrl(params: HostedPluginSurfaceUrlPara const forwardedHostRaw = parseForwardedHost(params.forwardedHost); const parsedForwardedHost = parseHostHeader(forwardedHostRaw); const parsedRequestHost = parseHostHeader(params.requestHost); - const requestHost = normalizeHost(parsedRequestHost.host, !!override); - const forwardedHost = normalizeHost(parsedForwardedHost.host, !!override); + const requestHost = normalizeHost(parsedRequestHost.host, Boolean(override)); + const forwardedHost = normalizeHost(parsedForwardedHost.host, Boolean(override)); const advertisedHost = forwardedHost ? parsedForwardedHost : parsedRequestHost; const localAddress = normalizeHost( params.localAddress, diff --git a/src/gateway/plugin-activation-runtime-config.ts b/src/gateway/plugin-activation-runtime-config.ts index 7974d3d2dcf5..725e3dcc1720 100644 --- a/src/gateway/plugin-activation-runtime-config.ts +++ b/src/gateway/plugin-activation-runtime-config.ts @@ -2,7 +2,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isRecord } from "../utils.js"; function hasOwnValue(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } function mergeChannelActivationSections(params: { diff --git a/src/gateway/server-aux-handlers.ts b/src/gateway/server-aux-handlers.ts index b626dc9a9b45..f74416f3e19b 100644 --- a/src/gateway/server-aux-handlers.ts +++ b/src/gateway/server-aux-handlers.ts @@ -1,7 +1,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { isTruthyEnvValue } from "../infra/env.js"; import { createExecApprovalForwarder } from "../infra/exec-approval-forwarder.js"; -import { type PluginApprovalRequestPayload } from "../infra/plugin-approvals.js"; +import type { PluginApprovalRequestPayload } from "../infra/plugin-approvals.js"; import { resolveCommandSecretsFromActiveRuntimeSnapshot, type CommandSecretAssignment, diff --git a/src/gateway/server-channels.approval-bootstrap.test.ts b/src/gateway/server-channels.approval-bootstrap.test.ts index 921fffc40292..c026f15913e7 100644 --- a/src/gateway/server-channels.approval-bootstrap.test.ts +++ b/src/gateway/server-channels.approval-bootstrap.test.ts @@ -1,5 +1,5 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest"; -import { type ChannelId, type ChannelPlugin } from "../channels/plugins/types.js"; +import type { ChannelId, ChannelPlugin } from "../channels/plugins/types.js"; import { createSubsystemLogger, runtimeForLogger, diff --git a/src/gateway/server-channels.test.ts b/src/gateway/server-channels.test.ts index 477c7e50842e..eb02e6d7f5bb 100644 --- a/src/gateway/server-channels.test.ts +++ b/src/gateway/server-channels.test.ts @@ -1,9 +1,5 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { - type ChannelGatewayContext, - type ChannelId, - type ChannelPlugin, -} from "../channels/plugins/types.js"; +import type { ChannelGatewayContext, ChannelId, ChannelPlugin } from "../channels/plugins/types.js"; import { createSubsystemLogger, type SubsystemLogger, diff --git a/src/gateway/server-methods/agent.ts b/src/gateway/server-methods/agent.ts index 38d42d51e27c..22de86fa5a1f 100644 --- a/src/gateway/server-methods/agent.ts +++ b/src/gateway/server-methods/agent.ts @@ -1276,10 +1276,7 @@ export const agentHandlers: GatewayRequestHandlers = { : false; const canAutoRouteVoiceWake = !agentId && !explicitVoiceWakeSessionTarget && !requestedSessionId && !replyTo && !to; - const hasVoiceWakeTriggerField = Object.prototype.hasOwnProperty.call( - request, - "voiceWakeTrigger", - ); + const hasVoiceWakeTriggerField = Object.hasOwn(request, "voiceWakeTrigger"); if (hasVoiceWakeTriggerField && canAutoRouteVoiceWake) { try { const routingConfig = await loadVoiceWakeRoutingConfig(); @@ -1694,8 +1691,7 @@ export const agentHandlers: GatewayRequestHandlers = { }); const hadLegacyStoreKey = preMigrationTarget.storeKeys.some( (storeKey) => - storeKey !== preMigrationTarget.canonicalKey && - Object.prototype.hasOwnProperty.call(store, storeKey), + storeKey !== preMigrationTarget.canonicalKey && Object.hasOwn(store, storeKey), ); const { target, primaryKey } = migrateAndPruneGatewaySessionStoreKey({ cfg, @@ -1703,7 +1699,7 @@ export const agentHandlers: GatewayRequestHandlers = { store, }); const prunedStoreKey = [...storeKeysBeforeMigration].some( - (storeKey) => !Object.prototype.hasOwnProperty.call(store, storeKey), + (storeKey) => !Object.hasOwn(store, storeKey), ); const freshEntry = store[primaryKey]; patchBuild = buildSessionPatch(freshEntry); diff --git a/src/gateway/server-methods/chat.inject.parentid.test.ts b/src/gateway/server-methods/chat.inject.parentid.test.ts index 20a7b4a0f9b5..61f9ba4e892a 100644 --- a/src/gateway/server-methods/chat.inject.parentid.test.ts +++ b/src/gateway/server-methods/chat.inject.parentid.test.ts @@ -43,7 +43,7 @@ describe("gateway chat.inject transcript writes", () => { expect(last.type).toBe("message"); // The regression we saw: raw jsonl appends omitted this field entirely. - expect(Object.prototype.hasOwnProperty.call(last, "parentId")).toBe(true); + expect(Object.hasOwn(last, "parentId")).toBe(true); expect(last).toHaveProperty("id"); expect(last).toHaveProperty("message"); } finally { @@ -89,7 +89,7 @@ describe("gateway chat.inject transcript writes", () => { expect(last.type).toBe("message"); expect(last).toHaveProperty("id", messageId); expect(last).toHaveProperty("message"); - expect(Object.prototype.hasOwnProperty.call(last, "parentId")).toBe(false); + expect(Object.hasOwn(last, "parentId")).toBe(false); } finally { fs.rmSync(dir, { recursive: true, force: true }); } diff --git a/src/gateway/server-methods/config.ts b/src/gateway/server-methods/config.ts index d765ca2d1cdc..7f49fbda5bf1 100644 --- a/src/gateway/server-methods/config.ts +++ b/src/gateway/server-methods/config.ts @@ -199,7 +199,7 @@ function formatConfigOpenError(error: unknown): string { } function hasOwnRecordValue(value: unknown, key: string): boolean { - return isRecord(value) && Object.prototype.hasOwnProperty.call(value, key); + return isRecord(value) && Object.hasOwn(value, key); } function stripBundledProviderRuntimeDefaults(params: { diff --git a/src/gateway/server-methods/send.ts b/src/gateway/server-methods/send.ts index b858e4aefcfe..aa1d2a6243a1 100644 --- a/src/gateway/server-methods/send.ts +++ b/src/gateway/server-methods/send.ts @@ -637,8 +637,8 @@ export const sendHandlers: GatewayRequestHandlers = { parseThreadSessionSuffix(providedSessionKey).baseSessionKey ?? providedSessionKey; const shouldUseDerivedThreadSessionKey = channel === "slack" && - !!providedSessionKey && - !!normalizeOptionalString(derivedRoute?.threadId) && + Boolean(providedSessionKey) && + Boolean(normalizeOptionalString(derivedRoute?.threadId)) && normalizeOptionalLowercaseString(derivedRoute?.baseSessionKey) === normalizeOptionalLowercaseString(providedSessionBaseKey) && normalizeOptionalLowercaseString(derivedRoute?.sessionKey) !== providedSessionKey; diff --git a/src/gateway/server-methods/server-methods.test.ts b/src/gateway/server-methods/server-methods.test.ts index 5c81098fa316..a0f093b09bad 100644 --- a/src/gateway/server-methods/server-methods.test.ts +++ b/src/gateway/server-methods/server-methods.test.ts @@ -1726,7 +1726,8 @@ describe("exec approval handlers", () => { ...defaultExecApprovalRequestParams, ...params.params, } as unknown as ExecApprovalRequestArgs["params"]; - const hasExplicitPlan = !!params.params && Object.hasOwn(params.params, "systemRunPlan"); + const hasExplicitPlan = + params.params !== undefined && Object.hasOwn(params.params, "systemRunPlan"); if ( !hasExplicitPlan && (requestParams as { host?: string }).host === "node" && diff --git a/src/gateway/server-methods/talk.ts b/src/gateway/server-methods/talk.ts index 504e594701b6..6b5eabbe8a7f 100644 --- a/src/gateway/server-methods/talk.ts +++ b/src/gateway/server-methods/talk.ts @@ -324,7 +324,7 @@ function resolveTalkSpeed(params: TalkSpeakParams): number | undefined { return undefined; } const resolved = params.rateWpm / 175; - if (resolved <= 0.5 || resolved >= 2.0) { + if (resolved <= 0.5 || resolved >= 2) { return undefined; } return resolved; diff --git a/src/gateway/server/hooks.ts b/src/gateway/server/hooks.ts index 621baa994ed2..5b3459ca47b9 100644 --- a/src/gateway/server/hooks.ts +++ b/src/gateway/server/hooks.ts @@ -18,7 +18,7 @@ import type { CronJob } from "../../cron/types.js"; import { requestHeartbeat } from "../../infra/heartbeat-wake.js"; import { enqueueSystemEvent } from "../../infra/system-events.js"; import type { createSubsystemLogger } from "../../logging/subsystem.js"; -import { type HookAgentDispatchPayload, type HooksConfigResolved } from "../hooks.js"; +import type { HookAgentDispatchPayload, HooksConfigResolved } from "../hooks.js"; import { createHooksRequestHandler, type HookClientIpConfig } from "./hooks-request-handler.js"; type SubsystemLogger = ReturnType; diff --git a/src/gateway/test-helpers.openai-mock.ts b/src/gateway/test-helpers.openai-mock.ts index caabdd722ca4..5513bb36c9e6 100644 --- a/src/gateway/test-helpers.openai-mock.ts +++ b/src/gateway/test-helpers.openai-mock.ts @@ -30,7 +30,7 @@ function extractLastUserText(input: unknown[]): string { const text = content .filter( (c): c is { type: "input_text"; text: string } => - !!c && + Boolean(c) && typeof c === "object" && (c as { type?: unknown }).type === "input_text" && typeof (c as { text?: unknown }).text === "string", diff --git a/src/gateway/test-helpers.runtime-state.ts b/src/gateway/test-helpers.runtime-state.ts index f7265483632b..35fd9b054edd 100644 --- a/src/gateway/test-helpers.runtime-state.ts +++ b/src/gateway/test-helpers.runtime-state.ts @@ -81,7 +81,7 @@ type GatewayTestHoistedState = { const gatewayTestHoisted = vi.hoisted(() => { const key = Symbol.for("openclaw.gatewayTestHelpers.hoisted"); const store = globalThis as Record; - if (Object.prototype.hasOwnProperty.call(store, key)) { + if (Object.hasOwn(store, key)) { return store[key] as GatewayTestHoistedState; } const created: GatewayTestHoistedState = { diff --git a/src/hooks/install.ts b/src/hooks/install.ts index 6e831734c44e..0d11b863c548 100644 --- a/src/hooks/install.ts +++ b/src/hooks/install.ts @@ -3,7 +3,7 @@ import path from "node:path"; import { normalizeTrimmedStringList } from "@openclaw/normalization-core/string-normalization"; import { MANIFEST_KEY } from "../compat/legacy-names.js"; import { resolveSafeInstallDir, unscopedPackageName } from "../infra/install-safe-path.js"; -import { type NpmIntegrityDrift, type NpmSpecResolution } from "../infra/install-source-utils.js"; +import type { NpmIntegrityDrift, NpmSpecResolution } from "../infra/install-source-utils.js"; import type { InstallSafetyOverrides } from "../plugins/install-security-scan.js"; import { CONFIG_DIR, resolveUserPath } from "../utils.js"; import { parseFrontmatter } from "./frontmatter.js"; diff --git a/src/infra/device-identity.ts b/src/infra/device-identity.ts index cdf352061f6b..b1dee31830e3 100644 --- a/src/infra/device-identity.ts +++ b/src/infra/device-identity.ts @@ -112,7 +112,7 @@ type NormalizedStoredIdentity = | { kind: "recognized-invalid" }; function isRecord(value: unknown): value is Record { - return !!value && typeof value === "object"; + return Boolean(value) && typeof value === "object"; } function hasRecognizedIdentityShape(parsed: unknown): boolean { diff --git a/src/infra/outbound/deliver.ts b/src/infra/outbound/deliver.ts index e8ea0d1d7157..0875e61d2bf3 100644 --- a/src/infra/outbound/deliver.ts +++ b/src/infra/outbound/deliver.ts @@ -85,7 +85,7 @@ import { } from "./payloads.js"; import { createReplyToDeliveryPolicy } from "./reply-policy.js"; import { stripInternalRuntimeScaffolding } from "./sanitize-text.js"; -import { type OutboundSendDeps } from "./send-deps.js"; +import type { OutboundSendDeps } from "./send-deps.js"; import type { OutboundSessionContext } from "./session-context.js"; import type { OutboundChannel } from "./targets.js"; diff --git a/src/infra/outbound/payloads.ts b/src/infra/outbound/payloads.ts index e3787dc86679..fe7d1b4cc63f 100644 --- a/src/infra/outbound/payloads.ts +++ b/src/infra/outbound/payloads.ts @@ -18,7 +18,7 @@ import { type MessagePresentation, type ReplyPayloadDelivery, } from "../../interactive/payload.js"; -import { type SilentReplyConversationType } from "../../shared/silent-reply-policy.js"; +import type { SilentReplyConversationType } from "../../shared/silent-reply-policy.js"; import { stripUnsupportedCitationControlMarkers } from "../../shared/text/citation-control-markers.js"; export type NormalizedOutboundPayload = { diff --git a/src/infra/shell-env.ts b/src/infra/shell-env.ts index c9ea02cafbc5..bef68e713a33 100644 --- a/src/infra/shell-env.ts +++ b/src/infra/shell-env.ts @@ -221,7 +221,7 @@ type ShellEnvFallbackOptions = { }; function hasExplicitEnvBinding(env: NodeJS.ProcessEnv, key: string): boolean { - return Object.prototype.hasOwnProperty.call(env, key); + return Object.hasOwn(env, key); } export function loadShellEnvFallback(opts: ShellEnvFallbackOptions): ShellEnvFallbackResult { diff --git a/src/llm/env-api-keys.ts b/src/llm/env-api-keys.ts index cb9c41c12c48..73d2645a9f01 100644 --- a/src/llm/env-api-keys.ts +++ b/src/llm/env-api-keys.ts @@ -208,7 +208,7 @@ export function findEnvKeys(provider: string): string[] | undefined { return undefined; } - const found = envVars.filter((envVar) => !!getEnvValue(envVar)); + const found = envVars.filter((envVar) => Boolean(getEnvValue(envVar))); return found.length > 0 ? found : undefined; } @@ -227,8 +227,10 @@ export function getEnvApiKey(provider: string): string | undefined { // Auth is configured via `gcloud auth application-default login`. if (provider === "google-vertex") { const hasCredentials = hasVertexAdcCredentials(); - const hasProject = !!(getEnvValue("GOOGLE_CLOUD_PROJECT") || getEnvValue("GCLOUD_PROJECT")); - const hasLocation = !!getEnvValue("GOOGLE_CLOUD_LOCATION"); + const hasProject = Boolean( + getEnvValue("GOOGLE_CLOUD_PROJECT") || getEnvValue("GCLOUD_PROJECT"), + ); + const hasLocation = Boolean(getEnvValue("GOOGLE_CLOUD_LOCATION")); if (hasCredentials && hasProject && hasLocation) { return ""; diff --git a/src/llm/providers/anthropic.ts b/src/llm/providers/anthropic.ts index f6393c0aa2a4..1810ed96ad22 100644 --- a/src/llm/providers/anthropic.ts +++ b/src/llm/providers/anthropic.ts @@ -1224,7 +1224,9 @@ function shouldUseFineGrainedToolStreamingBeta( model: Model<"anthropic-messages">, context: Context, ): boolean { - return !!context.tools?.length && !getAnthropicCompat(model).supportsEagerToolInputStreaming; + return ( + Boolean(context.tools?.length) && !getAnthropicCompat(model).supportsEagerToolInputStreaming + ); } function convertTools( diff --git a/src/llm/providers/openai-completions.ts b/src/llm/providers/openai-completions.ts index 22a2e2ddbafd..d925061495a7 100644 --- a/src/llm/providers/openai-completions.ts +++ b/src/llm/providers/openai-completions.ts @@ -622,12 +622,12 @@ function buildParams( } if (compat.thinkingFormat === "zai" && model.reasoning) { - params.enable_thinking = !!options?.reasoningEffort; + params.enable_thinking = Boolean(options?.reasoningEffort); } else if (compat.thinkingFormat === "qwen" && model.reasoning) { - params.enable_thinking = !!options?.reasoningEffort; + params.enable_thinking = Boolean(options?.reasoningEffort); } else if (compat.thinkingFormat === "qwen-chat-template" && model.reasoning) { params.chat_template_kwargs = { - enable_thinking: !!options?.reasoningEffort, + enable_thinking: Boolean(options?.reasoningEffort), preserve_thinking: true, }; } else if (compat.thinkingFormat === "deepseek" && model.reasoning) { @@ -651,7 +651,7 @@ function buildParams( reasoning?: { enabled: boolean }; reasoning_effort?: string; }; - togetherParams.reasoning = { enabled: !!options?.reasoningEffort }; + togetherParams.reasoning = { enabled: Boolean(options?.reasoningEffort) }; if (options?.reasoningEffort && compat.supportsReasoningEffort) { togetherParams.reasoning_effort = model.thinkingLevelMap?.[options.reasoningEffort] ?? options.reasoningEffort; diff --git a/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts b/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts index 423eead785c3..b6d762991a8c 100644 --- a/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts +++ b/src/llm/providers/stream-wrappers/anthropic-family-tool-payload-compat.ts @@ -147,7 +147,7 @@ export function createAnthropicToolPayloadCompatibilityWrapper( ) { payloadObj.tools = payloadObj.tools .map((tool) => normalizeOpenAiFunctionAnthropicToolDefinition(tool)) - .filter((tool): tool is Record => !!tool); + .filter((tool): tool is Record => Boolean(tool)); } if (usesOpenAiStringModeAnthropicToolChoiceForModel(model, options)) { payloadObj.tool_choice = normalizeOpenAiStringModeAnthropicToolChoice( diff --git a/src/logging/diagnostic-support-redaction.ts b/src/logging/diagnostic-support-redaction.ts index 67c188504428..3c28e6ba777a 100644 --- a/src/logging/diagnostic-support-redaction.ts +++ b/src/logging/diagnostic-support-redaction.ts @@ -95,7 +95,7 @@ function createSupportRecord(): Record { } function hasOwnRecordKey(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } function countOwnObjectEntries(record: Record): number { diff --git a/src/logging/diagnostic.ts b/src/logging/diagnostic.ts index efd30cb30067..1952b5c79b39 100644 --- a/src/logging/diagnostic.ts +++ b/src/logging/diagnostic.ts @@ -40,9 +40,9 @@ import { resetDiagnosticSessionRecoveryCoordinatorForTest, type RecoverStuckSession, } from "./diagnostic-session-recovery-coordinator.js"; -import { - type StuckSessionRecoveryOutcome, - type StuckSessionRecoveryRequest, +import type { + StuckSessionRecoveryOutcome, + StuckSessionRecoveryRequest, } from "./diagnostic-session-recovery.js"; import { diagnosticSessionStates, diff --git a/src/media/web-media.ts b/src/media/web-media.ts index ffaf82eab8ab..13bb440a7edc 100644 --- a/src/media/web-media.ts +++ b/src/media/web-media.ts @@ -262,7 +262,7 @@ function isPathInsideRoot(filePath: string | undefined, root: string): boolean { } const relative = path.relative(path.resolve(root), path.resolve(filePath)); return ( - relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative)) + relative === "" || (relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)) ); } diff --git a/src/plugin-sdk/ssrf-policy.ts b/src/plugin-sdk/ssrf-policy.ts index 731404d03a64..1c682a699284 100644 --- a/src/plugin-sdk/ssrf-policy.ts +++ b/src/plugin-sdk/ssrf-policy.ts @@ -64,7 +64,7 @@ export function ssrfPolicyFromDangerouslyAllowPrivateNetwork( export function hasLegacyFlatAllowPrivateNetworkAlias(value: unknown): boolean { const entry = asNullableRecord(value); - return Boolean(entry && Object.prototype.hasOwnProperty.call(entry, "allowPrivateNetwork")); + return Boolean(entry && Object.hasOwn(entry, "allowPrivateNetwork")); } export function migrateLegacyFlatAllowPrivateNetworkAlias(params: { diff --git a/src/plugin-sdk/test-helpers/provider-auth-contract.ts b/src/plugin-sdk/test-helpers/provider-auth-contract.ts index c110173d8e15..2f4ac9945a77 100644 --- a/src/plugin-sdk/test-helpers/provider-auth-contract.ts +++ b/src/plugin-sdk/test-helpers/provider-auth-contract.ts @@ -313,7 +313,7 @@ export function describeGithubCopilotProviderAuthContract(load: ProviderAuthCont }; const stdin = process.stdin as NodeJS.ReadStream & { isTTY?: boolean }; - const hadOwnIsTTY = Object.prototype.hasOwnProperty.call(stdin, "isTTY"); + const hadOwnIsTTY = Object.hasOwn(stdin, "isTTY"); const previousIsTTYDescriptor = Object.getOwnPropertyDescriptor(stdin, "isTTY"); Object.defineProperty(stdin, "isTTY", { configurable: true, @@ -444,7 +444,7 @@ export function describeGithubCopilotProviderAuthContract(load: ProviderAuthCont it("supports non-interactive (GUI/RPC) auth contexts without a TTY", async () => { const provider = await getProvider(); const stdin = process.stdin as NodeJS.ReadStream & { isTTY?: boolean }; - const hadOwnIsTTY = Object.prototype.hasOwnProperty.call(stdin, "isTTY"); + const hadOwnIsTTY = Object.hasOwn(stdin, "isTTY"); const previousIsTTYDescriptor = Object.getOwnPropertyDescriptor(stdin, "isTTY"); Object.defineProperty(stdin, "isTTY", { configurable: true, diff --git a/src/plugin-sdk/tool-payload.ts b/src/plugin-sdk/tool-payload.ts index a569f6acbf4b..25ef3cb183f7 100644 --- a/src/plugin-sdk/tool-payload.ts +++ b/src/plugin-sdk/tool-payload.ts @@ -39,7 +39,7 @@ export type ToolPayloadCarrier = { function isToolPayloadTextBlock(block: unknown): block is ToolPayloadTextBlock { return ( - !!block && + Boolean(block) && typeof block === "object" && (block as { type?: unknown }).type === "text" && typeof (block as { text?: unknown }).text === "string" diff --git a/src/plugins/activation-planner.ts b/src/plugins/activation-planner.ts index c6d3adcc58c3..034faf8d93fd 100644 --- a/src/plugins/activation-planner.ts +++ b/src/plugins/activation-planner.ts @@ -271,7 +271,9 @@ function dedupeReasons( reasons: readonly (PluginActivationPlannerReason | null)[], ): PluginActivationPlannerReason[] { return [ - ...new Set(reasons.filter((reason): reason is PluginActivationPlannerReason => !!reason)), + ...new Set( + reasons.filter((reason): reason is PluginActivationPlannerReason => Boolean(reason)), + ), ]; } diff --git a/src/plugins/bundled-channel-config-metadata.ts b/src/plugins/bundled-channel-config-metadata.ts index b988b4fee81b..8fe69b236a36 100644 --- a/src/plugins/bundled-channel-config-metadata.ts +++ b/src/plugins/bundled-channel-config-metadata.ts @@ -63,7 +63,7 @@ function isJsonSchemaConfigSurface(value: unknown): value is JsonSchemaObject { Array.isArray(candidate.oneOf) || Array.isArray(candidate.allOf) || Array.isArray(candidate.enum) || - Object.prototype.hasOwnProperty.call(candidate, "const") + Object.hasOwn(candidate, "const") ); } diff --git a/src/plugins/channel-plugin-ids.test.ts b/src/plugins/channel-plugin-ids.test.ts index d796f076254f..db6dab060fa6 100644 --- a/src/plugins/channel-plugin-ids.test.ts +++ b/src/plugins/channel-plugin-ids.test.ts @@ -9,7 +9,7 @@ const listExplicitlyDisabledChannelIdsForConfig = vi.hoisted(() => return Object.entries(config.channels ?? {}) .filter(([, value]) => { return ( - !!value && + Boolean(value) && typeof value === "object" && !Array.isArray(value) && (value as { enabled?: unknown }).enabled === false @@ -23,7 +23,7 @@ const hasPotentialConfiguredChannels = vi.hoisted(() => vi.fn()); const hasMeaningfulChannelConfig = vi.hoisted(() => vi.fn((value: unknown) => { return ( - !!value && + Boolean(value) && typeof value === "object" && !Array.isArray(value) && Object.keys(value).some((key) => key !== "enabled") @@ -648,7 +648,7 @@ function createStartupConfig(params: { describe("resolveGatewayStartupPluginIds", () => { beforeEach(() => { listPotentialConfiguredChannelIds.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.prototype.hasOwnProperty.call(config, "channels")) { + if (Object.hasOwn(config, "channels")) { return Object.keys(config.channels ?? {}); } return ["demo-channel"]; @@ -662,7 +662,7 @@ describe("resolveGatewayStartupPluginIds", () => { })); }); hasPotentialConfiguredChannels.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.prototype.hasOwnProperty.call(config, "channels")) { + if (Object.hasOwn(config, "channels")) { return Object.keys(config.channels ?? {}).length > 0; } return true; @@ -1822,7 +1822,7 @@ describe("resolveGatewayStartupPluginIds", () => { describe("resolveConfiguredChannelPluginIds", () => { beforeEach(() => { listPotentialConfiguredChannelIds.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.prototype.hasOwnProperty.call(config, "channels")) { + if (Object.hasOwn(config, "channels")) { return Object.keys(config.channels ?? {}); } return []; @@ -1836,7 +1836,7 @@ describe("resolveConfiguredChannelPluginIds", () => { })); }); hasPotentialConfiguredChannels.mockReset().mockImplementation((config: OpenClawConfig) => { - if (Object.prototype.hasOwnProperty.call(config, "channels")) { + if (Object.hasOwn(config, "channels")) { return Object.keys(config.channels ?? {}).length > 0; } return false; diff --git a/src/plugins/config-contract-matches.ts b/src/plugins/config-contract-matches.ts index 3b3764ac3f27..370dc0eb8720 100644 --- a/src/plugins/config-contract-matches.ts +++ b/src/plugins/config-contract-matches.ts @@ -71,7 +71,7 @@ export function collectPluginConfigContractMatches(params: { } continue; } - if (!isRecord(state.value) || !Object.prototype.hasOwnProperty.call(state.value, segment)) { + if (!isRecord(state.value) || !Object.hasOwn(state.value, segment)) { continue; } nextStates.push({ diff --git a/src/plugins/config-state.ts b/src/plugins/config-state.ts index 79ff70c5d666..7df6d7185ff8 100644 --- a/src/plugins/config-state.ts +++ b/src/plugins/config-state.ts @@ -94,13 +94,10 @@ export function createPluginActivationSource(params: { } const hasExplicitMemorySlot = (plugins?: OpenClawConfig["plugins"]) => - Boolean(plugins?.slots && Object.prototype.hasOwnProperty.call(plugins.slots, "memory")); + Boolean(plugins?.slots && Object.hasOwn(plugins.slots, "memory")); const hasExplicitMemoryEntry = (plugins?: OpenClawConfig["plugins"]) => - Boolean( - plugins?.entries && - Object.prototype.hasOwnProperty.call(plugins.entries, defaultSlotIdForKey("memory")), - ); + Boolean(plugins?.entries && Object.hasOwn(plugins.entries, defaultSlotIdForKey("memory"))); export const hasExplicitPluginConfig = (plugins?: OpenClawConfig["plugins"]) => hasExplicitPluginConfigShared(plugins); diff --git a/src/plugins/conversation-binding.ts b/src/plugins/conversation-binding.ts index 617edcfbf4fd..e6474d4ae9ad 100644 --- a/src/plugins/conversation-binding.ts +++ b/src/plugins/conversation-binding.ts @@ -15,7 +15,7 @@ import { getChannelPlugin, normalizeChannelId } from "../channels/plugins/index. import { formatErrorMessage } from "../infra/errors.js"; import { expandHomePrefix } from "../infra/home-dir.js"; import { writeJson } from "../infra/json-files.js"; -import { type ConversationRef } from "../infra/outbound/session-binding-service.js"; +import type { ConversationRef } from "../infra/outbound/session-binding-service.js"; import { createSubsystemLogger } from "../logging/subsystem.js"; import { resolveGlobalMap, resolveGlobalSingleton } from "../shared/global-singleton.js"; import type { diff --git a/src/plugins/discovery.test.ts b/src/plugins/discovery.test.ts index 81ef6e3662fa..4be85d52bf9c 100644 --- a/src/plugins/discovery.test.ts +++ b/src/plugins/discovery.test.ts @@ -103,7 +103,7 @@ function buildDiscoveryEnvWithOverrides( overrides: Partial = {}, ): NodeJS.ProcessEnv { const enablesBundledOverride = - Object.prototype.hasOwnProperty.call(overrides, "OPENCLAW_BUNDLED_PLUGINS_DIR") && + Object.hasOwn(overrides, "OPENCLAW_BUNDLED_PLUGINS_DIR") && overrides.OPENCLAW_BUNDLED_PLUGINS_DIR !== undefined; return { ...buildDiscoveryEnv(stateDir), diff --git a/src/plugins/doctor-contract-registry.ts b/src/plugins/doctor-contract-registry.ts index c4c348be354b..51e331fc68e8 100644 --- a/src/plugins/doctor-contract-registry.ts +++ b/src/plugins/doctor-contract-registry.ts @@ -218,7 +218,7 @@ function hasLegacyElevenLabsTalkFields(raw: unknown): boolean { return false; } return ["voiceId", "voiceAliases", "modelId", "outputFormat", "apiKey"].some((key) => - Object.prototype.hasOwnProperty.call(talk, key), + Object.hasOwn(talk, key), ); } diff --git a/src/plugins/host-hook-cleanup.ts b/src/plugins/host-hook-cleanup.ts index a9334520ccf1..ab90277869c3 100644 --- a/src/plugins/host-hook-cleanup.ts +++ b/src/plugins/host-hook-cleanup.ts @@ -159,7 +159,7 @@ function hasPromotedSessionEntrySlot( } const entryRecord = entry as Record; for (const slotKey of slotKeys) { - if (Object.prototype.hasOwnProperty.call(entryRecord, slotKey)) { + if (Object.hasOwn(entryRecord, slotKey)) { return true; } } diff --git a/src/plugins/installed-plugin-index-install-records.ts b/src/plugins/installed-plugin-index-install-records.ts index 65b3e0a1f348..61ac7ab47695 100644 --- a/src/plugins/installed-plugin-index-install-records.ts +++ b/src/plugins/installed-plugin-index-install-records.ts @@ -112,7 +112,7 @@ function restoreInstallRecordMap( export function extractPluginInstallRecordsFromInstalledPluginIndex( index: InstalledPluginIndex | null | undefined, ): Record { - if (index && Object.prototype.hasOwnProperty.call(index, "installRecords")) { + if (index && Object.hasOwn(index, "installRecords")) { return restoreInstallRecordMap(index.installRecords); } const records: Record = {}; diff --git a/src/plugins/installed-plugin-index-record-reader.ts b/src/plugins/installed-plugin-index-record-reader.ts index c3c5e23fcc5d..42a3f391da59 100644 --- a/src/plugins/installed-plugin-index-record-reader.ts +++ b/src/plugins/installed-plugin-index-record-reader.ts @@ -209,7 +209,7 @@ function extractPluginInstallRecordsFromPersistedInstalledPluginIndex( if (!isRecord(index)) { return null; } - if (Object.prototype.hasOwnProperty.call(index, "installRecords")) { + if (Object.hasOwn(index, "installRecords")) { return readRecordMap(index.installRecords) ?? {}; } if (!Array.isArray(index.plugins)) { diff --git a/src/plugins/installed-plugin-index-records.ts b/src/plugins/installed-plugin-index-records.ts index 3e395baa2c20..9812e68b7ff2 100644 --- a/src/plugins/installed-plugin-index-records.ts +++ b/src/plugins/installed-plugin-index-records.ts @@ -12,7 +12,7 @@ import { refreshPersistedInstalledPluginIndex, refreshPersistedInstalledPluginIndexSync, } from "./installed-plugin-index-store.js"; -import { type RefreshInstalledPluginIndexParams } from "./installed-plugin-index.js"; +import type { RefreshInstalledPluginIndexParams } from "./installed-plugin-index.js"; import { recordPluginInstall, type PluginInstallUpdate } from "./installs.js"; export { diff --git a/src/plugins/installed-plugin-index-store.test.ts b/src/plugins/installed-plugin-index-store.test.ts index bb23e8728367..1c72205506c2 100644 --- a/src/plugins/installed-plugin-index-store.test.ts +++ b/src/plugins/installed-plugin-index-store.test.ts @@ -194,10 +194,8 @@ describe("installed plugin index persistence", () => { const persistedIndex = requirePersisted(persisted); expectPluginIds(persistedIndex, ["demo"]); expectInstallRecord(persistedIndex, "demo", { source: "npm" }); - expect(Object.prototype.hasOwnProperty.call(persisted as object, "__proto__")).toBe(false); - expect(Object.prototype.hasOwnProperty.call(persisted?.installRecords ?? {}, "__proto__")).toBe( - false, - ); + expect(Object.hasOwn(persisted as object, "__proto__")).toBe(false); + expect(Object.hasOwn(persisted?.installRecords ?? {}, "__proto__")).toBe(false); expect(({} as Record).polluted).toBeUndefined(); }); diff --git a/src/plugins/installed-plugin-index.test.ts b/src/plugins/installed-plugin-index.test.ts index fc961aea1e6e..ea6b2bc505ea 100644 --- a/src/plugins/installed-plugin-index.test.ts +++ b/src/plugins/installed-plugin-index.test.ts @@ -212,9 +212,9 @@ describe("installed plugin index", () => { const records = readPersistedInstalledPluginIndexInstallRecordsSync({ filePath }); expect(records?.safe).toEqual({ source: "npm", spec: "safe" }); - expect(Object.prototype.hasOwnProperty.call(records ?? {}, "constructor")).toBe(false); - expect(Object.prototype.hasOwnProperty.call(records ?? {}, "prototype")).toBe(false); - expect(Object.prototype.hasOwnProperty.call(records ?? {}, "__proto__")).toBe(false); + expect(Object.hasOwn(records ?? {}, "constructor")).toBe(false); + expect(Object.hasOwn(records ?? {}, "prototype")).toBe(false); + expect(Object.hasOwn(records ?? {}, "__proto__")).toBe(false); }); it("builds a runtime-free installed plugin snapshot from manifest and package metadata", () => { diff --git a/src/plugins/interactive.ts b/src/plugins/interactive.ts index d303f90688bf..526719c2255b 100644 --- a/src/plugins/interactive.ts +++ b/src/plugins/interactive.ts @@ -55,7 +55,7 @@ export async function dispatchPluginInteractiveHandler< commitPluginInteractiveCallbackDedupe(dedupeKey); } const shouldExposeResult = - !!resolved && + Boolean(resolved) && typeof resolved === "object" && Object.keys(resolved as Record).some((key) => key !== "handled"); diff --git a/src/plugins/loader-records.ts b/src/plugins/loader-records.ts index c914a9c10c60..f987d26e9ac6 100644 --- a/src/plugins/loader-records.ts +++ b/src/plugins/loader-records.ts @@ -183,7 +183,7 @@ function describePluginModuleExportShape( const details = [`${label}:object keys=${keySummary}`]; for (const key of ["default", "module", "register", "activate"]) { - if (Object.prototype.hasOwnProperty.call(record, key)) { + if (Object.hasOwn(record, key)) { details.push(...describePluginModuleExportShape(record[key], `${label}.${key}`, seen)); } } diff --git a/src/plugins/manifest-registry.test.ts b/src/plugins/manifest-registry.test.ts index 0fddbd602b5f..10464d0aaf1c 100644 --- a/src/plugins/manifest-registry.test.ts +++ b/src/plugins/manifest-registry.test.ts @@ -1457,9 +1457,9 @@ describe("loadPluginManifestRegistry", () => { throw new Error("expected external chat manifest channel config map"); } expect(Object.getPrototypeOf(channelConfigs)).toBe(null); - expect(Object.prototype.hasOwnProperty.call(channelConfigs, "__proto__")).toBe(false); - expect(Object.prototype.hasOwnProperty.call(channelConfigs, "constructor")).toBe(false); - expect(Object.prototype.hasOwnProperty.call(channelConfigs, "prototype")).toBe(false); + expect(Object.hasOwn(channelConfigs, "__proto__")).toBe(false); + expect(Object.hasOwn(channelConfigs, "constructor")).toBe(false); + expect(Object.hasOwn(channelConfigs, "prototype")).toBe(false); expectRecordFields(channelConfigs["safe-chat"]?.schema, "safe-chat schema", { type: "object", additionalProperties: false, diff --git a/src/plugins/manifest-registry.ts b/src/plugins/manifest-registry.ts index 88cc54948938..dedafb0c91e8 100644 --- a/src/plugins/manifest-registry.ts +++ b/src/plugins/manifest-registry.ts @@ -326,7 +326,7 @@ function mergePackageChannelMetaIntoChannelConfigs(params: { !channelId || isBlockedObjectKey(channelId) || !params.channelConfigs || - !Object.prototype.hasOwnProperty.call(params.channelConfigs, channelId) + !Object.hasOwn(params.channelConfigs, channelId) ) { return params.channelConfigs; } @@ -712,7 +712,7 @@ function pushNonBundledChannelConfigDescriptorDiagnostic(params: { } const channelConfigs = params.record.channelConfigs ?? {}; const missingChannels = declaredChannels.filter( - (channelId) => !Object.prototype.hasOwnProperty.call(channelConfigs, channelId), + (channelId) => !Object.hasOwn(channelConfigs, channelId), ); if (missingChannels.length === 0) { return; diff --git a/src/plugins/provider-auth-choice-helpers.test.ts b/src/plugins/provider-auth-choice-helpers.test.ts index 8871be73bc2a..745e7bcdba71 100644 --- a/src/plugins/provider-auth-choice-helpers.test.ts +++ b/src/plugins/provider-auth-choice-helpers.test.ts @@ -77,7 +77,7 @@ describe("applyProviderAuthConfigPatch", () => { params: { maxTokens: 12000 }, }, }); - expect(Object.prototype.hasOwnProperty.call(models, "__proto__")).toBe(false); + expect(Object.hasOwn(models, "__proto__")).toBe(false); expect(Object.getPrototypeOf(Object.assign({}, models)).polluted).toBeUndefined(); expect(({} as Record).polluted).toBeUndefined(); }); diff --git a/src/plugins/provider-auth-choice-helpers.ts b/src/plugins/provider-auth-choice-helpers.ts index c679f00bce1e..48a35258f1eb 100644 --- a/src/plugins/provider-auth-choice-helpers.ts +++ b/src/plugins/provider-auth-choice-helpers.ts @@ -198,14 +198,14 @@ function normalizeAgentListForWrite(value: unknown): unknown { } let nextAgent = agent; - if (Object.prototype.hasOwnProperty.call(agent, "model")) { + if (Object.hasOwn(agent, "model")) { const normalizedModel = normalizeAgentModelConfigForWrite(agent.model); if (normalizedModel !== agent.model) { nextAgent = { ...nextAgent, model: normalizedModel }; mutated = true; } } - if (Object.prototype.hasOwnProperty.call(agent, "models")) { + if (Object.hasOwn(agent, "models")) { const normalizedModels = normalizeAgentModelMapForWrite(agent.models); if (normalizedModels !== agent.models) { nextAgent = { ...nextAgent, models: normalizedModels }; diff --git a/src/plugins/provider-discovery.ts b/src/plugins/provider-discovery.ts index ad522f7153aa..134ce1c578ee 100644 --- a/src/plugins/provider-discovery.ts +++ b/src/plugins/provider-discovery.ts @@ -5,7 +5,7 @@ import type { OpenClawConfig } from "../config/types.openclaw.js"; import { createLazyImportLoader } from "../shared/lazy-promise.js"; import { listManifestProviderContributionIds } from "./manifest-contribution-ids.js"; import type { PluginMetadataRegistryView } from "./plugin-metadata-snapshot.types.js"; -import { type LoadPluginRegistryParams, type PluginRegistrySnapshot } from "./plugin-registry.js"; +import type { LoadPluginRegistryParams, PluginRegistrySnapshot } from "./plugin-registry.js"; import type { ProviderDiscoveryOrder, ProviderPlugin } from "./types.js"; const DISCOVERY_ORDER: readonly ProviderDiscoveryOrder[] = ["simple", "profile", "paired", "late"]; diff --git a/src/plugins/provider-hook-runtime.ts b/src/plugins/provider-hook-runtime.ts index 4a005b7f9282..2e58dd5cacd0 100644 --- a/src/plugins/provider-hook-runtime.ts +++ b/src/plugins/provider-hook-runtime.ts @@ -93,7 +93,7 @@ function resolveProviderRuntimePluginCacheKey( function matchesProviderLiteralId(provider: ProviderPlugin, providerId: string): boolean { const normalized = normalizeLowercaseStringOrEmpty(providerId); - return !!normalized && normalizeLowercaseStringOrEmpty(provider.id) === normalized; + return Boolean(normalized) && normalizeLowercaseStringOrEmpty(provider.id) === normalized; } function resolveProviderRuntimeLookupModelId( diff --git a/src/plugins/schema-validator.ts b/src/plugins/schema-validator.ts index 83ab872d5dd4..e6110bc31e84 100644 --- a/src/plugins/schema-validator.ts +++ b/src/plugins/schema-validator.ts @@ -63,7 +63,7 @@ function schemaHasDefaults(schema: unknown): boolean { return schema.some((item) => schemaHasDefaults(item)); } const record = schema as Record; - if (Object.prototype.hasOwnProperty.call(record, "default")) { + if (Object.hasOwn(record, "default")) { return true; } return Object.values(record).some((value) => schemaHasDefaults(value)); @@ -222,7 +222,7 @@ function extractAllowedValues(error: TypeBoxValidationError): unknown[] | null { if (error.keyword === "const") { const params = error.params; - if (!params || !Object.prototype.hasOwnProperty.call(params, "allowedValue")) { + if (!params || !Object.hasOwn(params, "allowedValue")) { return null; } return [params.allowedValue]; diff --git a/src/plugins/sdk-alias.ts b/src/plugins/sdk-alias.ts index d0de24053039..03716da18089 100644 --- a/src/plugins/sdk-alias.ts +++ b/src/plugins/sdk-alias.ts @@ -151,14 +151,11 @@ function hasTrustedOpenClawRootIndicator(params: { packageJson: PluginSdkPackageJson; }): boolean { const packageExports = params.packageJson.exports ?? {}; - const hasPluginSdkRootExport = Object.prototype.hasOwnProperty.call( - packageExports, - "./plugin-sdk", - ); + const hasPluginSdkRootExport = Object.hasOwn(packageExports, "./plugin-sdk"); if (!hasPluginSdkRootExport) { return false; } - const hasCliEntryExport = Object.prototype.hasOwnProperty.call(packageExports, "./cli-entry"); + const hasCliEntryExport = Object.hasOwn(packageExports, "./cli-entry"); const hasOpenClawBin = (typeof params.packageJson.bin === "string" && normalizeLowercaseStringOrEmpty(params.packageJson.bin).includes("openclaw")) || @@ -1408,7 +1405,7 @@ export function resolvePluginSdkScopedAliasMap( } break; } - if (Object.prototype.hasOwnProperty.call(aliasMap, `openclaw/plugin-sdk/${subpath}`)) { + if (Object.hasOwn(aliasMap, `openclaw/plugin-sdk/${subpath}`)) { break; } } diff --git a/src/plugins/web-fetch-providers.runtime.ts b/src/plugins/web-fetch-providers.runtime.ts index db0902aece38..cf3dc93ce547 100644 --- a/src/plugins/web-fetch-providers.runtime.ts +++ b/src/plugins/web-fetch-providers.runtime.ts @@ -1,6 +1,6 @@ import { loadOpenClawPlugins } from "./loader.js"; import type { PluginLoadOptions } from "./loader.js"; -import { type PluginManifestRecord } from "./manifest-registry.js"; +import type { PluginManifestRecord } from "./manifest-registry.js"; import type { PluginWebFetchProviderEntry } from "./types.js"; import { resolveBundledWebFetchResolutionConfig, diff --git a/src/plugins/web-search-providers.runtime.ts b/src/plugins/web-search-providers.runtime.ts index fb30e6b62de5..7c93d2f420f9 100644 --- a/src/plugins/web-search-providers.runtime.ts +++ b/src/plugins/web-search-providers.runtime.ts @@ -1,6 +1,6 @@ import { loadOpenClawPlugins } from "./loader.js"; import type { PluginLoadOptions } from "./loader.js"; -import { type PluginManifestRecord } from "./manifest-registry.js"; +import type { PluginManifestRecord } from "./manifest-registry.js"; import type { PluginWebSearchProviderEntry } from "./types.js"; import { resolveBundledWebSearchProvidersFromPublicArtifacts } from "./web-provider-public-artifacts.js"; import { diff --git a/src/secrets/apply.ts b/src/secrets/apply.ts index c55664701960..318b08335205 100644 --- a/src/secrets/apply.ts +++ b/src/secrets/apply.ts @@ -169,7 +169,7 @@ function applyProviderPlanMutations(params: { let changed = false; for (const providerAlias of params.deletes ?? []) { - if (!Object.prototype.hasOwnProperty.call(currentProviders, providerAlias)) { + if (!Object.hasOwn(currentProviders, providerAlias)) { continue; } delete currentProviders[providerAlias]; diff --git a/src/secrets/channel-contract-api.ts b/src/secrets/channel-contract-api.ts index a47f000b5158..41d961dad8ee 100644 --- a/src/secrets/channel-contract-api.ts +++ b/src/secrets/channel-contract-api.ts @@ -159,7 +159,7 @@ function loadExternalChannelSecretContractFromRecord( function recordOwnsChannel(record: PluginManifestRecord, channelId: string): boolean { return ( record.channels.includes(channelId) || - Object.prototype.hasOwnProperty.call(record.channelConfigs ?? {}, channelId) || + Object.hasOwn(record.channelConfigs ?? {}, channelId) || record.channelCatalogMeta?.id === channelId || record.packageChannel?.id === channelId ); diff --git a/src/secrets/configure-plan.ts b/src/secrets/configure-plan.ts index 68fb31c0d5e6..5cf0173e1e66 100644 --- a/src/secrets/configure-plan.ts +++ b/src/secrets/configure-plan.ts @@ -174,7 +174,7 @@ function hasPath(root: unknown, segments: string[]): boolean { if (!isRecord(cursor)) { return false; } - if (!Object.prototype.hasOwnProperty.call(cursor, segment)) { + if (!Object.hasOwn(cursor, segment)) { return false; } if (index === segments.length - 1) { @@ -204,7 +204,7 @@ export function collectConfigureProviderChanges(params: { } for (const providerAlias of Object.keys(originalProviders)) { - if (!Object.prototype.hasOwnProperty.call(nextProviders, providerAlias)) { + if (!Object.hasOwn(nextProviders, providerAlias)) { deletes.push(providerAlias); } } diff --git a/src/secrets/configure.ts b/src/secrets/configure.ts index 10efb82bdaa5..8f9f5ea4a989 100644 --- a/src/secrets/configure.ts +++ b/src/secrets/configure.ts @@ -110,7 +110,7 @@ function removeSecretProvider(config: OpenClawConfig, providerAlias: string): bo return false; } const providers = config.secrets.providers; - if (!Object.prototype.hasOwnProperty.call(providers, providerAlias)) { + if (!Object.hasOwn(providers, providerAlias)) { return false; } delete providers[providerAlias]; diff --git a/src/secrets/path-utils.ts b/src/secrets/path-utils.ts index ac3af04f2cb6..a962e935ec8e 100644 --- a/src/secrets/path-utils.ts +++ b/src/secrets/path-utils.ts @@ -61,7 +61,7 @@ function traverseToLeafParent(params: { `Invalid path shape at ${params.segments.slice(0, index).join(".") || ""}.`, ); } - if (params.requireExistingSegment && !Object.prototype.hasOwnProperty.call(cursor, segment)) { + if (params.requireExistingSegment && !Object.hasOwn(cursor, segment)) { throw new Error( `Path segment does not exist at ${params.segments.slice(0, index + 1).join(".")}.`, ); @@ -176,7 +176,7 @@ export function setPathExistingStrict( if (!isRecord(cursor)) { throw new Error(`Invalid path shape at ${segments.slice(0, -1).join(".") || ""}.`); } - if (!Object.prototype.hasOwnProperty.call(cursor, leaf)) { + if (!Object.hasOwn(cursor, leaf)) { throw new Error(`Path segment does not exist at ${segments.join(".")}.`); } if (!isDeepStrictEqual(cursor[leaf], value)) { @@ -202,7 +202,7 @@ export function deletePathStrict(root: Record, segments: string if (!isRecord(cursor)) { throw new Error(`Invalid path shape at ${segments.slice(0, -1).join(".") || ""}.`); } - if (!Object.prototype.hasOwnProperty.call(cursor, leaf)) { + if (!Object.hasOwn(cursor, leaf)) { return false; } delete cursor[leaf]; diff --git a/src/secrets/runtime-config-collectors-channels.ts b/src/secrets/runtime-config-collectors-channels.ts index cef2ae2db6ec..a6739056dcfe 100644 --- a/src/secrets/runtime-config-collectors-channels.ts +++ b/src/secrets/runtime-config-collectors-channels.ts @@ -2,7 +2,7 @@ import { getBootstrapChannelSecrets } from "../channels/plugins/bootstrap-regist import type { OpenClawConfig } from "../config/types.openclaw.js"; import type { PluginOrigin } from "../plugins/plugin-origin.types.js"; import { loadChannelSecretContractApi } from "./channel-contract-api.js"; -import { type ResolverContext, type SecretDefaults } from "./runtime-shared.js"; +import type { ResolverContext, SecretDefaults } from "./runtime-shared.js"; export function collectChannelConfigAssignments(params: { config: OpenClawConfig; diff --git a/src/secrets/runtime-config-collectors-core.ts b/src/secrets/runtime-config-collectors-core.ts index 11d48eebaa62..983a18b2c8a2 100644 --- a/src/secrets/runtime-config-collectors-core.ts +++ b/src/secrets/runtime-config-collectors-core.ts @@ -135,12 +135,12 @@ function collectAgentMemorySearchAssignments(params: { if (memorySearch?.enabled === false) { continue; } - if (!memorySearch || !Object.prototype.hasOwnProperty.call(memorySearch, "remote")) { + if (!memorySearch || !Object.hasOwn(memorySearch, "remote")) { hasEnabledAgentWithoutOverride = true; continue; } const remote = isRecord(memorySearch.remote) ? memorySearch.remote : undefined; - if (!remote || !Object.prototype.hasOwnProperty.call(remote, "apiKey")) { + if (!remote || !Object.hasOwn(remote, "apiKey")) { hasEnabledAgentWithoutOverride = true; continue; } @@ -173,7 +173,7 @@ function collectAgentMemorySearchAssignments(params: { return; } const remote = isRecord(memorySearch.remote) ? memorySearch.remote : undefined; - if (!remote || !Object.prototype.hasOwnProperty.call(remote, "apiKey")) { + if (!remote || !Object.hasOwn(remote, "apiKey")) { return; } const enabled = rawAgent.enabled !== false && memorySearch.enabled !== false; @@ -591,7 +591,7 @@ function collectSandboxSshAssignments(params: { const active = normalizeOptionalLowercaseString(effectiveBackend) === "ssh" && effectiveMode !== "off"; for (const key of ["identityData", "certificateData", "knownHostsData"] as const) { - if (ssh && Object.prototype.hasOwnProperty.call(ssh, key)) { + if (ssh && Object.hasOwn(ssh, key)) { collectSecretInputAssignment({ value: ssh[key], path: `agents.list.${index}.sandbox.ssh.${key}`, diff --git a/src/secrets/runtime-fast-path.ts b/src/secrets/runtime-fast-path.ts index 4d4357991d48..d2f7c7df3560 100644 --- a/src/secrets/runtime-fast-path.ts +++ b/src/secrets/runtime-fast-path.ts @@ -170,7 +170,7 @@ function hasRuntimeWebToolConfigSurface(config: OpenClawConfig): boolean { } const pluginConfig = (entry as { config?: unknown }).config; return ( - !!pluginConfig && + Boolean(pluginConfig) && typeof pluginConfig === "object" && !Array.isArray(pluginConfig) && ("webSearch" in pluginConfig || (!fetchExplicitlyDisabled && "webFetch" in pluginConfig)) diff --git a/src/secrets/runtime-shared.ts b/src/secrets/runtime-shared.ts index 3b2e5e681565..0d969c42a292 100644 --- a/src/secrets/runtime-shared.ts +++ b/src/secrets/runtime-shared.ts @@ -141,7 +141,7 @@ export function applyResolvedAssignments(params: { } export function hasOwnProperty(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } export function isEnabledFlag(value: unknown): boolean { diff --git a/src/secrets/runtime-web-tools.ts b/src/secrets/runtime-web-tools.ts index b84df5eb06c6..5d3841cfc407 100644 --- a/src/secrets/runtime-web-tools.ts +++ b/src/secrets/runtime-web-tools.ts @@ -550,7 +550,7 @@ export async function resolveRuntimeWebTools(params: { if ( legacyXSearchSource && legacyXSearchResolved && - Object.prototype.hasOwnProperty.call(legacyXSearchSource, "apiKey") + Object.hasOwn(legacyXSearchSource, "apiKey") ) { const legacyXSearchSourceRecord = legacyXSearchSource as Record; const legacyXSearchResolvedRecord = legacyXSearchResolved as Record; diff --git a/src/secrets/runtime.ts b/src/secrets/runtime.ts index 01f7e18dbfe6..2d7dc4d645aa 100644 --- a/src/secrets/runtime.ts +++ b/src/secrets/runtime.ts @@ -77,7 +77,7 @@ async function resolveLoadablePluginOrigins(params: { function hasConfiguredPluginEntries(config: OpenClawConfig): boolean { const entries = config.plugins?.entries; return ( - !!entries && + Boolean(entries) && typeof entries === "object" && !Array.isArray(entries) && Object.keys(entries).length > 0 @@ -87,7 +87,7 @@ function hasConfiguredPluginEntries(config: OpenClawConfig): boolean { function hasConfiguredChannelEntries(config: OpenClawConfig): boolean { const channels = config.channels; return ( - !!channels && + Boolean(channels) && typeof channels === "object" && !Array.isArray(channels) && Object.keys(channels).some((channelId) => channelId !== "defaults") diff --git a/src/secrets/target-registry-pattern.ts b/src/secrets/target-registry-pattern.ts index fc32eb5f7dd7..0cadf39692c1 100644 --- a/src/secrets/target-registry-pattern.ts +++ b/src/secrets/target-registry-pattern.ts @@ -159,7 +159,7 @@ export function expandPathTokens(root: unknown, tokens: PathPatternToken[]): Exp }); return; } - if (!Object.prototype.hasOwnProperty.call(node, token.value)) { + if (!Object.hasOwn(node, token.value)) { return; } walk(node[token.value], tokenIndex + 1, [...segments, token.value], captures); diff --git a/src/shared/global-singleton.ts b/src/shared/global-singleton.ts index 525ebe56b3a5..a472b01a5e53 100644 --- a/src/shared/global-singleton.ts +++ b/src/shared/global-singleton.ts @@ -3,7 +3,7 @@ // runtime chunks; keep those on a direct globalThis[Symbol.for(...)] lookup. export function resolveGlobalSingleton(key: symbol, create: () => T): T { const globalStore = globalThis as Record; - if (Object.prototype.hasOwnProperty.call(globalStore, key)) { + if (Object.hasOwn(globalStore, key)) { return globalStore[key] as T; } const created = create(); diff --git a/src/shared/json-schema-defaults.ts b/src/shared/json-schema-defaults.ts index a0d71e5c7254..511abebe96d9 100644 --- a/src/shared/json-schema-defaults.ts +++ b/src/shared/json-schema-defaults.ts @@ -571,7 +571,7 @@ function findJsonSchemaNodeError( if (!isRecord(schema)) { return `${path}: schema must be an object or boolean`; } - if (Object.prototype.hasOwnProperty.call(schema, "type")) { + if (Object.hasOwn(schema, "type")) { const typeError = validateTypeKeyword(schema.type, path); if (typeError) { return typeError; @@ -581,7 +581,7 @@ function findJsonSchemaNodeError( if (typeof schema.nullable !== "boolean") { return `${path}.nullable: expected boolean`; } - if (!Object.prototype.hasOwnProperty.call(schema, "type")) { + if (!Object.hasOwn(schema, "type")) { return `${path}.nullable: expected type`; } } @@ -712,7 +712,7 @@ function cloneDefault(value: T): T { } function getDefault(schema: JsonSchemaValue): unknown { - if (!isRecord(schema) || !Object.prototype.hasOwnProperty.call(schema, "default")) { + if (!isRecord(schema) || !Object.hasOwn(schema, "default")) { return undefined; } return cloneDefault(schema.default); @@ -917,7 +917,7 @@ function applyObjectPropertyDefaults( if (isRecord(schema.additionalProperties)) { const additionalSchema = schema.additionalProperties as JsonSchemaValue; for (const key of Object.keys(value)) { - if (Object.prototype.hasOwnProperty.call(properties, key) || patternMatchedKeys.has(key)) { + if (Object.hasOwn(properties, key) || patternMatchedKeys.has(key)) { continue; } value[key] = applySchemaDefaults( @@ -944,10 +944,7 @@ function applyObjectDependencyDefaults( let nextValue = value; if (isRecord(schema.dependencies)) { for (const [key, dependencySchema] of Object.entries(schema.dependencies)) { - if ( - !Object.prototype.hasOwnProperty.call(nextValue, key) || - isStringArray(dependencySchema) - ) { + if (!Object.hasOwn(nextValue, key) || isStringArray(dependencySchema)) { continue; } nextValue = applySchemaDefaults( @@ -962,7 +959,7 @@ function applyObjectDependencyDefaults( } if (isRecord(schema.dependentSchemas)) { for (const [key, dependentSchema] of Object.entries(schema.dependentSchemas)) { - if (!Object.prototype.hasOwnProperty.call(nextValue, key)) { + if (!Object.hasOwn(nextValue, key)) { continue; } nextValue = applySchemaDefaults( diff --git a/src/skills/loading/workspace.ts b/src/skills/loading/workspace.ts index 5409a6d5b1d9..16426da84771 100644 --- a/src/skills/loading/workspace.ts +++ b/src/skills/loading/workspace.ts @@ -63,12 +63,12 @@ function resolveNativeUserHomeDir(): string | undefined { function resolveCompactHomePrefixes(): string[] { const homes = [resolveHomeDir(), resolveUserHomeDir(), resolveNativeUserHomeDir()].filter( - (home): home is string => !!home, + (home): home is string => Boolean(home), ); const resolvedHomes = homes.map((home) => path.resolve(home)); const realHomes = resolvedHomes .map((home) => tryRealpath(home)) - .filter((home): home is string => !!home); + .filter((home): home is string => Boolean(home)); return uniqueStrings([...resolvedHomes, ...realHomes]).toSorted((a, b) => b.length - a.length); } @@ -372,7 +372,7 @@ function hasLoadableSkillFrontmatter( }); const fallbackName = path.basename(skillDir).trim(); const name = frontmatter?.name?.trim() || fallbackName; - return !!name && !!frontmatter?.description?.trim(); + return Boolean(name) && Boolean(frontmatter?.description?.trim()); } function tryRealpath(filePath: string): string | null { diff --git a/src/skills/runtime/refresh.ts b/src/skills/runtime/refresh.ts index 50de35a8d048..2c586cd7558b 100644 --- a/src/skills/runtime/refresh.ts +++ b/src/skills/runtime/refresh.ts @@ -373,7 +373,7 @@ function tryRealpath(filePath: string): string | null { function isPathInside(parent: string, child: string): boolean { const relative = path.relative(parent, child); return ( - relative === "" || (!!relative && !relative.startsWith("..") && !path.isAbsolute(relative)) + relative === "" || (relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative)) ); } diff --git a/src/skills/workshop/service.ts b/src/skills/workshop/service.ts index ea37b6bc7dd1..4a44c6062ea3 100644 --- a/src/skills/workshop/service.ts +++ b/src/skills/workshop/service.ts @@ -980,8 +980,8 @@ function proposalMatchesName( } const normalizedCandidate = normalizeSkillIndexName(candidate); return ( - !!normalizedName && - !!normalizedCandidate && + Boolean(normalizedName) && + Boolean(normalizedCandidate) && (normalizedCandidate === normalizedName || normalizedCandidate.includes(normalizedName) || normalizedName.includes(normalizedCandidate)) diff --git a/src/tools/availability.ts b/src/tools/availability.ts index cd6ccf619cd4..e3ec492bf912 100644 --- a/src/tools/availability.ts +++ b/src/tools/availability.ts @@ -10,7 +10,7 @@ import type { } from "./types.js"; function isRecord(value: JsonValue | undefined): value is JsonObject { - return !!value && typeof value === "object" && !Array.isArray(value); + return Boolean(value) && typeof value === "object" && !Array.isArray(value); } function resolveConfigPath( diff --git a/src/tts/status-config.ts b/src/tts/status-config.ts index 660f78e9258d..3047735e321b 100644 --- a/src/tts/status-config.ts +++ b/src/tts/status-config.ts @@ -239,7 +239,7 @@ export function resolveStatusTtsSnapshot(params: { } const persona = - prefs.tts && Object.prototype.hasOwnProperty.call(prefs.tts, "persona") + prefs.tts && Object.hasOwn(prefs.tts, "persona") ? normalizeTtsPersonaId(prefs.tts.persona) : normalizeTtsPersonaId(raw.persona); const provider = diff --git a/src/tui/tui-pty-harness.e2e.test.ts b/src/tui/tui-pty-harness.e2e.test.ts index c5c7663c2ec1..27a5f39c8ae0 100644 --- a/src/tui/tui-pty-harness.e2e.test.ts +++ b/src/tui/tui-pty-harness.e2e.test.ts @@ -55,7 +55,7 @@ function objectFieldEquals(entry: FixtureLogEntry, field: string, value: unknown return false; } const payload = entry.payload as Record; - return Object.prototype.hasOwnProperty.call(payload, field) && payload[field] === value; + return Object.hasOwn(payload, field) && payload[field] === value; } async function writeTuiPtyFixtureScript(dir: string) { diff --git a/src/utils/usage-format.test.ts b/src/utils/usage-format.test.ts index 979757211ac7..6ca9caeba621 100644 --- a/src/utils/usage-format.test.ts +++ b/src/utils/usage-format.test.ts @@ -702,7 +702,7 @@ describe("usage-format", () => { const tiers: PricingTier[] = [ { input: 0.46, output: 2.3, cacheRead: 0, cacheWrite: 0, range: [0, 32_000] }, { input: 0.7, output: 3.5, cacheRead: 0, cacheWrite: 0, range: [32_000, 128_000] }, - { input: 1.4, output: 7.0, cacheRead: 0, cacheWrite: 0, range: [128_000, 256_000] }, + { input: 1.4, output: 7, cacheRead: 0, cacheWrite: 0, range: [128_000, 256_000] }, ]; const cost = { input: 0.46, output: 2.3, cacheRead: 0, cacheWrite: 0, tieredPricing: tiers }; @@ -768,9 +768,9 @@ describe("usage-format", () => { it("bills overflow at last tier when only a single small-range tier exists (e.g. <30K)", () => { // Only one tier covering [0, 30000), input is 100000 const tiers: PricingTier[] = [ - { input: 1.0, output: 3.0, cacheRead: 0.5, cacheWrite: 0, range: [0, 30_000] }, + { input: 1, output: 3, cacheRead: 0.5, cacheWrite: 0, range: [0, 30_000] }, ]; - const cost = { input: 1.0, output: 3.0, cacheRead: 0.5, cacheWrite: 0, tieredPricing: tiers }; + const cost = { input: 1, output: 3, cacheRead: 0.5, cacheWrite: 0, tieredPricing: tiers }; // 100000 input exceeds the only range, so Tier 1 is the whole-request fallback. // Total = 0.1 + 0.015 + 0.001 = 0.116 diff --git a/test/scripts/oxlint-config.test.ts b/test/scripts/oxlint-config.test.ts index 8350113858e0..f816ac824cb6 100644 --- a/test/scripts/oxlint-config.test.ts +++ b/test/scripts/oxlint-config.test.ts @@ -22,11 +22,13 @@ const ZERO_BASELINE_RULES = [ "eslint/no-sequences", "eslint/no-self-compare", "eslint/no-var", + "eslint/no-implicit-coercion", "eslint/no-new-wrappers", "eslint/no-else-return", "eslint/no-case-declarations", "eslint/prefer-exponentiation-operator", "eslint/prefer-numeric-literals", + "eslint/prefer-object-has-own", "eslint/radix", "eslint/unicode-bom", "eslint/yoda", @@ -37,6 +39,7 @@ const ZERO_BASELINE_RULES = [ "promise/no-new-statics", "typescript/adjacent-overload-signatures", "typescript/ban-tslint-comment", + "typescript/no-import-type-side-effects", "typescript/no-non-null-asserted-nullish-coalescing", "typescript/no-unnecessary-qualifier", "typescript/prefer-find", @@ -53,6 +56,7 @@ const ZERO_BASELINE_RULES = [ "unicorn/no-new-buffer", "unicorn/no-typeof-undefined", "unicorn/no-useless-error-capture-stack-trace", + "unicorn/no-zero-fractions", "unicorn/prefer-array-some", "unicorn/prefer-dom-node-text-content", "unicorn/prefer-keyboard-event-key", @@ -124,6 +128,7 @@ describe("oxlint config", () => { expect(ignorePatterns).toContain("**/.openclaw-runtime-deps-copy-*/**"); expect(ignorePatterns).toContain("extensions/diffs/assets/viewer-runtime.js"); expect(ignorePatterns).toContain("extensions/diffs-language-pack/assets/viewer-runtime.js"); + expect(ignorePatterns).toContain("extensions/canvas/src/host/a2ui/a2ui.bundle.js"); }); it("enables strict empty object type lint with named single-extends interfaces allowed", () => { diff --git a/ui/src/test-helpers/control-ui-e2e.ts b/ui/src/test-helpers/control-ui-e2e.ts index c616e003da05..2279e42a6d56 100644 --- a/ui/src/test-helpers/control-ui-e2e.ts +++ b/ui/src/test-helpers/control-ui-e2e.ts @@ -262,7 +262,7 @@ function installControlUiMockGateway(input: { } function hasOwn(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } function valuesEqual(actual: unknown, expected: unknown): boolean { diff --git a/ui/src/ui/app-render.helpers.ts b/ui/src/ui/app-render.helpers.ts index 74e0b1dcb080..d99fab8ce036 100644 --- a/ui/src/ui/app-render.helpers.ts +++ b/ui/src/ui/app-render.helpers.ts @@ -123,7 +123,7 @@ function saveChatQueueForSession(state: AppViewState, sessionKey: string) { state.chatQueueBySession = { ...queueBySession }; return; } - if (Object.prototype.hasOwnProperty.call(queueBySession, sessionKey)) { + if (Object.hasOwn(queueBySession, sessionKey)) { delete queueBySession[sessionKey]; state.chatQueueBySession = { ...queueBySession }; } diff --git a/ui/src/ui/app-render.ts b/ui/src/ui/app-render.ts index 6fbda7bedd57..e6ca1459617e 100644 --- a/ui/src/ui/app-render.ts +++ b/ui/src/ui/app-render.ts @@ -1278,8 +1278,8 @@ export function renderApp(state: AppViewState) { configPath: state.configSnapshot?.path ?? null, rawAvailable: typeof state.configSnapshot?.raw === "string" || - !!state.configSnapshot?.config || - !!state.configForm, + Boolean(state.configSnapshot?.config) || + Boolean(state.configForm), } satisfies Omit< ConfigProps, | "formMode" diff --git a/ui/src/ui/app.ts b/ui/src/ui/app.ts index 3561789c7584..e78a747c6781 100644 --- a/ui/src/ui/app.ts +++ b/ui/src/ui/app.ts @@ -140,7 +140,7 @@ import type { ToolsCatalogResult, ToolsEffectiveResult, } from "./types.ts"; -import { type ChatAttachment, type ChatQueueItem, type CronFormState } from "./ui-types.ts"; +import type { ChatAttachment, ChatQueueItem, CronFormState } from "./ui-types.ts"; import { generateUUID } from "./uuid.ts"; import type { NostrProfileFormState } from "./views/channels.nostr-profile-form.ts"; diff --git a/ui/src/ui/chat/realtime-talk.ts b/ui/src/ui/chat/realtime-talk.ts index d2aedd6c57f8..1fb7c929bf0d 100644 --- a/ui/src/ui/chat/realtime-talk.ts +++ b/ui/src/ui/chat/realtime-talk.ts @@ -2,16 +2,16 @@ import { normalizeTalkTransport } from "../../../../src/talk/talk-session-contro import type { GatewayBrowserClient } from "../gateway.ts"; import { GatewayRelayRealtimeTalkTransport } from "./realtime-talk-gateway-relay.ts"; import { GoogleLiveRealtimeTalkTransport } from "./realtime-talk-google-live.ts"; -import { - type RealtimeTalkCallbacks, - type RealtimeTalkEvent, - type RealtimeTalkGatewayRelaySessionResult, - type RealtimeTalkJsonPcmWebSocketSessionResult, - type RealtimeTalkSessionResult, - type RealtimeTalkStatus, - type RealtimeTalkTransport, - type RealtimeTalkTransportContext, - type RealtimeTalkWebRtcSdpSessionResult, +import type { + RealtimeTalkCallbacks, + RealtimeTalkEvent, + RealtimeTalkGatewayRelaySessionResult, + RealtimeTalkJsonPcmWebSocketSessionResult, + RealtimeTalkSessionResult, + RealtimeTalkStatus, + RealtimeTalkTransport, + RealtimeTalkTransportContext, + RealtimeTalkWebRtcSdpSessionResult, } from "./realtime-talk-shared.ts"; import { WebRtcSdpRealtimeTalkTransport } from "./realtime-talk-webrtc.ts"; diff --git a/ui/src/ui/chat/session-controls.ts b/ui/src/ui/chat/session-controls.ts index f73eaa8a2e92..18708b10eed4 100644 --- a/ui/src/ui/chat/session-controls.ts +++ b/ui/src/ui/chat/session-controls.ts @@ -1301,7 +1301,7 @@ export function resolveSessionOptionGroups( if (hideCron && row.key !== sessionKey && isCronSessionKey(row.key)) { continue; } - const isSubagent = isSubagentSessionKey(row.key) || !!row.spawnedBy; + const isSubagent = isSubagentSessionKey(row.key) || Boolean(row.spawnedBy); if (isSubagent && row.key !== sessionKey) { continue; } diff --git a/ui/src/ui/components/modal-dialog.test.ts b/ui/src/ui/components/modal-dialog.test.ts index f6a6bbf728ff..b27ba855a156 100644 --- a/ui/src/ui/components/modal-dialog.test.ts +++ b/ui/src/ui/components/modal-dialog.test.ts @@ -7,7 +7,7 @@ import { installDialogPolyfill, nextFrame, } from "../../test-helpers/modal-dialog.ts"; -import { type OpenClawModalDialog } from "./modal-dialog.ts"; +import type { OpenClawModalDialog } from "./modal-dialog.ts"; import "./modal-dialog.ts"; let container: HTMLDivElement; diff --git a/ui/src/ui/components/resizable-divider.test.ts b/ui/src/ui/components/resizable-divider.test.ts index f7f446208ce4..f14940b45045 100644 --- a/ui/src/ui/components/resizable-divider.test.ts +++ b/ui/src/ui/components/resizable-divider.test.ts @@ -2,7 +2,7 @@ import { html, nothing, render } from "lit"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -import { type ResizableDivider } from "./resizable-divider.ts"; +import type { ResizableDivider } from "./resizable-divider.ts"; import "./resizable-divider.ts"; let container: HTMLDivElement; diff --git a/ui/src/ui/controllers/config.ts b/ui/src/ui/controllers/config.ts index 430141698402..9eb5f89a97f9 100644 --- a/ui/src/ui/controllers/config.ts +++ b/ui/src/ui/controllers/config.ts @@ -113,7 +113,8 @@ export function applyConfigSnapshot( const draftBaseHash = state.configDraftBaseHash ?? state.configSnapshot?.hash ?? null; state.configSnapshot = snapshot; const editableConfig = resolveEditableSnapshotConfig(snapshot); - const rawAvailable = typeof snapshot.raw === "string" || !!editableConfig || !!state.configForm; + const rawAvailable = + typeof snapshot.raw === "string" || Boolean(editableConfig) || Boolean(state.configForm); if (!rawAvailable && state.configFormMode === "raw") { state.configFormMode = "form"; } diff --git a/ui/src/ui/controllers/config/form-utils.node.test.ts b/ui/src/ui/controllers/config/form-utils.node.test.ts index 1cc80fc90669..b198ac9aa5f9 100644 --- a/ui/src/ui/controllers/config/form-utils.node.test.ts +++ b/ui/src/ui/controllers/config/form-utils.node.test.ts @@ -87,7 +87,7 @@ function makeConfigWithProvider(): Record { name: "Grok 4", contextWindow: 131072, maxTokens: 8192, - cost: { input: 0.5, output: 1.0, cacheRead: 0.1, cacheWrite: 0.2 }, + cost: { input: 0.5, output: 1, cacheRead: 0.1, cacheWrite: 0.2 }, }, ], }, diff --git a/ui/src/ui/controllers/config/form-utils.ts b/ui/src/ui/controllers/config/form-utils.ts index 82f2b122dbf9..e0a88eb3ad90 100644 --- a/ui/src/ui/controllers/config/form-utils.ts +++ b/ui/src/ui/controllers/config/form-utils.ts @@ -22,7 +22,7 @@ function isRecord(value: unknown): value is Record { } function hasOwnRecordValue(record: Record | null, key: string): boolean { - return record != null && Object.prototype.hasOwnProperty.call(record, key); + return record != null && Object.hasOwn(record, key); } function sanitizeRedactedValue(params: { @@ -70,7 +70,7 @@ function sanitizeRedactedValue(params: { const next: Record = {}; for (const [key, item] of Object.entries(params.value)) { const originalFormValue = - originalFormRecord != null && Object.prototype.hasOwnProperty.call(originalFormRecord, key) + originalFormRecord != null && Object.hasOwn(originalFormRecord, key) ? originalFormRecord[key] : undefined; const originalRawPathExists = hasOwnRecordValue(originalRawRecord, key); diff --git a/ui/src/ui/controllers/sessions.ts b/ui/src/ui/controllers/sessions.ts index 02696abbb923..f5b2ec843463 100644 --- a/ui/src/ui/controllers/sessions.ts +++ b/ui/src/ui/controllers/sessions.ts @@ -365,7 +365,7 @@ function isRecord(value: unknown): value is Record { } function hasOwn(record: Record, key: string): boolean { - return Object.prototype.hasOwnProperty.call(record, key); + return Object.hasOwn(record, key); } export function parseSessionsFilterInteger(value: string): number { diff --git a/ui/src/ui/gateway.ts b/ui/src/ui/gateway.ts index c81f5d4e35ee..9715cd169774 100644 --- a/ui/src/ui/gateway.ts +++ b/ui/src/ui/gateway.ts @@ -620,7 +620,7 @@ export class GatewayBrowserClient { // crypto.subtle is only available in secure contexts (HTTPS, localhost). // Over plain HTTP, we skip device identity and fall back to token-only auth. // Gateways may reject this unless gateway.controlUi.allowInsecureAuth is enabled. - const isSecureContext = typeof crypto !== "undefined" && !!crypto.subtle; + const isSecureContext = typeof crypto !== "undefined" && Boolean(crypto.subtle); let deviceIdentity: Awaited> | null = null; let selectedAuth: SelectedConnectAuth = { authToken: explicitGatewayToken, diff --git a/ui/src/ui/views/chat.test.ts b/ui/src/ui/views/chat.test.ts index 9db23b421545..616fe34985e5 100644 --- a/ui/src/ui/views/chat.test.ts +++ b/ui/src/ui/views/chat.test.ts @@ -2031,11 +2031,9 @@ describe("chat session controls", () => { includeUnknown: true, limit: 50, }); - expect( - request.mock.calls.some(([, params]) => - Object.prototype.hasOwnProperty.call(params ?? {}, "agentId"), - ), - ).toBe(false); + expect(request.mock.calls.some(([, params]) => Object.hasOwn(params ?? {}, "agentId"))).toBe( + false, + ); }); it("reloads the picker after switching agents", async () => { diff --git a/ui/src/ui/views/config.ts b/ui/src/ui/views/config.ts index 40f93ceeb0d9..039eef98a33a 100644 --- a/ui/src/ui/views/config.ts +++ b/ui/src/ui/views/config.ts @@ -593,10 +593,7 @@ function computeDiff( return true; } for (const key of origKeys) { - if ( - !Object.prototype.hasOwnProperty.call(curr, key) || - valuesDiffer(orig[key], curr[key], depth + 1) - ) { + if (!Object.hasOwn(curr, key) || valuesDiffer(orig[key], curr[key], depth + 1)) { return true; } } diff --git a/ui/src/ui/views/cron.ts b/ui/src/ui/views/cron.ts index 55d3bb3bf6a6..19684ab9d7ff 100644 --- a/ui/src/ui/views/cron.ts +++ b/ui/src/ui/views/cron.ts @@ -1841,7 +1841,7 @@ function renderRun( ? `${usage.input_tokens} in / ${usage.output_tokens} out` : null; const bodySource = entry.summary || entry.error || t("cron.runEntry.noSummary"); - const showErrorInMeta = !!entry.error && !!entry.summary; + const showErrorInMeta = Boolean(entry.error) && Boolean(entry.summary); return html`
diff --git a/ui/src/ui/views/sessions.ts b/ui/src/ui/views/sessions.ts index ee8bb8bf7e56..39d56264e450 100644 --- a/ui/src/ui/views/sessions.ts +++ b/ui/src/ui/views/sessions.ts @@ -93,9 +93,7 @@ function getAgentIdentity( agentIdentityById: Record, agentId: string, ): AgentIdentityResult | null { - return Object.prototype.hasOwnProperty.call(agentIdentityById, agentId) - ? (agentIdentityById[agentId] ?? null) - : null; + return Object.hasOwn(agentIdentityById, agentId) ? (agentIdentityById[agentId] ?? null) : null; } function rowMatchesSessionDefaults( diff --git a/ui/src/ui/views/usage-render-details.test.ts b/ui/src/ui/views/usage-render-details.test.ts index 78e6d97f9eaa..e5f75d107b75 100644 --- a/ui/src/ui/views/usage-render-details.test.ts +++ b/ui/src/ui/views/usage-render-details.test.ts @@ -25,7 +25,7 @@ function makePoint(overrides: Partial = {}): TimeSeriesPoint { const baseUsage = { totalTokens: 1000, - totalCost: 1.0, + totalCost: 1, input: 300, output: 400, cacheRead: 200,