code-patch · git:20261013.53203f6 · 2026-10-13 · sha256 01c892a91d418d2b
code-patch git:20261013.53203f6A
Immutable. This exact content never changes and is served at /api/v1/blob/01c892a91d418d2b.
---
name: code-patch
description: Точечно вставить или заменить BSL-код в логически адресованном модуле XML-выгрузки Configuration или Extension 1С. Используй для одной проверяемой операции insert или replace.
argument-hint: <at> <insert|replace> <text>
allowed-tools:
- Read
- Glob
---
# /code-patch — безопасная вставка и замена BSL
## MCP routing
- Preferred path: use MCP `unica` tool `unica.apply` с операциями
`code.insert` и `code.replace`.
- Do not call internal MCP/CLI adapters directly. They are hidden behind
`unica` and synchronized by the orchestrator.
- Сначала вызови `unica.apply` с `at` и `ops`: это план без записи.
Когда пользователь поручил внести эту правку, вызови `unica.apply` только
с `executionToken` из `data.executionToken` успешного плана.
`args.at` выбирает модуль или его содержимое. У объекта с несколькими модулями
роль входит в адрес: `…Module.Object`, тело модуля — `…Module.Object.Body`.
Общий модуль сам себе модуль: `CommonModule.<Имя>` и `CommonModule.<Имя>.Body`.
Для `code.insert` без `selector` допустим адрес модуля или его `.Body`:
текст добавляется в конец модуля, `position` не передаётся. Адрес метода
`…Method.<Имя>` или его `.Body` вставку не адресует. Для точечной вставки
передай адрес самого модуля, `selector` с одним `anchor` или `method` и
обязательный `position: "before" | "after"`. `method` выбирает метод целиком;
для вставки внутрь его тела нужен `anchor`, который однозначно находится
внутри одного метода. Совпадения вне методов не учитываются. `before` вставляет
текст перед первой строкой anchor, `after` — после его последней строки;
это границы строк, а не позиция подстроки. Вставка перед методом сохраняет
его аннотации вместе с исходным методом.
В тексте вставки отдели новый метод от соседнего пустой строкой.
Автоматическую расстановку этих разделителей текущая операция ещё не делает.
`code.replace` принимает адрес тела модуля, метода или тела метода, например
`CommonModule.<Имя>.Method.<Имя>.Body`. При таком адресе отдельный `selector`
не передаётся. Метод целиком заменяется только по адресу `…Method.<Имя>`:
`selector.method` у замены получает отказ `bad_value`, а `next` ведёт к адресу
метода. На адресе самого модуля замена принимает лишь `selector` с `anchor`.
Сначала проверь выбранный адрес чтением.
Чтобы выделить метод, замени по адресу `…Method.<Имя>` весь метод текстом
из него самого и новых helper-методов. Helpers встанут сразу после метода,
а повтор той же замены ничего не запишет. Имена helpers должны быть новыми
для модуля: метод, уже объявленный в модуле, вызывает отказ `bad_value`
до записи. Одноимённые методы в ветвях `#Если … #Иначе` внутри текста
замены или уже в модуле дубликатами не считаются.
Правится модуль существующего объекта метаданных в допущенном наборе
исходников формата платформы. Физический путь к `*Module.bsl` остаётся
внутренней деталью: наружу его отдаёт только аварийный `unica.resolve`, и в
обычном ходе работы он не нужен. Создать объект метаданных, удалить модуль
целиком, править EDT или внешние файлы, синхронизировать исходники с базой
этим путём нельзя.
Если правку нельзя выразить одной безопасной операцией, остановись: прочитай
предмет через `unica.view {at}` на узле модуля — ветвь `Method` перечисляет
методы, ветвь `Body` отдаёт строки парами `{line, text}` — и вернись с более
узкой операцией.
## Операции
| Операция | Что делает | `args` |
|---|---|---|
| `code.insert` | Добавляет текст в конец модуля или до/после выбранного места | `at`, `text`; для точечной вставки — `selector`, `position` |
| `code.replace` | Заменяет содержимое узла по адресу | `at`, `text` |
Несколько операций одного вызова применяются как одна правка: либо все, либо
ни одной.
У заимствованного объекта расширения запись BSL также подключает модуль:
недостающее состояние `PropertyState` добавляется в дескриптор той же
транзакцией. Предпросмотр показывает обе правки. Уже установленное состояние
сохраняется; несовместимое состояние вызывает отказ до записи. После
применения проверь расширение через `unica.check {at: "ext:Configuration"}`,
подставив имя своего набора исходников.
## Порядок
1. Найди адрес: `unica.search {corpus: "names"}` по имени объекта, затем
`unica.view {at}` вниз по ветвям `Module` и `Method`.
2. Прочти предмет: `unica.view {at}` на узле метода даёт подпись, контекст
компиляции и собственные строки.
3. Предпросмотр: `unica.apply` с `at` и `ops`. Ответ несёт план правки и
токен `data.executionToken`.
4. Применение: вызов только с `executionToken` из успешного плана.
Исполнитель использует сохранённую транзакцию и проверяет её входы.
После `stale_revision` получи новый план; изменение файла вне входов плана
не мешает исполнению.
5. Проверка: `unica.check {at}` на модуле. Новые находки важности `error`
блокируют.
## MCP examples
### Вставить строку внутрь обработчика
Сначала прочитай тело метода и убедись, что `// insertion point` однозначно
находится внутри одного метода; совпадение вне методов не мешает выбору.
Адрес и имена ниже иллюстративные; подставь адрес, полученный через `unica.view`.
```json
{
"at": "main:Catalog.Пример.Module.Object",
"ops": [
{
"op": "code.insert",
"args": {
"at": "main:Catalog.Пример.Module.Object",
"selector": {"anchor": "// insertion point"},
"position": "before",
"text": " Сообщить(\"Проверка вставки\");\n"
}
}
]
}
```
### Предпросмотр замены тела метода
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:CommonModule.Пример",
"ops": [
{
"op": "code.replace",
"args": {
"at": "main:CommonModule.Пример.Method.ОбработатьПример.Body",
"text": " Возврат Истина;"
}
}
]
}
}
}
```
### Исполнение сохранённого плана
Сначала получи план этого изменения. В примере метод `ОбработатьПример` ещё
отсутствует: перед вставкой проверь имена и выбери новое, если оно занято.
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:CommonModule.Пример",
"ops": [
{
"op": "code.insert",
"args": {
"at": "main:CommonModule.Пример.Body",
"text": "\nПроцедура ОбработатьПример() Экспорт\nКонецПроцедуры\n"
}
}
]
}
}
}
```
Для исполнения передай `data.executionToken` из этого успешного плана:
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"executionToken": "<data.executionToken из успешного плана>"
}
}
}
```