Протокол языкового сервера (LSP)
VibeOS запускает полноценные языковые серверы — pyright, gopls, rust-analyzer,
typescript-language-server, clangd и ещё около 20 — в фоновых
подпроцессах и передаёт их семантическую диагностику в пост-записную
проверку lint, используемую write_file и patch. Когда агент
редактирует файл, он видит именно те ошибки, которые внёс этот
редакт — не только синтаксические ошибки, но и ошибки типов,
неопределённые имена, отсутствующие импорты и семантические проблемы
на уровне всего проекта, которые обнаруживает языковой сервер.
Это та же архитектура, которую используют лучшие агенты для написания кода. VibeOS поставляется самодостаточно: не требуется хост-редактор, не нужно устанавливать плагины или управлять отдельным демоном.
Когда запускается LSP
LSP привязан к обнаружению git-рабочей области. Когда рабочая директория агента (или редактируемый файл) находится внутри git-репозитория, LSP запускается для этой рабочей области. Если ни то, ни другое не находится в git-репозитории, LSP остаётся неактивным — полезно для шлюзов обмена сообщениями, где текущая рабочая директория — это домашняя директория пользователя и нет проекта для диагностики.
Проверка многоуровневая: сначала внутрипроцессная синтаксическая проверка (микросекунды), затем, если синтаксис чист, диагностика LSP. Нестабильный или отсутствующий языковой сервер никогда не может нарушить запись — любой путь сбоя LSP бесшумно возвращается к результату только синтаксической проверки.
Конкретно, при каждом успешном write_file или patch:
- VibeOS захватывает базовый уровень текущих диагностик для файла.
- Выполняет запись.
- Повторно опрашивает языковой сервер, отфильтровывает диагностики, которые уже были в базовом уровне, и показывает только новые.
Агент видит вывод, подобный этому:
{
"bytes_written": 42,
"dirs_created": false,
"lint": {"status": "ok", "output": ""},
"lsp_diagnostics": "LSP diagnostics introduced by this edit:\n<diagnostics file=\"/path/to/foo.py\">\nERROR [42:5] Cannot find name 'foo' [reportUndefinedVariable] (Pyright)\nERROR [50:1] Argument of type \"str\" is not assignable to \"int\" [reportArgumentType] (Pyright)\n</diagnostics>"
}
Поле lint содержит результат синтаксической проверки (внутрипроцессный разбор
за микросекунды через ast.parse, json.loads и т.д.); поле
lsp_diagnostics содержит семантическую диагностику от настоящего
языкового сервера. Два канала, независимые сигналы —
агент видит синтаксически чистый файл с семантическими проблемами как
lint: ok плюс заполненный lsp_diagnostics.
Поддерживаемые языки
| Язык | Сервер | Автоустановка |
|---|---|---|
| Python | pyright-langserver | npm |
| TypeScript / JavaScript / JSX / TSX | typescript-language-server | npm |
| Vue | @vue/language-server | npm |
| Svelte | svelte-language-server | npm |
| Astro | @astrojs/language-server | npm |
| Go | gopls | go install |
| Rust | rust-analyzer | вручную (rustup) |
| C / C++ | clangd | вручную (LLVM) |
| Bash / Zsh | bash-language-server | npm |
| YAML | yaml-language-server | npm |
| Lua | lua-language-server | вручную (релизы GitHub) |
| PHP | intelephense | npm |
| OCaml | ocaml-lsp | вручную (opam) |
| Dockerfile | dockerfile-language-server-nodejs | npm |
| Terraform | terraform-ls | вручную |
| Dart | dart language-server | вручную (dart sdk) |
| Haskell | haskell-language-server | вручную (ghcup) |
| Julia | julia + LanguageServer.jl | вручную |
| Clojure | clojure-lsp | вручную |
| Nix | nixd | вручную |
| Zig | zls | вручную |
| Gleam | gleam lsp | вручную (gleam install) |
| Elixir | elixir-ls | вручную |
| Prisma | prisma language-server | вручную |
| Kotlin | kotlin-language-server | вручную |
| Java | jdtls | вручную |
Для записей «вручную» установите сервер через соответствующий менеджер
инструментария для этого языка (rustup, ghcup, opam, brew,
…). VibeOS автоматически обнаруживает бинарный файл в PATH или в
<VIBEOS_HOME>/lsp/bin/.
Некоторые серверы устанавливаются вместе с зависимостью, которую npm
не подтягивает автоматически. Текущий случай — typescript-language-server,
который требует, чтобы SDK typescript был импортируем из того же
дерева node_modules — VibeOS устанавливает оба пакета вместе, когда вы
запускаете vibeos lsp install typescript или автоустановка срабатывает при первом
использовании.
CLI
vibeos lsp status # состояние службы + статус установки каждого сервера
vibeos lsp list # реестр, опционально --installed-only
vibeos lsp install <id> # немедленная установка одного сервера
vibeos lsp install-all # попробовать каждый сервер с известным рецептом
vibeos lsp restart # перезапустить работающие клиенты
vibeos lsp which <id> # вывести разрешённый путь к бинарному файлу
vibeos lsp status — лучшая отправная точка: он показывает, какие
языки будут получать семантическую диагностику сегодня, а для каких нужен
установленный бинарный файл.
Конфигурация
Настройки по умолчанию подходят для типичных конфигураций; ничего задавать не нужно, если бинарные файлы находятся в PATH.
# config.yaml
lsp:
# Главный переключатель. Отключение пропускает всю подсистему — никакие серверы
# не запускаются, фоновый цикл событий не работает.
enabled: true
# Как долго ждать диагностику после каждой записи.
wait_mode: document # "document" или "full"
wait_timeout: 5.0
# Как обрабатывать отсутствующие бинарные файлы серверов.
# auto — установить через npm/pip/go install в <VIBEOS_HOME>/lsp/bin
# manual — использовать только бинарные файлы, уже находящиеся в PATH
install_strategy: auto
# Переопределения для отдельных серверов (все опциональны).
servers:
pyright:
disabled: false
command: ["/abs/path/to/pyright-langserver", "--stdio"]
env: { PYRIGHT_LOG_LEVEL: "info" }
initialization_options:
python:
analysis:
typeCheckingMode: "strict"
typescript:
disabled: true # пропускать TS, даже если его расширения совпадают
Ключи для отдельных серверов
disabled: true— полностью пропустить этот сервер, даже если его расширения совпадают с файлом.command: [bin, ...args]— зафиксировать пользовательский путь к бинарному файлу. Обходит автоустановку.env: {KEY: value}— дополнительные переменные окружения, передаваемые запущенному процессу.initialization_options: {...}— объединяется с полезной нагрузкой LSPinitializationOptions, отправляемой в рукопожатииinitialize. Зависит от сервера; обратитесь к документации языкового сервера.
Места установки
Когда install_strategy: auto, VibeOS устанавливает бинарные файлы в
<VIBEOS_HOME>/lsp/bin/. Пакеты NPM размещаются в
<VIBEOS_HOME>/lsp/node_modules/ с символическими ссылками на бинарные файлы на уровень выше.
Бинарные файлы Go поступают из go install с GOBIN, указывающим на
промежуточную директорию.
Ничего никогда не устанавливается в /usr/local/, ~/.local/ или любое другое
общее место — промежуточная директория полностью принадлежит VibeOS и
удаляется при сбросе профиля.
Характеристики производительности
Серверы LSP лениво запускаются при первом использовании. Редактирование файла Python
в проекте, который никогда не видел трафика .py, запускает pyright;
запуск занимает 1-3 секунды для большинства серверов (rust-analyzer может занимать 10+
на холодном проекте). Последующие редактирования в той же рабочей области повторно используют
запущенный сервер.
Слой LSP добавляет несколько миллисекунд к чистым записям, когда диагностика
не выводится. Когда диагностика выводится, бюджет ожидания составляет wait_timeout секунд — обычно сервер отвечает за
десятки миллисекунд для pyright/tsserver и за несколько секунд для
rust-analyzer во время индексации.
Серверы остаются активными в течение всего времени жизни процесса VibeOS. Нет сборщика по таймауту бездействия — стоимость перезапуска индекса сервера при каждой записи была бы намного выше, чем удержание демона.
Отключение
Установите lsp.enabled: false в config.yaml, чтобы отключить всю
подсистему. Пост-записная проверка возвращается к внутрипроцессной синтаксической
проверке (ast.parse для Python, json.loads для JSON и т.д.), которая
поставляется без изменений из более ранних версий.
Чтобы отключить один язык без отключения всего слоя:
lsp:
servers:
rust-analyzer:
disabled: true
Устранение неполадок
vibeos lsp status показывает сервер как «отсутствующий»
Бинарный файл не находится в PATH и не находится в <VIBEOS_HOME>/lsp/bin/. Запустите
vibeos lsp install <server_id>`, чтобы попытаться выполнить автоустановку, или
установите бинарный файл вручную через обычный инструментарий языка.
Раздел Backend warnings в vibeos lsp status
Некоторые серверы поставляются как тонкие обёртки вокруг внешнего CLI для фактической
диагностики — они запускаются чисто и принимают запросы, но никогда не выдают
ошибки, когда отсутствует вспомогательный бинарный файл. Самый распространённый случай —
bash-language-server, который делегирует диагностику shellcheck.
Когда vibeos lsp status показывает раздел Backend warnings, установите
именованный инструмент через менеджер пакетов вашей ОС:
apt install shellcheck # Debian / Ubuntu
brew install shellcheck # macOS
scoop install shellcheck # Windows
То же предупреждение однократно записывается в журнал при запуске сервера в
~/.vibeos/logs/agent.log.
Сервер запускается, но никогда не возвращает диагностику
Проверьте ~/.vibeos/logs/agent.log на наличие записей [agent.lsp.client] —
туда попадают как stderr от языкового сервера, так и ошибки протокола.
Некоторым серверам (особенно rust-analyzer) необходимо завершить
индексацию всего проекта, прежде чем они выдадут диагностику для отдельных файлов; первое
редактирование после запуска сервера может завершиться без диагностики, а
последующие редактирования её подхватят.
Сервер упал
Упавший сервер добавляется в набор сломанных и не будет повторно запущен до конца
сессии. Запустите vibeos lsp restart, чтобы очистить набор;
следующее редактирование перезапустит его.
Редактирование файла вне git-репозитория
По замыслу, LSP работает только внутри git-репозитория. Если проект ещё не
инициализирован, запустите git init, чтобы включить диагностику LSP. В противном случае применяется
внутрипроцессная синтаксическая проверка.