Skip to content
Back to skills

Api Storyboards

ASecurity

Call nodetool.storyboards from a code action: create a storyboard, write and reorder its shots, set the board's style, entities and models, render stills and clips, revise a clip, and assemble the board into a timeline. Load before the first call into nodetool.storyboards.

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

Works with

  • cli
  • api

Security analysis

A100/100

Scanned September 29, 2026

npx -y skills add nodetool-ai/nodetool --skill api-storyboards --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Api Storyboards?

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

Security grade badge for Api Storyboards
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/nodetool-ai-api-storyboards/badge)](https://www.skillsdirectory.com/skills/nodetool-ai-api-storyboards)

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: api-storyboards
description: "Call nodetool.storyboards from a code action: create a storyboard, write and reorder its shots, set the board's style, entities and models, render stills and clips, revise a clip, and assemble the board into a timeline. Load before the first call into nodetool.storyboards."
---

# nodetool.storyboards

A storyboard turns a brief into shots: an action, a camera, a motion and a
duration for each, with cast entities. Stills are the cheap step, clips the
expensive one, and the board assembles into a timeline. The directing
contract is `storyboard-core`. The brief shapes are the board skills
(`commercial-beat-sheet`, `explainer-storyboard`, `music-video-treatment`,
`trailer-template`, and the job skills such as `product-commercial` and
`short-film`). Search for them with `list_skills`.

| Call | Does | Answers |
| :--- | :--- | :--- |
| `list({limit})` | Lists boards, newest first, with shot, still and clip counts. | Board rows |
| `create(name, {brief, style, aspect_ratio, project_id, id})` | Creates a blank board. `aspect_ratio` defaults to `"16:9"`. `style` is added to every shot prompt. | `{id, storyboard_id, …}` |
| `get(id)` | Reads the brief, style, aspect ratio, models, and every shot with its id, index, slug, action, camera, motion, duration, status, `has_still`, `has_clip` and `covered_by`. | The board |
| `edit(id, ops)` | Applies ops in order and saves. It spends nothing. | The result of each op |
| `renderStills(id, {targets, provider, model, style, stale_only, concurrency})` | Makes keyframe stills with the image model. | The stills it made |
| `renderClips(id, {targets, provider, model, resolution, mode, stale_only, concurrency})` | Makes clips with the video model. This is the expensive step. | The clips it made, and the shots it skipped |
| `reviseClip(id, target, instruction, {provider, model})` | Changes one clip with a video-to-video edit: "make it darker, add rain". | The new take |
| `assembleTimeline(id, {name, fps})` | Lays the rendered clips end to end into a timeline. | The timeline id, and what it skipped |

`targets` and `target` take a shot id, a 0-based index or a slug. Omit
`targets` to render every shot that needs the step.

## Ops

| Op | Arguments |
| :--- | :--- |
| `add_shot` | `action`, `slug?`, `camera?`, `motion?`, `dialogue?`, `narration?`, `duration_seconds?`, `duration_source?`, `render_mode?`, `entity_ids?`, `location_id?`, `covered_by?`, `notes?`, `index?` |
| `update_shot` | `target` and the same fields |
| `remove_shot`, `duplicate_shot` | `target` |
| `reorder_shot` | `target`, `index` |
| `move_shot` | `target`, `scene_id?`, `position` (0-based inside the scene) |
| `set_board` | `brief?`, `style?`, `aspect_ratio?`, `entity_ids?`, `image_model?`, `video_model?` |
| `set_setup` | `brief?`, `genre?`, `stage?` |
| `set_style` | `entity_id` (a style entity becomes the board preset) or `style` (the descriptor alone) |
| `create_scene`, `update_scene`, `merge_scene` | `after_scene_id?`; `scene_id`, `slugline?`, `lighting?`; `scene_id` |
| `select_version`, `delete_version` | `target`, `kind`, `version` (0-based, oldest first) |
| `add_keyframe_version` | `target`, `asset_id`, `flip_of?` |

- `image_model` and `video_model` take a model object from
  `nodetool.models.pick` and become the render defaults of the board.
- `covered_by: {shot_id, start_seconds?, end_seconds?}` says that this shot's
  picture is a window into another shot's clip, for one generation whose
  length covers several beats. The covered shot counts as rendered. Pass
  `null` to undo it.

## Render modes

A shot renders the way its `render_mode` says, or the way `mode` says for one
call:

- `keyframe` (default) animates the selected still with `image_to_video`. A
  shot with no still is reported, not rendered. Render its still first.
- `direct` makes the clip from the prompt with `text_to_video`. No still is
  needed.
- `reference` uses the reference images of the cast entities with
  `reference_to_video`.

Earlier stills and clips are kept as versions. `stale_only: true` renders
only shots whose current version was made against a style, model, aspect
ratio or prompt they no longer have.

## The loop

```js
const { id } = await nodetool.storyboards.create("Lamp launch", { brief, style });
await nodetool.storyboards.edit(id, [
  { op: "set_board", image_model: await nodetool.models.pick("text_to_image"),
    video_model: await nodetool.models.pick("image_to_video") },
  { op: "add_shot", action: "Wide of the lamp on a desk at dusk", duration_seconds: 4 },
  { op: "add_shot", action: "Close on the switch as a hand reaches in", duration_seconds: 3 }
]);
await nodetool.storyboards.renderStills(id);   // cheap: look at them first
// … view the stills, fix shots with update_shot, render again with stale_only …
await nodetool.storyboards.renderClips(id);    // expensive
const cut = await nodetool.storyboards.assembleTimeline(id);
```

When the board links a script, assembly times each shot to the takes it
covers and adds a voiceover clip for each voiced line. Validate the timeline
with `nodetool.timelines.validate` before a render.

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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.