- Fix: discoverTests падал с ENOTDIR при передаче .test.mjs файла
- Добавлен 01-navigation.test.mjs — навигация по разделам, открытие
списков через navigateLink, переключение между подсистемами
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>
- Fix empty dataPath when field is specified as object { field, title }
- Add title to presentation fallback chain: presentation → title → name
- Add compact DSL for AreaTemplate: rows/widths/style instead of raw XML
- Built-in style presets: header, data, subheader, total
- User-defined presets via skd-styles.json (project-level overrides)
- Support vertical merge ("|"), parameters ("{Name}"), static text, null cells
- Update SKILL.md, skd-dsl-spec.md, skd-guide.md with template DSL docs
- Add examples/skd-styles.json with all supported keys
- Bump version v1.1 → v1.2
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Move screenshot capture to before fetchErrorStack call in the ACTION_FNS
wrapper, so the error modal is still visible on the screenshot. Skip the
duplicate screenshot in catch block when one was already taken.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dismissPendingErrors() now detects and closes leftover platform dialogs
(About, Support Info, Error Report) before checking for 1C error modals.
This prevents action functions from failing with timeouts when a stale
platform dialog blocks interaction via modalSurface.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
getFormState() now returns `platformDialogs` array when platform-level
dialogs are open (About, Support Info, Error Report). These dialogs are
invisible to 1C form detection and not closeable via Escape.
closeForm() detects platform dialogs first and closes them via
_closePlatformDialogs() instead of sending Escape, returning
closedPlatformDialogs in the result.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a 1C error modal is detected, automatically retrieve the full call
stack before throwing. Uses two strategies: Path 1 clicks the OpenReport
link for platform exceptions, Path 2 navigates hamburger → About →
Support Info for handled ВызватьИсключение errors. The stack is returned
as structured {raw, entries[{location, code}], timestamp} in the error
result. Handles unstable modal redraws with a 1.5s re-check delay.
Platform dialogs are always cleaned up via try/finally.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When the open-windows tab bar is hidden in 1C settings, the model had no
way to know how many forms are open or whether a form is modal. Now
getFormState returns openForms/formCount/modal derived from DOM form
elements (independent of tab bar), and closeForm compares form number
before/after Escape to return closed: true/false.
Tested on ncc (tab bar hidden) and bpdemo (tab bar visible).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- addNarration: use cap.voice override per caption (fallback to global)
- showCaption/showImage/showTitleSlide: pass opts.voice to caption entry
- showCaption: record caption when text is empty but speech is explicit
- startRecording: add speechRate option (default 70ms/char, 85 for ElevenLabs)
- run.mjs: increase exec timeout to 30min for long recordings
- docs: update recording.md and web-test-recording-guide.md
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Remove redundant sections (Source table, exit codes, mapping internals)
and trim examples from 6 to 2. Update mapping description to reflect
that all non-XML files (not just BSL) are now handled.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Remove .xml/.bsl-only filter — now any changed file (HTML, BSL, etc.)
maps to parent object XML + pulls entire Ext/ directory
- Fix: ru.html changes without Help.xml in same commit range were silently
skipped, leaving help text stale in the database
- Fix PY: add encoding="utf-8" to subprocess.run in run_git() — Cyrillic
paths were garbled on Windows due to default cp1251 decoding
- Bump to v1.3
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>