Commit Graph
42 Commits
Author SHA1 Message Date
Claude 24aed7f219 App: launching opens an empty project, not the demo (#204)
The desktop app opened the demo project whenever it wasn't given a
project file, so File ▸ New Composition on the Home screen added "Comp
4" to the three demo comps. As in After Effects, a launch now starts
with an empty Untitled Project. --demo opens the demo (Help ▸ Open
Demo Project and the Home screen tile still do); --empty is kept.

The arguments are parsed by a function now, with a test
(no_arguments_start_an_empty_project).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Claude-Session: https://claude.ai/code/session_018gnTnH3Jmk5zr4tMq1Mc9f
2026-10-07 22:13:19 +00:00
bflatasticandClaude Opus 5.5 d416d9a01f MCP: add_effect is one undo step and leaves nothing applied when it fails (#175)
add_effect ran effect.apply and then one prop.set per `values` entry as
separate commands: each became its own undo step, and a bad value (an
unknown parameter id) returned an error but left the effect, and any
values set before it, on the layer, so a corrected retry landed at
effects/#2.

It now runs them as one engine.batch, named like effect.apply's own undo
step ("Apply Gaussian Blur"): one undo removes the effect with its values,
and a failing step rolls the whole call back. The reply is unchanged.

Test: add_effect_is_one_undo_step_and_all_or_nothing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 15:48:17 +07:00
bflatasticandClaude Opus 5.5 8421489167 Expressions: prop.get reports a syntax error that disabled the expression (#163)
prop.setExpression keeps an expression with a syntax error but disables
it, and says why only in its own reply. MCP set_property answers with
prop.get instead, and prop.get reported `evaluated` / `expressionError`
only for enabled expressions, so set_property, get_property and prop.get
all showed the broken expression as if it were installed.

prop.get now reports a disabled expression too: `evaluated` is the
static value that renders, and `expressionError` is its syntax error.

Test: expression_syntax_errors_reach_the_reply (set_property and
get_property carry the SyntaxError; runtime errors and valid expressions
report as before).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 15:48:17 +07:00
bflatasticandClaude Opus 5.5 50f26e6a47 CLI: unknown options are usage errors (#168)
Args::parse kept any unrecognised `--option` as a valueless flag nobody
read, so `exec comp.new --bogus` ran with defaults and exit 0, and a
misspelt valued option left its value behind as a positional:
`--saveas z.ecproj` opened z.ecproj as the project and failed with an
unrelated "cannot read" error.

Options are now checked against the declared lists (VALUED and the new
FLAGS) before anything runs; unknown ones are a usage error naming them
(exit 2), and `--flag=value` on a flag says it takes no value.
render-frame's `--transparent` (the MCP render_frame option) was one of
the silently ignored options; it now keeps the frame's alpha.

Tests: unknown_options_are_refused, every_option_read_is_declared (every
option the code reads is declared, so none is refused),
unknown_options_are_usage_errors (exit 2, nothing runs or renders, and
--transparent renders alpha).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 15:48:17 +07:00
bflatasticandClaude Opus 5.5 eb5e72cdfa Docs: agents.md lists every MCP tool and argument, checked by a test (#137)
The Tools table gains history and script_ui, get_layer's depth,
add_keyframe's comp and the bridge screenshot's max_side and path.
agents_doc_tools_table_is_current (effectcraft-automation) fails when a
tool or an argument of its input schema is missing from the table, as
effects_doc_is_current guards docs/effects.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-07 12:00:47 +07:00
Claude dda9961889 G2: font menus list the installed fonts
A Windows user reported that the Properties panel's font menu offered only the bundled Inter,
JetBrains Mono and Noto Serif. The system font folders were scanned only when a project asked for
a family the bundled fonts lack, so until then every font menu (Properties, Character, Essential
Graphics) and `file.findMissing {what: fonts}` saw the bundled families alone, on every
platform. Listing the families now scans the system fonts first, and the desktop app starts that
scan on a background thread at launch so the menus are complete when first opened.

The style menus in the Properties and Character panels list the chosen family's own styles
instead of a fixed Regular / Medium / SemiBold / Bold / Italic. Both menus build their lists only
while open.

New query for agents: `text.fonts {query?, rescan?}` (MCP tool `list_fonts`) lists every family
with its styles, origin (bundled / system / user) and own-language name; `rescan` picks up fonts
installed since launch.

Tests: a fresh-process test that the family list includes every family in the platform's font
folders without a prior scan (failed before), and `text.fonts` filtering, rescan and per-family
styles, and the `list_fonts` MCP tool.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_019EjTYdt76hTG4Kh2CJFnCr
2026-10-06 15:14:55 +00:00
bflatasticandClaude Opus 5.5 e43bf66775 M13.36: face tracking trained model — MediaPipe Face Landmarker on a pure-Rust TFLite interpreter
- effectcraft-segment: a FaceModel interface (find a face in a region, follow it; a Topology
  maps the model's points to the tracker's landmarks and outline), a TensorFlow Lite reader and
  interpreter (float ops, float16 weights folded; matches ai-edge-litert to ~1e-6), and
  MediaPipe Face Landmarker (Google, Apache-2.0: BlazeFace + Face Mesh V2, 3.8 MB, pinned
  SHA-256). The registry gains a task and authors per model; installed weights get a NOTICE.
- effectcraft-track: FaceTracker::new_with uses the model, falls back to the classical fitter
  when it finds no face; chin and jaw come from the outline either way so measurements agree.
- Engine: roto_models becomes models (both tasks); face.models / face.model.* commands,
  Settings ▸ Face Tracking, `wait` on select/install/download for scripts; track.mask reports
  faceModel.
- Credits: ATTRIBUTION.md lists the optional models and the Apache-2.0 specs the code follows.
- Docs: README, ROADMAP (G7), gaps, parity (TRK-3 score unchanged pending G1), agents,
  preferences, architecture, segment README.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 20:39:45 +07:00
bflatasticandClaude Opus 5.5 7579de21c6 M13.35: Roto Brush trained model — swappable segment module, MobileSAM in pure Rust
- New L1 crate effectcraft-segment: the MaskModel interface (prompts → foreground probability),
  a registry of open-licensed models (licence must be MIT/Apache/BSD/…; URL, size, SHA-256),
  a PyTorch checkpoint reader (zip + pickle subset), dependency-free SHA-256, and MobileSAM
  (TinyViT-5M + SAM prompt encoder / two-way transformer / mask decoder) on rayon and ndarray's
  safe GEMM. Loads the official mobile_sam.pt as published; checked against candle
  (embedding 0.3% RMS, 99.9% equal mask pixels); ~0.7 s/frame encoder at 32 threads, cached
  per frame, ~0.1 s decoder.
- track::roto: segment_with / propagate_with prompt a model with the strokes or the flow-warped
  matte (box, core points, mask); its probability is a strong, unblurred prior for the same
  graph cut (strokes stay hard constraints); a failing model or one disagreeing with the flow
  (IoU < 0.5) is ignored. Prior gets a weight.
- effects::roto: Version 2.0 / 3.0 use the model chosen in Settings (set_model / model_for);
  the model id is part of the chain seed.
- engine: roto_models (roto.models, roto.model.select / install / download / remove), weights in
  the models folder (host::config_dir()/models, shared by the app, CLI and MCP), background
  loading, downloads through the system curl, verified; Settings ▸ Roto Brush page (prefs
  roto.model). host::config_dir moved from the desktop app.
- Tests: segment (kernels vs direct sums, checkpoint reader, SHA-256 vectors, registry), track
  (fake model: prior shapes the cut, failing / disagreeing models ignored; real weights with
  EFFECTCRAFT_MOBILESAM: base IoU 0.989, propagated ≥ 0.980 vs classic 0.973), engine (registry,
  verification, selection; real install + load), MCP.
- Docs: README, ROADMAP, parity (MSK-4 done: 90/2/0), preferences, agents, architecture,
  crates/segment/README.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 17:55:02 +07:00
bflatasticandClaude Opus 5.5 73b2607c9a M5.16: Key Light: keyer eyedroppers pick from the effect input (effect.pickColor); "keylight" search
- effect.pickColor {effect, param|prop, x, y (layer px), average?}: the colour of the effect's
  input at a point, set on the parameter (one undo step). Keying effects' Effect Controls
  eyedroppers use it, since the shown frame is already keyed; Ctrl/Cmd+click averages 5x5.
- effects::aliases / name_matches: Effects & Presets and effect.list (MCP list_effects) find
  Key Light by After Effects' name ("Keylight (1.2)").
- End-to-end test: a green-screen plate with an uneven screen, spill and soft edges keyed via
  effect.apply "Keylight (1.2)", pick, Clip Black / White and a render; UI eyedropper test.
- Docs: parity, agents (green-screen recipe).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 11:04:10 +07:00
bflatasticandClaude Opus 5.5 47f2a5a3e6 M5.15: J / K and Select All Keyframes use what the Timeline shows; Graph Editor Auto-Select Graph Type
- J / K (Go to Previous / Next Keyframe) and Ctrl+Alt+A (Select All Keyframes) act on what the
  Timeline shows, as in After Effects: the keys of its revealed properties, layer and comp
  markers and the work area (they used every property of the selected or all layers, revealed
  or not). The commands take `visible: [{layer, prop}]`, which the Timeline fills in; agents
  calling them without it keep the previous behaviour.
- Graph Editor ▸ Auto-Select Graph Type (an "Auto" button, on by default as in After Effects):
  the speed graph when every property shown is spatial (Position, Anchor Point…), else the
  value graph; choosing Value or Speed turns it off.
- Docs: parity, agents.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 10:36:55 +07:00
bflatasticandClaude Opus 5.5 ef856d8f67 M5.14: docs: parity, agents and preferences cover the keyframe, clipboard and responsiveness fixes
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 08:06:32 +07:00
bflatasticandClaude Opus 5.5 cb892b5239 M4.12: docs: ROADMAP, parity, web, preferences and agents brought up to date after M3 and M4
- parity: the status note covers the M3.9–M4.12 passes (feature counts unchanged: they fixed
  behaviour inside features already counted done) and the GPU effect count matches EFF-5 (280);
  the Layers, Compositions, Interface, Project and Preview rows name what is left and what
  landed; landed items in "Highest-value gaps" are struck through with where they landed, the
  gaps the passes left are items 16–18, and the closing paragraph no longer says 69 menu entries
  are disabled.
- ROADMAP: what is left includes the preview gaps.
- web: a restored session with unsaved changes stays modified and asks before closing.
- preferences: Adaptive Resolution Limit applies while dragging, not to playing previews.
- agents: nested comp settings and New Comp from Selection for several items.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-05 06:35:00 +07:00
bflatasticandClaude Opus 5.5 89653f37de M3.11: layer commands respect locks, keep children in place on delete, arrange step by step, keep depth and separated dimensions, keep links on duplicate/paste
- Locked layers can't be selected (Timeline click, Select All, Ctrl+Up/Down; shy layers while
  hidden too) and are left alone by Clear/Delete, Arrange, Layer ▸ Transform and Center Anchor
  Point, which fail when every target is locked (`commands::unlocked`, `commands::selectable`).
- Deleting a parent unparents its children where they are, in the same undo step: the
  pick-whip compensation moved out of `layer.setParent` into `layer::parent_fixes` /
  `ParentFix::apply`, which now also handles separated X/Y Position.
- Bring Forward / Send Backward move each selected layer one step (a non-contiguous selection
  was squeezed into one block).
- Center In View / Fit to Comp keep a 3D layer's Z (and Fit keeps Scale/Anchor Z); Reset /
  Center / Fit / Center Anchor Point work with separated dimensions (`layer::update_position`).
- Duplicate and paste keep parents and track mattes, following the copies when both were
  copied; paste dropped them always.
- Docs: agents, parity.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:33:54 +07:00
bflatasticandClaude Opus 5.5 753de070a0 M3.10: Layer Settings opens Solid Settings with "Affect all layers that use this solid"; settings dialogs register every control
- Layer ▸ Layer Settings on a solid or adjustment layer opens Solid Settings on the layer's
  solid (it ran an empty command before): name (renames the layer and the solid), size, Pixel
  Aspect Ratio, colour, and "Affect all layers that use this solid". It starts off, as in After
  Effects, so changing a solid other layers share gives this layer its own copy.
  `layer.settings {pixelAspect?, affectAll?}` → `{layer, solid?}`; `layer.newSolid {pixelAspect?}`.
- Nulls ask for their name; text and shape layers have no settings (the entry is disabled).
- Composition Settings / New Composition and Solid Settings register an automation id for
  every control (`dialog.comp.*`, `dialog.solid.*`). Composition Settings takes any typed frame
  rate besides the list, and New Composition starts from the last settings used.
- Colour buttons in both dialogs show the stored sRGB colour (`widgets::srgb_color_button`);
  egui's linear picker showed it lighter.
- Docs: agents, parity.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:22:09 +07:00
bflatasticandClaude Opus 5.5 e0ed28f55d M3.9: closing a modified project asks to save it first; the modified mark follows undo
- Quit and the window's close button, File ▸ New Project, Open Project, Open Recent, Close
  Project, the demo project and a Home template show Save / Don't Save / Cancel when the
  project has unsaved changes (Save asks for a path when untitled; cancelling that keeps the
  project open). File ▸ Revert asks to discard. Before, all of them dropped unsaved work
  without asking.
- The window title shows the project's path and `*` while it is modified.
- The modified mark follows undo: the session keeps the snapshot it last opened or saved
  (`Session::saved_project`), so undoing, jumping in the History panel or rolling back a batch
  to the saved state clears it.
- An edit that changes nothing (a value set to what it already is) records no undo step and
  doesn't mark the project modified (`Project::same_content`, comparing untouched comps by
  pointer).
- Agents' `engine.execute` / MCP calls are never asked; `ui.menu.invoke` shows the prompt like a
  click (automation ids `dialog.unsaved.save` / `dontSave` / `revert` / `cancel`), and the
  control channel's `app.quit {force: true}` skips it.
- Docs: architecture, agents, control protocol, parity.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 23:02:14 +07:00
Brandon ThomasandClaude Opus 5.5 b73028d999 Merge branch 'main' into worktree-agent-a9fea98fe9839069d (filmcraft rev 2c5ba7a: AAF and OMF interchange)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 00:45:00 -04:00
Brandon ThomasandClaude Opus 5.5 955422819c M13.26: Premiere Pro interop commands (file.importTimeline, file.exportTimeline with ProRes 4444 pre-renders), File menu entries, export dialog, docs and pixel round-trip tests
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-04 00:25:43 -04:00
Brandon ThomasandClaude Opus 5.5 cc5c831c0a media: WebM VP9 alpha imports as straight alpha (FilmCraft 2c5ba7a)
Bump the FilmCraft crates from 89cfbf2 to 2c5ba7a (118 commits; no API
changes needed here), whose Matroska reader now decodes the VP9 alpha
stream from BlockAdditions. The compositing QA scenario now checks that
WebM renders round-trip their alpha like ProRes 4444.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 23:57:57 -04:00
Brandon ThomasandClaude Opus 5.5 081ce79de3 Merge M13.14 agent-interface audit + lazy open (worktree-agent-a5f8967ebd42ce98b)
The branch's commits say M13.14; on main that id is the puppet work, so this arc is M13.21.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 17:23:10 -04:00
bflatastic f95eface83 M13.20: docs — README (Timeline shortcuts and Puppet tools), control protocol (reveal / keyAt / twirlSelected UI commands, timeline.layer.<id>.row and viewer.puppetPin.<uid> element ids), agents guide (Timeline: layer.arrange above, reveal shortcuts, keys.toggleTransform, rename), architecture (puppet selection, rigging and follow-through; per-thread expression context recovery), parity (M13.17–M13.20) 2026-10-04 01:10:36 +07:00
BFlat bb06a66083 Merge pull request #2 from storytold/puppet-rigging
Puppet tools: pin editing, rigging to nulls, follow-through; expression runtime fix
2026-10-04 00:26:24 +07:00
bflatastic a02bcc8441 M13.16: puppet Follow-Through — puppet.follow (Puppet tool bar ▸ Follow-Through…) makes pins trail a leader pin for hair, cloth and overlapping action: each follower's Position adds the leader's displacement from rest delayed by delay (the k-th nearest by k × delay with Cascade), scaled by Amount, keeping its own keyframes; leader = the first selected pin, followers = the others; one undo step; reachable over MCP (execute_command) 2026-10-04 00:19:26 +07:00
bflatastic 6ec177de83 M13.15: rig puppet pins to nulls — Points Follow Nulls / Nulls Follow Points (Window ▸ Create Nulls From Paths, paths.* {pins?}) take selected pins, named pins, or every pin of a layer with no path: a null per Position / Advanced pin drives its Position (fromComp of the null's anchor, so parented nulls rig limbs), or rides on it (toComp of the pin's Position) to carry other layers; one undo step 2026-10-04 00:19:25 +07:00
bflatastic 6869cff51b M13.14: puppet pin editing — click / Shift-click selects pins (puppet.selectPins), a drag from empty canvas or Alt-drag marquee-selects them, Select All with a pin selected takes every pin of that kind, Delete removes the selected pins instead of their layer; Advanced and Bend pins rotate by their ring and scale by its square (Shift: 15° / 5 % steps, one undo step per drag); ⌘/Ctrl-dragging one of several selected pins records them all; pins in their kind's colour, larger under the pointer; pushpin icons for the five pin tools 2026-10-04 00:19:24 +07:00
Brandon Thomas 91bd8ca7c8 Merge main into M13.14
# Conflicts:
#	crates/engine/src/lib.rs
#	docs/agents.md
2026-10-03 13:13:50 -04:00
Brandon ThomasandClaude Opus 5.5 12235b5dc5 M13.15: qa project lifecycle; Collect Files makes its folder; agents cookbook
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 12:56:41 -04:00
Brandon ThomasandClaude Opus 5.5 8a4a2bfc52 M13.14: lazy project open, non-blocking UI with large projects, bench --ops
- footage.check: background footage check after File > Open (Progress panel), not an undo step
- timeline: track-matte / parent menus built only while open (was O(n^2) per frame);
  expression-row lookup per layer; panels hold Arc<Comp> snapshots instead of deep clones
- Project panel: virtualised vertical scrolling, selection reveal, thumbnails rendered off
  the UI thread
- effectcraft-cli bench --ops (engine::perf + ui-egui::bench)

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 11:49:55 -04:00
Brandon Thomas 6102d1523e Merge branch 'worktree-agent-a5320bec04bab3dac'
# Conflicts:
#	docs/parity.md
2026-10-03 05:09:10 -04:00
Brandon ThomasandClaude Opus 5.5 d209fa001f M13.3: face tracking methods, Face Track Points / Measurements, camera lens distortion, docs
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 04:36:12 -04:00
Brandon ThomasandClaude Opus 5.5 00eb951711 M13.1: ScriptUI frontend (dialogs, palettes, dockable panels), script menus, example plug-in, docs
- ui-egui: scriptui_view draws script windows at engine layout bounds; PanelKind::ScriptPanel; File ▸ Scripts and Window menu list scripts/panels (egui + native menus)
- examples/plugins/posterize-bands (WebAssembly, API v1); host plug-in tests; desktop loads <config>/Plug-ins
- MCP: script_ui and history tools; docs/plugins.md, agents.md, parity, architecture, ATTRIBUTION

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-03 04:24:01 -04:00
Brandon ThomasandClaude Opus 5.5 197b27b6f4 Merge main into M12.6 (3D Camera Tracker)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 23:03:57 -04:00
Brandon ThomasandClaude Opus 5.5 cba8d7e737 M12.6: 3D Camera Tracker effect + UI
Effect > Perspective > 3D Camera Tracker (Shot Type, Horizontal Angle of
View, Show/Render Track Points, Track Point Size, Target Size, Advanced:
Solve Method, Method Used, Average Error, Detailed Analysis, Auto-delete
Points Across Time, Hide Warning Banner); tracks and solve stored in the
effect with keys (frame edits re-track, setting / deleted-point edits only
re-solve). Background job (Analyzing in background (step 1 of 2) / Solving
camera banner, cancel, one undo step). Commands: track.camera (replaces the
stub), camera.analyze/cancel/solveStatus/points/selectPoints/
createFromSolve/create/setGroundPlane/deletePoints; the one-node 3D Tracker
Camera keyed per frame and text / solids / nulls / shadow catcher + light on
the target plane, Create Multiple. Viewer: depth-sized coloured targets,
hover target plane, click / shift / marquee selection, AE right-click menu,
Delete; Effect Controls Analyze / Cancel / Create Camera; Tracker panel
Track Camera. Solver: adaptive noise thresholds, denser keyframes, quick
tripod check, faster Cholesky and parallel Schur complement.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 23:02:47 -04:00
Brandon Thomas 93f4fe7314 Merge branch 'main' into worktree-agent-ad0c2eed1a8890262
# Conflicts:
#	crates/effects/Cargo.toml
#	crates/ui-egui/src/panels/mod.rs
#	docs/parity.md
2026-10-02 22:27:43 -04:00
Brandon ThomasandClaude Opus 5.5 ed72e67155 M6.7: refine edge + freeze + UI
Refine Edge tool (Alt+W cycles Roto Brush / Refine Edge), Layer panel
roto strokes with matte overlays (Alpha Boundary in pink, Alpha, Alpha
Overlay, View Search Region), segmentation span bar, Freeze/Propagate in
the Layer panel and Effect Controls, background propagation polling,
docs.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 22:27:22 -04:00
Brandon ThomasandClaude Opus 5.5 78cd313d3c M14.4: scripting with an After Effects-style JavaScript object model
New crate effectcraft-script (L4): boa runtime with app/Project/CompItem/
Layer/PropertyGroup/Property/TextDocument/MarkerValue/RenderQueue/File
object model over engine commands (undoable, undo groups), AE match-name
table, file/network security gate. Entry points: script.run command,
File > Scripts > Run Script File (.jsx/.js), Window > Script Console,
effectcraft-cli script, MCP run_script. Engine: project.delete/duplicate,
prop.renameGroup/setGroupEnabled/removeGroup/duplicateGroup/moveGroup.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 22:13:09 -04:00
Brandon ThomasandClaude Opus 5.5 9645ff9a66 M6.6: mask tracking + mask interpolation; M12.5: Warp Stabilizer
Mask tracking (track.mask, background job with progress/cancel, one undo
step, Mask Path keys; Tracker panel mask mode; Layer > Mask > Track Mask),
Mask Interpolation panel + mask.interpolate, and the Warp Stabilizer
effect (Effect > Distort, AE parameter groups, warp.analyze/cancel/status,
analysis stored in the effect, invalidation on source/in/out/remap edits,
viewer banner, crop/auto-scale/synthesize edges, track points).
Adds the effects -> track same-layer edge.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 21:14:29 -04:00
Brandon ThomasandClaude Opus 5.5 744ccd6b48 M9.10: on-canvas text editing
Type tool point/box text creation, double-click editing, caret and selection
in the viewer (viewer_text.rs), keyboard/IME/clipboard, box handles; engine
text.edit/endEdit/setSelection/moveCaret/insert/delete, layer.setText range,
caret insertion style, Paste Text and Match Formatting / Paste Text
Formatting Only (stubs removed); Character/Paragraph/Properties panels act
on the selection.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 10:34:13 -04:00
Brandon Thomas e1f72413e0 Merge branch 'worktree-agent-a94e35b1679a89a56'
# Conflicts:
#	README.md
#	crates/engine/Cargo.toml
#	crates/engine/src/commands/mod.rs
#	crates/engine/src/lib.rs
#	crates/ui-egui/src/panels/viewer.rs
2026-10-02 09:26:35 -04:00
Brandon ThomasandClaude Opus 5.5 c4100bcf80 M11.4: Lottie export/import
New crate effectcraft-lottie (L3): export a comp to Lottie JSON / dotLottie
(precomp and base64 image assets; shape, solid, null, precomp, image and text
layers or glyph shapes; transforms with parenting, separated position,
anchor; keyframes with speed/influence converted to normalised i/o tangents,
hold keys, spatial ti/to; all shape items incl. gradients, dashes, trim,
repeater and path operators; masks, track mattes, blend modes, time remap,
timing, markers, optional expressions, a few Lottie effects) with a warnings
list for what Lottie cannot express, and the inverse import. Commands
file.exportLottie / file.importLottie with File > Export / Import entries.
Round-trip tests (values and rendered frames) and hand-written fixtures.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 08:56:03 -04:00
Brandon ThomasandClaude Opus 5.5 e57e6a5120 M12.3: tracker panel + apply
Tracker panel (Window > Tracker): Track Camera / Warp Stabilizer (disabled),
Track Motion / Stabilize Motion, Motion Source, Current Track, Track Type,
Position/Rotation/Scale, Motion Target with Edit Target..., Options...
(Motion Tracker Options dialog), Analyze (1 frame back, back, forward,
1 frame forward; stop while running) with progress, Reset and Apply (Apply
Dimensions dialog). Track point widgets in the viewer: feature and search
regions with corner handles, attach point crosshair and track path, all
draggable through track.setPoint (one undo step per drag). Automation ids for
every widget; headless UI test.

Tracker: featureless regions no longer drift (ties keep the prediction, only
confident matches predict motion). docs/agents.md: tracking example.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-02 08:52:20 -04:00
Brandon ThomasandClaude Opus 5.5 7f43d537ed M14.1: ship .mcp.json (headless + bridge servers)
Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 21:49:20 -04:00
Brandon ThomasandClaude Opus 5.5 c672e03160 M14.1: MCP server + agent CLI
- crates/automation (L5, no egui): hand-rolled JSON-RPC 2.0 MCP server over
  stdio (initialize, ping, tools/list, tools/call); headless backend (in-process
  Session) and bridge backend (desktop control channel). Tools: list_commands,
  execute_command, get_project/comp/layer, get/set_property, add_keyframe,
  render_frame (inline PNG), open/save_project, undo/redo; bridge-only
  screenshot, ui_* and raw control passthrough.
- effectcraft-cli: info, commands, exec, run, props, get, set, render-frame,
  mcp [--bridge PORT]; --json, --project/--demo/--empty, --save/--save-as.
- engine: prop.get, layer.tree node paths + time, Session::resolve_comp,
  render_rgba8, execute_checked (rejects unknown params, lists accepted keys).
- control channel: render.frame; engine.execute runs every engine command
  directly (no dialogs, validated params).
- docs: control-protocol.md, agents.md.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 21:40:31 -04:00