diff --git a/.claude/skills/cf-edit/scripts/cf-edit.ps1 b/.claude/skills/cf-edit/scripts/cf-edit.ps1
index 1e876400..0973ae9c 100644
--- a/.claude/skills/cf-edit/scripts/cf-edit.ps1
+++ b/.claude/skills/cf-edit/scripts/cf-edit.ps1
@@ -1,4 +1,4 @@
-# cf-edit v1.7 — Edit 1C configuration root (Configuration.xml)
+# cf-edit v1.8 — Edit 1C configuration root (Configuration.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)][Alias('Path')][string]$ConfigPath,
@@ -196,7 +196,7 @@ Info "Configuration: $($script:objName)"
$script:typeOrder = @(
"Language","Subsystem","StyleItem","Style",
"CommonPicture","SessionParameter","Role","CommonTemplate",
- "FilterCriterion","CommonModule","CommonAttribute","ExchangePlan",
+ "FilterCriterion","CommonModule","Bot","CommonAttribute","ExchangePlan",
"XDTOPackage","WebService","HTTPService","WSReference",
"EventSubscription","ScheduledJob","SettingsStorage","FunctionalOption",
"FunctionalOptionsParameter","DefinedType","CommonCommand","CommandGroup",
@@ -212,7 +212,7 @@ $script:typeOrder = @(
$script:typeToDir = @{
"Language"="Languages"; "Subsystem"="Subsystems"; "StyleItem"="StyleItems"; "Style"="Styles"
"CommonPicture"="CommonPictures"; "SessionParameter"="SessionParameters"; "Role"="Roles"; "CommonTemplate"="CommonTemplates"
- "FilterCriterion"="FilterCriteria"; "CommonModule"="CommonModules"; "CommonAttribute"="CommonAttributes"; "ExchangePlan"="ExchangePlans"
+ "FilterCriterion"="FilterCriteria"; "CommonModule"="CommonModules"; "Bot"="Bots"; "CommonAttribute"="CommonAttributes"; "ExchangePlan"="ExchangePlans"
"XDTOPackage"="XDTOPackages"; "WebService"="WebServices"; "HTTPService"="HTTPServices"; "WSReference"="WSReferences"
"EventSubscription"="EventSubscriptions"; "ScheduledJob"="ScheduledJobs"; "SettingsStorage"="SettingsStorages"; "FunctionalOption"="FunctionalOptions"
"FunctionalOptionsParameter"="FunctionalOptionsParameters"; "DefinedType"="DefinedTypes"; "CommonCommand"="CommonCommands"; "CommandGroup"="CommandGroups"
@@ -700,6 +700,7 @@ $script:ruTypeMap = @{
"регистррасчёта" = "CalculationRegister"
"бизнеспроцесс" = "BusinessProcess"
"задача" = "Task"
+ "бот" = "Bot"
"планобмена" = "ExchangePlan"
"хранилищенастроек" = "SettingsStorage"
}
diff --git a/.claude/skills/cf-edit/scripts/cf-edit.py b/.claude/skills/cf-edit/scripts/cf-edit.py
index f10bffef..9aa6c5c8 100644
--- a/.claude/skills/cf-edit/scripts/cf-edit.py
+++ b/.claude/skills/cf-edit/scripts/cf-edit.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# cf-edit v1.7 — Edit 1C configuration root (Configuration.xml)
+# cf-edit v1.8 — Edit 1C configuration root (Configuration.xml)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -182,7 +182,7 @@ XS_NS = "http://www.w3.org/2001/XMLSchema"
TYPE_ORDER = [
"Language", "Subsystem", "StyleItem", "Style",
"CommonPicture", "SessionParameter", "Role", "CommonTemplate",
- "FilterCriterion", "CommonModule", "CommonAttribute", "ExchangePlan",
+ "FilterCriterion", "CommonModule", "Bot", "CommonAttribute", "ExchangePlan",
"XDTOPackage", "WebService", "HTTPService", "WSReference",
"EventSubscription", "ScheduledJob", "SettingsStorage", "FunctionalOption",
"FunctionalOptionsParameter", "DefinedType", "CommonCommand", "CommandGroup",
@@ -198,7 +198,7 @@ TYPE_ORDER = [
TYPE_TO_DIR = {
"Language": "Languages", "Subsystem": "Subsystems", "StyleItem": "StyleItems", "Style": "Styles",
"CommonPicture": "CommonPictures", "SessionParameter": "SessionParameters", "Role": "Roles", "CommonTemplate": "CommonTemplates",
- "FilterCriterion": "FilterCriteria", "CommonModule": "CommonModules", "CommonAttribute": "CommonAttributes", "ExchangePlan": "ExchangePlans",
+ "FilterCriterion": "FilterCriteria", "CommonModule": "CommonModules", "Bot": "Bots", "CommonAttribute": "CommonAttributes", "ExchangePlan": "ExchangePlans",
"XDTOPackage": "XDTOPackages", "WebService": "WebServices", "HTTPService": "HTTPServices", "WSReference": "WSReferences",
"EventSubscription": "EventSubscriptions", "ScheduledJob": "ScheduledJobs", "SettingsStorage": "SettingsStorages", "FunctionalOption": "FunctionalOptions",
"FunctionalOptionsParameter": "FunctionalOptionsParameters", "DefinedType": "DefinedTypes", "CommonCommand": "CommonCommands", "CommandGroup": "CommandGroups",
@@ -771,6 +771,7 @@ def main():
"регистррасчета": "CalculationRegister",
"регистррасчёта": "CalculationRegister",
"бизнеспроцесс": "BusinessProcess",
+ "бот": "Bot",
"задача": "Task", "планобмена": "ExchangePlan",
"хранилищенастроек": "SettingsStorage",
}
diff --git a/.claude/skills/cf-info/scripts/cf-info.ps1 b/.claude/skills/cf-info/scripts/cf-info.ps1
index be050f68..b2d5a1b2 100644
--- a/.claude/skills/cf-info/scripts/cf-info.ps1
+++ b/.claude/skills/cf-info/scripts/cf-info.ps1
@@ -1,4 +1,4 @@
-# cf-info v1.3 — Compact summary of 1C configuration root
+# cf-info v1.4 — Compact summary of 1C configuration root
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory=$true)][Alias('Path')][string]$ConfigPath,
@@ -89,7 +89,7 @@ function Get-PropML([string]$propName) {
$typeOrder = @(
"Language","Subsystem","StyleItem","Style",
"CommonPicture","SessionParameter","Role","CommonTemplate",
- "FilterCriterion","CommonModule","CommonAttribute","ExchangePlan",
+ "FilterCriterion","CommonModule","Bot","CommonAttribute","ExchangePlan",
"XDTOPackage","WebService","HTTPService","WSReference",
"EventSubscription","ScheduledJob","SettingsStorage","FunctionalOption",
"FunctionalOptionsParameter","DefinedType","CommonCommand","CommandGroup",
@@ -105,6 +105,7 @@ $typeRuNames = @{
"Language"="Языки"; "Subsystem"="Подсистемы"; "StyleItem"="Элементы стиля"; "Style"="Стили"
"CommonPicture"="Общие картинки"; "SessionParameter"="Параметры сеанса"; "Role"="Роли"
"CommonTemplate"="Общие макеты"; "FilterCriterion"="Критерии отбора"; "CommonModule"="Общие модули"
+ "Bot"="Боты"
"CommonAttribute"="Общие реквизиты"; "ExchangePlan"="Планы обмена"; "XDTOPackage"="XDTO-пакеты"
"WebService"="Веб-сервисы"; "HTTPService"="HTTP-сервисы"; "WSReference"="WS-ссылки"
"EventSubscription"="Подписки на события"; "ScheduledJob"="Регламентные задания"
diff --git a/.claude/skills/cf-info/scripts/cf-info.py b/.claude/skills/cf-info/scripts/cf-info.py
index 4814cc27..eada7323 100644
--- a/.claude/skills/cf-info/scripts/cf-info.py
+++ b/.claude/skills/cf-info/scripts/cf-info.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# cf-info v1.3 — Compact summary of 1C configuration root
+# cf-info v1.4 — Compact summary of 1C configuration root
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -95,7 +95,7 @@ def get_prop_ml(prop_name):
type_order = [
"Language", "Subsystem", "StyleItem", "Style",
"CommonPicture", "SessionParameter", "Role", "CommonTemplate",
- "FilterCriterion", "CommonModule", "CommonAttribute", "ExchangePlan",
+ "FilterCriterion", "CommonModule", "Bot", "CommonAttribute", "ExchangePlan",
"XDTOPackage", "WebService", "HTTPService", "WSReference",
"EventSubscription", "ScheduledJob", "SettingsStorage", "FunctionalOption",
"FunctionalOptionsParameter", "DefinedType", "CommonCommand", "CommandGroup",
@@ -111,6 +111,7 @@ type_ru_names = {
"Language": "Языки", "Subsystem": "Подсистемы", "StyleItem": "Элементы стиля", "Style": "Стили",
"CommonPicture": "Общие картинки", "SessionParameter": "Параметры сеанса", "Role": "Роли",
"CommonTemplate": "Общие макеты", "FilterCriterion": "Критерии отбора", "CommonModule": "Общие модули",
+ "Bot": "Боты",
"CommonAttribute": "Общие реквизиты", "ExchangePlan": "Планы обмена", "XDTOPackage": "XDTO-пакеты",
"WebService": "Веб-сервисы", "HTTPService": "HTTP-сервисы", "WSReference": "WS-ссылки",
"EventSubscription": "Подписки на события", "ScheduledJob": "Регламентные задания",
diff --git a/.claude/skills/cf-validate/scripts/cf-validate.ps1 b/.claude/skills/cf-validate/scripts/cf-validate.ps1
index 365853b9..e59ff3c6 100644
--- a/.claude/skills/cf-validate/scripts/cf-validate.ps1
+++ b/.claude/skills/cf-validate/scripts/cf-validate.ps1
@@ -1,4 +1,4 @@
-# cf-validate v1.3 — Validate 1C configuration root structure
+# cf-validate v1.4 — Validate 1C configuration root structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
@@ -104,11 +104,11 @@ $validClassIds = @(
"fb282519-d103-4dd3-bc12-cb271d631dfc" # home page / client app interface
)
-# 44 types in canonical order
+# 45 types in canonical order
$childObjectTypes = @(
"Language","Subsystem","StyleItem","Style",
"CommonPicture","SessionParameter","Role","CommonTemplate",
- "FilterCriterion","CommonModule","CommonAttribute","ExchangePlan",
+ "FilterCriterion","CommonModule","Bot","CommonAttribute","ExchangePlan",
"XDTOPackage","WebService","HTTPService","WSReference",
"EventSubscription","ScheduledJob","SettingsStorage","FunctionalOption",
"FunctionalOptionsParameter","DefinedType","CommonCommand","CommandGroup",
@@ -125,6 +125,7 @@ $childTypeDirMap = @{
"Language"="Languages"; "Subsystem"="Subsystems"; "StyleItem"="StyleItems"; "Style"="Styles"
"CommonPicture"="CommonPictures"; "SessionParameter"="SessionParameters"; "Role"="Roles"
"CommonTemplate"="CommonTemplates"; "FilterCriterion"="FilterCriteria"; "CommonModule"="CommonModules"
+ "Bot"="Bots"
"CommonAttribute"="CommonAttributes"; "ExchangePlan"="ExchangePlans"; "XDTOPackage"="XDTOPackages"
"WebService"="WebServices"; "HTTPService"="HTTPServices"; "WSReference"="WSReferences"
"EventSubscription"="EventSubscriptions"; "ScheduledJob"="ScheduledJobs"
diff --git a/.claude/skills/cf-validate/scripts/cf-validate.py b/.claude/skills/cf-validate/scripts/cf-validate.py
index df1426d9..9b3ba9b6 100644
--- a/.claude/skills/cf-validate/scripts/cf-validate.py
+++ b/.claude/skills/cf-validate/scripts/cf-validate.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# cf-validate v1.3 — Validate 1C configuration XML structure
+# cf-validate v1.4 — Validate 1C configuration XML structure
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
"""Validates Configuration.xml: root structure, InternalInfo, properties, ChildObjects, languages."""
import sys, os, argparse, re
@@ -33,11 +33,11 @@ VALID_CLASS_IDS = [
'fb282519-d103-4dd3-bc12-cb271d631dfc', # home page / client app interface
]
-# 44 types in canonical order
+# 45 types in canonical order
CHILD_OBJECT_TYPES = [
'Language', 'Subsystem', 'StyleItem', 'Style',
'CommonPicture', 'SessionParameter', 'Role', 'CommonTemplate',
- 'FilterCriterion', 'CommonModule', 'CommonAttribute', 'ExchangePlan',
+ 'FilterCriterion', 'CommonModule', 'Bot', 'CommonAttribute', 'ExchangePlan',
'XDTOPackage', 'WebService', 'HTTPService', 'WSReference',
'EventSubscription', 'ScheduledJob', 'SettingsStorage', 'FunctionalOption',
'FunctionalOptionsParameter', 'DefinedType', 'CommonCommand', 'CommandGroup',
@@ -54,6 +54,7 @@ CHILD_TYPE_DIR_MAP = {
'Language': 'Languages', 'Subsystem': 'Subsystems', 'StyleItem': 'StyleItems', 'Style': 'Styles',
'CommonPicture': 'CommonPictures', 'SessionParameter': 'SessionParameters', 'Role': 'Roles',
'CommonTemplate': 'CommonTemplates', 'FilterCriterion': 'FilterCriteria', 'CommonModule': 'CommonModules',
+ 'Bot': 'Bots',
'CommonAttribute': 'CommonAttributes', 'ExchangePlan': 'ExchangePlans', 'XDTOPackage': 'XDTOPackages',
'WebService': 'WebServices', 'HTTPService': 'HTTPServices', 'WSReference': 'WSReferences',
'EventSubscription': 'EventSubscriptions', 'ScheduledJob': 'ScheduledJobs',
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1
index 1424c784..f0a881fe 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.49 — Compile 1C metadata object from JSON
+# meta-compile v1.50 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[Parameter(Mandatory)]
diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py
index ddfa5eb7..66e895ec 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.49 — Compile 1C metadata object from JSON
+# meta-compile v1.50 — Compile 1C metadata object from JSON
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
@@ -4031,21 +4031,19 @@ reg_result = None
child_tag = obj_type
if os.path.isfile(config_xml_path):
- # Parse preserving whitespace via raw string manipulation
- with open(config_xml_path, 'r', encoding='utf-8-sig') as f:
+ # Read raw content, preserving BOM/EOL byte-for-byte (newline='' => no translation).
+ with open(config_xml_path, 'r', encoding='utf-8-sig', newline='') as f:
config_content = f.read()
ns = 'http://v8.1c.ru/8.3/MDClasses'
- ET.register_namespace('', ns)
- # Parse all namespaces used in the file
- # Use iterparse to collect namespace prefixes
- namespaces_in_file = {}
- for evt, elem in ET.iterparse(config_xml_path, events=['start-ns']):
- prefix, uri = elem
- if prefix:
- namespaces_in_file[prefix] = uri
- ET.register_namespace(prefix, uri)
-
+ # ET is used ONLY read-only here: to locate ChildObjects and detect a duplicate.
+ # We deliberately do NOT re-serialize Configuration.xml with ElementTree.write():
+ # it drops every xmlns declaration used only inside attribute VALUES (e.g.
+ # xsi:type="app:ApplicationUsePurpose" in UsePurposes) because ET never sees those
+ # prefixes in element/attribute names. The dropped declaration makes XDTO read the
+ # value as anyType and Designer refuses to load the file (issue #38). Registration is
+ # therefore done by raw-text insertion, preserving BOM, EOL and all namespaces
+ # byte-for-byte (same approach as subsystem-compile).
tree = ET.parse(config_xml_path)
root = tree.getroot()
@@ -4056,41 +4054,47 @@ if os.path.isfile(config_xml_path):
if config_elem is not None:
child_objects = config_elem.find(f'{{{ns}}}ChildObjects')
- if child_objects is not None:
+ if child_objects is None:
+ reg_result = 'no-childobj'
+ else:
existing = child_objects.findall(f'{{{ns}}}{child_tag}')
- already_exists = False
- for e in existing:
- if (e.text or '').strip() == obj_name:
- already_exists = True
- break
+ already_exists = any((e.text or '').strip() == obj_name for e in existing)
if already_exists:
reg_result = 'already'
else:
- new_elem = ET.SubElement(child_objects, f'{{{ns}}}{child_tag}')
- new_elem.text = obj_name
+ eol = '\r\n' if '\r\n' in config_content else '\n'
+ entry = f'<{child_tag}>{esc_xml(obj_name)}{child_tag}>'
- if existing:
- # Insert after last existing element of same type
- last_elem = existing[-1]
- all_children = list(child_objects)
- idx = all_children.index(last_elem)
- child_objects.remove(new_elem)
- child_objects.insert(idx + 1, new_elem)
-
- # Write back preserving BOM
- tree.write(config_xml_path, encoding='utf-8', xml_declaration=True)
- # Re-read to add BOM, fix declaration quotes, ensure trailing newline
- with open(config_xml_path, 'r', encoding='utf-8') as f:
- raw = f.read()
- if raw.startswith(""):
- raw = raw.replace("", '', 1)
- if not raw.endswith('\n'):
- raw += '\n'
- write_utf8_bom(config_xml_path, raw)
- reg_result = 'added'
- else:
- reg_result = 'no-childobj'
+ block = re.search(r'.*?', config_content, re.S)
+ if block is None:
+ # Empty self-closing => open it with the first entry.
+ empty = re.search(r'', config_content)
+ if empty is None:
+ reg_result = 'no-childobj'
+ else:
+ replacement = f'{eol}\t\t\t{entry}{eol}\t\t'
+ new_content = config_content[:empty.start()] + replacement + config_content[empty.end():]
+ write_utf8_bom(config_xml_path, new_content)
+ reg_result = 'added'
+ else:
+ close_same = f'{child_tag}>'
+ last_same = config_content.rfind(close_same, block.start(), block.end())
+ if last_same != -1:
+ # After the last element of the same type (keeps them grouped).
+ insert_at = last_same + len(close_same)
+ new_content = (config_content[:insert_at]
+ + f'{eol}\t\t\t{entry}'
+ + config_content[insert_at:])
+ else:
+ # No element of this type yet: new line before ,
+ # reusing the block's existing closing indent for .
+ close_at = config_content.rfind('', block.start(), block.end())
+ new_content = (config_content[:close_at]
+ + f'\t{entry}{eol}\t\t'
+ + config_content[close_at:])
+ write_utf8_bom(config_xml_path, new_content)
+ reg_result = 'added'
else:
reg_result = 'no-config'
diff --git a/docs/1c-configuration-spec.md b/docs/1c-configuration-spec.md
index 8a9d08ab..3afc40a3 100644
--- a/docs/1c-configuration-spec.md
+++ b/docs/1c-configuration-spec.md
@@ -193,6 +193,7 @@ ClassId — фиксированные идентификаторы классо
fresh
ДокументыПоВидуОплаты
АвтоматическиеСкидки
+
КомментарийЯзык1
ОбновлениеИнформационнойБазы
AgentScripts
@@ -244,40 +245,41 @@ ClassId — фиксированные идентификаторы классо
| 8 | `CommonTemplate` | `CommonTemplates/` | Общие макеты |
| 9 | `FilterCriterion` | `FilterCriteria/` | Критерии отбора |
| 10 | `CommonModule` | `CommonModules/` | Общие модули |
-| 11 | `CommonAttribute` | `CommonAttributes/` | Общие реквизиты |
-| 12 | `ExchangePlan` | `ExchangePlans/` | Планы обмена |
-| 13 | `XDTOPackage` | `XDTOPackages/` | XDTO-пакеты |
-| 14 | `WebService` | `WebServices/` | Веб-сервисы |
-| 15 | `HTTPService` | `HTTPServices/` | HTTP-сервисы |
-| 16 | `WSReference` | `WSReferences/` | WS-ссылки |
-| 17 | `EventSubscription` | `EventSubscriptions/` | Подписки на события |
-| 18 | `ScheduledJob` | `ScheduledJobs/` | Регламентные задания |
-| 19 | `SettingsStorage` | `SettingsStorages/` | Хранилища настроек |
-| 20 | `FunctionalOption` | `FunctionalOptions/` | Функциональные опции |
-| 21 | `FunctionalOptionsParameter` | `FunctionalOptionsParameters/` | Параметры ФО |
-| 22 | `DefinedType` | `DefinedTypes/` | Определяемые типы |
-| 23 | `CommonCommand` | `CommonCommands/` | Общие команды |
-| 24 | `CommandGroup` | `CommandGroups/` | Группы команд |
-| 25 | `Constant` | `Constants/` | Константы |
-| 26 | `CommonForm` | `CommonForms/` | Общие формы |
-| 27 | `Catalog` | `Catalogs/` | Справочники |
-| 28 | `Document` | `Documents/` | Документы |
-| 29 | `DocumentNumerator` | `DocumentNumerators/` | Нумераторы документов |
-| 30 | `Sequence` | `Sequences/` | Последовательности |
-| 31 | `DocumentJournal` | `DocumentJournals/` | Журналы документов |
-| 32 | `Enum` | `Enums/` | Перечисления |
-| 33 | `Report` | `Reports/` | Отчёты |
-| 34 | `DataProcessor` | `DataProcessors/` | Обработки |
-| 35 | `InformationRegister` | `InformationRegisters/` | Регистры сведений |
-| 36 | `AccumulationRegister` | `AccumulationRegisters/` | Регистры накопления |
-| 37 | `ChartOfCharacteristicTypes` | `ChartsOfCharacteristicTypes/` | Планы видов характеристик |
-| 38 | `ChartOfAccounts` | `ChartsOfAccounts/` | Планы счетов |
-| 39 | `AccountingRegister` | `AccountingRegisters/` | Регистры бухгалтерии |
-| 40 | `ChartOfCalculationTypes` | `ChartsOfCalculationTypes/` | Планы видов расчёта |
-| 41 | `CalculationRegister` | `CalculationRegisters/` | Регистры расчёта |
-| 42 | `BusinessProcess` | `BusinessProcesses/` | Бизнес-процессы |
-| 43 | `Task` | `Tasks/` | Задачи |
-| 44 | `IntegrationService` | `IntegrationServices/` | Сервисы интеграции |
+| 11 | `Bot` | `Bots/` | Боты (платформа 8.3.18+) |
+| 12 | `CommonAttribute` | `CommonAttributes/` | Общие реквизиты |
+| 13 | `ExchangePlan` | `ExchangePlans/` | Планы обмена |
+| 14 | `XDTOPackage` | `XDTOPackages/` | XDTO-пакеты |
+| 15 | `WebService` | `WebServices/` | Веб-сервисы |
+| 16 | `HTTPService` | `HTTPServices/` | HTTP-сервисы |
+| 17 | `WSReference` | `WSReferences/` | WS-ссылки |
+| 18 | `EventSubscription` | `EventSubscriptions/` | Подписки на события |
+| 19 | `ScheduledJob` | `ScheduledJobs/` | Регламентные задания |
+| 20 | `SettingsStorage` | `SettingsStorages/` | Хранилища настроек |
+| 21 | `FunctionalOption` | `FunctionalOptions/` | Функциональные опции |
+| 22 | `FunctionalOptionsParameter` | `FunctionalOptionsParameters/` | Параметры ФО |
+| 23 | `DefinedType` | `DefinedTypes/` | Определяемые типы |
+| 24 | `CommonCommand` | `CommonCommands/` | Общие команды |
+| 25 | `CommandGroup` | `CommandGroups/` | Группы команд |
+| 26 | `Constant` | `Constants/` | Константы |
+| 27 | `CommonForm` | `CommonForms/` | Общие формы |
+| 28 | `Catalog` | `Catalogs/` | Справочники |
+| 29 | `Document` | `Documents/` | Документы |
+| 30 | `DocumentNumerator` | `DocumentNumerators/` | Нумераторы документов |
+| 31 | `Sequence` | `Sequences/` | Последовательности |
+| 32 | `DocumentJournal` | `DocumentJournals/` | Журналы документов |
+| 33 | `Enum` | `Enums/` | Перечисления |
+| 34 | `Report` | `Reports/` | Отчёты |
+| 35 | `DataProcessor` | `DataProcessors/` | Обработки |
+| 36 | `InformationRegister` | `InformationRegisters/` | Регистры сведений |
+| 37 | `AccumulationRegister` | `AccumulationRegisters/` | Регистры накопления |
+| 38 | `ChartOfCharacteristicTypes` | `ChartsOfCharacteristicTypes/` | Планы видов характеристик |
+| 39 | `ChartOfAccounts` | `ChartsOfAccounts/` | Планы счетов |
+| 40 | `AccountingRegister` | `AccountingRegisters/` | Регистры бухгалтерии |
+| 41 | `ChartOfCalculationTypes` | `ChartsOfCalculationTypes/` | Планы видов расчёта |
+| 42 | `CalculationRegister` | `CalculationRegisters/` | Регистры расчёта |
+| 43 | `BusinessProcess` | `BusinessProcesses/` | Бизнес-процессы |
+| 44 | `Task` | `Tasks/` | Задачи |
+| 45 | `IntegrationService` | `IntegrationServices/` | Сервисы интеграции |
Внутри одного типа объекты отсортированы по имени (алфавитный порядок). Типы, для которых нет объектов, в ChildObjects не записываются.
diff --git a/tests/skills/cases/cf-edit/add-bot.json b/tests/skills/cases/cf-edit/add-bot.json
new file mode 100644
index 00000000..45cf651d
--- /dev/null
+++ b/tests/skills/cases/cf-edit/add-bot.json
@@ -0,0 +1,7 @@
+{
+ "name": "Регистрация Bot в ChildObjects",
+ "setup": "fixture:add-bot",
+ "input": [
+ { "operation": "add-childObject", "value": "Bot.ОповещенияПользователейОСобытиях" }
+ ]
+}
diff --git a/tests/skills/cases/cf-edit/fixtures/add-bot/Bots/ОповещенияПользователейОСобытиях.xml b/tests/skills/cases/cf-edit/fixtures/add-bot/Bots/ОповещенияПользователейОСобытиях.xml
new file mode 100644
index 00000000..0c700217
--- /dev/null
+++ b/tests/skills/cases/cf-edit/fixtures/add-bot/Bots/ОповещенияПользователейОСобытиях.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ ОповещенияПользователейОСобытиях
+
+
+ true
+
+
+
+
diff --git a/tests/skills/cases/cf-edit/fixtures/add-bot/Configuration.xml b/tests/skills/cases/cf-edit/fixtures/add-bot/Configuration.xml
new file mode 100644
index 00000000..3a873eda
--- /dev/null
+++ b/tests/skills/cases/cf-edit/fixtures/add-bot/Configuration.xml
@@ -0,0 +1,67 @@
+
+
+
+
+
+ 9cd510cd-abfc-11d4-9434-004095e12fc7
+ 2145bb60-cbf8-459a-aa10-bea7f44e3f2f
+
+
+ 9fcd25a0-4822-11d4-9414-008048da11f9
+ 6a26f594-55f0-4be3-ac78-98f735640668
+
+
+ e3687481-0a87-462c-a166-9f34594f9bba
+ 7a4686f3-b998-4656-8cba-2dd53cca2c29
+
+
+ 9de14907-ec23-4a07-96f0-85521cb6b53b
+ 1078616c-b4eb-469d-a25c-2ff8b13eeb1e
+
+
+ 51f2d5d8-ea4d-4064-8892-82951750031e
+ db007a87-7b0a-416f-bf30-ccf10c265e5e
+
+
+ e68182ea-4237-4383-967f-90c1e3370bc7
+ de40bd20-2175-4d6f-a131-e4ba036aaf5f
+
+
+ fb282519-d103-4dd3-bc12-cb271d631dfc
+ b26c5d95-9559-4a74-bdde-db40d73f3596
+
+
+
+ БотДемо
+
+
+ ru
+ Бот демо
+
+
+
+
+ Version8_3_24
+ ManagedApplication
+
+ PlatformApplication
+
+ Russian
+
+
+
+ Version8_3_24
+ Language.Русский
+ Managed
+ NotAutoFree
+ DontUse
+ DontUse
+ TaxiEnableVersion8_2
+ Normal
+
+
+
+ Русский
+
+
+
diff --git a/tests/skills/cases/cf-edit/fixtures/add-bot/Languages/Русский.xml b/tests/skills/cases/cf-edit/fixtures/add-bot/Languages/Русский.xml
new file mode 100644
index 00000000..21119ca7
--- /dev/null
+++ b/tests/skills/cases/cf-edit/fixtures/add-bot/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
diff --git a/tests/skills/cases/cf-info/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml b/tests/skills/cases/cf-info/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml
new file mode 100644
index 00000000..0c700217
--- /dev/null
+++ b/tests/skills/cases/cf-info/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ ОповещенияПользователейОСобытиях
+
+
+ true
+
+
+
+
diff --git a/tests/skills/cases/cf-info/fixtures/with-bot/Configuration.xml b/tests/skills/cases/cf-info/fixtures/with-bot/Configuration.xml
new file mode 100644
index 00000000..f4ad7c07
--- /dev/null
+++ b/tests/skills/cases/cf-info/fixtures/with-bot/Configuration.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+ 9cd510cd-abfc-11d4-9434-004095e12fc7
+ 2145bb60-cbf8-459a-aa10-bea7f44e3f2f
+
+
+ 9fcd25a0-4822-11d4-9414-008048da11f9
+ 6a26f594-55f0-4be3-ac78-98f735640668
+
+
+ e3687481-0a87-462c-a166-9f34594f9bba
+ 7a4686f3-b998-4656-8cba-2dd53cca2c29
+
+
+ 9de14907-ec23-4a07-96f0-85521cb6b53b
+ 1078616c-b4eb-469d-a25c-2ff8b13eeb1e
+
+
+ 51f2d5d8-ea4d-4064-8892-82951750031e
+ db007a87-7b0a-416f-bf30-ccf10c265e5e
+
+
+ e68182ea-4237-4383-967f-90c1e3370bc7
+ de40bd20-2175-4d6f-a131-e4ba036aaf5f
+
+
+ fb282519-d103-4dd3-bc12-cb271d631dfc
+ b26c5d95-9559-4a74-bdde-db40d73f3596
+
+
+
+ БотДемо
+
+
+ ru
+ Бот демо
+
+
+
+
+ Version8_3_24
+ ManagedApplication
+
+ PlatformApplication
+
+ Russian
+
+
+
+ Version8_3_24
+ Language.Русский
+ Managed
+ NotAutoFree
+ DontUse
+ DontUse
+ TaxiEnableVersion8_2
+ Normal
+
+
+
+ Русский
+ ОповещенияПользователейОСобытиях
+
+
+
diff --git a/tests/skills/cases/cf-info/fixtures/with-bot/Languages/Русский.xml b/tests/skills/cases/cf-info/fixtures/with-bot/Languages/Русский.xml
new file mode 100644
index 00000000..21119ca7
--- /dev/null
+++ b/tests/skills/cases/cf-info/fixtures/with-bot/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
diff --git a/tests/skills/cases/cf-info/with-bot.json b/tests/skills/cases/cf-info/with-bot.json
new file mode 100644
index 00000000..312e5a4b
--- /dev/null
+++ b/tests/skills/cases/cf-info/with-bot.json
@@ -0,0 +1,5 @@
+{
+ "name": "Bot попадает в состав конфигурации",
+ "setup": "fixture:with-bot",
+ "expect": { "stdoutContains": "Боты" }
+}
diff --git a/tests/skills/cases/cf-validate/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml b/tests/skills/cases/cf-validate/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml
new file mode 100644
index 00000000..0c700217
--- /dev/null
+++ b/tests/skills/cases/cf-validate/fixtures/with-bot/Bots/ОповещенияПользователейОСобытиях.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ ОповещенияПользователейОСобытиях
+
+
+ true
+
+
+
+
diff --git a/tests/skills/cases/cf-validate/fixtures/with-bot/Configuration.xml b/tests/skills/cases/cf-validate/fixtures/with-bot/Configuration.xml
new file mode 100644
index 00000000..f4ad7c07
--- /dev/null
+++ b/tests/skills/cases/cf-validate/fixtures/with-bot/Configuration.xml
@@ -0,0 +1,68 @@
+
+
+
+
+
+ 9cd510cd-abfc-11d4-9434-004095e12fc7
+ 2145bb60-cbf8-459a-aa10-bea7f44e3f2f
+
+
+ 9fcd25a0-4822-11d4-9414-008048da11f9
+ 6a26f594-55f0-4be3-ac78-98f735640668
+
+
+ e3687481-0a87-462c-a166-9f34594f9bba
+ 7a4686f3-b998-4656-8cba-2dd53cca2c29
+
+
+ 9de14907-ec23-4a07-96f0-85521cb6b53b
+ 1078616c-b4eb-469d-a25c-2ff8b13eeb1e
+
+
+ 51f2d5d8-ea4d-4064-8892-82951750031e
+ db007a87-7b0a-416f-bf30-ccf10c265e5e
+
+
+ e68182ea-4237-4383-967f-90c1e3370bc7
+ de40bd20-2175-4d6f-a131-e4ba036aaf5f
+
+
+ fb282519-d103-4dd3-bc12-cb271d631dfc
+ b26c5d95-9559-4a74-bdde-db40d73f3596
+
+
+
+ БотДемо
+
+
+ ru
+ Бот демо
+
+
+
+
+ Version8_3_24
+ ManagedApplication
+
+ PlatformApplication
+
+ Russian
+
+
+
+ Version8_3_24
+ Language.Русский
+ Managed
+ NotAutoFree
+ DontUse
+ DontUse
+ TaxiEnableVersion8_2
+ Normal
+
+
+
+ Русский
+ ОповещенияПользователейОСобытиях
+
+
+
diff --git a/tests/skills/cases/cf-validate/fixtures/with-bot/Languages/Русский.xml b/tests/skills/cases/cf-validate/fixtures/with-bot/Languages/Русский.xml
new file mode 100644
index 00000000..21119ca7
--- /dev/null
+++ b/tests/skills/cases/cf-validate/fixtures/with-bot/Languages/Русский.xml
@@ -0,0 +1,16 @@
+
+
+
+
+ Русский
+
+
+ ru
+ Русский
+
+
+
+ ru
+
+
+
diff --git a/tests/skills/cases/cf-validate/with-bot.json b/tests/skills/cases/cf-validate/with-bot.json
new file mode 100644
index 00000000..b2889993
--- /dev/null
+++ b/tests/skills/cases/cf-validate/with-bot.json
@@ -0,0 +1,4 @@
+{
+ "name": "Bot в ChildObjects проходит валидацию",
+ "setup": "fixture:with-bot"
+}
diff --git a/tests/skills/runner.mjs b/tests/skills/runner.mjs
index ec9790c0..8a1dec65 100644
--- a/tests/skills/runner.mjs
+++ b/tests/skills/runner.mjs
@@ -292,7 +292,7 @@ function buildArgs(skillConfig, caseData, workDir, inputFilePath, runtime) {
const UUID_RE = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
-function normalizeXmlContent(text) {
+function normalizeXmlContent(text, opts = {}) {
let s = text;
// 1. XML declaration: normalize quotes and encoding case
s = s.replace(
@@ -301,8 +301,13 @@ function normalizeXmlContent(text) {
);
// 2. Remove
(CR encoded as XML entity by Python etree)
s = s.replace(/
/g, '');
- // 3. Strip xmlns declarations (Python etree strips unused ones)
- s = s.replace(/\s+xmlns(?::[\w]+)?="[^"]*"/g, '');
+ // 3. Strip xmlns declarations (Python etree strips unused ones).
+ // Skipped for Configuration.xml: those declarations are load-bearing (they back
+ // xsi:type values like app:ApplicationUsePurpose in UsePurposes) and dropping them
+ // is exactly the corruption of issue #38 — keeping them lets the test guard against it.
+ if (!opts.keepXmlns) {
+ s = s.replace(/\s+xmlns(?::[\w]+)?="[^"]*"/g, '');
+ }
// 4. Normalize self-closing tags: remove space before />
s = s.replace(/\s*\/>/g, '/>');
// 5. Collapse whitespace between tags: "> \n\t <" → "><"
@@ -314,14 +319,15 @@ function normalizeXmlContent(text) {
return s;
}
-function normalizeContent(text, config) {
+function normalizeContent(text, config, relFile) {
// Strip BOM
let s = text.replace(/^\uFEFF/, '');
// Normalize line endings
s = s.replace(/\r\n/g, '\n');
// Normalize XML differences (Python etree serialization quirks)
if (config?.runtime === 'python') {
- s = normalizeXmlContent(s);
+ const base = relFile ? relFile.split(/[\\/]/).pop() : '';
+ s = normalizeXmlContent(s, { keepXmlns: base === 'Configuration.xml' });
}
// Normalize UUIDs
@@ -403,8 +409,8 @@ function compareSnapshot(workDir, snapshotDir, snapshotConfig) {
const actualRaw = readFileSync(actualPath, 'utf8');
const snapshotRaw = readFileSync(snapshotPath, 'utf8');
- const actual = normalizeContent(actualRaw, snapshotConfig);
- const expected = normalizeContent(snapshotRaw, snapshotConfig);
+ const actual = normalizeContent(actualRaw, snapshotConfig, relFile);
+ const expected = normalizeContent(snapshotRaw, snapshotConfig, relFile);
if (actual !== expected) {
// Find first differing line
@@ -446,7 +452,7 @@ function updateSnapshot(workDir, snapshotDir, snapshotConfig) {
mkdirSync(dirname(dst), { recursive: true });
const raw = readFileSync(src, 'utf8');
- const normalized = normalizeContent(raw, snapshotConfig);
+ const normalized = normalizeContent(raw, snapshotConfig, relFile);
writeFileSync(dst, normalized, 'utf8');
}
}
diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs
index 42f17036..0689af58 100644
--- a/tests/skills/verify-snapshots.mjs
+++ b/tests/skills/verify-snapshots.mjs
@@ -357,6 +357,16 @@ function buildSkillArgs(skillConfig, caseData, workDir, inputFile, runtime) {
function runPreSteps(preRun, workDir, runtime, log) {
if (!preRun) return;
for (const step of preRun) {
+ // writeFile step — записать произвольный файл в workDir перед запуском скрипта
+ if (step.writeFile) {
+ const wfPath = join(workDir, step.writeFile.path);
+ const wfContent = typeof step.writeFile.content === 'string'
+ ? step.writeFile.content
+ : JSON.stringify(step.writeFile.content, null, 2);
+ writeFileSync(wfPath, wfContent, 'utf8');
+ log(`preRun: writeFile ${step.writeFile.path}`, true);
+ continue;
+ }
const preArgs = [];
for (const [flag, value] of Object.entries(step.args || {})) {
preArgs.push(flag);