reelforge2 1.0.0 → 1.0.1

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.
@@ -19,9 +19,9 @@ export function registerAudio(program) {
19
19
  .addHelpText("after", [
20
20
  "",
21
21
  "Examples:",
22
- " rf audio transcribe -f ./narration.mp3",
23
- " rf audio transcribe --url https://example.com/clip.mp3 --language zh",
24
- " rf audio transcribe -f ./voice.wav --json | jq '.words[:5]'",
22
+ " rf2 audio transcribe -f ./narration.mp3",
23
+ " rf2 audio transcribe --url https://example.com/clip.mp3 --language zh",
24
+ " rf2 audio transcribe -f ./voice.wav --json | jq '.words[:5]'",
25
25
  ].join("\n"))
26
26
  .action(async (opts) => {
27
27
  if (!opts.file && !opts.url) {
@@ -22,9 +22,9 @@ export function registerContent(program) {
22
22
  " fixed --script @file or text LLM only segments + writes image prompts; text unchanged verbatim",
23
23
  "",
24
24
  "Examples:",
25
- " rf content scene-plan -t '深夜便利店' -d 60 -p slow",
26
- " rf content scene-plan --script @./my-script.txt -p fast",
27
- " rf content scene-plan -t '雨天的玻璃窗' --json | jq .scenes",
25
+ " rf2 content scene-plan -t '深夜便利店' -d 60 -p slow",
26
+ " rf2 content scene-plan --script @./my-script.txt -p fast",
27
+ " rf2 content scene-plan -t '雨天的玻璃窗' --json | jq .scenes",
28
28
  ].join("\n"))
29
29
  .action(async (opts) => {
30
30
  const hasTopic = typeof opts.topic === "string" && opts.topic.length > 0;
@@ -346,7 +346,7 @@ export function registerCreate(program) {
346
346
  .option("--brand-position <pos>", "where to render brand chrome: top-left | top-right | bottom-left | bottom-right")
347
347
  .option("--brand-color <css>", "brand text color, e.g. '#ffffff' (default)")
348
348
  // --- Audio (TTS) ---
349
- .option("--voice-id <id>", "RelayX TTS voice id (default 专业解说); see `rf tts voices`")
349
+ .option("--voice-id <id>", "RelayX TTS voice id (default 专业解说); see `rf2 tts voices`")
350
350
  .option("--tts-speed <n>", "speech speed 0.5..2 (default 1.0). Only honored by Edge-TTS backends — vox/index-tts-2 (the default) ignores it.", parseFloat)
351
351
  // --- Service overrides ---
352
352
  .option("--llm-model <id>", "override the LLM model used for scene-plan")
@@ -366,7 +366,7 @@ export function registerCreate(program) {
366
366
  .option("--no-download", "do not save the video locally — just print JSON with video_url")
367
367
  .option("--poll-ms <ms>", "poll interval while waiting", (v) => parseInt(v, 10), 1500)
368
368
  .option("--timeout-ms <ms>", "max wait time before aborting (default unlimited)", (v) => parseInt(v, 10))
369
- .option("--preview-only", "skip the MP4 render — build the HyperFrames composition + open a browser preview URL. Render later via `rf render <task-id>`. Fastest iteration loop.")
369
+ .option("--preview-only", "skip the MP4 render — build the HyperFrames composition + open a browser preview URL. Render later via `rf2 render <task-id>`. Fastest iteration loop.")
370
370
  .option("--no-open", "do not auto-open the preview URL in the system browser (preview mode only)")
371
371
  .addHelpText("after", [
372
372
  "",
@@ -418,7 +418,7 @@ export function registerCreate(program) {
418
418
  " Build the HyperFrames composition, skip the MP4 render. The CLI prints",
419
419
  " preview URLs (a full studio-like page + a bare-player page) and opens",
420
420
  " the studio in your browser. Iterate visually first; render to MP4 later",
421
- " with `rf render <task-id>` — much faster feedback loop than waiting",
421
+ " with `rf2 render <task-id>` — much faster feedback loop than waiting",
422
422
  " 60-90s for the MP4 on every tweak.",
423
423
  "",
424
424
  "Image style presets (--style <preset>) — quick shortcut for --prompt-prefix:",
@@ -434,46 +434,46 @@ export function registerCreate(program) {
434
434
  "",
435
435
  "Examples (`rf` is the short alias):",
436
436
  " # Minimum — AI writes a 45s script",
437
- ' rf create "为什么我们还没找到外星文明?"',
437
+ ' rf2 create "为什么我们还没找到外星文明?"',
438
438
  "",
439
439
  " # 60-second video with slow visual pace",
440
- ' rf create "..." -d 60 -p slow',
440
+ ' rf2 create "..." -d 60 -p slow',
441
441
  "",
442
442
  " # Your own script, you decide the wording",
443
- " rf create --script @./script.txt",
444
- ' rf create --script "整段文案文本..."',
443
+ " rf2 create --script @./script.txt",
444
+ ' rf2 create --script "整段文案文本..."',
445
445
  "",
446
446
  " # Pick a built-in image style preset",
447
- ' rf create "..." --style cinematic',
447
+ ' rf2 create "..." --style cinematic',
448
448
  "",
449
449
  " # Cross-scene character consistency (auto-switches image model)",
450
- ' rf create "主角小女孩的一天" --character-ref ./hero.png',
451
- ' rf create "..." --character-ref https://example.com/hero.png',
450
+ ' rf2 create "主角小女孩的一天" --character-ref ./hero.png',
451
+ ' rf2 create "..." --character-ref https://example.com/hero.png',
452
452
  "",
453
453
  " # Motion + subtitle style combos",
454
- ' rf create "..." --motion max --subtitle-style stroke # 抖音网红风',
455
- ' rf create "..." --motion lite --subtitle-style cinema # 文艺纪录片',
456
- ' rf create "..." --motion off # PPT 模式(旧行为)',
454
+ ' rf2 create "..." --motion max --subtitle-style stroke # 抖音网红风',
455
+ ' rf2 create "..." --motion lite --subtitle-style cinema # 文艺纪录片',
456
+ ' rf2 create "..." --motion off # PPT 模式(旧行为)',
457
457
  "",
458
458
  " # Layout combos",
459
- ' rf create "财经日报" --layout blur-bg # 小红书 / 抖音 风(图表内容首选)',
460
- ' rf create "纪录片片段" --layout letterbox --motion max # 电影感',
461
- ' rf create "..." --layout letterbox --layout-matte-color "#1a1a1a" # 柔和黑',
459
+ ' rf2 create "财经日报" --layout blur-bg # 小红书 / 抖音 风(图表内容首选)',
460
+ ' rf2 create "纪录片片段" --layout letterbox --motion max # 电影感',
461
+ ' rf2 create "..." --layout letterbox --layout-matte-color "#1a1a1a" # 柔和黑',
462
462
  "",
463
463
  " # Preview-first workflow — see the storyboard before paying for the MP4",
464
- ' rf create "..." --preview-only # opens browser studio, no MP4 yet',
465
- " rf render <task-id> # finalize the MP4 when happy",
464
+ ' rf2 create "..." --preview-only # opens browser studio, no MP4 yet',
465
+ " rf2 render <task-id> # finalize the MP4 when happy",
466
466
  "",
467
467
  " # Recipe + replay last",
468
- " rf create --recipe ./space.recipe.json",
469
- " rf create --redo # replay last successful create",
470
- " rf create --redo -p fast # replay with one knob tweaked",
468
+ " rf2 create --recipe ./space.recipe.json",
469
+ " rf2 create --redo # replay last successful create",
470
+ " rf2 create --redo -p fast # replay with one knob tweaked",
471
471
  "",
472
472
  " # See exactly what would be sent (no submission)",
473
- ' rf create "..." -d 60 --dry-run',
473
+ ' rf2 create "..." -d 60 --dry-run',
474
474
  "",
475
475
  " # Pipe-friendly",
476
- ' rf create "..." --no-download --json | jq -r .video_url',
476
+ ' rf2 create "..." --no-download --json | jq -r .video_url',
477
477
  ].join("\n"))
478
478
  .action(async (topicArg, opts) => {
479
479
  if (opts.output) {
@@ -620,7 +620,7 @@ export function registerCreate(program) {
620
620
  // preview_only=true → no MP4; we just announce URLs and (optionally) open the browser
621
621
  // normal → download MP4 (current behavior)
622
622
  if (result?.render_pending) {
623
- info(`MP4 渲染未触发 (preview-only)。完成后用 \`rf render ${t.id}\` 生成。`);
623
+ info(`MP4 渲染未触发 (preview-only)。完成后用 \`rf2 render ${t.id}\` 生成。`);
624
624
  if (previewPageAbs && !opts.noOpen) {
625
625
  await openInBrowser(previewPageAbs).catch((e) => {
626
626
  warn(`无法自动打开浏览器: ${e.message}; 请手动复制 URL`);
@@ -26,7 +26,7 @@ export function registerLlm(program) {
26
26
  "",
27
27
  "Model IDs:",
28
28
  " Pass the bare model id (e.g. `deepseek-v4-flash`, `gpt-5-nano`).",
29
- " The provider/model form returned by `rf models` (e.g. `openai/gpt-5-nano`)",
29
+ " The provider/model form returned by `rf2 models` (e.g. `openai/gpt-5-nano`)",
30
30
  " may need explicit provider access on your RelayX account and is more",
31
31
  " likely to return 'no permission'.",
32
32
  ].join("\n"))
@@ -50,11 +50,11 @@ export function registerPipelines(program) {
50
50
  .option("--layout <preset>", "image layout: full (default) | blur-bg | letterbox. See below.")
51
51
  .option("--layout-matte-color <css>", "letterbox matte color (CSS). Ignored unless --layout letterbox. Default: black.")
52
52
  .option("--subtitle-style <preset>", "subtitle visual style: plate (default) | stroke | cinema")
53
- .option("--preview-only", "build the HyperFrames composition and return preview URLs; skip MP4 render. Finalize later with `rf render <task-id>`.")
53
+ .option("--preview-only", "build the HyperFrames composition and return preview URLs; skip MP4 render. Finalize later with `rf2 render <task-id>`.")
54
54
  .option("--image-model <id>", "RelayX image model (rx-image-z | rx-image-flux | rx-image-qwen | rx-image-qwen-edit)")
55
55
  .option("--prompt-prefix <text>", "style prefix prepended to every image prompt")
56
56
  .option("--character-ref <urlOrPath>", "main character ref for cross-scene identity lock")
57
- .option("--voice-id <id>", "RelayX TTS voice id (default 专业解说); see `rf tts voices`")
57
+ .option("--voice-id <id>", "RelayX TTS voice id (default 专业解说); see `rf2 tts voices`")
58
58
  .option("--tts-speed <n>", "speech speed (0.5..2; default 1.0). Only honored by Edge-TTS backends — vox/index-tts-2 (default) ignores it.", parseFloat)
59
59
  .option("--video-fps <n>", "output video fps (default 30)", (v) => parseInt(v, 10))
60
60
  .option("--segment-min-chars <N>", "subtitle SEGMENT (分段) min chars (default 10). Segment = one on-screen subtitle unit, not a visual line.", (v) => parseInt(v, 10))
@@ -78,12 +78,12 @@ export function registerPipelines(program) {
78
78
  " · Image is generated at the actual on-screen size, so you don't pay for cropped pixels.",
79
79
  "",
80
80
  "Examples:",
81
- " rf pipelines standard -t 'why we explore space' -d 60 -o space.mp4",
82
- " rf pipelines standard --script @script.txt -p slow --motion max -o out.mp4",
83
- " rf pipelines standard -t '财经日报' --layout blur-bg --subtitle-style plate -o out.mp4",
84
- " rf pipelines standard -t '纪录片' --layout letterbox --motion max -o film.mp4",
81
+ " rf2 pipelines standard -t 'why we explore space' -d 60 -o space.mp4",
82
+ " rf2 pipelines standard --script @script.txt -p slow --motion max -o out.mp4",
83
+ " rf2 pipelines standard -t '财经日报' --layout blur-bg --subtitle-style plate -o out.mp4",
84
+ " rf2 pipelines standard -t '纪录片' --layout letterbox --motion max -o film.mp4",
85
85
  "",
86
- "Tip: `rf create` is a more ergonomic wrapper around the same endpoint.",
86
+ "Tip: `rf2 create` is a more ergonomic wrapper around the same endpoint.",
87
87
  ].join("\n"))).action(async (opts) => {
88
88
  const hasTopic = typeof opts.topic === "string" && opts.topic.length > 0;
89
89
  const hasScript = typeof opts.script === "string" && opts.script.length > 0;
@@ -7,7 +7,7 @@ export function registerRender(program) {
7
7
  .command("render")
8
8
  .description("Finalize a preview-only task into an MP4 by running the HF render step on the server.")
9
9
  .helpOption("-h, --help", "show help")
10
- .argument("<task-id>", "task id from `rf create --preview-only`")
10
+ .argument("<task-id>", "task id from `rf2 create --preview-only`")
11
11
  .option("-o, --output <file>", "save the MP4 to this exact path (must include filename, e.g. ./out/x.mp4)")
12
12
  .option("--no-download", "do not save the video locally — just print JSON with video_url")
13
13
  .option("--fps <n>", "override FPS for this render (default: storyboard.config.videoFps)", (v) => parseInt(v, 10))
@@ -28,9 +28,9 @@ export function registerRender(program) {
28
28
  " • If you've already rendered once, calling render again will overwrite.",
29
29
  "",
30
30
  "Examples:",
31
- " rf render 2026-05-28T12-00-00-000Z_abcd",
32
- " rf render 2026-05-28T12-00-00-000Z_abcd -o ./final/space.mp4",
33
- " rf render 2026-05-28T12-00-00-000Z_abcd --fps 60",
31
+ " rf2 render 2026-05-28T12-00-00-000Z_abcd",
32
+ " rf2 render 2026-05-28T12-00-00-000Z_abcd -o ./final/space.mp4",
33
+ " rf2 render 2026-05-28T12-00-00-000Z_abcd --fps 60",
34
34
  ].join("\n"))
35
35
  .action(async (taskId, opts) => {
36
36
  info(`Submitting render for ${taskId}…`);
@@ -28,8 +28,8 @@ export function registerSubtitles(program) {
28
28
  " No punctuation in window → force-cut at max.",
29
29
  "",
30
30
  "Examples:",
31
- " rf subtitles split -t '雨水缓缓滑落在玻璃窗上,像是无声的泪珠。'",
32
- " rf subtitles split -t @./narration.txt --min 8 --max 30",
31
+ " rf2 subtitles split -t '雨水缓缓滑落在玻璃窗上,像是无声的泪珠。'",
32
+ " rf2 subtitles split -t @./narration.txt --min 8 --max 30",
33
33
  ].join("\n"))
34
34
  .action(async (opts) => {
35
35
  let text = opts.text;
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * ReelForge CLI — entry point.
3
3
  *
4
- * Every leaf command supports `--help`. Sub-groups (e.g. `reelforge llm`) print
4
+ * Every leaf command supports `--help`. Sub-groups (e.g. `reelforge2 llm`) print
5
5
  * a list of their sub-commands when invoked without arguments OR with `--help`.
6
6
  */
7
7
  import { readFileSync } from "node:fs";
@@ -67,14 +67,14 @@ program
67
67
  program.addHelpText("afterAll", [
68
68
  "",
69
69
  "Examples (tip: `rf` works wherever you see `reelforge`):",
70
- " rf create '为什么我们还没有找到外星文明?' # auto-saves to ./<title>-<id>.mp4 in cwd",
71
- " rf create '...' -o ./videos/space.mp4 # pick the exact path",
72
- " rf llm chat --prompt 'explain antifragile in 3 sentences'",
73
- " rf tts edge --text 'hello world' --voice en-US-AriaNeural -o out.mp3",
74
- " rf images generate --prompt 'a cat' --model rx-image-flux -o cat.png",
75
- " rf pipelines standard -t 'why we explore space' -d 60",
76
- " rf tasks list --status running",
77
- " rf config get",
70
+ " rf2 create '为什么我们还没有找到外星文明?' # auto-saves to ./<title>-<id>.mp4 in cwd",
71
+ " rf2 create '...' -o ./videos/space.mp4 # pick the exact path",
72
+ " rf2 llm chat --prompt 'explain antifragile in 3 sentences'",
73
+ " rf2 tts edge --text 'hello world' --voice en-US-AriaNeural -o out.mp3",
74
+ " rf2 images generate --prompt 'a cat' --model rx-image-flux -o cat.png",
75
+ " rf2 pipelines standard -t 'why we explore space' -d 60",
76
+ " rf2 tasks list --status running",
77
+ " rf2 config get",
78
78
  ].join("\n"));
79
79
  registerAuth(program);
80
80
  registerCreate(program);
@@ -105,7 +105,7 @@ async function main() {
105
105
  catch (err) {
106
106
  if (err instanceof ApiCallError) {
107
107
  const hint = err.status === 401
108
- ? " → Run `reelforge login <api_key>` first, or pass --api-key <key>."
108
+ ? " → Run `reelforge2 login <api_key>` first, or pass --api-key <key>."
109
109
  : err.status === 402
110
110
  ? " → Insufficient balance. Top up via admin."
111
111
  : err.status === 403
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "reelforge2",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "CLI for ReelForge2 — HyperFrames-powered video engine, sibling deployment of the legacy `reelforge`. Installs as `reelforge2` and the short alias `rf2`. Defaults to https://reelforge2.timor419.com. Use this CLI for the HF-engine line; the legacy ffmpeg-line stays on `reelforge` (0.x.x).",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",