@bitmagic/cli 0.1.54 → 0.1.55-dev.1
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 +43 -2
- package/dist/cli.d.ts +23 -1
- package/dist/cli.js +4 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/cover.d.ts +13 -2
- package/dist/commands/cover.js +21 -7
- package/dist/commands/cover.js.map +1 -1
- package/dist/commands/forge.d.ts +14 -0
- package/dist/commands/forge.js +41 -3
- package/dist/commands/forge.js.map +1 -1
- package/dist/commands/generate.d.ts +12 -0
- package/dist/commands/generate.js +77 -24
- package/dist/commands/generate.js.map +1 -1
- package/dist/commands/init.js +4 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/ios.d.ts +2 -0
- package/dist/commands/ios.js +333 -0
- package/dist/commands/ios.js.map +1 -0
- package/dist/commands/reference.d.ts +41 -0
- package/dist/commands/reference.js +398 -0
- package/dist/commands/reference.js.map +1 -0
- package/dist/generate/stream.d.ts +6 -0
- package/dist/generate/stream.js +2 -1
- package/dist/generate/stream.js.map +1 -1
- package/dist/ios/app-config.d.ts +54 -0
- package/dist/ios/app-config.js +109 -0
- package/dist/ios/app-config.js.map +1 -0
- package/dist/ios/collect-urls.d.ts +73 -0
- package/dist/ios/collect-urls.js +230 -0
- package/dist/ios/collect-urls.js.map +1 -0
- package/dist/ios/icon.d.ts +12 -0
- package/dist/ios/icon.js +70 -0
- package/dist/ios/icon.js.map +1 -0
- package/dist/ios/local-server.d.ts +11 -0
- package/dist/ios/local-server.js +88 -0
- package/dist/ios/local-server.js.map +1 -0
- package/dist/ios/paths.d.ts +21 -0
- package/dist/ios/paths.js +23 -0
- package/dist/ios/paths.js.map +1 -0
- package/dist/ios/record-validate.d.ts +25 -0
- package/dist/ios/record-validate.js +98 -0
- package/dist/ios/record-validate.js.map +1 -0
- package/dist/ios/transform.d.ts +47 -0
- package/dist/ios/transform.js +67 -0
- package/dist/ios/transform.js.map +1 -0
- package/dist/ios/vendor.d.ts +29 -0
- package/dist/ios/vendor.js +113 -0
- package/dist/ios/vendor.js.map +1 -0
- package/dist/ios/xcode-template.d.ts +11 -0
- package/dist/ios/xcode-template.js +615 -0
- package/dist/ios/xcode-template.js.map +1 -0
- package/dist/ios/xcodebuild.d.ts +71 -0
- package/dist/ios/xcodebuild.js +216 -0
- package/dist/ios/xcodebuild.js.map +1 -0
- package/dist/project/jobs.d.ts +1 -1
- package/dist/project/reference-file.d.ts +44 -0
- package/dist/project/reference-file.js +94 -0
- package/dist/project/reference-file.js.map +1 -0
- package/dist/project/reference.d.ts +78 -0
- package/dist/project/reference.js +175 -0
- package/dist/project/reference.js.map +1 -0
- package/dist/scaffold/project-files.js +19 -16
- package/dist/scaffold/project-files.js.map +1 -1
- package/dist/scaffold/reference-guidance.d.ts +20 -0
- package/dist/scaffold/reference-guidance.js +79 -0
- package/dist/scaffold/reference-guidance.js.map +1 -0
- package/dist/verify/browser.d.ts +8 -0
- package/dist/verify/browser.js +2 -0
- package/dist/verify/browser.js.map +1 -1
- package/package.json +4 -4
|
@@ -0,0 +1,398 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `bitmagic reference` — the concept image of the game's world the creator iterates on, and the
|
|
3
|
+
* accept that makes one picture the visual reference every later generation inherits.
|
|
4
|
+
*
|
|
5
|
+
* The loop this command exists for: the creator's agent proposes a picture (`make`), the CREATOR
|
|
6
|
+
* looks at it and decides — iterate (`make --from <id>`), or accept (`accept <id>`). From then on
|
|
7
|
+
* `generate skybox|background|block-type|image`, `bitmagic cover` and `bitmagic forge` all use the
|
|
8
|
+
* accepted image as their reference by default (see project/reference.ts), which is what keeps a
|
|
9
|
+
* game's sky, blocks, cover and forged levels looking like the same place.
|
|
10
|
+
*
|
|
11
|
+
* Candidates deliberately touch NOTHING: no world.json entry, no upload, no billing beyond the
|
|
12
|
+
* one image call. Only `accept` has consequences, and its first act is to re-host the picture to
|
|
13
|
+
* the game's own bucket — Asset Forger URLs are not contractually long-lived, and the accepted
|
|
14
|
+
* reference must outlive them (the same reason cover variants are re-hosted in the web lane).
|
|
15
|
+
*
|
|
16
|
+
* Built on the `generate image` lane's plumbing (`requestAssetWithJobRecord`) exactly as
|
|
17
|
+
* `bitmagic cover` is, so ownership, spark billing, the SSE keepalive and the server-side
|
|
18
|
+
* deadline all behave identically — but through the `reference` wire type, whose whole result is
|
|
19
|
+
* a URL on the terminal frame rather than a world.json patch.
|
|
20
|
+
*/
|
|
21
|
+
import { defineCommand } from 'citty';
|
|
22
|
+
import { Buffer } from 'buffer';
|
|
23
|
+
import { createHash } from 'crypto';
|
|
24
|
+
import * as fs from 'fs';
|
|
25
|
+
import * as path from 'path';
|
|
26
|
+
import { buildReferenceImagePrompt } from '@bitmagic/asset-core';
|
|
27
|
+
import { CliError } from '../errors.js';
|
|
28
|
+
import { loadProjectContext } from '../project/context.js';
|
|
29
|
+
import { acceptedReferencePath, candidateImagePath, isSafeCandidateId, listCandidates, newCandidateId, readAcceptedReference, readCandidate, clearAcceptedReference, writeAcceptedReference, writeCandidate, } from '../project/reference.js';
|
|
30
|
+
import { resolveEnvironmentForCommand, resolveAuth0ClientId } from '../config/environments.js';
|
|
31
|
+
import { getAccessToken } from '../auth/session.js';
|
|
32
|
+
import { uploadProjectFile } from '../http/signed-upload.js';
|
|
33
|
+
import { requestAssetWithJobRecord } from './generate.js';
|
|
34
|
+
import { creatorPromptField, ORIGINAL_PROMPT_FLAG } from '../telemetry/creator-prompt.js';
|
|
35
|
+
import { renderInlineImage } from '../render/inline-image.js';
|
|
36
|
+
import { createOutput } from '../output.js';
|
|
37
|
+
import { commandRunDeps } from './run-deps.js';
|
|
38
|
+
import { GAME_DESIGN_FILE } from './cover.js';
|
|
39
|
+
import { REFERENCE_FILE_FLAG, REFERENCE_IMAGE_FLAG } from '../project/reference.js';
|
|
40
|
+
import { sniffImageContentType, uploadReferenceImageFile } from '../project/reference-file.js';
|
|
41
|
+
/** How much of the composed prompt the candidate record keeps — enough to recognise it in a list. */
|
|
42
|
+
const RECORD_PROMPT_CHARS = 300;
|
|
43
|
+
const JSON_FLAG = {
|
|
44
|
+
type: 'boolean',
|
|
45
|
+
description: 'Print the result as JSON on stdout; all progress goes to stderr.',
|
|
46
|
+
};
|
|
47
|
+
function defaultDeps(json) {
|
|
48
|
+
const output = createOutput(json);
|
|
49
|
+
return {
|
|
50
|
+
...commandRunDeps(json),
|
|
51
|
+
result: output.result,
|
|
52
|
+
generate: (type, label, body, deps) => requestAssetWithJobRecord(type, label, body, deps, (outcome) => outcome),
|
|
53
|
+
renderImage: (bytes) => renderInlineImage(bytes),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Shared helpers
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* The prose the picture is drawn from: `--prompt` when given, otherwise GAME-DESIGN.md. The same
|
|
61
|
+
* source `bitmagic cover` reads, because the two pictures describe the same game — but the error
|
|
62
|
+
* paths name THIS command, since "write the design or pass --prompt" must say which command to
|
|
63
|
+
* re-run.
|
|
64
|
+
*/
|
|
65
|
+
export function resolveReferenceDesignText(options) {
|
|
66
|
+
const flag = options.promptFlag?.trim();
|
|
67
|
+
if (flag)
|
|
68
|
+
return flag;
|
|
69
|
+
const designPath = path.join(options.root, GAME_DESIGN_FILE);
|
|
70
|
+
let contents;
|
|
71
|
+
try {
|
|
72
|
+
contents = fs.readFileSync(designPath, 'utf-8');
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
throw new CliError(`No ${GAME_DESIGN_FILE} at ${designPath}, and no --prompt given. A reference image is drawn ` +
|
|
76
|
+
'from the game design, so there must be one or the other.\n' +
|
|
77
|
+
`Write ${GAME_DESIGN_FILE} describing the world and its look, then run \`bitmagic reference ` +
|
|
78
|
+
'make` again — or describe the world directly with `bitmagic reference make --prompt "..."`.');
|
|
79
|
+
}
|
|
80
|
+
if (!contents.trim()) {
|
|
81
|
+
throw new CliError(`${designPath} is empty. Describe the game's world and look there, or pass ` +
|
|
82
|
+
'`bitmagic reference make --prompt "..."`.');
|
|
83
|
+
}
|
|
84
|
+
return contents;
|
|
85
|
+
}
|
|
86
|
+
/** Best-effort download of a generated candidate, exactly `saveCoverImage`'s contract. */
|
|
87
|
+
async function downloadImage(url, deps) {
|
|
88
|
+
try {
|
|
89
|
+
const response = await deps.fetch(url);
|
|
90
|
+
if (!response.ok) {
|
|
91
|
+
deps.log(` could not download the image for a local copy (HTTP ${response.status}).`);
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
return Buffer.from(await response.arrayBuffer());
|
|
95
|
+
}
|
|
96
|
+
catch (error) {
|
|
97
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
98
|
+
deps.log(` could not download the image for a local copy: ${message}`);
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
function saveCandidateBytes(root, id, bytes) {
|
|
103
|
+
const file = candidateImagePath(root, id);
|
|
104
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
105
|
+
fs.writeFileSync(file, bytes);
|
|
106
|
+
return path.relative(root, file);
|
|
107
|
+
}
|
|
108
|
+
/** The three formats the platform round-trips; anything else uploads as webp and still displays. */
|
|
109
|
+
function sniffContentType(bytes) {
|
|
110
|
+
return sniffImageContentType(bytes)?.contentType ?? 'image/webp';
|
|
111
|
+
}
|
|
112
|
+
export async function runReferenceMake(args, deps = defaultDeps(args.json === true)) {
|
|
113
|
+
const context = loadProjectContext(deps.startDir);
|
|
114
|
+
const root = context.root;
|
|
115
|
+
const designText = resolveReferenceDesignText({ promptFlag: args.prompt, root });
|
|
116
|
+
// What the image model iterates FROM. Any two of --from, --reference-image-url and
|
|
117
|
+
// --reference-image together would be two answers to the same question, so a pair is refused
|
|
118
|
+
// rather than ranked. The accepted project reference is deliberately NOT a default here —
|
|
119
|
+
// `make` explores; only these flags say "stay close to this picture".
|
|
120
|
+
const explicitUrl = args['reference-image-url'];
|
|
121
|
+
const filePath = args['reference-image']?.trim();
|
|
122
|
+
const fromId = args.from?.trim();
|
|
123
|
+
const named = [
|
|
124
|
+
fromId ? '--from' : null,
|
|
125
|
+
explicitUrl !== undefined ? '--reference-image-url' : null,
|
|
126
|
+
filePath ? '--reference-image' : null,
|
|
127
|
+
].filter((flag) => flag !== null);
|
|
128
|
+
if (named.length > 1) {
|
|
129
|
+
throw new CliError(`${named.join(' and ')} both name an image to iterate from — pass one of them.`);
|
|
130
|
+
}
|
|
131
|
+
let from = null;
|
|
132
|
+
if (fromId) {
|
|
133
|
+
from = readCandidate(root, fromId);
|
|
134
|
+
if (!from) {
|
|
135
|
+
throw new CliError(`No reference candidate "${fromId}" in this project. \`bitmagic reference show\` lists the ones that exist.`);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
let uploadedUrl;
|
|
139
|
+
if (filePath) {
|
|
140
|
+
uploadedUrl = (await uploadReferenceImageFile({ root, gameId: context.metadata.gameId, filePath, deps })).url;
|
|
141
|
+
deps.log(`Uploaded ${filePath} as the image to iterate from: ${uploadedUrl}`);
|
|
142
|
+
}
|
|
143
|
+
const referenceImageUrl = explicitUrl ?? uploadedUrl ?? from?.url;
|
|
144
|
+
const prompt = buildReferenceImagePrompt(designText);
|
|
145
|
+
const body = {
|
|
146
|
+
prompt,
|
|
147
|
+
...(referenceImageUrl !== undefined ? { referenceImageUrl } : {}),
|
|
148
|
+
...creatorPromptField(),
|
|
149
|
+
};
|
|
150
|
+
const outcome = await deps.generate('reference', 'reference image', body, deps);
|
|
151
|
+
const url = outcome.imageUrl;
|
|
152
|
+
if (url === undefined) {
|
|
153
|
+
throw new CliError('The reference image was generated, but the response carried no image URL, so there is ' +
|
|
154
|
+
'nothing to save or accept. Re-run `bitmagic reference make`; if it happens again, report it.');
|
|
155
|
+
}
|
|
156
|
+
const id = newCandidateId();
|
|
157
|
+
const bytes = await downloadImage(url, deps);
|
|
158
|
+
const imagePath = bytes ? saveCandidateBytes(root, id, bytes) : null;
|
|
159
|
+
writeCandidate(root, {
|
|
160
|
+
id,
|
|
161
|
+
url,
|
|
162
|
+
prompt: prompt.slice(0, RECORD_PROMPT_CHARS),
|
|
163
|
+
createdAt: new Date().toISOString(),
|
|
164
|
+
...(from ? { from: from.id } : {}),
|
|
165
|
+
...(explicitUrl !== undefined || uploadedUrl !== undefined
|
|
166
|
+
? { referenceImageUrl: explicitUrl ?? uploadedUrl }
|
|
167
|
+
: {}),
|
|
168
|
+
});
|
|
169
|
+
deps.log(`Reference candidate ${id}: ${imagePath ?? '(no local copy)'}`);
|
|
170
|
+
deps.log(` ${url}`);
|
|
171
|
+
// Plain lines first, always: they are what an agent reads, and the image is strictly extra.
|
|
172
|
+
if (bytes)
|
|
173
|
+
deps.renderImage(bytes);
|
|
174
|
+
deps.log(`Happy with it? bitmagic reference accept ${id}`);
|
|
175
|
+
deps.log(`Not quite? bitmagic reference make --from ${id} --prompt "what to change"`);
|
|
176
|
+
deps.result({ ok: true, id, url, imagePath, from: from?.id ?? null });
|
|
177
|
+
}
|
|
178
|
+
async function resolveAcceptSource(root, raw, deps) {
|
|
179
|
+
const value = raw.trim();
|
|
180
|
+
if (isSafeCandidateId(value)) {
|
|
181
|
+
const candidate = readCandidate(root, value);
|
|
182
|
+
if (candidate) {
|
|
183
|
+
let bytes = null;
|
|
184
|
+
try {
|
|
185
|
+
bytes = fs.readFileSync(candidateImagePath(root, value));
|
|
186
|
+
}
|
|
187
|
+
catch {
|
|
188
|
+
bytes = await downloadImage(candidate.url, deps);
|
|
189
|
+
}
|
|
190
|
+
return { id: value, sourceUrl: candidate.url, candidateId: value, bytes, mustHost: false };
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
if (/^https?:\/\//.test(value)) {
|
|
194
|
+
// The re-accept path: a fresh clone holding only the URL from GAME-DESIGN.md.
|
|
195
|
+
const id = `ref-url-${createHash('sha256').update(value).digest('hex').slice(0, 8)}`;
|
|
196
|
+
return { id, sourceUrl: value, bytes: await downloadImage(value, deps), mustHost: false };
|
|
197
|
+
}
|
|
198
|
+
// The creator's own picture — "use this image as the game's reference". Checked after the
|
|
199
|
+
// candidate ids so an id can never be shadowed by a file of the same name.
|
|
200
|
+
if (fs.existsSync(value)) {
|
|
201
|
+
let bytes;
|
|
202
|
+
try {
|
|
203
|
+
bytes = fs.readFileSync(value);
|
|
204
|
+
}
|
|
205
|
+
catch (error) {
|
|
206
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
207
|
+
throw new CliError(`Could not read ${value}: ${message}`);
|
|
208
|
+
}
|
|
209
|
+
if (!sniffImageContentType(bytes)) {
|
|
210
|
+
throw new CliError(`${value} is not a PNG, JPEG or WebP image — those are the formats the generators accept as a reference.`);
|
|
211
|
+
}
|
|
212
|
+
const id = `ref-file-${createHash('sha256').update(bytes).digest('hex').slice(0, 8)}`;
|
|
213
|
+
return { id, sourceUrl: value, bytes, mustHost: true };
|
|
214
|
+
}
|
|
215
|
+
throw new CliError(`"${value}" is not a reference candidate in this project, a URL, or a file that exists. ` +
|
|
216
|
+
'`bitmagic reference show` lists the candidates; an image of your own is accepted by its ' +
|
|
217
|
+
'file path or https URL.');
|
|
218
|
+
}
|
|
219
|
+
export async function runReferenceAccept(args, deps = defaultDeps(args.json === true)) {
|
|
220
|
+
const context = loadProjectContext(deps.startDir);
|
|
221
|
+
const root = context.root;
|
|
222
|
+
const source = await resolveAcceptSource(root, args.candidate, deps);
|
|
223
|
+
// Re-host to the game's own bucket, so the accepted reference outlives the Asset Forger URL it
|
|
224
|
+
// came from. Failure records the source URL instead (`hosted: false`) rather than failing the
|
|
225
|
+
// accept: the creator's decision stands either way, and a re-accept later retries the upload.
|
|
226
|
+
let url = source.sourceUrl;
|
|
227
|
+
let hosted = false;
|
|
228
|
+
if (source.bytes) {
|
|
229
|
+
try {
|
|
230
|
+
const environment = resolveEnvironmentForCommand({ cwd: root, baseDir: deps.baseDir });
|
|
231
|
+
const clientId = resolveAuth0ClientId(environment);
|
|
232
|
+
const token = await getAccessToken(environment, clientId, { fetch: deps.fetch, sleep: deps.sleep, now: deps.now }, deps.baseDir);
|
|
233
|
+
const contentType = sniffContentType(source.bytes);
|
|
234
|
+
const upload = await uploadProjectFile(environment, token, {
|
|
235
|
+
gameId: context.metadata.gameId,
|
|
236
|
+
filename: `reference-${source.id}.${contentType === 'image/png' ? 'png' : contentType === 'image/jpeg' ? 'jpg' : 'webp'}`,
|
|
237
|
+
contentType,
|
|
238
|
+
bytes: source.bytes,
|
|
239
|
+
}, { fetch: deps.fetch });
|
|
240
|
+
url = upload.url;
|
|
241
|
+
hosted = true;
|
|
242
|
+
}
|
|
243
|
+
catch (error) {
|
|
244
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
245
|
+
if (source.mustHost) {
|
|
246
|
+
// A local file has no URL to fall back to — recording its path would hand the
|
|
247
|
+
// generators an address none of them can fetch.
|
|
248
|
+
throw new CliError(`Could not upload ${args.candidate} to the game's storage (${message}), and a local file ` +
|
|
249
|
+
'is only usable as a reference once hosted. Fix that and re-run the accept.');
|
|
250
|
+
}
|
|
251
|
+
deps.log(` Could not re-host the image (${message}); recording its current URL instead, which may expire.`);
|
|
252
|
+
deps.log(` Re-run \`bitmagic reference accept ${args.candidate}\` later to retry.`);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
deps.log(' No image bytes to re-host; recording the URL as-is — it may expire.');
|
|
257
|
+
}
|
|
258
|
+
// Keep a local copy under the candidate id, so `show` can draw it and a later accept can retry
|
|
259
|
+
// the upload without a download.
|
|
260
|
+
const imagePath = source.bytes ? saveCandidateBytes(root, source.id, source.bytes) : undefined;
|
|
261
|
+
const accepted = {
|
|
262
|
+
url,
|
|
263
|
+
hosted,
|
|
264
|
+
sourceUrl: source.sourceUrl,
|
|
265
|
+
acceptedAt: new Date().toISOString(),
|
|
266
|
+
...(source.candidateId !== undefined ? { candidateId: source.candidateId } : {}),
|
|
267
|
+
...(imagePath !== undefined ? { imagePath } : {}),
|
|
268
|
+
};
|
|
269
|
+
writeAcceptedReference(root, accepted);
|
|
270
|
+
deps.log(`Accepted ${source.candidateId ?? source.sourceUrl} as the project's reference image.`);
|
|
271
|
+
deps.log(` ${url}`);
|
|
272
|
+
deps.log('This is now the default reference for `generate skybox|background|block-type|image`, ' +
|
|
273
|
+
'`bitmagic cover` and `bitmagic forge`. Pass --no-reference to skip it for one call; ' +
|
|
274
|
+
'`bitmagic reference clear` removes it.');
|
|
275
|
+
deps.log("Paste the URL above into GAME-DESIGN.md's world/look section — `.bitmagic/` is not committed, " +
|
|
276
|
+
'and that line is how a fresh clone re-accepts the same image (`bitmagic reference accept <url>`).');
|
|
277
|
+
deps.result({ ok: true, url, hosted, candidateId: source.candidateId ?? null, imagePath: imagePath ?? null });
|
|
278
|
+
}
|
|
279
|
+
export async function runReferenceShow(args, deps = defaultDeps(args.json === true)) {
|
|
280
|
+
const context = loadProjectContext(deps.startDir);
|
|
281
|
+
const root = context.root;
|
|
282
|
+
const accepted = readAcceptedReference(root);
|
|
283
|
+
const candidates = listCandidates(root);
|
|
284
|
+
if (accepted) {
|
|
285
|
+
deps.log(`Accepted reference${accepted.candidateId ? ` (${accepted.candidateId})` : ''}, ${accepted.acceptedAt}:`);
|
|
286
|
+
deps.log(` ${accepted.url}`);
|
|
287
|
+
if (!accepted.hosted) {
|
|
288
|
+
deps.log(' Not re-hosted yet — this URL may expire. Re-run `bitmagic reference accept` to retry the upload.');
|
|
289
|
+
}
|
|
290
|
+
if (accepted.imagePath) {
|
|
291
|
+
deps.log(` ${accepted.imagePath}`);
|
|
292
|
+
try {
|
|
293
|
+
deps.renderImage(fs.readFileSync(path.join(root, accepted.imagePath)));
|
|
294
|
+
}
|
|
295
|
+
catch {
|
|
296
|
+
// The local copy is a convenience; the URL above is the reference.
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
else {
|
|
301
|
+
deps.log('No accepted reference image. `bitmagic reference make` creates candidates to choose from.');
|
|
302
|
+
}
|
|
303
|
+
if (candidates.length > 0) {
|
|
304
|
+
deps.log(`Candidates (${candidates.length}):`);
|
|
305
|
+
for (const candidate of candidates) {
|
|
306
|
+
const marks = [
|
|
307
|
+
candidate.id === accepted?.candidateId ? 'accepted' : null,
|
|
308
|
+
candidate.from ? `from ${candidate.from}` : null,
|
|
309
|
+
].filter((mark) => mark !== null);
|
|
310
|
+
deps.log(` ${candidate.id}${marks.length > 0 ? ` (${marks.join(', ')})` : ''} — ${candidate.createdAt}`);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
deps.result({ ok: true, accepted, candidates });
|
|
314
|
+
}
|
|
315
|
+
export async function runReferenceClear(args, deps = defaultDeps(args.json === true)) {
|
|
316
|
+
const context = loadProjectContext(deps.startDir);
|
|
317
|
+
const cleared = clearAcceptedReference(context.root);
|
|
318
|
+
deps.log(cleared
|
|
319
|
+
? 'Cleared the accepted reference image. Candidates are kept — accept one again any time.'
|
|
320
|
+
: `No accepted reference image to clear (${path.relative(context.root, acceptedReferencePath(context.root))} does not exist).`);
|
|
321
|
+
deps.result({ ok: true, cleared });
|
|
322
|
+
}
|
|
323
|
+
// ============================================================================
|
|
324
|
+
// The command
|
|
325
|
+
// ============================================================================
|
|
326
|
+
const makeCommand = defineCommand({
|
|
327
|
+
meta: {
|
|
328
|
+
name: 'make',
|
|
329
|
+
description: "Make a concept image of the game's world to look at, iterate on, and maybe accept.",
|
|
330
|
+
},
|
|
331
|
+
args: {
|
|
332
|
+
prompt: {
|
|
333
|
+
type: 'string',
|
|
334
|
+
description: `Describe the world for this call only, instead of reading ${GAME_DESIGN_FILE}.`,
|
|
335
|
+
},
|
|
336
|
+
from: {
|
|
337
|
+
type: 'string',
|
|
338
|
+
description: 'Iterate from an earlier candidate: its image steers this one (say what to change in --prompt).',
|
|
339
|
+
},
|
|
340
|
+
'reference-image-url': REFERENCE_IMAGE_FLAG,
|
|
341
|
+
'reference-image': REFERENCE_FILE_FLAG,
|
|
342
|
+
'original-prompt': ORIGINAL_PROMPT_FLAG,
|
|
343
|
+
json: JSON_FLAG,
|
|
344
|
+
},
|
|
345
|
+
async run({ args }) {
|
|
346
|
+
await runReferenceMake({
|
|
347
|
+
prompt: args.prompt,
|
|
348
|
+
from: args.from,
|
|
349
|
+
'reference-image-url': args['reference-image-url'],
|
|
350
|
+
'reference-image': args['reference-image'],
|
|
351
|
+
json: args.json,
|
|
352
|
+
});
|
|
353
|
+
},
|
|
354
|
+
});
|
|
355
|
+
const acceptCommand = defineCommand({
|
|
356
|
+
meta: {
|
|
357
|
+
name: 'accept',
|
|
358
|
+
description: "Make one candidate (or your own image file/URL) the project's reference — every later generation inherits it.",
|
|
359
|
+
},
|
|
360
|
+
args: {
|
|
361
|
+
candidate: {
|
|
362
|
+
type: 'positional',
|
|
363
|
+
required: true,
|
|
364
|
+
description: 'A candidate id from `bitmagic reference show`, a local image file, or an https image URL.',
|
|
365
|
+
},
|
|
366
|
+
json: JSON_FLAG,
|
|
367
|
+
},
|
|
368
|
+
async run({ args }) {
|
|
369
|
+
await runReferenceAccept({ candidate: args.candidate, json: args.json });
|
|
370
|
+
},
|
|
371
|
+
});
|
|
372
|
+
const showCommand = defineCommand({
|
|
373
|
+
meta: { name: 'show', description: 'Show the accepted reference image and the candidates made so far.' },
|
|
374
|
+
args: { json: JSON_FLAG },
|
|
375
|
+
async run({ args }) {
|
|
376
|
+
await runReferenceShow({ json: args.json });
|
|
377
|
+
},
|
|
378
|
+
});
|
|
379
|
+
const clearCommand = defineCommand({
|
|
380
|
+
meta: { name: 'clear', description: 'Stop using the accepted reference image. Candidates are kept.' },
|
|
381
|
+
args: { json: JSON_FLAG },
|
|
382
|
+
async run({ args }) {
|
|
383
|
+
await runReferenceClear({ json: args.json });
|
|
384
|
+
},
|
|
385
|
+
});
|
|
386
|
+
export const referenceCommand = defineCommand({
|
|
387
|
+
meta: {
|
|
388
|
+
name: 'reference',
|
|
389
|
+
description: "Make and accept the reference image of the game's world that other generations follow.",
|
|
390
|
+
},
|
|
391
|
+
subCommands: {
|
|
392
|
+
make: makeCommand,
|
|
393
|
+
accept: acceptCommand,
|
|
394
|
+
show: showCommand,
|
|
395
|
+
clear: clearCommand,
|
|
396
|
+
},
|
|
397
|
+
});
|
|
398
|
+
//# sourceMappingURL=reference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reference.js","sourceRoot":"","sources":["../../src/commands/reference.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,12 @@ export interface GenerationOutcome {
|
|
|
18
18
|
* came back is what tells the caller which one to send.
|
|
19
19
|
*/
|
|
20
20
|
masterUrl?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Only the `reference` type sets this: the concept image `bitmagic reference make` iterates on.
|
|
23
|
+
* That generator returns NO patches — a candidate must not touch the project until the creator
|
|
24
|
+
* accepts it — so this field is its whole result.
|
|
25
|
+
*/
|
|
26
|
+
imageUrl?: string;
|
|
21
27
|
/**
|
|
22
28
|
* Only the `vehicle` type sets this: the bake settings its GLB was authored for. `minVoxelSize`
|
|
23
29
|
* is derived from the vehicle's own proportions rather than fixed, so the CLI cannot pick it —
|
package/dist/generate/stream.js
CHANGED
|
@@ -39,7 +39,7 @@ function asVehicleOutcome(value) {
|
|
|
39
39
|
function asGenerationOutcome(data) {
|
|
40
40
|
if (!isRecord(data))
|
|
41
41
|
return null;
|
|
42
|
-
const { success, message, patches, glbUrl, masterUrl, vehicle } = data;
|
|
42
|
+
const { success, message, patches, glbUrl, masterUrl, imageUrl, vehicle } = data;
|
|
43
43
|
if (typeof success !== 'boolean' || typeof message !== 'string' || !Array.isArray(patches)) {
|
|
44
44
|
return null;
|
|
45
45
|
}
|
|
@@ -50,6 +50,7 @@ function asGenerationOutcome(data) {
|
|
|
50
50
|
patches: patches,
|
|
51
51
|
...(typeof glbUrl === 'string' ? { glbUrl } : {}),
|
|
52
52
|
...(typeof masterUrl === 'string' ? { masterUrl } : {}),
|
|
53
|
+
...(typeof imageUrl === 'string' ? { imageUrl } : {}),
|
|
53
54
|
...(vehicleOutcome ? { vehicle: vehicleOutcome } : {}),
|
|
54
55
|
};
|
|
55
56
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/generate/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAQnE,gGAAgG;AAChG,gGAAgG;AAChG,qCAAqC;AACrC,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/generate/stream.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC,OAAO,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AACxG,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAQnE,gGAAgG;AAChG,gGAAgG;AAChG,qCAAqC;AACrC,OAAO,EAAE,cAAc,EAAiB,MAAM,gBAAgB,CAAC;AA8C/D,SAAS,QAAQ,CAAC,KAAc;IAC9B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;AACrD,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAa;IACtC,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClF,CAAC;AAED;;;;GAIG;AACH;;;;GAIG;AACH,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,GAAG,KAAK,CAAC;IAC1D,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;QACrG,OAAO,IAAI,CAAC;IACd,CAAC;IACD,OAAO;QACL,IAAI;QACJ,YAAY;QACZ,YAAY;QACZ,KAAK,EAAE,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE;KAC3F,CAAC;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,IAAa;IACxC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACjC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IACjF,IAAI,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,cAAc,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO;QACL,OAAO;QACP,OAAO;QACP,OAAO,EAAE,OAAuB;QAChC,GAAG,CAAC,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACjD,GAAG,CAAC,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACvD,GAAG,CAAC,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,GAAG,CAAC,cAAc,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvD,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CAAC,QAAuB;IACjD,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9C,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,IAA6B;IAC/C,OAAO,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,gBAAgB,CAAC;AACpG,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,UAAU,CAAC,QAAuB,EAAE,IAAY,EAAE,IAA6B;IAC5F,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC/C,MAAM,aAAa,GAAG,OAAO,SAAS,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IAExF,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,QAAQ,CACjB,wBAAwB,UAAU,CAAC,IAAI,CAAC,8BAA8B,IAAI,gBAAgB,CAC3F,CAAC;IACJ,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,0EAA0E;QAC1E,4EAA4E;QAC5E,uEAAuE;QACvE,oDAAoD;QACpD,MAAM,IAAI,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QACzC,IAAI,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,QAAQ,CAAC,mBAAmB,CAAC,mBAAmB,IAAI,QAAQ,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC;QAClC,MAAM,QAAQ,GAAG,SAAS,CAAC,QAAQ,CAAC;QACpC,MAAM,MAAM,GACV,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ;YACzD,CAAC,CAAC,aAAa,OAAO,4BAA4B,IAAI,mBAAmB,QAAQ,GAAG;YACpF,CAAC,CAAC,EAAE,CAAC;QACT,OAAO,IAAI,QAAQ,CAAC,sCAAsC,IAAI,UAAU,MAAM,EAAE,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;IAC7F,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,OAAO,IAAI,QAAQ,CAAC,aAAa,IAAI,4BAA4B,IAAI,sBAAsB,CAAC,CAAC;IAC/F,CAAC;IAED,OAAO,IAAI,QAAQ,CACjB,4BAA4B,QAAQ,CAAC,MAAM,iBAAiB,IAAI,QAAQ;QACtE,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,aAAa,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAC/C,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,WAAwB,EACxB,WAAmB,EACnB,IAAY,EACZ,IAA6B,EAC7B,IAAgB;IAEhB,MAAM,GAAG,GAAG,GAAG,WAAW,CAAC,MAAM,sBAAsB,IAAI,SAAS,CAAC;IAErE,IAAI,QAAuB,CAAC;IAC5B,IAAI,CAAC;QACH,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;YAC/B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,GAAG,gBAAgB,EAAE;gBACrB,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,MAAM,EAAE,mBAAmB;gBAC3B,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,gFAAgF;QAChF,MAAM,IAAI,QAAQ,CAAC,8BAA8B,WAAW,CAAC,MAAM,GAAG,EAAE,CAAC,EAAE,aAAa,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,MAAM,UAAU,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnB,MAAM,IAAI,QAAQ,CAAC,8DAA8D,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;IAClC,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;IAE3C,SAAS,CAAC;QACR,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;QAC5C,IAAI,IAAI;YAAE,MAAM;QAEhB,uFAAuF;QACvF,4FAA4F;QAC5F,uEAAuE;QACvE,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;QACrD,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3C,IAAI,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;gBAC/B,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC9C,IAAI,OAAO,KAAK,IAAI;oBAAE,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBAC/C,SAAS;YACX,CAAC;YACD,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,KAAK,KAAK,OAAO,EAAE,CAAC;gBACxD,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,OAAO;oBAAE,OAAO,OAAO,CAAC;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,QAAQ,CAChB,iDAAiD,IAAI,wBAAwB;QAC3E,oFAAoF;QACpF,8EAA8E,CACjF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type MobileOrientation } from '../project/platform-declaration.js';
|
|
2
|
+
/** What `.bitmagic/ios.json` may hold. Every field optional — absent means "derive". */
|
|
3
|
+
export interface IosConfigFile {
|
|
4
|
+
bundleId?: string;
|
|
5
|
+
displayName?: string;
|
|
6
|
+
version?: string;
|
|
7
|
+
teamId?: string;
|
|
8
|
+
}
|
|
9
|
+
export interface IosAppConfig {
|
|
10
|
+
/** Reverse-DNS id, `ai.bitmagic.game.<gameid>` unless overridden. */
|
|
11
|
+
bundleId: string;
|
|
12
|
+
/** What the home screen shows — any unicode, from game.json's gameName. */
|
|
13
|
+
displayName: string;
|
|
14
|
+
/** PRODUCT_NAME / the .app filename — sanitized ASCII (Steam export §4 rules). */
|
|
15
|
+
productName: string;
|
|
16
|
+
/** CFBundleShortVersionString. */
|
|
17
|
+
version: string;
|
|
18
|
+
/** CFBundleVersion — a UTC yyyyMMddHHmm stamp, so store uploads always increase. */
|
|
19
|
+
buildNumber: string;
|
|
20
|
+
/** Apple Developer team, required only for the device/store lane. */
|
|
21
|
+
teamId?: string;
|
|
22
|
+
/** From the project's own declaration; decides the Info.plist orientation mask. */
|
|
23
|
+
orientation?: MobileOrientation;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The default bundle id. Game ids are uppercase alphanumerics; lowercased they are valid
|
|
27
|
+
* reverse-DNS segments. Anything else (a hand-edited id) is filtered to the characters Apple
|
|
28
|
+
* accepts rather than rejected — the id only has to be stable and valid, not pretty.
|
|
29
|
+
*/
|
|
30
|
+
export declare function deriveBundleId(gameId: string): string;
|
|
31
|
+
/**
|
|
32
|
+
* PRODUCT_NAME under the Steam export's filename rules: ASCII letters, digits, space, dash;
|
|
33
|
+
* whitespace collapsed; max 40 chars. The pretty, unsanitized name still ships as
|
|
34
|
+
* CFBundleDisplayName — this only names the executable and the .app on disk.
|
|
35
|
+
*/
|
|
36
|
+
export declare function sanitizeProductName(name: string, gameId: string): string;
|
|
37
|
+
/** The moment's UTC yyyyMMddHHmm — monotonic across builds, which App Store uploads require. */
|
|
38
|
+
export declare function buildNumberNow(now?: Date): string;
|
|
39
|
+
export interface ResolveAppConfigOptions {
|
|
40
|
+
root: string;
|
|
41
|
+
gameId: string;
|
|
42
|
+
configPath: string;
|
|
43
|
+
/** `--name` for this build only — never persisted, mirroring publish's override semantics. */
|
|
44
|
+
nameOverride?: string;
|
|
45
|
+
/** `--team` — persisted to ios.json so the device lane needs it only once. */
|
|
46
|
+
teamOverride?: string;
|
|
47
|
+
now?: Date;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolve the app identity, persisting `--team` (the one flag worth remembering) back to
|
|
51
|
+
* `.bitmagic/ios.json`. Everything else derives fresh each build so the wrapper follows the
|
|
52
|
+
* project: rename the game in game.json and the next build renames the app.
|
|
53
|
+
*/
|
|
54
|
+
export declare function resolveAppConfig(options: ResolveAppConfigOptions): IosAppConfig;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The packaged app's identity: bundle id, names, version — resolved from the project with
|
|
3
|
+
* `.bitmagic/ios.json` as the persistent override file.
|
|
4
|
+
*
|
|
5
|
+
* The file is deliberately OUTSIDE the project source (`.bitmagic` is excluded from the publish
|
|
6
|
+
* fingerprint), because nothing here changes the game: it names the wrapper. Defaults are
|
|
7
|
+
* derived deterministically from the project, so a deleted ios.json regenerates the same app
|
|
8
|
+
* identity — the file only needs to exist once the creator overrides something (or a `--team`
|
|
9
|
+
* is worth remembering).
|
|
10
|
+
*/
|
|
11
|
+
import * as fs from 'fs';
|
|
12
|
+
import * as path from 'path';
|
|
13
|
+
import { CliError } from '../errors.js';
|
|
14
|
+
import { readPlatformDeclaration } from '../project/platform-declaration.js';
|
|
15
|
+
import { aliasSourceDir } from '../scaffold/aliases.js';
|
|
16
|
+
/**
|
|
17
|
+
* The default bundle id. Game ids are uppercase alphanumerics; lowercased they are valid
|
|
18
|
+
* reverse-DNS segments. Anything else (a hand-edited id) is filtered to the characters Apple
|
|
19
|
+
* accepts rather than rejected — the id only has to be stable and valid, not pretty.
|
|
20
|
+
*/
|
|
21
|
+
export function deriveBundleId(gameId) {
|
|
22
|
+
const segment = gameId.toLowerCase().replace(/[^a-z0-9-]/g, '');
|
|
23
|
+
if (segment.length === 0) {
|
|
24
|
+
throw new CliError(`Cannot derive a bundle id from gameId ${JSON.stringify(gameId)}.`);
|
|
25
|
+
}
|
|
26
|
+
return `ai.bitmagic.game.${segment}`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* PRODUCT_NAME under the Steam export's filename rules: ASCII letters, digits, space, dash;
|
|
30
|
+
* whitespace collapsed; max 40 chars. The pretty, unsanitized name still ships as
|
|
31
|
+
* CFBundleDisplayName — this only names the executable and the .app on disk.
|
|
32
|
+
*/
|
|
33
|
+
export function sanitizeProductName(name, gameId) {
|
|
34
|
+
const cleaned = name
|
|
35
|
+
.replace(/[^A-Za-z0-9 -]/g, '')
|
|
36
|
+
.replace(/\s+/g, ' ')
|
|
37
|
+
.trim()
|
|
38
|
+
.slice(0, 40)
|
|
39
|
+
.trim();
|
|
40
|
+
return cleaned.length > 0 ? cleaned : `Bitmagic Game ${gameId}`;
|
|
41
|
+
}
|
|
42
|
+
/** The moment's UTC yyyyMMddHHmm — monotonic across builds, which App Store uploads require. */
|
|
43
|
+
export function buildNumberNow(now = new Date()) {
|
|
44
|
+
const pad = (n) => String(n).padStart(2, '0');
|
|
45
|
+
return (`${now.getUTCFullYear()}${pad(now.getUTCMonth() + 1)}${pad(now.getUTCDate())}`
|
|
46
|
+
+ `${pad(now.getUTCHours())}${pad(now.getUTCMinutes())}`);
|
|
47
|
+
}
|
|
48
|
+
function readConfigFile(configPath) {
|
|
49
|
+
let parsed;
|
|
50
|
+
try {
|
|
51
|
+
parsed = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return {};
|
|
55
|
+
}
|
|
56
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
|
|
57
|
+
return {};
|
|
58
|
+
const record = parsed;
|
|
59
|
+
const str = (key) => typeof record[key] === 'string' && record[key].length > 0
|
|
60
|
+
? record[key]
|
|
61
|
+
: undefined;
|
|
62
|
+
return {
|
|
63
|
+
bundleId: str('bundleId'),
|
|
64
|
+
displayName: str('displayName'),
|
|
65
|
+
version: str('version'),
|
|
66
|
+
teamId: str('teamId'),
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** The game's display name as game.json declares it, or null when the file doesn't say. */
|
|
70
|
+
function readGameName(root) {
|
|
71
|
+
try {
|
|
72
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(root, aliasSourceDir('work'), 'game.json'), 'utf-8'));
|
|
73
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
74
|
+
return null;
|
|
75
|
+
const name = parsed.gameName;
|
|
76
|
+
return typeof name === 'string' && name.trim().length > 0 ? name.trim() : null;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Resolve the app identity, persisting `--team` (the one flag worth remembering) back to
|
|
84
|
+
* `.bitmagic/ios.json`. Everything else derives fresh each build so the wrapper follows the
|
|
85
|
+
* project: rename the game in game.json and the next build renames the app.
|
|
86
|
+
*/
|
|
87
|
+
export function resolveAppConfig(options) {
|
|
88
|
+
const file = readConfigFile(options.configPath);
|
|
89
|
+
if (options.teamOverride !== undefined && options.teamOverride !== file.teamId) {
|
|
90
|
+
const updated = { ...file, teamId: options.teamOverride };
|
|
91
|
+
fs.mkdirSync(path.dirname(options.configPath), { recursive: true });
|
|
92
|
+
fs.writeFileSync(options.configPath, `${JSON.stringify(updated, null, 2)}\n`);
|
|
93
|
+
file.teamId = options.teamOverride;
|
|
94
|
+
}
|
|
95
|
+
const displayName = options.nameOverride ?? file.displayName ?? readGameName(options.root) ?? `Bitmagic Game ${options.gameId}`;
|
|
96
|
+
const declaration = readPlatformDeclaration(options.root);
|
|
97
|
+
return {
|
|
98
|
+
bundleId: file.bundleId ?? deriveBundleId(options.gameId),
|
|
99
|
+
displayName,
|
|
100
|
+
productName: sanitizeProductName(displayName, options.gameId),
|
|
101
|
+
version: file.version ?? '1.0.0',
|
|
102
|
+
buildNumber: buildNumberNow(options.now),
|
|
103
|
+
...(file.teamId !== undefined ? { teamId: file.teamId } : {}),
|
|
104
|
+
...(declaration.mobileOrientation !== undefined
|
|
105
|
+
? { orientation: declaration.mobileOrientation }
|
|
106
|
+
: {}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=app-config.js.map
|