From 304e2c83c01f2371554c251646418f2b650afebb Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Sun, 31 May 2026 18:43:54 +0100 Subject: [PATCH] chore(lint): enable stricter oxlint rules --- .../scripts/secret-scanning.mjs | 98 +++-- .oxlintrc.json | 14 +- extensions/acpx/register.runtime.ts | 4 +- extensions/acpx/src/runtime.test.ts | 19 +- extensions/active-memory/index.ts | 8 +- .../mantle-anthropic.runtime.test.ts | 2 +- .../amazon-bedrock/embedding-provider.ts | 12 +- extensions/amazon-bedrock/index.test.ts | 2 +- extensions/arcee/index.ts | 4 +- extensions/bonjour/src/advertiser.ts | 13 +- extensions/browser/src/browser-tool.ts | 14 +- .../src/browser/cdp-proxy-bypass.test.ts | 39 +- .../browser/src/browser/chrome-mcp.test.ts | 6 +- ...-core.screenshots-element-selector.test.ts | 2 +- .../browser/src/browser/routes/agent.debug.ts | 8 +- ...ime-lifecycle.unhandled-rejections.test.ts | 6 +- .../browser/src/browser/server-context.ts | 2 +- extensions/browser/src/browser/vision.test.ts | 26 +- .../browser/src/cli/browser-cli-manage.ts | 12 +- extensions/codex/index.test.ts | 2 +- extensions/codex/provider.test.ts | 6 +- .../codex/src/app-server/compact.test.ts | 2 +- .../src/app-server/dynamic-tools.test.ts | 22 +- .../app-server/run-attempt-test-harness.ts | 12 +- .../run-attempt.context-engine.test.ts | 24 +- .../codex/src/app-server/run-attempt.test.ts | 21 +- .../codex/src/app-server/run-attempt.ts | 41 +- .../codex/src/app-server/test-support.ts | 2 +- extensions/codex/src/app-server/trajectory.ts | 4 +- extensions/codex/src/commands.test.ts | 20 +- extensions/copilot/harness.test.ts | 10 +- extensions/copilot/src/attempt.test.ts | 37 +- extensions/copilot/src/auth-bridge.test.ts | 4 +- extensions/copilot/src/hooks-bridge.test.ts | 2 +- .../copilot/src/telemetry-bridge.test.ts | 4 +- extensions/deepseek/index.test.ts | 2 +- extensions/diffs/src/browser.ts | 6 +- .../diffs/src/tool-render-output.test.ts | 4 +- extensions/diffs/src/tool.test.ts | 56 +-- .../src/actions/handle-action.guild-admin.ts | 4 +- extensions/discord/src/channel.test.ts | 4 +- extensions/discord/src/channel.ts | 8 +- extensions/discord/src/components.builders.ts | 2 +- .../discord/src/internal/command-deploy.ts | 16 +- .../discord/src/internal/gateway.test.ts | 2 +- extensions/discord/src/internal/rest.test.ts | 2 +- .../src/monitor/agent-components-dm-auth.ts | 4 +- extensions/discord/src/monitor/allow-list.ts | 2 +- .../src/monitor/exec-approvals.test.ts | 14 +- .../src/monitor/gateway-plugin.test.ts | 8 +- .../src/monitor/native-command-reply.ts | 6 +- .../src/monitor/provider.lifecycle.test.ts | 10 +- .../src/monitor/provider.proxy.test.ts | 76 ++-- .../src/monitor/provider.rest-proxy.test.ts | 28 +- .../src/monitor/thread-bindings.manager.ts | 37 +- extensions/discord/src/send.permissions.ts | 6 +- extensions/discord/src/targets.test.ts | 42 ++- .../discord/src/voice/manager.e2e.test.ts | 16 +- extensions/discord/src/voice/manager.ts | 6 +- extensions/fal/image-generation-provider.ts | 4 +- extensions/fal/video-generation-provider.ts | 4 +- .../feishu/src/bot.checkBotMentioned.test.ts | 6 +- extensions/feishu/src/bot.test.ts | 7 - extensions/feishu/src/bot.ts | 14 +- extensions/feishu/src/channel.test.ts | 6 +- extensions/feishu/src/docx.test.ts | 2 +- ...acp-init-failure.lifecycle.test-support.ts | 7 +- ...monitor.bot-menu.lifecycle.test-support.ts | 7 +- ...itor.card-action.lifecycle.test-support.ts | 7 +- .../feishu/src/monitor.message-handler.ts | 4 +- extensions/feishu/src/reply-dispatcher.ts | 20 +- extensions/feishu/src/thread-bindings.ts | 14 +- .../feishu/src/tool-account-routing.test.ts | 14 +- .../src/shared/node-invoke-policy.test.ts | 2 - extensions/firecrawl/src/firecrawl-client.ts | 28 +- extensions/github-copilot/index.test.ts | 5 - extensions/google-meet/index.test.ts | 4 +- .../google-meet/src/config-compat.test.ts | 4 +- extensions/google-meet/src/realtime.ts | 11 +- extensions/google/embedding-provider.ts | 4 +- extensions/google/google.live.test.ts | 6 +- .../google/music-generation-provider.test.ts | 11 +- .../google/realtime-voice-provider.test.ts | 20 +- extensions/google/transport-stream.test.ts | 6 +- .../google/video-generation-provider.test.ts | 21 +- extensions/googlechat/src/channel.adapters.ts | 8 +- .../src/google-auth.runtime.test.ts | 16 +- .../googlechat/src/monitor-webhook.test.ts | 6 +- extensions/googlechat/src/monitor.ts | 2 +- extensions/gradium/tts.ts | 4 +- extensions/imessage/src/actions.runtime.ts | 8 +- extensions/imessage/src/approval-reactions.ts | 6 +- .../imessage/src/monitor/catchup.test.ts | 4 +- .../imessage/src/monitor/coalesce.test.ts | 2 +- extensions/imessage/src/send.test.ts | 20 +- extensions/imessage/src/shared.ts | 11 +- extensions/irc/src/inbound.ts | 2 +- extensions/line/src/download.test.ts | 6 +- .../line/src/flex-templates/basic-cards.ts | 6 +- extensions/line/src/rich-menu.test.ts | 11 +- extensions/line/src/send.test.ts | 52 +-- extensions/line/src/setup-surface.test.ts | 11 +- extensions/matrix/src/channel.ts | 4 +- .../matrix/src/matrix/actions/client.test.ts | 10 +- .../src/matrix/client-bootstrap.test.ts | 4 +- .../matrix/monitor/handler.test-helpers.ts | 4 +- .../matrix/src/matrix/monitor/handler.ts | 32 +- .../matrix/src/matrix/monitor/index.test.ts | 2 +- .../matrix/src/matrix/monitor/replies.test.ts | 4 +- .../src/matrix/monitor/room-history.test.ts | 4 +- .../matrix/src/matrix/monitor/status.ts | 12 +- .../src/matrix/monitor/sync-lifecycle.ts | 6 +- extensions/matrix/src/matrix/sdk.test.ts | 14 +- .../matrix/src/matrix/send/client.test.ts | 16 +- .../matrix/src/matrix/send/targets.test.ts | 18 +- extensions/matrix/src/outbound.test.ts | 2 +- .../src/mattermost/monitor-resources.ts | 8 +- .../monitor.inbound-system-event.test.ts | 5 +- .../mattermost/src/mattermost/monitor.ts | 70 ++-- .../memory/manager.readonly-recovery.test.ts | 7 - extensions/memory-core/src/memory/manager.ts | 4 +- .../src/memory/manager.watcher-config.test.ts | 8 +- .../memory-core/src/memory/qmd-manager.ts | 47 +-- .../src/memory/search-manager.test.ts | 2 +- .../memory-core/src/short-term-promotion.ts | 4 +- extensions/memory-lancedb/config.ts | 6 +- extensions/memory-lancedb/index.test.ts | 30 +- .../memory-wiki/src/config-compat.test.ts | 4 +- extensions/migrate-hermes/auth.ts | 6 +- extensions/moonshot/moonshot.live.test.ts | 2 +- extensions/msteams/src/attachments.test.ts | 5 - .../src/monitor-handler.file-consent.test.ts | 12 - extensions/msteams/src/outbound.test.ts | 20 +- extensions/msteams/src/outbound.ts | 4 +- extensions/msteams/src/sdk.test.ts | 4 +- extensions/msteams/src/send.test.ts | 9 - extensions/nextcloud-talk/src/core.test.ts | 10 +- extensions/nextcloud-talk/src/inbound.ts | 4 +- extensions/nostr/src/nostr-bus.ts | 8 +- extensions/oc-path/src/oc-path/oc-path.ts | 4 +- .../src/oc-path/tests/jsonl/resolve.test.ts | 8 +- .../scenarios/roundtrip-property.test.ts | 3 +- extensions/ollama/src/embedding-provider.ts | 11 +- extensions/openai/embedding-provider.ts | 7 +- extensions/openai/index.test.ts | 13 +- .../openai/openai-provider.live.test.ts | 1 - extensions/openai/openai.live.test.ts | 1 - extensions/openai/tts.ts | 4 +- extensions/opencode-go/index.ts | 6 +- extensions/openrouter/index.ts | 4 +- .../openshell/src/openshell-core.test.ts | 6 +- extensions/policy/src/doctor/register.ts | 16 +- extensions/qa-channel/src/bus-client.test.ts | 4 +- extensions/qa-lab/src/bus-server.test.ts | 2 +- extensions/qa-lab/src/cli.test.ts | 2 +- extensions/qa-lab/src/lab-server.ts | 4 +- .../discord/discord-live.runtime.test.ts | 4 +- extensions/qa-lab/src/qa-gateway-config.ts | 4 +- extensions/qa-lab/src/qa-transport.ts | 4 +- extensions/qa-lab/src/scenario-catalog.ts | 4 +- extensions/qa-lab/src/temp-dir.test-helper.ts | 4 +- extensions/qa-lab/web/src/ui-render.ts | 28 +- extensions/qa-matrix/src/cli.runtime.test.ts | 8 +- .../qa-matrix/src/runners/contract/runtime.ts | 4 +- .../src/runners/contract/scenarios.test.ts | 24 +- .../shared/live-transport-cli.runtime.test.ts | 16 +- .../qa-matrix/src/substrate/e2ee-client.ts | 4 +- .../src/engine/api/media-chunked.test.ts | 10 +- extensions/qqbot/src/engine/api/media.test.ts | 42 +-- .../commands/builtin/log-helpers.test.ts | 8 +- extensions/slack/src/action-runtime.test.ts | 2 +- extensions/slack/src/blocks-render.ts | 6 +- extensions/slack/src/channel.ts | 8 +- .../slack/src/monitor/events/channels.ts | 16 +- .../slack/src/monitor/events/members.ts | 21 +- extensions/slack/src/monitor/media.test.ts | 12 +- .../message-handler.app-mention-race.test.ts | 4 +- .../dispatch.preview-fallback.test.ts | 11 - .../src/monitor/message-handler/dispatch.ts | 4 +- extensions/slack/src/streaming.test.ts | 2 +- extensions/sms/src/send.ts | 4 +- extensions/synology-chat/src/client.test.ts | 4 +- .../telegram/src/bot-handlers.runtime.ts | 18 +- .../src/bot-message-context.session.ts | 8 +- .../telegram/src/bot-message-dispatch.test.ts | 6 +- .../telegram/src/bot-message-dispatch.ts | 6 +- ...t-native-commands.skills-allowlist.test.ts | 4 +- .../src/bot.create-telegram-bot.test.ts | 8 +- ...dia-file-path-no-file-download.e2e.test.ts | 4 +- ...t.media.stickers-and-fragments.e2e.test.ts | 14 - extensions/telegram/src/bot.test.ts | 2 +- .../telegram/src/channel.gateway.test.ts | 13 - extensions/telegram/src/channel.ts | 4 +- extensions/telegram/src/message-cache.ts | 8 +- .../telegram/src/message-dispatch-dedupe.ts | 52 +-- extensions/telegram/src/outbound-adapter.ts | 4 +- .../telegram/src/polling-session.test.ts | 3 +- extensions/telegram/src/send.proxy.test.ts | 2 +- extensions/telegram/src/send.ts | 6 +- extensions/telegram/src/thread-bindings.ts | 6 +- extensions/telegram/src/webhook.test.ts | 2 +- extensions/tlon/src/security.test.ts | 3 - extensions/tokenjuice/index.test.ts | 8 +- extensions/twitch/src/send.test.ts | 4 +- extensions/twitch/src/twitch-client.test.ts | 3 +- extensions/voice-call/index.test.ts | 26 +- .../voice-call/src/media-stream.test.ts | 10 +- extensions/voice-call/src/webhook.test.ts | 14 +- .../src/webhook/realtime-handler.ts | 4 +- extensions/voyage/embedding-provider.ts | 6 +- extensions/whatsapp/login-qr-runtime.ts | 8 +- extensions/whatsapp/src/auto-reply/monitor.ts | 4 +- .../monitor/inbound-dispatch.test.ts | 10 +- .../src/connection-controller.test.ts | 12 +- extensions/whatsapp/src/inbound/monitor.ts | 16 +- extensions/whatsapp/src/login-qr.test.ts | 20 +- .../whatsapp/src/login.coverage.test.ts | 15 +- extensions/whatsapp/src/media.test.ts | 2 - extensions/whatsapp/src/qa-driver.runtime.ts | 8 +- extensions/whatsapp/src/runtime-api.ts | 4 +- extensions/whatsapp/src/shared.ts | 4 +- extensions/workboard/src/store.ts | 4 +- extensions/xai/tts.ts | 3 +- extensions/xiaomi/index.test.ts | 2 +- extensions/zai/index.test.ts | 2 +- extensions/zalo/src/api.test.ts | 2 +- extensions/zalo/src/monitor.ts | 8 +- .../zalouser/src/monitor.group-gating.test.ts | 44 +-- extensions/zalouser/src/zalo-js.ts | 6 +- packages/agent-core/src/harness/env/nodejs.ts | 8 +- .../src/host/embeddings.test.ts | 6 +- .../memory-host-sdk/src/host/embeddings.ts | 14 +- packages/sdk/src/index.test.ts | 2 +- packages/terminal-core/src/table.ts | 18 +- scripts/check-codex-app-server-protocol.ts | 10 +- scripts/control-ui-i18n.ts | 7 +- scripts/crabbox-wrapper.mjs | 44 +-- .../dev/discord-acp-plain-language-smoke.ts | 6 +- scripts/dev/realtime-talk-live-smoke.ts | 4 +- scripts/docker-e2e-rerun.mjs | 14 +- .../lib/codex-npm-plugin-live/assertions.mjs | 4 +- .../docker-stats/assert-resource-ceiling.mjs | 4 +- .../lib/kitchen-sink-plugin/assertions.mjs | 4 +- scripts/e2e/mcp-channels-docker-client.ts | 8 +- scripts/e2e/parallels/smoke-common.ts | 2 +- .../session-runtime-context-docker-client.ts | 4 +- scripts/e2e/telegram-user-credential.ts | 24 +- scripts/generate-kysely-types.mjs | 4 +- scripts/generate-npm-shrinkwrap.mjs | 5 - scripts/github/real-behavior-proof-policy.mjs | 8 +- scripts/kova-ci-summary.mjs | 26 +- scripts/lib/config-boundary-guard.mjs | 48 +-- scripts/lib/mintlify-accordion.mjs | 8 +- scripts/perf/issue-78851-model-resolution.ts | 4 +- scripts/qa-otel-smoke.ts | 4 +- scripts/release-candidate-checklist.mjs | 26 +- scripts/release-preflight.mjs | 12 +- scripts/sync-labels.ts | 4 +- scripts/update-clawtributors.ts | 80 ++-- src/acp/event-mapper.test.ts | 2 +- src/acp/server.startup.test.ts | 2 +- src/acp/translator.cancel-scoping.test.ts | 2 +- .../agent-command.live-model-switch.test.ts | 7 +- src/agents/agent-command.ts | 18 +- .../agent-hooks/compaction-safeguard.test.ts | 2 +- .../agent-hooks/compaction-safeguard.ts | 16 +- .../agent-hooks/context-pruning.test.ts | 2 +- src/agents/anthropic.setup-token.live.test.ts | 2 +- src/agents/apply-patch.ts | 2 +- .../auth-profiles/oauth-manager.test.ts | 1 - src/agents/auth-profiles/session-override.ts | 4 +- src/agents/auth-profiles/usage.ts | 12 +- src/agents/bash-tools.exec-runtime.test.ts | 6 +- src/agents/bash-tools.exec.ts | 32 +- src/agents/bash-tools.process.ts | 4 +- src/agents/code-mode.ts | 6 +- src/agents/codex-mcp-config.ts | 8 +- .../command/attempt-execution.cli.test.ts | 2 +- src/agents/command/session-store.test.ts | 14 +- src/agents/command/session-store.ts | 3 +- src/agents/compaction-planning-worker.ts | 30 +- .../embedded-agent-runner/compact.runtime.ts | 5 +- .../context-engine-maintenance.test.ts | 8 +- .../embedded-agent-runner/extensions.test.ts | 2 +- .../resource-loader.test.ts | 2 +- .../run.codex-app-server-recovery.test.ts | 4 +- .../run.compaction-loop-guard.test.ts | 8 +- .../run.overflow-compaction.loop.test.ts | 3 +- src/agents/embedded-agent-runner/run.ts | 12 +- .../attempt.memory-flush-forwarding.test.ts | 2 +- .../run/attempt.prompt-helpers.ts | 4 +- .../run/attempt.session-lock.test.ts | 216 +++++------ .../attempt.spawn-workspace.test-support.ts | 2 +- .../embedded-agent-runner/run/attempt.test.ts | 15 +- .../attempt.tool-call-argument-repair.test.ts | 6 +- .../run/auth-controller.test.ts | 2 +- .../transcript-file-state.ts | 6 +- ...-agent-subscribe.handlers.messages.test.ts | 4 +- ...edded-agent-subscribe.handlers.messages.ts | 12 +- src/agents/embedded-agent-subscribe.ts | 88 ++--- src/agents/harness/native-hook-relay.ts | 4 +- src/agents/harness/selection.test.ts | 4 +- src/agents/harness/v2.test.ts | 6 +- .../media-generation-task-status-shared.ts | 4 +- src/agents/model-auth.profiles.test.ts | 2 +- src/agents/model-catalog-browse.test.ts | 2 +- src/agents/model-catalog.test.ts | 14 +- src/agents/model-fallback.test.ts | 4 +- src/agents/modes/interactive/theme/theme.ts | 10 +- .../openai-reasoning-compat.live.test.ts | 2 +- src/agents/openai-transport-stream.test.ts | 127 ++++--- .../outcome-fallback-runtime-contract.test.ts | 9 +- src/agents/provider-http-errors.ts | 3 +- src/agents/provider-local-service.ts | 6 +- src/agents/session-file-repair.test.ts | 6 +- src/agents/session-write-lock.ts | 8 +- src/agents/sessions/extensions/loader.ts | 6 +- src/agents/sessions/sdk.test.ts | 2 +- src/agents/sessions/sdk.ts | 28 +- src/agents/sessions/tools/bash.ts | 14 +- src/agents/sessions/tools/edit.ts | 6 +- src/agents/sessions/tools/find.ts | 8 +- src/agents/sessions/tools/grep.ts | 8 +- src/agents/sessions/tools/ls.ts | 4 +- src/agents/sessions/tools/read.ts | 4 +- src/agents/sessions/tools/write.ts | 4 +- src/agents/simple-completion-runtime.test.ts | 2 +- src/agents/subagent-announce-delivery.test.ts | 12 - .../subagent-announce.format.e2e.test.ts | 6 +- .../subagent-registry.steer-restart.test.ts | 2 +- src/agents/tool-call-id.test.ts | 3 +- src/agents/tool-replay-repair.live.test.ts | 4 +- src/agents/tool-search.ts | 4 +- src/agents/tools-effective-inventory.test.ts | 353 ++++++++++-------- .../tools/image-generate-background.test.ts | 19 - src/agents/tools/image-tool.test.ts | 10 +- .../media-generate-background.test-support.ts | 28 +- src/agents/tools/video-generate-tool.test.ts | 2 +- src/agents/tools/web-guarded-fetch.test.ts | 8 +- .../tools/web-tool-runtime-context.test.ts | 5 +- src/agents/workspace-run.test.ts | 1 - src/auto-reply/commands-registry.test.ts | 4 +- src/auto-reply/commands-registry.ts | 2 +- src/auto-reply/dispatch.test.ts | 10 +- src/auto-reply/media-note.ts | 12 +- .../reply/agent-runner-execution.ts | 4 +- src/auto-reply/reply/agent-runner.ts | 2 +- .../reply/commands-export-session.test.ts | 2 +- .../reply/commands-info.tools.test.ts | 85 +++-- src/auto-reply/reply/dispatch-acp.test.ts | 8 +- .../reply/dispatch-from-config.test.ts | 4 +- .../export-html/template.security.test.ts | 2 +- src/auto-reply/reply/followup-runner.ts | 4 +- src/auto-reply/reply/get-reply.ts | 7 +- src/auto-reply/reply/inbound-meta.ts | 4 +- .../reply/model-selection-directive.ts | 10 +- src/auto-reply/reply/model-selection.test.ts | 74 ++-- src/auto-reply/reply/session.ts | 4 +- .../message-access/message-access.test.ts | 22 +- .../channel-import-guardrails.test.ts | 4 +- src/channels/plugins/session-conversation.ts | 6 +- .../plugins/setup-wizard-helpers.test.ts | 6 +- src/channels/status-reactions.test.ts | 15 - src/cli/capability-cli.test.ts | 16 +- src/cli/command-path-policy.test.ts | 22 +- src/cli/config-cli.test.ts | 2 +- src/cli/logs-cli.test.ts | 2 +- src/cli/nodes-cli/register.status.ts | 7 +- src/cli/plugins-cli-test-helpers.ts | 24 +- src/cli/program.test-mocks.ts | 6 +- src/cli/program/message/helpers.test.ts | 2 +- src/cli/program/preaction.test.ts | 37 +- src/cli/program/register.transcripts.ts | 14 +- src/cli/program/root-help.test.ts | 2 +- src/cli/proxy-cli.runtime.test.ts | 24 +- src/cli/skills-cli.commands.test.ts | 6 +- src/cli/update-cli.test.ts | 8 - src/cli/update-cli/update-command.ts | 6 +- src/commands/agent-via-gateway.test.ts | 12 +- src/commands/auth-choice.test.ts | 6 +- src/commands/backup.test.ts | 2 +- src/commands/channels.add.test.ts | 6 +- src/commands/channels/add.ts | 20 +- src/commands/configure.daemon.test.ts | 2 +- src/commands/doctor-auth-profile-config.ts | 6 +- src/commands/doctor-completion.ts | 6 +- src/commands/doctor-config-analysis.ts | 8 +- src/commands/doctor-config-flow.test.ts | 13 +- src/commands/doctor-config-flow.ts | 2 +- src/commands/doctor-gateway-health.ts | 4 +- src/commands/doctor-memory-search.test.ts | 9 +- ...te-migrations-yes-mode-without.e2e.test.ts | 28 +- .../cron/dreaming-payload-migration.test.ts | 2 +- .../active-tool-schema-warnings.test.ts | 4 +- .../shared/codex-route-warnings.test.ts | 2 +- .../shared/plugin-registry-migration.test.ts | 9 - .../shared/plugin-tool-allowlist-warnings.ts | 5 +- src/commands/health-format.ts | 2 +- src/commands/migrate.test.ts | 4 +- src/commands/migrate.ts | 4 +- src/commands/models/aliases.ts | 10 +- src/commands/models/list.list-command.ts | 6 +- src/commands/models/list.status-command.ts | 16 +- src/commands/onboard-auth.test.ts | 14 +- .../local/auth-choice.ts | 25 +- .../local/daemon-install.test.ts | 2 +- src/commands/sandbox-explain.ts | 4 +- src/commands/status.scan-overview.ts | 16 +- src/commands/status.test.ts | 16 +- src/config/doc-baseline.ts | 14 +- src/config/io.ts | 50 +-- src/config/io.write-prepare.test.ts | 2 +- src/config/mcp-config.test.ts | 16 +- .../store.pruning.integration.test.ts | 8 +- .../validation.channel-metadata.test.ts | 2 +- src/config/validation.ts | 90 ++--- src/crestodian/operations.test.ts | 4 +- .../isolated-agent.session-identity.test.ts | 2 +- .../run.payload-fallbacks.test.ts | 15 - src/cron/service.issue-regressions.test.ts | 1 - src/cron/service.jobs.test.ts | 1 - src/cron/service/store.test.ts | 13 - src/cron/store.test.ts | 1 - src/cron/store.ts | 8 +- src/daemon/service-audit.test.ts | 4 +- src/docker-setup.e2e.test.ts | 6 +- src/flows/doctor-core-checks.test.ts | 2 +- src/flows/doctor-core-checks.ts | 4 +- src/flows/doctor-lint-flow.test.ts | 4 +- src/flows/doctor-repair-flow.test.ts | 34 +- src/gateway/client-start-readiness.test.ts | 6 +- src/gateway/client.test.ts | 31 +- src/gateway/connection-auth.test.ts | 22 +- src/gateway/control-ui.http.test.ts | 2 +- ...drain-active-sessions-for-shutdown.test.ts | 2 +- src/gateway/http-endpoint-helpers.test.ts | 8 +- ...server-channels.approval-bootstrap.test.ts | 4 +- src/gateway/server-channels.test.ts | 18 +- src/gateway/server-channels.ts | 12 +- src/gateway/server-chat.agent-events.test.ts | 42 +-- src/gateway/server-close.test.ts | 2 +- src/gateway/server-cron-lazy.test.ts | 16 +- src/gateway/server-cron.ts | 38 +- src/gateway/server-http.ts | 36 +- .../server-methods/agent-wait-dedupe.ts | 4 +- src/gateway/server-methods/agent.test.ts | 4 +- src/gateway/server-methods/agent.ts | 37 +- .../server-methods/agents-mutate.test.ts | 16 - src/gateway/server-methods/artifacts.ts | 2 +- src/gateway/server-methods/channels.ts | 4 +- src/gateway/server-methods/chat.ts | 45 +-- src/gateway/server-methods/commands.test.ts | 2 +- src/gateway/server-methods/doctor.ts | 6 +- src/gateway/server-methods/exec-approval.ts | 10 +- src/gateway/server-methods/plugin-approval.ts | 10 +- .../server-methods/server-methods.test.ts | 10 +- src/gateway/server-methods/sessions.ts | 2 +- .../server-methods/skills-upload.test.ts | 6 +- src/gateway/server-model-catalog.ts | 5 +- src/gateway/server-reload-handlers.ts | 8 +- .../server-startup-config.secrets.test.ts | 4 +- .../server-startup-post-attach.test.ts | 46 +-- src/gateway/server-startup-post-attach.ts | 4 +- ...erver.agent.gateway-server-agent-b.test.ts | 16 +- ...server.agent.gateway-server-agent.mocks.ts | 9 +- .../server.chat.gateway-server-chat.test.ts | 14 +- src/gateway/server.config-patch.test.ts | 16 +- src/gateway/server.cron.test.ts | 6 +- src/gateway/server.hooks.test.ts | 4 +- src/gateway/server.impl.ts | 33 +- src/gateway/server/event-loop-health.test.ts | 2 +- src/gateway/server/http-listen.test.ts | 2 +- .../server/ws-connection/message-handler.ts | 22 +- src/gateway/session-utils.fs.ts | 2 +- src/gateway/sessions-history-http.test.ts | 2 +- src/gateway/sessions-history-http.ts | 8 +- src/hooks/gmail.ts | 4 +- .../approval-native-route-coordinator.ts | 10 +- src/infra/approval-native-runtime.ts | 20 +- src/infra/backoff.test.ts | 2 +- src/infra/bonjour-discovery.ts | 4 +- src/infra/exec-approval-forwarder.test.ts | 6 +- src/infra/fetch.test.ts | 2 +- src/infra/git-commit.test.ts | 32 +- .../heartbeat-runner.commitments.test.ts | 30 +- src/infra/install-package-dir.ts | 6 +- src/infra/json-files.test.ts | 1 - src/infra/net/proxy-fetch.test.ts | 38 +- src/infra/net/proxy/proxy-lifecycle.test.ts | 16 +- .../net/undici-global-dispatcher.test.ts | 69 ++-- src/infra/npm-managed-root.ts | 14 +- .../account-scoped-conversation-bindings.ts | 8 +- src/infra/outbound/envelope.test.ts | 4 +- ...sage-action-runner.plugin-dispatch.test.ts | 24 +- src/infra/outbound/targets-loaded.test.ts | 4 +- src/infra/path-prepend.test.ts | 51 ++- src/infra/push-apns-http2.test.ts | 28 +- src/infra/run-node.test.ts | 2 +- src/infra/session-cost-usage.ts | 10 +- src/infra/sqlite-wal.test.ts | 16 +- src/infra/ssh-config.test.ts | 4 +- src/infra/state-migrations.ts | 4 +- src/infra/update-runner.ts | 10 +- src/llm/providers/anthropic.ts | 16 +- src/llm/providers/google-vertex.ts | 4 +- src/llm/providers/google.ts | 4 +- src/llm/providers/openai-chatgpt-responses.ts | 2 +- src/logger.test.ts | 10 +- src/logging/console-settings.test.ts | 20 +- src/logging/diagnostic.test.ts | 13 +- .../apply.echo-transcript.test.ts | 4 +- src/media/fetch.ts | 4 +- src/media/qr-image.test.ts | 10 +- src/media/store.test.ts | 199 +++++----- src/media/store.ts | 2 +- src/music-generation/provider-assets.ts | 4 +- src/node-host/invoke-system-run-plan.test.ts | 12 +- src/node-host/invoke-system-run.test.ts | 8 +- src/node-host/invoke.ts | 6 +- src/plugin-sdk/allowlist-config-edit.test.ts | 12 +- src/plugin-sdk/file-lock.test.ts | 1 - src/plugin-sdk/pair-loop-guard-runtime.ts | 23 +- src/plugin-sdk/persistent-dedupe.ts | 12 +- src/plugin-sdk/provider-auth-runtime.ts | 9 +- .../qa-runner-runtime.integration.test.ts | 2 +- src/plugin-sdk/reply-payload.ts | 4 +- src/plugin-sdk/session-transcript-hit.ts | 6 +- .../test-helpers/provider-contract.ts | 4 +- .../web-search-provider-contract.ts | 8 +- .../plugin-state-store.e2e.test.ts | 1 - src/plugin-state/plugin-state-store.test.ts | 1 - src/plugins/bundle-manifest.test.ts | 2 +- .../capability-provider-runtime.test.ts | 10 +- src/plugins/channel-plugin-ids.test.ts | 3 +- src/plugins/cli.test.ts | 4 +- src/plugins/git-install.test.ts | 5 - src/plugins/hook-lifecycle-gates.test.ts | 4 +- src/plugins/hooks.before-agent-start.test.ts | 6 +- .../hooks.model-override-wiring.test.ts | 2 +- src/plugins/hooks.ts | 12 +- src/plugins/install.npm-spec.test.ts | 8 +- src/plugins/manifest.ts | 22 +- src/plugins/marketplace.ts | 24 +- ...enai-compatible-embedding-provider.test.ts | 2 +- .../provider-auth-choice-helpers.test.ts | 4 +- src/plugins/providers.test.ts | 29 -- src/plugins/registry.ts | 12 +- src/plugins/runtime.test.ts | 4 +- src/plugins/sdk-alias.test.ts | 3 +- src/process/exec.ts | 18 +- src/process/exec.windows.test.ts | 12 +- src/process/supervisor/adapters/child.test.ts | 8 +- src/secrets/apply.ts | 4 +- .../runtime-external-channel-audit.test.ts | 8 +- ...it-channel-readonly-setup-fallback.test.ts | 2 +- src/security/audit-gateway-config.ts | 4 +- src/security/audit-gateway-exposure.test.ts | 2 +- src/sessions/user-turn-transcript.ts | 6 +- src/shared/config-eval.test.ts | 4 +- src/shared/json-schema-defaults.ts | 8 +- src/shared/pid-alive.test.ts | 4 +- src/skills/discovery/skill-index.test.ts | 6 +- src/skills/discovery/status.test.ts | 4 +- src/skills/lifecycle/install-download.test.ts | 5 +- src/skills/loading/workspace-load.test.ts | 14 +- src/talk/session-runtime.test.ts | 8 +- src/tasks/task-flow-registry.store.test.ts | 1 - src/tasks/task-registry.store.test.ts | 1 - src/tools/availability.ts | 4 +- src/tts/directives.ts | 6 +- src/tui/tui-event-handlers.ts | 4 +- src/tui/tui-local-shell.ts | 4 +- src/web-fetch/runtime.ts | 4 +- src/web-search/runtime.ts | 18 +- src/wizard/setup.finalize.ts | 6 +- src/wizard/setup.gateway-config.test.ts | 4 +- src/wizard/setup.ts | 4 +- .../agents/happy-path-prompt-snapshots.ts | 4 +- test/helpers/gateway-e2e-harness.ts | 2 +- ...android-node-capabilities-policy-config.ts | 2 +- test/helpers/live-image-probe.ts | 2 +- test/helpers/plugins/plugin-sdk-stub.cjs | 4 +- test/package-manager-config.test.ts | 2 +- test/proof/thinking-signature-real-proof.ts | 20 +- test/release-check.test.ts | 14 - test/scripts/docker-build-helper.test.ts | 2 +- test/scripts/kitchen-sink-rpc-walk.test.ts | 2 +- .../mantis-publish-pr-evidence.test.ts | 2 +- ...enai-web-search-minimal-assertions.test.ts | 2 +- test/scripts/oxlint-config.test.ts | 8 - .../package-acceptance-workflow.test.ts | 3 +- test/scripts/parallels-smoke-model.test.ts | 2 +- .../postinstall-bundled-plugins.test.ts | 8 - .../release-user-journey-assertions.test.ts | 54 +-- test/scripts/test-extension.test.ts | 14 +- test/scripts/test-live-shard.test.ts | 2 +- test/vitest-scoped-config.test.ts | 10 - test/vitest/vitest.scoped-config.ts | 11 +- tsdown.config.ts | 2 +- ui/src/ui/app-render.ts | 47 +-- ui/src/ui/chat/message-extract.ts | 2 +- ui/src/ui/chat/realtime-talk-google-live.ts | 2 +- ui/src/ui/chat/session-controls.ts | 6 +- ui/src/ui/chat/slash-commands.node.test.ts | 2 +- ui/src/ui/controllers/channels.test.ts | 4 +- ui/src/ui/custom-theme.test.ts | 4 +- ui/src/ui/icons.ts | 4 +- ui/src/ui/markdown.test.ts | 4 +- ui/src/ui/markdown.ts | 4 +- ui/src/ui/navigation.browser.test.ts | 2 +- ui/src/ui/realtime-talk-gateway-relay.test.ts | 40 +- ui/src/ui/realtime-talk-google-live.test.ts | 20 +- ui/src/ui/views/config.browser.test.ts | 4 +- ui/src/ui/views/usage-metrics.ts | 6 +- ui/src/ui/views/usage-render-details.ts | 8 +- 615 files changed, 3603 insertions(+), 3701 deletions(-) diff --git a/.agents/skills/openclaw-secret-scanning-maintainer/scripts/secret-scanning.mjs b/.agents/skills/openclaw-secret-scanning-maintainer/scripts/secret-scanning.mjs index 28fcb653f01..2dab21dbfd8 100644 --- a/.agents/skills/openclaw-secret-scanning-maintainer/scripts/secret-scanning.mjs +++ b/.agents/skills/openclaw-secret-scanning-maintainer/scripts/secret-scanning.mjs @@ -2,7 +2,7 @@ // Secret scanning alert handler for OpenClaw maintainers. // Usage: node secret-scanning.mjs [options] -import { execFileSync, spawnSync } from "node:child_process"; +import { spawnSync } from "node:child_process"; import crypto from "node:crypto"; import fs from "node:fs"; import os from "node:os"; @@ -39,7 +39,9 @@ function gh(args, { json = true, allowFailure = false } = {}) { stderr: proc.stderr, }; } - if (!json) return proc.stdout; + if (!json) { + return proc.stdout; + } try { return JSON.parse(proc.stdout); } catch { @@ -70,7 +72,9 @@ export function loadBodyRedactionResult(locationType, resultFile) { if (!resultFile) { fail("Body notifications require a redaction result file from redact-body-if-needed"); } - if (!fs.existsSync(resultFile)) fail(`File not found: ${resultFile}`); + if (!fs.existsSync(resultFile)) { + fail(`File not found: ${resultFile}`); + } const result = JSON.parse(fs.readFileSync(resultFile, "utf8")); if (typeof result.notify_required !== "boolean") { @@ -182,10 +186,11 @@ function fetchDiscussionComment(discussionNumber, discussionCommentDbId) { failOnGraphQLFailure(gql, `Failed to fetch discussion #${discussionNumber}`); const discussion = gql?.data?.repository?.discussion; - if (!discussion) + if (!discussion) { fail( `Discussion #${discussionNumber} not found — it may have been deleted. The alert cannot be processed via this skill.`, ); + } discussionId = discussion.id; @@ -205,15 +210,18 @@ function fetchDiscussionComment(discussionNumber, discussionCommentDbId) { `Failed to fetch replies for discussion comment ${topLevelComment.id}`, ); const replies = replyPage?.data?.node?.replies; - if (!replies) + if (!replies) { fail(`Failed to paginate replies for discussion comment ${topLevelComment.id}`); + } reply = findDiscussionCommentNode(replies.nodes, discussionCommentDbId); hasMoreReplies = replies.pageInfo.hasNextPage; replyCursor = replies.pageInfo.endCursor; } - if (reply) return { discussionId, comment: reply }; + if (reply) { + return { discussionId, comment: reply }; + } } hasNextPage = discussion.comments.pageInfo.hasNextPage; @@ -241,7 +249,9 @@ function createDiscussionComment(discussionNodeId, body, replyToNodeId) { * Fetch alert metadata + locations. Never exposes .secret. */ function cmdFetchAlert(alertNumber) { - if (!alertNumber) fail("Usage: fetch-alert "); + if (!alertNumber) { + fail("Usage: fetch-alert "); + } const alert = gh(["api", `repos/${REPO}/secret-scanning/alerts/${alertNumber}?hide_secret=true`]); @@ -280,17 +290,23 @@ function cmdFetchAlert(alertNumber) { * Saves full body to a temp file. Prints metadata + file path to stdout. */ function cmdFetchContent(locationJson) { - if (!locationJson) fail("Usage: fetch-content ''"); + if (!locationJson) { + fail("Usage: fetch-content ''"); + } const location = JSON.parse(locationJson); const type = location.type; const details = location.details; if (type === "discussion_comment") { const commentUrl = details.discussion_comment_url; - if (!commentUrl) fail("No discussion_comment_url in location details"); + if (!commentUrl) { + fail("No discussion_comment_url in location details"); + } const urlMatch = commentUrl.match(/discussions\/(\d+)#discussioncomment-(\d+)/); - if (!urlMatch) fail(`Cannot parse discussion comment URL: ${commentUrl}`); + if (!urlMatch) { + fail(`Cannot parse discussion comment URL: ${commentUrl}`); + } const discussionNumber = urlMatch[1]; const discussionCommentDbId = urlMatch[2]; @@ -298,10 +314,11 @@ function cmdFetchContent(locationJson) { discussionNumber, discussionCommentDbId, ); - if (!comment) + if (!comment) { fail( `Discussion comment #${discussionCommentDbId} not found in discussion #${discussionNumber}`, ); + } const bodyFile = tmpFile("body.md"); fs.writeFileSync(bodyFile, comment.body || ""); @@ -334,7 +351,9 @@ function cmdFetchContent(locationJson) { details.issue_comment_url || details.pull_request_comment_url || details.pull_request_review_comment_url; - if (!commentUrl) fail(`No comment URL in location details`); + if (!commentUrl) { + fail(`No comment URL in location details`); + } const comment = gh(["api", commentUrl]); const bodyFile = tmpFile("body.md"); @@ -378,7 +397,9 @@ function cmdFetchContent(locationJson) { ); } else if (type === "issue_body") { const issueUrl = details.issue_body_url || details.issue_url; - if (!issueUrl) fail("No issue URL in location details"); + if (!issueUrl) { + fail("No issue URL in location details"); + } const issue = gh(["api", issueUrl]); const bodyFile = tmpFile("body.md"); @@ -414,7 +435,9 @@ function cmdFetchContent(locationJson) { ); } else if (type === "pull_request_body") { const prUrl = details.pull_request_body_url || details.pull_request_url; - if (!prUrl) fail("No PR URL in location details"); + if (!prUrl) { + fail("No PR URL in location details"); + } const pr = gh(["api", prUrl]); const bodyFile = tmpFile("body.md"); @@ -490,7 +513,9 @@ function cmdRedactBody(kind, number, bodyFile) { if (!kind || !number || !bodyFile) { fail("Usage: redact-body "); } - if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`); + if (!fs.existsSync(bodyFile)) { + fail(`File not found: ${bodyFile}`); + } const endpoint = kind === "pr" ? `repos/${REPO}/pulls/${number}` : `repos/${REPO}/issues/${number}`; @@ -509,8 +534,12 @@ function cmdRedactBodyIfNeeded(kind, number, currentBodyFile, redactedBodyFile, "Usage: redact-body-if-needed ", ); } - if (!fs.existsSync(currentBodyFile)) fail(`File not found: ${currentBodyFile}`); - if (!fs.existsSync(redactedBodyFile)) fail(`File not found: ${redactedBodyFile}`); + if (!fs.existsSync(currentBodyFile)) { + fail(`File not found: ${currentBodyFile}`); + } + if (!fs.existsSync(redactedBodyFile)) { + fail(`File not found: ${redactedBodyFile}`); + } const currentBody = fs.readFileSync(currentBodyFile, "utf8"); const redactedBody = fs.readFileSync(redactedBodyFile, "utf8"); @@ -541,7 +570,9 @@ function cmdRedactBodyIfNeeded(kind, number, currentBodyFile, redactedBodyFile, * Delete a comment (and all its edit history). */ function cmdDeleteComment(commentId) { - if (!commentId) fail("Usage: delete-comment "); + if (!commentId) { + fail("Usage: delete-comment "); + } gh(["api", `repos/${REPO}/issues/comments/${commentId}`, "-X", "DELETE"], { json: false }); console.log(JSON.stringify({ ok: true, deleted_comment_id: Number(commentId) })); } @@ -551,7 +582,9 @@ function cmdDeleteComment(commentId) { * Delete a discussion comment via GraphQL (and all its edit history). */ function cmdDeleteDiscussionComment(nodeId) { - if (!nodeId) fail("Usage: delete-discussion-comment "); + if (!nodeId) { + fail("Usage: delete-discussion-comment "); + } const result = ghGraphQL( `mutation { deleteDiscussionComment(input: { id: "${nodeId}" }) { comment { id } } }`, ); @@ -566,9 +599,12 @@ function cmdDeleteDiscussionComment(nodeId) { * Create a new discussion comment via GraphQL. */ function cmdRecreateDiscussionComment(discussionNodeId, bodyFile, replyToNodeId) { - if (!discussionNodeId || !bodyFile) + if (!discussionNodeId || !bodyFile) { fail("Usage: recreate-discussion-comment [reply-to-node-id]"); - if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`); + } + if (!fs.existsSync(bodyFile)) { + fail(`File not found: ${bodyFile}`); + } const body = fs.readFileSync(bodyFile, "utf8"); const newComment = createDiscussionComment(discussionNodeId, body, replyToNodeId); @@ -586,8 +622,12 @@ function cmdRecreateDiscussionComment(discussionNodeId, bodyFile, replyToNodeId) * Create a new comment from a file. */ function cmdRecreateComment(issueNumber, bodyFile) { - if (!issueNumber || !bodyFile) fail("Usage: recreate-comment "); - if (!fs.existsSync(bodyFile)) fail(`File not found: ${bodyFile}`); + if (!issueNumber || !bodyFile) { + fail("Usage: recreate-comment "); + } + if (!fs.existsSync(bodyFile)) { + fail(`File not found: ${bodyFile}`); + } const result = gh([ "api", @@ -715,7 +755,9 @@ function cmdNotify(target, author, locationType, secretTypes, replyToNodeId) { * Close a secret scanning alert. */ function cmdResolve(alertNumber, resolution, comment) { - if (!alertNumber) fail("Usage: resolve [resolution] [comment]"); + if (!alertNumber) { + fail("Usage: resolve [resolution] [comment]"); + } const res = resolution || "revoked"; const resComment = comment || "Content redacted and author notified to rotate credentials."; @@ -773,8 +815,12 @@ function cmdListOpen() { * Print a formatted summary table from a JSON results file. */ function cmdSummary(jsonFile) { - if (!jsonFile) fail("Usage: summary "); - if (!fs.existsSync(jsonFile)) fail(`File not found: ${jsonFile}`); + if (!jsonFile) { + fail("Usage: summary "); + } + if (!fs.existsSync(jsonFile)) { + fail(`File not found: ${jsonFile}`); + } const results = JSON.parse(fs.readFileSync(jsonFile, "utf8")); const lines = []; diff --git a/.oxlintrc.json b/.oxlintrc.json index 058beaa0cb4..a9f57f0ed95 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -26,7 +26,7 @@ "eslint/no-return-assign": "error", "eslint/no-sequences": "error", "eslint/no-self-compare": "error", - "eslint/no-shadow": "off", + "eslint/no-shadow": "error", "eslint/no-implicit-coercion": "error", "eslint/no-var": "error", "eslint/no-useless-call": "error", @@ -35,7 +35,7 @@ "eslint/no-useless-constructor": "error", "eslint/no-useless-rename": "error", "eslint/no-useless-return": "error", - "eslint/no-unused-vars": "off", + "eslint/no-unused-vars": "error", "eslint/no-warning-comments": "error", "eslint/no-unmodified-loop-condition": "error", "eslint/no-new-wrappers": "error", @@ -229,15 +229,7 @@ "**/*test-support.ts" ], "rules": { - "typescript/no-explicit-any": "off", - "typescript/unbound-method": "off", - "eslint/no-unsafe-optional-chaining": "off" - } - }, - { - "files": ["src/agents/embedded-agent-runner/run/attempt.ts"], - "rules": { - "eslint/no-shadow": "error" + "typescript/no-explicit-any": "off" } } ] diff --git a/extensions/acpx/register.runtime.ts b/extensions/acpx/register.runtime.ts index ff22997ea91..9710d6d320e 100644 --- a/extensions/acpx/register.runtime.ts +++ b/extensions/acpx/register.runtime.ts @@ -37,8 +37,8 @@ async function startRealService(state: DeferredServiceState): Promise { - const { createAcpxRuntimeService } = await loadServiceModule(); - const service = createAcpxRuntimeService(state.params); + const { createAcpxRuntimeService: createAcpxRuntimeServiceLocal } = await loadServiceModule(); + const service = createAcpxRuntimeServiceLocal(state.params); state.realService = service; await service.start(state.ctx as OpenClawPluginServiceContext); const backend = getAcpRuntimeBackend(ACPX_BACKEND_ID); diff --git a/extensions/acpx/src/runtime.test.ts b/extensions/acpx/src/runtime.test.ts index ebd798d6f78..41e58ce186c 100644 --- a/extensions/acpx/src/runtime.test.ts +++ b/extensions/acpx/src/runtime.test.ts @@ -335,7 +335,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { }); await expect(async () => { - for await (const eventValue of runtime.runTurn({ + for await (const ignoredEventValue of runtime.runTurn({ handle: { sessionKey: "agent:codex:acp:test", backend: "acpx", @@ -346,6 +346,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { mode: "prompt", requestId: "turn-1", })) { + void ignoredEventValue; // no-op } }).rejects.toMatchObject({ @@ -568,7 +569,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { }), ); - for await (const eventValue of runtime.runTurn({ + for await (const ignoredEventValue of runtime.runTurn({ handle: { sessionKey: "agent:codex:acp:test", backend: "acpx", @@ -579,6 +580,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { mode: "prompt", requestId: "turn-1", })) { + void ignoredEventValue; // no-op } @@ -599,7 +601,8 @@ describe("AcpxRuntime fresh reset wrapper", () => { mode: "prompt", requestId: "turn-2", }); - for await (const eventValue of turn.events) { + for await (const ignoredEventValue of turn.events) { + void ignoredEventValue; // no-op } await turn.result; @@ -947,16 +950,16 @@ describe("AcpxRuntime fresh reset wrapper", () => { expect(await wrappedStore.load("agent:codex:acp:binding:test")).toEqual({ acpxRecordId: "stale", }); - expect(baseStore.load).toHaveBeenCalledTimes(1); + expect(baseStore["load"]).toHaveBeenCalledTimes(1); await runtime.prepareFreshSession({ sessionKey: "agent:codex:acp:binding:test", }); expect(await wrappedStore.load("agent:codex:acp:binding:test")).toBeUndefined(); - expect(baseStore.load).toHaveBeenCalledTimes(1); + expect(baseStore["load"]).toHaveBeenCalledTimes(1); expect(await wrappedStore.load("agent:codex:acp:binding:test")).toBeUndefined(); - expect(baseStore.load).toHaveBeenCalledTimes(1); + expect(baseStore["load"]).toHaveBeenCalledTimes(1); await wrappedStore.save({ acpxRecordId: "fresh-record", @@ -966,7 +969,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { expect(await wrappedStore.load("agent:codex:acp:binding:test")).toEqual({ acpxRecordId: "stale", }); - expect(baseStore.load).toHaveBeenCalledTimes(2); + expect(baseStore["load"]).toHaveBeenCalledTimes(2); }); it("marks the session fresh after discardPersistentState close", async () => { @@ -998,7 +1001,7 @@ describe("AcpxRuntime fresh reset wrapper", () => { discardPersistentState: true, }); expect(await wrappedStore.load("agent:codex:acp:binding:test")).toBeUndefined(); - expect(baseStore.load).toHaveBeenCalledOnce(); + expect(baseStore["load"]).toHaveBeenCalledOnce(); }); it("cleans up OpenClaw-owned ACPX process trees after close", async () => { diff --git a/extensions/active-memory/index.ts b/extensions/active-memory/index.ts index 4ec5f25bebc..14e72efe671 100644 --- a/extensions/active-memory/index.ts +++ b/extensions/active-memory/index.ts @@ -605,25 +605,25 @@ function resolveRecallRunChannelContext(params: { (!explicitProvider || explicitProvider === "webchat") ? runnableExplicitChannel : undefined; - const resolveReturnValue = (params: { + const resolveReturnValue = (paramsLocal: { resolvedChannel?: string; resolvedChannelStrength?: "strong" | "weak"; }) => { const trustedResolvedChannel = - params.resolvedChannelStrength === "strong" ? params.resolvedChannel : undefined; + paramsLocal.resolvedChannelStrength === "strong" ? paramsLocal.resolvedChannel : undefined; return { messageChannel: trustedExplicitChannel ?? trustedResolvedChannel ?? explicitProvider ?? runnableExplicitChannel ?? - params.resolvedChannel, + paramsLocal.resolvedChannel, messageProvider: trustedExplicitChannel ?? trustedResolvedChannel ?? explicitProvider ?? runnableExplicitChannel ?? - params.resolvedChannel, + paramsLocal.resolvedChannel, }; }; const resolvedSessionKey = diff --git a/extensions/amazon-bedrock-mantle/mantle-anthropic.runtime.test.ts b/extensions/amazon-bedrock-mantle/mantle-anthropic.runtime.test.ts index 530e91d855b..13eeca2e0b2 100644 --- a/extensions/amazon-bedrock-mantle/mantle-anthropic.runtime.test.ts +++ b/extensions/amazon-bedrock-mantle/mantle-anthropic.runtime.test.ts @@ -1,4 +1,4 @@ -import type { Api, Model } from "openclaw/plugin-sdk/llm"; +import type { Model } from "openclaw/plugin-sdk/llm"; import { describe, expect, it, vi } from "vitest"; import { createMantleAnthropicStreamFn, diff --git a/extensions/amazon-bedrock/embedding-provider.ts b/extensions/amazon-bedrock/embedding-provider.ts index bcb9f8cd27e..981e2d80f76 100644 --- a/extensions/amazon-bedrock/embedding-provider.ts +++ b/extensions/amazon-bedrock/embedding-provider.ts @@ -365,29 +365,29 @@ export async function createBedrockEmbeddingProvider( const embedQuery = async ( text: string, - options?: { signal?: AbortSignal }, + optionsValue?: { signal?: AbortSignal }, ): Promise => { if (!text.trim()) { return []; } if (isCohere) { - return (await embedCohere([text], "search_query", options?.signal))[0] ?? []; + return (await embedCohere([text], "search_query", optionsValue?.signal))[0] ?? []; } - return embedSingle(text, options?.signal); + return embedSingle(text, optionsValue?.signal); }; const embedBatch = async ( texts: string[], - options?: { signal?: AbortSignal }, + optionsLocal?: { signal?: AbortSignal }, ): Promise => { if (texts.length === 0) { return []; } if (isCohere) { - return embedCohere(texts, "search_document", options?.signal); + return embedCohere(texts, "search_document", optionsLocal?.signal); } return Promise.all( - texts.map((t) => (t.trim() ? embedSingle(t, options?.signal) : Promise.resolve([]))), + texts.map((t) => (t.trim() ? embedSingle(t, optionsLocal?.signal) : Promise.resolve([]))), ); }; diff --git a/extensions/amazon-bedrock/index.test.ts b/extensions/amazon-bedrock/index.test.ts index 1df6edc084f..f16f79151bc 100644 --- a/extensions/amazon-bedrock/index.test.ts +++ b/extensions/amazon-bedrock/index.test.ts @@ -272,7 +272,7 @@ describe("amazon-bedrock provider plugin", () => { setBedrockAppProfileControlPlaneForTest((region) => ({ async getInferenceProfile(input) { class GetInferenceProfileCommand { - constructor(readonly input: Record = {}) {} + constructor(readonly inputLocal: Record = {}) {} } bedrockClientConfigs.push(region ? { region } : {}); return await sendBedrockCommand(new GetInferenceProfileCommand(input)); diff --git a/extensions/arcee/index.ts b/extensions/arcee/index.ts index e7fd0126950..37fc29e84a5 100644 --- a/extensions/arcee/index.ts +++ b/extensions/arcee/index.ts @@ -127,11 +127,11 @@ export default definePluginEntry({ : undefined; }, normalizeResolvedModel: ({ model }) => normalizeArceeResolvedModel(model), - normalizeTransport: ({ api, baseUrl }) => { + normalizeTransport: ({ api: apiLocal, baseUrl }) => { const normalizedBaseUrl = normalizeArceeOpenRouterBaseUrl(baseUrl); return normalizedBaseUrl && normalizedBaseUrl !== baseUrl ? { - api, + api: apiLocal, baseUrl: normalizedBaseUrl, } : undefined; diff --git a/extensions/bonjour/src/advertiser.ts b/extensions/bonjour/src/advertiser.ts index 06a0f89d6bb..5e0ddb6bd99 100644 --- a/extensions/bonjour/src/advertiser.ts +++ b/extensions/bonjour/src/advertiser.ts @@ -495,7 +495,10 @@ export async function startGatewayBonjourAdvertiser( return { responder, services }; } - async function stopCycle(cycle: BonjourCycle | null, opts?: { shutdownResponder?: boolean }) { + async function stopCycle( + cycle: BonjourCycle | null, + optsValue?: { shutdownResponder?: boolean }, + ) { if (!cycle) { return; } @@ -507,7 +510,7 @@ export async function startGatewayBonjourAdvertiser( } } try { - if (opts?.shutdownResponder) { + if (optsValue?.shutdownResponder) { await cycle.responder.shutdown(); } } catch { @@ -615,7 +618,7 @@ export async function startGatewayBonjourAdvertiser( } }; - const recreateAdvertiser = async (reason: string, opts?: { stuckState?: boolean }) => { + const recreateAdvertiser = async (reason: string, optsLocal?: { stuckState?: boolean }) => { if (stopped || disabled) { return; } @@ -624,7 +627,9 @@ export async function startGatewayBonjourAdvertiser( } recreatePromise = (async () => { consecutiveRestarts += 1; - consecutiveStuckStateRestarts = opts?.stuckState ? consecutiveStuckStateRestarts + 1 : 0; + consecutiveStuckStateRestarts = optsLocal?.stuckState + ? consecutiveStuckStateRestarts + 1 + : 0; const now = Date.now(); while ( restartTimestamps.length > 0 && diff --git a/extensions/browser/src/browser-tool.ts b/extensions/browser/src/browser-tool.ts index 374ca674ce8..901fd385e35 100644 --- a/extensions/browser/src/browser-tool.ts +++ b/extensions/browser/src/browser-tool.ts @@ -530,7 +530,7 @@ export function createBrowserTool(opts?: { }); const proxyRequest = nodeTarget - ? async (opts: { + ? async (optsLocal: { method: string; path: string; query?: Record; @@ -540,12 +540,12 @@ export function createBrowserTool(opts?: { }) => { const proxy = await callBrowserProxy({ nodeId: nodeTarget.nodeId, - method: opts.method, - path: opts.path, - query: opts.query, - body: opts.body, - timeoutMs: opts.timeoutMs, - profile: opts.profile, + method: optsLocal.method, + path: optsLocal.path, + query: optsLocal.query, + body: optsLocal.body, + timeoutMs: optsLocal.timeoutMs, + profile: optsLocal.profile, }); const mapping = await persistProxyFiles(proxy.files); applyProxyPaths(proxy.result, mapping); diff --git a/extensions/browser/src/browser/cdp-proxy-bypass.test.ts b/extensions/browser/src/browser/cdp-proxy-bypass.test.ts index bc95670cf4c..f25884695a9 100644 --- a/extensions/browser/src/browser/cdp-proxy-bypass.test.ts +++ b/extensions/browser/src/browser/cdp-proxy-bypass.test.ts @@ -232,12 +232,13 @@ describe("cdp-proxy-bypass", () => { describe("withNoProxyForLocalhost concurrency", () => { it("does not leak NO_PROXY when called concurrently", async () => { await withIsolatedNoProxyEnv(async () => { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostScoped } = + await import("./cdp-proxy-bypass.js"); const releaseA = createDeferred(); const enteredA = createDeferred(); - const callA = withNoProxyForLocalhost(async () => { + const callA = withNoProxyForLocalhostScoped(async () => { expect(process.env.NO_PROXY).toContain("localhost"); expect(process.env.NO_PROXY).toContain("[::1]"); enteredA.resolve(); @@ -247,7 +248,7 @@ describe("withNoProxyForLocalhost concurrency", () => { await enteredA.promise; - const callB = withNoProxyForLocalhost(async () => { + const callB = withNoProxyForLocalhostScoped(async () => { return "b"; }); @@ -264,21 +265,22 @@ describe("withNoProxyForLocalhost concurrency", () => { describe("withNoProxyForLocalhost reverse exit order", () => { it("restores NO_PROXY when first caller exits before second", async () => { await withIsolatedNoProxyEnv(async () => { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostItem } = + await import("./cdp-proxy-bypass.js"); const enteredA = createDeferred(); const enteredB = createDeferred(); const releaseA = createDeferred(); const releaseB = createDeferred(); - const callA = withNoProxyForLocalhost(async () => { + const callA = withNoProxyForLocalhostItem(async () => { enteredA.resolve(); await releaseA.promise; return "a"; }); await enteredA.promise; - const callB = withNoProxyForLocalhost(async () => { + const callB = withNoProxyForLocalhostItem(async () => { enteredB.resolve(); await releaseB.promise; return "b"; @@ -306,9 +308,10 @@ describe("withNoProxyForLocalhost preserves user-configured NO_PROXY", () => { process.env.HTTP_PROXY = "http://proxy:8080"; try { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostCandidate } = + await import("./cdp-proxy-bypass.js"); - await withNoProxyForLocalhost(async () => { + await withNoProxyForLocalhostCandidate(async () => { // Should not modify since loopback is already covered expect(process.env.NO_PROXY).toBe(userNoProxy); return "ok"; @@ -332,9 +335,10 @@ describe("withNoProxyForLocalhost preserves user-configured NO_PROXY", () => { process.env.HTTP_PROXY = "http://proxy:8080"; try { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostEntry } = + await import("./cdp-proxy-bypass.js"); - await withNoProxyForLocalhost(async () => { + await withNoProxyForLocalhostEntry(async () => { expect(process.env.NO_PROXY).toBe(`${coveredNoProxy},localhost,127.0.0.1,[::1]`); expect(process.env.no_proxy).toBe(`${staleLowerNoProxy},localhost,127.0.0.1,[::1]`); }); @@ -355,9 +359,10 @@ describe("withNoProxyForLocalhost preserves user-configured NO_PROXY", () => { process.env.HTTP_PROXY = "http://proxy:8080"; try { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostResult } = + await import("./cdp-proxy-bypass.js"); - await withNoProxyForLocalhost(async () => { + await withNoProxyForLocalhostResult(async () => { expect(process.env.NO_PROXY).toBe(`${lowerNoProxy},localhost,127.0.0.1,[::1]`); expect(process.env.no_proxy).toBe(`${lowerNoProxy},localhost,127.0.0.1,[::1]`); }); @@ -378,9 +383,10 @@ describe("withNoProxyForLocalhost preserves user-configured NO_PROXY", () => { process.env.HTTP_PROXY = "http://proxy:8080"; try { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostValue } = + await import("./cdp-proxy-bypass.js"); - await withNoProxyForLocalhost(async () => { + await withNoProxyForLocalhostValue(async () => { expect(process.env.NO_PROXY).toBe(`${userNoProxy},localhost,127.0.0.1,[::1]`); expect(process.env.no_proxy).toBe(`${userNoProxy},localhost,127.0.0.1,[::1]`); delete process.env.no_proxy; @@ -402,9 +408,10 @@ describe("withNoProxyForLocalhost preserves user-configured NO_PROXY", () => { process.env.HTTP_PROXY = "http://proxy:8080"; try { - const { withNoProxyForLocalhost } = await import("./cdp-proxy-bypass.js"); + const { withNoProxyForLocalhost: withNoProxyForLocalhostLocal } = + await import("./cdp-proxy-bypass.js"); - await withNoProxyForLocalhost(async () => { + await withNoProxyForLocalhostLocal(async () => { expect(process.env.NO_PROXY).toBe(`${userNoProxy},localhost,127.0.0.1,[::1]`); expect(process.env.no_proxy).toBe(`${userNoProxy},localhost,127.0.0.1,[::1]`); }); diff --git a/extensions/browser/src/browser/chrome-mcp.test.ts b/extensions/browser/src/browser/chrome-mcp.test.ts index 33f2dcd993d..382bdcf3276 100644 --- a/extensions/browser/src/browser/chrome-mcp.test.ts +++ b/extensions/browser/src/browser/chrome-mcp.test.ts @@ -490,11 +490,11 @@ describe("chrome MCP page parsing", () => { url: "about:blank", type: "page", }); - expect(session.client.callTool).toHaveBeenCalledWith({ + expect(session.client["callTool"]).toHaveBeenCalledWith({ name: "new_page", arguments: { url: "about:blank", timeout: 5000 }, }); - const callToolMock = session.client.callTool as unknown as ToolCallMock; + const callToolMock = session.client["callTool"] as unknown as ToolCallMock; const callNames = callToolMock.mock.calls.map(([call]) => call.name); expect(callNames).not.toContain("navigate_page"); }); @@ -917,7 +917,7 @@ describe("chrome MCP page parsing", () => { // intentionally no timeoutMs }); - const callToolMock = session.client.callTool as unknown as ToolCallMock; + const callToolMock = session.client["callTool"] as unknown as ToolCallMock; const navigateCall = callToolMock.mock.calls.find( ([call]) => call.name === "navigate_page", )?.[0]; diff --git a/extensions/browser/src/browser/pw-tools-core.screenshots-element-selector.test.ts b/extensions/browser/src/browser/pw-tools-core.screenshots-element-selector.test.ts index d26639480c0..c9c73531bc5 100644 --- a/extensions/browser/src/browser/pw-tools-core.screenshots-element-selector.test.ts +++ b/extensions/browser/src/browser/pw-tools-core.screenshots-element-selector.test.ts @@ -107,7 +107,7 @@ describe("pw-tools-core", () => { await fs.writeFile(uploadPath, "fixture", "utf8"); const canonicalUploadPath = await fs.realpath(uploadPath); const fileChooser = { setFiles: vi.fn(async () => {}) }; - const waitForEvent = vi.fn(async (eventValue: string, _opts: unknown) => fileChooser); + const waitForEvent = vi.fn(async (_eventValue: string, _opts: unknown) => fileChooser); setPwToolsCoreCurrentPage({ waitForEvent, keyboard: { press: vi.fn(async () => {}) }, diff --git a/extensions/browser/src/browser/routes/agent.debug.ts b/extensions/browser/src/browser/routes/agent.debug.ts index 55dfbf5f733..ef232395155 100644 --- a/extensions/browser/src/browser/routes/agent.debug.ts +++ b/extensions/browser/src/browser/routes/agent.debug.ts @@ -86,10 +86,10 @@ export function registerBrowserAgentDebugRoutes( ctx, targetId, feature: "page errors", - collect: async ({ cdpUrl, targetId, pw }) => + collect: async ({ cdpUrl, targetId: targetIdValue, pw }) => await pw.getPageErrorsViaPlaywright({ cdpUrl, - targetId, + targetId: targetIdValue, clear, }), }); @@ -109,10 +109,10 @@ export function registerBrowserAgentDebugRoutes( ctx, targetId, feature: "network requests", - collect: async ({ cdpUrl, targetId, pw }) => + collect: async ({ cdpUrl, targetId: targetIdLocal, pw }) => await pw.getNetworkRequestsViaPlaywright({ cdpUrl, - targetId, + targetId: targetIdLocal, filter: normalizeOptionalString(filter), clear, }), diff --git a/extensions/browser/src/browser/runtime-lifecycle.unhandled-rejections.test.ts b/extensions/browser/src/browser/runtime-lifecycle.unhandled-rejections.test.ts index 87a839f5743..35f6c663db1 100644 --- a/extensions/browser/src/browser/runtime-lifecycle.unhandled-rejections.test.ts +++ b/extensions/browser/src/browser/runtime-lifecycle.unhandled-rejections.test.ts @@ -25,14 +25,14 @@ const { stopKnownBrowserProfilesMock, trackedTabCleanupMock, } = vi.hoisted(() => { - const trackedTabCleanupMock = vi.fn(); + const trackedTabCleanupMockLocal = vi.fn(); return { ensureExtensionRelayForProfilesMock: vi.fn(async () => {}), getPwAiModuleMock: vi.fn(), isPwAiLoadedMock: vi.fn(() => false), - startTrackedBrowserTabCleanupTimerMock: vi.fn(() => trackedTabCleanupMock), + startTrackedBrowserTabCleanupTimerMock: vi.fn(() => trackedTabCleanupMockLocal), stopKnownBrowserProfilesMock: vi.fn(async () => {}), - trackedTabCleanupMock, + trackedTabCleanupMock: trackedTabCleanupMockLocal, }; }); diff --git a/extensions/browser/src/browser/server-context.ts b/extensions/browser/src/browser/server-context.ts index c07d63bfb2f..5522b92a7c1 100644 --- a/extensions/browser/src/browser/server-context.ts +++ b/extensions/browser/src/browser/server-context.ts @@ -264,7 +264,7 @@ export function createBrowserRouteContext(opts: ContextOptions): BrowserRouteCon isTransportAvailable: (timeoutMs) => getDefaultContext().isTransportAvailable(timeoutMs), isReachable: (timeoutMs, options) => getDefaultContext().isReachable(timeoutMs, options), listTabs: () => getDefaultContext().listTabs(), - openTab: (url, opts) => getDefaultContext().openTab(url, opts), + openTab: (url, optsLocal) => getDefaultContext().openTab(url, optsLocal), labelTab: (targetId, label) => getDefaultContext().labelTab(targetId, label), focusTab: (targetId) => getDefaultContext().focusTab(targetId), closeTab: (targetId) => getDefaultContext().closeTab(targetId), diff --git a/extensions/browser/src/browser/vision.test.ts b/extensions/browser/src/browser/vision.test.ts index 50530cd0496..79865c3ed4e 100644 --- a/extensions/browser/src/browser/vision.test.ts +++ b/extensions/browser/src/browser/vision.test.ts @@ -11,14 +11,14 @@ import { type DescribeFn = ReturnType; function makeDeps( - describe: DescribeFn, + describeCandidate: DescribeFn, overrides?: { normalizeBrowserScreenshot?: ReturnType; saveMediaBuffer?: ReturnType; }, ) { return { - describeImageFile: describe as never, + describeImageFile: describeCandidate as never, normalizeBrowserScreenshot: (overrides?.normalizeBrowserScreenshot as never) ?? (vi.fn(async (buffer: Buffer) => ({ buffer })) as never), @@ -41,7 +41,7 @@ async function withTempImage(fn: (filePath: string) => Promise): Promise { it("uses existing image understanding config with a browser screenshot prompt", async () => { - const describe = vi.fn().mockResolvedValue({ + const describeEntry = vi.fn().mockResolvedValue({ text: "A login screen.", provider: "openai", model: "gpt-vision", @@ -62,7 +62,7 @@ describe("describeBrowserScreenshot", () => { activeModel: { provider: "anthropic", model: "claude-sonnet-4.6" }, mediaScope: { sessionKey: "agent:main:telegram:dm:123", channel: "telegram" }, }, - makeDeps(describe), + makeDeps(describeEntry), ); expect(result).toEqual({ @@ -71,7 +71,7 @@ describe("describeBrowserScreenshot", () => { model: "gpt-vision", decision: { outcome: "success" }, }); - expect(describe).toHaveBeenCalledWith({ + expect(describeEntry).toHaveBeenCalledWith({ filePath, cfg: { tools: { @@ -92,7 +92,7 @@ describe("describeBrowserScreenshot", () => { }); it("resizes screenshots before image understanding when image sanitization is configured", async () => { - const describe = vi.fn().mockResolvedValue({ text: "Small screenshot." }); + const describeResult = vi.fn().mockResolvedValue({ text: "Small screenshot." }); const normalizeBrowserScreenshot = vi.fn(async () => ({ buffer: Buffer.from("small"), contentType: "image/jpeg" as const, @@ -106,7 +106,7 @@ describe("describeBrowserScreenshot", () => { filePath, imageSanitization: { maxDimensionPx: 800 }, }, - makeDeps(describe, { normalizeBrowserScreenshot, saveMediaBuffer }), + makeDeps(describeResult, { normalizeBrowserScreenshot, saveMediaBuffer }), ); }); @@ -114,11 +114,11 @@ describe("describeBrowserScreenshot", () => { maxSide: 800, }); expect(saveMediaBuffer).toHaveBeenCalledWith(Buffer.from("small"), "image/jpeg", "browser"); - expect(describe.mock.calls[0][0].filePath).toBe("/tmp/resized.jpg"); + expect(describeResult.mock.calls[0][0].filePath).toBe("/tmp/resized.jpg"); }); it("returns null when image understanding is skipped or not configured", async () => { - const describe = vi.fn().mockResolvedValue({ + const describeValue = vi.fn().mockResolvedValue({ text: undefined, decision: { outcome: "skipped" }, }); @@ -126,13 +126,13 @@ describe("describeBrowserScreenshot", () => { await expect( describeBrowserScreenshot( { cfg: { browser: {} }, filePath: "/tmp/screenshot.png" }, - makeDeps(describe), + makeDeps(describeValue), ), ).resolves.toBeNull(); }); it("does not pass an incomplete active model to media understanding", async () => { - const describe = vi.fn().mockResolvedValue({ text: "ok" }); + const describeLocal = vi.fn().mockResolvedValue({ text: "ok" }); await describeBrowserScreenshot( { @@ -144,10 +144,10 @@ describe("describeBrowserScreenshot", () => { filePath: "/tmp/screenshot.png", activeModel: { model: "missing-provider" }, }, - makeDeps(describe), + makeDeps(describeLocal), ); - expect(describe.mock.calls[0][0].activeModel).toBeUndefined(); + expect(describeLocal.mock.calls[0][0].activeModel).toBeUndefined(); }); }); diff --git a/extensions/browser/src/cli/browser-cli-manage.ts b/extensions/browser/src/cli/browser-cli-manage.ts index e138b78b96c..0b2170ac050 100644 --- a/extensions/browser/src/cli/browser-cli-manage.ts +++ b/extensions/browser/src/cli/browser-cli-manage.ts @@ -495,8 +495,10 @@ export function registerBrowserManageCommands( if (printJsonResult(parent, result)) { return; } - const tab = (result as { tab?: BrowserTab }).tab; - defaultRuntime.log(`labeled tab ${tab?.tabId ?? targetId} as ${tab?.label ?? label}`); + const tabValue = (result as { tab?: BrowserTab }).tab; + defaultRuntime.log( + `labeled tab ${tabValue?.tabId ?? targetId} as ${tabValue?.label ?? label}`, + ); }); }); @@ -555,7 +557,7 @@ export function registerBrowserManageCommands( const parent = parentOpts(cmd); const profile = parent?.browserProfile; await runBrowserCommand(async () => { - const tab = await callBrowserRequest( + const tabLocal = await callBrowserRequest( parent, { method: "POST", @@ -565,11 +567,11 @@ export function registerBrowserManageCommands( }, { timeoutMs: BROWSER_MANAGE_REQUEST_TIMEOUT_MS }, ); - if (printJsonResult(parent, tab)) { + if (printJsonResult(parent, tabLocal)) { return; } defaultRuntime.log( - `opened: ${tab.url}\n${tab.tabId ? `tab: ${tab.tabId}\n` : ""}${tab.label ? `label: ${tab.label}\n` : ""}id: ${tab.targetId}`, + `opened: ${tabLocal.url}\n${tabLocal.tabId ? `tab: ${tabLocal.tabId}\n` : ""}${tabLocal.label ? `label: ${tabLocal.label}\n` : ""}id: ${tabLocal.targetId}`, ); }); }); diff --git a/extensions/codex/index.test.ts b/extensions/codex/index.test.ts index 9a8bce0c251..27cb7517b13 100644 --- a/extensions/codex/index.test.ts +++ b/extensions/codex/index.test.ts @@ -216,7 +216,7 @@ describe("codex plugin", () => { it("enables the native hook relay for public Codex side questions", async () => { const harness = createCodexAppServerAgentHarness({ pluginConfig: { appServer: {} } }); - const runSideQuestion = harness.runSideQuestion; + const runSideQuestion = harness["runSideQuestion"]; const result = { text: "ok" }; runCodexAppServerSideQuestionMock.mockResolvedValueOnce(result); diff --git a/extensions/codex/provider.test.ts b/extensions/codex/provider.test.ts index abc8966478a..3e9e98cd2f9 100644 --- a/extensions/codex/provider.test.ts +++ b/extensions/codex/provider.test.ts @@ -266,7 +266,7 @@ describe("codex provider", () => { listModels: listTestCodexAppServerModels, }); - expect(client.close).toHaveBeenCalledTimes(1); + expect(client["close"]).toHaveBeenCalledTimes(1); }); it("does not close an active shared app-server client during live discovery", async () => { @@ -293,8 +293,8 @@ describe("codex provider", () => { listModels: listTestCodexAppServerModels, }); - expect(activeClient.close).not.toHaveBeenCalled(); - expect(discoveryClient.close).toHaveBeenCalledTimes(1); + expect(activeClient["close"]).not.toHaveBeenCalled(); + expect(discoveryClient["close"]).toHaveBeenCalledTimes(1); }); it("resolves arbitrary Codex app-server model ids as text-only until discovered", () => { diff --git a/extensions/codex/src/app-server/compact.test.ts b/extensions/codex/src/app-server/compact.test.ts index 2b0e53bcf0a..7cbf985522b 100644 --- a/extensions/codex/src/app-server/compact.test.ts +++ b/extensions/codex/src/app-server/compact.test.ts @@ -114,7 +114,7 @@ describe("maybeCompactCodexAppServerSession", () => { ); expect(fake.request).toHaveBeenCalledWith("thread/compact/start", { threadId: "thread-1" }); - expect(fake.client.addNotificationHandler).not.toHaveBeenCalled(); + expect(fake.client["addNotificationHandler"]).not.toHaveBeenCalled(); expect(result.ok).toBe(true); expect(result.compacted).toBe(false); expect(result.result?.tokensBefore).toBe(123); diff --git a/extensions/codex/src/app-server/dynamic-tools.test.ts b/extensions/codex/src/app-server/dynamic-tools.test.ts index 417332288ec..3088cdcc7ab 100644 --- a/extensions/codex/src/app-server/dynamic-tools.test.ts +++ b/extensions/codex/src/app-server/dynamic-tools.test.ts @@ -1,15 +1,15 @@ import type { AgentToolResult } from "openclaw/plugin-sdk/agent-core"; -import { - onInternalDiagnosticEvent, - waitForDiagnosticEventsDrained, - type DiagnosticEventPayload, -} from "openclaw/plugin-sdk/diagnostic-runtime"; import type { AnyAgentTool } from "openclaw/plugin-sdk/agent-harness"; import { HEARTBEAT_RESPONSE_TOOL_NAME, embeddedAgentLog, wrapToolWithBeforeToolCallHook, } from "openclaw/plugin-sdk/agent-harness-runtime"; +import { + onInternalDiagnosticEvent, + waitForDiagnosticEventsDrained, + type DiagnosticEventPayload, +} from "openclaw/plugin-sdk/diagnostic-runtime"; import { initializeGlobalHookRunner, resetGlobalHookRunner, @@ -85,12 +85,6 @@ function requireRecord(value: unknown, label: string): Record { } return value as Record; } - -function requireArray(value: unknown, label: string): Array { - expect(Array.isArray(value), label).toBe(true); - return value as Array; -} - function callArg( mock: { mock: { calls: Array> } }, callIndex: number, @@ -346,9 +340,7 @@ describe("createCodexDynamicToolBridge", () => { }), ); const blockedEvents = diagnosticEvents.filter( - ( - event, - ): event is Extract => + (event): event is Extract => event.type === "tool.execution.blocked", ); expect(blockedEvents).toContainEqual( @@ -889,7 +881,7 @@ describe("createCodexDynamicToolBridge", () => { it("passes raw tool failure state into agent tool result middleware", async () => { const registry = createEmptyPluginRegistry(); - const handler = vi.fn(async (eventValue: { isError?: boolean }) => undefined); + const handler = vi.fn(async (_eventValue: { isError?: boolean }) => undefined); registry.agentToolResultMiddlewares.push({ pluginId: "tokenjuice", pluginName: "Tokenjuice", diff --git a/extensions/codex/src/app-server/run-attempt-test-harness.ts b/extensions/codex/src/app-server/run-attempt-test-harness.ts index d58890c0d4d..2cd5d94b8d2 100644 --- a/extensions/codex/src/app-server/run-attempt-test-harness.ts +++ b/extensions/codex/src/app-server/run-attempt-test-harness.ts @@ -312,7 +312,7 @@ export function createAppServerHarness( return { request, requests, - async waitForMethod(method: string, timeoutMs: number = appServerHarnessWait.timeout) { + waitForMethod: async (method: string, timeoutMs: number = appServerHarnessWait.timeout) => { await vi.waitFor( () => { if (!requests.some((entry) => entry.method === method)) { @@ -330,15 +330,15 @@ export function createAppServerHarness( { interval: 1, timeout: timeoutMs }, ); }, - async notify(notification: CodexServerNotification) { + notify: async (notification: CodexServerNotification) => { await sendNotification(notification); }, waitForServerRequestHandler, - async handleServerRequest(request: Parameters[0]) { + handleServerRequest: async (requestLocal: Parameters[0]) => { const handler = await waitForServerRequestHandler(); - return handler(request); + return handler(requestLocal); }, - async completeTurn(params: { threadId: string; turnId: string }) { + completeTurn: async (params: { threadId: string; turnId: string }) => { await sendNotification({ method: "turn/completed", params: { @@ -348,7 +348,7 @@ export function createAppServerHarness( }, }); }, - close() { + close: () => { for (const handler of closeHandlers) { handler(); } diff --git a/extensions/codex/src/app-server/run-attempt.context-engine.test.ts b/extensions/codex/src/app-server/run-attempt.context-engine.test.ts index d62eadcb7f3..6975ee3b6f2 100644 --- a/extensions/codex/src/app-server/run-attempt.context-engine.test.ts +++ b/extensions/codex/src/app-server/run-attempt.context-engine.test.ts @@ -334,16 +334,17 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => { if (!contextEngine.bootstrap) { throw new Error("expected bootstrap hook"); } - expect(contextEngine.bootstrap).toHaveBeenCalledTimes(1); - const bootstrapParams = requireFirstCallArg(contextEngine.bootstrap, "bootstrap") as Parameters< - NonNullable - >[0]; + expect(contextEngine["bootstrap"]).toHaveBeenCalledTimes(1); + const bootstrapParams = requireFirstCallArg( + contextEngine["bootstrap"], + "bootstrap", + ) as Parameters>[0]; expect(bootstrapParams.sessionId).toBe("session-1"); expect(bootstrapParams.sessionKey).toBe("agent:main:session-1"); expect(bootstrapParams.sessionFile).toBe(sessionFile); - expect(contextEngine.assemble).toHaveBeenCalledTimes(1); - const assembleParams = requireFirstCallArg(contextEngine.assemble, "assemble") as Parameters< + expect(contextEngine["assemble"]).toHaveBeenCalledTimes(1); + const assembleParams = requireFirstCallArg(contextEngine["assemble"], "assemble") as Parameters< ContextEngine["assemble"] >[0]; expect(assembleParams.sessionId).toBe("session-1"); @@ -385,12 +386,13 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => { if (!contextEngine.bootstrap) { throw new Error("expected bootstrap hook"); } - const bootstrapParams = requireFirstCallArg(contextEngine.bootstrap, "bootstrap") as Parameters< - NonNullable - >[0]; + const bootstrapParams = requireFirstCallArg( + contextEngine["bootstrap"], + "bootstrap", + ) as Parameters>[0]; expect(bootstrapParams.sessionKey).toBe("agent:main:main"); - const assembleParams = requireFirstCallArg(contextEngine.assemble, "assemble") as Parameters< + const assembleParams = requireFirstCallArg(contextEngine["assemble"], "assemble") as Parameters< ContextEngine["assemble"] >[0]; expect(assembleParams.sessionKey).toBe("agent:main:main"); @@ -1640,7 +1642,7 @@ describe("runCodexAppServerAttempt context-engine lifecycle", () => { await harness.completeTurn(); await run; - const assembleParams = requireFirstCallArg(contextEngine.assemble, "assemble") as Parameters< + const assembleParams = requireFirstCallArg(contextEngine["assemble"], "assemble") as Parameters< ContextEngine["assemble"] >[0]; expect(assembleParams.messages.map((message) => message.role)).toEqual([ diff --git a/extensions/codex/src/app-server/run-attempt.test.ts b/extensions/codex/src/app-server/run-attempt.test.ts index 109c4e37f8b..a8cdedf249e 100644 --- a/extensions/codex/src/app-server/run-attempt.test.ts +++ b/extensions/codex/src/app-server/run-attempt.test.ts @@ -1,10 +1,7 @@ import fs from "node:fs/promises"; import path from "node:path"; import { - abortAgentHarnessRun, embeddedAgentLog, - onAgentEvent, - type AgentEventPayload, type EmbeddedRunAttemptParams, } from "openclaw/plugin-sdk/agent-harness-runtime"; import { SessionManager } from "openclaw/plugin-sdk/agent-sessions"; @@ -12,15 +9,10 @@ import { onInternalDiagnosticEvent, waitForDiagnosticEventsDrained, type DiagnosticEventPayload, - type DiagnosticEventPrivateData, } from "openclaw/plugin-sdk/diagnostic-runtime"; import { initializeGlobalHookRunner, registerInternalHook } from "openclaw/plugin-sdk/hook-runtime"; import { registerPluginCommand } from "openclaw/plugin-sdk/plugin-runtime"; -import { - createMockPluginRegistry, - onTrustedInternalDiagnosticEvent, -} from "openclaw/plugin-sdk/plugin-test-runtime"; -import { registerSandboxBackend } from "openclaw/plugin-sdk/sandbox"; +import { createMockPluginRegistry } from "openclaw/plugin-sdk/plugin-test-runtime"; import { describe, expect, it, vi } from "vitest"; import WebSocket from "ws"; import { CODEX_GPT5_BEHAVIOR_CONTRACT } from "../../prompt-overlay.js"; @@ -32,7 +24,6 @@ import { getCodexWorkspaceMemoryToolNames, prependCodexOpenClawPromptContext, } from "./attempt-context.js"; -import * as authBridge from "./auth-bridge.js"; import { resolveCodexAppServerEnvApiKeyCacheKey } from "./auth-bridge.js"; import { CodexAppServerRpcError } from "./client.js"; import { readCodexPluginConfig, resolveCodexAppServerRuntimeOptions } from "./config.js"; @@ -49,10 +40,10 @@ import { buildCodexPluginAppCacheKey } from "./plugin-app-cache-key.js"; import { buildCodexPluginThreadConfig } from "./plugin-thread-config.js"; import type { CodexServerNotification } from "./protocol.js"; import { - createAppServerHarness, assistantMessage, - createParams, + createAppServerHarness, createCodexRuntimePlanFixture, + createParams, createResumeHarness, createStartedThreadHarness, fastWait, @@ -1638,11 +1629,11 @@ describe("runCodexAppServerAttempt", () => { "assistant", "toolResult", ]); - const assistantMessage = result.messagesSnapshot[1]; - if (assistantMessage?.role !== "assistant") { + const assistantMessageLocal = result.messagesSnapshot[1]; + if (assistantMessageLocal?.role !== "assistant") { throw new Error("expected mirrored assistant tool-call message"); } - expect(assistantMessage.content).toStrictEqual([ + expect(assistantMessageLocal.content).toStrictEqual([ { type: "toolCall", id: "call-wiki-status-1", diff --git a/extensions/codex/src/app-server/run-attempt.ts b/extensions/codex/src/app-server/run-attempt.ts index 88334133480..8ca3b94135f 100644 --- a/extensions/codex/src/app-server/run-attempt.ts +++ b/extensions/codex/src/app-server/run-attempt.ts @@ -1217,7 +1217,7 @@ export async function runCodexAppServerAttempt( }, }); - const releaseTurnAfterTerminalDynamicTool = (params: { + const releaseTurnAfterTerminalDynamicTool = (paramsValue: { call: CodexDynamicToolCallParams; response: CodexDynamicToolCallResponse; durationMs: number; @@ -1226,7 +1226,7 @@ export async function runCodexAppServerAttempt( !shouldReleaseTurnAfterTerminalDynamicTool({ completed, aborted: runAbortController.signal.aborted, - responseSuccess: params.response.success, + responseSuccess: paramsValue.response.success, currentTurnHadNonTerminalDynamicToolResult, activeAppServerTurnRequests, activeTurnItemIdsCount: activeTurnItemIds.size, @@ -1237,22 +1237,22 @@ export async function runCodexAppServerAttempt( } pendingTerminalDynamicToolRelease = undefined; trajectoryRecorder?.recordEvent("turn.dynamic_tool_terminal_release", { - threadId: params.call.threadId, - turnId: params.call.turnId, - toolCallId: params.call.callId, - name: params.call.tool, - durationMs: params.durationMs, + threadId: paramsValue.call.threadId, + turnId: paramsValue.call.turnId, + toolCallId: paramsValue.call.callId, + name: paramsValue.call.tool, + durationMs: paramsValue.durationMs, }); embeddedAgentLog.info("codex app-server turn released after terminal dynamic tool result", { - threadId: params.call.threadId, - turnId: params.call.turnId, - toolCallId: params.call.callId, - tool: params.call.tool, - durationMs: params.durationMs, + threadId: paramsValue.call.threadId, + turnId: paramsValue.call.turnId, + toolCallId: paramsValue.call.callId, + tool: paramsValue.call.tool, + durationMs: paramsValue.durationMs, }); interruptCodexTurnBestEffort(client, { - threadId: params.call.threadId, - turnId: params.call.turnId, + threadId: paramsValue.call.threadId, + turnId: paramsValue.call.turnId, timeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS, }); completed = true; @@ -1290,12 +1290,12 @@ export async function runCodexAppServerAttempt( immediate.unref?.(); }; - const scheduleTurnReleaseAfterTerminalDynamicTool = (params: { + const scheduleTurnReleaseAfterTerminalDynamicTool = (paramsLocal: { call: CodexDynamicToolCallParams; response: CodexDynamicToolCallResponse; durationMs: number; }) => { - pendingTerminalDynamicToolRelease = params; + pendingTerminalDynamicToolRelease = paramsLocal; scheduleTerminalDynamicToolReleaseCheck(); }; @@ -2090,8 +2090,8 @@ export async function runCodexAppServerAttempt( steeringQueueRef.current = activeSteeringQueue; const handle = { kind: "embedded" as const, - queueMessage: async (text: string, options?: CodexSteeringQueueOptions) => - activeSteeringQueue.queue(text, options), + queueMessage: async (text: string, optionsLocal?: CodexSteeringQueueOptions) => + activeSteeringQueue.queue(text, optionsLocal), isStreaming: () => !completed, isCompacting: () => projectorRef.current?.isCompacting() ?? false, sourceReplyDeliveryMode: params.sourceReplyDeliveryMode, @@ -2280,7 +2280,8 @@ export async function runCodexAppServerAttempt( }); } if (activeContextEngine) { - const activeContextEnginePluginId = resolveContextEngineOwnerPluginId(activeContextEngine); + const activeContextEnginePluginIdLocal = + resolveContextEngineOwnerPluginId(activeContextEngine); const finalMessages = (await readMirroredSessionHistoryMessages(activeSessionFile)) ?? historyMessages.concat(result.messagesSnapshot); @@ -2301,7 +2302,7 @@ export async function runCodexAppServerAttempt( cwd: effectiveCwd, agentDir, activeAgentId: sessionAgentId, - contextEnginePluginId: activeContextEnginePluginId, + contextEnginePluginId: activeContextEnginePluginIdLocal, tokenBudget: params.contextTokenBudget, lastCallUsage: result.attemptUsage, promptCache: result.promptCache, diff --git a/extensions/codex/src/app-server/test-support.ts b/extensions/codex/src/app-server/test-support.ts index 87de538567b..067d1e2e6c1 100644 --- a/extensions/codex/src/app-server/test-support.ts +++ b/extensions/codex/src/app-server/test-support.ts @@ -1,6 +1,6 @@ import { EventEmitter } from "node:events"; import { PassThrough, Writable } from "node:stream"; -import type { Api, Model } from "openclaw/plugin-sdk/llm"; +import type { Model } from "openclaw/plugin-sdk/llm"; import { vi } from "vitest"; import { CodexAppServerClient } from "./client.js"; diff --git a/extensions/codex/src/app-server/trajectory.ts b/extensions/codex/src/app-server/trajectory.ts index e8d4f5d6b53..9709b0db37f 100644 --- a/extensions/codex/src/app-server/trajectory.ts +++ b/extensions/codex/src/app-server/trajectory.ts @@ -335,8 +335,8 @@ function sanitizeValue(value: unknown, depth = 0, key = ""): unknown { } if (typeof value === "object") { const next: Record = {}; - for (const [key, child] of Object.entries(value).slice(0, 100)) { - next[key] = sanitizeValue(child, depth + 1, key); + for (const [keyLocal, child] of Object.entries(value).slice(0, 100)) { + next[keyLocal] = sanitizeValue(child, depth + 1, keyLocal); } return next; } diff --git a/extensions/codex/src/commands.test.ts b/extensions/codex/src/commands.test.ts index adb75c49959..e013a3d7b2f 100644 --- a/extensions/codex/src/commands.test.ts +++ b/extensions/codex/src/commands.test.ts @@ -218,11 +218,6 @@ function mockCall(mockFn: ReturnType, callIndex = 0): ReadonlyArra function mockArg(mockFn: ReturnType, callIndex: number, argIndex: number) { return mockCall(mockFn, callIndex)[argIndex]; } - -function requireRequestParams(call: unknown[] | undefined): Record { - return requireRecord(call?.[2], "expected request params object"); -} - function requestParams(mockFn: ReturnType, callIndex = 0): Record { return requireRecord(mockArg(mockFn, callIndex, 2), "expected request params object"); } @@ -347,8 +342,8 @@ describe("codex command", () => { const requests: Array<{ method: string; params: unknown }> = []; const deps = createDeps({ codexControlRequest: vi.fn( - async (_pluginConfig: unknown, method: string, requestParams: unknown) => { - requests.push({ method, params: requestParams }); + async (_pluginConfig: unknown, method: string, requestParamsValue: unknown) => { + requests.push({ method, params: requestParamsValue }); return { thread: { id: "thread-123", cwd: "/repo" }, model: "gpt-5.4", @@ -1757,7 +1752,8 @@ describe("codex command", () => { it("respects openai-alias explicit order over stale lastGood for API key profiles", async () => { const config = {}; - const now = Date.now(); + const ignoredNow = Date.now(); + void ignoredNow; installAuthProfileStore( { version: 1, @@ -2384,12 +2380,14 @@ describe("codex command", () => { `${secondSessionFile}.codex-app-server.json`, JSON.stringify({ schemaVersion: 1, threadId: "thread-222", cwd: "/repo" }), ); - const safeCodexControlRequest = vi.fn(async (configForTest, _method, requestParams) => ({ + const safeCodexControlRequest = vi.fn(async (configForTest, _method, requestParamsLocal) => ({ ok: true as const, value: { threadId: - requestParams && typeof requestParams === "object" && "threadId" in requestParams - ? requestParams.threadId + requestParamsLocal && + typeof requestParamsLocal === "object" && + "threadId" in requestParamsLocal + ? requestParamsLocal.threadId : undefined, }, })); diff --git a/extensions/copilot/harness.test.ts b/extensions/copilot/harness.test.ts index 6bbcb75a735..f5c97a1ba9b 100644 --- a/extensions/copilot/harness.test.ts +++ b/extensions/copilot/harness.test.ts @@ -280,7 +280,7 @@ describe("createCopilotAgentHarness", () => { await expect(firstDispose).resolves.toBeUndefined(); await expect(secondDispose).resolves.toBeUndefined(); - expect(pool.dispose).toHaveBeenCalledTimes(1); + expect(pool["dispose"]).toHaveBeenCalledTimes(1); }); it("dispose waits for in-flight runAttempt before disposing", async () => { @@ -301,14 +301,14 @@ describe("createCopilotAgentHarness", () => { await flushAsyncWork(); - expect(pool.dispose).not.toHaveBeenCalled(); + expect(pool["dispose"]).not.toHaveBeenCalled(); expect(disposeSettled).toBe(false); deferred.resolve(ATTEMPT_RESULT); await expect(attemptPromise).resolves.toBe(ATTEMPT_RESULT); await expect(disposePromise).resolves.toBeUndefined(); - expect(pool.dispose).toHaveBeenCalledTimes(1); + expect(pool["dispose"]).toHaveBeenCalledTimes(1); }); it("runAttempt after dispose rejects without creating a new pool", async () => { @@ -348,7 +348,7 @@ describe("createCopilotAgentHarness", () => { await harness.runAttempt(ATTEMPT_PARAMS); await expect(harness.dispose?.()).resolves.toBeUndefined(); - expect(pool.dispose).not.toHaveBeenCalled(); + expect(pool["dispose"]).not.toHaveBeenCalled(); }); it("uses options.pool when supplied", async () => { @@ -1170,7 +1170,7 @@ describe("createCopilotAgentHarness", () => { describe("runSideQuestion", () => { it("is not implemented; /btw falls through to the in-tree PI fallback path", () => { const harness = createCopilotAgentHarness({ pool: makePoolMock() }); - expect(harness.runSideQuestion).toBeUndefined(); + expect(harness["runSideQuestion"]).toBeUndefined(); }); }); }); diff --git a/extensions/copilot/src/attempt.test.ts b/extensions/copilot/src/attempt.test.ts index fa28be0d818..0c17bbb28c6 100644 --- a/extensions/copilot/src/attempt.test.ts +++ b/extensions/copilot/src/attempt.test.ts @@ -560,8 +560,7 @@ describe("runCopilotAttempt", () => { expect(sdk.resumeSession).toHaveBeenCalledTimes(1); expect(sdk.resumeSession.mock.calls[0]?.[0]).toBe("resume-1"); expect( - (sdk.resumeSession.mock.calls[0]?.[1] as { continuePendingWork?: boolean }) - .continuePendingWork, + (sdk.resumeSession.mock.calls[0][1] as { continuePendingWork?: boolean }).continuePendingWork, ).toBe(false); expect(sdk.createSession).toHaveBeenCalledTimes(0); }); @@ -754,7 +753,7 @@ describe("runCopilotAttempt", () => { expect(result.aborted).toBe(true); expect(result.externalAbort).toBe(true); expect(sdk.createSession).toHaveBeenCalledTimes(0); - expect(pool.acquire).toHaveBeenCalledTimes(0); + expect(pool["acquire"]).toHaveBeenCalledTimes(0); }); it("abort path (signal fires after settled)", async () => { @@ -810,7 +809,7 @@ describe("runCopilotAttempt", () => { expect(bridgeCall.attemptParams).toBeDefined(); expect(bridgeCall.sessionRef).toBeDefined(); expect( - ((sdk.createSession.mock.calls[0] as unknown[] | undefined)?.[0] as { tools?: unknown[] }) + ((sdk.createSession.mock.calls[0] as unknown[] | undefined)![0] as { tools?: unknown[] }) .tools, ).toBe(sdkTools); }); @@ -930,8 +929,8 @@ describe("runCopilotAttempt", () => { "[copilot-attempt] tool-bridge construction failed: bridge failed", ); expect(sdk.createSession).toHaveBeenCalledTimes(0); - expect(pool.acquire).toHaveBeenCalledTimes(0); - expect(pool.release).toHaveBeenCalledTimes(0); + expect(pool["acquire"]).toHaveBeenCalledTimes(0); + expect(pool["release"]).toHaveBeenCalledTimes(0); }); it("unsupported providers skip injected tool bridge wiring", async () => { @@ -958,7 +957,7 @@ describe("runCopilotAttempt", () => { await runCopilotAttempt(makeParams(), { pool }); const handler = ( - (sdk.createSession.mock.calls[0] as unknown[] | undefined)?.[0] as { + (sdk.createSession.mock.calls[0] as unknown[] | undefined)![0] as { onPermissionRequest: ( request: { kind: string }, invocation: { sessionId: string }, @@ -1371,8 +1370,8 @@ describe("runCopilotAttempt", () => { expect(getPromptErrorCode(result)).toBe("model_not_supported"); expect(sdk.createSession).toHaveBeenCalledTimes(0); - expect(pool.acquire).toHaveBeenCalledTimes(0); - expect(pool.release).toHaveBeenCalledTimes(0); + expect(pool["acquire"]).toHaveBeenCalledTimes(0); + expect(pool["release"]).toHaveBeenCalledTimes(0); }); it("acquire failure", async () => { @@ -1387,7 +1386,7 @@ describe("runCopilotAttempt", () => { expect(result.promptError).toBe(error); expect(sdk.createSession).toHaveBeenCalledTimes(0); - expect(pool.release).toHaveBeenCalledTimes(0); + expect(pool["release"]).toHaveBeenCalledTimes(0); }); it("release failure after a successful send rejects the attempt", async () => { @@ -1449,7 +1448,7 @@ describe("runCopilotAttempt", () => { const session = sdk.sessions[0]; expect(session.off).toHaveBeenCalledTimes(session.on.mock.calls.length); expect(session.disconnect).toHaveBeenCalledTimes(1); - expect(pool.release).toHaveBeenCalledTimes(1); + expect(pool["release"]).toHaveBeenCalledTimes(1); }); it("cleanup on send error", async () => { @@ -1467,7 +1466,7 @@ describe("runCopilotAttempt", () => { expect(result.promptError).toBe(error); expect(session.off).toHaveBeenCalledTimes(session.on.mock.calls.length); expect(session.disconnect).toHaveBeenCalledTimes(1); - expect(pool.release).toHaveBeenCalledTimes(1); + expect(pool["release"]).toHaveBeenCalledTimes(1); }); it("cleanup on disconnect throw", async () => { @@ -1504,10 +1503,10 @@ describe("runCopilotAttempt", () => { { pool }, ); - const key = (vi.mocked(pool.acquire).mock.calls[0] as unknown[] | undefined)?.[0] as { + const key = (vi.mocked(pool["acquire"]).mock.calls[0] as unknown[] | undefined)?.[0] as { authMode: string; }; - const options = (vi.mocked(pool.acquire).mock.calls[0] as unknown[] | undefined)?.[1] as { + const options = (vi.mocked(pool["acquire"]).mock.calls[0] as unknown[] | undefined)?.[1] as { gitHubToken?: string; useLoggedInUser?: boolean; }; @@ -1525,7 +1524,7 @@ describe("runCopilotAttempt", () => { ).rejects.toThrow( "[copilot-attempt] gitHubToken auth requires profileId+profileVersion (pool keying safety; per Q5/Q1 decisions)", ); - expect(pool.acquire).toHaveBeenCalledTimes(0); + expect(pool["acquire"]).toHaveBeenCalledTimes(0); expect(sdk.createSession).toHaveBeenCalledTimes(0); }); @@ -1540,12 +1539,12 @@ describe("runCopilotAttempt", () => { { pool }, ); - const key = (vi.mocked(pool.acquire).mock.calls[0] as unknown[] | undefined)?.[0] as { + const key = (vi.mocked(pool["acquire"]).mock.calls[0] as unknown[] | undefined)?.[0] as { authMode: string; authProfileId?: string; authProfileVersion?: string; }; - const options = (vi.mocked(pool.acquire).mock.calls[0] as unknown[] | undefined)?.[1] as { + const options = (vi.mocked(pool["acquire"]).mock.calls[0] as unknown[] | undefined)?.[1] as { gitHubToken?: string; useLoggedInUser?: boolean; }; @@ -1926,12 +1925,12 @@ describe("runCopilotAttempt", () => { const calls = dualWriteMock.dualWriteCopilotTranscriptBestEffort.mock.calls; const id1 = ( - calls[0]?.[0] as { + calls[0][0] as { messages: Array<{ role: string; __openclaw?: { mirrorIdentity?: string } }>; } ).messages.find((m) => m.role === "user")?.["__openclaw"]?.mirrorIdentity; const id2 = ( - calls[1]?.[0] as { + calls[1][0] as { messages: Array<{ role: string; __openclaw?: { mirrorIdentity?: string } }>; } ).messages.find((m) => m.role === "user")?.["__openclaw"]?.mirrorIdentity; diff --git a/extensions/copilot/src/auth-bridge.test.ts b/extensions/copilot/src/auth-bridge.test.ts index eb835eb69d9..459de13d5fe 100755 --- a/extensions/copilot/src/auth-bridge.test.ts +++ b/extensions/copilot/src/auth-bridge.test.ts @@ -1,6 +1,6 @@ import { createHash } from "node:crypto"; -import { resolve, join } from "node:path"; -import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; +import { join, resolve } from "node:path"; +import { afterEach, beforeEach, describe, expect, it } from "vitest"; import { COPILOT_DEFAULT_AGENT_ID, COPILOT_TOKEN_PROFILE_ERROR, diff --git a/extensions/copilot/src/hooks-bridge.test.ts b/extensions/copilot/src/hooks-bridge.test.ts index 8d3b6a273c4..d6644012fd4 100755 --- a/extensions/copilot/src/hooks-bridge.test.ts +++ b/extensions/copilot/src/hooks-bridge.test.ts @@ -70,7 +70,7 @@ describe("createHooksBridge", () => { hookName: "onPostToolUse", error: expect.any(Error), }); - expect((onHookError.mock.calls[0]?.[0]?.error as Error).message).toBe("post boom"); + expect((onHookError.mock.calls[0][0]!.error as Error).message).toBe("post boom"); }); it("isolates async rejections: returns undefined and notifies onHookError", async () => { diff --git a/extensions/copilot/src/telemetry-bridge.test.ts b/extensions/copilot/src/telemetry-bridge.test.ts index 9c2af2814a1..d3999eb2c68 100755 --- a/extensions/copilot/src/telemetry-bridge.test.ts +++ b/extensions/copilot/src/telemetry-bridge.test.ts @@ -164,7 +164,7 @@ describe("createTraceContextProvider", () => { }); await expect(provider()).resolves.toEqual({}); expect(onError).toHaveBeenCalledTimes(1); - expect((onError.mock.calls[0]?.[0] as CopilotTraceContextErrorInfo).part).toBe("traceparent"); + expect((onError.mock.calls[0][0] as CopilotTraceContextErrorInfo).part).toBe("traceparent"); }); it("getTracestate failure → partial success (traceparent kept) + notifier called", async () => { @@ -180,7 +180,7 @@ describe("createTraceContextProvider", () => { traceparent: "00-aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-bbbbbbbbbbbbbbbb-01", }); expect(onError).toHaveBeenCalledTimes(1); - expect((onError.mock.calls[0]?.[0] as CopilotTraceContextErrorInfo).part).toBe("tracestate"); + expect((onError.mock.calls[0][0] as CopilotTraceContextErrorInfo).part).toBe("tracestate"); }); it("default notifier uses console.warn", async () => { diff --git a/extensions/deepseek/index.test.ts b/extensions/deepseek/index.test.ts index c3a9d78cec1..6711f0ca917 100644 --- a/extensions/deepseek/index.test.ts +++ b/extensions/deepseek/index.test.ts @@ -484,7 +484,7 @@ describe("deepseek provider plugin", () => { expect(readThinking(capture.payload)?.type).toBe("disabled"); expect(capture.payload).not.toHaveProperty("reasoning_effort"); - expect((capture.payload?.messages as Array>)[1]).not.toHaveProperty( + expect((capture.payload!.messages as Array>)[1]).not.toHaveProperty( "reasoning_content", ); }); diff --git a/extensions/diffs/src/browser.ts b/extensions/diffs/src/browser.ts index a41f77804db..90b284e6879 100644 --- a/extensions/diffs/src/browser.ts +++ b/extensions/diffs/src/browser.ts @@ -176,15 +176,15 @@ export class PlaywrightDiffScreenshotter implements DiffScreenshotter { await page.evaluate(() => { const html = document.documentElement; const body = document.body; - const frame = document.querySelector(".oc-frame"); + const frameLocal = document.querySelector(".oc-frame"); html.style.background = "transparent"; body.style.margin = "0"; body.style.padding = "0"; body.style.background = "transparent"; body.style.setProperty("-webkit-print-color-adjust", "exact"); - if (frame instanceof HTMLElement) { - frame.style.margin = "0"; + if (frameLocal instanceof HTMLElement) { + frameLocal.style.margin = "0"; } }); diff --git a/extensions/diffs/src/tool-render-output.test.ts b/extensions/diffs/src/tool-render-output.test.ts index 2dadb1a3048..33edfda98c5 100644 --- a/extensions/diffs/src/tool-render-output.test.ts +++ b/extensions/diffs/src/tool-render-output.test.ts @@ -67,8 +67,8 @@ describe("diffs tool rendered output guards", () => { mode: "file", }); - expect(screenshotter.screenshotHtml).toHaveBeenCalledTimes(1); - expect((result?.details as Record).filePath).toMatch(/preview\.png$/); + expect(screenshotter["screenshotHtml"]).toHaveBeenCalledTimes(1); + expect((result.details as Record).filePath).toMatch(/preview\.png$/); }); }); diff --git a/extensions/diffs/src/tool.test.ts b/extensions/diffs/src/tool.test.ts index 96d2e71073a..c566c01380b 100644 --- a/extensions/diffs/src/tool.test.ts +++ b/extensions/diffs/src/tool.test.ts @@ -63,7 +63,7 @@ describe("diffs tool", () => { expect(readTextContent(result, 0)).toContain( "https://example.com/openclaw/plugins/diffs/view/", ); - expect(String((result?.details as Record).viewerUrl)).toContain( + expect(String((result.details as Record).viewerUrl)).toContain( "https://example.com/openclaw/plugins/diffs/view/", ); }); @@ -89,7 +89,7 @@ describe("diffs tool", () => { expect(readTextContent(result, 0)).toContain( "https://preview.example.com/review/plugins/diffs/view/", ); - expect(String((result?.details as Record).viewerUrl)).toContain( + expect(String((result.details as Record).viewerUrl)).toContain( "https://preview.example.com/review/plugins/diffs/view/", ); }); @@ -127,7 +127,7 @@ describe("diffs tool", () => { mode: "image", }); - expect(screenshotter.screenshotHtml).toHaveBeenCalledTimes(1); + expect(screenshotter["screenshotHtml"]).toHaveBeenCalledTimes(1); expect(readTextContent(result, 0)).toContain("Diff PNG generated at:"); expect(readTextContent(result, 0)).toContain("Use the `message` tool"); expect(result?.content).toHaveLength(1); @@ -166,10 +166,10 @@ describe("diffs tool", () => { fileFormat: "pdf", }); - expect(screenshotter.screenshotHtml).toHaveBeenCalledTimes(1); + expect(screenshotter["screenshotHtml"]).toHaveBeenCalledTimes(1); expect(readTextContent(result, 0)).toContain("Diff PDF generated at:"); - expect((result?.details as Record).format).toBe("pdf"); - expect((result?.details as Record).filePath).toMatch(/preview\.pdf$/); + expect((result.details as Record).format).toBe("pdf"); + expect((result.details as Record).filePath).toMatch(/preview\.pdf$/); }); it("accepts mode=file as an alias for file artifact rendering", async () => { @@ -258,7 +258,7 @@ describe("diffs tool", () => { after: "two\n", mode: "file", }); - const filePath = (result?.details as Record).filePath as string; + const filePath = (result.details as Record).filePath as string; const stat = await fs.stat(filePath); expect(stat.isFile()).toBe(true); @@ -290,9 +290,9 @@ describe("diffs tool", () => { imageMaxWidth: "1100", }); - expect((result?.details as Record).fileQuality).toBe("hq"); - expect((result?.details as Record).fileScale).toBe(2.4); - expect((result?.details as Record).fileMaxWidth).toBe(1100); + expect((result.details as Record).fileQuality).toBe("hq"); + expect((result.details as Record).fileScale).toBe(2.4); + expect((result.details as Record).fileMaxWidth).toBe(1100); }); it("accepts deprecated format alias for fileFormat", async () => { @@ -312,8 +312,8 @@ describe("diffs tool", () => { format: "pdf", }); - expect((result?.details as Record).fileFormat).toBe("pdf"); - expect((result?.details as Record).filePath).toMatch(/preview\.pdf$/); + expect((result.details as Record).fileFormat).toBe("pdf"); + expect((result.details as Record).filePath).toMatch(/preview\.pdf$/); }); it("honors defaults.mode=file when mode is omitted", async () => { @@ -351,8 +351,8 @@ describe("diffs tool", () => { expect(result?.content).toHaveLength(1); expect(readTextContent(result, 0)).toContain("File rendering failed"); - expect((result?.details as Record).fileError).toBe("browser missing"); - expect((result?.details as Record).imageError).toBe("browser missing"); + expect((result.details as Record).fileError).toBe("browser missing"); + expect((result.details as Record).imageError).toBe("browser missing"); }); it("rejects invalid base URLs as tool input errors", async () => { @@ -433,15 +433,15 @@ describe("diffs tool", () => { }); expect(readTextContent(result, 0)).toContain("Diff viewer ready."); - expect((result?.details as Record).mode).toBe("view"); - expect((result?.details as Record).context).toEqual({ + expect((result.details as Record).mode).toBe("view"); + expect((result.details as Record).context).toEqual({ agentId: "main", sessionId: "session-123", messageChannel: "discord", agentAccountId: "default", }); - const viewerPath = String((result?.details as Record).viewerPath); + const viewerPath = String((result.details as Record).viewerPath); const id = extractViewerArtifactId(viewerPath); const html = await store.readHtml(id); expect(html).toContain('body data-theme="light"'); @@ -482,13 +482,13 @@ describe("diffs tool", () => { fileMaxWidth: 1320, }); - expect((result?.details as Record).mode).toBe("both"); - expect(screenshotter.screenshotHtml).toHaveBeenCalledTimes(1); - expect((result?.details as Record).format).toBe("png"); - expect((result?.details as Record).fileQuality).toBe("print"); - expect((result?.details as Record).fileScale).toBe(2.75); - expect((result?.details as Record).fileMaxWidth).toBe(1320); - const viewerPath = String((result?.details as Record).viewerPath); + expect((result.details as Record).mode).toBe("both"); + expect(screenshotter["screenshotHtml"]).toHaveBeenCalledTimes(1); + expect((result.details as Record).format).toBe("png"); + expect((result.details as Record).fileQuality).toBe("print"); + expect((result.details as Record).fileScale).toBe(2.75); + expect((result.details as Record).fileMaxWidth).toBe(1320); + const viewerPath = String((result.details as Record).viewerPath); const id = extractViewerArtifactId(viewerPath); const html = await store.readHtml(id); expect(html).toContain('body data-theme="dark"'); @@ -509,7 +509,7 @@ describe("diffs tool", () => { mode: "file", }); - expect((result?.details as Record).context).toEqual({ + expect((result.details as Record).context).toEqual({ agentId: "reviewer", sessionId: "session-456", messageChannel: "telegram", @@ -559,9 +559,9 @@ function expectArtifactOnlyFileResult( screenshotter: DiffScreenshotter, result: { details?: unknown } | null | undefined, ) { - expect(screenshotter.screenshotHtml).toHaveBeenCalledTimes(1); - expect((result?.details as Record).mode).toBe("file"); - expect((result?.details as Record).viewerUrl).toBeUndefined(); + expect(screenshotter["screenshotHtml"]).toHaveBeenCalledTimes(1); + expect((result!.details as Record).mode).toBe("file"); + expect((result!.details as Record).viewerUrl).toBeUndefined(); } function createPngScreenshotter( diff --git a/extensions/discord/src/actions/handle-action.guild-admin.ts b/extensions/discord/src/actions/handle-action.guild-admin.ts index e46cae2d7de..af39650eb45 100644 --- a/extensions/discord/src/actions/handle-action.guild-admin.ts +++ b/extensions/discord/src/actions/handle-action.guild-admin.ts @@ -355,7 +355,7 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: { message: "deleteDays must be an integer from 0 to 7", }), }); - const senderUserId = normalizeOptionalString(ctx.requesterSenderId); + const senderUserIdLocal = normalizeOptionalString(ctx.requesterSenderId); return await handleDiscordAction( { action: moderation.action, @@ -366,7 +366,7 @@ export async function tryHandleDiscordMessageActionGuildAdmin(params: { until: moderation.until, reason: moderation.reason, deleteMessageDays: moderation.deleteMessageDays, - senderUserId, + senderUserId: senderUserIdLocal, }, cfg, ); diff --git a/extensions/discord/src/channel.test.ts b/extensions/discord/src/channel.test.ts index 662dd6982aa..bd4d7f711ab 100644 --- a/extensions/discord/src/channel.test.ts +++ b/extensions/discord/src/channel.test.ts @@ -548,8 +548,8 @@ describe("discordPlugin outbound", () => { }) => void) | undefined; probeDiscordMock.mockReturnValue( - new Promise((resolve) => { - resolveProbe = resolve; + new Promise((resolveLocal) => { + resolveProbe = resolveLocal; }), ); monitorDiscordProviderMock.mockResolvedValue(undefined); diff --git a/extensions/discord/src/channel.ts b/extensions/discord/src/channel.ts index bf54916b232..3b8ba58e87e 100644 --- a/extensions/discord/src/channel.ts +++ b/extensions/discord/src/channel.ts @@ -394,10 +394,10 @@ export const discordPlugin: ChannelPlugin token: account.token, inputs, missingTokenNote: "missing Discord token", - resolveWithToken: async ({ token, inputs }) => + resolveWithToken: async ({ token, inputs: inputsValue }) => (await loadDiscordResolveChannelsModule()).resolveDiscordChannelAllowlist({ token, - entries: inputs, + entries: inputsValue, }), mapResolved: (entry) => ({ input: entry.input, @@ -415,10 +415,10 @@ export const discordPlugin: ChannelPlugin token: account.token, inputs, missingTokenNote: "missing Discord token", - resolveWithToken: async ({ token, inputs }) => + resolveWithToken: async ({ token, inputs: inputsLocal }) => (await loadDiscordResolveUsersModule()).resolveDiscordUserAllowlist({ token, - entries: inputs, + entries: inputsLocal, }), mapResolved: (entry) => ({ input: entry.input, diff --git a/extensions/discord/src/components.builders.ts b/extensions/discord/src/components.builders.ts index 722fcecaeab..7e4a416c0e1 100644 --- a/extensions/discord/src/components.builders.ts +++ b/extensions/discord/src/components.builders.ts @@ -390,7 +390,7 @@ export function buildDiscordComponentMessage(params: { const lastChild = containerChildren.at(-1); if (lastChild instanceof Row) { const row = lastChild; - const hasSelect = row.components.some((entry) => isSelectComponent(entry)); + const hasSelect = row.components.some((entryLocal) => isSelectComponent(entryLocal)); if (row.components.length < 5 && !hasSelect) { row.addComponent(component as Button); } else { diff --git a/extensions/discord/src/internal/command-deploy.ts b/extensions/discord/src/internal/command-deploy.ts index 0eb54ba9453..0db9d208dda 100644 --- a/extensions/discord/src/internal/command-deploy.ts +++ b/extensions/discord/src/internal/command-deploy.ts @@ -238,10 +238,10 @@ const optionComparisonOmittedFields = new Set([ ]); const nullableLocalizationFields = new Set(["description_localizations", "name_localizations"]); -function stableComparableObject(value: unknown, path: string[] = []): unknown { +function stableComparableObject(value: unknown, pathValue: string[] = []): unknown { if (Array.isArray(value)) { - const normalized = value.map((entry) => stableComparableObject(entry, path)); - const key = path.at(-1); + const normalized = value.map((entry) => stableComparableObject(entry, pathValue)); + const key = pathValue.at(-1); if ( key && unorderedCommandArrayFields.has(key) && @@ -266,7 +266,7 @@ function stableComparableObject(value: unknown, path: string[] = []): unknown { if (entry === null && nullableLocalizationFields.has(key)) { return false; } - if (path.includes("options") && optionComparisonOmittedFields.has(key)) { + if (pathValue.includes("options") && optionComparisonOmittedFields.has(key)) { return false; } if ((key === "required" || key === "autocomplete") && entry === false) { @@ -277,21 +277,21 @@ function stableComparableObject(value: unknown, path: string[] = []): unknown { .toSorted(([a], [b]) => a.localeCompare(b)) .map(([key, entry]) => [ key, - shouldNormalizeDescriptionValue(path, key, entry) + shouldNormalizeDescriptionValue(pathValue, key, entry) ? normalizeDescriptionForComparison(entry) - : stableComparableObject(entry, [...path, key]), + : stableComparableObject(entry, [...pathValue, key]), ]), ); } function shouldNormalizeDescriptionValue( - path: string[], + pathLocal: string[], key: string, entry: unknown, ): entry is string { return ( typeof entry === "string" && - (key === "description" || path.at(-1) === "description_localizations") + (key === "description" || pathLocal.at(-1) === "description_localizations") ); } diff --git a/extensions/discord/src/internal/gateway.test.ts b/extensions/discord/src/internal/gateway.test.ts index 2de7e776291..917e876ebee 100644 --- a/extensions/discord/src/internal/gateway.test.ts +++ b/extensions/discord/src/internal/gateway.test.ts @@ -303,7 +303,7 @@ describe("GatewayPlugin", () => { it("preserves MESSAGE_CREATE author payloads for inbound dispatch", async () => { const gateway = new GatewayPlugin({ autoInteractions: false }); - const dispatchGatewayEvent = vi.fn(async (eventValue: string, dataValue: unknown) => {}); + const dispatchGatewayEvent = vi.fn(async (_eventValue: string, _dataValue: unknown) => {}); (gateway as unknown as { client: unknown }).client = { dispatchGatewayEvent, }; diff --git a/extensions/discord/src/internal/rest.test.ts b/extensions/discord/src/internal/rest.test.ts index fc8cabc87ce..98f029465e6 100644 --- a/extensions/discord/src/internal/rest.test.ts +++ b/extensions/discord/src/internal/rest.test.ts @@ -717,7 +717,7 @@ describe("RequestClient", () => { it("dispatches multipart uploads with a multipart/form-data content type", async () => { const fetchSpy = vi.fn(async (_input: string | URL | Request, init?: RequestInit) => { expect(init?.headers).toBeInstanceOf(Headers); - expect((init?.headers as Headers).get("Content-Type")).toMatch( + expect((init!.headers as Headers).get("Content-Type")).toMatch( /^multipart\/form-data; boundary=/, ); expect(init?.body).not.toBeInstanceOf(FormData); diff --git a/extensions/discord/src/monitor/agent-components-dm-auth.ts b/extensions/discord/src/monitor/agent-components-dm-auth.ts index f80da094a03..8eaae167d5c 100644 --- a/extensions/discord/src/monitor/agent-components-dm-auth.ts +++ b/extensions/discord/src/monitor/agent-components-dm-auth.ts @@ -45,11 +45,11 @@ async function ensureDmComponentAuthorized(params: { allowNameMatching: isDangerousNameMatchingEnabled(ctx.discordConfig), cfg: ctx.cfg, token: ctx.token, - readStoreAllowFrom: async ({ accountId, dmPolicy }) => + readStoreAllowFrom: async ({ accountId, dmPolicy: dmPolicyLocal }) => await readChannelIngressStoreAllowFromForDmPolicy({ provider: "discord", accountId, - dmPolicy, + dmPolicy: dmPolicyLocal, }), eventKind: "button", }); diff --git a/extensions/discord/src/monitor/allow-list.ts b/extensions/discord/src/monitor/allow-list.ts index 9411505aa57..c28aad72d50 100644 --- a/extensions/discord/src/monitor/allow-list.ts +++ b/extensions/discord/src/monitor/allow-list.ts @@ -71,7 +71,7 @@ export function normalizeDiscordAllowList(raw: string[] | undefined, prefixes: s ids.add(maybeId); continue; } - const prefix = prefixes.find((entry) => text.startsWith(entry)); + const prefix = prefixes.find((entryLocal) => text.startsWith(entryLocal)); if (prefix) { const candidate = text.slice(prefix.length); if (candidate) { diff --git a/extensions/discord/src/monitor/exec-approvals.test.ts b/extensions/discord/src/monitor/exec-approvals.test.ts index 95a22c06196..78bf961137a 100644 --- a/extensions/discord/src/monitor/exec-approvals.test.ts +++ b/extensions/discord/src/monitor/exec-approvals.test.ts @@ -92,7 +92,7 @@ describe("discord exec approval monitor helpers", () => { await button.run(interaction, { id: "", action: "" }); - expect(interaction.reply).toHaveBeenCalledWith({ + expect(interaction["reply"]).toHaveBeenCalledWith({ content: "This approval is no longer valid.", ephemeral: true, }); @@ -107,7 +107,7 @@ describe("discord exec approval monitor helpers", () => { await button.run(interaction, { id: "abc", action: "allow-once" }); - expect(interaction.reply).toHaveBeenCalledWith({ + expect(interaction["reply"]).toHaveBeenCalledWith({ content: "⛔ You are not authorized to approve exec requests.", ephemeral: true, }); @@ -123,9 +123,9 @@ describe("discord exec approval monitor helpers", () => { await button.run(interaction, { id: "abc", action: "allow-once" }); - expect(interaction.acknowledge).toHaveBeenCalled(); + expect(interaction["acknowledge"]).toHaveBeenCalled(); expect(resolveApproval).toHaveBeenCalledWith("abc", "allow-once"); - expect(interaction.followUp).not.toHaveBeenCalled(); + expect(interaction["followUp"]).not.toHaveBeenCalled(); }); it("shows a follow-up when gateway resolution fails", async () => { @@ -137,7 +137,7 @@ describe("discord exec approval monitor helpers", () => { await button.run(interaction, { id: "abc", action: "deny" }); - expect(interaction.followUp).toHaveBeenCalledWith({ + expect(interaction["followUp"]).toHaveBeenCalledWith({ content: "Failed to submit approval decision for **Denied**. The request may have expired or already been resolved.", ephemeral: true, @@ -153,8 +153,8 @@ describe("discord exec approval monitor helpers", () => { await button.run(interaction, { id: "abc", action: "allow-once" }); - expect(interaction.acknowledge).toHaveBeenCalled(); - expect(interaction.followUp).toHaveBeenCalledWith({ + expect(interaction["acknowledge"]).toHaveBeenCalled(); + expect(interaction["followUp"]).toHaveBeenCalledWith({ content: "That approval request is no longer pending. It may have expired or already been resolved.", ephemeral: true, diff --git a/extensions/discord/src/monitor/gateway-plugin.test.ts b/extensions/discord/src/monitor/gateway-plugin.test.ts index 42fcb954147..94d87e8acc0 100644 --- a/extensions/discord/src/monitor/gateway-plugin.test.ts +++ b/extensions/discord/src/monitor/gateway-plugin.test.ts @@ -3,7 +3,7 @@ import { beforeAll, describe, expect, it, vi } from "vitest"; import { DISCORD_GATEWAY_TRANSPORT_ACTIVITY_EVENT } from "./gateway-handle.js"; const { GatewayIntents, GatewayPlugin } = vi.hoisted(() => { - const GatewayIntents = { + const GatewayIntentsLocal = { Guilds: 1 << 0, GuildMessages: 1 << 1, MessageContent: 1 << 2, @@ -31,7 +31,7 @@ const { GatewayIntents, GatewayPlugin } = vi.hoisted(() => { } } - class GatewayPlugin { + class GatewayPluginLocal { options: unknown; gatewayInfo: unknown; emitter = new TestEmitter(); @@ -44,12 +44,12 @@ const { GatewayIntents, GatewayPlugin } = vi.hoisted(() => { this.options = options; } - async registerClient(clientForTest: unknown): Promise {} + async registerClient(_clientForTest: unknown): Promise {} connect(_resume = false): void {} } - return { GatewayIntents, GatewayPlugin }; + return { GatewayIntents: GatewayIntentsLocal, GatewayPlugin: GatewayPluginLocal }; }); vi.mock("../internal/gateway.js", () => ({ diff --git a/extensions/discord/src/monitor/native-command-reply.ts b/extensions/discord/src/monitor/native-command-reply.ts index 64d2cd1d691..5d5a50c5120 100644 --- a/extensions/discord/src/monitor/native-command-reply.ts +++ b/extensions/discord/src/monitor/native-command-reply.ts @@ -92,7 +92,7 @@ export async function deliverDiscordInteractionReply(params: { components?: TopLevelComponents[], ) => { const contentPayload = content ? { content } : {}; - const payload = + const payloadLocal = files && files.length > 0 ? { ...contentPayload, @@ -117,12 +117,12 @@ export async function deliverDiscordInteractionReply(params: { }; await safeDiscordInteractionCall("interaction send", async () => { if (!preferFollowUp && !hasReplied) { - await interaction.reply(payload); + await interaction.reply(payloadLocal); hasReplied = true; firstMessageComponents = undefined; return; } - await interaction.followUp(payload); + await interaction.followUp(payloadLocal); hasReplied = true; firstMessageComponents = undefined; }); diff --git a/extensions/discord/src/monitor/provider.lifecycle.test.ts b/extensions/discord/src/monitor/provider.lifecycle.test.ts index e9d4fdb3590..e6cda6c96a3 100644 --- a/extensions/discord/src/monitor/provider.lifecycle.test.ts +++ b/extensions/discord/src/monitor/provider.lifecycle.test.ts @@ -29,17 +29,17 @@ const { unregisterGatewayMock, waitForDiscordGatewayStopMock, } = vi.hoisted(() => { - const stopGatewayLoggingMock = vi.fn(); - const getDiscordGatewayEmitterMock = vi.fn<() => EventEmitter | undefined>(() => undefined); + const stopGatewayLoggingMockLocal = vi.fn(); + const getDiscordGatewayEmitterMockLocal = vi.fn<() => EventEmitter | undefined>(() => undefined); return { - attachDiscordGatewayLoggingMock: vi.fn(() => stopGatewayLoggingMock), - getDiscordGatewayEmitterMock, + attachDiscordGatewayLoggingMock: vi.fn(() => stopGatewayLoggingMockLocal), + getDiscordGatewayEmitterMock: getDiscordGatewayEmitterMockLocal, waitForDiscordGatewayStopMock: vi.fn((_params: WaitForDiscordGatewayStopParams) => Promise.resolve(), ), registerGatewayMock: vi.fn(), unregisterGatewayMock: vi.fn(), - stopGatewayLoggingMock, + stopGatewayLoggingMock: stopGatewayLoggingMockLocal, }; }); diff --git a/extensions/discord/src/monitor/provider.proxy.test.ts b/extensions/discord/src/monitor/provider.proxy.test.ts index ca9aa6405e3..e83d5c733f1 100644 --- a/extensions/discord/src/monitor/provider.proxy.test.ts +++ b/extensions/discord/src/monitor/provider.proxy.test.ts @@ -46,16 +46,16 @@ const { httpsAgentSpy, wsProxyAgentSpy, } = vi.hoisted(() => { - const wsProxyAgentSpy = vi.fn(); - const httpsAgentSpy = vi.fn(); - const globalFetchMock = vi.fn(); - const baseRegisterClientSpy = vi.fn(); - const webSocketSpy = vi.fn(); - const captureHttpExchangeSpy = vi.fn(); - const captureWsEventSpy = vi.fn(); - const resolveDebugProxySettingsMock = vi.fn(() => ({ enabled: false })); - const fetchWithSsrFGuardMock = vi.fn(async (params: { url: string; init?: RequestInit }) => { - const source = (await globalFetchMock(params.url, params.init)) as Response; + const wsProxyAgentSpyLocal = vi.fn(); + const httpsAgentSpyLocal = vi.fn(); + const globalFetchMockLocal = vi.fn(); + const baseRegisterClientSpyLocal = vi.fn(); + const webSocketSpyLocal = vi.fn(); + const captureHttpExchangeSpyLocal = vi.fn(); + const captureWsEventSpyLocal = vi.fn(); + const resolveDebugProxySettingsMockLocal = vi.fn(() => ({ enabled: false })); + const fetchWithSsrFGuardMockLocal = vi.fn(async (params: { url: string; init?: RequestInit }) => { + const source = (await globalFetchMockLocal(params.url, params.init)) as Response; const body = await source.text(); return { response: new Response(body, { @@ -67,7 +67,7 @@ const { }; }); - const GatewayIntents = { + const GatewayIntentsLocal = { Guilds: 1 << 0, GuildMessages: 1 << 1, MessageContent: 1 << 2, @@ -79,7 +79,7 @@ const { GuildVoiceStates: 1 << 8, } as const; - class GatewayPlugin { + class GatewayPluginLocal { options: unknown; gatewayInfo: unknown; client: unknown; @@ -93,53 +93,53 @@ const { this.isConnecting = false; } async registerClient(client: unknown) { - baseRegisterClientSpy(client); + baseRegisterClientSpyLocal(client); } } - class HttpsAgent { - static lastCreated: HttpsAgent | undefined; + class HttpsAgentLocal { + static lastCreated: HttpsAgentLocal | undefined; options: unknown; constructor(options?: unknown) { this.options = options; - HttpsAgent.lastCreated = this; - httpsAgentSpy(options); + HttpsAgentLocal.lastCreated = this; + httpsAgentSpyLocal(options); } } - class HttpsProxyAgent { - static lastCreated: HttpsProxyAgent | undefined; + class HttpsProxyAgentLocal { + static lastCreated: HttpsProxyAgentLocal | undefined; proxyUrl: string; constructor(proxyUrl: string) { if (proxyUrl === "bad-proxy") { throw new Error("bad proxy"); } this.proxyUrl = proxyUrl; - HttpsProxyAgent.lastCreated = this; - wsProxyAgentSpy(proxyUrl); + HttpsProxyAgentLocal.lastCreated = this; + wsProxyAgentSpyLocal(proxyUrl); } } return { - baseRegisterClientSpy, - GatewayIntents, - GatewayPlugin, - globalFetchMock, - HttpsAgent, - HttpsProxyAgent, - fetchWithSsrFGuardMock, - getLastAgent: () => HttpsAgent.lastCreated, - getLastProxyAgent: () => HttpsProxyAgent.lastCreated, - captureHttpExchangeSpy, - captureWsEventSpy, - httpsAgentSpy, - resolveDebugProxySettingsMock, + baseRegisterClientSpy: baseRegisterClientSpyLocal, + GatewayIntents: GatewayIntentsLocal, + GatewayPlugin: GatewayPluginLocal, + globalFetchMock: globalFetchMockLocal, + HttpsAgent: HttpsAgentLocal, + HttpsProxyAgent: HttpsProxyAgentLocal, + fetchWithSsrFGuardMock: fetchWithSsrFGuardMockLocal, + getLastAgent: () => HttpsAgentLocal.lastCreated, + getLastProxyAgent: () => HttpsProxyAgentLocal.lastCreated, + captureHttpExchangeSpy: captureHttpExchangeSpyLocal, + captureWsEventSpy: captureWsEventSpyLocal, + httpsAgentSpy: httpsAgentSpyLocal, + resolveDebugProxySettingsMock: resolveDebugProxySettingsMockLocal, resetLastAgent: () => { - HttpsAgent.lastCreated = undefined; - HttpsProxyAgent.lastCreated = undefined; + HttpsAgentLocal.lastCreated = undefined; + HttpsProxyAgentLocal.lastCreated = undefined; }, - webSocketSpy, - wsProxyAgentSpy, + webSocketSpy: webSocketSpyLocal, + wsProxyAgentSpy: wsProxyAgentSpyLocal, }; }); diff --git a/extensions/discord/src/monitor/provider.rest-proxy.test.ts b/extensions/discord/src/monitor/provider.rest-proxy.test.ts index 114ea71480e..129e79c9c85 100644 --- a/extensions/discord/src/monitor/provider.rest-proxy.test.ts +++ b/extensions/discord/src/monitor/provider.rest-proxy.test.ts @@ -5,16 +5,16 @@ import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vite const { undiciFetchMock, agentSpy, envHttpProxyAgentSpy, proxyAgentSpy, createMockUndiciRuntime } = vi.hoisted(() => { - const undiciFetchMock = vi.fn(); - const agentSpy = vi.fn(); - const envHttpProxyAgentSpy = vi.fn(); - const proxyAgentSpy = vi.fn(); - const createMockUndiciRuntime = () => { + const undiciFetchMockLocal = vi.fn(); + const agentSpyLocal = vi.fn(); + const envHttpProxyAgentSpyLocal = vi.fn(); + const proxyAgentSpyLocal = vi.fn(); + const createMockUndiciRuntimeLocal = () => { class Agent { options: unknown; constructor(options?: unknown) { this.options = options; - agentSpy(options); + agentSpyLocal(options); } } class EnvHttpProxyAgent { @@ -31,7 +31,7 @@ const { undiciFetchMock, agentSpy, envHttpProxyAgentSpy, proxyAgentSpy, createMo } } this.options = options; - envHttpProxyAgentSpy(options); + envHttpProxyAgentSpyLocal(options); } } class ProxyAgent { @@ -44,22 +44,22 @@ const { undiciFetchMock, agentSpy, envHttpProxyAgentSpy, proxyAgentSpy, createMo } this.options = resolved; this.uri = resolved.uri; - proxyAgentSpy(resolved); + proxyAgentSpyLocal(resolved); } } return { Agent, EnvHttpProxyAgent, ProxyAgent, - fetch: undiciFetchMock, + fetch: undiciFetchMockLocal, }; }; return { - undiciFetchMock, - agentSpy, - envHttpProxyAgentSpy, - proxyAgentSpy, - createMockUndiciRuntime, + undiciFetchMock: undiciFetchMockLocal, + agentSpy: agentSpyLocal, + envHttpProxyAgentSpy: envHttpProxyAgentSpyLocal, + proxyAgentSpy: proxyAgentSpyLocal, + createMockUndiciRuntime: createMockUndiciRuntimeLocal, }; }); diff --git a/extensions/discord/src/monitor/thread-bindings.manager.ts b/extensions/discord/src/monitor/thread-bindings.manager.ts index c977f6ef015..2529c696b7f 100644 --- a/extensions/discord/src/monitor/thread-bindings.manager.ts +++ b/extensions/discord/src/monitor/thread-bindings.manager.ts @@ -274,8 +274,8 @@ export function createThreadBindingManager(params: { if (!key) { return null; } - const existing = BINDINGS_BY_THREAD_ID.get(key); - if (!existing || existing.accountId !== accountId) { + const existingResult = BINDINGS_BY_THREAD_ID.get(key); + if (!existingResult || existingResult.accountId !== accountId) { return null; } const now = Date.now(); @@ -284,8 +284,8 @@ export function createThreadBindingManager(params: { ? Math.max(0, Math.floor(touchParams.at)) : now; const nextRecord: ThreadBindingRecord = { - ...existing, - lastActivityAt: Math.max(existing.lastActivityAt || 0, at), + ...existingResult, + lastActivityAt: Math.max(existingResult.lastActivityAt || 0, at), }; setBindingRecord(nextRecord); if (touchParams.persist ?? persist) { @@ -342,7 +342,7 @@ export function createThreadBindingManager(params: { return null; } - const existing = manager.getByThreadId(threadId); + const existingValue = manager.getByThreadId(threadId); const targetSessionKey = normalizeOptionalString(bindParams.targetSessionKey) ?? ""; if (!targetSessionKey) { return null; @@ -351,11 +351,11 @@ export function createThreadBindingManager(params: { const targetKind = normalizeTargetKind(bindParams.targetKind, targetSessionKey); let webhookId = normalizeOptionalString(bindParams.webhookId) ?? - normalizeOptionalString(existing?.webhookId) ?? + normalizeOptionalString(existingValue?.webhookId) ?? ""; let webhookToken = normalizeOptionalString(bindParams.webhookToken) ?? - normalizeOptionalString(existing?.webhookToken) ?? + normalizeOptionalString(existingValue?.webhookToken) ?? ""; if (!directConversationBinding && (!webhookId || !webhookToken)) { const cachedWebhook = findReusableWebhook({ accountId, channelId }); @@ -382,26 +382,29 @@ export function createThreadBindingManager(params: { targetSessionKey, agentId: normalizeOptionalString(bindParams.agentId) ?? - normalizeOptionalString(existing?.agentId) ?? + normalizeOptionalString(existingValue?.agentId) ?? resolveAgentIdFromSessionKey(targetSessionKey), label: - normalizeOptionalString(bindParams.label) ?? normalizeOptionalString(existing?.label), + normalizeOptionalString(bindParams.label) ?? + normalizeOptionalString(existingValue?.label), webhookId: webhookId || undefined, webhookToken: webhookToken || undefined, boundBy: normalizeOptionalString(bindParams.boundBy) ?? - normalizeOptionalString(existing?.boundBy) ?? + normalizeOptionalString(existingValue?.boundBy) ?? "system", boundAt: now, lastActivityAt: now, idleTimeoutMs: - typeof existing?.idleTimeoutMs === "number" ? existing.idleTimeoutMs : idleTimeoutMs, - maxAgeMs: typeof existing?.maxAgeMs === "number" ? existing.maxAgeMs : maxAgeMs, + typeof existingValue?.idleTimeoutMs === "number" + ? existingValue.idleTimeoutMs + : idleTimeoutMs, + maxAgeMs: typeof existingValue?.maxAgeMs === "number" ? existingValue.maxAgeMs : maxAgeMs, metadata: bindParams.metadata && typeof bindParams.metadata === "object" - ? { ...existing?.metadata, ...bindParams.metadata } - : existing?.metadata - ? { ...existing.metadata } + ? { ...existingValue?.metadata, ...bindParams.metadata } + : existingValue?.metadata + ? { ...existingValue.metadata } : undefined, }; @@ -424,8 +427,8 @@ export function createThreadBindingManager(params: { if (!bindingKey) { return null; } - const existing = BINDINGS_BY_THREAD_ID.get(bindingKey); - if (!existing || existing.accountId !== accountId) { + const existingLocal = BINDINGS_BY_THREAD_ID.get(bindingKey); + if (!existingLocal || existingLocal.accountId !== accountId) { return null; } const removed = removeBindingRecord(bindingKey); diff --git a/extensions/discord/src/send.permissions.ts b/extensions/discord/src/send.permissions.ts index ec15390226d..ea5589f54dd 100644 --- a/extensions/discord/src/send.permissions.ts +++ b/extensions/discord/src/send.permissions.ts @@ -64,16 +64,16 @@ function resolveMemberGuildPermissionBits(params: { guild: Pick; member: Pick; }) { - const rolesById = new Map( + const rolesByIdLocal = new Map( (params.guild.roles ?? []).map((role) => [role.id, role]), ); - const everyoneRole = rolesById.get(params.guild.id); + const everyoneRole = rolesByIdLocal.get(params.guild.id); let permissions = 0n; if (everyoneRole?.permissions) { permissions = addPermissionBits(permissions, everyoneRole.permissions); } for (const roleId of params.member.roles ?? []) { - const role = rolesById.get(roleId); + const role = rolesByIdLocal.get(roleId); if (role?.permissions) { permissions = addPermissionBits(permissions, role.permissions); } diff --git a/extensions/discord/src/targets.test.ts b/extensions/discord/src/targets.test.ts index d5ee1fabfe2..3bfafe68a62 100644 --- a/extensions/discord/src/targets.test.ts +++ b/extensions/discord/src/targets.test.ts @@ -137,7 +137,7 @@ describe("resolveDiscordTarget", () => { it("treats bare numeric ids in allowFrom as users even when channels are the default", async () => { const listPeers = vi.spyOn(directoryLive, "listDiscordDirectoryPeersLive"); - const cfg = { + const cfgCandidate = { channels: { discord: { accounts: { @@ -150,14 +150,18 @@ describe("resolveDiscordTarget", () => { } as OpenClawConfig; expectTargetFields( - await resolveDiscordTarget("123", { cfg, accountId: "default" }, { defaultKind: "channel" }), + await resolveDiscordTarget( + "123", + { cfg: cfgCandidate, accountId: "default" }, + { defaultKind: "channel" }, + ), { kind: "user", id: "123", normalized: "user:123" }, ); expect(listPeers).not.toHaveBeenCalled(); }); it("uses legacy dm.allowFrom when disambiguating bare numeric ids", async () => { - const cfg = { + const cfgEntry = { channels: { discord: { accounts: { @@ -170,13 +174,17 @@ describe("resolveDiscordTarget", () => { } as OpenClawConfig; expectTargetFields( - await resolveDiscordTarget("456", { cfg, accountId: "default" }, { defaultKind: "channel" }), + await resolveDiscordTarget( + "456", + { cfg: cfgEntry, accountId: "default" }, + { defaultKind: "channel" }, + ), { kind: "user", id: "456", normalized: "user:456" }, ); }); it("prefers top-level allowFrom over legacy dm.allowFrom for bare numeric ids", async () => { - const cfg = { + const cfgResult = { channels: { discord: { accounts: { @@ -190,13 +198,17 @@ describe("resolveDiscordTarget", () => { } as OpenClawConfig; expectTargetFields( - await resolveDiscordTarget("456", { cfg, accountId: "default" }, { defaultKind: "channel" }), + await resolveDiscordTarget( + "456", + { cfg: cfgResult, accountId: "default" }, + { defaultKind: "channel" }, + ), { kind: "channel", id: "456", normalized: "channel:456" }, ); }); it("uses account legacy dm.allowFrom before inherited root allowFrom for bare numeric ids", async () => { - const cfg = { + const cfgValue = { channels: { discord: { allowFrom: ["123"], @@ -210,17 +222,25 @@ describe("resolveDiscordTarget", () => { } as OpenClawConfig; expectTargetFields( - await resolveDiscordTarget("456", { cfg, accountId: "work" }, { defaultKind: "channel" }), + await resolveDiscordTarget( + "456", + { cfg: cfgValue, accountId: "work" }, + { defaultKind: "channel" }, + ), { kind: "user", id: "456", normalized: "user:456" }, ); expectTargetFields( - await resolveDiscordTarget("123", { cfg, accountId: "work" }, { defaultKind: "channel" }), + await resolveDiscordTarget( + "123", + { cfg: cfgValue, accountId: "work" }, + { defaultKind: "channel" }, + ), { kind: "channel", id: "123", normalized: "channel:123" }, ); }); it("caches username lookups under the configured default account when accountId is omitted", async () => { - const cfg = { + const cfgLocal = { channels: { discord: { defaultAccount: "work", @@ -237,7 +257,7 @@ describe("resolveDiscordTarget", () => { { kind: "user", id: "user:999", name: "Jane" } as const, ]); - expectTargetFields(await resolveDiscordTarget("jane", { cfg }), { + expectTargetFields(await resolveDiscordTarget("jane", { cfg: cfgLocal }), { kind: "user", id: "999", normalized: "user:999", diff --git a/extensions/discord/src/voice/manager.e2e.test.ts b/extensions/discord/src/voice/manager.e2e.test.ts index 244d69e8196..f6a066767d8 100644 --- a/extensions/discord/src/voice/manager.e2e.test.ts +++ b/extensions/discord/src/voice/manager.e2e.test.ts @@ -57,7 +57,7 @@ const { handlers: Map; }; - const createConnectionMock = (): MockConnection => { + const createConnectionMockLocal = (): MockConnection => { const handlers = new Map(); const daveSetPassthroughMode = vi.fn(); const connection: MockConnection = { @@ -98,9 +98,9 @@ const { return connection; }; - const getVoiceConnectionMock = vi.fn((): MockConnection | undefined => undefined); + const getVoiceConnectionMockLocal = vi.fn((): MockConnection | undefined => undefined); - const realtimeSessionMock = { + const realtimeSessionMockLocal = { bridge: { supportsToolResultContinuation: true }, acknowledgeMark: vi.fn(), close: vi.fn(), @@ -114,9 +114,9 @@ const { }; return { - createConnectionMock, - getVoiceConnectionMock, - joinVoiceChannelMock: vi.fn(() => createConnectionMock()), + createConnectionMock: createConnectionMockLocal, + getVoiceConnectionMock: getVoiceConnectionMockLocal, + joinVoiceChannelMock: vi.fn(() => createConnectionMockLocal()), entersStateMock: vi.fn(async (_target?: unknown, _state?: string, _timeoutMs?: number) => { return undefined; }), @@ -148,7 +148,7 @@ const { provider: { id: "openai" }, providerConfig: { model: "gpt-realtime-2", voice: "cedar" }, })), - createRealtimeVoiceBridgeSessionMock: vi.fn((_params?: unknown) => realtimeSessionMock), + createRealtimeVoiceBridgeSessionMock: vi.fn((_params?: unknown) => realtimeSessionMockLocal), controlRealtimeVoiceAgentRunMock: vi.fn<() => Promise>( async () => ({ ok: false, @@ -163,7 +163,7 @@ const { suppress: false, }), ), - realtimeSessionMock, + realtimeSessionMock: realtimeSessionMockLocal, decodeOpusStreamMock: vi.fn(), decodeOpusStreamChunksMock: vi.fn(), updateVoiceStateMock: vi.fn(), diff --git a/extensions/discord/src/voice/manager.ts b/extensions/discord/src/voice/manager.ts index bced89f9e4d..c8efb533315 100644 --- a/extensions/discord/src/voice/manager.ts +++ b/extensions/discord/src/voice/manager.ts @@ -683,7 +683,7 @@ export class DiscordVoiceManager { }; const stopEntry = ( entry: VoiceSessionEntry, - options: { destroyConnection: boolean; reason: string }, + optionsLocal: { destroyConnection: boolean; reason: string }, ) => { if (stopped) { return; @@ -710,11 +710,11 @@ export class DiscordVoiceManager { entry.realtime?.close(); entry.realtime = undefined; player.stop(); - if (options.destroyConnection) { + if (optionsLocal.destroyConnection) { destroyVoiceConnectionSafely({ connection, voiceSdk, - reason: options.reason, + reason: optionsLocal.reason, }); } }; diff --git a/extensions/fal/image-generation-provider.ts b/extensions/fal/image-generation-provider.ts index 82b35afc6c7..c9b086ca89d 100644 --- a/extensions/fal/image-generation-provider.ts +++ b/extensions/fal/image-generation-provider.ts @@ -512,8 +512,8 @@ async function fetchImageBuffer( const mimeType = response.headers.get("content-type")?.trim() || "image/png"; return { buffer: await readResponseWithLimit(response, maxBytes, { - onOverflow: ({ maxBytes }) => - new Error(`fal generated image download exceeds ${maxBytes} bytes`), + onOverflow: ({ maxBytes: maxBytesLocal }) => + new Error(`fal generated image download exceeds ${maxBytesLocal} bytes`), }), mimeType, }; diff --git a/extensions/fal/video-generation-provider.ts b/extensions/fal/video-generation-provider.ts index b388b5e917c..488500cb4ec 100644 --- a/extensions/fal/video-generation-provider.ts +++ b/extensions/fal/video-generation-provider.ts @@ -207,9 +207,9 @@ async function downloadFalVideo( let buffer: Buffer; try { buffer = await readResponseWithLimit(response, maxBytes, { - onOverflow: ({ maxBytes }) => { + onOverflow: ({ maxBytes: maxBytesLocal }) => { exceededMaxBytes = true; - return new Error(`fal generated video download exceeds ${maxBytes} bytes`); + return new Error(`fal generated video download exceeds ${maxBytesLocal} bytes`); }, }); } catch (error) { diff --git a/extensions/feishu/src/bot.checkBotMentioned.test.ts b/extensions/feishu/src/bot.checkBotMentioned.test.ts index e2064f9d6ba..342121a5382 100644 --- a/extensions/feishu/src/bot.checkBotMentioned.test.ts +++ b/extensions/feishu/src/bot.checkBotMentioned.test.ts @@ -168,14 +168,14 @@ describe("parseFeishuMessageEvent – mentionedBot", () => { }); it("returns mentionedBot=true for post message with at (no top-level mentions)", () => { - const BOT_OPEN_ID = "ou_bot_123"; + const BOT_OPEN_IDLocal = "ou_bot_123"; const event = makePostEvent({ content: [ - [{ tag: "at", user_id: BOT_OPEN_ID, user_name: "claw" }], + [{ tag: "at", user_id: BOT_OPEN_IDLocal, user_name: "claw" }], [{ tag: "text", text: "What does this document say" }], ], }); - const ctx = parseFeishuMessageEvent(event, BOT_OPEN_ID); + const ctx = parseFeishuMessageEvent(event, BOT_OPEN_IDLocal); expect(ctx.mentionedBot).toBe(true); }); diff --git a/extensions/feishu/src/bot.test.ts b/extensions/feishu/src/bot.test.ts index c76b36dd68a..18c8a7d9de5 100644 --- a/extensions/feishu/src/bot.test.ts +++ b/extensions/feishu/src/bot.test.ts @@ -162,13 +162,6 @@ function buildDefaultResolveRoute(): ResolvedAgentRoute { matchedBy: "default", }; } - -function createUnboundConfiguredRoute( - route: NonNullable["route"], -): ConfiguredBindingRoute { - return { bindingResolution: null, route }; -} - function createFeishuBotRuntime(overrides: DeepPartial = {}): PluginRuntime { return { channel: { diff --git a/extensions/feishu/src/bot.ts b/extensions/feishu/src/bot.ts index 40aba4629f3..f3504c195a7 100644 --- a/extensions/feishu/src/bot.ts +++ b/extensions/feishu/src/bot.ts @@ -808,10 +808,10 @@ export async function handleFeishuMessage(params: { if (!isGroup && route.matchedBy === "default") { const dynamicCfg = feishuCfg?.dynamicAgentCreation as DynamicAgentCreationConfig | undefined; if (dynamicCfg?.enabled) { - const runtime = getFeishuRuntime(); + const runtimeLocal = getFeishuRuntime(); const result = await maybeCreateDynamicAgent({ cfg, - runtime, + runtime: runtimeLocal, senderOpenId: ctx.senderOpenId, dynamicCfg, configWritesAllowed: resolveChannelConfigWrites({ @@ -1387,22 +1387,22 @@ export async function handleFeishuMessage(params: { .map((id) => (id ? normalizeFeishuAllowEntry(id) : "")) .find((recipient) => recipient === pinnedMainDmOwner) : undefined; - const buildFeishuInboundLastRouteUpdate = (params: { + const buildFeishuInboundLastRouteUpdate = (paramsLocal: { accountId: string; sessionKey: string; }) => { const inboundLastRouteSessionKey = - params.sessionKey === route.sessionKey + paramsLocal.sessionKey === route.sessionKey ? resolveInboundLastRouteSessionKey({ route, - sessionKey: params.sessionKey, + sessionKey: paramsLocal.sessionKey, }) - : params.sessionKey; + : paramsLocal.sessionKey; return { sessionKey: inboundLastRouteSessionKey, channel: "feishu" as const, to: feishuTo, - accountId: params.accountId, + accountId: paramsLocal.accountId, ...(lastRouteThreadId ? { threadId: lastRouteThreadId } : {}), mainDmOwnerPin: !isGroup && inboundLastRouteSessionKey === route.mainSessionKey && pinnedMainDmOwner diff --git a/extensions/feishu/src/channel.test.ts b/extensions/feishu/src/channel.test.ts index 90d96936d43..f457270e827 100644 --- a/extensions/feishu/src/channel.test.ts +++ b/extensions/feishu/src/channel.test.ts @@ -279,7 +279,7 @@ describe("feishuPlugin actions", () => { }); it("honors the selected Feishu account during discovery", () => { - const cfg = { + const cfgLocal = { channels: { feishu: { enabled: true, @@ -302,7 +302,7 @@ describe("feishuPlugin actions", () => { }, } as OpenClawConfig; - expect(getDescribedActions(cfg, "default")).toEqual([ + expect(getDescribedActions(cfgLocal, "default")).toEqual([ "send", "read", "edit", @@ -314,7 +314,7 @@ describe("feishuPlugin actions", () => { "channel-info", "channel-list", ]); - expect(getDescribedActions(cfg, "work")).toEqual([ + expect(getDescribedActions(cfgLocal, "work")).toEqual([ "send", "read", "edit", diff --git a/extensions/feishu/src/docx.test.ts b/extensions/feishu/src/docx.test.ts index a0f99b6cd5f..446a4a34374 100644 --- a/extensions/feishu/src/docx.test.ts +++ b/extensions/feishu/src/docx.test.ts @@ -276,7 +276,7 @@ describe("feishu_doc image fetch hardening", () => { const call = blockDescendantCreateMock.mock.calls[0]?.[0]; expect(call?.data.children_id).toEqual(["h1", "p1", "h2", "list1"]); - expect((call?.data.descendants as Array<{ block_id: string }>).map((b) => b.block_id)).toEqual([ + expect((call!.data.descendants as Array<{ block_id: string }>).map((b) => b.block_id)).toEqual([ "h1", "p1", "h2", diff --git a/extensions/feishu/src/monitor.acp-init-failure.lifecycle.test-support.ts b/extensions/feishu/src/monitor.acp-init-failure.lifecycle.test-support.ts index 88e74f52094..e429113db4b 100644 --- a/extensions/feishu/src/monitor.acp-init-failure.lifecycle.test-support.ts +++ b/extensions/feishu/src/monitor.acp-init-failure.lifecycle.test-support.ts @@ -28,8 +28,6 @@ const { sendMessageFeishuMock, withReplyDispatcherMock, } = getFeishuLifecycleTestMocks(); - -let handlers: Record Promise> = {}; let lastRuntime = createRuntimeEnv(); const originalStateDir = process.env.OPENCLAW_STATE_DIR; const { cfg: lifecycleConfig, account: lifecycleAccount } = createFeishuLifecycleFixture({ @@ -62,9 +60,7 @@ async function setupLifecycleMonitor() { lastRuntime = createRuntimeEnv(); return setupFeishuLifecycleHandler({ createEventDispatcherMock, - onRegister: (registered) => { - handlers = registered; - }, + onRegister: () => {}, runtime: lastRuntime, cfg: lifecycleConfig, account: lifecycleAccount, @@ -77,7 +73,6 @@ describe("Feishu ACP-init failure lifecycle", () => { beforeEach(() => { vi.useRealTimers(); resetFeishuLifecycleTestMocks(); - handlers = {}; lastRuntime = createRuntimeEnv(); setFeishuLifecycleStateDir("openclaw-feishu-acp-failure"); diff --git a/extensions/feishu/src/monitor.bot-menu.lifecycle.test-support.ts b/extensions/feishu/src/monitor.bot-menu.lifecycle.test-support.ts index 4aab2e1763f..5e50671b195 100644 --- a/extensions/feishu/src/monitor.bot-menu.lifecycle.test-support.ts +++ b/extensions/feishu/src/monitor.bot-menu.lifecycle.test-support.ts @@ -31,8 +31,6 @@ const { touchBindingMock, withReplyDispatcherMock, } = getFeishuLifecycleTestMocks(); - -let handlers: Record Promise> = {}; let lastRuntime = createRuntimeEnv(); const originalStateDir = process.env.OPENCLAW_STATE_DIR; const lifecycleConfig = createFeishuLifecycleConfig({ @@ -77,9 +75,7 @@ async function setupLifecycleMonitor() { lastRuntime = createRuntimeEnv(); return setupFeishuLifecycleHandler({ createEventDispatcherMock, - onRegister: (registered) => { - handlers = registered; - }, + onRegister: () => {}, runtime: lastRuntime, cfg: lifecycleConfig, account: lifecycleAccount, @@ -92,7 +88,6 @@ describe("Feishu bot-menu lifecycle", () => { beforeEach(() => { vi.useRealTimers(); resetFeishuLifecycleTestMocks(); - handlers = {}; lastRuntime = createRuntimeEnv(); setFeishuLifecycleStateDir("openclaw-feishu-bot-menu"); diff --git a/extensions/feishu/src/monitor.card-action.lifecycle.test-support.ts b/extensions/feishu/src/monitor.card-action.lifecycle.test-support.ts index add9fee7b76..58d464d8f93 100644 --- a/extensions/feishu/src/monitor.card-action.lifecycle.test-support.ts +++ b/extensions/feishu/src/monitor.card-action.lifecycle.test-support.ts @@ -33,8 +33,6 @@ const { touchBindingMock, withReplyDispatcherMock, } = getFeishuLifecycleTestMocks(); - -let handlers: Record Promise> = {}; let lastRuntime = createRuntimeEnv(); const originalStateDir = process.env.OPENCLAW_STATE_DIR; const lifecycleConfig = createFeishuLifecycleConfig({ @@ -104,9 +102,7 @@ async function setupLifecycleMonitor() { lastRuntime = createRuntimeEnv(); return setupFeishuLifecycleHandler({ createEventDispatcherMock, - onRegister: (registered) => { - handlers = registered; - }, + onRegister: () => {}, runtime: lastRuntime, cfg: lifecycleConfig, account: lifecycleAccount, @@ -143,7 +139,6 @@ describe("Feishu card-action lifecycle", () => { beforeEach(() => { vi.useRealTimers(); resetFeishuLifecycleTestMocks(); - handlers = {}; lastRuntime = createRuntimeEnv(); resetProcessedFeishuCardActionTokensForTests(); setFeishuLifecycleStateDir("openclaw-feishu-card-action"); diff --git a/extensions/feishu/src/monitor.message-handler.ts b/extensions/feishu/src/monitor.message-handler.ts index 8eb36d80d7c..870464e241f 100644 --- a/extensions/feishu/src/monitor.message-handler.ts +++ b/extensions/feishu/src/monitor.message-handler.ts @@ -166,8 +166,8 @@ export function createFeishuMessageReceiveHandler({ recordProcessedMessage, getBotOpenId = () => undefined, getBotName = () => undefined, - resolveSequentialKey = ({ accountId, event }) => - `feishu:${accountId}:${event.message.chat_id?.trim() || "unknown"}`, + resolveSequentialKey = ({ accountId: accountIdLocal, event }) => + `feishu:${accountIdLocal}:${event.message.chat_id?.trim() || "unknown"}`, }: FeishuMessageReceiveHandlerContext): (data: unknown) => Promise { const inboundDebounceMs = channelRuntime.debounce.resolveInboundDebounceMs({ cfg, diff --git a/extensions/feishu/src/reply-dispatcher.ts b/extensions/feishu/src/reply-dispatcher.ts index 6b2fd4f0e70..7e45469fb78 100644 --- a/extensions/feishu/src/reply-dispatcher.ts +++ b/extensions/feishu/src/reply-dispatcher.ts @@ -440,27 +440,27 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP flushStreamingCardUpdate(buildCombinedStreamText(reasoningText, streamText)); }; - const sendChunkedTextReply = async (params: { + const sendChunkedTextReply = async (paramsLocal: { text: string; useCard: boolean; infoKind?: string; sendChunk: (params: { chunk: string; isFirst: boolean }) => Promise; }) => { - const chunkSource = params.useCard - ? params.text - : core.channel.text.convertMarkdownTables(params.text, tableMode); + const chunkSource = paramsLocal.useCard + ? paramsLocal.text + : core.channel.text.convertMarkdownTables(paramsLocal.text, tableMode); const chunks = resolveTextChunksWithFallback( chunkSource, core.channel.text.chunkTextWithMode(chunkSource, textChunkLimit, chunkMode), ); for (const [index, chunk] of chunks.entries()) { - await params.sendChunk({ + await paramsLocal.sendChunk({ chunk, isFirst: index === 0, }); } - if (params.infoKind === "final") { - deliveredFinalTexts.add(params.text); + if (paramsLocal.infoKind === "final") { + deliveredFinalTexts.add(paramsLocal.text); } }; @@ -744,7 +744,7 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP if (!isChannelProgressDraftWorkToolName(payload.name)) { return; } - const statusLine = formatChannelProgressDraftLineForEntry( + const statusLineLocal = formatChannelProgressDraftLineForEntry( account.config, { event: "tool", @@ -756,8 +756,8 @@ export function createFeishuReplyDispatcher(params: CreateFeishuReplyDispatcherP detailMode: payload.detailMode, }, ); - if (statusLine) { - updateStreamingStatusLine(statusLine); + if (statusLineLocal) { + updateStreamingStatusLine(statusLineLocal); } } : undefined, diff --git a/extensions/feishu/src/thread-bindings.ts b/extensions/feishu/src/thread-bindings.ts index d39f9791bc7..505fabcc426 100644 --- a/extensions/feishu/src/thread-bindings.ts +++ b/extensions/feishu/src/thread-bindings.ts @@ -163,7 +163,7 @@ export function createFeishuThreadBindingManager(params: { if (!normalizedConversationId || !normalizedTargetSessionKey) { return null; } - const existing = getState().bindingsByAccountConversation.get( + const existingLocal = getState().bindingsByAccountConversation.get( resolveBindingKey({ accountId, conversationId: normalizedConversationId }), ); const now = Date.now(); @@ -171,29 +171,29 @@ export function createFeishuThreadBindingManager(params: { accountId, conversationId: normalizedConversationId, parentConversationId: - normalizeOptionalString(parentConversationId) ?? existing?.parentConversationId, + normalizeOptionalString(parentConversationId) ?? existingLocal?.parentConversationId, deliveryTo: typeof metadata?.deliveryTo === "string" && metadata.deliveryTo.trim() ? metadata.deliveryTo.trim() - : existing?.deliveryTo, + : existingLocal?.deliveryTo, deliveryThreadId: typeof metadata?.deliveryThreadId === "string" && metadata.deliveryThreadId.trim() ? metadata.deliveryThreadId.trim() - : existing?.deliveryThreadId, + : existingLocal?.deliveryThreadId, targetKind: toFeishuTargetKind(targetKind), targetSessionKey: normalizedTargetSessionKey, agentId: typeof metadata?.agentId === "string" && metadata.agentId.trim() ? metadata.agentId.trim() - : (existing?.agentId ?? resolveAgentIdFromSessionKey(normalizedTargetSessionKey)), + : (existingLocal?.agentId ?? resolveAgentIdFromSessionKey(normalizedTargetSessionKey)), label: typeof metadata?.label === "string" && metadata.label.trim() ? metadata.label.trim() - : existing?.label, + : existingLocal?.label, boundBy: typeof metadata?.boundBy === "string" && metadata.boundBy.trim() ? metadata.boundBy.trim() - : existing?.boundBy, + : existingLocal?.boundBy, boundAt: now, lastActivityAt: now, }; diff --git a/extensions/feishu/src/tool-account-routing.test.ts b/extensions/feishu/src/tool-account-routing.test.ts index 7b5703b568f..884680b3135 100644 --- a/extensions/feishu/src/tool-account-routing.test.ts +++ b/extensions/feishu/src/tool-account-routing.test.ts @@ -83,12 +83,14 @@ function lastClientAppId(): string | undefined { describe("feishu tool account routing", () => { beforeAll(async () => { ({ registerFeishuBitableTools, registerFeishuDriveTools, registerFeishuPermTools } = - await import("./bitable.js").then(async ({ registerFeishuBitableTools }) => ({ - registerFeishuBitableTools, - ...(await import("./drive.js")), - ...(await import("./perm.js")), - ...(await import("./wiki.js")), - }))); + await import("./bitable.js").then( + async ({ registerFeishuBitableTools: registerFeishuBitableToolsLocal }) => ({ + registerFeishuBitableTools: registerFeishuBitableToolsLocal, + ...(await import("./drive.js")), + ...(await import("./perm.js")), + ...(await import("./wiki.js")), + }), + )); ({ registerFeishuWikiTools } = await import("./wiki.js")); }); diff --git a/extensions/file-transfer/src/shared/node-invoke-policy.test.ts b/extensions/file-transfer/src/shared/node-invoke-policy.test.ts index adf51bbc64b..c382385b12e 100644 --- a/extensions/file-transfer/src/shared/node-invoke-policy.test.ts +++ b/extensions/file-transfer/src/shared/node-invoke-policy.test.ts @@ -1,6 +1,4 @@ import fs from "node:fs/promises"; -import os from "node:os"; -import path from "node:path"; import { gzipSync } from "node:zlib"; import type { OpenClawPluginNodeInvokePolicyContext } from "openclaw/plugin-sdk/plugin-entry"; import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; diff --git a/extensions/firecrawl/src/firecrawl-client.ts b/extensions/firecrawl/src/firecrawl-client.ts index b18c901d30c..b786a524938 100644 --- a/extensions/firecrawl/src/firecrawl-client.ts +++ b/extensions/firecrawl/src/firecrawl-client.ts @@ -417,17 +417,17 @@ export async function runFirecrawlSearch( errorLabel: "Firecrawl Search", }, async (response) => { - const payload = await readFirecrawlJsonResponse(response, "Firecrawl Search API error"); - if (payload.success === false) { + const payloadValue = await readFirecrawlJsonResponse(response, "Firecrawl Search API error"); + if (payloadValue.success === false) { const error = - typeof payload.error === "string" - ? payload.error - : typeof payload.message === "string" - ? payload.message + typeof payloadValue.error === "string" + ? payloadValue.error + : typeof payloadValue.message === "string" + ? payloadValue.message : "unknown error"; throw new Error(`Firecrawl Search API error: ${error}`); } - return payload; + return payloadValue; }, ); const result = buildSearchPayload({ @@ -573,19 +573,19 @@ export async function runFirecrawlScrape( }, }, async (response) => { - const payload = await readFirecrawlJsonResponse(response, "Firecrawl fetch failed"); - if (payload.success === false) { + const payloadLocal = await readFirecrawlJsonResponse(response, "Firecrawl fetch failed"); + if (payloadLocal.success === false) { const detail = - typeof payload.error === "string" - ? payload.error - : typeof payload.message === "string" - ? payload.message + typeof payloadLocal.error === "string" + ? payloadLocal.error + : typeof payloadLocal.message === "string" + ? payloadLocal.message : response.statusText; throw new Error( `Firecrawl fetch failed (${response.status}): ${wrapWebContent(detail, "web_fetch")}`.trim(), ); } - return payload; + return payloadLocal; }, ); const result = parseFirecrawlScrapePayload({ diff --git a/extensions/github-copilot/index.test.ts b/extensions/github-copilot/index.test.ts index ebf5674e9eb..e93540ea238 100644 --- a/extensions/github-copilot/index.test.ts +++ b/extensions/github-copilot/index.test.ts @@ -83,11 +83,6 @@ async function createAgentDir() { tempDirs.push(dir); return dir; } - -function registerProviderForTest() { - return registerProviderWithPluginConfig({}); -} - function requireFirstMockArg( mock: { mock: { calls: Array<[T, ...unknown[]]> } }, label: string, diff --git a/extensions/google-meet/index.test.ts b/extensions/google-meet/index.test.ts index 99d26c91bd6..d971401cd18 100644 --- a/extensions/google-meet/index.test.ts +++ b/extensions/google-meet/index.test.ts @@ -1997,7 +1997,9 @@ describe("google-meet plugin", () => { "Chrome observe-only mode does not require a realtime audio bridge", ); expect( - result.details.checks?.filter((check) => check.id === "chrome-local-audio-device"), + result.details.checks?.filter( + (checkLocal) => checkLocal.id === "chrome-local-audio-device", + ), ).toStrictEqual([]); expect(runCommandWithTimeout).not.toHaveBeenCalled(); } finally { diff --git a/extensions/google-meet/src/config-compat.test.ts b/extensions/google-meet/src/config-compat.test.ts index 22982fe3628..5ed9e8f0d16 100644 --- a/extensions/google-meet/src/config-compat.test.ts +++ b/extensions/google-meet/src/config-compat.test.ts @@ -46,7 +46,7 @@ describe("google-meet config compatibility", () => { ]); expect( ( - migration?.config.plugins?.entries?.["google-meet"] as { + migration!.config.plugins!.entries!["google-meet"] as { config?: { realtime?: Record }; } ).config?.realtime, @@ -85,7 +85,7 @@ describe("google-meet config compatibility", () => { expect(migration.changes).toStrictEqual([]); expect( ( - migration.config.plugins?.entries?.["google-meet"] as { + migration.config.plugins!.entries!["google-meet"] as { config?: { realtime?: Record }; } ).config?.realtime, diff --git a/extensions/google-meet/src/realtime.ts b/extensions/google-meet/src/realtime.ts index 2610f0c14d7..ade1b010b6d 100644 --- a/extensions/google-meet/src/realtime.ts +++ b/extensions/google-meet/src/realtime.ts @@ -521,8 +521,8 @@ export async function startCommandAgentAudioBridge(params: { { onEvent: recordTalkObservabilityEvent }, ); const recentTalkEvents: TalkEvent[] = []; - const emitTalkEvent = (input: TalkEventInput) => - pushGoogleMeetTalkEvent(recentTalkEvents, talk.emit(input)); + const emitTalkEvent = (inputResult: TalkEventInput) => + pushGoogleMeetTalkEvent(recentTalkEvents, talk.emit(inputResult)); const ensureTalkTurn = () => { const turn = talk.ensureTurn({ payload: { meetingSessionId: params.meetingSessionId }, @@ -1081,8 +1081,8 @@ export async function startCommandRealtimeAudioBridge(params: { pushGoogleMeetTalkEvent(recentTalkEvents, event); } }; - const emitTalkEvent = (input: TalkEventInput): void => { - rememberTalkEvent(talk.emit(input)); + const emitTalkEvent = (inputValue: TalkEventInput): void => { + rememberTalkEvent(talk.emit(inputValue)); }; const ensureTalkTurn = (): string => { const turn = talk.ensureTurn({ @@ -1270,7 +1270,8 @@ export async function startCommandRealtimeAudioBridge(params: { meetingSessionId: params.meetingSessionId, requesterSessionKey: params.requesterSessionKey, transcript, - onTalkEvent: (input) => emitTalkEvent({ ...input, turnId: input.turnId ?? turnId }), + onTalkEvent: (inputLocal) => + emitTalkEvent({ ...inputLocal, turnId: inputLocal.turnId ?? turnId }), }); }, onError: (error) => { diff --git a/extensions/google/embedding-provider.ts b/extensions/google/embedding-provider.ts index 80330807a0d..50eb4346ab0 100644 --- a/extensions/google/embedding-provider.ts +++ b/extensions/google/embedding-provider.ts @@ -363,13 +363,13 @@ export async function createGeminiEmbeddingProvider( const embedBatch = async ( texts: string[], - options?: { signal?: AbortSignal }, + optionsLocal?: { signal?: AbortSignal }, ): Promise => { return await embedBatchInputs( texts.map((text) => ({ text, })), - options, + optionsLocal, ); }; diff --git a/extensions/google/google.live.test.ts b/extensions/google/google.live.test.ts index 6bf3c7f40c7..1000d9dc206 100644 --- a/extensions/google/google.live.test.ts +++ b/extensions/google/google.live.test.ts @@ -145,7 +145,7 @@ describeLive("google plugin live", () => { expect(result?.provider).toBe("gemini"); expect(typeof result?.content).toBe("string"); - expect((result?.content as string).length).toBeGreaterThan(20); + expect((result!.content as string).length).toBeGreaterThan(20); expect(Array.isArray(result?.citations)).toBe(true); }, 120_000); @@ -171,9 +171,9 @@ describeLive("google plugin live", () => { expect(process.env.GOOGLE_API_KEY).toBeUndefined(); expect(result?.provider).toBe("gemini"); expect(typeof result?.content).toBe("string"); - expect((result?.content as string).length).toBeGreaterThan(20); + expect((result!.content as string).length).toBeGreaterThan(20); expect(Array.isArray(result?.citations)).toBe(true); - expect((result?.citations as unknown[]).length).toBeGreaterThan(0); + expect((result!.citations as unknown[]).length).toBeGreaterThan(0); }); }, 120_000); }); diff --git a/extensions/google/music-generation-provider.test.ts b/extensions/google/music-generation-provider.test.ts index 153adb60ee6..43f6027ef88 100644 --- a/extensions/google/music-generation-provider.test.ts +++ b/extensions/google/music-generation-provider.test.ts @@ -1,15 +1,18 @@ import { afterAll, afterEach, describe, expect, it, vi } from "vitest"; const { createGoogleGenAIMock, generateContentMock } = vi.hoisted(() => { - const generateContentMock = vi.fn(); - const createGoogleGenAIMock = vi.fn(() => { + const generateContentMockLocal = vi.fn(); + const createGoogleGenAIMockLocal = vi.fn(() => { return { models: { - generateContent: generateContentMock, + generateContent: generateContentMockLocal, }, }; }); - return { createGoogleGenAIMock, generateContentMock }; + return { + createGoogleGenAIMock: createGoogleGenAIMockLocal, + generateContentMock: generateContentMockLocal, + }; }); vi.mock("./google-genai-runtime.js", () => ({ diff --git a/extensions/google/realtime-voice-provider.test.ts b/extensions/google/realtime-voice-provider.test.ts index 3a1f7388f41..9968b2f586d 100644 --- a/extensions/google/realtime-voice-provider.test.ts +++ b/extensions/google/realtime-voice-provider.test.ts @@ -21,17 +21,21 @@ type MockGoogleLiveConnectParams = { }; const { connectMock, createTokenMock, session } = vi.hoisted(() => { - const session: MockGoogleLiveSession = { + const sessionValue: MockGoogleLiveSession = { close: vi.fn(), sendClientContent: vi.fn(), sendRealtimeInput: vi.fn(), sendToolResponse: vi.fn(), }; - const connectMock = vi.fn(async (_params: MockGoogleLiveConnectParams) => session); - const createTokenMock = vi.fn(async (_params: unknown) => ({ + const connectMockLocal = vi.fn(async (_params: MockGoogleLiveConnectParams) => sessionValue); + const createTokenMockLocal = vi.fn(async (_params: unknown) => ({ name: "auth_tokens/browser-session", })); - return { connectMock, createTokenMock, session }; + return { + connectMock: connectMockLocal, + createTokenMock: createTokenMockLocal, + session: sessionValue, + }; }); vi.mock("./google-genai-runtime.js", () => ({ @@ -365,7 +369,7 @@ describe("buildGoogleRealtimeVoiceProvider", () => { it("creates constrained browser sessions for Google Live Talk", async () => { const provider = buildGoogleRealtimeVoiceProvider(); - const session = await provider.createBrowserSession?.({ + const sessionLocal = await provider.createBrowserSession?.({ providerConfig: { apiKey: "gemini-key", model: "gemini-live-2.5-flash-preview", @@ -420,9 +424,9 @@ describe("buildGoogleRealtimeVoiceProvider", () => { expect(liveConstraints?.config?.tools?.[0]?.functionDeclarations?.[0]?.behavior).toBe( "NON_BLOCKING", ); - expect(session?.provider).toBe("google"); - expect(session?.transport).toBe("provider-websocket"); - const websocketSession = session as { + expect(sessionLocal?.provider).toBe("google"); + expect(sessionLocal?.transport).toBe("provider-websocket"); + const websocketSession = sessionLocal as { audio: { inputEncoding: string; inputSampleRateHz: number; diff --git a/extensions/google/transport-stream.test.ts b/extensions/google/transport-stream.test.ts index f4fa057aec2..05bde93ca1b 100644 --- a/extensions/google/transport-stream.test.ts +++ b/extensions/google/transport-stream.test.ts @@ -10,14 +10,14 @@ const { googleAuthGetAccessTokenMock, googleAuthMock, } = vi.hoisted(() => { - const googleAuthGetAccessTokenMock = vi.fn(); + const googleAuthGetAccessTokenMockLocal = vi.fn(); return { buildGuardedModelFetchMock: vi.fn(), guardedFetchMock: vi.fn(), - googleAuthGetAccessTokenMock, + googleAuthGetAccessTokenMock: googleAuthGetAccessTokenMockLocal, googleAuthMock: vi.fn(function GoogleAuthMock() { return { - getAccessToken: googleAuthGetAccessTokenMock, + getAccessToken: googleAuthGetAccessTokenMockLocal, }; }), }; diff --git a/extensions/google/video-generation-provider.test.ts b/extensions/google/video-generation-provider.test.ts index ac412c44d90..c35ab684bcb 100644 --- a/extensions/google/video-generation-provider.test.ts +++ b/extensions/google/video-generation-provider.test.ts @@ -3,23 +3,28 @@ import { afterAll, afterEach, beforeEach, describe, expect, it, vi } from "vites const { createGoogleGenAIMock, downloadMock, generateVideosMock, getVideosOperationMock } = vi.hoisted(() => { - const generateVideosMock = vi.fn(); - const getVideosOperationMock = vi.fn(); - const downloadMock = vi.fn(); - const createGoogleGenAIMock = vi.fn(() => { + const generateVideosMockLocal = vi.fn(); + const getVideosOperationMockLocal = vi.fn(); + const downloadMockLocal = vi.fn(); + const createGoogleGenAIMockLocal = vi.fn(() => { return { models: { - generateVideos: generateVideosMock, + generateVideos: generateVideosMockLocal, }, operations: { - getVideosOperation: getVideosOperationMock, + getVideosOperation: getVideosOperationMockLocal, }, files: { - download: downloadMock, + download: downloadMockLocal, }, }; }); - return { createGoogleGenAIMock, downloadMock, generateVideosMock, getVideosOperationMock }; + return { + createGoogleGenAIMock: createGoogleGenAIMockLocal, + downloadMock: downloadMockLocal, + generateVideosMock: generateVideosMockLocal, + getVideosOperationMock: getVideosOperationMockLocal, + }; }); vi.mock("./google-genai-runtime.js", () => ({ diff --git a/extensions/googlechat/src/channel.adapters.ts b/extensions/googlechat/src/channel.adapters.ts index a1b91dbf25e..5fbc4310254 100644 --- a/extensions/googlechat/src/channel.adapters.ts +++ b/extensions/googlechat/src/channel.adapters.ts @@ -287,13 +287,13 @@ export const googlechatOutboundAdapter = { typeof threadId === "number" ? String(threadId) : (threadId ?? replyToId ?? undefined); const maxBytes = resolveChannelMediaMaxBytes({ cfg, - resolveChannelLimitMb: ({ cfg, accountId }) => + resolveChannelLimitMb: ({ cfg: cfgLocal, accountId: accountIdLocal }) => ( - cfg.channels?.googlechat as + cfgLocal.channels?.googlechat as | { accounts?: Record; mediaMaxMb?: number } | undefined - )?.accounts?.[accountId]?.mediaMaxMb ?? - (cfg.channels?.googlechat as { mediaMaxMb?: number } | undefined)?.mediaMaxMb, + )?.accounts?.[accountIdLocal]?.mediaMaxMb ?? + (cfgLocal.channels?.googlechat as { mediaMaxMb?: number } | undefined)?.mediaMaxMb, accountId, }); const effectiveMaxBytes = maxBytes ?? (account.config.mediaMaxMb ?? 20) * 1024 * 1024; diff --git a/extensions/googlechat/src/google-auth.runtime.test.ts b/extensions/googlechat/src/google-auth.runtime.test.ts index 30cc8feab35..110195c71df 100644 --- a/extensions/googlechat/src/google-auth.runtime.test.ts +++ b/extensions/googlechat/src/google-auth.runtime.test.ts @@ -381,12 +381,12 @@ describe("googlechat google auth runtime", () => { try { const transport = await getGoogleAuthTransport(); const transportDefaults = transport.defaults as { fetchImplementation?: unknown }; - const requestInterceptorAdd = transport.interceptors.request.add as unknown as ReturnType< - typeof vi.fn - >; - const responseInterceptorAdd = transport.interceptors.response.add as unknown as ReturnType< + const requestInterceptorAdd = transport.interceptors.request["add"] as unknown as ReturnType< typeof vi.fn >; + const responseInterceptorAdd = transport.interceptors.response[ + "add" + ] as unknown as ReturnType; const requestInterceptor = mockCallArg(requestInterceptorAdd) as | { resolved?: unknown } | undefined; @@ -414,10 +414,10 @@ describe("googlechat google auth runtime", () => { expect(first).not.toBe(second); expect(mocks.gaxiosCtor).toHaveBeenCalledTimes(2); - expect(first.interceptors.request.add).toHaveBeenCalledOnce(); - expect(first.interceptors.response.add).toHaveBeenCalledOnce(); - expect(second.interceptors.request.add).toHaveBeenCalledOnce(); - expect(second.interceptors.response.add).toHaveBeenCalledOnce(); + expect(first.interceptors.request["add"]).toHaveBeenCalledOnce(); + expect(first.interceptors.response["add"]).toHaveBeenCalledOnce(); + expect(second.interceptors.request["add"]).toHaveBeenCalledOnce(); + expect(second.interceptors.response["add"]).toHaveBeenCalledOnce(); }); it("normalizes Google auth request headers before upstream interceptors run", () => { diff --git a/extensions/googlechat/src/monitor-webhook.test.ts b/extensions/googlechat/src/monitor-webhook.test.ts index 5944697353f..5361c73b466 100644 --- a/extensions/googlechat/src/monitor-webhook.test.ts +++ b/extensions/googlechat/src/monitor-webhook.test.ts @@ -267,9 +267,9 @@ describe("googlechat monitor webhook", () => { }, }); resolveWebhookTargetWithAuthOrReject.mockImplementation(async ({ isMatch, targets }) => { - for (const target of targets) { - if (await isMatch(target)) { - return target; + for (const targetLocal of targets) { + if (await isMatch(targetLocal)) { + return targetLocal; } } return null; diff --git a/extensions/googlechat/src/monitor.ts b/extensions/googlechat/src/monitor.ts index e0065c76d7d..8741d268bf7 100644 --- a/extensions/googlechat/src/monitor.ts +++ b/extensions/googlechat/src/monitor.ts @@ -221,7 +221,7 @@ async function processMessageWithPipeline(params: { senderEmail, rawBody, statusSink, - logVerbose: (message) => logVerbose(core, runtime, message), + logVerbose: (messageLocal) => logVerbose(core, runtime, messageLocal), }); if (!access.ok) { return; diff --git a/extensions/gradium/tts.ts b/extensions/gradium/tts.ts index fd00dbc596c..63d437c007b 100644 --- a/extensions/gradium/tts.ts +++ b/extensions/gradium/tts.ts @@ -52,8 +52,8 @@ export async function gradiumTTS(params: { await assertOkOrThrowProviderError(response, "Gradium API error"); return await readResponseWithLimit(response, maxBytes, { - onOverflow: ({ maxBytes }) => - new Error(`Gradium TTS audio response exceeds ${maxBytes} bytes`), + onOverflow: ({ maxBytes: maxBytesLocal }) => + new Error(`Gradium TTS audio response exceeds ${maxBytesLocal} bytes`), }); } finally { await release(); diff --git a/extensions/imessage/src/actions.runtime.ts b/extensions/imessage/src/actions.runtime.ts index 6d21f77404a..5d415df6d4a 100644 --- a/extensions/imessage/src/actions.runtime.ts +++ b/extensions/imessage/src/actions.runtime.ts @@ -189,20 +189,20 @@ async function runIMessageCliJson( let stderr = ""; let killEscalation: ReturnType | null = null; let settled = false; - const clearTimers = (options: { keepKillEscalation?: boolean } = {}): void => { + const clearTimers = (optionsValue: { keepKillEscalation?: boolean } = {}): void => { if (timer) { clearTimeout(timer); } - if (killEscalation && !options.keepKillEscalation) { + if (killEscalation && !optionsValue.keepKillEscalation) { clearTimeout(killEscalation); } }; - const fail = (error: Error, options: { keepKillEscalation?: boolean } = {}): void => { + const fail = (error: Error, optionsLocal: { keepKillEscalation?: boolean } = {}): void => { if (settled) { return; } settled = true; - clearTimers(options); + clearTimers(optionsLocal); reject(error); }; const succeed = (value: Record): void => { diff --git a/extensions/imessage/src/approval-reactions.ts b/extensions/imessage/src/approval-reactions.ts index 1d7f9534b43..a3ffb14e8cd 100644 --- a/extensions/imessage/src/approval-reactions.ts +++ b/extensions/imessage/src/approval-reactions.ts @@ -201,8 +201,10 @@ function readPersistedTarget(value: unknown): IMessageApprovalReactionTarget | n return null; } const allowedDecisions = target.allowedDecisions - .map((value) => (typeof value === "string" ? normalizeApprovalDecision(value) : null)) - .filter((value): value is ExecApprovalReplyDecision => Boolean(value)); + .map((valueValue) => + typeof valueValue === "string" ? normalizeApprovalDecision(valueValue) : null, + ) + .filter((valueLocal): valueLocal is ExecApprovalReplyDecision => Boolean(valueLocal)); if (allowedDecisions.length === 0) { return null; } diff --git a/extensions/imessage/src/monitor/catchup.test.ts b/extensions/imessage/src/monitor/catchup.test.ts index 80a1e988e56..14c6dccc93b 100644 --- a/extensions/imessage/src/monitor/catchup.test.ts +++ b/extensions/imessage/src/monitor/catchup.test.ts @@ -419,9 +419,9 @@ describe("performIMessageCatchup", () => { // clamped to `earliestHeldFailureRow.rowid - 1` (== 9) so the next pass // refetches row 10. let dispatchCount = 0; - const dispatch = vi.fn(async (row) => { + const dispatch = vi.fn(async (rowLocal) => { dispatchCount += 1; - if (row.guid === "A") { + if (rowLocal.guid === "A") { return { ok: false }; } return { ok: true }; diff --git a/extensions/imessage/src/monitor/coalesce.test.ts b/extensions/imessage/src/monitor/coalesce.test.ts index 057cb26cd7b..d0447b149a8 100644 --- a/extensions/imessage/src/monitor/coalesce.test.ts +++ b/extensions/imessage/src/monitor/coalesce.test.ts @@ -96,7 +96,7 @@ describe("combineIMessagePayloads", () => { const payloads = Array.from({ length: 6 }, (_, i) => makePayload({ guid: `row-${i}`, - attachments: Array.from({ length: 5 }, (_, j) => ({ + attachments: Array.from({ length: 5 }, (_Local, j) => ({ original_path: `/tmp/${i}-${j}.jpg`, mime_type: "image/jpeg", })), diff --git a/extensions/imessage/src/send.test.ts b/extensions/imessage/src/send.test.ts index 80368f9a8fc..ffc6083f9a6 100644 --- a/extensions/imessage/src/send.test.ts +++ b/extensions/imessage/src/send.test.ts @@ -118,7 +118,7 @@ describe("sendMessageIMessage receipts", () => { expect(result.echoText).toBe(""); expect(result.receipt.primaryPlatformMessageId).toBe("p:0/media-guid"); expect(result.receipt.platformMessageIds).toEqual(["p:0/media-guid"]); - expect(client.request).not.toHaveBeenCalled(); + expect(client["request"]).not.toHaveBeenCalled(); expect(runCliJson.mock.calls).toEqual([ [["send-attachment", "--chat", "chat-1", "--file", "/tmp/image.png", "--transport", "auto"]], ]); @@ -162,7 +162,7 @@ describe("sendMessageIMessage receipts", () => { }); expect(result.messageId).toBe("p:0/media-guid"); - expect(client.request).not.toHaveBeenCalled(); + expect(client["request"]).not.toHaveBeenCalled(); expect(runCliJson.mock.calls).toEqual([ [["group", "--chat-id", "42"]], [ @@ -208,7 +208,7 @@ describe("sendMessageIMessage receipts", () => { expect(runCliJson.mock.calls).toEqual([ [["send-attachment", "--chat", "chat-1", "--file", "/tmp/image.png", "--transport", "auto"]], ]); - expect(client.request).toHaveBeenCalledWith( + expect(client["request"]).toHaveBeenCalledWith( "send", expect.objectContaining({ chat_guid: "chat-1", @@ -233,7 +233,7 @@ describe("sendMessageIMessage receipts", () => { expect(result.messageId).toBe("12345"); expect(runCliJson.mock.calls).toEqual([[["group", "--chat-id", "42"]]]); - expect(client.request).toHaveBeenCalledWith( + expect(client["request"]).toHaveBeenCalledWith( "send", expect.objectContaining({ chat_id: 42, @@ -259,7 +259,7 @@ describe("sendMessageIMessage receipts", () => { runCliJson, }), ).rejects.toThrow("attachment delivery failed"); - expect(client.request).not.toHaveBeenCalled(); + expect(client["request"]).not.toHaveBeenCalled(); }); it("routes DM handle media-only sends through send-attachment", async () => { @@ -395,7 +395,7 @@ describe("sendMessageIMessage receipts", () => { }); expect(runCliJson).not.toHaveBeenCalled(); - expect(client.request).toHaveBeenCalledWith( + expect(client["request"]).toHaveBeenCalledWith( "send", expect.objectContaining({ chat_identifier: "team-thread", @@ -545,7 +545,7 @@ describe("sendMessageIMessage receipts", () => { expect(result.sentText).toBe("literal text"); expect(result.echoText).toBe("literal text"); - expect(client.request).toHaveBeenCalledWith( + expect(client["request"]).toHaveBeenCalledWith( "send", expect.objectContaining({ chat_id: 42, @@ -619,14 +619,14 @@ describe("sendMessageIMessage receipts", () => { it("recovers approval prompt GUID without resending when rpc send times out", async () => { const client = createRejectingClient(new Error("imsg rpc timeout (send)")); - const createClient = vi.fn(async () => client); + const createClientLocal = vi.fn(async () => client); const runCliJson = vi.fn(); const resolveSentMessageGuidImpl = vi.fn(async () => "p:0/fallback-guid"); const approvalText = createApprovalText(); const result = await sendMessageIMessage("chat_id:42", approvalText, { config: IMESSAGE_TEST_CFG, - createClient, + createClient: createClientLocal, runCliJson, service: "sms", dbPath: "/Users/me/Library/Messages/chat.db", @@ -635,7 +635,7 @@ describe("sendMessageIMessage receipts", () => { expect(result.messageId).toBe("p:0/fallback-guid"); expect(result.guid).toBe("p:0/fallback-guid"); - expect(client.stop).toHaveBeenCalledOnce(); + expect(client["stop"]).toHaveBeenCalledOnce(); expect(runCliJson).not.toHaveBeenCalled(); expect(resolveSentMessageGuidImpl).toHaveBeenCalledWith({ dbPath: "/Users/me/Library/Messages/chat.db", diff --git a/extensions/imessage/src/shared.ts b/extensions/imessage/src/shared.ts index 9d857b7401e..239ade5fa15 100644 --- a/extensions/imessage/src/shared.ts +++ b/extensions/imessage/src/shared.ts @@ -106,10 +106,13 @@ export function createIMessagePluginBase(params: { return { ...base, messaging: { - resolveInboundAttachmentRoots: (params) => - resolveIMessageAttachmentRoots({ accountId: params.accountId, cfg: params.cfg }), - resolveRemoteInboundAttachmentRoots: (params) => - resolveIMessageRemoteAttachmentRoots({ accountId: params.accountId, cfg: params.cfg }), + resolveInboundAttachmentRoots: (paramsValue) => + resolveIMessageAttachmentRoots({ accountId: paramsValue.accountId, cfg: paramsValue.cfg }), + resolveRemoteInboundAttachmentRoots: (paramsLocal) => + resolveIMessageRemoteAttachmentRoots({ + accountId: paramsLocal.accountId, + cfg: paramsLocal.cfg, + }), }, } as Pick< ChannelPlugin, diff --git a/extensions/irc/src/inbound.ts b/extensions/irc/src/inbound.ts index 117056556d3..a51dd4d7205 100644 --- a/extensions/irc/src/inbound.ts +++ b/extensions/irc/src/inbound.ts @@ -207,7 +207,7 @@ export async function handleIrcInbound(params: { providerKey: "irc", accountId: account.accountId, blockedLabel: GROUP_POLICY_BLOCKED_LABEL.channel, - log: (message) => runtime.log?.(message), + log: (messageLocal) => runtime.log?.(messageLocal), }); const groupMatch = resolveIrcGroupMatch({ diff --git a/extensions/line/src/download.test.ts b/extensions/line/src/download.test.ts index 805279c8d11..82f9a552668 100644 --- a/extensions/line/src/download.test.ts +++ b/extensions/line/src/download.test.ts @@ -75,11 +75,11 @@ describe("downloadLineMedia", () => { saveMediaStreamMock.mockReset(); saveMediaStreamMock.mockImplementation( async (stream: AsyncIterable, contentType?: string, subdir?: string) => { - const chunks: Buffer[] = []; + const chunksLocal: Buffer[] = []; for await (const chunk of stream) { - chunks.push(Buffer.from(chunk)); + chunksLocal.push(Buffer.from(chunk)); } - const buffer = Buffer.concat(chunks); + const buffer = Buffer.concat(chunksLocal); return { path: `/home/user/.openclaw/media/${subdir ?? "unknown"}/saved-media`, contentType: detectMockContentType(buffer, contentType), diff --git a/extensions/line/src/flex-templates/basic-cards.ts b/extensions/line/src/flex-templates/basic-cards.ts index d1daa4be647..bec66158c3a 100644 --- a/extensions/line/src/flex-templates/basic-cards.ts +++ b/extensions/line/src/flex-templates/basic-cards.ts @@ -91,7 +91,7 @@ export function createInfoCard(title: string, body: string, footer?: string): Fl */ export function createListCard(title: string, items: ListItem[]): FlexBubble { const itemContents: FlexComponent[] = items.slice(0, 8).map((item, index) => { - const itemContents: FlexComponent[] = [ + const itemContentsLocal: FlexComponent[] = [ { type: "text", text: item.title, @@ -103,7 +103,7 @@ export function createListCard(title: string, items: ListItem[]): FlexBubble { ]; if (item.subtitle) { - itemContents.push({ + itemContentsLocal.push({ type: "text", text: item.subtitle, size: "sm", @@ -140,7 +140,7 @@ export function createListCard(title: string, items: ListItem[]): FlexBubble { { type: "box", layout: "vertical", - contents: itemContents, + contents: itemContentsLocal, flex: 1, } as FlexBox, ], diff --git a/extensions/line/src/rich-menu.test.ts b/extensions/line/src/rich-menu.test.ts index 744a2f509a9..2f18889f2dc 100644 --- a/extensions/line/src/rich-menu.test.ts +++ b/extensions/line/src/rich-menu.test.ts @@ -14,11 +14,14 @@ import { } from "./rich-menu.js"; const { setRichMenuImageMock, MessagingApiBlobClientMock } = vi.hoisted(() => { - const setRichMenuImageMock = vi.fn(); - const MessagingApiBlobClientMock = vi.fn(function () { - return { setRichMenuImage: setRichMenuImageMock }; + const setRichMenuImageMockLocal = vi.fn(); + const MessagingApiBlobClientMockLocal = vi.fn(function () { + return { setRichMenuImage: setRichMenuImageMockLocal }; }); - return { setRichMenuImageMock, MessagingApiBlobClientMock }; + return { + setRichMenuImageMock: setRichMenuImageMockLocal, + MessagingApiBlobClientMock: MessagingApiBlobClientMockLocal, + }; }); vi.mock("@line/bot-sdk", () => ({ diff --git a/extensions/line/src/send.test.ts b/extensions/line/src/send.test.ts index 9e056aa34b3..230c902560d 100644 --- a/extensions/line/src/send.test.ts +++ b/extensions/line/src/send.test.ts @@ -13,36 +13,36 @@ const { logVerboseMock, resolvePinnedHostnameWithPolicyMock, } = vi.hoisted(() => { - const pushMessageMock = vi.fn(); - const replyMessageMock = vi.fn(); - const showLoadingAnimationMock = vi.fn(); - const getProfileMock = vi.fn(); - const MessagingApiClientMock = vi.fn(function () { + const pushMessageMockLocal = vi.fn(); + const replyMessageMockLocal = vi.fn(); + const showLoadingAnimationMockLocal = vi.fn(); + const getProfileMockLocal = vi.fn(); + const MessagingApiClientMockLocal = vi.fn(function () { return { - pushMessage: pushMessageMock, - replyMessage: replyMessageMock, - showLoadingAnimation: showLoadingAnimationMock, - getProfile: getProfileMock, + pushMessage: pushMessageMockLocal, + replyMessage: replyMessageMockLocal, + showLoadingAnimation: showLoadingAnimationMockLocal, + getProfile: getProfileMockLocal, }; }); - const requireRuntimeConfigMock = vi.fn((cfg: unknown) => cfg ?? {}); - const resolveLineAccountMock = vi.fn(() => ({ accountId: "default" })); - const resolveLineChannelAccessTokenMock = vi.fn(() => "line-token"); - const recordChannelActivityMock = vi.fn(); - const logVerboseMock = vi.fn(); - const resolvePinnedHostnameWithPolicyMock = vi.fn(); + const requireRuntimeConfigMockLocal = vi.fn((cfg: unknown) => cfg ?? {}); + const resolveLineAccountMockLocal = vi.fn(() => ({ accountId: "default" })); + const resolveLineChannelAccessTokenMockLocal = vi.fn(() => "line-token"); + const recordChannelActivityMockLocal = vi.fn(); + const logVerboseMockLocal = vi.fn(); + const resolvePinnedHostnameWithPolicyMockLocal = vi.fn(); return { - pushMessageMock, - replyMessageMock, - showLoadingAnimationMock, - getProfileMock, - MessagingApiClientMock, - requireRuntimeConfigMock, - resolveLineAccountMock, - resolveLineChannelAccessTokenMock, - recordChannelActivityMock, - logVerboseMock, - resolvePinnedHostnameWithPolicyMock, + pushMessageMock: pushMessageMockLocal, + replyMessageMock: replyMessageMockLocal, + showLoadingAnimationMock: showLoadingAnimationMockLocal, + getProfileMock: getProfileMockLocal, + MessagingApiClientMock: MessagingApiClientMockLocal, + requireRuntimeConfigMock: requireRuntimeConfigMockLocal, + resolveLineAccountMock: resolveLineAccountMockLocal, + resolveLineChannelAccessTokenMock: resolveLineChannelAccessTokenMockLocal, + recordChannelActivityMock: recordChannelActivityMockLocal, + logVerboseMock: logVerboseMockLocal, + resolvePinnedHostnameWithPolicyMock: resolvePinnedHostnameWithPolicyMockLocal, }; }); diff --git a/extensions/line/src/setup-surface.test.ts b/extensions/line/src/setup-surface.test.ts index 578e5b0ac7d..edd0e083803 100644 --- a/extensions/line/src/setup-surface.test.ts +++ b/extensions/line/src/setup-surface.test.ts @@ -19,11 +19,14 @@ import { lineSetupWizard } from "./setup-surface.js"; import { lineStatusAdapter } from "./status.js"; const { getBotInfoMock, MessagingApiClientMock } = vi.hoisted(() => { - const getBotInfoMock = vi.fn(); - const MessagingApiClientMock = vi.fn(function () { - return { getBotInfo: getBotInfoMock }; + const getBotInfoMockLocal = vi.fn(); + const MessagingApiClientMockLocal = vi.fn(function () { + return { getBotInfo: getBotInfoMockLocal }; }); - return { getBotInfoMock, MessagingApiClientMock }; + return { + getBotInfoMock: getBotInfoMockLocal, + MessagingApiClientMock: MessagingApiClientMockLocal, + }; }); vi.mock("@line/bot-sdk", () => ({ diff --git a/extensions/matrix/src/channel.ts b/extensions/matrix/src/channel.ts index 0cda362469e..71e3e173501 100644 --- a/extensions/matrix/src/channel.ts +++ b/extensions/matrix/src/channel.ts @@ -542,9 +542,9 @@ export const matrixPlugin: ChannelPlugin = buildProbeChannelStatusSummary(snapshot, { baseUrl: snapshot.baseUrl ?? null }), probeAccount: async ({ account, timeoutMs, cfg }) => await createMatrixProbeAccount({ - resolveMatrixAuth: async ({ cfg, accountId }) => + resolveMatrixAuth: async ({ cfg: cfgLocal, accountId }) => (await loadMatrixChannelRuntime()).resolveMatrixAuth({ - cfg, + cfg: cfgLocal, accountId, }), probeMatrix: async (params) => diff --git a/extensions/matrix/src/matrix/actions/client.test.ts b/extensions/matrix/src/matrix/actions/client.test.ts index d769303a5e1..cdcad4a69e8 100644 --- a/extensions/matrix/src/matrix/actions/client.test.ts +++ b/extensions/matrix/src/matrix/actions/client.test.ts @@ -111,7 +111,7 @@ describe("action client helpers", () => { expect(result).toBe("ok"); expect(acquireSharedMatrixClientMock).not.toHaveBeenCalled(); - expect(activeClient.stop).not.toHaveBeenCalled(); + expect(activeClient["stop"]).not.toHaveBeenCalled(); }); it("starts active clients when started readiness is required", async () => { @@ -122,10 +122,10 @@ describe("action client helpers", () => { expect(client).toBe(activeClient); }); - expect(activeClient.start).toHaveBeenCalledTimes(1); - expect(activeClient.prepareForOneOff).not.toHaveBeenCalled(); - expect(activeClient.stop).not.toHaveBeenCalled(); - expect(activeClient.stopAndPersist).not.toHaveBeenCalled(); + expect(activeClient["start"]).toHaveBeenCalledTimes(1); + expect(activeClient["prepareForOneOff"]).not.toHaveBeenCalled(); + expect(activeClient["stop"]).not.toHaveBeenCalled(); + expect(activeClient["stopAndPersist"]).not.toHaveBeenCalled(); }); it("uses the implicit resolved account id for active client lookup and storage", async () => { diff --git a/extensions/matrix/src/matrix/client-bootstrap.test.ts b/extensions/matrix/src/matrix/client-bootstrap.test.ts index 421add0998a..9f1bb5aab33 100644 --- a/extensions/matrix/src/matrix/client-bootstrap.test.ts +++ b/extensions/matrix/src/matrix/client-bootstrap.test.ts @@ -53,7 +53,7 @@ describe("client bootstrap", () => { it("releases leased shared clients when readiness setup fails", async () => { const sharedClient = createMockMatrixClient(); - vi.mocked(sharedClient.prepareForOneOff).mockRejectedValue(new Error("prepare failed")); + vi.mocked(sharedClient["prepareForOneOff"]).mockRejectedValue(new Error("prepare failed")); acquireSharedMatrixClientMock.mockResolvedValue(sharedClient); await expect( @@ -69,7 +69,7 @@ describe("client bootstrap", () => { it("releases leased shared clients when the wrapped action throws during readiness", async () => { const sharedClient = createMockMatrixClient(); - vi.mocked(sharedClient.start).mockRejectedValue(new Error("start failed")); + vi.mocked(sharedClient["start"]).mockRejectedValue(new Error("start failed")); acquireSharedMatrixClientMock.mockResolvedValue(sharedClient); await expect( diff --git a/extensions/matrix/src/matrix/monitor/handler.test-helpers.ts b/extensions/matrix/src/matrix/monitor/handler.test-helpers.ts index b459ad7045c..09080c1b28f 100644 --- a/extensions/matrix/src/matrix/monitor/handler.test-helpers.ts +++ b/extensions/matrix/src/matrix/monitor/handler.test-helpers.ts @@ -259,9 +259,9 @@ export function createMatrixHandlerTestHarness( run: () => Promise; onSettled?: () => void | Promise; }) => { - const { dispatcher, run, onSettled } = params; + const { dispatcher, run: runLocal, onSettled } = params; try { - return await run(); + return await runLocal(); } finally { dispatcher.markComplete?.(); try { diff --git a/extensions/matrix/src/matrix/monitor/handler.ts b/extensions/matrix/src/matrix/monitor/handler.ts index ca9ce31b380..ebeddc69c76 100644 --- a/extensions/matrix/src/matrix/monitor/handler.ts +++ b/extensions/matrix/src/matrix/monitor/handler.ts @@ -468,7 +468,7 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam type LiveAllowlistCacheEntry = { signature: string; entries: string[] }; let liveDmAllowlistCache: LiveAllowlistCacheEntry | null = null; let liveGroupAllowlistCache: LiveAllowlistCacheEntry | null = null; - const resolveCachedLiveAllowlist = async (params: { + const resolveCachedLiveAllowlist = async (paramsValue: { cfg: CoreConfig; entries?: ReadonlyArray; failClosedOnUnresolved?: boolean; @@ -476,25 +476,25 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam cache: LiveAllowlistCacheEntry | null; updateCache: (next: LiveAllowlistCacheEntry) => void; }): Promise => { - const accountConfig = resolveMatrixAccountConfig({ cfg: params.cfg, accountId }); + const accountConfigLocal = resolveMatrixAccountConfig({ cfg: paramsValue.cfg, accountId }); const signature = JSON.stringify({ - entries: (params.entries ?? []).map((entry) => String(entry).trim()), - failClosedOnUnresolved: params.failClosedOnUnresolved === true, - dangerouslyAllowNameMatching: isDangerousNameMatchingEnabled(accountConfig), + entries: (paramsValue.entries ?? []).map((entry) => String(entry).trim()), + failClosedOnUnresolved: paramsValue.failClosedOnUnresolved === true, + dangerouslyAllowNameMatching: isDangerousNameMatchingEnabled(accountConfigLocal), }); - if (params.cache?.signature === signature) { - return params.cache.entries; + if (paramsValue.cache?.signature === signature) { + return paramsValue.cache.entries; } const entries = await resolveLiveUserAllowlist({ - cfg: params.cfg, + cfg: paramsValue.cfg, accountId, - entries: params.entries, - failClosedOnUnresolved: params.failClosedOnUnresolved, - startupResolvedEntries: params.startupResolvedEntries, + entries: paramsValue.entries, + failClosedOnUnresolved: paramsValue.failClosedOnUnresolved, + startupResolvedEntries: paramsValue.startupResolvedEntries, runtime, }); const next = { signature, entries }; - params.updateCache(next); + paramsValue.updateCache(next); return entries; }; const pairingReplySentAtMsBySender = new Map(); @@ -677,16 +677,16 @@ export function createMatrixRoomMessageHandler(params: MatrixMonitorHandlerParam }); return { content, isDirectMessage, locationPayload, selfUserId }; }; - const continueIngress = async (params: { + const continueIngress = async (paramsLocal: { content: RoomMessageEventContent; isDirectMessage: boolean; locationPayload: MatrixLocationPayload | null; selfUserId: string; }) => { - let content = params.content; - const isDirectMessage = params.isDirectMessage; + let content = paramsLocal.content; + const isDirectMessage = paramsLocal.isDirectMessage; const isRoom = !isDirectMessage; - const { locationPayload, selfUserId } = params; + const { locationPayload, selfUserId } = paramsLocal; if (isRoom && groupPolicy === "disabled") { await commitInboundEventIfClaimed(); return undefined; diff --git a/extensions/matrix/src/matrix/monitor/index.test.ts b/extensions/matrix/src/matrix/monitor/index.test.ts index 8d3b27eb0cc..0951eb5ceef 100644 --- a/extensions/matrix/src/matrix/monitor/index.test.ts +++ b/extensions/matrix/src/matrix/monitor/index.test.ts @@ -64,7 +64,7 @@ const hoisted = vi.hoisted(() => { }); const createMatrixRoomMessageHandler = vi.fn(() => vi.fn()); const createDirectRoomTracker = vi.fn( - (clientForTest: unknown, _opts?: DirectRoomTrackerOptions) => ({ + (_clientForTest: unknown, _opts?: DirectRoomTrackerOptions) => ({ isDirectMessage: vi.fn(async () => false), }), ); diff --git a/extensions/matrix/src/matrix/monitor/replies.test.ts b/extensions/matrix/src/matrix/monitor/replies.test.ts index 8a30ffa9bd6..4808d21bf26 100644 --- a/extensions/matrix/src/matrix/monitor/replies.test.ts +++ b/extensions/matrix/src/matrix/monitor/replies.test.ts @@ -56,8 +56,8 @@ describe("deliverMatrixReplies", () => { text: { resolveMarkdownTableMode: (params: unknown) => resolveMarkdownTableModeMock(params), convertMarkdownTables: (text: string) => convertMarkdownTablesMock(text), - resolveChunkMode: (cfg: unknown, channel: unknown, accountId?: unknown) => - resolveChunkModeMock(cfg, channel, accountId), + resolveChunkMode: (cfgLocal: unknown, channel: unknown, accountId?: unknown) => + resolveChunkModeMock(cfgLocal, channel, accountId), chunkMarkdownTextWithMode: (text: string) => chunkMarkdownTextWithModeMock(text), }, }, diff --git a/extensions/matrix/src/matrix/monitor/room-history.test.ts b/extensions/matrix/src/matrix/monitor/room-history.test.ts index 7d20ba39ebf..c0ac7b501a6 100644 --- a/extensions/matrix/src/matrix/monitor/room-history.test.ts +++ b/extensions/matrix/src/matrix/monitor/room-history.test.ts @@ -60,8 +60,8 @@ describe("createRoomHistoryTracker — watermark monotonicity", () => { messageId: "$trigger", }); - expect(first.history.map((entry) => entry.body)).toEqual(["msg1"]); - expect(retried.history.map((entry) => entry.body)).toEqual(["msg1"]); + expect(first.history.map((entryValue) => entryValue.body)).toEqual(["msg1"]); + expect(retried.history.map((entryLocal) => entryLocal.body)).toEqual(["msg1"]); expect(retried.snapshotIdx).toBe(first.snapshotIdx); }); diff --git a/extensions/matrix/src/matrix/monitor/status.ts b/extensions/matrix/src/matrix/monitor/status.ts index 108485b2fad..ad52cbfa9ff 100644 --- a/extensions/matrix/src/matrix/monitor/status.ts +++ b/extensions/matrix/src/matrix/monitor/status.ts @@ -70,9 +70,13 @@ export function createMatrixMonitorStatusController(params: { emit(); }; - const noteDisconnected = (params: { state: MatrixSyncState; at?: number; error?: unknown }) => { - const at = params.at ?? Date.now(); - const error = formatSyncError(params.error); + const noteDisconnected = (paramsLocal: { + state: MatrixSyncState; + at?: number; + error?: unknown; + }) => { + const at = paramsLocal.at ?? Date.now(); + const error = formatSyncError(paramsLocal.error); status.connected = false; status.lastEventAt = at; status.lastDisconnect = { @@ -80,7 +84,7 @@ export function createMatrixMonitorStatusController(params: { ...(error ? { error } : {}), }; status.lastError = error; - status.healthState = params.state.toLowerCase(); + status.healthState = paramsLocal.state.toLowerCase(); emit(); }; diff --git a/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts b/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts index db58300fe33..67173ab71b0 100644 --- a/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts +++ b/extensions/matrix/src/matrix/monitor/sync-lifecycle.ts @@ -37,9 +37,9 @@ export function createMatrixMonitorSyncLifecycle(params: { const onSyncState = (state: MatrixSyncState, _prevState: string | null, error?: unknown) => { if (isMatrixTerminalSyncState(state) && !params.isStopping?.()) { - const fatalError = formatSyncLifecycleError(state, error); - params.statusController.noteUnexpectedError(fatalError); - settleFatal(fatalError); + const fatalErrorLocal = formatSyncLifecycleError(state, error); + params.statusController.noteUnexpectedError(fatalErrorLocal); + settleFatal(fatalErrorLocal); return; } // Fatal sync failures are sticky for telemetry; later SDK state churn during diff --git a/extensions/matrix/src/matrix/sdk.test.ts b/extensions/matrix/src/matrix/sdk.test.ts index bc0e1c61ea3..08671cccd57 100644 --- a/extensions/matrix/src/matrix/sdk.test.ts +++ b/extensions/matrix/src/matrix/sdk.test.ts @@ -39,16 +39,6 @@ async function expectAbortError(promise: Promise) { name: "AbortError", }); } - -function expectMockCallOptions( - mock: ReturnType, - callIndex: number, - fields: Record, -) { - const call = (mock.mock.calls as unknown[][])[callIndex]?.[0]; - expectRecordFields(requireRecord(call, `mock call ${callIndex + 1} options`), fields); -} - function expectSomeMockCallOptions( mock: ReturnType, fields: Record, @@ -623,7 +613,7 @@ describe("MatrixClient request hardening", () => { it("aborts requests after timeout", async () => { vi.useFakeTimers(); const fetchMock = vi.fn((_: URL | string, init?: RequestInit) => { - return new Promise((_, reject) => { + return new Promise((_Value, reject) => { init?.signal?.addEventListener("abort", () => { reject(new Error("aborted")); }); @@ -646,7 +636,7 @@ describe("MatrixClient request hardening", () => { it("falls back to the default timeout for non-finite localTimeoutMs", async () => { vi.useFakeTimers(); const fetchMock = vi.fn((_: URL | string, init?: RequestInit) => { - return new Promise((_, reject) => { + return new Promise((_Local, reject) => { init?.signal?.addEventListener("abort", () => { reject(new Error("aborted")); }); diff --git a/extensions/matrix/src/matrix/send/client.test.ts b/extensions/matrix/src/matrix/send/client.test.ts index 81a0e7711eb..f72454cf8cb 100644 --- a/extensions/matrix/src/matrix/send/client.test.ts +++ b/extensions/matrix/src/matrix/send/client.test.ts @@ -85,9 +85,9 @@ describe("matrix send client helpers", () => { expect(result).toBe("ok"); expect(acquireSharedMatrixClientMock).not.toHaveBeenCalled(); - expect(activeClient.start).toHaveBeenCalledTimes(1); - expect(activeClient.stop).not.toHaveBeenCalled(); - expect(activeClient.stopAndPersist).not.toHaveBeenCalled(); + expect(activeClient["start"]).toHaveBeenCalledTimes(1); + expect(activeClient["stop"]).not.toHaveBeenCalled(); + expect(activeClient["stopAndPersist"]).not.toHaveBeenCalled(); }); it("uses the effective account id when auth resolution is implicit", async () => { @@ -143,8 +143,8 @@ describe("matrix send client helpers", () => { await withResolvedMatrixSendClient({ cfg: TEST_CFG, accountId: "default" }, async () => "ok"); - expect(sharedClient.start).toHaveBeenCalledTimes(1); - expect(sharedClient.prepareForOneOff).not.toHaveBeenCalled(); + expect(sharedClient["start"]).toHaveBeenCalledTimes(1); + expect(sharedClient["prepareForOneOff"]).not.toHaveBeenCalled(); }); it("keeps one-off control clients lightweight when no active monitor client is registered", async () => { @@ -175,8 +175,8 @@ describe("matrix send client helpers", () => { expect(result).toBe("ok"); expect(acquireSharedMatrixClientMock).not.toHaveBeenCalled(); - expect(activeClient.start).not.toHaveBeenCalled(); - expect(activeClient.stop).not.toHaveBeenCalled(); - expect(activeClient.stopAndPersist).not.toHaveBeenCalled(); + expect(activeClient["start"]).not.toHaveBeenCalled(); + expect(activeClient["stop"]).not.toHaveBeenCalled(); + expect(activeClient["stopAndPersist"]).not.toHaveBeenCalled(); }); }); diff --git a/extensions/matrix/src/matrix/send/targets.test.ts b/extensions/matrix/src/matrix/send/targets.test.ts index 8ccebb99f34..32c390d0e99 100644 --- a/extensions/matrix/src/matrix/send/targets.test.ts +++ b/extensions/matrix/src/matrix/send/targets.test.ts @@ -53,8 +53,8 @@ describe("resolveMatrixRoomId", () => { const roomId = await resolveMatrixRoomId(client, userId); expect(roomId).toBe("!room:example.org"); - expect(client.getJoinedRooms).toHaveBeenCalledTimes(1); - expect(client.setAccountData).not.toHaveBeenCalled(); + expect(client["getJoinedRooms"]).toHaveBeenCalledTimes(1); + expect(client["setAccountData"]).not.toHaveBeenCalled(); }); it("falls back to joined rooms and persists m.direct", async () => { @@ -65,7 +65,7 @@ describe("resolveMatrixRoomId", () => { const resolved = await resolveMatrixRoomId(client, userId); expect(resolved).toBe(roomId); - expect(client.setAccountData).toHaveBeenCalledWith(EventType.Direct, { [userId]: [roomId] }); + expect(client["setAccountData"]).toHaveBeenCalledWith(EventType.Direct, { [userId]: [roomId] }); }); it("prefers joined rooms marked direct in local member state over plain strict rooms", async () => { @@ -87,7 +87,7 @@ describe("resolveMatrixRoomId", () => { const resolved = await resolveMatrixRoomId(client, userId); expect(resolved).toBe("!explicit:example.org"); - expect(client.setAccountData).toHaveBeenCalledWith(EventType.Direct, { + expect(client["setAccountData"]).toHaveBeenCalledWith(EventType.Direct, { [userId]: ["!explicit:example.org"], }); }); @@ -111,7 +111,7 @@ describe("resolveMatrixRoomId", () => { const resolved = await resolveMatrixRoomId(client, userId); expect(resolved).toBe("!fallback:example.org"); - expect(client.setAccountData).toHaveBeenCalledWith(EventType.Direct, { + expect(client["setAccountData"]).toHaveBeenCalledWith(EventType.Direct, { [userId]: ["!fallback:example.org"], }); }); @@ -150,7 +150,7 @@ describe("resolveMatrixRoomId", () => { await expect(resolveMatrixRoomId(client, userId)).rejects.toThrow( `No direct room found for ${userId} (m.direct missing)`, ); - expect(client.setAccountData).not.toHaveBeenCalled(); + expect(client["setAccountData"]).not.toHaveBeenCalled(); }); it("accepts nested Matrix user target prefixes", async () => { @@ -167,7 +167,7 @@ describe("resolveMatrixRoomId", () => { const resolved = await resolveMatrixRoomId(client, `matrix:user:${userId}`); expect(resolved).toBe(roomId); - expect(client.resolveRoom).not.toHaveBeenCalled(); + expect(client["resolveRoom"]).not.toHaveBeenCalled(); }); it("scopes direct-room cache per Matrix client", async () => { @@ -196,8 +196,8 @@ describe("resolveMatrixRoomId", () => { await expect(resolveMatrixRoomId(clientA, userId)).resolves.toBe("!room-a:example.org"); await expect(resolveMatrixRoomId(clientB, userId)).resolves.toBe("!room-b:example.org"); - expect(clientA.getAccountData).toHaveBeenCalledTimes(1); - expect(clientB.getAccountData).toHaveBeenCalledTimes(1); + expect(clientA["getAccountData"]).toHaveBeenCalledTimes(1); + expect(clientB["getAccountData"]).toHaveBeenCalledTimes(1); }); it("ignores m.direct entries that point at shared rooms", async () => { diff --git a/extensions/matrix/src/outbound.test.ts b/extensions/matrix/src/outbound.test.ts index 6e805d72aab..9cad01a618b 100644 --- a/extensions/matrix/src/outbound.test.ts +++ b/extensions/matrix/src/outbound.test.ts @@ -230,7 +230,7 @@ describe("matrixOutbound cfg threading", () => { expect(rendered?.text).toBe("---"); expect( - (rendered?.channelData?.matrix as { extraContent?: Record }).extraContent?.[ + (rendered!.channelData!.matrix as { extraContent?: Record }).extraContent?.[ "com.openclaw.presentation" ], ).toEqual({ diff --git a/extensions/mattermost/src/mattermost/monitor-resources.ts b/extensions/mattermost/src/mattermost/monitor-resources.ts index ae10b6cd774..df71fcdcbc5 100644 --- a/extensions/mattermost/src/mattermost/monitor-resources.ts +++ b/extensions/mattermost/src/mattermost/monitor-resources.ts @@ -166,17 +166,17 @@ export function createMattermostMonitorResources(params: { buttons, }); - const updateModelPickerPost = async (params: { + const updateModelPickerPost = async (paramsLocal: { channelId: string; postId: string; message: string; buttons?: Array; }): Promise => { - const props = buildModelPickerProps(params.channelId, params.buttons ?? []) ?? { + const props = buildModelPickerProps(paramsLocal.channelId, paramsLocal.buttons ?? []) ?? { attachments: [], }; - await updateMattermostPost(client, params.postId, { - message: params.message, + await updateMattermostPost(client, paramsLocal.postId, { + message: paramsLocal.message, props, }); return {}; diff --git a/extensions/mattermost/src/mattermost/monitor.inbound-system-event.test.ts b/extensions/mattermost/src/mattermost/monitor.inbound-system-event.test.ts index c91baef38a4..510718cb5e0 100644 --- a/extensions/mattermost/src/mattermost/monitor.inbound-system-event.test.ts +++ b/extensions/mattermost/src/mattermost/monitor.inbound-system-event.test.ts @@ -904,9 +904,10 @@ describe("mattermost inbound user posts", () => { team_id: "team-1", type: "D", }); - const { monitorMattermostProvider } = await import("./monitor.js"); + const { monitorMattermostProvider: monitorMattermostProviderLocal } = + await import("./monitor.js"); - const monitor = monitorMattermostProvider({ + const monitor = monitorMattermostProviderLocal({ config: directConfig, runtime: testRuntime(), abortSignal: abortController.signal, diff --git a/extensions/mattermost/src/mattermost/monitor.ts b/extensions/mattermost/src/mattermost/monitor.ts index 8250f24bd1e..dda2506dd8f 100644 --- a/extensions/mattermost/src/mattermost/monitor.ts +++ b/extensions/mattermost/src/mattermost/monitor.ts @@ -695,11 +695,11 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} threadRootId: post.root_id, }).sessionKey; }, - dispatchButtonClick: async (opts) => { - const channelInfo = await resolveChannelInfo(opts.channelId); + dispatchButtonClick: async (optsLocal) => { + const channelInfo = await resolveChannelInfo(optsLocal.channelId); if (!channelInfo?.type) { logVerboseMessage( - `mattermost: drop interaction dispatch (cannot resolve channel type for ${opts.channelId})`, + `mattermost: drop interaction dispatch (cannot resolve channel type for ${optsLocal.channelId})`, ); return; } @@ -707,7 +707,7 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} const chatType = channelChatType(kind); const teamId = channelInfo?.team_id ?? undefined; const channelName = channelInfo?.name ?? undefined; - const channelDisplay = channelInfo?.display_name ?? channelName ?? opts.channelId; + const channelDisplay = channelInfo?.display_name ?? channelName ?? optsLocal.channelId; const route = core.channel.routing.resolveAgentRoute({ cfg, channel: "mattermost", @@ -715,19 +715,20 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} teamId, peer: { kind, - id: kind === "direct" ? opts.userId : opts.channelId, + id: kind === "direct" ? optsLocal.userId : optsLocal.channelId, }, }); const replyToMode = resolveMattermostReplyToMode(account, kind); const threadContext = resolveMattermostThreadSessionContext({ baseSessionKey: route.sessionKey, kind, - postId: opts.post.id || opts.postId, + postId: optsLocal.post.id || optsLocal.postId, replyToMode, - threadRootId: opts.post.root_id, + threadRootId: optsLocal.post.root_id, }); - const to = kind === "direct" ? `user:${opts.userId}` : `channel:${opts.channelId}`; - const bodyText = `[Button click: user @${opts.userName} selected "${opts.actionName}"]`; + const to = + kind === "direct" ? `user:${optsLocal.userId}` : `channel:${optsLocal.channelId}`; + const bodyText = `[Button click: user @${optsLocal.userName} selected "${optsLocal.actionName}"]`; const ctxPayload = core.channel.reply.finalizeInboundContext({ Body: bodyText, BodyForAgent: bodyText, @@ -735,24 +736,24 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} CommandBody: bodyText, From: kind === "direct" - ? `mattermost:${opts.userId}` + ? `mattermost:${optsLocal.userId}` : kind === "group" - ? `mattermost:group:${opts.channelId}` - : `mattermost:channel:${opts.channelId}`, + ? `mattermost:group:${optsLocal.channelId}` + : `mattermost:channel:${optsLocal.channelId}`, To: to, SessionKey: threadContext.sessionKey, ParentSessionKey: threadContext.parentSessionKey, AccountId: route.accountId, ChatType: chatType, - ConversationLabel: `mattermost:${opts.userName}`, + ConversationLabel: `mattermost:${optsLocal.userName}`, GroupSubject: kind !== "direct" ? channelDisplay : undefined, GroupChannel: channelName ? `#${channelName}` : undefined, GroupSpace: teamId, - SenderName: opts.userName, - SenderId: opts.userId, + SenderName: optsLocal.userName, + SenderId: optsLocal.userId, Provider: "mattermost" as const, Surface: "mattermost" as const, - MessageSid: `interaction:${opts.postId}:${opts.actionId}`, + MessageSid: `interaction:${optsLocal.postId}:${optsLocal.actionId}`, ReplyToId: threadContext.effectiveReplyToId, MessageThreadId: threadContext.effectiveReplyToId, WasMentioned: true, @@ -779,12 +780,13 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} channel: "mattermost", accountId: account.accountId, typing: { - start: () => sendTypingIndicator(opts.channelId, threadContext.effectiveReplyToId), + start: () => + sendTypingIndicator(optsLocal.channelId, threadContext.effectiveReplyToId), onStartError: (err) => { logTypingFailure({ log: (message) => logger.debug?.(message), channel: "mattermost", - target: opts.channelId, + target: optsLocal.channelId, error: err, }); }, @@ -1742,9 +1744,9 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} ...replyPipeline, humanDelay: core.channel.reply.resolveHumanDelayConfig(cfg, route.agentId), typingCallbacks, - deliver: async (payload: ReplyPayload, info) => { + deliver: async (payloadEntry: ReplyPayload, info) => { await deliverMattermostReplyWithDraftPreview({ - payload, + payload: payloadEntry, info, kind, client, @@ -1883,9 +1885,9 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} ? { suppressDefaultToolProgressMessages: true } : {}), onModelSelected, - onPartialReply: (payload) => { + onPartialReply: (payloadResult) => { if (account.streamingMode !== "progress") { - updateDraftFromPartial(payload.text); + updateDraftFromPartial(payloadResult.text); } }, onAssistantMessageStart: () => { @@ -1899,18 +1901,18 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} draftStream.update("Thinking…"); } }, - onToolStart: async (payload) => { + onToolStart: async (payloadValue) => { if (!draftToolProgressEnabled) { return; } draftStream.update( buildMattermostToolStatusText({ - ...payload, + ...payloadValue, config: account.config, }), ); }, - onItemEvent: async (payload) => { + onItemEvent: async (payloadLocal) => { if (!draftToolProgressEnabled) { return; } @@ -1918,15 +1920,15 @@ export async function monitorMattermostProvider(opts: MonitorMattermostOpts = {} account.config, { event: "item", - itemId: payload.itemId, - itemKind: payload.kind, - title: payload.title, - name: payload.name, - phase: payload.phase, - status: payload.status, - summary: payload.summary, - progressText: payload.progressText, - meta: payload.meta, + itemId: payloadLocal.itemId, + itemKind: payloadLocal.kind, + title: payloadLocal.title, + name: payloadLocal.name, + phase: payloadLocal.phase, + status: payloadLocal.status, + summary: payloadLocal.summary, + progressText: payloadLocal.progressText, + meta: payloadLocal.meta, }, ); if (progressText) { diff --git a/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts b/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts index 47cf6be3c81..d2881acaf97 100644 --- a/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts +++ b/extensions/memory-core/src/memory/manager.readonly-recovery.test.ts @@ -2,11 +2,9 @@ import fs from "node:fs/promises"; import os from "node:os"; import path from "node:path"; import type { DatabaseSync } from "node:sqlite"; -import type { OpenClawConfig } from "openclaw/plugin-sdk/memory-core-host-engine-foundation"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { openMemoryDatabaseAtPath } from "./manager-db.js"; import { - createMemorySyncControlConfigForTests, enqueueMemoryTargetedSessionSync, runMemorySyncWithReadonlyRecovery, type MemoryReadonlyRecoveryState, @@ -53,11 +51,6 @@ describe("memory manager readonly recovery", () => { }, }; } - - function createMemoryConfigForTests(): OpenClawConfig { - return createMemorySyncControlConfigForTests(workspaceDir, indexPath); - } - function createReadonlyRecoveryHarness() { const reopenedClose = vi.fn(); const initialClose = vi.fn(); diff --git a/extensions/memory-core/src/memory/manager.ts b/extensions/memory-core/src/memory/manager.ts index b89bbffbbe3..909e47eb58e 100644 --- a/extensions/memory-core/src/memory/manager.ts +++ b/extensions/memory-core/src/memory/manager.ts @@ -353,8 +353,8 @@ export class MemoryIndexManager extends MemoryManagerEmbeddingOps implements Mem this.providerKey = this.computeProviderKey(); this.batch = this.resolveBatchConfig(); this.vector.semanticAvailable = false; - void Promise.resolve(degradedProvider.close?.()).catch((err: unknown) => { - log.debug(`memory embeddings: failed to close degraded local provider: ${String(err)}`); + void Promise.resolve(degradedProvider.close?.()).catch((errLocal: unknown) => { + log.debug(`memory embeddings: failed to close degraded local provider: ${String(errLocal)}`); }); log.warn("memory embeddings: local provider degraded after worker failure", { error: message, diff --git a/extensions/memory-core/src/memory/manager.watcher-config.test.ts b/extensions/memory-core/src/memory/manager.watcher-config.test.ts index 721cc0bd012..244573f968e 100644 --- a/extensions/memory-core/src/memory/manager.watcher-config.test.ts +++ b/extensions/memory-core/src/memory/manager.watcher-config.test.ts @@ -493,7 +493,7 @@ describe("memory watcher config", () => { // attaching a watcher per entry, defeating the constant-watcher-profile // goal of this fix. The PR explicitly gates the native path off those // platforms. - const originalPlatform = process.platform; + const originalPlatformValue = process.platform; try { Object.defineProperty(process, "platform", { value: "linux", configurable: true }); await setupWatcherWorkspace({ name: "notes.md", contents: "hello" }); @@ -519,7 +519,7 @@ describe("memory watcher config", () => { ); } finally { Object.defineProperty(process, "platform", { - value: originalPlatform, + value: originalPlatformValue, configurable: true, }); } @@ -529,7 +529,7 @@ describe("memory watcher config", () => { // Windows uses ReadDirectoryChangesW for `fs.watch(dir, { recursive: true })`, // which is a single-watcher native recursive backend (constant FD profile). // The PR explicitly opts Windows into the native path alongside macOS. - const originalPlatform = process.platform; + const originalPlatformLocal = process.platform; try { Object.defineProperty(process, "platform", { value: "win32", configurable: true }); await setupWatcherWorkspace({ name: "notes.md", contents: "hello" }); @@ -569,7 +569,7 @@ describe("memory watcher config", () => { } } finally { Object.defineProperty(process, "platform", { - value: originalPlatform, + value: originalPlatformLocal, configurable: true, }); } diff --git a/extensions/memory-core/src/memory/qmd-manager.ts b/extensions/memory-core/src/memory/qmd-manager.ts index ca956076bd0..6e304c3e540 100644 --- a/extensions/memory-core/src/memory/qmd-manager.ts +++ b/extensions/memory-core/src/memory/qmd-manager.ts @@ -2576,8 +2576,8 @@ export class QmdMemoryManager implements MemorySearchManager { } private toCollectionRelativePath(collection: string, filePath: string): string | null { - const root = this.collectionRoots.get(collection); - if (!root) { + const rootItem = this.collectionRoots.get(collection); + if (!rootItem) { return null; } const trimmedFilePath = filePath.trim(); @@ -2587,11 +2587,11 @@ export class QmdMemoryManager implements MemorySearchManager { const normalizedInput = path.normalize(trimmedFilePath); const absolutePath = path.isAbsolute(normalizedInput) ? normalizedInput - : path.resolve(root.path, normalizedInput); - if (!this.isWithinRoot(root.path, absolutePath)) { + : path.resolve(rootItem.path, normalizedInput); + if (!this.isWithinRoot(rootItem.path, absolutePath)) { return null; } - const relative = path.relative(root.path, absolutePath); + const relative = path.relative(rootItem.path, absolutePath); if (!relative || relative === ".") { return null; } @@ -2758,8 +2758,8 @@ export class QmdMemoryManager implements MemorySearchManager { } let total = 0; for (const row of rows) { - const root = this.collectionRoots.get(row.collection); - const source = root?.kind ?? "memory"; + const rootCandidate = this.collectionRoots.get(row.collection); + const source = rootCandidate?.kind ?? "memory"; const entry = bySource.get(source) ?? { files: 0, chunks: 0 }; entry.files += row.c ?? 0; entry.chunks += row.c ?? 0; @@ -2800,12 +2800,12 @@ export class QmdMemoryManager implements MemorySearchManager { collection: string, collectionRelativePath: string, ): { rel: string; abs: string; source: MemorySource } | null { - const root = this.collectionRoots.get(collection); - if (!root) { + const rootEntry = this.collectionRoots.get(collection); + if (!rootEntry) { return null; } const normalizedRelative = collectionRelativePath.replace(/\\/g, "/"); - const absPath = path.normalize(path.resolve(root.path, collectionRelativePath)); + const absPath = path.normalize(path.resolve(rootEntry.path, collectionRelativePath)); const relativeToWorkspace = path.relative(this.workspaceDir, absPath); const relPath = this.buildSearchPath( collection, @@ -2813,7 +2813,7 @@ export class QmdMemoryManager implements MemorySearchManager { relativeToWorkspace, absPath, ); - return { rel: relPath, abs: absPath, source: root.kind }; + return { rel: relPath, abs: absPath, source: rootEntry.kind }; } private buildSearchPath( @@ -2860,13 +2860,13 @@ export class QmdMemoryManager implements MemorySearchManager { if (!collection || rest.length === 0) { throw new Error("invalid qmd path"); } - const root = this.collectionRoots.get(collection); - if (!root) { + const rootResult = this.collectionRoots.get(collection); + if (!rootResult) { throw new Error(`unknown qmd collection: ${collection}`); } const joined = rest.join("/"); - const resolved = path.resolve(root.path, joined); - if (!this.isWithinRoot(root.path, resolved)) { + const resolved = path.resolve(rootResult.path, joined); + if (!this.isWithinRoot(rootResult.path, resolved)) { throw new Error("qmd path escapes collection"); } return resolved; @@ -2884,12 +2884,12 @@ export class QmdMemoryManager implements MemorySearchManager { private isIndexedWorkspaceReadPath(absPath: string): boolean { const normalizedAbsPath = path.normalize(absPath); - for (const [collection, root] of this.collectionRoots.entries()) { - if (!this.isWithinRoot(root.path, normalizedAbsPath)) { + for (const [collection, rootValue] of this.collectionRoots.entries()) { + if (!this.isWithinRoot(rootValue.path, normalizedAbsPath)) { continue; } const collectionRelativePath = path - .relative(root.path, normalizedAbsPath) + .relative(rootValue.path, normalizedAbsPath) .replace(/\\/g, "/"); if (!collectionRelativePath || collectionRelativePath.startsWith("..")) { continue; @@ -2900,7 +2900,7 @@ export class QmdMemoryManager implements MemorySearchManager { .get(collection, collectionRelativePath) as { path: string } | undefined; if ( exactRow && - path.normalize(path.resolve(root.path, exactRow.path)) === normalizedAbsPath + path.normalize(path.resolve(rootValue.path, exactRow.path)) === normalizedAbsPath ) { return true; } @@ -2910,7 +2910,10 @@ export class QmdMemoryManager implements MemorySearchManager { const match = rows.find((row) => this.matchesPreferredFileHint(row.path, collectionRelativePath), ); - if (match && path.normalize(path.resolve(root.path, match.path)) === normalizedAbsPath) { + if ( + match && + path.normalize(path.resolve(rootValue.path, match.path)) === normalizedAbsPath + ) { return true; } } catch (err) { @@ -2928,8 +2931,8 @@ export class QmdMemoryManager implements MemorySearchManager { return isPathInside(this.workspaceDir, absPath); } - private isWithinRoot(root: string, candidate: string): boolean { - return isPathInside(root, candidate); + private isWithinRoot(rootLocal: string, candidate: string): boolean { + return isPathInside(rootLocal, candidate); } private clampResultsByInjectedChars(results: MemorySearchResult[]): MemorySearchResult[] { diff --git a/extensions/memory-core/src/memory/search-manager.test.ts b/extensions/memory-core/src/memory/search-manager.test.ts index 958ae5c5ca2..8571f9b284d 100644 --- a/extensions/memory-core/src/memory/search-manager.test.ts +++ b/extensions/memory-core/src/memory/search-manager.test.ts @@ -139,7 +139,7 @@ import { closeMemorySearchManager, getMemorySearchManager, } from "./search-manager.js"; -const createQmdManagerMock = vi.mocked(QmdMemoryManager.create); +const createQmdManagerMock = vi.mocked(QmdMemoryManager["create"]); type QmdManagerInstance = Awaited>; type SearchManagerResult = Awaited>; diff --git a/extensions/memory-core/src/short-term-promotion.ts b/extensions/memory-core/src/short-term-promotion.ts index fc098d69571..951e6f706c7 100644 --- a/extensions/memory-core/src/short-term-promotion.ts +++ b/extensions/memory-core/src/short-term-promotion.ts @@ -536,8 +536,8 @@ function normalizeStore(raw: unknown, nowIso: string): ShortTermRecallStore { : []; const recallDays = Array.isArray(entry.recallDays) ? entry.recallDays - .map((value) => normalizeIsoDay(String(value))) - .filter((value): value is string => value !== null) + .map((valueValue) => normalizeIsoDay(String(valueValue))) + .filter((valueLocal): valueLocal is string => valueLocal !== null) : []; const conceptTags = Array.isArray(entry.conceptTags) ? normalizeDistinctStrings( diff --git a/extensions/memory-lancedb/config.ts b/extensions/memory-lancedb/config.ts index 7356678c43c..229a06339d5 100644 --- a/extensions/memory-lancedb/config.ts +++ b/extensions/memory-lancedb/config.ts @@ -226,11 +226,11 @@ export const memoryConfigSchema = { } storageOptions = {}; // Validate all values are strings - for (const [key, value] of Object.entries(storageOpts)) { - if (typeof value !== "string") { + for (const [key, valueLocal] of Object.entries(storageOpts)) { + if (typeof valueLocal !== "string") { throw new Error(`storageOptions.${key} must be a string`); } - storageOptions[key] = resolveEnvVars(value); + storageOptions[key] = resolveEnvVars(valueLocal); } } diff --git a/extensions/memory-lancedb/index.test.ts b/extensions/memory-lancedb/index.test.ts index 4e993a2abd9..75e17107bdf 100644 --- a/extensions/memory-lancedb/index.test.ts +++ b/extensions/memory-lancedb/index.test.ts @@ -361,7 +361,7 @@ describe("memory plugin e2e", () => { await fs.mkdir(path.join(workspaceDir, "memory"), { recursive: true }); await fs.writeFile(path.join(workspaceDir, "MEMORY.md"), "# Durable Memory\n", "utf8"); await fs.writeFile(path.join(workspaceDir, "memory", "2026-05-18.md"), "# Daily\n", "utf8"); - const registerMemoryCapability = vi.fn(); + const registerMemoryCapabilityLocal = vi.fn(); const mockApi = { id: "memory-lancedb", name: "Memory (LanceDB)", @@ -383,7 +383,7 @@ describe("memory plugin e2e", () => { error: vi.fn(), debug: vi.fn(), }, - registerMemoryCapability, + registerMemoryCapability: registerMemoryCapabilityLocal, registerTool: vi.fn(), registerCli: vi.fn(), registerService: vi.fn(), @@ -393,7 +393,7 @@ describe("memory plugin e2e", () => { memoryPlugin.register(mockApi as any); const capability = firstObjectArg( - registerMemoryCapability as unknown as MockCallSource, + registerMemoryCapabilityLocal as unknown as MockCallSource, "memory capability", ); const publicArtifacts = capability.publicArtifacts as @@ -2327,7 +2327,7 @@ describe("memory plugin e2e", () => { })); try { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginItem } = await import("./index.js"); const registeredTools: any[] = []; const mockApi = { id: "memory-lancedb", @@ -2360,7 +2360,7 @@ describe("memory plugin e2e", () => { resolvePath: (p: string) => p, }; - memoryPlugin.register(mockApi as any); + memoryPluginItem.register(mockApi as any); const recallTool = registeredTools.find((t) => t.opts?.name === "memory_recall")?.tool; if (!recallTool) { throw new Error("memory_recall tool was not registered"); @@ -2479,9 +2479,9 @@ describe("memory plugin e2e", () => { }); test("config schema accepts storageOptions with string values", async () => { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginCandidate } = await import("./index.js"); - const config = memoryPlugin.configSchema?.parse?.({ + const config = memoryPluginCandidate.configSchema?.parse?.({ embedding: { apiKey: OPENAI_API_KEY, model: "text-embedding-3-small", @@ -2502,14 +2502,14 @@ describe("memory plugin e2e", () => { }); test("config schema resolves env vars in storageOptions", async () => { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginEntry } = await import("./index.js"); const previousAccessKey = process.env.TEST_MEMORY_STORAGE_ACCESS_KEY; const previousSecretKey = process.env.TEST_MEMORY_STORAGE_SECRET_KEY; process.env.TEST_MEMORY_STORAGE_ACCESS_KEY = "env-access"; process.env.TEST_MEMORY_STORAGE_SECRET_KEY = "env-secret"; try { - const config = memoryPlugin.configSchema?.parse?.({ + const config = memoryPluginEntry.configSchema?.parse?.({ embedding: { apiKey: OPENAI_API_KEY, model: "text-embedding-3-small", @@ -2542,14 +2542,14 @@ describe("memory plugin e2e", () => { }); test("config schema rejects missing env vars in storageOptions", async () => { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginResult } = await import("./index.js"); const previousMissing = process.env.TEST_MEMORY_STORAGE_MISSING; try { delete process.env.TEST_MEMORY_STORAGE_MISSING; expect(() => { - memoryPlugin.configSchema?.parse?.({ + memoryPluginResult.configSchema?.parse?.({ embedding: { apiKey: OPENAI_API_KEY, model: "text-embedding-3-small", @@ -2570,10 +2570,10 @@ describe("memory plugin e2e", () => { }); test("config schema rejects storageOptions with non-string values", async () => { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginValue } = await import("./index.js"); expect(() => { - memoryPlugin.configSchema?.parse?.({ + memoryPluginValue.configSchema?.parse?.({ embedding: { apiKey: OPENAI_API_KEY, model: "text-embedding-3-small", @@ -2845,7 +2845,7 @@ describe("memory plugin e2e", () => { })); try { - const { default: memoryPlugin } = await import("./index.js"); + const { default: memoryPluginLocal } = await import("./index.js"); const registeredTools: any[] = []; const mockApi = { id: "memory-lancedb", @@ -2869,7 +2869,7 @@ describe("memory plugin e2e", () => { resolvePath: (p: string) => p, }; - memoryPlugin.register(mockApi as any); + memoryPluginLocal.register(mockApi as any); const forgetTool = registeredTools.find((t) => t.opts?.name === "memory_forget")?.tool; if (!forgetTool) { throw new Error("expected memory_forget tool registration"); diff --git a/extensions/memory-wiki/src/config-compat.test.ts b/extensions/memory-wiki/src/config-compat.test.ts index d58c3ce86c7..f2309659ea6 100644 --- a/extensions/memory-wiki/src/config-compat.test.ts +++ b/extensions/memory-wiki/src/config-compat.test.ts @@ -38,7 +38,7 @@ describe("memory-wiki config compatibility", () => { ]); expect( ( - migration?.config.plugins?.entries?.["memory-wiki"] as { + migration!.config.plugins!.entries!["memory-wiki"] as { config?: { bridge?: Record }; } ).config?.bridge, @@ -71,7 +71,7 @@ describe("memory-wiki config compatibility", () => { ]); expect( ( - migration.config.plugins?.entries?.["memory-wiki"] as { + migration.config.plugins!.entries!["memory-wiki"] as { config?: { bridge?: Record }; } ).config?.bridge, diff --git a/extensions/migrate-hermes/auth.ts b/extensions/migrate-hermes/auth.ts index 1547c651123..55c7ad35817 100644 --- a/extensions/migrate-hermes/auth.ts +++ b/extensions/migrate-hermes/auth.ts @@ -433,7 +433,7 @@ export async function applyAuthItem( typeof item.details?.sourceCredentialIndex === "number" ? item.details.sourceCredentialIndex : undefined; - const sourceCredentialFingerprint = + const sourceCredentialFingerprintLocal = typeof item.details?.sourceCredentialFingerprint === "string" ? item.details.sourceCredentialFingerprint : undefined; @@ -448,7 +448,9 @@ export async function applyAuthItem( profiles, sourceProfileId, ...(sourceCredentialIndex === undefined ? {} : { sourceCredentialIndex }), - ...(sourceCredentialFingerprint ? { sourceCredentialFingerprint } : {}), + ...(sourceCredentialFingerprintLocal + ? { sourceCredentialFingerprint: sourceCredentialFingerprintLocal } + : {}), }); if (!profile) { return markMigrationItemSkipped(item, HERMES_REASON_SECRET_NO_LONGER_PRESENT); diff --git a/extensions/moonshot/moonshot.live.test.ts b/extensions/moonshot/moonshot.live.test.ts index 1a811722909..9c82c96e9da 100644 --- a/extensions/moonshot/moonshot.live.test.ts +++ b/extensions/moonshot/moonshot.live.test.ts @@ -50,7 +50,7 @@ describeLive("moonshot plugin live", () => { expect(result?.provider).toBe("kimi"); expect(typeof result?.content).toBe("string"); - expect((result?.content as string).length).toBeGreaterThan(20); + expect((result!.content as string).length).toBeGreaterThan(20); expect(Array.isArray(result?.citations)).toBe(true); }, 180_000); }); diff --git a/extensions/msteams/src/attachments.test.ts b/extensions/msteams/src/attachments.test.ts index 81b4bc11b66..5464c5505f0 100644 --- a/extensions/msteams/src/attachments.test.ts +++ b/extensions/msteams/src/attachments.test.ts @@ -154,7 +154,6 @@ type DownloadedMediaExpectation = { path?: string; placeholder?: string }; const DEFAULT_MAX_BYTES = 1024 * 1024; const DEFAULT_ALLOW_HOSTS = [TEST_HOST]; -const MEDIA_PLACEHOLDER_IMAGE = ""; const MEDIA_PLACEHOLDER_DOCUMENT = ""; const formatDocumentPlaceholder = (count: number) => count > 1 ? `${MEDIA_PLACEHOLDER_DOCUMENT} (${count} files)` : MEDIA_PLACEHOLDER_DOCUMENT; @@ -198,8 +197,6 @@ const createTeamsFileDownloadInfoAttachments = ( content: { downloadUrl, fileType }, }), ); -const createHostedContentsWithType = (contentType: string, ...ids: string[]) => - ids.map((id) => ({ id, contentType, contentBytes: PNG_BASE64 })); type BinaryPayload = Uint8Array | string; const createBufferResponse = (payload: BinaryPayload, contentType: string, status = 200) => { const raw = typeof payload === "string" ? Buffer.from(payload) : payload; @@ -208,8 +205,6 @@ const createBufferResponse = (payload: BinaryPayload, contentType: string, statu headers: { "content-type": contentType }, }); }; -const createJsonResponse = (payload: unknown, status = 200) => - new Response(JSON.stringify(payload), { status }); const createTextResponse = (body: string, status = 200) => new Response(body, { status }); const createNotFoundResponse = () => new Response("not found", { status: 404 }); const createRedirectResponse = (location: string, status = 302) => diff --git a/extensions/msteams/src/monitor-handler.file-consent.test.ts b/extensions/msteams/src/monitor-handler.file-consent.test.ts index d572378038e..05380bc0920 100644 --- a/extensions/msteams/src/monitor-handler.file-consent.test.ts +++ b/extensions/msteams/src/monitor-handler.file-consent.test.ts @@ -139,18 +139,6 @@ function requirePendingUpload(uploadId: string) { } return upload; } - -function expectInvokeResponse(sendActivity: ReturnType): void { - expect( - sendActivity.mock.calls.some( - ([activity]) => - typeof activity === "object" && - activity !== null && - (activity as { type?: unknown }).type === "invokeResponse", - ), - ).toBe(true); -} - function expectPendingUploadFields(uploadId: string): void { const upload = requirePendingUpload(uploadId); expect(upload.conversationId).toBe("19:victim@thread.v2"); diff --git a/extensions/msteams/src/outbound.test.ts b/extensions/msteams/src/outbound.test.ts index 76d32df8403..4dea824c212 100644 --- a/extensions/msteams/src/outbound.test.ts +++ b/extensions/msteams/src/outbound.test.ts @@ -125,7 +125,7 @@ describe("msteamsOutbound cfg threading", () => { }); it("passes resolved cfg to sendMessageMSTeams for text sends", async () => { - const cfg = { + const cfgResult = { channels: { msteams: { appId: "resolved-app-id", @@ -134,20 +134,20 @@ describe("msteamsOutbound cfg threading", () => { } as OpenClawConfig; await requireSendText()({ - cfg, + cfg: cfgResult, to: "conversation:abc", text: "hello", }); expect(mocks.sendMessageMSTeams).toHaveBeenCalledWith({ - cfg, + cfg: cfgResult, to: "conversation:abc", text: "hello", }); }); it("passes resolved cfg and media roots for media sends", async () => { - const cfg = { + const cfgValue = { channels: { msteams: { appId: "resolved-app-id", @@ -156,7 +156,7 @@ describe("msteamsOutbound cfg threading", () => { } as OpenClawConfig; await requireSendMedia()({ - cfg, + cfg: cfgValue, to: "conversation:abc", text: "photo", mediaUrl: "file:///tmp/photo.png", @@ -164,7 +164,7 @@ describe("msteamsOutbound cfg threading", () => { }); expect(mocks.sendMessageMSTeams).toHaveBeenCalledWith({ - cfg, + cfg: cfgValue, to: "conversation:abc", text: "photo", mediaUrl: "file:///tmp/photo.png", @@ -222,7 +222,7 @@ describe("msteamsOutbound cfg threading", () => { expect(mocks.sendAdaptiveCardMSTeams).toHaveBeenCalledWith({ cfg, to: "conversation:abc", - card: (rendered?.channelData?.msteams as { presentationCard: unknown }).presentationCard, + card: (rendered!.channelData!.msteams as { presentationCard: unknown }).presentationCard, }); expect(result).toEqual({ channel: "msteams", @@ -351,7 +351,7 @@ describe("msteamsOutbound cfg threading", () => { }); it("passes resolved cfg to sendPollMSTeams and stores poll metadata", async () => { - const cfg = { + const cfgLocal = { channels: { msteams: { appId: "resolved-app-id", @@ -360,7 +360,7 @@ describe("msteamsOutbound cfg threading", () => { } as OpenClawConfig; await requireSendPoll()({ - cfg, + cfg: cfgLocal, to: "conversation:abc", poll: { question: "Snack?", @@ -369,7 +369,7 @@ describe("msteamsOutbound cfg threading", () => { }); expect(mocks.sendPollMSTeams).toHaveBeenCalledWith({ - cfg, + cfg: cfgLocal, to: "conversation:abc", question: "Snack?", options: ["Pizza", "Sushi"], diff --git a/extensions/msteams/src/outbound.ts b/extensions/msteams/src/outbound.ts index ae3d7b81b3d..02312067457 100644 --- a/extensions/msteams/src/outbound.ts +++ b/extensions/msteams/src/outbound.ts @@ -140,8 +140,8 @@ export const msteamsOutbound: ChannelOutboundAdapter = { const result = await sendPayloadMediaSequence({ text, mediaUrls, - send: async ({ text, mediaUrl }) => - await send(to, text, { mediaUrl, mediaLocalRoots, mediaReadFile }), + send: async ({ text: textLocal, mediaUrl: mediaUrlLocal }) => + await send(to, textLocal, { mediaUrl: mediaUrlLocal, mediaLocalRoots, mediaReadFile }), }); if (result) { return attachChannelToResult("msteams", result); diff --git a/extensions/msteams/src/sdk.test.ts b/extensions/msteams/src/sdk.test.ts index 1878435611e..37e04be981e 100644 --- a/extensions/msteams/src/sdk.test.ts +++ b/extensions/msteams/src/sdk.test.ts @@ -14,8 +14,8 @@ vi.mock("node:fs", async (importOriginal) => { }); const { mockGetToken } = vi.hoisted(() => { - const mockGetToken = vi.fn().mockResolvedValue({ token: "mock-managed-token" }); - return { mockGetToken }; + const mockGetTokenLocal = vi.fn().mockResolvedValue({ token: "mock-managed-token" }); + return { mockGetToken: mockGetTokenLocal }; }); vi.mock("@azure/identity", () => { class ManagedIdentityCredential { diff --git a/extensions/msteams/src/send.test.ts b/extensions/msteams/src/send.test.ts index 3df918a716d..ff15f35eead 100644 --- a/extensions/msteams/src/send.test.ts +++ b/extensions/msteams/src/send.test.ts @@ -214,15 +214,6 @@ function firstObjectArg(mock: MockWithCalls): Record { } return value as Record; } - -function continueConversationRef(mock: MockWithCalls): Record { - const ref = mock.mock.calls[0]?.[1]; - if (ref === undefined || ref === null || typeof ref !== "object" || Array.isArray(ref)) { - throw new Error("expected continueConversation ref object"); - } - return ref as Record; -} - describe("sendMessageMSTeams", () => { beforeEach(() => { mockState.loadOutboundMediaFromUrl.mockReset(); diff --git a/extensions/nextcloud-talk/src/core.test.ts b/extensions/nextcloud-talk/src/core.test.ts index 0e66c40d7fd..3b8db2fcbf7 100644 --- a/extensions/nextcloud-talk/src/core.test.ts +++ b/extensions/nextcloud-talk/src/core.test.ts @@ -205,17 +205,19 @@ describe("nextcloud talk core", () => { }); try { - const { generateNextcloudTalkSignature, verifyNextcloudTalkSignature } = - await import("./signature.js"); + const { + generateNextcloudTalkSignature: generateNextcloudTalkSignatureLocal, + verifyNextcloudTalkSignature: verifyNextcloudTalkSignatureLocal, + } = await import("./signature.js"); const body = JSON.stringify({ hello: "world" }); - const generated = generateNextcloudTalkSignature({ + const generated = generateNextcloudTalkSignatureLocal({ body, secret: "secret-123", }); const shortSignature = generated.signature.slice(0, 12); expect( - verifyNextcloudTalkSignature({ + verifyNextcloudTalkSignatureLocal({ signature: shortSignature, random: generated.random, body, diff --git a/extensions/nextcloud-talk/src/inbound.ts b/extensions/nextcloud-talk/src/inbound.ts index 9fdcf2317c7..7e48374eb4d 100644 --- a/extensions/nextcloud-talk/src/inbound.ts +++ b/extensions/nextcloud-talk/src/inbound.ts @@ -230,7 +230,7 @@ export async function handleNextcloudTalkInbound(params: { providerKey: "nextcloud-talk", accountId: account.accountId, blockedLabel: GROUP_POLICY_BLOCKED_LABEL.room, - log: (message) => runtime.log?.(message), + log: (messageValue) => runtime.log?.(messageValue), }); const commandAuthorized = access.commandAccess.authorized; const accessReason = @@ -279,7 +279,7 @@ export async function handleNextcloudTalkInbound(params: { if (access.commandAccess.shouldBlockControlCommand) { logInboundDrop({ - log: (message) => runtime.log?.(message), + log: (messageLocal) => runtime.log?.(messageLocal), channel: CHANNEL_ID, reason: "control command (unauthorized)", target: senderId, diff --git a/extensions/nostr/src/nostr-bus.ts b/extensions/nostr/src/nostr-bus.ts index 4211ec71b7c..e9f4cc8e4e9 100644 --- a/extensions/nostr/src/nostr-bus.ts +++ b/extensions/nostr/src/nostr-bus.ts @@ -684,11 +684,11 @@ export async function startNostrBus(options: NostrBusOptions): Promise { - const state = await readNostrProfileState({ accountId }); + const stateLocal = await readNostrProfileState({ accountId }); return { - lastPublishedAt: state?.lastPublishedAt ?? null, - lastPublishedEventId: state?.lastPublishedEventId ?? null, - lastPublishResults: state?.lastPublishResults ?? null, + lastPublishedAt: stateLocal?.lastPublishedAt ?? null, + lastPublishedEventId: stateLocal?.lastPublishedEventId ?? null, + lastPublishResults: stateLocal?.lastPublishResults ?? null, }; }; diff --git a/extensions/oc-path/src/oc-path/oc-path.ts b/extensions/oc-path/src/oc-path/oc-path.ts index 8c5e573c195..0ac4ded7d61 100644 --- a/extensions/oc-path/src/oc-path/oc-path.ts +++ b/extensions/oc-path/src/oc-path/oc-path.ts @@ -652,7 +652,7 @@ function scanBracketAware(s: string, onChar: ScanCallback, onUnbalanced: () => n /** First top-level occurrence of `ch` in `s`; -1 when absent. */ export function indexOfTopLevel(s: string, ch: string): number { let result = -1; - const fail = (): never => { + const failLocal = (): never => { throw new OcPathError(`Unbalanced bracket/brace in oc:// path: ${s}`, s, "OC_PATH_UNBALANCED"); }; scanBracketAware( @@ -664,7 +664,7 @@ export function indexOfTopLevel(s: string, ch: string): number { } return undefined; }, - fail, + failLocal, ); return result; } diff --git a/extensions/oc-path/src/oc-path/tests/jsonl/resolve.test.ts b/extensions/oc-path/src/oc-path/tests/jsonl/resolve.test.ts index 7eaac01f4a6..cd2e0988e21 100644 --- a/extensions/oc-path/src/oc-path/tests/jsonl/resolve.test.ts +++ b/extensions/oc-path/src/oc-path/tests/jsonl/resolve.test.ts @@ -76,7 +76,7 @@ describe("resolveJsonlToUniversal — file-relative line metadata (regression)", // line's bytes; the universal resolve was preferring that local // number over the JsonlLine's file-relative line. - const log = [ + const logLocal = [ '{"event":"start"}', // line 1 '{"event":"step","n":1}', // line 2 '{"event":"step","n":2}', // line 3 @@ -85,7 +85,7 @@ describe("resolveJsonlToUniversal — file-relative line metadata (regression)", ].join("\n"); it("resolves L2/event with line=2 (not 1)", () => { - const { ast } = parseJsonl(log); + const { ast } = parseJsonl(logLocal); const m = resolveOcPath(ast, parseOcPath("oc://session.jsonl/L2/event")); if (m === null) { throw new Error("expected L2/event match"); @@ -94,7 +94,7 @@ describe("resolveJsonlToUniversal — file-relative line metadata (regression)", }); it("resolves L4/event with line=4", () => { - const { ast } = parseJsonl(log); + const { ast } = parseJsonl(logLocal); const m = resolveOcPath(ast, parseOcPath("oc://session.jsonl/L4/event")); if (m === null) { throw new Error("expected L4/event match"); @@ -103,7 +103,7 @@ describe("resolveJsonlToUniversal — file-relative line metadata (regression)", }); it("findOcPaths over wildcard surfaces correct file-relative lines", () => { - const { ast } = parseJsonl(log); + const { ast } = parseJsonl(logLocal); const matches = findOcPaths(ast, parseOcPath("oc://session.jsonl/*/event")); expect(matches).toHaveLength(4); const lines = matches.map((m) => m.match.line); diff --git a/extensions/oc-path/src/oc-path/tests/scenarios/roundtrip-property.test.ts b/extensions/oc-path/src/oc-path/tests/scenarios/roundtrip-property.test.ts index 859216ec41c..60a2a319566 100644 --- a/extensions/oc-path/src/oc-path/tests/scenarios/roundtrip-property.test.ts +++ b/extensions/oc-path/src/oc-path/tests/scenarios/roundtrip-property.test.ts @@ -82,7 +82,6 @@ describe("roundtrip-property", () => { }); }); - function generateCorpus(count: number): string[] { const corpus: string[] = []; // Deterministic seed so flaky failures don't surface differently each run. @@ -123,7 +122,7 @@ function generateCorpus(count: number): string[] { parts.push(`## ${choose(headings)}`); parts.push(""); const itemCount = Math.floor(rand() * 4); - for (let it = 0; it < itemCount; it++) { + for (let itLocal = 0; itLocal < itemCount; itLocal++) { parts.push(`- ${choose(itemTexts)}`); } if (rand() < 0.2) { diff --git a/extensions/ollama/src/embedding-provider.ts b/extensions/ollama/src/embedding-provider.ts index c110eefccf3..44843ec8bd1 100644 --- a/extensions/ollama/src/embedding-provider.ts +++ b/extensions/ollama/src/embedding-provider.ts @@ -369,15 +369,18 @@ export async function createOllamaEmbeddingProvider( return embedding; }; - const embedQuery = async (text: string, options?: { signal?: AbortSignal }): Promise => - await embedOne(applyQueryInstructionTemplate(client.model, text), options?.signal); + const embedQuery = async ( + text: string, + optionsValue?: { signal?: AbortSignal }, + ): Promise => + await embedOne(applyQueryInstructionTemplate(client.model, text), optionsValue?.signal); const provider: OllamaEmbeddingProvider = { id: "ollama", model: client.model, embedQuery, - embedBatch: async (texts, options) => - texts.length === 0 ? [] : await embedMany(texts, options?.signal), + embedBatch: async (texts, optionsLocal) => + texts.length === 0 ? [] : await embedMany(texts, optionsLocal?.signal), }; return { diff --git a/extensions/openai/embedding-provider.ts b/extensions/openai/embedding-provider.ts index 6f5755517e7..19c0da28109 100644 --- a/extensions/openai/embedding-provider.ts +++ b/extensions/openai/embedding-provider.ts @@ -81,11 +81,12 @@ export async function createOpenAiEmbeddingProvider( ...(typeof OPENAI_MAX_INPUT_TOKENS[client.model] === "number" ? { maxInputTokens: OPENAI_MAX_INPUT_TOKENS[client.model] } : {}), - embedQuery: async (text, options) => { - const [vec] = await embed([text], "query", options?.signal); + embedQuery: async (text, optionsValue) => { + const [vec] = await embed([text], "query", optionsValue?.signal); return vec ?? []; }, - embedBatch: async (texts, options) => await embed(texts, "document", options?.signal), + embedBatch: async (texts, optionsLocal) => + await embed(texts, "document", optionsLocal?.signal), }, client, }; diff --git a/extensions/openai/index.test.ts b/extensions/openai/index.test.ts index 4044e66c5c2..aca69a34247 100644 --- a/extensions/openai/index.test.ts +++ b/extensions/openai/index.test.ts @@ -1,9 +1,6 @@ import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; import { createTestPluginApi } from "openclaw/plugin-sdk/plugin-test-api"; -import { - registerProviderPlugin, - requireRegisteredProvider, -} from "openclaw/plugin-sdk/plugin-test-runtime"; +import { requireRegisteredProvider } from "openclaw/plugin-sdk/plugin-test-runtime"; import * as providerAuth from "openclaw/plugin-sdk/provider-auth-runtime"; import * as providerHttp from "openclaw/plugin-sdk/provider-http"; import type { ProviderPlugin } from "openclaw/plugin-sdk/provider-model-shared"; @@ -37,14 +34,6 @@ vi.mock("./openai-chatgpt-oauth-flow.runtime.js", () => ({ })); import { createOpenAICodexProviderRuntime } from "./openai-chatgpt-provider.runtime.js"; - -const registerOpenAIPluginForTest = async () => - registerProviderPlugin({ - plugin, - id: "openai", - name: "OpenAI Provider", - }); - async function registerOpenAIPluginWithHook(params?: { pluginConfig?: Record }) { const on = vi.fn(); const providers: ProviderPlugin[] = []; diff --git a/extensions/openai/openai-provider.live.test.ts b/extensions/openai/openai-provider.live.test.ts index 3fffa066f94..ff0d5eb84aa 100644 --- a/extensions/openai/openai-provider.live.test.ts +++ b/extensions/openai/openai-provider.live.test.ts @@ -1,5 +1,4 @@ import OpenAI from "openai"; -import type { Api } from "openclaw/plugin-sdk/llm"; import type { ProviderRuntimeModel } from "openclaw/plugin-sdk/plugin-entry"; import { describe, expect, it } from "vitest"; import { buildOpenAIProvider } from "./openai-provider.js"; diff --git a/extensions/openai/openai.live.test.ts b/extensions/openai/openai.live.test.ts index 1590e10c545..b239ae5ad45 100644 --- a/extensions/openai/openai.live.test.ts +++ b/extensions/openai/openai.live.test.ts @@ -5,7 +5,6 @@ import OpenAI from "openai"; import type { ResolvedTtsConfig } from "openclaw/plugin-sdk/agent-runtime"; import { AuthStorage, ModelRegistry } from "openclaw/plugin-sdk/agent-sessions"; import type { OpenClawConfig } from "openclaw/plugin-sdk/config-contracts"; -import type { Api, Model } from "openclaw/plugin-sdk/llm"; import { encodePngRgba, fillPixel } from "openclaw/plugin-sdk/media-runtime"; import { registerProviderPlugin, diff --git a/extensions/openai/tts.ts b/extensions/openai/tts.ts index 0a794c437f5..d3b1a1039c8 100644 --- a/extensions/openai/tts.ts +++ b/extensions/openai/tts.ts @@ -182,8 +182,8 @@ export async function openaiTTS(params: { await assertOkOrThrowProviderError(response, "OpenAI TTS API error"); return await readResponseWithLimit(response, maxBytes, { - onOverflow: ({ maxBytes }) => - new Error(`OpenAI TTS audio response exceeds ${maxBytes} bytes`), + onOverflow: ({ maxBytes: maxBytesLocal }) => + new Error(`OpenAI TTS audio response exceeds ${maxBytesLocal} bytes`), }); } finally { await release(); diff --git a/extensions/opencode-go/index.ts b/extensions/opencode-go/index.ts index 0117a7d488f..5a28fe88744 100644 --- a/extensions/opencode-go/index.ts +++ b/extensions/opencode-go/index.ts @@ -81,11 +81,11 @@ export default definePluginEntry({ } return baseUrlNormalized !== model ? baseUrlNormalized : undefined; }, - normalizeTransport: ({ api, baseUrl }) => { - const normalizedBaseUrl = normalizeOpencodeGoBaseUrl({ api, baseUrl }); + normalizeTransport: ({ api: apiLocal, baseUrl }) => { + const normalizedBaseUrl = normalizeOpencodeGoBaseUrl({ api: apiLocal, baseUrl }); return normalizedBaseUrl && normalizedBaseUrl !== baseUrl ? { - api, + api: apiLocal, baseUrl: normalizedBaseUrl, } : undefined; diff --git a/extensions/openrouter/index.ts b/extensions/openrouter/index.ts index d065881930a..9771fb69428 100644 --- a/extensions/openrouter/index.ts +++ b/extensions/openrouter/index.ts @@ -172,11 +172,11 @@ export default definePluginEntry({ : undefined; }, normalizeResolvedModel: ({ model }) => normalizeOpenRouterResolvedModel(model), - normalizeTransport: ({ api, baseUrl }) => { + normalizeTransport: ({ api: apiLocal, baseUrl }) => { const normalizedBaseUrl = normalizeOpenRouterBaseUrl(baseUrl); return normalizedBaseUrl && normalizedBaseUrl !== baseUrl ? { - api, + api: apiLocal, baseUrl: normalizedBaseUrl, } : undefined; diff --git a/extensions/openshell/src/openshell-core.test.ts b/extensions/openshell/src/openshell-core.test.ts index 09bc43877b5..7332dce4f64 100644 --- a/extensions/openshell/src/openshell-core.test.ts +++ b/extensions/openshell/src/openshell-core.test.ts @@ -405,7 +405,7 @@ describe("openshell fs bridges", () => { }); expect(await fs.readFile(path.join(workspaceDir, "nested", "file.txt"), "utf8")).toBe("hello"); - expect(backend.syncLocalPathToRemote).toHaveBeenCalledWith( + expect(backend["syncLocalPathToRemote"]).toHaveBeenCalledWith( path.join(workspaceDir, "nested", "file.txt"), "/sandbox/nested/file.txt", ); @@ -437,7 +437,7 @@ describe("openshell fs bridges", () => { ).rejects.toThrow("Sandbox path escapes allowed mounts"); await expectPathMissing(path.join(outsideDir, "escape.txt")); await expect(fs.readdir(outsideDir)).resolves.toStrictEqual([]); - expect(backend.syncLocalPathToRemote).not.toHaveBeenCalled(); + expect(backend["syncLocalPathToRemote"]).not.toHaveBeenCalled(); }); it("rejects writes whose final target is a symlink inside the local mount root", async () => { @@ -467,7 +467,7 @@ describe("openshell fs bridges", () => { ).rejects.toThrow("Sandbox boundary checks failed"); await expect(fs.readlink(path.join(workspaceDir, "link.txt"))).resolves.toBe("existing.txt"); await expect(fs.readFile(linkedTarget, "utf8")).resolves.toBe("keep"); - expect(backend.syncLocalPathToRemote).not.toHaveBeenCalled(); + expect(backend["syncLocalPathToRemote"]).not.toHaveBeenCalled(); }); it("rejects a parent symlink that lands outside the sandbox root", async () => { diff --git a/extensions/policy/src/doctor/register.ts b/extensions/policy/src/doctor/register.ts index 0c96edacae9..6f47779fdfa 100644 --- a/extensions/policy/src/doctor/register.ts +++ b/extensions/policy/src/doctor/register.ts @@ -1697,12 +1697,12 @@ export function policyContainerShapeFindings( if (sandboxFinding !== undefined) { return [sandboxFinding]; } - const ingressFinding = ingressPolicyShapeFinding(policy.ingress, { + const ingressFindingValue = ingressPolicyShapeFinding(policy.ingress, { policyDocName, policyPath, }); - if (ingressFinding !== undefined) { - return [ingressFinding]; + if (ingressFindingValue !== undefined) { + return [ingressFindingValue]; } const gatewayFinding = gatewayPolicyShapeFinding(policy.gateway, { policyDocName, @@ -1992,15 +1992,15 @@ function scopedPolicyShapeFinding( if (sandboxFinding !== undefined) { return sandboxFinding; } - const ingressFinding = ingressPolicyShapeFinding(overlay.ingress, { + const ingressFindingLocal = ingressPolicyShapeFinding(overlay.ingress, { policyDocName: params.policyDocName, policyPath: params.policyPath, targetPrefix: `${targetPrefix}/ingress`, propertyPrefix: `scopes.${scopeName}.ingress`, allowSession: false, }); - if (ingressFinding !== undefined) { - return ingressFinding; + if (ingressFindingLocal !== undefined) { + return ingressFindingLocal; } } return duplicateScopedPolicyFieldFinding(value, { @@ -4386,10 +4386,10 @@ function bindHostLooksLikeContainerRuntimeSocket(value: string | undefined): boo return false; } const normalized = value.replaceAll("\\", "/").toLowerCase(); - const basename = normalized.split("/").at(-1) ?? ""; + const basenameLocal = normalized.split("/").at(-1) ?? ""; return ( CONTAINER_RUNTIME_SOCKET_PATHS.has(normalized) || - CONTAINER_RUNTIME_SOCKET_BASENAMES.has(basename) + CONTAINER_RUNTIME_SOCKET_BASENAMES.has(basenameLocal) ); } diff --git a/extensions/qa-channel/src/bus-client.test.ts b/extensions/qa-channel/src/bus-client.test.ts index fb5eba7229c..59750c55735 100644 --- a/extensions/qa-channel/src/bus-client.test.ts +++ b/extensions/qa-channel/src/bus-client.test.ts @@ -73,7 +73,7 @@ describe("qa-bus client", () => { const server = await startJsonServer(() => ({ body: '{"cursor":1,"events":[', })); - stops.push(server.stop); + stops.push(server["stop"]); await expect( pollQaBus({ @@ -140,7 +140,7 @@ describe("qa-bus client", () => { }) : JSON.stringify({ error: `unexpected path: ${req.url}` }), })); - stops.push(server.stop); + stops.push(server["stop"]); await expect(getQaBusState(`${server.baseUrl}/qa-bus`)).resolves.toEqual({ cursor: 1, diff --git a/extensions/qa-lab/src/bus-server.test.ts b/extensions/qa-lab/src/bus-server.test.ts index 67469bba18f..4488b3c6189 100644 --- a/extensions/qa-lab/src/bus-server.test.ts +++ b/extensions/qa-lab/src/bus-server.test.ts @@ -97,7 +97,7 @@ describe("qa-bus server", () => { it("wakes stale-cursor long polls as soon as matching account traffic arrives", async () => { const state = createQaBusState(); const bus = await startQaBusServer({ state }); - stops.push(bus.stop); + stops.push(bus["stop"]); const pending = pollQaBus({ baseUrl: bus.baseUrl, diff --git a/extensions/qa-lab/src/cli.test.ts b/extensions/qa-lab/src/cli.test.ts index 4ede788a83d..8be4e2ad7b1 100644 --- a/extensions/qa-lab/src/cli.test.ts +++ b/extensions/qa-lab/src/cli.test.ts @@ -539,7 +539,7 @@ describe("qa cli registration", () => { }); it("delegates discovered qa runner registration through the generic host seam", () => { - const [{ registration }] = listQaRunnerCliContributions.mock.results[0]?.value; + const [{ registration }] = listQaRunnerCliContributions.mock.results[0].value; expect(registration.register).toHaveBeenCalledTimes(1); }); diff --git a/extensions/qa-lab/src/lab-server.ts b/extensions/qa-lab/src/lab-server.ts index 32d1c6c2715..0f7815a7335 100644 --- a/extensions/qa-lab/src/lab-server.ts +++ b/extensions/qa-lab/src/lab-server.ts @@ -387,7 +387,7 @@ export async function startQaLabServer( if (req.method === "GET" && url.pathname === "/api/capture/startup-status") { const proxyUrl = captureSettings.proxyUrl || "http://127.0.0.1:7799"; const gatewayUrl = controlUiUrl || "http://127.0.0.1:18789/"; - const [proxy, gateway] = await Promise.all([ + const [proxy, gatewayLocal] = await Promise.all([ probeTcpReachability(proxyUrl), probeTcpReachability(gatewayUrl), ]); @@ -398,7 +398,7 @@ export async function startQaLabServer( label: "Proxy", }, gateway: { - ...gateway, + ...gatewayLocal, label: "Gateway", }, qaLab: { diff --git a/extensions/qa-lab/src/live-transports/discord/discord-live.runtime.test.ts b/extensions/qa-lab/src/live-transports/discord/discord-live.runtime.test.ts index 4b89e0a2403..1bb4c963bfd 100644 --- a/extensions/qa-lab/src/live-transports/discord/discord-live.runtime.test.ts +++ b/extensions/qa-lab/src/live-transports/discord/discord-live.runtime.test.ts @@ -426,7 +426,7 @@ describe("discord live qa runtime", () => { await vi.advanceTimersByTimeAsync(600); await expect(readyPromise).resolves.toBeUndefined(); - expect(gateway.call).toHaveBeenCalledTimes(2); + expect(gateway["call"]).toHaveBeenCalledTimes(2); } finally { vi.useRealTimers(); } @@ -484,7 +484,7 @@ describe("discord live qa runtime", () => { "fetch", vi.fn(async (_input: string | URL | globalThis.Request, init?: RequestInit) => { expect(init?.headers).toBeInstanceOf(Headers); - expect((init?.headers as Headers).get("authorization")).toBe("Bot token"); + expect((init!.headers as Headers).get("authorization")).toBe("Bot token"); return new Response( JSON.stringify([ { id: "623456789012345678", name: "help" }, diff --git a/extensions/qa-lab/src/qa-gateway-config.ts b/extensions/qa-lab/src/qa-gateway-config.ts index ae5d9295a3e..fb91b79ec67 100644 --- a/extensions/qa-lab/src/qa-gateway-config.ts +++ b/extensions/qa-lab/src/qa-gateway-config.ts @@ -74,7 +74,7 @@ export function buildQaGatewayConfig(params: { ); const modelProviderIds = [primaryModel, alternateModel] .map((ref) => splitQaModelRef(ref)?.provider) - .filter((provider): provider is string => Boolean(provider)); + .filter((providerValue): providerValue is string => Boolean(providerValue)); const imageGenerationModelRef = params.imageGenerationModel !== undefined ? params.imageGenerationModel @@ -86,7 +86,7 @@ export function buildQaGatewayConfig(params: { .map((value) => typeof value === "string" ? (splitQaModelRef(value)?.provider ?? value) : null, ) - .filter((provider): provider is string => Boolean(provider)), + .filter((providerLocal): providerLocal is string => Boolean(providerLocal)), ), ] : []; diff --git a/extensions/qa-lab/src/qa-transport.ts b/extensions/qa-lab/src/qa-transport.ts index 3d8924a08b1..d07e4cd814b 100644 --- a/extensions/qa-lab/src/qa-transport.ts +++ b/extensions/qa-lab/src/qa-transport.ts @@ -212,8 +212,8 @@ export abstract class QaStateBackedTransportAdapter implements QaTransportAdapte await this.state.reset(); }, readNormalizedMessage: this.state.readMessage.bind(this.state), - executeGenericAction: (params) => this.handleAction(params), - waitForReady: (params) => this.waitReady(params), + executeGenericAction: (paramsValue) => this.handleAction(paramsValue), + waitForReady: (paramsLocal) => this.waitReady(paramsLocal), waitForCondition: createFailureAwareTransportWaitForCondition(this.state), assertNoFailureReplies: (options) => { assertNoFailureReplies(this.state, options); diff --git a/extensions/qa-lab/src/scenario-catalog.ts b/extensions/qa-lab/src/scenario-catalog.ts index e429763f78d..a3e4fd971e3 100644 --- a/extensions/qa-lab/src/scenario-catalog.ts +++ b/extensions/qa-lab/src/scenario-catalog.ts @@ -318,8 +318,8 @@ function extractQaScenarioFlow(content: string, relativePath: string) { return parseQaYamlWithContext(qaFlowSchema, YAML.parse(match[1]) as unknown, relativePath); } -function formatZodIssuePath(path: PropertyKey[]) { - return path.length ? path.map(String).join(".") : ""; +function formatZodIssuePath(pathLocal: PropertyKey[]) { + return pathLocal.length ? pathLocal.map(String).join(".") : ""; } function parseQaYamlWithContext(schema: z.ZodType, value: unknown, label: string): T { diff --git a/extensions/qa-lab/src/temp-dir.test-helper.ts b/extensions/qa-lab/src/temp-dir.test-helper.ts index 983613f2b36..2b596e3331e 100644 --- a/extensions/qa-lab/src/temp-dir.test-helper.ts +++ b/extensions/qa-lab/src/temp-dir.test-helper.ts @@ -8,10 +8,10 @@ export function createTempDirHarness() { const tempDirs: TempWorkspace[] = []; return { - async cleanup() { + cleanup: async () => { await Promise.all(tempDirs.splice(0).map((dir) => dir.cleanup())); }, - async makeTempDir(prefix: string) { + makeTempDir: async (prefix: string) => { const dir = await tempWorkspace({ rootDir: resolvePreferredOpenClawTmpDir(), prefix, diff --git a/extensions/qa-lab/web/src/ui-render.ts b/extensions/qa-lab/web/src/ui-render.ts index 1a1c64698da..9fd86f851c6 100644 --- a/extensions/qa-lab/web/src/ui-render.ts +++ b/extensions/qa-lab/web/src/ui-render.ts @@ -2981,14 +2981,15 @@ function renderCaptureView(state: UiState): string { const key = captureEventKey(event); return key === selectedEventKey; }) ?? null; - const selectedFlowId = + const selectedFlowIdLocal = selectedLaneEvent?.flowId || selectedEvent?.flowId || ""; const focusSelectedFlow = state.captureTimelineFocusSelectedFlow && - selectedFlowId.length > 0; + selectedFlowIdLocal.length > 0; const laneFocusedEventCount = focusSelectedFlow - ? lane.events.filter((event) => event.flowId === selectedFlowId) - .length + ? lane.events.filter( + (event) => event.flowId === selectedFlowIdLocal, + ).length : 0; const laneBackgroundEventCount = focusSelectedFlow ? lane.events.length - laneFocusedEventCount @@ -3056,11 +3057,11 @@ function renderCaptureView(state: UiState): string { const length = Math.sqrt(dx * dx + dy * dy); const angle = (Math.atan2(dy, dx) * 180) / Math.PI; const selected = - selectedFlowId.length > 0 && - marker.event.flowId === selectedFlowId; + selectedFlowIdLocal.length > 0 && + marker.event.flowId === selectedFlowIdLocal; const dimmed = focusSelectedFlow && - marker.event.flowId !== selectedFlowId; + marker.event.flowId !== selectedFlowIdLocal; const paired = pairedEventKey != null && captureEventKey(marker.event) === pairedEventKey; @@ -3087,7 +3088,7 @@ function renderCaptureView(state: UiState): string { selectedEventKey != null && key === selectedEventKey; const kindClass = `capture-timeline-marker-${event.kind.replace(/[^a-z0-9]+/gi, "-").toLowerCase()}`; const dimmed = - focusSelectedFlow && event.flowId !== selectedFlowId; + focusSelectedFlow && event.flowId !== selectedFlowIdLocal; const paired = pairedEventKey != null && key === pairedEventKey; const label = [ @@ -3121,7 +3122,8 @@ function renderCaptureView(state: UiState): string { .replace(/[^a-z0-9]+/gi, "-") .toLowerCase()}`; const dimmed = - focusSelectedFlow && event.flowId !== selectedFlowId; + focusSelectedFlow && + event.flowId !== selectedFlowIdLocal; const paired = pairedEventKey != null && key === pairedEventKey; return `