@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.
- package/README.md +32 -1
- package/dist/commands/edit.js +6 -0
- package/dist/commands/edit.js.map +1 -1
- package/dist/commands/generate.d.ts +15 -0
- package/dist/commands/generate.js +72 -0
- package/dist/commands/generate.js.map +1 -1
- package/dist/editor/journal.d.ts +134 -0
- package/dist/editor/journal.js +220 -0
- package/dist/editor/journal.js.map +1 -0
- package/dist/editor/server.d.ts +10 -0
- package/dist/editor/server.js +217 -4
- package/dist/editor/server.js.map +1 -1
- package/dist/editor/shell-page.js +160 -0
- package/dist/editor/shell-page.js.map +1 -1
- package/dist/generate/prop.d.ts +69 -0
- package/dist/generate/prop.js +240 -0
- package/dist/generate/prop.js.map +1 -0
- package/dist/generate/stream.d.ts +6 -0
- package/dist/generate/stream.js +7 -2
- package/dist/generate/stream.js.map +1 -1
- package/dist/scaffold/project-files.js +35 -1
- package/dist/scaffold/project-files.js.map +1 -1
- package/package.json +3 -3
package/dist/editor/server.d.ts
CHANGED
|
@@ -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>;
|
package/dist/editor/server.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
111
|
-
|
|
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
|
|
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":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,yBAAyB,EAAE,MAAM,iCAAiC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,uBAAuB,EAAqB,MAAM,WAAW,CAAC;AAoBvE,mFAAmF;AACnF,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAC;AAEvC,SAAS,QAAQ,CAAC,GAAyB;IACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,IAAI,IAAI,GAAG,EAAE,CAAC;QACd,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC;YACtB,IAAI,IAAI,CAAC,MAAM,GAAG,cAAc,EAAE,CAAC;gBACjC,MAAM,CAAC,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC,CAAC;gBAC5C,GAAG,CAAC,OAAO,EAAE,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,GAAG,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACnC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,SAAS,CAAC,GAAwB;IACzC,GAAG,CAAC,SAAS,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAC;IAClD,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,oBAAoB,CAAC,CAAC;IACpE,GAAG,CAAC,SAAS,CAAC,8BAA8B,EAAE,cAAc,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,QAAQ,CAAC,GAAwB,EAAE,MAAc,EAAE,IAAa;IACvE,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC;AAC1F,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,YAAY,CAAC,SAAiB;IACrC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,SAAiB;IAClC,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IACxE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3E,MAAM,IAAI,QAAQ,CAAC,GAAG,SAAS,mCAAmC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,MAAwB,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAA4B;IAClE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,GAAS,EAAE,GAAE,CAAC,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,oBAAoB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,MAAM,KAAK,GAAG,iBAAiB,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAExF,gFAAgF;IAChF,IAAI,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAEjD,MAAM,UAAU,GAAG,KAAK,EAAE,GAAyB,EAAE,GAAwB,EAAiB,EAAE;QAC9F,IAAI,OAAqB,CAAC;QAC1B,IAAI,CAAC;YACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,GAAG,CAAC,CAAiB,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2BAA2B,EAAE,CAAC,CAAC;YACtE,OAAO;QACT,CAAC;QACD,IAAI,OAAO,EAAE,MAAM,EAAE,QAAQ,KAAK,IAAI,EAAE,CAAC;YACvC,wFAAwF;YACxF,wCAAwC;YACxC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,yBAAyB,EAAE,CAAC,CAAC;YACjF,OAAO;QACT,CAAC;QAED,IAAI,aAAa,CAAC;QAClB,IAAI,CAAC;YACH,aAAa,GAAG,uBAAuB,CAAC,OAAO,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC;QACzE,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,GAAG,CAAC,2BAA2B,SAAS,KAAK,OAAO,EAAE,CAAC,CAAC;YACxD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAClD,OAAO;QACT,CAAC;QACD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,EAAE,YAAY,EAAE,kBAAkB,EAAE,CAAC,CAAC;YAC/E,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,yBAAyB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;YACpE,kBAAkB,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;YAC7C,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,OAAO;gBAAE,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;YAC5D,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;gBACjB,EAAE,EAAE,IAAI;gBACR,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,OAAO,EAAE,OAAO,CAAC,OAAO;gBACxB,YAAY,EAAE,kBAAkB;aACjC,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,uFAAuF;YACvF,2FAA2F;YAC3F,2EAA2E;YAC3E,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,GAAG,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;YACzC,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC;IAEF,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;QAC5C,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,SAAS,CAAC,GAAG,CAAC,CAAC;YACf,IAAI,GAAG,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC7B,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,CAAC;gBACzB,OAAO;YACT,CAAC;YACD,MAAM,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YAE3C,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,CAAC,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,aAAa,CAAC,EAAE,CAAC;gBACnE,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;gBAC9E,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;gBACrD,IAAI,CAAC;oBACH,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;wBACjB,MAAM,EAAE,OAAO,CAAC,MAAM;wBACtB,qEAAqE;wBACrE,oFAAoF;wBACpF,4BAA4B;wBAC5B,QAAQ,EAAE,mBAAmB,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;wBACvE,YAAY,EAAE,YAAY,CAAC,SAAS,CAAC;qBACtC,CAAC,CAAC;gBACL,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;oBACvE,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;gBACpD,CAAC;gBACD,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,KAAK,KAAK,IAAI,GAAG,KAAK,YAAY,EAAE,CAAC;gBACjD,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE;oBACjB,YAAY,EAAE,YAAY,CAAC,SAAS,CAAC;oBACrC,kBAAkB;iBACnB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,KAAK,MAAM,IAAI,GAAG,KAAK,iBAAiB,EAAE,CAAC;gBACvD,MAAM,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBAC3B,OAAO;YACT,CAAC;YAED,QAAQ,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,gBAAgB,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAE,EAAE,CAAC,CAAC;QACvF,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;IAEH,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAgC,EAAE,EAAE;YACxD,MAAM,CACJ,KAAK,CAAC,IAAI,KAAK,YAAY;gBACzB,CAAC,CAAC,IAAI,QAAQ,CACV,QAAQ,OAAO,CAAC,IAAI,kDAAkD;sBACpE,qDAAqD,CACxD;gBACH,CAAC,CAAC,IAAI,QAAQ,CAAC,sCAAsC,KAAK,CAAC,OAAO,EAAE,CAAC,CACxE,CAAC;QACJ,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,GAAG,EAAE,oBAAoB,OAAO,CAAC,IAAI,GAAG;QACxC,KAAK,EAAE,GAAG,EAAE,CAAC,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;KAC3E,CAAC;AACJ,CAAC"}
|
|
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
|
|
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 {};
|