---
name: 1c-change-package
description: Пакет ручного внесения правок - по двум версиям модулей 1С строит инструкцию для Конфигуратора (что найти и на что заменить целиком). Нужен когда править исходники нельзя: объект на поддержке без права изменения, модуль занят другим пользователем в хранилище, доступен только Конфигуратор
argument-hint: -Before <файл|каталог> -After <файл|каталог> [-OutFile <пакет.md>]
allowed-tools:
  - Bash
  - Read
  - Glob
---

# /change-package - пакет ручного внесения изменений

Берет две версии модулей - до и после - и превращает разницу в инструкцию, которую человек
выполняет в Конфигураторе: по каждому методу что найти и на что заменить целиком.

Правка при этом делается уже в базе, а не в исходниках. Навык не открывает платформу, не
запускает базу и ничего не меняет ни в одной из версий: он только читает файлы и пишет markdown.

## Когда применять

- объект на поддержке с запретом изменения - исходники недоступны на запись;
- модуль захвачен другим пользователем в хранилище конфигурации;
- форма обычная (не управляемая): в исходниках ей соответствует `.form`, а не `.xml`, и собирается
  она только Конфигуратором;
- у пользователя есть база и Конфигуратор, но нет доступа к выгрузке исходников;
- правку выполняет человек: агент готовит текст, но не применяет его.

## Когда не применять

| Ситуация | Чем решать |
|----------|------------|
| Право правки исходников есть | обычная правка модуля: `1c-meta-edit`, `1c-form-edit` или редактор |
| Доработку типовой оформляют расширением | `1c-cfe-init`, `1c-cfe-borrow`, `1c-cfe-patch-method` |
| Нужно сравнить конфигурацию с расширением | `1c-cfe-diff` |
| Нужен построчный diff для чтения человеком | `git diff` или diff-инструмент, разбор по методам не нужен |
| Правка уже сделана в исходниках | ничего: база обновляется загрузкой выгрузки |

Пакет - обходной путь. Он имеет смысл, только когда исходники недоступны; в остальных случаях
правка исходников дешевле и не требует ручной работы.

## Параметры

| Параметр | Обяз. | Описание |
|----------|:-----:|----------|
| `-Before` | да | Файл или каталог до правки |
| `-After` | да | Файл или каталог после правки |
| `-OutFile` | нет | Куда записать пакет. Без него пакет печатается в stdout |

`-Before` и `-After` должны быть однотипными: либо два файла, либо два каталога. Каталоги
сверяются как выгрузки конфигурации (`Catalogs/Товары/Ext/ObjectModule.bsl`) и сопоставляются по
относительному пути; сравниваются только модули `.bsl`, остальные различия попадают в список для
ручной правки.

Тип объекта и вид модуля берутся из пути, поэтому подписи в пакете зависят от раскладки выгрузки:
`Catalogs/Товары/Ext/ObjectModule.bsl` дает "Справочник Товары, модуль объекта". Незнакомый каталог
или незнакомое имя файла оставляют в заголовке только путь - разбор методов от этого не страдает.

## Команда

```powershell
powershell.exe -NoProfile -File "skills/1c-change-package/scripts/change-package.ps1" -Before "src-old" -After "src-new" -OutFile "package.md"
```

```bash
python skills/1c-change-package/scripts/change-package.py -Before src-old -After src-new -OutFile package.md
```

Оба порта дают байт-в-байт одинаковый пакет: UTF-8 без BOM, перевод строки LF. Это закреплено
кейсами, поэтому пакет можно передавать человеку независимо от того, чем он собран.

## Что в пакете

| Место в файле | Что там |
|---------------|---------|
| Шапка | Пути, счетчики: модулей с правками, методов изменено, добавлено, удалено, правок вне методов |
| `## <путь> - <объект>` | Раздел модуля. Один пункт - одно действие |
| `### Изменить метод <Имя>` | Блоки `Найти:` и `Заменить целиком на:` с текстом метода |
| `### Добавить метод <Имя> после метода <Соседний>` | Блок `Текст метода:` |
| `### Удалить метод <Имя>` | Блок `Удалить целиком:` |
| `### Изменить код вне методов` | Блоки `Найти:` и `Заменить целиком на:` для переменных модуля и основного кода |
| `## Файлы для правки вручную` | Файлы, которые не `.bsl`, а также новые и удаленные файлы |

Метод отдается целиком, вместе с директивой компиляции и комментарием перед объявлением: замена
идет по методу, а не по отдельной строке. Поиск в Конфигураторе ведется по блоку `Найти:` - он
начинается с объявления метода, и в большинстве модулей такой фрагмент единственный.

Порядок пунктов повторяет порядок методов в новой версии, поэтому пакет можно выполнять сверху
вниз, не возвращаясь назад.

## Ограничения разбора

Навык разбирает модуль по объявлениям методов и не анализирует код внутри. Отсюда следствия,
которые важно понимать, прежде чем отдавать пакет человеку:

- переименование метода выглядит как удаление одного и добавление другого, а не как правка;
- правка внутри метода показывается заменой метода целиком, даже если изменилась одна строка:
  это осознанно - такую замену механически выполняет и человек, и сама платформа;
- директива компиляции попадает в тот метод, объявление которого идет следом: строка примыкает
  к объявлению, поэтому показывается вместе с методом, а не в блоке вне методов;
- разбор идет по ключевым словам обоих написаний, русского и английского: модуль на английском
  BSL разбирается так же, как русский.

Пакет не проверяет, что правка применится к той версии модуля, которая лежит в базе: сверять
блок `Найти:` с фактическим текстом модуля - дело того, кто выполняет правку.

## Проверка на реальных данных

Ручную приемку делает человек: пакет строится по файлам, а применяется в Конфигураторе. Перед
выдачей пакета убедиться, что версия `-Before` совпадает с модулем в базе - иначе блок `Найти:`
не будет найден.

## Связанные навыки

- `1c-cfe-diff` - сравнение конфигурации с расширением: показывает, что уже перенесено
- `1c-cfe-patch-method` - перехват метода расширением, когда исходники менять не нужно
- `1c-config-index` - индекс выгрузки: пути модулей и имена объектов
