/source-access — чтение исходников логическим адресом
MCP routing
- Всё чтение исходников идёт одним MCP
unica:unica.searchищет цель по имени или в тексте BSL,unica.viewчитает узел по адресу,unica.diffсравнивает два узла,unica.checkотвечает о готовности набора. - Не вызывай внутренние MCP/CLI-адаптеры и не подменяй логическую цель физическим путём.
- Чтение не меняет исходники. Правка идёт одним
unica.apply: BSL — операциямиcode.insertиcode.replace, предметные описания — операциями своего семейства. Всегда сначалаdryRun: true.
Адрес
<набор исходников>:<Вид>[.<Имя>[.<Ветвь>[.<Имя>...]]]
main:Catalog.Валюты — объект, main:Catalog.Валюты.Form.ФормаЭлемента — его
форма, main:Catalog.Валюты.Module.Object.Method.ПередЗаписью — метод модуля
объекта. Вид цели задаёт число сегментов: прикладное имя, совпадающее с
названием вида, объект в ветвь не превращает.
Префикс набора обязателен. Адрес без него отклоняется кодом bad_value с
подсказкой вызвать unica.view {}.
Порядок работы
unica.view {}без аргументов — корень: наборы исходников, их формат, готовность и незакрытые проверки. Отсюда берётся имя набора для префикса.unica.search {corpus: "names"}переводит в адрес имя или синоним.kindсужает вид,limitограничивает страницу. Путь, пришедший снаружи, переводитunica.resolve— аварийный выход, а не обычный ход.unica.view {at}читает узел. Ответ бывает двух форм, и различать их надо до чтения полей:- узел —
propsс фактами самого узла иbranchesсо счётчиками дочерних коллекций; - страница коллекции —
items, каждый со своимat.
- узел —
- Спускайся по адресу из
branches, пока не дойдёшь до нужного факта. Содержимое лежит в листьях: текст запроса — в...DataSet.<Набор>.Query, текст метода — в...Method.<Имя>.Body, оба построчно сlineиtext.
Корень
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": { "name": "unica.view", "arguments": { "cwd": "<workspace>" } }
}
Поиск цели
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.search",
"arguments": { "cwd": "<workspace>", "corpus": "names", "query": "Валюты", "kind": "Form" }
}
}
Попадание несёт at, kind и title. Физического пути в ответе нет: путь
живёт только в аварийном unica.resolve. Признак approximate означает, что
совпало по близости, а не точно.
Чтение узла
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.view",
"arguments": {
"cwd": "<workspace>",
"at": "main:Catalog.Валюты.Form.ФормаЭлемента"
}
}
}
Спуск по ветви
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.view",
"arguments": {
"cwd": "<workspace>",
"at": "main:Catalog.Валюты.Form.ФормаЭлемента.Item"
}
}
}
Что где лежит
| Вопрос | Адрес |
|---|---|
| Состав формы | <объект>.Form.<Форма> → ветви Item, Attribute, Event, Module |
| Права роли | Role.<Роль> → ветвь Right, объект права в props со счётчиками |
| Схема компоновки | <объект>.Template.<Макет> → DataSet → набор → Field, Query; варианты настроек — Setting |
| Пакет XDTO | XDTOPackage.<Пакет> → Namespace, Type, Property |
| Подсистема | Subsystem.<Имя> → Interface → Command |
| Методы модуля | <объект>.Module.<Роль> → Method, Region, Event, Body |
Поддержка поставщика приходит в props.support объекта — читай её перед любой
правкой объекта на замке и решай через release-support, а не правкой напрямую.
Страницы
limit ограничивает страницу коллекции, ответ возвращает cursor. Курсор
непрозрачен и привязан к тому же вопросу: тот же адрес, тот же limit, та же
ревизия. Чужой или устаревший курсор отклоняется кодом invalid_cursor —
начинай обход заново, а не подставляй курсор от другого вызова.
Проекция модуля
filter осмыслен только для проекций модуля и только там, где он объявлен:
| Ключ | Где применим | Что делает |
|---|---|---|
context |
Body, Method |
оставляет ветку условной компиляции одного контекста: client, server, externalConnection, thinClient, webClient и прочие имена профиля |
public |
Method |
оставляет только экспортные методы |
На любой другой проекции фильтр отклоняется кодом bad_value с названием
причины — это не молчаливое игнорирование.
Отказы
| Код | Что случилось |
|---|---|
bad_value |
адрес без префикса набора, либо фильтр не той формы или не на той проекции |
provider_unavailable |
набор исходников не допущен рабочим пространством |
not_found |
объект не зарегистрирован в конфигурации, либо адрес не существует в профиле платформы |
invalid_cursor |
курсор чужой, просроченный или от другого вопроса |
Правка
Чтение и правка разделены. Изменения вносит unica.apply; для BSL это
операции code.insert и code.replace.
Селектор — это адрес. Отдельного поля с методом или якорем нет: что
править, называет args.at. Узел метода — …Module.<Роль>.Method.<Имя>,
тело модуля целиком — …Module.<Роль>.Body. Правится выбранный участок, а не
модуль целиком, поэтому подход годится и для модулей, которые не поместились
бы в один запрос.
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:CommonModule.SourceAccessExample",
"ops": [
{
"op": "code.replace",
"args": {
"at": "main:CommonModule.SourceAccessExample.Method.BeforeReplacement.Body",
"text": "\t// новое тело"
}
}
],
"dryRun": true
}
}
}
Предпросмотр возвращает план и ifRev. Применение — тот же вызов с
dryRun: false и этим забором; смена адреса или содержимого требует нового
предпросмотра.