diff --git a/.claude/skills/cf-edit/SKILL.md b/.claude/skills/cf-edit/SKILL.md index 34809a3e..e2c0e395 100644 --- a/.claude/skills/cf-edit/SKILL.md +++ b/.claude/skills/cf-edit/SKILL.md @@ -32,7 +32,7 @@ powershell.exe -NoProfile -File .claude/skills/cf-edit/scripts/cf-edit.ps1 -Conf | Операция | Формат Value | Описание | |----------|-------------|----------| | `modify-property` | `Ключ=Значение` (batch `;;`) | Изменить свойство | -| `add-childObject` | `Type.Name` (batch `;;`) | Добавить объект в ChildObjects | +| `add-childObject` | `Type.Name` (batch `;;`) | Зарегистрировать уже существующий файл объекта в ChildObjects. Для создания нового объекта используй `/meta-compile`, `/role-compile`, `/subsystem-compile` — они регистрируют автоматически | | `remove-childObject` | `Type.Name` (batch `;;`) | Удалить объект из ChildObjects | | `add-defaultRole` | `Role.Name` или `Name` | Добавить роль по умолчанию | | `remove-defaultRole` | `Role.Name` или `Name` | Удалить роль по умолчанию | diff --git a/.claude/skills/cf-edit/reference.md b/.claude/skills/cf-edit/reference.md index 02c6a36a..57a8c0f9 100644 --- a/.claude/skills/cf-edit/reference.md +++ b/.claude/skills/cf-edit/reference.md @@ -13,7 +13,7 @@ ### Enum | Свойство | Допустимые значения | |----------|---------------------| -| `CompatibilityMode` | `Version8_3_20` ... `Version8_3_27`, `DontUse` | +| `CompatibilityMode` | `Version8_3_20` ... `Version8_3_28`, `Version8_5_1`, `DontUse` | | `ConfigurationExtensionCompatibilityMode` | то же | | `DefaultRunMode` | `ManagedApplication`, `OrdinaryApplication`, `Auto` | | `ScriptVariant` | `Russian`, `English` | @@ -21,7 +21,7 @@ | `ObjectAutonumerationMode` | `NotAutoFree`, `AutoFree` | | `ModalityUseMode` | `DontUse`, `Use`, `UseWithWarnings` | | `SynchronousPlatformExtensionAndAddInCallUseMode` | `DontUse`, `Use`, `UseWithWarnings` | -| `InterfaceCompatibilityMode` | `Taxi`, `TaxiEnableVersion8_2`, `Version8_2` | +| `InterfaceCompatibilityMode` | `Version8_2`, `Version8_2EnableTaxi`, `Taxi`, `TaxiEnableVersion8_2`, `TaxiEnableVersion8_5`, `Version8_5EnableTaxi`, `Version8_5` | | `DatabaseTablespacesUseMode` | `DontUse`, `Use` | | `MainClientApplicationWindowMode` | `Normal`, `Fullscreen`, `Kiosk` | @@ -35,6 +35,10 @@ Формат: `Type.Name` — XML-тип и имя объекта через точку. +**Важно про `add-childObject`**: операция регистрирует в `` Configuration.xml только объект, **файл которого уже существует на диске** (например `Catalogs/Товары.xml`). Если файла нет — скрипт падает с exit 1 и подсказкой. Для создания нового объекта используй профильный навык — `/meta-compile` (Catalog, Document, Enum, Report, регистры и т.д.), `/role-compile` (Role), `/subsystem-compile` (Subsystem). Они создают файл И регистрируют его в Configuration.xml за один вызов. + +Когда `add-childObject` всё-таки нужен: откатили Configuration.xml (или перезаписали из выгрузки БД), а файлы объектов остались — нужно восстановить ссылки в ``. + При добавлении объект вставляется в каноническую позицию: 1. Находит последний элемент того же типа → вставляет после 2. Если тип отсутствует → находит последний элемент предшествующего типа → вставляет после diff --git a/.claude/skills/cf-edit/scripts/cf-edit.ps1 b/.claude/skills/cf-edit/scripts/cf-edit.ps1 index fcf91b47..72e48a24 100644 --- a/.claude/skills/cf-edit/scripts/cf-edit.ps1 +++ b/.claude/skills/cf-edit/scripts/cf-edit.ps1 @@ -1,7 +1,7 @@ -# cf-edit v1.0 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.1 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( - [Parameter(Mandatory)][string]$ConfigPath, + [Parameter(Mandatory)][Alias('Path')][string]$ConfigPath, [string]$DefinitionFile, [ValidateSet("modify-property","add-childObject","remove-childObject","add-defaultRole","remove-defaultRole","set-defaultRoles")] [string]$Operation, @@ -27,6 +27,7 @@ if (Test-Path $ConfigPath -PathType Container) { } if (-not (Test-Path $ConfigPath)) { Write-Error "File not found: $ConfigPath"; exit 1 } $resolvedPath = (Resolve-Path $ConfigPath).Path +$script:configDir = [System.IO.Path]::GetDirectoryName($resolvedPath) # --- Load XML with PreserveWhitespace --- $script:xmlDoc = New-Object System.Xml.XmlDocument @@ -87,6 +88,22 @@ $script:typeOrder = @( "BusinessProcess","Task","IntegrationService" ) +# --- Type → on-disk directory name (plural) --- +$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" + "XDTOPackage"="XDTOPackages"; "WebService"="WebServices"; "HTTPService"="HTTPServices"; "WSReference"="WSReferences" + "EventSubscription"="EventSubscriptions"; "ScheduledJob"="ScheduledJobs"; "SettingsStorage"="SettingsStorages"; "FunctionalOption"="FunctionalOptions" + "FunctionalOptionsParameter"="FunctionalOptionsParameters"; "DefinedType"="DefinedTypes"; "CommonCommand"="CommonCommands"; "CommandGroup"="CommandGroups" + "Constant"="Constants"; "CommonForm"="CommonForms"; "Catalog"="Catalogs"; "Document"="Documents" + "DocumentNumerator"="DocumentNumerators"; "Sequence"="Sequences"; "DocumentJournal"="DocumentJournals"; "Enum"="Enums" + "Report"="Reports"; "DataProcessor"="DataProcessors"; "InformationRegister"="InformationRegisters"; "AccumulationRegister"="AccumulationRegisters" + "ChartOfCharacteristicTypes"="ChartsOfCharacteristicTypes"; "ChartOfAccounts"="ChartsOfAccounts"; "AccountingRegister"="AccountingRegisters" + "ChartOfCalculationTypes"="ChartsOfCalculationTypes"; "CalculationRegister"="CalculationRegisters" + "BusinessProcess"="BusinessProcesses"; "Task"="Tasks"; "IntegrationService"="IntegrationServices" +} + # --- XML manipulation helpers (from subsystem-edit pattern) --- function Get-ChildIndent($container) { foreach ($child in $container.ChildNodes) { @@ -247,6 +264,29 @@ function Do-AddChildObject([string]$batchVal) { exit 1 } + # Check that the referenced object actually exists on disk. + # cf-edit add-childObject is a low-level operation for rare scenarios + # (e.g. restoring a rolled-back Configuration.xml when object files are intact). + # For creating NEW objects, meta-compile/role-compile/subsystem-compile already + # auto-register in Configuration.xml — calling cf-edit add-childObject there is + # unnecessary and error-prone. + $typeDir = $script:typeToDir[$typeName] + $objFile = Join-Path (Join-Path $script:configDir $typeDir) "$objNameVal.xml" + if (-not (Test-Path $objFile)) { + $hintSkill = switch ($typeName) { + "Subsystem" { "subsystem-compile" } + "Role" { "role-compile" } + default { "meta-compile" } + } + Write-Error @" +Object file not found: $typeDir/$objNameVal.xml +cf-edit add-childObject only references objects that already exist on disk. +To create a new $typeName, use $hintSkill (auto-registers in Configuration.xml): + /$hintSkill with {"type":"$typeName","name":"$objNameVal"} +"@ + exit 1 + } + # Dedup check $existing = $false foreach ($child in $script:childObjsEl.ChildNodes) { diff --git a/.claude/skills/cf-edit/scripts/cf-edit.py b/.claude/skills/cf-edit/scripts/cf-edit.py index 39313f06..614902e8 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.0 — Edit 1C configuration root (Configuration.xml) +# cf-edit v1.1 — Edit 1C configuration root (Configuration.xml) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -32,6 +32,22 @@ TYPE_ORDER = [ "BusinessProcess", "Task", "IntegrationService", ] +# Type → on-disk directory name (plural) +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", + "XDTOPackage": "XDTOPackages", "WebService": "WebServices", "HTTPService": "HTTPServices", "WSReference": "WSReferences", + "EventSubscription": "EventSubscriptions", "ScheduledJob": "ScheduledJobs", "SettingsStorage": "SettingsStorages", "FunctionalOption": "FunctionalOptions", + "FunctionalOptionsParameter": "FunctionalOptionsParameters", "DefinedType": "DefinedTypes", "CommonCommand": "CommonCommands", "CommandGroup": "CommandGroups", + "Constant": "Constants", "CommonForm": "CommonForms", "Catalog": "Catalogs", "Document": "Documents", + "DocumentNumerator": "DocumentNumerators", "Sequence": "Sequences", "DocumentJournal": "DocumentJournals", "Enum": "Enums", + "Report": "Reports", "DataProcessor": "DataProcessors", "InformationRegister": "InformationRegisters", "AccumulationRegister": "AccumulationRegisters", + "ChartOfCharacteristicTypes": "ChartsOfCharacteristicTypes", "ChartOfAccounts": "ChartsOfAccounts", "AccountingRegister": "AccountingRegisters", + "ChartOfCalculationTypes": "ChartsOfCalculationTypes", "CalculationRegister": "CalculationRegisters", + "BusinessProcess": "BusinessProcesses", "Task": "Tasks", "IntegrationService": "IntegrationServices", +} + ML_PROPS = ["Synonym", "BriefInformation", "DetailedInformation", "Copyright", "VendorInformationAddress", "ConfigurationInformationAddress"] SCALAR_PROPS = ["Name", "Version", "Vendor", "Comment", "NamePrefix", "UpdateCatalogAddress"] REF_PROPS = ["DefaultLanguage"] @@ -143,7 +159,7 @@ def main(): sys.stdout.reconfigure(encoding="utf-8") sys.stderr.reconfigure(encoding="utf-8") parser = argparse.ArgumentParser(description="Edit 1C configuration root (Configuration.xml)", allow_abbrev=False) - parser.add_argument("-ConfigPath", required=True) + parser.add_argument("-ConfigPath", "-Path", required=True) parser.add_argument("-DefinitionFile", default=None) parser.add_argument("-Operation", default=None, choices=["modify-property", "add-childObject", "remove-childObject", "add-defaultRole", "remove-defaultRole", "set-defaultRoles"]) parser.add_argument("-Value", default=None) @@ -171,6 +187,7 @@ def main(): print(f"File not found: {config_path}", file=sys.stderr) sys.exit(1) resolved_path = os.path.abspath(config_path) + config_dir = os.path.dirname(resolved_path) xml_parser = etree.XMLParser(remove_blank_text=False) tree = etree.parse(resolved_path, xml_parser) @@ -285,6 +302,25 @@ def main(): sys.exit(1) type_idx = TYPE_ORDER.index(type_name) + # Check that the referenced object actually exists on disk. + # cf-edit add-childObject is a low-level operation for rare scenarios + # (e.g. restoring a rolled-back Configuration.xml when object files are intact). + # For creating NEW objects, meta-compile/role-compile/subsystem-compile already + # auto-register in Configuration.xml — calling cf-edit add-childObject there is + # unnecessary and error-prone. + type_dir = TYPE_TO_DIR.get(type_name) + obj_file = os.path.join(config_dir, type_dir, f"{obj_name_val}.xml") + if not os.path.exists(obj_file): + hint_skill = {"Subsystem": "subsystem-compile", "Role": "role-compile"}.get(type_name, "meta-compile") + print( + f"Object file not found: {type_dir}/{obj_name_val}.xml\n" + f"cf-edit add-childObject only references objects that already exist on disk.\n" + f"To create a new {type_name}, use {hint_skill} (auto-registers in Configuration.xml):\n" + f' /{hint_skill} with {{"type":"{type_name}","name":"{obj_name_val}"}}', + file=sys.stderr + ) + sys.exit(1) + # Dedup exists = False for child in child_objs_el: @@ -502,7 +538,7 @@ def main(): if os.path.isfile(validate_script): print() print("--- Running cf-validate ---") - subprocess.run([sys.executable, validate_script, "-ConfigPath", resolved_path]) + subprocess.run([sys.executable, validate_script, "-ConfigPath", "-Path", resolved_path]) # --- Summary --- print() diff --git a/.claude/skills/cf-info/scripts/cf-info.ps1 b/.claude/skills/cf-info/scripts/cf-info.ps1 index c2a9e6fc..adf18ec3 100644 --- a/.claude/skills/cf-info/scripts/cf-info.ps1 +++ b/.claude/skills/cf-info/scripts/cf-info.ps1 @@ -1,7 +1,7 @@ # cf-info v1.0 — Compact summary of 1C configuration root # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( - [Parameter(Mandatory=$true)][string]$ConfigPath, + [Parameter(Mandatory=$true)][Alias('Path')][string]$ConfigPath, [ValidateSet("overview","brief","full")] [string]$Mode = "overview", [int]$Limit = 150, diff --git a/.claude/skills/cf-info/scripts/cf-info.py b/.claude/skills/cf-info/scripts/cf-info.py index 836556a7..0677436a 100644 --- a/.claude/skills/cf-info/scripts/cf-info.py +++ b/.claude/skills/cf-info/scripts/cf-info.py @@ -13,7 +13,7 @@ sys.stderr.reconfigure(encoding="utf-8") # --- Argument parsing --- parser = argparse.ArgumentParser(description="Analyze 1C configuration structure", allow_abbrev=False) -parser.add_argument("-ConfigPath", required=True, help="Path to Configuration.xml or directory") +parser.add_argument("-ConfigPath", "-Path", required=True, help="Path to Configuration.xml or directory") parser.add_argument("-Mode", choices=["overview", "brief", "full"], default="overview", help="Output mode") parser.add_argument("-Limit", type=int, default=150, help="Max lines to show") parser.add_argument("-Offset", type=int, default=0, help="Lines to skip") diff --git a/.claude/skills/cf-validate/scripts/cf-validate.ps1 b/.claude/skills/cf-validate/scripts/cf-validate.ps1 index ad13c404..06d2bcb0 100644 --- a/.claude/skills/cf-validate/scripts/cf-validate.ps1 +++ b/.claude/skills/cf-validate/scripts/cf-validate.ps1 @@ -1,7 +1,8 @@ -# cf-validate v1.1 — Validate 1C configuration root structure +# cf-validate v1.2 — Validate 1C configuration root structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] + [Alias('Path')] [string]$ConfigPath, [switch]$Detailed, @@ -145,17 +146,17 @@ $childTypeDirMap = @{ # Valid enum values for Configuration properties $validEnumValues = @{ - "ConfigurationExtensionCompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28") + "ConfigurationExtensionCompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28","Version8_5_1") "DefaultRunMode" = @("ManagedApplication","OrdinaryApplication","Auto") "ScriptVariant" = @("Russian","English") "DataLockControlMode" = @("Automatic","Managed","AutomaticAndManaged") "ObjectAutonumerationMode" = @("NotAutoFree","AutoFree") "ModalityUseMode" = @("DontUse","Use","UseWithWarnings") "SynchronousPlatformExtensionAndAddInCallUseMode" = @("DontUse","Use","UseWithWarnings") - "InterfaceCompatibilityMode" = @("Taxi","TaxiEnableVersion8_2","Version8_2") + "InterfaceCompatibilityMode" = @("Version8_2","Version8_2EnableTaxi","Taxi","TaxiEnableVersion8_2","TaxiEnableVersion8_5","Version8_5EnableTaxi","Version8_5") "DatabaseTablespacesUseMode" = @("DontUse","Use") "MainClientApplicationWindowMode" = @("Normal","Fullscreen","Kiosk") - "CompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28") + "CompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28","Version8_5_1") } # --- 1. Parse XML --- @@ -203,8 +204,8 @@ if ($root.NamespaceURI -ne $expectedNs) { $version = $root.GetAttribute("version") if (-not $version) { Report-Warn "1. Missing version attribute on MetaDataObject" -} elseif ($version -ne "2.17" -and $version -ne "2.20") { - Report-Warn "1. Unusual version '$version' (expected 2.17 or 2.20)" +} elseif ($version -ne "2.17" -and $version -ne "2.20" -and $version -ne "2.21") { + Report-Warn "1. Unusual version '$version' (expected 2.17, 2.20 or 2.21)" } # Must have Configuration child diff --git a/.claude/skills/cf-validate/scripts/cf-validate.py b/.claude/skills/cf-validate/scripts/cf-validate.py index 0c04ce77..30a901cd 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.1 — Validate 1C configuration XML structure +# cf-validate v1.2 — 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 @@ -82,7 +82,7 @@ VALID_ENUM_VALUES = { 'Version8_3_11', 'Version8_3_12', 'Version8_3_13', 'Version8_3_14', 'Version8_3_15', 'Version8_3_16', 'Version8_3_17', 'Version8_3_18', 'Version8_3_19', 'Version8_3_20', 'Version8_3_21', 'Version8_3_22', 'Version8_3_23', 'Version8_3_24', 'Version8_3_25', - 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', + 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', 'Version8_5_1', ], 'DefaultRunMode': ['ManagedApplication', 'OrdinaryApplication', 'Auto'], 'ScriptVariant': ['Russian', 'English'], @@ -90,7 +90,10 @@ VALID_ENUM_VALUES = { 'ObjectAutonumerationMode': ['NotAutoFree', 'AutoFree'], 'ModalityUseMode': ['DontUse', 'Use', 'UseWithWarnings'], 'SynchronousPlatformExtensionAndAddInCallUseMode': ['DontUse', 'Use', 'UseWithWarnings'], - 'InterfaceCompatibilityMode': ['Taxi', 'TaxiEnableVersion8_2', 'Version8_2'], + 'InterfaceCompatibilityMode': [ + 'Version8_2', 'Version8_2EnableTaxi', 'Taxi', 'TaxiEnableVersion8_2', + 'TaxiEnableVersion8_5', 'Version8_5EnableTaxi', 'Version8_5', + ], 'DatabaseTablespacesUseMode': ['DontUse', 'Use'], 'MainClientApplicationWindowMode': ['Normal', 'Fullscreen', 'Kiosk'], 'CompatibilityMode': [ @@ -100,7 +103,7 @@ VALID_ENUM_VALUES = { 'Version8_3_11', 'Version8_3_12', 'Version8_3_13', 'Version8_3_14', 'Version8_3_15', 'Version8_3_16', 'Version8_3_17', 'Version8_3_18', 'Version8_3_19', 'Version8_3_20', 'Version8_3_21', 'Version8_3_22', 'Version8_3_23', 'Version8_3_24', 'Version8_3_25', - 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', + 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', 'Version8_5_1', ], } @@ -162,7 +165,7 @@ def main(): parser = argparse.ArgumentParser( description='Validate 1C configuration XML structure', allow_abbrev=False ) - parser.add_argument('-ConfigPath', dest='ConfigPath', required=True) + parser.add_argument('-ConfigPath', '-Path', dest='ConfigPath', required=True) parser.add_argument('-Detailed', action='store_true') parser.add_argument('-MaxErrors', dest='MaxErrors', type=int, default=30) parser.add_argument('-OutFile', dest='OutFile', default='') @@ -228,8 +231,8 @@ def main(): version = root.get('version', '') if not version: r.warn('1. Missing version attribute on MetaDataObject') - elif version not in ('2.17', '2.20'): - r.warn(f"1. Unusual version '{version}' (expected 2.17 or 2.20)") + elif version not in ('2.17', '2.20', '2.21'): + r.warn(f"1. Unusual version '{version}' (expected 2.17, 2.20 or 2.21)") # Must have Configuration child cfg_node = None diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 index c186c3f9..099ddac2 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 @@ -1,4 +1,4 @@ -# cfe-borrow v1.2 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.3 — Borrow objects from configuration into extension (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][string]$ExtensionPath, @@ -316,6 +316,25 @@ function Expand-SelfClosingElement($container, $parentIndent) { } } +# --- 7b. Detect format version --- + +function Detect-FormatVersion([string]$dir) { + $d = $dir + while ($d) { + $cfgPath = Join-Path $d "Configuration.xml" + if (Test-Path $cfgPath) { + $head = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8).Substring(0, [Math]::Min(2000, (Get-Item $cfgPath).Length)) + if ($head -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } + $parent = Split-Path $d -Parent + if ($parent -eq $d) { break } + $d = $parent + } + return "2.17" +} + +$script:formatVersion = Detect-FormatVersion $extDir + # --- 8. Namespaces declaration for object XML --- $script:xmlnsDecl = 'xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8.2/managed-application/core" xmlns:cfg="http://v8.1c.ru/8.1/data/enterprise/current-config" xmlns:cmi="http://v8.1c.ru/8.2/managed-application/cmi" xmlns:ent="http://v8.1c.ru/8.1/data/enterprise" xmlns:lf="http://v8.1c.ru/8.2/managed-application/logform" xmlns:style="http://v8.1c.ru/8.1/data/ui/style" xmlns:sys="http://v8.1c.ru/8.1/data/ui/fonts/system" xmlns:v8="http://v8.1c.ru/8.1/data/core" xmlns:v8ui="http://v8.1c.ru/8.1/data/ui" xmlns:web="http://v8.1c.ru/8.1/data/ui/colors/web" xmlns:win="http://v8.1c.ru/8.1/data/ui/colors/windows" xmlns:xen="http://v8.1c.ru/8.3/xcf/enums" xmlns:xpr="http://v8.1c.ru/8.3/xcf/predef" xmlns:xr="http://v8.1c.ru/8.3/xcf/readable" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' @@ -466,7 +485,7 @@ function Borrow-Form { $newFormUuid = [guid]::NewGuid().ToString() $formMetaSb = New-Object System.Text.StringBuilder $formMetaSb.AppendLine("") | Out-Null - $formMetaSb.AppendLine("") | Out-Null + $formMetaSb.AppendLine("") | Out-Null $formMetaSb.AppendLine("`t
") | Out-Null $formMetaSb.AppendLine("`t`t") | Out-Null $formMetaSb.AppendLine("`t`t") | Out-Null @@ -498,7 +517,7 @@ function Borrow-Form { $srcFormEl = $srcFormDoc.DocumentElement $formVersion = $srcFormEl.GetAttribute("version") - if (-not $formVersion) { $formVersion = "2.17" } + if (-not $formVersion) { $formVersion = $script:formatVersion } # Find direct children: form properties, AutoCommandBar, ChildItems $srcAutoCmd = $null @@ -1529,7 +1548,7 @@ function Build-BorrowedObjectXml { $sb = New-Object System.Text.StringBuilder $sb.AppendLine("") | Out-Null - $sb.AppendLine("") | Out-Null + $sb.AppendLine("") | Out-Null $sb.AppendLine("`t<${typeName} uuid=`"${newUuid}`">") | Out-Null # InternalInfo diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index 0140da1c..7ba8ade9 100644 --- a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py +++ b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# cfe-borrow v1.2 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.3 — Borrow objects from configuration into extension (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -254,6 +254,22 @@ XMLNS_DECL = ( ) +def detect_format_version(d): + while d: + cfg_path = os.path.join(d, "Configuration.xml") + if os.path.isfile(cfg_path): + with open(cfg_path, "r", encoding="utf-8-sig") as f: + head = f.read(2000) + m = re.search(r']+version="(\d+\.\d+)"', head) + if m: + return m.group(1) + parent = os.path.dirname(d) + if parent == d: + break + d = parent + return "2.17" + + def get_child_indent(container): if container.text and "\n" in container.text: after_nl = container.text.rsplit("\n", 1)[-1] @@ -365,6 +381,8 @@ def main(): cfg_resolved = os.path.abspath(cfg_path) cfg_dir = os.path.dirname(cfg_resolved) + format_version = detect_format_version(ext_dir) + # --- 2. Load extension Configuration.xml --- xml_parser = etree.XMLParser(remove_blank_text=False) tree = etree.parse(ext_resolved, xml_parser) @@ -501,7 +519,7 @@ def main(): lines = [] lines.append('') - lines.append(f'') + lines.append(f'') lines.append(f'\t<{type_name} uuid="{new_uuid_val}">') lines.append(internal_info_xml) lines.append("\t\t") @@ -1086,7 +1104,7 @@ def main(): new_form_uuid = new_guid() form_meta_lines = [ '', - f'', + f'', f'\t', '\t\t', '\t\t', @@ -1113,7 +1131,7 @@ def main(): src_form_tree = etree.parse(src_form_xml_path, src_form_parser) src_form_el = src_form_tree.getroot() - form_version = src_form_el.get("version", "2.17") + form_version = src_form_el.get("version", format_version) src_auto_cmd = None form_props = [] diff --git a/.claude/skills/cfe-validate/scripts/cfe-validate.ps1 b/.claude/skills/cfe-validate/scripts/cfe-validate.ps1 index 2d5672f9..2b6d5738 100644 --- a/.claude/skills/cfe-validate/scripts/cfe-validate.ps1 +++ b/.claude/skills/cfe-validate/scripts/cfe-validate.ps1 @@ -1,7 +1,8 @@ -# cfe-validate v1.3 — Validate 1C configuration extension structure (CFE) +# cfe-validate v1.4 — Validate 1C configuration extension structure (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] + [Alias('Path')] [string]$ExtensionPath, [switch]$Detailed, @@ -145,10 +146,10 @@ $childTypeDirMap = @{ # Valid enum values for extension properties $validEnumValues = @{ - "ConfigurationExtensionCompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28") + "ConfigurationExtensionCompatibilityMode" = @("DontUse","Version8_1","Version8_2_13","Version8_2_16","Version8_3_1","Version8_3_2","Version8_3_3","Version8_3_4","Version8_3_5","Version8_3_6","Version8_3_7","Version8_3_8","Version8_3_9","Version8_3_10","Version8_3_11","Version8_3_12","Version8_3_13","Version8_3_14","Version8_3_15","Version8_3_16","Version8_3_17","Version8_3_18","Version8_3_19","Version8_3_20","Version8_3_21","Version8_3_22","Version8_3_23","Version8_3_24","Version8_3_25","Version8_3_26","Version8_3_27","Version8_3_28","Version8_5_1") "DefaultRunMode" = @("ManagedApplication","OrdinaryApplication","Auto") "ScriptVariant" = @("Russian","English") - "InterfaceCompatibilityMode" = @("Taxi","TaxiEnableVersion8_2","Version8_2") + "InterfaceCompatibilityMode" = @("Version8_2","Version8_2EnableTaxi","Taxi","TaxiEnableVersion8_2","TaxiEnableVersion8_5","Version8_5EnableTaxi","Version8_5") } # --- 1. Parse XML --- @@ -196,8 +197,8 @@ if ($root.NamespaceURI -ne $expectedNs) { $version = $root.GetAttribute("version") if (-not $version) { Report-Warn "1. Missing version attribute on MetaDataObject" -} elseif ($version -ne "2.17" -and $version -ne "2.20") { - Report-Warn "1. Unusual version '$version' (expected 2.17 or 2.20)" +} elseif ($version -ne "2.17" -and $version -ne "2.20" -and $version -ne "2.21") { + Report-Warn "1. Unusual version '$version' (expected 2.17, 2.20 or 2.21)" } # Must have Configuration child diff --git a/.claude/skills/cfe-validate/scripts/cfe-validate.py b/.claude/skills/cfe-validate/scripts/cfe-validate.py index 5818b109..870851e7 100644 --- a/.claude/skills/cfe-validate/scripts/cfe-validate.py +++ b/.claude/skills/cfe-validate/scripts/cfe-validate.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# cfe-validate v1.3 — Validate 1C configuration extension XML structure (CFE) +# cfe-validate v1.4 — Validate 1C configuration extension XML structure (CFE) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills """Validates extension Configuration.xml: root, InternalInfo, extension properties, ChildObjects, borrowed objects.""" import sys, os, argparse, re @@ -82,11 +82,14 @@ VALID_ENUM_VALUES = { 'Version8_3_11', 'Version8_3_12', 'Version8_3_13', 'Version8_3_14', 'Version8_3_15', 'Version8_3_16', 'Version8_3_17', 'Version8_3_18', 'Version8_3_19', 'Version8_3_20', 'Version8_3_21', 'Version8_3_22', 'Version8_3_23', 'Version8_3_24', 'Version8_3_25', - 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', + 'Version8_3_26', 'Version8_3_27', 'Version8_3_28', 'Version8_5_1', ], 'DefaultRunMode': ['ManagedApplication', 'OrdinaryApplication', 'Auto'], 'ScriptVariant': ['Russian', 'English'], - 'InterfaceCompatibilityMode': ['Taxi', 'TaxiEnableVersion8_2', 'Version8_2'], + 'InterfaceCompatibilityMode': [ + 'Version8_2', 'Version8_2EnableTaxi', 'Taxi', 'TaxiEnableVersion8_2', + 'TaxiEnableVersion8_5', 'Version8_5EnableTaxi', 'Version8_5', + ], } EXPECTED_NS = 'http://v8.1c.ru/8.3/MDClasses' @@ -147,7 +150,7 @@ def main(): parser = argparse.ArgumentParser( description='Validate 1C configuration extension XML structure (CFE)', allow_abbrev=False ) - parser.add_argument('-ExtensionPath', dest='ExtensionPath', required=True) + parser.add_argument('-ExtensionPath', '-Path', dest='ExtensionPath', required=True) parser.add_argument('-Detailed', action='store_true') parser.add_argument('-MaxErrors', dest='MaxErrors', type=int, default=30) parser.add_argument('-OutFile', dest='OutFile', default='') @@ -213,8 +216,8 @@ def main(): version = root.get('version', '') if not version: r.warn('1. Missing version attribute on MetaDataObject') - elif version not in ('2.17', '2.20'): - r.warn(f"1. Unusual version '{version}' (expected 2.17 or 2.20)") + elif version not in ('2.17', '2.20', '2.21'): + r.warn(f"1. Unusual version '{version}' (expected 2.17, 2.20 or 2.21)") # Must have Configuration child cfg_node = None diff --git a/.claude/skills/db-create/SKILL.md b/.claude/skills/db-create/SKILL.md index f98c940c..519b4a6e 100644 --- a/.claude/skills/db-create/SKILL.md +++ b/.claude/skills/db-create/SKILL.md @@ -1,6 +1,6 @@ --- name: db-create -description: Создание информационной базы 1С. Используй когда пользователь просит создать базу, новую ИБ, пустую базу +description: Создание информационной базы 1С. Используй когда нужно создать базу, новую ИБ, пустую базу argument-hint: allowed-tools: - Bash diff --git a/.claude/skills/db-dump-cf/SKILL.md b/.claude/skills/db-dump-cf/SKILL.md index f7f4f0df..2ccbf765 100644 --- a/.claude/skills/db-dump-cf/SKILL.md +++ b/.claude/skills/db-dump-cf/SKILL.md @@ -1,6 +1,6 @@ --- name: db-dump-cf -description: Выгрузка конфигурации 1С в CF-файл. Используй когда пользователь просит выгрузить конфигурацию в CF, сохранить конфигурацию, сделать бэкап CF +description: Выгрузка конфигурации 1С в CF-файл. Используй когда нужно выгрузить конфигурацию в CF, сохранить конфигурацию, сделать бэкап CF argument-hint: "[database] [output.cf]" allowed-tools: - Bash diff --git a/.claude/skills/db-dump-xml/SKILL.md b/.claude/skills/db-dump-xml/SKILL.md index 3e6df550..07024f99 100644 --- a/.claude/skills/db-dump-xml/SKILL.md +++ b/.claude/skills/db-dump-xml/SKILL.md @@ -1,6 +1,6 @@ --- name: db-dump-xml -description: Выгрузка конфигурации 1С в XML-файлы. Используй когда пользователь просит выгрузить конфигурацию в файлы, XML, исходники, DumpConfigToFiles +description: Выгрузка конфигурации 1С в XML-файлы. Используй когда нужно выгрузить конфигурацию в файлы, XML, исходники, DumpConfigToFiles argument-hint: "[database] [outputDir]" allowed-tools: - Bash diff --git a/.claude/skills/db-list/SKILL.md b/.claude/skills/db-list/SKILL.md index 1669159b..41e0cb26 100644 --- a/.claude/skills/db-list/SKILL.md +++ b/.claude/skills/db-list/SKILL.md @@ -1,6 +1,6 @@ --- name: db-list -description: Управление реестром баз данных 1С (.v8-project.json). Используй когда пользователь говорит про базы данных, список баз, "добавь базу", "какие базы есть" +description: Управление реестром баз данных 1С (.v8-project.json). Используй когда нужно работать с реестром баз — список баз, зарегистрировать базу в реестре, какие базы есть argument-hint: "[add|remove|show]" allowed-tools: - Read diff --git a/.claude/skills/db-load-cf/SKILL.md b/.claude/skills/db-load-cf/SKILL.md index dcc43147..5e7de1c3 100644 --- a/.claude/skills/db-load-cf/SKILL.md +++ b/.claude/skills/db-load-cf/SKILL.md @@ -1,6 +1,6 @@ --- name: db-load-cf -description: Загрузка конфигурации 1С из CF-файла. Используй когда пользователь просит загрузить конфигурацию из CF, восстановить из бэкапа CF +description: Загрузка конфигурации 1С из CF-файла. Используй когда нужно загрузить конфигурацию из CF, восстановить из бэкапа CF argument-hint: [database] allowed-tools: - Bash diff --git a/.claude/skills/db-load-git/SKILL.md b/.claude/skills/db-load-git/SKILL.md index d3cb7cf4..9d80795b 100644 --- a/.claude/skills/db-load-git/SKILL.md +++ b/.claude/skills/db-load-git/SKILL.md @@ -1,6 +1,6 @@ --- name: db-load-git -description: Загрузка изменений из Git в базу 1С. Используй когда пользователь просит загрузить изменения из гита, обновить базу из репозитория, partial load из коммита +description: Загрузка изменений из Git в базу 1С. Используй когда нужно загрузить изменения из гита, обновить базу из репозитория, partial load из коммита argument-hint: "[database] [source]" allowed-tools: - Bash diff --git a/.claude/skills/db-load-xml/SKILL.md b/.claude/skills/db-load-xml/SKILL.md index 1a72f685..8fe089c1 100644 --- a/.claude/skills/db-load-xml/SKILL.md +++ b/.claude/skills/db-load-xml/SKILL.md @@ -1,6 +1,6 @@ --- name: db-load-xml -description: Загрузка конфигурации 1С из XML-файлов. Используй когда пользователь просит загрузить конфигурацию из файлов, XML, исходников, LoadConfigFromFiles +description: Загрузка конфигурации 1С из XML-файлов. Используй когда нужно загрузить конфигурацию из файлов, XML, исходников, LoadConfigFromFiles argument-hint: [database] allowed-tools: - Bash diff --git a/.claude/skills/db-load-xml/scripts/db-load-xml.ps1 b/.claude/skills/db-load-xml/scripts/db-load-xml.ps1 index 27bbda9f..bdbcd9cf 100644 --- a/.claude/skills/db-load-xml/scripts/db-load-xml.ps1 +++ b/.claude/skills/db-load-xml/scripts/db-load-xml.ps1 @@ -1,4 +1,4 @@ -# db-load-xml v1.1 — Load 1C configuration from XML files +# db-load-xml v1.3 — Load 1C configuration from XML files # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills <# .SYNOPSIS @@ -98,7 +98,10 @@ param( [string]$Format = "Hierarchical", [Parameter(Mandatory=$false)] - [switch]$UpdateDB + [switch]$UpdateDB, + + [Parameter(Mandatory=$false)] + [switch]$StrictLog ) $OutputEncoding = [System.Text.Encoding]::UTF8 @@ -213,20 +216,58 @@ try { $process = Start-Process -FilePath $V8Path -ArgumentList $arguments -NoNewWindow -Wait -PassThru $exitCode = $process.ExitCode + # --- Read log --- + $logContent = $null + if (Test-Path $outFile) { + $logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue + } + + # --- Scan log for silent rejections --- + # Platform often writes load-time rejections into /Out but exits with code 0. + # These patterns flag cases where metadata was dropped or rejected silently. + $fatalLogPatterns = @( + 'Неверное свойство объекта метаданных', + 'не входит в состав объекта метаданных', + 'Неизвестное имя типа', + 'Неизвестный объект метаданных', + 'Ни один из документов не является регистратором для регистра', + 'Неверное значение перечисления', + 'не может быть приведен к типу' + ) + $silentFailures = @() + if ($logContent) { + foreach ($line in ($logContent -split "`r?`n")) { + foreach ($pat in $fatalLogPatterns) { + if ($line -match [regex]::Escape($pat)) { + $silentFailures += $line.Trim() + break + } + } + } + } + # --- Result --- + # Default: mirror platform's verdict via exit code. Log content (including any + # rejection warnings) is always printed to stdout for visibility. With -StrictLog, + # elevate exit code to 1 when rejection patterns are found even if platform said 0. if ($exitCode -eq 0) { Write-Host "Load completed successfully" -ForegroundColor Green } else { Write-Host "Error loading configuration (code: $exitCode)" -ForegroundColor Red } - if (Test-Path $outFile) { - $logContent = Get-Content $outFile -Raw -ErrorAction SilentlyContinue - if ($logContent) { - Write-Host "--- Log ---" - Write-Host $logContent - Write-Host "--- End ---" - } + if ($logContent) { + Write-Host "--- Log ---" + Write-Host $logContent + Write-Host "--- End ---" + } + + if ($silentFailures.Count -gt 0) { + $msg = "[warning] log contains $($silentFailures.Count) rejection(s) — platform loaded config but dropped properties/refs" + if (-not $StrictLog) { $msg += " (pass -StrictLog to treat as error)" } + Write-Host $msg -ForegroundColor Yellow + foreach ($f in $silentFailures) { Write-Host " $f" -ForegroundColor Yellow } + if ($StrictLog -and $exitCode -eq 0) { $exitCode = 1 } } exit $exitCode diff --git a/.claude/skills/db-load-xml/scripts/db-load-xml.py b/.claude/skills/db-load-xml/scripts/db-load-xml.py index 60529ad3..e51286b2 100644 --- a/.claude/skills/db-load-xml/scripts/db-load-xml.py +++ b/.claude/skills/db-load-xml/scripts/db-load-xml.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# db-load-xml v1.1 — Load 1C configuration from XML files +# db-load-xml v1.3 — Load 1C configuration from XML files # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -63,6 +63,11 @@ def main(): help="File format (default: Hierarchical)", ) parser.add_argument("-UpdateDB", action="store_true", help="Also update database configuration after load") + parser.add_argument( + "-StrictLog", + action="store_true", + help="Treat silent rejection warnings in the log as errors (elevate exit code to 1)", + ) args = parser.parse_args() # --- Resolve V8Path --- @@ -157,22 +162,60 @@ def main(): ) exit_code = result.returncode + # --- Read log --- + log_content = "" + if os.path.isfile(out_file): + try: + with open(out_file, "r", encoding="utf-8-sig") as f: + log_content = f.read() + except Exception: + log_content = "" + + # --- Scan log for silent rejections --- + # Platform often writes load-time rejections into /Out but exits with code 0. + # These patterns flag cases where metadata was dropped or rejected silently. + fatal_log_patterns = [ + "Неверное свойство объекта метаданных", + "не входит в состав объекта метаданных", + "Неизвестное имя типа", + "Неизвестный объект метаданных", + "Ни один из документов не является регистратором для регистра", + "Неверное значение перечисления", + "не может быть приведен к типу", + ] + silent_failures = [] + if log_content: + for line in log_content.splitlines(): + for pat in fatal_log_patterns: + if pat in line: + silent_failures.append(line.strip()) + break + # --- Result --- + # Default: mirror platform's verdict via exit code. Log content (including any + # rejection warnings) is always printed to stdout for visibility. With -StrictLog, + # elevate exit code to 1 when rejection patterns are found even if platform said 0. if exit_code == 0: print("Load completed successfully") else: print(f"Error loading configuration (code: {exit_code})", file=sys.stderr) - if os.path.isfile(out_file): - try: - with open(out_file, "r", encoding="utf-8-sig") as f: - log_content = f.read() - if log_content: - print("--- Log ---") - print(log_content) - print("--- End ---") - except Exception: - pass + if log_content: + print("--- Log ---") + print(log_content) + print("--- End ---") + + if silent_failures: + suffix = "" if args.StrictLog else " (pass -StrictLog to treat as error)" + print( + f"[warning] log contains {len(silent_failures)} rejection(s) — " + f"platform loaded config but dropped properties/refs{suffix}", + file=sys.stderr, + ) + for f in silent_failures: + print(f" {f}", file=sys.stderr) + if args.StrictLog and exit_code == 0: + exit_code = 1 sys.exit(exit_code) diff --git a/.claude/skills/db-run/SKILL.md b/.claude/skills/db-run/SKILL.md index df00e4f3..262676ed 100644 --- a/.claude/skills/db-run/SKILL.md +++ b/.claude/skills/db-run/SKILL.md @@ -1,6 +1,6 @@ --- name: db-run -description: Запуск 1С:Предприятие. Используй когда пользователь просит запустить 1С, открыть базу, запустить предприятие +description: Запуск 1С:Предприятие. Используй когда нужно запустить 1С, открыть базу, запустить предприятие argument-hint: "[database]" allowed-tools: - Bash diff --git a/.claude/skills/db-update/SKILL.md b/.claude/skills/db-update/SKILL.md index 61a862f3..7d2ff2ee 100644 --- a/.claude/skills/db-update/SKILL.md +++ b/.claude/skills/db-update/SKILL.md @@ -1,6 +1,6 @@ --- name: db-update -description: Обновление конфигурации базы данных 1С. Используй когда пользователь просит обновить БД, применить конфигурацию, UpdateDBCfg +description: Обновление конфигурации базы данных 1С. Используй когда нужно обновить БД, применить конфигурацию, UpdateDBCfg argument-hint: "[database]" allowed-tools: - Bash diff --git a/.claude/skills/epf-add-form/SKILL.md b/.claude/skills/epf-add-form/SKILL.md deleted file mode 100644 index e339b46e..00000000 --- a/.claude/skills/epf-add-form/SKILL.md +++ /dev/null @@ -1,60 +0,0 @@ ---- -name: epf-add-form -description: Добавить управляемую форму к внешней обработке 1С -argument-hint: [Synonym] -allowed-tools: - - Bash - - Read - - Write - - Edit - - Glob - - Grep ---- - -# /epf-add-form — Добавление формы - -Создаёт управляемую форму и регистрирует её в корневом XML обработки. - -## Usage - -``` -/epf-add-form [Synonym] [--main] -``` - -| Параметр | Обязательный | По умолчанию | Описание | -|---------------|:------------:|--------------|-------------------------------------------| -| ProcessorName | да | — | Имя обработки (должна существовать) | -| FormName | да | — | Имя формы | -| Synonym | нет | = FormName | Синоним формы | -| --main | нет | авто | Установить как форму по умолчанию (автоматически для первой формы) | -| SrcDir | нет | `src` | Каталог исходников | - -## Команда - -```powershell -powershell.exe -NoProfile -File .claude/skills/epf-add-form/scripts/add-form.ps1 -ProcessorName "" -FormName "" [-Synonym ""] [-Main] [-SrcDir ""] -``` - -## Что создаётся - -``` -//Forms/ -├── .xml # Метаданные формы (1 UUID) -└── / - └── Ext/ - ├── Form.xml # Описание формы (logform namespace) - └── Form/ - └── Module.bsl # BSL-модуль с 4 регионами -``` - -## Что модифицируется - -- `/.xml` — добавляется `` в `ChildObjects`, обновляется `DefaultForm` (автоматически если это первая форма, или явно при `--main`) - -## Детали - -- FormType: Managed -- UsePurposes: PlatformApplication, MobilePlatformApplication -- AutoCommandBar с id=-1 -- Реквизит "Объект" с MainAttribute=true -- BSL-модуль содержит 5 регионов: ОбработчикиСобытийФормы, ОбработчикиСобытийЭлементовФормы, ОбработчикиКомандФормы, ОбработчикиОповещений, СлужебныеПроцедурыИФункции \ No newline at end of file diff --git a/.claude/skills/epf-add-form/scripts/add-form.ps1 b/.claude/skills/epf-add-form/scripts/add-form.ps1 deleted file mode 100644 index 15266f7d..00000000 --- a/.claude/skills/epf-add-form/scripts/add-form.ps1 +++ /dev/null @@ -1,207 +0,0 @@ -# epf-add-form v1.0 — Add managed form to 1C processor -# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills -param( - [Parameter(Mandatory)] - [string]$ProcessorName, - - [Parameter(Mandatory)] - [string]$FormName, - - [string]$Synonym = $FormName, - - [switch]$Main, - - [string]$SrcDir = "src" -) - -$ErrorActionPreference = "Stop" - -# --- Проверки --- - -$rootXmlPath = Join-Path $SrcDir "$ProcessorName.xml" -if (-not (Test-Path $rootXmlPath)) { - Write-Error "Корневой файл обработки не найден: $rootXmlPath. Сначала выполните epf-init." - exit 1 -} - -$processorDir = Join-Path $SrcDir $ProcessorName -$formsDir = Join-Path $processorDir "Forms" -$formMetaPath = Join-Path $formsDir "$FormName.xml" - -if (Test-Path $formMetaPath) { - Write-Error "Форма уже существует: $formMetaPath" - exit 1 -} - -# --- Создание каталогов --- - -$formDir = Join-Path $formsDir $FormName -$formExtDir = Join-Path $formDir "Ext" -$formModuleDir = Join-Path $formExtDir "Form" - -New-Item -ItemType Directory -Path $formModuleDir -Force | Out-Null - -# --- Кодировка --- - -$encBom = New-Object System.Text.UTF8Encoding($true) -$encNoBom = New-Object System.Text.UTF8Encoding($false) - -# --- 1. Метаданные формы (Forms/.xml) --- - -$formUuid = [guid]::NewGuid().ToString() - -$formMetaXml = @" - - - - - $FormName - - - ru - $Synonym - - - - Managed - false - - PlatformApplication - MobilePlatformApplication - - - - - -"@ - -[System.IO.File]::WriteAllText($formMetaPath, $formMetaXml, $encBom) - -# --- 2. Описание формы (Forms//Ext/Form.xml) --- - -$formXmlPath = Join-Path $formExtDir "Form.xml" - -$formXml = @" - -
- - true - - - - - - cfg:ExternalDataProcessorObject.$ProcessorName - - true - - - -"@ - -[System.IO.File]::WriteAllText($formXmlPath, $formXml, $encBom) - -# --- 3. BSL-модуль (Forms//Ext/Form/Module.bsl) --- - -$modulePath = Join-Path $formModuleDir "Module.bsl" - -$moduleBsl = @" -#Область ОбработчикиСобытийФормы - -#КонецОбласти - -#Область ОбработчикиСобытийЭлементовФормы - -#КонецОбласти - -#Область ОбработчикиКомандФормы - -#КонецОбласти - -#Область ОбработчикиОповещений - -#КонецОбласти - -#Область СлужебныеПроцедурыИФункции - -#КонецОбласти -"@ - -[System.IO.File]::WriteAllText($modulePath, $moduleBsl, $encBom) - -# --- 4. Модификация корневого XML --- - -$rootXmlFull = Resolve-Path $rootXmlPath -$xmlDoc = New-Object System.Xml.XmlDocument -$xmlDoc.PreserveWhitespace = $true -$xmlDoc.Load($rootXmlFull.Path) - -$nsMgr = New-Object System.Xml.XmlNamespaceManager($xmlDoc.NameTable) -$nsMgr.AddNamespace("md", "http://v8.1c.ru/8.3/MDClasses") - -$childObjects = $xmlDoc.SelectSingleNode("//md:ChildObjects", $nsMgr) -if (-not $childObjects) { - Write-Error "Не найден элемент ChildObjects в $rootXmlPath" - exit 1 -} - -# Добавить
перед первым