@bitmagic/cli 0.1.64-dev.1 → 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 (150) 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 +88 -1
  27. package/dist/commands/generate.js +400 -21
  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/project/art-style.d.ts +34 -0
  81. package/dist/project/art-style.js +63 -0
  82. package/dist/project/art-style.js.map +1 -0
  83. package/dist/prompt.d.ts +9 -0
  84. package/dist/prompt.js +36 -0
  85. package/dist/prompt.js.map +1 -0
  86. package/dist/publish/bundle.d.ts +12 -0
  87. package/dist/publish/bundle.js +32 -0
  88. package/dist/publish/bundle.js.map +1 -1
  89. package/dist/render/qr-png.d.ts +6 -3
  90. package/dist/render/qr-png.js +8 -8
  91. package/dist/render/qr-png.js.map +1 -1
  92. package/dist/scaffold/blender-level-skill-files.d.ts +26 -0
  93. package/dist/scaffold/blender-level-skill-files.js +570 -0
  94. package/dist/scaffold/blender-level-skill-files.js.map +1 -0
  95. package/dist/scaffold/claude-settings.js +2 -0
  96. package/dist/scaffold/claude-settings.js.map +1 -1
  97. package/dist/scaffold/project-files.d.ts +2 -1
  98. package/dist/scaffold/project-files.js +125 -42
  99. package/dist/scaffold/project-files.js.map +1 -1
  100. package/dist/scaffold/project.d.ts +9 -0
  101. package/dist/scaffold/project.js +29 -3
  102. package/dist/scaffold/project.js.map +1 -1
  103. package/dist/scaffold/reference-guidance.d.ts +1 -1
  104. package/dist/scaffold/reference-guidance.js +2 -1
  105. package/dist/scaffold/reference-guidance.js.map +1 -1
  106. package/dist/scaffold/skill-files.js +3 -1
  107. package/dist/scaffold/skill-files.js.map +1 -1
  108. package/dist/scaffold/unity-skill-files.js +1 -2
  109. package/dist/scaffold/unity-skill-files.js.map +1 -1
  110. package/dist/tools/bundles.d.ts +21 -0
  111. package/dist/tools/bundles.js +67 -0
  112. package/dist/tools/bundles.js.map +1 -0
  113. package/dist/trailer/ffmpeg.d.ts +10 -0
  114. package/dist/trailer/ffmpeg.js +51 -6
  115. package/dist/trailer/ffmpeg.js.map +1 -1
  116. package/dist/trailer/hud-raster.d.ts +12 -12
  117. package/dist/trailer/hud-raster.js +85 -32
  118. package/dist/trailer/hud-raster.js.map +1 -1
  119. package/dist/trailer/hud-state.d.ts +75 -4
  120. package/dist/trailer/hud-state.js +132 -17
  121. package/dist/trailer/hud-state.js.map +1 -1
  122. package/dist/trailer/io.d.ts +2 -0
  123. package/dist/trailer/io.js +6 -1
  124. package/dist/trailer/io.js.map +1 -1
  125. package/dist/trailer/link.d.ts +1 -0
  126. package/dist/trailer/link.js +15 -0
  127. package/dist/trailer/link.js.map +1 -0
  128. package/dist/trailer/make.d.ts +2 -0
  129. package/dist/trailer/make.js +1 -0
  130. package/dist/trailer/make.js.map +1 -1
  131. package/dist/trailer/merge.js +32 -11
  132. package/dist/trailer/merge.js.map +1 -1
  133. package/dist/trailer/music-beats.js +4 -39
  134. package/dist/trailer/music-beats.js.map +1 -1
  135. package/dist/trailer/render.d.ts +2 -0
  136. package/dist/trailer/render.js +94 -48
  137. package/dist/trailer/render.js.map +1 -1
  138. package/dist/trailer/timeline-types.d.ts +19 -0
  139. package/dist/trailer/timeline-types.js +42 -2
  140. package/dist/trailer/timeline-types.js.map +1 -1
  141. package/dist/trailer/title-raster.js +2 -1
  142. package/dist/trailer/title-raster.js.map +1 -1
  143. package/dist/trailer/titles.js +6 -1
  144. package/dist/trailer/titles.js.map +1 -1
  145. package/dist/trailer/video-chain.d.ts +96 -8
  146. package/dist/trailer/video-chain.js +183 -0
  147. package/dist/trailer/video-chain.js.map +1 -1
  148. package/dist/verify/browser.js +4 -1
  149. package/dist/verify/browser.js.map +1 -1
  150. 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,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"}
@@ -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
  *
@@ -1,6 +1,7 @@
1
1
  import { createHash } from 'crypto';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { rapierFlavorForGame } from '@bitmagic/world-forger/physics-mode.js';
4
5
  import { CliError } from '../errors.js';
5
6
  import { projectBin } from '../project/context.js';
6
7
  import { spawnBinSync } from '../project/spawn-bin.js';
@@ -18,6 +19,30 @@ export const VITE_PUBLISH_STANDALONE_CONFIG = 'vite.publish-standalone.config.js
18
19
  export function publishConfigFor(singleFile) {
19
20
  return singleFile ? VITE_PUBLISH_STANDALONE_CONFIG : VITE_PUBLISH_CONFIG;
20
21
  }
22
+ /**
23
+ * The single Rapier flavor this project's bundle ships — the game's EFFECTIVE
24
+ * physics mode (src/work/game.json genre + physicsMode + physics2d, clamped
25
+ * exactly the way the engine clamps at boot), not the raw declared value.
26
+ *
27
+ * A build ships exactly one physics engine, never both: a game.json that
28
+ * cannot be read fails the build here, before `tsc` runs, rather than guessing
29
+ * which engine to drop. (The vendored config applies the same rule itself when
30
+ * the variable is unset, so a hand-run `vite build` is single-flavor too.)
31
+ */
32
+ export function resolveRapierFlavor(root) {
33
+ const file = path.join(root, 'src', 'work', 'game.json');
34
+ let raw;
35
+ try {
36
+ raw = JSON.parse(fs.readFileSync(file, 'utf-8'));
37
+ }
38
+ catch (err) {
39
+ throw new CliError(`Cannot decide which physics engine to bundle: ${path.relative(root, file)} is unreadable ` +
40
+ `(${err instanceof Error ? err.message : String(err)}). A build ships exactly one Rapier flavor, ` +
41
+ "chosen from the game's physicsMode.", 1);
42
+ }
43
+ const gameGenre = typeof raw.gameGenre === 'string' ? raw.gameGenre : '';
44
+ return rapierFlavorForGame(gameGenre, raw.physicsMode, raw.physics2d === true);
45
+ }
21
46
  export function buildBundlePaths(root) {
22
47
  const dir = path.join(root, '.bitmagic', 'build');
23
48
  return { dir, htmlPath: path.join(dir, 'index.html'), manifestPath: path.join(dir, 'manifest.json') };
@@ -90,9 +115,16 @@ export function runBuild(root, engineVersion, options = {}) {
90
115
  const { dir, htmlPath } = buildBundlePaths(root);
91
116
  fs.mkdirSync(dir, { recursive: true });
92
117
  const vite = projectBin(root, 'vite');
118
+ // Covers `bitmagic build`, `bitmagic publish` and `bitmagic ios` in one
119
+ // place: the vendored configs read BUNDLE_RAPIER_FLAVOR and stub the Rapier
120
+ // flavor this game does not run, so the bundle ships exactly one. The
121
+ // variable is OWNED here — an inherited value from the caller's shell never
122
+ // overrides the game's own physics mode.
123
+ const bundleEnv = { ...process.env, BUNDLE_RAPIER_FLAVOR: resolveRapierFlavor(root) };
93
124
  const bundle = spawnBinSync(vite, ['build', '--config', configFile, '--outDir', dir, '--emptyOutDir'], {
94
125
  cwd: root,
95
126
  stdio: 'inherit',
127
+ env: bundleEnv,
96
128
  });
97
129
  if (bundle.error)
98
130
  throw new CliError(`Could not run vite: ${bundle.error.message}`, 1);
@@ -1 +1 @@
1
- {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bundle.js","sourceRoot":"","sources":["../../src/publish/bundle.ts"],"names":[],"mappings":"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"}
@@ -15,11 +15,14 @@
15
15
  *
16
16
  * Two other hand-rolled PNG encoders exist in this repo — `world-forger-internal`'s vehicle atlas
17
17
  * and `game-play-agent`'s solid-colour tile — and neither is reachable from here: the first is in a
18
- * `private: true` package the CLI does not depend on, the second is server code. A shared home
19
- * would have to be `@bitmagic/asset-core`; that is worth doing when something needs the third copy,
20
- * not for the second.
18
+ * `private: true` package the CLI does not depend on, the second is server code. Within the CLI the
19
+ * chunk/CRC/signature primitives are exported from here and shared with the trailer's transparent
20
+ * frame filler (trailer/video-chain.ts); `ios/icon.ts` predates that and keeps its own.
21
21
  */
22
22
  import { Buffer } from 'buffer';
23
+ export declare const PNG_SIGNATURE: Buffer<ArrayBuffer>;
24
+ /** One PNG chunk: length, type, data, and the CRC over type+data (never over the length). */
25
+ export declare function pngChunk(type: string, data: Buffer): Buffer;
23
26
  export interface QrPngOptions {
24
27
  /** Pixels per module. Defaults to `MODULE_PIXELS`. */
25
28
  scale?: number;
@@ -15,9 +15,9 @@
15
15
  *
16
16
  * Two other hand-rolled PNG encoders exist in this repo — `world-forger-internal`'s vehicle atlas
17
17
  * and `game-play-agent`'s solid-colour tile — and neither is reachable from here: the first is in a
18
- * `private: true` package the CLI does not depend on, the second is server code. A shared home
19
- * would have to be `@bitmagic/asset-core`; that is worth doing when something needs the third copy,
20
- * not for the second.
18
+ * `private: true` package the CLI does not depend on, the second is server code. Within the CLI the
19
+ * chunk/CRC/signature primitives are exported from here and shared with the trailer's transparent
20
+ * frame filler (trailer/video-chain.ts); `ios/icon.ts` predates that and keeps its own.
21
21
  */
22
22
  import { Buffer } from 'buffer';
23
23
  import * as zlib from 'zlib';
@@ -28,7 +28,7 @@ const MODULE_PIXELS = 8;
28
28
  * uses — that one is trading margin for terminal columns, and a file has no such constraint.
29
29
  */
30
30
  const QUIET_MODULES = 4;
31
- const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
31
+ export const PNG_SIGNATURE = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
32
32
  /** The standard CRC-32 table (PNG spec annex D), built once. */
33
33
  function buildCrcTable() {
34
34
  const table = new Uint32Array(256);
@@ -50,7 +50,7 @@ function crc32(bytes) {
50
50
  return (crc ^ 0xffffffff) >>> 0;
51
51
  }
52
52
  /** One PNG chunk: length, type, data, and the CRC over type+data (never over the length). */
53
- function chunk(type, data) {
53
+ export function pngChunk(type, data) {
54
54
  const length = Buffer.alloc(4);
55
55
  length.writeUInt32BE(data.length, 0);
56
56
  const typeAndData = Buffer.concat([Buffer.from(type, 'ascii'), data]);
@@ -101,11 +101,11 @@ export function encodeQrPng(matrix, options = {}) {
101
101
  ihdr[12] = 0; // interlace: none
102
102
  return Buffer.concat([
103
103
  PNG_SIGNATURE,
104
- chunk('IHDR', ihdr),
104
+ pngChunk('IHDR', ihdr),
105
105
  // deflateSync, not fflate's — fflate's `deflateSync` emits RAW deflate with no zlib header,
106
106
  // and an IDAT must carry the zlib wrapper. (fflate's `zlibSync` would also do.)
107
- chunk('IDAT', zlib.deflateSync(raw)),
108
- chunk('IEND', Buffer.alloc(0)),
107
+ pngChunk('IDAT', zlib.deflateSync(raw)),
108
+ pngChunk('IEND', Buffer.alloc(0)),
109
109
  ]);
110
110
  }
111
111
  //# sourceMappingURL=qr-png.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"qr-png.js","sourceRoot":"","sources":["../../src/render/qr-png.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"qr-png.js","sourceRoot":"","sources":["../../src/render/qr-png.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The `building-levels-in-blender` skill: a hand-designed low-poly world written as a Python script
3
+ * against the shipped `bmlevel` library, built by Blender into one GLB plus the collider / door /
4
+ * light / landmark JSON, audited with ray casts, reviewed from rendered stills, and loaded by the
5
+ * engine's `MeshLevel`. Distilled from a creator's space-station game whose agent installed Blender
6
+ * and hand-rolled every part of this — the build vocabulary, the audits, the review renders, the
7
+ * level loader — and hit the two failures the skill now names up front (a GLB fetched from a local
8
+ * path that 404s after publish; NPC spawns routed into an absent voxel grid).
9
+ *
10
+ * Same contract as `unity-skill-files.ts`: pure functions returning file contents, registered in
11
+ * `SHIPPED_SKILLS` (project.ts). The Python and Blender scripts ship in the package's
12
+ * `assets/blender-level/` (see `files` in package.json) rather than being rendered into every
13
+ * project; the skill's step 1 copies them into `tools/blender-level/`.
14
+ *
15
+ * The skill's first section is the gate: the path is for frontier models with Blender available,
16
+ * and everything else goes to `bitmagic forge`. The CLI cannot tell which model drives it, so the
17
+ * gate is the agent's own call — stated once, plainly, where the planning skill sends it.
18
+ *
19
+ * Backticks and `${` are escaped for the template literal; `project-files.test.ts` checks the
20
+ * rendered frontmatter and that no escape leaks into the output.
21
+ */
22
+ export declare function renderBlenderLevelsSkill(): string;
23
+ export declare function renderBlenderConventionsReference(): string;
24
+ export declare function renderBlenderAuditsReference(): string;
25
+ export declare function renderBlenderPassesReference(): string;
26
+ export declare function renderBlenderEngineHandoffReference(): string;