diff --git a/.claude/skills/meta-edit/SKILL.md b/.claude/skills/meta-edit/SKILL.md index fcd485283..3ae1505bf 100644 --- a/.claude/skills/meta-edit/SKILL.md +++ b/.claude/skills/meta-edit/SKILL.md @@ -33,7 +33,7 @@ powershell.exe -NoProfile -File "${CLAUDE_SKILL_DIR}/scripts/meta-edit.ps1" -Def | Operation | Inline-операция (альтернатива DefinitionFile) | | Value | Значение для inline-операции | | DefinitionFile | JSON-файл с операциями (альтернатива Operation) | -| NoValidate | Не запускать meta-validate после правки | +| NoValidate | Не запускать валидацию после правки | ## Частые операции diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1 index 1c9a1baa1..5f6db278a 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.ps1 +++ b/.claude/skills/meta-edit/scripts/meta-edit.ps1 @@ -1,4 +1,4 @@ -# meta-edit v1.53 — Edit existing 1C metadata object XML +# meta-edit v1.54 — Edit existing 1C metadata object XML # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills [CmdletBinding(PositionalBinding=$false)] param( @@ -3897,15 +3897,17 @@ Info "Saved: $resolvedPath" # ============================================================ if (-not $NoValidate) { - $validateScript = Join-Path (Join-Path $PSScriptRoot "..\..\meta-validate") "scripts\meta-validate.ps1" + # Внешняя обработка/отчёт — автономный объект, meta-validate его не знает (#108). + $validateSkill = if (@('ExternalDataProcessor','ExternalReport') -contains $script:objType) { "epf-validate" } else { "meta-validate" } + $validateScript = Join-Path (Join-Path $PSScriptRoot "..\..\$validateSkill") "scripts\$validateSkill.ps1" $validateScript = [System.IO.Path]::GetFullPath($validateScript) if (Test-Path $validateScript) { Write-Host "" - Write-Host "--- Running meta-validate ---" -ForegroundColor DarkGray + Write-Host "--- Running $validateSkill ---" -ForegroundColor DarkGray & powershell.exe -NoProfile -File $validateScript -ObjectPath $resolvedPath } else { Write-Host "" - Write-Host "[SKIP] meta-validate not found at: $validateScript" -ForegroundColor DarkGray + Write-Host "[SKIP] $validateSkill not found at: $validateScript" -ForegroundColor DarkGray } } diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py index b4c0971ab..ff918a758 100644 --- a/.claude/skills/meta-edit/scripts/meta-edit.py +++ b/.claude/skills/meta-edit/scripts/meta-edit.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# meta-edit v1.53 — Edit existing 1C metadata object XML +# meta-edit v1.54 — Edit existing 1C metadata object XML # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -3985,16 +3985,20 @@ def main(): # --- Auto-validate --- if not args.NoValidate: + # Внешняя обработка/отчёт — автономный объект, meta-validate его не знает (#108). + validate_skill = "epf-validate" if obj_type in ("ExternalDataProcessor", "ExternalReport") else "meta-validate" script_dir = os.path.dirname(os.path.abspath(__file__)) - validate_script = os.path.normpath(os.path.join(script_dir, "..", "..", "meta-validate", "scripts", "meta-validate.py")) + validate_script = os.path.normpath(os.path.join(script_dir, "..", "..", validate_skill, "scripts", f"{validate_skill}.py")) if os.path.exists(validate_script): print() - print("--- Running meta-validate ---") + print(f"--- Running {validate_skill} ---") python_exe = sys.executable + # Буфер stdout сбросить до запуска: иначе вывод дочернего процесса обгоняет наш. + sys.stdout.flush() subprocess.run([python_exe, validate_script, "-ObjectPath", resolved_path]) else: print() - print(f"[SKIP] meta-validate not found at: {validate_script}") + print(f"[SKIP] {validate_skill} not found at: {validate_script}") # --- Summary --- print() diff --git a/tests/skills/cases/meta-edit/epf-autovalidate.json b/tests/skills/cases/meta-edit/epf-autovalidate.json new file mode 100644 index 000000000..c4bfa26a6 --- /dev/null +++ b/tests/skills/cases/meta-edit/epf-autovalidate.json @@ -0,0 +1,24 @@ +{ + "name": "Внешняя обработка: автопроверка через epf-validate, не meta-validate (#108)", + "setup": "none", + "skipValidation": true, + "preRun": [ + { + "script": "epf-init/scripts/init", + "args": { "-Name": "Проба", "-SrcDir": "{workDir}" } + } + ], + "params": { "objectPath": "Проба.xml", "objectName": "Проба" }, + "input": { + "add": { + "attributes": ["Текст: String(50)"], + "tabularSections": [ + { "name": "Строки", "attrs": ["Сумма: Number(15,2)"] } + ] + } + }, + "expect": { + "stdoutContains": ["--- Running epf-validate ---", "Validation OK"], + "stdoutNotContains": ["Unrecognized metadata type", "meta-validate"] + } +} diff --git a/tests/skills/cases/meta-edit/erf-autovalidate.json b/tests/skills/cases/meta-edit/erf-autovalidate.json new file mode 100644 index 000000000..0bf903018 --- /dev/null +++ b/tests/skills/cases/meta-edit/erf-autovalidate.json @@ -0,0 +1,24 @@ +{ + "name": "Внешний отчёт: автопроверка через epf-validate, не meta-validate (#108)", + "setup": "none", + "skipValidation": true, + "preRun": [ + { + "script": "erf-init/scripts/init", + "args": { "-Name": "ПробаОтчёт", "-SrcDir": "{workDir}" } + } + ], + "params": { "objectPath": "ПробаОтчёт.xml", "objectName": "ПробаОтчёт" }, + "input": { + "add": { + "attributes": ["Текст: String(50)"], + "tabularSections": [ + { "name": "Строки", "attrs": ["Сумма: Number(15,2)"] } + ] + } + }, + "expect": { + "stdoutContains": ["--- Running epf-validate ---", "Validation OK"], + "stdoutNotContains": ["Unrecognized metadata type", "meta-validate"] + } +} diff --git a/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба.xml b/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба.xml new file mode 100644 index 000000000..b0b097bb8 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба.xml @@ -0,0 +1,162 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + Проба + + + ru + Проба + + + + + + + + + + Текст + + + ru + Текст + + + + + xs:string + + 50 + Variable + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + + + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Строки + + + ru + Строки + + + + + DontCheck + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + + + + Сумма + + + ru + Сумма + + + + + xs:decimal + + 15 + 2 + Any + + + false + + + + false + + false + false + + + false + 0 + DontCheck + Items + + + Auto + Auto + + + Auto + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба/Ext/ObjectModule.bsl b/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба/Ext/ObjectModule.bsl new file mode 100644 index 000000000..15543d277 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/epf-autovalidate/Проба/Ext/ObjectModule.bsl @@ -0,0 +1,11 @@ +#Область ОписаниеПеременных + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт.xml b/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт.xml new file mode 100644 index 000000000..f27ccdb50 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт.xml @@ -0,0 +1,168 @@ + + + + + + UUID-002 + UUID-003 + + + UUID-004 + UUID-005 + + + + ПробаОтчёт + + + ru + ПробаОтчёт + + + + + + + + + + + + + + + + Текст + + + ru + Текст + + + + + xs:string + + 50 + Variable + + + false + + + + false + + false + false + + + DontCheck + Items + + + Auto + Auto + + + Auto + + + + + + UUID-008 + UUID-009 + + + UUID-010 + UUID-011 + + + + Строки + + + ru + Строки + + + + + DontCheck + + + + DontCheck + false + false + Auto + + + false + + + Auto + Auto + + false + Use + false + + + + Use + + + + + + + + + + + Сумма + + + ru + Сумма + + + + + xs:decimal + + 15 + 2 + Any + + + false + + + + false + + false + false + + + false + 0 + DontCheck + Items + + + Auto + Auto + + + Auto + + + + + + + \ No newline at end of file diff --git a/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт/Ext/ObjectModule.bsl b/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт/Ext/ObjectModule.bsl new file mode 100644 index 000000000..15543d277 --- /dev/null +++ b/tests/skills/cases/meta-edit/snapshots/erf-autovalidate/ПробаОтчёт/Ext/ObjectModule.bsl @@ -0,0 +1,11 @@ +#Область ОписаниеПеременных + +#КонецОбласти + +#Область ПрограммныйИнтерфейс + +#КонецОбласти + +#Область СлужебныеПроцедурыИФункции + +#КонецОбласти \ No newline at end of file diff --git a/tests/skills/verify-snapshots.mjs b/tests/skills/verify-snapshots.mjs index ce021829d..89c732773 100644 --- a/tests/skills/verify-snapshots.mjs +++ b/tests/skills/verify-snapshots.mjs @@ -713,7 +713,7 @@ const EPF_SKILLS = new Map([ // Skills that produce either an EPF/ERF source or a full Configuration — // route is auto-detected after the main script runs. -const EPF_OR_CONFIG_SKILLS = new Set(['template-add', 'help-add']); +const EPF_OR_CONFIG_SKILLS = new Set(['template-add', 'help-add', 'meta-edit']); // Диагностика падения навыка. Оба потока вместе: ps1 печатает строку ошибки в stdout, py — в // stderr, а лог платформы оба кладут в stdout. Читать только `stderr || stdout` значило на @@ -918,8 +918,12 @@ async function verifyCase(skillName, caseName, skillConfig, caseData, opts) { // setup кейса перекрывает setup навыка — как в runner.mjs. Без этого кейсы с гейтом по версии // формата (empty-config-218/220/221) проверялись на конфигурации 2.17, то есть платформа не // видела ровно того поведения, ради которого кейс написан. + // Кейс навыка «EPF или конфигурация» с setup `none` правит внешнюю обработку: пустая конфигурация + // вокруг неё — ложный PASS (корневой XML обработки платформа при загрузке конфигурации не видит). const caseSetup = typeof caseData.setup === 'string' ? caseData.setup : null; - const setupType = (caseSetup && caseSetup.startsWith('empty-config')) ? caseSetup : (skillConfig.setup || 'empty-config'); + const caseSetupWins = caseSetup && (caseSetup.startsWith('empty-config') || + (caseSetup === 'none' && EPF_OR_CONFIG_SKILLS.has(skillName))); + const setupType = caseSetupWins ? caseSetup : (skillConfig.setup || 'empty-config'); const isStandalone = STANDALONE_SKILLS.has(skillName); let epfExt = EPF_SKILLS.get(skillName); let isEpf = !!epfExt;