zerocut-cli 0.1.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.
Files changed (63) hide show
  1. package/.eslintrc.js +11 -0
  2. package/.prettierignore +3 -0
  3. package/.prettierrc.json +6 -0
  4. package/README.md +205 -0
  5. package/dist/bin/zerocut.d.ts +2 -0
  6. package/dist/bin/zerocut.js +5 -0
  7. package/dist/cli.d.ts +3 -0
  8. package/dist/cli.js +24 -0
  9. package/dist/commands/config.d.ts +4 -0
  10. package/dist/commands/config.js +129 -0
  11. package/dist/commands/ffmpeg.d.ts +4 -0
  12. package/dist/commands/ffmpeg.js +32 -0
  13. package/dist/commands/foo.d.ts +4 -0
  14. package/dist/commands/foo.js +14 -0
  15. package/dist/commands/help.d.ts +4 -0
  16. package/dist/commands/help.js +14 -0
  17. package/dist/commands/image.d.ts +4 -0
  18. package/dist/commands/image.js +149 -0
  19. package/dist/commands/music.d.ts +4 -0
  20. package/dist/commands/music.js +74 -0
  21. package/dist/commands/pandoc.d.ts +4 -0
  22. package/dist/commands/pandoc.js +32 -0
  23. package/dist/commands/skill.d.ts +4 -0
  24. package/dist/commands/skill.js +24 -0
  25. package/dist/commands/tts.d.ts +4 -0
  26. package/dist/commands/tts.js +74 -0
  27. package/dist/commands/video.d.ts +4 -0
  28. package/dist/commands/video.js +166 -0
  29. package/dist/index.d.ts +1 -0
  30. package/dist/index.js +6 -0
  31. package/dist/services/cerevox.d.ts +34 -0
  32. package/dist/services/cerevox.js +256 -0
  33. package/dist/services/commandLoader.d.ts +3 -0
  34. package/dist/services/commandLoader.js +80 -0
  35. package/dist/services/config.d.ts +15 -0
  36. package/dist/services/config.js +235 -0
  37. package/dist/skill/SKILL.md +133 -0
  38. package/dist/types/command.d.ts +6 -0
  39. package/dist/types/command.js +2 -0
  40. package/dist/utils/progress.d.ts +1 -0
  41. package/dist/utils/progress.js +13 -0
  42. package/eslint.config.js +30 -0
  43. package/package.json +52 -0
  44. package/scripts/copy-skill-md.cjs +8 -0
  45. package/src/bin/zerocut.ts +3 -0
  46. package/src/cli.ts +25 -0
  47. package/src/commands/config.ts +130 -0
  48. package/src/commands/ffmpeg.ts +37 -0
  49. package/src/commands/help.ts +13 -0
  50. package/src/commands/image.ts +194 -0
  51. package/src/commands/music.ts +78 -0
  52. package/src/commands/pandoc.ts +37 -0
  53. package/src/commands/skill.ts +20 -0
  54. package/src/commands/tts.ts +80 -0
  55. package/src/commands/video.ts +202 -0
  56. package/src/index.ts +1 -0
  57. package/src/services/cerevox.ts +296 -0
  58. package/src/services/commandLoader.ts +42 -0
  59. package/src/services/config.ts +230 -0
  60. package/src/skill/SKILL.md +209 -0
  61. package/src/types/command.ts +7 -0
  62. package/src/utils/progress.ts +10 -0
  63. package/tsconfig.json +16 -0
@@ -0,0 +1,74 @@
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.description = exports.name = void 0;
7
+ exports.register = register;
8
+ const cerevox_1 = require("../services/cerevox");
9
+ const progress_1 = require("../utils/progress");
10
+ const node_fs_1 = __importDefault(require("node:fs"));
11
+ const node_path_1 = __importDefault(require("node:path"));
12
+ exports.name = "music";
13
+ exports.description = "Music command: create music";
14
+ function register(program) {
15
+ const parent = program.command("music").description("Create a new music; requires --prompt");
16
+ async function musicCreateAction(opts) {
17
+ const session = (0, cerevox_1.getSessionFromCommand)(this);
18
+ if (!session) {
19
+ process.stderr.write("No active session\n");
20
+ return;
21
+ }
22
+ const prompt = typeof opts.prompt === "string" ? opts.prompt : undefined;
23
+ if (!prompt || prompt.trim().length === 0) {
24
+ process.stderr.write("Missing required option: --prompt\n");
25
+ process.exitCode = 1;
26
+ return;
27
+ }
28
+ const res = await session.ai.generateMusic({
29
+ prompt,
30
+ onProgress: (0, progress_1.createProgressSpinner)("inferencing"),
31
+ });
32
+ process.stdout.write("\n");
33
+ try {
34
+ if (res?.url) {
35
+ const tosUrl = await (0, cerevox_1.syncToTOS)(res.url);
36
+ if (tosUrl) {
37
+ res.url = tosUrl;
38
+ }
39
+ }
40
+ }
41
+ catch (ex) {
42
+ console.log(ex.message);
43
+ }
44
+ const output = typeof opts.output === "string" ? opts.output : undefined;
45
+ if (output) {
46
+ const dir = process.cwd();
47
+ const url = res.url;
48
+ const response = await fetch(url);
49
+ const buffer = Buffer.from(await response.arrayBuffer());
50
+ const filePath = node_path_1.default.resolve(dir, output);
51
+ if (!node_fs_1.default.existsSync(node_path_1.default.dirname(filePath))) {
52
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
53
+ }
54
+ node_fs_1.default.writeFileSync(filePath, buffer);
55
+ res.output = filePath;
56
+ }
57
+ console.log({
58
+ url: res.url,
59
+ duration: res.duration,
60
+ usage: res.usage,
61
+ output: res.output,
62
+ });
63
+ }
64
+ parent
65
+ .option("--prompt <prompt>", "Text prompt for music generation (required)")
66
+ .option("--output <file>", "Output file path")
67
+ .action(musicCreateAction);
68
+ parent
69
+ .command("create")
70
+ .description("Create a new music; requires --prompt")
71
+ .option("--prompt <prompt>", "Text prompt for music generation (required)")
72
+ .option("--output <file>", "Output file path")
73
+ .action(musicCreateAction);
74
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ export declare const name = "pandoc";
3
+ export declare const description = "Run pandoc in sandbox";
4
+ export declare function register(program: Command): void;
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.description = exports.name = void 0;
4
+ exports.register = register;
5
+ const cerevox_1 = require("../services/cerevox");
6
+ exports.name = "pandoc";
7
+ exports.description = "Run pandoc in sandbox";
8
+ function register(program) {
9
+ program
10
+ .command("pandoc")
11
+ .description("Run pandoc command in sandbox")
12
+ .allowUnknownOption(true)
13
+ .option("--args <args...>", "Arguments passed to pandoc")
14
+ .option("--resources <resources...>", "Resource files/urls to sync into sandbox")
15
+ .action(async function (opts) {
16
+ const session = (0, cerevox_1.getSessionFromCommand)(this);
17
+ if (!session) {
18
+ process.stderr.write("No active session\n");
19
+ return;
20
+ }
21
+ const args = Array.isArray(opts.args) ? opts.args : [];
22
+ if (args.length === 0) {
23
+ process.stderr.write("Missing required option: --args\n");
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ const command = `pandoc ${args.join(" ")}`;
28
+ const resources = Array.isArray(opts.resources) ? opts.resources : [];
29
+ const res = await (0, cerevox_1.runPandocCommand)(session, command, resources);
30
+ console.log(res);
31
+ });
32
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ export declare const name = "skill";
3
+ export declare const description = "Print built-in SKILL.md content";
4
+ export declare function register(program: Command): void;
@@ -0,0 +1,24 @@
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.description = exports.name = void 0;
7
+ exports.register = register;
8
+ const node_fs_1 = __importDefault(require("node:fs"));
9
+ const node_path_1 = __importDefault(require("node:path"));
10
+ exports.name = "skill";
11
+ exports.description = "Print built-in SKILL.md content";
12
+ function register(program) {
13
+ program
14
+ .command("skill")
15
+ .description("Print built-in skill markdown")
16
+ .action(() => {
17
+ const filePath = node_path_1.default.resolve(__dirname, "../skill/SKILL.md");
18
+ const content = node_fs_1.default.readFileSync(filePath, "utf8");
19
+ process.stdout.write(content);
20
+ if (!content.endsWith("\n")) {
21
+ process.stdout.write("\n");
22
+ }
23
+ });
24
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ export declare const name = "tts";
3
+ export declare const description = "TTS command: create speech audio";
4
+ export declare function register(program: Command): void;
@@ -0,0 +1,74 @@
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.description = exports.name = void 0;
7
+ exports.register = register;
8
+ const cerevox_1 = require("../services/cerevox");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ exports.name = "tts";
12
+ exports.description = "TTS command: create speech audio";
13
+ function register(program) {
14
+ const parent = program.command("tts").description("Create speech audio; requires --text");
15
+ async function ttsCreateAction(opts) {
16
+ const session = (0, cerevox_1.getSessionFromCommand)(this);
17
+ if (!session) {
18
+ process.stderr.write("No active session\n");
19
+ return;
20
+ }
21
+ const text = typeof opts.text === "string" ? opts.text : undefined;
22
+ if (!text || text.trim().length === 0) {
23
+ process.stderr.write("Missing required option: --text\n");
24
+ process.exitCode = 1;
25
+ return;
26
+ }
27
+ const prompt = typeof opts.prompt === "string" ? opts.prompt : undefined;
28
+ const voiceId = typeof opts.voiceId === "string" ? opts.voiceId : undefined;
29
+ const res = await session.ai.textToSpeech({
30
+ prompt,
31
+ text,
32
+ voiceId,
33
+ });
34
+ try {
35
+ if (res?.url) {
36
+ const tosUrl = await (0, cerevox_1.syncToTOS)(res.url);
37
+ if (tosUrl) {
38
+ res.url = tosUrl;
39
+ }
40
+ }
41
+ }
42
+ catch (ex) {
43
+ console.log(ex.message);
44
+ }
45
+ const output = typeof opts.output === "string" ? opts.output : undefined;
46
+ if (output) {
47
+ const dir = process.cwd();
48
+ const url = res.url;
49
+ const response = await fetch(url);
50
+ const buffer = Buffer.from(await response.arrayBuffer());
51
+ const filePath = node_path_1.default.resolve(dir, output);
52
+ if (!node_fs_1.default.existsSync(node_path_1.default.dirname(filePath))) {
53
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
54
+ }
55
+ node_fs_1.default.writeFileSync(filePath, buffer);
56
+ res.output = filePath;
57
+ }
58
+ console.log(res);
59
+ }
60
+ parent
61
+ .option("--prompt <prompt>", "Prompt for speech style/context")
62
+ .option("--text <text>", "Text to synthesize (required)")
63
+ .option("--voiceId <voiceId>", "Voice ID")
64
+ .option("--output <file>", "Output file path")
65
+ .action(ttsCreateAction);
66
+ parent
67
+ .command("create")
68
+ .description("Create speech audio; requires --text")
69
+ .option("--prompt <prompt>", "Prompt for speech style/context")
70
+ .option("--text <text>", "Text to synthesize (required)")
71
+ .option("--voiceId <voiceId>", "Voice ID")
72
+ .option("--output <file>", "Output file path")
73
+ .action(ttsCreateAction);
74
+ }
@@ -0,0 +1,4 @@
1
+ import type { Command } from "commander";
2
+ export declare const name = "video";
3
+ export declare const description = "Video command: create video";
4
+ export declare function register(program: Command): void;
@@ -0,0 +1,166 @@
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.description = exports.name = void 0;
7
+ exports.register = register;
8
+ const cerevox_1 = require("../services/cerevox");
9
+ const node_fs_1 = __importDefault(require("node:fs"));
10
+ const node_path_1 = __importDefault(require("node:path"));
11
+ const progress_1 = require("../utils/progress");
12
+ exports.name = "video";
13
+ exports.description = "Video command: create video";
14
+ function register(program) {
15
+ const parent = program.command("video").description("Create a new video; requires --prompt");
16
+ const allowedTypes = [
17
+ "zerocut3.0",
18
+ "seedance-1.5-pro",
19
+ "vidu",
20
+ "vidu-pro",
21
+ "viduq3",
22
+ "viduq3-turbo",
23
+ "kling",
24
+ "kling-v3",
25
+ "wan",
26
+ "wan-flash",
27
+ "sora2",
28
+ "sora2-pro",
29
+ "veo3.1",
30
+ "veo3.1-pro",
31
+ ];
32
+ async function videoCreateAction(opts) {
33
+ const session = (0, cerevox_1.getSessionFromCommand)(this);
34
+ if (!session) {
35
+ process.stderr.write("No active session\n");
36
+ return;
37
+ }
38
+ const prompt = typeof opts.prompt === "string" ? opts.prompt : undefined;
39
+ if (!prompt || prompt.trim().length === 0) {
40
+ process.stderr.write("Missing required option: --prompt\n");
41
+ process.exitCode = 1;
42
+ return;
43
+ }
44
+ let model = typeof opts.video === "string" ? opts.video.trim() : undefined;
45
+ if (model && !allowedTypes.includes(model)) {
46
+ process.stderr.write(`Invalid value for --video: ${model}. Allowed: ${allowedTypes.join("|")}\n`);
47
+ process.exitCode = 1;
48
+ return;
49
+ }
50
+ if (!model)
51
+ model = "vidu";
52
+ const durationStr = typeof opts.duration === "string" ? opts.duration.trim() : undefined;
53
+ let duration = 0;
54
+ if (durationStr) {
55
+ const n = Number.parseInt(durationStr, 10);
56
+ if (!Number.isFinite(n) || n < 1 || n > 16) {
57
+ process.stderr.write("Invalid value for --duration: must be integer 1-16\n");
58
+ process.exitCode = 1;
59
+ return;
60
+ }
61
+ duration = n;
62
+ }
63
+ const allowedAspectRatios = ["9:16", "16:9", "1:1"];
64
+ const ar = typeof opts.aspectRatio === "string" ? opts.aspectRatio : undefined;
65
+ if (ar && !allowedAspectRatios.includes(ar)) {
66
+ process.stderr.write(`Invalid value for --aspectRatio: ${ar}. Allowed: ${allowedAspectRatios.join("|")}\n`);
67
+ process.exitCode = 1;
68
+ return;
69
+ }
70
+ const aspectRatio = ar;
71
+ const images = [];
72
+ if (opts.firstFrame) {
73
+ images.push({
74
+ type: "first_frame",
75
+ url: await (0, cerevox_1.getMaterialUri)(session, opts.firstFrame),
76
+ });
77
+ }
78
+ if (opts.lastFrame) {
79
+ images.push({
80
+ type: "last_frame",
81
+ url: await (0, cerevox_1.getMaterialUri)(session, opts.lastFrame),
82
+ });
83
+ }
84
+ const refsList = typeof opts.refs === "string" && opts.refs.length > 0
85
+ ? opts.refs
86
+ .split(",")
87
+ .map((s) => s.trim())
88
+ .filter((s) => s.length > 0)
89
+ : [];
90
+ for (const ref of refsList) {
91
+ images.push({
92
+ type: "reference",
93
+ url: await (0, cerevox_1.getMaterialUri)(session, ref),
94
+ });
95
+ }
96
+ const res = await session.ai.generateVideo({
97
+ prompt,
98
+ model: model,
99
+ duration: duration || undefined,
100
+ resolution: opts.resolution,
101
+ aspect_ratio: aspectRatio,
102
+ mute: !opts.withAudio,
103
+ optimize_camera: opts.optimizeCameraMotion,
104
+ seed: opts.seed ? Number.parseInt(opts.seed, 10) : undefined,
105
+ images: images.length > 0 ? images : undefined,
106
+ onProgress: (0, progress_1.createProgressSpinner)("inferencing"),
107
+ });
108
+ try {
109
+ if (res?.url) {
110
+ const tosUrl = await (0, cerevox_1.syncToTOS)(res.url);
111
+ if (tosUrl) {
112
+ res.url = tosUrl;
113
+ }
114
+ }
115
+ }
116
+ catch { }
117
+ process.stdout.write("\n");
118
+ const output = typeof opts.output === "string" ? opts.output : undefined;
119
+ if (output) {
120
+ const dir = process.cwd();
121
+ const url = res.url;
122
+ const response = await fetch(url);
123
+ const buffer = Buffer.from(await response.arrayBuffer());
124
+ const filePath = node_path_1.default.resolve(dir, output);
125
+ if (!node_fs_1.default.existsSync(node_path_1.default.dirname(filePath))) {
126
+ node_fs_1.default.mkdirSync(node_path_1.default.dirname(filePath), { recursive: true });
127
+ }
128
+ node_fs_1.default.writeFileSync(filePath, buffer);
129
+ res.output = filePath;
130
+ }
131
+ console.log(res);
132
+ }
133
+ // default action on `zerocut video`
134
+ parent
135
+ .option("--prompt <prompt>", "Text prompt for video generation (required)")
136
+ .option("--duration <duration>", "Video duration in seconds")
137
+ .option("--video <video>", `Video model: ${allowedTypes.join("|")} (default: vidu)`)
138
+ .option("--seed <seed>", "Random seed")
139
+ .option("--firstFrame <image>", "First frame image path/url")
140
+ .option("--lastFrame <image>", "Last frame image path/url")
141
+ .option("--refs <refs>", "Comma-separated reference image/video paths/urls")
142
+ .option("--resolution <resolution>", "Resolution, e.g., 720p")
143
+ .option("--aspectRatio <ratio>", "Aspect ratio: 9:16|16:9|1:1")
144
+ .option("--withAudio", "Include audio track")
145
+ .option("--optimizeCameraMotion", "Optimize camera motion")
146
+ .option("--output <file>", "Output file path")
147
+ .action(videoCreateAction);
148
+ // keep `video create` for compatibility
149
+ parent
150
+ .command("create")
151
+ .description("Create a new video; requires --prompt")
152
+ .option("--prompt <prompt>", "Text prompt for video generation (required)")
153
+ .option("--duration <duration>", "Video duration in seconds")
154
+ .option("--video <video>", `Video model: ${allowedTypes.join("|")} (default: vidu)`)
155
+ .option("--seed <seed>", "Random seed")
156
+ .option("--firstFrame <image>", "First frame image path/url")
157
+ .option("--lastFrame <image>", "Last frame image path/url")
158
+ .option("--refs <refs>", "Comma-separated reference image/video paths/urls")
159
+ .option("--resolution <resolution>", "Resolution, e.g., 720p")
160
+ .option("--aspectRatio <ratio>", "Aspect ratio: 9:16|16:9|1:1")
161
+ .option("--withAudio", "Include audio track")
162
+ .option("--optimizeCameraMotion", "Optimize camera motion")
163
+ .option("--output <file>", "Output file path")
164
+ .action(videoCreateAction);
165
+ // removed `video edit`
166
+ }
@@ -0,0 +1 @@
1
+ export { run, createProgram } from "./cli";
package/dist/index.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createProgram = exports.run = void 0;
4
+ var cli_1 = require("./cli");
5
+ Object.defineProperty(exports, "run", { enumerable: true, get: function () { return cli_1.run; } });
6
+ Object.defineProperty(exports, "createProgram", { enumerable: true, get: function () { return cli_1.createProgram; } });
@@ -0,0 +1,34 @@
1
+ import { type Session } from "cerevox";
2
+ export declare const SESSION_SYMBOL: unique symbol;
3
+ export declare function attachSessionToCommand(cmd: {
4
+ [k: symbol]: unknown;
5
+ }, session: Session): void;
6
+ export declare function getSessionFromCommand(cmd: {
7
+ [k: symbol]: unknown;
8
+ }): Session | undefined;
9
+ export declare function getApiKey(): string;
10
+ export declare function getRegion(): "cn" | "us";
11
+ export declare function openSession(): Promise<Session>;
12
+ export declare function closeSession(session: Session): Promise<void>;
13
+ interface GetMaterialUriOptions {
14
+ fileSizeLimit?: number;
15
+ }
16
+ export declare function getMaterialUri(session: Session, fileName: string, options?: GetMaterialUriOptions): Promise<string>;
17
+ export declare function syncToTOS(url: string): Promise<string>;
18
+ export declare function runFFMpegCommand(session: Session, command: string, resources?: string[]): Promise<{
19
+ exitCode: number;
20
+ outputFilePath: string;
21
+ data: {
22
+ stdout: string;
23
+ stderr: string | undefined;
24
+ };
25
+ }>;
26
+ export declare function runPandocCommand(session: Session, command: string, resources?: string[]): Promise<{
27
+ exitCode: number;
28
+ outputFilePath: string;
29
+ data: {
30
+ stdout: string;
31
+ stderr: string | undefined;
32
+ };
33
+ }>;
34
+ export {};