@nodetool-ai/agents 0.8.4-a24.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/.nodetool-build-stamp +1 -1
  2. package/dist/_skills/LICENSE-iart-motion-design-skills +21 -0
  3. package/dist/_skills/README.md +211 -0
  4. package/dist/_skills/api-agents/SKILL.md +58 -0
  5. package/dist/_skills/api-apps/SKILL.md +54 -0
  6. package/dist/_skills/api-assets/SKILL.md +66 -0
  7. package/dist/_skills/api-collections/SKILL.md +33 -0
  8. package/dist/_skills/api-games/SKILL.md +81 -0
  9. package/dist/_skills/api-media/SKILL.md +131 -0
  10. package/dist/_skills/api-memory/SKILL.md +72 -0
  11. package/dist/_skills/api-models/SKILL.md +78 -0
  12. package/dist/_skills/api-scripts/SKILL.md +79 -0
  13. package/dist/_skills/api-settings/SKILL.md +49 -0
  14. package/dist/_skills/api-sketches/SKILL.md +61 -0
  15. package/dist/_skills/api-storyboards/SKILL.md +94 -0
  16. package/dist/_skills/api-timelines/SKILL.md +151 -0
  17. package/dist/_skills/api-web/SKILL.md +57 -0
  18. package/dist/_skills/api-workflows/SKILL.md +123 -0
  19. package/dist/_skills/beat-sync-editing/SKILL.md +208 -0
  20. package/dist/_skills/caption-titles/SKILL.md +94 -0
  21. package/dist/_skills/color-motion/SKILL.md +185 -0
  22. package/dist/_skills/commercial-beat-sheet/SKILL.md +338 -0
  23. package/dist/_skills/elevenlabs-audio-prompting/SKILL.md +163 -0
  24. package/dist/_skills/explainer-storyboard/SKILL.md +63 -0
  25. package/dist/_skills/flux-2-klein-prompting/SKILL.md +107 -0
  26. package/dist/_skills/frame-composition/SKILL.md +291 -0
  27. package/dist/_skills/game-direction/SKILL.md +99 -0
  28. package/dist/_skills/gpt-image-2-prompting/SKILL.md +161 -0
  29. package/dist/_skills/hailuo-prompting/SKILL.md +107 -0
  30. package/dist/_skills/kling-video-prompting/SKILL.md +188 -0
  31. package/dist/_skills/launch-commercial/SKILL.md +267 -0
  32. package/dist/_skills/launch-kit/SKILL.md +120 -0
  33. package/dist/_skills/logo-reveal/SKILL.md +225 -0
  34. package/dist/_skills/manimgx/SKILL.md +123 -0
  35. package/dist/_skills/minimax-h3-prompting/SKILL.md +134 -0
  36. package/dist/_skills/motion-ad/SKILL.md +281 -0
  37. package/dist/_skills/motion-background/SKILL.md +145 -0
  38. package/dist/_skills/motion-curves/SKILL.md +302 -0
  39. package/dist/_skills/motion-direction/SKILL.md +259 -0
  40. package/dist/_skills/motion-graphics/SKILL.md +217 -0
  41. package/dist/_skills/motion-principles/SKILL.md +255 -0
  42. package/dist/_skills/music-video-treatment/SKILL.md +40 -0
  43. package/dist/_skills/nano-banana-pro-prompting/SKILL.md +133 -0
  44. package/dist/_skills/native-game/SKILL.md +310 -0
  45. package/dist/_skills/native-game-reference/SKILL.md +879 -0
  46. package/dist/_skills/nodetool-3d-scene/SKILL.md +110 -0
  47. package/dist/_skills/nodetool-api-reference/SKILL.md +338 -0
  48. package/dist/_skills/nodetool-app-builder/SKILL.md +291 -0
  49. package/dist/_skills/nodetool-browser-agent/SKILL.md +119 -0
  50. package/dist/_skills/nodetool-chat-cli/SKILL.md +184 -0
  51. package/dist/_skills/nodetool-custom-node-developer/SKILL.md +294 -0
  52. package/dist/_skills/nodetool-deployment/SKILL.md +195 -0
  53. package/dist/_skills/nodetool-js-scripting/SKILL.md +223 -0
  54. package/dist/_skills/nodetool-model-provider-config/SKILL.md +348 -0
  55. package/dist/_skills/nodetool-rag-indexing/SKILL.md +153 -0
  56. package/dist/_skills/nodetool-sketch/SKILL.md +138 -0
  57. package/dist/_skills/nodetool-skill-author/SKILL.md +125 -0
  58. package/dist/_skills/nodetool-troubleshooter/SKILL.md +370 -0
  59. package/dist/_skills/nodetool-video-post/SKILL.md +149 -0
  60. package/dist/_skills/nodetool-workflow-builder/SKILL.md +295 -0
  61. package/dist/_skills/product-commercial/SKILL.md +132 -0
  62. package/dist/_skills/qwen-image-prompting/SKILL.md +122 -0
  63. package/dist/_skills/script-video/SKILL.md +106 -0
  64. package/dist/_skills/seedance-2-prompting/SKILL.md +194 -0
  65. package/dist/_skills/seedream-prompting/SKILL.md +117 -0
  66. package/dist/_skills/short-film/SKILL.md +123 -0
  67. package/dist/_skills/stable-audio-prompting/SKILL.md +130 -0
  68. package/dist/_skills/storyboard-core/SKILL.md +716 -0
  69. package/dist/_skills/timeline-edit-ops/SKILL.md +736 -0
  70. package/dist/_skills/trailer-template/SKILL.md +291 -0
  71. package/dist/_skills/ugc-video/SKILL.md +186 -0
  72. package/dist/_skills/veo-3-prompting/SKILL.md +140 -0
  73. package/dist/_skills/video-audio-continuity/SKILL.md +90 -0
  74. package/dist/_skills/video-clone/SKILL.md +96 -0
  75. package/dist/_skills/video-workflow/SKILL.md +119 -0
  76. package/dist/_skills/wan-2-6-prompting/SKILL.md +107 -0
  77. package/dist/app-build/bridge.d.ts.map +1 -1
  78. package/dist/app-build/bridge.js +44 -17
  79. package/dist/app-build/bridge.js.map +1 -1
  80. package/dist/capabilities/apps.d.ts.map +1 -1
  81. package/dist/capabilities/apps.js +55 -13
  82. package/dist/capabilities/apps.js.map +1 -1
  83. package/dist/capabilities/apps.specs.d.ts.map +1 -1
  84. package/dist/capabilities/apps.specs.js +5 -3
  85. package/dist/capabilities/apps.specs.js.map +1 -1
  86. package/dist/capabilities/game-asset-browser.d.ts.map +1 -1
  87. package/dist/capabilities/game-asset-browser.js +6 -1
  88. package/dist/capabilities/game-asset-browser.js.map +1 -1
  89. package/dist/capabilities/game.d.ts +1 -1
  90. package/dist/capabilities/game.d.ts.map +1 -1
  91. package/dist/capabilities/game.js +71 -56
  92. package/dist/capabilities/game.js.map +1 -1
  93. package/dist/capabilities/game.specs.js +1 -1
  94. package/dist/capabilities/game.specs.js.map +1 -1
  95. package/dist/capabilities/game3d.d.ts.map +1 -1
  96. package/dist/capabilities/game3d.js +14 -19
  97. package/dist/capabilities/game3d.js.map +1 -1
  98. package/dist/capabilities/gameAssertions.d.ts +52 -0
  99. package/dist/capabilities/gameAssertions.d.ts.map +1 -0
  100. package/dist/capabilities/gameAssertions.js +32 -0
  101. package/dist/capabilities/gameAssertions.js.map +1 -0
  102. package/dist/capabilities/models.d.ts.map +1 -1
  103. package/dist/capabilities/models.js +9 -0
  104. package/dist/capabilities/models.js.map +1 -1
  105. package/dist/capabilities/storyboards.d.ts.map +1 -1
  106. package/dist/capabilities/storyboards.js +36 -11
  107. package/dist/capabilities/storyboards.js.map +1 -1
  108. package/dist/capabilities/storyboards.specs.d.ts.map +1 -1
  109. package/dist/capabilities/storyboards.specs.js +11 -1
  110. package/dist/capabilities/storyboards.specs.js.map +1 -1
  111. package/dist/capabilities/workflows.d.ts.map +1 -1
  112. package/dist/capabilities/workflows.js +1 -0
  113. package/dist/capabilities/workflows.js.map +1 -1
  114. package/dist/capabilities/workflows.specs.d.ts.map +1 -1
  115. package/dist/capabilities/workflows.specs.js +4 -3
  116. package/dist/capabilities/workflows.specs.js.map +1 -1
  117. package/dist/evals/surfaces/game.d.ts.map +1 -1
  118. package/dist/evals/surfaces/game.js +29 -1
  119. package/dist/evals/surfaces/game.js.map +1 -1
  120. package/dist/game-authoring.d.ts +120 -0
  121. package/dist/game-authoring.d.ts.map +1 -1
  122. package/dist/game-build-integrity.d.ts +12 -0
  123. package/dist/game-build-integrity.d.ts.map +1 -0
  124. package/dist/game-build-integrity.js +78 -0
  125. package/dist/game-build-integrity.js.map +1 -0
  126. package/dist/game-examples.d.ts +44 -3
  127. package/dist/game-examples.d.ts.map +1 -1
  128. package/dist/game-examples.js +60 -10
  129. package/dist/game-examples.js.map +1 -1
  130. package/dist/system-skills.d.ts +1 -1
  131. package/dist/system-skills.js +1 -1
  132. package/dist/tools/builtin-tools.d.ts.map +1 -1
  133. package/dist/tools/builtin-tools.js +2 -0
  134. package/dist/tools/builtin-tools.js.map +1 -1
  135. package/package.json +19 -19
@@ -0,0 +1,123 @@
1
+ ---
2
+ name: manimgx
3
+ description: "Write, inspect and render ManimGX scenes: math and 3D animations in Manim Community Edition's Python API, run by the nodetool.manimgx nodes. Use for equations, proofs, plots, geometry, 3D surfaces and explainer animations."
4
+ ---
5
+
6
+ # Animate with ManimGX
7
+
8
+ ManimGX renders animations written in Manim Community Edition's Python API on a
9
+ Rust GPU engine. A scene is a Python module; the `nodetool.manimgx` nodes run
10
+ it on the machine NodeTool runs on. They need `manimgx` installed there
11
+ (ManimGX in the desktop Package Manager, or `uv tool install manimgx` with
12
+ Python 3.13 or newer) and are absent from the hosted cloud, because a scene is
13
+ a program.
14
+
15
+ | Node | Takes | Gives |
16
+ | :--- | :--- | :--- |
17
+ | `nodetool.manimgx.InspectScene` | `code`, `scene_name`, `times`, `timeout` | `ok`, `problems`, `report`, `storyboard`, `duration` |
18
+ | `nodetool.manimgx.RenderScene` | `code`, `scene_name`, `width`, `height`, `fps`, `preset`, `crf`, `timeout` | `video`, `storyboard`, `report`, `subtitles`, `duration` |
19
+ | `nodetool.manimgx.GenerateScene` | `prompt`, `model`, `max_attempts`, `send_storyboard`, `width`, `height`, `fps`, `timeout` | `video`, `code`, `storyboard`, `report`, `attempts` |
20
+
21
+ `timeout` is the limit in seconds for each ManimGX run (default 300).
22
+
23
+ `GenerateScene` runs the whole loop below inside one node with a language
24
+ model, for up to `max_attempts` rounds (default 3, at most 8). Each round is a
25
+ paid model call, and `send_storyboard` (on by default) sends the storyboard
26
+ pictures to it, which needs a vision model. Confirm the model with the user
27
+ before running it. Write the scene yourself when you can see the storyboard and
28
+ fix it.
29
+
30
+ ## The loop
31
+
32
+ 1. **Write** the module. Start from the template under
33
+ [Authoring](#authoring).
34
+ 2. **Inspect** it with `InspectScene`. `ok: false` means the scene failed:
35
+ `report` holds the traceback trimmed to the scene's lines and a "did you
36
+ mean" hint. `problems: true` means it ran but the 2D layout checks found
37
+ clipped content, overlapping text or labels too small to read. Each problem
38
+ is numbered in `report` and outlined on the storyboard. Look at the
39
+ storyboard pictures, not only the report. 3D scenes get pictures and a
40
+ timeline without layout checks.
41
+ 3. **Fix and inspect again** until `ok` is true and `problems` is false. To
42
+ check particular moments, pass `times: "1.5,end"`.
43
+ 4. **Render** with `RenderScene` at the size and frame rate asked for. Drafts
44
+ at 1280x720 and 30 fps render in seconds. The default is 1920x1080 at 30 fps.
45
+ 5. **Deliver** the video and the scene's code. Save the code where the person
46
+ can edit it, such as the `code` of a `RenderScene` node in their workflow.
47
+
48
+ From a code action or a Code node, call the nodes as functions:
49
+
50
+ ```js
51
+ import "@nodetool-ai/sandbox-nodetool/flow";
52
+ import { inspectScene, renderScene } from "@nodetool-ai/sandbox-flow/nodetool.manimgx";
53
+
54
+ const check = await inspectScene({ code, title: "Circle area" });
55
+ if (check.ok && !check.problems) {
56
+ const film = await renderScene({ code, width: 1280, height: 720, fps: 30, title: "Circle area" });
57
+ }
58
+ ```
59
+
60
+ Extra keys such as `title` above are the node's dynamic inputs.
61
+
62
+ ## Inputs from the workflow
63
+
64
+ Every node takes dynamic inputs. Their values reach the scene as a dict:
65
+
66
+ ```python
67
+ from nodetool_inputs import inputs
68
+ ```
69
+
70
+ Numbers, strings, lists and dicts arrive as JSON. Image, audio and video
71
+ inputs arrive as file paths: `m.ImageMobject(inputs["logo"])` for an image,
72
+ `self.add_sound(inputs["voice"])` for audio.
73
+
74
+ A scene is Python that runs as the server user, with that user's file and
75
+ network access. Only its environment is restricted, so it never sees the
76
+ server's secrets. Treat scene code as trusted code: do not run a scene from a
77
+ source the user has not vouched for.
78
+
79
+ ## Authoring
80
+
81
+ ```python
82
+ import manimgx as m
83
+ from nodetool_inputs import inputs
84
+
85
+
86
+ class CircleArea(m.Scene):
87
+ def construct(self) -> None:
88
+ circle = m.Circle(radius=1, color=m.BLUE, fill_opacity=0.3)
89
+ formula = m.MathTex(r"A = \pi r^2").next_to(circle, m.RIGHT, buff=0.6)
90
+ m.VGroup(circle, formula).center()
91
+ self.play(m.Create(circle), m.Write(formula))
92
+ self.wait(1)
93
+ ```
94
+
95
+ - Import `manimgx as m`. Put the animation in a `Scene` subclass's
96
+ `construct`. With more than one scene in the module, set `scene_name`.
97
+ - Time advances only through `self.play(...)` and `self.wait(...)`.
98
+ `self.add(...)` adds without animating.
99
+ - Compose placement with `VGroup`, `arrange`, `next_to`, `to_edge` and
100
+ `center`, so labels follow their subjects. The frame is about 14.2 units wide
101
+ and 8 tall, centred on the origin.
102
+ - `Text` for prose. `MathTex` with raw strings for LaTeX mathematics, or Typst.
103
+ No LaTeX installation is needed.
104
+ - For changing values, animate a `ValueTracker` and derive geometry from it.
105
+ An updater uses elapsed time or current state, never a frame count, so the
106
+ motion keeps its timing at any `fps`.
107
+ - For 3D, derive from `m.ThreeDScene`: `self.set_camera_orientation(phi=65 *
108
+ m.DEGREES, theta=-45 * m.DEGREES)`, `Surface`, `Sphere`, `Cube`,
109
+ `ThreeDAxes`, `self.begin_ambient_camera_rotation(rate=0.5)`.
110
+ - `self.next_section("name")` splits a film into sections. Subcaptions and
111
+ `self.say(...)` produce subtitles, which `RenderScene` returns as SubRip text.
112
+
113
+ ManimGX's own reference lists every class and keyword:
114
+ [manimgx.academa.ai/reference](https://manimgx.academa.ai/reference/), and
115
+ [llms.txt](https://manimgx.academa.ai/llms.txt) links the guides as Markdown.
116
+ Where ManimGX and Manim CE differ, ManimGX's page is right.
117
+
118
+ ## Where the result goes next
119
+
120
+ `video` is an inline video ref. Save it as an asset, or place it on a timeline
121
+ like any generated clip. A narrated explainer keeps its timing from the voice:
122
+ write the script first (`script-video`), then size each scene's waits to its
123
+ line.
@@ -0,0 +1,134 @@
1
+ ---
2
+ name: minimax-h3-prompting
3
+ description: Prompt MiniMax H3 — choosing between its text-to-video, first-and-last-frame and reference-to-video endpoints, assigning an explicit job to every reference image, clip and audio file, writing a timecoded shot list inside the prompt, art-directing the native stereo audio, and naming a change and its constraint together when editing a clip. Use whenever the model id names MiniMax H3 (minimax/h3/text-to-video, minimax/h3/image-to-video, minimax/h3/reference-to-video, their /lora variants, minimax/h3-max/*, minimax/h3-max-turbo/*, AtlasCloud's minimax/h3-fast and minimax/h3-developer, kie's minimax-h3/*) on generate_video, animate_image, generate_video_from_references or a TextToVideo node. Not for MiniMax Hailuo.
4
+ ---
5
+
6
+ # MiniMax H3 → one context, many references
7
+
8
+ H3 is a general-purpose multimodal video model rather than a set of task
9
+ models. Text, images, video and audio all enter one context, so a single
10
+ request can carry a character's identity from a photo, camera language and
11
+ cutting rhythm from a clip, and a voice from a recording, and resolve them into
12
+ one shot with native stereo audio. Base H3 runs 5 to 15 seconds in 2K on fal
13
+ (4 to 15 on kie and AtlasCloud), with prompts up to 7,000 characters — a full
14
+ shot list with sound design fits in one request. H3-Max and H3-Max-Turbo
15
+ default to 768P and take prompts up to 50,000 characters.
16
+
17
+ Reach text-to-video and image-to-video with `find_model` for `text_to_video`
18
+ or `image_to_video`, then `generate_video` / `animate_image`. Reach
19
+ reference-to-video with `find_model` for `reference_to_video`, then
20
+ `generate_video_from_references`. Those forward the prompt, the media, the
21
+ duration, the aspect ratio and the resolution. `generate_video_from_references`
22
+ carries reference images and videos but no audio files, `animate_image` sends
23
+ one image and no end frame, and none of them sets prompt expansion. Audio
24
+ references, an end frame and the expansion switch exist only on the route's
25
+ own node: find it with `search_nodes`, read its fields with `get_node_info`,
26
+ and run it with `run_node`. Each run is a paid generation, so confirm the
27
+ scope with the user before rendering several.
28
+
29
+ **Turn prompt expansion off for a precise brief.** H3-Max, H3-Max-Turbo and
30
+ the fal `/lora` routes set `prompt_expansion_mode` to `balanced` by default,
31
+ and fal's `extend-video` and `insert-video` set `enable_prompt_expansion` true.
32
+ An LLM then rewrites the prompt before generation, which can undo a timecoded
33
+ shot list. AtlasCloud's `prompt_expansion` defaults to false.
34
+
35
+ A timecoded shot list in one request is also what keeps the native audio
36
+ continuous across the cuts — `video-audio-continuity` for when to fit a whole
37
+ multi-scene piece into a single generation.
38
+
39
+ ## Which endpoint
40
+
41
+ The rule is mechanical:
42
+
43
+ - **No media in the request** → text to video. Best for anything you can fully
44
+ describe, and for letting the model invent the look rather than match one.
45
+ Distinct hand-drawn styles carry surprisingly far on prompt alone.
46
+ - **An image that is literally the first or last frame** → first and last
47
+ frame, the image-to-video route. One image for the opening, or two for
48
+ opening and closing (`end_image_url` on fal, `end_image` on AtlasCloud),
49
+ with H3 generating the motion between. This is the one for animating a static poster,
50
+ a UI mockup or key art. Output follows the uploaded image's aspect ratio.
51
+ - **Anything you are treating as a reference** → reference to video. Up to 9
52
+ images, 3 video clips of 2 to 15 seconds, and 3 audio clips, 12 files
53
+ maximum. Audio clips go in through the route's own node. Identity locking, motion and camera transfer, style matching, voice
54
+ cloning, and editing an existing clip all live here. Default to it whenever
55
+ you have an asset in hand.
56
+
57
+ ## The eight techniques
58
+
59
+ **1. Assign a job to every reference.** This is the one habit that changes the
60
+ most. "Use Image 1 for the overall mood, location and film texture; Image 2 for the
61
+ talent; Image 3 for the bag; and Image 4 for the closing brand mark" beats four
62
+ images and a description. It works across modalities too: "Match the camera
63
+ move in Video 1. Make the subject in Video 2 sing, using Video 3 as the
64
+ reference for both the vocal performance and physical delivery."
65
+
66
+ **2. Write a timed shot list for anything past one beat.** Timecoded blocks
67
+ hold the pacing: "[0 to 2 seconds] High-angle overhead shot… [2 to 4 seconds]
68
+ Smoothly push in to her right arm… [10 to 15 seconds] As she stands, the full
69
+ world loads around her." Without them a 15-second generation drifts into a
70
+ slideshow.
71
+
72
+ **3. Direct the audio.** It is generated natively, so art-direct it like a
73
+ shot: "a deep sub-bass pulse, distant metallic resonance, and one restrained
74
+ hit as the title locks into focus", or "ice tapping crystal, a faint cigar
75
+ burn, subtle room air, clothing movement, controlled breathing". For music,
76
+ describe instrumentation and structure over time, including where the beat
77
+ lands.
78
+
79
+ **4. State what you do not want.** No H3 route has a `negative_prompt` field,
80
+ so negative direction is prompt text. fal's guide calls it unusually effective
81
+ when specific. "No soft dissolves or fluid morphs." "Do not
82
+ introduce garbled characters or misspellings." "No tearing, black frames,
83
+ obvious VFX, or compositing seams." These keep a stylized prompt from sliding
84
+ into a neighbouring genre.
85
+
86
+ **5. Lock identity by listing the details.** "Preserve the half-up long black
87
+ hair, openwork silver crown, indigo ribbon, layered pale hanfu, translucent
88
+ blue outer robe, deep-blue sash, silver floral fastener, and long tassels."
89
+ Naming features gives the model something to hold. The same works for products,
90
+ sets and typography.
91
+
92
+ **6. For edits, name the change and the constraint together.** Write
93
+ substitutions as a list: "Replace the newspaper with a green hardcover book;
94
+ replace the chair with a red sofa; remove the subject's sunglasses and reveal a
95
+ clear face." Pair each change with what must stay stable and you get a
96
+ localized edit instead of a regenerated shot.
97
+
98
+ **7. Use camera and film language.** Lens choice, movement, exposure behaviour
99
+ and stock character all translate: "subtle handheld shake, then push in quickly
100
+ and rack focus", "wide angle with strong perspective distortion", "fine grain,
101
+ soft highlight halation, restrained colour", "backlit exposure breathing,
102
+ slightly coarse noise in the shadows".
103
+
104
+ **8. Describe transitions as events, not names.** "Fast binocular-scan
105
+ transitions with whip movement, motion blur, optical smearing, and brief
106
+ exposure flicker. Cut at peak blur, then settle and snap back into focus."
107
+ Circular vinyl-record wipes, vertical car-door cuts and oversized letter masks
108
+ all land better described than labelled.
109
+
110
+ ## What it is unusually good at
111
+
112
+ Reading many references at once, rendering legible text and interfaces, and
113
+ making precise localized edits to video you already have. That combination
114
+ covers brand films and trailers, title sequences and motion-graphics collage,
115
+ vertical short drama, product and e-commerce spots, game and web UI motion,
116
+ character and motion transfer, voice cloning, and green-screen replacement — all
117
+ from the same model.
118
+
119
+ H3-Max also has single-purpose routes (`3d-to-video`, `camera-controls`,
120
+ `multi-angle`, `insert-video`, `extend-video`, `lip-sync`, `styles/*`) with
121
+ their own fields and defaults. This guide does not cover them, so read the
122
+ route with `get_node_info` before using one.
123
+
124
+ Two shapes worth stealing. For a title sequence: name the design language, the
125
+ transition vocabulary, the credit typography rules ("each role and each name
126
+ appears once"), and a timed BGM brief. For a fashion or product film: assign
127
+ mood, talent, product and brand mark to separate images, then keep the story
128
+ simple and let the references carry the look.
129
+
130
+ Check the render with `analyze_video`, `detect_video_scenes` and
131
+ `understand_video`; `analyze_audio` for the mix you directed.
132
+
133
+ Adapted from fal's MiniMax H3 prompting guide:
134
+ https://fal.ai/learn/devs/minimax-h3-prompting-guide
@@ -0,0 +1,281 @@
1
+ ---
2
+ name: motion-ad
3
+ description: "Make a short sound-off motion-graphics ad (a 15s Facebook, Instagram or TikTok ad, 4:5 or 9:16) from a product's real screenshots and photos, with every claim checked against the page it links to. Use for an animated promo, a kinetic-type ad, a 9:16 version of one, or a revision of one (swap the hero, change the CTA, re-render). For generated footage use product-commercial, or launch-commercial for a finished spot with voice and music from a product page; for a person on camera ugc-video."
4
+ featured: true
5
+ ---
6
+
7
+ # Motion ad
8
+
9
+ A motion ad animates real product imagery and short headlines on the timeline.
10
+ Nothing in the picture is generated by default. The storyboard is the beat plan
11
+ and holds the real image each beat shows. The timeline carries the motion, and
12
+ `render_timeline` produces the MP4.
13
+
14
+ **Load `/storyboard-core` first** for the board contract. Load `timeline-edit-ops`
15
+ with `load_skill` before the first `edit_timeline` call: it owns every op shape
16
+ this skill quotes, and `motion-graphics` owns the build loop.
17
+
18
+ ## Rules that do not bend
19
+
20
+ - **Every claim matches the destination page.** Read the page before writing a
21
+ word. A price, a count, a speed, a guarantee, a rating or "free" appears in
22
+ the ad only if it appears there. When the user asks for copy the page
23
+ contradicts, write it and name the mismatch once in the report.
24
+ - **Real assets only.** Use the user's files or images taken from their live
25
+ site. Never invent a customer, a review, a rating, a result or a logo. A beat
26
+ with no real proof to show is cut, not filled.
27
+ - **Never fabricate a person.** A beat that needs more pictures of someone than
28
+ exist gets crops or mirrors of the real ones, and the report says so. A
29
+ generated face is out even when the rest of the board uses a model.
30
+ - **The brand decides the look.** Colours, logo, tone and type come from the
31
+ brand, not from the beat table below. Default to plain claims: no hype, no
32
+ exclamation marks, no emoji unless the brand writes that way.
33
+ - **Never overwrite a delivered version.** Each revision is a new timeline
34
+ version and a new rendered asset with a versioned name
35
+ (`<brand>-<topic>-ad-4x5-v2`).
36
+
37
+ ## Production policy
38
+
39
+ The canonical machine-readable policy is the shot's `production` requirement.
40
+ For social ads, choose `media_strategy` deliberately:
41
+
42
+ - `still_motion_graphics` is the default. Preserve the source image and build motion, type, shapes and transitions in the Timeline.
43
+ - `hybrid` uses generated/existing footage for atmosphere or physical motion while product, logo and exact copy remain separate protected layers.
44
+ - `generated_video` is reserved for actor performance, lifestyle movement or scene motion that materially benefits from video generation.
45
+
46
+ Put source truth in `protected_inputs`. Product/logo/source assets carry their exact `asset_id`; copy and brand colours carry their exact `value`. Declare only non-destructive `allowed_transformations`: `position`, `scale`, `crop`, `rotate`, `mask`, `opacity`, `composite`. Replacing or regenerating a protected asset, changing exact copy or colour, or applying an undeclared transform breaks the policy. The render tools enforce part of it: `render_storyboard_stills` refuses a selection holding a shot with a protected asset, and `render_storyboard_clips` refuses a `still_motion_graphics` shot. The rest is yours to keep on the timeline.
47
+
48
+ Do not use `generated_video` merely because a keyframe exists. Price cards, packshots, feature callouts, carousels, comparisons, typography hooks and CTA endings normally stay `still_motion_graphics`.
49
+
50
+ ## The loop
51
+
52
+ 1. Research the page and the brand.
53
+ 2. Collect the assets and pick the hero pair.
54
+ 3. Write the board: one shot per beat, the real image attached to each.
55
+ 4. Build the timeline: pictures, type, shapes, animations.
56
+ 5. Review preview frames and fix.
57
+ 6. Render, measure, report.
58
+
59
+ Stop where the request stops. "Just the storyboard" ends at step 3.
60
+
61
+ ## 1. Research
62
+
63
+ Ask for, or infer from context: the product, the destination URL, the audience
64
+ and the format. The format defaults to **4:5 feed (1080×1350)**. Stories and
65
+ reels are **9:16 (1080×1920)**.
66
+
67
+ - `browser {url}` on the destination page, then on the homepage and pricing
68
+ page. Pull the headline promise, prices, rating and review counts, speed
69
+ claims, and what is free versus paid. Record each fact with the page it came
70
+ from.
71
+ - `http_request {url}` returns the raw HTML. Read the brand's hex values, font
72
+ family and logo URL from its CSS variables or stylesheet links. Tokens in the
73
+ source beat colours picked from a screenshot.
74
+ - `take_screenshot {url, full_page: true}` captures the live product UI. For
75
+ software, that screenshot is often the best hero image. When it fails, say
76
+ so once and continue with downloaded images.
77
+
78
+ A fact the page does not state is `[CLIENT INPUT NEEDED]`, never a guess.
79
+
80
+ ## 2. Assets
81
+
82
+ Every image the ad shows must be a stored asset before it goes on a board or a
83
+ timeline.
84
+
85
+ - An image URL from the page: `save_asset {source: "<url>", name}` copies it
86
+ into the library and returns an `asset_id`. `download_file` writes a workspace
87
+ file instead, which is not an asset and cannot go on a timeline.
88
+ - A user upload: find it with `asset_search` or `list_assets`. Prefer the
89
+ user's files over scraped ones when they offer any.
90
+ - Logos: keep one for light backgrounds and, when the site has one, a white
91
+ version for the brand-colour end card.
92
+
93
+ Look before choosing. `view_image` each candidate and note its pixel size.
94
+ Site images are often thumbnails, and a 400px image on a 1080px canvas reads as
95
+ soft. Say which images are low resolution in the report instead of upscaling
96
+ them silently.
97
+
98
+ Pick the **hero pair** for the clearest transformation. For a physical
99
+ product, that is before and after. For software, it is the messy input and the
100
+ finished output, as screenshots. Portrait images near 4:5 fill the hero and
101
+ showcase slots best.
102
+
103
+ `edit_image` may crop, mirror or extend a real image to fit a slot. It may not
104
+ add a person, a product or a claim that was not in the source.
105
+
106
+ ## 3. The board
107
+
108
+ `create_storyboard {name, brief, style, aspect_ratio: "4:5"}` (or `"9:16"`).
109
+ Put the researched facts and their source URLs in `brief` so a later revision
110
+ can re-check them. Put the brand palette and type in `style`.
111
+
112
+ Add one shot per beat with `edit_storyboard`. Each shot carries:
113
+
114
+ - `slug`: `1a`, `2a`, and so on. "Change the 3a headline" then means one shot.
115
+ - `action`: what is on screen, in plain words.
116
+ - `notes`: the exact on-screen copy for the beat, including line breaks.
117
+ - `duration_seconds`: the beat length from the table below.
118
+ - `production`: the policy from § Production policy, for example
119
+ `{"media_strategy": "still_motion_graphics", "protected_inputs": [{"id": "hero-after",
120
+ "kind": "product", "asset_id": "<hero after>", "allowed_transformations": ["position",
121
+ "scale", "crop", "mask"]}, {"id": "headline-2a", "kind": "exact_text", "value": "<copy>"}]}`.
122
+
123
+ Then attach each beat's real image as its still:
124
+
125
+ ```json
126
+ {"storyboard_id": "<id>", "ops": [
127
+ {"op": "add_keyframe_version", "target": "2a", "asset_id": "<hero after>"}
128
+ ]}
129
+ ```
130
+
131
+ The shot moves to `keyframe_ready` with the real picture and no generation. A
132
+ still-only board is what the user reviews before any motion work.
133
+
134
+ Do not call `render_storyboard_stills` without `targets` on this board. It
135
+ selects every shot without a still, so a beat you forgot to attach would be
136
+ generated. Generate a shot only when the user asked for it, and only for a
137
+ background or texture, never for the product, a screen or a person.
138
+
139
+ ### Beats
140
+
141
+ Four or five beats in 15 seconds. One short headline per beat, at most about
142
+ 20 characters per line, sized to read muted on a phone. The shape below is a
143
+ starting point. Cut or replace a beat that does not fit the product. A desktop
144
+ tool with no mobile app has no phone beat, so open on the hero instead.
145
+
146
+ | Slug | Time | Beat | Picture |
147
+ |---|---|---|---|
148
+ | `1a` | 0–2.2s | Hook headline over the product in context: a phone or browser frame scrolling a real screenshot, a pointer or tap on the input | The screenshot |
149
+ | `2a` | 2.2–5.4s | The tapped card grows into the hero. A scan line crosses it and reveals before becoming after. Two or three benefit chips | Hero before, hero after |
150
+ | `3a` | 5.5–8.7s | The hero shrinks into a tilted wall of more real outputs | Four to nine outputs |
151
+ | `4a` | 8.7–11.8s | Three showcase cards, optionally with a small "before" inset, and one proof line | Showcase images, a real rating or count |
152
+ | `5a` | 11.8–15s | Brand-colour wipe to the end card: logo, CTA headline, one chip, the button | Logo |
153
+
154
+ Beat `4a` loses its proof line when the page has no number to quote. Beat `3a`
155
+ is cut when there are not enough distinct real outputs to fill a wall without
156
+ repeats.
157
+
158
+ ## 4. The timeline
159
+
160
+ `assemble_storyboard_timeline` lays down rendered clips only and skips shots
161
+ that have a still and no clip, so it builds nothing here.
162
+
163
+ When the shots carry `graphics` intent (the exact copy and assets as elements),
164
+ `finish_storyboard {storyboardId, expectedStoryboardRevision}` writes the board as
165
+ editable timeline layers with no generation. Its default deterministic strategy
166
+ returns an unreviewed scaffold; `layout_storyboard` composes the static layout
167
+ with a vision model first. Review either through § 5 like a hand build.
168
+ `storyboard-core` § Still-motion-graphics boards has the arguments. Without
169
+ `graphics` on the shots, create the sequence directly:
170
+
171
+ ```json
172
+ {"name": "acme-scan-ad-4x5-v1", "width": 1080, "height": 1350, "fps": 30}
173
+ ```
174
+
175
+ `create_timeline` with those arguments. Then `create_timeline_version` before
176
+ the first edit, and build with `edit_timeline` in batches of at most 60 ops.
177
+ Read `get_state` for track and clip ids before animating anything.
178
+
179
+ **Tracks, top to bottom.** A lower index draws on top, and `add_track` appends
180
+ at the bottom, so add them in this order: headlines, chips and buttons, the
181
+ scan line and wipes, pictures, background. Give every element whose timing
182
+ overlaps another its own track. Two clips that overlap on one track dissolve
183
+ into each other.
184
+
185
+ **Pictures.** `add_media_clip {asset: "asset://<id>", trackId, startMs,
186
+ durationMs, transform}` per image. An image has no duration of its own, so
187
+ always pass `durationMs`. `transform.position` is in canvas pixels measured from
188
+ the frame centre (`{x: 0, y: 0}` is centred, positive y moves down), and `scale`
189
+ is a factor. Frame each image with `frame-composition` rules.
190
+
191
+ **Type.** `add_text_clip` per headline, with the brand colour and a
192
+ `fontFamily` NodeTool bundles: Inter, Space Grotesk, Bebas Neue, Playfair
193
+ Display, Lora or JetBrains Mono. When the brand font is not among them, use
194
+ the closest bundled family and say so. Put an accent word in its own text clip
195
+ in the accent colour, aligned to the line. What the copy says and when it
196
+ appears belongs to `caption-titles`.
197
+
198
+ **Shapes.** `add_shape_clip` draws the background, chips, the button, the scan
199
+ line and the brand-colour disc of the end-card wipe.
200
+
201
+ **Motion per beat.** One easing family and one timing unit for the whole ad,
202
+ fixed before the first animation (`motion-direction`). Durations and stagger
203
+ come from `motion-principles`.
204
+
205
+ | Beat | Build it with |
206
+ |---|---|
207
+ | Hook | Headline `animate_clip` `in` `pop` with a `word` stagger. The screenshot's scroll is a custom `positionY` curve inside a masked frame (`set_mask`). The tap is a small shape with `pop` then `pulse` |
208
+ | Reveal | The "after" image sits on the track above "before". `animate_clip` `in` `wipe` on "after", with the scan line moving on the same window and easing. Benefit chips enter with `stagger_animations` |
209
+ | Wall | Output images with `rotationY` and `perspective` on their transforms, entering with `stagger_animations`. A slow `kenBurns` loop keeps the wall alive |
210
+ | Showcase | Cards `slide` in from one side. The proof line enters last and holds at least 1.5s |
211
+ | End card | `set_transition` `iris` or a scaled brand-colour disc, then the logo per `logo-reveal`. The CTA holds still for the last second |
212
+
213
+ Sound is optional. The ad must work muted. When the user wants a bed,
214
+ `find_model` with `text_to_music`, `load_skill` the `prompting_skill` it
215
+ names, then `generate_music` at the exact runtime. Put cuts on its beats with
216
+ `beat-sync-editing`.
217
+
218
+ `validate_timeline` after every batch. Fix `text_illegible`,
219
+ `text_backing_unproven`, `font_not_portable`, `stagger_compressed` and
220
+ `animation_exceeds_clip` before looking at frames.
221
+
222
+ ## 5. Review frames
223
+
224
+ `preview_timeline_frame {timeline_id, times_ms, sheet: true}`, then
225
+ `view_image` on the sheet. For the table above, sample
226
+ `[300, 1900, 2700, 3800, 4900, 6600, 9800, 11500, 13600]`, plus the midpoint
227
+ of every entrance you added.
228
+
229
+ Look for:
230
+
231
+ - text overlapping text, or a headline under a shape it should sit above
232
+ - empty gaps where one beat ends before the next starts
233
+ - a label that contradicts its image ("after" on the before picture)
234
+ - the same image twice side by side in the wall
235
+ - a headline that cannot be read at thumbnail size
236
+ - a soft image at hero size
237
+
238
+ Name each defect, fix it, and preview the same timecodes again.
239
+
240
+ ## 6. Render and report
241
+
242
+ 1. `render_timeline {timeline_id, preview_scale: 0.5, wait: true}` for a draft
243
+ while iterating.
244
+ 2. `render_timeline {timeline_id, wait: true}` at full size when the frames
245
+ are right.
246
+ 3. `analyze_video` on the result. Check duration, width, height and frame
247
+ count against the plan.
248
+ 4. `preview_timeline_frame` at each transition to check the frames the stills
249
+ review did not sample.
250
+
251
+ Report:
252
+
253
+ - the rendered asset and the timeline and board to open
254
+ - the copy, beat by beat
255
+ - every caveat: low-resolution sources, crops and mirrors, the font
256
+ substitution, copy that differs from the page, and any
257
+ `[CLIENT INPUT NEEDED]` left in the board
258
+ - actual spend from `get_cost_summary` when anything was generated
259
+
260
+ ## A second format
261
+
262
+ A 9:16 cut is its own timeline, not a crop. `retarget_format` derives a
263
+ sequence by cropping, which cuts headlines and chips placed for 4:5. Create a
264
+ 1080×1920 timeline from the same board, re-space every vertical position
265
+ (headlines, frame, hero, carousel, end card), and review and render it the
266
+ same way. Name it `<brand>-<topic>-ad-9x16-v1`.
267
+
268
+ ## Revisions this loop handles
269
+
270
+ ```
271
+ Swap the hero for the image I uploaded. Keep everything else.
272
+ Change the CTA to "Start free". Check the page says free first.
273
+ Make a 9:16 version.
274
+ The headline in 1a is too long. Two lines, same words.
275
+ Drop the proof line. The review count is out of date.
276
+ Re-render as v3. Keep v2.
277
+ ```
278
+
279
+ Each one is `create_timeline_version`, the smallest edit that answers it, a
280
+ validate, a preview of the changed beats, and a new render with the next
281
+ version number.