diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 8c71b8d9d..67d3b114b 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -13,12 +13,12 @@ import { WriteFileTool, DEFAULT_QWEN_MODEL, OutputFormat, + NativeLspService, } from '@qwen-code/qwen-code-core'; import { loadCliConfig, parseArguments, type CliArgs } from './config.js'; import type { Settings } from './settings.js'; import * as ServerConfig from '@qwen-code/qwen-code-core'; import { isWorkspaceTrusted } from './trustedFolders.js'; -import { NativeLspService } from '../services/lsp/NativeLspService.js'; const createNativeLspServiceInstance = () => ({ discoverAndPrepare: vi.fn(), @@ -38,26 +38,6 @@ const createNativeLspServiceInstance = () => ({ applyWorkspaceEdit: vi.fn().mockResolvedValue(false), }); -vi.mock('../services/lsp/NativeLspService.js', () => ({ - NativeLspService: vi.fn().mockImplementation(() => ({ - discoverAndPrepare: vi.fn(), - start: vi.fn(), - definitions: vi.fn().mockResolvedValue([]), - references: vi.fn().mockResolvedValue([]), - workspaceSymbols: vi.fn().mockResolvedValue([]), - hover: vi.fn().mockResolvedValue(null), - documentSymbols: vi.fn().mockResolvedValue([]), - implementations: vi.fn().mockResolvedValue([]), - prepareCallHierarchy: vi.fn().mockResolvedValue([]), - incomingCalls: vi.fn().mockResolvedValue([]), - outgoingCalls: vi.fn().mockResolvedValue([]), - diagnostics: vi.fn().mockResolvedValue([]), - workspaceDiagnostics: vi.fn().mockResolvedValue([]), - codeActions: vi.fn().mockResolvedValue([]), - applyWorkspaceEdit: vi.fn().mockResolvedValue(false), - })), -})); - vi.mock('./trustedFolders.js', () => ({ isWorkspaceTrusted: vi .fn() @@ -129,6 +109,9 @@ vi.mock('@qwen-code/qwen-code-core', async (importOriginal) => { const actualServer = await importOriginal(); return { ...actualServer, + NativeLspService: vi + .fn() + .mockImplementation(() => createNativeLspServiceInstance()), IdeClient: { getInstance: vi.fn().mockResolvedValue({ getConnectionStatus: vi.fn(), diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index a6613e73e..26509c141 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -27,6 +27,8 @@ import { EditTool, ShellTool, WriteFileTool, + NativeLspClient, + NativeLspService, } from '@qwen-code/qwen-code-core'; import { extensionsCommand } from '../commands/extensions.js'; import type { Settings } from './settings.js'; @@ -45,8 +47,6 @@ import { getCliVersion } from '../utils/version.js'; import { loadSandboxConfig } from './sandboxConfig.js'; import { appEvents } from '../utils/events.js'; import { mcpCommand } from '../commands/mcp.js'; -import { NativeLspClient } from '../services/lsp/NativeLspClient.js'; -import { NativeLspService } from '../services/lsp/NativeLspService.js'; import { isWorkspaceTrusted } from './trustedFolders.js'; import { buildWebSearchConfig } from './webSearch.js'; @@ -729,9 +729,7 @@ export async function loadCliConfig( await loadHierarchicalGeminiMemory( cwd, - settings.context?.loadMemoryFromIncludeDirectories - ? includeDirectories - : [], + settings.context?.loadFromIncludeDirectories ? includeDirectories : [], debugMode, fileService, extensionContextFilePaths, diff --git a/packages/cli/src/services/lsp/LspTypes.ts b/packages/cli/src/services/lsp/LspTypes.ts deleted file mode 100644 index 55b89cbef..000000000 --- a/packages/cli/src/services/lsp/LspTypes.ts +++ /dev/null @@ -1,205 +0,0 @@ -/** - * @license - * Copyright 2025 Qwen Team - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * LSP Service Type Definitions - * - * Centralized type definitions for the LSP service modules. - */ - -import type { ChildProcess } from 'node:child_process'; - -// ============================================================================ -// LSP Initialization Options -// ============================================================================ - -/** - * LSP server initialization options passed during the initialize request. - */ -export interface LspInitializationOptions { - [key: string]: unknown; -} - -// ============================================================================ -// LSP Socket Options -// ============================================================================ - -/** - * Socket connection options for TCP or Unix socket transport. - */ -export interface LspSocketOptions { - /** Host address for TCP connections */ - host?: string; - /** Port number for TCP connections */ - port?: number; - /** Path for Unix socket connections */ - path?: string; -} - -// ============================================================================ -// LSP Server Configuration -// ============================================================================ - -/** - * Configuration for an LSP server instance. - */ -export interface LspServerConfig { - /** Unique name identifier for the server */ - name: string; - /** List of languages this server handles */ - languages: string[]; - /** Command to start the server (required for stdio transport) */ - command?: string; - /** Command line arguments */ - args?: string[]; - /** Transport type: stdio, tcp, or socket */ - transport: 'stdio' | 'tcp' | 'socket'; - /** Environment variables for the server process */ - env?: Record; - /** LSP initialization options */ - initializationOptions?: LspInitializationOptions; - /** Server-specific settings */ - settings?: Record; - /** Custom file extension to language mappings */ - extensionToLanguage?: Record; - /** Root URI for the workspace */ - rootUri: string; - /** Workspace folder path */ - workspaceFolder?: string; - /** Startup timeout in milliseconds */ - startupTimeout?: number; - /** Shutdown timeout in milliseconds */ - shutdownTimeout?: number; - /** Whether to restart on crash */ - restartOnCrash?: boolean; - /** Maximum number of restart attempts */ - maxRestarts?: number; - /** Whether trusted workspace is required */ - trustRequired?: boolean; - /** Socket connection options */ - socket?: LspSocketOptions; -} - -// ============================================================================ -// LSP JSON-RPC Message -// ============================================================================ - -/** - * JSON-RPC message format for LSP communication. - */ -export interface JsonRpcMessage { - jsonrpc: string; - id?: number | string; - method?: string; - params?: unknown; - result?: unknown; - error?: { - code: number; - message: string; - data?: unknown; - }; -} - -// ============================================================================ -// LSP Connection Interface -// ============================================================================ - -/** - * Interface for LSP JSON-RPC connection. - */ -export interface LspConnectionInterface { - /** Start listening on a readable stream */ - listen: (readable: NodeJS.ReadableStream) => void; - /** Send a message to the server */ - send: (message: JsonRpcMessage) => void; - /** Register a notification handler */ - onNotification: (handler: (notification: JsonRpcMessage) => void) => void; - /** Register a request handler */ - onRequest: (handler: (request: JsonRpcMessage) => Promise) => void; - /** Send a request and wait for response */ - request: (method: string, params: unknown) => Promise; - /** Send initialize request */ - initialize: (params: unknown) => Promise; - /** Send shutdown request */ - shutdown: () => Promise; - /** End the connection */ - end: () => void; -} - -// ============================================================================ -// LSP Server Status -// ============================================================================ - -/** - * Status of an LSP server instance. - */ -export type LspServerStatus = - | 'NOT_STARTED' - | 'IN_PROGRESS' - | 'READY' - | 'FAILED'; - -// ============================================================================ -// LSP Server Handle -// ============================================================================ - -/** - * Handle for managing an LSP server instance. - */ -export interface LspServerHandle { - /** Server configuration */ - config: LspServerConfig; - /** Current status */ - status: LspServerStatus; - /** Active connection to the server */ - connection?: LspConnectionInterface; - /** Server process (for stdio transport) */ - process?: ChildProcess; - /** Error that caused failure */ - error?: Error; - /** Whether TypeScript server has been warmed up */ - warmedUp?: boolean; - /** Whether stop was explicitly requested */ - stopRequested?: boolean; - /** Number of restart attempts */ - restartAttempts?: number; - /** Lock to prevent concurrent startup attempts */ - startingPromise?: Promise; -} - -// ============================================================================ -// LSP Service Options -// ============================================================================ - -/** - * Options for NativeLspService constructor. - */ -export interface NativeLspServiceOptions { - /** Whether to require trusted workspace */ - requireTrustedWorkspace?: boolean; - /** Override workspace root path */ - workspaceRoot?: string; -} - -// ============================================================================ -// LSP Connection Result -// ============================================================================ - -/** - * Result from creating an LSP connection. - */ -export interface LspConnectionResult { - /** The JSON-RPC connection */ - connection: LspConnectionInterface; - /** Server process (for stdio transport) */ - process?: ChildProcess; - /** Shutdown the connection gracefully */ - shutdown: () => Promise; - /** Force exit the connection */ - exit: () => void; - /** Send initialize request */ - initialize: (params: unknown) => Promise; -} diff --git a/packages/core/src/core/__snapshots__/prompts.test.ts.snap b/packages/core/src/core/__snapshots__/prompts.test.ts.snap index 6d1eff9fc..0c0b6c6ad 100644 --- a/packages/core/src/core/__snapshots__/prompts.test.ts.snap +++ b/packages/core/src/core/__snapshots__/prompts.test.ts.snap @@ -124,19 +124,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -356,19 +343,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -598,19 +572,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -825,19 +786,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -1052,19 +1000,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -1279,19 +1214,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -1506,19 +1428,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -1733,19 +1642,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -1960,19 +1856,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -2187,19 +2070,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -2437,19 +2307,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -2747,19 +2604,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -2997,19 +2841,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -3303,19 +3134,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. @@ -3530,19 +3348,6 @@ IMPORTANT: Always use the todo_write tool to plan and track tasks throughout the - **Subagent Delegation:** When doing file search, prefer to use the 'task' tool in order to reduce context usage. You should proactively use the 'task' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the 'save_memory' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the 'lsp' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use 'grep_search' or 'glob' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. diff --git a/packages/core/src/core/prompts.ts b/packages/core/src/core/prompts.ts index 94d54b911..8d3ff4683 100644 --- a/packages/core/src/core/prompts.ts +++ b/packages/core/src/core/prompts.ts @@ -258,19 +258,6 @@ IMPORTANT: Always use the ${ToolNames.TODO_WRITE} tool to plan and track tasks t - **Subagent Delegation:** When doing file search, prefer to use the '${ToolNames.TASK}' tool in order to reduce context usage. You should proactively use the '${ToolNames.TASK}' tool with specialized agents when the task at hand matches the agent's description. - **Remembering Facts:** Use the '${ToolNames.MEMORY}' tool to remember specific, *user-related* facts or preferences when the user explicitly asks, or when they state a clear, concise piece of information that would help personalize or streamline *your future interactions with them* (e.g., preferred coding style, common project paths they use, personal tool aliases). This tool is for user-specific information that should persist across sessions. Do *not* use it for general project context or information. If unsure whether to save something, you can ask the user, "Should I remember that for you?" - **Respect User Confirmations:** Most tool calls (also denoted as 'function calls') will first require confirmation from the user, where they will either approve or cancel the function call. If a user cancels a function call, respect their choice and do _not_ try to make the function call again. It is okay to request the tool call again _only_ if the user requests that same tool call on a subsequent prompt. When a user cancels a function call, assume best intentions from the user and consider inquiring if they prefer any alternative paths forward. -- **LSP (Language Server Protocol):** When the '${ToolNames.LSP}' tool is available, you MUST use it as the PRIMARY tool for code intelligence queries. Do NOT use '${ToolNames.GREP}' or '${ToolNames.GLOB}' first - go directly to LSP. Supported operations: - - goToDefinition: Find where a symbol is defined (requires filePath, line, character) - - findReferences: Find all references to a symbol (requires filePath, line, character) - - hover: Get hover information (documentation, type info) for a symbol (requires filePath, line, character) - - documentSymbol: Get all symbols (functions, classes, variables) in a document (requires filePath only) - - workspaceSymbol: Search for symbols across the entire workspace (requires query only, NOT filePath/line/character) - - goToImplementation: Find implementations of an interface or abstract method (requires filePath, line, character) - - prepareCallHierarchy: Get call hierarchy item at a position (requires filePath, line, character) - - incomingCalls: Find all functions/methods that call the given function (requires callHierarchyItem) - - outgoingCalls: Find all functions/methods called by the given function (requires callHierarchyItem) - - diagnostics: Get errors/warnings for a file (requires filePath only) - - workspaceDiagnostics: Get all errors/warnings across the workspace (no parameters required) - IMPORTANT: When user asks "where is X defined?" without specifying a file, use workspaceSymbol with query="X" directly! ## Interaction Details - **Help Command:** The user can use '/help' to display help information. diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 42950ffb9..a9c091a08 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -141,6 +141,14 @@ export * from './tools/exitPlanMode.js'; // Export LSP types and tools export * from './lsp/types.js'; +export * from './lsp/constants.js'; +export * from './lsp/LspConfigLoader.js'; +export * from './lsp/LspConnectionFactory.js'; +export * from './lsp/LspLanguageDetector.js'; +export * from './lsp/LspResponseNormalizer.js'; +export * from './lsp/LspServerManager.js'; +export * from './lsp/NativeLspClient.js'; +export * from './lsp/NativeLspService.js'; export * from './tools/lsp.js'; // MCP OAuth diff --git a/packages/cli/src/services/lsp/LspConfigLoader.test.ts b/packages/core/src/lsp/LspConfigLoader.test.ts similarity index 82% rename from packages/cli/src/services/lsp/LspConfigLoader.test.ts rename to packages/core/src/lsp/LspConfigLoader.test.ts index 2207aa5ea..9f0ee8548 100644 --- a/packages/cli/src/services/lsp/LspConfigLoader.test.ts +++ b/packages/core/src/lsp/LspConfigLoader.test.ts @@ -7,7 +7,7 @@ import { describe, it, expect, afterEach } from 'vitest'; import mock from 'mock-fs'; import { LspConfigLoader } from './LspConfigLoader.js'; -import type { Extension } from '@qwen-code/qwen-code-core'; +import type { Extension } from '../extension/extensionManager.js'; describe('LspConfigLoader extension configs', () => { const workspaceRoot = '/workspace'; @@ -20,9 +20,15 @@ describe('LspConfigLoader extension configs', () => { it('loads inline lspServers config from extension', async () => { const loader = new LspConfigLoader(workspaceRoot); const extension = { + id: 'ts-plugin', name: 'ts-plugin', + version: '1.0.0', + isActive: true, path: extensionPath, + contextFiles: [], config: { + name: 'ts-plugin', + version: '1.0.0', lspServers: { typescript: { command: 'typescript-language-server', @@ -63,9 +69,15 @@ describe('LspConfigLoader extension configs', () => { const loader = new LspConfigLoader(workspaceRoot); const extension = { + id: 'ts-plugin', name: 'ts-plugin', + version: '1.0.0', + isActive: true, path: extensionPath, + contextFiles: [], config: { + name: 'ts-plugin', + version: '1.0.0', lspServers: './.lsp.json', }, } as Extension; @@ -73,6 +85,6 @@ describe('LspConfigLoader extension configs', () => { const configs = await loader.loadExtensionConfigs([extension]); expect(configs).toHaveLength(1); - expect(configs[0]?.env?.EXT_ROOT).toBe(extensionPath); + expect(configs[0]?.env?.['EXT_ROOT']).toBe(extensionPath); }); }); diff --git a/packages/cli/src/services/lsp/LspConfigLoader.ts b/packages/core/src/lsp/LspConfigLoader.ts similarity index 96% rename from packages/cli/src/services/lsp/LspConfigLoader.ts rename to packages/core/src/lsp/LspConfigLoader.ts index c82f5323a..b091a957a 100644 --- a/packages/cli/src/services/lsp/LspConfigLoader.ts +++ b/packages/core/src/lsp/LspConfigLoader.ts @@ -9,14 +9,14 @@ import * as path from 'path'; import { pathToFileURL } from 'url'; import { recursivelyHydrateStrings, - type Extension, type JsonValue, -} from '@qwen-code/qwen-code-core'; +} from '../extension/variables.js'; +import type { Extension } from '../extension/extensionManager.js'; import type { LspInitializationOptions, LspServerConfig, LspSocketOptions, -} from './LspTypes.js'; +} from './types.js'; export class LspConfigLoader { constructor(private readonly workspaceRoot: string) {} @@ -44,7 +44,9 @@ export class LspConfigLoader { /** * Load LSP configurations declared by extensions (Claude plugins). */ - async loadExtensionConfigs(extensions: Extension[]): Promise { + async loadExtensionConfigs( + extensions: Extension[], + ): Promise { const configs: LspServerConfig[] = []; for (const extension of extensions) { @@ -60,19 +62,14 @@ export class LspConfigLoader { lspServers, ); if (!fs.existsSync(configPath)) { - console.warn( - `LSP config not found for ${originBase}: ${configPath}`, - ); + console.warn(`LSP config not found for ${originBase}: ${configPath}`); continue; } try { const configContent = fs.readFileSync(configPath, 'utf-8'); const data = JSON.parse(configContent) as JsonValue; - const hydrated = this.hydrateExtensionLspConfig( - data, - extension.path, - ); + const hydrated = this.hydrateExtensionLspConfig(data, extension.path); configs.push( ...this.parseConfigSource( hydrated, @@ -91,10 +88,7 @@ export class LspConfigLoader { extension.path, ); configs.push( - ...this.parseConfigSource( - hydrated, - `${originBase} (lspServers)`, - ), + ...this.parseConfigSource(hydrated, `${originBase} (lspServers)`), ); } else { console.warn( diff --git a/packages/cli/src/services/lsp/LspConnectionFactory.ts b/packages/core/src/lsp/LspConnectionFactory.ts similarity index 99% rename from packages/cli/src/services/lsp/LspConnectionFactory.ts rename to packages/core/src/lsp/LspConnectionFactory.ts index 84b23878d..dfcecd86d 100644 --- a/packages/cli/src/services/lsp/LspConnectionFactory.ts +++ b/packages/core/src/lsp/LspConnectionFactory.ts @@ -7,7 +7,7 @@ import * as cp from 'node:child_process'; import * as net from 'node:net'; import { DEFAULT_LSP_REQUEST_TIMEOUT_MS } from './constants.js'; -import type { JsonRpcMessage } from './LspTypes.js'; +import type { JsonRpcMessage } from './types.js'; interface PendingRequest { resolve: (value: unknown) => void; diff --git a/packages/cli/src/services/lsp/LspLanguageDetector.ts b/packages/core/src/lsp/LspLanguageDetector.ts similarity index 97% rename from packages/cli/src/services/lsp/LspLanguageDetector.ts rename to packages/core/src/lsp/LspLanguageDetector.ts index 863332867..9c3f96e73 100644 --- a/packages/cli/src/services/lsp/LspLanguageDetector.ts +++ b/packages/core/src/lsp/LspLanguageDetector.ts @@ -14,10 +14,8 @@ import * as fs from 'node:fs'; import * as path from 'path'; import { globSync } from 'glob'; -import type { - WorkspaceContext, - FileDiscoveryService, -} from '@qwen-code/qwen-code-core'; +import type { FileDiscoveryService } from '../services/fileDiscoveryService.js'; +import type { WorkspaceContext } from '../utils/workspaceContext.js'; /** * Extension to language ID mapping diff --git a/packages/cli/src/services/lsp/LspResponseNormalizer.ts b/packages/core/src/lsp/LspResponseNormalizer.ts similarity index 99% rename from packages/cli/src/services/lsp/LspResponseNormalizer.ts rename to packages/core/src/lsp/LspResponseNormalizer.ts index a9720a8a4..9a9a478c0 100644 --- a/packages/cli/src/services/lsp/LspResponseNormalizer.ts +++ b/packages/core/src/lsp/LspResponseNormalizer.ts @@ -27,7 +27,7 @@ import type { LspSymbolInformation, LspTextEdit, LspWorkspaceEdit, -} from '@qwen-code/qwen-code-core'; +} from './types.js'; import { CODE_ACTION_KIND_LABELS, DIAGNOSTIC_SEVERITY_LABELS, diff --git a/packages/cli/src/services/lsp/LspServerManager.ts b/packages/core/src/lsp/LspServerManager.ts similarity index 98% rename from packages/cli/src/services/lsp/LspServerManager.ts rename to packages/core/src/lsp/LspServerManager.ts index 0bb129529..74b25f779 100644 --- a/packages/cli/src/services/lsp/LspServerManager.ts +++ b/packages/core/src/lsp/LspServerManager.ts @@ -4,11 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { - Config as CoreConfig, - WorkspaceContext, - FileDiscoveryService, -} from '@qwen-code/qwen-code-core'; +import type { Config as CoreConfig } from '../config/config.js'; +import type { FileDiscoveryService } from '../services/fileDiscoveryService.js'; +import type { WorkspaceContext } from '../utils/workspaceContext.js'; import { spawn, type ChildProcess } from 'node:child_process'; import * as fs from 'node:fs'; import * as path from 'path'; @@ -29,7 +27,7 @@ import type { LspServerHandle, LspServerStatus, LspSocketOptions, -} from './LspTypes.js'; +} from './types.js'; export interface LspServerManagerOptions { requireTrustedWorkspace: boolean; diff --git a/packages/cli/src/services/lsp/NativeLspClient.ts b/packages/core/src/lsp/NativeLspClient.ts similarity index 98% rename from packages/cli/src/services/lsp/NativeLspClient.ts rename to packages/core/src/lsp/NativeLspClient.ts index 890ed0755..8510ed876 100644 --- a/packages/cli/src/services/lsp/NativeLspClient.ts +++ b/packages/core/src/lsp/NativeLspClient.ts @@ -9,7 +9,7 @@ * by delegating all calls to NativeLspService. * * This class bridges the gap between the generic LspClient interface (defined in core) - * and the CLI-specific NativeLspService implementation. + * and the NativeLspService implementation. */ import type { @@ -28,7 +28,7 @@ import type { LspReference, LspSymbolInformation, LspWorkspaceEdit, -} from '@qwen-code/qwen-code-core'; +} from './types.js'; import type { NativeLspService } from './NativeLspService.js'; diff --git a/packages/cli/src/services/lsp/NativeLspService.integration.test.ts b/packages/core/src/lsp/NativeLspService.integration.test.ts similarity index 98% rename from packages/cli/src/services/lsp/NativeLspService.integration.test.ts rename to packages/core/src/lsp/NativeLspService.integration.test.ts index f9fc6b106..cf737fbf7 100644 --- a/packages/cli/src/services/lsp/NativeLspService.integration.test.ts +++ b/packages/core/src/lsp/NativeLspService.integration.test.ts @@ -7,14 +7,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { EventEmitter } from 'events'; import { NativeLspService } from './NativeLspService.js'; -import type { - Config as CoreConfig, - WorkspaceContext, - FileDiscoveryService, - IdeContextStore, - LspLocation, - LspDiagnostic, -} from '@qwen-code/qwen-code-core'; +import type { Config as CoreConfig } from '../config/config.js'; +import type { FileDiscoveryService } from '../services/fileDiscoveryService.js'; +import type { IdeContextStore } from '../ide/ideContext.js'; +import type { WorkspaceContext } from '../utils/workspaceContext.js'; +import type { LspDiagnostic, LspLocation } from './types.js'; /** * Mock LSP server responses for integration testing. diff --git a/packages/cli/src/services/lsp/NativeLspService.test.ts b/packages/core/src/lsp/NativeLspService.test.ts similarity index 90% rename from packages/cli/src/services/lsp/NativeLspService.test.ts rename to packages/core/src/lsp/NativeLspService.test.ts index 553581d29..218f2e3c7 100644 --- a/packages/cli/src/services/lsp/NativeLspService.test.ts +++ b/packages/core/src/lsp/NativeLspService.test.ts @@ -4,14 +4,13 @@ * SPDX-License-Identifier: Apache-2.0 */ +import { describe, beforeEach, expect, test } from 'vitest'; import { NativeLspService } from './NativeLspService.js'; import { EventEmitter } from 'events'; -import type { - Config as CoreConfig, - WorkspaceContext, - FileDiscoveryService, - IdeContextStore, -} from '@qwen-code/qwen-code-core'; +import type { Config as CoreConfig } from '../config/config.js'; +import type { FileDiscoveryService } from '../services/fileDiscoveryService.js'; +import type { IdeContextStore } from '../ide/ideContext.js'; +import type { WorkspaceContext } from '../utils/workspaceContext.js'; // 模拟依赖项 class MockConfig { diff --git a/packages/cli/src/services/lsp/NativeLspService.ts b/packages/core/src/lsp/NativeLspService.ts similarity index 98% rename from packages/cli/src/services/lsp/NativeLspService.ts rename to packages/core/src/lsp/NativeLspService.ts index a57ad3483..23447ad70 100644 --- a/packages/cli/src/services/lsp/NativeLspService.ts +++ b/packages/core/src/lsp/NativeLspService.ts @@ -4,11 +4,12 @@ * SPDX-License-Identifier: Apache-2.0 */ +import type { Config as CoreConfig } from '../config/config.js'; +import type { Extension } from '../extension/extensionManager.js'; +import type { IdeContextStore } from '../ide/ideContext.js'; +import type { FileDiscoveryService } from '../services/fileDiscoveryService.js'; +import type { WorkspaceContext } from '../utils/workspaceContext.js'; import type { - Config as CoreConfig, - WorkspaceContext, - FileDiscoveryService, - IdeContextStore, LspCallHierarchyIncomingCall, LspCallHierarchyItem, LspCallHierarchyOutgoingCall, @@ -24,19 +25,18 @@ import type { LspSymbolInformation, LspTextEdit, LspWorkspaceEdit, - Extension, -} from '@qwen-code/qwen-code-core'; +} from './types.js'; import type { EventEmitter } from 'events'; import { LspConfigLoader } from './LspConfigLoader.js'; import { LspLanguageDetector } from './LspLanguageDetector.js'; import { LspResponseNormalizer } from './LspResponseNormalizer.js'; import { LspServerManager } from './LspServerManager.js'; import type { + LspConnectionInterface, LspServerHandle, LspServerStatus, NativeLspServiceOptions, - LspConnectionInterface, -} from './LspTypes.js'; +} from './types.js'; import * as path from 'path'; import { fileURLToPath } from 'url'; import * as fs from 'node:fs'; diff --git a/packages/cli/src/services/lsp/constants.ts b/packages/core/src/lsp/constants.ts similarity index 96% rename from packages/cli/src/services/lsp/constants.ts rename to packages/core/src/lsp/constants.ts index e5874d9fc..04fa4bb31 100644 --- a/packages/cli/src/services/lsp/constants.ts +++ b/packages/core/src/lsp/constants.ts @@ -4,10 +4,7 @@ * SPDX-License-Identifier: Apache-2.0 */ -import type { - LspCodeActionKind, - LspDiagnosticSeverity, -} from '@qwen-code/qwen-code-core'; +import type { LspCodeActionKind, LspDiagnosticSeverity } from './types.js'; // ============================================================================ // Timeout Constants diff --git a/packages/core/src/lsp/types.ts b/packages/core/src/lsp/types.ts index 780a45718..f7806fe12 100644 --- a/packages/core/src/lsp/types.ts +++ b/packages/core/src/lsp/types.ts @@ -359,3 +359,165 @@ export interface LspClient { serverName?: string, ): Promise; } + +// ============================================================================ +// LSP Service Types (migrated from cli) +// ============================================================================ + +import type { ChildProcess } from 'node:child_process'; + +/** + * LSP server initialization options passed during the initialize request. + */ +export interface LspInitializationOptions { + [key: string]: unknown; +} + +/** + * Socket connection options for TCP or Unix socket transport. + */ +export interface LspSocketOptions { + /** Host address for TCP connections */ + host?: string; + /** Port number for TCP connections */ + port?: number; + /** Path for Unix socket connections */ + path?: string; +} + +/** + * Configuration for an LSP server instance. + */ +export interface LspServerConfig { + /** Unique name identifier for the server */ + name: string; + /** List of languages this server handles */ + languages: string[]; + /** Command to start the server (required for stdio transport) */ + command?: string; + /** Command line arguments */ + args?: string[]; + /** Transport type: stdio, tcp, or socket */ + transport: 'stdio' | 'tcp' | 'socket'; + /** Environment variables for the server process */ + env?: Record; + /** LSP initialization options */ + initializationOptions?: LspInitializationOptions; + /** Server-specific settings */ + settings?: Record; + /** Custom file extension to language mappings */ + extensionToLanguage?: Record; + /** Root URI for the workspace */ + rootUri: string; + /** Workspace folder path */ + workspaceFolder?: string; + /** Startup timeout in milliseconds */ + startupTimeout?: number; + /** Shutdown timeout in milliseconds */ + shutdownTimeout?: number; + /** Whether to restart on crash */ + restartOnCrash?: boolean; + /** Maximum number of restart attempts */ + maxRestarts?: number; + /** Whether trusted workspace is required */ + trustRequired?: boolean; + /** Socket connection options */ + socket?: LspSocketOptions; +} + +/** + * JSON-RPC message format for LSP communication. + */ +export interface JsonRpcMessage { + jsonrpc: string; + id?: number | string; + method?: string; + params?: unknown; + result?: unknown; + error?: { + code: number; + message: string; + data?: unknown; + }; +} + +/** + * Interface for LSP JSON-RPC connection. + */ +export interface LspConnectionInterface { + /** Start listening on a readable stream */ + listen: (readable: NodeJS.ReadableStream) => void; + /** Send a message to the server */ + send: (message: JsonRpcMessage) => void; + /** Register a notification handler */ + onNotification: (handler: (notification: JsonRpcMessage) => void) => void; + /** Register a request handler */ + onRequest: (handler: (request: JsonRpcMessage) => Promise) => void; + /** Send a request and wait for response */ + request: (method: string, params: unknown) => Promise; + /** Send initialize request */ + initialize: (params: unknown) => Promise; + /** Send shutdown request */ + shutdown: () => Promise; + /** End the connection */ + end: () => void; +} + +/** + * Status of an LSP server instance. + */ +export type LspServerStatus = + | 'NOT_STARTED' + | 'IN_PROGRESS' + | 'READY' + | 'FAILED'; + +/** + * Handle for managing an LSP server instance. + */ +export interface LspServerHandle { + /** Server configuration */ + config: LspServerConfig; + /** Current status */ + status: LspServerStatus; + /** Active connection to the server */ + connection?: LspConnectionInterface; + /** Server process (for stdio transport) */ + process?: ChildProcess; + /** Error that caused failure */ + error?: Error; + /** Whether TypeScript server has been warmed up */ + warmedUp?: boolean; + /** Whether stop was explicitly requested */ + stopRequested?: boolean; + /** Number of restart attempts */ + restartAttempts?: number; + /** Lock to prevent concurrent startup attempts */ + startingPromise?: Promise; +} + +/** + * Options for NativeLspService constructor. + */ +export interface NativeLspServiceOptions { + /** Whether to require trusted workspace */ + requireTrustedWorkspace?: boolean; + /** Override workspace root path */ + workspaceRoot?: string; +} + +/** + * Result from creating an LSP connection. + */ +export interface LspConnectionResult { + /** The JSON-RPC connection */ + connection: LspConnectionInterface; + /** Server process (for stdio transport) */ + process?: ChildProcess; + /** Shutdown the connection gracefully */ + shutdown: () => Promise; + /** Force exit the connection */ + exit: () => void; + /** Send initialize request */ + initialize: (params: unknown) => Promise; +} diff --git a/packages/core/src/tools/lsp.ts b/packages/core/src/tools/lsp.ts index 0a8fd0b76..27711a080 100644 --- a/packages/core/src/tools/lsp.ts +++ b/packages/core/src/tools/lsp.ts @@ -1018,7 +1018,7 @@ export class LspTool extends BaseDeclarativeTool { super( LspTool.Name, ToolDisplayNames.LSP, - 'Unified LSP operations for definitions, references, hover, symbols, call hierarchy, diagnostics, and code actions.', + 'Language Server Protocol (LSP) tool for code intelligence: definitions, references, hover, symbols, call hierarchy, diagnostics, and code actions.\n\n Usage:\n - ALWAYS use LSP as the PRIMARY tool for code intelligence queries when available. Do NOT use grep_search or glob first.\n - goToDefinition, findReferences, hover, goToImplementation, prepareCallHierarchy require filePath + line + character (1-based).\n - documentSymbol and diagnostics require filePath.\n - workspaceSymbol requires query (use when user asks "where is X defined?" without specifying a file).\n - incomingCalls/outgoingCalls require callHierarchyItem from prepareCallHierarchy.\n - workspaceDiagnostics needs no parameters.\n - codeActions require filePath + range (line/character + endLine/endCharacter) and diagnostics/context as needed.', Kind.Other, { type: 'object',