@scenerok/cli 1.0.0 → 1.0.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/README.md CHANGED
@@ -25,6 +25,15 @@ scenerok validate video.vidscript
25
25
  # Render a video
26
26
  scenerok render video.vidscript --resolution 1080x1920 --watch
27
27
 
28
+ # Upload a local project and assets
29
+ scenerok project upload video.vidscript --assets ./assets
30
+
31
+ # Upload, render, watch, and download
32
+ scenerok project upload video.vidscript --assets ./assets --render --watch --download ./renders
33
+
34
+ # Pull generated asset cache
35
+ scenerok cache pull
36
+
28
37
  # Check render status
29
38
  scenerok status 42
30
39
  ```
@@ -35,8 +44,8 @@ scenerok status 42
35
44
 
36
45
  ```bash
37
46
  scenerok auth login # Log in via browser
38
- reelforge auth status # Check auth status
39
- reelforge auth logout # Remove credentials
47
+ scenerok auth status # Check auth status
48
+ scenerok auth logout # Remove credentials
40
49
  ```
41
50
 
42
51
  ### `skills`
@@ -64,7 +73,9 @@ scenerok render <file.vidscript> [options]
64
73
 
65
74
  Options:
66
75
  - `-r, --resolution <resolution>` - Output resolution (e.g. 1080x1920)
76
+ - `-p, --project-id <id>` - Attach the render to an uploaded project
67
77
  - `-w, --watch` - Watch render status until complete
78
+ - `--download [dir]` - Download the completed MP4
68
79
 
69
80
  ### `status`
70
81
 
@@ -74,6 +85,28 @@ scenerok status <render-id>
74
85
 
75
86
  Check the status of a render job.
76
87
 
88
+ Use `scenerok status <render-id> --download ./renders` to download a completed render.
89
+
90
+ ### `project`
91
+
92
+ ```bash
93
+ scenerok project upload <file.vidscript> --assets ./assets
94
+ scenerok project upload <file.vidscript> --assets ./assets --render --watch --download ./renders
95
+ scenerok project list
96
+ scenerok project render <project-id> --watch --download ./renders
97
+ ```
98
+
99
+ `project upload` creates a private SceneRok project on the main server, uploads referenced local assets, rewrites local `input` paths to server asset URLs, and returns a project id. Project renders are visible on the website.
100
+
101
+ ### `cache`
102
+
103
+ ```bash
104
+ scenerok cache pull
105
+ scenerok cache pull --plugin xai-media-video --output ~/.scenerok/cache/assets
106
+ ```
107
+
108
+ Downloads cached generated assets and writes a `manifest.json` to the output folder.
109
+
77
110
  ## Configuration
78
111
 
79
112
  Config is stored in `~/.scenerok/config.json`:
@@ -90,25 +123,16 @@ Config is stored in `~/.scenerok/config.json`:
90
123
  VidScript is a declarative language for describing video compositions.
91
124
 
92
125
  ```vidscript
93
- config {
94
- resolution = "1080x1920";
95
- fps = 30;
96
- output = "video.mp4";
97
- }
126
+ input hero = "./assets/hero.mp4"
98
127
 
99
- scene "intro" {
100
- duration = 3;
101
- background { color = "#FF5733"; }
102
- text "title" {
103
- content = "Hello World";
104
- font = "Inter Bold";
105
- size = 72;
106
- x = 50%; y = 50%;
107
- align = "center";
108
- }
109
- }
128
+ [0s .. 5s] = hero
129
+ [0.4s .. 3s] = text "Hello World", font: "Inter Bold", size: 72, x: "50%", y: "50%", align: center, animate: [fadeIn(0.6s), slideY(40, 0, 0.8s)]
130
+
131
+ output to "video.mp4", resolution: "1080x1920", fps: 30
110
132
  ```
111
133
 
134
+ Animation helpers: `fadeIn`, `fadeOut`, `slideX`, `slideY`, `popIn`, `riseIn`, `swingIn`, `glitchIn`, `float`, `typewriter`.
135
+
112
136
  ## Links
113
137
 
114
138
  - Website: https://scenerok.com
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const cacheCommand: Command;
3
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/commands/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAwBpC,eAAO,MAAM,YAAY,SA6CtB,CAAC"}
@@ -0,0 +1,65 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { mkdirSync, writeFileSync } from 'node:fs';
5
+ import { basename, extname, join, resolve } from 'node:path';
6
+ import fetch from 'node-fetch';
7
+ import { getAssetCache } from '../lib/api.js';
8
+ import { getCacheDir, isAuthenticated } from '../lib/config.js';
9
+ function safeName(value) {
10
+ return value.replace(/[^a-zA-Z0-9._-]/g, '_').slice(0, 120);
11
+ }
12
+ function filenameFor(url, cacheKey) {
13
+ try {
14
+ const parsed = new URL(url);
15
+ const fromUrl = basename(parsed.pathname);
16
+ if (fromUrl && extname(fromUrl))
17
+ return safeName(fromUrl);
18
+ }
19
+ catch {
20
+ // fall through
21
+ }
22
+ return `${safeName(cacheKey)}.bin`;
23
+ }
24
+ export const cacheCommand = new Command('cache')
25
+ .description('Manage local SceneRok asset cache')
26
+ .addCommand(new Command('pull')
27
+ .description('Download cached generated assets to a local folder')
28
+ .option('-o, --output <dir>', 'Output directory', join(getCacheDir(), 'assets'))
29
+ .option('--plugin <name>', 'Filter by plugin name')
30
+ .option('--limit <count>', 'Maximum assets to pull', '100')
31
+ .action(async (options) => {
32
+ if (!isAuthenticated()) {
33
+ console.log(chalk.yellow('Not authenticated'));
34
+ console.log(chalk.dim('Run: scenerok auth login'));
35
+ process.exit(1);
36
+ }
37
+ const outputDir = resolve(options.output);
38
+ mkdirSync(outputDir, { recursive: true });
39
+ const spinner = ora('Fetching asset cache manifest...').start();
40
+ try {
41
+ const manifest = await getAssetCache({
42
+ plugin: options.plugin,
43
+ limit: Number.parseInt(options.limit, 10) || 100,
44
+ });
45
+ spinner.text = `Downloading ${manifest.entries.length} cached asset${manifest.entries.length === 1 ? '' : 's'}...`;
46
+ const downloaded = [];
47
+ for (const entry of manifest.entries) {
48
+ const response = await fetch(entry.r2Url);
49
+ if (!response.ok)
50
+ continue;
51
+ const filename = filenameFor(entry.r2Url, entry.cacheKey);
52
+ const filePath = join(outputDir, filename);
53
+ writeFileSync(filePath, Buffer.from(await response.arrayBuffer()));
54
+ downloaded.push({ ...entry, filePath });
55
+ }
56
+ writeFileSync(join(outputDir, 'manifest.json'), JSON.stringify(downloaded, null, 2));
57
+ spinner.succeed(`Downloaded ${downloaded.length} cached asset${downloaded.length === 1 ? '' : 's'}`);
58
+ console.log(chalk.dim(`Manifest: ${join(outputDir, 'manifest.json')}`));
59
+ }
60
+ catch (error) {
61
+ spinner.fail('Asset cache pull failed');
62
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
63
+ process.exit(1);
64
+ }
65
+ }));
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare const projectCommand: Command;
3
+ //# sourceMappingURL=project.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/commands/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA+BpC,eAAO,MAAM,cAAc,SAyJxB,CAAC"}
@@ -0,0 +1,159 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import ora from 'ora';
4
+ import { mkdirSync, writeFileSync } from 'node:fs';
5
+ import { join, resolve } from 'node:path';
6
+ import { downloadRender, getRenderStatus, listProjects, submitRender, uploadProject } from '../lib/api.js';
7
+ import { isAuthenticated } from '../lib/config.js';
8
+ import { appendProjectToForm, prepareProject } from '../lib/project.js';
9
+ async function waitForRender(renderId) {
10
+ while (true) {
11
+ await new Promise((resolveWait) => setTimeout(resolveWait, 3000));
12
+ const status = await getRenderStatus(renderId);
13
+ if (status.status === 'completed')
14
+ return status;
15
+ if (status.status === 'failed') {
16
+ throw new Error(status.error || 'Render failed');
17
+ }
18
+ process.stdout.write(`\r ${status.status}... ${status.progress}%`);
19
+ }
20
+ }
21
+ async function downloadRenderTo(renderId, outputDir) {
22
+ const result = await downloadRender(renderId);
23
+ mkdirSync(outputDir, { recursive: true });
24
+ const outputPath = join(outputDir, result.filename);
25
+ writeFileSync(outputPath, result.buffer);
26
+ return outputPath;
27
+ }
28
+ export const projectCommand = new Command('project')
29
+ .description('Upload and render SceneRok projects')
30
+ .addCommand(new Command('upload')
31
+ .description('Upload a local VidScript project and its assets')
32
+ .argument('<file>', 'Path to the project .vidscript file')
33
+ .option('-t, --title <title>', 'Project title')
34
+ .option('-d, --description <description>', 'Project description')
35
+ .option('-a, --assets <dir...>', 'Additional asset directories to upload')
36
+ .option('--tags <tags>', 'Comma-separated project tags')
37
+ .option('-r, --render', 'Create a render after uploading')
38
+ .option('--resolution <resolution>', 'Render resolution if --render is used')
39
+ .option('-w, --watch', 'Watch the render until complete')
40
+ .option('--download [dir]', 'Download completed render to a directory', false)
41
+ .action(async (file, options) => {
42
+ if (!isAuthenticated()) {
43
+ console.log(chalk.yellow('Not authenticated'));
44
+ console.log(chalk.dim('Run: scenerok auth login'));
45
+ process.exit(1);
46
+ }
47
+ const spinner = ora('Preparing project...').start();
48
+ try {
49
+ const project = prepareProject(file, options.assets || []);
50
+ const formData = new FormData();
51
+ formData.set('title', options.title || project.entryFile.replace(/\.(vid|vidscript)$/i, ''));
52
+ if (options.description)
53
+ formData.set('description', options.description);
54
+ if (options.tags)
55
+ formData.set('tags', options.tags);
56
+ if (options.render)
57
+ formData.set('render', 'true');
58
+ if (options.resolution)
59
+ formData.set('resolution', options.resolution);
60
+ await appendProjectToForm(formData, project);
61
+ spinner.text = `Uploading project (${project.assets.length} asset${project.assets.length === 1 ? '' : 's'})...`;
62
+ const result = await uploadProject(formData);
63
+ spinner.succeed(`Project uploaded (#${result.project.id})`);
64
+ console.log(chalk.cyan('\nProject\n'));
65
+ console.log(` ID: ${result.project.id}`);
66
+ console.log(` Title: ${result.project.title}`);
67
+ console.log(` URL: ${result.project.projectUrl}`);
68
+ console.log(` Assets: ${result.assets.length}`);
69
+ if (result.render) {
70
+ console.log(chalk.cyan('\nRender\n'));
71
+ console.log(` ID: ${result.render.renderId}`);
72
+ console.log(` Status: ${result.render.status}`);
73
+ console.log(` URL: ${result.render.renderUrl}`);
74
+ console.log(` Download: ${result.render.downloadUrl}`);
75
+ if (options.watch || options.download) {
76
+ console.log(chalk.dim('\nWatching render status...\n'));
77
+ await waitForRender(result.render.renderId);
78
+ console.log(chalk.green('\nRender complete'));
79
+ }
80
+ if (options.download) {
81
+ const outputDir = typeof options.download === 'string' ? options.download : 'renders';
82
+ const outputPath = await downloadRenderTo(result.render.renderId, resolve(outputDir));
83
+ console.log(chalk.green(`Downloaded: ${outputPath}`));
84
+ }
85
+ }
86
+ console.log('');
87
+ }
88
+ catch (error) {
89
+ spinner.fail('Project upload failed');
90
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
91
+ process.exit(1);
92
+ }
93
+ }))
94
+ .addCommand(new Command('list')
95
+ .description('List projects uploaded from CLI/agents')
96
+ .action(async () => {
97
+ if (!isAuthenticated()) {
98
+ console.log(chalk.yellow('Not authenticated'));
99
+ console.log(chalk.dim('Run: scenerok auth login'));
100
+ process.exit(1);
101
+ }
102
+ try {
103
+ const result = await listProjects();
104
+ console.log(chalk.cyan('\nProjects\n'));
105
+ for (const project of result.projects) {
106
+ console.log(` #${project.id} ${project.title} (${project.status})`);
107
+ }
108
+ if (result.projects.length === 0) {
109
+ console.log(chalk.dim(' No CLI projects yet.'));
110
+ }
111
+ console.log('');
112
+ }
113
+ catch (error) {
114
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
115
+ process.exit(1);
116
+ }
117
+ }))
118
+ .addCommand(new Command('render')
119
+ .description('Render an uploaded project')
120
+ .argument('<project-id>', 'Project ID')
121
+ .option('-r, --resolution <resolution>', 'Output resolution')
122
+ .option('-w, --watch', 'Watch render status until complete')
123
+ .option('--download [dir]', 'Download completed render to a directory', false)
124
+ .action(async (projectId, options) => {
125
+ if (!isAuthenticated()) {
126
+ console.log(chalk.yellow('Not authenticated'));
127
+ console.log(chalk.dim('Run: scenerok auth login'));
128
+ process.exit(1);
129
+ }
130
+ const id = Number.parseInt(projectId, 10);
131
+ if (Number.isNaN(id)) {
132
+ console.log(chalk.red('Invalid project ID'));
133
+ process.exit(1);
134
+ }
135
+ try {
136
+ const projects = await listProjects();
137
+ const project = projects.projects.find((item) => item.id === id);
138
+ if (!project) {
139
+ throw new Error(`Project not found: ${id}`);
140
+ }
141
+ const result = await submitRender('', options.resolution, id);
142
+ console.log(chalk.green(`Render submitted (#${result.renderId})`));
143
+ console.log(` URL: ${result.renderUrl}`);
144
+ console.log(` Download: ${result.downloadUrl}`);
145
+ if (options.watch || options.download) {
146
+ await waitForRender(result.renderId);
147
+ console.log(chalk.green('\nRender complete'));
148
+ }
149
+ if (options.download) {
150
+ const outputDir = typeof options.download === 'string' ? options.download : 'renders';
151
+ const outputPath = await downloadRenderTo(result.renderId, resolve(outputDir));
152
+ console.log(chalk.green(`Downloaded: ${outputPath}`));
153
+ }
154
+ }
155
+ catch (error) {
156
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
157
+ process.exit(1);
158
+ }
159
+ }));
@@ -1,3 +1,4 @@
1
1
  import { Command } from 'commander';
2
+ export declare const statusCommand: Command;
2
3
  export declare const renderCommand: Command;
3
4
  //# sourceMappingURL=render.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAOpC,eAAO,MAAM,aAAa,SAwEtB,CAAC"}
1
+ {"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/commands/render.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAkEpC,eAAO,MAAM,aAAa,SAAwB,CAAC;AAEnD,eAAO,MAAM,aAAa,SAuFtB,CAAC"}
@@ -1,14 +1,68 @@
1
1
  import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import ora from 'ora';
4
- import { readFileSync } from 'node:fs';
5
- import { submitRender, getRenderStatus } from '../lib/api.js';
4
+ import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
5
+ import { join, resolve } from 'node:path';
6
+ import { submitRender, getRenderStatus, downloadRender } from '../lib/api.js';
6
7
  import { isAuthenticated } from '../lib/config.js';
8
+ function createStatusCommand() {
9
+ return new Command('status')
10
+ .description('Check render status')
11
+ .argument('<id>', 'Render job ID')
12
+ .option('--download [dir]', 'Download completed render to a directory', false)
13
+ .action(async (id, options) => {
14
+ if (!isAuthenticated()) {
15
+ console.log(chalk.yellow('⚠️ Not authenticated'));
16
+ console.log(chalk.dim('Run: scenerok auth login'));
17
+ process.exit(1);
18
+ }
19
+ const renderId = Number.parseInt(id, 10);
20
+ if (Number.isNaN(renderId)) {
21
+ console.log(chalk.red('❌ Invalid render ID'));
22
+ process.exit(1);
23
+ }
24
+ try {
25
+ const status = await getRenderStatus(renderId);
26
+ console.log(chalk.cyan('\\n📹 Render Status\\n'));
27
+ console.log(` ID: ${status.id}`);
28
+ console.log(` Status: ${status.status}`);
29
+ console.log(` Progress: ${status.progress}%`);
30
+ if (status.outputUrl) {
31
+ console.log(` Output: ${status.outputUrl}`);
32
+ }
33
+ if (status.downloadUrl) {
34
+ console.log(` Download: ${status.downloadUrl}`);
35
+ }
36
+ if (options.download) {
37
+ if (status.status !== 'completed') {
38
+ throw new Error('Render is not completed yet');
39
+ }
40
+ const outputDir = typeof options.download === 'string' ? options.download : 'renders';
41
+ const downloaded = await downloadRender(renderId);
42
+ mkdirSync(resolve(outputDir), { recursive: true });
43
+ const outputPath = join(resolve(outputDir), downloaded.filename);
44
+ writeFileSync(outputPath, downloaded.buffer);
45
+ console.log(` Saved: ${outputPath}`);
46
+ }
47
+ if (status.error) {
48
+ console.log(chalk.red(` Error: ${status.error}`));
49
+ }
50
+ console.log('');
51
+ }
52
+ catch (error) {
53
+ console.error(chalk.red(error instanceof Error ? error.message : String(error)));
54
+ process.exit(1);
55
+ }
56
+ });
57
+ }
58
+ export const statusCommand = createStatusCommand();
7
59
  export const renderCommand = new Command('render')
8
60
  .description('Submit a VidScript for rendering')
9
61
  .argument('<file>', 'Path to .vidscript file')
10
62
  .option('-r, --resolution <resolution>', 'Output resolution (e.g. 1080x1920)')
63
+ .option('-p, --project-id <id>', 'Attach render to an uploaded project ID')
11
64
  .option('-w, --watch', 'Watch render status until complete')
65
+ .option('--download [dir]', 'Download completed render to a directory', false)
12
66
  .action(async (file, options) => {
13
67
  if (!isAuthenticated()) {
14
68
  console.log(chalk.yellow('⚠️ Not authenticated'));
@@ -25,7 +79,11 @@ export const renderCommand = new Command('render')
25
79
  }
26
80
  const spinner = ora('Submitting render job...').start();
27
81
  try {
28
- const result = await submitRender(vidscript, options.resolution);
82
+ const projectId = options.projectId ? Number.parseInt(options.projectId, 10) : undefined;
83
+ if (options.projectId && Number.isNaN(projectId)) {
84
+ throw new Error('Invalid project ID');
85
+ }
86
+ const result = await submitRender(vidscript, options.resolution, projectId);
29
87
  spinner.succeed(`Render job submitted (#${result.renderId})`);
30
88
  console.log(chalk.cyan('\\n📹 Render Job\\n'));
31
89
  console.log(` ID: ${result.renderId}`);
@@ -39,7 +97,7 @@ export const renderCommand = new Command('render')
39
97
  console.log(` Log: ${result.logUrl}`);
40
98
  }
41
99
  console.log('');
42
- if (options.watch) {
100
+ if (options.watch || options.download) {
43
101
  console.log(chalk.dim('Watching render status...\\n'));
44
102
  while (true) {
45
103
  await new Promise((resolve) => setTimeout(resolve, 3000));
@@ -47,6 +105,14 @@ export const renderCommand = new Command('render')
47
105
  if (status.status === 'completed') {
48
106
  console.log(chalk.green(`\\n✅ Render complete!\\n`));
49
107
  console.log(` Download: ${status.downloadUrl}`);
108
+ if (options.download) {
109
+ const outputDir = typeof options.download === 'string' ? options.download : 'renders';
110
+ const downloaded = await downloadRender(result.renderId);
111
+ mkdirSync(resolve(outputDir), { recursive: true });
112
+ const outputPath = join(resolve(outputDir), downloaded.filename);
113
+ writeFileSync(outputPath, downloaded.buffer);
114
+ console.log(` Saved: ${outputPath}`);
115
+ }
50
116
  console.log('');
51
117
  break;
52
118
  }
@@ -70,39 +136,4 @@ export const renderCommand = new Command('render')
70
136
  process.exit(1);
71
137
  }
72
138
  });
73
- renderCommand.addCommand(new Command('status')
74
- .description('Check render status')
75
- .argument('<id>', 'Render job ID')
76
- .action(async (id) => {
77
- if (!isAuthenticated()) {
78
- console.log(chalk.yellow('⚠️ Not authenticated'));
79
- console.log(chalk.dim('Run: scenerok auth login'));
80
- process.exit(1);
81
- }
82
- const renderId = Number.parseInt(id, 10);
83
- if (Number.isNaN(renderId)) {
84
- console.log(chalk.red('❌ Invalid render ID'));
85
- process.exit(1);
86
- }
87
- try {
88
- const status = await getRenderStatus(renderId);
89
- console.log(chalk.cyan('\\n📹 Render Status\\n'));
90
- console.log(` ID: ${status.id}`);
91
- console.log(` Status: ${status.status}`);
92
- console.log(` Progress: ${status.progress}%`);
93
- if (status.outputUrl) {
94
- console.log(` Output: ${status.outputUrl}`);
95
- }
96
- if (status.downloadUrl) {
97
- console.log(` Download: ${status.downloadUrl}`);
98
- }
99
- if (status.error) {
100
- console.log(chalk.red(` Error: ${status.error}`));
101
- }
102
- console.log('');
103
- }
104
- catch (error) {
105
- console.error(chalk.red(error instanceof Error ? error.message : String(error)));
106
- process.exit(1);
107
- }
108
- }));
139
+ renderCommand.addCommand(createStatusCommand());
package/dist/index.js CHANGED
@@ -2,8 +2,10 @@ import { Command } from 'commander';
2
2
  import chalk from 'chalk';
3
3
  import { authCommand } from './commands/auth.js';
4
4
  import { skillsCommand } from './commands/skills.js';
5
- import { renderCommand } from './commands/render.js';
5
+ import { renderCommand, statusCommand } from './commands/render.js';
6
6
  import { validateCommand } from './commands/validate.js';
7
+ import { projectCommand } from './commands/project.js';
8
+ import { cacheCommand } from './commands/cache.js';
7
9
  const program = new Command();
8
10
  program
9
11
  .name('scenerok')
@@ -12,7 +14,10 @@ program
12
14
  program.addCommand(authCommand);
13
15
  program.addCommand(skillsCommand);
14
16
  program.addCommand(renderCommand);
17
+ program.addCommand(projectCommand);
18
+ program.addCommand(cacheCommand);
15
19
  program.addCommand(validateCommand);
20
+ program.addCommand(statusCommand);
16
21
  // Default help
17
22
  program.on('--help', () => {
18
23
  console.log('');
@@ -21,6 +26,8 @@ program.on('--help', () => {
21
26
  console.log(' $ scenerok skills install opencode');
22
27
  console.log(' $ scenerok validate video.vidscript');
23
28
  console.log(' $ scenerok render video.vidscript --resolution 1080x1920');
29
+ console.log(' $ scenerok project upload video.vidscript --assets ./assets --render --watch --download');
30
+ console.log(' $ scenerok cache pull');
24
31
  console.log(' $ scenerok status 42');
25
32
  console.log('');
26
33
  console.log(chalk.cyan('Get started:'));
package/dist/lib/api.d.ts CHANGED
@@ -10,7 +10,7 @@ export declare function validateVidscript(vidscript: string): Promise<{
10
10
  warnings?: string[];
11
11
  error?: string;
12
12
  }>;
13
- export declare function submitRender(vidscript: string, resolution?: string): Promise<{
13
+ export declare function submitRender(vidscript: string, resolution?: string, templateId?: number): Promise<{
14
14
  renderId: number;
15
15
  status: string;
16
16
  resolution: string;
@@ -34,6 +34,48 @@ export declare function getRenderStatus(renderId: number): Promise<{
34
34
  createdAt: string;
35
35
  completedAt: string | null;
36
36
  }>;
37
+ export declare function downloadRender(renderId: number): Promise<{
38
+ buffer: Buffer;
39
+ filename: string;
40
+ }>;
41
+ export declare function uploadProject(formData: FormData): Promise<{
42
+ project: {
43
+ id: number;
44
+ title: string;
45
+ vidscript: string;
46
+ projectUrl: string;
47
+ };
48
+ assets: Array<{
49
+ id: number;
50
+ filename: string;
51
+ url: string;
52
+ mimeType: string | null;
53
+ fileSize: number;
54
+ }>;
55
+ render?: Awaited<ReturnType<typeof submitRender>> | null;
56
+ }>;
57
+ export declare function listProjects(): Promise<{
58
+ projects: Array<{
59
+ id: number;
60
+ title: string;
61
+ status: string;
62
+ updatedAt: string;
63
+ metadata?: unknown;
64
+ }>;
65
+ }>;
66
+ export declare function getAssetCache(options?: {
67
+ plugin?: string;
68
+ limit?: number;
69
+ }): Promise<{
70
+ entries: Array<{
71
+ id: string;
72
+ cacheKey: string;
73
+ r2Url: string;
74
+ pluginName: string | null;
75
+ metadata: unknown;
76
+ updatedAt: string;
77
+ }>;
78
+ }>;
37
79
  export declare function initiateDeviceAuth(deviceName: string): Promise<{
38
80
  device_code: string;
39
81
  user_code: string;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AASA,cAAM,QAAS,SAAQ,KAAK;IAGjB,MAAM,EAAE,MAAM;IACd,YAAY,CAAC,EAAE,OAAO;gBAF7B,OAAO,EAAE,MAAM,EACR,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,YAAA;CAKhC;AAqCD,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM;WAE9C,OAAO;aACL,MAAM;eACJ,MAAM;eACN,MAAM,EAAE;YACX,MAAM;GAEjB;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;cAE3D,MAAM;YACR,MAAM;gBACF,MAAM;oBACF,MAAM;eACX,MAAM;iBACJ,MAAM;aACV,MAAM;kBACD,MAAM;gBACR,MAAM,GAAG,IAAI;GAE5B;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM;QAE9C,MAAM;YACF,MAAM;cACJ,MAAM;eACL,MAAM,GAAG,IAAI;oBACR,MAAM;eACX,MAAM;iBACJ,MAAM;mBACJ,OAAO;WACf,MAAM,GAAG,IAAI;eACT,MAAM;iBACJ,MAAM,GAAG,IAAI;GAE7B;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM;iBAE1C,MAAM;eACR,MAAM;sBACC,MAAM;gBACZ,MAAM;cACR,MAAM;GAEnB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM;YAE3C,MAAM;mBACC,MAAM;iBACR,MAAM;iBACN,MAAM;YACX,MAAM;GAEjB;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AASA,cAAM,QAAS,SAAQ,KAAK;IAGjB,MAAM,EAAE,MAAM;IACd,YAAY,CAAC,EAAE,OAAO;gBAF7B,OAAO,EAAE,MAAM,EACR,MAAM,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,OAAO,YAAA;CAKhC;AAkED,wBAAsB,iBAAiB,CAAC,SAAS,EAAE,MAAM;WAE9C,OAAO;aACL,MAAM;eACJ,MAAM;eACN,MAAM,EAAE;YACX,MAAM;GAEjB;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM;cAEhF,MAAM;YACR,MAAM;gBACF,MAAM;oBACF,MAAM;eACX,MAAM;iBACJ,MAAM;aACV,MAAM;kBACD,MAAM;gBACR,MAAM,GAAG,IAAI;GAE5B;AAED,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM;QAE9C,MAAM;YACF,MAAM;cACJ,MAAM;eACL,MAAM,GAAG,IAAI;oBACR,MAAM;eACX,MAAM;iBACJ,MAAM;mBACJ,OAAO;WACf,MAAM,GAAG,IAAI;eACT,MAAM;iBACJ,MAAM,GAAG,IAAI;GAE7B;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC,CAmBpG;AAED,wBAAsB,aAAa,CAAC,QAAQ,EAAE,QAAQ;aAEzC;QACP,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;KACpB;YACO,KAAK,CAAC;QACZ,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,EAAE,MAAM,CAAC;QACZ,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;aACO,OAAO,CAAC,UAAU,CAAC,OAAO,YAAY,CAAC,CAAC,GAAG,IAAI;GAE3D;AAED,wBAAsB,YAAY;cAEpB,KAAK,CAAC;QACd,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,MAAM,EAAE,MAAM,CAAC;QACf,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;KACpB,CAAC;GAEL;AAED,wBAAsB,aAAa,CAAC,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO;aAMxE,KAAK,CAAC;QACb,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;QAC1B,QAAQ,EAAE,OAAO,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;GAEL;AAED,wBAAsB,kBAAkB,CAAC,UAAU,EAAE,MAAM;iBAE1C,MAAM;eACR,MAAM;sBACC,MAAM;gBACZ,MAAM;cACR,MAAM;GAEnB;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM;YAE3C,MAAM;mBACC,MAAM;iBACR,MAAM;iBACN,MAAM;YACX,MAAM;GAEjB;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}