agent-nuvira 3.5.9 → 3.5.10

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 (43) hide show
  1. package/README.md +19 -1
  2. package/dist/cli/cli-program.d.ts.map +1 -1
  3. package/dist/cli/cli-program.js +6 -0
  4. package/dist/cli/cli-program.js.map +1 -1
  5. package/dist/cli/motion.d.ts +53 -0
  6. package/dist/cli/motion.d.ts.map +1 -0
  7. package/dist/cli/motion.js +516 -0
  8. package/dist/cli/motion.js.map +1 -0
  9. package/dist/learning/machine-facts.d.ts +7 -0
  10. package/dist/learning/machine-facts.d.ts.map +1 -1
  11. package/dist/learning/machine-facts.js +37 -2
  12. package/dist/learning/machine-facts.js.map +1 -1
  13. package/dist/skills/bundled-skills-phase3.d.ts.map +1 -1
  14. package/dist/skills/bundled-skills-phase3.js +3 -3
  15. package/dist/skills/bundled-skills-phase3.js.map +1 -1
  16. package/dist/skills/sandbox-executor.d.ts.map +1 -1
  17. package/dist/skills/sandbox-executor.js +115 -34
  18. package/dist/skills/sandbox-executor.js.map +1 -1
  19. package/dist/tools/modality/motion-tool.d.ts +28 -1
  20. package/dist/tools/modality/motion-tool.d.ts.map +1 -1
  21. package/dist/tools/modality/motion-tool.js +261 -10
  22. package/dist/tools/modality/motion-tool.js.map +1 -1
  23. package/dist/tools/modality/motion.d.ts +403 -3
  24. package/dist/tools/modality/motion.d.ts.map +1 -1
  25. package/dist/tools/modality/motion.js +1096 -41
  26. package/dist/tools/modality/motion.js.map +1 -1
  27. package/dist/tools/registry.d.ts.map +1 -1
  28. package/dist/tools/registry.js +34 -4
  29. package/dist/tools/registry.js.map +1 -1
  30. package/dist/web-dashboard/motion-data.d.ts +62 -0
  31. package/dist/web-dashboard/motion-data.d.ts.map +1 -0
  32. package/dist/web-dashboard/motion-data.js +91 -0
  33. package/dist/web-dashboard/motion-data.js.map +1 -0
  34. package/dist/web-dashboard/server.d.ts.map +1 -1
  35. package/dist/web-dashboard/server.js +58 -30
  36. package/dist/web-dashboard/server.js.map +1 -1
  37. package/dist/web-dashboard/src/types.d.ts +31 -0
  38. package/dist/web-dashboard/src/types.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/web-dashboard/public/assets/{index-CzRU84ET.css → index-CXdBvA0N.css} +1 -1
  41. package/src/web-dashboard/public/assets/{index-CGYIlLpO.js → index-DfjkO16t.js} +81 -81
  42. package/src/web-dashboard/public/assets/{index-CGYIlLpO.js.map → index-DfjkO16t.js.map} +1 -1
  43. package/src/web-dashboard/public/index.html +2 -2
@@ -0,0 +1,516 @@
1
+ /**
2
+ * Motion command — the HUMAN entry point to the motion renderer.
3
+ *
4
+ * WHY THIS EXISTS. `motion_render` has been a real tool with a real skill since
5
+ * the modality work, and the only way to reach it was to know that: ask a chat
6
+ * turn for "an animated explainer", hope the model searched for the tool, and
7
+ * watch the artifact appear in the dashboard. A capability a user cannot name
8
+ * from the command line is a capability most users do not have. This command
9
+ * names it.
10
+ *
11
+ * Two audiences, one command:
12
+ *
13
+ * - `nuvira motion doctor` answers "why doesn't it work on my machine?" before
14
+ * a render: the renderer needs chromium (playwright) for frames and ffmpeg to
15
+ * encode them, and a missing binary is a fact, so it is reported as one.
16
+ * - `nuvira motion render` renders WITHOUT a model in the loop. A preset plus a
17
+ * CSV/JSON file is a deterministic render, so making one should not require a
18
+ * provider, a prompt, or token spend.
19
+ *
20
+ * `list` is the default action: a user who typed the command and does not know
21
+ * what to do next should see what already exists and the exact next step, not a
22
+ * usage error.
23
+ */
24
+ import { spawn } from 'node:child_process';
25
+ import { existsSync, readFileSync, statSync } from 'node:fs';
26
+ import { Command } from 'commander';
27
+ import { BaseCommand } from './commands.js';
28
+ import { logger } from '../utils/logger.js';
29
+ import { framesAvailability, listMotionManifests, loadMotionManifest, motionAvailability, motionHomeDir, } from '../tools/modality/motion.js';
30
+ import { MOTION_PRESETS, isMotionPreset, presetNeedsData, } from '../tools/modality/motion-presets.js';
31
+ /**
32
+ * `2.5s` / `1m 05s` — the length, not a frame count the user has to divide.
33
+ *
34
+ * Short renders keep a decimal: rounding 2.5s to "3s" would misreport the file
35
+ * that is about to be reviewed, and duration is the one number a user checks
36
+ * against what they asked for.
37
+ */
38
+ function formatDuration(ms) {
39
+ const seconds = ms / 1000;
40
+ if (seconds < 60) {
41
+ const short = seconds < 10 ? seconds.toFixed(1).replace(/\.0$/, '') : String(Math.round(seconds));
42
+ return `${short}s`;
43
+ }
44
+ const total = Math.round(seconds);
45
+ const minutes = Math.floor(total / 60);
46
+ return `${minutes}m ${String(total % 60).padStart(2, '0')}s`;
47
+ }
48
+ function formatBytes(bytes) {
49
+ if (!Number.isFinite(bytes) || bytes <= 0)
50
+ return '—';
51
+ if (bytes < 1024)
52
+ return `${bytes} B`;
53
+ if (bytes < 1024 * 1024)
54
+ return `${(bytes / 1024).toFixed(1)} KB`;
55
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
56
+ }
57
+ function fileSize(path) {
58
+ if (!path)
59
+ return 0;
60
+ try {
61
+ return existsSync(path) ? statSync(path).size : 0;
62
+ }
63
+ catch {
64
+ return 0;
65
+ }
66
+ }
67
+ /** What the render WAS: a preset name, or the fact that it was hand-written. */
68
+ function sourceLabel(manifest) {
69
+ if (manifest.preset)
70
+ return manifest.preset;
71
+ // A frames render was NOT authored as HTML — calling it that tells the user the
72
+ // opposite of where the animation actually lives (their own renderer, which is
73
+ // what has to run again to change it).
74
+ return manifest.framesDir ? 'your frames' : 'hand-written html';
75
+ }
76
+ /** One line per render — the id first, because that is the argument to `open`. */
77
+ function renderRow(manifest) {
78
+ const when = new Date(manifest.createdAt).toISOString().slice(0, 16).replace('T', ' ');
79
+ const size = formatBytes(fileSize(manifest.artifact));
80
+ const rev = manifest.revisions > 0 ? ` · rev ${manifest.revisions}` : '';
81
+ const audio = manifest.srt ? ' · captions' : '';
82
+ // Whether a frames render can be revised is decided by one fact, so it is in the
83
+ // row: a renderer command is recorded, or it is not.
84
+ const renderer = manifest.framesDir ? (manifest.renderer ? ' · revisable' : ' · no renderer') : '';
85
+ return ` ${manifest.id} ${when} ${sourceLabel(manifest).padEnd(16)} ${formatDuration(manifest.durationMs).padStart(6)} ${size.padStart(8)} ${manifest.width}×${manifest.height} ${manifest.format}${rev}${audio}${renderer}`;
86
+ }
87
+ /** An OS-appropriate opener, or `null` when we should just print the path. */
88
+ function opener() {
89
+ if (process.platform === 'darwin')
90
+ return { command: 'open', args: [] };
91
+ if (process.platform === 'win32')
92
+ return { command: 'cmd', args: ['/c', 'start', ''] };
93
+ // On Linux there is no guaranteed opener; a headless box has none at all.
94
+ return existsSync('/usr/bin/xdg-open') ? { command: 'xdg-open', args: [] } : null;
95
+ }
96
+ export class MotionCommand extends BaseCommand {
97
+ create() {
98
+ const command = new Command('motion')
99
+ .description('Create and inspect animated videos — code-authored, rendered frame-accurately. ' +
100
+ 'No model is needed: a preset plus your data is a render.');
101
+ // ── list (default) ──────────────────────────────────────────────────────
102
+ command
103
+ .command('list', { isDefault: true })
104
+ .description('Show the renders in this workspace (the default action)')
105
+ .option('-n, --limit <number>', 'Maximum renders to show', parseInt, 20)
106
+ .action((options) => {
107
+ this.list(options?.limit ?? 20);
108
+ });
109
+ // ── presets ─────────────────────────────────────────────────────────────
110
+ command
111
+ .command('presets')
112
+ .description('List the ready-made scenes and what data each one needs')
113
+ .action(() => {
114
+ this.presets();
115
+ });
116
+ // ── doctor ──────────────────────────────────────────────────────────────
117
+ command
118
+ .command('doctor')
119
+ .description('Check that this machine can render (chromium for frames, ffmpeg to encode)')
120
+ .action(() => {
121
+ this.doctor();
122
+ });
123
+ // ── render ──────────────────────────────────────────────────────────────
124
+ command
125
+ .command('render')
126
+ .description('Render a video now — from a preset, your own HTML animation, or your own renderer\'s frames')
127
+ .option('-p, --preset <name>', `scene to render (${MOTION_PRESETS.join(', ')})`)
128
+ .option('-d, --data <path>', 'CSV or JSON file to animate (required by chart presets)')
129
+ .option('-H, --html <path>', 'a self-contained HTML animation file instead of a preset')
130
+ .option('-F, --frames <dir>', 'frames YOUR renderer already wrote (python/PIL, Manim, Blender, Three.js…) — encoded here, no browser needed')
131
+ .option('--frames-pattern <glob>', "glob over the frame filenames, e.g. 'f_*.png' (a '/' in it selects across subdirectories, e.g. '**/*.png')")
132
+ .option('--renderer <command>', "record the command that made --frames (e.g. 'python render.py') so `motion revise` can re-run it")
133
+ .option('--renderer-cwd <dir>', 'directory --renderer runs in')
134
+ .option('-a, --audio <file>', 'music, SFX or a voice-over file to mux onto the video')
135
+ .option('-o, --out <name>', 'filename prefix for the artifact')
136
+ .option('-t, --title <text>', 'title shown in the scene')
137
+ .option('-s, --subtitle <text>', 'subtitle shown under the title')
138
+ .option('-k, --kicker <text>', 'small label above the title')
139
+ .option('--accent <colour>', 'accent colour for the moving parts')
140
+ .option('--unit <suffix>', "suffix for chart values, e.g. '%' or 'ms'")
141
+ .option('--aspect <ratio>', "shape instead of a size, e.g. 16:9, 9:16, 1:1")
142
+ .option('--duration <ms>', 'length in milliseconds', parseInt)
143
+ .option('--fps <number>', 'frames per second', parseInt)
144
+ .option('--width <px>', 'frame width', parseInt)
145
+ .option('--height <px>', 'frame height', parseInt)
146
+ .option('-f, --format <format>', 'mp4, webm or gif', 'mp4')
147
+ .option('--narration <text>', 'narration, synthesized locally and muxed onto the video')
148
+ .option('--voice <id>', 'TTS voice for the narration')
149
+ .action(async (options) => {
150
+ await this.render(options);
151
+ });
152
+ // ── revise ──────────────────────────────────────────────────────────────
153
+ command
154
+ .command('revise <id>')
155
+ .description('Re-render an existing render (re-runs the recorded renderer for a frame sequence)')
156
+ .option('--renderer <command>', 'the command that made the frames — records it on this render so future revisions can re-run it')
157
+ .option('--renderer-cwd <dir>', 'directory --renderer runs in')
158
+ .option('--allow-renderer-change', 'revise even though the recorded renderer changed since the render was made')
159
+ .option('-n, --preview', 'show what would run, and change nothing')
160
+ .option('--fps <number>', 'frames per second', parseInt)
161
+ .option('--duration <ms>', 'length in milliseconds', parseInt)
162
+ .option('-f, --format <format>', 'mp4, webm or gif', 'mp4')
163
+ .option('-a, --audio <file>', 'music, SFX or a voice-over file to mux onto the video')
164
+ .option('--narration <text>', 'narration, synthesized locally and muxed onto the video')
165
+ .action(async (id, options) => {
166
+ await this.revise(id, options);
167
+ });
168
+ // ── inspect ─────────────────────────────────────────────────────────────
169
+ command
170
+ .command('inspect')
171
+ .description('Render a contact sheet of keyframes — one image you can look at before delivering')
172
+ .option('-H, --html <path>', 'a self-contained HTML animation file to sample')
173
+ .option('-F, --frames <dir>', 'a frame sequence to sample')
174
+ .option('--frames-pattern <glob>', "glob over the frame filenames, e.g. 'f_*.png'")
175
+ .option('-n, --tiles <number>', 'keyframes on the sheet (default 12)', parseInt)
176
+ .option('--tile-width <px>', 'pixels per tile (default 480)', parseInt)
177
+ .option('-d, --duration <ms>', 'length of an HTML animation in milliseconds', parseInt)
178
+ .option('--fps <number>', 'frames per second of a frame sequence', parseInt)
179
+ .option('-o, --out <name>', 'filename prefix for the sheet')
180
+ .action(async (options) => {
181
+ await this.inspect(options);
182
+ });
183
+ // ── open ────────────────────────────────────────────────────────────────
184
+ command
185
+ .command('open [id]')
186
+ .description('Open a render in the OS viewer (the latest one when no id is given)')
187
+ .action(async (id) => {
188
+ await this.open(id);
189
+ });
190
+ return command;
191
+ }
192
+ list(limit) {
193
+ const renders = listMotionManifests();
194
+ if (renders.length === 0) {
195
+ logger.info(' No motion renders in this workspace yet.');
196
+ this.nextSteps();
197
+ return;
198
+ }
199
+ logger.highlight(` 🎬 Motion renders — ${renders.length} in ${motionHomeDir()}`);
200
+ logger.info(' id created source length size frame');
201
+ for (const manifest of renders.slice(0, limit)) {
202
+ logger.info(renderRow(manifest));
203
+ }
204
+ if (renders.length > limit) {
205
+ logger.info(` … ${renders.length - limit} more (use --limit)`);
206
+ }
207
+ console.log('');
208
+ logger.info(` Open one: nuvira motion open ${renders[0].id}`);
209
+ }
210
+ presets() {
211
+ logger.highlight(' 🎬 Ready-made scenes');
212
+ const help = {
213
+ 'title-card': 'a kinetic title — a kicker, title and subtitle',
214
+ 'bar-race': 'bars growing to their values, from a CSV or JSON file',
215
+ 'line-reveal': 'a line drawn left to right through your data points',
216
+ 'code-walkthrough': 'code revealed line by line, for a walkthrough video',
217
+ };
218
+ for (const preset of MOTION_PRESETS) {
219
+ const data = presetNeedsData(preset) ? 'needs --data' : 'no data needed';
220
+ logger.info(` ${preset.padEnd(16)} ${help[preset] ?? ''} (${data})`);
221
+ }
222
+ console.log('');
223
+ logger.info(' Example: nuvira motion render --preset title-card --title "Hello" --duration 5000');
224
+ logger.info(' Example: nuvira motion render --preset bar-race --data stars.csv --aspect 9:16');
225
+ }
226
+ doctor() {
227
+ const availability = motionAvailability();
228
+ // Two routes, two dependency sets: an HTML/preset render captures frames in a
229
+ // browser AND encodes them, while a frames render only encodes what YOUR
230
+ // renderer already wrote. Reporting one missing chromium as "cannot render"
231
+ // would be wrong for the route that never opens a browser.
232
+ const frames = framesAvailability();
233
+ const renders = listMotionManifests().length;
234
+ if (availability.ok) {
235
+ logger.success(' ✅ This machine can render every route: chromium (HTML/preset frames) and ffmpeg (encode).');
236
+ }
237
+ else if (frames.ok) {
238
+ logger.warn(` ⚠️ HTML and preset renders are unavailable — missing: ${availability.missing.join(', ')}`);
239
+ if (availability.hint)
240
+ logger.info(` ${availability.hint}`);
241
+ logger.info(' ✅ The frames route still works: pass --frames <dir> with your own renderer\'s PNGs.');
242
+ }
243
+ else {
244
+ logger.warn(` ⚠️ Cannot render yet — missing: ${availability.missing.join(', ')}`);
245
+ if (availability.hint)
246
+ logger.info(` ${availability.hint}`);
247
+ logger.info(' Until then `list`, `presets` and `open` still work; only `render` needs them.');
248
+ }
249
+ logger.info(` 📁 Renders live in ${motionHomeDir()}`);
250
+ logger.info(` 🎬 ${renders} render(s) in this workspace`);
251
+ this.nextSteps();
252
+ }
253
+ async render(options) {
254
+ const presetName = typeof options.preset === 'string' ? options.preset : undefined;
255
+ const htmlPath = typeof options.html === 'string' ? options.html : undefined;
256
+ const dataPath = typeof options.data === 'string' ? options.data : undefined;
257
+ const framesDir = typeof options.frames === 'string' ? options.frames : undefined;
258
+ const audioPath = typeof options.audio === 'string' ? options.audio : undefined;
259
+ // Validate the SOURCE here, where the user is, rather than letting the tool
260
+ // refuse after a chromium launch.
261
+ if (!presetName && !htmlPath && !framesDir) {
262
+ logger.error(' ❌ A render needs a source: --preset <name>, --html <file>, or --frames <dir>.');
263
+ logger.info(' Run `nuvira motion presets` to see the ready-made scenes.');
264
+ process.exitCode = 1;
265
+ return;
266
+ }
267
+ if (framesDir && (presetName || htmlPath)) {
268
+ logger.error(' ❌ Pass either --frames (your own renderer) or --preset/--html — not both.');
269
+ process.exitCode = 1;
270
+ return;
271
+ }
272
+ if (framesDir && !existsSync(framesDir)) {
273
+ logger.error(` ❌ No such frames directory: ${framesDir}`);
274
+ process.exitCode = 1;
275
+ return;
276
+ }
277
+ if (typeof options.renderer === 'string' && !framesDir) {
278
+ logger.error(' ❌ --renderer records the command that made --frames, so it needs --frames too.');
279
+ process.exitCode = 1;
280
+ return;
281
+ }
282
+ if (audioPath && !existsSync(audioPath)) {
283
+ logger.error(` ❌ No such audio file: ${audioPath}`);
284
+ process.exitCode = 1;
285
+ return;
286
+ }
287
+ let preset;
288
+ if (presetName) {
289
+ if (!isMotionPreset(presetName)) {
290
+ logger.error(` ❌ Unknown preset '${presetName}'. One of: ${MOTION_PRESETS.join(', ')}.`);
291
+ process.exitCode = 1;
292
+ return;
293
+ }
294
+ preset = presetName;
295
+ }
296
+ if (preset && presetNeedsData(preset) && !dataPath) {
297
+ logger.error(` ❌ '${preset}' animates YOUR data — pass --data <csv-or-json-file>.`);
298
+ process.exitCode = 1;
299
+ return;
300
+ }
301
+ if (dataPath && !existsSync(dataPath)) {
302
+ logger.error(` ❌ No such data file: ${dataPath}`);
303
+ process.exitCode = 1;
304
+ return;
305
+ }
306
+ // A frame sequence needs ffmpeg and no browser — the user already rendered it.
307
+ const availability = framesDir ? framesAvailability() : motionAvailability();
308
+ if (!availability.ok) {
309
+ logger.error(` ❌ Cannot render — missing: ${availability.missing.join(', ')}`);
310
+ if (availability.hint)
311
+ logger.info(` ${availability.hint}`);
312
+ process.exitCode = 1;
313
+ return;
314
+ }
315
+ const params = {};
316
+ if (typeof options.title === 'string')
317
+ params.title = options.title;
318
+ if (typeof options.subtitle === 'string')
319
+ params.subtitle = options.subtitle;
320
+ if (typeof options.kicker === 'string')
321
+ params.kicker = options.kicker;
322
+ if (typeof options.accent === 'string')
323
+ params.accent = options.accent;
324
+ if (typeof options.unit === 'string')
325
+ params.unit = options.unit;
326
+ const args = {
327
+ action: 'render',
328
+ ...(preset ? { preset } : {}),
329
+ ...(htmlPath ? { html_path: htmlPath } : {}),
330
+ ...(framesDir ? { frames_dir: framesDir } : {}),
331
+ ...(typeof options['framesPattern'] === 'string' ? { frames_pattern: options['framesPattern'] } : {}),
332
+ ...(typeof options.renderer === 'string' ? { renderer_command: options.renderer } : {}),
333
+ ...(typeof options['rendererCwd'] === 'string' ? { renderer_cwd: options['rendererCwd'] } : {}),
334
+ ...(audioPath ? { audio_path: audioPath } : {}),
335
+ ...(dataPath ? { data_path: dataPath } : {}),
336
+ ...(Object.keys(params).length > 0 ? { params } : {}),
337
+ ...(typeof options.out === 'string' ? { out_name: options.out } : {}),
338
+ ...(typeof options.aspect === 'string' ? { aspect_ratio: options.aspect } : {}),
339
+ ...(typeof options.duration === 'number' ? { duration_ms: options.duration } : {}),
340
+ ...(typeof options.fps === 'number' ? { fps: options.fps } : {}),
341
+ ...(typeof options.width === 'number' ? { width: options.width } : {}),
342
+ ...(typeof options.height === 'number' ? { height: options.height } : {}),
343
+ ...(typeof options.format === 'string' ? { format: options.format } : {}),
344
+ ...(typeof options.narration === 'string' ? { narration: options.narration } : {}),
345
+ ...(typeof options.voice === 'string' ? { voice: options.voice } : {}),
346
+ };
347
+ const { runMotionTool } = await import('../tools/modality/motion-tool.js');
348
+ try {
349
+ const result = await runMotionTool(args, { configManager: this.configManager });
350
+ logger.info(` ${result.text.split('\n').join('\n ')}`);
351
+ if (result.media) {
352
+ logger.success(` ✅ ${result.media.path}`);
353
+ logger.info(` Open it: nuvira motion open`);
354
+ }
355
+ else if (result.text.startsWith('Error:')) {
356
+ // A render that produced nothing must not exit 0: a script that chains a
357
+ // render into an upload would treat "no video" as success.
358
+ process.exitCode = 1;
359
+ }
360
+ }
361
+ catch (err) {
362
+ // The tool reports refusals as text; this catches the unexpected, and says
363
+ // what to do rather than only what broke.
364
+ logger.error(` ❌ Render failed: ${err instanceof Error ? err.message : String(err)}`);
365
+ logger.info(' Check the machine with `nuvira motion doctor`.');
366
+ process.exitCode = 1;
367
+ }
368
+ }
369
+ /**
370
+ * `nuvira motion revise <id>` — the same revision the tool performs, from the
371
+ * terminal.
372
+ *
373
+ * Worth having as a command for one reason: a frames revision RE-RUNS the
374
+ * renderer, so it is the one action a person wants to watch happen (and to
375
+ * re-run with a different fps) without a model in the loop.
376
+ */
377
+ async revise(id, options) {
378
+ const audioPath = typeof options.audio === 'string' ? options.audio : undefined;
379
+ if (audioPath && !existsSync(audioPath)) {
380
+ logger.error(` ❌ No such audio file: ${audioPath}`);
381
+ process.exitCode = 1;
382
+ return;
383
+ }
384
+ const args = {
385
+ action: 'revise',
386
+ source_id: id,
387
+ ...(typeof options.renderer === 'string' ? { renderer_command: options.renderer } : {}),
388
+ ...(typeof options['rendererCwd'] === 'string' ? { renderer_cwd: options['rendererCwd'] } : {}),
389
+ ...(options['allowRendererChange'] ? { allow_renderer_change: true } : {}),
390
+ ...(options.preview ? { preview: true } : {}),
391
+ ...(typeof options.fps === 'number' ? { fps: options.fps } : {}),
392
+ ...(typeof options.duration === 'number' ? { duration_ms: options.duration } : {}),
393
+ ...(typeof options.format === 'string' ? { format: options.format } : {}),
394
+ ...(audioPath ? { audio_path: audioPath } : {}),
395
+ ...(typeof options.narration === 'string' ? { narration: options.narration } : {}),
396
+ };
397
+ const { runMotionTool } = await import('../tools/modality/motion-tool.js');
398
+ try {
399
+ const result = await runMotionTool(args, { configManager: this.configManager });
400
+ logger.info(` ${result.text.split('\n').join('\n ')}`);
401
+ if (result.media)
402
+ logger.success(` ✅ ${result.media.path}`);
403
+ // A refusal is the tool's normal, honest answer here (no recorded renderer, or
404
+ // a changed one) — so it sets the exit code rather than looking like success.
405
+ else if (result.text.startsWith('Error:'))
406
+ process.exitCode = 1;
407
+ }
408
+ catch (err) {
409
+ logger.error(` ❌ Revise failed: ${err instanceof Error ? err.message : String(err)}`);
410
+ process.exitCode = 1;
411
+ }
412
+ }
413
+ /**
414
+ * `nuvira motion inspect` — the contact sheet.
415
+ *
416
+ * Here for the same reason `render` is: the loop is author → LOOK → fix, and a
417
+ * person reviewing someone else's animation needs the same dozen keyframes a
418
+ * model does.
419
+ */
420
+ async inspect(options) {
421
+ const htmlPath = typeof options.html === 'string' ? options.html : undefined;
422
+ const framesDir = typeof options.frames === 'string' ? options.frames : undefined;
423
+ if (!htmlPath && !framesDir) {
424
+ logger.error(' ❌ inspect needs a source: --html <file> or --frames <dir>.');
425
+ process.exitCode = 1;
426
+ return;
427
+ }
428
+ if (htmlPath && !existsSync(htmlPath)) {
429
+ logger.error(` ❌ No such html file: ${htmlPath}`);
430
+ process.exitCode = 1;
431
+ return;
432
+ }
433
+ if (framesDir && !existsSync(framesDir)) {
434
+ logger.error(` ❌ No such frames directory: ${framesDir}`);
435
+ process.exitCode = 1;
436
+ return;
437
+ }
438
+ const availability = framesDir ? framesAvailability() : motionAvailability();
439
+ if (!availability.ok) {
440
+ logger.error(` ❌ Cannot inspect — missing: ${availability.missing.join(', ')}`);
441
+ if (availability.hint)
442
+ logger.info(` ${availability.hint}`);
443
+ process.exitCode = 1;
444
+ return;
445
+ }
446
+ const { inspectMotion } = await import('../tools/modality/motion.js');
447
+ // Static import, never an inline `require` — that form threw at runtime in
448
+ // the published build once already (see publish-tool.ts).
449
+ const result = await inspectMotion({
450
+ ...(framesDir ? { framesDir } : { html: readFileSync(htmlPath, 'utf-8') }),
451
+ ...(typeof options.tiles === 'number' ? { tiles: options.tiles } : {}),
452
+ ...(typeof options['tileWidth'] === 'number' ? { tile_width: options['tileWidth'] } : {}),
453
+ ...(typeof options.duration === 'number' ? { duration_ms: options.duration } : {}),
454
+ ...(typeof options.fps === 'number' ? { fps: options.fps } : {}),
455
+ ...(typeof options.out === 'string' ? { out_name: options.out } : {}),
456
+ });
457
+ if (!result.ok) {
458
+ logger.error(` ❌ ${result.error}`);
459
+ if (result.hint)
460
+ logger.info(` ${result.hint}`);
461
+ process.exitCode = 1;
462
+ return;
463
+ }
464
+ logger.success(` ✅ ${result.file}`);
465
+ logger.info(` ${result.tiles} keyframes, ${result.cols}×${result.rows} grid, ${result.secondsPerTile.toFixed(1)}s apart, ` +
466
+ `from a ${result.width}×${result.height} ${result.frameSource === 'frames' ? 'frame sequence' : 'animation'}`);
467
+ for (const warning of result.warnings)
468
+ logger.warn(` ${warning}`);
469
+ }
470
+ async open(id) {
471
+ const renders = listMotionManifests();
472
+ if (renders.length === 0) {
473
+ logger.warn(' No motion renders in this workspace yet.');
474
+ this.nextSteps();
475
+ return;
476
+ }
477
+ const manifest = id ? loadMotionManifest(id) : renders[0];
478
+ if (!manifest) {
479
+ logger.error(` ❌ No render with id '${id}'. Run \`nuvira motion list\`.`);
480
+ process.exitCode = 1;
481
+ return;
482
+ }
483
+ if (!manifest.artifact || !existsSync(manifest.artifact)) {
484
+ logger.error(` ❌ ${manifest.id} recorded ${manifest.artifact || 'no artifact'}, which is gone.`);
485
+ logger.info(' Re-render it from the stored source, or pick another with `nuvira motion list`.');
486
+ process.exitCode = 1;
487
+ return;
488
+ }
489
+ logger.info(` 📁 ${manifest.artifact}`);
490
+ const launch = opener();
491
+ if (!launch) {
492
+ logger.info(' No viewer opener found on this machine — the path above is the artifact.');
493
+ return;
494
+ }
495
+ try {
496
+ spawn(launch.command, [...launch.args, manifest.artifact], { stdio: 'ignore', detached: true }).unref();
497
+ logger.success(' ▶️ Opened in the system viewer.');
498
+ }
499
+ catch (err) {
500
+ logger.warn(` ⚠️ Could not open a viewer (${err instanceof Error ? err.message : String(err)}).`);
501
+ logger.info(' The path above is the artifact.');
502
+ }
503
+ }
504
+ /** The one thing a user with no renders needs: how to get one, both ways. */
505
+ nextSteps() {
506
+ console.log('');
507
+ logger.highlight(' Make one');
508
+ logger.info(' • Without a model: nuvira motion render --preset title-card --title "Hello"');
509
+ logger.info(' • From your data: nuvira motion render --preset bar-race --data numbers.csv');
510
+ logger.info(' • Your own frames: nuvira motion render --frames ./frames --fps 30 --renderer "python render.py"');
511
+ logger.info(' • Re-render one: nuvira motion revise <id> --fps 30');
512
+ logger.info(' • In a chat turn: "turn README.md into a 20s animated explainer with captions"');
513
+ logger.info(' • In the dashboard: the Motion page plays every render inline.');
514
+ }
515
+ }
516
+ //# sourceMappingURL=motion.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"motion.js","sourceRoot":"","sources":["../../src/cli/motion.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,13 @@ export interface MachineFacts {
46
46
  shellName: string | null;
47
47
  /** Package managers/toolchain binaries actually present, in preference order. */
48
48
  packageManagers: string[];
49
+ /**
50
+ * Runtime tooling present that is NOT a package manager — container runtimes
51
+ * above all. Kept separate from `packageManagers` because these install
52
+ * nothing; they decide whether a command the model would otherwise GUESS
53
+ * about can run here.
54
+ */
55
+ tools: string[];
49
56
  }
50
57
  /** Options for a deterministic test (the real call passes none). */
51
58
  export interface MachineFactsProbe {
@@ -1 +1 @@
1
- {"version":3,"file":"machine-facts.d.ts","sourceRoot":"","sources":["../../src/learning/machine-facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,0BAA0B;IAC1B,EAAE,EAAE,YAAY,CAAC;IACjB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iFAAiF;IACjF,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAuBD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC;AAID,uCAAuC;AACvC,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAqCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,iBAAsB,GAAG,YAAY,CAmC9E;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,YAAmC,GAAG,MAAM,CASzF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,YAAmC,GAAG,UAAU,CAa7F"}
1
+ {"version":3,"file":"machine-facts.d.ts","sourceRoot":"","sources":["../../src/learning/machine-facts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAMH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AAExD,4DAA4D;AAC5D,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC;AAEnE,MAAM,WAAW,YAAY;IAC3B,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAC;IACnB,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC1B,0BAA0B;IAC1B,EAAE,EAAE,YAAY,CAAC;IACjB,kFAAkF;IAClF,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,iFAAiF;IACjF,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAuCD,oEAAoE;AACpE,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC;AAID,uCAAuC;AACvC,wBAAgB,sBAAsB,IAAI,IAAI,CAE7C;AAqCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,GAAE,iBAAsB,GAAG,YAAY,CA6C9E;AAED,2EAA2E;AAC3E,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,YAAmC,GAAG,MAAM,CAezF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,YAAmC,GAAG,UAAU,CAgB7F"}