Edit an animation
edit_animationChange an animation's code: ONE revision, checked and probed in a sandbox. Each direct save returns a contact sheet (preview: false skips; preview: true or {entry, timestamps, filmstrip, ...} looks closer; preview_warnings).
The server holds the files; keep no local copy. Create with each file's full text once, then edit the saved revision: files: [{path, content}] new file or rewrite files: [{path, edits: [{old, new, replace_all?}]}] a change edits: [{op: delete|move, path, to?}] On disk: patch (git diff) · {path, patch} · {path, upload_id} · upload_ids from upload_file. A non-matching edit, or code that fails to parse or build, saves nothing (saved: false; retry from the same base_rev). files_changed has sha256s.
Before writing animation code, read get_design_guide({topic: "animation"}); before writing any helper, search the stdlib with get_design_guide({topic: "stdlib", query}). Hard rules: code never reads voiceover words; one cue per story moment, set from word timings, small things timed from it; render is deterministic (no state between frames, randomness only from the seed).
CREATE IN PLACE: animation:'new' (scope, name, slug) + project_id + place: {clip_index} places it on the first passing save and returns element_id; then edit by element_id + project_id (saves update the editor live). More entries: place: {clip_index, entry}, no changes needed. WHILE DRAFTING, PASS project_id: passing saves move its uses; without it uses_behind names projects that "will see an update available" and the animation.update_uses call. checkpoint: '' keeps a version.
Reply: rev, saved, probe, checks, errors, files_changed, element_id, uses_moved, uses_behind, note; detail: 'full' adds hunks and thumbnails. Imports stay pinned (dependency_updates: animation.bump('', '')); project-scope importers re-pin (dependents_updated).
Refusals: stale_base, target_required ('shared'|'fork'), check_failed. Settings, actions, cues: update_elements({updates:[{element_id, cues:[{op:'set', key, t}]}]}).
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Only with animation 'new': the display name. | |
| slug | No | Only with animation 'new': lowercase letters, digits and dashes; becomes @org/<slug>. Slugs are workspace-wide: one an animation of another project (or the library) holds is saved as the next free <slug>-N (the reply's animation and note say which, nothing to resend); one this project already holds is refused, naming it and a free slug. | |
| edits | No | Operations, applied in order before `files`: delete and move (replace and write also work; files is the shorter way). | |
| files | No | Per-file changes, each with exactly one of edits, content, patch or upload_id. Applied in order after `edits` and `patch`, all saved as ONE revision. | |
| patch | No | For a client working from files on disk: a unified diff of any number of files against the saved revision (`git diff`, `diff -u` or `diff -ruN`), run from the folder holding manifest.json. The server holds the base. New files (--- /dev/null), deletes and renames apply too. A hunk whose context no longer matches is refused with the saved lines around it; nothing is saved. | |
| place | No | Put the animation on the canvas on the first passing save, as an animation element on this clip (the add_elements placement), and return its element_id: pass that on every later edit so each passing save updates the editor live. Needs project_id. Placing is per entry and clip: an entry already on that clip is not placed again (its element_id comes back); any other entry, or the same entry on another clip, is, and existing elements keep their own entries. Works for an existing animation too (animation: '@org/<slug>', or element_id + place.entry for another entry of the element's animation), and with no file changes at all it only places the latest revision. A failing save places nothing. | |
| scope | No | Only with animation 'new': one element, this project (the default with project_id; every scene of the video can import it), or the workspace library, only when the user asks to reuse it in other videos. | |
| detail | No | summary (default) returns the outcome and what changed; full adds the diff hunks and every probe thumbnail. | |
| folder | No | Only with animation 'new' and scope 'library' (a save the user asked to keep for the workspace): the library folder, by path, e.g. 'Characters' or 'Characters/Presenters'. Missing folders are created (at most three levels). | |
| target | No | Required when the animation is used outside this project: 'shared' changes it for everyone who updates, 'fork' copies it for this project first. Official and community animations always fork. | |
| dry_run | No | Build and check the edits without saving. Returns a `preview` token; render it with get_clip(render: {preview}). | |
| preview | No | Every direct save already returns a small contact sheet (four moments). false skips it; true or an object asks for a larger one with your choice of entry, moments, a filmstrip and test settings (parameter_values, where an image setting may be an upload id or a URL; param_tracks, actions, cues). With a project it shows a placed use of the entry with that element's own settings; with dry_run the unsaved code; without project_id a plain background. Nothing about the preview is saved. | |
| base_rev | No | The revision you read and expect to edit from. If it has moved, the save is refused with stale_base, the current revision and the files changed since. | |
| animation | No | The animation to edit when there is no element: @org/<slug> or an id. 'new' creates one (then pass scope, name and slug). | |
| checkpoint | No | A one-line note that saves this revision, when it passes, as a version in the element's history in the editor (the user can preview and restore it there). Set it when you reach a state worth returning to, not on every draft. | |
| element_id | No | The animation element this edit is about. The edit starts from the revision that element shows, and every use in this project moves to the new revision when it passes. | |
| project_id | No | Project the element is in. Needed with element_id. | |
| upload_ids | No | Whole files sent with upload_file(file_names: [...]) and its one curl: each upload's file name is its path in the animation (e.g. 'entries/city.js'), and its text replaces or adds that file. Applied after files. | |
| update_dependents | No | After a passing save, re-pin every animation that imports this one (a kit's scenes) to the new revision in the same call and move this project's uses of them; dependents_updated {report, project_uses_moved, note} says what moved. Left out: on for a project-scoped animation saved with project_id, off otherwise (a library animation's importers span the workspace: pass true). |