Серверы и плагины
Сервер LSP для редакторов, сервер MCP для агентов, локальная веб-панель и плагины со своими правилами, данными и уровнями.
Движок один, дотянуться до него можно по-разному: резидентный сервер для редактора, набор инструментов для агента, страница в браузере – и способ расширить всё это разом.
LSP-сервер
xbsl-lsp (extra [lsp]: pip install "xbsl[lsp]") запускает линтер долгоживущим
Language Server по stdio: живые пофайловые диагностики при наборе, проектные – по сохранению,
переход к определению, автодополнение и hover по резидентному индексу проекта, quick-fix-правки –
без платы за старт интерпретатора на каждый вызов. Флаги: --project-root (корень исходников
относительно папки воркспейса), --select/--ignore/--enable, --data-dir, --baseline,
--templates. Подойдёт любому редактору с LSP (VS Code, Neovim, JetBrains).
Всё, что редактору нужно для кода, – стандартный LSP, так что обычный клиент работает без
дополнительной обвязки. Сверх этого сервер отвечает на приватные запросы xbsl/* – на них
построены панели расширения VS Code, и по ним же панели можно повторить в другом редакторе:
| Группа | Запросы |
|---|---|
| Диагностики и подсказки | xbsl/relint, xbsl/hoverDoc, xbsl/templatesReload |
| Документация платформы | xbsl/docsAvailable, xbsl/docsSearch, xbsl/docsPage, xbsl/docsTree, xbsl/docsAsset, xbsl/docsForSymbol, xbsl/docsByName |
| Схемы и словари | xbsl/uiSchema, xbsl/metadataSchema, xbsl/formKeys, xbsl/metaKeys, xbsl/metaCapabilities, xbsl/httpMethods |
| Создание метаданных | xbsl/objectInfo, xbsl/metaNewObject, xbsl/metaAddField, xbsl/metaSetFieldProperty, xbsl/metaAddForm, xbsl/metaAddRoute, xbsl/metaAddSubsystem, xbsl/metaAddLocalization, xbsl/localizationInfo |
| Формы | xbsl/formTree, xbsl/formNodeAt, xbsl/formEdit, xbsl/searchForms, xbsl/bindingComplete |
| Обработчики событий | xbsl/moduleHandlers, xbsl/addHandler, xbsl/addModuleMethod, xbsl/removeHandler |
Запрос на создание метаданных возвращает план – полный текст каждого файла, который был бы записан, – а
редактор применяет его одной отменяемой правкой; сам сервер не пишет ничего (CLI и MCP-сервер на
том же коде – пишут). xbsl/metaCapabilities отвечает версией сервера и наборами видов, которые
он умеет создавать: объектов, элементов разделов, форм – по ним клиент строит меню от живого
движка, а не от жёстко зашитого списка.
MCP-сервер
Тонкий адаптер над тем же ядром – агент (напр. Claude Code) зовёт проверки как инструменты и получает структурированные диагностики.
pip install -e ".[mcp]"
claude mcp add xbsl -- xbsl-mcp
Каждый пишущий meta_* применяет изменения и в том же ответе возвращает линт записанных
файлов – создание и проверка за один вызов. Ядро и CLI зависимости mcp не требуют – она
только в extra [mcp].
У каждого инструмента meta_* и у lint_paths есть параметр root – корень проекта
вызывающего (агент в git worktree не делит рабочий каталог с сервером): относительные
directory, yaml_path, module_path, paths и baseline считаются от него, а ответ несёт
абсолютные пути (записанных файлов, находок) и поле root, от которого их считали. Без
параметра берётся рабочий каталог сервера, как раньше, – и относительный путь из worktree тогда
называет другой чекаут, чей чистый ответ выглядит как ваш.
Проверка и окружение
| Инструмент | Что делает |
|---|---|
lint_paths(paths, select, ignore, enable, baseline, no_baseline, root) |
проверить файлы и каталоги на диске (относительные пути – от root, сводка его называет); базлайн проекта .xbsllint-baseline применяется сам, как и в CLI (summary.baselined – сколько погашено, no_baseline – показать и замороженные); enable добавляет к умолчаниям правило, выключенное по умолчанию, – так проект спрашивает про пробелы словаря |
lint_source(filename, content, select, ignore) |
проверить содержимое в памяти, до записи файла |
list_rules() |
доступные здесь правила: id, заголовок, тир, область, severity |
version_info() |
чем отвечает окружение: движок, интерпретатор, версия данных, надстройки – различает два окружения, отвечающие на одном файле по-разному |
Документация платформы и схемы
| Инструмент | Что делает |
|---|---|
docs_search(query, limit) |
полнотекстовый поиск по документации 1С:Элемент |
docs_page(id, brief, section) |
страница документации по идентификатору из двух других инструментов; brief – одна шапка: краткое описание и имена разделов вместо текста, section – шапка плюс один раздел статьи (Свойства, Методы, Конструкторы, …; на неизвестный раздел ответ – перечень имён на выбор) |
docs_symbol(name, brief, section) |
страница символа по имени (тип или член), с теми же режимами brief и section |
type_members(name) |
члены stdlib-типа одним компактным ответом – что может стоять после точки; дешевле страницы, когда нужен только список членов |
ui_schema(component, brief, property) |
ui-схема компонента интерфейса: палитра конструктора и типизированные свойства |
metadata_schema(kind, sections, names) |
какие свойства вправе объявить элемент заданного ВидЭлемента |
Трём docs_* нужна база docs.sqlite (см. Поиск по документации), двум схемным – сгенерированные данные о языке. Страница типа – это тысячи знаков: конструкторы, каждое свойство, списки унаследованного, – поэтому статья целиком нужна, чтобы её читать: brief отвечает на вопрос “что это за страница и о чём она”, section – на один вопрос по ней.
Перевод исходников (см. Перевод проекта)
| Инструмент | Что делает |
|---|---|
translate_status(root) |
покрытие и остаток – дешёвая проверка перед любым решением; корень без словаря – отказ с перечнем мест поиска |
translate_gaps(root, kind, filter, limit, offset, compact) |
чего словарь ещё не покрывает, страницами: частота, первые места, собственное написание платформы подсказкой; compact оставляет в строке только ключ, вид и частоту; в ответе – прочитанный dictionary |
translate_entries(root, kind, filter, limit, offset) |
что словарь уже говорит, с файлом и строкой каждой записи |
translate_set(root, edits, edits_file, target, comment) |
запись: добавить, исправить на месте или снять, обнулив значение; edits_file – пачка файлом (yaml формата словаря либо список JSON), comment – заголовок, с которым создаётся новый файл словаря |
Все четыре отвечают СТРАНИЦАМИ поверх одного ядра движка, поэтому наполнение словаря на тысячи записей не требует вычитывать файлы.
Проект и его объекты
| Инструмент | Что делает |
|---|---|
meta_project_info(root) |
карта исходников под корнем: проекты, подсистемы, объекты по видам |
meta_object_info(root, name, yaml_path) |
описание одного объекта: всё, что нужно, чтобы писать его формы и код |
meta_new_project(...) |
создать проект: Проект.yaml, Проект.xbsl и первую подсистему |
meta_new_object(directory, kind, name, ...) |
создать объект: <Имя>.yaml и <Имя>.xbsl у видов с модулем |
meta_rename_object(..., dry_run) |
переименовать объект и обновить все ссылки в исходниках |
meta_delete_object(..., dry_run) |
удалить объект целиком: пару yaml/модуль и его формы |
meta_add_subsystem(parent_dir, name, ...) |
создать подсистему – папку с Подсистема.yaml |
meta_add_dependency(root, vendor, name, version, ...) |
подключить библиотеку – раздел Библиотеки в Проект.yaml |
meta_set_access(root, ..., default, permissions, calc_by) |
задать КонтрольДоступа.Разрешения у объекта |
Поля, маршруты, методы, формы, локализация
| Инструмент | Что делает |
|---|---|
meta_add_field(yaml_path, field_kind, name, type, props, ...) |
добавить элемент раздела: реквизит, измерение, ресурс, значение перечисления, параметр, поле, табличную часть. Стандартный реквизит (Номер, Дата, Код, Наименование, Владелец) судится своим классом: Длина, Уникальность и блок Автонумерация принимаются, type можно не указывать там, где класс его задаёт; props принимает вложенный блок словарём или ключом через точку (Автонумерация.Префикс) и список последовательностью; блок класса, которого метамодель не описывает (Представление), отвергается как известное ограничение; секция, которой в файле нет, заводится в конце файла, и у регистра notes говорят об этом и называют соседний вид, который положил бы элемент рядом с существующими полями (ресурс там, где просили реквизит, и наоборот) |
meta_set_field_property(yaml_path, field_kind, name, props, ...) |
задать свойства уже существующему элементу раздела; формы значений те же, что у meta_add_field, вложенный блок заменяется целиком |
meta_add_route(yaml_path, routes, template, methods) |
добавить HttpСервис шаблоны url и заготовки обработчиков |
meta_add_method(module_path, name, params, returns, ...) |
вставить метод в модуль .xbsl, не разрывая блоки аннотаций |
meta_add_form(root, ..., forms, card_min_width, card_placeholder) |
сгенерировать формы объекта и зарегистрировать их в Интерфейс |
meta_add_localization(yaml_path, language) |
добавить файл перевода элементу локализованных строк |
meta_localization_info(yaml_path) |
картина локализации: объявленные языки и что ещё не переведено |
Компоненты формы – конструктор из скрипта
| Инструмент | Что делает |
|---|---|
meta_component_tree(yaml_path, node_id, name, max_depth, properties) |
дерево узлов компонента интерфейса; большую форму можно брать частями – поддеревом (по идентификатору узла или по его Имя), с пределом глубины и без записей свойств |
meta_add_component(yaml_path, parent_id, slot, ...) |
вставить новый компонент в слот родительского узла |
meta_insert_fragment(yaml_path, parent_id, slot, fragment, ...) |
вставить в слот готовый блок yaml одного компонента (скопированное поддерево) |
meta_move_component(yaml_path, node_id, new_parent_id, slot, ...) |
перенести узел в другой (или тот же) слот; комментарии над ним едут следом |
meta_move_components(yaml_path, node_ids, ...) |
перенести несколько узлов одной операцией, сохранив их порядок в документе |
meta_remove_component(yaml_path, node_id) |
удалить узел вместе с его комментариями |
meta_remove_components(yaml_path, node_ids) |
удалить несколько узлов одной операцией |
meta_set_component_property(yaml_path, node_id, key, value, value_yaml) |
задать, заменить или удалить свойство узла |
meta_add_handler(yaml_path, node_id, key, method, signature) |
привязать событие узла к методу-обработчику парного модуля |
Те же операции доступны из CLI (Команды) и, для редактора, через LSP-запросы xbsl/meta*.
Веб-интерфейс
Локальная страница: указать папку проекта – увидеть замечания. Стандартная библиотека (без
внешних зависимостей), слушает только 127.0.0.1.
xbsl-web # затем открыть http://127.0.0.1:8771/
Настройки правил по тирам, выбор версии данных, фильтры по severity/тексту, тёмная/светлая тема;
клик по замечанию открывает файл в VS Code (vscode://).
Расширение: свои правила, данные и уровни
Три группы entry points позволяют отдельному пакету дополнить линтер, не форкая его. Это нужно
тем, чьи правила или языковые данные нельзя публиковать: их держат в закрытом пакете, который
зависит от xbsl.
# pyproject.toml вашего пакета
dependencies = ["xbsl>=0.16"]
[project.entry-points."xbsl.rules"]
мой-проект = "мой_проект.rules" # импорт модуля выполняет его декораторы @rule
[project.entry-points."xbsl.data"]
мой-проект = "мой_проект:data_root" # путь либо функция, возвращающая путь
[project.entry-points."xbsl.severity"]
мой-проект = "мой_проект:severity_overrides" # {id правила: "error"|"warning"|"info"|"off"}
Пакеты, объявившие группы под старым именем (xbsllint.rules/xbsllint.data/xbsllint.severity),
продолжают работать: легаси-группы сканируются вслед за новыми.
Словарь уровней (или функция без аргументов, возвращающая его) поднимает или понижает уровень
любого правила – встроенного или из плагина – для всех запусков этой установки: проект может
считать, например, style/abbreviation-case предупреждением, пока публичный дефолт остаётся
info. "off" убирает правило из набора по умолчанию (явный --select/--enable всё равно
включает его, с базовым уровнем).
Пакет установлен – и CLI, и MCP-сервер, и веб-панель видят все расширения: без ключей и файлов
настройки. Сбой точки расширения роняет запуск, а не печатает предупреждение: линтер, молча
потерявший правило, остаётся зелёным в CI и ничего не гарантирует; переопределение с неизвестным
id правила или уровнем падает по той же причине. XBSL_NO_PLUGINS=1 игнорирует все внешние
пакеты – только встроенные правила, вшитые данные и уровни по умолчанию.