308 Commits

Author SHA1 Message Date
Olli Paloviita 0f211bea64 editor: apply deferred (pending) codegen edits on connect
Accept codegen requests queued while no machine was connected: the poll
loop applies them like any other edit and logs "queued by <name>"
attribution. Update the editor docs to describe pending edits and code
sync.
2026-07-13 02:18:41 +03:00
Olli Paloviita 5730086240 editor: auto-resolve duplicate editIds via static analysis
A slug used at two distinct call sites silently merged both actions into
one runtime identity (the second became a phantom loop-repeat, its edits
unreachable) and was only caught reactively as an ambiguous-edit-id.

Static analysis now finds every duplicate up front, keeps the first
occurrence, and re-stamps the rest with fresh, never-reused slugs. Wired
into record (before the record run), the screenci edit startup handshake,
and the interactive codegen apply (retry-after-resolve, still-ambiguous
still throws). Genuine loops (one call site) stay untouched.

- codemod: collectEditIdOccurrences, renameEditIdAtCall
- editIdStamp: planDuplicateEditIdFixes (skips in-use slugs)
- record path reuses one --list discovery pass for both title and
  duplicate-editId checks
2026-07-13 01:54:23 +03:00
Olli Paloviita 9f3f1beebf editor: split a code autoZoom into two via codegen
blockRemoveEdit now unwraps autoZoom blocks (not only hide/speed/time), and
codeSync orders the unwrap before the two re-wraps in one pass, so splitting a
code-authored autoZoom yields two sibling brackets carrying the original zoom
options. Adds codeSync.spec coverage and documents the flow in editor.md.
2026-07-12 22:15:50 +03:00
Olli Paloviita 713f351bfc overlays: drop the language-major form (shared across languages)
Overlays no longer vary by language. video.overlays(...) accepts only a
names-only array or a shared content-major object; the language-major
spelling is rejected at the type level and throws a clear ScreenciError at
declare time. Narration (and the hidden values/audio) keep the per-language
form.

Removes the runtime per-language overlay resolution (buildOverlays is now
shared-only), the overlay language contribution/warning paths, the
AssetTranslation type and asset translations fields, and the assetStart branch
of the translation fold. Docs updated.
2026-07-12 21:49:49 +03:00
Olli Paloviita 3349cf73b9 editor: drag-to-resize adjacent waitForTimeout, merge back-to-back sleeps
Make recorded waitForTimeout calls web-editable and keep the source in sync
with timeline drags:

- Unlock recorded numeric waitForTimeout delays (instrument) so their
  durationMs can be rewritten in code instead of being locked.
- Add a durationMs codegen path (codeSync): locate the wait via a stamped
  neighbor action (findRecordedWait) and rewrite the numeric arg in place, or
  remove the call at 0. Refuse safely when the source has drifted.
- Coalesce back-to-back waitForTimeout statements into one summed call
  (mergeAdjacentWaitEdits), run as a post-pass on every file a sync changed.
  Adjacency is judged per source block, so it never crosses control flow;
  comment-separated sleeps are preserved.
- Carry schemaKind on editable snapshot entries so codegen can tell a recorded
  delay apart from other unstamped entries.

Docs and unit tests included.
2026-07-12 21:29:10 +03:00
Olli Paloviita 97f28572e1 cli: filter 'screenci edit' videos by positional title patterns
'screenci edit [patterns...]' filters managed videos by title, like
'playwright test <pattern>' (multiple positionals OR-combined). --grep
takes precedence when both are given.
2026-07-12 19:08:10 +03:00
Olli Paloviita 26b1d3f330 blocks: move identity to an editId option, stamp it on edit start
BREAKING: the name-first overloads of hide/speed/time are removed. A block's
stable identity now lives in the trailing options object, like an action's:
hide(fn, { editId: 'setup' }). The dev-startup handshake that stamps action
editIds now stamps blocks too (the options object lands right after the
callback argument), so every block gains a stable identity when an edit
session starts. blockRemoveEdit resolves blocks by the editId option (legacy
string-name args still match), making every stamped block web-removable.
2026-07-12 19:01:15 +03:00
Olli Paloviita 9965beb7ae Merge remote-tracking branch 'origin/editor' into editor
# Conflicts:
#	src/applyCodegen.spec.ts
2026-07-12 17:05:21 +03:00
Olli Paloviita 6d875ef0f0 Merge branch 'fable6' of /home/olli/projects/screenci-mono/worktrees/fable6/packages/screenci into editor 2026-07-12 16:40:05 +03:00
Olli Paloviita 351db23822 WIP: editor branch work in progress (auto-committed before merging fable6) 2026-07-12 16:39:20 +03:00
Olli Paloviita 0ad2115cf9 editor splits: add fromLeadMs/untilLeadMs for cuts before the first interaction
A gap span could only anchor forward (a sleep after an interaction's end or
a delay into it), so a cut over the footage leading into the first
interaction was unrepresentable. fromLeadMs pulls the span start to before
its anchor (codegen emits it as a leading waitForTimeout inside the wrap);
untilLeadMs is its end-boundary twin for editor-only bare splits. Bare-split
detection treats matching leads like matching sleeps.
2026-07-12 16:31:35 +03:00
Olli Paloviita c2aa007be3 Remove editor-owned overrides; codegen editor edits into code
Editor edits no longer fetch backend-stored overrides at record time.
Instead every edit is codegenned into the user's .screenci.ts sources
over the dev channel (or fails when no machine is connected).

- Remove the CLI override fetchers and their env plumbing
  (SCREENCI_VALUES_OVERRIDES / _RECORD_OPTIONS / _WEB_LANGUAGES), the
  parsers/merge in runtimeMode, resolveEffectiveRecordOptions, and the
  SCREENCI_DEBUG_OVERRIDES debug dump.
- Reconcile the languages model: drop the 'studio' sentinel, studioSeed,
  studioOwned, pending, and web-language unioning. A video with no
  .languages() is the implicit 'en' default; an explicit .languages([...])
  set is unioned with per-feature keys and filtered by --languages.
- Add codegen edit kinds and codemods: languagesEdit (setVideoLanguages),
  valuesEdit (setValuesValue), and editorMediaEdit (setEditorMedia).
- Add the { editor: '<name>' } media declaration for backend-hosted,
  editor-uploaded overlays / narration audio / audio tracks: the bytes
  stay in the backend, but the item is explicit in code (no local path).
- Rename internal resolveStudio* helpers to resolve*Base; keep wire/DB
  keys that deployed CLIs and stored recordings depend on.
- Update docs (languages, editor, overlays, narration, video-script-basics).
2026-07-12 16:29:41 +03:00
Olli Paloviita 13b6a36b48 codegen: format edited files with the project's Prettier, enabled by init
Editor codegen edits and dev startup editId stamping now format each
changed file with the user project's own prettier install before
writing. Formatting is gated on prettier resolving and a Prettier
config file being found for the edited file, so it is opt-in by
presence and never fails the edit: errors pass the content through
unchanged with a warning.

screenci init enables it by scaffolding a minimal user-editable
.prettierrc (2-space indent, single quotes, no semicolons, matching
the generated example style) and installing prettier in the island,
plus a format script and README note. Docs updated (editor.md,
manual-setup.mdx).
2026-07-12 16:02:03 +03:00
Olli Paloviita e30d12b1b3 docs: finish codegen-model pass on editor and cli docs
Remove the stale screenci status and sync sections from the CLI reference
(both commands are gone on this branch, codegen writes edits into sources
directly) and reword the timeline editing intros that still claimed edits
apply without code changes.
2026-07-12 13:32:15 +03:00
Olli Paloviita 36223a54b5 Merge fable4: align docs with the preview-first editor and screenci dev editing
# Conflicts:
#	docs/cli.mdx
#	docs/editor.md
2026-07-12 13:26:50 +03:00
Olli Paloviita ba8ae80c9a Merge fable6 screenci: typed refusals, alias resolution, stale wrap cleanup, shared wire types 2026-07-12 13:20:03 +03:00
Olli Paloviita c160b8a2f2 docs: align docs with the preview-first editor and screenci dev editing
Rewrite editor.md around the sync-gated codegen model (connected machine,
live preview, timeline, Export-first), fix the record vs export flow in
overview, agent-integration, manual-setup, cli, ci-setup, version-history,
public-urls-and-embeds, update-screenci, and video-script-basics, fix the
broken captureAudio examples (boolean | { gain }), document accent and the
web narration/overlay editing, add enableCaptureAudio to configuration, and
rename the CLI's Studio strings to Editor.
2026-07-12 10:28:39 +03:00
Olli Paloviita 075396f935 codegen: typed refusal reasons, aliased-import resolution, stale wrap cleanup, shared wire types
- planCodeSync unappliable items now carry a typed UnappliableReason
  plus the human message; applyCodegenRequest errors name the reason so
  the editor toast is actionable.
- Block/point/effect calls resolve through the file's import table, so
  aliased imports (autoZoom as az) are found, wrapped, unwrapped, and
  reused on insert; unresolvable functions refuse with
  unresolved-import.
- plannedRemoval unwraps stale editor-owned zoom/hide/speed/time wraps
  (anonymous blocks over the anchors) instead of leaving them in code.
- timelineEdits gains paramEditIdFor/renameEditIdFor and parseEditId,
  exported via the new screenci/timeline-edits subpath so the web app
  compiles against the same wire types and id encoding.
- Tests: refusal reasons, alias resolution, stale wrap unwrapping,
  TS-absent guard, plain-JS parsing, locator alias chains, editsOverlap.
- Docs: refusal reasons and alias support in cli.mdx and editor.md.
2026-07-12 03:22:37 +03:00
Olli Paloviita 7009d64b09 Merge fable4: allow expressive narration and style prompts on every plan 2026-07-12 02:30:53 +03:00
Olli Paloviita fc53ed765e billing: allow expressive narration and style prompts on every plan 2026-07-12 02:29:16 +03:00
Olli Paloviita 55b3fb0993 Merge editor-branch screenci (codegen model) into fable6
Adapts the scissors additions to the codegen architecture: blockRemoveEdit
is routed as a codify record through splitTimelineEditsByVideo and applied
by the dev codegen channel; bare-split hides stay editor-only (skipped by
the planner); the sync-era parse/apply/report subsystem removed on the
editor branch stays removed.
2026-07-12 00:22:21 +03:00
Olli Paloviita eacc5df17a editor codegen for options and narration, dev source watching
- optionsEdit and narrationEdit records (timeline edits v4): render/record
  option snapshots merge into .renderOptions/.recordOptions builder calls
  (section added when missing), narration cue values merge into the
  video.narration declaration via the new setNarrationValue codemod
  (content-major and language-major forms, conversion to language-major on
  a non-default language edit, names-only declarations stay app-managed)
- applyCodegenRequest wires the new records into planCodeSync
- screenci dev watches the managed videos' test sources and
  screenci.config.ts (src/devWatch.ts): a real content change re-records
  the affected videos as previews through a new machine-local record job
  in the listen loop; codegen self-writes are baseline-suppressed;
  --no-watch disables it
- docs: cli.mdx dev watching, editor.md option/narration codegen coverage
2026-07-12 00:04:38 +03:00
Olli Paloviita 10276a703b editor: hidden-action markers, bare-split skip, and named-block unwrap for the web scissors feature
- Record a hiddenAction marker event for every instrumented action inside
  hide(), so the web editor can show what a hide suppresses.
- Skip zero-width hide gapSpanEdits at sync: bare split markers stay
  editor-only state and are never codified as empty hide() blocks.
- New blockRemoveEdit record + unwrapBlockCall codemod: unwrap a NAMED
  hide/speed/time block from source, keeping the wrapped calls and their
  waitForTimeout pacing.
2026-07-12 00:03:13 +03:00
Olli Paloviita 4eb5805499 Merge branch 'fable4' into editor
# Conflicts:
#	docs/cli.mdx
2026-07-11 22:13:56 +03:00
Olli Paloviita 16dcce8e18 Merge code-as-source-of-truth editing (fable3)
Editor edits now arrive over the dev channel as codegen requests and are
written straight into the .screenci.ts sources; recordings always run purely
from code values.

- Keep data.json across uploads (media-only cleanup, last-data.json rename)
  and stamp a sourceHash of the test file into its metadata.
- screenci dev startup handshake: skip recording when the source hash matches
  and every editable action has an editId; otherwise stamp missing editIds
  and re-record as a preview. New --grep, --force-record and
  --record-kill-window flags.
- Dev loop: killable background record slot, serial codegen applies acked
  over /cli/dev/report-codegen, fast-poll during active editing, kill-or-queue
  policy for superseding triggers, sync-state timeline locking.
- Removed: editable-actions.json and action-params.json snapshots,
  SCREENCI_TIMELINE_EDITS injection, runtime override application,
  screenci sync / status / reset-web-edits and dev --sync.
2026-07-11 22:02:20 +03:00
Olli Paloviita f34dfb5edb release: hide unfinished features from the SDK surface and docs
Comment out (not delete) the screenshot(), narration positioning
(moveNarration/resizeNarration), setBackground, background audio, and
selected() dependency exports; remove values()/audio() from the public
builder type while keeping them attached at runtime. Move the values,
audio, screenshots, and dependencies guides out of the docs manifest
(sources now live in docs/removed/ at the mono repo root), trim the
overlay-updates guide to the still-exported APIs, and scrub mentions
from the remaining docs and the agent skill.
2026-07-11 21:52:56 +03:00
Olli Paloviita 04393fa30e feat: code-as-source-of-truth editing via dev codegen channel
Editor edits now arrive over the dev channel as codegen requests and are
written straight into the .screenci.ts sources; recordings always run purely
from code values.

- Keep data.json across uploads (media-only cleanup, last-data.json rename)
  and stamp a sourceHash of the test file into its metadata.
- screenci dev startup handshake: skip recording when the source hash matches
  and every editable action has an editId; otherwise stamp missing editIds
  and re-record as a preview. New --grep, --force-record and
  --record-kill-window flags.
- Dev loop: records run in a killable background slot while the loop keeps
  polling; codegen requests apply serially via the codemod pipeline and are
  acked over /cli/dev/report-codegen; fast-poll during active editing;
  kill-or-queue policy for superseding record triggers; sync-state reporting
  locks editor timelines during the startup handshake.
- Remove the server-override machinery: editable-actions.json and
  action-params.json snapshots, SCREENCI_TIMELINE_EDITS injection, runtime
  override application, screenci sync / status / reset-web-edits and
  dev --sync.
2026-07-11 21:52:29 +03:00
Olli Paloviita 8e0929d707 cli: rename --publish to --export (deprecated aliases kept), docs talk about exports 2026-07-11 20:29:20 +03:00
Olli Paloviita cac85fd4a9 docs: version retention is 5 per language on all tiers, with a prune grace window 2026-07-11 13:08:10 +03:00
Olli Paloviita 4b12051e49 feat: delay option to offset recorded event timestamps
Adds an optional delay (ms) to instant overlay updates (setBackground,
moveNarration, resizeNarration, resizeRecording, hideRecording,
showRecording, hideNarration, showNarration), media start() calls
(narration cues, overlays, audio), and the hide/speed/time wrappers
(start stamp only). The recorder stamps the event at call time + delay,
so a call written before an interaction can take effect during it.

Same-type events must stay in time order: recording fails with a clear
error when a delayed event would land behind one recorded after it, or
when a delay pushes an event past the end of the recording.

screenci sync learns delayMs on gapPointEdit/mediaEdit/gapSpanEdit:
the call is codified BEFORE the anchor interaction with { delay },
idempotently, including sleep<->delay placement switches and removal.
2026-07-11 10:21:27 +03:00
Olli Paloviita d3fb8d80bf editor: web-editable cursor curves with visual bezier editing support
- cursorCurve: controlPointsToTuple (inverse mapping) and parseCursorCurve
- instrument: stamp effective moveCurve/moveCurviness into editable defaults
  at every pointer wrapper, and apply saved curve overrides at record time
- codeSync: codify cursor-move param edits (move.duration/speed/easing/
  curve/curviness/delayAfter, duration, easing, dragSteps) onto the stamped
  call, with duration-vs-speed exclusivity and an overlap guard
- easing: browser-safe EASING_NAMES re-export for the web editor
- docs: visual curve editing and cursor-move codesync
2026-07-11 09:38:06 +03:00
Olli Paloviita e5e1cfb43d asset: require an explicit overlay placement (fill | over | box)
Breaking: an overlay config object must now pick exactly one placement
variant, enforced by a discriminated union (OverlayFillPlacement |
OverlayOverPlacement | OverlayBoxPlacement). The implicit "no placement
fields = fill the recording" default is removed for config objects; the
bare path-string and React-element shorthands still mean fill: 'recording'.
selected(...) render dependencies now require a placement too.

A placement resolved from an over locator additionally records
overLocked, marginPx, and the raw elementRect on the assetStart event,
so editors know the box is pinned to a live element and only its margin
is adjustable.
2026-07-11 01:45:35 +03:00
Olli Paloviita 08cec9e62c record: encode an alpha-capable preview clip for animated overlays
Animated (code/react) overlays are encoded as a dual-stream mp4 (color +
alpha matte) that only the renderer can composite; a browser <video> plays
the color stream alone, so the web editor's live preview showed the overlay
on an opaque black card. Rasterization now also encodes a VP9 .webm with a
real alpha channel (best-effort: skipped when ffmpeg lacks libvpx-vp9),
stamps it on the assetStart event as previewPath/previewFileHash, and the
CLI uploads it alongside the render clip so the editor can play it with
transparency.
2026-07-10 21:33:07 +03:00
Olli Paloviita ce1cc9573d record: make narration pacing opt-in via recordOptions.actualNarrationPace
Recording is now fast by default and independent of narration length; the
render's frame holds remain the source of truth for cue timing. Opt into
record-time cue-audio pacing with recordOptions.actualNarrationPace, replacing
the removed --fast-narration flag and SCREENCI_FAST_NARRATION env.
2026-07-09 16:23:58 +03:00
Olli Paloviita a58c5297eb Add nonlinear (curved) cursor movements
Cursor moves can now follow a cubic-bezier path instead of a straight line.
New move.curve ('none' | 'natural' | 'arc' | normalized [x1,y1,x2,y2] tuple)
and signed move.curviness options on every locator action and page.mouse
move/click, plus project-wide recordOptions.cursorCurve / cursorCurviness.

Curves resolve to absolute-px control points baked onto the recorded event
(FocusChangeEvent.mouse.control); the real dispatched cursor follows the
bezier so hover/pointer events fire along the arc. Easing still drives the
speed along the path.
2026-07-09 07:16:41 +03:00
Olli Paloviita 9f4559a97c sync: codify Studio render/record option edits into video builder calls
screenci sync now also writes web-editor render/record option edits into
video.renderOptions({...}) / video.recordOptions({...}) builder calls,
closing the code round-trip. New codemod setBuilderOptions locates the
video by its name literal and inserts or deep-merges the options into the
builder chain (video('N',fn), video.narration([...])('N',fn), etc.),
idempotent and conservative (null rather than mangle an unknown chain).
Re-adds the injectable studio-sync fetcher wired through runSync and
dev --sync.
2026-07-09 01:43:17 +03:00
Olli Paloviita 543560fa6a Remove vestigial autoZoom startOffset/endOffset
applyZoomWindowOffsets (the only consumer) was deleted with the linear
timeline redesign, and the renderer never read these fields, so
startOffset/endOffset on autoZoom did nothing. Drop them from
AutoZoomOptions, DEFAULT_ZOOM_OPTIONS, the autoZoomStart event, the
event serialization, and the sync codemod path. Zoom lead-in/hold is now
expressed by where the autoZoom block sits plus interior waitForTimeout
sleeps.
2026-07-09 01:35:34 +03:00
Olli Paloviita 1131eb0b55 sync codemod: ghost-sleep reconcile and idempotent re-sync
Re-syncing an unchanged edit set is now a no-op: media/point placements
find their prior codemod-authored effect call + adjacent sleep and update
in place instead of stacking; changed sleep values rewrite the existing
waitForTimeout; zoom/span wraps are detected and not re-wrapped. Removing
an effect in the editor (a disabled codify record) deletes the codemod-
authored call and re-coalesces its split gap sleep, but only when the
sleep ms matches the record so hand-authored sleeps are never touched.
Zoom/gap-span unwrap-on-removal is left conservative (documented).
2026-07-09 01:33:13 +03:00
Olli Paloviita dba07921f3 docs: rewrite to the linear call-position model
Drop timestamp()/waitSince()/place* and the sync-prompt agent path from
the guides; describe effects as call-position block wrappers (autoZoom/
hide/speed/time) plus waitForTimeout gaps, keyed to editId. Move the last
config-level use.recordOptions/renderOptions examples to the per-video
video.recordOptions()/renderOptions() builder form.
2026-07-09 00:57:42 +03:00
Olli Paloviita dfaa8f6f13 Linear timeline wire model: editId-keyed edits, drop anchors + prompt path
Replaces the anchor+offset placed-event wire model with editId-keyed
call-position records (MediaEdit/ZoomEdit/GapSpanEdit/GapPointEdit;
ParamEdit/RenameEdit kept). Deletes all record-time materialization of
anchored events (applyPlacedEvents/applyZoomWindowOffsets/resolveTimeline
Anchor/insertSorted) and the entire agent-prompt path (buildSyncPrompt,
buildEditablePlacementPrompt, buildStudioSyncPrompt, the sync-prompt
command, printSyncPrompt, codeSync fallback). Rewrites the sync codemod
to place effects into the linear code timeline: media/points inserted
between interactions with split waitForTimeout gaps, zoom/hide/speed/time
wrapped as blocks over interaction runs, with a loop/branch lock guard.
Ghost-sleep reconcile left as a follow-up (todo).

TIMELINE_EDITS_VERSION -> 3.
2026-07-09 00:40:33 +03:00
Olli Paloviita 0fb082bc56 Remove config-level use.recordOptions/renderOptions
Record and render options are now settable only per video via
video.recordOptions(...)/video.renderOptions(...) (the web editor is the
source of truth). Drops the config use.* fields and the remapConfigOptions
plumbing; the internal default-options fixtures stay as the base layer.
Docs (configuration, ci-setup, screen-audio) migrated to the per-video
form.
2026-07-08 22:48:17 +03:00
Olli Paloviita e0ac78f905 sync: apply edits exclusively by editId, remove heuristic matching
Option edits resolve their call sites via the editId recorded on
action-param records; sleepBefore, autoZoom offsets, and placed events
anchor by slug too. The selector/occurrence lexical matcher, line
anchors, and loop detection are gone: unstamped actions are never
guessed at and route to the agent prompt until a record plus sync
stamps them.
2026-07-08 21:21:05 +03:00
Olli Paloviita 8310f5b3e4 editId stamping: slug prefix is always the function name
pressSequentially stamps as pressSequentially1 (not type1), autoZoom as
autoZoom1, selectOption as selectOption1.
2026-07-08 21:11:13 +03:00
Olli Paloviita 24892e96f0 editId renames: web rename record applied to code by sync
New renameEdit timeline record { target: { editId }, newEditId }.
screenci sync and dev --sync apply it by replacing the slug string
literal (renames run last so earlier edits key on the old slug);
invalid or unlocatable renames fall through to the agent prompt.
Slugs validate as [A-Za-z0-9_-]+.
2026-07-08 20:44:11 +03:00
Olli Paloviita b18aca1619 editId: stable human-readable identity for editable actions
Actions and autoZoom blocks accept an optional editId slug (click1,
zoom2). screenci sync and dev --sync stamp missing slugs automatically
using the call sites captured at record time, allocating from the
committed .screenci/edit-ids.json (numbers never reused, ids never
removed). With an editId the stable key IS the slug, so editor edits
and placed-event anchors survive refactors, moved lines, and locator
changes; sync locates call sites by exact slug instead of heuristics.
Loop executions key as slug#N and stay web-runtime-only.

Also: record --no-render uploads the recording and editable data
without dispatching a render, for a fast first editor sync.
2026-07-08 20:03:02 +03:00
Olli Paloviita edfc0063c8 pressSequentially: editable typing duration scaled by character count
pressSequentially now tracks a typing duration like fill and exposes it as an
editable field, but because it types key by key its default total scales with
the text length (about 60ms per character) instead of a fixed spread. An
explicit duration wins; a native per-key delay is read as the per-character
cadence. The effective total drives the per-key delay handed to Playwright.
Adds a DEFAULT_PRESS_SEQUENTIALLY_MS_PER_CHAR constant, the duration option and
docs, and a test asserting the char-count scaling.
2026-07-08 19:34:05 +03:00
Olli Paloviita 2c7e4f4781 screenci dev --sync: auto-apply web editor edits to sources while listening
A background loop polls the editor's edits, applies what static
analysis can (screenci sync semantics), and clears the web edits of
videos whose pending edits were all applied. Pauses during triggered
records. sleepBefore edits now update an existing waitForTimeout
directly before the action instead of stacking a new one, keeping
repeated syncs idempotent; inserted placed events are remembered by
signature for the session.
2026-07-08 19:11:45 +03:00
Olli Paloviita d55b5b3cf1 Add screenci sync: apply web editor edits to sources via static analysis
New command applies action-option changes, sleepBefore waits, autoZoom
offsets, and placeHide/Speed/Time/Zoom calls directly to .screenci.ts
files using the TypeScript parser with raw text splices (formatting and
comments preserved). Anything ambiguous (loops, spreads, stale edits,
narration content) falls back to the existing agent sync prompt.
Dry-run diff by default; --write saves, --write --reset clears web
edits for fully applied videos.
2026-07-08 18:56:32 +03:00
Olli Paloviita e9f961c37e sync-prompt: include Studio render/record option overrides and content notes
Add a /cli/studio-sync fetch and a pure studioSync builder so screenci
sync-prompt emits SET directives for the render and record options the web
editor holds, plus NOTE lines for narration/text/audio/overlay edits, letting
an agent codify render options into the scripts too.
2026-07-08 18:03:59 +03:00
Olli Paloviita 25a6d61017 Merge commit '9c4cfd284f0a92a44b1ddaaa5a8e8d9f454d17f7' 2026-07-08 14:37:42 +03:00