Title slides can now have TTS narration, same as showCaption/showImage.
Pass opts.speech as string for custom narration text, or true to use
the title text. Includes smart wait for video timeline sync.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use min-width/min-height 50% to upscale small images (was showing
tiny 225px images at native size instead of scaling up)
- Keep max-width/max-height 92% for large images (no regression)
- Change full preset from cover to contain — no content cropping,
black bars instead of cutting off edges
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show image files (PNG, JPG, etc.) as full-screen overlays during video
recording — useful for presentation slides in video instructions.
- Read file → base64 → inject as <img> overlay (same pattern as showTitleSlide)
- Style presets: blur (default), dark, light, full
- blur: blurred+dimmed copy as background with shadow
- full: object-fit cover, fills entire screen
- TTS speech support with smart wait (same as showCaption)
- Custom background overrides preset
- Fixed no-record stubs: showImage/showTitleSlide not stubbed (visual-only)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1C web client uses native confirm() for scripts like vis.js file
access. Without handling, these block Playwright execution.
Added page.on('dialog') handler to auto-accept.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Auto-detect 1C:Enterprise browser extension from Chrome/Edge profiles
and load it via launchPersistentContext. Enables native file dialogs
(Excel import/export) without "install extension" prompt.
- findExtension() scans Chrome/Edge User Data by extension ID
- connect() uses launchPersistentContext when extension found, falls
back to chromium.launch() otherwise
- isConnected() handles both Browser and BrowserContext objects
- Temp userDataDir cleaned on disconnect()
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When expand/toggle is passed for gridGroup/gridParent elements,
click the .gridListH/.gridListV triangle icon to expand/collapse
in place instead of dblclick which enters the group. Without
expand, dblclick behavior is preserved.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Three fixes:
1. fillTableRow: match cells by column header text (headerText fallback)
when INPUT id-based fuzzy match fails due to metadata typos
2. fillTableRow: EDD filter preserves standalone enum values like "Создать"
by only filtering "Создать элемент/группу/:" patterns (was: startsWith)
3. clickElement: coordinate-based click for tabs without ID, avoiding
global [data-content] selector that picks invisible duplicates from
background forms
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tab past the last cell in 1C creates extra rows. Now when all unfilled
fields are checkboxes (boolean values), the Tab loop exits immediately
instead of pressing Tab 3 more times on non-INPUT cells.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Tab navigation skips checkbox cells (no INPUT). After Tab fill, unfilled
checkbox fields are retried via direct click. Previously the retry hit
the wrong row because the selected row shifted after Tab/commit. Now
we record row count before "Добавить" click and use that index for the
retry, ensuring checkboxes land on the same row as the text fields.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Previously fillTableRow returned immediately after toggling the first
checkbox field, ignoring any remaining fields. Now it recursively
processes the rest on the same row.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- clickElement: add `expand` option (alias for `toggle`) for tree expand/collapse
- clickElement: fallback to dblclick when tree +/- icon not found (was NumpadAdd)
- dom.mjs: search [tree="true"] in entire line, not just first imgBox
(fixes trees with checkbox column before tree column)
- fillTableRow: detect checkbox cells after first click, return immediately
without escalation (dblclick/F4). Checkbox state detected via .select class
- SKILL.md: document `expand` instead of `toggle`
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>