@bitmagic/cli 0.1.19 → 0.1.21

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.
@@ -1,6 +1,9 @@
1
+ import type { ProjectMetadata } from '../project/context.js';
1
2
  export interface EditorServerOptions {
2
3
  /** The project root — the directory holding `bitmagic.json`. */
3
4
  root: string;
5
+ /** The project's `bitmagic.json`, for the generation the HQ button runs. */
6
+ metadata: ProjectMetadata;
4
7
  /** The game this project owns, from `bitmagic.json`. */
5
8
  gameId: string;
6
9
  /** Port vite serves the game on; the shell iframes it. */
@@ -12,6 +15,13 @@ export interface EditorServerOptions {
12
15
  export interface EditorServer {
13
16
  /** The URL to open, e.g. `http://localhost:3011/`. */
14
17
  readonly url: string;
18
+ /** Where editor actions are journalled, so the startup banner can point an agent at it. */
19
+ readonly journalPath: string;
15
20
  close(): Promise<void>;
16
21
  }
22
+ /**
23
+ * The command the agent should run to fulfil an HQ request. One definition, quoted for a shell,
24
+ * so the journal line, the HTTP reply and the editor's own confirmation cannot drift apart.
25
+ */
26
+ export declare function hqCommand(assetId: string, prompt: string): string;
17
27
  export declare function startEditorServer(options: EditorServerOptions): Promise<EditorServer>;
@@ -22,6 +22,11 @@ import { readProjectGameData } from '../forge/browser-host.js';
22
22
  import { projectWorldJsonPath } from '../forge/run-pipeline.js';
23
23
  import { renderEditorShell } from './shell-page.js';
24
24
  import { buildSceneModifications } from './save.js';
25
+ import { deriveSceneEvents, EditorJournal } from './journal.js';
26
+ import { findPropAsset, generateAndInstallProp } from '../generate/prop.js';
27
+ import { resolveEnvironment, resolveAuth0ClientId } from '../config/environments.js';
28
+ import { readDefaultEnvironment } from '../config/credentials.js';
29
+ import { getAccessToken } from '../auth/session.js';
25
30
  /** Bodies are a scene snapshot, not an upload — a megabyte is already generous. */
26
31
  const MAX_BODY_BYTES = 8 * 1024 * 1024;
27
32
  function readBody(req) {
@@ -62,6 +67,30 @@ function worldMtimeMs(worldPath) {
62
67
  return 0;
63
68
  }
64
69
  }
70
+ function isRecord(value) {
71
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
72
+ }
73
+ /**
74
+ * The command the agent should run to fulfil an HQ request. One definition, quoted for a shell,
75
+ * so the journal line, the HTTP reply and the editor's own confirmation cannot drift apart.
76
+ */
77
+ export function hqCommand(assetId, prompt) {
78
+ const quoted = prompt.replace(/"/g, '\\"');
79
+ return `bitmagic generate prop --asset ${assetId} --prompt "${quoted}" --json`;
80
+ }
81
+ /**
82
+ * Whether `bitmagic generate prop` could actually regenerate this asset. Answered by the command's
83
+ * own precondition (`findPropAsset`), so the two cannot disagree about what is regenerable.
84
+ */
85
+ function hasFitBox(worldPath, assetId) {
86
+ try {
87
+ findPropAsset(JSON.parse(fs.readFileSync(worldPath, 'utf-8')), assetId);
88
+ return true;
89
+ }
90
+ catch {
91
+ return false;
92
+ }
93
+ }
65
94
  function readWorld(worldPath) {
66
95
  const parsed = JSON.parse(fs.readFileSync(worldPath, 'utf-8'));
67
96
  if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
@@ -73,8 +102,61 @@ export async function startEditorServer(options) {
73
102
  const log = options.log ?? (() => { });
74
103
  const worldPath = projectWorldJsonPath(options.root);
75
104
  const shell = renderEditorShell({ gamePort: options.gamePort, gameId: options.gameId });
105
+ const journal = new EditorJournal({ root: options.root, log });
76
106
  /** The mtime our own last write produced. Anything else is an external edit. */
77
107
  let lastWrittenMtimeMs = worldMtimeMs(worldPath);
108
+ /**
109
+ * The generation in flight, or the last one to finish. One at a time: each job spins up its own
110
+ * vite and headless Chrome, and two at once on a creator's laptop would fight for both.
111
+ */
112
+ let hqJob = null;
113
+ /** A token, or null when nobody is logged in. Never starts a device-code flow. */
114
+ const resolveAuth = async () => {
115
+ const environment = resolveEnvironment({ storedDefault: readDefaultEnvironment() });
116
+ const token = await getAccessToken(environment, resolveAuth0ClientId(environment), { fetch: globalThis.fetch, sleep: (ms) => new Promise((r) => setTimeout(r, ms)) });
117
+ return { environment, token };
118
+ };
119
+ /**
120
+ * Run the generation in the background and narrate it to the journal.
121
+ *
122
+ * Deliberately not awaited by the request: it takes minutes, and an HTTP response held open that
123
+ * long would time out somewhere in between. The shell polls `/api/editor/hq-status` instead.
124
+ */
125
+ const startHqJob = (auth, assetId, assetName, prompt) => {
126
+ hqJob = { assetId, assetName, prompt, status: 'running', message: 'Generating the mesh…' };
127
+ journal.append({ event: 'hq.started', assetId, assetName, prompt });
128
+ void generateAndInstallProp({
129
+ context: { root: options.root, metadata: options.metadata },
130
+ environment: auth.environment,
131
+ token: auth.token,
132
+ assetId,
133
+ prompt,
134
+ log: (message) => {
135
+ log(`[editor] ${message}`);
136
+ if (hqJob?.status === 'running')
137
+ hqJob.message = message;
138
+ },
139
+ }).then((result) => {
140
+ lastWrittenMtimeMs = worldMtimeMs(worldPath);
141
+ hqJob = {
142
+ assetId, assetName, prompt, status: 'done',
143
+ message: `Upgraded — ${result.instanceCount} placed instance`
144
+ + `${result.instanceCount === 1 ? '' : 's'} now use the generated version.`,
145
+ };
146
+ journal.append({
147
+ event: 'hq.completed',
148
+ assetId,
149
+ assetName,
150
+ instanceCount: result.instanceCount,
151
+ glbUrl: result.glbUrl,
152
+ ...(result.assetUrl ? { assetUrl: result.assetUrl } : {}),
153
+ });
154
+ }).catch((error) => {
155
+ const message = error instanceof Error ? error.message : String(error);
156
+ hqJob = { assetId, assetName, prompt, status: 'failed', message };
157
+ journal.append({ event: 'hq.failed', assetId, assetName, error: message });
158
+ });
159
+ };
78
160
  const handleSave = async (req, res) => {
79
161
  let payload;
80
162
  try {
@@ -91,8 +173,13 @@ export async function startEditorServer(options) {
91
173
  return;
92
174
  }
93
175
  let modifications;
176
+ let events;
94
177
  try {
95
- modifications = buildSceneModifications(payload, readWorld(worldPath));
178
+ // One read serves both: the modification builder needs the levels registry, and the journal
179
+ // needs the pre-edit transforms to report what each object moved FROM.
180
+ const before = readWorld(worldPath);
181
+ modifications = buildSceneModifications(payload, before);
182
+ events = deriveSceneEvents(before, payload);
96
183
  }
97
184
  catch (error) {
98
185
  const message = error instanceof Error ? error.message : String(error);
@@ -107,8 +194,9 @@ export async function startEditorServer(options) {
107
194
  try {
108
195
  const outcome = applyModificationsToWorld(worldPath, modifications);
109
196
  lastWrittenMtimeMs = worldMtimeMs(worldPath);
110
- for (const line of outcome.summary)
111
- log(`[editor] ${line}`);
197
+ // Journalled AFTER the write lands, never before: an agent reading a `object.moved` line
198
+ // must be able to trust that world.json already says so.
199
+ journal.append(...events);
112
200
  sendJson(res, 200, {
113
201
  ok: true,
114
202
  applied: outcome.applied,
@@ -125,6 +213,115 @@ export async function startEditorServer(options) {
125
213
  sendJson(res, 422, { ok: false, error: message });
126
214
  }
127
215
  };
216
+ /**
217
+ * The "Generate high-quality version" button.
218
+ *
219
+ * The editor RUNS the generation. An earlier version only recorded the request and printed the
220
+ * command for the agent to run, on the theory that the agent is this lane's job runner — but
221
+ * nothing makes an agent notice a line appearing in a file, so in practice the human had to
222
+ * copy the command over to their agent themselves. That is worse than asking the agent directly,
223
+ * which makes the button pointless.
224
+ *
225
+ * The journal keeps its role, which was always the useful one: the agent LEARNS that a job ran,
226
+ * what it cost and what it changed, instead of finding an asset that mutated on its own. The
227
+ * hand-off path survives as the fallback for the one case the editor genuinely cannot run —
228
+ * nobody is logged in, since the mesh comes from an authenticated api-server route.
229
+ *
230
+ * The confirmed text is saved onto the asset before anything else. That mirrors the Creator, and
231
+ * for the same reason: a forger placeholder often carries no description at all, and the
232
+ * description the human just wrote is worth keeping whether or not a generation ever follows.
233
+ */
234
+ const handleHqRequest = async (req, res) => {
235
+ let body;
236
+ try {
237
+ body = JSON.parse(await readBody(req));
238
+ }
239
+ catch {
240
+ sendJson(res, 400, { ok: false, error: 'Request body must be JSON' });
241
+ return;
242
+ }
243
+ const { assetId, prompt } = body;
244
+ if (typeof assetId !== 'string' || typeof prompt !== 'string' || prompt.trim() === '') {
245
+ sendJson(res, 400, { ok: false, error: 'assetId and a non-empty prompt are required' });
246
+ return;
247
+ }
248
+ const assetName = typeof body.assetName === 'string' && body.assetName !== '' ? body.assetName : assetId;
249
+ const description = prompt.trim();
250
+ try {
251
+ applyModificationsToWorld(worldPath, [{
252
+ type: 'updateRoot',
253
+ path: ['assets'],
254
+ predicate: (item) => isRecord(item) && item.id === assetId,
255
+ // An updater, not a replacement: the asset carries fitBox, sourceGlbUrl and the rest, and
256
+ // the generation the agent runs later depends on every one of them.
257
+ value: (item) => ({ ...(isRecord(item) ? item : {}), description }),
258
+ }]);
259
+ lastWrittenMtimeMs = worldMtimeMs(worldPath);
260
+ }
261
+ catch (error) {
262
+ const message = error instanceof Error ? error.message : String(error);
263
+ log(`[editor] could not save the description for ${assetId}: ${message}`);
264
+ sendJson(res, 422, { ok: false, error: message });
265
+ return;
266
+ }
267
+ // Only forge-baked assets carry a fitBox, and without one there is no envelope to voxelize
268
+ // to — `bitmagic generate prop` refuses. The engine offers its button on any asset flagged
269
+ // `placeholder`, so that combination is reachable, and handing the agent a command that cannot
270
+ // succeed is worse than saying so. The description is kept either way: it is what the human
271
+ // meant this object to be, and the asset agent reads it.
272
+ const generatable = hasFitBox(worldPath, assetId);
273
+ if (!generatable) {
274
+ log(`[editor] ${assetName} has no fitBox — description saved, but it cannot be regenerated.`);
275
+ sendJson(res, 200, {
276
+ ok: true,
277
+ canGenerate: false,
278
+ reason: 'This asset has no fitBox, so there is no size to generate it to. '
279
+ + 'Only forge-baked assets can be regenerated.',
280
+ worldMtimeMs: lastWrittenMtimeMs,
281
+ });
282
+ return;
283
+ }
284
+ if (hqJob !== null && hqJob.status === 'running') {
285
+ sendJson(res, 200, {
286
+ ok: true,
287
+ canGenerate: true,
288
+ running: true,
289
+ note: `Already generating "${hqJob.assetName}" — one at a time.`,
290
+ });
291
+ return;
292
+ }
293
+ // A token is the one thing the editor cannot conjure: the mesh comes from an authenticated
294
+ // api-server route. `getAccessToken` throws rather than opening a browser, so a logged-out
295
+ // creator degrades to the hand-off instead of having a device-code flow started under them.
296
+ let auth = null;
297
+ try {
298
+ auth = await resolveAuth();
299
+ }
300
+ catch {
301
+ auth = null;
302
+ }
303
+ if (auth === null) {
304
+ journal.append({
305
+ event: 'hq.requested', assetId, assetName, prompt: description, command: hqCommand(assetId, description),
306
+ });
307
+ sendJson(res, 200, {
308
+ ok: true,
309
+ canGenerate: true,
310
+ running: false,
311
+ reason: 'You are not logged in, so the editor cannot generate this itself. '
312
+ + 'Run `bitmagic login`, or have your agent run:',
313
+ command: hqCommand(assetId, description),
314
+ worldMtimeMs: lastWrittenMtimeMs,
315
+ });
316
+ return;
317
+ }
318
+ startHqJob(auth, assetId, assetName, description);
319
+ sendJson(res, 200, { ok: true, canGenerate: true, running: true });
320
+ };
321
+ /** Poll target for the dialog while a generation runs. */
322
+ const handleHqStatus = (res) => {
323
+ sendJson(res, 200, { ok: true, job: hqJob, worldMtimeMs: lastWrittenMtimeMs });
324
+ };
128
325
  const server = http.createServer((req, res) => {
129
326
  void (async () => {
130
327
  writeCors(res);
@@ -165,6 +362,14 @@ export async function startEditorServer(options) {
165
362
  await handleSave(req, res);
166
363
  return;
167
364
  }
365
+ if (req.method === 'POST' && url === '/api/editor/hq-request') {
366
+ await handleHqRequest(req, res);
367
+ return;
368
+ }
369
+ if (req.method === 'GET' && url === '/api/editor/hq-status') {
370
+ handleHqStatus(res);
371
+ return;
372
+ }
168
373
  sendJson(res, 404, { ok: false, error: `No route for ${req.method ?? '?'} ${url}` });
169
374
  })();
170
375
  });
@@ -177,8 +382,16 @@ export async function startEditorServer(options) {
177
382
  });
178
383
  server.listen(options.port, '127.0.0.1', resolve);
179
384
  });
385
+ const url = `http://localhost:${options.port}/`;
386
+ journal.append({
387
+ event: 'session.started',
388
+ gameId: options.gameId,
389
+ gameUrl: `http://localhost:${options.gamePort}/`,
390
+ editorUrl: url,
391
+ });
180
392
  return {
181
- url: `http://localhost:${options.port}/`,
393
+ url,
394
+ journalPath: journal.path,
182
395
  close: () => new Promise((resolve) => server.close(() => resolve())),
183
396
  };
184
397
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/editor/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/editor/server.ts"],"names":[],"mappings":"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"}
@@ -70,6 +70,21 @@ export function renderEditorShell(options) {
70
70
  .banner.show { display: flex; }
71
71
  #terrain-banner { background: #3d1f1c; border-bottom-color: #6b2f28; color: #f3c3bd; }
72
72
  #frame { display: block; flex: 1; width: 100%; border: 0; min-height: 0; }
73
+ #hq-overlay { display: none; position: fixed; inset: 0; background: rgba(8,8,12,.72);
74
+ align-items: center; justify-content: center; z-index: 10; }
75
+ #hq-overlay.show { display: flex; }
76
+ #hq-dialog { width: min(560px, 92vw); background: #17171d; border: 1px solid #34343f;
77
+ border-radius: 8px; padding: 18px; }
78
+ #hq-dialog h2 { margin: 0 0 6px; font-size: 15px; }
79
+ #hq-dialog p { margin: 0 0 12px; color: #9a9aab; }
80
+ #hq-prompt { width: 100%; min-height: 88px; resize: vertical; padding: 8px; border-radius: 6px;
81
+ background: #101014; color: #e6e6ea; border: 1px solid #34343f; font: inherit; }
82
+ #hq-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 12px; }
83
+ #hq-confirm { background: #3352c4; border-color: #3f61d8; }
84
+ #hq-note { display: none; margin-top: 10px; padding: 10px; border-radius: 6px;
85
+ background: #101014; border: 1px solid #26262e; }
86
+ #hq-note.show { display: block; }
87
+ #hq-note code { display: block; margin-top: 6px; color: #9fd0a8; word-break: break-all; }
73
88
  </style>
74
89
  </head>
75
90
  <body>
@@ -91,6 +106,22 @@ export function renderEditorShell(options) {
91
106
  <button id="terrain-discard" type="button">Discard terrain edits</button>
92
107
  </div>
93
108
  <iframe id="frame" allow="autoplay; fullscreen; xr-spatial-tracking; clipboard-write"></iframe>
109
+ <div id="hq-overlay">
110
+ <div id="hq-dialog">
111
+ <h2>Generate a high-quality <span id="hq-name"></span></h2>
112
+ <p>Describe what this object should be. The text is saved as the asset's description and
113
+ used as the generation prompt.</p>
114
+ <textarea id="hq-prompt" placeholder="e.g. a weathered stone archway covered in moss"></textarea>
115
+ <div id="hq-actions">
116
+ <button id="hq-cancel" type="button">Close</button>
117
+ <button id="hq-confirm" type="button">Generate</button>
118
+ </div>
119
+ <div id="hq-note">
120
+ <span id="hq-note-text"></span>
121
+ <code id="hq-command"></code>
122
+ </div>
123
+ </div>
124
+ </div>
94
125
  <script>
95
126
  (function () {
96
127
  'use strict';
@@ -178,6 +209,10 @@ export function renderEditorShell(options) {
178
209
  markersDirty = true;
179
210
  break;
180
211
 
212
+ case 'GENERATE_HQ_ASSET':
213
+ openHqDialog(message.assetId, message.assetName);
214
+ break;
215
+
181
216
  // No other tabs exist here, and asset re-baking is a "bitmagic generate" concern.
182
217
  case 'SWITCH_TO_TAB':
183
218
  case 'OPEN_ASSET_ACTION':
@@ -185,6 +220,131 @@ export function renderEditorShell(options) {
185
220
  }
186
221
  });
187
222
 
223
+ /**
224
+ * The "Generate high-quality version" button in the engine's object inspector.
225
+ *
226
+ * The engine only announces the intent — the HOST owns the flow from here, in the web lane too.
227
+ * There, the Creator collects a description and POSTs a background job. Here the editor cannot
228
+ * generate anything (the Asset Forger credentials are server-side and never reach this machine),
229
+ * so it collects the same description, saves it onto the asset, and journals the request for the
230
+ * agent to run. A placeholder often carries no description at all, which is why the text is
231
+ * asked for rather than assumed.
232
+ */
233
+ var hqOverlay = document.getElementById('hq-overlay');
234
+ var hqNote = document.getElementById('hq-note');
235
+ var hqPrompt = document.getElementById('hq-prompt');
236
+ var hqAsset = null;
237
+
238
+ function closeHqDialog() {
239
+ hqOverlay.classList.remove('show');
240
+ hqNote.classList.remove('show');
241
+ hqAsset = null;
242
+ }
243
+
244
+ async function openHqDialog(assetId, assetName) {
245
+ if (!assetId) return;
246
+ hqAsset = { id: assetId, name: assetName || assetId };
247
+ document.getElementById('hq-name').textContent = hqAsset.name;
248
+ hqNote.classList.remove('show');
249
+ // Prefill from the description ON DISK rather than anything cached here: the record the save
250
+ // patches is the stored one, and the agent may have written a description since boot.
251
+ var existing = '';
252
+ try {
253
+ var project = await (await fetch('/api/game-data')).json();
254
+ var asset = ((project.gameData && project.gameData.assets) || [])
255
+ .filter(function (a) { return a && a.id === assetId; })[0];
256
+ if (asset && typeof asset.description === 'string') existing = asset.description;
257
+ } catch (error) {
258
+ // No description to prefill is a worse dialog, not a broken one.
259
+ }
260
+ hqPrompt.value = existing;
261
+ hqOverlay.classList.add('show');
262
+ hqPrompt.focus();
263
+ }
264
+
265
+ async function confirmHq() {
266
+ if (!hqAsset) return;
267
+ var prompt = hqPrompt.value.trim();
268
+ if (prompt === '') { hqPrompt.focus(); return; }
269
+ var response = await fetch('/api/editor/hq-request', {
270
+ method: 'POST',
271
+ headers: { 'Content-Type': 'application/json' },
272
+ body: JSON.stringify({ assetId: hqAsset.id, assetName: hqAsset.name, prompt: prompt })
273
+ });
274
+ var result = await response.json();
275
+ if (!response.ok || !result.ok) {
276
+ setStatus('error', result.error || 'Could not record the request');
277
+ closeHqDialog();
278
+ return;
279
+ }
280
+ lastKnownMtime = result.worldMtimeMs || lastKnownMtime;
281
+ hqNote.classList.add('show');
282
+
283
+ // The description is saved either way; only what happens next differs.
284
+ if (result.canGenerate === false) {
285
+ showHqNote('Description saved. ' + (result.reason || 'This asset cannot be regenerated.'), '');
286
+ setStatus('saved', 'Description saved');
287
+ return;
288
+ }
289
+ if (result.running !== true) {
290
+ // The one case the editor cannot run itself: nobody is logged in.
291
+ showHqNote('Description saved. ' + (result.reason || ''), result.command || '');
292
+ setStatus('saved', 'Description saved');
293
+ return;
294
+ }
295
+
296
+ showHqNote(result.note || 'Generating — this takes a few minutes. You can keep editing.', '');
297
+ setStatus('saving', 'Generating…');
298
+ pollHqJob();
299
+ }
300
+
301
+ function showHqNote(text, command) {
302
+ document.getElementById('hq-note-text').textContent = text;
303
+ document.getElementById('hq-command').textContent = command;
304
+ hqNote.classList.add('show');
305
+ }
306
+
307
+ /**
308
+ * Follow the running generation. The dialog can be closed and the job keeps going — it lives in
309
+ * the CLI process, not this page — so the status bar is the durable indicator and the note is
310
+ * only updated while the dialog happens to be open.
311
+ */
312
+ var hqPollTimer = null;
313
+ function pollHqJob() {
314
+ if (hqPollTimer) clearTimeout(hqPollTimer);
315
+ var tick = async function () {
316
+ var job;
317
+ try {
318
+ job = (await (await fetch('/api/editor/hq-status')).json()).job;
319
+ } catch (error) {
320
+ hqPollTimer = setTimeout(tick, 3000);
321
+ return;
322
+ }
323
+ if (!job) return;
324
+ if (job.status === 'running') {
325
+ showHqNote(job.message, '');
326
+ setStatus('saving', 'Generating…');
327
+ hqPollTimer = setTimeout(tick, 3000);
328
+ return;
329
+ }
330
+ if (job.status === 'failed') {
331
+ showHqNote('Generation failed: ' + job.message, '');
332
+ setStatus('error', 'Generation failed');
333
+ return;
334
+ }
335
+ showHqNote(job.message + ' Reload to see it in the scene.', '');
336
+ setStatus('saved', 'Generated');
337
+ // The asset changed under the running engine, so the open scene is showing the old mesh.
338
+ banner.classList.add('show');
339
+ };
340
+ void tick();
341
+ }
342
+
343
+ document.getElementById('hq-cancel').addEventListener('click', closeHqDialog);
344
+ document.getElementById('hq-confirm').addEventListener('click', function () {
345
+ void confirmHq();
346
+ });
347
+
188
348
  async function boot(gen) {
189
349
  loaded = false;
190
350
  markersDirty = false;
@@ -1 +1 @@
1
- {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,oGAAoG;AACpG,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,kGAAkG;AAClG,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AASD,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,MAAM,OAAO,GAAG,oBAAoB,OAAO,CAAC,QAAQ,2BAA2B,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACpH,OAAO;;;;yBAIgB,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA8B5B,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;mBAmB9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;kBACxB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+OjC,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"shell-page.js","sourceRoot":"","sources":["../../src/editor/shell-page.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,oGAAoG;AACpG,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAE7B,kGAAkG;AAClG,SAAS,UAAU,CAAC,KAAa;IAC/B,OAAO,KAAK;SACT,OAAO,CAAC,IAAI,EAAE,OAAO,CAAC;SACtB,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;SACvB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC3B,CAAC;AASD,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,MAAM,OAAO,GAAG,oBAAoB,OAAO,CAAC,QAAQ,2BAA2B,kBAAkB,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;IACpH,OAAO;;;;yBAIgB,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBA6C5B,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBAmC9B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;kBACxB,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgXjC,CAAC;AACF,CAAC"}
@@ -0,0 +1,69 @@
1
+ import type { Environment } from '../config/environments.js';
2
+ import type { ProjectContext } from '../project/context.js';
3
+ interface FitBox {
4
+ x: number;
5
+ z: number;
6
+ height: number;
7
+ }
8
+ export interface PropVoxelizeOptions {
9
+ context: ProjectContext;
10
+ environment: Environment;
11
+ token: string;
12
+ assetId: string;
13
+ prompt: string;
14
+ glbUrl: string;
15
+ log: (message: string) => void;
16
+ }
17
+ export interface GenerateAndInstallOptions {
18
+ context: ProjectContext;
19
+ environment: Environment;
20
+ token: string;
21
+ assetId: string;
22
+ prompt: string;
23
+ /** Skip the paid generation and voxelize this mesh instead — how a failed run is retried. */
24
+ glbUrl?: string;
25
+ fetchImpl?: typeof globalThis.fetch;
26
+ log: (message: string) => void;
27
+ }
28
+ export interface PropVoxelizeResult {
29
+ assetId: string;
30
+ assetName: string;
31
+ assetUrl?: string;
32
+ /** How many placed instances now point at the upgraded asset. */
33
+ instanceCount: number;
34
+ }
35
+ /**
36
+ * The asset this command upgrades, with the `fitBox` the bake has to be constrained to.
37
+ *
38
+ * A missing `fitBox` is refused rather than defaulted. It records the size the object occupied
39
+ * when the level was baked, and every instance was placed against it — voxelizing to a different
40
+ * envelope produces an asset that is the wrong size everywhere it already sits, which nothing
41
+ * downstream would flag.
42
+ */
43
+ export declare function findPropAsset(world: Record<string, unknown>, assetId: string): {
44
+ asset: Record<string, unknown>;
45
+ fitBox: FitBox;
46
+ };
47
+ /**
48
+ * Building-scale boxes voxelize hollow (a closed shell); prop-scale fills solid. Same thresholds
49
+ * as the HQ job — a solid-filled building is millions of wasted voxels, and a hollow prop reads as
50
+ * a shell the moment anything clips into it.
51
+ */
52
+ export declare function shouldFillInterior(fitBox: FitBox): boolean;
53
+ /**
54
+ * All three steps, for the two callers that want the whole job: `bitmagic generate prop` and the
55
+ * editor's "Generate high-quality version" button. Shared rather than duplicated — the editor
56
+ * running a materially different flow from the command it also prints would be a trap.
57
+ *
58
+ * Everything the caller must resolve first (project, environment, token) is a parameter, so this
59
+ * stays free of CLI output plumbing and of how the token was obtained.
60
+ */
61
+ export declare function generateAndInstallProp(options: GenerateAndInstallOptions): Promise<PropVoxelizeResult & {
62
+ glbUrl: string;
63
+ }>;
64
+ /**
65
+ * Steps 2 and 3. Split from the command so the browser work is callable directly on a retry that
66
+ * already has a GLB, and so the command file stays about flags and output.
67
+ */
68
+ export declare function voxelizeAndInstall(options: PropVoxelizeOptions): Promise<PropVoxelizeResult>;
69
+ export {};