Commit Graph

98 Commits

Author SHA1 Message Date
Nick Shirokov 4f9d9aee97 feat(form-compile): группировка колонок таблицы (ColumnGroup)
Новый DSL-ключ columnGroup со значением-ориентацией horizontal/vertical/inCell
для элемента <ColumnGroup> внутри columns таблицы. Поддерживает вложение,
showTitle/showInHeader/width, тихие синонимы ColumnGroup и ГруппаКолонок.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 11:48:35 +03:00
Nick Shirokov 6c60398406 feat(form-compile): авто-вид кнопки по контексту АКП
Кнопки внутри cmdBar/autoCmdBar/popup автоматически получают
CommandBarButton (или CommandBarHyperlink при type="hyperlink") —
указывать вид вручную не нужно. Резолвер прощающий: принимает и
короткие DSL-формы, и XML-имена в любом контексте.

Пример «Диалог загрузки файла» в SKILL.md и тест-кейс file-dialog
переведены на нативный паттерн с autoCmdBar вместо отдельной
горизонтальной группы кнопок внизу формы.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 19:41:43 +03:00
Nick Shirokov dc0382cc06 chore(tests): обновлены снапшоты после meta-compile QuickChoice defaults
Снапшоты ссылочных реквизитов теперь содержат QuickChoice=false
в соответствии с дефолтами по реальным конфигам (см. 07b2ec3).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:43:33 +03:00
Nick Shirokov b1e29253d5 feat(form-compile): RadioButtonField и словарь синонимов типов элементов
Поле переключателя с RadioButtonType (Auto/RadioButtons/Tumbler) и
ChoiceList (массив value+presentation). Толерантно к написанию модели:
русские имена тегов (ПолеПереключателя, RadioButtonField),
ВидПереключателя по-русски (Авто/Переключатель/Тумблер),
Перечисление.X.Y без EnumValue, синоним title для presentation,
автогенерация презентации из имени значения.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 18:43:26 +03:00
Nick Shirokov 07b2ec36af feat(meta-compile): дефолты QuickChoice по реальным конфигам
Catalog/CCT/CoA/CoCT/ExchangePlan: дефолт false (раньше true). Enum: дефолт true (теперь параметризовано). Цифры из acc_8.3.27 + erp_8.3.24 — у Catalog ~95% объектов QuickChoice=false, у Enum ~99% true.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 17:34:16 +03:00
Nick Shirokov b4514dc350 feat(form-compile): AutoMaxWidth=false по умолчанию для multiLine InputField
В реальных формах ERP/БП у ~60% многострочных полей ввода явно стоит
АвтоМаксимальнаяШирина=Ложь. Теперь form-compile проставляет это
автоматически при multiLine: true, если пользователь не задал
autoMaxWidth явно.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 19:05:50 +03:00
Nick Shirokov 8ad5d80f7f feat(form-compile): автоподстановка RowPictureDataPath для DynamicList с MainTable
Document/InformationRegister/AccumulationRegister List-генераторы теперь
прописывают `Список.DefaultPicture` (как делает ERP/БП в 594/600 форм
списка документов). Плюс fallback в эвристике DynamicList-таблицы:
если у главного реквизита есть `settings.mainTable`, поле
подставляется автоматически и для ручного DSL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:39:29 +03:00
Nick Shirokov fc19df604b chore(tests): --help в runner и verify-snapshots, синхронизация README
Чтобы --help/-h/? не запускали полный прогон тестов.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:17:24 +03:00
Nick Shirokov 76800fc92b feat(form-compile): автоген Title из имени для узлов без источника синонима
Реквизиты формы, команды, страницы, попапы и декорации теперь получают Title,
сгенерированный из CamelCase-имени, если в DSL он не задан явно. Поля с path
и кнопки с command по-прежнему опускают Title — синоним подхватится платформой.
Главные реквизиты (Объект/Список/Запись с main=true) исключены.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 18:17:19 +03:00
Nick Shirokov 36cd63d8bb fix(form-compile): AutoTitle=false по умолчанию при заданном Title формы
Когда у формы задан Title (через defn.title или properties.title), эмитим
AutoTitle=false если пользователь явно его не указал. Иначе платформа
добавляет суффикс синонима и получается двойной заголовок (Номенклатура:
Номенклатура). В выгрузках ERP так делает ~95% форм с form-level Title.

Снапшоты form-compile/form-compile-from-object обновлены под новое поведение.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 17:22:48 +03:00
Nick Shirokov e216db5734 fix(form-compile): default TitleLocation=Right для CheckBoxField
Платформенный default TitleLocation для CheckBoxField — Left, что почти
никогда не соответствует UX-ожиданиям. В acc 8.3.27 для CheckBoxField:
Right (явно): 811, без тега (=Left): 406, None: 140, Left: 14, Top: 3 —
доминирующий паттерн «заголовок справа от флажка».

Эмитим <TitleLocation>Right</TitleLocation> по умолчанию для check.
Переопределяется через titleLocation: 'Left' / 'None' / 'Top' / 'Bottom'.

v1.11. Обновил 5 snapshot'ов.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:59:31 +03:00
Nick Shirokov a59be4b914 fix(form-compile): SavedData=true для object/RecordManager главного реквизита
Без <SavedData>true</SavedData> платформа не маркирует форму как modified
при изменении главного реквизита — confirmation dialog при Esc не появляется,
canonical flow «изменил → Esc → Да» сломан.

Правило выведено из реальной выгрузки acc 8.3.27: SavedData ставится только
для редактируемых форм с типом *Object.X (Catalog/Document/ChartOf…/
ExchangePlan/BusinessProcess/Task) или *RecordManager.X. DynamicList/Report/
DataProcessor/ConstantsSet/RecordSet — не трогаем, отдаём решение DSL через
явный savedData: true.

Поднял версию до v1.10. Обновил 5 snapshot'ов (формы элементов/документа).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 16:51:43 +03:00
Nick Shirokov 4b8d3b67dc fix(tests): platform-verifiable form-info DSL + external setup в verify-snapshots
- form-info/{rich-form,simple-form}: тип реквизита Объект исправлен
  с ExternalDataProcessorObject на DataProcessorObject — preRun создаёт
  обычную обработку, и платформа отвергала несоответствие XDTO-исключением.
- verify-snapshots.mjs: поддержка setup="external:<path>" — копирует
  внешний дамп (выгрузку ERP/БП) в workDir, пропускает cf-init и
  авто-регистрацию объектов через cf-edit. Платформенная загрузка
  целой вендорской конфы скипается — кейсы real-acc-form-* проверяют
  скрипт против реального XML, а не пригодность всей БП к чистой базе.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-02 14:31:18 +03:00
Nick Shirokov 6b63177687 feat(form-compile): не эмитить HorizontalAlign по умолчанию + чистка SKILL.md
- HorizontalAlign не эмитится, если не задан явно через autoCmdBar.horizontalAlign.
  Раньше был хардкод Right; платформенный дефолт — Left, эталонные формы
  типовых (Бригады/ФормаСписка) тег вообще не содержат.
- horizontalAlign принимает Left/Center/Right.
- SKILL.md: убран раздел «Эвристики компилятора» (внутренняя кухня скрипта),
  сжато описание autoCmdBar и main — модель пишет DSL явно, помощь
  компилятора видна в [INFO]/[WARN]-логе.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:54:57 +03:00
Nick Shirokov 13174b63b1 feat(form-compile): нативная AutoCommandBar формы + autoCmdBar DSL
- Эвристика главной АКП: без cmdBar/autoCmdBar остаётся Autofill=true
  (как в Конфигураторе), с cmdBar — Autofill=false (обратная совместимость).
- Новый элемент autoCmdBar для наполнения главной АКП кастомными кнопками.
- Тихие синонимы commandBar↔cmdBar, autoCommandBar↔autoCmdBar.
- Инференс main-реквизита по типу (*Object.*, *RecordSet.*, DynamicList,
  ConstantsSet) — единственный кандидат проставляется молча с [INFO].
- Эвристика DynamicList → таблица: tableAutofill=false +
  commandBarLocation=None для привязанной таблицы (соответствие ERP).
- Косметика: <Autofill>true</Autofill> не эмитится явно.

Snapshot'ы form-* также обновлены до актуального состояния cf-init
(Ext/ClientApplicationInterface.xml).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 20:46:23 +03:00
Nick Shirokov 42b96bbd21 feat(cf-*): set-home-page + drill-down -Section home-page + form-ref валидация
- cf-edit: новая операция set-home-page перезаписывает Ext/HomePageWorkArea.xml.
  DSL принимает template (OneColumn/TwoColumnsEqualWidth/TwoColumnsVariableWidth),
  left/right с записями форм (строка или объект form/height/visibility/roles).
  Тихая нормализация ссылок: русские типы, 3-сегмент → авто-Form, файловые пути
- cf-info: краткая HP-сводка (template + счётчики) в overview/full, детальный
  вид через -Section home-page (alias -Name) с раскладкой и переопределениями ролей
- cf-validate: Check 9 — валидация ссылок на формы из HomePageWorkArea и
  Default*Form свойств; битая ссылка → error
- reference.md: убран реализационный шум (canonical sort, авто-нормализация форм,
  panelDef detail, секция авто-валидации); путь src/ в примерах вместо репо-специфичных

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 19:13:18 +03:00
Nick Shirokov 336dade274 feat(cf-edit): операция set-panels для раскладки панелей
JSON-DSL уровня имён: алиасы sections/open/favorites/history/functions
для платформенных uuid, объект {group:[...]} для стека (даёт <group>-
вложенность как у Конфигуратора), несколько записей в одной стороне =
соседние теги (рядом). Файл Ext/ClientApplicationInterface.xml
перезаписывается полностью; panelDef для всех 5 панелей пишется всегда.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 17:03:57 +03:00
Nick Shirokov 3c3ed2ff46 feat(cf-init): генерить Ext/ClientApplicationInterface.xml с ERP-дефолтом
Без этого файла веб-клиент 1С рендерит секции icon-only (без подписей),
а web-test их не видит. Дефолтная раскладка как в типовых ERP/БП ≥ 8.3.24:
панель открытых сверху, панель разделов слева; функций/избранного/истории
объявлены через panelDef но не размещены.

Расширил docs/1c-configuration-spec.md § 4.2 моделью раскладки и таблицей
UUID 5 платформенных панелей. Обновил снапшоты cf-init под новый файл.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-01 16:43:39 +03:00
Nick Shirokov d75b4d96ca fix(verify-snapshots): структурные зависимости с preRun и ChartOfAccounts
getStructuralDeps теперь сканирует все inputs (caseData.input + preRun.input),
а не только верхний — без этого регистры, созданные через preRun, оставались
без документа-регистратора и платформа отвергала конфиг с
«Ни один из документов не является регистратором».

Добавлен случай ChartOfAccounts: при maxExtDimensionCount>0 (или непустых
extDimensionAccountingFlags) и без явной ссылки extDimensionTypes
автоматически создаётся стаб ChartOfCharacteristicTypes и линкуется через
meta-edit modify-property уже после preRun. Для этого getStructuralDeps
возвращает теперь { deps, hostEdits }, а в основной поток добавлен Step 3.5
(host-level structural edits).

InformationRegister с writeMode=Subordinate/RecorderSubordinate тоже
получает документ-регистратор.

Полный прогон verify-snapshots: 193/193.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 20:12:12 +03:00
Nick Shirokov 704fbc9f28 feat(verify-snapshots): платформенная верификация mxl-compile
Готовый Template.xml оборачивается в исходники EPF: epf-init создаёт
скелет, template-add регистрирует SpreadsheetDocument-макет, MXL копируется
поверх дефолтного, далее epf-build реально проверяет, что платформа
принимает разметку. mxl-compile убран из STANDALONE_SKILLS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:59:06 +03:00
Nick Shirokov cd74afa5e0 feat(verify-snapshots): платформенная верификация template-add и help-add
После main-скрипта определяется тип артефакта в workDir: Configuration.xml
→ обычная загрузка конфигурации, иначе по корню *.xml выбирается ветка
epf-build (.epf для ExternalDataProcessor, .erf для ExternalReport). Для
кейсов с cf-init теперь configDir переустанавливается на workDir, так что
конфиг действительно грузится в БД, а не пропускается.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 16:42:00 +03:00
Nick Shirokov 370873511d feat(verify-snapshots): платформенная верификация epf-init и erf-init
EPF_SKILLS превращён из «skip» в реальную сборку через epf-build —
строится .epf или .erf по расширению из map. Имя источника берётся
из caseData.params.name. erf-init добавлен в DEFAULT_SKILLS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 15:25:20 +03:00
Nick Shirokov 9ced410d8f feat(verify-snapshots): платформенная верификация skd-edit
skd-edit добавлен в SKD_PLATFORM_VERIFY — результат заворачивается в ERF и
собирается через epf-build, как уже сделано для skd-compile. Резолвер пути
шаблона теперь учитывает params.templatePath (фолбэк: outputPath, Template.xml).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-26 15:09:38 +03:00
Nick Shirokov 204a262746 feat(verify-snapshots): реальная платформенная проверка skd-compile
До сих пор для skd-compile (как и других STANDALONE_SKILLS)
verify-snapshots просто запускал скрипт и помечал PASS — без
платформенной нагрузки. Опасный пробел: можно было закоммитить
snapshot, который 1С Designer не примет.

Теперь для skd-compile snapshot оборачивается во внешний отчёт
(erf-init --WithSKD), Template.xml подменяется на сгенерированный
кейсом, и запускается erf-build. Платформа парсит схему — если
принимает, кейс PASS; если отклоняет, в errors попадает её stderr.
Ссылочные типы (CatalogRef.X и т.п.) не требуют реальной базы:
epf-build сам поднимает временную stub-конфигурацию.

Если v8 недоступен — мягкий skip с пометкой "no v8 context".

Замер: 21 кейс x ~5s avg = ~110s на полный verify-snapshots
--skill skd-compile. Все 21 текущих кейса проходят — значит каждый
snapshot гарантированно платформо-валиден.

Аналогичная обёртка для mxl-compile / role-compile — отдельной
задачей по образцу.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:56:13 +03:00
Nick Shirokov 576f6dda8a feat(skd-compile): многоязычный title/presentation (объектная форма)
Везде, где DSL принимает title/presentation, теперь поддерживается
объектная форма с языками: "title": { "ru": "...", "en": "..." }.
Строка по-прежнему работает как ru-only.

Покрыто: field title, calculatedField title, parameter title/presentation,
settingsVariant title/presentation (root и в structure-items),
availableValue title/presentation, userSettingPresentation в filter/dataParameter,
mltext-значения в conditionalAppearance.appearance (ключи Текст/Заголовок/Формат).

Реализация:
- Хелпер emit_mltext / Emit-MLText расширен — принимает string|dict и
  итерирует по языкам.
- 8 inline-блоков LocalStringType в каждом скрипте заменены на вызовы
  хелпера (унификация — побочный эффект, бенефит на будущее).
- На входе сняты str()/"$()" коэрции для title/presentation, чтобы dict
  доходил до хелпера живым.

- SKILL.md: одна строка про объектную форму title.
- tests: новый snapshot-кейс multi-lang-title (5 узлов с ru+en).
- Версия v1.21.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:30:37 +03:00
Nick Shirokov 1a5b788305 feat(skd-compile): составной тип поля valueType (массив типов)
В объектной форме поля DataSet ключ "type" теперь принимает массив:
"type": ["CatalogRef.A", "CatalogRef.B"] — генерирует несколько <v8:Type>
внутри одного <valueType>. Типичный паттерн в ERP для полей-расшифровок
с составным ссылочным типом.

Shorthand остаётся одно-типовым (без перегрузки). Квалификаторы
((N)/(D,F)) применяются к каждому элементу массива независимо.

- skd-compile.ps1/py: Emit-ValueType/emit_value_type диспатчат на
  Emit-SingleValueType при строке или итерируют при массиве; field-парсер
  сохраняет массив, не приводя к строке. Версия v1.20.
- SKILL.md: один абзац после описания типов.
- tests: новый snapshot-кейс field-multi-type на 3 ссылочных типа.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 18:04:49 +03:00
Nick Shirokov b39da27d20 docs(skd-compile): описать presentationExpression и appearance на поле
В DSL skd-compile уже поддерживались ключи presentationExpression и
appearance в объектной форме поля DataSet, но в SKILL.md они не были
задокументированы — фичи существовали де-факто, но обнаружить их можно
было только чтением скрипта.

Заодно зафиксирован детерминизм порядка ключей appearance: PS5.1
hashtable не сохраняет порядок вставки, из-за чего PS- и PY-рантаймы
давали разный XML на одном входе. Заменено на [ordered]@{}.

- SKILL.md: новый блок «Дополнительные ключи объектной формы» в разделе «Поля»
- skd-compile.ps1/py: appearance = [ordered]@{} вместо @{}, версия v1.19
- tests: новый snapshot-кейс field-appearance-and-presentation,
  проходит на обоих рантаймах

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 17:57:04 +03:00
Nick Shirokov eda7279de0 fix(skd-info): -Mode full на схеме без DataSetQuery
Show-Query/show_query при отсутствии DataSetQuery делал exit 1, что
обрывало full режим после Show-Overview — секции fields/resources/
params/variant пользователь не видел. Теперь в full проверяем наличие
Query-набора и при отсутствии печатаем "(no query datasets)" и
продолжаем. Прямой -Mode query сохраняет прежнее поведение.

Воспроизводилось на схемах-приёмниках с одним DataSetObject
(например, ЖурналОшибок в ERP).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 16:38:57 +03:00
Nick Shirokov b7fbede819 fix(tests): починить pre-existing фейлы integration и skd-* snapshots
- build-config/build-epf: заменить runtime-тип FormDataStructure на корректный *Object.XXX
- platform-cfe/config/epf: form-compile принимает -OutputPath (путь до Form.xml), не -FormPath
- skd-edit/info/validate: перегенерированы snapshots после feat(skd-compile) denyIncompleteValues=true (3729b63)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-25 15:48:23 +03:00
Nick Shirokov bdc38caffa refactor(form-add): объединить с epf-add-form, удалить специфичный навык
form-add теперь покрывает и объекты конфигурации, и standalone EPF/ERF
source tree (тип определяется из корневого XML, маппинг типов уже был).

Изменения form-add scaffold:
- Module.bsl: пустые регионы вместо скелета процедуры ПриСозданииНаСервере
- Form.xml: убран <Events> (раньше привязывал OnCreateAtServer к процедуре)
- Form.xml: <SavedData>true</SavedData> теперь условный — ставится для
  Catalog/Document/etc (стандарт ERP, 99% форм), не ставится для
  DataProcessor/Report/External* (где у объекта нет состояния)

Это согласуется с workflow: form-compile перегенерирует Form.xml целиком,
поэтому привязки в scaffold могут стать orphan; пустые регионы +
без Events — корректная стартовая точка, которую form-edit/form-compile
наполняют атомарно.

Удалён навык epf-add-form (директория + тесты), вызовы заменены на
form-add в integration-тестах, в кейсах epf-validate/help-add, в
description epf-init/epf-bsp-init, в docs и README.

Перегенерированы snapshot'ы 5 навыков (form-add, form-compile,
form-edit, form-info, form-validate). Платформенная верификация в 1С 8.3.24
прошла для всех 9 кейсов form-add.

Bump form-add v1.3 → v1.4.
2026-04-25 15:26:54 +03:00
Nick Shirokov 3729b63b89 feat(skd-compile): @autoDates — дефолты use=Always + denyIncompleteValues=true
Производные &НачалоПериода/&КонецПериода требуют заполненный период,
поэтому сам параметр теперь по умолчанию получает use=Always и
denyIncompleteValues=true. В объектной форме явные значения перекрывают.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 12:24:22 +03:00
Nick Shirokov 54d47aadad feat(skd-compile): dataParameters auto — копирование value всех типов (ЕРП-паттерн)
Раньше "auto" копировал только variant для StandardPeriod, остальные типы
теряли значение по умолчанию. Теперь:

- value задан (не-Custom для StandardPeriod) → value + use=true (implicit),
  правильный xsi:type: boolean/decimal/dateTime/string, DesignTimeValue для
  ссылочных типов.
- value отсутствует или StandardPeriod=Custom → <use>false</use>
  + <value xsi:nil="true"/>.

Соответствует тому, как 1С Designer и ЕРП-отчёты персистят
SettingsParameterValue. Тест auto-data-parameters расширен покрытием
decimal/string/ref/nil.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 16:13:04 +03:00
Nick Shirokov 3f23be8219 feat(skd-compile): @autoDates — НачалоПериода/КонецПериода вместо ДатаНачала/ДатаОкончания
Канонический паттерн БСП в Титан/ЕРП-отчётах использует имена
НачалоПериода/КонецПериода (~10:1 по частоте). Выражения
&Период.ДатаНачала/&Период.ДатаОкончания сохранены — это обращение
к внутренним полям StandardPeriod.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 15:51:22 +03:00
Nick Shirokov f5dd677ac8 fix(tests): cf-info/config-with-objects — preRun через meta-compile
Тест сломался с 0d5d345 (ужесточение cf-edit add-childObject: теперь требует, чтобы файл объекта существовал на диске). Там были пофикшены 4 теста cf-edit, но этот кейс cf-info с тем же паттерном в preRun пропустили.

Заменил cf-edit add-childObject на три meta-compile (Catalog.Товары, Document.Заказ, Enum.Статусы) — те сами регистрируют объекты в Configuration.xml и создают файлы. Snapshot перегенерирован.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-17 14:08:37 +03:00
Nick Shirokov be74d224be feat(skd-compile): dataParameters auto — наследовать variant для StandardPeriod
Для параметров типа StandardPeriod в режиме "dataParameters": "auto" эмитируется <dcscor:value> с variant из дефолта параметра (Custom, если не задан) — как это делает 1C Designer при сохранении SettingsParameterValue для периодов.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 21:00:58 +03:00
Nick Shirokov 1b46eb4d85 feat(skd-compile): parameters — title и presentation как синонимы
- parameter принимает presentation как синоним title (1C UI показывает
  подпись параметра как "Представление" — модель по аналогии пишет presentation)
- availableValues[] принимает title как синоним presentation (обратная
  ошибка: модель пишет title по аналогии с самим параметром)

Обе формы пишутся в один и тот же XML-узел. Версии: skd-compile v1.13 → v1.14.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 20:37:00 +03:00
Nick Shirokov 1cea9e794e feat(skd-compile,skd-edit): calculatedFields — shorthand и объектные синонимы
- skd-compile v1.13: Parse-CalcShorthand теперь понимает "[Title]:type=expr#flags"
  (синхронно со skd-edit). Emit-CalcFields принимает name как синоним
  field/dataPath и строковую форму useRestriction ("#noField #noFilter ...").
- skd-edit v1.11: #restrict парсится по known-names pattern — исключает ложные
  срабатывания на # внутри строковых литералов в выражении.

Закрывает три ловушки из upload/bug-skd-compile-calculated-field-datapath.md,
где модель писала name вместо field и строковый useRestriction по аналогии
с shorthand-флагами.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-16 20:31:14 +03:00
Nick Shirokov aedf6df674 fix(form-compile,meta-compile): PY ChartOfAccounts generators — list format + AccountingFlag name extraction
- form-compile.py: rewrite generate_chart_of_accounts_item_dsl and
  generate_chart_of_accounts_folder_dsl from dict-format to list-format
  (array of OrderedDict), matching PS1 canonical output
- meta-compile.py/ps1: extract flag['name'] from AccountingFlags and
  ExtDimensionAccountingFlags dicts instead of stringifying the whole object
- Update snapshots with clean flag names (Валютный/Количественный)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 15:55:33 +03:00
Nick Shirokov 2206c4cf3e fix(form-compile): convert new generators from dict to array DSL format
Root cause: new generators (IR, AccumReg, CoA, CCOCT/EP wrappers) used
OrderedDict for elements/columns, but PS1 compiler expects array format.
ConvertTo-Json→ConvertFrom-Json wraps dict into single PSCustomObject,
not iterable array — so ChildItems were empty.

Converted all new generators to array format matching existing
Document/Catalog patterns: elements=@(), columns=@().

Also fixed CCOCT/EP wrapper inject logic to iterate array elements
instead of dict keys.

PS1: 12/12, PY: 8/12 (minor case/autofill differences in PY port).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 15:11:55 +03:00
Nick Shirokov 8a9f285da9 fix(form-compile): port bugfixes to Python — Number/Date in lists, UserVisible for Ref
Port PS1 bugfixes to Python:
- Document List: add Номер + Дата as first columns
- Hidden Ref: userVisible=false instead of visible=false (both Catalog and Document lists)
- Emitter: support <UserVisible><xr:Common>false</xr:Common></UserVisible>
- Add userVisible to KNOWN_KEYS

Note: new_field_element calls in Python were already correct (no Bug 1 equivalent).
Python snapshots updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 14:55:56 +03:00
Nick Shirokov e5e3f199f2 fix(form-compile): empty forms, missing Number/Date in lists, UserVisible for Ref
Three bugs fixed in --from-object PS1 generators:

1. New-FieldElement called with wrong positional args in IR Record and CoA Item
   generators — hashtable passed as attrName instead of individual fields.
   Result: elements became "System.Collections.Hashtable" → compiler dropped them
   → empty forms. Fixed with named parameters.

2. Document List form missing Number/Date standard columns — only custom
   attributes were shown. Added Номер + Дата as first two columns.

3. Hidden Ref column used Visible=false (element completely hidden from
   "Customize form"). Changed to UserVisible=false so users can enable Ref
   and add sub-columns via dot notation. Matches ERP Контрагенты pattern.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:34:45 +03:00
Nick Shirokov 3ee715939b test(form-compile): regression tests for new --from-object types
8 test cases covering InformationRegister (Record periodic/nonperiodic, List),
AccumulationRegister (List), ChartOfCharacteristicTypes (Item),
ExchangePlan (Item), ChartOfAccounts (Item, List).

All 12 tests pass on both PS1 and Python runtimes with form-validate.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-13 13:21:46 +03:00
Nick Shirokov a41897a966 test(form-compile): regression tests for --from-object mode
4 snapshot tests: catalog item/list (Валюты-like) + document item/list
(АктВВР-like). Verified against platform 1C 8.3.24. Register
form-compile-from-object in verify-snapshots DEFAULT_SKILLS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-12 18:40:12 +03:00
Nick Shirokov d1e770c843 test(form-edit): declare Поле1 in preRun form-compile attributes
add-element and add-group-with-fields built their baseline form with an
InputField whose DataPath pointed to "Поле1", but "Поле1" was never
declared as a form attribute. runner.mjs snapshot diffing accepted the
output, but verify-snapshots caught the real XDTO error at load time:
"Неверный путь к данным: Поле1".

Add the missing attribute to both preRun form-compile inputs and
regenerate snapshots (the new attribute takes id=5, so form-edit's added
"Поле2" now lands at id=6).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:03:34 +03:00
Nick Shirokov e3069ceb36 fix(form-compile): throw on known invalid attribute types
KNOWN_INVALID_TYPES (FormDataStructure, FormDataCollection, FormDataTree,
etc.) was checked but only produced a Write-Warning/print warning — the
script still emitted the bad <v8:Type> into Form.xml, which XDTO later
rejected with a cryptic load-time error. Turn the warning into a hard
throw so misuse is caught at compile time with the correct hint.

Reveals two broken test cases that shipped invalid forms:
- form-compile/catalog-form: main attribute was FormDataStructure, fixed
  to CatalogObject.Товары (what ERP's reference catalog forms actually
  use with the cfg: prefix).
- form-info/overview: preRun form-compile used the same wrong type, fixed
  the same way; snapshot regenerated.

Bumps form-compile to v1.4 on both runtimes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:03:24 +03:00
Nick Shirokov 0b2c09f8d9 fix(verify-snapshots): support case fixture setup and workDir cwd
Two harness gaps that masked real issues and leaked stray files:

1. Case-level `setup: "fixture:<name>"` was ignored — runner.mjs handled
   it, verify-snapshots did not. skd-edit/add-drilldown silently failed
   with "File not found: Template.xml" because the fixture never reached
   workDir. Added Step 0 fixture copy mirroring runner.mjs behavior.

2. `skillConfig.cwd === "workDir"` was ignored — main skill always ran
   with cwd=REPO_ROOT. mxl-compile cases pass relative -OutputPath
   "Template.xml", which landed in the repo root on every run. Plumb cwd
   through execSkill and set mainCwd from skillConfig.cwd.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 22:03:11 +03:00
Nick Shirokov 0d5d3451ff fix(cf-edit): reject add-childObject when object file is missing
cf-edit add-childObject was a low-level XML-manipulation operation
with no file-existence validation — callers could register a reference
to any Type.Name in Configuration.xml's ChildObjects without the
underlying file existing on disk. Platform then refused to load:
"Файл объекта не существует".

The 4 failing tests (add-objects, remove-object, add-default-role,
set-default-roles) all used this operation with fake references in
either main input or preRun, and had no way to pass verify-snapshots
because the cf-init-ed config had no actual object files.

User observation: this is the tests being wrong, not the skill.
meta-compile/role-compile/subsystem-compile already auto-register
every new object in Configuration.xml as part of their normal flow
(meta-compile.ps1:2949-3068, role-compile.ps1:667-747,
subsystem-compile.ps1:430-506). Nobody should be calling cf-edit
add-childObject to create a new object — they should be calling the
profile skill. cf-edit add-childObject is only for rare recovery
scenarios: rolled-back Configuration.xml with intact object files,
re-import from DB dump that clobbered the root but left srcfiles.

Changes:

1. cf-edit.ps1/py: Do-AddChildObject now checks that the target file
   exists at {ConfigDir}/{PluralDir}/{Name}.xml before registering.
   On miss, exits 1 with a message that names the expected path and
   points the user at the right skill (/meta-compile, /role-compile,
   or /subsystem-compile depending on type). TYPE_TO_DIR mapping for
   all 44 metadata types covers irregular plurals (FilterCriteria,
   BusinessProcesses, ChartsOfAccounts, ChartsOfCharacteristicTypes,
   ChartsOfCalculationTypes).

2. Tests: 4 existing cases rewritten to build realistic fixtures via
   meta-compile/role-compile preRun (both skills auto-register, so
   the resulting Configuration.xml already references the preRun
   objects). add-objects now exercises the round-trip recovery
   scenario: meta-compile creates Catalog.Товары and Document.ПриходТоваров
   (auto-registered) → cf-edit remove-childObject un-registers both
   (files remain) → main run re-registers via add-childObject. This
   tests exactly the rollback-recovery use case the operation exists for.

3. New add-missing-errors case: negative test with expectError:
   "Object file not found". Verifies the new hard-error path.

4. verify-snapshots.mjs: added symmetric expectError handling (runner.mjs
   already had it at line 514). If caseData.expectError is set,
   expect skill to fail; check stderr substring match; skip db-load
   and mark passed. Without this, negative tests would go red in
   verify-snapshots even though runner.mjs accepts them.

5. SKILL.md / reference.md: documented the new constraint and the
   redirection to profile skills. Kept mention of legitimate use case
   (rollback recovery).

Bumped cf-edit.ps1/py v1.0→v1.1.

Verification:
- runner --filter cf-edit (PS1): 2/6 → 7/7 (6 positive + 1 negative)
- runner --filter cf-edit --runtime python: 7/7 (dual-port clean)
- verify-snapshots --skill cf-edit: 2/6 → 7/7

With this landed P3 from debug/snapshot-verify/NEXT-STEPS.md is closed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 20:18:05 +03:00
Nick Shirokov 7a8f437e77 test(subsystem-compile): cover bottom-up -Parent flow; hide children shortcut
The bottom-up flow (compile child with -Parent pointing at parent's
XML — skill creates the real child file AND registers it in parent's
ChildObjects) has been the documented canonical way to build nested
subsystems since forever. It's in SKILL.md Примеры:58 and implemented
in subsystem-compile.ps1:430-506. But zero test cases exercised it —
all 7 pre-existing cases used the top-down `children: [...]` shortcut
that aa93031 made honest with stubs.

Two problems with the status quo:

1. A model reading SKILL.md saw `"children": ["ДочерняяА", "ДочерняяБ"]`
   right in the main JSON-definition example and took it as the
   canonical way to create nested structure. It's a trap — the
   shortcut creates placeholder stubs with empty Synonym/Content that
   the model almost never actually wants. The natural flow (one
   subsystem-compile call per real subsystem) wasn't visible where
   the model looks first.

2. The canonical flow had no test safety net — nothing caught regressions
   in the register-in-parent code path (lines 430-506).

Fix, minimal surface:

- SKILL.md: remove `"children": [...]` from the JSON-definition example.
  Leave the `-Parent` example in the Примеры section (already there).
  The children field stays fully supported in the scripts (aa93031 stub
  behavior unchanged) for legacy JSON — just not advertised.

- New test case `nested-parent.json`: preRun compiles "Продажи" parent,
  main run compiles "Настройки" child with `-Parent Subsystems/Продажи.xml`.
  Verifies the real bottom-up flow: snapshot shows full child file with
  real Synonym/Explanation AND parent's `<ChildObjects>` updated to
  reference the child. verify-snapshots confirms platform accepts it.

- Runner plumbing: `_skill.json` gains `{ "flag": "-Parent", "from":
  "workPath", "field": "parent", "optional": true }`. Required extending
  both `tests/skills/runner.mjs` and `tests/skills/verify-snapshots.mjs`
  (they each have their own copy of buildArgs) to support `optional: true`
  on workPath mappings — otherwise existing cases without params.parent
  would get the flag pushed with an empty value.

Verification:
- runner --filter subsystem-compile (PS1): 8/8 (was 7/7 +1)
- runner --filter subsystem-compile --runtime python: 8/8 (dual-port clean)
- verify-snapshots --skill subsystem-compile: 8/8

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 19:15:07 +03:00
Nick Shirokov 6805b9da02 fix(subsystem-edit): write stub XML on add-child operation
Do-AddChild / do_add_child added `<Subsystem>Name</Subsystem>` to the
parent's `<ChildObjects>`, but never wrote the corresponding
`Subsystems/{Parent}/Subsystems/{Name}.xml` file. Same silent-drop
pattern that bit subsystem-compile (aa93031): platform used to swallow
the missing-file reference, `-StrictLog` now surfaces it as "Файл
объекта не существует" and fails add-child on load.

Both ports now mirror the subsystem-compile fix:
- Write-ChildSubsystemStub / write_child_subsystem_stub helpers
  duplicated from subsystem-compile (per memory rule "skills are
  autonomous, duplication acceptable")
- format_version read from loaded XmlDoc root (no need to walk up
  to Configuration.xml — we already have the parent XML in memory)
- Stub creation guarded by Test-Path / os.path.exists so a pre-existing
  real child file is never clobbered

Bumped subsystem-edit.ps1 v1.1→v1.2 and subsystem-edit.py v1.1→v1.2.

Verification:
- verify-snapshots --skill subsystem-edit: 3/4 → 4/4
- runner --filter subsystem-edit (PS1): 4/4
- runner --filter subsystem-edit --runtime python: 4/4 (dual-port drift clean)

With this landed P1 from debug/snapshot-verify/NEXT-STEPS.md is fully
closed: subsystem-compile 7/7, subsystem-edit 4/4, interface-edit 4/4,
role-compile 8/8, meta-compile 30/30.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:49:40 +03:00
Nick Shirokov aa93031a3f fix(subsystem-compile): write stub XML for declared children
When a subsystem definition includes `children: [...]`, the parent XML
was emitted with `<ChildObjects><Subsystem>Name</Subsystem></ChildObjects>`
refs, but the referenced `Subsystems/{Parent}/Subsystems/{Child}.xml`
files were never created. Before 96d1dea (-StrictLog) the platform
silently dropped the refs on load (exit 0), so verify-snapshots showed
these cases green. With the new strict log parsing, `full` and
`with-children` started failing on "Файл объекта не существует".

Both PS1 and PY ports now emit a minimal valid child subsystem stub
(full MetaDataObject, empty Synonym/Content/ChildObjects) via new
Write-ChildSubsystemStub / write_child_subsystem_stub helpers. Stub
creation is guarded by Test-Path / os.path.exists, so a subsequent
compile of the same child via -Parent does not get clobbered, and
re-running the parent compile is idempotent. Дубли в children[]
дедуплицируются через seen-set.

Also removed the "Что генерируется" section from SKILL.md — filesystem
layout is covered by the OutputDir param + [OK] stdout lines; the
section was noise for model consumers.

Bumped subsystem-compile.ps1 v1.4→v1.5 and subsystem-compile.py
v1.3→v1.5 (PY caught up with PS1 version pin).

Verification:
- verify-snapshots --skill subsystem-compile: 5/7 → 7/7
- runner --filter subsystem-compile (PS1): 7/7
- runner --filter subsystem-compile --runtime python: 7/7 (dual-port drift clean)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-11 18:38:03 +03:00