vidpipe 1.3.10 → 1.3.11
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/README.md +23 -0
- package/dist/cli.js +162 -2
- package/dist/cli.js.map +1 -1
- package/dist/index.js +160 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -152,6 +152,7 @@ vidpipe doctor # Check all prerequisites
|
|
|
152
152
|
| `--no-git` | Skip git commit/push |
|
|
153
153
|
| `--late-api-key <key>` | Override Late API key |
|
|
154
154
|
| `-v, --verbose` | Debug-level logging |
|
|
155
|
+
| `--progress` | Emit structured JSON progress events to stderr |
|
|
155
156
|
| `--doctor` | Check that all prerequisites are installed |
|
|
156
157
|
|
|
157
158
|
### Ideate Options
|
|
@@ -357,6 +358,28 @@ graph LR
|
|
|
357
358
|
|
|
358
359
|
Each stage can be independently skipped with `--no-*` flags. A stage failure does not abort the pipeline — subsequent stages proceed with whatever data is available.
|
|
359
360
|
|
|
361
|
+
### Progress Events
|
|
362
|
+
|
|
363
|
+
Pass `--progress` to emit structured JSONL progress events to stderr while normal logs continue on stdout:
|
|
364
|
+
|
|
365
|
+
```bash
|
|
366
|
+
vidpipe process video.mp4 --progress 2>progress.jsonl
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
Each line is a self-contained JSON object:
|
|
370
|
+
|
|
371
|
+
```jsonl
|
|
372
|
+
{"event":"pipeline:start","videoPath":"video.mp4","totalStages":16,"timestamp":"..."}
|
|
373
|
+
{"event":"stage:start","stage":"ingestion","stageNumber":1,"totalStages":16,"name":"Ingestion","timestamp":"..."}
|
|
374
|
+
{"event":"stage:complete","stage":"ingestion","stageNumber":1,"totalStages":16,"name":"Ingestion","duration":423,"success":true,"timestamp":"..."}
|
|
375
|
+
{"event":"stage:skip","stage":"shorts","stageNumber":7,"totalStages":16,"name":"Shorts","reason":"SKIP_SHORTS","timestamp":"..."}
|
|
376
|
+
{"event":"pipeline:complete","totalDuration":45000,"stagesCompleted":14,"stagesFailed":0,"stagesSkipped":2,"timestamp":"..."}
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Event types: `pipeline:start`, `stage:start`, `stage:complete`, `stage:error`, `stage:skip`, `pipeline:complete`.
|
|
380
|
+
|
|
381
|
+
Integrating tools can read stderr line-by-line to display a live progress UI (e.g., "Stage 3/16: Silence Removal").
|
|
382
|
+
|
|
360
383
|
---
|
|
361
384
|
|
|
362
385
|
## 🤖 LLM Providers
|
package/dist/cli.js
CHANGED
|
@@ -634,6 +634,11 @@ var init_configLogger = __esm({
|
|
|
634
634
|
});
|
|
635
635
|
|
|
636
636
|
// src/L0-pure/types/index.ts
|
|
637
|
+
function getStageInfo(stage) {
|
|
638
|
+
const info = PIPELINE_STAGES.find((s) => s.stage === stage);
|
|
639
|
+
if (!info) throw new Error(`Unknown pipeline stage: ${stage}`);
|
|
640
|
+
return info;
|
|
641
|
+
}
|
|
637
642
|
function toLatePlatform(platform) {
|
|
638
643
|
return platform === "x" /* X */ ? "twitter" : platform;
|
|
639
644
|
}
|
|
@@ -658,7 +663,7 @@ function normalizePlatformString(raw) {
|
|
|
658
663
|
function isSupportedVideoExtension(ext) {
|
|
659
664
|
return SUPPORTED_VIDEO_EXTENSIONS.includes(ext.toLowerCase());
|
|
660
665
|
}
|
|
661
|
-
var Platform, PLATFORM_CHAR_LIMITS, SUPPORTED_VIDEO_EXTENSIONS;
|
|
666
|
+
var Platform, PIPELINE_STAGES, TOTAL_STAGES, PLATFORM_CHAR_LIMITS, SUPPORTED_VIDEO_EXTENSIONS;
|
|
662
667
|
var init_types = __esm({
|
|
663
668
|
"src/L0-pure/types/index.ts"() {
|
|
664
669
|
"use strict";
|
|
@@ -670,6 +675,25 @@ var init_types = __esm({
|
|
|
670
675
|
Platform2["X"] = "x";
|
|
671
676
|
return Platform2;
|
|
672
677
|
})(Platform || {});
|
|
678
|
+
PIPELINE_STAGES = [
|
|
679
|
+
{ stage: "ingestion" /* Ingestion */, name: "Ingestion", stageNumber: 1 },
|
|
680
|
+
{ stage: "transcription" /* Transcription */, name: "Transcription", stageNumber: 2 },
|
|
681
|
+
{ stage: "silence-removal" /* SilenceRemoval */, name: "Silence Removal", stageNumber: 3 },
|
|
682
|
+
{ stage: "visual-enhancement" /* VisualEnhancement */, name: "Visual Enhancement", stageNumber: 4 },
|
|
683
|
+
{ stage: "captions" /* Captions */, name: "Captions", stageNumber: 5 },
|
|
684
|
+
{ stage: "caption-burn" /* CaptionBurn */, name: "Caption Burn", stageNumber: 6 },
|
|
685
|
+
{ stage: "shorts" /* Shorts */, name: "Shorts", stageNumber: 7 },
|
|
686
|
+
{ stage: "medium-clips" /* MediumClips */, name: "Medium Clips", stageNumber: 8 },
|
|
687
|
+
{ stage: "chapters" /* Chapters */, name: "Chapters", stageNumber: 9 },
|
|
688
|
+
{ stage: "summary" /* Summary */, name: "Summary", stageNumber: 10 },
|
|
689
|
+
{ stage: "social-media" /* SocialMedia */, name: "Social Media", stageNumber: 11 },
|
|
690
|
+
{ stage: "short-posts" /* ShortPosts */, name: "Short Posts", stageNumber: 12 },
|
|
691
|
+
{ stage: "medium-clip-posts" /* MediumClipPosts */, name: "Medium Clip Posts", stageNumber: 13 },
|
|
692
|
+
{ stage: "queue-build" /* QueueBuild */, name: "Queue Build", stageNumber: 14 },
|
|
693
|
+
{ stage: "blog" /* Blog */, name: "Blog", stageNumber: 15 },
|
|
694
|
+
{ stage: "git-push" /* GitPush */, name: "Git Push", stageNumber: 16 }
|
|
695
|
+
];
|
|
696
|
+
TOTAL_STAGES = PIPELINE_STAGES.length;
|
|
673
697
|
PLATFORM_CHAR_LIMITS = {
|
|
674
698
|
tiktok: 2200,
|
|
675
699
|
youtube: 5e3,
|
|
@@ -2570,6 +2594,32 @@ init_fileSystem();
|
|
|
2570
2594
|
init_configLogger();
|
|
2571
2595
|
init_environment();
|
|
2572
2596
|
|
|
2597
|
+
// src/L1-infra/progress/progressEmitter.ts
|
|
2598
|
+
var ProgressEmitter = class {
|
|
2599
|
+
enabled = false;
|
|
2600
|
+
/** Turn on progress event output to stderr. */
|
|
2601
|
+
enable() {
|
|
2602
|
+
this.enabled = true;
|
|
2603
|
+
}
|
|
2604
|
+
/** Turn off progress event output. */
|
|
2605
|
+
disable() {
|
|
2606
|
+
this.enabled = false;
|
|
2607
|
+
}
|
|
2608
|
+
/** Whether the emitter is currently active. */
|
|
2609
|
+
isEnabled() {
|
|
2610
|
+
return this.enabled;
|
|
2611
|
+
}
|
|
2612
|
+
/**
|
|
2613
|
+
* Write a progress event as a single JSON line to stderr.
|
|
2614
|
+
* No-op when the emitter is disabled.
|
|
2615
|
+
*/
|
|
2616
|
+
emit(event) {
|
|
2617
|
+
if (!this.enabled) return;
|
|
2618
|
+
process.stderr.write(JSON.stringify(event) + "\n");
|
|
2619
|
+
}
|
|
2620
|
+
};
|
|
2621
|
+
var progressEmitter = new ProgressEmitter();
|
|
2622
|
+
|
|
2573
2623
|
// src/L5-assets/Asset.ts
|
|
2574
2624
|
init_fileSystem();
|
|
2575
2625
|
var Asset = class {
|
|
@@ -12498,17 +12548,54 @@ function createScheduleAgent(...args) {
|
|
|
12498
12548
|
init_types();
|
|
12499
12549
|
async function runStage(stageName, fn, stageResults) {
|
|
12500
12550
|
const start = Date.now();
|
|
12551
|
+
if (progressEmitter.isEnabled()) {
|
|
12552
|
+
const info = getStageInfo(stageName);
|
|
12553
|
+
progressEmitter.emit({
|
|
12554
|
+
event: "stage:start",
|
|
12555
|
+
stage: stageName,
|
|
12556
|
+
stageNumber: info.stageNumber,
|
|
12557
|
+
totalStages: TOTAL_STAGES,
|
|
12558
|
+
name: info.name,
|
|
12559
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12560
|
+
});
|
|
12561
|
+
}
|
|
12501
12562
|
try {
|
|
12502
12563
|
const result = await fn();
|
|
12503
12564
|
const duration = Date.now() - start;
|
|
12504
12565
|
stageResults.push({ stage: stageName, success: true, duration });
|
|
12505
12566
|
logger_default.info(`Stage ${stageName} completed in ${duration}ms`);
|
|
12567
|
+
if (progressEmitter.isEnabled()) {
|
|
12568
|
+
const info = getStageInfo(stageName);
|
|
12569
|
+
progressEmitter.emit({
|
|
12570
|
+
event: "stage:complete",
|
|
12571
|
+
stage: stageName,
|
|
12572
|
+
stageNumber: info.stageNumber,
|
|
12573
|
+
totalStages: TOTAL_STAGES,
|
|
12574
|
+
name: info.name,
|
|
12575
|
+
duration,
|
|
12576
|
+
success: true,
|
|
12577
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12578
|
+
});
|
|
12579
|
+
}
|
|
12506
12580
|
return result;
|
|
12507
12581
|
} catch (err) {
|
|
12508
12582
|
const duration = Date.now() - start;
|
|
12509
12583
|
const message = err instanceof Error ? err.message : String(err);
|
|
12510
12584
|
stageResults.push({ stage: stageName, success: false, error: message, duration });
|
|
12511
12585
|
logger_default.error(`Stage ${stageName} failed after ${duration}ms: ${message}`);
|
|
12586
|
+
if (progressEmitter.isEnabled()) {
|
|
12587
|
+
const info = getStageInfo(stageName);
|
|
12588
|
+
progressEmitter.emit({
|
|
12589
|
+
event: "stage:error",
|
|
12590
|
+
stage: stageName,
|
|
12591
|
+
stageNumber: info.stageNumber,
|
|
12592
|
+
totalStages: TOTAL_STAGES,
|
|
12593
|
+
name: info.name,
|
|
12594
|
+
duration,
|
|
12595
|
+
error: message,
|
|
12596
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12597
|
+
});
|
|
12598
|
+
}
|
|
12512
12599
|
return void 0;
|
|
12513
12600
|
}
|
|
12514
12601
|
}
|
|
@@ -12516,16 +12603,50 @@ async function processVideo(videoPath, ideas) {
|
|
|
12516
12603
|
const pipelineStart = Date.now();
|
|
12517
12604
|
const stageResults = [];
|
|
12518
12605
|
const cfg = getConfig();
|
|
12606
|
+
let stagesSkipped = 0;
|
|
12519
12607
|
costTracker3.reset();
|
|
12520
12608
|
function trackStage(stage, fn) {
|
|
12521
12609
|
costTracker3.setStage(stage);
|
|
12522
12610
|
return runStage(stage, fn, stageResults);
|
|
12523
12611
|
}
|
|
12612
|
+
function skipStage(stage, reason) {
|
|
12613
|
+
stagesSkipped++;
|
|
12614
|
+
if (progressEmitter.isEnabled()) {
|
|
12615
|
+
const info = getStageInfo(stage);
|
|
12616
|
+
progressEmitter.emit({
|
|
12617
|
+
event: "stage:skip",
|
|
12618
|
+
stage,
|
|
12619
|
+
stageNumber: info.stageNumber,
|
|
12620
|
+
totalStages: TOTAL_STAGES,
|
|
12621
|
+
name: info.name,
|
|
12622
|
+
reason,
|
|
12623
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12624
|
+
});
|
|
12625
|
+
}
|
|
12626
|
+
}
|
|
12627
|
+
if (progressEmitter.isEnabled()) {
|
|
12628
|
+
progressEmitter.emit({
|
|
12629
|
+
event: "pipeline:start",
|
|
12630
|
+
videoPath,
|
|
12631
|
+
totalStages: TOTAL_STAGES,
|
|
12632
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12633
|
+
});
|
|
12634
|
+
}
|
|
12524
12635
|
logger_default.info(`Pipeline starting for: ${videoPath}`);
|
|
12525
12636
|
const asset = await trackStage("ingestion" /* Ingestion */, () => MainVideoAsset.ingest(videoPath));
|
|
12526
12637
|
if (!asset) {
|
|
12527
12638
|
const totalDuration = Date.now() - pipelineStart;
|
|
12528
12639
|
logger_default.error("Ingestion failed \u2014 cannot proceed without video metadata");
|
|
12640
|
+
if (progressEmitter.isEnabled()) {
|
|
12641
|
+
progressEmitter.emit({
|
|
12642
|
+
event: "pipeline:complete",
|
|
12643
|
+
totalDuration,
|
|
12644
|
+
stagesCompleted: 0,
|
|
12645
|
+
stagesFailed: 1,
|
|
12646
|
+
stagesSkipped: 0,
|
|
12647
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12648
|
+
});
|
|
12649
|
+
}
|
|
12529
12650
|
return {
|
|
12530
12651
|
video: { originalPath: videoPath, repoPath: "", videoDir: "", slug: "", filename: "", duration: 0, size: 0, createdAt: /* @__PURE__ */ new Date() },
|
|
12531
12652
|
transcript: void 0,
|
|
@@ -12552,28 +12673,40 @@ async function processVideo(videoPath, ideas) {
|
|
|
12552
12673
|
let editedVideoPath;
|
|
12553
12674
|
if (!cfg.SKIP_SILENCE_REMOVAL) {
|
|
12554
12675
|
editedVideoPath = await trackStage("silence-removal" /* SilenceRemoval */, () => asset.getEditedVideo());
|
|
12676
|
+
} else {
|
|
12677
|
+
skipStage("silence-removal" /* SilenceRemoval */, "SKIP_SILENCE_REMOVAL");
|
|
12555
12678
|
}
|
|
12556
12679
|
let enhancedVideoPath;
|
|
12557
12680
|
if (!cfg.SKIP_VISUAL_ENHANCEMENT) {
|
|
12558
12681
|
enhancedVideoPath = await trackStage("visual-enhancement" /* VisualEnhancement */, () => asset.getEnhancedVideo());
|
|
12682
|
+
} else {
|
|
12683
|
+
skipStage("visual-enhancement" /* VisualEnhancement */, "SKIP_VISUAL_ENHANCEMENT");
|
|
12559
12684
|
}
|
|
12560
12685
|
let captions;
|
|
12561
12686
|
if (!cfg.SKIP_CAPTIONS) {
|
|
12562
12687
|
captions = await trackStage("captions" /* Captions */, () => asset.getCaptions());
|
|
12688
|
+
} else {
|
|
12689
|
+
skipStage("captions" /* Captions */, "SKIP_CAPTIONS");
|
|
12563
12690
|
}
|
|
12564
12691
|
let captionedVideoPath;
|
|
12565
12692
|
if (!cfg.SKIP_CAPTIONS) {
|
|
12566
12693
|
captionedVideoPath = await trackStage("caption-burn" /* CaptionBurn */, () => asset.getCaptionedVideo());
|
|
12694
|
+
} else {
|
|
12695
|
+
skipStage("caption-burn" /* CaptionBurn */, "SKIP_CAPTIONS");
|
|
12567
12696
|
}
|
|
12568
12697
|
let shorts = [];
|
|
12569
12698
|
if (!cfg.SKIP_SHORTS) {
|
|
12570
12699
|
const shortAssets = await trackStage("shorts" /* Shorts */, () => asset.getShorts()) ?? [];
|
|
12571
12700
|
shorts = shortAssets.map((s) => s.clip);
|
|
12701
|
+
} else {
|
|
12702
|
+
skipStage("shorts" /* Shorts */, "SKIP_SHORTS");
|
|
12572
12703
|
}
|
|
12573
12704
|
let mediumClips = [];
|
|
12574
12705
|
if (!cfg.SKIP_MEDIUM_CLIPS) {
|
|
12575
12706
|
const mediumAssets = await trackStage("medium-clips" /* MediumClips */, () => asset.getMediumClips()) ?? [];
|
|
12576
12707
|
mediumClips = mediumAssets.map((m) => m.clip);
|
|
12708
|
+
} else {
|
|
12709
|
+
skipStage("medium-clips" /* MediumClips */, "SKIP_MEDIUM_CLIPS");
|
|
12577
12710
|
}
|
|
12578
12711
|
const chapters = await trackStage("chapters" /* Chapters */, () => asset.getChapters());
|
|
12579
12712
|
const summary = await trackStage("summary" /* Summary */, () => asset.getSummary());
|
|
@@ -12588,6 +12721,8 @@ async function processVideo(videoPath, ideas) {
|
|
|
12588
12721
|
socialPosts.push(...posts);
|
|
12589
12722
|
}
|
|
12590
12723
|
});
|
|
12724
|
+
} else {
|
|
12725
|
+
skipStage("short-posts" /* ShortPosts */, "NO_SHORTS");
|
|
12591
12726
|
}
|
|
12592
12727
|
if (mediumClips.length > 0) {
|
|
12593
12728
|
await trackStage("medium-clip-posts" /* MediumClipPosts */, async () => {
|
|
@@ -12596,14 +12731,26 @@ async function processVideo(videoPath, ideas) {
|
|
|
12596
12731
|
socialPosts.push(...posts);
|
|
12597
12732
|
}
|
|
12598
12733
|
});
|
|
12734
|
+
} else {
|
|
12735
|
+
skipStage("medium-clip-posts" /* MediumClipPosts */, "NO_MEDIUM_CLIPS");
|
|
12599
12736
|
}
|
|
12737
|
+
} else {
|
|
12738
|
+
skipStage("social-media" /* SocialMedia */, "SKIP_SOCIAL");
|
|
12739
|
+
skipStage("short-posts" /* ShortPosts */, "SKIP_SOCIAL");
|
|
12740
|
+
skipStage("medium-clip-posts" /* MediumClipPosts */, "SKIP_SOCIAL");
|
|
12600
12741
|
}
|
|
12601
12742
|
if (!cfg.SKIP_SOCIAL_PUBLISH && socialPosts.length > 0) {
|
|
12602
12743
|
await trackStage("queue-build" /* QueueBuild */, () => asset.buildQueue(shorts, mediumClips, socialPosts, captionedVideoPath));
|
|
12744
|
+
} else if (cfg.SKIP_SOCIAL_PUBLISH) {
|
|
12745
|
+
skipStage("queue-build" /* QueueBuild */, "SKIP_SOCIAL_PUBLISH");
|
|
12746
|
+
} else {
|
|
12747
|
+
skipStage("queue-build" /* QueueBuild */, "NO_SOCIAL_POSTS");
|
|
12603
12748
|
}
|
|
12604
12749
|
const blogPost = await trackStage("blog" /* Blog */, () => asset.getBlog());
|
|
12605
12750
|
if (!cfg.SKIP_GIT) {
|
|
12606
12751
|
await trackStage("git-push" /* GitPush */, () => asset.commitAndPushChanges());
|
|
12752
|
+
} else {
|
|
12753
|
+
skipStage("git-push" /* GitPush */, "SKIP_GIT");
|
|
12607
12754
|
}
|
|
12608
12755
|
const totalDuration = Date.now() - pipelineStart;
|
|
12609
12756
|
const report = costTracker3.getReport();
|
|
@@ -12614,6 +12761,18 @@ async function processVideo(videoPath, ideas) {
|
|
|
12614
12761
|
await writeTextFile(costPath, costMd);
|
|
12615
12762
|
logger_default.info(`Cost report saved: ${costPath}`);
|
|
12616
12763
|
}
|
|
12764
|
+
const stagesCompleted = stageResults.filter((r) => r.success).length;
|
|
12765
|
+
const stagesFailed = stageResults.filter((r) => !r.success).length;
|
|
12766
|
+
if (progressEmitter.isEnabled()) {
|
|
12767
|
+
progressEmitter.emit({
|
|
12768
|
+
event: "pipeline:complete",
|
|
12769
|
+
totalDuration,
|
|
12770
|
+
stagesCompleted,
|
|
12771
|
+
stagesFailed,
|
|
12772
|
+
stagesSkipped,
|
|
12773
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
12774
|
+
});
|
|
12775
|
+
}
|
|
12617
12776
|
logger_default.info(`Pipeline completed in ${totalDuration}ms`);
|
|
12618
12777
|
return {
|
|
12619
12778
|
video,
|
|
@@ -14520,7 +14679,7 @@ program.command("configure [subcommand]").description("Manage global configurati
|
|
|
14520
14679
|
await runConfigure(subcommand, args);
|
|
14521
14680
|
process.exit(process.exitCode ?? 0);
|
|
14522
14681
|
});
|
|
14523
|
-
var defaultCmd = program.command("process", { isDefault: true }).argument("[video-path]", "Path to a video file to process (implies --once)").option("--watch-dir <path>", "Folder to watch for new recordings (default: env WATCH_FOLDER)").option("--output-dir <path>", "Output directory for processed videos (default: ./recordings)").option("--openai-key <key>", "OpenAI API key (default: env OPENAI_API_KEY)").option("--exa-key <key>", "Exa AI API key for web search (default: env EXA_API_KEY)").option("--youtube-key <key>", "YouTube API key (default: env YOUTUBE_API_KEY)").option("--perplexity-key <key>", "Perplexity API key (default: env PERPLEXITY_API_KEY)").option("--once", "Process a single video and exit (no watching)").option("--brand <path>", "Path to brand.json config (default: ./brand.json)").option("--no-git", "Skip git commit/push stage").option("--no-silence-removal", "Skip silence removal stage").option("--no-shorts", "Skip shorts generation").option("--no-medium-clips", "Skip medium clip generation").option("--no-social", "Skip social media post generation").option("--no-captions", "Skip caption generation/burning").option("--no-visual-enhancement", "Skip visual enhancement (AI image overlays)").option("--no-social-publish", "Skip social media publishing/queue-build stage").option("--late-api-key <key>", "Late API key (default: env LATE_API_KEY)").option("--late-profile-id <id>", "Late profile ID (default: env LATE_PROFILE_ID)").option("--ideas <ids>", "Comma-separated idea IDs to link to this video").option("-v, --verbose", "Verbose logging").option("--doctor", "Check all prerequisites and exit").action(async (videoPath) => {
|
|
14682
|
+
var defaultCmd = program.command("process", { isDefault: true }).argument("[video-path]", "Path to a video file to process (implies --once)").option("--watch-dir <path>", "Folder to watch for new recordings (default: env WATCH_FOLDER)").option("--output-dir <path>", "Output directory for processed videos (default: ./recordings)").option("--openai-key <key>", "OpenAI API key (default: env OPENAI_API_KEY)").option("--exa-key <key>", "Exa AI API key for web search (default: env EXA_API_KEY)").option("--youtube-key <key>", "YouTube API key (default: env YOUTUBE_API_KEY)").option("--perplexity-key <key>", "Perplexity API key (default: env PERPLEXITY_API_KEY)").option("--once", "Process a single video and exit (no watching)").option("--brand <path>", "Path to brand.json config (default: ./brand.json)").option("--no-git", "Skip git commit/push stage").option("--no-silence-removal", "Skip silence removal stage").option("--no-shorts", "Skip shorts generation").option("--no-medium-clips", "Skip medium clip generation").option("--no-social", "Skip social media post generation").option("--no-captions", "Skip caption generation/burning").option("--no-visual-enhancement", "Skip visual enhancement (AI image overlays)").option("--no-social-publish", "Skip social media publishing/queue-build stage").option("--late-api-key <key>", "Late API key (default: env LATE_API_KEY)").option("--late-profile-id <id>", "Late profile ID (default: env LATE_PROFILE_ID)").option("--ideas <ids>", "Comma-separated idea IDs to link to this video").option("-v, --verbose", "Verbose logging").option("--progress", "Emit structured JSON progress events to stderr").option("--doctor", "Check all prerequisites and exit").action(async (videoPath) => {
|
|
14524
14683
|
const opts = defaultCmd.opts();
|
|
14525
14684
|
if (opts.doctor) {
|
|
14526
14685
|
await runDoctor();
|
|
@@ -14550,6 +14709,7 @@ var defaultCmd = program.command("process", { isDefault: true }).argument("[vide
|
|
|
14550
14709
|
logger_default.info(BANNER);
|
|
14551
14710
|
initConfig(cliOptions);
|
|
14552
14711
|
if (opts.verbose) setVerbose();
|
|
14712
|
+
if (opts.progress) progressEmitter.enable();
|
|
14553
14713
|
validateRequiredKeys();
|
|
14554
14714
|
const config2 = getConfig();
|
|
14555
14715
|
logger_default.info(`Watch folder: ${config2.WATCH_FOLDER}`);
|