Enables --no-record dry-run of video scripts without errors. stopRecording()
returns { file: null, duration: 0, size: 0 } instead of throwing, and
addNarration(null) returns a matching stub.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Group search in highlight() now filters by !classList.contains('logicGroupContainer')
instead of removing _div selector entirely. This skips invisible Representation=None
groups while preserving grid/table _div elements (frameGrid) that are the actual
highlightable panels (Оргструктура, Системы, БизнесПроцессы).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- highlight(): exact match by name ignores size filter (supports Representation=None groups),
error message lists available elements by category
- startRecording(): { force: true } option to restart if already recording
- executeScript(): auto-stop recording on script error (prevents "Already recording")
- fillField(name, value): silent alias for fillFields({ name: value })
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously fillFields errors showed only the error code (e.g. "not_found"),
making it ambiguous whether the field or the value was not found. Now shows
the message (e.g. 'Value "X" not found') when available.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously clickElement always toggled expand/collapse on tree nodes.
Now default = select (click text), and { toggle: true } = expand/collapse
(click tree icon). Hint in response guides the model to use toggle when needed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Previously findClickTargetScript used querySelector (first grid only),
making clickElement unable to find rows in second+ grids on multi-grid
forms (e.g. system composition wizard). Now uses querySelectorAll to
search all visible grids, and returns gridId so the tree node handler
can locate the correct grid for expand/collapse.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Prevents false positives like "Да" matching "Удаляемые" (group) or
"КомандаУстановитьВсе" (button). Exact and startsWith still work.
Applied to highlight groups, findClickTargetScript buttons/grid-scoped/grid rows.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clicking a different data row to exit edit mode re-entered edit on that
row, blocking subsequent button clicks like "Записать". Now the add-path
commit clicks the grid header which cleanly exits edit mode without
re-entering it.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
highlight() was ignoring the table parameter, always highlighting the
first matching button (e.g. "Добавить" for Входящие instead of
Исходящие). Now clickElement passes { table } to highlight, and
highlight pre-resolves the grid via resolveGridScript to pass
gridSelector to findClickTargetScript — same pattern as clickElement
itself.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CamelCase cell IDs like "ИсходящиеБизнесПроцессПриемник" have no
dashes, but user keys like "Бизнес-процесс приемник" do. The previous
regex only stripped spaces, leaving the dash and causing match failure.
Now strip both spaces and dashes with /[\s\-]+/g in both the Tab-loop
path and the row/dblclick column-lookup path.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Row selection clicks in deleteTableRow and fillTableRow commit now target
the second visible gridBox instead of the first, avoiding accidental
checkbox toggles on forms with checkbox columns (e.g. BP links master).
Also documents the new `table` parameter in SKILL.md for readTable,
clickElement, fillTableRow, deleteTableRow, and getFormState tables[].
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add semantic table binding to readTable, clickElement, fillTableRow,
and deleteTableRow — resolves the correct grid by name when a form
has multiple tables (e.g. "Входящие"/"Исходящие" in BP links).
- New resolveGridScript() in dom.mjs: cascade match by gridName → columns
- findClickTargetScript: scoped button search within grid's parent container
- getFormState: reports all grids via tables[] array (table still present for compat)
- All grids[grids.length-1] fallbacks wrapped in gridSelector ternary
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
navigateSection now normalizes \r\n to spaces, so callers don't need
literal newlines in section names. fillTableRow direct-edit path skips
cells that already contain the desired value (method: 'skip').
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
pickFromSelectionForm:
- 3-step escalation: scan visible → simple search → advanced search (Alt+F)
- Extract helpers: scanGridRows, dblclickAndVerify, advancedSearchInline
- dblclickAndVerify uses click+Enter instead of dblclick (dblclick toggles tree groups)
- Returns ok:false when selection form stays open (group/folder not selectable)
- Distinguish not_found vs not_selectable errors
- trySelect wrapper continues escalation on ok:false
fillTableRow direct-edit (tree grids):
- Click → dblclick → F4 escalation for entering edit mode
- F4 from INPUT mode for tree grid ref fields
- isTypeDialog check + pickFromTypeDialog for composite types
- Commit via click on different row instead of Escape (Escape cancels in tree grids)
fillTableRow regular path:
- Commit new row after fill loop by clicking another row or grid header
- Prevents Escape (e.g. from closeForm) from cancelling uncommitted new row
- Fixes accumulated unclosed forms from closeForm failing to close
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After F4/Enter that opens a modal, clickElement could fail because
detectFormScript found the parent form before the modal appeared.
Now retries up to 2s, re-detecting the form each time.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cell IDs in 1C tables are CamelCase without spaces (e.g.
"ВариантыАрхитектурыВариантАрхитектуры"), but users pass keys with
spaces ("Вариант архитектуры"). Added space-stripped fallback to
fuzzy match so fillTableRow correctly maps user keys to grid cells.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Group names often collide with command bar buttons (e.g. "БизнесПроцессы"
matched a tiny 38x35 button instead of the 959x580 panel). Move group
search before button/field search with min-size filter (100x50).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Added group/panel search step to highlight() — matches by visible title
or internal name (e.g. highlight('Оргструктура') finds the group container).
Search priority: popups → commands → form elements → groups → sections.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CDP screencast doesn't send frames for static pages, causing video to be
shorter than real time (gap-fill capped at 2s, smart pauses are 4-6s).
- Add _flushFrames() helper on recorder to write duplicate frames on demand
- Call _flushFrames() every 1s during smart TTS pauses in showCaption
- Call _flushFrames() in wait() for long explicit pauses during recording
- Call _flushFrames() in stopRecording for final gap before closing ffmpeg
- Increase gap-fill cap from fps*2 to fps*30 as safety net
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ffmpeg amix + adelay with large delays causes timestamp overflow
(dts near INT64_MAX), producing silent/truncated audio. Fix: use a
silence reference track as first amix input with duration=first,
so amix runs for full video length regardless of delayed stream
timestamps.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
showCaption now auto-waits for estimated TTS duration during recording
(~100ms/char, min 2s). Subsequent wait() uses credit system to avoid
double-waiting. addNarration: cap atempo at 1.3x (was 2.5x), replace
-shortest with explicit -t to prevent video truncation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add .confirm CSS selector to the server-response waitForSelector in
clickElement. 1C web client shows notifications (Изменение/Проведение)
as .confirm elements after write/post operations. This allows early
exit instead of waiting the full 10s timeout. Записать: 14s → 2.6s.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When clicking toolbar buttons like "Добавить" that put focus into a grid
INPUT cell, skip the 10-second waitForSelector for modal/balloon since
no server round-trip is expected. Also replace fixed waits with polling
in fillTableRow add/row paths. Total: 121s → 62s on composite test suite.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace hardcoded waitForTimeout calls with polling loops that check
DOM state and exit early. Saves ~12s on composite-type test suite.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When filling composite-type cells (String+Number+Date), the previous code
tried paste first and only fell back to type selection if paste was rejected.
This failed when rows inherited a type from previous rows — paste succeeded
but the value was silently converted to the wrong type.
Now when { value, type } is specified:
1. Always clear the cell first (Shift+F4) to reset inherited type
2. Open type dialog (F4) and select the requested type
3. Dismiss calculator/calendar popups with Escape
4. Re-enter edit mode if focus was lost, then paste the value
Tested with primitive types (Число/Строка/Дата) and reference types
(Физическое лицо via selection form). Regression-tested existing
composite-type flow in Операции.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Cells accepting multiple types (e.g. subconto on account 80.01) now
handled via { value, type } syntax. Paste rejection detected
automatically — F4 opens type dialog, picks type, then selects value
from the catalog form.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
selectValue now accepts search as object { field: value } for per-field
disambiguation in selection forms. All fields use advanced search (Alt+F)
by specific column — more efficient than simple full-text search on large
tables, and navigates to exact row even in virtual grids.
Also fixes filterList modal cleanup: now checks specific dialog form
instead of generic modalSurface, preventing accidental closure of
parent modal forms (e.g. selection forms).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When multiple types match the search term in the type selection dialog,
throw a descriptive error listing all matches instead of silently
picking the first one. This prevents the model from getting a misleading
"not found" error when the wrong type was selected.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add `{ type }` option to selectValue for fields that accept multiple
types (e.g. DocumentRef.*). When specified, selectValue navigates
through the type selection dialog via Ctrl+F search before opening
the value selection form. Auto-detects composite fields when type
is not specified and throws a helpful error message.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
navigateSection() now gives a clear error message when the section
panel is in icon-only mode instead of a confusing "not found" error.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Check form change before checkForErrors() to prevent misidentifying
a small EPF form (< 20 elements) as an informational modal dialog.
Only call checkForErrors() on suspiciously tiny new forms.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
After clicking "Да" on the security confirmation, check for a second
informational modal ("please re-open the file"). If present, dismiss it
and retry the full Ctrl+O → filechooser cycle.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Opens EPF/ERF files via Ctrl+O → 1C file dialog → native file picker.
Handles security confirmation dialog with up to 2 attempts for re-open.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Caption timestamps now use actual video timeline position (frame
counter) instead of wall-clock time, eliminating sync drift from
non-uniform frame duplication in CDP screencast recordings.
Also replace silence-file concatenation with adelay+amix for
sample-accurate TTS placement, and fix exec timeout for long
scenarios (fetch → http.request with 10min timeout).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Screencast frame duplication (Math.round) causes video to be ~5% longer
than wall-clock time. Caption timestamps are wall-clock based, so the
audio track drifted ahead by ~8s at the midpoint of a 5-minute video.
Fix:
- stopRecording() saves recordingDuration in captions.json
- addNarration() reads actual video duration via ffprobe and scales
caption timestamps by videoDuration/recordingDuration ratio
- Phase 2 timeline now tracks actual cumulative position instead of
computing gaps from previous caption data (prevents MP3 frame
quantization drift)
- Also fixed findFfmpeg() → resolveFfmpeg() call in addNarration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Mirrors resolveFfmpeg() pattern: tries global/project-level import
first, then tools/tts/node_modules/, then throws error with install
instructions. Caches resolved module for subsequent calls.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- node-edge-tts installed in tools/tts/ (alongside tools/ffmpeg/)
- Speed up TTS with ffmpeg atempo when it exceeds gap to next caption,
instead of hard-cutting the audio
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Dynamic import needs file:// URL on Windows and explicit entry point
for ESM resolution. Package installed in tools/ alongside ffmpeg.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
showCaption() collects captions with optional speech parameter,
stopRecording() saves .captions.json, addNarration() generates
TTS voiceover (Edge TTS or OpenAI) and merges audio with video.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JPEG full range (0-255) was tagged as pc/full in H.264 output, but most
players (VLC, etc.) expect limited range (16-235). Convert JPEG→limited
with scale filter and tag as tv. Also switch preset ultrafast→fast for
5-6x smaller files on static screen content.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
When the function panel is open over a form, highlight() was finding
buttons from the hidden form instead of visible commands on the panel.
Move command search (cmd_XXX_txt) to step 1 — before form-scoped
search — so visible panel commands always take priority. Form elements
searched at step 2 only if no command matched.
Highlight search order is now:
0. Open submenu/popup (elementFromPoint overlay)
1. Commands on function panel (visible cmd_ elements)
2. Form elements (buttons, fields, grid rows)
3. Sections (sidebar navigation)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add submenu/popup as priority 0 in highlight() — checks open
popups before form search, preventing false matches on grid rows
behind the popup overlay
- Use elementFromPoint + direct overlay for submenu items instead
of getElementById (1C duplicates IDs in cloud popups — hidden
copy in form + visible copy in cloud)
- Add startsWith step between exact and includes for section and
command matching — fixes "Поступление" matching "Поступление
билетов" instead of "Поступление (акты, накладные, УПД)"
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move unhighlight() before the fill action in fillFields — prevents
our overlay staying visible while platform focus moves to next field
on Tab/Enter. Consistent with clickElement/selectValue pattern:
highlight → wait → unhighlight → action.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Reorder highlight() search: form elements first, sections/commands as
fallback. Fixes false match where "ОК" matched section "Покупки" via
substring .includes() ("пок" contains "ок")
- Unhighlight before action in clickElement/selectValue (was only in
finally block, causing overlay to cover modals opened by the click)
- Add auto-highlight support to navigateSection and openCommand
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
JPEG frames from CDP screencast use full range (0-255) but H.264
defaults to limited range (16-235). Add -color_range pc to preserve
full range in output MP4, fixing washed-out/bright appearance.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Full-screen overlay with gradient background, centered title text,
optional subtitle. Useful for intro/outro frames in video recordings.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three improvements to browser automation reliability:
1. ё→е normalization: fuzzy matching now treats ё and е as equivalent
across all comparison points in both dom.mjs (norm() functions,
target variables) and browser.mjs (popup, radio, EDD, grid, confirmation
dialog, advanced search, filter badges). Prevents silent failures when
script uses ё but 1C displays е or vice versa.
2. DLB intercept handling in selectValue(): added force click + Escape
fallback when funcPanel overlay blocks the dropdown button click,
matching the pattern already used in clickElement().
3. Error handling: all exported functions now throw Error instead of
returning { error } objects. Error messages include function name,
what was searched, and available alternatives. Scenarios fail fast
at the broken step; interactive callers can use try/catch.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>