@bitmagic/cli 0.1.60-dev.0 → 0.1.60-dev.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +60 -4
  2. package/dist/cli.d.ts +36 -0
  3. package/dist/cli.js +2 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/forge.js +15 -25
  6. package/dist/commands/forge.js.map +1 -1
  7. package/dist/commands/generate.d.ts +2 -0
  8. package/dist/commands/generate.js +28 -1
  9. package/dist/commands/generate.js.map +1 -1
  10. package/dist/commands/import.d.ts +75 -0
  11. package/dist/commands/import.js +338 -0
  12. package/dist/commands/import.js.map +1 -0
  13. package/dist/commands/init.js +1 -45
  14. package/dist/commands/init.js.map +1 -1
  15. package/dist/commands/verify.js +17 -29
  16. package/dist/commands/verify.js.map +1 -1
  17. package/dist/editor/animation-preview-page.js +1 -1
  18. package/dist/editor/motion-panel.d.ts +3 -3
  19. package/dist/editor/motion-panel.js +272 -2
  20. package/dist/editor/motion-panel.js.map +1 -1
  21. package/dist/editor/motion-sink.d.ts +10 -2
  22. package/dist/editor/motion-sink.js +27 -2
  23. package/dist/editor/motion-sink.js.map +1 -1
  24. package/dist/editor/server.js +100 -1
  25. package/dist/editor/server.js.map +1 -1
  26. package/dist/generate/animation-from-video.d.ts +12 -0
  27. package/dist/generate/animation-from-video.js +15 -6
  28. package/dist/generate/animation-from-video.js.map +1 -1
  29. package/dist/generate/trim-analysis.d.ts +22 -0
  30. package/dist/generate/trim-analysis.js +31 -0
  31. package/dist/generate/trim-analysis.js.map +1 -0
  32. package/dist/local-port.d.ts +23 -4
  33. package/dist/local-port.js +44 -13
  34. package/dist/local-port.js.map +1 -1
  35. package/dist/scaffold/export-zip.d.ts +48 -0
  36. package/dist/scaffold/export-zip.js +167 -0
  37. package/dist/scaffold/export-zip.js.map +1 -0
  38. package/dist/scaffold/import-project.d.ts +34 -0
  39. package/dist/scaffold/import-project.js +108 -0
  40. package/dist/scaffold/import-project.js.map +1 -0
  41. package/dist/scaffold/project-files.js +9 -1
  42. package/dist/scaffold/project-files.js.map +1 -1
  43. package/dist/scaffold/project.d.ts +34 -0
  44. package/dist/scaffold/project.js +53 -22
  45. package/dist/scaffold/project.js.map +1 -1
  46. package/dist/scaffold/rehost-assets.d.ts +63 -0
  47. package/dist/scaffold/rehost-assets.js +270 -0
  48. package/dist/scaffold/rehost-assets.js.map +1 -0
  49. package/dist/scaffold/scaffold-run.d.ts +17 -0
  50. package/dist/scaffold/scaffold-run.js +57 -0
  51. package/dist/scaffold/scaffold-run.js.map +1 -0
  52. package/dist/theme/hud-theme-catalog.d.ts +0 -1
  53. package/dist/theme/hud-theme-catalog.js +9 -6
  54. package/dist/theme/hud-theme-catalog.js.map +1 -1
  55. package/dist/theme/theme-io.js +2 -1
  56. package/dist/theme/theme-io.js.map +1 -1
  57. package/dist/verify/browser.js +87 -18
  58. package/dist/verify/browser.js.map +1 -1
  59. package/dist/verify/classify.d.ts +12 -0
  60. package/dist/verify/classify.js +24 -3
  61. package/dist/verify/classify.js.map +1 -1
  62. package/dist/verify/start.d.ts +23 -3
  63. package/dist/verify/start.js +13 -1
  64. package/dist/verify/start.js.map +1 -1
  65. package/dist/verify/wait-for-server.d.ts +11 -0
  66. package/dist/verify/wait-for-server.js +29 -1
  67. package/dist/verify/wait-for-server.js.map +1 -1
  68. package/package.json +7 -5
@@ -1,5 +1,6 @@
1
1
  import * as net from 'net';
2
2
  import { CliError } from './errors.js';
3
+ import { currentPortLane } from './port-lane.js';
3
4
  /**
4
5
  * The port window the platform's bucket CORS policy allowlists as an origin.
5
6
  *
@@ -51,17 +52,37 @@ export function parseLocalPort(value, fallback, flag) {
51
52
  }
52
53
  return port;
53
54
  }
54
- function tryListen(port) {
55
+ /** `null` when the port bound cleanly on this host, otherwise the OS error code that refused it. */
56
+ function tryBind(port, host) {
55
57
  return new Promise((resolve) => {
56
58
  const server = net.createServer();
57
- server.once('error', () => resolve(null));
58
- server.listen(port, '127.0.0.1', () => {
59
- const address = server.address();
60
- const bound = address !== null && typeof address !== 'string' ? address.port : null;
61
- server.close(() => resolve(bound));
59
+ server.once('error', (error) => resolve(error.code ?? 'UNKNOWN'));
60
+ server.listen(port, host, () => {
61
+ server.close(() => resolve(null));
62
62
  });
63
63
  });
64
64
  }
65
+ /** Codes that mean "this machine has no such loopback family", not "this port is taken". */
66
+ const FAMILY_UNAVAILABLE_CODES = new Set(['EADDRNOTAVAIL', 'EAFNOSUPPORT']);
67
+ /**
68
+ * Whether this exact port is free right now. Same TOCTOU caveat as `reservePortInLane` below.
69
+ *
70
+ * A port counts as free only when BOTH loopback families are free. Vite binds `localhost`, which
71
+ * Node resolves to `::1` on modern systems — so a running `bitmagic dev` holds only the IPv6 side
72
+ * of its port. Probing 127.0.0.1 alone once called such a port "free": `verify` then bound its own
73
+ * vite to the IPv4 side, `http://localhost:<port>/` resolved to `::1`, and the run drove — and
74
+ * graded — whichever OTHER project's dev server was already there, printing "Verification passed"
75
+ * for a game it never loaded. A machine without IPv6 reports the family as unavailable rather
76
+ * than the port as busy, and that must not mark every port taken.
77
+ */
78
+ export async function isPortFree(port) {
79
+ for (const host of ['127.0.0.1', '::1']) {
80
+ const code = await tryBind(port, host);
81
+ if (code !== null && !FAMILY_UNAVAILABLE_CODES.has(code))
82
+ return false;
83
+ }
84
+ return true;
85
+ }
65
86
  /**
66
87
  * A free port in this install's lane, or `null` when every port in the lane is taken.
67
88
  *
@@ -75,7 +96,7 @@ function tryListen(port) {
75
96
  * quietly. A hundred held ports is a machine with a problem to report, not a lane to abandon.
76
97
  *
77
98
  * The scan starts at a pseudo-random offset so two concurrent runs do not both take the lane's
78
- * first port and race; `tryListen` closing before the caller binds leaves a window either way,
99
+ * first port and race; `isPortFree` closing before the caller binds leaves a window either way,
79
100
  * which is why callers must handle a bind failure rather than trusting this.
80
101
  */
81
102
  export async function reservePortInLane(lane, exclude = new Set()) {
@@ -85,9 +106,8 @@ export async function reservePortInLane(lane, exclude = new Set()) {
85
106
  const port = lane.min + ((start + i) % span);
86
107
  if (exclude.has(port))
87
108
  continue;
88
- const bound = await tryListen(port);
89
- if (bound !== null)
90
- return bound;
109
+ if (await isPortFree(port))
110
+ return port;
91
111
  }
92
112
  return null;
93
113
  }
@@ -104,9 +124,20 @@ export function laneExhaustedMessage(lane, remedy) {
104
124
  + 'the other half is left free so a bitmagic from the other release line can run beside this '
105
125
  + `one. ${remedy}`);
106
126
  }
107
- /** Whether this exact port is free right now. Same TOCTOU caveat as above. */
108
- export async function isPortFree(port) {
109
- return (await tryListen(port)) !== null;
127
+ /**
128
+ * A free port in THIS install's lane, or a `CliError` carrying `remedy` when the lane is full.
129
+ *
130
+ * What every command that serves the project for a real browser to load actually wants: `verify`
131
+ * and `forge` alike need a port inside the CDN's CORS window (see the file header) and have
132
+ * nothing useful to do with a `null`. Bundling the lane lookup, the scan and the refusal here
133
+ * keeps the three from drifting apart — a caller varies only what it tells the creator to do.
134
+ */
135
+ export async function reserveLanePort(remedy, exclude = new Set()) {
136
+ const lane = currentPortLane();
137
+ const port = await reservePortInLane(lane, exclude);
138
+ if (port === null)
139
+ throw new CliError(laneExhaustedMessage(lane, remedy));
140
+ return port;
110
141
  }
111
142
  /**
112
143
  * The port to actually bind: `preferred` when it is free, otherwise another one in the window.
@@ -1 +1 @@
1
- {"version":3,"file":"local-port.js","sourceRoot":"","sources":["../src/local-port.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"local-port.js","sourceRoot":"","sources":["../src/local-port.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /** One file from the export's `source/`, keyed by its path RELATIVE to that directory. */
2
+ export interface ExportSourceFile {
3
+ /** Forward-slash separated, e.g. `Game.ts` or `levels/level-2.json`. */
4
+ path: string;
5
+ contents: Uint8Array;
6
+ }
7
+ export interface CreatorExport {
8
+ /** The game's id on the Creator's api-server — the row a CLI project can adopt. */
9
+ gameId: string;
10
+ genre: string;
11
+ /** The engine the game was last edited against, or null when the export predates the field. */
12
+ engineVersion: string | null;
13
+ /** The Creator template the game began from (`metadata.importedFrom`), or null. */
14
+ template: string | null;
15
+ /** `game.json`'s `gameName`, for the summary. Null when absent or unreadable. */
16
+ gameName: string | null;
17
+ /** Every file under `<gameId>/source/`, with `.git` already dropped. */
18
+ sourceFiles: ExportSourceFile[];
19
+ }
20
+ /**
21
+ * Read and validate the export at `zipPath`.
22
+ *
23
+ * Every failure is a CliError naming the file, because all of them mean the same thing to a
24
+ * creator: this is not an export the CLI can convert, and nothing has been written yet.
25
+ */
26
+ export declare function readCreatorExport(zipPath: string): CreatorExport;
27
+ /**
28
+ * The hosts serving assets that belong to THIS game — http(s) URLs in `world.json` and
29
+ * `game.json` whose path carries the game's own id.
30
+ *
31
+ * Read for one reason: a game's assets are minted under `worlds/v3/<gameId>/` by the api-server
32
+ * that hosts the Creator, and so is the game row a CLI project adopts by id. Importing a dev game
33
+ * into a project pinned to prod produces something that builds, runs and then fails every server
34
+ * command with a flat "not found or is not owned by the caller" — the one failure this conversion
35
+ * can see coming and the creator cannot. The caller compares these against the environment it
36
+ * resolved; nothing here decides anything.
37
+ *
38
+ * **The gameId filter is the whole point, not a refinement.** Every game — on every environment —
39
+ * references shared defaults that live on prod: `mini.bitmagic.ai/worlds/v3/BaseCharacter.glb` is
40
+ * in the game.json of a dev game and a prod game alike. Classifying on "any bitmagic host" reads
41
+ * that one line and calls every dev export a prod game, which is precisely the mistake this check
42
+ * exists to prevent. Only a URL carrying the game's own id was minted for this game, by the
43
+ * api-server that owns it.
44
+ *
45
+ * Named for what it returns rather than `assetHosts`, which is `mobile/asset-hosts.ts` — a
46
+ * different question (which hosts the LAN bridge proxies for a phone) about the same URLs.
47
+ */
48
+ export declare function gameAssetHosts(source: CreatorExport): string[];
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Reading a Bitmagic Creator export — the `.zip` the web Creator's "Export game" button
3
+ * downloads — into the few things a CLI project actually needs from it.
4
+ *
5
+ * The archive is written by game-play-agent's ExportImportController and holds far more than a
6
+ * project does:
7
+ *
8
+ * manifest.json export version, the game id, the genre
9
+ * <gameId>/metadata.json engine version, the Creator template it began from
10
+ * <gameId>/source/ the game itself: .ts, game.json, world.json, design docs, .git
11
+ * <gameId>/edit-sessions/ ┐
12
+ * <gameId>/session-logs/ │ the web lane's own bookkeeping: an audit trail of every AI
13
+ * <gameId>/llm-usage/ │ edit ever made. Nothing in a CLI project reads any of it.
14
+ * <gameId>/operations.json ┘
15
+ *
16
+ * Only the first three are read, and the read is FILTERED rather than "unzip, then pick": the
17
+ * bookkeeping is the bulk of a real export (a 25MB zip whose source/ is 1.5MB), and `source/.git`
18
+ * alone can be hundreds of files. fflate applies the filter before inflating, so what is skipped
19
+ * costs nothing but a central-directory entry.
20
+ */
21
+ import * as fs from 'fs';
22
+ import { unzipSync } from 'fflate';
23
+ import { CliError, describeErrno } from '../errors.js';
24
+ /**
25
+ * Export manifest versions this understands, matching what the Creator's own importer accepts
26
+ * (ExportImportController.parseManifest). A newer version is refused by number rather than
27
+ * guessed at: an export whose layout changed would otherwise be half-read into a broken project.
28
+ */
29
+ const SUPPORTED_MANIFEST_VERSIONS = [1, 2];
30
+ const MANIFEST_NAME = 'manifest.json';
31
+ /**
32
+ * Is this archive entry one of the three things worth inflating?
33
+ *
34
+ * Directory entries (`name` ending in `/`) are excluded explicitly. They inflate to zero bytes
35
+ * rather than failing, so without this they would arrive as empty "files" and be written to disk
36
+ * as such — `<gameId>/source/` splits into three segments the same way a real file does.
37
+ */
38
+ function isWantedEntry(name) {
39
+ if (name.endsWith('/'))
40
+ return false;
41
+ if (name === MANIFEST_NAME)
42
+ return true;
43
+ const parts = name.split('/');
44
+ if (parts.length === 2 && parts[1] === 'metadata.json')
45
+ return true;
46
+ // `.git` is the Creator's own per-game history. Its paths are relative to source/, so replaying
47
+ // it into src/work/ would produce a repository whose every recorded path is wrong.
48
+ return parts.length >= 3 && parts[1] === 'source' && parts[2] !== '.git';
49
+ }
50
+ /** Parse JSON that must be an object, or null for anything else. Never throws. */
51
+ function readJsonObject(bytes) {
52
+ if (bytes === undefined)
53
+ return null;
54
+ let parsed;
55
+ try {
56
+ parsed = JSON.parse(Buffer.from(bytes).toString('utf-8'));
57
+ }
58
+ catch {
59
+ return null;
60
+ }
61
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed))
62
+ return null;
63
+ return parsed;
64
+ }
65
+ /** A field that is a non-empty string, or null — the shape every optional field here wants. */
66
+ function stringField(source, key) {
67
+ const value = source?.[key];
68
+ return typeof value === 'string' && value.length > 0 ? value : null;
69
+ }
70
+ /**
71
+ * Read and validate the export at `zipPath`.
72
+ *
73
+ * Every failure is a CliError naming the file, because all of them mean the same thing to a
74
+ * creator: this is not an export the CLI can convert, and nothing has been written yet.
75
+ */
76
+ export function readCreatorExport(zipPath) {
77
+ let archive;
78
+ try {
79
+ archive = fs.readFileSync(zipPath);
80
+ }
81
+ catch (error) {
82
+ throw new CliError(`Cannot read ${zipPath}: ${describeErrno(error)}`);
83
+ }
84
+ let entries;
85
+ try {
86
+ entries = unzipSync(archive, { filter: (file) => isWantedEntry(file.name) });
87
+ }
88
+ catch {
89
+ throw new CliError(`${zipPath} is not a readable zip archive.`);
90
+ }
91
+ const manifest = readJsonObject(entries[MANIFEST_NAME]);
92
+ if (manifest === null) {
93
+ throw new CliError(`${zipPath} has no readable ${MANIFEST_NAME} — it is not a Bitmagic Creator export. ` +
94
+ 'Export the game from the Creator with "Export game" and pass the .zip it downloads.');
95
+ }
96
+ const version = manifest.version;
97
+ if (typeof version !== 'number' || !SUPPORTED_MANIFEST_VERSIONS.includes(version)) {
98
+ throw new CliError(`${zipPath} is an export of version ${String(version)}, which this CLI does not understand. ` +
99
+ 'Run `bitmagic self-update` and try again.');
100
+ }
101
+ const gameId = stringField(manifest, 'originalGameId');
102
+ if (gameId === null) {
103
+ throw new CliError(`${zipPath}'s ${MANIFEST_NAME} names no originalGameId.`);
104
+ }
105
+ const sourcePrefix = `${gameId}/source/`;
106
+ const sourceFiles = Object.entries(entries)
107
+ .filter(([name]) => name.startsWith(sourcePrefix))
108
+ .map(([name, contents]) => ({ path: name.slice(sourcePrefix.length), contents }))
109
+ // Code-unit order, not `localeCompare`: the listing is reported back to the creator and
110
+ // asserted on in tests, and locale collation makes both depend on the machine's ICU data.
111
+ .sort((a, b) => (a.path < b.path ? -1 : a.path > b.path ? 1 : 0));
112
+ if (sourceFiles.length === 0) {
113
+ throw new CliError(`${zipPath} carries no ${sourcePrefix} — the export has no game code to convert.`);
114
+ }
115
+ const metadata = readJsonObject(entries[`${gameId}/metadata.json`]);
116
+ const gameJson = readJsonObject(sourceFiles.find((file) => file.path === 'game.json')?.contents);
117
+ return {
118
+ gameId,
119
+ // The manifest's genre is what the export declares; metadata.json is the game folder's own
120
+ // record of it. They agree in every export, and the fallback chain simply refuses to have an
121
+ // opinion about which is right — `unknown` is what the exporter itself writes when it cannot
122
+ // read metadata.json, so it is the honest floor rather than a made-up default.
123
+ genre: stringField(manifest, 'genre') ?? stringField(metadata, 'genre') ?? 'unknown',
124
+ engineVersion: stringField(metadata, 'engineVersion'),
125
+ template: stringField(metadata, 'importedFrom'),
126
+ gameName: stringField(gameJson, 'gameName'),
127
+ sourceFiles,
128
+ };
129
+ }
130
+ /**
131
+ * The hosts serving assets that belong to THIS game — http(s) URLs in `world.json` and
132
+ * `game.json` whose path carries the game's own id.
133
+ *
134
+ * Read for one reason: a game's assets are minted under `worlds/v3/<gameId>/` by the api-server
135
+ * that hosts the Creator, and so is the game row a CLI project adopts by id. Importing a dev game
136
+ * into a project pinned to prod produces something that builds, runs and then fails every server
137
+ * command with a flat "not found or is not owned by the caller" — the one failure this conversion
138
+ * can see coming and the creator cannot. The caller compares these against the environment it
139
+ * resolved; nothing here decides anything.
140
+ *
141
+ * **The gameId filter is the whole point, not a refinement.** Every game — on every environment —
142
+ * references shared defaults that live on prod: `mini.bitmagic.ai/worlds/v3/BaseCharacter.glb` is
143
+ * in the game.json of a dev game and a prod game alike. Classifying on "any bitmagic host" reads
144
+ * that one line and calls every dev export a prod game, which is precisely the mistake this check
145
+ * exists to prevent. Only a URL carrying the game's own id was minted for this game, by the
146
+ * api-server that owns it.
147
+ *
148
+ * Named for what it returns rather than `assetHosts`, which is `mobile/asset-hosts.ts` — a
149
+ * different question (which hosts the LAN bridge proxies for a phone) about the same URLs.
150
+ */
151
+ export function gameAssetHosts(source) {
152
+ const hosts = new Set();
153
+ for (const file of source.sourceFiles) {
154
+ if (file.path !== 'world.json' && file.path !== 'game.json')
155
+ continue;
156
+ const text = Buffer.from(file.contents).toString('utf-8');
157
+ // The path half stops at the first character that cannot appear in a JSON string's URL, so a
158
+ // quote or a comma ends it rather than running into the next field.
159
+ for (const match of text.matchAll(/https?:\/\/([A-Za-z0-9.-]+)([^"'\s,]*)/g)) {
160
+ const host = match[1];
161
+ if (host !== undefined && (match[2] ?? '').includes(source.gameId))
162
+ hosts.add(host);
163
+ }
164
+ }
165
+ return [...hosts].sort();
166
+ }
167
+ //# sourceMappingURL=export-zip.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export-zip.js","sourceRoot":"","sources":["../../src/scaffold/export-zip.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACnC,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAuBvD;;;;GAIG;AACH,MAAM,2BAA2B,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE3C,MAAM,aAAa,GAAG,eAAe,CAAC;AAEtC;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,IAAY;IACjC,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACrC,IAAI,IAAI,KAAK,aAAa;QAAE,OAAO,IAAI,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,eAAe;QAAE,OAAO,IAAI,CAAC;IACpE,gGAAgG;IAChG,mFAAmF;IACnF,OAAO,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC;AAC3E,CAAC;AAED,kFAAkF;AAClF,SAAS,cAAc,CAAC,KAA6B;IACnD,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IACxF,OAAO,MAAiC,CAAC;AAC3C,CAAC;AAED,+FAA+F;AAC/F,SAAS,WAAW,CAAC,MAAsC,EAAE,GAAW;IACtE,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;IAC5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC;AACtE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;IACrC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,QAAQ,CAAC,eAAe,OAAO,KAAK,aAAa,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC;IAED,IAAI,OAAmC,CAAC;IACxC,IAAI,CAAC;QACH,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,iCAAiC,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;IACxD,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,QAAQ,CAChB,GAAG,OAAO,oBAAoB,aAAa,0CAA0C;YACnF,qFAAqF,CACxF,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,2BAA2B,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,QAAQ,CAChB,GAAG,OAAO,4BAA4B,MAAM,CAAC,OAAO,CAAC,wCAAwC;YAC3F,2CAA2C,CAC9C,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,WAAW,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;IACvD,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,MAAM,IAAI,QAAQ,CAAC,GAAG,OAAO,MAAM,aAAa,2BAA2B,CAAC,CAAC;IAC/E,CAAC;IAED,MAAM,YAAY,GAAG,GAAG,MAAM,UAAU,CAAC;IACzC,MAAM,WAAW,GAAuB,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC;SAC5D,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;SACjD,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QACjF,wFAAwF;QACxF,0FAA0F;SACzF,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC7B,MAAM,IAAI,QAAQ,CAChB,GAAG,OAAO,eAAe,YAAY,4CAA4C,CAClF,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,cAAc,CAAC,OAAO,CAAC,GAAG,MAAM,gBAAgB,CAAC,CAAC,CAAC;IACpE,MAAM,QAAQ,GAAG,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC,EAAE,QAAQ,CAAC,CAAC;IAEjG,OAAO;QACL,MAAM;QACN,2FAA2F;QAC3F,6FAA6F;QAC7F,6FAA6F;QAC7F,+EAA+E;QAC/E,KAAK,EAAE,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,WAAW,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,SAAS;QACpF,aAAa,EAAE,WAAW,CAAC,QAAQ,EAAE,eAAe,CAAC;QACrD,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,cAAc,CAAC;QAC/C,QAAQ,EAAE,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;QAC3C,WAAW;KACZ,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,cAAc,CAAC,MAAqB;IAClD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;QACtC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW;YAAE,SAAS;QACtE,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC1D,6FAA6F;QAC7F,oEAAoE;QACpE,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,yCAAyC,CAAC,EAAE,CAAC;YAC7E,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACtB,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;gBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IACD,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { CreatorExport } from './export-zip.js';
2
+ import type { ProjectMetadata } from './project-files.js';
3
+ /**
4
+ * Documents the CLI lane keeps at the project ROOT, lifted out of the export's `source/`.
5
+ *
6
+ * `GAME-DESIGN.md` is read by `cover`, `judge` and `reference`, all of which look at the root.
7
+ * `mechanics-plan.md` is where AGENTS.md tells the agent its build order lives, and that
8
+ * instruction names the root too. Both are prose — moving them cannot break a build, and leaving
9
+ * them cannot be noticed until a command quietly reports the project has no design.
10
+ */
11
+ export declare const ROOT_DOC_FILES: string[];
12
+ export interface ImportProjectOptions {
13
+ targetDir: string;
14
+ /** Where extractEngine unpacked game/src/* and game/docs. */
15
+ extractedEngineDir: string;
16
+ source: CreatorExport;
17
+ metadata: ProjectMetadata;
18
+ projectName: string;
19
+ /**
20
+ * The id the project adopts, when it is NOT the one the game was exported under — i.e. `import
21
+ * --new-game`. Undefined means the project keeps the exported id and the two JSON files are
22
+ * written through untouched.
23
+ */
24
+ rewriteGameId?: string;
25
+ }
26
+ export interface ImportProjectResult {
27
+ /** Paths written under `src/work/`, relative to it. */
28
+ workFiles: string[];
29
+ /** Docs lifted to the project root, by name. */
30
+ rootDocs: string[];
31
+ /** Files whose embedded `gameId` was rewritten. Empty unless `rewriteGameId` was given. */
32
+ rewritten: string[];
33
+ }
34
+ export declare function importProject(options: ImportProjectOptions): ImportProjectResult;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Turning a read Creator export into a project on disk — `scaffoldProject`'s sibling, differing
3
+ * in exactly one thing: where `src/work/` comes from.
4
+ *
5
+ * `init` builds that directory from the genre baseline plus a template overlay. An import already
6
+ * HAS the finished article: the Creator's `source/` IS a project's `src/work/`, baseline files
7
+ * included (the export carries BitmagicPlayerCharacter.ts, Constants.ts and the rest alongside the
8
+ * game's own code, because the web lane's work copy is the same derived tree). So the export's
9
+ * files are written verbatim and nothing is overlaid on top of them — an overlay here would
10
+ * silently replace the creator's Game.ts with a template's.
11
+ *
12
+ * Two adjustments, and only two:
13
+ *
14
+ * - The design docs move to the project root. `bitmagic cover`, `judge` and `reference` all read
15
+ * `<root>/GAME-DESIGN.md`; in the web lane the same file lives beside the code because there is
16
+ * no root to put it at. Left where it was, the creator's design would be invisible to every
17
+ * command that wants it and `cover` would report the project has none.
18
+ * - `gameId` inside game.json and world.json, but only when the caller minted a new one. Both
19
+ * files carry the id the game was exported under, and a project whose bitmagic.json says one id
20
+ * while its world.json says another is a project whose publishes disagree with its assets.
21
+ */
22
+ import * as fs from 'fs';
23
+ import * as path from 'path';
24
+ import { CliError } from '../errors.js';
25
+ import { aliasSourceDir } from './aliases.js';
26
+ import { vendorEngine, writeProjectFiles } from './project.js';
27
+ /**
28
+ * Documents the CLI lane keeps at the project ROOT, lifted out of the export's `source/`.
29
+ *
30
+ * `GAME-DESIGN.md` is read by `cover`, `judge` and `reference`, all of which look at the root.
31
+ * `mechanics-plan.md` is where AGENTS.md tells the agent its build order lives, and that
32
+ * instruction names the root too. Both are prose — moving them cannot break a build, and leaving
33
+ * them cannot be noticed until a command quietly reports the project has no design.
34
+ */
35
+ export const ROOT_DOC_FILES = ['GAME-DESIGN.md', 'mechanics-plan.md'];
36
+ /** The two files in `source/` that carry the game's own id. */
37
+ const GAME_ID_FILES = ['game.json', 'world.json'];
38
+ /**
39
+ * Rewrite the `gameId` of a `source/` JSON file, returning the new bytes.
40
+ *
41
+ * Throws rather than skipping: these are the two files the engine loads to run the game at all, so
42
+ * one that is not a JSON object is a broken export, and an import that silently carried it through
43
+ * would fail far later with a blank screen instead of here with a filename.
44
+ */
45
+ function withGameId(file, gameId) {
46
+ const text = Buffer.from(file.contents).toString('utf-8');
47
+ let parsed;
48
+ try {
49
+ parsed = JSON.parse(text);
50
+ }
51
+ catch {
52
+ throw new CliError(`The export's ${file.path} is not valid JSON, so its game id cannot be updated.`);
53
+ }
54
+ if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
55
+ throw new CliError(`The export's ${file.path} does not contain an object.`);
56
+ }
57
+ const updated = { ...parsed, gameId };
58
+ return Buffer.from(`${JSON.stringify(updated, null, 2)}\n`, 'utf-8');
59
+ }
60
+ /**
61
+ * Guard against an export entry escaping the directory it is written into.
62
+ *
63
+ * Zip entry names come from the archive, not from us, and `..` in one is the classic way an
64
+ * archive writes outside its target. The export is produced by our own server, so this has never
65
+ * fired — which is exactly why it is a hard failure rather than a filter: an entry that needs it
66
+ * means something about the archive is not what this code believes.
67
+ */
68
+ function assertContained(root, filePath, entry) {
69
+ const resolved = path.resolve(filePath);
70
+ if (resolved !== root && !resolved.startsWith(root + path.sep)) {
71
+ throw new CliError(`The export entry "${entry}" would be written outside the project.`);
72
+ }
73
+ }
74
+ export function importProject(options) {
75
+ const { targetDir, extractedEngineDir, source, metadata, projectName, rewriteGameId } = options;
76
+ vendorEngine(extractedEngineDir, targetDir);
77
+ const workDir = path.join(targetDir, aliasSourceDir('work'));
78
+ const workRoot = path.resolve(workDir);
79
+ const docRoot = path.resolve(targetDir);
80
+ fs.mkdirSync(workDir, { recursive: true });
81
+ const result = { workFiles: [], rootDocs: [], rewritten: [] };
82
+ for (const file of source.sourceFiles) {
83
+ const lifted = ROOT_DOC_FILES.includes(file.path);
84
+ const destination = lifted ? path.join(targetDir, file.path) : path.join(workDir, file.path);
85
+ assertContained(lifted ? docRoot : workRoot, destination, file.path);
86
+ let contents = file.contents;
87
+ if (rewriteGameId !== undefined && GAME_ID_FILES.includes(file.path)) {
88
+ contents = withGameId(file, rewriteGameId);
89
+ result.rewritten.push(file.path);
90
+ }
91
+ fs.mkdirSync(path.dirname(destination), { recursive: true });
92
+ fs.writeFileSync(destination, contents);
93
+ if (lifted)
94
+ result.rootDocs.push(file.path);
95
+ else
96
+ result.workFiles.push(file.path);
97
+ }
98
+ writeProjectFiles({
99
+ targetDir,
100
+ metadata,
101
+ projectName,
102
+ // The creator's own design document came out of the export; rendering the empty skeleton over
103
+ // it is the one way this conversion could destroy something it was asked to preserve.
104
+ gameDesign: result.rootDocs.includes('GAME-DESIGN.md') ? 'keep' : 'render',
105
+ });
106
+ return result;
107
+ }
108
+ //# sourceMappingURL=import-project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"import-project.js","sourceRoot":"","sources":["../../src/scaffold/import-project.ts"],"names":[],"mappings":"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"}
@@ -871,6 +871,10 @@ are configured in **code** — there is no panel for them.
871
871
  …)\` for a gameplay action. The first strands phone players and the engine logs a
872
872
  \`[mobile-parity]\` error on game start; the raw listener strands them **silently** — the parity
873
873
  check cannot see a listener that never went through the engine.
874
+ - **A game played by tapping the scene** (board, builder, strategy) has nothing for a joystick to
875
+ drive, and verify treats the missing touch controls as declared when the engine can see why:
876
+ build no player controller (the \`no-character\` template) or declare \`"hasPlayerCharacter":
877
+ false\` in \`worldProfileData\` — never \`forceDisable()\` the controls to get there.
874
878
  - **\`bitmagic verify\` enforces this.** Every run reports the parity gaps, naming the key and the
875
879
  system that registered it — a warning normally, and a **failure** on a game whose
876
880
  \`primaryPlatform\` is \`mobile\`. \`bitmagic verify --platform mobile\` goes further and boots
@@ -1231,6 +1235,7 @@ the engine, already wired** — and hand-building a worse version of it is the m
1231
1235
  | Multiple levels or arenas | \`levels[]\` registry + \`engine.loadLevel()\` | \`level-system.md\` |
1232
1236
  | Voice input, speaking to NPCs | \`engine.enablePushToTalk()\` | \`voice-input.md\` |
1233
1237
  | A key for a new action — shoot, reload, boost, throw | \`registerCustomAction()\` / \`declareMobileActions()\` — one call binds the desktop key AND the phone button | \`control-system.md\` |
1238
+ | A game played by tapping the scene — board, builder, strategy, no player to move | No player controller (the \`no-character\` template) or \`hasPlayerCharacter: false\` in \`worldProfileData\` — the engine builds no joystick and verify treats the missing touch controls as declared | \`control-system.md\` |
1234
1239
  | The default player and its animation set | Already there | — |
1235
1240
 
1236
1241
  A built-in still covers the request when the human names a style ("a katana" → the built-in katana).
@@ -1261,7 +1266,9 @@ that I would otherwise have defaulted differently.
1261
1266
  ## Platform
1262
1267
  \`primaryPlatform\` in \`game.json\` — \`desktop\` or \`mobile\`. Plus \`worldProfileData.mobileOrientation\`
1263
1268
  in \`world.json\` when the game only works one way up. If \`mobile\`: every action needs a touch
1264
- button, and \`bitmagic verify\` fails the run otherwise.
1269
+ button, and \`bitmagic verify\` fails the run otherwise. A game played by tapping the scene (no
1270
+ player to move) either builds no player controller (the \`no-character\` template) or declares
1271
+ \`hasPlayerCharacter: false\`, so the engine and verify know there is no joystick to build.
1265
1272
 
1266
1273
  ## Slice 1 — the smallest playable thing
1267
1274
  - Core verb: the ONE thing the player does
@@ -1390,6 +1397,7 @@ tier 2.
1390
1397
  | Coordinates, forward direction, yaw, rotation, lookAt, spawn offsets | \`coordinate-system.md\` |
1391
1398
  | NPCs, enemies, creatures, companions, pets, followers | \`npc-system.md\` (routes to the four \`npc-*\` docs) |
1392
1399
  | NPC looks — block vs highres GLB, recolouring, animation packs | \`npc-appearance.md\` |
1400
+ | Changing a character's clothes/outfit AT RUNTIME — armour, uniform, costume swap | \`character-outfits.md\` |
1393
1401
  | NPC combat and death — HP, damage, ragdoll, exploding | \`npc-combat-death.md\` |
1394
1402
  | Respawning or bulk NPC populations, \`NpcManager\` | \`npc-managers.md\` |
1395
1403
  | NPC pathing, walkable targets, navmesh cell size | \`npc-navigation.md\` |
@@ -1 +1 @@
1
- {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"project-files.js","sourceRoot":"","sources":["../../src/scaffold/project-files.ts"],"names":[],"mappings":"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"}
@@ -146,4 +146,38 @@ export interface ScaffoldOptions {
146
146
  /** `bitmagic init --idea`, seeding GAME-DESIGN.md's Pitch. Absent leaves the skeleton empty. */
147
147
  idea?: string;
148
148
  }
149
+ /**
150
+ * Puts the platform's own code into the project: the vendored `engine/` tree and the service
151
+ * worker that has to sit beside it at the root.
152
+ *
153
+ * Split out of `scaffoldProject` so `importProject` gets the identical tree — including the
154
+ * "missing is a corrupt tarball" / "missing is just an older tarball" distinction the two
155
+ * constant lists above spend most of their comments on. A second copy of this loop would be a
156
+ * second place for that distinction to be got wrong.
157
+ */
158
+ export declare function vendorEngine(extractedEngineDir: string, targetDir: string): void;
159
+ export interface ProjectFileOptions {
160
+ targetDir: string;
161
+ metadata: ProjectMetadata;
162
+ projectName: string;
163
+ /** `bitmagic init --idea`, seeding GAME-DESIGN.md's Pitch. Ignored when `gameDesign` is 'keep'. */
164
+ idea?: string;
165
+ /**
166
+ * Whether to write GAME-DESIGN.md at all.
167
+ *
168
+ * 'keep' is for `import`, which lifts the creator's own design document out of the export and
169
+ * must not then overwrite it with an empty skeleton. Everything else about the file set is
170
+ * identical, which is why this is a flag rather than a second function.
171
+ */
172
+ gameDesign?: 'render' | 'keep';
173
+ }
174
+ /**
175
+ * Writes every generated file a Bitmagic project has — the platform-owned ones, and the
176
+ * creator-owned ones seeded once.
177
+ *
178
+ * Shared by `scaffoldProject` and `importProject` so the two lanes cannot drift on what a project
179
+ * contains. What belongs in PLATFORM_GENERATED_FILES, and what deliberately stays out of it, is
180
+ * argued on that constant.
181
+ */
182
+ export declare function writeProjectFiles(options: ProjectFileOptions): void;
149
183
  export declare function scaffoldProject(options: ScaffoldOptions): void;