Extract info bar messages from .stateWindowSupportSurface elements
into errors.stateText — covers missing parameters, "report not
generated", "settings changed", and "generating..." states.
readSpreadsheet() now includes the state message in its error.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When working with existing configs dumped from newer platforms (8.3.27+),
XML files use version="2.20" instead of "2.17". Skills now detect the
version from the nearest Configuration.xml walking up the directory tree,
falling back to "2.17" if not found. This prevents format version mismatch
errors during LoadConfigFromFiles.
Updated skills (11): meta-compile, form-compile, form-add, template-add,
cfe-borrow, epf-add-form, help-add, role-compile, subsystem-compile,
interface-edit. Also fixed form-validate to accept version 2.20.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
.strip()/.Trim() in batch-splitting was stripping the trailing space
of the " => " separator, making " => " (delete) unrecognizable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add two new validations found via platform snapshot verification:
- Registers without any Dimensions/Resources/Attributes → platform rejects
- Document.RegisterRecords referencing non-existent register objects
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
ChartOfAccounts, ChartOfCharacteristicTypes, ChartOfCalculationTypes
attributes don't support FillFromFillingValue, FillValue, DataHistory
properties — platform rejects them with "Неверное свойство объекта
метаданных". Add "chart" context to Emit-Attribute to skip these.
Found via platform snapshot verification (Finding A1).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Detect config vs EPF context by walking up from FormPath looking for
Configuration.xml. ExternalDataProcessorObject/ExternalReportObject are
valid in EPF/ERF but cause XDTO exception in configuration context.
- EPF forms: no warning (ExternalDataProcessorObject is correct)
- Config forms: ERROR with hint to use DataProcessorObject/ReportObject
- Fix test DSLs: compiled-form, table-form used wrong External* type
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Check 12 was flagging cfg:ExternalDataProcessorObject.X as "unrecognized cfg
prefix", but this is a valid XDTO type for external data processor (EPF) forms.
Found via snapshot verification against epf-add-form snapshots.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
form-compile now warns when model uses runtime types like
FormDataStructure that don't exist in XML schema. Expanded cfg:
regex to cover all 25 known prefixes.
form-validate adds Check 12 — validates all <v8:Type> values:
ERROR for known-invalid types, WARN for unrecognized bare types,
pass-through for unknown namespaced types (future-proof).
Updated SKILL.md with full type reference and invalid type warning.
Updated docs/1c-form-spec.md with missing type groups.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All operations (hide, show, place, order) now auto-normalize
the first segment of command names — e.g. Catalogs.X → Catalog.X,
Справочник.X → Catalog.X.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
subsystem-compile and subsystem-edit now auto-normalize content type
prefixes (Catalogs→Catalog, Справочник→Catalog, Справочники→Catalog).
subsystem-validate detects plural forms as errors in check #6.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Hardcoded threshold of 3 non-empty cells prevented header detection in
spreadsheets with 1-2 columns (e.g. query console results). Use
Math.min(3, maxCol + 1) so narrow tables can still be parsed structurally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a spreadsheet has 3 header levels (group → detail → codes), the
carry-forward logic for merged group headers would bleed into columns
belonging to different top-level groups. Detect a "super-row" above the
group row and reset carry-forward when a new top-level header starts.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rewrites scrollSpreadsheetToCell with fixes for multiple issues discovered
during E2E testing:
- Use Playwright boundingBox (page-level coords) instead of frame-internal
getBoundingClientRect for visibility checks — frame's clientWidth is wider
than the actual visible iframe area clipped by parent elements
- Use iframe element's boundingBox to determine visible region — cells behind
the section panel (x < iframeBox.x) were incorrectly considered "visible"
and focus clicks hit the section panel instead of the spreadsheet
- Use div[y]+div[x] attribute selectors instead of div.RxCy CSS classes —
the RxCy class numbering differs from y/x attribute values
- Accept cellLoc parameter from caller instead of re-searching — avoids
selector mismatch and handles cells missing from some rows
- Native click through mxlCurrBody overlay (page.mouse.click) for focus —
frame.locator().click() bypasses overlay causing header/data desync,
page.mouse.click() + frameEl.focus() doesn't transfer keyboard focus
- Pick rightmost/leftmost fully-visible cell for focus based on scroll
direction — each arrow press immediately triggers platform scroll
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Scroll via arrow keys with native platform behavior. Works for
moderate scroll (few columns off-screen). Known limitations:
- Far off-screen columns may timeout
- Re-clicking between direction changes can break scroll context
- Edge cells (first/last column) may not fully scroll into view
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Cells outside the visible iframe area couldn't be clicked because
boundingBox() returned null. Now scrollIntoView() is called first.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend clickElement to support clicking cells in rendered reports
(SpreadsheetDocument). First argument accepts { row, column } object
where coordinates match readSpreadsheet() output. Text fallback also
searches spreadsheet iframes when element not found in main DOM.
Refactor readSpreadsheet internals into reusable helpers:
scanSpreadsheetCells, buildSpreadsheetMapping.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Addresses user feedback: set-query is all-or-nothing, and editing XML
directly is fragile due to escaping. patch-query allows targeted string
replacement via "old => new" shorthand, with batch mode support.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Empty Ext/ directories for Constants, Enums, and DocumentJournals caused
platform to wipe all extension modules during LoadConfigFromFiles.
Now Ext/ is only created when files will be placed in it, and
Constant gets ManagerModule + ValueManagerModule, Enum gets ManagerModule.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Simple EPF forms with textarea fields were invisible to form detection
(formCount: 0) and misclassified as modal error dialogs. Also, backslash
paths in exec scripts caused "Invalid Unicode escape sequence" JS parse errors.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
highlight() now supports command group headers (eAccentColor labels)
on the 1C function panel. Matches group name, collects header +
commands below it, draws multi-element bounding box overlay.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace hardcoded Apache zip URL with dynamic parsing of the Apache
Lounge download page. Finds the latest Win64 build automatically,
so the script won't break when new versions are published.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The expand/collapse code re-searched for the target row by first-cell
text, which was ambiguous when parent and child rows share the same
prefix (e.g. "БУ"). This caused expand to hit the wrong (already-
expanded) row and skip. Use target.y from the initial findClickTarget
instead — matches the exact row.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
gridListH = collapsed (▶), gridListV = expanded (▼). The old code had it
backwards, so `expand: true` on a collapsed group was a no-op.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- interface-edit: expand SKILL.md from stub to full docs, remove redundant reference.md
- cf-edit: restore reference.md link with descriptive text
- cfe-borrow: clarify BorrowMainAttribute semantics (omit/Form/All)
- epf-bsp-add-command: fix example bug (Модификатор on non-print command)
- mxl-validate: keep only universal -TemplatePath in docs
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
All 11 validate skills: remove internal check tables and exit code lines
that provide no value to the model-user. Update Detailed param description
to be clearer. -221 lines, ~1550 tokens saved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When DLB dropdown shows only a hint ("Введите строку для поиска...") without
.eddText items, the code fell through without closing the popup. This left
editDropDown covering the input field, causing Playwright to wait up to 30s
for actionability on the next page.click(). Now we Escape the hint popup
when eddState.visible=true but items are empty (34s → 5s on cold cache).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- form-add v1.2: ExtendedPresentation only for DataProcessor/Report/External* forms
(Catalogs, Documents, Registers etc. don't have this property — platform rejects it)
- cf-init v1.1: InterfaceCompatibilityMode Taxi → TaxiEnableVersion8_2
(matches all real configs: acc 8.3.20/24/27, erp 8.3.24)
- cfe-init v1.1: read InterfaceCompatibilityMode from -ConfigPath base config
(analogous to existing CompatibilityMode auto-detection)
- Remove workaround in platform-cfe integration test (cf-edit modify-property)
- Update 162 snapshot Configuration.xml + 7 form metadata snapshots
Tests: 301/301 passed
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same alias dictionary + case-insensitive matching as meta-compile v1.4.
Applied at: fillChecking/indexing in attribute parsing, and scalar
property change in modify-attribute/modify-property operations.
Both PS1 and PY versions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add alias dictionary + case-insensitive matching for 23 system enum
properties (RegisterType, WriteMode, Periodicity, etc.). Accepts common
model mistakes like "Balances"→"Balance", "RecordSubordinate"→
"RecorderSubordinate", Russian synonyms, and wrong-case values.
Both PS1 and PY versions updated with identical dictionaries.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
interface-edit v1.1: place/order operations accept value as object
(not just JSON string) from DefinitionFile — no more JSON-in-JSON.
skd-compile v1.3: dataSetLinks accept both DSL names (sourceExpr,
destExpr, source, dest) and XML names (sourceExpression,
destinationExpression, sourceDataSet, destinationDataSet).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- OutputDir now accepts config root dir — creates Roles/ subdirectory
- Back-compat: if OutputDir ends with "Roles", uses it as-is
- Configuration.xml lookup adjusted accordingly
- Updated SKILL.md, PS1, PY scripts (v1.3)
- Updated test cases and snapshots for new Roles/ path
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Script logic fixes (PY mirroring PS1):
- skd-compile: fix (?i) regex flag placement for Python 3.11+
- mxl-compile: handle list-of-lists row format (PS1 silently ignores)
- subsystem-compile: add "objects" → "content" synonym alias
- role-compile: add "rights" → "objects" synonym alias
- meta-compile: sort HTTP/Web service method/operation iteration
- form-edit: insert ChildItems after Events/AutoCommandBar (not at end)
- mxl-compile: sort colWidthMap iteration in both PS1 and PY for
deterministic format indices
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Skill fixes (all ps1+py, version bumped to v1.1):
- role-compile: accept "rights" as synonym for "objects"
- subsystem-compile: accept "objects" as synonym for "content"
- form-add: resolve directory path to .xml (like meta-validate)
- form-info: resolve directory path to Ext/Form.xml (like form-validate)
- mxl-compile: support absolute OutputPath (IsPathRooted check)
- meta-remove: exit 1 when object not found; v1.1
- cfe-patch-method: accept plural type names (Catalogs → Catalog)
Test fixes:
- basic-role.json: use canonical "objects" key
- basic.json (subsystem): use canonical "content" key
- catalog-form.json: fix outdated DSL format
- New synonym test cases for role-compile and subsystem-compile
- error-not-found.json: expect error (exit 1)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getFormState now replaces non-breaking spaces with regular spaces in all
button names, field labels, checkbox/radio labels. Icon-only buttons
(pressCommand without text) expose tooltip from parent .framePress title
attribute. clickElement fuzzy match includes tooltip as lowest-priority
candidate.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add modifier option ('ctrl'|'shift') to clickElement for Ctrl+click
(add to selection) and Shift+click (select range) in grid rows.
Add _selected: true flag to readTable rows so the model can verify
which rows are currently selected before performing actions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Pass '' or null as value to clear any field (except checkbox/radio) via native 1C Shift+F4.
Returns method: 'clear'. Handles tree grids (close selection form first) and flat grids (dblclick to enter edit mode).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
clickElement confirmation handling is cleanup of stale dialogs — no pause needed.
closeForm confirmation is intentional user action — keep 500ms pause during recording
(on top of ~600ms from waitForStable = ~1.1s total dialog visibility).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Same 1.5s pause as in clickElement for confirmation dialogs when video
recording is active. Applies when closeForm({ save: true/false }) auto-clicks
the confirmation button.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When video recording is active, wait 1.5s before clicking confirmation
dialog buttons so viewers can see the dialog in the video.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace 10s waitForSelector timeout with CDP-based network monitoring.
For buttons that trigger server operations without producing a modal/balloon,
the old code waited the full 10s. Now it monitors actual HTTP requests via
Chrome DevTools Protocol and exits 300ms after the last request completes.
- Add startNetworkMonitor() — creates CDP session before click, tracks pending requests
- waitDone() polls for network quiet (300ms debounce) or UI element appearance
- CDP session cleaned up in finally block via cleanup()
- Add optional {timeout} parameter to clickElement for custom wait limits
- Tested: Записать ~1.9s (was ~11.5s), Записать и закрыть ~0.9s, confirmation dialogs OK
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Date fields have a CB (Choose Button) that opens a calendar, not a selection
form. fillFields detected hasPick → delegated to selectValue → error
"DLB click did not open a popup or selection form".
Fix: detect date fields by `iCalendB` CSS class on CB button (dom.mjs),
propagate `isDate` flag through field mapping, and use clipboard paste
for date fields instead of selectValue. Reference fields with CB (without
iCalendB) continue using selectValue as before.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
expand:false was silently ignored because `if (expand || toggle)` evaluates
to false when expand=false. Now uses `expand != null` to enter the branch,
checks current state (gridListH/gridListV for groups, backgroundImage gx=0
for tree nodes), and only clicks when the state needs to change.
- expand:true on collapsed → expand (click)
- expand:true on expanded → noop (idempotent)
- expand:false on expanded → collapse (click)
- expand:false on collapsed → noop (idempotent)
- toggle → always click (unchanged)
Returns `toggled: true/false` in result to indicate whether click happened.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Root cause: fillTableRow used child-index matching between grid header and
body cells. When headers are merged (e.g. "Бизнес-процесс источник" spanning
two body columns), header has more children than body — indices diverge,
click lands on wrong cell, fields stay empty.
Fixes:
- Use `colindex` attribute (set by 1C platform) to match header→body cells
reliably across merged headers (cellCoords + nextCoords)
- Add `scrollIntoView()` before clicking — fills cells behind horizontal scroll
- Sort fields by colindex before processing — Tab-loop goes left→right
regardless of field order in the passed object
- Limit F4 to tree grids only — prevents calculator popup on numeric fields
in flat grids which breaks Tab-loop focus
- Add paste fallback in directEditForm path for plain-text/numeric fields
Tested: 12/12 automated scenarios (single/multi field, add/edit, scroll,
reverse order, mixed types, tree grid, multiple tables, checkbox).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When adding a new attribute to a borrowed form, -BorrowMainAttribute
borrows the form's main attribute ("Объект") and all referenced object
attributes, tabular sections, and their transitive type dependencies.
Two modes: Form (default — only attributes referenced by form DataPath)
and All (all object attributes). Deep paths like Объект.A.B are resolved
transitively. Already-borrowed objects are not overwritten.
Also fixed: CommonPicture auto-borrow from AutoCommandBar, form-attribute
DataPath stripping (keep only Объект.* paths).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Create ManagerModule.bsl alongside ObjectModule.bsl for Report and
DataProcessor types — required for reports with НастроитьВариантыОтчета.
Bump version v1.2 → v1.3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>