mulmocast 0.0.1 → 0.0.3

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.
Files changed (115) hide show
  1. package/README.md +129 -15
  2. package/assets/font/NotoSansJP-Regular.ttf +0 -0
  3. package/assets/html/chart.html +38 -0
  4. package/assets/html/mermaid.html +51 -0
  5. package/assets/templates/business.json +57 -14
  6. package/assets/templates/children_book.json +1 -3
  7. package/assets/templates/coding.json +140 -0
  8. package/lib/actions/audio.d.ts +2 -2
  9. package/lib/actions/audio.js +88 -101
  10. package/lib/actions/images.d.ts +1 -1
  11. package/lib/actions/images.js +50 -88
  12. package/lib/actions/index.d.ts +5 -0
  13. package/lib/actions/index.js +5 -0
  14. package/lib/actions/movie.d.ts +9 -1
  15. package/lib/actions/movie.js +124 -65
  16. package/lib/actions/pdf.d.ts +2 -0
  17. package/lib/actions/pdf.js +211 -0
  18. package/lib/actions/pdf2.d.ts +2 -0
  19. package/lib/actions/pdf2.js +203 -0
  20. package/lib/actions/translate.d.ts +1 -1
  21. package/lib/actions/translate.js +38 -61
  22. package/lib/agents/add_bgm_agent.d.ts +1 -1
  23. package/lib/agents/add_bgm_agent.js +10 -14
  24. package/lib/agents/anthropic_agent.d.ts +23 -0
  25. package/lib/agents/anthropic_agent.js +162 -0
  26. package/lib/agents/combine_audio_files_agent.d.ts +1 -1
  27. package/lib/agents/combine_audio_files_agent.js +33 -32
  28. package/lib/agents/image_google_agent.d.ts +1 -1
  29. package/lib/agents/image_google_agent.js +8 -11
  30. package/lib/agents/image_openai_agent.js +7 -14
  31. package/lib/agents/index.d.ts +8 -8
  32. package/lib/agents/index.js +13 -30
  33. package/lib/agents/mulmo_prompts_agent.d.ts +1 -1
  34. package/lib/agents/mulmo_prompts_agent.js +7 -11
  35. package/lib/agents/nested_agent.d.ts +9 -0
  36. package/lib/agents/nested_agent.js +138 -0
  37. package/lib/agents/prompts_data.js +1 -4
  38. package/lib/agents/tts_nijivoice_agent.d.ts +1 -1
  39. package/lib/agents/tts_nijivoice_agent.js +8 -12
  40. package/lib/agents/tts_openai_agent.js +9 -16
  41. package/lib/agents/validate_mulmo_script_agent.d.ts +1 -1
  42. package/lib/agents/validate_mulmo_script_agent.js +6 -10
  43. package/lib/cli/args.d.ts +5 -2
  44. package/lib/cli/args.js +52 -35
  45. package/lib/cli/cli.d.ts +14 -0
  46. package/lib/cli/cli.js +74 -57
  47. package/lib/cli/common.js +1 -5
  48. package/lib/cli/tool-args.d.ts +4 -1
  49. package/lib/cli/tool-args.js +29 -18
  50. package/lib/cli/tool-cli.js +34 -51
  51. package/lib/methods/index.d.ts +4 -3
  52. package/lib/methods/index.js +4 -19
  53. package/lib/methods/mulmo_media_source.d.ts +4 -0
  54. package/lib/methods/mulmo_media_source.js +21 -0
  55. package/lib/methods/mulmo_script.d.ts +6 -5
  56. package/lib/methods/mulmo_script.js +29 -16
  57. package/lib/methods/mulmo_script_template.d.ts +1 -1
  58. package/lib/methods/mulmo_script_template.js +4 -10
  59. package/lib/methods/mulmo_studio_context.d.ts +1 -1
  60. package/lib/methods/mulmo_studio_context.js +3 -9
  61. package/lib/tools/create_mulmo_script_from_url.d.ts +3 -0
  62. package/lib/tools/create_mulmo_script_from_url.js +152 -0
  63. package/lib/tools/create_mulmo_script_interactively.d.ts +3 -0
  64. package/lib/tools/create_mulmo_script_interactively.js +258 -0
  65. package/lib/tools/dump_prompt.js +5 -8
  66. package/lib/tools/prompt.js +9 -11
  67. package/lib/tools/seed_from_url2.d.ts +3 -0
  68. package/lib/tools/seed_from_url2.js +154 -0
  69. package/lib/types/index.d.ts +2 -1
  70. package/lib/types/index.js +2 -17
  71. package/lib/types/schema.d.ts +3624 -2798
  72. package/lib/types/schema.js +172 -123
  73. package/lib/types/type.d.ts +34 -3
  74. package/lib/types/type.js +1 -2
  75. package/lib/utils/const.d.ts +4 -1
  76. package/lib/utils/const.js +6 -6
  77. package/lib/utils/file.d.ts +22 -4
  78. package/lib/utils/file.js +100 -79
  79. package/lib/utils/filters.d.ts +1 -0
  80. package/lib/utils/filters.js +47 -26
  81. package/lib/utils/image_plugins/chart.d.ts +3 -0
  82. package/lib/utils/image_plugins/chart.js +18 -0
  83. package/lib/utils/image_plugins/image.d.ts +2 -0
  84. package/lib/utils/image_plugins/image.js +3 -0
  85. package/lib/utils/image_plugins/index.d.ts +7 -0
  86. package/lib/utils/image_plugins/index.js +7 -0
  87. package/lib/utils/image_plugins/markdown.d.ts +3 -0
  88. package/lib/utils/image_plugins/markdown.js +11 -0
  89. package/lib/utils/image_plugins/mermaid.d.ts +3 -0
  90. package/lib/utils/image_plugins/mermaid.js +21 -0
  91. package/lib/utils/image_plugins/movie.d.ts +2 -0
  92. package/lib/utils/image_plugins/movie.js +3 -0
  93. package/lib/utils/image_plugins/source.d.ts +4 -0
  94. package/lib/utils/image_plugins/source.js +15 -0
  95. package/lib/utils/image_plugins/text_slide.d.ts +3 -0
  96. package/lib/utils/image_plugins/text_slide.js +12 -0
  97. package/lib/utils/image_plugins/type_guards.d.ts +6 -0
  98. package/lib/utils/image_plugins/type_guards.js +21 -0
  99. package/lib/utils/image_preprocess.d.ts +14 -0
  100. package/lib/utils/image_preprocess.js +52 -0
  101. package/lib/utils/inquirer.d.ts +2 -0
  102. package/lib/utils/inquirer.js +33 -0
  103. package/lib/utils/markdown.d.ts +3 -1
  104. package/lib/utils/markdown.js +20 -19
  105. package/lib/utils/pdf.d.ts +8 -0
  106. package/lib/utils/pdf.js +75 -0
  107. package/lib/utils/plugins.d.ts +5 -0
  108. package/lib/utils/plugins.js +11 -0
  109. package/lib/utils/preprocess.d.ts +70 -123
  110. package/lib/utils/preprocess.js +37 -43
  111. package/lib/utils/string.js +4 -10
  112. package/lib/utils/text_hash.js +2 -39
  113. package/lib/utils/utils.d.ts +12 -0
  114. package/lib/utils/utils.js +34 -0
  115. package/package.json +23 -8
package/lib/utils/file.js CHANGED
@@ -1,112 +1,133 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.writingMessage = exports.getAvailableTemplates = exports.readTemplatePrompt = exports.getFullPath = exports.getBaseDirPath = exports.defaultBGMPath = exports.silentLastPath = exports.silentPath = exports.mkdir = exports.getTemplateFilePath = exports.getScratchpadFilePath = exports.getOutputAudioFilePath = exports.getOutputVideoFilePath = exports.getOutputBGMFilePath = exports.getOutputStudioFilePath = void 0;
7
- exports.readMulmoScriptFile = readMulmoScriptFile;
8
- const fs_1 = __importDefault(require("fs"));
9
- const path_1 = __importDefault(require("path"));
10
- const graphai_1 = require("graphai");
11
- const mulmo_script_template_1 = require("../methods/mulmo_script_template");
12
- const schema_1 = require("../types/schema");
13
- function readMulmoScriptFile(arg2, errorMessage) {
14
- const scriptPath = path_1.default.resolve(arg2);
15
- if (!fs_1.default.existsSync(scriptPath)) {
1
+ import fs from "fs";
2
+ import path from "path";
3
+ import { parse as yamlParse } from "yaml";
4
+ import { fileURLToPath } from "url";
5
+ import { GraphAILogger } from "graphai";
6
+ import { MulmoScriptTemplateMethods } from "../methods/mulmo_script_template.js";
7
+ import { MulmoStudioContextMethods } from "../methods/index.js";
8
+ import { mulmoScriptTemplateSchema } from "../types/schema.js";
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+ export function readMulmoScriptFile(arg2, errorMessage) {
12
+ const scriptPath = path.resolve(arg2);
13
+ if (!fs.existsSync(scriptPath)) {
16
14
  if (errorMessage) {
17
- console.error(errorMessage);
15
+ GraphAILogger.info(errorMessage);
18
16
  process.exit(1);
19
17
  }
20
18
  return null;
21
19
  }
22
- const scriptData = fs_1.default.readFileSync(scriptPath, "utf-8");
23
- const script = JSON.parse(scriptData);
24
- const parsedPath = path_1.default.parse(scriptPath);
20
+ const scriptData = fs.readFileSync(scriptPath, "utf-8");
21
+ const script = ([".yaml", ".yml"].includes(path.extname(scriptPath).toLowerCase()) ? yamlParse(scriptData) : JSON.parse(scriptData));
22
+ const parsedPath = path.parse(scriptPath);
25
23
  return {
26
24
  mulmoData: script,
27
25
  mulmoDataPath: scriptPath,
28
26
  fileName: parsedPath.name,
29
27
  };
30
28
  }
31
- const getOutputStudioFilePath = (outDirPath, fileName) => {
32
- return path_1.default.resolve(outDirPath, fileName + "_studio.json");
33
- };
34
- exports.getOutputStudioFilePath = getOutputStudioFilePath;
35
- const getOutputBGMFilePath = (outDirPath, fileName) => {
36
- return path_1.default.resolve(outDirPath, fileName + "_bgm.mp3");
37
- };
38
- exports.getOutputBGMFilePath = getOutputBGMFilePath;
39
- const getOutputVideoFilePath = (outDirPath, fileName) => {
40
- return path_1.default.resolve(outDirPath, fileName + ".mp4");
41
- };
42
- exports.getOutputVideoFilePath = getOutputVideoFilePath;
43
- const getOutputAudioFilePath = (outDirPath, fileName) => {
44
- return path_1.default.resolve(outDirPath, fileName + ".mp3");
45
- };
46
- exports.getOutputAudioFilePath = getOutputAudioFilePath;
47
- const getScratchpadFilePath = (scratchpadDirName, fileName) => {
48
- return path_1.default.resolve(scratchpadDirName, fileName + ".mp3");
49
- };
50
- exports.getScratchpadFilePath = getScratchpadFilePath;
51
- const getTemplateFilePath = (templateName) => {
52
- return path_1.default.resolve(__dirname, "../../assets/templates/" + templateName + ".json");
53
- };
54
- exports.getTemplateFilePath = getTemplateFilePath;
55
- const mkdir = (dirPath) => {
56
- if (!fs_1.default.existsSync(dirPath)) {
57
- console.info("mkdir: " + dirPath);
58
- fs_1.default.mkdirSync(dirPath, { recursive: true });
29
+ export const fetchMulmoScriptFile = async (url) => {
30
+ try {
31
+ const res = await fetch(url);
32
+ if (!res.ok) {
33
+ return { result: false, status: res.status };
34
+ }
35
+ const script = await res.json();
36
+ return {
37
+ result: true,
38
+ script,
39
+ };
59
40
  }
41
+ catch {
42
+ return { result: false, status: "unknown" };
43
+ }
44
+ };
45
+ export const getOutputStudioFilePath = (outDirPath, fileName) => {
46
+ return path.resolve(outDirPath, fileName + "_studio.json");
47
+ };
48
+ export const getAudioSegmentDirPath = (audioDirPath, studioFileName) => {
49
+ return path.resolve(audioDirPath, studioFileName);
50
+ };
51
+ export const getAudioSegmentFilePath = (audioDirPath, studioFileName, fileName) => {
52
+ return path.resolve(getAudioSegmentDirPath(audioDirPath, studioFileName), fileName + ".mp3");
53
+ };
54
+ export const getAudioCombinedFilePath = (audioDirPath, fileName) => {
55
+ return path.resolve(audioDirPath, fileName, fileName + ".mp3");
56
+ };
57
+ export const getAudioArtifactFilePath = (outDirPath, fileName) => {
58
+ return path.resolve(outDirPath, fileName + ".mp3");
59
+ };
60
+ export const getOutputVideoFilePath = (outDirPath, fileName) => {
61
+ return path.resolve(outDirPath, fileName + ".mp4");
62
+ };
63
+ export const getOutputPdfFilePath = (outDirPath, fileName, pdfMode) => {
64
+ return path.resolve(outDirPath, fileName + "_" + pdfMode + ".pdf");
65
+ };
66
+ export const getTemplateFilePath = (templateName) => {
67
+ return path.resolve(__dirname, "../../assets/templates/" + templateName + ".json");
68
+ };
69
+ export const mkdir = (dirPath) => {
70
+ if (!fs.existsSync(dirPath)) {
71
+ GraphAILogger.info("mkdir: " + dirPath);
72
+ fs.mkdirSync(dirPath, { recursive: true });
73
+ }
74
+ };
75
+ export const silentPath = path.resolve(__dirname, "../../assets/audio/silent300.mp3");
76
+ export const silentLastPath = path.resolve(__dirname, "../../assets/audio/silent800.mp3");
77
+ export const defaultBGMPath = path.resolve(__dirname, "../../assets/music/StarsBeyondEx.mp3");
78
+ export const getHTMLFile = (filename) => {
79
+ const htmlPath = path.resolve(__dirname, `../../assets/html/${filename}.html`);
80
+ return fs.readFileSync(htmlPath, "utf-8");
60
81
  };
61
- exports.mkdir = mkdir;
62
- exports.silentPath = path_1.default.resolve(__dirname, "../../assets/audio/silent300.mp3");
63
- exports.silentLastPath = path_1.default.resolve(__dirname, "../../assets/audio/silent800.mp3");
64
- exports.defaultBGMPath = path_1.default.resolve(__dirname, "../../assets/music/StarsBeyondEx.mp3");
65
82
  // for cli
66
- const getBaseDirPath = (basedir) => {
83
+ export const getBaseDirPath = (basedir) => {
67
84
  if (!basedir) {
68
85
  return process.cwd();
69
86
  }
70
- if (path_1.default.isAbsolute(basedir)) {
71
- return path_1.default.normalize(basedir);
87
+ if (path.isAbsolute(basedir)) {
88
+ return path.normalize(basedir);
72
89
  }
73
- return path_1.default.resolve(process.cwd(), basedir);
90
+ return path.resolve(process.cwd(), basedir);
74
91
  };
75
- exports.getBaseDirPath = getBaseDirPath;
76
- const getFullPath = (baseDirPath, file) => {
77
- if (path_1.default.isAbsolute(file)) {
78
- return path_1.default.normalize(file);
92
+ export const getFullPath = (baseDirPath, file) => {
93
+ if (path.isAbsolute(file)) {
94
+ return path.normalize(file);
79
95
  }
80
96
  if (baseDirPath) {
81
- return path_1.default.resolve(baseDirPath, file);
97
+ return path.resolve(baseDirPath, file);
82
98
  }
83
- return path_1.default.resolve(file);
84
- };
85
- exports.getFullPath = getFullPath;
86
- const readTemplatePrompt = (templateName) => {
87
- const templatePath = (0, exports.getTemplateFilePath)(templateName);
88
- const scriptData = fs_1.default.readFileSync(templatePath, "utf-8");
89
- const template = schema_1.mulmoScriptTemplateSchema.parse(JSON.parse(scriptData));
90
- const prompt = mulmo_script_template_1.MulmoScriptTemplateMethods.getSystemPrompt(template);
99
+ return path.resolve(file);
100
+ };
101
+ export const readTemplatePrompt = (templateName) => {
102
+ const templatePath = getTemplateFilePath(templateName);
103
+ const scriptData = fs.readFileSync(templatePath, "utf-8");
104
+ const template = mulmoScriptTemplateSchema.parse(JSON.parse(scriptData));
105
+ const prompt = MulmoScriptTemplateMethods.getSystemPrompt(template);
91
106
  return prompt;
92
107
  };
93
- exports.readTemplatePrompt = readTemplatePrompt;
94
- const getAvailableTemplates = () => {
95
- const templatesDir = path_1.default.resolve(__dirname, "../../assets/templates");
96
- if (!fs_1.default.existsSync(templatesDir)) {
108
+ export const getAvailableTemplates = () => {
109
+ const templatesDir = path.resolve(__dirname, "../../assets/templates");
110
+ if (!fs.existsSync(templatesDir)) {
97
111
  return [];
98
112
  }
99
- const files = fs_1.default.readdirSync(templatesDir);
113
+ const files = fs.readdirSync(templatesDir);
100
114
  return files.map((file) => {
101
- const template = JSON.parse(fs_1.default.readFileSync(path_1.default.resolve(templatesDir, file), "utf-8"));
115
+ const template = JSON.parse(fs.readFileSync(path.resolve(templatesDir, file), "utf-8"));
102
116
  return {
103
- ...schema_1.mulmoScriptTemplateSchema.parse(template),
117
+ ...mulmoScriptTemplateSchema.parse(template),
104
118
  filename: file.replace(/\.json$/, ""),
105
119
  };
106
120
  });
107
121
  };
108
- exports.getAvailableTemplates = getAvailableTemplates;
109
- const writingMessage = (filePath) => {
110
- graphai_1.GraphAILogger.info(`writing: ${filePath}`);
122
+ export const writingMessage = (filePath) => {
123
+ GraphAILogger.info(`writing: ${filePath}`);
124
+ };
125
+ export const resolveMediaSource = (source, context) => {
126
+ if (source.kind === "path") {
127
+ return MulmoStudioContextMethods.resolveAssetPath(context, source.path);
128
+ }
129
+ if (source.kind === "url") {
130
+ return source.url;
131
+ }
132
+ return null;
111
133
  };
112
- exports.writingMessage = writingMessage;
@@ -1,3 +1,4 @@
1
1
  import "dotenv/config";
2
2
  import type { AgentFilterFunction } from "graphai";
3
3
  export declare const fileCacheAgentFilter: AgentFilterFunction;
4
+ export declare const browserlessCacheGenerator: (cacheDir: string) => AgentFilterFunction;
@@ -1,32 +1,53 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.fileCacheAgentFilter = void 0;
7
- require("dotenv/config");
8
- const promises_1 = __importDefault(require("fs/promises"));
9
- const graphai_1 = require("graphai");
10
- const file_1 = require("./file");
11
- const fileCacheAgentFilter = async (context, next) => {
1
+ import "dotenv/config";
2
+ import fs from "fs";
3
+ import path from "path";
4
+ import fsPromise from "fs/promises";
5
+ import { GraphAILogger } from "graphai";
6
+ import { writingMessage } from "./file.js";
7
+ import { text2hash } from "./utils.js";
8
+ export const fileCacheAgentFilter = async (context, next) => {
12
9
  const { namedInputs } = context;
13
- const { file, text } = namedInputs;
14
- try {
15
- await promises_1.default.access(file);
10
+ const { file, text, force } = namedInputs;
11
+ const shouldUseCache = async () => {
12
+ if (force) {
13
+ return false;
14
+ }
15
+ try {
16
+ await fsPromise.access(file);
17
+ return true;
18
+ }
19
+ catch (__e) {
20
+ return false;
21
+ }
22
+ };
23
+ if (await shouldUseCache()) {
16
24
  const elements = file.split("/");
17
- graphai_1.GraphAILogger.info("cache hit: " + elements[elements.length - 1], text.slice(0, 10));
25
+ GraphAILogger.info("cache hit: " + elements[elements.length - 1], text.slice(0, 10));
18
26
  return true;
19
27
  }
20
- catch (__e) {
21
- const output = (await next(context));
22
- const buffer = output ? output["buffer"] : undefined;
23
- if (buffer) {
24
- (0, file_1.writingMessage)(file);
25
- await promises_1.default.writeFile(file, buffer);
26
- return true;
27
- }
28
- graphai_1.GraphAILogger.log("no cache, no buffer: " + file);
29
- return false;
28
+ const output = (await next(context));
29
+ const buffer = output ? output["buffer"] : undefined;
30
+ if (buffer) {
31
+ writingMessage(file);
32
+ await fsPromise.writeFile(file, buffer);
33
+ return true;
30
34
  }
35
+ GraphAILogger.log("no cache, no buffer: " + file);
36
+ return false;
37
+ };
38
+ export const browserlessCacheGenerator = (cacheDir) => {
39
+ const browserlessCache = async (context, next) => {
40
+ const cacheKey = text2hash(context?.namedInputs?.url);
41
+ const cachePath = path.resolve(cacheDir, cacheKey + ".txt");
42
+ if (fs.existsSync(cachePath)) {
43
+ // console.log("cache hit!!");
44
+ const text = fs.readFileSync(cachePath, "utf-8");
45
+ return { text };
46
+ }
47
+ // console.log("cache not hit!!");
48
+ const result = (await next(context));
49
+ fs.writeFileSync(cachePath, result?.text, "utf8");
50
+ return result;
51
+ };
52
+ return browserlessCache;
31
53
  };
32
- exports.fileCacheAgentFilter = fileCacheAgentFilter;
@@ -0,0 +1,3 @@
1
+ import { ImageProcessorParams } from "../../types/index.js";
2
+ export declare const imageType = "chart";
3
+ export declare const process: (params: ImageProcessorParams) => Promise<string | undefined>;
@@ -0,0 +1,18 @@
1
+ import { getHTMLFile } from "../file.js";
2
+ import { renderHTMLToImage, interpolate } from "../markdown.js";
3
+ export const imageType = "chart";
4
+ const processChart = async (params) => {
5
+ const { beat, imagePath, canvasSize, textSlideStyle } = params;
6
+ if (!beat.image || beat.image.type !== imageType)
7
+ return;
8
+ const template = getHTMLFile("chart");
9
+ const htmlData = interpolate(template, {
10
+ title: beat.image.title,
11
+ style: textSlideStyle,
12
+ width: Math.round(canvasSize.width * 0.625).toString(),
13
+ chart_data: JSON.stringify(beat.image.chartData),
14
+ });
15
+ await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
16
+ return imagePath;
17
+ };
18
+ export const process = processChart;
@@ -0,0 +1,2 @@
1
+ export declare const imageType = "image";
2
+ export declare const process: (params: import("../../types/type.js").ImageProcessorParams) => string | undefined;
@@ -0,0 +1,3 @@
1
+ import { processSource } from "./source.js";
2
+ export const imageType = "image";
3
+ export const process = processSource(imageType);
@@ -0,0 +1,7 @@
1
+ import * as pluginTextSlide from "./text_slide.js";
2
+ import * as pluginMarkdown from "./markdown.js";
3
+ import * as pluginImage from "./image.js";
4
+ import * as pluginChart from "./chart.js";
5
+ import * as pluginMermaid from "./mermaid.js";
6
+ import * as pluginMovie from "./movie.js";
7
+ export declare const imagePlugins: (typeof pluginTextSlide | typeof pluginMarkdown | typeof pluginImage | typeof pluginChart | typeof pluginMermaid | typeof pluginMovie)[];
@@ -0,0 +1,7 @@
1
+ import * as pluginTextSlide from "./text_slide.js";
2
+ import * as pluginMarkdown from "./markdown.js";
3
+ import * as pluginImage from "./image.js";
4
+ import * as pluginChart from "./chart.js";
5
+ import * as pluginMermaid from "./mermaid.js";
6
+ import * as pluginMovie from "./movie.js";
7
+ export const imagePlugins = [pluginTextSlide, pluginMarkdown, pluginImage, pluginChart, pluginMermaid, pluginMovie];
@@ -0,0 +1,3 @@
1
+ import { ImageProcessorParams } from "../../types/index.js";
2
+ export declare const imageType = "markdown";
3
+ export declare const process: (params: ImageProcessorParams) => Promise<string | undefined>;
@@ -0,0 +1,11 @@
1
+ import { renderMarkdownToImage } from "../markdown.js";
2
+ export const imageType = "markdown";
3
+ const processMarkdown = async (params) => {
4
+ const { beat, imagePath, textSlideStyle, canvasSize } = params;
5
+ if (!beat.image || beat.image.type !== imageType)
6
+ return;
7
+ const markdown = Array.isArray(beat.image.markdown) ? beat.image.markdown.join("\n") : beat.image.markdown;
8
+ await renderMarkdownToImage(markdown, textSlideStyle, imagePath, canvasSize.width, canvasSize.height);
9
+ return imagePath;
10
+ };
11
+ export const process = processMarkdown;
@@ -0,0 +1,3 @@
1
+ import { ImageProcessorParams } from "../../types/index.js";
2
+ export declare const imageType = "mermaid";
3
+ export declare const process: (params: ImageProcessorParams) => Promise<string | undefined>;
@@ -0,0 +1,21 @@
1
+ import { MulmoMediaSourceMethods } from "../../methods/index.js";
2
+ import { getHTMLFile } from "../file.js";
3
+ import { renderHTMLToImage, interpolate } from "../markdown.js";
4
+ export const imageType = "mermaid";
5
+ const processMermaid = async (params) => {
6
+ const { beat, imagePath, canvasSize, context, textSlideStyle } = params;
7
+ if (!beat.image || beat.image.type !== imageType)
8
+ return;
9
+ const template = getHTMLFile("mermaid");
10
+ const diagram_code = await MulmoMediaSourceMethods.getText(beat.image.code, context);
11
+ if (diagram_code) {
12
+ const htmlData = interpolate(template, {
13
+ title: beat.image.title,
14
+ style: textSlideStyle,
15
+ diagram_code: `${diagram_code}\n${beat.image.appendix?.join("\n") ?? ""}`,
16
+ });
17
+ await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
18
+ }
19
+ return imagePath;
20
+ };
21
+ export const process = processMermaid;
@@ -0,0 +1,2 @@
1
+ export declare const imageType = "movie";
2
+ export declare const process: (params: import("../../types/type.js").ImageProcessorParams) => string | undefined;
@@ -0,0 +1,3 @@
1
+ import { processSource } from "./source.js";
2
+ export const imageType = "movie";
3
+ export const process = processSource(imageType);
@@ -0,0 +1,4 @@
1
+ import { ImageProcessorParams } from "../../types/index.js";
2
+ type ImageType = "image" | "movie";
3
+ export declare const processSource: (imageType: ImageType) => (params: ImageProcessorParams) => string | undefined;
4
+ export {};
@@ -0,0 +1,15 @@
1
+ import { GraphAILogger } from "graphai";
2
+ import { resolveMediaSource } from "../../utils/file.js";
3
+ export const processSource = (imageType) => {
4
+ return (params) => {
5
+ const { beat, context } = params;
6
+ if (!beat.image || beat.image.type !== imageType)
7
+ return;
8
+ const path = resolveMediaSource(beat.image.source, context);
9
+ if (path) {
10
+ return path;
11
+ }
12
+ GraphAILogger.error(`Image Plugin unknown ${imageType} source type:`, beat.image);
13
+ throw new Error(`ERROR: unknown ${imageType} source type`);
14
+ };
15
+ };
@@ -0,0 +1,3 @@
1
+ import { ImageProcessorParams } from "../../types/index.js";
2
+ export declare const imageType = "textSlide";
3
+ export declare const process: (params: ImageProcessorParams) => Promise<string | undefined>;
@@ -0,0 +1,12 @@
1
+ import { renderMarkdownToImage } from "../markdown.js";
2
+ export const imageType = "textSlide";
3
+ const processTextSlide = async (params) => {
4
+ const { beat, imagePath, textSlideStyle, canvasSize } = params;
5
+ if (!beat.image || beat.image.type !== imageType)
6
+ return;
7
+ const slide = beat.image.slide;
8
+ const markdown = `# ${slide.title}\n` + slide.bullets.map((text) => `- ${text}`).join("\n");
9
+ await renderMarkdownToImage(markdown, textSlideStyle, imagePath, canvasSize.width, canvasSize.height);
10
+ return imagePath;
11
+ };
12
+ export const process = processTextSlide;
@@ -0,0 +1,6 @@
1
+ import { MulmoTextSlideMedia, MulmoMarkdownMedia, MulmoImageMedia, MulmoChartMedia, MulmoMermaidMedia } from "../../types/index.js";
2
+ export declare const isMulmoImageTextSlide: (value: unknown) => value is MulmoTextSlideMedia;
3
+ export declare const isMulmoImageMarkdown: (value: unknown) => value is MulmoMarkdownMedia;
4
+ export declare const isMulmoImageImage: (value: unknown) => value is MulmoImageMedia;
5
+ export declare const isMulmoImageChart: (value: unknown) => value is MulmoChartMedia;
6
+ export declare const isMulmoImageMermaild: (value: unknown) => value is MulmoMermaidMedia;
@@ -0,0 +1,21 @@
1
+ import { mulmoTextSlideMediaSchema, mulmoMarkdownMediaSchema, mulmoImageMediaSchema, mulmoChartMediaSchema, mulmoMermaidMediaSchema, } from "../../types/index.js";
2
+ export const isMulmoImageTextSlide = (value) => {
3
+ const result = mulmoTextSlideMediaSchema.safeParse(value);
4
+ return result.success;
5
+ };
6
+ export const isMulmoImageMarkdown = (value) => {
7
+ const result = mulmoMarkdownMediaSchema.safeParse(value);
8
+ return result.success;
9
+ };
10
+ export const isMulmoImageImage = (value) => {
11
+ const result = mulmoImageMediaSchema.safeParse(value);
12
+ return result.success;
13
+ };
14
+ export const isMulmoImageChart = (value) => {
15
+ const result = mulmoChartMediaSchema.safeParse(value);
16
+ return result.success;
17
+ };
18
+ export const isMulmoImageMermaild = (value) => {
19
+ const result = mulmoMermaidMediaSchema.safeParse(value);
20
+ return result.success;
21
+ };
@@ -0,0 +1,14 @@
1
+ import { MulmoStudioBeat, MulmoStudioContext, MulmoCanvasDimension } from "../types/index.js";
2
+ type ImageProcessorParams = {
3
+ beat: MulmoStudioBeat;
4
+ context: MulmoStudioContext;
5
+ imagePath: string;
6
+ textSlideStyle: string;
7
+ canvasSize: MulmoCanvasDimension;
8
+ };
9
+ export declare const processTextSlide: (params: ImageProcessorParams) => Promise<void>;
10
+ export declare const processMarkdown: (params: ImageProcessorParams) => Promise<void>;
11
+ export declare const processImage: (params: ImageProcessorParams) => string | undefined;
12
+ export declare const processChart: (params: ImageProcessorParams) => Promise<void>;
13
+ export declare const processMermaid: (params: ImageProcessorParams) => Promise<void>;
14
+ export {};
@@ -0,0 +1,52 @@
1
+ import { MulmoStudioContextMethods } from "../methods/index.js";
2
+ import { getHTMLFile } from "./file.js";
3
+ import { renderMarkdownToImage, renderHTMLToImage, interpolate } from "./markdown.js";
4
+ export const processTextSlide = async (params) => {
5
+ const { beat, imagePath, textSlideStyle, canvasSize } = params;
6
+ if (!beat.image || beat.image.type !== "textSlide")
7
+ return;
8
+ const slide = beat.image.slide;
9
+ const markdown = `# ${slide.title}\n` + slide.bullets.map((text) => `- ${text}`).join("\n");
10
+ await renderMarkdownToImage(markdown, textSlideStyle, imagePath, canvasSize.width, canvasSize.height);
11
+ };
12
+ export const processMarkdown = async (params) => {
13
+ const { beat, imagePath, textSlideStyle, canvasSize } = params;
14
+ if (!beat.image || beat.image.type !== "markdown")
15
+ return;
16
+ const markdown = Array.isArray(beat.image.markdown) ? beat.image.markdown.join("\n") : beat.image.markdown;
17
+ await renderMarkdownToImage(markdown, textSlideStyle, imagePath, canvasSize.width, canvasSize.height);
18
+ };
19
+ export const processImage = (params) => {
20
+ const { beat, context } = params;
21
+ if (!beat.image || beat.image.type !== "image")
22
+ return;
23
+ if (beat.image.source.kind === "url") {
24
+ return beat.image.source.url;
25
+ }
26
+ else if (beat.image.source.kind === "path") {
27
+ return MulmoStudioContextMethods.resolveAssetPath(context, beat.image.source.path);
28
+ }
29
+ };
30
+ export const processChart = async (params) => {
31
+ const { beat, imagePath, canvasSize } = params;
32
+ if (!beat.image || beat.image.type !== "chart")
33
+ return;
34
+ const template = getHTMLFile("chart");
35
+ const htmlData = interpolate(template, {
36
+ title: beat.image.title,
37
+ width: Math.round(canvasSize.width * 0.625).toString(),
38
+ chart_data: JSON.stringify(beat.image.chartData),
39
+ });
40
+ await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
41
+ };
42
+ export const processMermaid = async (params) => {
43
+ const { beat, imagePath, canvasSize } = params;
44
+ if (!beat.image || beat.image.type !== "mermaid")
45
+ return;
46
+ const template = getHTMLFile("mermaid");
47
+ const htmlData = interpolate(template, {
48
+ title: beat.image.title,
49
+ diagram_code: beat.image.code,
50
+ });
51
+ await renderHTMLToImage(htmlData, imagePath, canvasSize.width, canvasSize.height);
52
+ };
@@ -0,0 +1,2 @@
1
+ export declare const selectTemplate: () => Promise<string>;
2
+ export declare const getUrlsIfNeeded: (urls: string[]) => Promise<string[]>;
@@ -0,0 +1,33 @@
1
+ import inquirer from "inquirer";
2
+ import { getAvailableTemplates } from "./file.js";
3
+ export const selectTemplate = async () => {
4
+ const availableTemplates = getAvailableTemplates();
5
+ const answers = await inquirer.prompt([
6
+ {
7
+ type: "list",
8
+ name: "templateName",
9
+ message: "Select a template to use",
10
+ choices: availableTemplates.map((t) => ({
11
+ name: `${t.filename} - ${t.description}`,
12
+ value: t.filename,
13
+ })),
14
+ },
15
+ ]);
16
+ return answers.templateName;
17
+ };
18
+ export const getUrlsIfNeeded = async (urls) => {
19
+ if (urls && urls.length > 0)
20
+ return urls;
21
+ const answers = await inquirer.prompt([
22
+ {
23
+ type: "input",
24
+ name: "urls",
25
+ message: "Enter URLs for scripting references (comma separated):",
26
+ validate: (input) => input.trim().length > 0 || "At least one URL is required",
27
+ },
28
+ ]);
29
+ return answers.urls
30
+ .split(",")
31
+ .map((u) => u.trim())
32
+ .filter((u) => u.length > 0);
33
+ };
@@ -1 +1,3 @@
1
- export declare const convertMarkdownToImage: (markdown: string, style: string, outputPath: string) => Promise<void>;
1
+ export declare const renderHTMLToImage: (html: string, outputPath: string, width: number, height: number) => Promise<void>;
2
+ export declare const renderMarkdownToImage: (markdown: string, style: string, outputPath: string, width: number, height: number) => Promise<void>;
3
+ export declare const interpolate: (template: string, data: Record<string, string>) => string;