diff --git a/.claude/skills/form-compile/scripts/form-compile.ps1 b/.claude/skills/form-compile/scripts/form-compile.ps1
index fb35c14b..6a3b4485 100644
--- a/.claude/skills/form-compile/scripts/form-compile.ps1
+++ b/.claude/skills/form-compile/scripts/form-compile.ps1
@@ -1,4 +1,4 @@
-# form-compile v1.153 — Compile 1C managed form from JSON or object metadata
+# form-compile v1.154 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
param(
[string]$JsonPath,
@@ -5722,6 +5722,8 @@ function Emit-Attributes {
if ($st.keyType) { X "$si$(Esc-Xml "$($st.keyType)")" }
if ($st.keyFields) { foreach ($kf in @($st.keyFields)) { X "$si$(Esc-Xml "$kf")" } }
if ($st.mainTable) { X "$si$(Normalize-MetaTypeRef "$($st.mainTable)")" }
+ # GetInvisibleFieldPresentations — после MainTable (дефолт true; эмитим только при заданном ключе = отклонении false).
+ if ($null -ne $st.getInvisibleFieldPresentations) { X "$si$(if ($st.getInvisibleFieldPresentations){'true'}else{'false'})" }
# AutoSaveUserSettings — после MainTable (дефолт true; эмитим только при заданном ключе = отклонении).
if ($null -ne $st.autoSaveUserSettings) { X "$si$(if ($st.autoSaveUserSettings){'true'}else{'false'})" }
# ListSettings: filter/order/conditionalAppearance (skd-грамматика) + каноничные блок-GUID.
diff --git a/.claude/skills/form-compile/scripts/form-compile.py b/.claude/skills/form-compile/scripts/form-compile.py
index 80682fb2..0afced2e 100644
--- a/.claude/skills/form-compile/scripts/form-compile.py
+++ b/.claude/skills/form-compile/scripts/form-compile.py
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
-# form-compile v1.153 — Compile 1C managed form from JSON or object metadata
+# form-compile v1.154 — Compile 1C managed form from JSON or object metadata
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
import argparse
import copy
@@ -5480,6 +5480,9 @@ def emit_attributes(lines, attrs, indent, conditional_appearance=None):
lines.append(f'{si}{esc_xml(str(kf))}')
if s.get('mainTable'):
lines.append(f'{si}{normalize_meta_type_ref(str(s["mainTable"]))}')
+ # GetInvisibleFieldPresentations — после MainTable (дефолт true; эмитим только при заданном ключе = отклонении false).
+ if s.get('getInvisibleFieldPresentations') is not None:
+ lines.append(f'{si}{"true" if s["getInvisibleFieldPresentations"] else "false"}')
# AutoSaveUserSettings — после MainTable (дефолт true; эмитим только при заданном ключе = отклонении).
if s.get('autoSaveUserSettings') is not None:
lines.append(f'{si}{"true" if s["autoSaveUserSettings"] else "false"}')
diff --git a/.claude/skills/form-decompile/scripts/form-decompile.ps1 b/.claude/skills/form-decompile/scripts/form-decompile.ps1
index 52eb0854..b3e33116 100644
--- a/.claude/skills/form-decompile/scripts/form-decompile.ps1
+++ b/.claude/skills/form-decompile/scripts/form-decompile.ps1
@@ -1,4 +1,4 @@
-# form-decompile v0.128 — Decompile 1C managed Form.xml to JSON DSL (draft)
+# form-decompile v0.129 — Decompile 1C managed Form.xml to JSON DSL (draft)
# Source: https://github.com/Nikolay-Shirokov/cc-1c-skills
# ВНИМАНИЕ: раундтрип не гарантируется. Навык исключён из авто-использования моделью.
param(
@@ -732,7 +732,25 @@ function Build-FilterItem {
$noValueOps = @('filled','notFilled')
- if ($userPresNode -or $valueIsArrayFlag -or $valueTypeAttr -or $fiPres) {
+ # Пустой xs:string right () ≠ отсутствие :
+ # Get-FilterValueWithType маппит наличие пустого/nil right в value='_' (отсутствие → $null).
+ # Shorthand `_` неоднозначен (схлопывает оба, компилятор → нет right). Пробельные значения рвут
+ # shorthand-парсинг (split по пробелам). → форсим объектную форму (value='_' → self-closing;
+ # пробелы — как есть в ).
+ $valNeedsObj = $false
+ if ($rightNodes.Count -eq 1 -and -not $valueIsArrayFlag -and $op -notin $noValueOps) {
+ if ("$value" -eq '_') {
+ # Truly-empty ИЛИ whitespace-only
+ # (PreserveWhitespace=false стрипнул пробелы в '' → Get-FilterValueWithType вернул '_').
+ # Восстанавливаем реальные пробелы из WS-дока (как у whitespace-заголовков).
+ $ws = Resolve-WS $rightNodes[0]
+ if ($ws -and $ws.Length -gt 0 -and $ws.Trim() -eq '') { $value = $ws }
+ $valNeedsObj = $true
+ }
+ elseif ($null -ne $value -and "$value" -match '\s') { $valNeedsObj = $true }
+ }
+
+ if ($userPresNode -or $valueIsArrayFlag -or $valueTypeAttr -or $fiPres -or $valNeedsObj) {
$obj = [ordered]@{ field = $field; op = $op }
if ($op -notin $noValueOps -and $null -ne $value) {
if ($valueIsArrayFlag) {
@@ -2693,6 +2711,8 @@ if ($attrsNode) {
# AutoFillAvailableFields — дефолт true, платформа эмитит только отклонение (false). Захват «как есть».
$afaf = Get-Child $setNode 'AutoFillAvailableFields'; if ($null -ne $afaf) { $so['autoFillAvailableFields'] = ($afaf -eq 'true') }
$mt = Get-Child $setNode 'MainTable'; if ($mt) { $so['mainTable'] = $mt }
+ # GetInvisibleFieldPresentations — дефолт true, платформа эмитит только отклонение (false, корпус 20/20). Факт. значение.
+ $gifp = Get-Child $setNode 'GetInvisibleFieldPresentations'; if ($null -ne $gifp) { $so['getInvisibleFieldPresentations'] = ($gifp -eq 'true') }
# Ключ набора (query-based список): KeyType (RowNumber/FieldValue/RowKey) + KeyField* (0+).
$kt = Get-Child $setNode 'KeyType'; if ($kt) { $so['keyType'] = $kt }
$kfNodes = @($setNode.SelectNodes("lf:KeyField", $ns) | ForEach-Object { $_.InnerText })
diff --git a/docs/form-dsl-spec.md b/docs/form-dsl-spec.md
index 3ec416fe..c2f23c9a 100644
--- a/docs/form-dsl-spec.md
+++ b/docs/form-dsl-spec.md
@@ -943,6 +943,7 @@ Forgiving-синонимы типа: XML-имя (`SpreadSheetDocumentField`) и
| `keyType` | string | Тип ключа набора запросного списка (без `mainTable`): `FieldValue` / `RowKey` / `RowNumber` |
| `keyFields` | array | Поля ключа набора (``, 0+) — для запросного списка без `mainTable`. Эмитятся после параметров |
| `autoSaveUserSettings` | bool | Авто-сохранение пользовательских настроек дин-списка (``, после `MainTable`). **Умолчание `true`** — указывать только для отключения (`false`) |
+| `getInvisibleFieldPresentations` | bool | Получать представления невидимых полей (``, после `MainTable`). **Умолчание `true`** — указывать только для отключения (`false`) |
| `query` | string | Текст запроса (`ManualQuery=true`). Поддерживает `@file.sql` (путь относительно JSON) |
| `dynamicDataRead` | bool | Динамическое считывание. **Умолчание `true`** — указывать только для отключения (`false`) |
| `autoFillAvailableFields` | bool | Автозаполнение доступных полей (``). **Умолчание `true`** — указывать только для отключения (`false`; тогда поля берутся из явного запроса, не авто). Эмитится первым в `` |