@scenerok/cli 2.2.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/README.md +173 -0
- package/dist/commands/auth.d.ts +3 -0
- package/dist/commands/auth.d.ts.map +1 -0
- package/dist/commands/auth.js +94 -0
- package/dist/commands/cache.d.ts +3 -0
- package/dist/commands/cache.d.ts.map +1 -0
- package/dist/commands/cache.js +65 -0
- package/dist/commands/lint-video.d.ts +21 -0
- package/dist/commands/lint-video.d.ts.map +1 -0
- package/dist/commands/lint-video.js +122 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.d.ts.map +1 -0
- package/dist/commands/project.js +173 -0
- package/dist/commands/render.d.ts +4 -0
- package/dist/commands/render.d.ts.map +1 -0
- package/dist/commands/render.js +242 -0
- package/dist/commands/skills.d.ts +3 -0
- package/dist/commands/skills.d.ts.map +1 -0
- package/dist/commands/skills.js +208 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +254 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/lib/api.d.ts +268 -0
- package/dist/lib/api.d.ts.map +1 -0
- package/dist/lib/api.js +160 -0
- package/dist/lib/config.d.ts +13 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +53 -0
- package/dist/lib/format-api-error.d.ts +2 -0
- package/dist/lib/format-api-error.d.ts.map +1 -0
- package/dist/lib/format-api-error.js +24 -0
- package/dist/lib/language.d.ts +3 -0
- package/dist/lib/language.d.ts.map +1 -0
- package/dist/lib/language.js +9 -0
- package/dist/lib/logger.d.ts +8 -0
- package/dist/lib/logger.d.ts.map +1 -0
- package/dist/lib/logger.js +51 -0
- package/dist/lib/project.d.ts +29 -0
- package/dist/lib/project.d.ts.map +1 -0
- package/dist/lib/project.js +156 -0
- package/dist/lib/sdk-scene-modules.d.ts +7 -0
- package/dist/lib/sdk-scene-modules.d.ts.map +1 -0
- package/dist/lib/sdk-scene-modules.js +35 -0
- package/dist/utils/skillsManifest.d.ts +42 -0
- package/dist/utils/skillsManifest.d.ts.map +1 -0
- package/dist/utils/skillsManifest.js +122 -0
- package/examples/system/3-tips-fitness.vid +45 -0
- package/examples/system/ecom-product-launch.vid +31 -0
- package/examples/system/glitch-title.vid +17 -0
- package/examples/system/meme-remix.vid +15 -0
- package/examples/system/minimal-text-reel.vid +11 -0
- package/examples/system/product-launch.vid +18 -0
- package/examples/system/rokmilk-chocolate-promo.vid +25 -0
- package/examples/system/testimonial-cut.vid +16 -0
- package/examples/system/ugc-testimonial-voiceover.vid +33 -0
- package/examples/system/voice-visual-promo.vid +21 -0
- package/package.json +51 -0
- package/skills/remote/ai-models.md +65 -0
- package/skills/remote/animations-catalog.md +89 -0
- package/skills/remote/animations-picker.md +77 -0
- package/skills/remote/brand-setup.md +69 -0
- package/skills/remote/catalog-index.json +1810 -0
- package/skills/remote/environments.md +73 -0
- package/skills/remote/intent-router.md +81 -0
- package/skills/remote/media-stdlib.md +66 -0
- package/skills/remote/music.md +69 -0
- package/skills/remote/sdk-guide.md +201 -0
- package/skills/remote/shaders-filters.md +97 -0
- package/skills/remote/text-styles.md +108 -0
- package/skills/remote/transitions-catalog.md +55 -0
- package/skills/remote/tts.md +82 -0
- package/skills/remote/vidscript-guide.md +574 -0
- package/skills/remote/vidscript-sample.md +28 -0
- package/skills/remote/vidscript-strict.md +251 -0
- package/skills/remote/workflow.md +72 -0
- package/skills/shared/SKILL.md +157 -0
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import chalk from 'chalk';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { dirname, resolve } from 'node:path';
|
|
5
|
+
import { validateVidscript, submitRender, getRenderStatus, } from '../lib/api.js';
|
|
6
|
+
import { isAuthenticated } from '../lib/config.js';
|
|
7
|
+
import { detectAuthoringLanguage } from '../lib/language.js';
|
|
8
|
+
import { buildSdkSceneModuleMap } from '../lib/sdk-scene-modules.js';
|
|
9
|
+
import { parseLintOptions, runVideoLint } from './lint-video.js';
|
|
10
|
+
function formatRange(start, end) {
|
|
11
|
+
return `${start.toFixed(2)}s → ${end.toFixed(2)}s`;
|
|
12
|
+
}
|
|
13
|
+
function printInspectionReport(report, jsonMode = false) {
|
|
14
|
+
if (!report)
|
|
15
|
+
return;
|
|
16
|
+
if (jsonMode) {
|
|
17
|
+
console.log(JSON.stringify(report, null, 2));
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
const suffix = report.estimated ? chalk.dim(' (estimated — run with --generate-assets for measured values)') : '';
|
|
21
|
+
console.log(chalk.cyan(`\n Inspection report${suffix}`));
|
|
22
|
+
if (report.text.length > 0) {
|
|
23
|
+
console.log('\n Text geometry:');
|
|
24
|
+
for (const t of report.text) {
|
|
25
|
+
const flags = [
|
|
26
|
+
t.offCanvas ? chalk.red('OFF-CANVAS') : null,
|
|
27
|
+
t.wasClamped ? chalk.yellow('clamped') : null,
|
|
28
|
+
t.wasShrunk ? chalk.yellow(`shrunk ${t.requestedSize}→${t.fittedSize}px`) : null,
|
|
29
|
+
].filter(Boolean).join(', ');
|
|
30
|
+
console.log(` ${t.id} "${t.content.slice(0, 30)}${t.content.length > 30 ? '…' : ''}" ` +
|
|
31
|
+
`[${formatRange(t.start, t.end)}] at (${t.bbox.x},${t.bbox.y}) ${t.bbox.width}x${t.bbox.height}` +
|
|
32
|
+
(flags ? ` ${flags}` : ''));
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
if (report.collisions.length > 0) {
|
|
36
|
+
console.log(chalk.yellow('\n Element collisions:'));
|
|
37
|
+
for (const c of report.collisions) {
|
|
38
|
+
console.log(chalk.yellow(` ${c.a} × ${c.b} overlap ${c.overlap.width}x${c.overlap.height}px during ${formatRange(c.timeRange[0], c.timeRange[1])}`));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
if (report.audio.tracks.length > 0) {
|
|
42
|
+
console.log('\n Audio tracks:');
|
|
43
|
+
for (const t of report.audio.tracks) {
|
|
44
|
+
console.log(` ${t.id} [${formatRange(t.start, t.end)}] volume ${t.volume}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (report.audio.overlaps.length > 0) {
|
|
48
|
+
console.log(chalk.yellow('\n Audio overlaps (fine for music beds, check voiceovers):'));
|
|
49
|
+
for (const o of report.audio.overlaps) {
|
|
50
|
+
console.log(chalk.yellow(` ${o.a} × ${o.b} during ${formatRange(o.range[0], o.range[1])}`));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function collectValidationErrors(result) {
|
|
55
|
+
if (result.errors && result.errors.length > 0) {
|
|
56
|
+
return result.errors;
|
|
57
|
+
}
|
|
58
|
+
if (result.error) {
|
|
59
|
+
return [result.error];
|
|
60
|
+
}
|
|
61
|
+
return ['Validation failed (no error details returned by server)'];
|
|
62
|
+
}
|
|
63
|
+
function printAestheticWarnings(result) {
|
|
64
|
+
if (!result.warnings || result.warnings.length === 0)
|
|
65
|
+
return;
|
|
66
|
+
console.log(chalk.yellow('\n Aesthetic warnings:'));
|
|
67
|
+
if (result.aestheticScore != null) {
|
|
68
|
+
console.log(chalk.yellow(` Score: ${result.aestheticScore}/100`));
|
|
69
|
+
}
|
|
70
|
+
for (const warning of result.warnings) {
|
|
71
|
+
console.log(chalk.yellow(` • ${warning}`));
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function formatUsd(value) {
|
|
75
|
+
return `$${value.toFixed(2)}`;
|
|
76
|
+
}
|
|
77
|
+
function printCostEstimate(costEstimate) {
|
|
78
|
+
if (!costEstimate)
|
|
79
|
+
return;
|
|
80
|
+
console.log('');
|
|
81
|
+
console.log(` Total Cost: ${formatUsd(costEstimate.totalCostUsd)}`);
|
|
82
|
+
console.log(` Savings through cache: ${formatUsd(costEstimate.cacheSavingsUsd)}`);
|
|
83
|
+
console.log(` Est. Spend: ${formatUsd(costEstimate.estimatedSpendUsd)}`);
|
|
84
|
+
}
|
|
85
|
+
async function watchRenderUntilDone(renderId) {
|
|
86
|
+
while (true) {
|
|
87
|
+
await new Promise((resolve) => setTimeout(resolve, 3000));
|
|
88
|
+
const status = await getRenderStatus(renderId);
|
|
89
|
+
if (status.status === 'completed') {
|
|
90
|
+
process.stdout.write('\n');
|
|
91
|
+
return 'completed';
|
|
92
|
+
}
|
|
93
|
+
if (status.status === 'failed') {
|
|
94
|
+
console.log(chalk.red(`\n❌ Render failed: ${status.error}\n`));
|
|
95
|
+
return 'failed';
|
|
96
|
+
}
|
|
97
|
+
process.stdout.write(`\r ${status.status}... ${status.progress}%`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
export const validateCommand = new Command('validate')
|
|
101
|
+
.description('Validate a VidScript (.vid) or @scenerok/sdk TypeScript/JavaScript (.ts/.js) file')
|
|
102
|
+
.argument('<file>', 'Path to .vid, .vidscript, .ts, or .js file')
|
|
103
|
+
.option('--generate-assets', 'Run a real compile: execute plugins, generate + cache assets, and report measured durations and text geometry (billed; requires auth; VidScript only)')
|
|
104
|
+
.option('--render', 'Full pipeline: validate with generated assets, render the video, then validate the output MP4 with ffprobe + LLM frame review (billed; requires auth). Exit code 0 only when every stage passes.')
|
|
105
|
+
.option('--cost <tier>', 'Frame-grab budget for the MP4 review when using --render: low, medium, high (more frames = higher LLM cost)', 'medium')
|
|
106
|
+
.option('--frames <n>', 'Exact number of MP4 frame grabs when using --render (overrides --cost, max 20)')
|
|
107
|
+
.option('--budget <usd>', 'Total USD cap for the --render pipeline: plugin generation + render + MP4 review')
|
|
108
|
+
.option('--render-budget <usd>', 'USD cap on plugin generation + render spend; the pipeline aborts before any billed call if the estimate exceeds it')
|
|
109
|
+
.option('--validation-budget <usd>', 'USD cap on the MP4 LLM review; frame count is clamped to fit')
|
|
110
|
+
.option('--resolution <resolution>', 'Output resolution for --render (e.g. 1080x1920)')
|
|
111
|
+
.option('--report-json', 'Print the inspection report as JSON (for agents)')
|
|
112
|
+
.action(async (file, opts) => {
|
|
113
|
+
let vidscript;
|
|
114
|
+
try {
|
|
115
|
+
vidscript = readFileSync(file, 'utf-8');
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
console.log(chalk.red(`❌ Could not read file: ${file}`));
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
const language = detectAuthoringLanguage(file);
|
|
122
|
+
const workingDirectory = resolve(dirname(file));
|
|
123
|
+
const moduleMap = language === 'vidscript'
|
|
124
|
+
? buildSdkSceneModuleMap(vidscript, workingDirectory)
|
|
125
|
+
: undefined;
|
|
126
|
+
const moduleOptions = moduleMap && Object.keys(moduleMap).length > 0
|
|
127
|
+
? { moduleMap, workingDirectory }
|
|
128
|
+
: { workingDirectory };
|
|
129
|
+
if (language !== 'vidscript' && opts.generateAssets) {
|
|
130
|
+
console.log(chalk.yellow('⚠️ --generate-assets is VidScript-only; validating SDK source without asset generation'));
|
|
131
|
+
opts.generateAssets = false;
|
|
132
|
+
}
|
|
133
|
+
if (opts.render && !isAuthenticated()) {
|
|
134
|
+
console.log(chalk.yellow('⚠️ Not authenticated — --render requires auth'));
|
|
135
|
+
console.log(chalk.dim('Run: scenerok auth login'));
|
|
136
|
+
process.exit(1);
|
|
137
|
+
}
|
|
138
|
+
const lintOptions = opts.render
|
|
139
|
+
? parseLintOptions({ cost: opts.cost, frames: opts.frames, budget: opts.validationBudget })
|
|
140
|
+
: undefined;
|
|
141
|
+
const parseBudget = (value, flag) => {
|
|
142
|
+
if (value === undefined)
|
|
143
|
+
return undefined;
|
|
144
|
+
const parsed = Number.parseFloat(value);
|
|
145
|
+
if (Number.isNaN(parsed) || parsed <= 0) {
|
|
146
|
+
console.log(chalk.red(`❌ ${flag} must be a positive USD amount`));
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|
|
149
|
+
return parsed;
|
|
150
|
+
};
|
|
151
|
+
const totalBudgetUsd = parseBudget(opts.budget, '--budget');
|
|
152
|
+
const renderBudgetUsd = parseBudget(opts.renderBudget, '--render-budget');
|
|
153
|
+
// Budget gate: a free dry-run validate returns the cache-aware spend
|
|
154
|
+
// estimate for plugin generation + render, checked against the caps
|
|
155
|
+
// BEFORE any billed call happens.
|
|
156
|
+
let spendEstimateUsd = 0;
|
|
157
|
+
if (opts.render && language === 'vidscript' && (totalBudgetUsd !== undefined || renderBudgetUsd !== undefined)) {
|
|
158
|
+
try {
|
|
159
|
+
const preflight = await validateVidscript(vidscript, { language, ...moduleOptions });
|
|
160
|
+
spendEstimateUsd = preflight.costEstimate?.estimatedSpendUsd ?? 0;
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
console.log(chalk.cyan('\n💰 Budget check\n'));
|
|
167
|
+
console.log(` Estimated plugin + render spend: ${formatUsd(spendEstimateUsd)}`);
|
|
168
|
+
if (renderBudgetUsd !== undefined)
|
|
169
|
+
console.log(` Render budget: ${formatUsd(renderBudgetUsd)}`);
|
|
170
|
+
if (totalBudgetUsd !== undefined)
|
|
171
|
+
console.log(` Total budget: ${formatUsd(totalBudgetUsd)}`);
|
|
172
|
+
if (lintOptions?.budgetUsd !== undefined)
|
|
173
|
+
console.log(` Validation budget: ${formatUsd(lintOptions.budgetUsd)}`);
|
|
174
|
+
if (renderBudgetUsd !== undefined && spendEstimateUsd > renderBudgetUsd) {
|
|
175
|
+
console.log(chalk.red(`\n❌ Estimated spend ${formatUsd(spendEstimateUsd)} exceeds --render-budget ${formatUsd(renderBudgetUsd)} — aborting before any billed call.`));
|
|
176
|
+
process.exit(1);
|
|
177
|
+
}
|
|
178
|
+
if (totalBudgetUsd !== undefined && spendEstimateUsd > totalBudgetUsd) {
|
|
179
|
+
console.log(chalk.red(`\n❌ Estimated spend ${formatUsd(spendEstimateUsd)} exceeds --budget ${formatUsd(totalBudgetUsd)} — aborting before any billed call.`));
|
|
180
|
+
process.exit(1);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
// Validation stage draws from what the total budget leaves after the
|
|
184
|
+
// estimated render spend.
|
|
185
|
+
let effectiveValidationBudgetUsd = lintOptions?.budgetUsd;
|
|
186
|
+
if (totalBudgetUsd !== undefined) {
|
|
187
|
+
const remaining = totalBudgetUsd - spendEstimateUsd;
|
|
188
|
+
effectiveValidationBudgetUsd = Math.min(effectiveValidationBudgetUsd ?? Number.POSITIVE_INFINITY, remaining);
|
|
189
|
+
if (effectiveValidationBudgetUsd <= 0) {
|
|
190
|
+
console.log(chalk.red(`\n❌ Total budget leaves ${formatUsd(Math.max(0, remaining))} for MP4 validation — not enough for a single frame. Raise --budget or lower render spend.`));
|
|
191
|
+
process.exit(1);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
// --render implies --generate-assets for VidScript: real timings, and the generated
|
|
196
|
+
// assets are cached so the render right after doesn't pay twice.
|
|
197
|
+
const result = await validateVidscript(vidscript, {
|
|
198
|
+
language,
|
|
199
|
+
generateAssets: language === 'vidscript' && (opts.generateAssets || opts.render),
|
|
200
|
+
...moduleOptions,
|
|
201
|
+
});
|
|
202
|
+
if (result.valid) {
|
|
203
|
+
const label = language === 'vidscript' ? 'VidScript' : `@scenerok/sdk (${language})`;
|
|
204
|
+
console.log(chalk.green(`\\n✅ ${label} is valid\\n`));
|
|
205
|
+
if (result.statements != null) {
|
|
206
|
+
console.log(` Statements: ${result.statements}`);
|
|
207
|
+
}
|
|
208
|
+
if (result.scenes != null) {
|
|
209
|
+
console.log(` Scenes: ${result.scenes}`);
|
|
210
|
+
}
|
|
211
|
+
if (result.duration != null) {
|
|
212
|
+
console.log(` Duration: ${result.duration}s`);
|
|
213
|
+
}
|
|
214
|
+
const pluginCalls = result.pluginCalls;
|
|
215
|
+
if (pluginCalls != null) {
|
|
216
|
+
console.log(` Plugin calls: ${pluginCalls}`);
|
|
217
|
+
}
|
|
218
|
+
printCostEstimate(result.costEstimate);
|
|
219
|
+
printAestheticWarnings(result);
|
|
220
|
+
printInspectionReport(result.report, opts.reportJson);
|
|
221
|
+
if (opts.render) {
|
|
222
|
+
console.log(chalk.cyan('\n📹 Rendering...\n'));
|
|
223
|
+
const render = await submitRender(vidscript, opts.resolution, undefined, { language, ...moduleOptions });
|
|
224
|
+
console.log(chalk.dim(` Render #${render.renderId} submitted, watching...`));
|
|
225
|
+
const outcome = await watchRenderUntilDone(render.renderId);
|
|
226
|
+
if (outcome === 'failed') {
|
|
227
|
+
process.exit(1);
|
|
228
|
+
}
|
|
229
|
+
console.log(chalk.green(`\n✅ Render #${render.renderId} complete — validating output MP4\n`));
|
|
230
|
+
const passed = await runVideoLint(render.renderId, {
|
|
231
|
+
cost: lintOptions?.cost,
|
|
232
|
+
frames: lintOptions?.frames,
|
|
233
|
+
budgetUsd: Number.isFinite(effectiveValidationBudgetUsd) ? effectiveValidationBudgetUsd : undefined,
|
|
234
|
+
json: opts.reportJson,
|
|
235
|
+
});
|
|
236
|
+
process.exit(passed ? 0 : 1);
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
const label = language === 'vidscript' ? 'VidScript' : `@scenerok/sdk (${language})`;
|
|
241
|
+
console.log(chalk.red(`\\n❌ ${label} is invalid\\n`));
|
|
242
|
+
for (const err of collectValidationErrors(result)) {
|
|
243
|
+
console.log(` • ${err}`);
|
|
244
|
+
}
|
|
245
|
+
printAestheticWarnings(result);
|
|
246
|
+
process.exit(1);
|
|
247
|
+
}
|
|
248
|
+
console.log('');
|
|
249
|
+
}
|
|
250
|
+
catch (error) {
|
|
251
|
+
console.error(chalk.red(error instanceof Error ? error.message : String(error)));
|
|
252
|
+
process.exit(1);
|
|
253
|
+
}
|
|
254
|
+
});
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import chalk from 'chalk';
|
|
4
|
+
import { readFileSync } from 'node:fs';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import { authCommand } from './commands/auth.js';
|
|
8
|
+
import { skillsCommand } from './commands/skills.js';
|
|
9
|
+
import { renderCommand, statusCommand } from './commands/render.js';
|
|
10
|
+
import { validateCommand } from './commands/validate.js';
|
|
11
|
+
import { lintVideoCommand } from './commands/lint-video.js';
|
|
12
|
+
import { projectCommand } from './commands/project.js';
|
|
13
|
+
import { cacheCommand } from './commands/cache.js';
|
|
14
|
+
const program = new Command();
|
|
15
|
+
const packageJson = JSON.parse(readFileSync(join(dirname(fileURLToPath(import.meta.url)), '..', 'package.json'), 'utf-8'));
|
|
16
|
+
program
|
|
17
|
+
.name('scenerok')
|
|
18
|
+
.description('SceneRok CLI - Create videos from your terminal and agent workflows')
|
|
19
|
+
.version(packageJson.version || '0.0.0')
|
|
20
|
+
.option('-v, --verbose', 'Log API requests to ~/.scenerok/logs/cli.log');
|
|
21
|
+
program.addCommand(authCommand);
|
|
22
|
+
program.addCommand(skillsCommand);
|
|
23
|
+
program.addCommand(renderCommand);
|
|
24
|
+
program.addCommand(projectCommand);
|
|
25
|
+
program.addCommand(cacheCommand);
|
|
26
|
+
program.addCommand(validateCommand);
|
|
27
|
+
program.addCommand(lintVideoCommand);
|
|
28
|
+
program.addCommand(statusCommand);
|
|
29
|
+
const agentsDocsPath = ['https://', 'scenerok', '.com/agents'].join('');
|
|
30
|
+
// Default help
|
|
31
|
+
program.on('--help', () => {
|
|
32
|
+
console.log('');
|
|
33
|
+
console.log(chalk.cyan('Examples:'));
|
|
34
|
+
console.log(' $ scenerok auth login');
|
|
35
|
+
console.log(' $ scenerok auth login --verbose # debug log at ~/.scenerok/logs/cli.log');
|
|
36
|
+
console.log(' $ scenerok skills install opencode');
|
|
37
|
+
console.log(' $ scenerok validate video.vidscript');
|
|
38
|
+
console.log(' $ scenerok validate scene.ts # @scenerok/sdk TypeScript');
|
|
39
|
+
console.log(' $ scenerok validate video.vidscript --render --cost medium # full loop: validate + render + video lint');
|
|
40
|
+
console.log(' $ scenerok render video.vidscript --resolution 1080x1920');
|
|
41
|
+
console.log(' $ scenerok render scene.ts --watch');
|
|
42
|
+
console.log(' $ scenerok render video.vidscript --watch --validate high # lint the MP4 after rendering');
|
|
43
|
+
console.log(' $ scenerok lint-video 42 --cost low --json');
|
|
44
|
+
console.log(' $ scenerok project upload video.vidscript --assets ./assets --render --watch --download');
|
|
45
|
+
console.log(' $ scenerok cache pull');
|
|
46
|
+
console.log(' $ scenerok status 42');
|
|
47
|
+
console.log('');
|
|
48
|
+
console.log(chalk.cyan('Get started:'));
|
|
49
|
+
console.log(` ${agentsDocsPath}`);
|
|
50
|
+
});
|
|
51
|
+
program.parse();
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
declare class ApiError extends Error {
|
|
2
|
+
status: number;
|
|
3
|
+
responseBody?: unknown | undefined;
|
|
4
|
+
constructor(message: string, status: number, responseBody?: unknown | undefined);
|
|
5
|
+
}
|
|
6
|
+
export interface RenderCostEstimate {
|
|
7
|
+
totalCostUsd: number;
|
|
8
|
+
cacheSavingsUsd: number;
|
|
9
|
+
estimatedSpendUsd: number;
|
|
10
|
+
renderCostUsd: number;
|
|
11
|
+
pluginCostUsd: number;
|
|
12
|
+
pluginCostAfterCacheUsd: number;
|
|
13
|
+
durationSeconds: number;
|
|
14
|
+
pluginMarkup: number;
|
|
15
|
+
renderTokensPerSecond: number;
|
|
16
|
+
lineItems: Array<{
|
|
17
|
+
name: string;
|
|
18
|
+
provider: string;
|
|
19
|
+
product: string;
|
|
20
|
+
rawCostUsd: number;
|
|
21
|
+
billedCostUsd: number;
|
|
22
|
+
cacheKey?: string;
|
|
23
|
+
cacheStatus: 'hit' | 'duplicate' | 'miss' | 'not_cacheable';
|
|
24
|
+
metadata?: unknown;
|
|
25
|
+
}>;
|
|
26
|
+
}
|
|
27
|
+
export interface InspectionReport {
|
|
28
|
+
estimated: boolean;
|
|
29
|
+
canvas: {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
timeline: Array<{
|
|
34
|
+
id: string;
|
|
35
|
+
kind: string;
|
|
36
|
+
type?: string;
|
|
37
|
+
start: number;
|
|
38
|
+
end: number;
|
|
39
|
+
source?: string;
|
|
40
|
+
}>;
|
|
41
|
+
text: Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
content: string;
|
|
44
|
+
start: number;
|
|
45
|
+
end: number;
|
|
46
|
+
bbox: {
|
|
47
|
+
x: number;
|
|
48
|
+
y: number;
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
};
|
|
52
|
+
requestedSize: number;
|
|
53
|
+
fittedSize: number;
|
|
54
|
+
wasClamped: boolean;
|
|
55
|
+
wasShrunk: boolean;
|
|
56
|
+
offCanvas: boolean;
|
|
57
|
+
}>;
|
|
58
|
+
collisions: Array<{
|
|
59
|
+
a: string;
|
|
60
|
+
b: string;
|
|
61
|
+
overlap: {
|
|
62
|
+
x: number;
|
|
63
|
+
y: number;
|
|
64
|
+
width: number;
|
|
65
|
+
height: number;
|
|
66
|
+
};
|
|
67
|
+
timeRange: [number, number];
|
|
68
|
+
}>;
|
|
69
|
+
audio: {
|
|
70
|
+
tracks: Array<{
|
|
71
|
+
id: string;
|
|
72
|
+
source: string;
|
|
73
|
+
start: number;
|
|
74
|
+
end: number;
|
|
75
|
+
volume: number;
|
|
76
|
+
}>;
|
|
77
|
+
overlaps: Array<{
|
|
78
|
+
a: string;
|
|
79
|
+
b: string;
|
|
80
|
+
range: [number, number];
|
|
81
|
+
}>;
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export declare function validateVidscript(vidscript: string, options?: {
|
|
85
|
+
generateAssets?: boolean;
|
|
86
|
+
language?: 'vidscript' | 'typescript' | 'javascript';
|
|
87
|
+
moduleMap?: Record<string, string>;
|
|
88
|
+
workingDirectory?: string;
|
|
89
|
+
}): Promise<{
|
|
90
|
+
valid: boolean;
|
|
91
|
+
language?: string;
|
|
92
|
+
statements?: number;
|
|
93
|
+
scenes?: number;
|
|
94
|
+
duration?: number;
|
|
95
|
+
warnings?: string[];
|
|
96
|
+
aestheticWarnings?: Array<{
|
|
97
|
+
ruleId: string;
|
|
98
|
+
severity: "warning";
|
|
99
|
+
category: string;
|
|
100
|
+
message: string;
|
|
101
|
+
recommendation: string;
|
|
102
|
+
elementId?: string;
|
|
103
|
+
start?: number;
|
|
104
|
+
end?: number;
|
|
105
|
+
}>;
|
|
106
|
+
aestheticScore?: number;
|
|
107
|
+
costEstimate?: RenderCostEstimate;
|
|
108
|
+
report?: InspectionReport;
|
|
109
|
+
errors?: string[];
|
|
110
|
+
error?: string;
|
|
111
|
+
}>;
|
|
112
|
+
export interface VideoLintProbe {
|
|
113
|
+
ok: boolean;
|
|
114
|
+
durationSeconds: number | null;
|
|
115
|
+
width: number | null;
|
|
116
|
+
height: number | null;
|
|
117
|
+
fps: number | null;
|
|
118
|
+
hasAudio: boolean;
|
|
119
|
+
videoCodec: string | null;
|
|
120
|
+
fileSizeBytes: number | null;
|
|
121
|
+
errors: string[];
|
|
122
|
+
}
|
|
123
|
+
export interface VideoLintFrameReview {
|
|
124
|
+
timestamp: number;
|
|
125
|
+
expected: string;
|
|
126
|
+
matches: boolean;
|
|
127
|
+
observed: string;
|
|
128
|
+
issues: string[];
|
|
129
|
+
}
|
|
130
|
+
export interface VideoLintResult {
|
|
131
|
+
valid: boolean;
|
|
132
|
+
renderId: number;
|
|
133
|
+
irSource?: 'resolved' | 'dry-run';
|
|
134
|
+
probe?: VideoLintProbe;
|
|
135
|
+
errors?: string[];
|
|
136
|
+
warnings?: string[];
|
|
137
|
+
llmReview?: {
|
|
138
|
+
frames: VideoLintFrameReview[];
|
|
139
|
+
overallScore: number;
|
|
140
|
+
verdict: 'pass' | 'fail';
|
|
141
|
+
summary: string;
|
|
142
|
+
suggestions: string[];
|
|
143
|
+
} | null;
|
|
144
|
+
framesAnalyzed?: number;
|
|
145
|
+
billing?: {
|
|
146
|
+
model: string;
|
|
147
|
+
totalTokens: number;
|
|
148
|
+
costUsd: number;
|
|
149
|
+
tokenUnitsCharged: number;
|
|
150
|
+
estimatedCostUsd?: number;
|
|
151
|
+
budgetUsd?: number;
|
|
152
|
+
} | null;
|
|
153
|
+
note?: string;
|
|
154
|
+
error?: string;
|
|
155
|
+
}
|
|
156
|
+
export declare function validateRender(renderId: number, options?: {
|
|
157
|
+
cost?: string;
|
|
158
|
+
frames?: number;
|
|
159
|
+
budgetUsd?: number;
|
|
160
|
+
}): Promise<VideoLintResult>;
|
|
161
|
+
export declare function submitRender(vidscript: string, resolution?: string, templateId?: number, options?: {
|
|
162
|
+
language?: 'vidscript' | 'typescript' | 'javascript';
|
|
163
|
+
moduleMap?: Record<string, string>;
|
|
164
|
+
workingDirectory?: string;
|
|
165
|
+
}): Promise<{
|
|
166
|
+
renderId: number;
|
|
167
|
+
status: string;
|
|
168
|
+
resolution: string;
|
|
169
|
+
outputFilename: string;
|
|
170
|
+
renderUrl: string;
|
|
171
|
+
downloadUrl: string;
|
|
172
|
+
logUrl?: string;
|
|
173
|
+
dispatchMode: string;
|
|
174
|
+
queueJobId: string | null;
|
|
175
|
+
language?: string;
|
|
176
|
+
}>;
|
|
177
|
+
export declare function getRenderStatus(renderId: number): Promise<{
|
|
178
|
+
id: number;
|
|
179
|
+
status: string;
|
|
180
|
+
progress: number;
|
|
181
|
+
outputUrl: string | null;
|
|
182
|
+
outputFilename: string;
|
|
183
|
+
renderUrl: string;
|
|
184
|
+
downloadUrl: string;
|
|
185
|
+
downloadReady: boolean;
|
|
186
|
+
error: string | null;
|
|
187
|
+
createdAt: string;
|
|
188
|
+
completedAt: string | null;
|
|
189
|
+
clickToDownloadMs: number | null;
|
|
190
|
+
}>;
|
|
191
|
+
export declare function downloadRender(renderId: number): Promise<{
|
|
192
|
+
buffer: Buffer;
|
|
193
|
+
filename: string;
|
|
194
|
+
}>;
|
|
195
|
+
export declare function uploadProject(formData: FormData): Promise<{
|
|
196
|
+
project: {
|
|
197
|
+
id: number;
|
|
198
|
+
title: string;
|
|
199
|
+
vidscript: string;
|
|
200
|
+
projectUrl: string;
|
|
201
|
+
};
|
|
202
|
+
assets: Array<{
|
|
203
|
+
id: number;
|
|
204
|
+
filename: string;
|
|
205
|
+
url: string;
|
|
206
|
+
mimeType: string | null;
|
|
207
|
+
fileSize: number;
|
|
208
|
+
}>;
|
|
209
|
+
render?: Awaited<ReturnType<typeof submitRender>> | null;
|
|
210
|
+
}>;
|
|
211
|
+
export declare function uploadCliAssets(formData: FormData): Promise<{
|
|
212
|
+
assets: Array<{
|
|
213
|
+
id: number;
|
|
214
|
+
filename: string;
|
|
215
|
+
url: string;
|
|
216
|
+
mimeType: string | null;
|
|
217
|
+
fileType: string;
|
|
218
|
+
fileSize: number;
|
|
219
|
+
externalId: string | null;
|
|
220
|
+
}>;
|
|
221
|
+
}>;
|
|
222
|
+
export declare function listProjects(): Promise<{
|
|
223
|
+
projects: Array<{
|
|
224
|
+
id: number;
|
|
225
|
+
title: string;
|
|
226
|
+
status: string;
|
|
227
|
+
updatedAt: string;
|
|
228
|
+
metadata?: unknown;
|
|
229
|
+
}>;
|
|
230
|
+
}>;
|
|
231
|
+
export declare function getAssetCache(options?: {
|
|
232
|
+
plugin?: string;
|
|
233
|
+
limit?: number;
|
|
234
|
+
}): Promise<{
|
|
235
|
+
entries: Array<{
|
|
236
|
+
id: string;
|
|
237
|
+
cacheKey: string;
|
|
238
|
+
r2Url: string;
|
|
239
|
+
pluginName: string | null;
|
|
240
|
+
metadata: unknown;
|
|
241
|
+
updatedAt: string;
|
|
242
|
+
}>;
|
|
243
|
+
}>;
|
|
244
|
+
export declare function checkAssetCache(cacheKeys: string[]): Promise<{
|
|
245
|
+
entries: Array<{
|
|
246
|
+
cacheKey: string;
|
|
247
|
+
r2Url: string;
|
|
248
|
+
pluginName: string | null;
|
|
249
|
+
metadata: unknown;
|
|
250
|
+
updatedAt: string;
|
|
251
|
+
}>;
|
|
252
|
+
}>;
|
|
253
|
+
export declare function initiateDeviceAuth(deviceName: string): Promise<{
|
|
254
|
+
device_code: string;
|
|
255
|
+
user_code: string;
|
|
256
|
+
verification_uri: string;
|
|
257
|
+
expires_in: number;
|
|
258
|
+
interval: number;
|
|
259
|
+
}>;
|
|
260
|
+
export declare function pollDeviceAuth(deviceCode: string): Promise<{
|
|
261
|
+
status: string;
|
|
262
|
+
access_token?: string;
|
|
263
|
+
token_type?: string;
|
|
264
|
+
expires_in?: number;
|
|
265
|
+
error?: string;
|
|
266
|
+
}>;
|
|
267
|
+
export { ApiError };
|
|
268
|
+
//# sourceMappingURL=api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
|