diff --git a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 index bbc0c882..96e276a0 100644 --- a/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 +++ b/.claude/skills/skd-decompile/scripts/skd-decompile.ps1 @@ -1,4 +1,4 @@ -# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft) +# skd-decompile v0.90 — Decompile 1C DCS Template.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills param( [Parameter(Mandatory)] @@ -2494,9 +2494,22 @@ function Build-Structure { return ,$items } +# True when selection/order is just the single auto element ("Auto") that the +# compiler adds by default to every shorthand group — folding such a group back +# to shorthand is bit-perfect (Parse-StructureShorthand re-adds it on compile). +# Disabled auto ({auto,use}), mixed lists ("Поле","Auto") and explicit fields +# are objects / non-singleton lists and won't match → those keep object form. +function Is-AutoOnly($val) { + if ($null -eq $val) { return $false } + $arr = @($val) + if ($arr.Count -ne 1) { return $false } + return ($arr[0] -is [string]) -and ($arr[0] -eq 'Auto') +} + # Try to fold a structure tree into string shorthand "A > B > details". # Conditions: linear chain (each level has exactly one child), each level is -# a plain group with single groupField and no local selection/order/filter. +# a plain group with single groupField and no local filter; selection/order are +# allowed only when they are the default single "Auto" element (see Is-AutoOnly). function Try-StructureShorthand { param($items) if ($items.Count -ne 1) { return $null } @@ -2506,8 +2519,8 @@ function Try-StructureShorthand { # Disallow extras if ($cur.Contains('type') -and $cur['type'] -ne 'group') { return $null } if ($cur.Contains('name')) { return $null } - if ($cur.Contains('selection')) { return $null } - if ($cur.Contains('order')) { return $null } + if ($cur.Contains('selection') -and -not (Is-AutoOnly $cur['selection'])) { return $null } + if ($cur.Contains('order') -and -not (Is-AutoOnly $cur['order'])) { return $null } if ($cur.Contains('filter')) { return $null } if ($cur.Contains('viewMode')) { return $null } if ($cur.Contains('itemsViewMode')) { return $null } diff --git a/.claude/skills/skd-decompile/scripts/skd-decompile.py b/.claude/skills/skd-decompile/scripts/skd-decompile.py index e23d5e4e..a88dc660 100644 --- a/.claude/skills/skd-decompile/scripts/skd-decompile.py +++ b/.claude/skills/skd-decompile/scripts/skd-decompile.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# skd-decompile v0.89 — Decompile 1C DCS Template.xml to JSON DSL (draft) +# skd-decompile v0.90 — Decompile 1C DCS Template.xml to JSON DSL (draft) # Source: https://github.com/Nikolay-Shirokov/cc-1c-skills import argparse import os @@ -2600,6 +2600,17 @@ def build_structure(node, loc): return items +def is_auto_only(val): + # True when selection/order is just the single auto element ("Auto") that the + # compiler adds by default to every shorthand group — folding such a group back + # to shorthand is bit-perfect (parse re-adds it on compile). Disabled auto + # ({auto,use}), mixed lists and explicit fields won't match → keep object form. + if val is None: + return False + arr = val if isinstance(val, list) else [val] + return len(arr) == 1 and isinstance(arr[0], str) and arr[0] == 'Auto' + + def try_structure_shorthand(items): if len(items) != 1: return None @@ -2610,9 +2621,9 @@ def try_structure_shorthand(items): return None if 'name' in cur: return None - if 'selection' in cur: + if 'selection' in cur and not is_auto_only(cur['selection']): return None - if 'order' in cur: + if 'order' in cur and not is_auto_only(cur['order']): return None if 'filter' in cur: return None diff --git a/tests/skills/cases/skd-decompile/snapshots/calc-total-params/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/calc-total-params/decompiled.json index 116c4213..5846ef98 100644 --- a/tests/skills/cases/skd-decompile/snapshots/calc-total-params/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/calc-total-params/decompiled.json @@ -9,5 +9,5 @@ "СлужебныйПар: string @hidden", { "name": "ПорядокОкругления", "type": "EnumRef.Округления", "value": "Перечисление.Округления.Окр1", "availableValues": [{ "value": "Перечисление.Округления.Окр1_00", "presentation": "руб. коп" }, { "value": "Перечисление.Округления.Окр1", "presentation": "руб." }] } ], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/dataset-query-multiline/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/dataset-query-multiline/decompiled.json index 74c181b6..ced46d29 100644 --- a/tests/skills/cases/skd-decompile/snapshots/dataset-query-multiline/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/dataset-query-multiline/decompiled.json @@ -1 +1 @@ -{ "dataSets": [{ "name": "ПродажиПоПериодам", "query": "@decompiled-ПродажиПоПериодам.sql", "fields": ["Номенклатура: CatalogRef.Номенклатура @dimension", "Количество: decimal(15,3)", "Сумма: decimal(15,2)"] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] } \ No newline at end of file +{ "dataSets": [{ "name": "ПродажиПоПериодам", "query": "@decompiled-ПродажиПоПериодам.sql", "fields": ["Номенклатура: CatalogRef.Номенклатура @dimension", "Количество: decimal(15,3)", "Сумма: decimal(15,2)"] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/dataset-types/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/dataset-types/decompiled.json index a0da0e35..8a1ba8ce 100644 --- a/tests/skills/cases/skd-decompile/snapshots/dataset-types/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/dataset-types/decompiled.json @@ -4,5 +4,5 @@ { "name": "Журнал", "objectName": "ЖурналОшибок", "fields": ["Сообщение: string(150)", "Уровень: string"] }, { "name": "Объединение", "items": [{ "name": "Часть1", "query": "ВЫБРАТЬ 1 КАК Поле", "fields": ["Поле: decimal(10,2)"] }, { "name": "Часть2", "query": "ВЫБРАТЬ 2 КАК Поле", "fields": ["Поле: decimal(10,2)"] }] } ], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/field-input-parameters/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/field-input-parameters/decompiled.json index 3338f28a..179d689f 100644 --- a/tests/skills/cases/skd-decompile/snapshots/field-input-parameters/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/field-input-parameters/decompiled.json @@ -10,5 +10,5 @@ ] } ], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/field-order-expression/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/field-order-expression/decompiled.json index f5359ccd..40340dbb 100644 --- a/tests/skills/cases/skd-decompile/snapshots/field-order-expression/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/field-order-expression/decompiled.json @@ -1,4 +1 @@ -{ - "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.ВидыРасчета", "fields": [{ "field": "ВидРасчета", "type": "CatalogRef.ВидыРасчета", "orderExpression": { "expression": "ЕстьNULL(ВидРасчета.Порядок, 10000)", "orderType": "Asc", "autoOrder": false } }] }], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] -} \ No newline at end of file +{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.ВидыРасчета", "fields": [{ "field": "ВидРасчета", "type": "CatalogRef.ВидыРасчета", "orderExpression": { "expression": "ЕстьNULL(ВидРасчета.Порядок, 10000)", "orderType": "Asc", "autoOrder": false } }] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/field-roles-rich/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/field-roles-rich/decompiled.json index 17864a82..6a0b879f 100644 --- a/tests/skills/cases/skd-decompile/snapshots/field-roles-rich/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/field-roles-rich/decompiled.json @@ -1,4 +1,4 @@ { "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ РегистрНакопления.Остатки", "fields": ["Период: date @period", "Контрагент: CatalogRef.Контрагенты @dimension @required", "СуммаНач: decimal(15,2) @balance balanceGroupName=Сумма balanceType=OpeningBalance", "СуммаКон: decimal(15,2) @balance balanceGroupName=Сумма balanceType=ClosingBalance"] }], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/fields-types-and-restrictions/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/fields-types-and-restrictions/decompiled.json index 6c6d69dc..b90535e2 100644 --- a/tests/skills/cases/skd-decompile/snapshots/fields-types-and-restrictions/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/fields-types-and-restrictions/decompiled.json @@ -18,5 +18,5 @@ ] } ], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/minimal-query/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/minimal-query/decompiled.json index 428604b4..8220e79f 100644 --- a/tests/skills/cases/skd-decompile/snapshots/minimal-query/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/minimal-query/decompiled.json @@ -1 +1 @@ -{ "dataSets": [{ "name": "НаборДанных1", "query": "ВЫБРАТЬ Номенклатура.Наименование КАК Наименование ИЗ Справочник.Номенклатура КАК Номенклатура", "fields": ["Наименование"] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] } \ No newline at end of file +{ "dataSets": [{ "name": "НаборДанных1", "query": "ВЫБРАТЬ Номенклатура.Наименование КАК Наименование ИЗ Справочник.Номенклатура КАК Номенклатура", "fields": ["Наименование"] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/template-custom-style/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/template-custom-style/decompiled.json index ded4ea2d..36cced34 100644 --- a/tests/skills/cases/skd-decompile/snapshots/template-custom-style/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/template-custom-style/decompiled.json @@ -1 +1 @@ -{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле: string"] }], "templates": [{ "name": "Заголовок", "style": "myHeader", "rows": [["A"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] } \ No newline at end of file +{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле: string"] }], "templates": [{ "name": "Заголовок", "style": "myHeader", "rows": [["A"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/template-inline-cell-style/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/template-inline-cell-style/decompiled.json index 30ab6076..2b9011a3 100644 --- a/tests/skills/cases/skd-decompile/snapshots/template-inline-cell-style/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/template-inline-cell-style/decompiled.json @@ -1 +1 @@ -{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле: string"] }], "templates": [{ "name": "СмешанныйМакет", "style": "data", "rows": [["A", { "value": "B", "style": "header" }, "C"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] } \ No newline at end of file +{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле: string"] }], "templates": [{ "name": "СмешанныйМакет", "style": "data", "rows": [["A", { "value": "B", "style": "header" }, "C"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/template-no-style/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/template-no-style/decompiled.json index 862b4814..4dbc75bb 100644 --- a/tests/skills/cases/skd-decompile/snapshots/template-no-style/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/template-no-style/decompiled.json @@ -1 +1 @@ -{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле1: string", "Поле2: string"] }], "templates": [{ "name": "БезСтиля", "style": "none", "widths": ["7", "7"], "rows": [["A", "B"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] } \ No newline at end of file +{ "dataSets": [{ "name": "Тест", "query": "ВЫБРАТЬ * ИЗ Справочник.Сотрудники", "fields": ["Поле1: string", "Поле2: string"] }], "templates": [{ "name": "БезСтиля", "style": "none", "widths": ["7", "7"], "rows": [["A", "B"]] }], "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file diff --git a/tests/skills/cases/skd-decompile/snapshots/templates-with-style-merge-drilldown/decompiled.json b/tests/skills/cases/skd-decompile/snapshots/templates-with-style-merge-drilldown/decompiled.json index b64c1a47..3150ed2b 100644 --- a/tests/skills/cases/skd-decompile/snapshots/templates-with-style-merge-drilldown/decompiled.json +++ b/tests/skills/cases/skd-decompile/snapshots/templates-with-style-merge-drilldown/decompiled.json @@ -4,5 +4,5 @@ { "name": "Шапка", "style": "header", "widths": ["20", "30", "25", "25"], "rows": [["Имя", "Сумма", "Поступление", ">"], ["|", "|", "из произв.", "со сч.40"], ["К1", "К2", "К3", "К4"]] }, { "name": "Данные", "style": "data", "widths": ["20", "30", "25", "25"], "rows": [["{Имя}", "{Сумма}", "{Поступление}", "{СчетПрочее}"]], "parameters": [{ "name": "Имя", "expression": "Имя" }, { "name": "Сумма", "expression": "Сумма" }, { "name": "Поступление", "expression": "СуммаПоступления", "drilldown": "СуммаПоступления" }, { "name": "СчетПрочее", "expression": "СчетПрочее" }] } ], - "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": [{ "selection": ["Auto"], "order": ["Auto"] }] } }] + "settingsVariants": [{ "name": "Основной", "settings": { "selection": ["Auto"], "structure": "details" } }] } \ No newline at end of file