meta-edit · git:20261105.ea38c96 · 2026-11-05 · sha256 ae589277d339cfb8
meta-edit git:20261105.ea38c96A
Immutable. This exact content never changes and is served at /api/v1/blob/ae589277d339cfb8.
---
name: meta-edit
description: Типизированно изменить существующий объект метаданных 1С по логическому адресу одной транзакцией.
argument-hint: <at> <operations>
allowed-tools:
- Read
- Glob
---
# /unica:meta-edit — структурное редактирование метаданных
## MCP routing
- Preferred path: use MCP `unica` tool `unica.apply` с операциями изменения
объекта метаданных.
- Объект и его коллекции называет адрес: `main:Catalog.Валюты` — сам объект,
`main:Catalog.Валюты.Attribute` — его реквизиты. Физический путь остаётся
внутренней деталью; наружу его отдаёт только аварийный `unica.resolve`.
- Имя набора даёт `unica.view {}`, адрес по имени — `unica.search {corpus:
"names"}`. `"main"` ниже только пример.
- Сначала вызови `unica.apply` с `at` и `ops`: это план без записи.
Когда пользователь поручил внести эту правку, вызови `unica.apply` только
с `executionToken` из `data.executionToken` успешного плана.
- Операции одного вызова упорядочены: каждая видит результат предыдущих, и
публикуются они одной транзакцией — либо все, либо ни одной.
- Читай из ответа `changed`, `effects` по порядку операций и диагностики.
Ответ описывает правку семантическими `effects`, а не возвращает
полный XML объекта.
- Проверка поддержки поставщика выполняется внутри `unica`. Для закрытого
объекта используй путь расширения, а не прямую правку служебных файлов.
- Какие операции исполнимы на узле, объявляет сам узел: словарь `can`
приходит в каждом ответе `unica.view`, а подробный контракт одной
операции читается адресом `<узел>.Can.<операция>`. Отказ `fixCall` несёт
`next` к узлу, где операция исполнима: выполни его, а не подбирай аргументы.
## Операции
| Предмет | Операции |
|---|---|
| Свойства объекта | `props.set` |
| Реквизиты | `attribute.add`, `attribute.set`, `attribute.remove`, `attribute.copy` |
| Табличные части | `tabularSection.add`, `tabularSection.set`, `tabularSection.remove` |
| Измерения и ресурсы | `dimension.*`, `resource.*` |
| Значения перечисления | `enumValue.add`, `enumValue.set`, `enumValue.remove` |
| Графы журнала | `column.add`, `column.set`, `column.remove` |
| Макеты и команды | `template.*`, `command.*` |
| Предопределённые элементы | `predefinedItem.add`, `predefinedItem.set`, `predefinedItem.remove` |
| Ссылки наружу | `relation.add`, `relation.replace`, `relation.remove` |
| Состав плана обмена и авторегистрация | `content.set` |
| Встроенная справка | `help.create` |
| Объект целиком | `object.remove` |
Допустимые свойства, коллекции, виды типов и связей берутся из контракта
операции (`argsSchema` подробного `can`). Общие прикладные правила — в
[соглашениях по метаданным](../../references/platform/metadata-conventions.md).
`props.set` изменяет только строковый `Comment` у существующих
`CommonAttribute`, `FunctionalOptionsParameter`,
`SessionParameter`, `FilterCriterion`, `SettingsStorage`, `CommonCommand`,
`CommandGroup`, `CommonForm`, `CommonTemplate`, `CommonPicture`,
`IntegrationService`, `XDTOPackage`,
`Sequence` и `Style`. Для общей формы адресуй дескриптор
`main:CommonForm.<Имя>.Metadata`; остальные владельцы адресуются как
`main:<Вид>.<Имя>`. Например, `{"values":{"Comment":"Назначение параметра"}}`;
пустая строка очищает комментарий. Имя `comment` — допустимый псевдоним,
одновременно оба написания не передаются. Отсутствующий, неоднозначный
или составной `Comment` требует исправления исходного дескриптора.
У `FunctionalOption` тот же `props.set` поддерживает строковый `Comment`,
строковый `Location` и булев `PrivilegedGetMode`, в том числе в одном `values`.
`Location` должен быть непустой ссылкой на существующую константу, реквизит
или ресурс в том же наборе исходников. Стандартные реквизиты и измерения
не подходят для хранилища.
Изменение только `Comment` сохраняет остальные свойства без проверки хранилища;
при переданном `Location` или `PrivilegedGetMode` хранилище проверяется.
Пользуйся точным набором полей и псевдонимов из подробного `Can.props.set`.
У `WSReference` строковый `Comment`/`comment` изменяется независимо от состояния
`LocationURL`. В конфигурации можно также изменить существующий `LocationURL`
или его псевдоним `locationURL`, в том числе вместе с комментарием. Пустая
строка очищает переданное поле. Смешанная операция проверяет оба поля и
регистрацию WS-ссылки до публикации; WSDL и соседние файлы сохраняются.
В расширении доступен профиль только комментария.
У `StyleItem` строковый `Comment`/`comment` изменяется независимо от типа и
состояния Value. Для подтверждённого цвета подробный `Can.props.set` дополнительно
объявляет `Value`: `#RRGGBB` или поддержанный цвет web/style. `Value` и комментарий
можно передать вместе; изменение цвета сохраняет проверки Type, регистрации и
формата, а ошибка любого поля отменяет всю операцию. Font/Border и неподдержанный
Value не получают контракт записи цвета.
Для существующего `DocumentNumerator` операция `props.set` меняет
`NumberType`, `NumberLength`, `NumberAllowedLength`, `NumberPeriodicity`,
`CheckUnique` и строковый `Comment`/`comment`, в том числе в одном
`values`. Имя, UUID и ссылки документов сохраняются. Числовой номер
допускает до 38 разрядов; сочетание типа и длины проверяется после всех
операций пакета. Перенумерация данных информационной базы не выполняется.
У `Language.<Имя>` обычной конфигурации `props.set` меняет строковый
`Comment`/`comment` и `LanguageCode`, в том числе в одном `values`.
`LanguageCode` меняется только у дополнительного языка. Пользовательские коды
допустимы; список ISO не ограничивает контракт. Смена требует отсутствия
конфликта кодов и текстов, связанных с прежним или новым кодом: многоязычных
XML, литералов `НСтр`/`NStr` и встроенной справки. Проверяются исходные тексты
и итог всего batch, включая созданные файлы. Если зависимость нельзя
доказать (например, аргумент `НСтр` вычисляется), операция отказывает до
записи. Язык по умолчанию не меняется, автоматического переноса переводов
нет. Повтор прежнего значения сохраняет байты. Язык расширения заимствован:
его код задаётся в основной конфигурации, в расширении меняется только `Comment`.
**Член создаётся на владельце, а изменяется и удаляется по своему адресу.**
`*.add` адресует того, кому член принадлежит, и несёт новые элементы в
`items`: `attribute.add` с `at: "main:Catalog.Валюты"` добавляет реквизит
шапки, а с `at: "main:Catalog.Валюты.TabularSection.Представления"` —
реквизит этой табличной части. `*.set` и `*.remove` адресуют сам член:
`main:Catalog.Валюты.TabularSection.Представления`,
`main:Catalog.Валюты.Attribute.Код`,
`main:Catalog.Валюты.TabularSection.Представления.Attribute.КодЯзыка`,
`main:Enum.ВидыОпераций.EnumValue.Приход`, `…Dimension.<Имя>`,
`…Resource.<Имя>`, `…Column.<Имя>`, `…Command.<Имя>`, `…Template.<Имя>`,
`…PredefinedItem.<Имя>`. Имени члена в аргументах нет: `set` несёт в `values`
только изменяемые поля, переименование — `newName`; `remove` аргументов не
принимает. Прежний вызов с `scope.tabularSection` или `values.name` получает
отказ, чей `next` называет правильный адрес.
Регистрация макета — `template.add` с `name` и необязательным `templateType`
из закрытого набора `HTMLDocument`, `TextDocument`, `SpreadsheetDocument` (по
умолчанию), `BinaryData`, `DataCompositionSchema`; снятие регистрации —
`template.remove`. Наполнение содержимого остаётся у предметных инструментов
своего вида.
`help.create` создаёт `Ext/Help.xml` и `Ext/Help/<lang>.html` владельца и
включает `IncludeHelpInContents` его формам; повтор — отказ, операция
создаёт только раз.
### Цвет элемента стиля
На существующем `StyleItem` с наблюдаемым `Type=Color` операция `props.set`
принимает только `values.Value`: RGB `#RRGGBB`, например `#F0F0F0`,
платформенный `web:Gray` или стандартный `style:SpecialTextColor`.
Конкретный словарь символических цветов выдаёт `Can.props.set`.
Пользовательские ссылки style и другие неизвестные формы остаются read-only;
Font/Border, повреждённый или отсутствующий Value не получают эту запись.
Не меняй Type и не подставляй цвет по умолчанию ради обхода ограничения.
Чтение известных символических цветов использует имена web/style независимо
от XML-prefix источника. Семантически тот же цвет — побайтовый no-op,
включая иной prefix или регистр RGB. Сначала проверь preview и сохранность
остальных свойств, затем исполни токен и перечитай результат.
### Состав плана обмена
Прочитай `ExchangePlan.<Имя>.Relation`: связи `content` содержат адреса
объектов и их `autoRecord`. Операция `content.set` на плане обмена обновляет
только перечисленные записи, сохраняя остальные и их порядок. Новые цели
добавляются в конец; каждая должна быть существующим справочником,
документом, константой, планом видов характеристик, счетов или видов
расчёта, регистром, бизнес-процессом или задачей того же набора исходников.
У плана с пустым составом платформа не пишет `Ext/Content.xml`: чтение
отдаёт пустой список, первая добавленная цель создаёт файл.
```json
{"at":"main:ExchangePlan.CorpusExchangePlan","ops":[{"op":"content.set","args":{"items":[{"at":"main:Catalog.Пример","autoRecord":"Allow"}]}}]}
```
В предпросмотре `data.exchangeContent` показывает итоговый состав с режимом
каждого элемента после всех операций пакета. Проверь его и исполни полученный
`executionToken`. Для смены режима передай ту же цель с `autoRecord: "Deny"`;
эквивалентный повтор не меняет байты. Повреждённый состав и повтор цели
в одном `items` приводят к отказу. Исключить объект из состава
`content.set` не может: операция только добавляет цели и меняет их режим.
Это изменение состава исходников. Фактическая регистрация изменений
в информационной базе проверяется отдельным прикладным сценарием.
В расширении состав заимствованного плана обмена складывается из состава
плана основной конфигурации и объектов, которые добавляет само расширение.
Платформа 8.3.27 хранит в `Ext/Content.xml` расширения только эти добавления
и пустой `<ExtensionProperty/>` после них; без добавлений файла нет. Поэтому
`Relation` заимствованного плана перечисляет только добавления расширения,
а без них называет `relations.content` в `limits`: полный состав читай у
плана основной конфигурации. `content.set` в расширении добавляет объекты
расширения — их сначала заимствуй — и `data.exchangeContent` предпросмотра
показывает те же добавления.
### Предопределённые элементы
Коллекция доступна только для `Catalog`, `ChartOfAccounts`,
`ChartOfCharacteristicTypes` и `ChartOfCalculationTypes`. Общие поля элемента:
`id`, `name`, `code`, `description`. Дополнительные поля закрыты видом
владельца:
- `Catalog`: `isFolder`;
- `ChartOfCharacteristicTypes`: `isFolder` и структурный `type` из
опубликованной схемы, не строка и не QName;
- `ChartOfAccounts`: `accountType`, `offBalance`, `order`, `accountingFlags`,
`extDimensionTypes`;
- `ChartOfCalculationTypes`: `actionPeriodIsBase`.
Для плана счетов `accountType` допускает `Active`, `Passive`,
`ActivePassive`; `accountingFlags` — закрытый объект `имя: boolean`;
`extDimensionTypes` — массив объектов с `name` и необязательными `turnover`,
`accountingFlags`. Явно переданные пустые `{}` и `[]` очищают соответственно
поддержанные `Flag` и `ExtDimensionType`; отсутствие поля сохраняет прежнее
значение.
`predefinedItem.add` на владельце создаёт только корневой элемент; `id` и
`name` задаются здесь. Совпадающий UUID даёт no-op только при эквивалентном
образе, иначе `already_exists`. `predefinedItem.set` адресует элемент
`…PredefinedItem.<Имя>` и принимает в `values` изменяемые поля,
переименование — `newName`; `predefinedItem.remove` — тот же адрес без
аргументов. Имя находится на любой глубине иерархии и уникально в объекте:
добавление или переименование на занятое имя отвергается. Удаление родителя
удаляет всё его поддерево. Неуказанные поля и неизвестные XML-узлы
сохраняются.
Элемент читается `unica.view` по тому же адресу: `props.id` — его UUID,
остальные поля — в `props`. Список элементов отдаёт ветвь
`…PredefinedItem` владельца.
### Ссылки наружу
Владельцы справочника и движения документа меняются через `relation.replace`
со связью `owners` или `registerRecords`. Источник подписки заменяется той же
операцией со связью `source`. Для точечного дополнения используй
`relation.add`, для удаления перечисленных источников — `relation.remove`.
Они сохраняют байты и относительный порядок прежних записей. Пустой `targets`
и удаление последнего логического источника отклоняются.
Цели — закрытое логическое объединение `object`, `manager`, `recordSet`,
`definedType` и `family`. `targets` — wire-массив набора:
порядок его членов семантически незначим, и перестановка тех же целей
является exact-byte no-op. `relation.replace` при изменении выпускает цели
в детерминированном порядке. `relation.add` сортирует только новые цели
и добавляет их после прежних в соответствующей группе XML: `Type` перед
`TypeSet`/`TypeId`. Повтор добавления существующих или удаления отсутствующих
целей не меняет файл. Повреждённый или неподдержанный `Source` для точечной
правки отклоняется; для полной замены остаётся `relation.replace`.
Ветвь `Relation` возвращает каждый логический источник с полем `target` —
той же целью, что принимает `targets`: так различаются объект и менеджер
одного справочника, `constantManager` и `constantValueManager`. Семейство
адреса не имеет и приходит элементом `{"relation":"source","kind":"family",
"target":…}`.
В расширении источник из основной конфигурации записан `v8:TypeId`; ветвь
`Relation` показывает его элементом `{"relation":"source","kind":"typeId",
"typeId":…,"readOnly":true}`. Задать его через `targets` нельзя, а
`relation.replace` меняет только логические цели и сохраняет такие элементы
как есть; итог из одних `v8:TypeId` платформа не загружает, поэтому нужна хотя
бы одна цель своего набора.
План проверяет изменённый источник против события подписки, раскрывая
определяемые типы: цикл, неподходящий член и класс без этого события или с
другой сигнатурой отклоняются без записи. Поэтому источник другого класса
и подходящее ему событие (`props.set` с `Event`) меняй одним вызовом `apply`.
Конфигурационные варианты передают логический `metadataPath`; Unica проверяет
регистрацию, дескриптор и совпадающий `GeneratedType` под тем же владельцем,
что и подписка. `DefinedType` разворачивается рекурсивно, а примитивы, ссылки
и `valueStorage` логическими источниками событий не являются.
## Границы
Не переноси поля снятого Meta JSON DSL по сходству имён:
- один вызов изменяет один объект; несколько объектов — несколько вызовов;
- вложенные шаблоны URL и методы HTTP-сервиса, операции и параметры
веб-сервиса, расписания, реквизиты адресации и учётные признаки читаются, но
типизированного писателя не имеют;
- shorthand-флаги `index`, `indexAdditional`, `nonneg`, `master`,
`mainFilter`, `denyIncomplete`, `useInTotals` нельзя упаковывать в строку;
- не подставляй составное значение в `props.set` строкой и не заводи временный
файл определения.
Тип значения константы задаётся через `props.set` по адресу константы:
`values: {"Type": {"variants": [{"kind": "boolean"}]}}`. При создании помести
эту операцию сразу после `object.create` в том же вызове. Для ссылки используй
вариант `{"kind": "reference", "metadataPath": "Catalog.Номенклатура"}`;
строка QName не принимается. Состав типов и квалификаторы те же, что у
реквизитов. `view` возвращает тип в `props.Type` объектом JSON; его
`mutationCapability` во вход не передаётся.
Если схема не представляет сценарий, остановись и скажи прямо, что оставшийся
шаг выполняется в Конфигураторе.
Скалярные свойства используй только под именем платформы в PascalCase и со
значением, опубликованным текущей схемой. Свойство наблюдения
`mutationCapability` во вход писателя не передаётся, и неизвестный QName
нельзя копировать из XML в аргументы. Вариант `{"kind":"typeId"}` — тип
основной конфигурации в расширении — только читается (`readOnly`); правка
других свойств реквизита его сохраняет.
## MCP examples
### Изменить свойства и реквизит
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:Catalog.Валюты",
"ops": [
{
"op": "props.set",
"args": {
"at": "main:Catalog.Валюты",
"values": {"Comment": "Справочник валют"}
}
},
{
"op": "attribute.set",
"args": {
"at": "main:Catalog.Валюты.Attribute.Код",
"values": {"required": true}
}
}
]
}
}
}
```
### Запрет пустых значений измерения
`dimension.set` у измерения регистра накопления, бухгалтерии или расчёта
принимает `values: {"denyIncompleteValues": true}`: платформа запретит запись
движения с пустым значением этого измерения. Это отдельное свойство,
`required` (проверка заполнения) оно не меняет. Меняется только значение
существующего `DenyIncompleteValues`; прежнее значение ничего не пишет.
У регистра сведений и у ресурсов поля нет. Сценарий корпуса —
`S-1702-dimension-deny-incomplete`.
### Копия реквизита табличной части
`attribute.copy` на адресе реквизита табличной части справочника,
например `main:Catalog.Валюты.TabularSection.Представления.Attribute.ПараметрыПрописи`,
с `values: {"name": "ПараметрыПрописиКопия"}` добавляет в конец той же
табличной части копию с новым UUID. Тип с квалификаторами, все настройки и
переводы синонима и подсказки переносятся из источника, задавать их не нужно.
Ссылки копии ведут туда же, куда у источника, а ссылки на источник на копию
не переходят. Реквизит шапки, другие виды владельца и расширения пока
не копируются; источник с вложенными UUID или ссылками на собственное имя
отклоняется. Сценарий корпуса — `S-1704-tabular-attribute-copy`.
### Правка реквизита табличной части и удаление
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:Catalog.Валюты",
"ops": [
{
"op": "attribute.set",
"args": {
"at": "main:Catalog.Валюты.TabularSection.Курсы.Attribute.Курс",
"values": {"required": true}
}
},
{
"op": "attribute.remove",
"args": {
"at": "main:Catalog.Валюты.TabularSection.Курсы.Attribute.Устарело"
}
}
]
}
}
}
```
### Реквизит табличной части и её переименование
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:Catalog.Валюты.TabularSection.Представления",
"ops": [
{
"op": "attribute.add",
"args": {
"at": "main:Catalog.Валюты.TabularSection.Представления",
"items": [
{
"name": "Сокращение",
"type": {"variants": [{"kind": "string", "length": 10, "allowedLength": "variable"}]}
}
]
}
},
{
"op": "tabularSection.set",
"args": {
"at": "main:Catalog.Валюты.TabularSection.Представления",
"values": {"newName": "ЯзыковыеПредставления"}
}
}
]
}
}
}
```
### Предопределённые элементы
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:Catalog.Валюты",
"ops": [
{
"op": "predefinedItem.add",
"args": {
"at": "main:Catalog.Валюты",
"items": [
{
"id": "0f5f4f2a-1a2b-4c3d-8e4f-5a6b7c8d9e0f",
"name": "Рубль",
"code": "643",
"description": "Российский рубль"
}
]
}
},
{
"op": "predefinedItem.set",
"args": {
"at": "main:Catalog.Валюты.PredefinedItem.Рубль",
"values": {"description": "Рубль РФ"}
}
},
{
"op": "predefinedItem.remove",
"args": {
"at": "main:Catalog.Валюты.PredefinedItem.Евро"
}
}
]
}
}
}
```
### Заменить источник подписки
Сначала получи план этого изменения:
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"at": "main:EventSubscription.ПриЗаписи",
"ops": [
{
"op": "relation.replace",
"args": {
"at": "main:EventSubscription.ПриЗаписи",
"values": {
"relation": "source",
"targets": [
{
"kind": "recordSet",
"metadataPath": "InformationRegister.ИсторияИзменений"
}
]
}
}
}
]
}
}
}
```
Для исполнения передай `data.executionToken` из этого успешного плана:
```json
{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "unica.apply",
"arguments": {
"executionToken": "<data.executionToken из успешного плана>"
}
}
}
```