@bitmagic/cli 0.1.37 → 0.1.38

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 (44) hide show
  1. package/README.md +16 -3
  2. package/dist/browser-gl.d.ts +23 -0
  3. package/dist/browser-gl.js +50 -0
  4. package/dist/browser-gl.js.map +1 -1
  5. package/dist/cli.d.ts +27 -1
  6. package/dist/cli.js +2 -0
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/login.js +10 -2
  9. package/dist/commands/login.js.map +1 -1
  10. package/dist/commands/usage.d.ts +76 -0
  11. package/dist/commands/usage.js +117 -0
  12. package/dist/commands/usage.js.map +1 -0
  13. package/dist/commands/verify.d.ts +13 -1
  14. package/dist/commands/verify.js +139 -15
  15. package/dist/commands/verify.js.map +1 -1
  16. package/dist/commands/whoami.d.ts +10 -0
  17. package/dist/commands/whoami.js +11 -1
  18. package/dist/commands/whoami.js.map +1 -1
  19. package/dist/forge/upload-proxy.js +1 -1
  20. package/dist/http/client.js +3 -2
  21. package/dist/http/client.js.map +1 -1
  22. package/dist/scaffold/claude-settings.js +4 -0
  23. package/dist/scaffold/claude-settings.js.map +1 -1
  24. package/dist/scaffold/project-files.d.ts +9 -0
  25. package/dist/scaffold/project-files.js +67 -8
  26. package/dist/scaffold/project-files.js.map +1 -1
  27. package/dist/scaffold/project.js +2 -1
  28. package/dist/scaffold/project.js.map +1 -1
  29. package/dist/verify/browser.d.ts +37 -1
  30. package/dist/verify/browser.js +389 -97
  31. package/dist/verify/browser.js.map +1 -1
  32. package/dist/verify/classify.d.ts +75 -2
  33. package/dist/verify/classify.js +48 -2
  34. package/dist/verify/classify.js.map +1 -1
  35. package/dist/verify/iterate.d.ts +47 -0
  36. package/dist/verify/iterate.js +162 -0
  37. package/dist/verify/iterate.js.map +1 -0
  38. package/dist/verify/result.d.ts +16 -3
  39. package/dist/verify/result.js +13 -3
  40. package/dist/verify/result.js.map +1 -1
  41. package/dist/verify/settle.d.ts +60 -0
  42. package/dist/verify/settle.js +90 -0
  43. package/dist/verify/settle.js.map +1 -0
  44. package/package.json +1 -1
@@ -0,0 +1,90 @@
1
+ /**
2
+ * The decision "has the game settled enough to observe", extracted pure so it is testable
3
+ * without a browser.
4
+ *
5
+ * Verify used to wait a fixed 15 seconds regardless of what the game was doing. The samples the
6
+ * browser loop feeds this function come from the live engine (`window.gameTemplate`), so a
7
+ * healthy game that reaches gameplay and holds steady is observed after ~4-5 seconds, while the
8
+ * fixed `--timeout` stays as the hard cap for games that never stabilise. An engine too old to
9
+ * answer the probes never settles early — it gets exactly the old fixed-wait behaviour.
10
+ */
11
+ export const DEFAULT_SETTLE_CONFIG = {
12
+ minSettleMs: 4_000,
13
+ minFrames: 90,
14
+ quietMs: 1_500,
15
+ };
16
+ export const SETTLE_POLL_MS = 500;
17
+ /**
18
+ * Per-sample drop (world units per poll) below which the player counts as falling. A walking
19
+ * player descends a slope far slower; a player falling out of the world drops tens of units
20
+ * between 500ms polls.
21
+ */
22
+ const FREEFALL_DROP_PER_SAMPLE = 2;
23
+ /** How many consecutive falling samples make a freefall. One can be a jump; three in a row
24
+ * (a full second and a half of accelerating descent) is not gameplay. */
25
+ const FREEFALL_SAMPLES = 3;
26
+ /**
27
+ * The player is in sustained freefall at the end of `samples`.
28
+ *
29
+ * Judged over the trailing samples that HAVE a player position; unobservable positions mean
30
+ * "cannot tell", never "falling". Exported because the final state snapshot reports the same
31
+ * judgement as `player.isFalling`.
32
+ */
33
+ export function isFreefalling(samples) {
34
+ const positioned = samples.filter((sample) => sample.playerY !== null);
35
+ if (positioned.length < FREEFALL_SAMPLES + 1)
36
+ return false;
37
+ const tail = positioned.slice(-(FREEFALL_SAMPLES + 1));
38
+ for (let i = 1; i < tail.length; i++) {
39
+ const drop = tail[i - 1].playerY - tail[i].playerY;
40
+ if (drop < FREEFALL_DROP_PER_SAMPLE)
41
+ return false;
42
+ }
43
+ return true;
44
+ }
45
+ /**
46
+ * True when the run has seen enough to stop settling early.
47
+ *
48
+ * Every condition must hold on the latest sample:
49
+ * - the minimum settle floor has passed;
50
+ * - gameplay is actually running — state 'playing' or 'end' (a run-to-completion minigame), or
51
+ * `hasStarted` when the state manager is not observable. Both unobservable → never settle
52
+ * early; the fixed timeout is the correct behaviour for an engine that cannot be asked;
53
+ * - the page has rendered enough frames to prove a live render loop;
54
+ * - the error counters have been flat for the quiet window;
55
+ * - the player is not falling out of the world.
56
+ */
57
+ export function settleVerdict(samples, config) {
58
+ if (samples.length === 0)
59
+ return 'keep-waiting';
60
+ const latest = samples[samples.length - 1];
61
+ if (latest.atMs < config.minSettleMs)
62
+ return 'keep-waiting';
63
+ const playing = latest.gameState === null
64
+ ? latest.hasStarted === true
65
+ : latest.gameState === 'playing' || latest.gameState === 'end';
66
+ if (!playing)
67
+ return 'keep-waiting';
68
+ if (latest.frameCount === null || latest.frameCount < config.minFrames)
69
+ return 'keep-waiting';
70
+ const quietWindowStart = latest.atMs - config.quietMs;
71
+ const windowSamples = samples.filter((sample) => sample.atMs >= quietWindowStart);
72
+ // The window must span actual time: right after the floor passes there may be only the latest
73
+ // sample in it, and "no errors between one sample and itself" proves nothing.
74
+ const earliest = windowSamples[0];
75
+ if (earliest === latest && samples.length > 1)
76
+ return 'keep-waiting';
77
+ if (windowSamples.some((sample) => sample.errorEventCount !== latest.errorEventCount)) {
78
+ return 'keep-waiting';
79
+ }
80
+ // Cumulative frames are not enough: a loop that rendered its 90 frames on the menu and froze
81
+ // at game start (measured under software WebGPU) would settle as "stable" on the count alone.
82
+ // Stable means frames are still being produced NOW — strictly more than at the window's start.
83
+ if (earliest !== latest && earliest.frameCount !== null && latest.frameCount <= earliest.frameCount) {
84
+ return 'keep-waiting';
85
+ }
86
+ if (isFreefalling(samples))
87
+ return 'keep-waiting';
88
+ return 'settled';
89
+ }
90
+ //# sourceMappingURL=settle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"settle.js","sourceRoot":"","sources":["../../src/verify/settle.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitmagic/cli",
3
- "version": "0.1.37",
3
+ "version": "0.1.38",
4
4
  "description": "Build Bitmagic games from your own agent tool",
5
5
  "type": "module",
6
6
  "bin": {