cfe-borrow · diff
git:20260903.46cb3e6 to git:20260916.b3dfbcd
63 added, 165 removed. Audit A to A.
---
name: cfe-borrow
description: Заимствование объектов из конфигурации 1С в расширение (CFE). Используй когда нужно перехватить метод, изменить форму или добавить реквизит к существующему объекту конфигурации
argument-hint: -ExtensionPath <path> -ConfigPath <path> -Object "Catalog.Контрагенты.Form.ФормаЭлемента" -BorrowMainAttribute
allowed-tools:
- Bash
- Read
- Glob
---
# /cfe-borrow — Заимствование объектов из конфигурации
## MCP routing
- - Preferred path: use MCP `unica` tool `unica.cfe.borrow`; `unica` owns XML/JSON DSL work and refreshes related workspace caches after mutations.
- - Do not call internal MCP/CLI adapters directly. They are hidden behind `unica` and synchronized by the orchestrator.
- - Execution path: call MCP `unica` tool `unica.cfe.borrow`; skill-local operation scripts are not part of the workflow.
- - For mutating operations, pass `dryRun: false` only when the user explicitly requested the change; otherwise keep the default dry run.
-
- Заимствует объекты из основной конфигурации в расширение. Создаёт XML-файлы с `ObjectBelonging=Adopted` и `ExtendedConfigurationObject`, добавляет запись в ChildObjects расширения.
-
- ## Предусловие
-
- Расширение должно быть создано (`/cfe-init`) и содержать валидный `Configuration.xml`.
-
- ### Авто-определение ConfigPath
-
- Если пользователь не указал `-ConfigPath` — попробуй определить автоматически:
- 1. Используй `./v8project.yaml`.
- 2. Найди `source-set` с `type: CONFIGURATION`.
- 3. Используй его `path` как `-ConfigPath`.
- 4. Если source-set не найден — спроси путь у пользователя.
-
- ## Параметры
-
- | Параметр | Описание |
- |----------|----------|
- | `ExtensionPath` | Путь к каталогу расширения (обязат.) |
- | `ConfigPath` | Путь к конфигурации-источнику (обязат.) |
- | `Object` | Что заимствовать (обязат.), batch через `;;` |
- | `BorrowMainAttribute` | Заимствовать основной реквизит формы. Без параметра — не заимствует. `Form` — реквизиты, используемые на форме. `All` — все реквизиты объекта. Требует форму в -Object |
-
- ## Формат -Object
-
- - `Catalog.Контрагенты` — справочник
- - `CommonModule.РаботаСФайлами` — общий модуль
- - `Document.РеализацияТоваров` — документ
- - `Enum.ВидыОплат` — перечисление
- - `Catalog.Контрагенты.Form.ФормаЭлемента` — форма объекта (заимствование формы)
- - `Catalog.X ;; CommonModule.Y ;; Enum.Z` — несколько объектов
- Поддерживаются все 44 типа объектов конфигурации.
-
- ### Заимствование форм
-
- Формат `Тип.Имя.Form.ИмяФормы` заимствует форму конкретного объекта. Если родительский объект ещё не заимствован — он будет заимствован автоматически.
-
- Создаётся:
- 1. **Метаданные формы** — `Forms/ИмяФормы.xml` с `ObjectBelonging=Adopted`, `FormType=Managed`
- 2. **Form.xml** — `Forms/ИмяФормы/Ext/Form.xml` с копией исходной формы + `<BaseForm>` (начальное состояние)
- 3. **Module.bsl** — пустой файл `Forms/ИмяФормы/Ext/Form/Module.bsl`
- 4. **Регистрация** — `<Form>` в ChildObjects родительского объекта
-
- ### Заимствование основного реквизита формы (-BorrowMainAttribute)
-
- **Когда нужно**: пользователь хочет добавить новый реквизит в существующий объект конфигурации и вывести его на заимствованную форму. Без `-BorrowMainAttribute` форма заимствуется "пустой" — только визуальные элементы, без привязки к данным объекта. С `-BorrowMainAttribute` форма сохраняет привязки к реквизитам объекта (DataPath), что позволяет затем добавить на неё новые элементы через `/form-edit`.
-
- **Два режима**:
- - `Form` (по умолчанию) — заимствует только те реквизиты объекта, которые уже выведены на форму. Оптимальный выбор для большинства случаев
- - `All` — заимствует все реквизиты и табличные части объекта. Используй если планируешь выводить на форму реквизиты, которых на ней ещё нет
-
- **Типовой сценарий** (добавление реквизита + вывод на форму):
- 1. `/cfe-borrow` с `-BorrowMainAttribute` — заимствовать форму с реквизитами
- 2. `/meta-edit` — добавить новый реквизит в объект расширения
- 3. `/form-edit` — вывести реквизит на заимствованную форму
+ - **Канонической операции заимствования на поверхности нет.** Разбор трёх
+ ролей (`own`, `borrowed`, корень расширения), проекция в `props` и форма
+ будущей операции `object.borrow` держит отдельная
+ архитектурная записка Unica; до её решения поверхность заимствование не
+ пишет.
+ - Не зови внутренние адаптеры напрямую: они спрятаны за MCP `unica`.
+ - Готовность проверяет `unica.check`, результат читает `unica.view` по адресу.
- **Защита существующих данных**: если зависимый объект уже заимствован с содержимым (реквизитами, формами) — скрипт не перезаписывает его, а добавляет только недостающее.
+ Что делать сейчас: сформировать дескриптор заимствованного объекта по формату
+ ниже (`ObjectBelonging>Adopted` плюс `ExtendedConfigurationObject` с UUID
+ объекта родителя), зарегистрировать его в `ChildObjects` корня расширения,
+ затем проверить `unica.check` и прочитать `unica.view`. Признак заимствования —
+ именно `ExtendedConfigurationObject`: корень расширения тоже `Adopted`, и
+ читать его как заимствованный объект — дефект.
- ## MCP вызов
+ Если нужна операция — сообщи о пробеле контракта Unica MCP и сошлись на
+ записку.
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src/extensions/MyExtension",
- "ConfigPath": "src",
- "Object": "Catalog.Контрагенты.Form.ФормаЭлемента",
- "BorrowMainAttribute": "Form",
- "dryRun": false
- }
- }
- }
- ```
+ ## Примеры дескриптора
- ## Примеры
+ Ниже — то, что должен нести записанный дескриптор заимствованного объекта в
+ наборе расширения. UUID берётся из дескриптора того же объекта у родителя.
- ### Заимствовать один объект
+ ### Заимствованный объект метаданных
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src",
- "ConfigPath": "C:\\cfsrc\\erp",
- "Object": "Catalog.Контрагенты",
- "dryRun": false
- }
- }
- }
+ ```xml
+ <MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses" version="2.20">
+ <Catalog uuid="<uuid объекта в расширении>">
+ <InternalInfo/>
+ <Properties>
+ <ObjectBelonging>Adopted</ObjectBelonging>
+ <Name>Контрагенты</Name>
+ <Comment/>
+ <ExtendedConfigurationObject><uuid объекта у родителя></ExtendedConfigurationObject>
+ </Properties>
+ <ChildObjects/>
+ </Catalog>
+ </MetaDataObject>
```
- ### Заимствовать форму
+ Имя обязано совпадать с именем у родителя, а сам объект — быть зарегистрирован
+ в `ChildObjects` корня расширения.
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src",
- "ConfigPath": "C:\\cfsrc\\erp",
- "Object": "Catalog.Контрагенты.Form.ФормаЭлемента",
- "dryRun": false
- }
- }
- }
- ```
+ ### Заимствованный объект с перекрытым свойством
- ### Несколько объектов за раз
+ Перекрытия несёт `InternalInfo` списком, а не флагом. Префикс `xr` объявляется
+ на корне дескриптора — фрагмент ниже без этого объявления не разбирается:
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src",
- "ConfigPath": "C:\\cfsrc\\erp",
- "Object": "Catalog.Контрагенты ;; CommonModule.ОбщийМодуль ;; Enum.ВидыОплат",
- "dryRun": false
- }
- }
- }
+ ```xml
+ <MetaDataObject xmlns="http://v8.1c.ru/8.3/MDClasses"
+ xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" version="2.20">
+ <Catalog uuid="<uuid объекта в расширении>">
+ <InternalInfo>
+ <xr:PropertyState>
+ <xr:Property>Synonym</xr:Property>
+ <xr:State>Extended</xr:State>
+ </xr:PropertyState>
+ </InternalInfo>
+ <Properties>
+ <ObjectBelonging>Adopted</ObjectBelonging>
+ <Name>Контрагенты</Name>
+ <ExtendedConfigurationObject><uuid объекта у родителя></ExtendedConfigurationObject>
+ </Properties>
+ </Catalog>
+ </MetaDataObject>
```
- ### Заимствовать форму с основным реквизитом
+ Платформа объявляет на корне весь свой набор пространств имён; здесь показаны
+ только те два, без которых пример не читается.
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src",
- "ConfigPath": "C:\\cfsrc\\erp",
- "Object": "Catalog.Номенклатура.Form.ФормаЭлемента",
- "BorrowMainAttribute": true,
- "dryRun": false
- }
- }
- }
- ```
+ Платформенной улики на эту форму у объекта метаданных пока нет: её снимает
+ круговой путь из архитектурной записки Unica. Пока улики нет, считай
+ перекрытие непроверенным фактом и говори об этом в ответе.
- ### Заимствовать форму со всеми реквизитами объекта
+ ### Заимствованная форма
- ```json
- {
- "jsonrpc": "2.0",
- "method": "tools/call",
- "params": {
- "name": "unica.cfe.borrow",
- "arguments": {
- "cwd": "<workspace>",
- "ExtensionPath": "src",
- "ConfigPath": "C:\\cfsrc\\erp",
- "Object": "Catalog.Номенклатура.Form.ФормаЭлемента",
- "BorrowMainAttribute": "All",
- "dryRun": false
- }
- }
- }
- ```
+ Дескриптор формы устроен так же: `Adopted` плюс `ExtendedConfigurationObject`
+ формы родителя. Реквизиты и элементы формы заимствуются вместе с ней; выборочно
+ перенести часть реквизитов поверхность не умеет — это тот же пробел контракта.
## Верификация
Проверка расширения — `unica.check` на корне набора-расширения (`ext` — имя набора типа `EXTENSION` в `v8project.yaml`); валидатор `cfe` выбирается по виду набора, вердикт в `data.status`.
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.check",
"arguments": {
"at": "ext:Configuration"
}
}
}
```