mulmocast 0.0.21 → 0.0.23
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 +5 -0
- package/lib/actions/captions.js +1 -1
- package/lib/actions/images.d.ts +13 -3
- package/lib/actions/images.js +91 -9
- package/lib/actions/movie.d.ts +2 -2
- package/lib/actions/movie.js +21 -6
- package/lib/agents/add_bgm_agent.js +1 -1
- package/lib/agents/combine_audio_files_agent.js +9 -5
- package/lib/agents/index.d.ts +2 -1
- package/lib/agents/index.js +2 -1
- package/lib/agents/movie_replicate_agent.d.ts +23 -0
- package/lib/agents/movie_replicate_agent.js +93 -0
- package/lib/cli/commands/tool/scripting/builder.d.ts +3 -1
- package/lib/cli/commands/tool/scripting/builder.js +5 -0
- package/lib/cli/commands/tool/scripting/handler.d.ts +1 -0
- package/lib/cli/commands/tool/scripting/handler.js +13 -4
- package/lib/cli/commands/tool/story_to_script/builder.d.ts +1 -1
- package/lib/cli/helpers.js +8 -3
- package/lib/methods/mulmo_presentation_style.d.ts +2 -1
- package/lib/methods/mulmo_presentation_style.js +21 -2
- package/lib/methods/mulmo_studio_context.js +1 -1
- package/lib/tools/create_mulmo_script_from_url.d.ts +1 -0
- package/lib/tools/create_mulmo_script_from_url.js +129 -43
- package/lib/types/schema.d.ts +1261 -165
- package/lib/types/schema.js +47 -1
- package/lib/types/type.d.ts +9 -2
- package/lib/utils/ffmpeg_utils.d.ts +2 -2
- package/lib/utils/ffmpeg_utils.js +9 -4
- package/lib/utils/preprocess.d.ts +47 -6
- package/lib/utils/utils.d.ts +1 -0
- package/lib/utils/utils.js +5 -0
- package/package.json +3 -2
- package/scripts/templates/presentation.json +123 -0
- package/scripts/templates/presentation.json~ +119 -0
package/lib/types/schema.js
CHANGED
|
@@ -84,6 +84,18 @@ export const mulmoTextSlideMediaSchema = z
|
|
|
84
84
|
}),
|
|
85
85
|
})
|
|
86
86
|
.strict();
|
|
87
|
+
export const mulmoCaptionParamsSchema = z
|
|
88
|
+
.object({
|
|
89
|
+
lang: langSchema.optional(),
|
|
90
|
+
textColor: z.string().default("#FFFFFF"),
|
|
91
|
+
backgroundColor: z.string().default("#000000"),
|
|
92
|
+
fontSize: z.number().default(16),
|
|
93
|
+
fontFamily: z.string().default("Arial"),
|
|
94
|
+
fontWeight: z.string().default("normal"),
|
|
95
|
+
textAlign: z.string().default("left"),
|
|
96
|
+
textDecoration: z.string().default("none"),
|
|
97
|
+
})
|
|
98
|
+
.strict();
|
|
87
99
|
export const mulmoChartMediaSchema = z
|
|
88
100
|
.object({
|
|
89
101
|
type: z.literal("chart"),
|
|
@@ -141,6 +153,11 @@ const mulmoMidiMediaSchema = z
|
|
|
141
153
|
export const mulmoAudioAssetSchema = z.union([mulmoAudioMediaSchema, mulmoMidiMediaSchema]);
|
|
142
154
|
const imageIdSchema = z.string();
|
|
143
155
|
export const mulmoImageParamsImagesSchema = z.record(imageIdSchema, mulmoImageMediaSchema);
|
|
156
|
+
export const mulmoFillOptionSchema = z
|
|
157
|
+
.object({
|
|
158
|
+
style: z.enum(["aspectFit", "aspectFill"]).default("aspectFit"),
|
|
159
|
+
})
|
|
160
|
+
.describe("How to handle aspect ratio differences between image and canvas");
|
|
144
161
|
export const mulmoImageParamsSchema = z
|
|
145
162
|
.object({
|
|
146
163
|
model: z.string().optional(), // default: provider specific
|
|
@@ -159,6 +176,11 @@ export const beatAudioParamsSchema = z
|
|
|
159
176
|
padding: z.number().optional().describe("Padding between beats"), // seconds
|
|
160
177
|
})
|
|
161
178
|
.strict();
|
|
179
|
+
export const mulmoHtmlImageParamsSchema = z
|
|
180
|
+
.object({
|
|
181
|
+
model: z.string().optional(), // default: provider specific
|
|
182
|
+
})
|
|
183
|
+
.strict();
|
|
162
184
|
// Note: we can't extend beatAudioParamsSchema because it has padding as optional
|
|
163
185
|
export const audioParamsSchema = z
|
|
164
186
|
.object({
|
|
@@ -171,6 +193,14 @@ export const audioParamsSchema = z
|
|
|
171
193
|
audioVolume: z.number().default(1.0).describe("Volume of the audio"),
|
|
172
194
|
})
|
|
173
195
|
.strict();
|
|
196
|
+
export const htmlPromptParamsSchema = z
|
|
197
|
+
.object({
|
|
198
|
+
systemPrompt: z.string().default("").optional(),
|
|
199
|
+
prompt: z.string().default(""),
|
|
200
|
+
data: z.any().optional(),
|
|
201
|
+
images: z.record(z.any()).optional(),
|
|
202
|
+
})
|
|
203
|
+
.strict();
|
|
174
204
|
export const mulmoBeatSchema = z
|
|
175
205
|
.object({
|
|
176
206
|
speaker: speakerIdSchema.default("Presenter"),
|
|
@@ -182,11 +212,19 @@ export const mulmoBeatSchema = z
|
|
|
182
212
|
duration: z.number().optional().describe("Duration of the beat. Used only when the text is empty"),
|
|
183
213
|
imageParams: mulmoImageParamsSchema.optional(), // beat specific parameters
|
|
184
214
|
audioParams: beatAudioParamsSchema.optional(), // beat specific parameters
|
|
215
|
+
movieParams: z
|
|
216
|
+
.object({
|
|
217
|
+
fillOption: mulmoFillOptionSchema,
|
|
218
|
+
})
|
|
219
|
+
.optional(),
|
|
220
|
+
htmlImageParams: mulmoHtmlImageParamsSchema.optional(),
|
|
185
221
|
speechOptions: speechOptionsSchema.optional(),
|
|
186
222
|
textSlideParams: textSlideParamsSchema.optional(),
|
|
223
|
+
captionParams: mulmoCaptionParamsSchema.optional(),
|
|
187
224
|
imageNames: z.array(imageIdSchema).optional(), // list of image names to use for image generation. The default is all images in the imageParams.images.
|
|
188
225
|
imagePrompt: z.string().optional(),
|
|
189
226
|
moviePrompt: z.string().optional(),
|
|
227
|
+
htmlPrompt: htmlPromptParamsSchema.optional(),
|
|
190
228
|
})
|
|
191
229
|
.strict();
|
|
192
230
|
export const mulmoCanvasDimensionSchema = z
|
|
@@ -209,7 +247,8 @@ export const mulmoSpeechParamsSchema = z
|
|
|
209
247
|
})
|
|
210
248
|
.strict();
|
|
211
249
|
export const text2ImageProviderSchema = z.union([z.literal("openai"), z.literal("google")]).default("openai");
|
|
212
|
-
export const
|
|
250
|
+
export const text2HtmlImageProviderSchema = z.union([z.literal("openai"), z.literal("anthropic")]).default("openai");
|
|
251
|
+
export const text2MovieProviderSchema = z.union([z.literal("openai"), z.literal("google"), z.literal("replicate")]).default("google");
|
|
213
252
|
export const mulmoTransitionSchema = z.object({
|
|
214
253
|
type: z.enum(["fade", "slideout_left"]),
|
|
215
254
|
duration: z.number().min(0).max(2).default(0.3), // transition duration in seconds
|
|
@@ -219,6 +258,7 @@ export const mulmoMovieParamsSchema = z
|
|
|
219
258
|
provider: text2MovieProviderSchema.optional(),
|
|
220
259
|
model: z.string().optional(), // default: provider specific
|
|
221
260
|
transition: mulmoTransitionSchema.optional(),
|
|
261
|
+
fillOption: mulmoFillOptionSchema.optional(),
|
|
222
262
|
})
|
|
223
263
|
.strict();
|
|
224
264
|
export const mulmoPresentationStyleSchema = z.object({
|
|
@@ -240,8 +280,14 @@ export const mulmoPresentationStyleSchema = z.object({
|
|
|
240
280
|
})
|
|
241
281
|
.optional(),
|
|
242
282
|
movieParams: mulmoMovieParamsSchema.optional(),
|
|
283
|
+
htmlImageParams: mulmoHtmlImageParamsSchema
|
|
284
|
+
.extend({
|
|
285
|
+
provider: text2HtmlImageProviderSchema,
|
|
286
|
+
})
|
|
287
|
+
.optional(),
|
|
243
288
|
// for textSlides
|
|
244
289
|
textSlideParams: textSlideParamsSchema.optional(),
|
|
290
|
+
captionParams: mulmoCaptionParamsSchema.optional(),
|
|
245
291
|
audioParams: audioParamsSchema.default({
|
|
246
292
|
introPadding: 1.0,
|
|
247
293
|
padding: 0.3,
|
package/lib/types/type.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema } from "./schema.js";
|
|
1
|
+
import { langSchema, localizedTextSchema, mulmoBeatSchema, mulmoScriptSchema, mulmoStudioSchema, mulmoStudioBeatSchema, mulmoStoryboardSchema, mulmoStoryboardSceneSchema, mulmoStudioMultiLingualSchema, mulmoStudioMultiLingualDataSchema, speakerDictionarySchema, mulmoImageParamsSchema, mulmoImageParamsImagesSchema, mulmoFillOptionSchema, mulmoMovieParamsSchema, mulmoSpeechParamsSchema, textSlideParamsSchema, speechOptionsSchema, speakerDataSchema, mulmoCanvasDimensionSchema, mulmoScriptTemplateSchema, mulmoScriptTemplateFileSchema, text2ImageProviderSchema, text2HtmlImageProviderSchema, text2MovieProviderSchema, text2SpeechProviderSchema, mulmoPresentationStyleSchema, multiLingualTextsSchema, mulmoMermaidMediaSchema, mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mediaSourceSchema, mulmoSessionStateSchema } from "./schema.js";
|
|
2
2
|
import { pdf_modes, pdf_sizes, storyToScriptGenerateMode } from "../utils/const.js";
|
|
3
3
|
import { LLM } from "../utils/utils.js";
|
|
4
4
|
import { z } from "zod";
|
|
@@ -10,8 +10,10 @@ export type SpeechOptions = z.infer<typeof speechOptionsSchema>;
|
|
|
10
10
|
export type SpeakerData = z.infer<typeof speakerDataSchema>;
|
|
11
11
|
export type MulmoImageParams = z.infer<typeof mulmoImageParamsSchema>;
|
|
12
12
|
export type MulmoImageParamsImages = z.infer<typeof mulmoImageParamsImagesSchema>;
|
|
13
|
+
export type MulmoFillOption = z.infer<typeof mulmoFillOptionSchema>;
|
|
13
14
|
export type TextSlideParams = z.infer<typeof textSlideParamsSchema>;
|
|
14
15
|
export type Text2ImageProvider = z.infer<typeof text2ImageProviderSchema>;
|
|
16
|
+
export type Text2HtmlImageProvider = z.infer<typeof text2HtmlImageProviderSchema>;
|
|
15
17
|
export type Text2MovieProvider = z.infer<typeof text2MovieProviderSchema>;
|
|
16
18
|
export type Text2SpeechProvider = z.infer<typeof text2SpeechProviderSchema>;
|
|
17
19
|
export type LocalizedText = z.infer<typeof localizedTextSchema>;
|
|
@@ -49,7 +51,6 @@ export type MulmoStudioContext = {
|
|
|
49
51
|
lang?: string;
|
|
50
52
|
dryRun?: boolean;
|
|
51
53
|
force: boolean;
|
|
52
|
-
caption?: string;
|
|
53
54
|
sessionState: MulmoSessionState;
|
|
54
55
|
presentationStyle: MulmoPresentationStyle;
|
|
55
56
|
multiLingual: MulmoStudioMultiLingual;
|
|
@@ -62,6 +63,7 @@ export type ScriptingParams = {
|
|
|
62
63
|
filename: string;
|
|
63
64
|
llm_model?: string;
|
|
64
65
|
llm?: LLM;
|
|
66
|
+
verbose?: boolean;
|
|
65
67
|
};
|
|
66
68
|
export type ImageProcessorParams = {
|
|
67
69
|
beat: MulmoBeat;
|
|
@@ -77,6 +79,11 @@ export type Text2ImageAgentInfo = {
|
|
|
77
79
|
agent: string;
|
|
78
80
|
imageParams: MulmoImageParams;
|
|
79
81
|
};
|
|
82
|
+
export type Text2HtmlAgentInfo = {
|
|
83
|
+
provider: Text2HtmlImageProvider;
|
|
84
|
+
agent: string;
|
|
85
|
+
model: string;
|
|
86
|
+
};
|
|
80
87
|
export type BeatMediaType = "movie" | "image";
|
|
81
88
|
export type StoryToScriptGenerateMode = (typeof storyToScriptGenerateMode)[keyof typeof storyToScriptGenerateMode];
|
|
82
89
|
export type SessionType = "audio" | "image" | "video" | "multiLingual" | "caption" | "pdf";
|
|
@@ -5,9 +5,9 @@ export type FfmpegContext = {
|
|
|
5
5
|
filterComplex: string[];
|
|
6
6
|
};
|
|
7
7
|
export declare const FfmpegContextInit: () => FfmpegContext;
|
|
8
|
-
export declare const FfmpegContextAddInput: (context: FfmpegContext, input: string) => number;
|
|
8
|
+
export declare const FfmpegContextAddInput: (context: FfmpegContext, input: string, inputOptions?: string[]) => number;
|
|
9
9
|
export declare const FfmpegContextPushFormattedAudio: (context: FfmpegContext, sourceId: string, outputId: string, duration?: number | undefined) => void;
|
|
10
|
-
export declare const FfmpegContextInputFormattedAudio: (context: FfmpegContext, input: string, duration?: number | undefined) => string;
|
|
10
|
+
export declare const FfmpegContextInputFormattedAudio: (context: FfmpegContext, input: string, duration?: number | undefined, inputOptions?: string[]) => string;
|
|
11
11
|
export declare const FfmpegContextGenerateOutput: (context: FfmpegContext, output: string, options?: string[]) => Promise<number>;
|
|
12
12
|
export declare const ffmpegGetMediaDuration: (filePath: string) => Promise<number>;
|
|
13
13
|
export declare const extractImageFromMovie: (movieFile: string, imagePath: string) => Promise<void>;
|
|
@@ -7,8 +7,13 @@ export const FfmpegContextInit = () => {
|
|
|
7
7
|
filterComplex: [],
|
|
8
8
|
};
|
|
9
9
|
};
|
|
10
|
-
export const FfmpegContextAddInput = (context, input) => {
|
|
11
|
-
|
|
10
|
+
export const FfmpegContextAddInput = (context, input, inputOptions) => {
|
|
11
|
+
if (inputOptions) {
|
|
12
|
+
context.command.input(input).inputOptions(inputOptions);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
context.command.input(input);
|
|
16
|
+
}
|
|
12
17
|
context.inputCount++;
|
|
13
18
|
return context.inputCount - 1; // returned the index of the input
|
|
14
19
|
};
|
|
@@ -20,8 +25,8 @@ export const FfmpegContextPushFormattedAudio = (context, sourceId, outputId, dur
|
|
|
20
25
|
context.filterComplex.push(`${sourceId}aformat=sample_fmts=fltp:sample_rates=44100:channel_layouts=stereo${outputId}`);
|
|
21
26
|
}
|
|
22
27
|
};
|
|
23
|
-
export const FfmpegContextInputFormattedAudio = (context, input, duration = undefined) => {
|
|
24
|
-
const index = FfmpegContextAddInput(context, input);
|
|
28
|
+
export const FfmpegContextInputFormattedAudio = (context, input, duration = undefined, inputOptions) => {
|
|
29
|
+
const index = FfmpegContextAddInput(context, input, inputOptions);
|
|
25
30
|
const audioId = `[a${index}]`;
|
|
26
31
|
FfmpegContextPushFormattedAudio(context, `[${index}:a]`, audioId, duration);
|
|
27
32
|
return audioId;
|
|
@@ -182,8 +182,8 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
182
182
|
} | undefined;
|
|
183
183
|
description?: string | undefined;
|
|
184
184
|
imageParams?: {
|
|
185
|
-
model?: string | undefined;
|
|
186
185
|
style?: string | undefined;
|
|
186
|
+
model?: string | undefined;
|
|
187
187
|
moderation?: string | undefined;
|
|
188
188
|
images?: Record<string, {
|
|
189
189
|
type: "image";
|
|
@@ -205,20 +205,44 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
205
205
|
audioParams?: {
|
|
206
206
|
padding?: number | undefined;
|
|
207
207
|
} | undefined;
|
|
208
|
+
movieParams?: {
|
|
209
|
+
fillOption: {
|
|
210
|
+
style: "aspectFit" | "aspectFill";
|
|
211
|
+
};
|
|
212
|
+
} | undefined;
|
|
213
|
+
htmlImageParams?: {
|
|
214
|
+
model?: string | undefined;
|
|
215
|
+
} | undefined;
|
|
208
216
|
textSlideParams?: {
|
|
209
217
|
cssStyles: string | string[];
|
|
210
218
|
} | undefined;
|
|
219
|
+
captionParams?: {
|
|
220
|
+
textColor: string;
|
|
221
|
+
backgroundColor: string;
|
|
222
|
+
fontSize: number;
|
|
223
|
+
fontFamily: string;
|
|
224
|
+
fontWeight: string;
|
|
225
|
+
textAlign: string;
|
|
226
|
+
textDecoration: string;
|
|
227
|
+
lang?: string | undefined;
|
|
228
|
+
} | undefined;
|
|
211
229
|
imageNames?: string[] | undefined;
|
|
212
230
|
imagePrompt?: string | undefined;
|
|
213
231
|
moviePrompt?: string | undefined;
|
|
232
|
+
htmlPrompt?: {
|
|
233
|
+
prompt: string;
|
|
234
|
+
data?: any;
|
|
235
|
+
images?: Record<string, any> | undefined;
|
|
236
|
+
systemPrompt?: string | undefined;
|
|
237
|
+
} | undefined;
|
|
214
238
|
}[];
|
|
215
239
|
lang?: string | undefined;
|
|
216
240
|
title?: string | undefined;
|
|
217
241
|
description?: string | undefined;
|
|
218
242
|
imageParams?: {
|
|
219
243
|
provider: "openai" | "google";
|
|
220
|
-
model?: string | undefined;
|
|
221
244
|
style?: string | undefined;
|
|
245
|
+
model?: string | undefined;
|
|
222
246
|
moderation?: string | undefined;
|
|
223
247
|
images?: Record<string, {
|
|
224
248
|
type: "image";
|
|
@@ -237,17 +261,34 @@ export declare const createOrUpdateStudioData: (_mulmoScript: MulmoScript, curre
|
|
|
237
261
|
};
|
|
238
262
|
}> | undefined;
|
|
239
263
|
} | undefined;
|
|
240
|
-
textSlideParams?: {
|
|
241
|
-
cssStyles: string | string[];
|
|
242
|
-
} | undefined;
|
|
243
264
|
movieParams?: {
|
|
244
|
-
provider?: "openai" | "google" | undefined;
|
|
265
|
+
provider?: "openai" | "google" | "replicate" | undefined;
|
|
245
266
|
model?: string | undefined;
|
|
267
|
+
fillOption?: {
|
|
268
|
+
style: "aspectFit" | "aspectFill";
|
|
269
|
+
} | undefined;
|
|
246
270
|
transition?: {
|
|
247
271
|
type: "fade" | "slideout_left";
|
|
248
272
|
duration: number;
|
|
249
273
|
} | undefined;
|
|
250
274
|
} | undefined;
|
|
275
|
+
htmlImageParams?: {
|
|
276
|
+
provider: "openai" | "anthropic";
|
|
277
|
+
model?: string | undefined;
|
|
278
|
+
} | undefined;
|
|
279
|
+
textSlideParams?: {
|
|
280
|
+
cssStyles: string | string[];
|
|
281
|
+
} | undefined;
|
|
282
|
+
captionParams?: {
|
|
283
|
+
textColor: string;
|
|
284
|
+
backgroundColor: string;
|
|
285
|
+
fontSize: number;
|
|
286
|
+
fontFamily: string;
|
|
287
|
+
fontWeight: string;
|
|
288
|
+
textAlign: string;
|
|
289
|
+
textDecoration: string;
|
|
290
|
+
lang?: string | undefined;
|
|
291
|
+
} | undefined;
|
|
251
292
|
references?: {
|
|
252
293
|
type: "image" | "audio" | "article" | "paper" | "video";
|
|
253
294
|
url: string;
|
package/lib/utils/utils.d.ts
CHANGED
|
@@ -16,3 +16,4 @@ export declare const isHttp: (fileOrUrl: string) => boolean;
|
|
|
16
16
|
export declare const text2hash: (input: string) => string;
|
|
17
17
|
export declare const localizedText: (beat: MulmoBeat, multiLingualData?: MulmoStudioMultiLingualData, lang?: string) => string;
|
|
18
18
|
export declare const sleep: (milliseconds: number) => Promise<unknown>;
|
|
19
|
+
export declare function userAssert(condition: boolean, message: string): asserts condition;
|
package/lib/utils/utils.js
CHANGED
|
@@ -55,3 +55,8 @@ export const localizedText = (beat, multiLingualData, lang) => {
|
|
|
55
55
|
export const sleep = async (milliseconds) => {
|
|
56
56
|
return await new Promise((resolve) => setTimeout(resolve, milliseconds));
|
|
57
57
|
};
|
|
58
|
+
export function userAssert(condition, message) {
|
|
59
|
+
if (!condition) {
|
|
60
|
+
throw new Error(message);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mulmocast",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.23",
|
|
4
4
|
"description": "",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
@@ -74,11 +74,12 @@
|
|
|
74
74
|
"dotenv": "^16.4.7",
|
|
75
75
|
"fluent-ffmpeg": "^2.1.3",
|
|
76
76
|
"google-auth-library": "^9.15.1",
|
|
77
|
-
"graphai": "^2.0.
|
|
77
|
+
"graphai": "^2.0.9",
|
|
78
78
|
"inquirer": "^12.6.1",
|
|
79
79
|
"marked": "^15.0.12",
|
|
80
80
|
"ora": "^8.2.0",
|
|
81
81
|
"puppeteer": "^24.10.2",
|
|
82
|
+
"replicate": "^1.0.1",
|
|
82
83
|
"yaml": "^2.8.0",
|
|
83
84
|
"yargs": "^17.7.2",
|
|
84
85
|
"zod": "^3.25.67",
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$mulmocast": {
|
|
3
|
+
"version": "1.0",
|
|
4
|
+
"credit": "closing"
|
|
5
|
+
},
|
|
6
|
+
"htmlImageParams": {
|
|
7
|
+
"provider": "anthropic",
|
|
8
|
+
"model": "claude-3-7-sonnet-20250219"
|
|
9
|
+
},
|
|
10
|
+
"title": "Sample Title",
|
|
11
|
+
"references": [
|
|
12
|
+
{
|
|
13
|
+
"url": "https://www.somegreatwebsite.com/article/123",
|
|
14
|
+
"title": "Title of the article we are referencing",
|
|
15
|
+
"type": "article"
|
|
16
|
+
}
|
|
17
|
+
],
|
|
18
|
+
"lang": "en",
|
|
19
|
+
"beats": [
|
|
20
|
+
{
|
|
21
|
+
"speaker": "Presenter",
|
|
22
|
+
"text": "Book rooms with locals, not hotels.",
|
|
23
|
+
"htmlPrompt": {
|
|
24
|
+
"prompt": "Create a clean and bold title slide featuring the original name 'AirBed & Breakfast' with the tagline: 'Book rooms with locals, not hotels'. Include the old logo and a travel-themed background."
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
"speaker": "Presenter",
|
|
29
|
+
"text": "Hotels are expensive and detached from local culture.",
|
|
30
|
+
"htmlPrompt": {
|
|
31
|
+
"prompt": "Design a slide that lists the main problems with hotels: high prices, lack of personality, and cultural disconnection. Use simple icons for cost, generic room, and traveler."
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"speaker": "Presenter",
|
|
36
|
+
"text": "Airbnb lets people rent out their spaces, offering affordable, authentic experiences.",
|
|
37
|
+
"htmlPrompt": {
|
|
38
|
+
"prompt": "Illustrate Airbnb's solution: locals listing their spare rooms or homes, travelers booking directly, and both benefiting. Use a flow diagram to represent this."
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"speaker": "Presenter",
|
|
43
|
+
"text": "Craigslist and Couchsurfing prove the demand for alternative lodging.",
|
|
44
|
+
"htmlPrompt": {
|
|
45
|
+
"prompt": "Show a bar graph comparing Craigslist listings, Couchsurfing users, and early Airbnb listings to demonstrate existing demand and opportunity."
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"speaker": "Presenter",
|
|
50
|
+
"text": "A massive market: over 630 million travel bookings annually.",
|
|
51
|
+
"htmlPrompt": {
|
|
52
|
+
"prompt": "Visualize the global travel booking market. Use a world map and large numbers to emphasize the size and growth potential."
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"speaker": "Presenter",
|
|
57
|
+
"text": "Our platform enables hosts to list once and earn; guests search, book, and review.",
|
|
58
|
+
"htmlPrompt": {
|
|
59
|
+
"prompt": "Create a product overview slide showing how the platform works from host listing to guest review. Highlight simplicity and trust."
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"speaker": "Presenter",
|
|
64
|
+
"text": "We charge a 10% commission per booking.",
|
|
65
|
+
"htmlPrompt": {
|
|
66
|
+
"prompt": "Display a slide with the monetization strategy—Airbnb earns through a 10% commission. Use a simple pie chart or booking flow with fee annotation."
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"speaker": "Presenter",
|
|
71
|
+
"text": "Competitors include hotels, Craigslist, Couchsurfing — we offer a better, scalable solution.",
|
|
72
|
+
"htmlPrompt": {
|
|
73
|
+
"prompt": "Design a comparison table: price, uniqueness, trust, scalability. Airbnb should clearly stand out on all dimensions."
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"speaker": "Presenter",
|
|
78
|
+
"text": "Key advantages: lower price, wide selection, ease of use, host incentives, trusted system.",
|
|
79
|
+
"htmlPrompt": {
|
|
80
|
+
"prompt": "List Airbnb’s competitive advantages using 6 icons or badges, one for each feature."
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"speaker": "Presenter",
|
|
85
|
+
"text": "Founders: Brian Chesky (Design), Joe Gebbia (Marketing), Nathan Blecharczyk (Engineering).",
|
|
86
|
+
"htmlPrompt": {
|
|
87
|
+
"prompt": "Introduce the founding team with photos and brief bios. Highlight their roles and strengths in product, marketing, and tech."
|
|
88
|
+
}
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"speaker": "Presenter",
|
|
92
|
+
"text": "Media buzz: featured on TechCrunch and buzz from SXSW.",
|
|
93
|
+
"htmlPrompt": {
|
|
94
|
+
"prompt": "Showcase media recognition. Include TechCrunch logo and SXSW quotes or metrics. This adds credibility and traction."
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"speaker": "Presenter",
|
|
99
|
+
"text": "Early users love the authentic and affordable experiences.",
|
|
100
|
+
"htmlPrompt": {
|
|
101
|
+
"prompt": "Add 2–3 short testimonials from early users (guests and hosts), displayed in speech bubbles with faces or usernames."
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"speaker": "Presenter",
|
|
106
|
+
"text": "We’re raising $600K to support 12 months of growth and reach 80K bookings with $2M in revenue.",
|
|
107
|
+
"htmlPrompt": {
|
|
108
|
+
"prompt": "Closing investment slide. Include fund usage (pie chart: 40% marketing, 30% product, 30% ops), and KPIs: 80K bookings, $2M revenue.",
|
|
109
|
+
"data": {
|
|
110
|
+
"ask": 600000,
|
|
111
|
+
"duration_months": 12,
|
|
112
|
+
"target_bookings": 80000,
|
|
113
|
+
"target_revenue": 2000000,
|
|
114
|
+
"use_of_funds": {
|
|
115
|
+
"marketing": 40,
|
|
116
|
+
"product": 30,
|
|
117
|
+
"operations": 30
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
]
|
|
123
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$mulmocast": {
|
|
3
|
+
"version": "1.0",
|
|
4
|
+
"credit": "closing"
|
|
5
|
+
},
|
|
6
|
+
"title": "Sample Title",
|
|
7
|
+
"references": [
|
|
8
|
+
{
|
|
9
|
+
"url": "https://www.somegreatwebsite.com/article/123",
|
|
10
|
+
"title": "Title of the article we are referencing",
|
|
11
|
+
"type": "article"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"lang": "en",
|
|
15
|
+
"beats": [
|
|
16
|
+
{
|
|
17
|
+
"speaker": "Presenter",
|
|
18
|
+
"text": "Book rooms with locals, not hotels.",
|
|
19
|
+
"htmlPrompt": {
|
|
20
|
+
"prompt": "Create a clean and bold title slide featuring the original name 'AirBed & Breakfast' with the tagline: 'Book rooms with locals, not hotels'. Include the old logo and a travel-themed background."
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"speaker": "Presenter",
|
|
25
|
+
"text": "Hotels are expensive and detached from local culture.",
|
|
26
|
+
"htmlPrompt": {
|
|
27
|
+
"prompt": "Design a slide that lists the main problems with hotels: high prices, lack of personality, and cultural disconnection. Use simple icons for cost, generic room, and traveler."
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"speaker": "Presenter",
|
|
32
|
+
"text": "Airbnb lets people rent out their spaces, offering affordable, authentic experiences.",
|
|
33
|
+
"htmlPrompt": {
|
|
34
|
+
"prompt": "Illustrate Airbnb's solution: locals listing their spare rooms or homes, travelers booking directly, and both benefiting. Use a flow diagram to represent this."
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
"speaker": "Presenter",
|
|
39
|
+
"text": "Craigslist and Couchsurfing prove the demand for alternative lodging.",
|
|
40
|
+
"htmlPrompt": {
|
|
41
|
+
"prompt": "Show a bar graph comparing Craigslist listings, Couchsurfing users, and early Airbnb listings to demonstrate existing demand and opportunity."
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"speaker": "Presenter",
|
|
46
|
+
"text": "A massive market: over 630 million travel bookings annually.",
|
|
47
|
+
"htmlPrompt": {
|
|
48
|
+
"prompt": "Visualize the global travel booking market. Use a world map and large numbers to emphasize the size and growth potential."
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"speaker": "Presenter",
|
|
53
|
+
"text": "Our platform enables hosts to list once and earn; guests search, book, and review.",
|
|
54
|
+
"htmlPrompt": {
|
|
55
|
+
"prompt": "Create a product overview slide showing how the platform works from host listing to guest review. Highlight simplicity and trust."
|
|
56
|
+
}
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
"speaker": "Presenter",
|
|
60
|
+
"text": "We charge a 10% commission per booking.",
|
|
61
|
+
"htmlPrompt": {
|
|
62
|
+
"prompt": "Display a slide with the monetization strategy—Airbnb earns through a 10% commission. Use a simple pie chart or booking flow with fee annotation."
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"speaker": "Presenter",
|
|
67
|
+
"text": "Competitors include hotels, Craigslist, Couchsurfing — we offer a better, scalable solution.",
|
|
68
|
+
"htmlPrompt": {
|
|
69
|
+
"prompt": "Design a comparison table: price, uniqueness, trust, scalability. Airbnb should clearly stand out on all dimensions."
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"speaker": "Presenter",
|
|
74
|
+
"text": "Key advantages: lower price, wide selection, ease of use, host incentives, trusted system.",
|
|
75
|
+
"htmlPrompt": {
|
|
76
|
+
"prompt": "List Airbnb’s competitive advantages using 6 icons or badges, one for each feature."
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
"speaker": "Presenter",
|
|
81
|
+
"text": "Founders: Brian Chesky (Design), Joe Gebbia (Marketing), Nathan Blecharczyk (Engineering).",
|
|
82
|
+
"htmlPrompt": {
|
|
83
|
+
"prompt": "Introduce the founding team with photos and brief bios. Highlight their roles and strengths in product, marketing, and tech."
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"speaker": "Presenter",
|
|
88
|
+
"text": "Media buzz: featured on TechCrunch and buzz from SXSW.",
|
|
89
|
+
"htmlPrompt": {
|
|
90
|
+
"prompt": "Showcase media recognition. Include TechCrunch logo and SXSW quotes or metrics. This adds credibility and traction."
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"speaker": "Presenter",
|
|
95
|
+
"text": "Early users love the authentic and affordable experiences.",
|
|
96
|
+
"htmlPrompt": {
|
|
97
|
+
"prompt": "Add 2–3 short testimonials from early users (guests and hosts), displayed in speech bubbles with faces or usernames."
|
|
98
|
+
}
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"speaker": "Presenter",
|
|
102
|
+
"text": "We’re raising $600K to support 12 months of growth and reach 80K bookings with $2M in revenue.",
|
|
103
|
+
"htmlPrompt": {
|
|
104
|
+
"prompt": "Closing investment slide. Include fund usage (pie chart: 40% marketing, 30% product, 30% ops), and KPIs: 80K bookings, $2M revenue.",
|
|
105
|
+
"data": {
|
|
106
|
+
"ask": 600000,
|
|
107
|
+
"duration_months": 12,
|
|
108
|
+
"target_bookings": 80000,
|
|
109
|
+
"target_revenue": 2000000,
|
|
110
|
+
"use_of_funds": {
|
|
111
|
+
"marketing": 40,
|
|
112
|
+
"product": 30,
|
|
113
|
+
"operations": 30
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
]
|
|
119
|
+
}
|