@bitmagic/cli 0.1.52-dev.0 → 0.1.52-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. package/README.md +178 -6
  2. package/dist/assets/add.d.ts +40 -0
  3. package/dist/assets/add.js +229 -0
  4. package/dist/assets/add.js.map +1 -0
  5. package/dist/assets/entry.d.ts +44 -0
  6. package/dist/assets/entry.js +71 -0
  7. package/dist/assets/entry.js.map +1 -0
  8. package/dist/assets/file-kind.d.ts +61 -0
  9. package/dist/assets/file-kind.js +195 -0
  10. package/dist/assets/file-kind.js.map +1 -0
  11. package/dist/assets/list.d.ts +27 -0
  12. package/dist/assets/list.js +50 -0
  13. package/dist/assets/list.js.map +1 -0
  14. package/dist/assets/remove.d.ts +50 -0
  15. package/dist/assets/remove.js +91 -0
  16. package/dist/assets/remove.js.map +1 -0
  17. package/dist/assets/voxelize-glb.d.ts +37 -0
  18. package/dist/assets/voxelize-glb.js +65 -0
  19. package/dist/assets/voxelize-glb.js.map +1 -0
  20. package/dist/assets/vxl-summary.d.ts +32 -0
  21. package/dist/assets/vxl-summary.js +118 -0
  22. package/dist/assets/vxl-summary.js.map +1 -0
  23. package/dist/bin.js +25 -0
  24. package/dist/bin.js.map +1 -1
  25. package/dist/browser-gl.d.ts +46 -8
  26. package/dist/browser-gl.js +54 -26
  27. package/dist/browser-gl.js.map +1 -1
  28. package/dist/cli.d.ts +22 -0
  29. package/dist/cli.js +17 -1
  30. package/dist/cli.js.map +1 -1
  31. package/dist/commands/assets.d.ts +56 -0
  32. package/dist/commands/assets.js +328 -0
  33. package/dist/commands/assets.js.map +1 -0
  34. package/dist/commands/cover.js +2 -3
  35. package/dist/commands/cover.js.map +1 -1
  36. package/dist/commands/forge.d.ts +7 -9
  37. package/dist/commands/forge.js +12 -14
  38. package/dist/commands/forge.js.map +1 -1
  39. package/dist/commands/generate.d.ts +41 -9
  40. package/dist/commands/generate.js +234 -54
  41. package/dist/commands/generate.js.map +1 -1
  42. package/dist/commands/init.js +19 -12
  43. package/dist/commands/init.js.map +1 -1
  44. package/dist/commands/judge.d.ts +36 -0
  45. package/dist/commands/judge.js +216 -0
  46. package/dist/commands/judge.js.map +1 -0
  47. package/dist/commands/levels.d.ts +33 -0
  48. package/dist/commands/levels.js +241 -0
  49. package/dist/commands/levels.js.map +1 -0
  50. package/dist/commands/number-flag.d.ts +7 -0
  51. package/dist/commands/number-flag.js +38 -0
  52. package/dist/commands/number-flag.js.map +1 -0
  53. package/dist/commands/publish.js +13 -0
  54. package/dist/commands/publish.js.map +1 -1
  55. package/dist/commands/reset-account.js +2 -8
  56. package/dist/commands/reset-account.js.map +1 -1
  57. package/dist/commands/run-deps.d.ts +27 -0
  58. package/dist/commands/run-deps.js +43 -0
  59. package/dist/commands/run-deps.js.map +1 -0
  60. package/dist/commands/verify.js +3 -3
  61. package/dist/commands/verify.js.map +1 -1
  62. package/dist/editor/journal.d.ts +48 -1
  63. package/dist/editor/journal.js +44 -0
  64. package/dist/editor/journal.js.map +1 -1
  65. package/dist/editor/previews.d.ts +6 -0
  66. package/dist/editor/previews.js +16 -0
  67. package/dist/editor/previews.js.map +1 -1
  68. package/dist/editor/server.js +228 -53
  69. package/dist/editor/server.js.map +1 -1
  70. package/dist/editor/shell-page.js +221 -116
  71. package/dist/editor/shell-page.js.map +1 -1
  72. package/dist/editor/voxel-save.d.ts +47 -0
  73. package/dist/editor/voxel-save.js +49 -0
  74. package/dist/editor/voxel-save.js.map +1 -0
  75. package/dist/errors.d.ts +10 -0
  76. package/dist/errors.js +16 -0
  77. package/dist/errors.js.map +1 -1
  78. package/dist/forge/apply-modifications.d.ts +18 -1
  79. package/dist/forge/apply-modifications.js +15 -32
  80. package/dist/forge/apply-modifications.js.map +1 -1
  81. package/dist/forge/browser-host.js +9 -4
  82. package/dist/forge/browser-host.js.map +1 -1
  83. package/dist/forge/voxelize-session.d.ts +61 -0
  84. package/dist/forge/voxelize-session.js +137 -0
  85. package/dist/forge/voxelize-session.js.map +1 -0
  86. package/dist/generate/model.d.ts +36 -0
  87. package/dist/generate/model.js +90 -0
  88. package/dist/generate/model.js.map +1 -0
  89. package/dist/generate/prop.d.ts +52 -4
  90. package/dist/generate/prop.js +169 -102
  91. package/dist/generate/prop.js.map +1 -1
  92. package/dist/generate/stream.d.ts +7 -0
  93. package/dist/generate/stream.js +2 -1
  94. package/dist/generate/stream.js.map +1 -1
  95. package/dist/generate/vehicle.js +5 -85
  96. package/dist/generate/vehicle.js.map +1 -1
  97. package/dist/http/signed-upload.d.ts +55 -0
  98. package/dist/http/signed-upload.js +168 -0
  99. package/dist/http/signed-upload.js.map +1 -0
  100. package/dist/judge/facts.d.ts +18 -0
  101. package/dist/judge/facts.js +180 -0
  102. package/dist/judge/facts.js.map +1 -0
  103. package/dist/judge/record.d.ts +16 -0
  104. package/dist/judge/record.js +55 -0
  105. package/dist/judge/record.js.map +1 -0
  106. package/dist/judge/stream.d.ts +36 -0
  107. package/dist/judge/stream.js +122 -0
  108. package/dist/judge/stream.js.map +1 -0
  109. package/dist/levels/registry.d.ts +88 -0
  110. package/dist/levels/registry.js +309 -0
  111. package/dist/levels/registry.js.map +1 -0
  112. package/dist/messages/check.d.ts +30 -0
  113. package/dist/messages/check.js +119 -0
  114. package/dist/messages/check.js.map +1 -0
  115. package/dist/messages/notice.d.ts +58 -0
  116. package/dist/messages/notice.js +54 -0
  117. package/dist/messages/notice.js.map +1 -0
  118. package/dist/messages/refresh.d.ts +19 -0
  119. package/dist/messages/refresh.js +42 -0
  120. package/dist/messages/refresh.js.map +1 -0
  121. package/dist/project/jobs.d.ts +1 -1
  122. package/dist/project/jobs.js.map +1 -1
  123. package/dist/publish/client.d.ts +13 -0
  124. package/dist/publish/client.js +13 -34
  125. package/dist/publish/client.js.map +1 -1
  126. package/dist/publish/platform.d.ts +46 -0
  127. package/dist/publish/platform.js +92 -0
  128. package/dist/publish/platform.js.map +1 -0
  129. package/dist/scaffold/project-files.d.ts +8 -0
  130. package/dist/scaffold/project-files.js +192 -34
  131. package/dist/scaffold/project-files.js.map +1 -1
  132. package/dist/scaffold/project.js +2 -1
  133. package/dist/scaffold/project.js.map +1 -1
  134. package/dist/verify/browser.d.ts +11 -6
  135. package/dist/verify/browser.js +31 -15
  136. package/dist/verify/browser.js.map +1 -1
  137. package/dist/verify/iterate.js +3 -3
  138. package/dist/verify/iterate.js.map +1 -1
  139. package/package.json +4 -4
@@ -0,0 +1,32 @@
1
+ export interface VxlSummary {
2
+ version: number;
3
+ minVoxelSize: number;
4
+ boundingBox: {
5
+ minX: number;
6
+ minY: number;
7
+ minZ: number;
8
+ maxX: number;
9
+ maxY: number;
10
+ maxZ: number;
11
+ };
12
+ fragmentCount: number;
13
+ /** Absent when the fragment table could not be walked to its end. */
14
+ voxelCount?: number;
15
+ }
16
+ /** True when the first four bytes are the VXL3 magic — cheap, no copy, no decompression. */
17
+ export declare function isVxl3(bytes: Uint8Array): boolean;
18
+ /**
19
+ * Read a VXL3 file's header. Returns `null` for anything that is not a well-formed VXL3 — a legacy
20
+ * JSON `.vxl`, a truncated file, an unknown compression id — so the caller can name the problem
21
+ * instead of writing an asset entry the engine would then fail to load.
22
+ */
23
+ export declare function summarizeVxl(bytes: Uint8Array): VxlSummary | null;
24
+ /**
25
+ * True when these bytes really are a binary GLB.
26
+ *
27
+ * Checked before `assets add` uploads a `.glb` and spends a minute launching a browser: a `.gltf`
28
+ * renamed, a truncated download or a Git-LFS pointer otherwise sails through classification and
29
+ * fails inside the engine, with the bytes already in storage and no way to delete them. The `.vxl`
30
+ * lane has always had this via `isVxl3`; this is the same guard for the other binary kind.
31
+ */
32
+ export declare function isGlb(bytes: Uint8Array): boolean;
@@ -0,0 +1,118 @@
1
+ /**
2
+ * The metadata a `.vxl` file carries in its own header, read here so `bitmagic assets add x.vxl`
3
+ * can record `boundingBox` / `voxelSize` / `voxelCount` the way the Creator's upload does — the
4
+ * Creator gets them from game-play-agent's `/api/analyze-asset` (`AssetsController.parseVxlV3Summary`),
5
+ * which a CLI project cannot reach, and this is the same read of the same bytes.
6
+ *
7
+ * Only what the fixed 48-byte body header states outright is trusted unconditionally: bounds,
8
+ * LOD-0 voxel size and fragment count. `voxelCount` is the sum of the LOD-0 fragments' leaf counts,
9
+ * found by walking the fragment table (its stride is `16 + leafCount × (7 + paletteIdxBytes)` for
10
+ * every version through v8 — the columnar and emissive/slot additions changed what is INSIDE a
11
+ * fragment and what follows the table, not its size). Should a future version change that, the
12
+ * walk runs off the end and the count is simply omitted rather than reported wrong.
13
+ *
14
+ * Layout reference: game/src/engine/VxlV3Format.ts (the wire-format doc comment at its top).
15
+ */
16
+ import * as zlib from 'zlib';
17
+ /** "VXL3" little-endian, as `VxlV3Format.ts` writes it. */
18
+ const VXL3_MAGIC = 0x33_4c_58_56;
19
+ const WRAPPER_BYTES = 5;
20
+ const BODY_HEADER_BYTES = 48;
21
+ /**
22
+ * The versions the engine's own decoder accepts (`VxlV3Format.ts`: 3 no-LOD, 4 LOD trailer,
23
+ * 5 columnar, 6 emissive, 7 slots, 8 per-LOD material columns, 9 block types).
24
+ *
25
+ * Checked rather than merely recorded: this header parse only reads the fixed 48-byte prologue,
26
+ * which a FUTURE version could keep byte-compatible while changing what follows. Accepting such a
27
+ * file would write an `assets[]` entry the vendored engine then throws on at load — the exact
28
+ * outcome returning `null` exists to prevent.
29
+ */
30
+ const MIN_SUPPORTED_VERSION = 3;
31
+ const MAX_SUPPORTED_VERSION = 9;
32
+ /** True when the first four bytes are the VXL3 magic — cheap, no copy, no decompression. */
33
+ export function isVxl3(bytes) {
34
+ if (bytes.byteLength < 4)
35
+ return false;
36
+ return new DataView(bytes.buffer, bytes.byteOffset, 4).getUint32(0, true) === VXL3_MAGIC;
37
+ }
38
+ /**
39
+ * Read a VXL3 file's header. Returns `null` for anything that is not a well-formed VXL3 — a legacy
40
+ * JSON `.vxl`, a truncated file, an unknown compression id — so the caller can name the problem
41
+ * instead of writing an asset entry the engine would then fail to load.
42
+ */
43
+ export function summarizeVxl(bytes) {
44
+ // Only the WRAPPER is guaranteed to be on disk at full size — the body header's 48 bytes are
45
+ // measured after decompression below. A gzipped body compresses well under 48 bytes for a
46
+ // near-empty asset, and gating on the raw length here rejected such files as malformed.
47
+ if (!isVxl3(bytes) || bytes.byteLength < WRAPPER_BYTES)
48
+ return null;
49
+ const compressionId = bytes[4];
50
+ const payload = bytes.subarray(WRAPPER_BYTES);
51
+ let body;
52
+ if (compressionId === 1) {
53
+ try {
54
+ body = new Uint8Array(zlib.gunzipSync(payload));
55
+ }
56
+ catch {
57
+ return null;
58
+ }
59
+ }
60
+ else if (compressionId === 0) {
61
+ body = payload;
62
+ }
63
+ else {
64
+ return null;
65
+ }
66
+ if (body.byteLength < BODY_HEADER_BYTES)
67
+ return null;
68
+ const view = new DataView(body.buffer, body.byteOffset, body.byteLength);
69
+ const version = view.getUint32(0, true);
70
+ if (version < MIN_SUPPORTED_VERSION || version > MAX_SUPPORTED_VERSION)
71
+ return null;
72
+ const minVoxelSize = view.getFloat32(4, true);
73
+ const boundingBox = {
74
+ minX: view.getFloat32(16, true),
75
+ minY: view.getFloat32(20, true),
76
+ minZ: view.getFloat32(24, true),
77
+ maxX: view.getFloat32(28, true),
78
+ maxY: view.getFloat32(32, true),
79
+ maxZ: view.getFloat32(36, true),
80
+ };
81
+ const paletteIdxBytes = body[41];
82
+ if (paletteIdxBytes !== 1 && paletteIdxBytes !== 2)
83
+ return null;
84
+ const paletteCount = view.getUint16(42, true);
85
+ const fragmentCount = view.getUint16(44, true);
86
+ const summary = { version, minVoxelSize, boundingBox, fragmentCount };
87
+ // Best-effort leaf total. Every fragment header is 16 bytes (leafCount + aabb) followed by
88
+ // leafCount records of 7 + paletteIdxBytes bytes, however those bytes are arranged inside.
89
+ const leafBytes = 7 + paletteIdxBytes;
90
+ let cursor = BODY_HEADER_BYTES + paletteCount * 2;
91
+ let voxelCount = 0;
92
+ for (let f = 0; f < fragmentCount; f++) {
93
+ if (cursor + 16 > body.byteLength)
94
+ return summary;
95
+ const leafCount = view.getUint32(cursor, true);
96
+ voxelCount += leafCount;
97
+ cursor += 16 + leafCount * leafBytes;
98
+ if (cursor > body.byteLength)
99
+ return summary;
100
+ }
101
+ return { ...summary, voxelCount };
102
+ }
103
+ /** "glTF" little-endian — the magic every binary GLB starts with (`VoxelMessageHandlers` checks it too). */
104
+ const GLB_MAGIC = 0x46546c67;
105
+ /**
106
+ * True when these bytes really are a binary GLB.
107
+ *
108
+ * Checked before `assets add` uploads a `.glb` and spends a minute launching a browser: a `.gltf`
109
+ * renamed, a truncated download or a Git-LFS pointer otherwise sails through classification and
110
+ * fails inside the engine, with the bytes already in storage and no way to delete them. The `.vxl`
111
+ * lane has always had this via `isVxl3`; this is the same guard for the other binary kind.
112
+ */
113
+ export function isGlb(bytes) {
114
+ if (bytes.byteLength < 12)
115
+ return false;
116
+ return new DataView(bytes.buffer, bytes.byteOffset, 4).getUint32(0, true) === GLB_MAGIC;
117
+ }
118
+ //# sourceMappingURL=vxl-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vxl-summary.js","sourceRoot":"","sources":["../../src/assets/vxl-summary.ts"],"names":[],"mappings":"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"}
package/dist/bin.js CHANGED
@@ -4,6 +4,8 @@ import { main } from './cli.js';
4
4
  import { CliError } from './errors.js';
5
5
  import { readPinnedEnvironment } from './config/environments.js';
6
6
  import { refreshUpdateCacheInBackground, startupNotice } from './update/check.js';
7
+ import { pendingMessagesNotice } from './messages/check.js';
8
+ import { resolveEnvironmentForCommand } from './config/environments.js';
7
9
  import { currentCliVersion } from './update/cli-version.js';
8
10
  // The version is READ here, not at the import time of anything cli.ts pulls in — cli.test.ts
9
11
  // imports cli.ts for `subCommands`, and a version check triggered against the test runner is
@@ -20,6 +22,29 @@ const version = currentCliVersion();
20
22
  const notice = startupNotice(version, readPinnedEnvironment());
21
23
  if (notice !== null)
22
24
  console.error(notice);
25
+ // A SECOND line, and deliberately not folded into startupNotice's "at most one" rule. That rule
26
+ // exists to stop two contradictory `npm i -g` commands appearing in the same breath; a count of
27
+ // unread messages contradicts nothing and instructs nothing, so the two can coexist.
28
+ //
29
+ // Read from the cache written by a previous run — no network, no measurable time — and printed
30
+ // before the command runs so an early exit has still shown it. The cache is refreshed at the END
31
+ // of a command, where the environment and a token are already resolved (messages/refresh.ts).
32
+ //
33
+ // Known imprecision, shared with the notice above: citty has not parsed argv yet, so a one-off
34
+ // `--env=dev` is invisible HERE while the refresh does see it. The consequence is a nudge one
35
+ // run late after switching environments by flag, which is the same cost every first run pays.
36
+ const inboxNotice = pendingMessagesNotice(currentEnvironmentName());
37
+ if (inboxNotice !== null)
38
+ console.error(inboxNotice);
39
+ /** Where this command will point, as far as anything readable before argv is parsed can tell. */
40
+ function currentEnvironmentName() {
41
+ try {
42
+ return resolveEnvironmentForCommand().name;
43
+ }
44
+ catch {
45
+ return undefined;
46
+ }
47
+ }
23
48
  // Deliberately NOT awaited: this is for the next invocation, not this one. Bounded by its own
24
49
  // short timeout so a sulking registry cannot hold a finished command open. The version is passed
25
50
  // because it selects the dist-tag to ask about — a prerelease build tracks the `dev` line.
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AACjE,OAAO,EAAE,8BAA8B,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,6FAA6F;AAC7F,6FAA6F;AAC7F,+FAA+F;AAC/F,+BAA+B;AAC/B,EAAE;AACF,kGAAkG;AAClG,gGAAgG;AAChG,oFAAoF;AACpF,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;AACpC,oGAAoG;AACpG,qGAAqG;AACrG,gDAAgD;AAChD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAC,CAAC;AAC/D,IAAI,MAAM,KAAK,IAAI;IAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAE3C,8FAA8F;AAC9F,iGAAiG;AACjG,2FAA2F;AAC3F,KAAK,8BAA8B,CAAC,OAAO,CAAC,CAAC;AAE7C,wFAAwF;AACxF,+FAA+F;AAC/F,8FAA8F;AAC9F,gGAAgG;AAChG,2FAA2F;AAC3F,kGAAkG;AAClG,mGAAmG;AACnG,gGAAgG;AAChG,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,GAAI,IAAI,CAAC,IAAgC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC1G,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,qBAAqB,EAAwB,MAAM,0BAA0B,CAAC;AACvF,OAAO,EAAE,8BAA8B,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClF,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,OAAO,EAAE,4BAA4B,EAAE,MAAM,0BAA0B,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,6FAA6F;AAC7F,6FAA6F;AAC7F,+FAA+F;AAC/F,+BAA+B;AAC/B,EAAE;AACF,kGAAkG;AAClG,gGAAgG;AAChG,oFAAoF;AACpF,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;AACpC,oGAAoG;AACpG,qGAAqG;AACrG,gDAAgD;AAChD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,EAAE,qBAAqB,EAAE,CAAC,CAAC;AAC/D,IAAI,MAAM,KAAK,IAAI;IAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;AAE3C,gGAAgG;AAChG,gGAAgG;AAChG,qFAAqF;AACrF,EAAE;AACF,+FAA+F;AAC/F,iGAAiG;AACjG,8FAA8F;AAC9F,EAAE;AACF,+FAA+F;AAC/F,8FAA8F;AAC9F,8FAA8F;AAC9F,MAAM,WAAW,GAAG,qBAAqB,CAAC,sBAAsB,EAAE,CAAC,CAAC;AACpE,IAAI,WAAW,KAAK,IAAI;IAAE,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;AAErD,iGAAiG;AACjG,SAAS,sBAAsB;IAC7B,IAAI,CAAC;QACH,OAAO,4BAA4B,EAAE,CAAC,IAAI,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED,8FAA8F;AAC9F,iGAAiG;AACjG,2FAA2F;AAC3F,KAAK,8BAA8B,CAAC,OAAO,CAAC,CAAC;AAE7C,wFAAwF;AACxF,+FAA+F;AAC/F,8FAA8F;AAC9F,gGAAgG;AAChG,2FAA2F;AAC3F,kGAAkG;AAClG,mGAAmG;AACnG,gGAAgG;AAChG,OAAO,CAAC,EAAE,GAAG,IAAI,EAAE,IAAI,EAAE,EAAE,GAAI,IAAI,CAAC,IAAgC,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC1G,IAAI,KAAK,YAAY,QAAQ,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -43,13 +43,10 @@ export type RendererChoice = 'webgpu' | 'webgl';
43
43
  /**
44
44
  * Chrome flags for the GL backend, given the environment and platform.
45
45
  *
46
- * Software GL is used when `CI=true` (GitHub-hosted runners have no GPU, and asking ANGLE for a
47
- * Vulkan device there just wastes the startup) or when `BITMAGIC_BROWSER_SOFTWARE_GL=true`, the
48
- * escape hatch for a machine whose driver makes the GPU path worse than the software one.
49
- *
50
- * Everywhere else the real GPU is requested. The Vulkan flags are Linux-only because they are only
51
- * a fix there: macOS headless already reaches the GPU through ANGLE's Metal backend, and asking it
52
- * for Vulkan would take that away.
46
+ * Software GL is forced wherever `usesSoftwareGl` holds. Everywhere else the real GPU is
47
+ * requested. The Vulkan flags are Linux-only because they are only a fix there: macOS headless
48
+ * already reaches the GPU through ANGLE's Metal backend, and asking it for Vulkan would take that
49
+ * away.
53
50
  */
54
51
  export declare function browserGlArgs(env: Record<string, string | undefined>, platform?: Platform): string[];
55
52
  /**
@@ -61,12 +58,53 @@ export declare function browserGlArgs(env: Record<string, string | undefined>, p
61
58
  * verify exists to catch.
62
59
  */
63
60
  export declare function browserRendererArgs(env: Record<string, string | undefined>, renderer: RendererChoice, platform?: Platform): string[];
61
+ /**
62
+ * How to launch Chrome for a renderer: headless or headed, and with which args.
63
+ *
64
+ * Headed exists for exactly one case — **WebGPU on Linux**, where headless Chrome cannot produce
65
+ * a real-GPU frame that a screenshot can see, in either compositing mode (measured on Chrome 151
66
+ * against an NVIDIA GPU with the Vulkan ICD installed):
67
+ *
68
+ * - With `--disable-gpu-compositing` (the WebGL fix above), WebGPU reports `enabled_readback`,
69
+ * Dawn reaches the native adapter and the game renders — but the presented frames never reach
70
+ * the compositor OR the canvas: `page.screenshot()` and an in-page `drawImage(canvas)` both
71
+ * come back black. Verify's black-frame detection then fails a healthy game.
72
+ * - Without it, GPU compositing comes up and WebGPU reports `enabled` — but Dawn's adapter
73
+ * request dies in the GPU process (`A valid external Instance reference no longer exists`),
74
+ * `requestAdapter()` resolves null, and the game silently runs its WebGL2 fallback, which the
75
+ * renderer probe rightly fails.
76
+ *
77
+ * Headed Chrome has neither problem: GPU compositing initialises against the display, Dawn gets
78
+ * the native adapter, and screenshots carry the real frame. So when webgpu is requested on Linux
79
+ * and a display exists, the plan is headed — with the window parked far off-screen so nothing
80
+ * flashes over the creator's desktop, and `--disable-backgrounding-occluded-windows` so Chrome
81
+ * does not throttle rendering in a window nobody can see. `--disable-gpu-compositing` is dropped
82
+ * in this mode: compositing is the point, and keeping the flag puts the run back in the black
83
+ * readback mode above.
84
+ *
85
+ * Everywhere else — webgl, macOS, CI, software GL, or a Linux box with no display (ssh, systemd,
86
+ * detached agents) — the plan is headless with the exact args `browserRendererArgs` always chose.
87
+ */
88
+ export interface BrowserLaunchPlan {
89
+ headless: boolean;
90
+ args: string[];
91
+ }
92
+ export declare function browserLaunchPlan(env: Record<string, string | undefined>, renderer: RendererChoice, platform?: Platform): BrowserLaunchPlan;
93
+ /**
94
+ * The plan for the automatic software-GL re-run: `browserLaunchPlan` as if
95
+ * `BITMAGIC_BROWSER_SOFTWARE_GL=true` had been set.
96
+ *
97
+ * Both verify paths (one-shot and `--watch`) relaunch through this after `shouldRetrySoftwareGl`
98
+ * says the machine's GPU stack is the likely culprit, so neither has to know which env var forces
99
+ * the fallback.
100
+ */
101
+ export declare function softwareGlLaunchPlan(env: Record<string, string | undefined>, renderer: RendererChoice, platform?: Platform): BrowserLaunchPlan;
64
102
  /**
65
103
  * Whether a failed run is worth one automatic re-run on software GL.
66
104
  *
67
105
  * A lost WebGL context is a property of the machine's GPU/driver/compositor stack, not of the
68
106
  * game (see the file header) — the software path sidesteps that stack entirely. Pointless when
69
- * software GL was already in effect, which is what the env checks establish.
107
+ * software GL was already in effect, which is what `usesSoftwareGl` establishes.
70
108
  */
71
109
  export declare function shouldRetrySoftwareGl(observations: {
72
110
  webglContextLost: boolean;
@@ -37,18 +37,25 @@
37
37
  /** Chrome falls back to SwiftShader on its own; these force it, for machines with no GPU at all. */
38
38
  const SOFTWARE_GL_ARGS = ['--enable-unsafe-swiftshader', '--use-gl=angle', '--use-angle=swiftshader'];
39
39
  /**
40
- * Chrome flags for the GL backend, given the environment and platform.
40
+ * Whether software GL is in force rather than the machine's real GPU.
41
41
  *
42
- * Software GL is used when `CI=true` (GitHub-hosted runners have no GPU, and asking ANGLE for a
43
- * Vulkan device there just wastes the startup) or when `BITMAGIC_BROWSER_SOFTWARE_GL=true`, the
44
- * escape hatch for a machine whose driver makes the GPU path worse than the software one.
42
+ * True on CI (GitHub-hosted runners have no GPU, and asking ANGLE for a Vulkan device there just
43
+ * wastes the startup), and under `BITMAGIC_BROWSER_SOFTWARE_GL=true` the escape hatch for a
44
+ * machine whose driver makes the GPU path worse than the software one.
45
+ */
46
+ function usesSoftwareGl(env) {
47
+ return env.CI === 'true' || env.BITMAGIC_BROWSER_SOFTWARE_GL === 'true';
48
+ }
49
+ /**
50
+ * Chrome flags for the GL backend, given the environment and platform.
45
51
  *
46
- * Everywhere else the real GPU is requested. The Vulkan flags are Linux-only because they are only
47
- * a fix there: macOS headless already reaches the GPU through ANGLE's Metal backend, and asking it
48
- * for Vulkan would take that away.
52
+ * Software GL is forced wherever `usesSoftwareGl` holds. Everywhere else the real GPU is
53
+ * requested. The Vulkan flags are Linux-only because they are only a fix there: macOS headless
54
+ * already reaches the GPU through ANGLE's Metal backend, and asking it for Vulkan would take that
55
+ * away.
49
56
  */
50
57
  export function browserGlArgs(env, platform = process.platform) {
51
- if (env.CI === 'true' || env.BITMAGIC_BROWSER_SOFTWARE_GL === 'true')
58
+ if (usesSoftwareGl(env))
52
59
  return [...SOFTWARE_GL_ARGS];
53
60
  if (platform !== 'linux')
54
61
  return ['--enable-unsafe-swiftshader'];
@@ -88,31 +95,52 @@ export function browserRendererArgs(env, renderer, platform = process.platform)
88
95
  */
89
96
  function mergeEnableFeatures(args, features) {
90
97
  const PREFIX = '--enable-features=';
91
- const merged = [];
92
- for (const arg of args) {
93
- if (!arg.startsWith(PREFIX))
94
- continue;
95
- for (const value of arg.slice(PREFIX.length).split(',')) {
96
- if (value !== '' && !merged.includes(value))
97
- merged.push(value);
98
- }
99
- }
100
- for (const value of features) {
101
- if (!merged.includes(value))
102
- merged.push(value);
103
- }
104
- return [...args.filter((arg) => !arg.startsWith(PREFIX)), `${PREFIX}${merged.join(',')}`];
98
+ const present = args
99
+ .filter((arg) => arg.startsWith(PREFIX))
100
+ .flatMap((arg) => arg.slice(PREFIX.length).split(','));
101
+ const merged = new Set([...present, ...features].filter((value) => value !== ''));
102
+ return [...args.filter((arg) => !arg.startsWith(PREFIX)), `${PREFIX}${[...merged].join(',')}`];
103
+ }
104
+ /** An off-screen position keeps the headed window out of sight without occluding-throttle risk. */
105
+ const HEADED_OFFSCREEN_ARGS = [
106
+ '--window-position=-2400,-2400',
107
+ '--disable-backgrounding-occluded-windows',
108
+ ];
109
+ function hasDisplay(env) {
110
+ return Boolean(env.DISPLAY || env.WAYLAND_DISPLAY);
111
+ }
112
+ export function browserLaunchPlan(env, renderer, platform = process.platform) {
113
+ const args = browserRendererArgs(env, renderer, platform);
114
+ const headedWebgpu = renderer === 'webgpu'
115
+ && platform === 'linux'
116
+ && !usesSoftwareGl(env)
117
+ && hasDisplay(env);
118
+ if (!headedWebgpu)
119
+ return { headless: true, args };
120
+ return {
121
+ headless: false,
122
+ args: [...args.filter((arg) => arg !== '--disable-gpu-compositing'), ...HEADED_OFFSCREEN_ARGS],
123
+ };
124
+ }
125
+ /**
126
+ * The plan for the automatic software-GL re-run: `browserLaunchPlan` as if
127
+ * `BITMAGIC_BROWSER_SOFTWARE_GL=true` had been set.
128
+ *
129
+ * Both verify paths (one-shot and `--watch`) relaunch through this after `shouldRetrySoftwareGl`
130
+ * says the machine's GPU stack is the likely culprit, so neither has to know which env var forces
131
+ * the fallback.
132
+ */
133
+ export function softwareGlLaunchPlan(env, renderer, platform = process.platform) {
134
+ return browserLaunchPlan({ ...env, BITMAGIC_BROWSER_SOFTWARE_GL: 'true' }, renderer, platform);
105
135
  }
106
136
  /**
107
137
  * Whether a failed run is worth one automatic re-run on software GL.
108
138
  *
109
139
  * A lost WebGL context is a property of the machine's GPU/driver/compositor stack, not of the
110
140
  * game (see the file header) — the software path sidesteps that stack entirely. Pointless when
111
- * software GL was already in effect, which is what the env checks establish.
141
+ * software GL was already in effect, which is what `usesSoftwareGl` establishes.
112
142
  */
113
143
  export function shouldRetrySoftwareGl(observations, env) {
114
- return (observations.webglContextLost
115
- && env.CI !== 'true'
116
- && env.BITMAGIC_BROWSER_SOFTWARE_GL !== 'true');
144
+ return observations.webglContextLost && !usesSoftwareGl(env);
117
145
  }
118
146
  //# sourceMappingURL=browser-gl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"browser-gl.js","sourceRoot":"","sources":["../src/browser-gl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AAUH,oGAAoG;AACpG,MAAM,gBAAgB,GAAG,CAAC,6BAA6B,EAAE,gBAAgB,EAAE,yBAAyB,CAAC,CAAC;AAEtG;;;;;;;;;;GAUG;AACH,MAAM,UAAU,aAAa,CAC3B,GAAuC,EACvC,WAAqB,OAAO,CAAC,QAAQ;IAErC,IAAI,GAAG,CAAC,EAAE,KAAK,MAAM,IAAI,GAAG,CAAC,4BAA4B,KAAK,MAAM;QAAE,OAAO,CAAC,GAAG,gBAAgB,CAAC,CAAC;IACnG,IAAI,QAAQ,KAAK,OAAO;QAAE,OAAO,CAAC,6BAA6B,CAAC,CAAC;IACjE,OAAO;QACL,oBAAoB;QACpB,0BAA0B;QAC1B,6FAA6F;QAC7F,uEAAuE;QACvE,wBAAwB;QACxB,cAAc;QACd,2FAA2F;QAC3F,mBAAmB;QACnB,2BAA2B;QAC3B,6BAA6B;KAC9B,CAAC;AACJ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CACjC,GAAuC,EACvC,QAAwB,EACxB,WAAqB,OAAO,CAAC,QAAQ;IAErC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAC1C,IAAI,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvC,OAAO,mBAAmB,CAAC,CAAC,GAAG,IAAI,EAAE,wBAAwB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;GAMG;AACH,SAAS,mBAAmB,CAAC,IAAc,EAAE,QAAkB;IAC7D,MAAM,MAAM,GAAG,oBAAoB,CAAC;IACpC,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QACtC,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YACxD,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;gBAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IACD,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAClD,CAAC;IACD,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAC5F,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CACnC,YAA2C,EAC3C,GAAuC;IAEvC,OAAO,CACL,YAAY,CAAC,gBAAgB;WAC1B,GAAG,CAAC,EAAE,KAAK,MAAM;WACjB,GAAG,CAAC,4BAA4B,KAAK,MAAM,CAC/C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"browser-gl.js","sourceRoot":"","sources":["../src/browser-gl.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts CHANGED
@@ -9,6 +9,8 @@ import { type CommandReport } from './telemetry/report.js';
9
9
  export interface CommandRunDeps {
10
10
  begin: (input: BeginCommandInput) => void;
11
11
  report: (report: CommandReport) => Promise<void>;
12
+ /** Refresh the cached unread-messages count for the NEXT run (see messages/refresh.ts). */
13
+ refreshMessages: () => Promise<void>;
12
14
  now: () => number;
13
15
  }
14
16
  /**
@@ -229,6 +231,8 @@ declare const rawCommands: {
229
231
  };
230
232
  }>;
231
233
  generate: CommandDef<ArgsDef>;
234
+ assets: CommandDef<ArgsDef>;
235
+ levels: CommandDef<ArgsDef>;
232
236
  cover: CommandDef<{
233
237
  readonly prompt: {
234
238
  readonly type: "string";
@@ -251,6 +255,20 @@ declare const rawCommands: {
251
255
  readonly description: "Print the result as JSON on stdout; all progress goes to stderr.";
252
256
  };
253
257
  }>;
258
+ judge: CommandDef<{
259
+ readonly genre: {
260
+ readonly type: "string";
261
+ readonly description: "Genre hint for the rubric: platformer, racing, shooter, combat, driving, tower-defense.";
262
+ };
263
+ readonly 'min-score': {
264
+ readonly type: "string";
265
+ readonly description: "Fail (exit 4) when the overall score is below this 1-10 bar. Without it the judge informs and exits 0.";
266
+ };
267
+ readonly json: {
268
+ readonly type: "boolean";
269
+ readonly description: "Print the result as JSON on stdout; all progress goes to stderr.";
270
+ };
271
+ }>;
254
272
  forge: CommandDef<{
255
273
  readonly prompt: {
256
274
  readonly type: "string";
@@ -280,6 +298,10 @@ declare const rawCommands: {
280
298
  readonly type: "boolean";
281
299
  readonly description: "Build a custom place (arena, fortress, camp).";
282
300
  };
301
+ readonly 'make-start': {
302
+ readonly type: "boolean";
303
+ readonly description: "Boot the game into this level. Without it, only a game's FIRST forge becomes the start level, so a later forge lands in the level list unseen.";
304
+ };
283
305
  readonly json: {
284
306
  readonly type: "boolean";
285
307
  readonly description: "Print the result as JSON on stdout; all progress goes to stderr.";
package/dist/cli.js CHANGED
@@ -3,6 +3,7 @@ import { CliError } from './errors.js';
3
3
  import { jsonErrorResult } from './output.js';
4
4
  import { beginCommand } from './telemetry/command-context.js';
5
5
  import { crashCategory, reportCommandEvent } from './telemetry/report.js';
6
+ import { refreshUnreadMessages } from './messages/refresh.js';
6
7
  import { loginCommand } from './commands/login.js';
7
8
  import { logoutCommand } from './commands/logout.js';
8
9
  import { resetAccountCommand } from './commands/reset-account.js';
@@ -18,7 +19,10 @@ import { reloadCommand } from './commands/reload.js';
18
19
  import { verifyCommand } from './commands/verify.js';
19
20
  import { buildCommand } from './commands/build.js';
20
21
  import { generateCommand } from './commands/generate.js';
22
+ import { assetsCommand } from './commands/assets.js';
23
+ import { levelsCommand } from './commands/levels.js';
21
24
  import { coverCommand } from './commands/cover.js';
25
+ import { judgeCommand } from './commands/judge.js';
22
26
  import { forgeCommand } from './commands/forge.js';
23
27
  import { publishCommand } from './commands/publish.js';
24
28
  // citty's runMain() catches every error thrown from a command's `run()` internally and calls
@@ -46,6 +50,7 @@ function subCommandsOf(command) {
46
50
  const realRunDeps = {
47
51
  begin: beginCommand,
48
52
  report: reportCommandEvent,
53
+ refreshMessages: refreshUnreadMessages,
49
54
  now: Date.now,
50
55
  };
51
56
  /**
@@ -109,7 +114,15 @@ export function withCleanErrors(command, name = commandNameOf(command), deps = r
109
114
  // step backwards mid-command would otherwise send a negative duration, which api-server
110
115
  // rejects — discarding the outcome and the failure category along with it, rather than
111
116
  // just the one bad field.
112
- const finished = (outcome) => deps.report({ stage: 'finished', durationMs: Math.max(0, deps.now() - startedAt), ...outcome });
117
+ // Reported first, then the inbox count refreshed for the next run — both awaited, both
118
+ // bounded, for the same reason: process.exit may come immediately after and would cut a
119
+ // fire-and-forget request off mid-flight. Riding the wrapper means the count follows
120
+ // whatever environment the command actually resolved, and a logged-out creator never
121
+ // triggers a request at all (messages/refresh.ts).
122
+ const finished = async (outcome) => {
123
+ await deps.report({ stage: 'finished', durationMs: Math.max(0, deps.now() - startedAt), ...outcome });
124
+ await deps.refreshMessages();
125
+ };
113
126
  try {
114
127
  const result = await originalRun(context);
115
128
  await finished({ ok: true });
@@ -184,7 +197,10 @@ const rawCommands = {
184
197
  verify: verifyCommand,
185
198
  build: buildCommand,
186
199
  generate: generateCommand,
200
+ assets: assetsCommand,
201
+ levels: levelsCommand,
187
202
  cover: coverCommand,
203
+ judge: judgeCommand,
188
204
  forge: forgeCommand,
189
205
  publish: publishCommand,
190
206
  };
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,56 @@
1
+ import { type CommandRunDeps } from './run-deps.js';
2
+ import { type AddAssetResult } from '../assets/add.js';
3
+ import type { VoxelizeGlb } from '../assets/voxelize-glb.js';
4
+ import { type AssetRow } from '../assets/list.js';
5
+ /** The Creator's voxelize-dialog defaults (assetsVoxelizeDialog.ts), so a plain `add` bakes the same way. */
6
+ export declare const DEFAULT_MIN_VOXEL_SIZE = 0.1;
7
+ export declare const DEFAULT_MAX_VOXEL_SIZE = 0.5;
8
+ export interface AssetsRunDeps extends CommandRunDeps {
9
+ /** Test-only override for the headless bake, so the lane runs without Chrome. */
10
+ voxelize?: VoxelizeGlb;
11
+ }
12
+ /**
13
+ * Whether to fill the model's interior with voxels.
14
+ *
15
+ * `--hollow` and `--solid` are explicit; otherwise this mirrors `generate prop`'s size rule
16
+ * (`shouldFillInterior`), which the web lane has always applied: prop-scale objects fill solid so
17
+ * nothing reads as a shell when the camera clips inside, while building-scale ones stay hollow
18
+ * because a solid-filled building is millions of wasted voxels. `assets add` has no `fitBox`, so
19
+ * the only size it knows is `--height` — enough to catch the case that actually hurts.
20
+ */
21
+ export declare const SOLID_FILL_MAX_HEIGHT_M = 6;
22
+ export interface AddOptions {
23
+ file: string;
24
+ name?: string;
25
+ assetId?: string;
26
+ keepGlb: boolean;
27
+ force: boolean;
28
+ voxelSize?: string;
29
+ maxVoxelSize?: string;
30
+ height?: string;
31
+ hollow: boolean;
32
+ solid: boolean;
33
+ json: boolean;
34
+ deps?: AssetsRunDeps;
35
+ }
36
+ export declare function runAssetsAdd(options: AddOptions): Promise<AddAssetResult>;
37
+ export declare function runAssetsList(options: {
38
+ json: boolean;
39
+ deps?: AssetsRunDeps;
40
+ }): Promise<AssetRow[]>;
41
+ export interface RemoveOptions {
42
+ assetId: string;
43
+ force: boolean;
44
+ json: boolean;
45
+ deps?: AssetsRunDeps;
46
+ }
47
+ export interface RemoveResult {
48
+ assetId: string;
49
+ name: string;
50
+ /** Placed instances removed alongside the asset (only ever non-zero under --force). */
51
+ instancesRemoved: number;
52
+ /** References that remain, by path — under --force only. */
53
+ remainingReferences: string[];
54
+ }
55
+ export declare function runAssetsRemove(options: RemoveOptions): Promise<RemoveResult>;
56
+ export declare const assetsCommand: import("citty").CommandDef<import("citty").ArgsDef>;