import { createContext, useCallback, useContext, useMemo, useRef, type MutableRefObject, type ReactNode, } from "react"; import React from "react"; import type { ToastApi } from "@/components/toast-host"; import type { OpenFileDisposition } from "@/workspace/file-open"; import type { InlinePathTarget } from "./parse"; import type { AssistantFileLinkContext, GetDirectorySuggestions } from "./resolver"; export interface AssistantFileLinkDaemonClient { getDirectorySuggestions: GetDirectorySuggestions; } export interface AssistantFileLinkResolverConfig { client?: AssistantFileLinkDaemonClient | null; serverId?: string; workspaceRoot?: string; onOpenWorkspaceFile?: (target: InlinePathTarget, disposition: OpenFileDisposition) => void; toast?: ToastApi | null; } export interface AssistantFileLinkResolverProviderProps extends AssistantFileLinkResolverConfig { children: ReactNode; } export interface AssistantFileLinkResolverContextValue { configRef: MutableRefObject; getDirectorySuggestions: GetDirectorySuggestions; } const AssistantFileLinkResolverContext = createContext(null); export function AssistantFileLinkResolverProvider({ client, serverId, workspaceRoot, onOpenWorkspaceFile, toast, children, }: AssistantFileLinkResolverProviderProps) { const configRef = useRef({ client, serverId, workspaceRoot, onOpenWorkspaceFile, toast, }); configRef.current = { client, serverId, workspaceRoot, onOpenWorkspaceFile, toast }; const getDirectorySuggestions = useCallback(async (input) => { const activeClient = configRef.current.client; if (!activeClient) { return { entries: [], error: null }; } const result = await activeClient.getDirectorySuggestions(input); return { entries: result.entries, error: result.error }; }, []); const value = useMemo( () => ({ configRef, getDirectorySuggestions }), [getDirectorySuggestions], ); return ( {children} ); } export function useAssistantFileLinkResolverContext(): AssistantFileLinkResolverContextValue { const context = useContext(AssistantFileLinkResolverContext); if (!context) { throw new Error("AssistantFileLinkResolverProvider is required for assistant file links."); } return context; } export type { AssistantFileLinkContext };