Skip to content
Back to skills

Video Workflow

ASecurity

Build a reusable NodeTool video workflow for batches or repeated inputs. For a single finished piece, use a storyboard skill.

  • 552 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 1, 2026
ai-agentsgonode

Works with

  • cli

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add nodetool-ai/nodetool --skill video-workflow --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Video Workflow?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Video Workflow
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nodetool-ai-video-workflow/badge)](https://www.skillsdirectory.com/skills/nodetool-ai-video-workflow)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: video-workflow
description: "Build a reusable NodeTool video workflow for batches or repeated inputs. For a single finished piece, use a storyboard skill."
---

**Load `/storyboard-core` for what a shot is and how entities season a prompt,
and `/nodetool-workflow-builder` for how to author a graph at all** — node search,
handles, validation, the tools. This skill is the seam between them: the nodes that
turn a brief into shots, and when a graph is the wrong answer.

## First, check a graph is actually wanted

A graph earns its cost only when the pipeline gets **re-run on new inputs**. One video,
even a complicated one, is faster and cheaper to direct on a storyboard — no node
search, no handle wiring, no validation pass, and the user can see and fix each shot.

Build a graph when the user says template, pipeline, batch, factory, "for every SKU",
"run it again next month", or wants it callable from Chat by name. If they asked for a
video and you are reaching for a graph, go back to the storyboard skills.

## The creative nodes

Search the registry before adding any of these — `search_nodes` or `ui_search_nodes`
with `include_properties` and `include_outputs` — and never invent a type, a property
or a handle name. Verified types:

| Node | Does |
|---|---|
| `nodetool.creative.Director` | brief → `Screenplay`. Props: `model` (language_model), `brief`, `style`, `shot_count` (1–20). Outputs: `screenplay`, `narration`, `music_prompt`, `title`. |
| `nodetool.creative.ScreenplayShots` | fans a screenplay out one shot at a time. Outputs `shot`, `shot_prompt`, `index` per iteration plus `output` as the whole list. |
| `nodetool.creative.ShotBatch` | flattens a screenplay into generation-ready specs in one go. Output: `shots` (list[dict]) with prompt, timing and keyframe. |
| `nodetool.creative.ShotChain` | animates a spec list sequentially, seeding each shot's first frame from the previous clip's last frame. Output: `videos`. Needs the `ffmpeg` runtime. |
| `nodetool.creative.ApplyEntities` | seasons a prompt with entity descriptors, the same rule the storyboard render path uses. |
| `nodetool.image.TextToImage` | prompt → image. |
| `nodetool.video.ImageToVideo` / `nodetool.video.TextToVideo` | still → clip, or prompt → clip. |

## Re-run an approved document instead of re-directing

When the user already has a board, a script or a cut they signed off, do not put
`Director` in the graph. Start from the approved row and derive:

| Node | Does |
|---|---|
| `nodetool.constant.Storyboard` / `.Entity` | a picked board or library entity as a graph value. Outputs `output`. |
| `nodetool.entity.CreateEntity` | `image`, `kind`, `name`, `descriptor`, `key` → `entity`, `created`. Upserts on `key` (a SKU), so a second run reuses the row instead of growing the library. |
| `nodetool.entity.LoadEntity` / `ListEntities` | read one entity, or stream a filtered set. |
| `nodetool.storyboard.RecastStoryboard` | `storyboard`, `cast`, `replaces`, `reuse_existing` → the copy, `invalidated`, `kept`. Keeps every frame whose prompt did not move. |
| `nodetool.storyboard.RenderStills` / `RenderClips` | render the stale shots of a derived board. `only_stale`, `max_shots`, `require_keyframe` are the spend gates. |
| `nodetool.storyboard.AssembleTimeline` | the derived board → `timeline`. A copy inherits the template's cut, titles and music. |
| `nodetool.storyboard.LoadStoryboard` / `StoryboardShots` | read a board's shots, entities and settings, or stream one message per shot with its still and clip. |
| `nodetool.script.WriteScript` / `FillScript` | write a script from a brief and a cast, or fill `{{key}}` placeholders in an approved one. Both make a new row. |
| `nodetool.timeline.FillTimelineText` | `timeline`, `values` → a new sequence with the overlay filled. |
| `nodetool.timeline.RetargetTimeline` | `timeline`, `aspect_ratio`, `fit` → a new sequence, plus `cropped` naming the clips the crop cuts into. |

**The write contract.** A `storyboard` ref is read-only unless the run derived it.
`RenderStills`, `RenderClips` and `AssembleTimeline` refuse a picked board and name
`allow_writes`, which is the override for a graph whose whole purpose is to render the
board a person chose. Wire `RecastStoryboard` first and pass its output along; that ref
carries the permission.

Shipped examples to read before wiring one yourself: **Per-SKU Ad Factory**,
**Localized Explainer**, **Three Ratios** (`get_example_workflow`).

## Two shapes, and they are not interchangeable

**Per-shot fan-out** — `Director` → `ScreenplayShots` → `TextToImage` → `ImageToVideo`.
Each shot renders independently. Use it when shots are separate takes: an ad, a set of
social cuts, anything where a shot failing should not spoil the rest.

**Continuous chain** — `Director` → `ShotBatch` → `ShotChain`. Each clip's first frame
is the previous clip's last frame, so motion and framing carry across the cut. Use it
for a sequence that has to feel continuous. It is sequential, so it is slower and one
bad clip propagates.

`ApplyEntities` goes between the prompt source and the image node whenever the pipeline
has a recurring character or product to hold steady.

## Wire the gate in

The storyboard loop's value is that a human sees the stills before the clips are paid
for. A graph loses that unless you build it in: keep the still half and the clip half
separable, so the user can run to the stills, look, and then run the clip half. Say
which inputs do that when you hand the workflow over.

## Validate and deliver the requested result

`validate_workflow` with the inline graph before saving — it catches unknown node
types, missing required properties, unselected models, dangling edges and a model id
the provider does not offer, in well under a second and with no spend.

`create_workflow` refuses to save a graph whose model properties are unselected, so
pick real ones with `find_model` and stamp them in. Nothing fills them in at run time.

Save and read back the graph. A request to build a template ends with a validated
workflow and its input instructions. If the user also requested execution, run
the authorized stages within their scope and budget. Do not request the same
authorization again.

## Brief

Adapt these examples to the user's brief. Example deliverables, style choices,
and approval checkpoints apply only when the user adopts them.

```
Build a workflow named "UGC factory" that I can re-run from Chat.

Inputs: a product image, a brief, an aspect ratio.
Shape: nodetool.creative.Director (brief + style + shot_count) ->
nodetool.creative.ScreenplayShots -> nodetool.creative.ApplyEntities ->
nodetool.image.TextToImage -> a point I can stop at and look ->
nodetool.video.ImageToVideo -> timeline assembly.

Search the registry for every node type and read its real properties and handles
before you add it. Pick concrete models with find_model and stamp them in.
validate_workflow before saving.

Save it and stop. Do not run the clip stage.
```

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…