Платформа отчитывается успехом и о расширении, которое не применит: отказ всплывает лениво, при первом вызове метода, записью в журнал регистрации. Теперь db-load-xml, db-load-git, db-load-cf и db-update после успешной операции с расширением спрашивают платформу явно и печатают предупреждение; код возврата операции не меняется — применение неприменимого расширения не разрушительно, платформа просто работает по оригиналу. Поднять код возврата может -StrictLog, он для регрессов и в инструкциях не значится. Проверка обязана быть ОТДЕЛЬНЫМ запуском платформы: в одной командной строке DESIGNER выполняет только последнюю пакетную команду, и дописанная проверка отменила бы саму загрузку (замер: /LoadConfigFromFiles + /CheckCanApply… → код 0, пустой лог, расширение в базе не изменилось). Об этом сказано в теле функции, чтобы «оптимизация» не вернула команды в одну строку. Выключатель: ключ -NoApplyCheck и настройка проекта extensionApplyCheck (ключ команды сильнее). В ветке ibcmd проверка идёт соседним 1cv8; если его рядом нет — одна строка [note], а не тишина. Общий блок (Invoke-ApplyCheck / Invoke-ApplyCheckReport / Get-ApplyCheckEnabled и их py-двойники) объявлен семьёй в check-inline-drift.mjs: разъехавшиеся копии означали бы, что один навык предупреждает, а соседний по той же операции молчит. db-load-cf получил недостающие копии Find-V8Project и ключ -StrictLog. Раннер: у фейковой платформы появился отдельный ответ на проверку (spec.check), выбираемый по составу аргументов, — иначе сценарий «загрузка прошла, проверка провалилась» невыразим. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QoAJmoNbgWKobA7JGgN5S3
12 KiB
name, description, argument-hint, allowed-tools
| name | description | argument-hint | allowed-tools | |||
|---|---|---|---|---|---|---|
| cfe-patch-method | Генерация и актуализация перехватчика метода в расширении 1С (CFE). Используй когда нужно перехватить метод заимствованного объекта — вставить код до, после, вместо оригинала, изменить его тело (ИзменениеИКонтроль) — или актуализировать перехватчик после изменения оригинала | -ExtensionPath <path> -ConfigPath <path> -ModulePath "Catalog.X.ObjectModule" -MethodName "ПриЗаписи" -InterceptorType Before |
|
/cfe-patch-method — Генерация перехватчика метода
Читает оригинал метода из конфигурации-источника и генерирует .bsl-перехватчик заимствованного объекта: с правильной директивой контекста, полной сигнатурой, обрамляющими инструкциями препроцессора и областями. Для ИзменениеИКонтроль копирует всё тело оригинала. Создаёт файл модуля, дописывает в существующий или актуализирует уже заимствованный метод.
Предусловие
Объект должен быть заимствован в расширение (/cfe-borrow). Нужен доступ к исходникам базовой конфигурации (-ConfigPath) — оттуда читается оригинал метода. NamePrefix берётся из Configuration.xml расширения.
Авто-определение ConfigPath
Если пользователь не указал -ConfigPath — попробуй определить автоматически:
- Прочитай
.v8-project.jsonиз корня проекта - Разреши целевую базу (по имени, ветке или
default— алгоритм из/db-list) - Если у базы есть поле
configSrc— используй как-ConfigPath - Если
configSrcнет — спроси у пользователя
Параметры
| Параметр | Описание | По умолчанию |
|---|---|---|
ExtensionPath |
Путь к расширению (обязат.) | — |
ConfigPath |
Путь к конфигурации-источнику | обязат., кроме случая, когда ModulePath — путь к файлу |
ModulePath |
Логическое имя (Тип.Имя.Модуль) или путь к файлу модуля .bsl |
обязат. для генерации |
MethodName |
Имя перехватываемого метода | обязат. для генерации |
InterceptorType |
Before / After / Instead / ModificationAndControl |
обязат. для генерации |
Check |
Проверить контролируемые методы на дрейф (только отчёт) | — |
Actualize |
Актуализировать дрейфнувшие контролируемые методы | — |
Формат ModulePath
| ModulePath | Файл |
|---|---|
Catalog.X.ObjectModule |
Catalogs/X/Ext/ObjectModule.bsl |
Catalog.X.ManagerModule |
Catalogs/X/Ext/ManagerModule.bsl |
Catalog.X.Form.Y |
Catalogs/X/Forms/Y/Ext/Form/Module.bsl |
CommonModule.X |
CommonModules/X/Ext/Module.bsl |
Document.X.ObjectModule |
Documents/X/Ext/ObjectModule.bsl |
Document.X.Form.Y |
Documents/X/Forms/Y/Ext/Form/Module.bsl |
Аналогично для Report, DataProcessor, InformationRegister и других типов.
Вместо логического имени в ModulePath можно передать путь к файлу модуля-источника .bsl — тогда -ConfigPath указывать не нужно (оригинал читается прямо из этого файла). Путь модуля расширения определяется от типовой папки в пути автоматически.
Типы перехвата
| InterceptorType | Декоратор | Назначение | Применим к |
|---|---|---|---|
Before |
&Перед |
Код до вызова оригинального метода | процедуры |
After |
&После |
Код после вызова оригинального метода | процедуры |
Instead |
&Вместо |
Замена метода; в теле — скаффолд ПродолжитьВызов(...) |
процедуры и функции |
ModificationAndControl |
&ИзменениеИКонтроль |
Копия тела оригинала для правки маркерами #Вставка/#Удаление |
процедуры и функции |
Маркеры #Вставка / #Удаление (для ModificationAndControl)
&ИзменениеИКонтроль вставляет в перехватчик копию тела оригинала. Дальше отредактируй тело под свою доработку, помечая каждое изменение — платформа так отличает твою правку от неизменного оригинала:
- Добавляешь код → оберни его
#Вставка…#КонецВставки. - Удаляешь код оригинала → оберни удаляемые строки
#Удаление…#КонецУдаления, но сами строки оставь между маркерами (платформа сверяет их с оригиналом). - Заменяешь →
#Удалениестарое#КонецУдалениясразу за ним#Вставкановое#КонецВставки.
Пример:
&ИзменениеИКонтроль("ПриЗаписи")
Процедура Расш_ПриЗаписи(Отказ)
СуммаДокумента = РассчитатьСумму();
#Вставка
// доработка: округляем
СуммаДокумента = Окр(СуммаДокумента, 2);
#КонецВставки
#Удаление
Записать();
#КонецУдаления
#Вставка
ЗаписатьСПроверкой(Отказ);
#КонецВставки
КонецПроцедуры
Правила:
- Маркеры — на отдельной строке с 0-й колонки (без отступа), даже внутри отступов и текста запроса (
|…). - Незамеченные (unmarked) строки должны совпадать с оригиналом дословно — это и есть «контроль». Дословно — включая комментарии, регистр и пробелы внутри строки (
Х = Х + 1≠Х=Х+1); свободны только отступ и пустые строки. Если оригинал в конфигурации-источнике изменится, unmarked-контекст разойдётся → метод потребует актуализации (см. ниже; проверить пачкой —-Check). - Меняешь только свои
#Вставка/#Удаление; чужой оригинал не трогай.
Актуализация
После изменения оригинала в конфигурации-источнике перехватчик &ИзменениеИКонтроль может рассинхронизироваться — unmarked-контекст разойдётся с новым оригиналом. Платформа при загрузке об этом молчит, поэтому актуализируй сам:
- Проверить —
-Check: отчёт по всем контролируемым методам расширения, ничего не пишет (exit 1, если есть дрейф или конфликт). - Актуализировать —
-Actualize: переносит правки (#Вставка/#Удаление) на новый оригинал по всему расширению. Сузить область:-ModulePath— один модуль,+ -MethodName— один метод. Для одного метода то же делает повторный вызов с-InterceptorType ModificationAndControl.
Статусы в выводе:
[АКТУАЛЕН]— оригинал не менялся, правок нет;[АКТУАЛИЗИРОВАН]— тело обновлено по новому оригиналу, правки сохранены (в выводе — сводка);[АКТУАЛИЗИРОВАН-ЧАСТИЧНО]— часть правок не удалось разместить (якорь изменился в новом оригинале). Они помечены// [РЕСИНК-КОНФЛИКТ]в модуле и не потеряны; путь к merge-воркспейсу — в выводе (начни сindex.md, дальше по каждому конфликту егоconflict.md, размести блоки вручную в.bslрасширения);[ПЕРЕНЕСЕНО В ОСНОВНУЮ]— правка уже есть в новом оригинале (вставленный код внесён вендором) или удаляемый блок уже вырезан. Правка неактуальна — убирается из тела, дублировать/конфликтовать не нужно. Если так со всеми правками метода — перехватчик можно удалить.-Checkэтим не роняетexit.
Повторный вызов Before/After/Instead для уже перехваченного метода дубль не создаёт ([ПРОПУЩЕН]).
-Check смотрит исходники. Вердикт платформы — уже после загрузки в базу: /db-cfe-admin check.
Команда
powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/cfe-patch-method.ps1" -ExtensionPath src\cfe\extname -ConfigPath src\cf -ModulePath "Catalog.Контрагенты.ObjectModule" -MethodName "ПриЗаписи" -InterceptorType Before
Примеры
# Код перед записью
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -ModulePath "Catalog.Контрагенты.ObjectModule" -MethodName "ПриЗаписи" -InterceptorType Before
# Перехват После на форме
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -ModulePath "Document.Заказ.Form.ФормаДокумента" -MethodName "ПослеЗаписиНаСервере" -InterceptorType After
# Замена функции (ПродолжитьВызов)
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -ModulePath "CommonModule.ОбщийМодуль" -MethodName "ПолучитьДанные" -InterceptorType Instead
# ИзменениеИКонтроль — копия тела для правки маркерами
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -ModulePath "Document.РеализацияТоваров.ObjectModule" -MethodName "ОбработкаПроведения" -InterceptorType ModificationAndControl
# ModulePath как путь к файлу модуля-источника (без -ConfigPath)
... -ExtensionPath src\cfe\extname -ModulePath "src\cf\CommonModules\ОбщийМодуль\Ext\Module.bsl" -MethodName "ПолучитьДанные" -InterceptorType Instead
# Проверить все контролируемые методы расширения на дрейф
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -Check
# Актуализировать дрейфнувшие контролируемые методы пачкой
... -ExtensionPath src\cfe\extname -ConfigPath src\cf -Actualize
Верификация
/cfe-validate <ExtensionPath> -ConfigPath <ConfigPath>