diff --git a/.claude/skills/meta-compile/reference/catalog.md b/.claude/skills/meta-compile/reference/catalog.md
index 92b36e93..7504cbf9 100644
--- a/.claude/skills/meta-compile/reference/catalog.md
+++ b/.claude/skills/meta-compile/reference/catalog.md
@@ -15,7 +15,7 @@
| `limitLevelCount` | `false` | bool (ограничивать кол-во уровней) |
| `levelCount` | `2` | число уровней (при `limitLevelCount`) |
| `foldersOnTop` | `true` | bool (группы сверху) |
-| `owners` | `[]` | массив ссылок-владельцев: `["CatalogRef.Контрагенты"]` |
+| `owners` | `[]` | массив владельцев: `["Catalog.Контрагенты"]` |
| `subordinationUse` | `ToItems` | `ToItems` / `ToFolders` / `ToFoldersAndItems` (кому подчинён) |
| `codeLength` | `9` | длина кода (0 — без кода) |
| `codeType` | `String` | `String` / `Number` |
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1
index 9ba047d5..1be7c23f 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.ps1
+++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1
@@ -1,4 +1,4 @@
-# meta-compile v1.66 — Compile 1C metadata object from JSON
+# meta-compile v1.67 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -786,11 +786,28 @@ $script:mdRefRoots = @{
'журналдокументов'='DocumentJournal'; 'отчет'='Report'; 'отчёт'='Report'; 'обработка'='DataProcessor';
'табличнаячасть'='TabularSection'; 'реквизит'='Attribute'; 'измерение'='Dimension'; 'ресурс'='Resource';
'стандартныйреквизит'='StandardAttribute'; 'значениеперечисления'='EnumValue'; 'команда'='Command';
- 'признакучета'='AccountingFlag'; 'признакучёта'='AccountingFlag'
+ 'признакучета'='AccountingFlag'; 'признакучёта'='AccountingFlag';
+ # Ссылочные формы (тип ссылки вместо объекта метаданных): в MDObjectRef-пути нужен ОБЪЕКТ, т.е.
+ # "CatalogRef.Валюты" → "Catalog.Валюты". Вид метаданных, оканчивающийся на Ref, не существует,
+ # поэтому схлопывание однозначно. В ТИПАХ реквизитов запись CatalogRef.X верна — там эта мапа не применяется.
+ 'catalogref'='Catalog'; 'documentref'='Document'; 'enumref'='Enum';
+ 'chartofaccountsref'='ChartOfAccounts'; 'chartofcharacteristictypesref'='ChartOfCharacteristicTypes';
+ 'chartofcalculationtypesref'='ChartOfCalculationTypes'; 'exchangeplanref'='ExchangePlan';
+ 'businessprocessref'='BusinessProcess'; 'taskref'='Task';
+ 'справочникссылка'='Catalog'; 'документссылка'='Document'; 'перечислениессылка'='Enum';
+ 'плансчетовссылка'='ChartOfAccounts'; 'планвидовхарактеристикссылка'='ChartOfCharacteristicTypes';
+ 'планвидоврасчетассылка'='ChartOfCalculationTypes'; 'планвидоврасчётассылка'='ChartOfCalculationTypes';
+ 'планобменассылка'='ExchangePlan'; 'бизнеспроцессссылка'='BusinessProcess'; 'задачассылка'='Task'
}
+# $defaultRoot — корень для ГОЛОГО имени без точки (напр. owners: "Валюты" → "Catalog.Валюты").
+# Без него голое имя возвращается как есть (прежнее поведение вызывающих без подстановки).
function Normalize-MDObjectRef {
- param([string]$ref)
- if (-not $ref -or -not $ref.Contains('.')) { return $ref }
+ param([string]$ref, [string]$defaultRoot)
+ if (-not $ref) { return $ref }
+ if (-not $ref.Contains('.')) {
+ if ($defaultRoot) { return "$defaultRoot.$ref" }
+ return $ref
+ }
$parts = $ref -split '\.'
for ($k = 0; $k -lt $parts.Count; $k += 2) {
$t = $script:mdRefRoots[$parts[$k].ToLower()]
@@ -1497,7 +1514,7 @@ function Emit-BasedOn {
$arr = @($items | Where-Object { $_ })
if ($arr.Count -eq 0) { X "$indent"; return }
X "$indent"
- foreach ($it in $arr) { X "$indent`t$(Esc-Xml "$it")" }
+ foreach ($it in $arr) { X "$indent`t$(Esc-Xml (Normalize-MDObjectRef "$it"))" }
X "$indent"
}
@@ -2258,8 +2275,7 @@ function Emit-CatalogProperties {
if ($def.owners -and $def.owners.Count -gt 0) {
X "$i"
foreach ($ownerRef in $def.owners) {
- $fullRef = if ("$ownerRef" -match '\.') { "$ownerRef" } else { "Catalog.$ownerRef" }
- X "$i`t$fullRef"
+ X "$i`t$(Esc-Xml (Normalize-MDObjectRef "$ownerRef" 'Catalog'))"
}
X "$i"
} else {
@@ -2410,7 +2426,7 @@ function Emit-DocumentProperties {
}
if ($regRecords.Count -gt 0) {
X "$i"
- foreach ($rr in $regRecords) { X "$i`t$rr" }
+ foreach ($rr in $regRecords) { X "$i`t$(Esc-Xml (Normalize-MDObjectRef "$rr"))" }
X "$i"
} else {
X "$i"
@@ -3524,7 +3540,7 @@ function Emit-ChartOfCalculationTypesProperties {
$baseTypes = @(); if ($def.baseCalculationTypes) { $baseTypes = @($def.baseCalculationTypes | ForEach-Object { Resolve-TypePrefixSyn "$_" }) }
if ($baseTypes.Count -gt 0) {
X "$i"
- foreach ($bt in $baseTypes) { X "$i`t$(Esc-Xml $bt)" }
+ foreach ($bt in $baseTypes) { X "$i`t$(Esc-Xml (Normalize-MDObjectRef "$bt"))" }
X "$i"
} else { X "$i" }
$actionPeriodUse = if ($def.actionPeriodUse -eq $true) { "true" } else { "false" }
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py
index cff57fa9..80df290e 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.py
+++ b/.claude/skills/meta-compile/scripts/meta-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# meta-compile v1.66 — Compile 1C metadata object from JSON
+# meta-compile v1.67 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -822,11 +822,26 @@ md_ref_roots = {
'табличнаячасть': 'TabularSection', 'реквизит': 'Attribute', 'измерение': 'Dimension', 'ресурс': 'Resource',
'стандартныйреквизит': 'StandardAttribute', 'значениеперечисления': 'EnumValue', 'команда': 'Command',
'признакучета': 'AccountingFlag', 'признакучёта': 'AccountingFlag',
+ # Ссылочные формы (тип ссылки вместо объекта метаданных): в MDObjectRef-пути нужен ОБЪЕКТ, т.е.
+ # "CatalogRef.Валюты" → "Catalog.Валюты". Вид метаданных, оканчивающийся на Ref, не существует,
+ # поэтому схлопывание однозначно. В ТИПАХ реквизитов запись CatalogRef.X верна — там мапа не применяется.
+ 'catalogref': 'Catalog', 'documentref': 'Document', 'enumref': 'Enum',
+ 'chartofaccountsref': 'ChartOfAccounts', 'chartofcharacteristictypesref': 'ChartOfCharacteristicTypes',
+ 'chartofcalculationtypesref': 'ChartOfCalculationTypes', 'exchangeplanref': 'ExchangePlan',
+ 'businessprocessref': 'BusinessProcess', 'taskref': 'Task',
+ 'справочникссылка': 'Catalog', 'документссылка': 'Document', 'перечислениессылка': 'Enum',
+ 'плансчетовссылка': 'ChartOfAccounts', 'планвидовхарактеристикссылка': 'ChartOfCharacteristicTypes',
+ 'планвидоврасчетассылка': 'ChartOfCalculationTypes', 'планвидоврасчётассылка': 'ChartOfCalculationTypes',
+ 'планобменассылка': 'ExchangePlan', 'бизнеспроцессссылка': 'BusinessProcess', 'задачассылка': 'Task',
}
-def normalize_md_object_ref(ref):
- if not ref or '.' not in ref:
+def normalize_md_object_ref(ref, default_root=None):
+ """default_root — корень для ГОЛОГО имени без точки (owners: "Валюты" → "Catalog.Валюты").
+ Без него голое имя возвращается как есть (прежнее поведение вызывающих без подстановки)."""
+ if not ref:
return ref
+ if '.' not in ref:
+ return f'{default_root}.{ref}' if default_root else ref
parts = ref.split('.')
for k in range(0, len(parts), 2):
t = md_ref_roots.get(parts[k].lower())
@@ -1587,7 +1602,7 @@ def emit_based_on(indent, items):
return
X(f'{indent}')
for it in arr:
- X(f'{indent}\t{esc_xml(str(it))}')
+ X(f'{indent}\t{esc_xml(normalize_md_object_ref(str(it)))}')
X(f'{indent}')
# --- Параметры/связи выбора (порт из form-compile) ---
@@ -2288,8 +2303,7 @@ def emit_catalog_properties(indent):
if owners:
X(f'{i}')
for owner_ref in owners:
- full_ref = owner_ref if '.' in str(owner_ref) else f'Catalog.{owner_ref}'
- X(f'{i}\t{full_ref}')
+ X(f'{i}\t{esc_xml(normalize_md_object_ref(str(owner_ref), "Catalog"))}')
X(f'{i}')
else:
X(f'{i}')
@@ -2429,7 +2443,7 @@ def emit_document_properties(indent):
if reg_records:
X(f'{i}')
for rr in reg_records:
- X(f'{i}\t{rr}')
+ X(f'{i}\t{esc_xml(normalize_md_object_ref(str(rr)))}')
X(f'{i}')
else:
X(f'{i}')
@@ -3483,7 +3497,7 @@ def emit_chart_of_calculation_types_properties(indent):
if base_types:
X(f'{i}')
for bt in base_types:
- X(f'{i}\t{esc_xml(bt)}')
+ X(f'{i}\t{esc_xml(normalize_md_object_ref(bt))}')
X(f'{i}')
else:
X(f'{i}')
diff --git a/tests/skills/cases/meta-compile/catalog-inputbystring-datalock.json b/tests/skills/cases/meta-compile/catalog-inputbystring-datalock.json
index 5eedb7aa..6deaf44b 100644
--- a/tests/skills/cases/meta-compile/catalog-inputbystring-datalock.json
+++ b/tests/skills/cases/meta-compile/catalog-inputbystring-datalock.json
@@ -1,14 +1,14 @@
{
- "name": "InputByString / DataLockFields / BasedOn каталога",
+ "name": "InputByString / DataLockFields / BasedOn каталога (+нормализация MDObjectRef: CatalogRef./рус. → Catalog.)",
"input": {
"type": "Catalog",
"name": "ДоговорыКонтрагентов",
- "owners": ["Catalog.Контрагенты"],
+ "owners": ["CatalogRef.Контрагенты"],
"codeLength": 11,
"descriptionLength": 100,
"inputByString": ["Код", "Наименование", "НомерДоговора"],
"dataLockFields": ["Организация", "Контрагент", "Владелец"],
- "basedOn": ["Catalog.Контрагенты", "Document.ЗаказПоставщику"],
+ "basedOn": ["Справочник.Контрагенты", "DocumentRef.ЗаказПоставщику"],
"attributes": [
"Организация: CatalogRef.Организации",
"Контрагент: CatalogRef.Контрагенты",