diff --git a/.claude/skills/meta-edit/scripts/meta-edit.ps1 b/.claude/skills/meta-edit/scripts/meta-edit.ps1 index 6ee9117a..e2331d05 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.10 — Edit existing 1C metadata object XML (inline mode + complex properties + TS attribute ops + modify-ts) +# meta-edit v1.11 — Edit existing 1C metadata object XML (inline mode + complex properties + TS attribute ops + modify-ts) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [string]$DefinitionFile, @@ -78,7 +78,7 @@ $script:validEnumValues = @{ "Posting" = @("Allow","Deny") "RealTimePosting" = @("Allow","Deny") "EditType" = @("InDialog","InList","BothWays") - "HierarchyType" = @("HierarchyFoldersAndItems","HierarchyItemsOnly") + "HierarchyType" = @("HierarchyFoldersAndItems","HierarchyOfItems") "CodeType" = @("String","Number") "CodeAllowedLength" = @("Variable","Fixed") "NumberType" = @("String","Number") diff --git a/.claude/skills/meta-edit/scripts/meta-edit.py b/.claude/skills/meta-edit/scripts/meta-edit.py index 032406b0..7d496acd 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.10 — Edit existing 1C metadata object XML (inline mode + complex properties + TS attribute ops + modify-ts) +# meta-edit v1.11 — Edit existing 1C metadata object XML (inline mode + complex properties + TS attribute ops + modify-ts) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse @@ -285,7 +285,7 @@ valid_enum_values = { 'Posting': ['Allow', 'Deny'], 'RealTimePosting': ['Allow', 'Deny'], 'EditType': ['InDialog', 'InList', 'BothWays'], - 'HierarchyType': ['HierarchyFoldersAndItems', 'HierarchyItemsOnly'], + 'HierarchyType': ['HierarchyFoldersAndItems', 'HierarchyOfItems'], 'CodeType': ['String', 'Number'], 'CodeAllowedLength': ['Variable', 'Fixed'], 'NumberType': ['String', 'Number'], diff --git a/.claude/skills/meta-validate/scripts/meta-validate.ps1 b/.claude/skills/meta-validate/scripts/meta-validate.ps1 index e8b4cd87..cd99b51b 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.ps1 +++ b/.claude/skills/meta-validate/scripts/meta-validate.ps1 @@ -1,4 +1,4 @@ -# meta-validate v1.5 — Validate 1C metadata object structure +# meta-validate v1.6 — Validate 1C metadata object structure # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -253,7 +253,7 @@ $validPropertyValues = @{ "DataLockControlMode" = @("Automatic","Managed") "FullTextSearch" = @("Use","DontUse") "DefaultPresentation" = @("AsDescription","AsCode") - "HierarchyType" = @("HierarchyFoldersAndItems","HierarchyItemsOnly") + "HierarchyType" = @("HierarchyFoldersAndItems","HierarchyOfItems") "EditType" = @("InDialog","InList","BothWays") "WriteMode" = @("Independent","RecorderSubordinate") "InformationRegisterPeriodicity" = @("Nonperiodical","Second","Day","Month","Quarter","Year","RecorderPosition") diff --git a/.claude/skills/meta-validate/scripts/meta-validate.py b/.claude/skills/meta-validate/scripts/meta-validate.py index f306d520..87f7c8cb 100644 --- a/.claude/skills/meta-validate/scripts/meta-validate.py +++ b/.claude/skills/meta-validate/scripts/meta-validate.py @@ -1,4 +1,4 @@ -# meta-validate v1.5 — Validate 1C metadata object structure (Python port) +# meta-validate v1.6 — Validate 1C metadata object structure (Python port) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -253,7 +253,7 @@ valid_property_values = { "DataLockControlMode": ["Automatic", "Managed"], "FullTextSearch": ["Use", "DontUse"], "DefaultPresentation": ["AsDescription", "AsCode"], - "HierarchyType": ["HierarchyFoldersAndItems", "HierarchyItemsOnly"], + "HierarchyType": ["HierarchyFoldersAndItems", "HierarchyOfItems"], "EditType": ["InDialog", "InList", "BothWays"], "WriteMode": ["Independent", "RecorderSubordinate"], "InformationRegisterPeriodicity": ["Nonperiodical", "Second", "Day", "Month", "Quarter", "Year", "RecorderPosition"], diff --git a/tests/skills/check-enum-drift.mjs b/tests/skills/check-enum-drift.mjs new file mode 100644 index 00000000..3c2c313b --- /dev/null +++ b/tests/skills/check-enum-drift.mjs @@ -0,0 +1,56 @@ +#!/usr/bin/env node +// Анти-дрейф enum-allowlist-ов: сверяет продублированные списки допустимых значений перечислений +// meta-compile (АВТОРИТЕТ) ↔ meta-validate ↔ meta-edit. Навыки автономны (allowlist-ы копируются +// намеренно), поэтому нужен гард от расхождений значений (напр. HierarchyItemsOnly vs HierarchyOfItems). +// Парсит .ps1 (канонический порт). Выход 1 при дрейфе. Запуск: node tests/skills/check-enum-drift.mjs +import { readFileSync } from 'node:fs'; +import { fileURLToPath } from 'node:url'; +import { dirname, join } from 'node:path'; + +const ROOT = join(dirname(fileURLToPath(import.meta.url)), '..', '..'); + +// Извлечь PS1-хэштейбл по имени переменной, распарсить "Prop" = @("v1","v2", ...) +function parsePs1EnumMap(file, varName) { + const text = readFileSync(join(ROOT, file), 'utf8'); + const at = text.indexOf(varName); + if (at < 0) throw new Error(`${varName} not found in ${file}`); + let i = text.indexOf('@{', at) + 2, depth = 1, end = i; + while (i < text.length && depth > 0) { + const c = text[i]; + if (c === '{') depth++; + else if (c === '}') { depth--; if (depth === 0) { end = i; break; } } + i++; + } + const block = text.slice(text.indexOf('@{', at) + 2, end); + const map = {}; + const re = /"([\wА-Яа-яЁё]+)"\s*=\s*@\(([^)]*)\)/g; + let m; + while ((m = re.exec(block)) !== null) { + map[m[1]] = [...m[2].matchAll(/"([^"]*)"/g)].map(v => v[1]); + } + return map; +} + +const compile = parsePs1EnumMap('.claude/skills/meta-compile/scripts/meta-compile.ps1', '$script:validEnumValues'); +const validate = parsePs1EnumMap('.claude/skills/meta-validate/scripts/meta-validate.ps1', '$validPropertyValues'); +const edit = parsePs1EnumMap('.claude/skills/meta-edit/scripts/meta-edit.ps1', '$script:validEnumValues'); + +const eq = (a, b) => a.length === b.length && [...a].sort().join('|') === [...b].sort().join('|'); + +let drift = 0; +for (const [name, map] of [['meta-validate', validate], ['meta-edit', edit]]) { + for (const prop of Object.keys(map)) { + if (compile[prop] && !eq(map[prop], compile[prop])) { + console.log(`DRIFT ${name}.${prop}: [${map[prop].join(', ')}] != meta-compile [${compile[prop].join(', ')}]`); + drift++; + } + } +} +// Информационно: свойства в валидаторе/редакторе, которых НЕТ в авторитете (возможен опечатка-ключ или устаревшее) +for (const [name, map] of [['meta-validate', validate], ['meta-edit', edit]]) { + for (const prop of Object.keys(map)) { + if (!compile[prop]) console.log(`INFO ${name}.${prop} нет в meta-compile.validEnumValues (проверьте ключ)`); + } +} +console.log(drift === 0 ? 'OK — нет дрейфа значений enum-allowlist vs meta-compile' : `\n${drift} DRIFT(s) — свести к meta-compile.`); +process.exit(drift ? 1 : 0);