@lalalic/markcut 1.0.0 → 1.1.1
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/bin/markcut +19 -0
- package/package.json +4 -4
- package/src/render/cli.mjs +27 -32
- package/src/render/cli.test.ts +13 -0
package/bin/markcut
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { spawnSync } from "node:child_process";
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = dirname(__filename);
|
|
8
|
+
const entry = resolve(__dirname, "..", "src", "render", "cli.mjs");
|
|
9
|
+
|
|
10
|
+
const result = spawnSync(process.execPath, [entry, ...process.argv.slice(2)], {
|
|
11
|
+
stdio: "inherit",
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (result.error) {
|
|
15
|
+
console.error(result.error.message);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
process.exit(result.status ?? 1);
|
package/package.json
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lalalic/markcut",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Markdown-to-video engine. Describe scenes in markdown, get a rendered video.",
|
|
5
5
|
"bin": {
|
|
6
|
-
"markcut": "
|
|
6
|
+
"markcut": "bin/markcut"
|
|
7
7
|
},
|
|
8
8
|
"type": "module",
|
|
9
9
|
"main": "./src/entry.tsx",
|
|
@@ -17,8 +17,8 @@
|
|
|
17
17
|
},
|
|
18
18
|
"scripts": {
|
|
19
19
|
"render": "node src/render/cli.mjs render",
|
|
20
|
-
"render:all": "node src/render/cli.mjs render
|
|
21
|
-
"render:demo": "node src/render/cli.mjs render src/demo-components.json
|
|
20
|
+
"render:all": "node src/render/cli.mjs render",
|
|
21
|
+
"render:demo": "node src/render/cli.mjs render src/demo-components.json",
|
|
22
22
|
"templates": "node src/render/cli.mjs templates",
|
|
23
23
|
"preview": "node src/render/cli.mjs preview",
|
|
24
24
|
"verify": "node src/render/cli.mjs verify",
|
package/src/render/cli.mjs
CHANGED
|
@@ -45,47 +45,46 @@ markcut CLI — Markdown/JSON → video pipeline
|
|
|
45
45
|
|
|
46
46
|
Commands:
|
|
47
47
|
|
|
48
|
-
compile <file> --output <path> Parse + compile → stream tree JSON (sync, no I/O)
|
|
49
|
-
|
|
50
48
|
verify <file> Parse + validate descriptive file
|
|
51
49
|
--cli Check required CLI tools are installed
|
|
52
50
|
|
|
53
|
-
resolve <file> --output <path> Run async pipeline: TTS, STT, media durations
|
|
54
|
-
--script-output-dir <dir> Directory for generated TTS/STT files
|
|
55
|
-
--media-output-dir <dir> Directory for generated TTI/TTV media files
|
|
56
|
-
--compile Also compile to stream tree after resolving
|
|
57
|
-
|
|
58
|
-
render <file.json|.md> Resolve + compile + render to MP4
|
|
59
|
-
--aspect <16x9|9x16|1x1|all> Aspect ratio (default: 16x9)
|
|
60
|
-
--output <path> Output path (default: out/video-{aspect}.mp4)
|
|
61
|
-
--verbose Show full per-frame progress (default: compact)
|
|
62
|
-
|
|
63
51
|
preview <file.json|.md> Open player with live preview
|
|
64
52
|
--edit Auto-reload on file change
|
|
65
53
|
--label Open label input overlay
|
|
66
54
|
--no-browser Skip opening browser automatically
|
|
67
55
|
--port <num> Port for the player server (default: 3001)
|
|
68
56
|
|
|
69
|
-
|
|
57
|
+
render <file.json|.md> Resolve + compile + render to MP4
|
|
58
|
+
--output <path> Output path (default: out/video.mp4)
|
|
59
|
+
--verbose Show full per-frame progress (default: compact)
|
|
60
|
+
|
|
61
|
+
vision <folder> Extract metadata into metadata.json
|
|
70
62
|
--label Full pipeline: preview → label → normalize → percept → segments
|
|
71
63
|
--agent <template> Custom text LLM CLI for detect-scenes ({prompt})
|
|
72
64
|
--itt <template> Custom ITT CLI template with {input}, {prompt}
|
|
73
65
|
--vtt <template> Custom VTT CLI template with {input}, {prompt}
|
|
74
66
|
--stt <template> Custom STT CLI template with {input}, {output}
|
|
75
|
-
--
|
|
76
|
-
|
|
67
|
+
--prompts-file <path> Path to prompts markdown file (default: vision_prompts.md)
|
|
68
|
+
--vtt-sample-interval <n> Sample one video frame every N seconds (default: 5)
|
|
69
|
+
--context "text" Background context about people/places (injected into prompts)
|
|
70
|
+
--pick <files> Comma-separated filenames to process
|
|
71
|
+
--skip-stt Skip speech-to-text for videos
|
|
72
|
+
--dry-run Show what would be processed without running AI
|
|
73
|
+
--show-prompts Print the prompts file and exit
|
|
74
|
+
--show-clis Print the default ITT/VTT/STT CLI templates
|
|
75
|
+
--help Show this help
|
|
76
|
+
--<prompt-name> "text" Override any prompt template from vision_prompts.md
|
|
77
77
|
`);
|
|
78
78
|
}
|
|
79
79
|
|
|
80
|
-
function parseArgs(argv) {
|
|
81
|
-
const args = { command: "", file: "",
|
|
80
|
+
export function parseArgs(argv) {
|
|
81
|
+
const args = { command: "", file: "", output: "", forceNew: false, verbose: false, label: false, edit: false, noBrowser: false, chat: false, port: 3001, compile: false, cli: false, scriptOutputDir: "", mediaOutputDir: "", variant: [] };
|
|
82
82
|
let i = 2;
|
|
83
83
|
if (argv[i]) args.command = argv[i++];
|
|
84
84
|
if (argv[i] && !argv[i].startsWith("--")) args.file = argv[i++];
|
|
85
85
|
while (i < argv.length) {
|
|
86
86
|
const flag = argv[i++];
|
|
87
|
-
if (flag === "--
|
|
88
|
-
else if (flag === "--output" && argv[i]) args.output = argv[i++];
|
|
87
|
+
if (flag === "--output" && argv[i]) args.output = argv[i++];
|
|
89
88
|
else if (flag === "--script-output-dir" && argv[i]) args.scriptOutputDir = argv[i++];
|
|
90
89
|
else if (flag === "--media-output-dir" && argv[i]) args.mediaOutputDir = argv[i++];
|
|
91
90
|
else if (flag === "--cli") args.cli = true;
|
|
@@ -341,16 +340,10 @@ async function main() {
|
|
|
341
340
|
process.exit(1);
|
|
342
341
|
}
|
|
343
342
|
|
|
344
|
-
const
|
|
345
|
-
|
|
346
|
-
for (const aspect of aspects) {
|
|
347
|
-
const output = args.output && aspects.length === 1
|
|
348
|
-
? resolve(args.output)
|
|
349
|
-
: join(ROOT, "out", `video-${aspect}.mp4`);
|
|
350
|
-
await renderOne(streamTree, aspect, output, args.verbose);
|
|
351
|
-
}
|
|
343
|
+
const output = args.output ? resolve(args.output) : join(ROOT, "out", "video.mp4");
|
|
344
|
+
await renderOne(streamTree, "16x9", output, args.verbose);
|
|
352
345
|
|
|
353
|
-
console.log("\n✅
|
|
346
|
+
console.log("\n✅ Render complete.");
|
|
354
347
|
process.exit(0);
|
|
355
348
|
}
|
|
356
349
|
|
|
@@ -622,7 +615,9 @@ function hasScript(root) {
|
|
|
622
615
|
process.exit(1);
|
|
623
616
|
}
|
|
624
617
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
618
|
+
if (process.argv[1] && process.argv[1].endsWith("cli.mjs")) {
|
|
619
|
+
main().catch((e) => {
|
|
620
|
+
console.error(e);
|
|
621
|
+
process.exit(1);
|
|
622
|
+
});
|
|
623
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { parseArgs } from "./cli.mjs";
|
|
3
|
+
|
|
4
|
+
describe("parseArgs", () => {
|
|
5
|
+
it("supports render without an aspect flag", () => {
|
|
6
|
+
const args = parseArgs(["node", "markcut", "render", "input.md", "--output", "out/video.mp4"]);
|
|
7
|
+
|
|
8
|
+
expect(args.command).toBe("render");
|
|
9
|
+
expect(args.file).toBe("input.md");
|
|
10
|
+
expect(args.output).toBe("out/video.mp4");
|
|
11
|
+
expect(args).not.toHaveProperty("aspect");
|
|
12
|
+
});
|
|
13
|
+
});
|