code-search · git:20261016.114fbc9 · 2026-10-16 · sha256 ecfdc9744384c9df

code-search git:20261016.114fbc9A

Immutable. This exact content never changes and is served at /api/v1/blob/ecfdc9744384c9df.

---
name: code-search
description: "Поиск и исследование BSL-кода и точек входа 1С. Используй когда нужно найти реализацию, вызовы, обработчики, модули, поток выполнения или быстро разобраться в механизме конфигурации."
---

# Code Search

## MCP routing

- Preferred path: use MCP `unica` tools `unica.search`, `unica.view`, and and.
  `unica.check`.
- Не зови индекс кода, анализатор или пакетные адаптеры напрямую: они спрятаны
  за MCP `unica`.
- Имя набора исходников — не константа. Его называет `unica.view {}`;
  `"main"` в примерах ниже иллюстрация, а не умолчание. В адресе имя стоит до
  двоеточия: `main:Document.Заказ`.

## Tool choice

- MCP-first discipline: держись публичных `unica.*` до того, как спускаться к
  оболочке. К поиску по файлам переходи, только когда вызовы выше не закрыли
  пробел, и сообщай what was tried, если это важно для ответа.
- **Что искать** выбирает свод. `unica.search` с `corpus: "text"` (умолчание)
  ищет по тексту BSL. Локальное совпадение сохраняет `scope`, `line`, `column`
  и `snippet`; его `at` открывай напрямую в `unica.view`: это
  `…Method.<Имя>.Body#L<n>` внутри установленного метода либо
  `…Body#L<n>` вне метода. Номер строки абсолютный, от начала файла.
  Провайдерный результат тоже получает такой `at`, когда текущий исходник
  подтверждает его строки и фрагмент. Символьное имя от поставщика само
  по себе не доказывает границы метода. Если их установить нельзя,
  `limits` называет предел; адрес строки Body модуля не доказывает,
  что строка находится вне метода. Если текущий текст не подтверждает
  фрагмент поставщика, сохраняется исходное свидетельство с `limits`,
  без выдуманного адреса чтения.
  Совпадение без доказанного модуля (файл вне раскладки,
  незарегистрированный владелец) приходит без `at`, с причиной
  `unaddressed` и `fileId`. С `corpus: "names"` поиск по именам и синонимам
  отвечает `at`, `kind`, `title` объекта. Физического пути нет ни у одного свода.
- **Чем искать** выбирает `role` в текстовом своде: `lexical` совпадает
  буквально, `symbol` идёт по индексу символов, `semantic` — по смыслу. Без
  `role` Unica ищет литерал сама и провайдеров не поднимает.
- Если `symbol` завершён со `status: "empty"` и `searchComplete: true`,
  поставщик не нашёл символ. Это успешный пустой результат. Ожидание индекса
  с `dependencyPending` требует повторить тот же запрос; оно не доказывает
  отсутствия символа. `indexFreshness: "unknown"` сохраняет предел актуальности.
- `scope` сужает поиск до одного логического поддерева. У локального поиска
  по тексту и именам `limit` задаёт размер страницы (по умолчанию 20,
  максимум 50). Пока есть `cursor`, продолжай с теми же аргументами поиска.
  `page.stoppedBy: "complete"` означает конец полученного потока. Если прочитанный
  ответ изменился, курсор отвечает `stale_cursor`; начни поиск заново. Роли
  провайдеров дают страницы только внутри полученного окна: если секция
  сообщает `limitReached`, последняя страница не доказывает полноту поиска.
  При 200 полученных совпадениях попроси пользователя уточнить искомое, прежде
  чем искать снова; `scope` предлагай только для `lexical`, поскольку `symbol`
  и `semantic` пока не поддерживают ограничение логическим поддеревом.
  Меньшие пределы `bsl-analyzer` и RLM сохраняй как неполный результат, не
  называя запрос слишком широким только по этому признаку.
- Признак `approximate` у попадания по имени означает совпадение по близости,
  а не точное. Проверяй `sourceCoverage`: при `complete: false` часть
  дескрипторов не прочитана, `omitted` и `details` называют число и причину
  пропусков. Даже пустая выдача тогда не доказывает отсутствия объекта.
- **Читать узел** — `unica.view {at}`. У владельца есть ветвь `Module`, у
  модуля — `Method`, у метода — подпись, контекст компиляции, собственные
  строки и ветвь `Body` с исходным текстом метода. Это дешевле, чем читать модуль
  целиком, и точнее, чем догадываться по совпадению.
- **Граф вызовов** — ветви `Caller` и `Callee`, которые узел метода называет
  в `branches` без счёта. Читай их адресом ветви:
  `unica.view {at: "<метод>.Caller"}`. Секции `callGraph` у `view` нет.
  Ответ ветви называет состояние графа в `props.callGraph`: страница соседей
  приходит только при `ready`, а `indexing` просит повторить позже. Если
  анализатора нет, а установка может заказать его поставку, ветвь заказывает
  её этим же вызовом; при `delivery_in_progress` повтори тот же вызов.
  Иначе ответ — отказ `provider_absent` с полями движка в `data`: `tool`,
  `stage` и следующий шаг в сообщении. Передай пользователю этот шаг, не
  повторяя вызов.
- Профиль объекта метаданных — тот же `unica.view {at}`: состав, модули, права,
  подписки и функциональные опции лежат в его `props` и ветвях.
- Путь к файлу нужен только когда он пришёл снаружи — из диффа, лога сборки
  или трассы. Тогда его переводит в адрес аварийный `unica.resolve`. В обычном
  ходе работы он не нужен.

## Workflow

1. Разметь пространство: `unica.view {}` называет наборы исходников и их
   формат, когда набор или формат неясен.
2. Найди предмет по имени: `unica.search {corpus: "names"}` с необязательным
   `kind`. Точное имя объекта закрывает вопрос быстрее любого текстового
   поиска.
3. Прочти узел: `unica.view {at}`. Ветвь `Module` ведёт к модулям владельца,
   ветвь `Method` — к его методам; узел метода даёт подпись и строки.
4. Ищи по тексту то, что именем не находится: фрагменты запросов, строковые
   литералы, заголовки, нестандартные токены. `role` выбирай под вопрос.
5. Расширяй только после неудачи точного поиска: синонимы, деловые термины,
   префиксы общих модулей, заголовки команд форм.
6. К локальному `rg` спускайся только за файлами вне индекса Unica или когда
   попытки выше не закрыли пробел — и скажи, что было испробовано.
7. Разделяй объявление, вызов, обработчик и мёртвое совпадение. Поток по
   одному попаданию не выводится.
8. Отчитывайся логическими адресами и строками внутри узла, а не путями к
   файлам; приводи запрос, которым получено важное попадание.

## Common searches

- Object lifecycle: `ОбработкаПроведения`, `ПередЗаписью`, `ПриЗаписи`, `ПриСозданииНаСервере`.
- Managed form flow: command handler, server procedure, client wrapper, form attribute name.
- Integrations: HTTP service root URL, method name, header name, endpoint path, exchange plan node.
- BSP entry points: exported common-module procedure plus surrounding callers.

## MCP examples

```jsonc
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.view",
    "arguments": {}
  }
}
```

Объект по имени:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.search",
    "arguments": {
      "query": "Заказ",
      "corpus": "names",
      "kind": "Document",
      "limit": 20
    }
  }
}
```

Текст внутри поддерева:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.search",
    "arguments": {
      "query": "ОбработкаПроведения",
      "scope": "main:Configuration",
      "limit": 20
    }
  }
}
```

Символ по индексу — определения и ссылки по имени:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.search",
    "arguments": {
      "query": "ОбработкаПроведения",
      "role": "symbol",
      "limit": 25
    }
  }
}
```

Кто вызывает метод — ветвь графа:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.view",
    "arguments": { "at": "main:CommonModule.ПроведениеСервер.Method.ОбработкаПроведения.Caller" }
  }
}
```

Профиль объекта метаданных:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.view",
    "arguments": { "at": "main:Document.Заказ" }
  }
}
```

Метод целиком: подпись в узле, текст в ветви `Body`:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "name": "unica.view",
    "arguments": { "at": "main:CommonModule.Продажи.Method.ОбработкаПроведения" }
  }
}
```