diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1
index ed8cc6f4..37ccf14a 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.ps1
+++ b/.claude/skills/meta-compile/scripts/meta-compile.ps1
@@ -185,6 +185,10 @@ $script:typeSynonyms["бизнеспроцессссылка"] = "Bus
$script:typeSynonyms["задачассылка"] = "TaskRef"
$script:typeSynonyms["определяемыйтип"] = "DefinedType"
$script:typeSynonyms["definedtype"] = "DefinedType"
+# English lowercase ref synonyms
+$script:typeSynonyms["catalogref"] = "CatalogRef"
+$script:typeSynonyms["documentref"] = "DocumentRef"
+$script:typeSynonyms["enumref"] = "EnumRef"
function Resolve-TypeStr {
param([string]$typeStr)
@@ -248,6 +252,17 @@ function Emit-TypeContent {
return
}
+ # Number without params → Number(10,0)
+ if ($typeStr -eq "Number") {
+ X "$indentxs:decimal"
+ X "$indent"
+ X "$indent`t10"
+ X "$indent`t0"
+ X "$indent`tAny"
+ X "$indent"
+ return
+ }
+
# Number(D,F) or Number(D,F,nonneg)
if ($typeStr -match '^Number\((\d+),(\d+)(,nonneg)?\)$') {
$digits = $Matches[1]
@@ -285,6 +300,12 @@ function Emit-TypeContent {
return
}
+ # ValueStorage
+ if ($typeStr -eq "ValueStorage") {
+ X "$indentxs:base64Binary"
+ return
+ }
+
# Reference types — use local xmlns declaration for 1C compatibility
if ($typeStr -match '^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef)\.(.+)$') {
X "$indentd5p1:$typeStr"
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py
index f1e9db8b..9a7b5042 100644
--- a/.claude/skills/meta-compile/scripts/meta-compile.py
+++ b/.claude/skills/meta-compile/scripts/meta-compile.py
@@ -198,6 +198,10 @@ type_synonyms = {
'задачассылка': 'TaskRef',
'определяемыйтип': 'DefinedType',
'definedtype': 'DefinedType',
+ # English lowercase ref synonyms
+ 'catalogref': 'CatalogRef',
+ 'documentref': 'DocumentRef',
+ 'enumref': 'EnumRef',
}
def resolve_type_str(type_str):
@@ -251,6 +255,16 @@ def emit_type_content(indent, type_str):
X(f'{indent}\tVariable')
X(f'{indent}')
return
+ # Number without params -> Number(10,0)
+ if type_str == 'Number':
+ X(f'{indent}xs:decimal')
+ X(f'{indent}')
+ X(f'{indent}\t10')
+ X(f'{indent}\t0')
+ X(f'{indent}\tAny')
+ X(f'{indent}')
+ return
+
# Number(D,F) or Number(D,F,nonneg)
m = re.match(r'^Number\((\d+),(\d+)(,nonneg)?\)$', type_str)
if m:
@@ -283,6 +297,11 @@ def emit_type_content(indent, type_str):
dt_name = m.group(1)
X(f'{indent}cfg:DefinedType.{dt_name}')
return
+ # ValueStorage
+ if type_str == 'ValueStorage':
+ X(f'{indent}xs:base64Binary')
+ return
+
# Reference types — use local xmlns declaration for 1C compatibility
m = re.match(r'^(CatalogRef|DocumentRef|EnumRef|ChartOfAccountsRef|ChartOfCharacteristicTypesRef|ChartOfCalculationTypesRef|ExchangePlanRef|BusinessProcessRef|TaskRef)\.(.+)$', type_str)
if m:
diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1
index 89ca13e0..cafc9eaf 100644
--- a/.claude/skills/meta-edit/scripts/meta-edit.ps1
+++ b/.claude/skills/meta-edit/scripts/meta-edit.ps1
@@ -297,7 +297,7 @@ function Build-TypeContentXml {
# String or String(N)
if ($typeStr -match '^String(\((\d+)\))?$') {
- $len = if ($Matches[2]) { $Matches[2] } else { "0" }
+ $len = if ($Matches[2]) { $Matches[2] } else { "10" }
$sb.AppendLine("$indentxs:string") | Out-Null
$sb.AppendLine("$indent") | Out-Null
$sb.AppendLine("$indent`t$len") | Out-Null
@@ -689,10 +689,34 @@ function Get-AttributeContext {
}
}
+$script:reservedAttrNames = @{
+ "Ref"="Ссылка"; "DeletionMark"="ПометкаУдаления"; "Code"="Код"; "Description"="Наименование"
+ "Date"="Дата"; "Number"="Номер"; "Posted"="Проведен"; "Parent"="Родитель"; "Owner"="Владелец"
+ "IsFolder"="ЭтоГруппа"; "Predefined"="Предопределенный"; "PredefinedDataName"="ИмяПредопределенныхДанных"
+ "Recorder"="Регистратор"; "Period"="Период"; "LineNumber"="НомерСтроки"; "Active"="Активность"
+ "Order"="Порядок"; "Type"="Тип"; "OffBalance"="Забалансовый"
+ "Started"="Стартован"; "Completed"="Завершен"; "HeadTask"="ВедущаяЗадача"
+ "Executed"="Выполнена"; "RoutePoint"="ТочкаМаршрута"; "BusinessProcess"="БизнесПроцесс"
+ "ThisNode"="ЭтотУзел"; "SentNo"="НомерОтправленного"; "ReceivedNo"="НомерПринятого"
+ "CalculationType"="ВидРасчета"; "RegistrationPeriod"="ПериодРегистрации"; "ReversingEntry"="СторноЗапись"
+ "Account"="Счет"; "ValueType"="ТипЗначения"; "ActionPeriodIsBasic"="ПериодДействияБазовый"
+}
+
function Build-AttributeFragment {
param($parsed, [string]$context, [string]$indent)
if (-not $context) { $context = Get-AttributeContext }
+
+ # Check reserved attribute names
+ $attrName = $parsed.name
+ if ($script:reservedAttrNames.ContainsKey($attrName)) {
+ Write-Warning "Attribute '$attrName' conflicts with a standard attribute name. This may cause errors when loading into 1C."
+ }
+ $ruValues = $script:reservedAttrNames.Values
+ if ($ruValues -contains $attrName) {
+ Write-Warning "Attribute '$attrName' conflicts with a standard attribute name (Russian). This may cause errors when loading into 1C."
+ }
+
$uuid = New-Guid-String
$sb = New-Object System.Text.StringBuilder
diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py
index e593f6c7..f2f4fdca 100644
--- a/.claude/skills/meta-edit/scripts/meta-edit.py
+++ b/.claude/skills/meta-edit/scripts/meta-edit.py
@@ -214,7 +214,7 @@ def build_type_content_xml(indent, type_str):
# String or String(N)
m = re.match(r"^String(\((\d+)\))?$", type_str)
if m:
- length = m.group(2) if m.group(2) else "0"
+ length = m.group(2) if m.group(2) else "10"
lines.append(f"{indent}xs:string")
lines.append(f"{indent}")
lines.append(f"{indent}\t{length}")
@@ -600,10 +600,38 @@ def get_attribute_context():
return "object"
+RESERVED_ATTR_NAMES = {
+ 'Ref', 'DeletionMark', 'Code', 'Description', 'Date', 'Number', 'Posted',
+ 'Parent', 'Owner', 'IsFolder', 'Predefined', 'PredefinedDataName',
+ 'Recorder', 'Period', 'LineNumber', 'Active', 'Order', 'Type', 'OffBalance',
+ 'Started', 'Completed', 'HeadTask', 'Executed', 'RoutePoint', 'BusinessProcess',
+ 'ThisNode', 'SentNo', 'ReceivedNo', 'CalculationType', 'RegistrationPeriod',
+ 'ReversingEntry', 'Account', 'ValueType', 'ActionPeriodIsBasic',
+}
+RESERVED_ATTR_NAMES_RU = {
+ 'Ссылка', 'ПометкаУдаления', 'Код', 'Наименование',
+ 'Дата', 'Номер', 'Проведен', 'Родитель', 'Владелец',
+ 'ЭтоГруппа', 'Предопределенный', 'ИмяПредопределенныхДанных',
+ 'Регистратор', 'Период', 'НомерСтроки', 'Активность',
+ 'Порядок', 'Тип', 'Забалансовый',
+ 'Стартован', 'Завершен', 'ВедущаяЗадача',
+ 'Выполнена', 'ТочкаМаршрута', 'БизнесПроцесс',
+ 'ЭтотУзел', 'НомерОтправленного', 'НомерПринятого',
+ 'ВидРасчета', 'ПериодРегистрации', 'СторноЗапись',
+ 'Счет', 'ТипЗначения', 'ПериодДействияБазовый',
+}
+
+
def build_attribute_fragment(parsed, context, indent):
"""Build XML fragment string for an Attribute element."""
if not context:
context = get_attribute_context()
+
+ # Check reserved attribute names
+ attr_name = parsed['name']
+ if attr_name in RESERVED_ATTR_NAMES or attr_name in RESERVED_ATTR_NAMES_RU:
+ print(f"WARNING: Attribute '{attr_name}' conflicts with a standard attribute name. This may cause errors when loading into 1C.", file=sys.stderr)
+
uid = new_uuid()
lines = []