Двадцать один py-порт печатал ошибки в stderr, тогда как их PS-мастера пишут
через Write-Host в stdout. Счётчики совпадали один в один (14↔14, 19↔19,
13↔13) — сообщения были те же, разъехался только поток. Это нарушало
соответствие из docs/python-porting-guide.md, где Write-Host сопоставлен
обычному print.
Это не косметика. Харнесс не чередует потоки, а группирует: сначала весь
stderr, потом весь stdout. Из-за этого в py-порте вердикт «Error dumping
configuration (code: 1)» печатался ПЕРЕД строками, которые его объясняют, а
причина из лога платформы оказывалась в самом низу — причинный порядок вывода
переворачивался. Порт, работающий на macOS, читался хуже того, что работает на
Windows.
Тесты этого не ловили по построению: текст ошибки сверяют только кейсы со
строковым expectError, а он смотрит в stderr — потому такие кейсы есть лишь у
семейства, где потоки сходятся, а в db-* их ноль.
Добавлен гард check-error-streams.mjs: нет записи в stderr в PS-порте — не
должно быть и в py, и симметрично. Он сразу нашёл пять навыков сверх тех, что
я насчитал вручную, и отсеял два ложных срабатывания (в meta-remove слово
Write-Error стоит в комментарии «почему НЕ Write-Error»).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Тот же класс дефекта, что закрыт в role-validate, был возможен во всей семье
*-info / *-validate / cfe-diff: лишний позиционный аргумент связывается со
следующим параметром по порядку объявления. Остальные скрипты спасала
случайность типов — на втором слоте оказался [int]MaxErrors/Limit или строка
с [ValidateSet], которые падают на конвертации. Любая перестановка параметров
в param() открывала дыру заново, а снапшот-тесты сверяют вывод, а не связывание.
Во всех 21 скрипте объявлен [CmdletBinding(PositionalBinding=$false)], входной
путь помечен Position=0. Инвариант: анализирующий навык не пишет в файл, который
ему не назвали по имени. Документированные вызовы в репозитории все именованные,
поведение навыков не меняется — 835 кейсов зелёные на обоих рантаймах без дрейфа
снэпшотов.
Гард check-positional-binding.mjs держит инвариант статически (объявление и
единственный Position=0; в py-порте все add_argument именованные) и поведенчески
(лишний позиционный аргумент роняет вызов, канареечный файл остаётся цел).
Семья определяется по имени навыка, поэтому новый *-info/*-validate попадает под
гард сам. На состоянии до правки гард падает на role-validate обеими проверками.
Версии обоих портов подняты синхронно; из шапок убраны чужие хвосты.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Дорожка CLI из кампании паритета: PowerShell не различает регистр ни в именах
параметров, ни в значениях [ValidateSet], argparse различает и в том и в
другом. Проверено на читающем навыке: cf-info -Mode BRIEF на PS отрабатывает,
на py падал.
ci_parse_args (эталон — meta-compile) вставлен в 68 py-портов, вызовы
parser.parse_args заменены. Навыков с DSL меньше трети, поэтому именно эта
правка делает паритет общим: *-info, *-validate, db-*, cfe-*, web-* тоже
принимают ввод так же, как их .ps1.
Реестр check-inline-drift дополнен списком потребителей — и сразу окупился:
поймал, что массовая замена переписала последнюю строку внутри самого
хелпера и копии стали рекурсивными.
Версии бампнуты синхронно в обоих портах всех 68 навыков.
Проверка: 673/673 (PS), 670+3 skipped (PY), гарды 4/4; паритет версий портов
проверен по заголовкам.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Тип метаданных Bot (Боты, платформа 8.3.18+) присутствует в
ChildObjects новых конфигураций, но не входил в зашитый список
типов — cf-validate падал с «Unknown type 'Bot'».
- cf-validate: Bot добавлен в список типов и маппинг каталогов (→ Bots)
- cf-edit: Bot в порядке типов + каталог + синоним DSL «бот»
- cf-info: Bot в порядке типов + рус. название «Боты»
- docs/1c-configuration-spec: Bot в перечне ChildObjects (поз. 11)
- tests: фикстуры + кейсы на Bot для cf-validate/cf-edit/cf-info
Позиция Bot — сразу после CommonModule (по выгрузке Конфигуратора).
Разнесение алгоритмов по версии формата/режиму совместимости
остаётся отдельной задачей бэклога.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Приводим авторский контент (.ps1/.psm1/.py/.mjs/.md/.json, пин .bsl)
к единому LF и закрепляем политикой в .gitattributes. Инструмент правки
всегда пишет LF, поэтому единый LF убирает EOL-шум в диффах, ложные
срабатывания blame и налог на ручную синхронизацию CRLF-файлов.
BOM на .ps1 сохранён (git с eol=lf меняет только CR<->LF, BOM не трогает).
Данные 1С (*.xml) и бинарники под нормализацию не берём.
Гейт: PS-порт 459/459, Python-порт 459/459, web-test E2E 22/22 (с пересборкой стенда).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Декодер Ext/ParentConfigurations.bin (нативная копия в каждом скрипте,
без общего модуля — по конвенции автономности навыков; single-pass,
не падает на битом/пустом файле).
cf-info (v1.3): блок «Поддержка:» в overview/full — на поддержке /
возможность изменения вкл-выкл / счётчики на замке/редактируется/снято
(только при G=0) / снята полностью / расширение (CFE). При G=1 показывает
read-only без вводящих в заблуждение счётчиков; тяжёлый скан 7.4МБ
пропускается, когда не нужен. При K>1 перечисляет конфигурации поставщика.
meta-info (v1.3): строка «Поддержка:» под заголовком объекта — walk-up к
корню конфигурации, статус с учётом G-vs-f1 и консервативной свёртки
min(f1) по блокам поставщиков. Для на-замке/read-only — короткое
последствие+действие (cfe-*), для остальных терсно.
Проверено на корпусе и размеченных дампах (acc G=1, erp снято,
ЧастьОбъектов, Корень, НесколькоПоддержек K=7 мультивендор, CFE) —
оба порта байт-в-байт. Формат: docs/1c-support-state-spec.md.
Тесты: cf-info 7/7, meta-info 17/17 на PowerShell и Python.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- 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>
Читает Ext/ClientApplicationInterface.xml (если есть) и выводит секцию
«Раскладка панелей» с маппингом UUID → имя для 5 платформенных панелей.
Стек панелей внутри одной стороны отображается как «Стек(a, b)»,
несколько отдельных тегов стороны (рядом) — через « | ».
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Добавлен Alias('Path') / "-Path" к основному файловому параметру
в *-info, *-validate, *-edit, *-decompile (24 навыка × PS+PY).
Не документируется — fallback на случай если модель напишет -Path
вместо -TemplatePath/-FormPath/-ObjectPath/-SubsystemPath/-RightsPath/
-ConfigPath/-ExtensionPath/-CIPath. Поведение строго аддитивное.
Регресс: 336/336 PS, 336/336 PY.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Without reconfiguring stderr, Cyrillic error messages appear garbled
on Windows (cp1251 default). Mirrors the existing stdout fix.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Python on Windows defaults to cp1251 for piped stdout, which cannot
handle Unicode box-drawing characters used in info/analysis output.
Added sys.stdout.reconfigure(encoding="utf-8") to all 59 Python scripts.
Tested on real config data: epf-init, epf-validate, cf-info, cf-validate,
meta-info, form-info, role-info, skd-info, subsystem-info — all passing.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add cross-platform Python alternatives alongside existing PowerShell
scripts. PS1 remains the default runtime; Python is opt-in via switch
scripts. All parameters are identical between runtimes.
New files:
- 58 Python scripts in .claude/skills/*/scripts/*.py
- scripts/switch-to-python.py and switch-to-powershell.py
- docs/python-porting-guide.md
- __pycache__/ added to .gitignore
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>