diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 b/.claude/skills/cfe-borrow/scripts/cfe-borrow.ps1 index aa94d7d6..dfc530be 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.16 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.17 — Borrow objects from configuration into extension (CFE) (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][string]$ExtensionPath, @@ -368,6 +368,14 @@ function Expand-SelfClosingElement($container, $parentIndent) { function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/cfe-borrow/scripts/cfe-borrow.py b/.claude/skills/cfe-borrow/scripts/cfe-borrow.py index a4a4f03d..346487f1 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.16 — Borrow objects from configuration into extension (CFE) +# cfe-borrow v1.17 — Borrow objects from configuration into extension (CFE) (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -309,6 +309,16 @@ XMLNS_DECL = ( def detect_format_version(d): while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/.claude/skills/help-add/scripts/add-help.ps1 b/.claude/skills/help-add/scripts/add-help.ps1 index 4ee4d0d3..77813ac7 100644 --- a/.claude/skills/help-add/scripts/add-help.ps1 +++ b/.claude/skills/help-add/scripts/add-help.ps1 @@ -1,4 +1,4 @@ -# help-add v1.16 — Add built-in help to 1C object +# help-add v1.17 — Add built-in help to 1C object (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -159,8 +159,10 @@ function Detect-FormatVersion([string]$dir) { } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { - $content = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) - $head = $content.Substring(0, [Math]::Min(2000, $content.Length)) + $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) + # Длину среза берём по СТРОКЕ, а не по размеру файла: размер в БАЙТАХ, Substring считает + # СИМВОЛЫ, и на кириллице байт больше — короткий Configuration.xml ронял навык исключением. + $head = $cfgText.Substring(0, [Math]::Min(2000, $cfgText.Length)) if ($head -match ']+version="(\d+\.\d+)"') { return $Matches[1] } } $parent = Split-Path $d -Parent diff --git a/.claude/skills/help-add/scripts/add-help.py b/.claude/skills/help-add/scripts/add-help.py index bad7c0d9..6aaf9f4a 100644 --- a/.claude/skills/help-add/scripts/add-help.py +++ b/.claude/skills/help-add/scripts/add-help.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# help-add v1.16 — Add built-in help to 1C object +# help-add v1.17 — Add built-in help to 1C object (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse diff --git a/.claude/skills/interface-edit/scripts/interface-edit.ps1 b/.claude/skills/interface-edit/scripts/interface-edit.ps1 index 9171539f..f7f89f99 100644 --- a/.claude/skills/interface-edit/scripts/interface-edit.ps1 +++ b/.claude/skills/interface-edit/scripts/interface-edit.ps1 @@ -1,4 +1,4 @@ -# interface-edit v1.13 — Edit 1C CommandInterface.xml +# interface-edit v1.14 — Edit 1C CommandInterface.xml (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)][Alias('Path')][string]$CIPath, @@ -162,6 +162,14 @@ Assert-EditAllowed $CIPath 'editable' function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/interface-edit/scripts/interface-edit.py b/.claude/skills/interface-edit/scripts/interface-edit.py index 0596385e..2cafeaae 100644 --- a/.claude/skills/interface-edit/scripts/interface-edit.py +++ b/.claude/skills/interface-edit/scripts/interface-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# interface-edit v1.13 — Edit 1C CommandInterface.xml +# interface-edit v1.14 — Edit 1C CommandInterface.xml (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -189,6 +189,16 @@ def assert_edit_allowed(target_path, require): def detect_format_version(d): while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/.claude/skills/meta-compile/scripts/meta-compile.ps1 b/.claude/skills/meta-compile/scripts/meta-compile.ps1 index 3604ef90..a8f4d857 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.88 — Compile 1C metadata object from JSON +# meta-compile v1.89 — Compile 1C metadata object from JSON (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -4190,6 +4190,14 @@ $script:xmlnsDecl = 'xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8. function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/meta-compile/scripts/meta-compile.py b/.claude/skills/meta-compile/scripts/meta-compile.py index 1aa3a715..8f8eba32 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.88 — Compile 1C metadata object from JSON +# meta-compile v1.89 — Compile 1C metadata object from JSON (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -4110,6 +4110,16 @@ xmlns_decl = 'xmlns="http://v8.1c.ru/8.3/MDClasses" xmlns:app="http://v8.1c.ru/8 def detect_format_version(d): while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/.claude/skills/role-compile/scripts/role-compile.ps1 b/.claude/skills/role-compile/scripts/role-compile.ps1 index 3d0117ee..21567d56 100644 --- a/.claude/skills/role-compile/scripts/role-compile.ps1 +++ b/.claude/skills/role-compile/scripts/role-compile.ps1 @@ -1,4 +1,4 @@ -# role-compile v1.18 — Compile 1C role from JSON +# role-compile v1.19 — Compile 1C role from JSON (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -644,6 +644,14 @@ if ($def.objects) { function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/role-compile/scripts/role-compile.py b/.claude/skills/role-compile/scripts/role-compile.py index 8cbdfa49..87949750 100644 --- a/.claude/skills/role-compile/scripts/role-compile.py +++ b/.claude/skills/role-compile/scripts/role-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# role-compile v1.18 — Compile 1C role from JSON +# role-compile v1.19 — Compile 1C role from JSON (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -189,6 +189,16 @@ def assert_edit_allowed(target_path, require): def detect_format_version(d): while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 b/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 index 35bcd53e..a8495392 100644 --- a/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 +++ b/.claude/skills/subsystem-compile/scripts/subsystem-compile.ps1 @@ -1,4 +1,4 @@ -# subsystem-compile v1.19 — Create 1C subsystem from JSON definition +# subsystem-compile v1.20 — Create 1C subsystem from JSON definition (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -430,6 +430,14 @@ if ($def.children) { function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/subsystem-compile/scripts/subsystem-compile.py b/.claude/skills/subsystem-compile/scripts/subsystem-compile.py index a725fa50..48cdc8a7 100644 --- a/.claude/skills/subsystem-compile/scripts/subsystem-compile.py +++ b/.claude/skills/subsystem-compile/scripts/subsystem-compile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# subsystem-compile v1.19 — Create 1C subsystem from JSON definition +# subsystem-compile v1.20 — Create 1C subsystem from JSON definition (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -190,6 +190,16 @@ def assert_edit_allowed(target_path, require): def detect_format_version(d): while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 index ddbffff6..4d1b257e 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.ps1 @@ -1,4 +1,4 @@ -# xdto-compile v1.8 — Build a 1C XDTO package from an XML Schema (XSD) +# xdto-compile v1.9 — Build a 1C XDTO package from an XML Schema (XSD) (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory=$true, ParameterSetName='File')] @@ -47,6 +47,14 @@ $V8_NS = "http://v8.1c.ru/8.1/data/core" function Detect-FormatVersion([string]$dir) { $d = $dir while ($d) { + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + $extPath = "$d.xml" + if (Test-Path $extPath) { + $extText = [System.IO.File]::ReadAllText($extPath, [System.Text.Encoding]::UTF8) + $extHead = $extText.Substring(0, [Math]::Min(2000, $extText.Length)) + if ($extHead -match '<(ExternalDataProcessor|ExternalReport)[ >]' -and $extHead -match ']+version="(\d+\.\d+)"') { return $Matches[1] } + } $cfgPath = Join-Path $d "Configuration.xml" if (Test-Path $cfgPath) { $cfgText = [System.IO.File]::ReadAllText($cfgPath, [System.Text.Encoding]::UTF8) diff --git a/.claude/skills/xdto-compile/scripts/xdto-compile.py b/.claude/skills/xdto-compile/scripts/xdto-compile.py index 7911d1d9..2b24d745 100644 --- a/.claude/skills/xdto-compile/scripts/xdto-compile.py +++ b/.claude/skills/xdto-compile/scripts/xdto-compile.py @@ -1,4 +1,4 @@ -# xdto-compile v1.8 — Build a 1C XDTO package from an XML Schema (XSD) (Python port) +# xdto-compile v1.9 — Build a 1C XDTO package from an XML Schema (XSD) (Python port) (+detect_format_version: ветка автономной EPF/ERF) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import json @@ -106,6 +106,16 @@ def detect_format_version(d): Тело — точная копия из остальных навыков (разрешение пути делает вызывающая сторона). """ while d: + # Автономная внешняя обработка/отчёт: своего Configuration.xml у неё нет, версию несёт + # корень самой обработки. Без этого форма и макет внутри обработки 2.21 писались бы 2.17. + ext_path = d + ".xml" + if os.path.isfile(ext_path): + with open(ext_path, "r", encoding="utf-8-sig") as f: + ext_head = f.read(2000) + if re.search(r'<(ExternalDataProcessor|ExternalReport)[ >]', ext_head): + m = re.search(r']+version="(\d+\.\d+)"', ext_head) + if m: + return m.group(1) 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: diff --git a/tests/skills/check-inline-drift.mjs b/tests/skills/check-inline-drift.mjs index 66e06b74..fd29b477 100644 --- a/tests/skills/check-inline-drift.mjs +++ b/tests/skills/check-inline-drift.mjs @@ -88,13 +88,12 @@ const FAMILIES = [ { name: 'detect_format_version', py: 'detect_format_version', ps1: 'Detect-FormatVersion', variants: [ - { id: 'config-only', authority: 'meta-compile', - consumers: ['cfe-borrow', 'interface-edit', 'role-compile', 'subsystem-compile', 'xdto-compile'] }, - { id: 'with-external-root', authority: 'form-compile', - why: 'EPF/ERF не имеет своего Configuration.xml — версию несёт корень самой обработки', - consumers: ['form-add', 'mxl-compile', 'template-add'], consumersPy: ['help-add'] }, - // Тот же алгоритм, отличается только именем переменной — редакторский дрейф PS1-копии. - { id: 'with-external-root-help-add-ps1', authority: 'help-add', consumers: [], port: 'ps1' }, + // Ветка автономной EPF/ERF безвредна для конфигурационных навыков: она срабатывает только + // если <каталог>.xml — корень ExternalDataProcessor/ExternalReport, чего в дереве + // конфигурации не бывает. Поэтому вариант один на всех, переключателя не нужно. + { id: 'base', authority: 'form-compile', + consumers: ['cfe-borrow', 'form-add', 'help-add', 'interface-edit', 'meta-compile', + 'mxl-compile', 'role-compile', 'subsystem-compile', 'template-add', 'xdto-compile'] }, ], }, {