بنقرة واحدة
generate-story
Generate and publish a bedtime story for James with consistent text, cover art, and video.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
القائمة
Generate and publish a bedtime story for James with consistent text, cover art, and video.
التثبيت باستخدام Codex أو Claude انسخ هذا Prompt والصقه في Codex أو Claude أو مساعد آخر ليراجع صفحة Skill ويثبّتها لك.
استنادا إلى تصنيف SOC المهني
| name | generate-story |
| description | Generate and publish a bedtime story for James with consistent text, cover art, and video. |
| metadata | {"short-description":"Generate and publish a bedtime story for James."} |
Use this skill when the user wants a new bedtime story for James or wants to refresh media for an existing story.
Expect some combination of:
YYYY-MM-DD).If the user provides a long synopsis, movie plot, or article-like background, treat it as inspiration only. Do not retell it beat-by-beat.
Always return:
titlestory_contentimage_keyvideo_keystory_idWhen relevant, also return the resolved date.
Required env vars:
STORY_API_TOKENREPLICATE_API_TOKEN for default replicate media generationOPENAI_API_KEY for openai-media, openai-image, or openai-video
OPENAI_BEDTIME_STORY_KEY is also accepted as a local alias by the bundled scriptsSTORY_API_BASE_URL (optional, defaults to https://bedtimestories.bruce-hart.workers.dev)STORY_API_USER_AGENT (optional, defaults to a browser-like user agent for Cloudflare Browser Integrity Check compatibility)The bundled scripts will also auto-load $HOME/.config/secrets/codex.env when these vars are not already exported.
For any Python step, activate the venv first:
source ~/scripts/.venv/bin/activate
Prefer this path unless blocked:
run-generate-story.py.Use the manual image/video/upload steps only if the runner cannot satisfy the task.
Run this first:
source ~/scripts/.venv/bin/activate
set -a
source "$HOME/.config/secrets/codex.env"
set +a
python -c 'import os; assert os.getenv("STORY_API_TOKEN"), "STORY_API_TOKEN missing"'
python -c 'import os; assert os.getenv("REPLICATE_API_TOKEN") or os.getenv("OPENAI_API_KEY") or os.getenv("OPENAI_BEDTIME_STORY_KEY"), "REPLICATE_API_TOKEN or OpenAI key missing"'
command -v ffmpeg >/dev/null
command -v curl >/dev/null
Use this order:
YYYY-MM-DD, use that.YYYY-MM-DD, use that.America/New_York.Preferred helper:
source ~/scripts/.venv/bin/activate
python .codex/skills/generate-story/scripts/next-open-date.py
Relevant env vars:
STORY_API_TOKEN requiredSTORY_API_BASE_URL optionalSTORY_CALENDAR_DAYS optional, default 365STORY_TIMEZONE optional, default America/New_YorkWrite a bedtime story for James.
Hard requirements:
story_content.180-260 words.8-14 short paragraphs.If the user provides complex source material:
1-3 child-friendly ideas.Only include people or pets that matter to the specific story.
Reference details:
Image requirements:
16:9Video requirements:
16:95 secondsKeep prompts short and scene-specific.
Character fidelity requirements:
Mom or Dad, when a physical description is available in Character rulesImage prompt template:
Landscape 16:9 cartoon bedtime scene. {scene}. Include only {relevant_characters_with_physical_descriptions}. Setting details: {visual_setting_details}. Warm storybook mood. No text, letters, or signage.
Video prompt template:
Gentle cartoon motion scene: {action}. Show {relevant_characters_with_physical_descriptions}. Setting details: {visual_setting_details}. Keep it cozy, readable, and simple. No text or letters.
Do not dump the whole story into the media prompt. Use one scene only.
Default runner mode:
replicate uses Replicate for both image and video.Bundled Replicate defaults:
google/nano-banana-2, landscape 16:9, resolution=1Kwan-video/wan-2.2-i2v-fast, 81 frames, 16 fps, go_fast=true, resolution=480p--video-model pixverse/pixverse-v5.Optional runner modes:
--media-provider openai-media uses OpenAI for both steps.--media-provider openai-image uses OpenAI for image and Replicate for video.--media-provider openai-video uses Replicate for image and OpenAI for video.Bundled OpenAI defaults:
gpt-image-2, 1280x720, quality=low, output_format=jpegsora-2, 1280x720, 4 secondsCurrent OpenAI video caveat:
input_reference must match the target video size, and input images with human faces may be rejected. If openai-video or openai-media fails on a people-focused scene, retry with the default provider.After writing the story, save the body to a temp file such as /tmp/story.txt, then run:
source ~/scripts/.venv/bin/activate
python .codex/skills/generate-story/scripts/run-generate-story.py \
--title "TITLE" \
--content-file /tmp/story.txt \
--date YYYY-MM-DD \
--ref-image /path/to/reference-image
Useful flags:
--date YYYY-MM-DD to force a date--ref-image /path/to.jpg repeatable--media-provider replicate|openai-media|openai-image|openai-video to choose the media backend mix--video-model pixverse/pixverse-v5 to use PixVerse instead of the default Replicate video modelSTORY_VIDEO_MODEL=pixverse/pixverse-v5 to make that override persistent for Replicate video runs--image-prompt "..." to override the default image prompt--video-prompt "..." to override the default video prompt--json for machine-readable outputUse this when the user wants to keep the story record but regenerate media:
source ~/scripts/.venv/bin/activate
python .codex/skills/generate-story/scripts/run-generate-story.py \
--title "TITLE" \
--content-file /tmp/story.txt \
--story-id ID \
--ref-image /path/to/reference-image
This regenerates media, uploads it, and updates image_url and video_url for the existing record.
Use the manual path only if the runner is not suitable.
Generate image:
source ~/scripts/.venv/bin/activate
IMAGE_PATH=$(python .codex/skills/generate-story/scripts/generate-image.py \
--image "/path/to/reference.jpg" \
"IMAGE_PROMPT")
Add --provider openai to use gpt-image-2.
Generate video:
source ~/scripts/.venv/bin/activate
VIDEO_PATH=$(python .codex/skills/generate-story/scripts/generate-video.py \
"$IMAGE_PATH" \
"VIDEO_PROMPT")
Add --provider openai to use sora-2.
Add --model pixverse/pixverse-v5 to use the older PixVerse v5 video model.
Re-encode for iPhone compatibility:
ffmpeg -y -i "$VIDEO_PATH" \
-c:v libx264 -profile:v high -level 4.0 -pix_fmt yuv420p \
-c:a aac -b:a 128k -movflags +faststart \
/tmp/story-video-encoded.mp4
Upload media:
curl -s "${STORY_API_BASE_URL:-https://bedtimestories.bruce-hart.workers.dev}/api/media" \
-A "${STORY_API_USER_AGENT:-Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36}" \
-H "X-Story-Token: $STORY_API_TOKEN" \
-F "file=@/path/to/image.jpg"
curl -s "${STORY_API_BASE_URL:-https://bedtimestories.bruce-hart.workers.dev}/api/media" \
-A "${STORY_API_USER_AGENT:-Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36}" \
-H "X-Story-Token: $STORY_API_TOKEN" \
-F "file=@/tmp/story-video-encoded.mp4"
Create story:
curl -s "${STORY_API_BASE_URL:-https://bedtimestories.bruce-hart.workers.dev}/api/stories" \
-A "${STORY_API_USER_AGENT:-Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36}" \
-H "X-Story-Token: $STORY_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "TITLE",
"content": "STORY_CONTENT",
"date": "YYYY-MM-DD",
"image_url": "IMAGE_KEY",
"video_url": "VIDEO_KEY"
}'
Before finishing, verify: