@bitmagic/cli 0.1.64-dev.0 → 0.1.64-dev.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 (155) hide show
  1. package/README.md +80 -5
  2. package/assets/blender-level/README.md +25 -0
  3. package/assets/blender-level/audit.py +232 -0
  4. package/assets/blender-level/bmlevel/__init__.py +294 -0
  5. package/assets/blender-level/bmlevel/core.py +438 -0
  6. package/assets/blender-level/bmlevel/scene_bpy.py +186 -0
  7. package/assets/blender-level/bmlevel/scene_null.py +44 -0
  8. package/assets/blender-level/example_level.py +80 -0
  9. package/assets/blender-level/find_blender.py +62 -0
  10. package/assets/blender-level/review.py +117 -0
  11. package/assets/blender-level/sync_world.py +85 -0
  12. package/assets/blender-level/tests/test_core.py +189 -0
  13. package/dist/assets/keep-glb.d.ts +20 -0
  14. package/dist/assets/keep-glb.js +45 -0
  15. package/dist/assets/keep-glb.js.map +1 -0
  16. package/dist/cli.d.ts +5 -0
  17. package/dist/cli.js +2 -0
  18. package/dist/cli.js.map +1 -1
  19. package/dist/commands/assets.d.ts +3 -0
  20. package/dist/commands/assets.js +33 -3
  21. package/dist/commands/assets.js.map +1 -1
  22. package/dist/commands/cover.js +7 -1
  23. package/dist/commands/cover.js.map +1 -1
  24. package/dist/commands/forge.js +70 -11
  25. package/dist/commands/forge.js.map +1 -1
  26. package/dist/commands/generate.d.ts +93 -0
  27. package/dist/commands/generate.js +491 -18
  28. package/dist/commands/generate.js.map +1 -1
  29. package/dist/commands/init.d.ts +11 -0
  30. package/dist/commands/init.js +33 -1
  31. package/dist/commands/init.js.map +1 -1
  32. package/dist/commands/judge.d.ts +0 -11
  33. package/dist/commands/judge.js +15 -2
  34. package/dist/commands/judge.js.map +1 -1
  35. package/dist/commands/levels.d.ts +1 -1
  36. package/dist/commands/levels.js +14 -3
  37. package/dist/commands/levels.js.map +1 -1
  38. package/dist/commands/reference.js +5 -1
  39. package/dist/commands/reference.js.map +1 -1
  40. package/dist/commands/reset-account.js +2 -11
  41. package/dist/commands/reset-account.js.map +1 -1
  42. package/dist/commands/tools.d.ts +1 -0
  43. package/dist/commands/tools.js +73 -0
  44. package/dist/commands/tools.js.map +1 -0
  45. package/dist/commands/trailer.js +18 -4
  46. package/dist/commands/trailer.js.map +1 -1
  47. package/dist/editor/asset-detail-panel.d.ts +8 -3
  48. package/dist/editor/asset-detail-panel.js +11 -1
  49. package/dist/editor/asset-detail-panel.js.map +1 -1
  50. package/dist/editor/hud-replay-page.js +317 -22
  51. package/dist/editor/hud-replay-page.js.map +1 -1
  52. package/dist/editor/shell-page.js +117 -7
  53. package/dist/editor/shell-page.js.map +1 -1
  54. package/dist/forge/apply-modifications.js +70 -2
  55. package/dist/forge/apply-modifications.js.map +1 -1
  56. package/dist/forge/progress.d.ts +10 -0
  57. package/dist/forge/progress.js +7 -6
  58. package/dist/forge/progress.js.map +1 -1
  59. package/dist/forge/run-pipeline.d.ts +8 -0
  60. package/dist/forge/run-pipeline.js +37 -2
  61. package/dist/forge/run-pipeline.js.map +1 -1
  62. package/dist/forge/stream.d.ts +7 -1
  63. package/dist/forge/stream.js +5 -2
  64. package/dist/forge/stream.js.map +1 -1
  65. package/dist/forge/two-d-gate.d.ts +72 -0
  66. package/dist/forge/two-d-gate.js +198 -0
  67. package/dist/forge/two-d-gate.js.map +1 -0
  68. package/dist/generate/animation-from-video.d.ts +11 -3
  69. package/dist/generate/animation-from-video.js +12 -2
  70. package/dist/generate/animation-from-video.js.map +1 -1
  71. package/dist/generate/model.d.ts +11 -0
  72. package/dist/generate/model.js +41 -1
  73. package/dist/generate/model.js.map +1 -1
  74. package/dist/generate/prop.d.ts +9 -0
  75. package/dist/generate/prop.js +59 -9
  76. package/dist/generate/prop.js.map +1 -1
  77. package/dist/generate/video-review.d.ts +28 -0
  78. package/dist/generate/video-review.js +120 -0
  79. package/dist/generate/video-review.js.map +1 -0
  80. package/dist/generate/video.d.ts +52 -0
  81. package/dist/generate/video.js +177 -0
  82. package/dist/generate/video.js.map +1 -0
  83. package/dist/project/art-style.d.ts +34 -0
  84. package/dist/project/art-style.js +63 -0
  85. package/dist/project/art-style.js.map +1 -0
  86. package/dist/project/jobs.d.ts +1 -1
  87. package/dist/project/jobs.js.map +1 -1
  88. package/dist/prompt.d.ts +9 -0
  89. package/dist/prompt.js +36 -0
  90. package/dist/prompt.js.map +1 -0
  91. package/dist/publish/bundle.d.ts +12 -0
  92. package/dist/publish/bundle.js +32 -0
  93. package/dist/publish/bundle.js.map +1 -1
  94. package/dist/render/qr-png.d.ts +6 -3
  95. package/dist/render/qr-png.js +8 -8
  96. package/dist/render/qr-png.js.map +1 -1
  97. package/dist/scaffold/blender-level-skill-files.d.ts +26 -0
  98. package/dist/scaffold/blender-level-skill-files.js +570 -0
  99. package/dist/scaffold/blender-level-skill-files.js.map +1 -0
  100. package/dist/scaffold/claude-settings.js +2 -0
  101. package/dist/scaffold/claude-settings.js.map +1 -1
  102. package/dist/scaffold/project-files.d.ts +2 -1
  103. package/dist/scaffold/project-files.js +135 -43
  104. package/dist/scaffold/project-files.js.map +1 -1
  105. package/dist/scaffold/project.d.ts +9 -0
  106. package/dist/scaffold/project.js +29 -3
  107. package/dist/scaffold/project.js.map +1 -1
  108. package/dist/scaffold/reference-guidance.d.ts +1 -1
  109. package/dist/scaffold/reference-guidance.js +2 -1
  110. package/dist/scaffold/reference-guidance.js.map +1 -1
  111. package/dist/scaffold/skill-files.js +3 -1
  112. package/dist/scaffold/skill-files.js.map +1 -1
  113. package/dist/scaffold/unity-skill-files.js +1 -2
  114. package/dist/scaffold/unity-skill-files.js.map +1 -1
  115. package/dist/tools/bundles.d.ts +21 -0
  116. package/dist/tools/bundles.js +67 -0
  117. package/dist/tools/bundles.js.map +1 -0
  118. package/dist/trailer/ffmpeg.d.ts +10 -0
  119. package/dist/trailer/ffmpeg.js +51 -6
  120. package/dist/trailer/ffmpeg.js.map +1 -1
  121. package/dist/trailer/hud-raster.d.ts +12 -12
  122. package/dist/trailer/hud-raster.js +85 -32
  123. package/dist/trailer/hud-raster.js.map +1 -1
  124. package/dist/trailer/hud-state.d.ts +75 -4
  125. package/dist/trailer/hud-state.js +132 -17
  126. package/dist/trailer/hud-state.js.map +1 -1
  127. package/dist/trailer/io.d.ts +2 -0
  128. package/dist/trailer/io.js +6 -1
  129. package/dist/trailer/io.js.map +1 -1
  130. package/dist/trailer/link.d.ts +1 -0
  131. package/dist/trailer/link.js +15 -0
  132. package/dist/trailer/link.js.map +1 -0
  133. package/dist/trailer/make.d.ts +2 -0
  134. package/dist/trailer/make.js +1 -0
  135. package/dist/trailer/make.js.map +1 -1
  136. package/dist/trailer/merge.js +32 -11
  137. package/dist/trailer/merge.js.map +1 -1
  138. package/dist/trailer/music-beats.js +4 -39
  139. package/dist/trailer/music-beats.js.map +1 -1
  140. package/dist/trailer/render.d.ts +2 -0
  141. package/dist/trailer/render.js +94 -48
  142. package/dist/trailer/render.js.map +1 -1
  143. package/dist/trailer/timeline-types.d.ts +19 -0
  144. package/dist/trailer/timeline-types.js +42 -2
  145. package/dist/trailer/timeline-types.js.map +1 -1
  146. package/dist/trailer/title-raster.js +2 -1
  147. package/dist/trailer/title-raster.js.map +1 -1
  148. package/dist/trailer/titles.js +6 -1
  149. package/dist/trailer/titles.js.map +1 -1
  150. package/dist/trailer/video-chain.d.ts +96 -8
  151. package/dist/trailer/video-chain.js +183 -0
  152. package/dist/trailer/video-chain.js.map +1 -1
  153. package/dist/verify/browser.js +4 -1
  154. package/dist/verify/browser.js.map +1 -1
  155. package/package.json +4 -4
@@ -0,0 +1,120 @@
1
+ /**
2
+ * Looking at the clip `bitmagic generate video` just paid for.
3
+ *
4
+ * A generated clip was the one asset the CLI could produce but not show: the command printed a URL,
5
+ * and checking whether the rider actually jumps meant a curl and a hand-written ffmpeg tile filter.
6
+ * Both facts that decide whether a clip is usable are cheap to read off the file, so both are read
7
+ * here and printed with the result:
8
+ *
9
+ * - a contact sheet, 8 frames spread across the clip, written into `.bitmagic/` as a PNG the
10
+ * agent (or the creator) can open;
11
+ * - whether the file carries an audio track, which is what decides if the cutscene needs a music
12
+ * bed under it. Today's generator produces silent clips, but that is the generator's property,
13
+ * not a promise — so it is probed, never assumed.
14
+ *
15
+ * Every step is best-effort by design, exactly as `cover.ts` downloads its image: the clip is
16
+ * generated, billed and already in world.json by the time this runs, so nothing here may turn a
17
+ * successful generation into a failed command. ffmpeg is not a dependency of this CLI's core lane
18
+ * either, so its absence is one note, not an error.
19
+ */
20
+ import * as fs from 'fs';
21
+ import * as path from 'path';
22
+ import { captureFfmpegTool, missingFfmpegTool, runFfmpeg } from '../trailer/ffmpeg.js';
23
+ /** Frames in the sheet, and the grid they are tiled into. 4x2 fits a 16:9 clip on one screen. */
24
+ const SHEET_COLUMNS = 4;
25
+ const SHEET_ROWS = 2;
26
+ const SHEET_FRAMES = SHEET_COLUMNS * SHEET_ROWS;
27
+ /** Per-frame width in the sheet. 4 across is ~1280px total — readable, and a small PNG. */
28
+ const FRAME_WIDTH = 320;
29
+ /** Where a reviewed clip's frames land. Gitignored, and outside the publish fingerprint. */
30
+ export function contactSheetPath(root, assetId) {
31
+ return path.join(root, '.bitmagic', 'videos', `${safeFileStem(assetId)}.png`);
32
+ }
33
+ /** Asset ids come from `--asset-id` too, so they are not trusted to be a safe filename. */
34
+ function safeFileStem(assetId) {
35
+ const cleaned = assetId.replace(/[^A-Za-z0-9_-]/g, '-').slice(0, 96);
36
+ return cleaned.length > 0 ? cleaned : 'clip';
37
+ }
38
+ /**
39
+ * Download the clip, tile frames from it, and report whether it has sound.
40
+ *
41
+ * The mp4 itself is deliberately not kept: it is several MB per generation, the URL is printed
42
+ * beside the sheet, and the dev view plays the clip when a creator wants to watch it move.
43
+ */
44
+ export async function reviewGeneratedClip(options) {
45
+ const missing = missingFfmpegTool(['ffmpeg', 'ffprobe']);
46
+ if (missing !== null) {
47
+ return {
48
+ sheetPath: null,
49
+ hasAudioTrack: null,
50
+ notes: [`${missing} is not on PATH, so no frames were grabbed (macOS: brew install ffmpeg).`],
51
+ };
52
+ }
53
+ const sheetPath = contactSheetPath(options.root, options.assetId);
54
+ const clipPath = `${sheetPath}.download`;
55
+ fs.mkdirSync(path.dirname(sheetPath), { recursive: true });
56
+ try {
57
+ const response = await options.fetch(options.videoUrl);
58
+ if (!response.ok) {
59
+ return { sheetPath: null, hasAudioTrack: null, notes: [`could not download the clip to look at it (HTTP ${response.status}).`] };
60
+ }
61
+ fs.writeFileSync(clipPath, Buffer.from(await response.arrayBuffer()));
62
+ const notes = [];
63
+ const hasAudioTrack = await probeHasAudioTrack(clipPath).catch((error) => {
64
+ notes.push(`could not read the clip's streams: ${messageOf(error)}`);
65
+ return null;
66
+ });
67
+ const written = await writeContactSheet(clipPath, sheetPath, options.durationSeconds)
68
+ .then(() => true)
69
+ .catch((error) => {
70
+ notes.push(`could not grab frames from the clip: ${messageOf(error)}`);
71
+ return false;
72
+ });
73
+ return { sheetPath: written ? sheetPath : null, hasAudioTrack, notes };
74
+ }
75
+ catch (error) {
76
+ return { sheetPath: null, hasAudioTrack: null, notes: [`could not download the clip to look at it: ${messageOf(error)}`] };
77
+ }
78
+ finally {
79
+ try {
80
+ fs.rmSync(clipPath, { force: true });
81
+ }
82
+ catch {
83
+ // A leftover download in .bitmagic/ is not worth a word to the creator.
84
+ }
85
+ }
86
+ }
87
+ /** True when the container holds at least one audio stream. Empty ffprobe output means none. */
88
+ async function probeHasAudioTrack(clipPath) {
89
+ const stdout = await captureFfmpegTool('ffprobe', [
90
+ '-v', 'error',
91
+ '-select_streams', 'a',
92
+ '-show_entries', 'stream=codec_type',
93
+ '-of', 'csv=p=0',
94
+ clipPath,
95
+ ]);
96
+ return stdout.toString('utf-8').trim().length > 0;
97
+ }
98
+ /**
99
+ * Tile `SHEET_FRAMES` frames spread evenly across the clip into one PNG.
100
+ *
101
+ * `fps` rather than `select='not(mod(n,N))'`: the sample rate follows the clip's length, so a 3 s
102
+ * and a 10 s clip both come back as a full grid instead of one dense row and one sparse one.
103
+ */
104
+ async function writeContactSheet(clipPath, sheetPath, durationSeconds) {
105
+ const seconds = Math.max(durationSeconds, 0.5);
106
+ const fps = (SHEET_FRAMES / seconds).toFixed(6);
107
+ await runFfmpeg([
108
+ '-v', 'error',
109
+ '-nostdin',
110
+ '-y',
111
+ '-i', clipPath,
112
+ '-vf', `fps=${fps},scale=${FRAME_WIDTH}:-1,tile=${SHEET_COLUMNS}x${SHEET_ROWS}`,
113
+ '-frames:v', '1',
114
+ sheetPath,
115
+ ]);
116
+ }
117
+ function messageOf(error) {
118
+ return error instanceof Error ? error.message : String(error);
119
+ }
120
+ //# sourceMappingURL=video-review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-review.js","sourceRoot":"","sources":["../../src/generate/video-review.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { VIDEO_MAX_SECONDS, VIDEO_MIN_SECONDS, type VideoJobResult } from '@bitmagic/asset-core';
2
+ import type { Environment } from '../config/environments.js';
3
+ import { type ApiDeps } from '../http/client.js';
4
+ import type { ProjectContext } from '../project/context.js';
5
+ export declare const JOBS_PATH = "/api/cli/v1/assets/video/jobs";
6
+ /** A first frame is a still, not a film reel; anything larger is a mistake worth catching here. */
7
+ export declare const MAX_IMAGE_BYTES: number;
8
+ export declare const IMAGE_EXTENSIONS: string[];
9
+ export interface VideoRun {
10
+ prompt: string;
11
+ durationSeconds?: number;
12
+ name?: string;
13
+ /** Local first-frame image; uploaded before the job is submitted. */
14
+ imagePath?: string;
15
+ /** Already-uploaded first frame. When set, `imagePath` is not read. */
16
+ imageUrl?: string;
17
+ seed?: number;
18
+ assetId?: string;
19
+ creatorPrompt?: string;
20
+ }
21
+ export interface VideoDeps extends ApiDeps {
22
+ log: (message: string) => void;
23
+ sleep: (ms: number) => Promise<void>;
24
+ }
25
+ export interface VideoInstallResult {
26
+ assetId: string;
27
+ videoUrl: string;
28
+ webmUrl?: string;
29
+ durationSeconds: number;
30
+ width?: number;
31
+ height?: number;
32
+ sparksCharged: number;
33
+ patchesApplied: number;
34
+ }
35
+ interface JobStatus {
36
+ status: 'pending' | 'running' | 'succeeded' | 'failed';
37
+ result?: VideoJobResult;
38
+ error?: {
39
+ kind?: string;
40
+ message?: string;
41
+ } | string;
42
+ }
43
+ /** The creator-facing sentence for a failed job — `error.kind` decides it, never the raw JSON. */
44
+ export declare function describeJobFailure(error: JobStatus['error']): string;
45
+ export declare function generateAndInstallVideo(options: {
46
+ context: ProjectContext;
47
+ environment: Environment;
48
+ token: string;
49
+ run: VideoRun;
50
+ deps: VideoDeps;
51
+ }): Promise<VideoInstallResult>;
52
+ export { VIDEO_MIN_SECONDS, VIDEO_MAX_SECONDS };
@@ -0,0 +1,177 @@
1
+ /**
2
+ * `bitmagic generate video` — a prompt becomes a short 720p clip the engine can play.
3
+ *
4
+ * The asset row this writes is `type: 'video'`, which `engine.playVideo(assetId)` mounts as a
5
+ * fullscreen overlay. That engine API shipped with nothing able to produce a clip for it; this is
6
+ * the producer, so a generated cutscene is playable from game code the moment it lands.
7
+ *
8
+ * Four steps, the same shape `generate animation --video` uses:
9
+ *
10
+ * 1. With `--image`, upload the first frame under `worlds/v3/<gameId>/` through the CLI's
11
+ * signed-URL lane (`http/signed-upload.ts`). The bytes never go through api-server: it only
12
+ * mints the URL.
13
+ * 2. `POST /api/cli/v1/assets/video/jobs` — api-server checks ownership and the spark balance,
14
+ * hands the job to the Asset Forger, charges per second of the REQUESTED length, and returns
15
+ * the job id.
16
+ * 3. Poll `GET .../jobs/<id>?gameId=` until it settles. This is not the SSE lane every other
17
+ * generator uses because it cannot promise to finish inside that lane's 280 s deadline:
18
+ * measured 37-44 s for a prompt alone, but 189-202 s with a first frame.
19
+ * 4. Build the assets[] row with asset-core's `buildVideoPatch` — the same row any other lane
20
+ * would write — and apply it to world.json.
21
+ */
22
+ import * as fs from 'fs';
23
+ import * as path from 'path';
24
+ import { buildVideoPatch, formatZodIssues, videoParamsSchema, VIDEO_MAX_SECONDS, VIDEO_MIN_SECONDS, } from '@bitmagic/asset-core';
25
+ import { CliError, errnoCode } from '../errors.js';
26
+ import { apiGet, apiPost } from '../http/client.js';
27
+ import { uploadProjectFile } from '../http/signed-upload.js';
28
+ import { fileExtension } from '../assets/file-kind.js';
29
+ import { applyPatchesToWorld } from './apply-patches.js';
30
+ import { aliasSourceDir } from '../scaffold/aliases.js';
31
+ export const JOBS_PATH = '/api/cli/v1/assets/video/jobs';
32
+ /** 5 s ± jitter, the same cadence asset-core's own job poller uses against the Forger. */
33
+ const POLL_BASE_MS = 5000;
34
+ /** Above asset-core's 10-minute job ceiling, so the server gives up before this does. */
35
+ const POLL_DEADLINE_MS = 12 * 60 * 1000;
36
+ /** A first frame is a still, not a film reel; anything larger is a mistake worth catching here. */
37
+ export const MAX_IMAGE_BYTES = 20 * 1024 * 1024;
38
+ /** What `--image` takes. The Forger passes the URL straight to Runware. */
39
+ const IMAGE_TYPES = {
40
+ png: 'image/png',
41
+ jpg: 'image/jpeg',
42
+ jpeg: 'image/jpeg',
43
+ webp: 'image/webp',
44
+ };
45
+ export const IMAGE_EXTENSIONS = Object.keys(IMAGE_TYPES);
46
+ /** The creator-facing sentence for a failed job — `error.kind` decides it, never the raw JSON. */
47
+ export function describeJobFailure(error) {
48
+ const kind = typeof error === 'object' && error !== null ? error.kind : undefined;
49
+ const message = typeof error === 'object' && error !== null ? error.message : error;
50
+ // Seen live on a bland test prompt: the provider's own filter, not ours.
51
+ if (typeof message === 'string' && message.includes('invalidProviderContent')) {
52
+ return 'The video provider\'s content filter rejected this prompt. Rephrase it — describing a '
53
+ + 'scene and its motion works better than naming people, brands or styles.';
54
+ }
55
+ if (kind === 'invalid-request') {
56
+ return `The video could not be generated: ${message ?? 'the request was refused as invalid.'}`;
57
+ }
58
+ if (kind === 'timeout') {
59
+ return 'Video generation timed out upstream. A first frame (--image) is much slower than a '
60
+ + 'prompt alone; try a shorter clip, or the same prompt without an image.';
61
+ }
62
+ return message ? `Video generation failed: ${message}` : 'Video generation failed.';
63
+ }
64
+ function readImage(imagePath) {
65
+ const extension = fileExtension(imagePath);
66
+ const contentType = IMAGE_TYPES[extension];
67
+ if (contentType === undefined) {
68
+ throw new CliError(`--image takes ${IMAGE_EXTENSIONS.map((e) => `.${e}`).join(', ')}; `
69
+ + `${JSON.stringify(path.basename(imagePath))} is none of those.`);
70
+ }
71
+ let stat;
72
+ try {
73
+ stat = fs.statSync(imagePath);
74
+ }
75
+ catch (error) {
76
+ if (errnoCode(error) === 'ENOENT') {
77
+ throw new CliError(`--image: no such file ${JSON.stringify(imagePath)}.`);
78
+ }
79
+ throw error;
80
+ }
81
+ if (!stat.isFile())
82
+ throw new CliError(`--image: ${JSON.stringify(imagePath)} is not a file.`);
83
+ if (stat.size === 0)
84
+ throw new CliError(`--image: ${JSON.stringify(path.basename(imagePath))} is empty.`);
85
+ if (stat.size > MAX_IMAGE_BYTES) {
86
+ throw new CliError(`--image: ${JSON.stringify(path.basename(imagePath))} is ${Math.round(stat.size / 1024 / 1024)} MB; `
87
+ + `the limit is ${MAX_IMAGE_BYTES / 1024 / 1024} MB.`);
88
+ }
89
+ const bytes = new Uint8Array(fs.readFileSync(imagePath));
90
+ const stem = path.basename(imagePath, path.extname(imagePath)).replace(/[^A-Za-z0-9_-]+/g, '_') || 'frame';
91
+ return { bytes, contentType, filename: `video-frame-${Date.now()}-${stem}.${extension}` };
92
+ }
93
+ function formatElapsed(ms) {
94
+ const total = Math.round(ms / 1000);
95
+ const minutes = Math.floor(total / 60);
96
+ const seconds = total % 60;
97
+ return minutes > 0 ? `${minutes}m${String(seconds).padStart(2, '0')}s` : `${seconds}s`;
98
+ }
99
+ export async function generateAndInstallVideo(options) {
100
+ const { context, environment, token, run, deps } = options;
101
+ const gameId = context.metadata.gameId;
102
+ const worldPath = path.join(context.root, aliasSourceDir('work'), 'world.json');
103
+ let imageUrl = run.imageUrl;
104
+ if (imageUrl === undefined && run.imagePath !== undefined) {
105
+ const image = readImage(run.imagePath);
106
+ deps.log(`Uploading ${path.basename(run.imagePath)} (${Math.round(image.bytes.byteLength / 1024)} KB)…`);
107
+ const uploaded = await uploadProjectFile(environment, token, {
108
+ gameId, filename: image.filename, contentType: image.contentType, bytes: image.bytes,
109
+ }, deps);
110
+ imageUrl = uploaded.url;
111
+ }
112
+ const params = {
113
+ prompt: run.prompt,
114
+ ...(run.durationSeconds !== undefined ? { durationSeconds: run.durationSeconds } : {}),
115
+ ...(run.name !== undefined ? { name: run.name } : {}),
116
+ ...(imageUrl !== undefined ? { imageUrl } : {}),
117
+ ...(run.seed !== undefined ? { seed: run.seed } : {}),
118
+ ...(run.assetId !== undefined ? { assetId: run.assetId } : {}),
119
+ };
120
+ // Parsed here as well as server-side so the defaults the patch is built from
121
+ // are the ones the server applied, not `undefined`.
122
+ const parsed = videoParamsSchema.safeParse(params);
123
+ if (!parsed.success) {
124
+ // Named through asset-core's own formatter: the field name is what makes
125
+ // the message actionable ("prompt: …", not "String must contain …").
126
+ throw new CliError(`${formatZodIssues(parsed.error)}. world.json is unchanged.`);
127
+ }
128
+ deps.log(imageUrl !== undefined
129
+ ? 'Submitting the video job (a first frame takes a few minutes)…'
130
+ : 'Submitting the video job…');
131
+ const accepted = await apiPost(environment, JOBS_PATH, token, {
132
+ gameId,
133
+ ...params,
134
+ ...(run.creatorPrompt !== undefined ? { creatorPrompt: run.creatorPrompt } : {}),
135
+ }, deps);
136
+ if (typeof accepted.jobId !== 'string' || typeof accepted.statusPath !== 'string') {
137
+ throw new CliError('api-server accepted the job but returned no job id — is it newer than this CLI?');
138
+ }
139
+ const sparksCharged = typeof accepted.sparksCharged === 'number' ? accepted.sparksCharged : 0;
140
+ const startedAt = Date.now();
141
+ let result;
142
+ for (;;) {
143
+ const elapsed = Date.now() - startedAt;
144
+ if (elapsed > POLL_DEADLINE_MS) {
145
+ throw new CliError(`Video generation did not finish within ${formatElapsed(POLL_DEADLINE_MS)}. `
146
+ + `Job ${accepted.jobId} may still complete server-side.`);
147
+ }
148
+ await deps.sleep(Math.round(POLL_BASE_MS * (0.8 + Math.random() * 0.4)));
149
+ const status = await apiGet(environment, accepted.statusPath, token, deps);
150
+ if (status.status === 'succeeded') {
151
+ if (!status.result?.videoUrl || !status.result.videoId) {
152
+ throw new CliError('Video generation finished but returned no clip. world.json is unchanged.');
153
+ }
154
+ result = status.result;
155
+ break;
156
+ }
157
+ if (status.status === 'failed') {
158
+ throw new CliError(`${describeJobFailure(status.error)} world.json is unchanged.`);
159
+ }
160
+ deps.log(`Generating… (${formatElapsed(Date.now() - startedAt)})`);
161
+ }
162
+ const patch = buildVideoPatch(parsed.data, result);
163
+ const applied = applyPatchesToWorld(worldPath, [patch]);
164
+ const assetId = patch.value.id;
165
+ return {
166
+ assetId,
167
+ videoUrl: result.videoUrl,
168
+ ...(result.webmUrl !== undefined ? { webmUrl: result.webmUrl } : {}),
169
+ durationSeconds: result.durationSeconds,
170
+ ...(result.width !== undefined ? { width: result.width } : {}),
171
+ ...(result.height !== undefined ? { height: result.height } : {}),
172
+ sparksCharged,
173
+ patchesApplied: applied.applied,
174
+ };
175
+ }
176
+ export { VIDEO_MIN_SECONDS, VIDEO_MAX_SECONDS };
177
+ //# sourceMappingURL=video.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video.js","sourceRoot":"","sources":["../../src/generate/video.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * What a project DECLARES about its art style: `artStyle` at the top level of `src/work/game.json`,
3
+ * `voxel` or `low-poly`, absent meaning `voxel` — every game made before the field existed.
4
+ *
5
+ * One reader, the `platform-declaration.ts` shape, because six commands act on the same field
6
+ * and must never disagree about it: `cover` and `reference make` choose their prompt lead by it,
7
+ * `assets add` and `generate model|prop|character` choose whether a mesh is kept or voxelized,
8
+ * and `judge` uses it as the art direction when GAME-DESIGN.md has no heading for one.
9
+ *
10
+ * Best effort throughout: a missing or unreadable file means "declares nothing" (voxel), never
11
+ * an error. A value that is present but not one of the two lands in `rejected` so the caller can
12
+ * say so once — a typo'd `"lowpoly"` silently voxelizing a Blender level is the failure this
13
+ * exists to make visible.
14
+ */
15
+ import { type ArtStyle } from '@bitmagic/asset-core/art-style';
16
+ export type { ArtStyle } from '@bitmagic/asset-core/art-style';
17
+ export interface ArtStyleDeclaration {
18
+ /** `undefined` means the project declares nothing — which every consumer treats as `voxel`. */
19
+ artStyle?: ArtStyle;
20
+ /** Present but not an accepted value, verbatim, for the caller's message. */
21
+ rejected?: unknown;
22
+ /** Whether game.json could be read at all. */
23
+ workCopyReadable: boolean;
24
+ }
25
+ /** The exact declaration, for callers that must tell "says nothing" from "says voxel". */
26
+ export declare function readArtStyleDeclaration(root: string): ArtStyleDeclaration;
27
+ /**
28
+ * The style every command acts on. A rejected value is reported through `log` (once per call —
29
+ * commands call this once) and treated as voxel, the same as absent: refusing the command would
30
+ * turn a typo in a field most creators never touch into a blocked cover.
31
+ */
32
+ export declare function resolveArtStyle(root: string, log?: (line: string) => void): ArtStyle;
33
+ /** One line for a command's output, so a transcript shows which style drove it. */
34
+ export declare function describeArtStyleSource(root: string): string;
@@ -0,0 +1,63 @@
1
+ /**
2
+ * What a project DECLARES about its art style: `artStyle` at the top level of `src/work/game.json`,
3
+ * `voxel` or `low-poly`, absent meaning `voxel` — every game made before the field existed.
4
+ *
5
+ * One reader, the `platform-declaration.ts` shape, because six commands act on the same field
6
+ * and must never disagree about it: `cover` and `reference make` choose their prompt lead by it,
7
+ * `assets add` and `generate model|prop|character` choose whether a mesh is kept or voxelized,
8
+ * and `judge` uses it as the art direction when GAME-DESIGN.md has no heading for one.
9
+ *
10
+ * Best effort throughout: a missing or unreadable file means "declares nothing" (voxel), never
11
+ * an error. A value that is present but not one of the two lands in `rejected` so the caller can
12
+ * say so once — a typo'd `"lowpoly"` silently voxelizing a Blender level is the failure this
13
+ * exists to make visible.
14
+ */
15
+ import * as fs from 'node:fs';
16
+ import * as path from 'node:path';
17
+ import { DEFAULT_ART_STYLE, parseArtStyle } from '@bitmagic/asset-core/art-style';
18
+ import { aliasSourceDir } from '../scaffold/aliases.js';
19
+ /** The exact declaration, for callers that must tell "says nothing" from "says voxel". */
20
+ export function readArtStyleDeclaration(root) {
21
+ const gamePath = path.join(root, aliasSourceDir('work'), 'game.json');
22
+ let game = null;
23
+ try {
24
+ if (fs.existsSync(gamePath)) {
25
+ const parsed = JSON.parse(fs.readFileSync(gamePath, 'utf-8'));
26
+ if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
27
+ game = parsed;
28
+ }
29
+ }
30
+ }
31
+ catch {
32
+ game = null;
33
+ }
34
+ const declaration = { workCopyReadable: game !== null };
35
+ const declared = game?.artStyle;
36
+ const parsed = parseArtStyle(declared);
37
+ if (parsed !== undefined)
38
+ declaration.artStyle = parsed;
39
+ else if (declared !== undefined)
40
+ declaration.rejected = declared;
41
+ return declaration;
42
+ }
43
+ /**
44
+ * The style every command acts on. A rejected value is reported through `log` (once per call —
45
+ * commands call this once) and treated as voxel, the same as absent: refusing the command would
46
+ * turn a typo in a field most creators never touch into a blocked cover.
47
+ */
48
+ export function resolveArtStyle(root, log) {
49
+ const declaration = readArtStyleDeclaration(root);
50
+ if (declaration.rejected !== undefined && log) {
51
+ log(`note: game.json says artStyle ${JSON.stringify(declaration.rejected)}, which is not "voxel" or `
52
+ + `"low-poly" — treating it as voxel.`);
53
+ }
54
+ return declaration.artStyle ?? DEFAULT_ART_STYLE;
55
+ }
56
+ /** One line for a command's output, so a transcript shows which style drove it. */
57
+ export function describeArtStyleSource(root) {
58
+ const declaration = readArtStyleDeclaration(root);
59
+ return declaration.artStyle !== undefined
60
+ ? `Art style: ${declaration.artStyle} (game.json)`
61
+ : 'Art style: voxel (game.json declares none)';
62
+ }
63
+ //# sourceMappingURL=art-style.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"art-style.js","sourceRoot":"","sources":["../../src/project/art-style.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAiB,MAAM,gCAAgC,CAAC;AACjG,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAaxD,0FAA0F;AAC1F,MAAM,UAAU,uBAAuB,CAAC,IAAY;IAClD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,CAAC;IACtE,IAAI,IAAI,GAAmC,IAAI,CAAC;IAChD,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC5B,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;YACvE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,IAAI,GAAG,MAAiC,CAAC;YAC3C,CAAC;QACH,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,IAAI,GAAG,IAAI,CAAC;IACd,CAAC;IACD,MAAM,WAAW,GAAwB,EAAE,gBAAgB,EAAE,IAAI,KAAK,IAAI,EAAE,CAAC;IAC7E,MAAM,QAAQ,GAAG,IAAI,EAAE,QAAQ,CAAC;IAChC,MAAM,MAAM,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACvC,IAAI,MAAM,KAAK,SAAS;QAAE,WAAW,CAAC,QAAQ,GAAG,MAAM,CAAC;SACnD,IAAI,QAAQ,KAAK,SAAS;QAAE,WAAW,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACjE,OAAO,WAAW,CAAC;AACrB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY,EAAE,GAA4B;IACxE,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,IAAI,WAAW,CAAC,QAAQ,KAAK,SAAS,IAAI,GAAG,EAAE,CAAC;QAC9C,GAAG,CACD,iCAAiC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,4BAA4B;cAC/F,oCAAoC,CACvC,CAAC;IACJ,CAAC;IACD,OAAO,WAAW,CAAC,QAAQ,IAAI,iBAAiB,CAAC;AACnD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,CAAC,CAAC;IAClD,OAAO,WAAW,CAAC,QAAQ,KAAK,SAAS;QACvC,CAAC,CAAC,cAAc,WAAW,CAAC,QAAQ,cAAc;QAClD,CAAC,CAAC,4CAA4C,CAAC;AACnD,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import type { ForgeProgressSnapshot } from '../forge/progress.js';
2
2
  import type { ForgeLayoutMap } from '@bitmagic/world-forger/pipeline/index.js';
3
3
  /** Which command is running. Shown as-is in the dev view, so these are creator-facing words. */
4
- export type JobKind = 'skybox' | 'background' | 'block-type' | 'sound' | 'music' | 'image' | 'character' | 'animation' | 'animation-video' | 'prop' | 'vehicle' | 'forge' | 'cover' | 'reference' | 'hq' | 'judge' | 'upload' | 'model';
4
+ export type JobKind = 'skybox' | 'background' | 'block-type' | 'sound' | 'music' | 'image' | 'character' | 'animation' | 'animation-video' | 'video' | 'prop' | 'vehicle' | 'forge' | 'cover' | 'reference' | 'hq' | 'judge' | 'upload' | 'model';
5
5
  export interface JobRecord {
6
6
  jobId: string;
7
7
  kind: JobKind;
@@ -1 +1 @@
1
- {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/project/jobs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"jobs.js","sourceRoot":"","sources":["../../src/project/jobs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** Whether a person is at the keyboard, as opposed to a pipe, an agent or CI. */
2
+ export declare function isInteractive(): boolean;
3
+ /** One line of answer, trimmed. The question is written to stderr. */
4
+ export declare function askOnStdin(question: string): Promise<string>;
5
+ /**
6
+ * `y` / `yes`, case-insensitive. Everything else is no — including an empty line, so
7
+ * hitting return on a `[y/N]` prompt declines rather than spends.
8
+ */
9
+ export declare function isAffirmative(answer: string): boolean;
package/dist/prompt.js ADDED
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Asking the person at the keyboard a question.
3
+ *
4
+ * The question goes to STDERR, never stdout. stdout carries the `--json` result document
5
+ * (see output.ts), and a prompt written there corrupts it — the same rule `output.info`
6
+ * follows for progress lines.
7
+ *
8
+ * `isInteractive` is separate from `ask` because callers need them separately: a command
9
+ * has to know whether asking is possible at all before it asks. Blocking on a stdin that
10
+ * is a closed pipe, or one carrying data (`generate --spec -` reads a document from fd 0),
11
+ * hangs forever instead of prompting.
12
+ */
13
+ import { createInterface } from 'readline/promises';
14
+ /** Whether a person is at the keyboard, as opposed to a pipe, an agent or CI. */
15
+ export function isInteractive() {
16
+ return process.stdin.isTTY === true;
17
+ }
18
+ /** One line of answer, trimmed. The question is written to stderr. */
19
+ export async function askOnStdin(question) {
20
+ const rl = createInterface({ input: process.stdin, output: process.stderr });
21
+ try {
22
+ return (await rl.question(question)).trim();
23
+ }
24
+ finally {
25
+ rl.close();
26
+ }
27
+ }
28
+ /**
29
+ * `y` / `yes`, case-insensitive. Everything else is no — including an empty line, so
30
+ * hitting return on a `[y/N]` prompt declines rather than spends.
31
+ */
32
+ export function isAffirmative(answer) {
33
+ const normalized = answer.trim().toLowerCase();
34
+ return normalized === 'y' || normalized === 'yes';
35
+ }
36
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../src/prompt.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEpD,iFAAiF;AACjF,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC;AACtC,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,QAAgB;IAC/C,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,IAAI,CAAC;QACH,OAAO,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9C,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC/C,OAAO,UAAU,KAAK,GAAG,IAAI,UAAU,KAAK,KAAK,CAAC;AACpD,CAAC"}
@@ -1,3 +1,4 @@
1
+ import { type RapierFlavor } from '@bitmagic/world-forger/physics-mode.js';
1
2
  /**
2
3
  * The configs the scaffold vendors alongside `engine/`, one per bundle mode.
3
4
  *
@@ -9,6 +10,17 @@ export declare const VITE_PUBLISH_CONFIG = "vite.publish.config.js";
9
10
  export declare const VITE_PUBLISH_STANDALONE_CONFIG = "vite.publish-standalone.config.js";
10
11
  /** The vendored config a build of this mode loads. */
11
12
  export declare function publishConfigFor(singleFile: boolean): string;
13
+ /**
14
+ * The single Rapier flavor this project's bundle ships — the game's EFFECTIVE
15
+ * physics mode (src/work/game.json genre + physicsMode + physics2d, clamped
16
+ * exactly the way the engine clamps at boot), not the raw declared value.
17
+ *
18
+ * A build ships exactly one physics engine, never both: a game.json that
19
+ * cannot be read fails the build here, before `tsc` runs, rather than guessing
20
+ * which engine to drop. (The vendored config applies the same rule itself when
21
+ * the variable is unset, so a hand-run `vite build` is single-flavor too.)
22
+ */
23
+ export declare function resolveRapierFlavor(root: string): RapierFlavor;
12
24
  /**
13
25
  * What was built, and from what.
14
26
  *