@mulmocast/slide 0.1.7 → 0.3.0
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/.claude/skills/extend/SKILL.md +120 -0
- package/.claude/skills/extend/references/extended-script-schema.md +153 -0
- package/.claude/skills/narrate/SKILL.md +145 -0
- package/.claude/skills/narrate/references/extended-script-schema.md +153 -0
- package/README.md +154 -0
- package/lib/actions/bundle.js +14 -20
- package/lib/actions/bundle.js.map +1 -1
- package/lib/actions/common.d.ts +1 -1
- package/lib/actions/common.d.ts.map +1 -1
- package/lib/actions/common.js +26 -66
- package/lib/actions/common.js.map +1 -1
- package/lib/actions/extend-init.d.ts +2 -0
- package/lib/actions/extend-init.d.ts.map +1 -0
- package/lib/actions/extend-init.js +49 -0
- package/lib/actions/extend-init.js.map +1 -0
- package/lib/actions/extend-validate.d.ts +2 -0
- package/lib/actions/extend-validate.d.ts.map +1 -0
- package/lib/actions/extend-validate.js +56 -0
- package/lib/actions/extend-validate.js.map +1 -0
- package/lib/actions/movie.js +14 -20
- package/lib/actions/movie.js.map +1 -1
- package/lib/actions/preview.d.ts.map +1 -1
- package/lib/actions/preview.js +19 -55
- package/lib/actions/preview.js.map +1 -1
- package/lib/actions/upload.js +5 -44
- package/lib/actions/upload.js.map +1 -1
- package/lib/cli.js +60 -73
- package/lib/cli.js.map +1 -1
- package/lib/convert/markdown-plugins/directive.d.ts +1 -1
- package/lib/convert/markdown-plugins/directive.d.ts.map +1 -1
- package/lib/convert/markdown-plugins/directive.js +2 -5
- package/lib/convert/markdown-plugins/directive.js.map +1 -1
- package/lib/convert/markdown-plugins/index.d.ts +2 -2
- package/lib/convert/markdown-plugins/index.d.ts.map +1 -1
- package/lib/convert/markdown-plugins/index.js +23 -30
- package/lib/convert/markdown-plugins/index.js.map +1 -1
- package/lib/convert/markdown-plugins/layout.d.ts +91 -0
- package/lib/convert/markdown-plugins/layout.d.ts.map +1 -0
- package/lib/convert/markdown-plugins/layout.js +251 -0
- package/lib/convert/markdown-plugins/layout.js.map +1 -0
- package/lib/convert/markdown-plugins/mermaid.d.ts +1 -1
- package/lib/convert/markdown-plugins/mermaid.d.ts.map +1 -1
- package/lib/convert/markdown-plugins/mermaid.js +2 -5
- package/lib/convert/markdown-plugins/mermaid.js.map +1 -1
- package/lib/convert/markdown-plugins/types.d.ts +2 -0
- package/lib/convert/markdown-plugins/types.d.ts.map +1 -1
- package/lib/convert/markdown-plugins/types.js +1 -2
- package/lib/convert/markdown-plugins/types.js.map +1 -1
- package/lib/convert/markdown-transform.d.ts +42 -0
- package/lib/convert/markdown-transform.d.ts.map +1 -0
- package/lib/convert/markdown-transform.js +58 -0
- package/lib/convert/markdown-transform.js.map +1 -0
- package/lib/convert/markdown-utils-common.d.ts +21 -0
- package/lib/convert/markdown-utils-common.d.ts.map +1 -0
- package/lib/convert/markdown-utils-common.js +51 -0
- package/lib/convert/markdown-utils-common.js.map +1 -0
- package/lib/convert/markdown-utils.d.ts +4 -17
- package/lib/convert/markdown-utils.d.ts.map +1 -1
- package/lib/convert/markdown-utils.js +10 -91
- package/lib/convert/markdown-utils.js.map +1 -1
- package/lib/convert/markdown.d.ts +1 -1
- package/lib/convert/markdown.d.ts.map +1 -1
- package/lib/convert/markdown.js +36 -88
- package/lib/convert/markdown.js.map +1 -1
- package/lib/convert/marp.d.ts +4 -11
- package/lib/convert/marp.d.ts.map +1 -1
- package/lib/convert/marp.js +25 -119
- package/lib/convert/marp.js.map +1 -1
- package/lib/convert/movie.d.ts +1 -1
- package/lib/convert/movie.d.ts.map +1 -1
- package/lib/convert/movie.js +26 -64
- package/lib/convert/movie.js.map +1 -1
- package/lib/convert/movie_bundle.js +5 -44
- package/lib/convert/movie_bundle.js.map +1 -1
- package/lib/convert/pdf.d.ts +2 -1
- package/lib/convert/pdf.d.ts.map +1 -1
- package/lib/convert/pdf.js +27 -56
- package/lib/convert/pdf.js.map +1 -1
- package/lib/convert/pptx.d.ts +1 -1
- package/lib/convert/pptx.d.ts.map +1 -1
- package/lib/convert/pptx.js +31 -68
- package/lib/convert/pptx.js.map +1 -1
- package/lib/index.browser.d.ts +13 -0
- package/lib/index.browser.d.ts.map +1 -0
- package/lib/index.browser.js +13 -0
- package/lib/index.browser.js.map +1 -0
- package/lib/index.common.d.ts +17 -0
- package/lib/index.common.d.ts.map +1 -0
- package/lib/index.common.js +18 -0
- package/lib/index.common.js.map +1 -0
- package/lib/index.node.d.ts +11 -0
- package/lib/index.node.d.ts.map +1 -0
- package/lib/index.node.js +13 -0
- package/lib/index.node.js.map +1 -0
- package/lib/utils/audio-save.js +8 -49
- package/lib/utils/audio-save.js.map +1 -1
- package/lib/utils/bundle-server.js +6 -45
- package/lib/utils/bundle-server.js.map +1 -1
- package/lib/utils/dependencies.js +6 -43
- package/lib/utils/dependencies.js.map +1 -1
- package/lib/utils/lang-common.d.ts +10 -0
- package/lib/utils/lang-common.d.ts.map +1 -0
- package/lib/utils/lang-common.js +11 -0
- package/lib/utils/lang-common.js.map +1 -0
- package/lib/utils/lang.d.ts +3 -4
- package/lib/utils/lang.d.ts.map +1 -1
- package/lib/utils/lang.js +11 -21
- package/lib/utils/lang.js.map +1 -1
- package/lib/utils/llm.d.ts +1 -1
- package/lib/utils/llm.d.ts.map +1 -1
- package/lib/utils/llm.js +6 -46
- package/lib/utils/llm.js.map +1 -1
- package/lib/utils/pdf.d.ts +1 -1
- package/lib/utils/pdf.d.ts.map +1 -1
- package/lib/utils/pdf.js +13 -52
- package/lib/utils/pdf.js.map +1 -1
- package/lib/vue/main.js +4 -9
- package/lib/vue/main.js.map +1 -1
- package/package.json +22 -9
package/README.md
CHANGED
|
@@ -136,6 +136,8 @@ Commands:
|
|
|
136
136
|
mulmo-slide keynote <file> Convert Keynote to MulmoScript (macOS only)
|
|
137
137
|
mulmo-slide movie <file> Generate movie from presentation
|
|
138
138
|
mulmo-slide bundle <file> Generate MulmoViewer bundle from presentation
|
|
139
|
+
mulmo-slide extend init Install Claude Code skills (/narrate, /extend)
|
|
140
|
+
mulmo-slide extend validate Validate ExtendedScript JSON against schema
|
|
139
141
|
```
|
|
140
142
|
|
|
141
143
|
The `convert` command auto-detects file format by extension (.pptx, .md, .key, .pdf).
|
|
@@ -291,6 +293,7 @@ yarn markdown path/to/document.md -s heading --mermaid --style corporate-blue
|
|
|
291
293
|
- `-s, --separator` - Slide separator mode (see below)
|
|
292
294
|
- `--mermaid` - Convert mermaid code blocks to mermaid beat type
|
|
293
295
|
- `--directive` - Remove Marp-style directives
|
|
296
|
+
- `--layout` - Auto-detect layout based on content (see below)
|
|
294
297
|
- `--style` - Markdown slide style (e.g., corporate-blue, finance-green)
|
|
295
298
|
|
|
296
299
|
**Separator Modes:**
|
|
@@ -306,6 +309,76 @@ yarn markdown path/to/document.md -s heading --mermaid --style corporate-blue
|
|
|
306
309
|
| `comment` | Split by `<!-- slide -->` | HTML-compatible |
|
|
307
310
|
| `page-break` | Split by `<!-- pagebreak -->` | Print-style documents |
|
|
308
311
|
|
|
312
|
+
**Layout Auto-Detection (`--layout`):**
|
|
313
|
+
|
|
314
|
+
When enabled, the converter automatically detects the best layout based on content.
|
|
315
|
+
|
|
316
|
+
Detection rules are evaluated in order (first match wins):
|
|
317
|
+
|
|
318
|
+
**Phase 1: Header Detection (H1)**
|
|
319
|
+
|
|
320
|
+
If markdown contains an H1 heading (`# Title`), it becomes the header and remaining content is analyzed:
|
|
321
|
+
|
|
322
|
+
```
|
|
323
|
+
┌─────────────────────────────────────┬─────────────────┬─────────────────────────────────┐
|
|
324
|
+
│ Content Pattern │ Layout │ Conditions │
|
|
325
|
+
├─────────────────────────────────────┼─────────────────┼─────────────────────────────────┤
|
|
326
|
+
│ H1 only │ (no layout) │ Only H1, no other content │
|
|
327
|
+
│ │ │ → default markdown (array) │
|
|
328
|
+
├─────────────────────────────────────┼─────────────────┼─────────────────────────────────┤
|
|
329
|
+
│ H1 + unstructured content │ header+content │ H1 + text without H2/H3 │
|
|
330
|
+
│ │ │ → { header, content: [...] } │
|
|
331
|
+
├─────────────────────────────────────┼─────────────────┼─────────────────────────────────┤
|
|
332
|
+
│ H1 + structured content │ header+row-2 │ H1 + content matching row-2/2x2 │
|
|
333
|
+
│ │ header+2x2 │ → { header, "row-2": [...] } │
|
|
334
|
+
└─────────────────────────────────────┴─────────────────┴─────────────────────────────────┘
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
**Phase 2: Content Layout Rules (no H1, or applied to content after H1)**
|
|
338
|
+
|
|
339
|
+
```
|
|
340
|
+
┌─────────────────────────────────────┬────────────┬─────────────────────────────────────┐
|
|
341
|
+
│ Content Pattern │ Layout │ Conditions │
|
|
342
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
343
|
+
│ 1. Single code block + text │ row-2 │ Exactly 1 code block (```) │
|
|
344
|
+
│ │ │ Text content > 20 chars │
|
|
345
|
+
│ │ │ → [text, code] │
|
|
346
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
347
|
+
│ 2. Single image + text │ row-2 │ Exactly 1 image (![]()) │
|
|
348
|
+
│ │ │ Text content > 20 chars │
|
|
349
|
+
│ │ │ → [text, image] │
|
|
350
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
351
|
+
│ 3. 4+ H3 sections (short) │ 2x2 │ 4 or more ### headings │
|
|
352
|
+
│ │ │ Avg content < 200 chars │
|
|
353
|
+
│ │ │ → first 4 sections │
|
|
354
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
355
|
+
│ 4. 4+ H2 sections (short) │ 2x2 │ 4 or more ## headings │
|
|
356
|
+
│ │ │ Avg content < 200 chars │
|
|
357
|
+
│ │ │ → first 4 sections │
|
|
358
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
359
|
+
│ 5. 4+ H2 sections (long) │ row-2 │ 4 or more ## headings │
|
|
360
|
+
│ │ │ Avg content >= 200 chars │
|
|
361
|
+
│ │ │ → first 2 sections │
|
|
362
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
363
|
+
│ 6. 2+ H2 sections │ row-2 │ 2 or more ## headings │
|
|
364
|
+
│ │ │ → first 2 sections │
|
|
365
|
+
├─────────────────────────────────────┼────────────┼─────────────────────────────────────┤
|
|
366
|
+
│ 7. Otherwise │ default │ No layout applied │
|
|
367
|
+
└─────────────────────────────────────┴────────────┴─────────────────────────────────────┘
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
**Notes:**
|
|
371
|
+
- "Meaningful text" = text without headings > 20 characters
|
|
372
|
+
- Multiple code blocks or images → no layout detected
|
|
373
|
+
- H3 has no fallback (only 2x2 if short, otherwise no layout)
|
|
374
|
+
- H1 always becomes header; remaining content is analyzed for structure
|
|
375
|
+
|
|
376
|
+
Example:
|
|
377
|
+
```bash
|
|
378
|
+
# Auto-detect layout for better visual presentation
|
|
379
|
+
mulmo-slide markdown document.md --layout --style corporate-blue
|
|
380
|
+
```
|
|
381
|
+
|
|
309
382
|
**Output:**
|
|
310
383
|
- `scripts/<basename>/mulmo_script.json` - MulmoScript JSON file (Markdown format)
|
|
311
384
|
|
|
@@ -484,6 +557,87 @@ mulmo-slide bundle presentation.pptx -f -g
|
|
|
484
557
|
- The LLM considers the overall presentation structure to generate contextual narration
|
|
485
558
|
- Output is in the specified language (`-l` option)
|
|
486
559
|
|
|
560
|
+
## Narrate: Source File to Narrated Video (Claude Code Skill)
|
|
561
|
+
|
|
562
|
+
The `/narrate` skill converts any supported source file into a narrated ExtendedScript in one step. It handles the full pipeline: conversion, narration generation, metadata, and validation.
|
|
563
|
+
|
|
564
|
+
### Setup
|
|
565
|
+
|
|
566
|
+
Install the Claude Code skills into your project:
|
|
567
|
+
|
|
568
|
+
```bash
|
|
569
|
+
# If installed globally
|
|
570
|
+
mulmo-slide extend init
|
|
571
|
+
|
|
572
|
+
# With npx
|
|
573
|
+
npx @mulmocast/slide extend init
|
|
574
|
+
|
|
575
|
+
# Development
|
|
576
|
+
yarn cli extend init
|
|
577
|
+
```
|
|
578
|
+
|
|
579
|
+
This copies the skill files to `.claude/skills/` in your project directory.
|
|
580
|
+
|
|
581
|
+
### Usage
|
|
582
|
+
|
|
583
|
+
In Claude Code, use the `/narrate` command with any supported source file:
|
|
584
|
+
|
|
585
|
+
```
|
|
586
|
+
/narrate your-paper.pdf
|
|
587
|
+
/narrate your-slides.pptx
|
|
588
|
+
/narrate your-slides.md
|
|
589
|
+
/narrate your-slides.key
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
The skill automatically:
|
|
593
|
+
1. Converts the source file to MulmoScript (slide images + text extraction)
|
|
594
|
+
2. Generates AI narration for each slide
|
|
595
|
+
3. Adds metadata (keywords, sections, context, FAQ)
|
|
596
|
+
4. Validates the output
|
|
597
|
+
5. Shows you the next steps
|
|
598
|
+
|
|
599
|
+
**Output:** `scripts/{basename}/extended_script.json`
|
|
600
|
+
|
|
601
|
+
### After `/narrate`: Next Steps
|
|
602
|
+
|
|
603
|
+
```bash
|
|
604
|
+
# Query the content interactively
|
|
605
|
+
npx mulmocast-preprocessor query scripts/{basename}/extended_script.json -i
|
|
606
|
+
|
|
607
|
+
# Generate a summary
|
|
608
|
+
npx mulmocast-preprocessor summarize scripts/{basename}/extended_script.json
|
|
609
|
+
|
|
610
|
+
# Generate a narrated video
|
|
611
|
+
npx mulmocast-preprocessor scripts/{basename}/extended_script.json -o scripts/{basename}/mulmo_script.json
|
|
612
|
+
npx mulmo movie scripts/{basename}/mulmo_script.json
|
|
613
|
+
```
|
|
614
|
+
|
|
615
|
+
### Validating ExtendedScript
|
|
616
|
+
|
|
617
|
+
Validate an ExtendedScript JSON file against the schema:
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
mulmo-slide extend validate scripts/simple_text/extended_script.json
|
|
621
|
+
|
|
622
|
+
# Development
|
|
623
|
+
yarn cli extend validate scripts/simple_text/extended_script.json
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
Outputs beat count, scriptMeta presence, meta coverage percentage, and sections found.
|
|
627
|
+
|
|
628
|
+
### Low-level: `/extend`
|
|
629
|
+
|
|
630
|
+
If you already have a MulmoScript and just want to add metadata:
|
|
631
|
+
|
|
632
|
+
```
|
|
633
|
+
/extend scripts/simple_text/mulmo_script.json
|
|
634
|
+
```
|
|
635
|
+
|
|
636
|
+
### Tutorials
|
|
637
|
+
|
|
638
|
+
- [English: PDF to Narrated Video](docs/tutorial-pdf-to-video-en.md)
|
|
639
|
+
- [Japanese: PDF からナレーション付き動画](docs/tutorial-pdf-to-video-ja.md)
|
|
640
|
+
|
|
487
641
|
## Output Structure
|
|
488
642
|
|
|
489
643
|
All tools generate MulmoScript output in `scripts/<basename>/` with a unified structure:
|
package/lib/actions/bundle.js
CHANGED
|
@@ -1,35 +1,29 @@
|
|
|
1
1
|
#!/usr/bin/env tsx
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
exports.runMulmoBundle = runMulmoBundle;
|
|
8
|
-
const mulmocast_1 = require("mulmocast");
|
|
9
|
-
const yargs_1 = __importDefault(require("yargs"));
|
|
10
|
-
const helpers_1 = require("yargs/helpers");
|
|
11
|
-
const common_1 = require("./common");
|
|
12
|
-
async function runMulmoBundle(mulmoScriptPath, outputDir) {
|
|
2
|
+
import { audio, images, translate, mulmoViewerBundle, bundleTargetLang } from "mulmocast";
|
|
3
|
+
import yargs from "yargs";
|
|
4
|
+
import { hideBin } from "yargs/helpers";
|
|
5
|
+
import { initializeContext, runAction } from "./common.js";
|
|
6
|
+
export async function runMulmoBundle(mulmoScriptPath, outputDir) {
|
|
13
7
|
console.log(`\nGenerating bundle with mulmo...`);
|
|
14
8
|
console.log(` Input: ${mulmoScriptPath}`);
|
|
15
9
|
console.log(` Output: ${outputDir}`);
|
|
16
|
-
const context = await
|
|
10
|
+
const context = await initializeContext(mulmoScriptPath, outputDir);
|
|
17
11
|
const current = { context };
|
|
18
12
|
console.log(" Translating...");
|
|
19
|
-
current.context = await
|
|
20
|
-
for (const lang of
|
|
13
|
+
current.context = await translate(current.context, { targetLangs: bundleTargetLang });
|
|
14
|
+
for (const lang of bundleTargetLang.filter((_lang) => _lang !== current.context.lang)) {
|
|
21
15
|
console.log(` Generating audio (${lang})...`);
|
|
22
|
-
current.context = await
|
|
16
|
+
current.context = await audio({ ...current.context, lang });
|
|
23
17
|
}
|
|
24
18
|
console.log(` Generating audio (${current.context.lang})...`);
|
|
25
|
-
current.context = await
|
|
19
|
+
current.context = await audio(current.context);
|
|
26
20
|
console.log(" Generating images...");
|
|
27
|
-
current.context = await
|
|
21
|
+
current.context = await images(current.context);
|
|
28
22
|
console.log(" Creating bundle...");
|
|
29
|
-
await
|
|
23
|
+
await mulmoViewerBundle(current.context, { skipZip: true });
|
|
30
24
|
}
|
|
31
25
|
async function main() {
|
|
32
|
-
const argv = await (
|
|
26
|
+
const argv = await yargs(hideBin(process.argv))
|
|
33
27
|
.usage("Usage: $0 <presentation-file> [options]")
|
|
34
28
|
.command("$0 <file>", "Generate MulmoViewer bundle from presentation", (yargs) => {
|
|
35
29
|
return yargs.positional("file", {
|
|
@@ -54,7 +48,7 @@ async function main() {
|
|
|
54
48
|
})
|
|
55
49
|
.help()
|
|
56
50
|
.parse();
|
|
57
|
-
await
|
|
51
|
+
await runAction("Bundle", argv.file, runMulmoBundle, {
|
|
58
52
|
force: argv.f,
|
|
59
53
|
generateText: argv.g,
|
|
60
54
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/actions/bundle.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/actions/bundle.ts"],"names":[],"mappings":"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"}
|
package/lib/actions/common.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { MulmoStudioContext } from "mulmocast";
|
|
2
|
-
import type { SupportedLang } from "../utils/lang";
|
|
2
|
+
import type { SupportedLang } from "../utils/lang.js";
|
|
3
3
|
export declare function getPackageRoot(): string;
|
|
4
4
|
export declare function getKeynoteScriptPath(): string;
|
|
5
5
|
export type FileType = "pptx" | "marp" | "keynote" | "pdf" | "movie";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/actions/common.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../src/actions/common.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAMtD,wBAAgB,cAAc,IAAI,MAAM,CAGvC;AAGD,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,CAAC;AAIrE,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,CAiBzD;AAED,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED,MAAM,WAAW,cAAc;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,IAAI,CAAC,EAAE,aAAa,CAAC;CACtB;AAED,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAiCjB;AAED,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAsB,iBAAiB,CACrC,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,kBAAkB,CAAC,CA4B7B;AAED,MAAM,MAAM,YAAY,GAAG,CAAC,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAEzF,MAAM,WAAW,gBAAgB;IAC/B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE3D;AAED,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,YAAY,EAC1B,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuCf"}
|
package/lib/actions/common.js
CHANGED
|
@@ -1,65 +1,25 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.getPackageRoot = getPackageRoot;
|
|
37
|
-
exports.getKeynoteScriptPath = getKeynoteScriptPath;
|
|
38
|
-
exports.detectFileType = detectFileType;
|
|
39
|
-
exports.getBasename = getBasename;
|
|
40
|
-
exports.convertToMulmoScript = convertToMulmoScript;
|
|
41
|
-
exports.initializeContext = initializeContext;
|
|
42
|
-
exports.getMulmoScriptPath = getMulmoScriptPath;
|
|
43
|
-
exports.runAction = runAction;
|
|
44
|
-
const fs = __importStar(require("fs"));
|
|
45
|
-
const path = __importStar(require("path"));
|
|
46
|
-
const child_process_1 = require("child_process");
|
|
47
|
-
const pptx_1 = require("../convert/pptx");
|
|
48
|
-
const marp_1 = require("../convert/marp");
|
|
49
|
-
const pdf_1 = require("../convert/pdf");
|
|
50
|
-
const movie_1 = require("../convert/movie");
|
|
51
|
-
const mulmocast_1 = require("mulmocast");
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { convertPptx } from "../convert/pptx.js";
|
|
6
|
+
import { convertMarp } from "../convert/marp.js";
|
|
7
|
+
import { convertPdf } from "../convert/pdf.js";
|
|
8
|
+
import { convertMovie } from "../convert/movie.js";
|
|
9
|
+
import { getFileObject, initializeContextFromFiles } from "mulmocast";
|
|
10
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
11
|
+
const __dirname = path.dirname(__filename);
|
|
52
12
|
// Get package root directory (works for both development and npm installed)
|
|
53
|
-
function getPackageRoot() {
|
|
13
|
+
export function getPackageRoot() {
|
|
54
14
|
// __dirname points to lib/actions/ when compiled, so go up 2 levels
|
|
55
15
|
return path.resolve(__dirname, "..", "..");
|
|
56
16
|
}
|
|
57
17
|
// Get path to Keynote AppleScript
|
|
58
|
-
function getKeynoteScriptPath() {
|
|
18
|
+
export function getKeynoteScriptPath() {
|
|
59
19
|
return path.join(getPackageRoot(), "tools", "keynote", "extract.scpt");
|
|
60
20
|
}
|
|
61
21
|
const VIDEO_EXTENSIONS = [".mp4", ".mov", ".mkv", ".webm", ".avi", ".m4v"];
|
|
62
|
-
function detectFileType(filePath) {
|
|
22
|
+
export function detectFileType(filePath) {
|
|
63
23
|
const ext = path.extname(filePath).toLowerCase();
|
|
64
24
|
switch (ext) {
|
|
65
25
|
case ".pptx":
|
|
@@ -77,35 +37,35 @@ function detectFileType(filePath) {
|
|
|
77
37
|
throw new Error(`Unsupported file type: ${ext}`);
|
|
78
38
|
}
|
|
79
39
|
}
|
|
80
|
-
function getBasename(filePath) {
|
|
40
|
+
export function getBasename(filePath) {
|
|
81
41
|
const ext = path.extname(filePath);
|
|
82
42
|
return path.basename(filePath, ext);
|
|
83
43
|
}
|
|
84
|
-
async function convertToMulmoScript(filePath, fileType, options = {}) {
|
|
44
|
+
export async function convertToMulmoScript(filePath, fileType, options = {}) {
|
|
85
45
|
const absolutePath = path.resolve(filePath);
|
|
86
46
|
const { generateText = false, lang } = options;
|
|
87
47
|
console.log(`Converting ${fileType.toUpperCase()} to MulmoScript...`);
|
|
88
48
|
switch (fileType) {
|
|
89
49
|
case "pptx": {
|
|
90
|
-
const result = await
|
|
50
|
+
const result = await convertPptx({ inputPath: absolutePath, generateText, lang });
|
|
91
51
|
return result.mulmoScriptPath;
|
|
92
52
|
}
|
|
93
53
|
case "marp": {
|
|
94
|
-
const result = await
|
|
54
|
+
const result = await convertMarp({ inputPath: absolutePath, generateText, lang });
|
|
95
55
|
return result.mulmoScriptPath;
|
|
96
56
|
}
|
|
97
57
|
case "pdf": {
|
|
98
|
-
const result = await
|
|
58
|
+
const result = await convertPdf({ inputPath: absolutePath, generateText, lang });
|
|
99
59
|
return result.mulmoScriptPath;
|
|
100
60
|
}
|
|
101
61
|
case "movie": {
|
|
102
|
-
const result = await
|
|
62
|
+
const result = await convertMovie({ inputPath: absolutePath, lang });
|
|
103
63
|
return result.mulmoScriptPath;
|
|
104
64
|
}
|
|
105
65
|
case "keynote": {
|
|
106
66
|
const basename = getBasename(filePath);
|
|
107
67
|
const scriptPath = getKeynoteScriptPath();
|
|
108
|
-
|
|
68
|
+
execSync(`osascript "${scriptPath}" "${absolutePath}"`, {
|
|
109
69
|
stdio: "inherit",
|
|
110
70
|
cwd: process.cwd(),
|
|
111
71
|
});
|
|
@@ -113,12 +73,12 @@ async function convertToMulmoScript(filePath, fileType, options = {}) {
|
|
|
113
73
|
}
|
|
114
74
|
}
|
|
115
75
|
}
|
|
116
|
-
async function initializeContext(mulmoScriptPath, outputDir, options = {}) {
|
|
76
|
+
export async function initializeContext(mulmoScriptPath, outputDir, options = {}) {
|
|
117
77
|
const absoluteScriptPath = path.resolve(mulmoScriptPath);
|
|
118
78
|
const scriptDir = path.dirname(absoluteScriptPath);
|
|
119
79
|
const scriptFile = path.basename(absoluteScriptPath);
|
|
120
80
|
const absoluteOutputDir = path.resolve(outputDir);
|
|
121
|
-
const files =
|
|
81
|
+
const files = getFileObject({
|
|
122
82
|
basedir: scriptDir,
|
|
123
83
|
outdir: absoluteOutputDir,
|
|
124
84
|
file: scriptFile,
|
|
@@ -126,16 +86,16 @@ async function initializeContext(mulmoScriptPath, outputDir, options = {}) {
|
|
|
126
86
|
// targetLang sets context.lang (target language for audio)
|
|
127
87
|
// captionLang sets the caption/subtitle language
|
|
128
88
|
// context.studio.script.lang contains the original script language
|
|
129
|
-
const context = await
|
|
89
|
+
const context = await initializeContextFromFiles(files, false, false, false, options.captionLang, options.targetLang);
|
|
130
90
|
if (!context) {
|
|
131
91
|
throw new Error("Failed to initialize MulmoStudio context");
|
|
132
92
|
}
|
|
133
93
|
return context;
|
|
134
94
|
}
|
|
135
|
-
function getMulmoScriptPath(basename) {
|
|
95
|
+
export function getMulmoScriptPath(basename) {
|
|
136
96
|
return path.join("scripts", basename, "mulmo_script.json");
|
|
137
97
|
}
|
|
138
|
-
async function runAction(commandName, inputFile, actionRunner, options = {}) {
|
|
98
|
+
export async function runAction(commandName, inputFile, actionRunner, options = {}) {
|
|
139
99
|
const { force = false, generateText = false } = options;
|
|
140
100
|
if (!fs.existsSync(inputFile)) {
|
|
141
101
|
console.error(`File not found: ${inputFile}`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/actions/common.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/actions/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,MAAM,WAAW,CAAC;AAItE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C,4EAA4E;AAC5E,MAAM,UAAU,cAAc;IAC5B,oEAAoE;IACpE,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC7C,CAAC;AAED,kCAAkC;AAClC,MAAM,UAAU,oBAAoB;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,CAAC,CAAC;AACzE,CAAC;AAID,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3E,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;IACjD,QAAQ,GAAG,EAAE,CAAC;QACZ,KAAK,OAAO;YACV,OAAO,MAAM,CAAC;QAChB,KAAK,KAAK;YACR,OAAO,MAAM,CAAC;QAChB,KAAK,MAAM;YACT,OAAO,SAAS,CAAC;QACnB,KAAK,MAAM;YACT,OAAO,KAAK,CAAC;QACf;YACE,IAAI,gBAAgB,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnC,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACtC,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,QAAgB,EAChB,QAAkB,EAClB,UAA0B,EAAE;IAE5B,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC5C,MAAM,EAAE,YAAY,GAAG,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC;IAE/C,OAAO,CAAC,GAAG,CAAC,cAAc,QAAQ,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;IAEtE,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,OAAO,MAAM,CAAC,eAAe,CAAC;QAChC,CAAC;QACD,KAAK,MAAM,CAAC,CAAC,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,WAAW,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YAClF,OAAO,MAAM,CAAC,eAAe,CAAC;QAChC,CAAC;QACD,KAAK,KAAK,CAAC,CAAC,CAAC;YACX,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YACjF,OAAO,MAAM,CAAC,eAAe,CAAC;QAChC,CAAC;QACD,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC;YACrE,OAAO,MAAM,CAAC,eAAe,CAAC;QAChC,CAAC;QACD,KAAK,SAAS,CAAC,CAAC,CAAC;YACf,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;YACvC,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAC;YAC1C,QAAQ,CAAC,cAAc,UAAU,MAAM,YAAY,GAAG,EAAE;gBACtD,KAAK,EAAE,SAAS;gBAChB,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE;aACnB,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC;AAOD,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,eAAuB,EACvB,SAAiB,EACjB,UAAoC,EAAE;IAEtC,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IACrD,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAElD,MAAM,KAAK,GAAG,aAAa,CAAC;QAC1B,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,iBAAiB;QACzB,IAAI,EAAE,UAAU;KACjB,CAAC,CAAC;IAEH,2DAA2D;IAC3D,iDAAiD;IACjD,mEAAmE;IACnE,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAC9C,KAAK,EACL,KAAK,EACL,KAAK,EACL,KAAK,EACL,OAAO,CAAC,WAAW,EACnB,OAAO,CAAC,UAAU,CACnB,CAAC;IACF,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AASD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,OAAO,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,EAAE,mBAAmB,CAAC,CAAC;AAC7D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,WAAmB,EACnB,SAAiB,EACjB,YAA0B,EAC1B,UAA4B,EAAE;IAE9B,MAAM,EAAE,KAAK,GAAG,KAAK,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAExD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,mBAAmB,SAAS,EAAE,CAAC,CAAC;QAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,WAAW,CAAC,SAAS,CAAC,CAAC;QACxC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAEhD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,MAAM,eAAe,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;QAErD,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAC7C,OAAO,CAAC,GAAG,CAAC,mCAAmC,eAAe,EAAE,CAAC,CAAC;QACpE,CAAC;aAAM,CAAC;YACN,MAAM,oBAAoB,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,YAAY,EAAE,CAAC,CAAC;YAElE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;gBACpC,MAAM,IAAI,KAAK,CAAC,8BAA8B,eAAe,EAAE,CAAC,CAAC;YACnE,CAAC;YAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,eAAe,EAAE,CAAC,CAAC;QAC/D,CAAC;QAED,MAAM,YAAY,CAAC,eAAe,EAAE,SAAS,CAAC,CAAC;QAE/C,OAAO,CAAC,GAAG,CAAC,OAAO,WAAW,uBAAuB,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,uBAAuB,SAAS,EAAE,CAAC,CAAC;IAClD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend-init.d.ts","sourceRoot":"","sources":["../../src/actions/extend-init.ts"],"names":[],"mappings":"AAgCA,eAAO,MAAM,aAAa,QAAO,IA2BhC,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { fileURLToPath } from "url";
|
|
4
|
+
const SKILL_DIRS = [".claude/skills/extend", ".claude/skills/narrate"];
|
|
5
|
+
const getPackageRoot = () => {
|
|
6
|
+
const currentDir = path.dirname(fileURLToPath(import.meta.url));
|
|
7
|
+
// From lib/actions/ or src/actions/, go up two levels to package root
|
|
8
|
+
return path.resolve(currentDir, "..", "..");
|
|
9
|
+
};
|
|
10
|
+
const copyDirRecursive = (src, dest) => {
|
|
11
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
12
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
13
|
+
let count = 0;
|
|
14
|
+
entries.forEach((entry) => {
|
|
15
|
+
const srcPath = path.join(src, entry.name);
|
|
16
|
+
const destPath = path.join(dest, entry.name);
|
|
17
|
+
if (entry.isDirectory()) {
|
|
18
|
+
count += copyDirRecursive(srcPath, destPath);
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
fs.copyFileSync(srcPath, destPath);
|
|
22
|
+
count++;
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
return count;
|
|
26
|
+
};
|
|
27
|
+
export const runExtendInit = () => {
|
|
28
|
+
const packageRoot = getPackageRoot();
|
|
29
|
+
let totalFiles = 0;
|
|
30
|
+
SKILL_DIRS.forEach((skillDir) => {
|
|
31
|
+
const srcSkillDir = path.join(packageRoot, skillDir);
|
|
32
|
+
if (!fs.existsSync(srcSkillDir)) {
|
|
33
|
+
console.warn(`Skill files not found at: ${srcSkillDir}, skipping`);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
const destSkillDir = path.join(process.cwd(), skillDir);
|
|
37
|
+
if (fs.existsSync(destSkillDir)) {
|
|
38
|
+
console.log(`Overwriting: ${destSkillDir}`);
|
|
39
|
+
}
|
|
40
|
+
const fileCount = copyDirRecursive(srcSkillDir, destSkillDir);
|
|
41
|
+
totalFiles += fileCount;
|
|
42
|
+
console.log(` ${skillDir}/ (${fileCount} files)`);
|
|
43
|
+
});
|
|
44
|
+
console.log(`\nInstalled skills (${totalFiles} files total)`);
|
|
45
|
+
console.log(`\nUsage in Claude Code:`);
|
|
46
|
+
console.log(` /narrate <source file> Full pipeline (recommended)`);
|
|
47
|
+
console.log(` /extend <mulmo_script.json> Add metadata to existing MulmoScript`);
|
|
48
|
+
};
|
|
49
|
+
//# sourceMappingURL=extend-init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend-init.js","sourceRoot":"","sources":["../../src/actions/extend-init.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,CAAC,uBAAuB,EAAE,wBAAwB,CAAC,CAAC;AAEvE,MAAM,cAAc,GAAG,GAAW,EAAE;IAClC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,sEAAsE;IACtE,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9C,CAAC,CAAC;AAEF,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,IAAY,EAAU,EAAE;IAC7D,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7D,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,OAAO,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;QACxB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,IAAI,gBAAgB,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YACnC,KAAK,EAAE,CAAC;QACV,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,GAAS,EAAE;IACtC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,UAAU,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;QAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;QAErD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,IAAI,CAAC,6BAA6B,WAAW,YAAY,CAAC,CAAC;YACnE,OAAO;QACT,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,QAAQ,CAAC,CAAC;QAExD,IAAI,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,gBAAgB,YAAY,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAC9D,UAAU,IAAI,SAAS,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,KAAK,QAAQ,MAAM,SAAS,SAAS,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,eAAe,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACvC,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC5E,OAAO,CAAC,GAAG,CAAC,uEAAuE,CAAC,CAAC;AACvF,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend-validate.d.ts","sourceRoot":"","sources":["../../src/actions/extend-validate.ts"],"names":[],"mappings":"AAuCA,eAAO,MAAM,iBAAiB,GAAI,UAAU,MAAM,KAAG,IAmCpD,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { extendedScriptSchema } from "@mulmocast/extended-types";
|
|
4
|
+
const summarizeScript = (data) => {
|
|
5
|
+
const script = data;
|
|
6
|
+
const beats = script.beats;
|
|
7
|
+
const beatsWithMeta = beats.filter((b) => b.meta);
|
|
8
|
+
const sections = [
|
|
9
|
+
...new Set(beats.map((b) => b.meta?.section).filter(Boolean)),
|
|
10
|
+
];
|
|
11
|
+
return {
|
|
12
|
+
beatCount: beats.length,
|
|
13
|
+
hasScriptMeta: !!script.scriptMeta,
|
|
14
|
+
metaCoverage: beats.length > 0 ? Math.round((beatsWithMeta.length / beats.length) * 100) : 0,
|
|
15
|
+
sections,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const formatZodError = (error) => {
|
|
19
|
+
const lines = error.issues.map((issue) => {
|
|
20
|
+
const pathStr = issue.path.length > 0 ? issue.path.map((p) => String(p)).join(".") : "(root)";
|
|
21
|
+
return ` - ${pathStr}: ${issue.message}`;
|
|
22
|
+
});
|
|
23
|
+
return lines.join("\n");
|
|
24
|
+
};
|
|
25
|
+
export const runExtendValidate = (filePath) => {
|
|
26
|
+
const resolvedPath = path.resolve(filePath);
|
|
27
|
+
if (!fs.existsSync(resolvedPath)) {
|
|
28
|
+
console.error(`File not found: ${resolvedPath}`);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
let data;
|
|
32
|
+
try {
|
|
33
|
+
const content = fs.readFileSync(resolvedPath, "utf-8");
|
|
34
|
+
data = JSON.parse(content);
|
|
35
|
+
}
|
|
36
|
+
catch (e) {
|
|
37
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
38
|
+
console.error(`Failed to parse JSON: ${message}`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
const result = extendedScriptSchema.safeParse(data);
|
|
42
|
+
if (!result.success) {
|
|
43
|
+
console.error(`\n✗ Validation failed: ${resolvedPath}\n`);
|
|
44
|
+
console.error(formatZodError(result.error));
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
const summary = summarizeScript(data);
|
|
48
|
+
console.log(`\n✓ Valid ExtendedScript: ${resolvedPath}`);
|
|
49
|
+
console.log(` Beats: ${summary.beatCount}`);
|
|
50
|
+
console.log(` ScriptMeta: ${summary.hasScriptMeta ? "yes" : "no"}`);
|
|
51
|
+
console.log(` Meta coverage: ${summary.metaCoverage}%`);
|
|
52
|
+
if (summary.sections.length > 0) {
|
|
53
|
+
console.log(` Sections: ${summary.sections.join(", ")}`);
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=extend-validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extend-validate.js","sourceRoot":"","sources":["../../src/actions/extend-validate.ts"],"names":[],"mappings":"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"}
|