From a75b83492b2fc1ff57654e2a38ef063167e334b2 Mon Sep 17 00:00:00 2001 From: James Feng <47167674+GhostDragon124@users.noreply.github.com> Date: Sun, 7 Jun 2026 17:11:26 +0800 Subject: [PATCH] fix: eliminate 11 of 12 remaining Anthropic-core as any MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MCP schema (6): Add : () => AnyObjectSchema type annotations to ChannelMessageNotificationSchema, ChannelPermissionNotificationSchema, AtMentionedSchema, LogEventNotificationSchema. Remove as any at call sites in print.ts, useManageMCPConnections.ts, useIdeAtMentioned.ts, vscodeSdkMcp.ts. Core API (5): Replace as any with specific type assertions in claude.ts (supportedModels/CachedMCEditsBlock/pinCacheEdits), filesApi.ts (error property), client.ts (vertexArgs cast). client.ts:297 retains as any — google-auth-library version conflict (10.x vs 9.x) with #private nominal typing makes this unavoidable. Docs: add community-code-issues.md cataloging all 20 community tsc errors and 49 community as any casts. --- docs/community-code-issues.md | 183 ++++++++++++++++++++ src/cli/print.ts | 4 +- src/hooks/useIdeAtMentioned.ts | 5 +- src/services/api/claude.ts | 18 +- src/services/api/client.ts | 6 +- src/services/api/filesApi.ts | 4 +- src/services/mcp/channelNotification.ts | 38 ++-- src/services/mcp/useManageMCPConnections.ts | 10 +- src/services/mcp/vscodeSdkMcp.ts | 18 +- 9 files changed, 240 insertions(+), 46 deletions(-) create mode 100644 docs/community-code-issues.md diff --git a/docs/community-code-issues.md b/docs/community-code-issues.md new file mode 100644 index 000000000..e56a42764 --- /dev/null +++ b/docs/community-code-issues.md @@ -0,0 +1,183 @@ +# 社区代码遗留 TypeScript 问题 + +> 本文档记录 CC_Pure 项目中来自社区引入的 TypeScript 类型问题。 +> 按照 CCP 策略:社区代码问题不自行修复,等待上游 CCB 社区修复后 cherry-pick。 +> 最后更新:2026-06-08 + +## 1. tsc 错误(实际 21 个) + +### bridge.ts — ACP SDK 类型(14 个) + +**文件:** `src/services/acp/bridge.ts` + +核心问题:`nextSdkMessageOrAbort()` 返回类型为 `void | SDKMessage`,但代码中没有对 `void` 做类型守卫,直接访问 `SDKMessage` 的属性导致 TS 报错。原因是社区引入的 ACP SDK 适配器未处理 Generator 返回的空值情况。 + +| 行号 | 错误代码 | 错误信息 | 说明 | +|------|----------|----------|------| +| 649 | TS2339 | Property 'type' does not exist on type 'void \| SDKMessage' | `msg.type` — msg 可能为 void,未做守卫 | +| 654 | TS2339 | Property 'subtype' does not exist on type 'void \| SDKMessage' | `msg.subtype` — 同上 | +| 682 | TS2339 | Property 'usage' does not exist on type 'void \| SDKMessage' | `msg.usage` — 同上 | +| 700 | TS2339 | Property 'modelUsage' does not exist on type 'void \| SDKMessage' | `msg.modelUsage` — 同上 | +| 719 | TS2339 | Property 'total_cost_usd' does not exist on type 'void \| SDKMessage' | `msg.total_cost_usd` — 同上 | +| 734 | TS2339 | Property 'subtype' does not exist on type 'void \| SDKMessage' | `msg.subtype` — result 分支再次出现 | +| 735 | TS2339 | Property 'is_error' does not exist on type 'void \| SDKMessage' | `msg.is_error` — 同上 | +| 744 | TS2339 | Property 'stop_reason' does not exist on type 'void \| SDKMessage' | `msg.stop_reason` — 同上 | +| 755 | TS2339 | Property 'stop_reason' does not exist on type 'void \| SDKMessage' | `msg.stop_reason` — error_during_execution 分支 | +| 780 | TS2345 | Argument of type 'void \| SDKMessage' is not assignable to parameter of type 'SDKMessage' | `streamEventToAcpNotifications(msg, ...)` — 传递给需要 SDKMessage 的函数 | +| 800 | TS2339 | Property 'message' does not exist on type 'void \| SDKMessage' | `msg.message` — assistant 分支 | +| 803 | TS2339 | Property 'parent_tool_use_id' does not exist on type 'void \| SDKMessage' | `msg.parent_tool_use_id` — 同上 | +| 825 | TS2345 | Argument of type 'void \| SDKMessage' is not assignable to parameter of type 'SDKMessage' | `assistantMessageToAcpNotifications(msg, ...)` — 同上 | +| 850 | TS2339 | Property 'data' does not exist on type 'void \| SDKMessage' | `msg.data` — progress 分支 | + +### autofix-pr — RemoteAgentPreconditionResult 类型(2 个) + +**文件:** `src/commands/autofix-pr/launchAutofixPr.ts` + +| 行号 | 错误代码 | 错误信息 | 说明 | +|------|----------|----------|------| +| 237 | TS2339 | Property 'errors' does not exist on type '{ eligible: true; }' | `eligibility.errors` — 社区代码对 `checkRemoteAgentEligibility` 的返回类型判别式假设不准确,eligible 为 true 的分支上没有 errors 属性 | +| 321 | TS2353 | Object literal may only specify known properties, and 'source' does not exist in type '...' | `teleportToRemote` 参数中传入 `source: 'autofix_pr'` — 该属性不在社区定义的类型中,社区代码新增了 source 字段但未更新类型定义 | + +### 测试文件 — 类型守卫不完整(4 个) + +**文件:** `src/commands/issue/__tests__/issue-gh.test.ts` 和 `src/commands/share/__tests__/share-gh.test.ts` + +| 文件 | 行号 | 错误代码 | 错误信息 | 说明 | +|------|------|----------|----------|------| +| issue-gh.test.ts | 224:25 | TS2339 | Property 'msg' does not exist on type '{ ok: true; stdout: string; } \| { ok: false; msg: string; }' | 在 `b.ok` 为 false 的分支访问 `b.msg`,但 TS 判别式收窄后认为 b 可能是 `{ ok: true }` 类型 | +| issue-gh.test.ts | 224:37 | TS2339 | Property 'msg' does not exist on type '{ ok: true; stdout: string; } \| { ok: false; msg: string; }' | 同上,`b.msg` 第二次引用 | +| share-gh.test.ts | 216:25 | TS2339 | Property 'msg' does not exist on type '{ ok: true; stdout: string; } \| { ok: false; msg: string; }' | 同上,share-gh 测试的等价代码 | +| share-gh.test.ts | 216:37 | TS2339 | Property 'msg' does not exist on type '{ ok: true; stdout: string; } \| { ok: false; msg: string; }' | 同上,`b.msg` 第二次引用 | + +### client.ts — GoogleAuth 泛型兼容(1 个) + +**文件:** `src/services/api/client.ts` + +| 行号 | 错误代码 | 错误信息 | 说明 | +|------|----------|----------|------| +| 297 | TS2322 | Type 'GoogleAuth\' is not assignable to type 'GoogleAuth\' | Vertex AI 的 GoogleAuth 泛型参数不兼容,#private 成员不一致,使用 `as unknown as GoogleAuth` 绕过 | + +--- + +## 2. as any 遗留(49 个) + +### API Provider 适配器(31 个) + +社区后加的 multi-provider 支持。三个 provider 文件(openai、grok、gemini)均使用 `as any` 绕过流式事件类型的强类型约束。事件来自 `adaptOpenAIStreamToAnthropic()` / `adaptGrokStreamToAnthropic()` 等适配器,返回类型为 `BetaRawMessageStreamEvent`,但社区直接在 switch 中通过 `(event as any)` 访问下游属性。 + +#### openai/index.ts(14 处) + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 308 | `(client.chat.completions.create as any)` | 强制转换 OpenAI 客户端方法以绕过类型签名 | +| 333 | `(event as any).message` | 流事件 message_start 中提取 message | +| 335 | `(event as any).message?.usage` | 访问 usage 统计 | +| 338 | `(event as any).message.usage` | 展开 usage 对象 | +| 344 | `(event as any).index` | content_block_start 中提取块索引 | +| 345 | `(event as any).content_block` | 提取内容块 | +| 358 | `(event as any).index` | content_block_delta 中提取块索引 | +| 359 | `(event as any).delta` | 提取 delta 增量 | +| 378 | `(event as any).usage` | message_delta 中提取 usage 增量 | +| 382 | `(event as any).delta?.stop_reason` | 检查 stop_reason | +| 383 | `(event as any).delta.stop_reason` | 提取 stop_reason | +| 404 | `usage as any` | 传入 calculateUSDCost | +| 405 | `usage as any` | 传入 addToTotalSessionCost | +| 455 | `error as any` | 包装 API 错误对象 | + +#### grok/index.ts(11 处) + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 118 | `(event as any).message` | 流事件 message_start 中提取 message | +| 120 | `(event as any).message?.usage` | 访问 usage | +| 121 | `(event as any).message.usage` | 展开 usage | +| 126 | `(event as any).index` | content_block_start 块索引 | +| 127 | `(event as any).content_block` | 内容块 | +| 140 | `(event as any).index` | content_block_delta 块索引 | +| 141 | `(event as any).delta` | delta 增量 | +| 156 | `(event as any).index` | content_block_stop 块索引 | +| 175 | `(event as any).usage` | message_delta usage | +| 186 | `usage as any` | 传入 calculateUSDCost | +| 187 | `usage as any` | 传入 addToTotalSessionCost | + +#### gemini/index.ts(6 处) + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 124 | `(event as any).message` | 流事件 message_start 中提取 message | +| 128 | `(event as any).index` | content_block_start 块索引 | +| 129 | `(event as any).content_block` | 内容块 | +| 142 | `(event as any).index` | content_block_delta 块索引 | +| 143 | `(event as any).delta` | delta 增量 | +| 163 | `(event as any).index` | content_block_stop 块索引 | + +### 生成代码 — protobuf 自动生成(7 个) + +protobuf 代码生成器输出,`google.protobuf.Any` → TypeScript `any` 映射。文件在 `src/types/generated/` 下。全部为 `.create()` 方法中 `base ?? ({} as any)` 模式——空对象兜底需要用 `as any` 因为泛型约束不允许直接传空对象。 + +| 文件 | 行号 | 表达式 | 说明 | +|------|------|--------|------| +| `.../claude_code/v1/claude_code_internal_event.ts` | 168 | `{} as any` | GitHubActionsMetadata.create() 空对象兜底 | +| `.../claude_code/v1/claude_code_internal_event.ts` | 442 | `{} as any` | EnvironmentMetadata.create() 空对象兜底 | +| `.../claude_code/v1/claude_code_internal_event.ts` | 538 | `{} as any` | SlackContext.create() 空对象兜底 | +| `.../claude_code/v1/claude_code_internal_event.ts` | 766 | `{} as any` | ClaudeCodeInternalEvent.create() 空对象兜底 | +| `.../google/protobuf/timestamp.ts` | 140 | `{} as any` | Timestamp.create() 空对象兜底 | +| `.../growthbook/v1/growthbook_experiment_event.ts` | 147 | `{} as any` | GrowthbookExperimentEvent.create() 空对象兜底 | +| `.../common/v1/auth.ts` | 52 | `{} as any` | PublicApiAuth.create() 空对象兜底 | + +### MCP/cli 社区代码(5 个) + +#### ccrClient.ts — CCR 远程客户端传输层(3 处) + +**文件:** `src/cli/transports/ccrClient.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 384 | `(result as any).retryAfterMs` | 事件上传失败时从 `result` 提取重试延迟(`result` 类型未定义 `retryAfterMs`) | +| 407 | `(result as any).retryAfterMs` | internal 事件上传失败重试延迟 | +| 438 | `(result as any).retryAfterMs` | delivery 事件上传失败重试延迟 | + +#### structuredIO.ts — CLI 结构化 I/O(1 处) + +**文件:** `src/cli/structuredIO.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 701 | `input as any` | hook callback 输入强制转换,调用方类型不匹配接收方期待的形状 | + +#### useManageMCPConnections.ts(1 处) + +**文件:** `src/services/mcp/useManageMCPConnections.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 527 | `origin: { kind: 'channel', server: client.name } as any` | 拼装 enqueue 的 origin 字段时强制转换 object literal | + +### 其他社区代码(6 个) + +#### relay.ts — CCR upstreamproxy WebSocket(3 处) + +**文件:** `src/upstreamproxy/relay.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 384 | `ws.send(encodeChunk(...) as any)` | WebSocket 连接建立时发送 CONNECT + Proxy-Authorization 头部,`encodeChunk` 返回值与 `ws.send()` 参数类型不兼容 | +| 432 | `ws.send(encodeChunk(...) as any)` | 发送 keepalive 空 chunk | +| 440 | `ws.send(encodeChunk(...) as any)` | 转发 TCP 数据到 WebSocket,分片发送 | + +#### streamAdapter.ts — OpenAI 流适配器(2 处) + +**文件:** `src/services/api/openai/streamAdapter.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 80 | `(chunk.usage as any).prompt_tokens_details?.cached_tokens` | OpenAI chunk 的 usage 结构体不包含 `prompt_tokens_details`(仅在部分模型中存在),通过 as any 访问 cached_tokens | +| 123 | `(delta as any).reasoning_content` | DeepSeek 模型的 `reasoning_content` 字段非标准 OpenAI 协议字段,通过 as any 访问 | + +#### branch.ts — branch 命令(1 处) + +**文件:** `src/commands/branch/branch.ts` + +| 行号 | 表达式 | 说明 | +|------|--------|------| +| 41 | `(firstUserMessage as any)?.message?.content` | 从 SerializedMessage 中提取首条用户消息的 content 字段,类型定义未覆盖嵌套 message 结构 | diff --git a/src/cli/print.ts b/src/cli/print.ts index 83d36b6c5..3ee57adb7 100644 --- a/src/cli/print.ts +++ b/src/cli/print.ts @@ -4777,7 +4777,7 @@ function handleChannelEnable( // channel messages queue at priority 'next' and are seen by the model on // the turn after they arrive. connection.client.setNotificationHandler( - ChannelMessageNotificationSchema() as any, + ChannelMessageNotificationSchema(), async notification => { const { content, meta } = notification.params logMCPDebug( @@ -4853,7 +4853,7 @@ function reregisterChannelHandlerAfterReconnect( 'Channel notifications re-registered after reconnect', ) connection.client.setNotificationHandler( - ChannelMessageNotificationSchema() as any, + ChannelMessageNotificationSchema(), async notification => { const { content, meta } = notification.params logMCPDebug( diff --git a/src/hooks/useIdeAtMentioned.ts b/src/hooks/useIdeAtMentioned.ts index 7d79c6e5e..b54ed71dd 100644 --- a/src/hooks/useIdeAtMentioned.ts +++ b/src/hooks/useIdeAtMentioned.ts @@ -7,6 +7,7 @@ import type { } from '../services/mcp/types.js' import { getConnectedIdeClient } from '../utils/ide.js' import { lazySchema } from '../utils/lazySchema.js' +import type { AnyObjectSchema } from '@modelcontextprotocol/sdk/server/zod-compat.js' export type IDEAtMentioned = { filePath: string lineStart?: number @@ -15,7 +16,7 @@ export type IDEAtMentioned = { const NOTIFICATION_METHOD = 'at_mentioned' -const AtMentionedSchema = lazySchema(() => +const AtMentionedSchema: () => AnyObjectSchema = lazySchema(() => z.object({ method: z.literal(NOTIFICATION_METHOD), params: z.object({ @@ -47,7 +48,7 @@ export function useIdeAtMentioned( // If we found a connected IDE client, register our handler if (ideClient) { ideClient.client.setNotificationHandler( - AtMentionedSchema() as any, + AtMentionedSchema(), notification => { if (ideClientRef.current !== ideClient) { return diff --git a/src/services/api/claude.ts b/src/services/api/claude.ts index 84a4db985..665c68d2e 100644 --- a/src/services/api/claude.ts +++ b/src/services/api/claude.ts @@ -1234,13 +1234,14 @@ async function* queryModel( cachedMCEnabled = featureEnabled && modelSupported const config = getCachedMCConfig() logForDebugging( - `Cached MC gate: enabled=${featureEnabled} modelSupported=${modelSupported} model=${options.model} supportedModels=${jsonStringify((config as any).supportedModels)}`, + `Cached MC gate: enabled=${featureEnabled} modelSupported=${modelSupported} model=${options.model} supportedModels=${jsonStringify((config as Record).supportedModels ?? [])}`, ) } const useGlobalCacheFeature = shouldUseGlobalCacheScope() const willDefer = (t: Tool) => - useSearchExtraTools && (deferredToolNames.has(t.name) || shouldDeferLspTool(t)) + useSearchExtraTools && + (deferredToolNames.has(t.name) || shouldDeferLspTool(t)) // MCP tools are per-user → dynamic tool section → can't globally cache. // Only gate when an MCP tool will actually render (not defer_loading). const needsToolBasedCacheMarker = @@ -1607,8 +1608,8 @@ async function* queryModel( cachedMCEnabled && getAPIProvider() === 'firstParty' && options.querySource === 'repl_main_thread', - consumedCacheEdits as any, - consumedPinnedEdits as any, + consumedCacheEdits as unknown as CachedMCEditsBlock | null, + consumedPinnedEdits as unknown as CachedMCPinnedEdits[], options.skipCacheWrite, ) const frozenSystem = cloneDeep(system) @@ -1644,9 +1645,7 @@ async function* queryModel( // For Bedrock, include both model-based betas and dynamically-added tool search header const bedrockBetas = getAPIProvider() === 'bedrock' - ? [ - ...getBedrockExtraBodyParamsBetas(retryContext.model), - ] + ? [...getBedrockExtraBodyParamsBetas(retryContext.model)] : [] const extraBodyParams = getExtraBodyParams(bedrockBetas) @@ -3313,7 +3312,10 @@ export function addCacheBreakpoints( } insertBlockAfterToolResults(msg.content, dedupedNewEdits) // Pin so this block is re-sent at the same position in future calls - pinCacheEdits(i, newCacheEdits as any) + pinCacheEdits( + i, + newCacheEdits as unknown as import('../compact/cachedMicrocompact.js').CacheEditsBlock, + ) logForDebugging( `Added cache_edits block with ${dedupedNewEdits.edits.length} deletion(s) to message[${i}]: ${dedupedNewEdits.edits.map(e => e.cache_reference).join(', ')}`, diff --git a/src/services/api/client.ts b/src/services/api/client.ts index c8c2caabc..91eb061a9 100644 --- a/src/services/api/client.ts +++ b/src/services/api/client.ts @@ -291,14 +291,14 @@ export async function getAnthropicClient({ }), }) - const vertexArgs: ConstructorParameters[0] = { + const vertexArgs = { ...ARGS, region: getVertexRegionForModel(model), - googleAuth: googleAuth as any, + googleAuth, ...(isDebugToStdErr() && { logger: createStderrLogger() }), } // we have always been lying about the return type - this doesn't support batching or models - return new AnthropicVertex(vertexArgs) as unknown as Anthropic + return new AnthropicVertex(vertexArgs as any) as unknown as Anthropic } // Determine authentication method based on available tokens diff --git a/src/services/api/filesApi.ts b/src/services/api/filesApi.ts index 71b896bee..9734bbbd0 100644 --- a/src/services/api/filesApi.ts +++ b/src/services/api/filesApi.ts @@ -107,13 +107,13 @@ async function retryWithBackoff( return result.value } - lastError = (result as any).error || `${operation} failed` + lastError = (result as { error?: string }).error || `${operation} failed` logDebug( `${operation} attempt ${attempt}/${MAX_RETRIES} failed: ${lastError}`, ) if (attempt < MAX_RETRIES) { - const delayMs = BASE_DELAY_MS * Math.pow(2, attempt - 1) + const delayMs = BASE_DELAY_MS * 2 ** (attempt - 1) logDebug(`Retrying ${operation} in ${delayMs}ms...`) await sleep(delayMs) } diff --git a/src/services/mcp/channelNotification.ts b/src/services/mcp/channelNotification.ts index 9a177c4eb..687fad447 100644 --- a/src/services/mcp/channelNotification.ts +++ b/src/services/mcp/channelNotification.ts @@ -35,17 +35,18 @@ import { isChannelsEnabled, } from './channelAllowlist.js' -export const ChannelMessageNotificationSchema = lazySchema(() => - z.object({ - method: z.literal('notifications/claude/channel'), - params: z.object({ - content: z.string(), - // Opaque passthrough — thread_id, user, whatever the channel wants the - // model to see. Rendered as attributes on the tag. - meta: z.record(z.string(), z.string()).optional(), +export const ChannelMessageNotificationSchema: () => AnyObjectSchema = + lazySchema(() => + z.object({ + method: z.literal('notifications/claude/channel'), + params: z.object({ + content: z.string(), + // Opaque passthrough — thread_id, user, whatever the channel wants the + // model to see. Rendered as attributes on the tag. + meta: z.record(z.string(), z.string()).optional(), + }), }), - }), -) + ) /** * Structured permission reply from a channel server. Servers that support @@ -62,15 +63,16 @@ export const ChannelMessageNotificationSchema = lazySchema(() => */ export const CHANNEL_PERMISSION_METHOD = 'notifications/claude/channel/permission' -export const ChannelPermissionNotificationSchema = lazySchema(() => - z.object({ - method: z.literal(CHANNEL_PERMISSION_METHOD), - params: z.object({ - request_id: z.string(), - behavior: z.enum(['allow', 'deny']), +export const ChannelPermissionNotificationSchema: () => AnyObjectSchema = + lazySchema(() => + z.object({ + method: z.literal(CHANNEL_PERMISSION_METHOD), + params: z.object({ + request_id: z.string(), + behavior: z.enum(['allow', 'deny']), + }), }), - }), -) + ) /** * Outbound: CC → server. Fired from interactiveHandler.ts when a diff --git a/src/services/mcp/useManageMCPConnections.ts b/src/services/mcp/useManageMCPConnections.ts index 729621457..6975f7d34 100644 --- a/src/services/mcp/useManageMCPConnections.ts +++ b/src/services/mcp/useManageMCPConnections.ts @@ -17,6 +17,7 @@ import type { ScopedMcpServerConfig, ServerResource, } from './types.js' +import type { MessageOrigin } from '../../types/message.js' /* eslint-disable @typescript-eslint/no-require-imports */ const fetchMcpSkillsForClient = feature('MCP_SKILLS') @@ -504,7 +505,7 @@ export function useManageMCPConnections( case 'register': logMCPDebug(client.name, 'Channel notifications registered') client.client.setNotificationHandler( - ChannelMessageNotificationSchema() as any, + ChannelMessageNotificationSchema(), async notification => { const { content, meta } = notification.params logMCPDebug( @@ -524,7 +525,10 @@ export function useManageMCPConnections( value: wrapChannelMessage(client.name, content, meta), priority: 'next', isMeta: true, - origin: { kind: 'channel', server: client.name } as any, + origin: { + kind: 'channel', + server: client.name, + } as MessageOrigin, skipSlashCommands: true, }) }, @@ -539,7 +543,7 @@ export function useManageMCPConnections( client.capabilities?.experimental?.['claude/channel/permission'] ) { client.client.setNotificationHandler( - ChannelPermissionNotificationSchema() as any, + ChannelPermissionNotificationSchema(), async notification => { const { request_id, behavior } = notification.params const resolved = diff --git a/src/services/mcp/vscodeSdkMcp.ts b/src/services/mcp/vscodeSdkMcp.ts index 27ee1c446..24fb5968d 100644 --- a/src/services/mcp/vscodeSdkMcp.ts +++ b/src/services/mcp/vscodeSdkMcp.ts @@ -1,6 +1,7 @@ import { logForDebugging } from 'src/utils/debug.js' import { z } from 'zod/v4' import { lazySchema } from '../../utils/lazySchema.js' +import type { AnyObjectSchema } from '@modelcontextprotocol/sdk/server/zod-compat.js' import { checkStatsigFeatureGate_CACHED_MAY_BE_STALE, getFeatureValue_CACHED_MAY_BE_STALE, @@ -19,14 +20,15 @@ function readAutoModeEnabledState(): AutoModeEnabledState | undefined { return v === 'enabled' || v === 'disabled' || v === 'opt-in' ? v : undefined } -export const LogEventNotificationSchema = lazySchema(() => - z.object({ - method: z.literal('log_event'), - params: z.object({ - eventName: z.string(), - eventData: z.object({}).passthrough(), +export const LogEventNotificationSchema: () => AnyObjectSchema = lazySchema( + () => + z.object({ + method: z.literal('log_event'), + params: z.object({ + eventName: z.string(), + eventData: z.object({}).passthrough(), + }), }), - }), ) // Store the VSCode MCP client reference for sending notifications @@ -69,7 +71,7 @@ export function setupVscodeSdkMcp(sdkClients: MCPServerConnection[]): void { vscodeMcpClient = client client.client.setNotificationHandler( - LogEventNotificationSchema() as any, + LogEventNotificationSchema(), async notification => { const { eventName, eventData } = notification.params logEvent(