@vibeframe/cli 0.113.27 → 0.113.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -26882,12 +26882,12 @@ colors:
26882
26882
  ---
26883
26883
 
26884
26884
  `;
26885
- const intro = style ? `Visual identity for **${name}**, scaffolded from the **${style.name}** style (after ${style.designer}). Customise freely \u2014 this file is the single source of truth for every scene's palette, typography, and motion.` : `Visual identity for **${name}**. Fill the sections below before authoring any scene HTML or generating any backdrop. Pick a named style with \`vibe scene list-styles\` if you want a credible starting point.`;
26886
- const moodLine = style ? `**Mood:** ${style.mood} \xB7 **Best for:** ${style.bestFor}` : `**Mood:** _(one line \u2014 what should the viewer FEEL?)_`;
26885
+ const intro = style ? `Visual identity for **${name}**, scaffolded from the **${style.name}** style (after ${style.designer}). Customise freely - this file is the single source of truth for every scene's palette, typography, and motion.` : `Visual identity for **${name}**. Fill the sections below before authoring any scene HTML or generating any backdrop. Pick a named style with \`vibe scene list-styles\` if you want a credible starting point.`;
26886
+ const moodLine = style ? `**Mood:** ${style.mood} \xB7 **Best for:** ${style.bestFor}` : `**Mood:** _(one line - what should the viewer FEEL?)_`;
26887
26887
  const palette = style ? `${style.palette.map((c) => `- \`${c}\``).join("\n")}
26888
26888
 
26889
- ${style.paletteNotes}` : `- _hex_ \u2014 primary
26890
- - _hex_ \u2014 accent
26889
+ ${style.paletteNotes}` : `- _hex_ - primary
26890
+ - _hex_ - accent
26891
26891
 
26892
26892
  _2\u20133 colours max. Declare explicit hex values; never name colours abstractly._`;
26893
26893
  const typography = style ? style.typography : `_One family, two weights. State the role of each (headline / label / body)._`;
@@ -26901,7 +26901,7 @@ _2\u20133 colours max. Declare explicit hex values; never name colours abstractl
26901
26901
  const avoid = style ? style.avoid.map((a) => `- ${a}`).join("\n") : `- _anti-pattern 1_
26902
26902
  - _anti-pattern 2_
26903
26903
  - _anti-pattern 3_`;
26904
- return `${frontmatter}# ${name} \u2014 Design
26904
+ return `${frontmatter}# ${name} - Design
26905
26905
 
26906
26906
  > **Hard-gate (BUILD flow only).** This file is the visual contract for
26907
26907
  > the scene-project flow (\`vibe build\`, \`vibe scene ...\`, composition
@@ -26949,8 +26949,8 @@ ${style ? `_This file was seeded by \`vibe scene init --visual-style "${style.na
26949
26949
  `;
26950
26950
  }
26951
26951
  function buildScriptMd(name, kind = DEFAULT_SCENE_KIND) {
26952
- const intent = kind === "product" ? "Product walkthrough \u2014 what each section demonstrates, in order." : kind === "motion" ? "Motion piece \u2014 the message and the beats of on-screen text/graphics." : kind === "aivideo" ? "AI-video script \u2014 the spoken/voiced narrative the generated shots illustrate." : "Narrative script \u2014 scene-by-scene story, dialogue, and voiceover.";
26953
- return `# ${name} \u2014 Script
26952
+ const intent = kind === "product" ? "Product walkthrough - what each section demonstrates, in order." : kind === "motion" ? "Motion piece - the message and the beats of on-screen text/graphics." : kind === "aivideo" ? "AI-video script - the spoken/voiced narrative the generated shots illustrate." : "Narrative script - scene-by-scene story, dialogue, and voiceover.";
26953
+ return `# ${name} - Script
26954
26954
 
26955
26955
  > **Authoring order:** SCRIPT.md (this file) \u2192 STORYBOARD.md (beats + cues)${kindHasCast(kind) ? " \u2192 CHARACTERS.md (cast bible)" : ""}.
26956
26956
  > ${intent}
@@ -26978,7 +26978,7 @@ Voiceover / on-screen: \u2026
26978
26978
  `;
26979
26979
  }
26980
26980
  function buildCharactersMd(name) {
26981
- return `# ${name} \u2014 Characters
26981
+ return `# ${name} - Characters
26982
26982
 
26983
26983
  > Each character is referenced from STORYBOARD beats via the \`characters:\` cue.
26984
26984
  > The reference sheet + identity block keep keyframes and image-to-video on-model
@@ -26987,8 +26987,8 @@ function buildCharactersMd(name) {
26987
26987
  ## hero
26988
26988
 
26989
26989
  - **Reference sheet:** \`assets/characters/hero.png\` (a clean, front-lit full-body
26990
- or portrait sheet \u2014 the identity anchor for keyframe edits).
26991
- - **Identity:** one paragraph of fixed, on-model traits \u2014 age, build, hair,
26990
+ or portrait sheet - the identity anchor for keyframe edits).
26991
+ - **Identity:** one paragraph of fixed, on-model traits - age, build, hair,
26992
26992
  wardrobe, palette. Keep this stable across every beat.
26993
26993
  - **Range:** expressions / poses this character should hit.
26994
26994
 
@@ -27006,14 +27006,14 @@ tts: auto
27006
27006
  imageProvider: openai
27007
27007
  ---
27008
27008
 
27009
- # ${name} \u2014 Storyboard
27009
+ # ${name} - Storyboard
27010
27010
 
27011
27011
  Edit these beats before running \`vibe build\`. Each beat starts with
27012
27012
  YAML cues that drive narration, backdrop generation, and timing.
27013
27013
  Pacing: keep beats 6-15 seconds (split longer ones); a 90s video should
27014
27014
  have 6-8 beats, not 3 long ones.
27015
27015
 
27016
- ## Beat hook \u2014 Hook
27016
+ ## Beat hook - Hook
27017
27017
 
27018
27018
  \`\`\`yaml
27019
27019
  narration: "Introduce the promise in one crisp sentence."
@@ -27024,7 +27024,7 @@ duration: 4
27024
27024
  Show the core visual identity immediately. Keep copy short enough for one
27025
27025
  screen and one spoken breath.
27026
27026
 
27027
- ## Beat proof \u2014 Proof
27027
+ ## Beat proof - Proof
27028
27028
 
27029
27029
  \`\`\`yaml
27030
27030
  narration: "Show the mechanism or proof point that makes the promise believable."
@@ -27035,7 +27035,7 @@ duration: 4
27035
27035
  Use this beat for the concrete differentiator: command, workflow, metric, or
27036
27036
  before/after.
27037
27037
 
27038
- ## Beat close \u2014 Close
27038
+ ## Beat close - Close
27039
27039
 
27040
27040
  \`\`\`yaml
27041
27041
  narration: "Close with the action the viewer should remember."
@@ -27048,7 +27048,7 @@ final beat.
27048
27048
  `;
27049
27049
  }
27050
27050
  function buildProjectAgentsMd(name) {
27051
- return `# ${name} \u2014 Scene Authoring Project
27051
+ return `# ${name} - Scene Authoring Project
27052
27052
 
27053
27053
  This is the canonical cross-agent guidance file for this scene project.
27054
27054
  Claude Code imports it through \`CLAUDE.md\`; Codex, Cursor, Aider,
@@ -27087,7 +27087,7 @@ contradict DESIGN.md are rejected by the Hyperframes \`hyperframes\`
27087
27087
  skill.
27088
27088
 
27089
27089
  Single-asset requests (\`vibe generate image|video|speech|...\`) do NOT
27090
- consult this file \u2014 run the generate command directly.
27090
+ consult this file - run the generate command directly.
27091
27091
 
27092
27092
  Browse named styles: \`vibe scene list-styles\`. Re-seed from one with
27093
27093
  \`vibe scene init . --visual-style "Swiss Pulse"\` (idempotent).
@@ -27102,8 +27102,9 @@ after init, those two files are the working source of truth.
27102
27102
  Use \`media/\` for user-provided source files: product photos, screenshots,
27103
27103
  logos, B-roll, recorded narration, or reference clips. Keep those inputs
27104
27104
  inside this project so build references stay project-relative. Do not put user
27105
- media in \`references/\`; that directory is reserved for local composition
27106
- rules installed by VibeFrame.
27105
+ media in \`references/\`; older VibeFrame versions vendored composition rules
27106
+ there, and current installs keep the rules under \`.agents/skills/hyperframes/\`
27107
+ via \`vibe scene install-skill\`.
27107
27108
 
27108
27109
  When a beat should reuse a local file, reference it from \`STORYBOARD.md\`
27109
27110
  with a project-relative path:
@@ -27159,7 +27160,7 @@ project-level agent loop; it provides \`--json\` commands, dry runs, cost caps,
27159
27160
  \`requiresConfirmation\`, \`fixOwner\`, deterministic repair, and render
27160
27161
  inspection for the host agent to reason over.
27161
27162
 
27162
- Copy-paste agent prompts \u2014 plain prompts, not a built-in command:
27163
+ Copy-paste agent prompts - plain prompts, not a built-in command:
27163
27164
 
27164
27165
  \`\`\`text
27165
27166
  Build this VibeFrame project into renders/final.mp4. Use --json for every
@@ -27187,13 +27188,13 @@ target duration/aspect ratio, clean render inspection, any AI review score >= 90
27187
27188
  no unresolved unacknowledged host-agent issues.
27188
27189
  \`\`\`
27189
27190
 
27190
- ## Skills \u2014 USE THESE FIRST
27191
+ ## Skills - USE THESE FIRST
27191
27192
 
27192
- **Load the \`hyperframes\` skill before authoring scenes** \u2014 it encodes the
27193
+ **Load the \`hyperframes\` skill before authoring scenes** - it encodes the
27193
27194
  composition rules, motion principles, type system, and visual-identity gate.
27194
27195
  If your agent has it installed globally it is already available; otherwise run
27195
- \`vibe scene install-skill\` to eject a local, editable copy (\`SKILL.md\` +
27196
- \`references/\`, gitignored by default) and read \`SKILL.md\`.
27196
+ \`vibe scene install-skill\`, which runs upstream's installer and writes
27197
+ \`.agents/skills/hyperframes/SKILL.md\`. Read that file before authoring.
27197
27198
 
27198
27199
  **Always invoke the relevant skill before authoring scenes.** Skills encode
27199
27200
  framework-specific patterns (GSAP timeline registration, data-attribute
@@ -27201,7 +27202,7 @@ semantics, VibeFrame pipeline conventions) that are NOT in generic web docs.
27201
27202
 
27202
27203
  | Skill | Command | When to use |
27203
27204
  | ----------------- | ---------------- | ------------------------------------------------------------------------------------- |
27204
- | **hyperframes** | \`/hyperframes\` | Cinematic-quality composition \u2014 DESIGN.md hard-gate, named styles, motion principles |
27205
+ | **hyperframes** | \`/hyperframes\` | Cinematic-quality composition - DESIGN.md hard-gate, named styles, motion principles |
27205
27206
  | **vibe-scene** | \`/vibe-scene\` | VibeFrame's authoring loop, AI assets, lint feedback, pipeline integration |
27206
27207
  | **gsap** | \`/gsap\` | GSAP tweens, timelines, easing |
27207
27208
 
@@ -27212,22 +27213,22 @@ npx skills add heygen-com/hyperframes
27212
27213
  \`\`\`
27213
27214
 
27214
27215
  Restart your agent session (or reload the skill list) after installing.
27215
- If skills aren't available, follow the **Key Rules** below \u2014 they cover
27216
+ If skills aren't available, follow the **Key Rules** below - they cover
27216
27217
  the framework-level minimum, not the cinematic craft layer.
27217
27218
 
27218
27219
  ## Project structure
27219
27220
 
27220
- - \`DESIGN.md\` \u2014 visual identity contract (palette, type, motion, transitions)
27221
- - \`STORYBOARD.md\` \u2014 per-beat narration/backdrop/duration cues for \`vibe build\`
27222
- - \`media/\` \u2014 user-provided source files (photos, logos, clips, voice recordings)
27223
- - \`index.html\` \u2014 root composition (timeline)
27224
- - \`compositions/scene-*.html\` \u2014 per-scene HTML authored by you or the agent
27225
- - \`assets/\` \u2014 generated/canonical build media (narration audio, images, video)
27226
- - \`references/\` \u2014 composition rule docs, only when ejected via \`vibe scene install-skill\` (not user media)
27227
- - \`transcript.json\` \u2014 Whisper word-level transcript (if narration exists)
27228
- - \`hyperframes.json\` \u2014 HF registry config (speak to both toolchains)
27229
- - \`vibe.config.json\` \u2014 canonical VibeFrame config (providers, budget)
27230
- - \`renders/\` \u2014 output MP4s
27221
+ - \`DESIGN.md\` - visual identity contract (palette, type, motion, transitions)
27222
+ - \`STORYBOARD.md\` - per-beat narration/backdrop/duration cues for \`vibe build\`
27223
+ - \`media/\` - user-provided source files (photos, logos, clips, voice recordings)
27224
+ - \`index.html\` - root composition (timeline)
27225
+ - \`compositions/scene-*.html\` - per-scene HTML authored by you or the agent
27226
+ - \`assets/\` - generated/canonical build media (narration audio, images, video)
27227
+ - \`.agents/skills/hyperframes/\` - upstream composition rules, when installed here rather than globally
27228
+ - \`transcript.json\` - Whisper word-level transcript (if narration exists)
27229
+ - \`hyperframes.json\` - HF registry config (speak to both toolchains)
27230
+ - \`vibe.config.json\` - canonical VibeFrame config (providers, budget)
27231
+ - \`renders/\` - output MP4s
27231
27232
 
27232
27233
  ## Commands
27233
27234
 
@@ -27237,7 +27238,7 @@ vibe build # STORYBOARD.md \u219
27237
27238
  vibe scene lint # Validate scenes (in-process HF linter)
27238
27239
  vibe render # Render to MP4
27239
27240
 
27240
- # Hyperframes CLI (if installed \u2014 works in this project too)
27241
+ # Hyperframes CLI (if installed - works in this project too)
27241
27242
  npx hyperframes preview
27242
27243
  npx hyperframes render
27243
27244
  \`\`\`
@@ -27245,7 +27246,7 @@ npx hyperframes render
27245
27246
  ## Key Rules (for hand-authored scene HTML)
27246
27247
 
27247
27248
  1. Every timed element needs \`data-start\`, \`data-duration\`, and \`data-track-index\`.
27248
- 2. Elements with timing **MUST** have \`class="clip"\` \u2014 the framework uses this for visibility control.
27249
+ 2. Elements with timing **MUST** have \`class="clip"\` - the framework uses this for visibility control.
27249
27250
  3. Timelines must be paused and registered on \`window.__timelines\`:
27250
27251
  \`\`\`js
27251
27252
  window.__timelines = window.__timelines || {};
@@ -27257,12 +27258,12 @@ npx hyperframes render
27257
27258
  \`filter\` tweens to \`.scene-content\` or any ancestor containing live text.
27258
27259
  Animate background/media layers instead; text/cards should enter briefly and
27259
27260
  then hold still at their final CSS positions.
27260
- 7. Only deterministic logic \u2014 no \`Date.now()\`, \`Math.random()\`, or network fetches.
27261
+ 7. Only deterministic logic - no \`Date.now()\`, \`Math.random()\`, or network fetches.
27261
27262
 
27262
- ## Linting \u2014 run after changes
27263
+ ## Linting - run after changes
27263
27264
 
27264
27265
  \`\`\`bash
27265
- vibe scene lint # preferred \u2014 in-process, no network
27266
+ vibe scene lint # preferred - in-process, no network
27266
27267
  vibe scene lint --fix # auto-fix mechanical issues
27267
27268
  vibe scene lint --json # structured output for agent loops
27268
27269
  \`\`\`
@@ -27271,7 +27272,7 @@ vibe scene lint --json # structured output for agent loops
27271
27272
  function buildProjectClaudeMd(name) {
27272
27273
  return `@AGENTS.md
27273
27274
 
27274
- # ${name} \u2014 Claude Code Overrides
27275
+ # ${name} - Claude Code Overrides
27275
27276
 
27276
27277
  This file imports \`AGENTS.md\`; keep cross-agent VibeFrame and
27277
27278
  Hyperframes instructions there so Codex, Cursor, Aider, Gemini CLI, and
@@ -27280,15 +27281,16 @@ only when this project needs them.
27280
27281
  `;
27281
27282
  }
27282
27283
  function buildSceneGitignore() {
27283
- return `# VibeFrame \u2014 caches, checkpoints, and project-scope config.yaml (may contain API keys)
27284
+ return `# VibeFrame - caches, checkpoints, and project-scope config.yaml (may contain API keys)
27284
27285
  .vibeframe/
27285
27286
 
27286
27287
  # Render outputs
27287
27288
  renders/*.mp4
27288
27289
  tmp/
27289
27290
 
27290
- # Vendored Hyperframes skill copies \u2014 regenerable via 'vibe scene install-skill'.
27291
- # Delete these lines if you eject and want to commit per-project customizations.
27291
+ # Hyperframes skill copies left by older VibeFrame versions. Nothing writes
27292
+ # these now - upstream's installer owns the rules and puts them under
27293
+ # .agents/skills/hyperframes/, which is yours to commit or ignore.
27292
27294
  /SKILL.md
27293
27295
  /references/
27294
27296
  /.claude/skills/hyperframes/
@@ -27329,12 +27331,7 @@ function describeSceneScaffold(opts) {
27329
27331
  ];
27330
27332
  }
27331
27333
  if (profile === "agent" || profile === "full") {
27332
- groups.agent = [
27333
- resolve7(dir, "AGENTS.md"),
27334
- resolve7(dir, "SKILL.md"),
27335
- resolve7(dir, "references"),
27336
- resolve7(dir, "CLAUDE.md")
27337
- ];
27334
+ groups.agent = [resolve7(dir, "AGENTS.md"), resolve7(dir, "CLAUDE.md")];
27338
27335
  }
27339
27336
  return groups;
27340
27337
  }
@@ -57545,13 +57542,15 @@ var init_walkthroughs = __esm({
57545
57542
  SCENE_WALKTHROUGH = `# Scene authoring with vibe
57546
57543
 
57547
57544
  A scene project is a directory that is **bilingual**: it works with both
57548
- \`vibe\` and \`npx hyperframes\`. Each scene is one HTML file with scoped CSS
57549
- and a paused GSAP timeline. Cheap to edit, cheap to lint, expensive only
57545
+ \`vibe\` and \`npx hyperframes\`. Scene composition is Hyperframes' job:
57546
+ each scene is one HTML file with scoped CSS and a paused GSAP timeline,
57547
+ authored to upstream's composition rules (install them with
57548
+ \`vibe scene install-skill\`). Cheap to edit, cheap to lint, expensive only
57550
57549
  at render.
57551
57550
 
57552
- \`vibe build\` (v0.60+) is the supported one-shot driver from a
57553
- written storyboard to an MP4. Plan H (v0.70) added \`--mode agent\` so the
57554
- host agent itself authors the per-beat HTML \u2014 no internal LLM call.
57551
+ \`vibe build\` is the supported one-shot driver from a written storyboard
57552
+ to an MP4. The host agent authors the per-beat HTML - the CLI makes no
57553
+ internal LLM call.
57555
57554
 
57556
57555
  ## Three authoring paths
57557
57556
 
@@ -57566,20 +57565,20 @@ narration / backdrop intent.
57566
57565
 
57567
57566
  ## High-craft path
57568
57567
 
57569
- 1. \`vibe init my-promo --visual-style "Swiss Pulse"\` \u2014 seeds
57568
+ 1. \`vibe init my-promo --visual-style "Swiss Pulse"\` - seeds
57570
57569
  \`DESIGN.md\` (palette, typography, motion, transitions) plus the
57571
57570
  \`vibe.config.json\` / \`hyperframes.json\` / \`index.html\` scaffold.
57572
- In Plan H this **also installs local composition rules** at the
57573
- right place for your host (\`.claude/skills/hyperframes/\` for Claude
57574
- Code, \`.cursor/rules/hyperframes.mdc\` for Cursor, universal
57575
- \`SKILL.md\` for everyone else).
57576
- 2. Read \`SKILL.md\` (or the host-specific copy) \u2014 Hyperframes
57571
+ It does **not** install the composition rules; if your agent does not
57572
+ already have the \`hyperframes\` skill, run
57573
+ \`vibe scene install-skill\` to fetch them from upstream into
57574
+ \`.agents/skills/hyperframes/\`.
57575
+ 2. Read \`.agents/skills/hyperframes/SKILL.md\` (or your global copy) -
57577
57576
  framework rules, motion principles, type system, transition recipes.
57578
- 3. Read \`DESIGN.md\` \u2014 project-specific palette / typography / motion
57577
+ 3. Read \`DESIGN.md\` - project-specific palette / typography / motion
57579
57578
  signature (visual identity hard-gate).
57580
57579
  4. Author each scene HTML directly under \`compositions/scene-<id>.html\`
57581
57580
  using the rules from steps 2 and 3. The skill enforces the visual
57582
- identity contract \u2014 scenes that contradict DESIGN.md fail lint.
57581
+ identity contract - scenes that contradict DESIGN.md fail lint.
57583
57582
  5. \`vibe scene lint --fix\` for mechanical issues, \`vibe render my-promo\`
57584
57583
  to MP4.
57585
57584
 
@@ -57593,16 +57592,16 @@ vibe scene lint
57593
57592
  vibe render my-promo
57594
57593
  \`\`\`
57595
57594
 
57596
- \`vibe init\` is **idempotent** \u2014 running it on an existing Hyperframes
57595
+ \`vibe init\` is **idempotent** - running it on an existing Hyperframes
57597
57596
  directory merges \`hyperframes.json\` instead of clobbering it. Safe to
57598
57597
  invoke on user-provided projects.
57599
57598
 
57600
57599
  ## Subcommands
57601
57600
 
57602
57601
  \`\`\`bash
57603
- # Project flow (top-level \u2014 preferred entry points)
57602
+ # Project flow (top-level - preferred entry points)
57604
57603
  vibe init <dir> [-r 16:9|9:16|1:1|4:5] [-d <sec>] [--visual-style "<name>"]
57605
- vibe build [<dir>] [--mode agent|batch|auto] # H3 dispatch
57604
+ vibe build [<dir>] [--composer template] # agent authors scenes by default
57606
57605
  vibe render [<dir>] [--fps 30] [--quality standard] [--format mp4]
57607
57606
 
57608
57607
  # Lower-level scene authoring
@@ -57615,11 +57614,11 @@ vibe scene lint [<root>] [--json] [--fix]
57615
57614
 
57616
57615
  ## Style presets (for \`vibe scene add --style\`)
57617
57616
 
57618
- - **simple** \u2014 backdrop + bottom caption (default)
57619
- - **announcement** \u2014 single huge headline, gradient text
57620
- - **explainer** \u2014 kicker + title + subtitle stack
57621
- - **kinetic-type** \u2014 words animate in word-by-word
57622
- - **product-shot** \u2014 corner label + bottom headline + slow zoom
57617
+ - **simple** - backdrop + bottom caption (default)
57618
+ - **announcement** - single huge headline, gradient text
57619
+ - **explainer** - kicker + title + subtitle stack
57620
+ - **kinetic-type** - words animate in word-by-word
57621
+ - **product-shot** - corner label + bottom headline + slow zoom
57623
57622
 
57624
57623
  All presets accept \`--narration <text|file>\`, \`--visuals <prompt>\`,
57625
57624
  \`--headline\`, \`--kicker\`. With \`--narration\`, scene duration auto-derives
@@ -57629,21 +57628,19 @@ from the generated TTS audio.
57629
57628
 
57630
57629
  \`\`\`bash
57631
57630
  vibe init my-promo --visual-style "Swiss Pulse" -d 12
57632
- # (edit STORYBOARD.md with per-beat YAML cues \u2014 narration, backdrop, duration)
57631
+ # (edit STORYBOARD.md with per-beat YAML cues - narration, backdrop, duration)
57633
57632
  vibe build my-promo
57634
57633
  \`\`\`
57635
57634
 
57636
57635
  \`vibe build\` reads the STORYBOARD frontmatter + per-beat cues,
57637
57636
  dispatches TTS + image-gen per beat, then either:
57638
57637
 
57639
- - **\`--mode agent\`** (default when an agent host is detected) \u2014 emits a
57640
- \`needs-author\` plan via \`vibe scene compose-prompts\`. The host agent
57641
- authors each \`compositions/scene-<id>.html\` itself, then re-invoking
57642
- \`vibe build\` proceeds to lint + render.
57643
- - **\`--mode batch\`** \u2014 VibeFrame runs an internal LLM (Claude / OpenAI /
57644
- Gemini) to compose the HTML, then renders.
57645
-
57646
- \`VIBE_BUILD_MODE\` env var overrides the auto-resolve.
57638
+ - **Agent authoring** (default) - emits a \`needs-author\` plan via
57639
+ \`vibe scene compose-prompts\`. The host agent authors each
57640
+ \`compositions/scene-<id>.html\` itself, then re-invoking \`vibe build\`
57641
+ proceeds to lint + render. The CLI makes no internal LLM call.
57642
+ - **\`--composer template\`** - the deterministic no-model composer
57643
+ (concat background + lower-thirds), for when no agent is available.
57647
57644
 
57648
57645
  ## Lint feedback loop
57649
57646
 
@@ -57653,7 +57650,7 @@ vibe scene lint --json --fix
57653
57650
 
57654
57651
  Returns structured findings. The recommended loop: 1) run lint with
57655
57652
  \`--fix\` (mechanical fixes applied), 2) if \`errorCount > 0\`, edit the
57656
- scene HTML, 3) re-lint. Cap retries at 3 \u2014 if errors persist, fall back
57653
+ scene HTML, 3) re-lint. Cap retries at 3 - if errors persist, fall back
57657
57654
  to a template preset (\`vibe scene add <id> --style simple --force\`)
57658
57655
  and surface the error to the user.
57659
57656
 
@@ -57729,9 +57726,9 @@ The full set lives in \`packages/cli/src/pipeline/executor.ts\`.
57729
57726
 
57730
57727
  ## Variable references
57731
57728
 
57732
- - \`$<step-id>.output\` \u2014 previous step's output path
57733
- - \`$<step-id>.result.<field>\` \u2014 structured field from JSON result
57734
- - \`\${ENV_VAR}\` \u2014 environment variable
57729
+ - \`$<step-id>.output\` - previous step's output path
57730
+ - \`$<step-id>.result.<field>\` - structured field from JSON result
57731
+ - \`\${ENV_VAR}\` - environment variable
57735
57732
  - Values can be templated: \`"\${SCRIPT_TITLE} - Episode \${EPISODE}"\`
57736
57733
 
57737
57734
  ## Running
@@ -57748,12 +57745,12 @@ Checkpoints land next to the YAML: \`pipeline.yaml.checkpoint.json\`.
57748
57745
 
57749
57746
  ## Authoring tips
57750
57747
 
57751
- 1. **Start from a tiny YAML** \u2014 keep it in your project directory and run
57748
+ 1. **Start from a tiny YAML** - keep it in your project directory and run
57752
57749
  \`vibe run pipeline.yaml --dry-run\` before spending provider budget.
57753
- 2. **Dry-run first** \u2014 you see estimated cost and resolved variable
57750
+ 2. **Dry-run first** - you see estimated cost and resolved variable
57754
57751
  graph before spending API credits.
57755
57752
  3. **Keep step ids short and descriptive** (\`intro\`, \`scene1\`, \`voice\`,
57756
- \`bgm\`) \u2014 they appear in logs and variable refs.
57753
+ \`bgm\`) - they appear in logs and variable refs.
57757
57754
  4. **Name outputs** with extensions matching the action (\`.mp4\`, \`.mp3\`,
57758
57755
  \`.png\`, \`.json\`).
57759
57756
  5. **Declare \`budget:\`** on expensive pipelines:
@@ -57777,9 +57774,9 @@ When the user has a working shell sequence, extract steps:
57777
57774
  - Wrap the entire chain in a \`name:\` + \`steps:\` skeleton
57778
57775
 
57779
57776
  The \`compose\` action is the catch-all assembly step (audio mux, video
57780
- overlay, etc.) \u2014 useful at the tail of a pipeline.
57777
+ overlay, etc.) - useful at the tail of a pipeline.
57781
57778
  `;
57782
- ARCHITECTURE_WALKTHROUGH = `# vibe agent / build / run \u2014 when to pick which
57779
+ ARCHITECTURE_WALKTHROUGH = `# vibe agent / build / run - when to pick which
57783
57780
 
57784
57781
  The CLI has three orchestrating commands that coordinate other primitives:
57785
57782
  \`vibe agent\`, \`vibe build\`, \`vibe run\`. New users routinely ask which one
@@ -57808,14 +57805,14 @@ built-in fallback when you do not already have an agent host.
57808
57805
  - "I have a finished script + visual identity" \u2192 \`vibe build\`
57809
57806
  - "I want this to run again next month" \u2192 \`vibe run\`
57810
57807
 
57811
- If two seem to fit, pick the rightmost one \u2014 more reproducible, less surprise.
57808
+ If two seem to fit, pick the rightmost one - more reproducible, less surprise.
57812
57809
 
57813
57810
  ## Cost-tier awareness (v0.83+)
57814
57811
 
57815
57812
  Every primitive subcommand carries a cost tier (\`free\` / \`low\` / \`high\` /
57816
57813
  \`very-high\`). \`vibe schema --list\` exposes the tier as JSON, and each
57817
57814
  \`vibe <group> <sub> --help\` page shows it as a colored footer. Use
57818
- \`vibe doctor --test-keys\` before kicking off any high-cost orchestrator \u2014
57815
+ \`vibe doctor --test-keys\` before kicking off any high-cost orchestrator -
57819
57816
  a single bad key wastes time and money.
57820
57817
 
57821
57818
  ## Cross-command primitives
@@ -57903,9 +57900,10 @@ vibe generate motion "animated product logo reveal" --render -o logo-reveal.mp4
57903
57900
  title: "Scene authoring with vibe",
57904
57901
  summary: "Author per-scene HTML compositions and render to MP4 (BUILD flow)",
57905
57902
  steps: [
57906
- 'Run `vibe init <dir> --visual-style "<style name>"` to scaffold the project + install local composition rules.',
57903
+ 'Run `vibe init <dir> --visual-style "<style name>"` to scaffold the project.',
57904
+ "Run `vibe scene install-skill` unless your agent already has the `hyperframes` skill; `vibe doctor` tells you which.",
57907
57905
  "Edit `STORYBOARD.md` with per-beat YAML cues (narration / backdrop / duration).",
57908
- "Read `SKILL.md` for the framework rules and `DESIGN.md` for the visual-identity hard-gate.",
57906
+ "Read `.agents/skills/hyperframes/SKILL.md` for the framework rules and `DESIGN.md` for the visual-identity hard-gate.",
57909
57907
  "Run `vibe build <dir>`. With an agent host detected, the CLI emits a `needs-author` plan; the host agent authors each `compositions/scene-<id>.html` and re-invokes to render.",
57910
57908
  "Run `vibe build <dir> --stage sync` to assemble index.html, `vibe scene lint <dir> --fix` to validate, then `vibe render <dir>` to produce the MP4."
57911
57909
  ],
@@ -57924,7 +57922,7 @@ vibe generate motion "animated product logo reveal" --render -o logo-reveal.mp4
57924
57922
  title: "YAML pipelines (Video as Code)",
57925
57923
  summary: "Author and run reproducible multi-step video workflows",
57926
57924
  steps: [
57927
- "Sketch the workflow as YAML \u2014 `name`, `description`, then `steps:` with `id` + `action` + inputs/outputs.",
57925
+ "Sketch the workflow as YAML - `name`, `description`, then `steps:` with `id` + `action` + inputs/outputs.",
57928
57926
  "Reference previous step outputs via `$<step-id>.output` (or `$<step-id>.result.<field>` for structured returns).",
57929
57927
  "Run `vibe run pipeline.yaml --dry-run` to see the resolved graph + cost estimate before spending API budget.",
57930
57928
  "Add a `budget:` block (tokens / cost_usd / max_tool_errors) to cap expensive runs.",
@@ -69586,7 +69584,7 @@ var init_scene2 = __esm({
69586
69584
  cost: "free",
69587
69585
  title: "Get Scene Authoring Prompts",
69588
69586
  annotations: { readOnly: true, openWorld: false },
69589
- description: "Emit the per-beat compose plan for the host agent to author scene HTML itself. Reads STORYBOARD.md + DESIGN.md and returns each beat's outputPath + userPrompt + cues + body, plus references to the project's SKILL.md (Hyperframes rules) and DESIGN.md (visual identity). The host agent writes each compositions/scene-<id>.html file directly \u2014 VibeFrame makes NO LLM call here. Hosts that cannot write files (e.g. Claude Desktop) submit each authored beat with scene_submit instead. Pairs with scene_install_skill (Phase H1). Phase H2 of the agentic-native composer plan; the internal-LLM batch path (build) remains as a fallback for non-agent contexts.",
69587
+ description: "Emit the per-beat compose plan for the host agent to author scene HTML itself. Reads STORYBOARD.md + DESIGN.md and returns each beat's outputPath + userPrompt + cues + body, plus the path to the Hyperframes rules (skillReference) and DESIGN.md (visual identity). The host agent writes each compositions/scene-<id>.html file directly \u2014 VibeFrame makes NO LLM call here, and there is no internal-LLM fallback: authoring is always the host agent's job. Hosts that cannot write files (e.g. Claude Desktop) submit each authored beat with scene_submit instead. Pairs with scene_install_skill, which fetches the rules from upstream when the agent does not already have them.",
69590
69588
  schema: sceneComposePromptsSchema,
69591
69589
  async execute(args, ctx) {
69592
69590
  const projectDir = resolve79(ctx.workingDirectory, args.projectDir);
@@ -74251,8 +74249,8 @@ init_source();
74251
74249
  // package.json
74252
74250
  var package_default = {
74253
74251
  name: "@vibeframe/cli",
74254
- version: "0.113.27",
74255
- description: "VibeFrame CLI - agentic video workflow runtime",
74252
+ version: "0.113.29",
74253
+ description: "Frontier AI video generation for coding agents - Seedance, Runway, Veo, and Kling on your own keys, behind a hard cost cap",
74256
74254
  private: false,
74257
74255
  license: "MIT",
74258
74256
  repository: {
@@ -74263,13 +74261,21 @@ var package_default = {
74263
74261
  bugs: {
74264
74262
  url: "https://github.com/vericontext/vibeframe/issues"
74265
74263
  },
74264
+ homepage: "https://vibeframe.ai",
74266
74265
  keywords: [
74267
74266
  "vibeframe",
74268
74267
  "cli",
74269
- "video-editing",
74270
- "ai",
74271
- "ffmpeg",
74272
- "commander"
74268
+ "ai-video",
74269
+ "video-generation",
74270
+ "text-to-video",
74271
+ "image-to-video",
74272
+ "seedance",
74273
+ "runway",
74274
+ "veo",
74275
+ "kling",
74276
+ "ai-agent",
74277
+ "mcp",
74278
+ "ffmpeg"
74273
74279
  ],
74274
74280
  type: "module",
74275
74281
  bin: {
@@ -81600,7 +81606,7 @@ function parseScope(raw) {
81600
81606
  }
81601
81607
  return v;
81602
81608
  }
81603
- var setupCommand = new Command("setup").description("Configure VibeFrame (LLM provider, API keys)").option("--reset", "Reset configuration to defaults").option("--full", "Run full setup with all optional providers").option("--show", "Show current configuration (for debugging)").option(
81609
+ var setupCommand = new Command("setup").description("Configure VibeFrame (video/image provider keys, LLM provider)").option("--reset", "Reset configuration to defaults").option("--full", "Run full setup with all optional providers").option("--show", "Show current configuration (for debugging)").option(
81604
81610
  "-v, --verbose",
81605
81611
  "With --show: include unset providers + Resolution order + Defaults block"
81606
81612
  ).option("--claude-code", "Show Claude Code integration guide").option("-y, --yes", "Non-interactive: write config without prompting (CI / devcontainer)").option(
@@ -81620,8 +81626,8 @@ Non-interactive examples (no TTY required):
81620
81626
  vibe setup --scope project --yes --import-env Project-only setup (./.vibeframe/config.yaml)
81621
81627
 
81622
81628
  Scopes:
81623
- user (default) ~/.vibeframe/config.yaml \u2014 shared across every project
81624
- project ./.vibeframe/config.yaml \u2014 gitignored, isolates keys/defaults to this directory
81629
+ user (default) ~/.vibeframe/config.yaml - shared across every project
81630
+ project ./.vibeframe/config.yaml - gitignored, isolates keys/defaults to this directory
81625
81631
  When a project config exists at the cwd, it is used and the user file is ignored.
81626
81632
 
81627
81633
  Exit codes (non-interactive):
@@ -81828,7 +81834,7 @@ var AI_FEATURES = [
81828
81834
  {
81829
81835
  label: "Audio",
81830
81836
  desc: "TTS, SFX, music, voice clone",
81831
- defaultProvider: "ElevenLabs (paid, premium quality) \u2014 falls back to local Kokoro when no key (free, since v0.54)",
81837
+ defaultProvider: "ElevenLabs (paid, premium quality) - falls back to local Kokoro when no key (free, since v0.54)",
81832
81838
  alsoAvailable: "Replicate MusicGen (music only)",
81833
81839
  keyHint: "0-1 key",
81834
81840
  keys: [
@@ -82134,7 +82140,7 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
82134
82140
  const displayPath2 = scope === "user" ? userStatus?.source === "legacy" ? userStatus.configPath : USER_CONFIG_PATH : getConfigPath(scope);
82135
82141
  const cfgPath = displayPath2.replace(homedir6(), "~");
82136
82142
  const scopeNote = scope === "project" ? "applies to this project only \xB7 user config is ignored while this file exists \xB7 add .vibeframe/ to .gitignore" : "applies to every project for this user";
82137
- console.log(source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` \u2014 ${scope} scope`));
82143
+ console.log(source_default.bold.magenta("VibeFrame Setup") + source_default.bold(` - ${scope} scope`));
82138
82144
  console.log(source_default.dim(`${cfgPath} \xB7 ${scopeNote}`));
82139
82145
  if (userStatus?.source === "legacy") {
82140
82146
  console.log(
@@ -82165,14 +82171,14 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
82165
82171
  console.log(source_default.bold("What would you like to do?"));
82166
82172
  console.log();
82167
82173
  const topLabels = [
82174
+ `Generate AI video ${source_default.dim("(build from a storyboard, remix highlights, auto-shorts)")}`,
82175
+ `AI features ${source_default.dim("(pick what you need - images, videos, audio, editing)")}`,
82168
82176
  `Edit videos offline ${source_default.dim("(silence-cut, fade, noise-reduce, detect)")} ${source_default.green("no API keys")}`,
82169
- `AI features ${source_default.dim("(pick what you need \u2014 images, videos, audio, editing)")}`,
82170
- `Full AI pipeline ${source_default.dim("(build, remix highlights, auto-shorts)")}`,
82171
- `Full provider list ${source_default.dim("(every supported provider, one by one \u2014 same as --full)")}`
82177
+ `Full provider list ${source_default.dim("(every supported provider, one by one - same as --full)")}`
82172
82178
  ];
82173
82179
  const topIndex = await promptSelect(source_default.cyan(" Select [1-4]: "), topLabels, 0);
82174
82180
  console.log();
82175
- if (topIndex === 0) {
82181
+ if (topIndex === 2) {
82176
82182
  await saveConfig(config2, { scope });
82177
82183
  await completeOrContinue(config2, "vibe edit silence-cut video.mp4 -o clean.mp4", [], scope);
82178
82184
  return;
@@ -82183,7 +82189,7 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
82183
82189
  await completeOrContinue(config2, "vibe doctor --test-keys", [], scope);
82184
82190
  return;
82185
82191
  }
82186
- if (topIndex === 2) {
82192
+ if (topIndex === 0) {
82187
82193
  config2.llm.provider = "claude";
82188
82194
  const pipelineKeys = [
82189
82195
  {
@@ -82191,7 +82197,7 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
82191
82197
  envVar: "ANTHROPIC_API_KEY",
82192
82198
  name: "Anthropic",
82193
82199
  url: "https://console.anthropic.com/settings/keys",
82194
- what: "Claude \u2014 storyboard generation + reasoning"
82200
+ what: "Claude - storyboard generation + reasoning"
82195
82201
  },
82196
82202
  {
82197
82203
  configKey: "openai",
@@ -82205,7 +82211,7 @@ async function runSetupWizard(fullSetup = false, scope = "user") {
82205
82211
  envVar: "FAL_API_KEY",
82206
82212
  name: "fal.ai",
82207
82213
  url: "https://fal.ai/dashboard/keys",
82208
- what: "Seedance 2.0 \u2014 video generation, default since v0.57"
82214
+ what: "Seedance 2.0 - video generation, default since v0.57"
82209
82215
  },
82210
82216
  {
82211
82217
  configKey: "elevenlabs",
@@ -82517,7 +82523,7 @@ async function runCustomSetup(config2, scope = "user", opts = {}) {
82517
82523
  xai: "Grok 4.1 Fast, 2M context, great for tool calling",
82518
82524
  openrouter: "300+ models via one API key (Claude, GPT, Gemini, Llama, etc.)",
82519
82525
  evolink: "GPT-5, Claude, Gemini, DeepSeek & more via one key",
82520
- ollama: "Free, local, no API key \u2014 offline capable (default: llama3.2)"
82526
+ ollama: "Free, local, no API key - offline capable (default: llama3.2)"
82521
82527
  };
82522
82528
  const providerLabels = providers.map((p) => {
82523
82529
  const rec = p === "claude" ? source_default.dim(" (recommended)") : "";
@@ -82638,19 +82644,19 @@ async function showComplete(config2, defaultTryCommand, features = [], scope = "
82638
82644
  console.log();
82639
82645
  console.log(
82640
82646
  source_default.dim(
82641
- ` Detected ${primary.label} \u2014 \`vibe init\` will scaffold ${primary.projectFiles.join(" + ")} in your project.`
82647
+ ` Detected ${primary.label} - \`vibe init\` will scaffold ${primary.projectFiles.join(" + ")} in your project.`
82642
82648
  )
82643
82649
  );
82644
82650
  console.log(
82645
82651
  source_default.dim(
82646
- ` Scene composer will auto-dispatch to ${primary.label} (${source_default.bold("--mode agent")}). Run \`vibe init my-promo\` to scaffold a video project + install local composition rules.`
82652
+ ` ${primary.label} authors each scene during \`vibe build\`. Run \`vibe init my-promo\` to scaffold a video project.`
82647
82653
  )
82648
82654
  );
82649
82655
  } else {
82650
82656
  console.log();
82651
82657
  console.log(
82652
82658
  source_default.dim(
82653
- ` No agent host detected \u2014 \`vibe build\` will use the internal LLM composer (${source_default.bold("--mode batch")}).`
82659
+ ` No agent host detected - scenes are authored by a coding agent during \`vibe build\`; pass ${source_default.bold("--composer template")} for the deterministic no-model fallback.`
82654
82660
  )
82655
82661
  );
82656
82662
  }
@@ -82661,7 +82667,7 @@ async function setupClaudeCode() {
82661
82667
  console.log(source_default.bold.cyan("Claude Code Integration"));
82662
82668
  console.log(source_default.dim("\u2500".repeat(40)));
82663
82669
  console.log();
82664
- console.log(" VibeFrame CLI is self-discoverable \u2014 no extra setup needed.");
82670
+ console.log(" VibeFrame CLI is self-discoverable - no extra setup needed.");
82665
82671
  console.log(" Claude Code can use these commands to understand the CLI:");
82666
82672
  console.log();
82667
82673
  console.log(` ${source_default.green("vibe --help")} All command groups`);
@@ -82766,7 +82772,7 @@ async function showConfig(opts = { verbose: false }) {
82766
82772
  if (!verbose && unsetCount > 0) {
82767
82773
  console.log(
82768
82774
  source_default.dim(
82769
- ` (${unsetCount} provider${unsetCount === 1 ? "" : "s"} unset \u2014 run with --verbose to list)`
82775
+ ` (${unsetCount} provider${unsetCount === 1 ? "" : "s"} unset - run with --verbose to list)`
82770
82776
  )
82771
82777
  );
82772
82778
  }
@@ -82837,7 +82843,7 @@ providers:
82837
82843
  # ${product} - Storyboard
82838
82844
 
82839
82845
  Pacing: keep beats 6-15 seconds. Longer beats render as static, overstuffed
82840
- scenes \u2014 split them instead.
82846
+ scenes - split them instead.
82841
82847
 
82842
82848
  Brief: ${brief}
82843
82849
 
@@ -83351,26 +83357,27 @@ function cmdQuote(value) {
83351
83357
  // src/commands/_shared/init-templates.ts
83352
83358
  var AGENTS_MD = `# AGENTS.md
83353
83359
 
83354
- This project uses [VibeFrame](https://github.com/vericontext/vibeframe) \u2014
83355
- a CLI for AI-powered video editing. The \`vibe\` command provides 80+
83356
- subcommands for video generation, editing, analysis, and pipeline
83357
- orchestration. Cost tiers below \u2014 **always confirm with the user before
83358
- running High / Very High tier commands**.
83360
+ This project uses [VibeFrame](https://github.com/vericontext/vibeframe) -
83361
+ a CLI for AI video generation on the user's own provider keys (Seedance,
83362
+ Runway, Veo, Kling), behind dry runs and a hard \`--max-cost\` ceiling.
83363
+ The \`vibe\` command provides 80+ subcommands for video generation,
83364
+ editing, and analysis. Cost tiers below - **always confirm with the user
83365
+ before running High / Very High tier commands**.
83359
83366
 
83360
83367
  ## Agent host coverage
83361
83368
 
83362
83369
  VibeFrame's CLI works with any bash-capable AI coding agent. Six host
83363
83370
  families have first-class auto-detection and scaffolds today:
83364
83371
 
83365
- - **Claude Code** \u2014 \`CLAUDE.md\` (this file's import wrapper) +
83372
+ - **Claude Code** - \`CLAUDE.md\` (this file's import wrapper) +
83366
83373
  \`AGENTS.md\` + \`/vibe-*\` slash commands.
83367
- - **OpenAI Codex** \u2014 reads \`AGENTS.md\` natively (agents.md spec).
83368
- - **Cursor** \u2014 reads \`AGENTS.md\` plus \`.cursor/rules/\` for project
83374
+ - **OpenAI Codex** - reads \`AGENTS.md\` natively (agents.md spec).
83375
+ - **Cursor** - reads \`AGENTS.md\` plus \`.cursor/rules/\` for project
83369
83376
  rules; supports MCP via \`.cursor/mcp.json\`.
83370
- - **Aider** \u2014 reads \`AGENTS.md\` (binary-only detection by VibeFrame).
83371
- - **Gemini CLI** \u2014 primary context file is \`GEMINI.md\`; also reads
83377
+ - **Aider** - reads \`AGENTS.md\` (binary-only detection by VibeFrame).
83378
+ - **Gemini CLI** - primary context file is \`GEMINI.md\`; also reads
83372
83379
  \`AGENTS.md\` if present.
83373
- - **OpenCode** \u2014 reads \`AGENTS.md\` (officially supported per
83380
+ - **OpenCode** - reads \`AGENTS.md\` (officially supported per
83374
83381
  \`opencode.ai/docs/rules\`); supports MCP via \`.opencode/mcp.json\`.
83375
83382
 
83376
83383
  Run \`vibe doctor\` to see which host(s) the CLI detects in your
@@ -83380,7 +83387,7 @@ fallback.
83380
83387
 
83381
83388
  ## Self-discovery
83382
83389
 
83383
- Don't memorise the command surface \u2014 read it from the CLI:
83390
+ Don't memorise the command surface - read it from the CLI:
83384
83391
 
83385
83392
  \`\`\`bash
83386
83393
  vibe --help # command groups overview
@@ -83400,10 +83407,10 @@ vibe guide pipeline # step-by-step authoring guide (pipeline)
83400
83407
  Routing the user's request correctly is the most important judgement call
83401
83408
  you'll make. Do not force everything into a scene project.
83402
83409
 
83403
- **ASSET \u2014 default for any single-asset request OR ambiguous prompt.**
83410
+ **ASSET - default for any single-asset request OR ambiguous prompt.**
83404
83411
  If the user asks for a single image, single video clip, sound effect, music
83405
- bed, or narration file \u2014 **OR pastes a visual/audio brief without explicit
83406
- storyboard / scene / multi-scene language** \u2014 treat it as ASSET. Use
83412
+ bed, or narration file - **OR pastes a visual/audio brief without explicit
83413
+ storyboard / scene / multi-scene language** - treat it as ASSET. Use
83407
83414
  \`vibe generate ...\` directly. Do **not** edit \`DESIGN.md\`,
83408
83415
  \`STORYBOARD.md\`, run \`vibe scene ...\`, or auto-load the hyperframes
83409
83416
  skill until BUILD intent is explicit. The visual-identity hard-gate
@@ -83420,13 +83427,13 @@ If genuinely uncertain, ask one short question: *"single asset or
83420
83427
  multi-scene project?"* before authoring DESIGN.md or loading the
83421
83428
  hyperframes skill.
83422
83429
 
83423
- **BUILD \u2014 create new video from text intent.**
83430
+ **BUILD - create new video from text intent.**
83424
83431
  Use \`vibe build\` with a STORYBOARD.md + DESIGN.md. The
83425
83432
  skills-driven pipeline (v0.60+) dispatches narration TTS + backdrop
83426
83433
  image-gen per beat, composes scene HTML via the bundled composition rules
83427
83434
  bundle, then renders to MP4. Idempotent re-runs reuse cached assets.
83428
83435
 
83429
- **REMIX \u2014 transform existing video / audio.**
83436
+ **REMIX - transform existing video / audio.**
83430
83437
  Use \`vibe remix\`, \`vibe edit\`, or \`vibe audio\`. One-shot,
83431
83438
  batch-oriented operations on a file the user already has on disk.
83432
83439
  \`vibe edit text-overlay\` is the free deterministic path for simple static
@@ -83486,7 +83493,7 @@ starting from a media file and wants it transformed, it's REMIX.
83486
83493
  When you run vibe commands programmatically:
83487
83494
 
83488
83495
  1. **Always \`--json\`** for structured output you can parse without regex
83489
- 2. **Always \`--dry-run\` first** for any High/Very-High tier command \u2014 it returns
83496
+ 2. **Always \`--dry-run\` first** for any High/Very-High tier command - it returns
83490
83497
  the cost estimate without spending API budget
83491
83498
  3. **Use \`vibe schema <command>\`** to discover parameters; do not guess flags
83492
83499
  4. **Pass complex options via \`--stdin\`**:
@@ -83528,7 +83535,7 @@ vibe host doctor all --json # verify readiness
83528
83535
 
83529
83536
  Default setup is snippet-only; use \`--write\` when you want VibeFrame to merge
83530
83537
  the generated config. Keep provider keys in \`.vibeframe/config.yaml\`, user
83531
- config, or env files \u2014 not in app host config.
83538
+ config, or env files - not in app host config.
83532
83539
 
83533
83540
  ## Host agent loop
83534
83541
 
@@ -83539,7 +83546,7 @@ budget caps, \`build-report.json\`, \`review-report.json\`, \`nextActions\`,
83539
83546
  \`safeToAutoRun\`, \`requiresConfirmation\`, \`fixOwner\`, deterministic repair,
83540
83547
  and render inspection for the host agent to decide what to do next.
83541
83548
 
83542
- Copy-paste agent prompt (Codex) \u2014 a plain prompt, not a built-in command:
83549
+ Copy-paste agent prompt (Codex) - a plain prompt, not a built-in command:
83543
83550
 
83544
83551
  \`\`\`text
83545
83552
  Build this VibeFrame project into renders/final.mp4. Use --json for every
@@ -83556,7 +83563,7 @@ remaining host-agent issue is fixed, accepted with rationale, or reported as
83556
83563
  blocked.
83557
83564
  \`\`\`
83558
83565
 
83559
- Copy-paste agent prompt (Claude Code) \u2014 a plain prompt, not a built-in command:
83566
+ Copy-paste agent prompt (Claude Code) - a plain prompt, not a built-in command:
83560
83567
 
83561
83568
  \`\`\`text
83562
83569
  Finish this VibeFrame render using your host's agent loop as the outer
@@ -83571,7 +83578,7 @@ no unresolved unacknowledged host-agent issues.
83571
83578
 
83572
83579
  ### Composition rules (scene HTML)
83573
83580
 
83574
- Composition rules live in the **Hyperframes skill** \u2014 framework rules, motion
83581
+ Composition rules live in the **Hyperframes skill** - framework rules, motion
83575
83582
  principles, type system, and visual-identity hard-gate. **Load that skill
83576
83583
  before authoring any scene composition HTML under \`compositions/\`.** The same
83577
83584
  rules govern \`vibe scene lint\`, so your authored HTML and the linter stay in
@@ -83580,14 +83587,14 @@ agreement.
83580
83587
  Where the skill comes from depends on your setup:
83581
83588
 
83582
83589
  - If the \`hyperframes\` skill is installed globally (e.g. Claude Code), your
83583
- agent already has it \u2014 \`vibe init\` does **not** copy it into the project.
83584
- - Otherwise \`vibe init\` writes a local copy: universal \`SKILL.md\` (with
83585
- \`references/*.md\`) at the project root, plus host layouts
83586
- (\`.claude/skills/hyperframes/\`, \`.cursor/rules/hyperframes.mdc\`).
83590
+ agent already has it and nothing else is needed.
83591
+ - Otherwise install it into this project with \`vibe scene install-skill\`,
83592
+ which runs upstream's own installer and writes
83593
+ \`.agents/skills/hyperframes/\`.
83587
83594
 
83588
- To get editable per-project copies on demand, run
83589
- \`vibe scene install-skill [--host all]\` (these copies are gitignored by
83590
- default \u2014 see \`.gitignore\`).
83595
+ \`vibe init\` never copies the rules in. They come from upstream so they stay
83596
+ current, and fetching them is a network call the scaffold does not make on
83597
+ your behalf. \`vibe doctor\` reports whether your agent can read them.
83591
83598
 
83592
83599
  For render-stable text, do not apply continuous \`scale\`, \`x\`, \`y\`,
83593
83600
  \`filter\`, or other transform tweens to \`.scene-content\` or any ancestor
@@ -83595,22 +83602,12 @@ containing live text/cards. Put ambient zoom/parallax on background or media
83595
83602
  layers only; text should enter briefly and then hold still at its final CSS
83596
83603
  position.
83597
83604
 
83598
- ### Scene composer (batch / non-agent fallback)
83605
+ ### Scene composer (non-agent fallback)
83599
83606
 
83600
- When you don't want to author HTML yourself, \`vibe build --mode batch\` runs an
83601
- LLM internally with the same skill bundle. It auto-picks a provider based
83602
- on available keys (\`claude > gemini > openai\`) \u2014 pass \`--composer <name>\`
83603
- to force one:
83604
-
83605
- | Provider | Env var | Spike notes (v0.70) |
83606
- |---|---|---|
83607
- | Claude (default) | \`ANTHROPIC_API_KEY\` | ~9 s/beat. Fastest, validated baseline. |
83608
- | Gemini | \`GOOGLE_API_KEY\` | ~20 s/beat. ~2.6\xD7 cheaper than Claude. |
83609
- | OpenAI | \`OPENAI_API_KEY\` | ~70 s/beat. gpt-5 reasoning latency \u2014 opt-in only. |
83610
-
83611
- All three pass first-shot lint at every effort tier on the \`vibeframe-promo\`
83612
- fixture. Quality on more complex storyboards may differ \u2014 fall back to
83613
- \`--composer claude\` if a non-default provider repeatedly fails lint.
83607
+ Scene HTML is authored by you, the host agent - the CLI makes no LLM call
83608
+ during \`vibe build\`. When no agent is available to author scenes, pass
83609
+ \`--composer template\` for the deterministic no-model composer
83610
+ (concat background + lower-thirds).
83614
83611
 
83615
83612
  ## Project conventions
83616
83613
 
@@ -83625,7 +83622,7 @@ var CLAUDE_MD = `@AGENTS.md
83625
83622
 
83626
83623
  # Claude Code overrides
83627
83624
 
83628
- This file imports \`AGENTS.md\` (above) \u2014 that's the canonical source.
83625
+ This file imports \`AGENTS.md\` (above) - that's the canonical source.
83629
83626
  Add anything Claude-Code-specific *below*; everything generic should
83630
83627
  stay in AGENTS.md so other agent hosts (Codex, Cursor, Aider, Gemini CLI, OpenCode) see it
83631
83628
  too.
@@ -83633,11 +83630,11 @@ too.
83633
83630
  ## Skills
83634
83631
 
83635
83632
  If you ran \`vibe init\` with Claude Code detected, the VibeFrame skill
83636
- pack is available as slash commands (consolidated to 2 in v0.62 \u2014 the
83633
+ pack is available as slash commands (consolidated to 2 in v0.62 - the
83637
83634
  overview content moved into AGENTS.md above):
83638
83635
 
83639
- - \`/vibe-pipeline\` \u2014 YAML pipeline authoring helper (Video as Code)
83640
- - \`/vibe-scene\` \u2014 per-scene HTML authoring + \`vibe build\`
83636
+ - \`/vibe-pipeline\` - YAML pipeline authoring helper (Video as Code)
83637
+ - \`/vibe-scene\` - per-scene HTML authoring + \`vibe build\`
83641
83638
 
83642
83639
  Claude-specific routing note: follow the ASSET / BUILD / REMIX decision
83643
83640
  rules in \`AGENTS.md\`. In particular, a request for one generated image or
@@ -83664,7 +83661,7 @@ var GEMINI_MD = `@AGENTS.md
83664
83661
 
83665
83662
  # Gemini CLI overrides
83666
83663
 
83667
- This project's canonical agent guidance lives in \`AGENTS.md\` \u2014 read
83664
+ This project's canonical agent guidance lives in \`AGENTS.md\` - read
83668
83665
  it first. The \`@AGENTS.md\` line above is the import marker; if
83669
83666
  Gemini CLI doesn't inline imported files in your version, open
83670
83667
  \`AGENTS.md\` directly. Both files are kept in sync by \`vibe init\`.
@@ -83681,11 +83678,11 @@ function renderEnvExample(opts = {}) {
83681
83678
  # Run \`vibe doctor\` to see what's currently detected.
83682
83679
 
83683
83680
  `;
83684
- return `# VibeFrame API keys \u2014 copy this file to \`.env\` and fill in what you need.
83681
+ return `# VibeFrame API keys - copy this file to \`.env\` and fill in what you need.
83685
83682
  # Free local fallbacks work without any keys. See README for the full list.
83686
83683
 
83687
83684
  ${fallback2}# \u2500\u2500 LLM provider / optional \`vibe agent\` fallback (pick one) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
83688
- ANTHROPIC_API_KEY= # Claude \u2014 recommended default
83685
+ ANTHROPIC_API_KEY= # Claude - recommended default
83689
83686
  OPENAI_API_KEY= # GPT-5-mini \xB7 Whisper \xB7 gpt-image-2
83690
83687
  GOOGLE_API_KEY= # Gemini \xB7 Veo
83691
83688
  XAI_API_KEY= # Grok image+video
@@ -83694,7 +83691,7 @@ OPENROUTER_API_KEY= # multiplexes any provider above
83694
83691
 
83695
83692
  # \u2500\u2500 Media providers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
83696
83693
  ELEVENLABS_API_KEY= # paid TTS / SFX / music (Kokoro is the free fallback)
83697
- FAL_API_KEY= # Seedance 2.0 \u2014 default video provider since v0.57
83694
+ FAL_API_KEY= # Seedance 2.0 - default video provider since v0.57
83698
83695
  IMGBB_API_KEY= # image hosting for Seedance/Kling image-to-video
83699
83696
  RUNWAY_API_SECRET= # Runway Gen-4.5 video
83700
83697
  KLING_API_KEY= # Kling video
@@ -83721,8 +83718,10 @@ renders/
83721
83718
  *.vibe.json
83722
83719
  .vibeframe/
83723
83720
 
83724
- # Vendored Hyperframes skill copies \u2014 regenerable via 'vibe scene install-skill'.
83725
- # Delete these lines if you eject and want to commit per-project customizations.
83721
+ # Hyperframes skill copies left by older VibeFrame versions, which vendored a
83722
+ # snapshot of upstream's rules. Nothing writes these now - upstream's installer
83723
+ # owns the rules and puts them under .agents/skills/hyperframes/, which is
83724
+ # yours to commit or ignore. These lines only keep pre-existing copies quiet.
83726
83725
  /SKILL.md
83727
83726
  /references/
83728
83727
  /.claude/skills/hyperframes/
@@ -85144,7 +85143,7 @@ function printNeedsAuthor(result) {
85144
85143
  console.log(" Then run: vibe build");
85145
85144
  console.log(
85146
85145
  source_default.dim(
85147
- " Use `vibe build --mode batch` when you want the CLI to call an LLM composer instead."
85146
+ " Use `vibe build --composer template` for the deterministic no-model composer instead."
85148
85147
  )
85149
85148
  );
85150
85149
  }
@@ -85772,6 +85771,7 @@ import { existsSync as existsSync53 } from "node:fs";
85772
85771
  import { resolve as resolve73 } from "node:path";
85773
85772
  init_composer_resolve();
85774
85773
  init_cost_tier();
85774
+ init_install_skill();
85775
85775
  init_output();
85776
85776
  var COMMAND_KEY_MAP = getCommandKeyMap();
85777
85777
  var FREE_COMMANDS = [
@@ -85798,7 +85798,7 @@ var doctorCommand = new Command("doctor").description("Check system health and a
85798
85798
  `
85799
85799
  Examples:
85800
85800
  $ vibe doctor Compact health summary (issues + Ready %)
85801
- $ vibe doctor --verbose Full report \u2014 all providers, composer, free commands
85801
+ $ vibe doctor --verbose Full report - all providers, composer, free commands
85802
85802
  $ vibe doctor --test-keys Validate each configured key against its provider
85803
85803
  $ vibe doctor --json Machine-readable output
85804
85804
  `
@@ -85979,7 +85979,8 @@ async function runDiagnostics() {
85979
85979
  if (!(err instanceof ComposerResolveError)) throw err;
85980
85980
  }
85981
85981
  const sceneProjectInCwd = existsSync53(resolve73(cwd, "STORYBOARD.md"));
85982
- const skillInstalled = existsSync53(resolve73(cwd, "SKILL.md"));
85982
+ const skillInstalled = hyperframesSkillAvailable(cwd);
85983
+ const skillPath = resolveSkillReference(cwd);
85983
85984
  return {
85984
85985
  system: {
85985
85986
  node: { version: nodeVersion, ok: true },
@@ -86016,7 +86017,8 @@ async function runDiagnostics() {
86016
86017
  composer: composerResolved,
86017
86018
  composerEnvVar: composerEnv,
86018
86019
  sceneProjectInCwd,
86019
- skillInstalled
86020
+ skillInstalled,
86021
+ skillPath
86020
86022
  },
86021
86023
  ...configError ? { configError } : {}
86022
86024
  },
@@ -86138,26 +86140,25 @@ function printReport(results, opts = { verbose: false }) {
86138
86140
  );
86139
86141
  if (sc.composer) {
86140
86142
  console.log(
86141
- ` Revise LLM ${source_default.green("OK")} ${source_default.dim(`${composerLabel(sc.composer)} (${sc.composerEnvVar}) \u2014 powers 'vibe storyboard revise'`)}`
86143
+ ` Revise LLM ${source_default.green("OK")} ${source_default.dim(`${composerLabel(sc.composer)} (${sc.composerEnvVar}) - powers 'vibe storyboard revise'`)}`
86142
86144
  );
86143
86145
  } else {
86144
86146
  console.log(
86145
- ` Revise LLM ${source_default.yellow("--")} ${source_default.dim("no ANTHROPIC_API_KEY / GOOGLE_API_KEY / OPENAI_API_KEY \u2014 'vibe storyboard revise' unavailable")}`
86147
+ ` Revise LLM ${source_default.yellow("--")} ${source_default.dim("no ANTHROPIC_API_KEY / GOOGLE_API_KEY / OPENAI_API_KEY - 'vibe storyboard revise' unavailable")}`
86146
86148
  );
86147
86149
  }
86148
86150
  if (sc.sceneProjectInCwd) {
86149
86151
  if (sc.skillInstalled) {
86150
- console.log(
86151
- ` SKILL.md ${source_default.green("OK")} ${source_default.dim("installed in this scene project")}`
86152
- );
86152
+ const where = sc.skillPath ?? "installed globally for your agent";
86153
+ console.log(` HF rules ${source_default.green("OK")} ${source_default.dim(where)}`);
86153
86154
  } else {
86154
86155
  console.log(
86155
- ` SKILL.md ${source_default.yellow("MISSING")} ${source_default.dim("Run: vibe scene install-skill")}`
86156
+ ` HF rules ${source_default.yellow("MISSING")} ${source_default.dim(`Run: vibe scene install-skill`)}`
86156
86157
  );
86157
86158
  }
86158
86159
  } else {
86159
86160
  console.log(
86160
- ` SKILL.md ${source_default.dim("(no STORYBOARD.md in cwd \u2014 skill is per-scene-project)")}`
86161
+ ` HF rules ${source_default.dim("(no STORYBOARD.md in cwd - rules are per-scene-project)")}`
86161
86162
  );
86162
86163
  }
86163
86164
  }
@@ -86281,7 +86282,7 @@ async function runLiveKeyTests(results) {
86281
86282
  );
86282
86283
  const configured = Object.entries(results.providers).filter(([, info]) => info.configured);
86283
86284
  if (configured.length === 0) {
86284
- console.log(source_default.dim(" No keys configured \u2014 nothing to test."));
86285
+ console.log(source_default.dim(" No keys configured - nothing to test."));
86285
86286
  return;
86286
86287
  }
86287
86288
  const { testKey: testKey2 } = await Promise.resolve().then(() => (init_key_live_test(), key_live_test_exports));
@@ -86317,7 +86318,7 @@ function pickNextStep(results, hasMissingProviders) {
86317
86318
  }
86318
86319
  const sc = results.scope.sceneComposer;
86319
86320
  if (sc.sceneProjectInCwd && !sc.skillInstalled) {
86320
- return "Next: run 'vibe scene install-skill' so your host agent can read the Hyperframes rules from this project.";
86321
+ return `Next: run 'vibe scene install-skill' (or '${HYPERFRAMES_SKILL_INSTALL_COMMAND}') so your host agent can read the Hyperframes composition rules.`;
86321
86322
  }
86322
86323
  if (hasMissingProviders) {
86323
86324
  return "Run 'vibe setup' to add more provider keys.";
@@ -87235,7 +87236,7 @@ async function registerAllTools(registry) {
87235
87236
  // src/agent/prompts/system.ts
87236
87237
  function getSystemPrompt(context) {
87237
87238
  const projectInfo = context.projectPath ? `Current project: ${context.projectPath}` : "No timeline loaded. Use timeline_create or project_create to start.";
87238
- return `You are VibeFrame, an AI video editing assistant. You help users edit videos through natural language commands.
87239
+ return `You are VibeFrame, an AI video generation and editing assistant. You help users generate video from frontier models on their own provider keys - behind dry runs and cost caps - and edit the results, through natural language commands.
87239
87240
 
87240
87241
  ## Current Context
87241
87242
  - Working directory: ${context.workingDirectory}
@@ -87243,10 +87244,10 @@ function getSystemPrompt(context) {
87243
87244
 
87244
87245
  ## Your Capabilities
87245
87246
  You have access to tools for:
87246
- 1. **Timeline Management**: Create, open, save, and modify low-level timeline JSON state
87247
- 2. **Timeline Editing**: Add sources, create clips, add tracks, apply effects, trim, split, move, and delete clips
87248
- 3. **Media Analysis**: Detect scenes, silence, and beats in media files
87249
- 4. **AI Generation**: Generate images, videos, TTS, sound effects, music, and more
87247
+ 1. **AI Generation**: Generate images, videos, TTS, sound effects, music, and more on the user's provider keys
87248
+ 2. **Media Analysis**: Detect scenes, silence, and beats in media files
87249
+ 3. **Timeline Management**: Create, open, save, and modify low-level timeline JSON state
87250
+ 4. **Timeline Editing**: Add sources, create clips, add tracks, apply effects, trim, split, move, and delete clips
87250
87251
  5. **Export**: Export projects to video files
87251
87252
 
87252
87253
  ## Guidelines
@@ -88202,20 +88203,24 @@ async function markBannerShown() {
88202
88203
  function showFirstRunBanner() {
88203
88204
  console.log();
88204
88205
  console.log(source_default.cyan.bold(" Welcome to VibeFrame!"));
88205
- console.log(source_default.dim(" AI-native video editing from your terminal."));
88206
+ console.log(source_default.dim(" Frontier video generation for your coding agent. Your keys, your ceiling."));
88206
88207
  console.log();
88207
88208
  console.log(
88208
- ` ${source_default.white("1.")} ${source_default.green("vibe setup")} Configure API keys ${source_default.dim("(1 min)")}`
88209
+ ` ${source_default.white("1.")} ${source_default.green('vibe init demo --from "30s video"')} Scaffold a project ${source_default.dim("(no key needed)")}`
88210
+ );
88211
+ console.log(
88212
+ ` ${source_default.white("2.")} ${source_default.green("vibe build demo --dry-run")} Price it before any spend`
88213
+ );
88214
+ console.log(
88215
+ ` ${source_default.white("3.")} ${source_default.green("vibe setup")} Add provider keys when a step generates`
88209
88216
  );
88210
- console.log(` ${source_default.white("2.")} ${source_default.green("vibe doctor")} Check system health`);
88211
- console.log(` ${source_default.white("3.")} ${source_default.green("vibe --help")} See all commands`);
88212
88217
  console.log();
88213
88218
  console.log(source_default.dim(" Try without keys:"));
88214
88219
  console.log(
88215
- ` ${source_default.green("vibe demo")} Run sample edits on a test video`
88220
+ ` ${source_default.green("vibe build demo --dry-run --max-cost 5")} See the cost gate refuse an over-budget build`
88216
88221
  );
88222
+ console.log(source_default.dim(" vibe demo Run sample edits on a test video"));
88217
88223
  console.log(source_default.dim(" vibe edit silence-cut video.mp4 -o clean.mp4"));
88218
- console.log(source_default.dim(" vibe detect scenes video.mp4"));
88219
88224
  console.log();
88220
88225
  }
88221
88226
 
@@ -88279,7 +88284,7 @@ async function readStdin() {
88279
88284
  return Buffer.concat(chunks).toString("utf-8").trim();
88280
88285
  }
88281
88286
  var program2 = new Command();
88282
- program2.name("vibe").showSuggestionAfterError(true).description("VibeFrame CLI - video projects, AI media generation, and workflow automation").version(package_default.version).option("--json", "Output in JSON format").option("-q, --quiet", "Output only the primary result value (path, URL, or ID)").option("--fields <fields>", "Limit JSON output to specific fields (comma-separated)").option("--stdin", "Read options from stdin as JSON (for agent/script use)").option("--describe", "Show JSON schema for the command and exit (no execution)").exitOverride().configureOutput({
88287
+ program2.name("vibe").showSuggestionAfterError(true).description("VibeFrame CLI - AI video generation on your own provider keys, behind dry runs and a hard cost cap").version(package_default.version).option("--json", "Output in JSON format").option("-q, --quiet", "Output only the primary result value (path, URL, or ID)").option("--fields <fields>", "Limit JSON output to specific fields (comma-separated)").option("--stdin", "Read options from stdin as JSON (for agent/script use)").option("--describe", "Show JSON schema for the command and exit (no execution)").exitOverride().configureOutput({
88283
88288
  outputError: (str, write2) => {
88284
88289
  if (process.env.VIBE_JSON_OUTPUT === "1" || process.argv.includes("--json")) {
88285
88290
  const err = {