Skip to content

I'll analyze the code and inspect the referenced local packages to ensure accurate documentation.I have enough context now. Let me check the validate.go briefly for output behavior context.I now have a complete understanding. Here is the documentation:


title: keryx storyboard draft description: Drafts a reel storyboard from a blog post using an LLM, or injects a ready-made storyboard file without any LLM call. date: 2026-07-21 tags: [cli, command, draft, storyboard, reel, llm] authors: [Claude (claude-opus-4-8)]


keryx storyboard draft

Draft a reel storyboard from a post using a configured chat provider (LLM), or inject a ready-made one directly. The result is always validated and written as an unreviewed draft — never an auto-finalised asset.

Usage

$ keryx storyboard draft [<post.md>] [flags]

The command operates in one of two mutually exclusive modes:

  • Draft mode — provide a post file as the first positional argument. The post is distilled by the LLM into a short vertical promo-reel storyboard.

  • Inject mode — provide --inject <board.json> to write a supplied storyboard directly, with no LLM round-trip.

Description

keryx storyboard draft produces a storyboard.json for a reel workspace. It supports two complementary workflows so you can either let an LLM do the initial distillation or supply a hand-authored (or externally generated) storyboard yourself.

When a post file is supplied, the command reads it, connects to the configured chat provider, and asks the model to distil the post into roughly nine cards. Each card carries one idea, with an on-screen line (text), spoken narration (vo), palette hints (bg, fg, accent), and bookend/cover markers. The final card is always the bare URL closer (mono: true).

The chat provider is chosen from your configuration (providers.chat.provider) or inferred when exactly one matching API key is present in the environment. If no provider is configured and none can be inferred, the command fails with a hint to set providers.chat.provider (claude, gemini, or openai) and the matching API key.

When --inject is supplied, the given file is read and parsed as a storyboard directly — no LLM is contacted, and any positional post argument is ignored.

In both modes, the resulting storyboard is semantically validated (non-empty text, balanced accent markers, valid overlay scenes, and palette roles). An invalid storyboard is rejected with an itemised list of issues rather than being written to disk.

Closing URL is templated from config

When drafting from a post, if site.base_url is configured and --workspace is set, the closing mono (URL) card's text is overwritten with the canonical post URL (site.base_url + the reel slug). This prevents the LLM from inventing an incorrect host.

Drafts are unreviewed

The output always lands as a draft intended for human review. Review and edit the storyboard before generating any media from it.

Output location

The output path is resolved in the following order of precedence:

  1. The explicit --out path, if provided.

  2. The workspace's storyboard.json (under the reel root), if --workspace is set.

  3. A standalone storyboard.json in the current directory.

The reel root defaults to reels unless overridden by the workspace.root configuration key.

Flags

Name Description Default Required
--out Output path for the generated storyboard.json. Takes precedence over --workspace when resolving the destination. "" No
--inject Path to a ready-made storyboard.json to write directly, bypassing the LLM entirely. When set, no chat provider is contacted. "" No
--workspace Reel workspace slug. When set (and --out is not), the storyboard is written to that workspace's storyboard.json, and enables config-templated closing URLs. "" No
--theme Reel theme used as a tone/style hint passed to the LLM. Ignored in inject mode. "" No

Either a post or --inject

You must supply either a post file as the first argument or --inject <board.json>. Running the command with neither results in an error.

Examples

Draft a storyboard from a post and write it to the default storyboard.json in the current directory:

$ keryx storyboard draft post.md
storyboard.json (9 cards, review before use)

Draft directly into a named reel workspace, with a tone hint:

$ keryx storyboard draft post.md --workspace my-launch-reel --theme "warm, upbeat"
reels/my-launch-reel/storyboard.json (9 cards, review before use)

Draft to an explicit output path:

$ keryx storyboard draft post.md --out drafts/preview.json
drafts/preview.json (9 cards, review before use)

Inject a ready-made storyboard into a workspace with no LLM call:

$ keryx storyboard draft --inject ready-board.json --workspace my-launch-reel
reels/my-launch-reel/storyboard.json (9 cards, review before use)

Inject a storyboard to a standalone file:

$ keryx storyboard draft --inject ready-board.json --out storyboard.json
storyboard.json (9 cards, review before use)

Machine-readable output

Like other keryx commands, storyboard draft emits a structured result (including the output path and the card count) that can be consumed programmatically, alongside the human-friendly line shown above.