motion-ad

GitHub

用于制作15秒社交媒体动态广告的技能,基于真实产品截图和照片生成4:5或9:16比例的MP4。严格遵循品牌规范,确保所有宣传主张与目标页面一致,禁止虚构内容。支持从故事板到渲染的完整生产流程及版本迭代。

packages/system-skills/motion-ad/SKILL.md nodetool-ai/nodetool

Trigger Scenarios

制作社交媒体动态广告 基于产品素材生成动画宣传片 修改现有广告的视觉元素或CTA

Install

npx skills add nodetool-ai/nodetool --skill motion-ad -g -y
More Options

Non-standard path

npx skills add https://github.com/nodetool-ai/nodetool/tree/main/packages/system-skills/motion-ad -g -y

Use without installing

npx skills use nodetool-ai/nodetool@motion-ad

指定 Agent (Claude Code)

npx skills add nodetool-ai/nodetool --skill motion-ad -a claude-code -g -y

安装 repo 全部 skill

npx skills add nodetool-ai/nodetool --all -g -y

预览 repo 内 skill

npx skills add nodetool-ai/nodetool --list

SKILL.md

Frontmatter
{
    "name": "motion-ad",
    "featured": true,
    "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."
}

Motion ad

A motion ad animates real product imagery and short headlines on the timeline. Nothing in the picture is generated by default. The storyboard is the beat plan and holds the real image each beat shows. The timeline carries the motion, and render_timeline produces the MP4.

Load /storyboard-core first for the board contract. Load timeline-edit-ops with load_skill before the first edit_timeline call: it owns every op shape this skill quotes, and motion-graphics owns the build loop.

Rules that do not bend

  • Every claim matches the destination page. Read the page before writing a word. A price, a count, a speed, a guarantee, a rating or "free" appears in the ad only if it appears there. When the user asks for copy the page contradicts, write it and name the mismatch once in the report.
  • Real assets only. Use the user's files or images taken from their live site. Never invent a customer, a review, a rating, a result or a logo. A beat with no real proof to show is cut, not filled.
  • Never fabricate a person. A beat that needs more pictures of someone than exist gets crops or mirrors of the real ones, and the report says so. A generated face is out even when the rest of the board uses a model.
  • The brand decides the look. Colours, logo, tone and type come from the brand, not from the beat table below. Default to plain claims: no hype, no exclamation marks, no emoji unless the brand writes that way.
  • Never overwrite a delivered version. Each revision is a new timeline version and a new rendered asset with a versioned name (<brand>-<topic>-ad-4x5-v2).

Production policy

The canonical machine-readable policy is the shot's production requirement. For social ads, choose media_strategy deliberately:

  • still_motion_graphics is the default. Preserve the source image and build motion, type, shapes and transitions in the Timeline.
  • hybrid uses generated/existing footage for atmosphere or physical motion while product, logo and exact copy remain separate protected layers.
  • generated_video is reserved for actor performance, lifestyle movement or scene motion that materially benefits from video generation.

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.

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.

The loop

  1. Research the page and the brand.
  2. Collect the assets and pick the hero pair.
  3. Write the board: one shot per beat, the real image attached to each.
  4. Build the timeline: pictures, type, shapes, animations.
  5. Review preview frames and fix.
  6. Render, measure, report.

Stop where the request stops. "Just the storyboard" ends at step 3.

1. Research

Ask for, or infer from context: the product, the destination URL, the audience and the format. The format defaults to 4:5 feed (1080×1350). Stories and reels are 9:16 (1080×1920).

  • browser {url} on the destination page, then on the homepage and pricing page. Pull the headline promise, prices, rating and review counts, speed claims, and what is free versus paid. Record each fact with the page it came from.
  • http_request {url} returns the raw HTML. Read the brand's hex values, font family and logo URL from its CSS variables or stylesheet links. Tokens in the source beat colours picked from a screenshot.
  • take_screenshot {url, full_page: true} captures the live product UI. For software, that screenshot is often the best hero image. When it fails, say so once and continue with downloaded images.

A fact the page does not state is [CLIENT INPUT NEEDED], never a guess.

2. Assets

Every image the ad shows must be a stored asset before it goes on a board or a timeline.

  • An image URL from the page: save_asset {source: "<url>", name} copies it into the library and returns an asset_id. download_file writes a workspace file instead, which is not an asset and cannot go on a timeline.
  • A user upload: find it with asset_search or list_assets. Prefer the user's files over scraped ones when they offer any.
  • Logos: keep one for light backgrounds and, when the site has one, a white version for the brand-colour end card.

Look before choosing. view_image each candidate and note its pixel size. Site images are often thumbnails, and a 400px image on a 1080px canvas reads as soft. Say which images are low resolution in the report instead of upscaling them silently.

Pick the hero pair for the clearest transformation. For a physical product, that is before and after. For software, it is the messy input and the finished output, as screenshots. Portrait images near 4:5 fill the hero and showcase slots best.

edit_image may crop, mirror or extend a real image to fit a slot. It may not add a person, a product or a claim that was not in the source.

3. The board

create_storyboard {name, brief, style, aspect_ratio: "4:5"} (or "9:16"). Put the researched facts and their source URLs in brief so a later revision can re-check them. Put the brand palette and type in style.

Add one shot per beat with edit_storyboard. Each shot carries:

  • slug: 1a, 2a, and so on. "Change the 3a headline" then means one shot.
  • action: what is on screen, in plain words.
  • notes: the exact on-screen copy for the beat, including line breaks.
  • duration_seconds: the beat length from the table below.
  • production: the policy from § Production policy, for example {"media_strategy": "still_motion_graphics", "protected_inputs": [{"id": "hero-after", "kind": "product", "asset_id": "<hero after>", "allowed_transformations": ["position", "scale", "crop", "mask"]}, {"id": "headline-2a", "kind": "exact_text", "value": "<copy>"}]}.

Then attach each beat's real image as its still:

{"storyboard_id": "<id>", "ops": [
  {"op": "add_keyframe_version", "target": "2a", "asset_id": "<hero after>"}
]}

The shot moves to keyframe_ready with the real picture and no generation. A still-only board is what the user reviews before any motion work.

Do not call render_storyboard_stills without targets on this board. It selects every shot without a still, so a beat you forgot to attach would be generated. Generate a shot only when the user asked for it, and only for a background or texture, never for the product, a screen or a person.

Beats

Four or five beats in 15 seconds. One short headline per beat, at most about 20 characters per line, sized to read muted on a phone. The shape below is a starting point. Cut or replace a beat that does not fit the product. A desktop tool with no mobile app has no phone beat, so open on the hero instead.

Slug Time Beat Picture
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
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
3a 5.5–8.7s The hero shrinks into a tilted wall of more real outputs Four to nine outputs
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
5a 11.8–15s Brand-colour wipe to the end card: logo, CTA headline, one chip, the button Logo

Beat 4a loses its proof line when the page has no number to quote. Beat 3a is cut when there are not enough distinct real outputs to fill a wall without repeats.

4. The timeline

assemble_storyboard_timeline lays down rendered clips only and skips shots that have a still and no clip, so it builds nothing here.

When the shots carry graphics intent (the exact copy and assets as elements), finish_storyboard {storyboardId, expectedStoryboardRevision} writes the board as editable timeline layers with no generation. Its default deterministic strategy returns an unreviewed scaffold; layout_storyboard composes the static layout with a vision model first. Review either through § 5 like a hand build. storyboard-core § Still-motion-graphics boards has the arguments. Without graphics on the shots, create the sequence directly:

{"name": "acme-scan-ad-4x5-v1", "width": 1080, "height": 1350, "fps": 30}

create_timeline with those arguments. Then create_timeline_version before the first edit, and build with edit_timeline in batches of at most 60 ops. Read get_state for track and clip ids before animating anything.

Tracks, top to bottom. A lower index draws on top, and add_track appends at the bottom, so add them in this order: headlines, chips and buttons, the scan line and wipes, pictures, background. Give every element whose timing overlaps another its own track. Two clips that overlap on one track dissolve into each other.

Pictures. add_media_clip {asset: "asset://<id>", trackId, startMs, durationMs, transform} per image. An image has no duration of its own, so always pass durationMs. transform.position is in canvas pixels measured from the frame centre ({x: 0, y: 0} is centred, positive y moves down), and scale is a factor. Frame each image with frame-composition rules.

Type. add_text_clip per headline, with the brand colour and a fontFamily NodeTool bundles: Inter, Space Grotesk, Bebas Neue, Playfair Display, Lora or JetBrains Mono. When the brand font is not among them, use the closest bundled family and say so. Put an accent word in its own text clip in the accent colour, aligned to the line. What the copy says and when it appears belongs to caption-titles.

Shapes. add_shape_clip draws the background, chips, the button, the scan line and the brand-colour disc of the end-card wipe.

Motion per beat. One easing family and one timing unit for the whole ad, fixed before the first animation (motion-direction). Durations and stagger come from motion-principles.

Beat Build it with
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
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
Wall Output images with rotationY and perspective on their transforms, entering with stagger_animations. A slow kenBurns loop keeps the wall alive
Showcase Cards slide in from one side. The proof line enters last and holds at least 1.5s
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

Sound is optional. The ad must work muted. When the user wants a bed, find_model with text_to_music, load_skill the prompting_skill it names, then generate_music at the exact runtime. Put cuts on its beats with beat-sync-editing.

validate_timeline after every batch. Fix text_illegible, text_backing_unproven, font_not_portable, stagger_compressed and animation_exceeds_clip before looking at frames.

5. Review frames

preview_timeline_frame {timeline_id, times_ms, sheet: true}, then view_image on the sheet. For the table above, sample [300, 1900, 2700, 3800, 4900, 6600, 9800, 11500, 13600], plus the midpoint of every entrance you added.

Look for:

  • text overlapping text, or a headline under a shape it should sit above
  • empty gaps where one beat ends before the next starts
  • a label that contradicts its image ("after" on the before picture)
  • the same image twice side by side in the wall
  • a headline that cannot be read at thumbnail size
  • a soft image at hero size

Name each defect, fix it, and preview the same timecodes again.

6. Render and report

  1. render_timeline {timeline_id, preview_scale: 0.5, wait: true} for a draft while iterating.
  2. render_timeline {timeline_id, wait: true} at full size when the frames are right.
  3. analyze_video on the result. Check duration, width, height and frame count against the plan.
  4. preview_timeline_frame at each transition to check the frames the stills review did not sample.

Report:

  • the rendered asset and the timeline and board to open
  • the copy, beat by beat
  • every caveat: low-resolution sources, crops and mirrors, the font substitution, copy that differs from the page, and any [CLIENT INPUT NEEDED] left in the board
  • actual spend from get_cost_summary when anything was generated

A second format

A 9:16 cut is its own timeline, not a crop. retarget_format derives a sequence by cropping, which cuts headlines and chips placed for 4:5. Create a 1080×1920 timeline from the same board, re-space every vertical position (headlines, frame, hero, carousel, end card), and review and render it the same way. Name it <brand>-<topic>-ad-9x16-v1.

Revisions this loop handles

Swap the hero for the image I uploaded. Keep everything else.
Change the CTA to "Start free". Check the page says free first.
Make a 9:16 version.
The headline in 1a is too long. Two lines, same words.
Drop the proof line. The review count is out of date.
Re-render as v3. Keep v2.

Each one is create_timeline_version, the smallest edit that answers it, a validate, a preview of the changed beats, and a new render with the next version number.

Version History

  • 97aad94 Current 2026-10-19 19:19

    重构技能以对齐当前代码:更新工具名称、操作符和参数引用;将重叠的作业和技能指向统一的storyboard-core合同;解决冲突的时间参数;增加付费生成的权限门控检查。

  • 85ff020 2026-09-28 10:24

Same Skill Collection

.agents/skills/agentic-qa/SKILL.md
.agents/skills/ask-matt/SKILL.md
.agents/skills/ast-grep-outline/SKILL.md
.agents/skills/ast-grep/SKILL.md
.agents/skills/code-review/SKILL.md
.agents/skills/codebase-design/SKILL.md
.agents/skills/companion-clis/SKILL.md
.agents/skills/diagnosing-bugs/SKILL.md
.agents/skills/domain-modeling/SKILL.md
.agents/skills/flash/SKILL.md
.agents/skills/grill-with-docs/SKILL.md
.agents/skills/implement/SKILL.md
.agents/skills/improve-codebase-architecture/SKILL.md
.agents/skills/prototype/SKILL.md
.agents/skills/research/SKILL.md
.agents/skills/resolving-merge-conflicts/SKILL.md
.agents/skills/runpodctl/SKILL.md
.agents/skills/setup-matt-pocock-skills/SKILL.md
.agents/skills/tdd/SKILL.md
.agents/skills/to-spec/SKILL.md
.agents/skills/to-tickets/SKILL.md
.agents/skills/triage/SKILL.md
.agents/skills/unslop/SKILL.md
.agents/skills/ux-research/SKILL.md
.agents/skills/wayfinder/SKILL.md
.agents/skills/wizard/SKILL.md
.agents/skills/yts806379-everything-claude-code-e2e-testing/SKILL.md
.claude/skills/ask-matt/SKILL.md
.claude/skills/ast-grep-outline/SKILL.md
.claude/skills/ast-grep/SKILL.md
.claude/skills/codebase-design/SKILL.md
.claude/skills/companion-clis/SKILL.md
.claude/skills/diagnosing-bugs/SKILL.md
.claude/skills/domain-modeling/SKILL.md
.claude/skills/flash/SKILL.md
.claude/skills/implement/SKILL.md
.claude/skills/improve-codebase-architecture/SKILL.md
.claude/skills/nodetool-api-reference/SKILL.md
.claude/skills/nodetool-browser-agent/SKILL.md
.claude/skills/nodetool-chat-cli/SKILL.md
.claude/skills/nodetool-custom-node-developer/SKILL.md
.claude/skills/nodetool-deployment/SKILL.md
.claude/skills/nodetool-model-provider-config/SKILL.md
.claude/skills/nodetool-rag-indexing/SKILL.md
.claude/skills/nodetool-troubleshooter/SKILL.md
.claude/skills/nodetool-workflow-builder/SKILL.md
.claude/skills/prototype/SKILL.md
.claude/skills/research/SKILL.md
.claude/skills/resolving-merge-conflicts/SKILL.md
.claude/skills/setup-matt-pocock-skills/SKILL.md

Metadata

Files
0
Version
97aad94
Hash
5ca3696f
Indexed
2026-09-28 10:24

trang chủ - Wiki
Copyright © 2011-2026 iteam. Current version is 2.155.2. UTC+08:00, 2026-10-24 23:48
浙ICP备14020137号-1