diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1 index 9b53ee86..75fa34b8 100644 --- a/.claude/skills/form-compile/scripts/form-compile.ps1 +++ b/.claude/skills/form-compile/scripts/form-compile.ps1 @@ -1,4 +1,4 @@ -# form-compile v1.185 — Compile 1C managed form from JSON or object metadata +# form-compile v1.186 — Compile 1C managed form from JSON or object metadata (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$JsonPath, @@ -2397,26 +2397,48 @@ $script:knownInvalidTypes = @{ "FormTable" = "UI element type, not a data type" } +# Алиас на локальный словарь: тело Resolve-TypeStr ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +$script:typeSynonyms = $script:formTypeSynonyms + function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } - # Lenient: strip leading cfg: prefix if user passed it (canonical form is without prefix) - if ($typeStr -match '^cfg:(.+)$') { $typeStr = $Matches[1] } + + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { - $base = $Matches[1].Trim(); $params = $Matches[2] - $r = $script:formTypeSynonyms[$base.ToLower()] - if ($r) { return "$r($params)" } + $baseName = $Matches[1].Trim() + $params = $Matches[2] + $resolved = $script:typeSynonyms[$baseName.ToLower()] + if ($resolved) { return "$resolved($params)" } return $typeStr } + + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { - $i = $typeStr.IndexOf('.') - $prefix = $typeStr.Substring(0, $i); $suffix = $typeStr.Substring($i) - $r = $script:formTypeSynonyms[$prefix.ToLower()] - if ($r) { return "$r$suffix" } + $dotIdx = $typeStr.IndexOf('.') + $prefix = $typeStr.Substring(0, $dotIdx) + $suffix = $typeStr.Substring($dotIdx) # includes the dot + $resolved = $script:typeSynonyms[$prefix.ToLower()] + if ($resolved) { return "$resolved$suffix" } return $typeStr } - $r = $script:formTypeSynonyms[$typeStr.ToLower()] - if ($r) { return $r } + + # Простое имя + $resolved = $script:typeSynonyms[$typeStr.ToLower()] + if ($resolved) { return $resolved } return $typeStr } diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py index e6fdbbf2..2f9e46aa 100644 --- a/.claude/skills/form-compile/scripts/form-compile.py +++ b/.claude/skills/form-compile/scripts/form-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# form-compile v1.185 — Compile 1C managed form from JSON or object metadata +# form-compile v1.186 — Compile 1C managed form from JSON or object metadata (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import copy @@ -3757,26 +3757,47 @@ _FORM_TYPE_SYNONYMS = { } +# Алиас на локальный словарь: тело resolve_type_str ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +TYPE_SYNONYMS = _FORM_TYPE_SYNONYMS + + def resolve_type_str(type_str): if not type_str: return type_str - # Lenient: strip leading cfg: prefix if user passed it (canonical form is without prefix) + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. if type_str.startswith('cfg:'): type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: - base, params = m.group(1).strip(), m.group(2) - r = _FORM_TYPE_SYNONYMS.get(base.lower()) - return f"{r}({params})" if r else type_str + base_name = m.group(1).strip() + params = m.group(2) + resolved = TYPE_SYNONYMS.get(base_name.lower()) + if resolved: + return f'{resolved}({params})' + return type_str + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации if '.' in type_str: - i = type_str.index('.') - prefix, suffix = type_str[:i], type_str[i:] - r = _FORM_TYPE_SYNONYMS.get(prefix.lower()) - return f"{r}{suffix}" if r else type_str - r = _FORM_TYPE_SYNONYMS.get(type_str.lower()) - return r if r else type_str - - + dot_idx = type_str.index('.') + prefix = type_str[:dot_idx] + suffix = type_str[dot_idx:] # includes the dot + resolved = TYPE_SYNONYMS.get(prefix.lower()) + if resolved: + return f'{resolved}{suffix}' + return type_str + # Простое имя + resolved = TYPE_SYNONYMS.get(type_str.lower()) + if resolved: + return resolved + return type_str def emit_single_type(lines, type_str, indent): type_str = resolve_type_str(type_str) # TypeId — тип, заданный глобальным стабильным GUID (, не ). Платформа так diff --git a/.claude/skills/form-edit/scripts/form-edit.ps1 b/.claude/skills/form-edit/scripts/form-edit.ps1 index 7cc68de9..57b5a376 100644 --- a/.claude/skills/form-edit/scripts/form-edit.ps1 +++ b/.claude/skills/form-edit/scripts/form-edit.ps1 @@ -1,4 +1,4 @@ -# form-edit v1.9 — Edit 1C managed form elements +# form-edit v1.10 — Edit 1C managed form elements (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -311,24 +311,48 @@ $script:formTypeSynonyms["бизнеспроцессссылка"] = " $script:formTypeSynonyms["задачассылка"] = "TaskRef" $script:formTypeSynonyms["определяемыйтип"] = "DefinedType" +# Алиас на локальный словарь: тело Resolve-TypeStr ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +$script:typeSynonyms = $script:formTypeSynonyms + function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } + + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { - $base = $Matches[1].Trim(); $params = $Matches[2] - $r = $script:formTypeSynonyms[$base.ToLower()] - if ($r) { return "$r($params)" } + $baseName = $Matches[1].Trim() + $params = $Matches[2] + $resolved = $script:typeSynonyms[$baseName.ToLower()] + if ($resolved) { return "$resolved($params)" } return $typeStr } + + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { - $i = $typeStr.IndexOf('.') - $prefix = $typeStr.Substring(0, $i); $suffix = $typeStr.Substring($i) - $r = $script:formTypeSynonyms[$prefix.ToLower()] - if ($r) { return "$r$suffix" } + $dotIdx = $typeStr.IndexOf('.') + $prefix = $typeStr.Substring(0, $dotIdx) + $suffix = $typeStr.Substring($dotIdx) # includes the dot + $resolved = $script:typeSynonyms[$prefix.ToLower()] + if ($resolved) { return "$resolved$suffix" } return $typeStr } - $r = $script:formTypeSynonyms[$typeStr.ToLower()] - if ($r) { return $r } + + # Простое имя + $resolved = $script:typeSynonyms[$typeStr.ToLower()] + if ($resolved) { return $resolved } return $typeStr } diff --git a/.claude/skills/form-edit/scripts/form-edit.py b/.claude/skills/form-edit/scripts/form-edit.py index 9577cadd..10746fc6 100644 --- a/.claude/skills/form-edit/scripts/form-edit.py +++ b/.claude/skills/form-edit/scripts/form-edit.py @@ -1,4 +1,4 @@ -# form-edit v1.9 — Edit 1C managed form elements (Python port) +# form-edit v1.10 — Edit 1C managed form elements (Python port) (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -386,23 +386,47 @@ _FORM_TYPE_SYNONYMS = { } +# Алиас на локальный словарь: тело resolve_type_str ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +TYPE_SYNONYMS = _FORM_TYPE_SYNONYMS + + def resolve_type_str(type_str): if not type_str: return type_str + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if type_str.startswith('cfg:'): + type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: - base, params = m.group(1).strip(), m.group(2) - r = _FORM_TYPE_SYNONYMS.get(base.lower()) - return f"{r}({params})" if r else type_str + base_name = m.group(1).strip() + params = m.group(2) + resolved = TYPE_SYNONYMS.get(base_name.lower()) + if resolved: + return f'{resolved}({params})' + return type_str + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации if '.' in type_str: - i = type_str.index('.') - prefix, suffix = type_str[:i], type_str[i:] - r = _FORM_TYPE_SYNONYMS.get(prefix.lower()) - return f"{r}{suffix}" if r else type_str - r = _FORM_TYPE_SYNONYMS.get(type_str.lower()) - return r if r else type_str - - + dot_idx = type_str.index('.') + prefix = type_str[:dot_idx] + suffix = type_str[dot_idx:] # includes the dot + resolved = TYPE_SYNONYMS.get(prefix.lower()) + if resolved: + return f'{resolved}{suffix}' + return type_str + # Простое имя + resolved = TYPE_SYNONYMS.get(type_str.lower()) + if resolved: + return resolved + return type_str def emit_type(type_str, indent): if not type_str: X(f"{indent}") diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index a8f4d857..b4871b4d 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.89 — Compile 1C metadata object from JSON (+detect_format_version: ветка автономной EPF/ERF) +# meta-compile v1.90 — Compile 1C metadata object from JSON (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -581,7 +581,19 @@ function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } - # Check for parameterized types: Number(15,2), Строка(100), etc. + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { $baseName = $Matches[1].Trim() $params = $Matches[2] @@ -590,7 +602,7 @@ function Resolve-TypeStr { return $typeStr } - # Check for reference types: СправочникСсылка.Организации → CatalogRef.Организации + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { $dotIdx = $typeStr.IndexOf('.') $prefix = $typeStr.Substring(0, $dotIdx) @@ -600,10 +612,9 @@ function Resolve-TypeStr { return $typeStr } - # Simple name lookup + # Простое имя $resolved = $script:typeSynonyms[$typeStr.ToLower()] if ($resolved) { return $resolved } - return $typeStr } diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 8f8eba32..3367da35 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.89 — Compile 1C metadata object from JSON (+detect_format_version: ветка автономной EPF/ERF) +# meta-compile v1.90 — Compile 1C metadata object from JSON (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -647,33 +647,47 @@ cfg_object_kinds = {"Catalog", "Document", "Enum", "ChartOfAccounts", "ChartOfCh "AccumulationRegister", "AccountingRegister", "CalculationRegister", "DataProcessor", "Report", "DocumentJournal", "Constant", "ConstantValue", "Sequence", "Recalculation"} +# Алиас на локальный словарь: тело resolve_type_str ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +TYPE_SYNONYMS = type_synonyms + + def resolve_type_str(type_str): if not type_str: return type_str - # Parameterized types: Number(15,2), Строка(100), etc. + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if type_str.startswith('cfg:'): + type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: base_name = m.group(1).strip() params = m.group(2) - resolved = type_synonyms.get(base_name.lower()) + resolved = TYPE_SYNONYMS.get(base_name.lower()) if resolved: return f'{resolved}({params})' return type_str - # Reference types: СправочникСсылка.Организации -> CatalogRef.Организации + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации if '.' in type_str: dot_idx = type_str.index('.') prefix = type_str[:dot_idx] suffix = type_str[dot_idx:] # includes the dot - resolved = type_synonyms.get(prefix.lower()) + resolved = TYPE_SYNONYMS.get(prefix.lower()) if resolved: return f'{resolved}{suffix}' return type_str - # Simple name lookup - resolved = type_synonyms.get(type_str.lower()) + # Простое имя + resolved = TYPE_SYNONYMS.get(type_str.lower()) if resolved: return resolved return type_str - def emit_type_content(indent, type_str): if not type_str: return diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1 index 80bd33a0..eb7f473e 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.ps1 +++ b/.claude/skills/meta-edit/scripts/meta-edit.ps1 @@ -1,4 +1,4 @@ -# meta-edit v1.32 — Edit existing 1C metadata object XML (+ReuseSessions: Use) +# meta-edit v1.33 — Edit existing 1C metadata object XML (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -461,7 +461,19 @@ function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } - # Parameterized: Number(15,2), Строка(100) + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { $baseName = $Matches[1].Trim() $params = $Matches[2] @@ -470,17 +482,17 @@ function Resolve-TypeStr { return $typeStr } - # Reference: СправочникСсылка.Организации + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { $dotIdx = $typeStr.IndexOf('.') $prefix = $typeStr.Substring(0, $dotIdx) - $suffix = $typeStr.Substring($dotIdx) + $suffix = $typeStr.Substring($dotIdx) # includes the dot $resolved = $script:typeSynonyms[$prefix.ToLower()] if ($resolved) { return "$resolved$suffix" } return $typeStr } - # Simple + # Простое имя $resolved = $script:typeSynonyms[$typeStr.ToLower()] if ($resolved) { return $resolved } return $typeStr diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py index 323f36a8..58ca5933 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.py +++ b/.claude/skills/meta-edit/scripts/meta-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-edit v1.32 — Edit existing 1C metadata object XML (+ReuseSessions: Use) +# meta-edit v1.33 — Edit existing 1C metadata object XML (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -416,37 +416,47 @@ type_synonyms = { # ============================================================ +# Алиас на локальный словарь: тело resolve_type_str ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +TYPE_SYNONYMS = type_synonyms + + def resolve_type_str(type_str): if not type_str: return type_str - - # Parameterized: Number(15,2), Строка(100) - m = re.match(r"^([^(]+)\((.+)\)$", type_str) + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if type_str.startswith('cfg:'): + type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) + m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: base_name = m.group(1).strip() params = m.group(2) - resolved = type_synonyms.get(base_name.lower()) + resolved = TYPE_SYNONYMS.get(base_name.lower()) if resolved: - return f"{resolved}({params})" + return f'{resolved}({params})' return type_str - - # Reference: СправочникСсылка.Организации - if "." in type_str: - dot_idx = type_str.index(".") + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации + if '.' in type_str: + dot_idx = type_str.index('.') prefix = type_str[:dot_idx] - suffix = type_str[dot_idx:] - resolved = type_synonyms.get(prefix.lower()) + suffix = type_str[dot_idx:] # includes the dot + resolved = TYPE_SYNONYMS.get(prefix.lower()) if resolved: - return f"{resolved}{suffix}" + return f'{resolved}{suffix}' return type_str - - # Simple - resolved = type_synonyms.get(type_str.lower()) + # Простое имя + resolved = TYPE_SYNONYMS.get(type_str.lower()) if resolved: return resolved return type_str - - def build_type_content_xml(indent, type_str): if not type_str: return "" diff --git a/.claude/skills/skd-compile/scripts/skd-compile.ps1 b/.claude/skills/skd-compile/scripts/skd-compile.ps1 index 7cbd1581..8cf5424d 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.ps1 +++ b/.claude/skills/skd-compile/scripts/skd-compile.ps1 @@ -1,4 +1,4 @@ -# skd-compile v1.111 — Compile 1C DCS from JSON +# skd-compile v1.112 — Compile 1C DCS from JSON (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -348,19 +348,28 @@ function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } - # Check for parameterized types: число(15,2), строка(100), etc. + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { $baseName = $Matches[1].Trim() $params = $Matches[2] - - # Resolve base name (case-insensitive via .ToLower()) $resolved = $script:typeSynonyms[$baseName.ToLower()] if ($resolved) { return "$resolved($params)" } - return $typeStr } - # Check for reference types: СправочникСсылка.Организации → CatalogRef.Организации + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { $dotIdx = $typeStr.IndexOf('.') $prefix = $typeStr.Substring(0, $dotIdx) @@ -370,10 +379,9 @@ function Resolve-TypeStr { return $typeStr } - # Simple name lookup (case-insensitive) + # Простое имя $resolved = $script:typeSynonyms[$typeStr.ToLower()] if ($resolved) { return $resolved } - return $typeStr } diff --git a/.claude/skills/skd-compile/scripts/skd-compile.py b/.claude/skills/skd-compile/scripts/skd-compile.py index 2945f1db..5143f8ce 100644 --- a/.claude/skills/skd-compile/scripts/skd-compile.py +++ b/.claude/skills/skd-compile/scripts/skd-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# skd-compile v1.111 — Compile 1C DCS from JSON +# skd-compile v1.112 — Compile 1C DCS from JSON (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -283,35 +283,39 @@ TYPE_SYNONYMS = { def resolve_type_str(type_str): if not type_str: return type_str - - # Check for parameterized types: число(15,2), строка(100), etc. + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if type_str.startswith('cfg:'): + type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: base_name = m.group(1).strip() params = m.group(2) resolved = TYPE_SYNONYMS.get(base_name.lower()) if resolved: - return f"{resolved}({params})" + return f'{resolved}({params})' return type_str - - # Check for reference types: СправочникСсылка.Организации -> CatalogRef.Организации + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации if '.' in type_str: dot_idx = type_str.index('.') prefix = type_str[:dot_idx] suffix = type_str[dot_idx:] # includes the dot resolved = TYPE_SYNONYMS.get(prefix.lower()) if resolved: - return f"{resolved}{suffix}" + return f'{resolved}{suffix}' return type_str - - # Simple name lookup (case-insensitive) + # Простое имя resolved = TYPE_SYNONYMS.get(type_str.lower()) if resolved: return resolved - return type_str - - def emit_value_type(lines, type_spec, indent): if not type_spec: return diff --git a/.claude/skills/skd-edit/scripts/skd-edit.ps1 b/.claude/skills/skd-edit/scripts/skd-edit.ps1 index 6f55a46f..772527a0 100644 --- a/.claude/skills/skd-edit/scripts/skd-edit.ps1 +++ b/.claude/skills/skd-edit/scripts/skd-edit.ps1 @@ -1,4 +1,4 @@ -# skd-edit v1.32 — Atomic 1C DCS editor +# skd-edit v1.33 — Atomic 1C DCS editor (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills # NB: парный .py собирает выражения автодат вне f-string ради совместимости с python 3.9 (PEP 701). param( @@ -247,6 +247,19 @@ function Resolve-TypeStr { param([string]$typeStr) if (-not $typeStr) { return $typeStr } + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if ($typeStr.StartsWith('cfg:')) { + $typeStr = $typeStr.Substring(4) + } elseif ($typeStr.StartsWith('d5p1:') -and $typeStr.Contains('.')) { + $typeStr = $typeStr.Substring(5) + } + + # Параметризованные типы: Number(15,2), Строка(100) if ($typeStr -match '^([^(]+)\((.+)\)$') { $baseName = $Matches[1].Trim() $params = $Matches[2] @@ -255,15 +268,17 @@ function Resolve-TypeStr { return $typeStr } + # Ссылочные типы: СправочникСсылка.Организации → CatalogRef.Организации if ($typeStr.Contains('.')) { $dotIdx = $typeStr.IndexOf('.') $prefix = $typeStr.Substring(0, $dotIdx) - $suffix = $typeStr.Substring($dotIdx) + $suffix = $typeStr.Substring($dotIdx) # includes the dot $resolved = $script:typeSynonyms[$prefix.ToLower()] if ($resolved) { return "$resolved$suffix" } return $typeStr } + # Простое имя $resolved = $script:typeSynonyms[$typeStr.ToLower()] if ($resolved) { return $resolved } return $typeStr diff --git a/.claude/skills/skd-edit/scripts/skd-edit.py b/.claude/skills/skd-edit/scripts/skd-edit.py index ffa233c4..ebccec48 100644 --- a/.claude/skills/skd-edit/scripts/skd-edit.py +++ b/.claude/skills/skd-edit/scripts/skd-edit.py @@ -1,4 +1,4 @@ -# skd-edit v1.32 — Atomic 1C DCS editor (Python port) +# skd-edit v1.33 — Atomic 1C DCS editor (Python port) (+resolve_type_str: срезание префикса cfg:/d5p1:) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -336,34 +336,47 @@ output_param_types = { } +# Алиас на локальный словарь: тело resolve_type_str ниже — общая реализация, +# одинаковая во всех навыках (реестр в tests/skills/check-inline-drift.mjs). +TYPE_SYNONYMS = type_synonyms + + def resolve_type_str(type_str): if not type_str: return type_str - + # Прощающий ввод: ведущий префикс приходит копипастой из выгрузки. Без срезания он ломает + # поиск в словаре — русское имя типа остаётся непереведённым, и платформа отвечает + # «Неизвестное имя типа». cfg: снимаем всегда (однозначно = текущая конфигурация), d5p1: — + # только у ССЫЛОЧНЫХ типов (с точкой): сам по себе префикс неоднозначен, в формах d5p1:Chart, + # d5p1:TextDocument, d5p1:GeographicalSchema и др. адресуют свои пространства имён, и там он + # часть канонического значения. + if type_str.startswith('cfg:'): + type_str = type_str[4:] + elif type_str.startswith('d5p1:') and '.' in type_str: + type_str = type_str[5:] + # Параметризованные типы: Number(15,2), Строка(100) m = re.match(r'^([^(]+)\((.+)\)$', type_str) if m: base_name = m.group(1).strip() params = m.group(2) - resolved = type_synonyms.get(base_name.lower()) + resolved = TYPE_SYNONYMS.get(base_name.lower()) if resolved: - return f"{resolved}({params})" + return f'{resolved}({params})' return type_str - - if "." in type_str: - dot_idx = type_str.index(".") + # Ссылочные типы: СправочникСсылка.Организации -> CatalogRef.Организации + if '.' in type_str: + dot_idx = type_str.index('.') prefix = type_str[:dot_idx] - suffix = type_str[dot_idx:] - resolved = type_synonyms.get(prefix.lower()) + suffix = type_str[dot_idx:] # includes the dot + resolved = TYPE_SYNONYMS.get(prefix.lower()) if resolved: - return f"{resolved}{suffix}" + return f'{resolved}{suffix}' return type_str - - resolved = type_synonyms.get(type_str.lower()) + # Простое имя + resolved = TYPE_SYNONYMS.get(type_str.lower()) if resolved: return resolved return type_str - - # ── 3. Parsers ────────────────────────────────────────────── def parse_field_shorthand(s): diff --git a/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Catalogs/Товары.xml b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Catalogs/Товары.xml new file mode 100644 index 00000000..9974d7df --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Catalogs/Товары.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Товары + + + ru + Товары + + + + false + HierarchyFoldersAndItems + false + 2 + true + true + + ToItems + 9 + 25 + String + Variable + WholeCatalog + false + true + AsDescription + + Auto + InDialog + false + BothWays + + Catalog.Товары.StandardAttribute.Description + Catalog.Товары.StandardAttribute.Code + + Begin + DontUse + Directly + + + + + + + + + + + false + + + Managed + Use + + + + + + Use + Auto + DontUse + false + false + + + + + СкладПлайн + + + ru + Склад плайн + + + + + cfg:CatalogRef.Склады + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + СкладCfg + + + ru + Складcfg + + + + + cfg:CatalogRef.Склады + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + СкладD5p1 + + + ru + Складd5p1 + + + + + cfg:CatalogRef.Склады + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + СкладEng + + + ru + Складeng + + + + + cfg:CatalogRef.Склады + + false + + + + false + + false + false + + + false + + DontCheck + Items + + + Auto + Auto + + + Auto + ForItem + DontIndex + Use + Use + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Catalogs/Товары/Ext/ObjectModule.bsl b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Catalogs/Товары/Ext/ObjectModule.bsl new file mode 100644 index 00000000..e69de29b diff --git a/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Configuration.xml b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Configuration.xml new file mode 100644 index 00000000..e67cf3a1 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Configuration.xml @@ -0,0 +1,252 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + UUID-006 + UUID-007 + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + UUID-012 + UUID-013 + + + UUID-014 + UUID-015 + + + + TestConfig + + + ru + TestConfig + + + + + Version8_3_24 + ManagedApplication + + PlatformApplication + + Russian + + + + + false + false + false + + + + + + + + + + + + + + + + + + + + + + Biometrics + true + + + Location + false + + + BackgroundLocation + false + + + BluetoothPrinters + false + + + WiFiPrinters + false + + + Contacts + false + + + Calendars + false + + + PushNotifications + false + + + LocalNotifications + false + + + InAppPurchases + false + + + PersonalComputerFileExchange + false + + + Ads + false + + + NumberDialing + false + + + CallProcessing + false + + + CallLog + false + + + AutoSendSMS + false + + + ReceiveSMS + false + + + SMSLog + false + + + Camera + false + + + Microphone + false + + + MusicLibrary + false + + + PictureAndVideoLibraries + false + + + AudioPlaybackAndVibration + false + + + BackgroundAudioPlaybackAndVibration + false + + + InstallPackages + false + + + OSBackup + true + + + ApplicationUsageStatistics + false + + + BarcodeScanning + false + + + BackgroundAudioRecording + false + + + AllFilesAccess + false + + + Videoconferences + false + + + NFC + false + + + DocumentScanning + false + + + SpeechToText + false + + + Geofences + false + + + IncomingShareRequests + false + + + AllIncomingShareRequestsTypesProcessing + false + + + + + + Normal + + + Language.Русский + + + + + + Managed + NotAutoFree + DontUse + DontUse + TaxiEnableVersion8_2 + DontUse + Version8_3_24 + + + + Русский + Товары + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Ext/ClientApplicationInterface.xml b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Ext/ClientApplicationInterface.xml new file mode 100644 index 00000000..3c1161b2 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Ext/ClientApplicationInterface.xml @@ -0,0 +1,18 @@ + + + + + UUID-002 + + + + + UUID-004 + + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Languages/Русский.xml b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Languages/Русский.xml new file mode 100644 index 00000000..37c60d78 --- /dev/null +++ b/tests/skills/cases/meta-compile/snapshots/type-prefix-lenient/Languages/Русский.xml @@ -0,0 +1,16 @@ + + + + + Русский + + + ru + Русский + + + + ru + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-compile/type-prefix-lenient.json b/tests/skills/cases/meta-compile/type-prefix-lenient.json new file mode 100644 index 00000000..c648e48a --- /dev/null +++ b/tests/skills/cases/meta-compile/type-prefix-lenient.json @@ -0,0 +1,25 @@ +{ + "name": "Префикс cfg:/d5p1: у ссылочного типа срезается (копипаста из выгрузки)", + "input": { + "type": "Catalog", + "name": "Товары", + "attributes": [ + "СкладПлайн: СправочникСсылка.Склады", + "СкладCfg: cfg:СправочникСсылка.Склады", + "СкладD5p1: d5p1:СправочникСсылка.Склады", + "СкладEng: cfg:CatalogRef.Склады" + ] + }, + "validatePath": "Catalogs/Товары", + "expect": { + "files": ["Catalogs/Товары.xml"], + "fileContains": { + "file": "Catalogs/Товары.xml", + "text": "cfg:CatalogRef.Склады" + }, + "fileNotContains": { + "file": "Catalogs/Товары.xml", + "text": ["cfg:СправочникСсылка", "d5p1:СправочникСсылка", "cfg:cfg:"] + } + } +} diff --git a/tests/skills/check-inline-drift.mjs b/tests/skills/check-inline-drift.mjs index fd29b477..6ad1bda8 100644 --- a/tests/skills/check-inline-drift.mjs +++ b/tests/skills/check-inline-drift.mjs @@ -107,6 +107,17 @@ const FAMILIES = [ ], }, + // ─── Прощающий ввод: разбор строки типа ────────────────────────────────── + { + name: 'resolve_type_str', py: 'resolve_type_str', ps1: 'Resolve-TypeStr', + // Тело одинаково во всех навыках, а словари синонимов разные — навык объявляет алиас + // TYPE_SYNONYMS / $script:typeSynonyms на свой локальный словарь. + variants: [ + { id: 'base', authority: 'meta-compile', + consumers: ['form-compile', 'form-edit', 'meta-edit', 'skd-compile', 'skd-edit'] }, + ], + }, + // ─── Экранирование XML ─────────────────────────────────────────────────── { name: 'esc_xml', py: 'esc_xml', ps1: 'Esc-Xml', @@ -195,8 +206,6 @@ const FAMILIES = [ // число групп не должно расти. Фаза 2 сводит семью к одному телу и переносит её в FAMILIES. const DRIFTED = [ - { name: 'resolve_type_str', py: 'resolve_type_str', ps1: 'Resolve-TypeStr', maxVariants: { py: 6, ps1: 4 }, - note: 'алгоритм один, отличия редакторские; отдельно — срезание префикса cfg: только в form-compile' }, { name: 'emit_mltext', py: 'emit_mltext', ps1: 'Emit-MLText', maxVariants: { py: 5, ps1: 5 } }, { name: 'get_ml_text', py: 'get_ml_text', ps1: 'Get-MLText', maxVariants: { py: 7, ps1: 6 } }, { name: 'validate: report_error', py: null, ps1: 'Report-Error', maxVariants: { ps1: 3 } },