Skip to Content
Руководство для пользователей

Плагин-компаньон Qwen Code: Спецификация интерфейса

Последнее обновление: 15 сентября 2025 г.

В этом документе описан контракт для разработки плагина-компаньона, который включает режим IDE в Qwen Code. Для VS Code эти функции (нативное сравнение изменений, осведомлённость о контексте) предоставляются официальным расширением (marketplace ). Эта спецификация предназначена для контрибьюторов, которые хотят добавить аналогичный функционал в другие редакторы, такие как JetBrains IDEs, Sublime Text и т. д.

I. Интерфейс взаимодействия

Qwen Code и плагин IDE взаимодействуют через локальный канал связи.

1. Транспортный уровень: MCP поверх HTTP

Плагин ОБЯЗАН запускать локальный HTTP-сервер, реализующий Model Context Protocol (MCP).

  • Протокол: Сервер должен быть валидным MCP-сервером. При наличии рекомендуем использовать готовый MCP SDK для вашего языка программирования.
  • Эндпоинт: Сервер должен предоставлять один эндпоинт (например, /mcp) для всего MCP-взаимодействия.
  • Порт: Сервер ОБЯЗАН слушать динамически назначенный порт (т. е. использовать порт 0).

2. Механизм обнаружения: Lock-файл

Чтобы Qwen Code мог подключиться, ему необходимо узнать, какой порт использует ваш сервер. Плагин ОБЯЗАН обеспечить это, создав «lock-файл» и установив переменную окружения с номером порта.

  • Как CLI находит файл: CLI считывает порт из QWEN_CODE_IDE_SERVER_PORT, а затем читает ~/.qwen/ide/<PORT>.lock. (Для старых расширений предусмотрены устаревшие механизмы fallback; см. примечание ниже.)

  • Расположение файла: Файл должен создаваться в определённой директории: ~/.qwen/ide/. Ваш плагин обязан создавать эту директорию, если она не существует.

  • Соглашение об именовании: Имя файла критически важно и ОБЯЗАНО соответствовать шаблону: <PORT>.lock

    • <PORT>: Порт, который слушает ваш MCP-сервер.
  • Содержимое файла и валидация workspace: Файл ОБЯЗАН содержать JSON-объект следующей структуры:

    { "port": 12345, "workspacePath": "/path/to/project1:/path/to/project2", "authToken": "a-very-secret-token", "ppid": 1234, "ideName": "VS Code" }
    • port (number, required): Порт MCP-сервера.
    • workspacePath (string, required): Список путей ко всем открытым корневым директориям workspace, разделённых специфичным для ОС разделителем путей (: для Linux/macOS, ; для Windows). CLI использует этот путь, чтобы убедиться, что он запущен в той же папке проекта, которая открыта в IDE. Если текущая рабочая директория CLI не является поддиректорией workspacePath, соединение будет отклонено. Ваш плагин ОБЯЗАН предоставлять корректные абсолютные пути к корням открытых workspace.
    • authToken (string, required): Секретный токен для защиты соединения. CLI будет добавлять этот токен в заголовок Authorization: Bearer <token> ко всем запросам.
    • ppid (number, required): ID родительского процесса IDE.
    • ideName (string, required): Понятное пользователю название IDE (например, VS Code, JetBrains IDE).
  • Аутентификация: Для защиты соединения плагин ОБЯЗАН генерировать уникальный секретный токен и включать его в файл обнаружения. Затем CLI будет передавать этот токен в заголовке Authorization для всех запросов к MCP-серверу (например, Authorization: Bearer a-very-secret-token). Ваш сервер ОБЯЗАН проверять этот токен в каждом запросе и отклонять все неавторизованные запросы.

  • Переменные окружения (обязательно): Ваш плагин ОБЯЗАН устанавливать QWEN_CODE_IDE_SERVER_PORT во встроенном терминале, чтобы CLI мог найти правильный файл <PORT>.lock.

Примечание об устаревшем функционале: Для расширений версии старше v0.5.1 Qwen Code может использовать fallback-механизм и читать JSON-файлы в системной временной директории с именами qwen-code-ide-server-<PID>.json или qwen-code-ide-server-<PORT>.json. Новым интеграциям не следует полагаться на эти устаревшие файлы.

II. Интерфейс контекста

Для обеспечения осведомлённости о контексте плагин МОЖЕТ передавать CLI информацию в реальном времени о действиях пользователя в IDE.

Уведомление ide/contextUpdate

Плагин МОЖЕТ отправлять CLI уведомление  ide/contextUpdate при каждом изменении контекста пользователя.

  • События-триггеры: Это уведомление следует отправлять (рекомендуемый debounce — 50 мс) при:

    • открытии, закрытии или получении фокуса файлом.
    • изменении позиции курсора или выделении текста в активном файле.
  • Полезная нагрузка (IdeContext): Параметры уведомления ОБЯЗАНЫ представлять собой объект IdeContext:

    interface IdeContext { workspaceState?: { openFiles?: File[]; isTrusted?: boolean; }; } interface File { // Absolute path to the file path: string; // Last focused Unix timestamp (for ordering) timestamp: number; // True if this is the currently focused file isActive?: boolean; cursor?: { // 1-based line number line: number; // 1-based character number character: number; }; // The text currently selected by the user selectedText?: string; }

    Примечание: Список openFiles должен включать только файлы, существующие на диске. Виртуальные файлы (например, несохранённые файлы без пути, страницы настроек редактора) ОБЯЗАНЫ быть исключены.

Как CLI использует этот контекст

Получив объект IdeContext, CLI выполняет несколько шагов нормализации и усечения перед отправкой данных модели.

  • Порядок файлов: CLI использует поле timestamp для определения последних использованных файлов. Список openFiles сортируется на основе этого значения. Поэтому ваш плагин ОБЯЗАН предоставлять точную Unix-метку времени последнего получения фокуса файлом.
  • Активный файл: CLI считает «активным» только самый последний файл (после сортировки). Он проигнорирует флаг isActive у всех остальных файлов и очистит их поля cursor и selectedText. Вашему плагину следует сосредоточиться на установке isActive: true и предоставлении данных о курсоре/выделении только для файла, находящегося в фокусе.
  • Усечение: Для управления лимитами токенов CLI усекает как список файлов (до 10 файлов), так и selectedText (до 16 КБ).

Несмотря на то, что финальное усечение выполняет CLI, настоятельно рекомендуется, чтобы ваш плагин также ограничивал объём отправляемого контекста.

III. Интерфейс сравнения изменений (Diffing)

Для поддержки интерактивного изменения кода плагин МОЖЕТ предоставлять интерфейс сравнения изменений (diffing). Это позволяет CLI запрашивать у IDE открытие diff-представления, показывающего предлагаемые изменения в файле. Пользователь может просмотреть, отредактировать и в итоге принять или отклонить эти изменения непосредственно в IDE.

Инструмент openDiff

Плагин ОБЯЗАН зарегистрировать инструмент openDiff на своём MCP-сервере.

  • Описание: Этот инструмент предписывает IDE открыть изменяемое diff-представление для конкретного файла.

  • Запрос (OpenDiffRequest): Инструмент вызывается через запрос tools/call. Поле arguments в params запроса ОБЯЗАНО быть объектом OpenDiffRequest.

    interface OpenDiffRequest { // The absolute path to the file to be diffed. filePath: string; // The proposed new content for the file. newContent: string; }
  • Ответ (CallToolResult): Инструмент ОБЯЗАН немедленно вернуть CallToolResult для подтверждения запроса и отчёта об успешном открытии diff-представления.

    • При успехе: Если diff-представление успешно открыто, ответ ОБЯЗАН содержать пустое содержимое (т. е. content: []).
    • При ошибке: Если ошибка помешала открытию diff-представления, ответ ОБЯЗАН содержать isError: true и включать блок TextContent в массиве content с описанием ошибки.

    Фактический результат сравнения (принятие или отклонение) передаётся асинхронно через уведомления.

Инструмент closeDiff

Плагин ОБЯЗАН зарегистрировать инструмент closeDiff на своём MCP-сервере.

  • Описание: Этот инструмент предписывает IDE закрыть открытое diff-представление для конкретного файла.

  • Запрос (CloseDiffRequest): Инструмент вызывается через запрос tools/call. Поле arguments в params запроса ОБЯЗАНО быть объектом CloseDiffRequest.

    interface CloseDiffRequest { // The absolute path to the file whose diff view should be closed. filePath: string; }
  • Ответ (CallToolResult): Инструмент ОБЯЗАН вернуть CallToolResult.

    • При успехе: Если diff-представление успешно закрыто, ответ ОБЯЗАН включать один блок TextContent в массиве content, содержащий финальное содержимое файла перед закрытием.
    • При ошибке: Если ошибка помешала закрытию diff-представления, ответ ОБЯЗАН содержать isError: true и включать блок TextContent в массиве content с описанием ошибки.

Уведомление ide/diffAccepted

Когда пользователь принимает изменения в diff-представлении (например, нажимая кнопку «Apply» или «Save»), плагин ОБЯЗАН отправить CLI уведомление ide/diffAccepted.

  • Полезная нагрузка: Параметры уведомления ОБЯЗАНЫ включать путь к файлу и его финальное содержимое. Содержимое может отличаться от исходного newContent, если пользователь внёс ручные правки в diff-представлении.

    { // The absolute path to the file that was diffed. filePath: string; // The full content of the file after acceptance. content: string; }

Уведомление ide/diffRejected

Когда пользователь отклоняет изменения (например, закрывая diff-представление без принятия), плагин ОБЯЗАН отправить CLI уведомление ide/diffRejected.

  • Полезная нагрузка: Параметры уведомления ОБЯЗАНЫ включать путь к файлу отклонённого diff.

    { // The absolute path to the file that was diffed. filePath: string; }

IV. Интерфейс жизненного цикла

Плагин ОБЯЗАН корректно управлять своими ресурсами и файлом обнаружения в соответствии с жизненным циклом IDE.

  • При активации (запуск IDE/включение плагина):
    1. Запустить MCP-сервер.
    2. Создать файл обнаружения.
  • При деактивации (завершение работы IDE/отключение плагина):
    1. Остановить MCP-сервер.
    2. Удалить файл обнаружения.
Last updated on