🎯 Use case
This file lives under “hooks/”, which covers reusable UI or integration hooks. On the API surface it exposes IDEAtMentioned and useIdeAtMentioned — mainly functions, hooks, or classes. Dependencies touch React UI, src, and schema validation. It composes internal code from services and utils (relative imports).
Generated from folder role, exports, dependency roots, and inline comments — not hand-reviewed for every path.
🧠 Inline summary
import { useEffect, useRef } from 'react' import { logError } from 'src/utils/log.js' import { z } from 'zod/v4' import type { ConnectedMCPServer,
📤 Exports (heuristic)
IDEAtMentioneduseIdeAtMentioned
📚 External import roots
Package roots from from "…" (relative paths omitted).
reactsrczod
🖥️ Source preview
import { useEffect, useRef } from 'react'
import { logError } from 'src/utils/log.js'
import { z } from 'zod/v4'
import type {
ConnectedMCPServer,
MCPServerConnection,
} from '../services/mcp/types.js'
import { getConnectedIdeClient } from '../utils/ide.js'
import { lazySchema } from '../utils/lazySchema.js'
export type IDEAtMentioned = {
filePath: string
lineStart?: number
lineEnd?: number
}
const NOTIFICATION_METHOD = 'at_mentioned'
const AtMentionedSchema = lazySchema(() =>
z.object({
method: z.literal(NOTIFICATION_METHOD),
params: z.object({
filePath: z.string(),
lineStart: z.number().optional(),
lineEnd: z.number().optional(),
}),
}),
)
/**
* A hook that tracks IDE at-mention notifications by directly registering
* with MCP client notification handlers,
*/
export function useIdeAtMentioned(
mcpClients: MCPServerConnection[],
onAtMentioned: (atMentioned: IDEAtMentioned) => void,
): void {
const ideClientRef = useRef<ConnectedMCPServer | undefined>(undefined)
useEffect(() => {
// Find the IDE client from the MCP clients list
const ideClient = getConnectedIdeClient(mcpClients)
if (ideClientRef.current !== ideClient) {
ideClientRef.current = ideClient
}
// If we found a connected IDE client, register our handler
if (ideClient) {
ideClient.client.setNotificationHandler(
AtMentionedSchema(),
notification => {
if (ideClientRef.current !== ideClient) {
return
}
try {
const data = notification.params
// Adjust line numbers to be 1-based instead of 0-based
const lineStart =
data.lineStart !== undefined ? data.lineStart + 1 : undefined
const lineEnd =
data.lineEnd !== undefined ? data.lineEnd + 1 : undefined
onAtMentioned({
filePath: data.filePath,
lineStart: lineStart,
lineEnd: lineEnd,
})
} catch (error) {
logError(error as Error)
}
},
)
}
// No cleanup needed as MCP clients manage their own lifecycle
}, [mcpClients, onAtMentioned])
}