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

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 (50) hide show
  1. package/README.md +44 -8
  2. package/dist/cli.d.ts +8 -0
  3. package/dist/commands/judge.d.ts +5 -0
  4. package/dist/commands/judge.js +28 -7
  5. package/dist/commands/judge.js.map +1 -1
  6. package/dist/commands/publish.d.ts +6 -1
  7. package/dist/commands/publish.js +29 -15
  8. package/dist/commands/publish.js.map +1 -1
  9. package/dist/commands/verify.d.ts +4 -0
  10. package/dist/commands/verify.js +94 -51
  11. package/dist/commands/verify.js.map +1 -1
  12. package/dist/judge/record.d.ts +3 -0
  13. package/dist/judge/record.js +3 -0
  14. package/dist/judge/record.js.map +1 -1
  15. package/dist/project/platform-declaration.d.ts +51 -0
  16. package/dist/project/platform-declaration.js +81 -0
  17. package/dist/project/platform-declaration.js.map +1 -0
  18. package/dist/publish/platform.d.ts +4 -8
  19. package/dist/publish/platform.js +19 -53
  20. package/dist/publish/platform.js.map +1 -1
  21. package/dist/scaffold/project-files.js +19 -5
  22. package/dist/scaffold/project-files.js.map +1 -1
  23. package/dist/verify/artifacts.d.ts +19 -0
  24. package/dist/verify/artifacts.js +34 -0
  25. package/dist/verify/artifacts.js.map +1 -0
  26. package/dist/verify/browser.d.ts +10 -0
  27. package/dist/verify/browser.js +79 -9
  28. package/dist/verify/browser.js.map +1 -1
  29. package/dist/verify/classify.d.ts +37 -1
  30. package/dist/verify/classify.js +66 -2
  31. package/dist/verify/classify.js.map +1 -1
  32. package/dist/verify/device.d.ts +43 -0
  33. package/dist/verify/device.js +59 -0
  34. package/dist/verify/device.js.map +1 -0
  35. package/dist/verify/iterate.d.ts +21 -2
  36. package/dist/verify/iterate.js +43 -36
  37. package/dist/verify/iterate.js.map +1 -1
  38. package/dist/verify/mobile-parity.d.ts +42 -0
  39. package/dist/verify/mobile-parity.js +84 -0
  40. package/dist/verify/mobile-parity.js.map +1 -0
  41. package/dist/verify/platform.d.ts +47 -0
  42. package/dist/verify/platform.js +89 -0
  43. package/dist/verify/platform.js.map +1 -0
  44. package/dist/verify/result.d.ts +90 -6
  45. package/dist/verify/result.js +89 -10
  46. package/dist/verify/result.js.map +1 -1
  47. package/dist/verify/url.d.ts +9 -1
  48. package/dist/verify/url.js +10 -2
  49. package/dist/verify/url.js.map +1 -1
  50. package/package.json +4 -4
@@ -1,5 +1,7 @@
1
- import type { RendererObservation, SettleObservation, StateSnapshot, VerifyResult } from './classify.js';
1
+ import type { RendererObservation, SettleObservation, StateSnapshot, TouchControlsObservation, VerifyObservations, VerifyResult } from './classify.js';
2
2
  import type { EventsObservation } from './events.js';
3
+ import type { MobileParityGap } from './mobile-parity.js';
4
+ import type { VerifyPlatform } from './platform.js';
3
5
  export declare const VERIFY_RESULT_FILENAME = "result.json";
4
6
  /**
5
7
  * What `bitmagic verify` observed, written so `bitmagic publish` can gate on it.
@@ -30,6 +32,53 @@ export interface VerifyRunRecord {
30
32
  /** Semantic gameplay events (deaths, pickups, match-end) from the engine's `?eventlog=1`
31
33
  * session; null when the engine predates it. Optional for the same cross-version reason. */
32
34
  events?: EventsObservation | null;
35
+ /**
36
+ * Which platform the fields above describe — the LEAD platform, `platforms[0]` of the run.
37
+ * Absent on records written before `--platform` existed, which were all desktop.
38
+ */
39
+ platform?: VerifyPlatform;
40
+ /**
41
+ * Touch affordances the engine rendered — the direct evidence that the mobile branch ran.
42
+ * Absent on a desktop lead run, where the engine never builds MobileControls at all, so
43
+ * absent is not the same as zero.
44
+ */
45
+ touchControls?: TouchControlsObservation | null;
46
+ /**
47
+ * The engine's mobile-parity gaps, as it reported them at game start. Null means it reported
48
+ * none: a clean game, an engine too old to have the check, or a genre whose controller does
49
+ * not implement it. A property of the game's CODE rather than of the emulated device, so it is
50
+ * reported once whatever the run covered.
51
+ */
52
+ mobileParity?: MobileParityGap | null;
53
+ /**
54
+ * One entry per platform, in run order, present ONLY on a run that covered more than one.
55
+ * A single-platform record keeps exactly the shape it has always had — nothing that reads
56
+ * these records today has a new key to learn.
57
+ */
58
+ platforms?: VerifyPlatformRun[];
59
+ }
60
+ /** One platform's half of a multi-platform run. */
61
+ export interface VerifyPlatformRun {
62
+ platform: VerifyPlatform;
63
+ ok: boolean;
64
+ /** Unprefixed — the platform is the sibling key, so the prefixing the merged top-level
65
+ * `failures`/`warnings` need would only be noise here. */
66
+ failures: string[];
67
+ warnings: string[];
68
+ renderer?: RendererObservation;
69
+ retriedWithSoftwareGl?: boolean;
70
+ settle?: SettleObservation;
71
+ snapshot?: StateSnapshot | null;
72
+ events?: EventsObservation | null;
73
+ /** Touch affordances the engine rendered. Only on a mobile run. */
74
+ touchControls?: TouchControlsObservation | null;
75
+ /**
76
+ * File names, not paths: every artifact is a sibling of the `result.json` these appear in, and
77
+ * an absolute path baked into a persisted record describes the machine that wrote it rather
78
+ * than the run.
79
+ */
80
+ screenshotFile?: string;
81
+ consoleFile: string;
33
82
  }
34
83
  export declare function writeVerifyRecord(artifactDir: string, record: VerifyRunRecord): void;
35
84
  /**
@@ -50,7 +99,38 @@ export declare function readVerifyRecord(artifactDir: string): VerifyRunRecord |
50
99
  * different messages and different remedies. Inside `run()` that ordering is only observable by
51
100
  * spawning vite and a browser, which is why it went unguarded.
52
101
  */
53
- export declare function decideVerifyOutcome(result: VerifyResult, fingerprint: string, at: string, extras?: Pick<VerifyRunRecord, 'renderer' | 'retriedWithSoftwareGl' | 'settle' | 'snapshot' | 'events'>): {
102
+ export type VerifyRunExtras = Pick<VerifyRunRecord, 'renderer' | 'retriedWithSoftwareGl' | 'settle' | 'snapshot' | 'events' | 'platform' | 'touchControls' | 'mobileParity' | 'platforms'>;
103
+ /**
104
+ * One platform's finished run, ready to merge.
105
+ *
106
+ * Shared by the one-shot command and the watch loop because both assemble exactly this from
107
+ * exactly these parts, and the only interesting thing about the assembly — which observations
108
+ * belong to the platform and which to the run as a whole — is the thing that would drift if it
109
+ * were written twice.
110
+ */
111
+ export declare function toVerifyPlatformRun(platform: VerifyPlatform, result: VerifyResult, observations: Pick<VerifyObservations, 'renderer' | 'settle' | 'snapshot' | 'events' | 'touchControls' | 'mobileParity'>, retriedWithSoftwareGl: boolean, paths: {
112
+ screenshotPath: string;
113
+ consolePath: string;
114
+ }, fast: boolean): VerifyPlatformRun;
115
+ /**
116
+ * One verdict, and one set of top-level fields, from however many platforms the run covered.
117
+ *
118
+ * The prefixing rule is what keeps a `both` run readable. A finding EVERY platform produced is
119
+ * one problem, not two — a missing `Loaded world.json` is the same missing file whichever
120
+ * viewport asked for it — so it is reported once, unprefixed. A finding only some platforms
121
+ * produced is prefixed with the platform, because there the platform IS the information. A
122
+ * single-platform run therefore comes out byte-identical to what it produced before this
123
+ * existed: every finding is in every run, so nothing is prefixed.
124
+ *
125
+ * The top-level observations are the LEAD run's (`runs[0]`), which `resolveVerifyPlatforms`
126
+ * chooses as the platform the game is actually for. `platforms` is only attached for a genuine
127
+ * multi-platform run, so a single-platform record grows no keys.
128
+ */
129
+ export declare function mergeVerifyPlatformRuns(runs: VerifyPlatformRun[], mobileParity: MobileParityGap | null | undefined): {
130
+ result: VerifyResult;
131
+ extras: VerifyRunExtras;
132
+ };
133
+ export declare function decideVerifyOutcome(result: VerifyResult, fingerprint: string, at: string, extras?: VerifyRunExtras): {
54
134
  record: VerifyRunRecord;
55
135
  shouldThrow: boolean;
56
136
  };
@@ -71,7 +151,11 @@ export interface VerifyReporter {
71
151
  export declare function recordAndGateVerify(artifactDir: string, outcome: {
72
152
  record: VerifyRunRecord;
73
153
  shouldThrow: boolean;
74
- }, paths: {
75
- consolePath: string;
76
- screenshotPath?: string;
77
- }, reporter: VerifyReporter): void;
154
+ },
155
+ /**
156
+ * Every file this run actually wrote, in the order to list them. A list rather than a
157
+ * console/screenshot pair because a run can now cover two platforms and write four files, and
158
+ * because a `--fast` run captures no screenshot at all — naming a file that does not exist
159
+ * (or worse, a stale one from an earlier run) is exactly what this avoids.
160
+ */
161
+ artifacts: string[], reporter: VerifyReporter): void;
@@ -36,14 +36,89 @@ export function readVerifyRecord(artifactDir) {
36
36
  }
37
37
  }
38
38
  /**
39
- * What a classified verify run produces: the record to write, and whether the command then
40
- * fails.
39
+ * One platform's finished run, ready to merge.
41
40
  *
42
- * Split out of the command so the ORDER is testable. The record must be written even when the
43
- * run failed publish distinguishes "verify failed" from "verify never ran", and those have
44
- * different messages and different remedies. Inside `run()` that ordering is only observable by
45
- * spawning vite and a browser, which is why it went unguarded.
41
+ * Shared by the one-shot command and the watch loop because both assemble exactly this from
42
+ * exactly these parts, and the only interesting thing about the assembly which observations
43
+ * belong to the platform and which to the run as a whole — is the thing that would drift if it
44
+ * were written twice.
46
45
  */
46
+ export function toVerifyPlatformRun(platform, result, observations, retriedWithSoftwareGl, paths, fast) {
47
+ return {
48
+ platform,
49
+ ok: result.ok,
50
+ failures: result.failures,
51
+ warnings: result.warnings,
52
+ renderer: observations.renderer,
53
+ ...(retriedWithSoftwareGl ? { retriedWithSoftwareGl } : {}),
54
+ settle: observations.settle,
55
+ snapshot: observations.snapshot,
56
+ events: observations.events,
57
+ ...(observations.touchControls !== undefined ? { touchControls: observations.touchControls } : {}),
58
+ consoleFile: path.basename(paths.consolePath),
59
+ ...(fast ? {} : { screenshotFile: path.basename(paths.screenshotPath) }),
60
+ };
61
+ }
62
+ /**
63
+ * One verdict, and one set of top-level fields, from however many platforms the run covered.
64
+ *
65
+ * The prefixing rule is what keeps a `both` run readable. A finding EVERY platform produced is
66
+ * one problem, not two — a missing `Loaded world.json` is the same missing file whichever
67
+ * viewport asked for it — so it is reported once, unprefixed. A finding only some platforms
68
+ * produced is prefixed with the platform, because there the platform IS the information. A
69
+ * single-platform run therefore comes out byte-identical to what it produced before this
70
+ * existed: every finding is in every run, so nothing is prefixed.
71
+ *
72
+ * The top-level observations are the LEAD run's (`runs[0]`), which `resolveVerifyPlatforms`
73
+ * chooses as the platform the game is actually for. `platforms` is only attached for a genuine
74
+ * multi-platform run, so a single-platform record grows no keys.
75
+ */
76
+ export function mergeVerifyPlatformRuns(runs, mobileParity) {
77
+ if (runs.length === 0) {
78
+ throw new CliError('A verify run covered no platforms, which should be impossible.');
79
+ }
80
+ const lead = runs[0];
81
+ return {
82
+ result: {
83
+ ok: runs.every((run) => run.ok),
84
+ failures: mergeFindings(runs, (run) => run.failures),
85
+ warnings: mergeFindings(runs, (run) => run.warnings),
86
+ },
87
+ extras: {
88
+ ...(lead.renderer !== undefined ? { renderer: lead.renderer } : {}),
89
+ ...(lead.retriedWithSoftwareGl === true ? { retriedWithSoftwareGl: true } : {}),
90
+ ...(lead.settle !== undefined ? { settle: lead.settle } : {}),
91
+ ...(lead.snapshot !== undefined ? { snapshot: lead.snapshot } : {}),
92
+ ...(lead.events !== undefined ? { events: lead.events } : {}),
93
+ platform: lead.platform,
94
+ ...(lead.touchControls !== undefined ? { touchControls: lead.touchControls } : {}),
95
+ ...(mobileParity !== undefined ? { mobileParity } : {}),
96
+ ...(runs.length > 1 ? { platforms: runs } : {}),
97
+ },
98
+ };
99
+ }
100
+ /** Findings from every run, deduplicated, in first-seen order, prefixed only where they differ. */
101
+ function mergeFindings(runs, pick) {
102
+ const seenIn = new Map();
103
+ for (const run of runs) {
104
+ for (const finding of pick(run)) {
105
+ const platforms = seenIn.get(finding);
106
+ if (platforms === undefined)
107
+ seenIn.set(finding, [run.platform]);
108
+ else if (!platforms.includes(run.platform))
109
+ platforms.push(run.platform);
110
+ }
111
+ }
112
+ const merged = [];
113
+ for (const [finding, platforms] of seenIn) {
114
+ if (platforms.length === runs.length)
115
+ merged.push(finding);
116
+ else
117
+ for (const platform of platforms)
118
+ merged.push(`[${platform}] ${finding}`);
119
+ }
120
+ return merged;
121
+ }
47
122
  export function decideVerifyOutcome(result, fingerprint, at, extras) {
48
123
  return {
49
124
  record: {
@@ -66,16 +141,20 @@ export function decideVerifyOutcome(result, fingerprint, at, extras) {
66
141
  * survives a failing run — inside `run()` it was observable only by spawning vite and a browser,
67
142
  * which is why it went unguarded.
68
143
  */
69
- export function recordAndGateVerify(artifactDir, outcome, paths, reporter) {
144
+ export function recordAndGateVerify(artifactDir, outcome,
145
+ /**
146
+ * Every file this run actually wrote, in the order to list them. A list rather than a
147
+ * console/screenshot pair because a run can now cover two platforms and write four files, and
148
+ * because a `--fast` run captures no screenshot at all — naming a file that does not exist
149
+ * (or worse, a stale one from an earlier run) is exactly what this avoids.
150
+ */
151
+ artifacts, reporter) {
70
152
  reporter.write(artifactDir, outcome.record);
71
153
  for (const warning of outcome.record.warnings)
72
154
  reporter.info(`warning: ${warning}`);
73
155
  if (outcome.shouldThrow) {
74
156
  for (const failure of outcome.record.failures)
75
157
  reporter.error(`✗ ${failure}`);
76
- // screenshotPath is absent on a `--fast` run, which captures none — listing it would point
77
- // the reader at a file that does not exist (or worse, a stale one from an earlier run).
78
- const artifacts = [paths.consolePath, paths.screenshotPath].filter((p) => p !== undefined);
79
158
  reporter.error(`\nArtifacts: ${artifacts.join(', ')}`);
80
159
  throw new CliError('Verification failed.');
81
160
  }
@@ -1 +1 @@
1
- {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/verify/result.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/verify/result.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import type { RendererChoice } from '../browser-gl.js';
2
+ import type { VerifyPlatform } from './platform.js';
2
3
  /**
3
4
  * The URL verify boots the game at — one place, because one-shot and watch
4
5
  * mode were already building it separately and drift here is invisible until
@@ -8,5 +9,12 @@ import type { RendererChoice } from '../browser-gl.js';
8
9
  * localStorage preference. `?eventlog=1` asks the engine to run a passive
9
10
  * GameEventLog session for the semantic-events probe — an engine too old to
10
11
  * know the param ignores it, and the probe then reads null ("not observed").
12
+ *
13
+ * `?platform=mobile` is the engine's own boot override and wins over every
14
+ * device probe (`isMobileRuntime.ts`), which is what makes the mobile run
15
+ * exercise the real branch — the touch HUD, the pixel-ratio clamp, the
16
+ * level-detail tier, the light warmup — rather than a resized desktop page.
17
+ * A desktop run sends NO platform param rather than `?platform=desktop`, so a
18
+ * vendored engine that predates the override boots exactly as it always has.
11
19
  */
12
- export declare function buildVerifyUrl(port: number, renderer: RendererChoice): string;
20
+ export declare function buildVerifyUrl(port: number, renderer: RendererChoice, platform?: VerifyPlatform): string;
@@ -7,8 +7,16 @@
7
7
  * localStorage preference. `?eventlog=1` asks the engine to run a passive
8
8
  * GameEventLog session for the semantic-events probe — an engine too old to
9
9
  * know the param ignores it, and the probe then reads null ("not observed").
10
+ *
11
+ * `?platform=mobile` is the engine's own boot override and wins over every
12
+ * device probe (`isMobileRuntime.ts`), which is what makes the mobile run
13
+ * exercise the real branch — the touch HUD, the pixel-ratio clamp, the
14
+ * level-detail tier, the light warmup — rather than a resized desktop page.
15
+ * A desktop run sends NO platform param rather than `?platform=desktop`, so a
16
+ * vendored engine that predates the override boots exactly as it always has.
10
17
  */
11
- export function buildVerifyUrl(port, renderer) {
12
- return `http://localhost:${port}/?renderer=${renderer}&eventlog=1`;
18
+ export function buildVerifyUrl(port, renderer, platform = 'desktop') {
19
+ const base = `http://localhost:${port}/?renderer=${renderer}&eventlog=1`;
20
+ return platform === 'mobile' ? `${base}&platform=mobile` : base;
13
21
  }
14
22
  //# sourceMappingURL=url.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/verify/url.ts"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,QAAwB;IACnE,OAAO,oBAAoB,IAAI,cAAc,QAAQ,aAAa,CAAC;AACrE,CAAC"}
1
+ {"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/verify/url.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,cAAc,CAC5B,IAAY,EACZ,QAAwB,EACxB,WAA2B,SAAS;IAEpC,MAAM,IAAI,GAAG,oBAAoB,IAAI,cAAc,QAAQ,aAAa,CAAC;IACzE,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,kBAAkB,CAAC,CAAC,CAAC,IAAI,CAAC;AAClE,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/cli",
3
- "version": "0.1.52-dev.10",
3
+ "version": "0.1.52-dev.11",
4
4
  "description": "Build Bitmagic games from your own agent tool",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "author": "Bitmagic Oy",
@@ -23,9 +23,9 @@
23
23
  "fflate": "^0.8.2",
24
24
  "playwright-core": "^1.59.1",
25
25
  "tar": "^7.4.3",
26
- "@bitmagic/animation-forger": "0.1.7-dev.10",
27
- "@bitmagic/world-forger": "0.1.12-dev.10",
28
- "@bitmagic/asset-core": "0.2.7-dev.10"
26
+ "@bitmagic/asset-core": "0.2.7-dev.11",
27
+ "@bitmagic/animation-forger": "0.1.7-dev.11",
28
+ "@bitmagic/world-forger": "0.1.12-dev.11"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@eslint/js": "^9.38.0",