vidpipe 1.3.8 → 1.3.9
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 +29 -0
- package/dist/cli.js +77 -5
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -96,6 +96,9 @@ vidpipe --watch-dir ~/Videos/Recordings
|
|
|
96
96
|
# Generate a saved idea bank for future recordings
|
|
97
97
|
vidpipe ideate --topics "GitHub Copilot, Azure, TypeScript" --count 4
|
|
98
98
|
|
|
99
|
+
# Add a single idea with AI enrichment
|
|
100
|
+
vidpipe ideate --add --topic "Building CI/CD with GitHub Actions"
|
|
101
|
+
|
|
99
102
|
# Full example with options
|
|
100
103
|
vidpipe \
|
|
101
104
|
--watch-dir ~/Videos/Recordings \
|
|
@@ -162,6 +165,17 @@ vidpipe doctor # Check all prerequisites
|
|
|
162
165
|
| `--format <format>` | Output format: `table` (default) or `json` |
|
|
163
166
|
| `--output <dir>` | Ideas directory (default: `./ideas`) |
|
|
164
167
|
| `--brand <path>` | Brand config path (default: `./brand.json`) |
|
|
168
|
+
| `--add` | Create a single idea (AI-enriched by default) |
|
|
169
|
+
| `--topic <topic>` | Topic for the idea (required with `--add`) |
|
|
170
|
+
| `--hook <hook>` | Opening hook (AI-generated if omitted) |
|
|
171
|
+
| `--audience <audience>` | Target audience (default: `"developers"`) |
|
|
172
|
+
| `--platforms <list>` | Comma-separated platforms: `youtube,tiktok,instagram,linkedin,x` |
|
|
173
|
+
| `--key-takeaway <msg>` | Core message (AI-generated if omitted) |
|
|
174
|
+
| `--talking-points <list>` | Comma-separated talking points |
|
|
175
|
+
| `--tags <list>` | Comma-separated categorization tags |
|
|
176
|
+
| `--publish-by <date>` | Publish-by date (default: 14 days from now) |
|
|
177
|
+
| `--trend-context <text>` | Trend research context |
|
|
178
|
+
| `--no-ai` | Skip AI research agent, use CLI values + defaults |
|
|
165
179
|
|
|
166
180
|
---
|
|
167
181
|
|
|
@@ -233,6 +247,21 @@ vidpipe ideate --list --format json
|
|
|
233
247
|
vidpipe process video.mp4 --ideas 12,15
|
|
234
248
|
```
|
|
235
249
|
|
|
250
|
+
### Manual Idea Creation
|
|
251
|
+
|
|
252
|
+
Add a single idea with AI enrichment or direct CLI values:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# AI-researched — full IdeationAgent with MCP research tools
|
|
256
|
+
vidpipe ideate --add --topic "Building CI/CD with GitHub Actions"
|
|
257
|
+
|
|
258
|
+
# Direct — skip AI, use CLI flags + defaults
|
|
259
|
+
vidpipe ideate --add --topic "Quick Demo" --no-ai --hook "Ship it live" --audience "developers"
|
|
260
|
+
|
|
261
|
+
# JSON output for programmatic consumers (e.g., VidRecord Electron app)
|
|
262
|
+
vidpipe ideate --add --topic "My Topic" --format json
|
|
263
|
+
```
|
|
264
|
+
|
|
236
265
|
### How It Works
|
|
237
266
|
|
|
238
267
|
The **IdeationAgent** uses MCP tools (Exa web search, YouTube, Perplexity) to research trending topics in your niche before generating ideas. Each idea includes:
|
package/dist/cli.js
CHANGED
|
@@ -11557,12 +11557,13 @@ function isStringArray(value) {
|
|
|
11557
11557
|
function hasField(source, field) {
|
|
11558
11558
|
return Object.prototype.hasOwnProperty.call(source, field);
|
|
11559
11559
|
}
|
|
11560
|
-
function normalizeCount(count) {
|
|
11560
|
+
function normalizeCount(count, allowSingle) {
|
|
11561
|
+
const min = allowSingle ? 1 : MIN_IDEA_COUNT;
|
|
11561
11562
|
if (typeof count !== "number" || Number.isNaN(count)) {
|
|
11562
|
-
return
|
|
11563
|
+
return min;
|
|
11563
11564
|
}
|
|
11564
11565
|
const rounded = Math.round(count);
|
|
11565
|
-
return Math.min(MAX_IDEA_COUNT, Math.max(
|
|
11566
|
+
return Math.min(MAX_IDEA_COUNT, Math.max(min, rounded));
|
|
11566
11567
|
}
|
|
11567
11568
|
function normalizeSeedTopics(seedTopics) {
|
|
11568
11569
|
return (seedTopics ?? []).map((topic) => topic.trim()).filter((topic) => topic.length > 0);
|
|
@@ -12207,7 +12208,7 @@ var IdeationAgent = class extends BaseAgent {
|
|
|
12207
12208
|
};
|
|
12208
12209
|
async function generateIdeas(options = {}) {
|
|
12209
12210
|
const seedTopics = normalizeSeedTopics(options.seedTopics);
|
|
12210
|
-
const count = normalizeCount(options.count);
|
|
12211
|
+
const count = normalizeCount(options.count, options.singleTopic);
|
|
12211
12212
|
const config2 = getConfig();
|
|
12212
12213
|
const previousBrandPath = config2.BRAND_PATH;
|
|
12213
12214
|
if (options.brandPath) {
|
|
@@ -13161,8 +13162,14 @@ function generateIdeas3(...args) {
|
|
|
13161
13162
|
}
|
|
13162
13163
|
|
|
13163
13164
|
// src/L7-app/commands/ideate.ts
|
|
13165
|
+
init_types();
|
|
13166
|
+
var VALID_PLATFORMS = new Set(Object.values(Platform));
|
|
13164
13167
|
async function runIdeate(options = {}) {
|
|
13165
13168
|
initConfig();
|
|
13169
|
+
if (options.add) {
|
|
13170
|
+
await handleAdd(options);
|
|
13171
|
+
return;
|
|
13172
|
+
}
|
|
13166
13173
|
if (options.list) {
|
|
13167
13174
|
const ideas2 = await listIdeas();
|
|
13168
13175
|
const filtered = options.status ? ideas2.filter((idea) => idea.status === options.status) : ideas2;
|
|
@@ -13251,6 +13258,71 @@ ${filtered.length} idea(s) total`);
|
|
|
13251
13258
|
console.log("Use `vidpipe ideate --list` to view all ideas.");
|
|
13252
13259
|
console.log("Use `vidpipe process video.mp4 --ideas <issueNumber1>,<issueNumber2>` to link ideas to a recording.");
|
|
13253
13260
|
}
|
|
13261
|
+
function parseCommaSeparated(value) {
|
|
13262
|
+
if (!value) return [];
|
|
13263
|
+
return value.split(",").map((s) => s.trim()).filter(Boolean);
|
|
13264
|
+
}
|
|
13265
|
+
function parsePlatforms(value) {
|
|
13266
|
+
if (!value) return ["youtube" /* YouTube */];
|
|
13267
|
+
const names = parseCommaSeparated(value);
|
|
13268
|
+
const platforms = [];
|
|
13269
|
+
for (const name of names) {
|
|
13270
|
+
const lower = name.toLowerCase();
|
|
13271
|
+
if (!VALID_PLATFORMS.has(lower)) {
|
|
13272
|
+
throw new Error(`Invalid platform "${name}". Valid platforms: ${[...VALID_PLATFORMS].join(", ")}`);
|
|
13273
|
+
}
|
|
13274
|
+
platforms.push(lower);
|
|
13275
|
+
}
|
|
13276
|
+
return platforms.length > 0 ? platforms : ["youtube" /* YouTube */];
|
|
13277
|
+
}
|
|
13278
|
+
function defaultPublishBy() {
|
|
13279
|
+
const date = /* @__PURE__ */ new Date();
|
|
13280
|
+
date.setDate(date.getDate() + 14);
|
|
13281
|
+
return date.toISOString().split("T")[0];
|
|
13282
|
+
}
|
|
13283
|
+
function buildDirectInput(options) {
|
|
13284
|
+
const topic = options.topic;
|
|
13285
|
+
const hook = options.hook ?? topic;
|
|
13286
|
+
const audience = options.audience ?? "developers";
|
|
13287
|
+
const platforms = parsePlatforms(options.platforms);
|
|
13288
|
+
const keyTakeaway = options.keyTakeaway ?? hook;
|
|
13289
|
+
const talkingPoints = parseCommaSeparated(options.talkingPoints);
|
|
13290
|
+
const tags = parseCommaSeparated(options.tags);
|
|
13291
|
+
const publishBy = options.publishBy ?? defaultPublishBy();
|
|
13292
|
+
const trendContext = options.trendContext;
|
|
13293
|
+
return { topic, hook, audience, keyTakeaway, talkingPoints, platforms, tags, publishBy, trendContext };
|
|
13294
|
+
}
|
|
13295
|
+
async function handleAdd(options) {
|
|
13296
|
+
if (!options.topic) {
|
|
13297
|
+
throw new Error("--topic is required when using --add");
|
|
13298
|
+
}
|
|
13299
|
+
const useAI = options.ai !== false;
|
|
13300
|
+
if (useAI) {
|
|
13301
|
+
const ideas = await generateIdeas3({
|
|
13302
|
+
seedTopics: [options.topic],
|
|
13303
|
+
count: 1,
|
|
13304
|
+
singleTopic: true,
|
|
13305
|
+
brandPath: options.brand
|
|
13306
|
+
});
|
|
13307
|
+
const idea = ideas[0];
|
|
13308
|
+
if (!idea) {
|
|
13309
|
+
throw new Error("IdeationAgent did not create an idea");
|
|
13310
|
+
}
|
|
13311
|
+
if (options.format === "json") {
|
|
13312
|
+
console.log(JSON.stringify(idea, null, 2));
|
|
13313
|
+
} else {
|
|
13314
|
+
console.log(`Created idea #${idea.issueNumber}: "${idea.topic}"`);
|
|
13315
|
+
}
|
|
13316
|
+
} else {
|
|
13317
|
+
const input = buildDirectInput(options);
|
|
13318
|
+
const idea = await createIdea(input);
|
|
13319
|
+
if (options.format === "json") {
|
|
13320
|
+
console.log(JSON.stringify(idea, null, 2));
|
|
13321
|
+
} else {
|
|
13322
|
+
console.log(`Created idea #${idea.issueNumber}: "${idea.topic}"`);
|
|
13323
|
+
}
|
|
13324
|
+
}
|
|
13325
|
+
}
|
|
13254
13326
|
|
|
13255
13327
|
// src/L1-infra/http/http.ts
|
|
13256
13328
|
import { default as default8 } from "express";
|
|
@@ -13885,7 +13957,7 @@ program.command("chat").description("Interactive chat session with the schedule
|
|
|
13885
13957
|
program.command("doctor").description("Check all prerequisites and dependencies").action(async () => {
|
|
13886
13958
|
await runDoctor();
|
|
13887
13959
|
});
|
|
13888
|
-
program.command("ideate").description("Generate AI-powered content ideas using trend research").option("--topics <topics>", "Comma-separated seed topics").option("--count <n>", "Number of ideas to generate (default: 5)", "5").option("--output <dir>", "Ideas directory (default: ./ideas)").option("--brand <path>", "Brand config path (default: ./brand.json)").option("--list", "List existing ideas instead of generating").option("--status <status>", "Filter by status when listing (draft|ready|recorded|published)").option("--format <format>", "Output format: table (default) or json").action(async (opts) => {
|
|
13960
|
+
program.command("ideate").description("Generate AI-powered content ideas using trend research").option("--topics <topics>", "Comma-separated seed topics").option("--count <n>", "Number of ideas to generate (default: 5)", "5").option("--output <dir>", "Ideas directory (default: ./ideas)").option("--brand <path>", "Brand config path (default: ./brand.json)").option("--list", "List existing ideas instead of generating").option("--status <status>", "Filter by status when listing (draft|ready|recorded|published)").option("--format <format>", "Output format: table (default) or json").option("--add", "Add a single idea (AI-researched by default, or --no-ai for direct)").option("--topic <topic>", "Idea topic/title (required with --add)").option("--hook <hook>", "Attention-grabbing hook (default: topic, --no-ai only)").option("--audience <audience>", "Target audience (default: developers, --no-ai only)").option("--platforms <platforms>", "Comma-separated platforms: tiktok,youtube,instagram,linkedin,x (--no-ai only)").option("--key-takeaway <takeaway>", "Core message the viewer should remember (--no-ai only)").option("--talking-points <points>", "Comma-separated talking points (--no-ai only)").option("--tags <tags>", "Comma-separated categorization tags (--no-ai only)").option("--publish-by <date>", "Publish deadline (ISO 8601 date, default: 14 days from now, --no-ai only)").option("--trend-context <context>", "Why this topic is timely (--no-ai only)").option("--no-ai", "Skip AI research agent \u2014 create directly from CLI flags + defaults").action(async (opts) => {
|
|
13889
13961
|
initConfig();
|
|
13890
13962
|
await runIdeate(opts);
|
|
13891
13963
|
process.exit(0);
|