@bitmagic/cli 0.1.70-dev.0 → 0.1.70-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 (155) hide show
  1. package/README.md +47 -1
  2. package/assets/skills/publishing-to-poki/SKILL.md +50 -0
  3. package/dist/bin.js +5 -4
  4. package/dist/bin.js.map +1 -1
  5. package/dist/cli.d.ts +8 -0
  6. package/dist/cli.js +6 -5
  7. package/dist/cli.js.map +1 -1
  8. package/dist/commands/publish.d.ts +11 -0
  9. package/dist/commands/publish.js +18 -0
  10. package/dist/commands/publish.js.map +1 -1
  11. package/dist/commands/trailer.js +6 -10
  12. package/dist/commands/trailer.js.map +1 -1
  13. package/dist/editor/recording-sink.d.ts +2 -9
  14. package/dist/editor/recording-sink.js +3 -15
  15. package/dist/editor/recording-sink.js.map +1 -1
  16. package/dist/editor/recording-stream.d.ts +3 -2
  17. package/dist/editor/recording-stream.js +14 -48
  18. package/dist/editor/recording-stream.js.map +1 -1
  19. package/dist/editor/shell-page.js +1 -1
  20. package/dist/editor/shell-page.js.map +1 -1
  21. package/dist/errors.d.ts +8 -0
  22. package/dist/errors.js +16 -0
  23. package/dist/errors.js.map +1 -1
  24. package/dist/generate/video-review.js +1 -1
  25. package/dist/generate/video-review.js.map +1 -1
  26. package/dist/ios/collect-urls.d.ts +1 -75
  27. package/dist/ios/collect-urls.js +2 -219
  28. package/dist/ios/collect-urls.js.map +1 -1
  29. package/dist/ios/local-server.d.ts +1 -11
  30. package/dist/ios/local-server.js +2 -87
  31. package/dist/ios/local-server.js.map +1 -1
  32. package/dist/ios/transform.d.ts +4 -45
  33. package/dist/ios/transform.js +3 -59
  34. package/dist/ios/transform.js.map +1 -1
  35. package/dist/ios/vendor.d.ts +1 -29
  36. package/dist/ios/vendor.js +2 -112
  37. package/dist/ios/vendor.js.map +1 -1
  38. package/dist/package/collect-urls.d.ts +75 -0
  39. package/dist/package/collect-urls.js +220 -0
  40. package/dist/package/collect-urls.js.map +1 -0
  41. package/dist/package/local-server.d.ts +13 -0
  42. package/dist/package/local-server.js +102 -0
  43. package/dist/package/local-server.js.map +1 -0
  44. package/dist/package/transform.d.ts +47 -0
  45. package/dist/package/transform.js +62 -0
  46. package/dist/package/transform.js.map +1 -0
  47. package/dist/package/vendor.d.ts +33 -0
  48. package/dist/package/vendor.js +114 -0
  49. package/dist/package/vendor.js.map +1 -0
  50. package/dist/poki/assets.d.ts +20 -0
  51. package/dist/poki/assets.js +154 -0
  52. package/dist/poki/assets.js.map +1 -0
  53. package/dist/poki/check.d.ts +21 -0
  54. package/dist/poki/check.js +134 -0
  55. package/dist/poki/check.js.map +1 -0
  56. package/dist/poki/publish.d.ts +22 -0
  57. package/dist/poki/publish.js +207 -0
  58. package/dist/poki/publish.js.map +1 -0
  59. package/dist/poki/transform.d.ts +6 -0
  60. package/dist/poki/transform.js +30 -0
  61. package/dist/poki/transform.js.map +1 -0
  62. package/dist/publish/bundle.d.ts +1 -0
  63. package/dist/publish/bundle.js +2 -2
  64. package/dist/publish/bundle.js.map +1 -1
  65. package/dist/render/qr-png.d.ts +3 -6
  66. package/dist/render/qr-png.js +4 -33
  67. package/dist/render/qr-png.js.map +1 -1
  68. package/dist/scaffold/asset-pipeline-skill-files.d.ts +1 -1
  69. package/dist/scaffold/asset-pipeline-skill-files.js +3 -3
  70. package/dist/scaffold/poki-skill-files.d.ts +2 -0
  71. package/dist/scaffold/poki-skill-files.js +7 -0
  72. package/dist/scaffold/poki-skill-files.js.map +1 -0
  73. package/dist/scaffold/project-files.js +1 -1
  74. package/dist/scaffold/project.js +2 -0
  75. package/dist/scaffold/project.js.map +1 -1
  76. package/dist/scaffold/skill-files.js +6 -4
  77. package/dist/scaffold/skill-files.js.map +1 -1
  78. package/dist/trailer/chrome-rasterizers.d.ts +7 -0
  79. package/dist/trailer/chrome-rasterizers.js +7 -0
  80. package/dist/trailer/chrome-rasterizers.js.map +1 -0
  81. package/dist/trailer/game-name.d.ts +2 -0
  82. package/dist/trailer/game-name.js +20 -0
  83. package/dist/trailer/game-name.js.map +1 -0
  84. package/dist/trailer/hud-raster.d.ts +1 -1
  85. package/dist/trailer/hud-raster.js +1 -1
  86. package/dist/trailer/hud-raster.js.map +1 -1
  87. package/dist/trailer/record-session.js +1 -2
  88. package/dist/trailer/record-session.js.map +1 -1
  89. package/dist/trailer/title-raster.d.ts +9 -2
  90. package/dist/trailer/title-raster.js +17 -3
  91. package/dist/trailer/title-raster.js.map +1 -1
  92. package/dist/verify/browser.d.ts +3 -1
  93. package/dist/verify/browser.js +14 -9
  94. package/dist/verify/browser.js.map +1 -1
  95. package/dist/verify/classify.d.ts +2 -0
  96. package/dist/verify/classify.js +4 -1
  97. package/dist/verify/classify.js.map +1 -1
  98. package/package.json +4 -4
  99. package/dist/editor/capture-file.d.ts +0 -70
  100. package/dist/editor/capture-file.js +0 -204
  101. package/dist/editor/capture-file.js.map +0 -1
  102. package/dist/trailer/analyze.d.ts +0 -23
  103. package/dist/trailer/analyze.js +0 -186
  104. package/dist/trailer/analyze.js.map +0 -1
  105. package/dist/trailer/auto-edl.d.ts +0 -50
  106. package/dist/trailer/auto-edl.js +0 -267
  107. package/dist/trailer/auto-edl.js.map +0 -1
  108. package/dist/trailer/beat-cut.d.ts +0 -57
  109. package/dist/trailer/beat-cut.js +0 -232
  110. package/dist/trailer/beat-cut.js.map +0 -1
  111. package/dist/trailer/edl-time.d.ts +0 -61
  112. package/dist/trailer/edl-time.js +0 -105
  113. package/dist/trailer/edl-time.js.map +0 -1
  114. package/dist/trailer/ffmpeg.d.ts +0 -18
  115. package/dist/trailer/ffmpeg.js +0 -100
  116. package/dist/trailer/ffmpeg.js.map +0 -1
  117. package/dist/trailer/hud-state.d.ts +0 -181
  118. package/dist/trailer/hud-state.js +0 -525
  119. package/dist/trailer/hud-state.js.map +0 -1
  120. package/dist/trailer/io.d.ts +0 -22
  121. package/dist/trailer/io.js +0 -20
  122. package/dist/trailer/io.js.map +0 -1
  123. package/dist/trailer/link.d.ts +0 -1
  124. package/dist/trailer/link.js +0 -15
  125. package/dist/trailer/link.js.map +0 -1
  126. package/dist/trailer/make.d.ts +0 -56
  127. package/dist/trailer/make.js +0 -212
  128. package/dist/trailer/make.js.map +0 -1
  129. package/dist/trailer/merge.d.ts +0 -7
  130. package/dist/trailer/merge.js +0 -165
  131. package/dist/trailer/merge.js.map +0 -1
  132. package/dist/trailer/music-beats.d.ts +0 -123
  133. package/dist/trailer/music-beats.js +0 -672
  134. package/dist/trailer/music-beats.js.map +0 -1
  135. package/dist/trailer/paths.d.ts +0 -28
  136. package/dist/trailer/paths.js +0 -101
  137. package/dist/trailer/paths.js.map +0 -1
  138. package/dist/trailer/render.d.ts +0 -59
  139. package/dist/trailer/render.js +0 -521
  140. package/dist/trailer/render.js.map +0 -1
  141. package/dist/trailer/revision.d.ts +0 -8
  142. package/dist/trailer/revision.js +0 -31
  143. package/dist/trailer/revision.js.map +0 -1
  144. package/dist/trailer/synth.d.ts +0 -9
  145. package/dist/trailer/synth.js +0 -120
  146. package/dist/trailer/synth.js.map +0 -1
  147. package/dist/trailer/timeline-types.d.ts +0 -195
  148. package/dist/trailer/timeline-types.js +0 -419
  149. package/dist/trailer/timeline-types.js.map +0 -1
  150. package/dist/trailer/titles.d.ts +0 -44
  151. package/dist/trailer/titles.js +0 -124
  152. package/dist/trailer/titles.js.map +0 -1
  153. package/dist/trailer/video-chain.d.ts +0 -129
  154. package/dist/trailer/video-chain.js +0 -261
  155. package/dist/trailer/video-chain.js.map +0 -1
@@ -0,0 +1,154 @@
1
+ import { createHash } from 'crypto';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { CliError } from '../errors.js';
5
+ import { vendorPathFor, vendorUrls } from '../package/vendor.js';
6
+ import { POKI_SDK_URL } from './transform.js';
7
+ /** Only static resources may be downloaded by discovery; never vendor API responses. */
8
+ export function isStaticAsset(url) {
9
+ if (url === POKI_SDK_URL)
10
+ return false;
11
+ try {
12
+ const parsed = new URL(url);
13
+ return /^https?:$/.test(parsed.protocol) && (/\.(?:glb|gltf|bin|vxl|vwld|spz|splat|ksplat|ply|png|jpe?g|webp|gif|svg|ico|ktx2|hdr|exr|woff2?|ttf|otf|mp3|ogg|opus|wav|mp4|webm|json|js|mjs|wasm|css)(?:\.br|\.gz)?$/i.test(parsed.pathname)
14
+ || (parsed.hostname === 'fonts.googleapis.com' && /^\/css2?$/.test(parsed.pathname)));
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ export function scanAssetUrls(text) {
21
+ return [...new Set((text.match(/https?:\/\/[^\s"'`<>\\)]+/g) ?? [])
22
+ .filter((url) => !url.includes('${') && isStaticAsset(url)))];
23
+ }
24
+ /** HTML resource attributes, excluding dormant URL strings in bundled engine code. */
25
+ export function scanHtmlAssets(html) {
26
+ const markup = html.replace(/<script\b[^>]*>[\s\S]*?<\/script>/gi, (tag) => tag.slice(0, tag.indexOf('>') + 1));
27
+ return [...new Set([...markup.matchAll(/(?:src|href)=["'](https?:\/\/[^"']+)["']/gi)]
28
+ .map((match) => match[1].replace(/&amp;/g, '&')).filter(isStaticAsset))];
29
+ }
30
+ /** Preserve sibling layout, but never merge distinct query resources or unsafe decoded paths. */
31
+ export function pokiAssetPath(url) {
32
+ const normal = vendorPathFor(url);
33
+ if (normal === null)
34
+ return null;
35
+ const parsed = new URL(url);
36
+ if (parsed.username || parsed.password)
37
+ return null;
38
+ const segments = normal.split('/').map((segment) => segment.replace(/[^a-zA-Z0-9._-]/g, (char) => '~' + char.charCodeAt(0).toString(16)));
39
+ let result = segments.join('/');
40
+ if (parsed.hostname === 'fonts.googleapis.com')
41
+ result += '.css';
42
+ if (parsed.search) {
43
+ const suffix = createHash('sha256').update(parsed.search).digest('hex').slice(0, 16);
44
+ const ext = path.posix.extname(result);
45
+ result = `${ext ? result.slice(0, -ext.length) : result}~${suffix}${ext}`;
46
+ }
47
+ return parsed.protocol === 'http:' ? result.replace(/^vendor\//, 'vendor-http/') : result;
48
+ }
49
+ /** References inside a sidecar, retained with their original spelling for rewriting. */
50
+ export function sidecarReferences(text, url) {
51
+ const refs = new Set();
52
+ const pathname = new URL(url).pathname;
53
+ if (/\.gltf$/i.test(pathname)) {
54
+ const walk = (value) => {
55
+ if (Array.isArray(value)) {
56
+ for (const child of value)
57
+ walk(child);
58
+ }
59
+ else if (typeof value === 'object' && value !== null) {
60
+ for (const [key, child] of Object.entries(value)) {
61
+ if (key === 'uri' && typeof child === 'string')
62
+ refs.add(child);
63
+ else
64
+ walk(child);
65
+ }
66
+ }
67
+ };
68
+ walk(JSON.parse(text));
69
+ }
70
+ else if (/\.css$/i.test(pathname) || new URL(url).hostname === 'fonts.googleapis.com') {
71
+ for (const match of text.matchAll(/url\(\s*["']?([^\s"')]+)["']?\s*\)|@import\s+["']([^"']+)["']/gi)) {
72
+ refs.add(match[1] ?? match[2]);
73
+ }
74
+ }
75
+ const result = new Map();
76
+ for (const ref of refs) {
77
+ if (/^(data:|blob:|#)/.test(ref))
78
+ continue;
79
+ const absolute = new URL(ref, url).href;
80
+ if (!/^https?:/.test(absolute))
81
+ throw new CliError(`Unsupported dependency ${ref} in ${url}.`);
82
+ result.set(ref, absolute);
83
+ }
84
+ return result;
85
+ }
86
+ /** Rewrite resource references only; short names must not replace arbitrary CSS or GLTF text. */
87
+ export function rewriteSidecar(text, url, replacements) {
88
+ if (/\.gltf$/i.test(new URL(url).pathname)) {
89
+ const data = JSON.parse(text);
90
+ const walk = (value) => {
91
+ if (Array.isArray(value)) {
92
+ for (const child of value)
93
+ walk(child);
94
+ }
95
+ else if (typeof value === 'object' && value !== null) {
96
+ for (const [key, child] of Object.entries(value)) {
97
+ if (key === 'uri' && typeof child === 'string' && replacements.has(child)) {
98
+ value[key] = replacements.get(child);
99
+ }
100
+ else
101
+ walk(child);
102
+ }
103
+ }
104
+ };
105
+ walk(data);
106
+ return JSON.stringify(data);
107
+ }
108
+ return text.replace(/url\(\s*["']?([^\s"')]+)["']?\s*\)|@import\s+["']([^"']+)["']/gi, (match, urlRef, importRef) => {
109
+ const ref = urlRef ?? importRef;
110
+ const replacement = ref === undefined ? undefined : replacements.get(ref);
111
+ return ref !== undefined && replacement !== undefined ? match.replace(ref, () => replacement) : match;
112
+ });
113
+ }
114
+ /** Walk GLTF/CSS dependencies as well as direct URLs; a missing declared asset is an error. */
115
+ export async function packageAssets(options) {
116
+ const entries = new Map();
117
+ let pending = [...new Set(options.urls)].filter((url) => url !== POKI_SDK_URL);
118
+ for (let depth = 0; pending.length > 0; depth++) {
119
+ if (depth >= 12 || entries.size + pending.length > 10_000) {
120
+ throw new CliError('Asset dependency discovery exceeded its limit. Check the reported asset URLs.');
121
+ }
122
+ const result = await vendorUrls({
123
+ ...options, urls: pending, fetchImpl: options.fetch, pathForUrl: pokiAssetPath,
124
+ // Correct for mutable URLs too; cache files are diagnostics, not proof of freshness.
125
+ reuseCache: false,
126
+ });
127
+ if (result.failures.length > 0) {
128
+ throw new CliError(`Could not package assets:\n${result.failures.map((f) => ` ${f.url}: ${f.error}`).join('\n')}`);
129
+ }
130
+ for (const [url, rel] of result.entries)
131
+ entries.set(url, rel);
132
+ const next = new Set();
133
+ for (const [url, rel] of result.entries) {
134
+ if (!/\.(gltf|css)(?:[?#]|$)/i.test(url) && new URL(url).hostname !== 'fonts.googleapis.com')
135
+ continue;
136
+ const file = path.join(options.payloadDir, rel);
137
+ const text = fs.readFileSync(file, 'utf-8');
138
+ const refs = sidecarReferences(text, url);
139
+ const rewrites = new Map();
140
+ for (const [ref, absolute] of refs) {
141
+ const dependency = pokiAssetPath(absolute);
142
+ if (dependency === null)
143
+ throw new CliError(`Cannot package dependency ${absolute}.`);
144
+ rewrites.set(ref, path.posix.relative(path.posix.dirname(rel), dependency) + new URL(absolute).hash);
145
+ if (!entries.has(absolute))
146
+ next.add(absolute);
147
+ }
148
+ fs.writeFileSync(file, rewriteSidecar(text, url, rewrites));
149
+ }
150
+ pending = [...next];
151
+ }
152
+ return entries;
153
+ }
154
+ //# sourceMappingURL=assets.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assets.js","sourceRoot":"","sources":["../../src/poki/assets.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type VerifyResult } from '../verify/classify.js';
2
+ import type { MobileOrientation } from '../project/platform-declaration.js';
3
+ export declare const POKI_SDK_STUB = "(() => {\n let playing = false, advertising = false;\n const event = (name) => console.info('BM_POKI_EVENT:' + name);\n window.PokiSDK = {\n init: async () => { event('init'); },\n gameLoadingStart: () => {},\n gameLoadingFinished: () => event('loaded'),\n gameplayStart: () => {\n if (playing || advertising) throw new Error('Poki: invalid gameplayStart');\n playing = true; event('start');\n },\n gameplayStop: () => {\n if (!playing || advertising) throw new Error('Poki: invalid gameplayStop');\n playing = false; event('stop');\n },\n commercialBreak: () => {\n if (playing || advertising) throw new Error('Poki: ad during gameplay');\n advertising = true; event('ad');\n return new Promise(resolve => setTimeout(() => { advertising = false; event('ad-end'); resolve(); }, 150));\n },\n setDebug: () => {}\n };\n})();";
4
+ export interface PokiCheckOptions {
5
+ root: string;
6
+ payloadDir: string;
7
+ artifactDir: string;
8
+ mode: 'record' | 'restricted';
9
+ platform: 'desktop' | 'mobile';
10
+ orientation?: MobileOrientation;
11
+ nested?: boolean;
12
+ settleMs?: number;
13
+ log: (message: string) => void;
14
+ }
15
+ export interface PokiCheckResult {
16
+ result: VerifyResult;
17
+ misses: string[];
18
+ localFailures: string[];
19
+ sdkEvents: string[];
20
+ }
21
+ export declare function runPokiCheck(options: PokiCheckOptions): Promise<PokiCheckResult>;
@@ -0,0 +1,134 @@
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ import { browserLaunchPlan } from '../browser-gl.js';
4
+ import { startPayloadServer } from '../package/local-server.js';
5
+ import { runHeadlessCheck } from '../verify/browser.js';
6
+ import { classifyVerifyRun } from '../verify/classify.js';
7
+ import { mobileContextOptions } from '../verify/device.js';
8
+ import { DEFAULT_START_INTERACTION } from '../verify/start.js';
9
+ import { withVerifyLock } from '../verify/lock.js';
10
+ import { POKI_SDK_URL } from './transform.js';
11
+ import { isStaticAsset } from './assets.js';
12
+ // Only the intercepted SDK response uses this stub. It never enters the delivered ZIP.
13
+ export const POKI_SDK_STUB = `(() => {
14
+ let playing = false, advertising = false;
15
+ const event = (name) => console.info('BM_POKI_EVENT:' + name);
16
+ window.PokiSDK = {
17
+ init: async () => { event('init'); },
18
+ gameLoadingStart: () => {},
19
+ gameLoadingFinished: () => event('loaded'),
20
+ gameplayStart: () => {
21
+ if (playing || advertising) throw new Error('Poki: invalid gameplayStart');
22
+ playing = true; event('start');
23
+ },
24
+ gameplayStop: () => {
25
+ if (!playing || advertising) throw new Error('Poki: invalid gameplayStop');
26
+ playing = false; event('stop');
27
+ },
28
+ commercialBreak: () => {
29
+ if (playing || advertising) throw new Error('Poki: ad during gameplay');
30
+ advertising = true; event('ad');
31
+ return new Promise(resolve => setTimeout(() => { advertising = false; event('ad-end'); resolve(); }, 150));
32
+ },
33
+ setDebug: () => {}
34
+ };
35
+ })();`;
36
+ /** Exercise the engine state contract after starting through actual UI, inside its iframe. */
37
+ async function pauseAndResume(frame) {
38
+ await frame.evaluate(async () => {
39
+ /* eslint-disable no-undef -- browser callback */
40
+ const w = window;
41
+ const state = w.gameTemplate?.getGameEngine?.().gameStateManager;
42
+ if (!state || state.getCurrentState() !== 'playing')
43
+ throw new Error('Poki check: game never entered PLAYING.');
44
+ state.setPaused(true, 'manual');
45
+ await new Promise((resolve) => setTimeout(resolve, 0));
46
+ state.setPaused(false, 'manual');
47
+ await new Promise((resolve) => setTimeout(resolve, 400));
48
+ if (state.getCurrentState() !== 'playing')
49
+ throw new Error('Poki check: game did not resume after the advertisement.');
50
+ /* eslint-enable no-undef */
51
+ });
52
+ }
53
+ export async function runPokiCheck(options) {
54
+ return withVerifyLock(options.root, 'publish --target poki', { info: options.log }, async () => {
55
+ fs.mkdirSync(options.artifactDir, { recursive: true });
56
+ const mountPath = options.nested ? '/poki/game/' : '/';
57
+ const server = await startPayloadServer(options.payloadDir, { mountPath });
58
+ const misses = new Set();
59
+ const localFailures = new Set();
60
+ const gameUrl = `${server.origin}${mountPath}index.html?platform=${options.platform}&renderer=webgl`;
61
+ const harnessUrl = `${server.origin}/__poki_check__.html`;
62
+ const routes = async (context) => {
63
+ context.on('response', (response) => {
64
+ if (new URL(response.url()).origin === server.origin && response.status() >= 400) {
65
+ localFailures.add(`${response.status()} ${response.url()}`);
66
+ }
67
+ });
68
+ await context.routeWebSocket('**', (socket) => { misses.add(socket.url()); socket.close(); });
69
+ await context.route('**/*', async (route) => {
70
+ const request = route.request();
71
+ const url = request.url();
72
+ if (url === POKI_SDK_URL) {
73
+ await route.fulfill({ contentType: 'text/javascript', body: POKI_SDK_STUB });
74
+ }
75
+ else if (url === harnessUrl) {
76
+ await route.fulfill({ contentType: 'text/html', body: `<html><head><meta name="viewport" content="width=device-width,initial-scale=1"></head>`
77
+ + `<body style="margin:0"><iframe allow="fullscreen; autoplay" src="${gameUrl.replace(/&/g, '&amp;')}" `
78
+ + 'style="position:fixed;inset:0;width:100%;height:100%;border:0"></iframe></body></html>',
79
+ });
80
+ }
81
+ else if (new URL(url).origin === server.origin) {
82
+ await route.continue();
83
+ }
84
+ else {
85
+ misses.add(url);
86
+ if (options.mode === 'record' && request.method() === 'GET' && isStaticAsset(url))
87
+ await route.continue();
88
+ else
89
+ await route.abort('blockedbyclient');
90
+ }
91
+ });
92
+ };
93
+ try {
94
+ const observations = await runHeadlessCheck({
95
+ url: harnessUrl, probeFrameUrlIncludes: `${server.origin}${mountPath}index.html`,
96
+ screenshotPath: path.join(options.artifactDir, 'screenshot.png'),
97
+ consolePath: path.join(options.artifactDir, 'console.log'),
98
+ settleMs: options.settleMs ?? 25_000,
99
+ startInteraction: DEFAULT_START_INTERACTION,
100
+ launch: browserLaunchPlan(process.env, 'webgl'),
101
+ ...(options.platform === 'mobile' ? { device: mobileContextOptions(options.orientation ?? 'landscape') } : {}),
102
+ routes, blockServiceWorkers: true,
103
+ ...(options.mode === 'restricted' ? { afterSettle: pauseAndResume } : {}),
104
+ });
105
+ const sdkEvents = observations.consoleLines.flatMap((line) => {
106
+ const event = /BM_POKI_EVENT:(\S+)/.exec(line);
107
+ return event ? [event[1]] : [];
108
+ });
109
+ const result = classifyVerifyRun(observations, { bundled: true, platform: options.platform });
110
+ if (!sdkEvents.includes('init') || !sdkEvents.includes('loaded') || !sdkEvents.includes('start')) {
111
+ result.failures.push('The Poki SDK did not initialize, finish loading, and report gameplay.');
112
+ }
113
+ if (options.mode === 'restricted' && !sdkEvents.includes('ad-end')) {
114
+ result.failures.push('The Poki pause/resume advertisement was not observed.');
115
+ }
116
+ result.ok = result.failures.length === 0;
117
+ const outcome = { result, misses: [...misses], localFailures: [...localFailures], sdkEvents };
118
+ fs.writeFileSync(path.join(options.artifactDir, 'result.json'), JSON.stringify(outcome, null, 2) + '\n');
119
+ return outcome;
120
+ }
121
+ catch (error) {
122
+ const outcome = {
123
+ result: { ok: false, failures: [error instanceof Error ? error.message : String(error)], warnings: [] },
124
+ misses: [...misses], localFailures: [...localFailures], sdkEvents: [],
125
+ };
126
+ fs.writeFileSync(path.join(options.artifactDir, 'result.json'), JSON.stringify(outcome, null, 2) + '\n');
127
+ return outcome;
128
+ }
129
+ finally {
130
+ await server.close();
131
+ }
132
+ });
133
+ }
134
+ //# sourceMappingURL=check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/poki/check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { type Output } from '../output.js';
2
+ import { runBuild } from '../publish/bundle.js';
3
+ import { collectUrls } from '../package/collect-urls.js';
4
+ import type { PokiCheckOptions, PokiCheckResult } from './check.js';
5
+ export interface PokiPublishArgs {
6
+ name?: string;
7
+ output?: string;
8
+ force?: boolean;
9
+ json?: boolean;
10
+ }
11
+ export interface PokiPublishDeps {
12
+ startDir?: string;
13
+ output?: Output;
14
+ fetch: typeof globalThis.fetch;
15
+ build: typeof runBuild;
16
+ collect: typeof collectUrls;
17
+ check: (options: PokiCheckOptions) => Promise<PokiCheckResult>;
18
+ }
19
+ /** Capability metadata lives in the engine tarball, including locally built engines. */
20
+ export declare function requirePokiCapability(root: string): void;
21
+ export declare function pokiOutputPath(root: string, output: string | undefined, cwd: string): string;
22
+ export declare function runPokiPublish(args: PokiPublishArgs, deps?: PokiPublishDeps): Promise<void>;
@@ -0,0 +1,207 @@
1
+ import { createHash } from 'crypto';
2
+ import * as fs from 'fs';
3
+ import * as path from 'path';
4
+ import { unzipSync, zipSync } from 'fflate';
5
+ import { CliError } from '../errors.js';
6
+ import { createOutput } from '../output.js';
7
+ import { loadProjectContext } from '../project/context.js';
8
+ import { readPlatformDeclaration } from '../project/platform-declaration.js';
9
+ import { computeFingerprint } from '../publish/fingerprint.js';
10
+ import { buildBundlePaths, readBuildManifest, runBuild, VITE_PUBLISH_STANDALONE_CONFIG } from '../publish/bundle.js';
11
+ import { checkVerifyGate } from '../publish/meta-block.js';
12
+ import { readVerifyRecord } from '../verify/result.js';
13
+ import { collectUrls, readCompiledGameCode } from '../package/collect-urls.js';
14
+ import { isStaticAsset, packageAssets, pokiAssetPath, scanAssetUrls, scanHtmlAssets } from './assets.js';
15
+ import { transformPokiHtml } from './transform.js';
16
+ function defaultDeps() {
17
+ return {
18
+ fetch: globalThis.fetch, build: runBuild, collect: collectUrls,
19
+ check: async (options) => (await import('./check.js')).runPokiCheck(options),
20
+ };
21
+ }
22
+ /** Capability metadata lives in the engine tarball, including locally built engines. */
23
+ export function requirePokiCapability(root) {
24
+ if (!fs.existsSync(path.join(root, VITE_PUBLISH_STANDALONE_CONFIG))) {
25
+ throw new CliError(`Missing ${VITE_PUBLISH_STANDALONE_CONFIG}. Run \`bitmagic upgrade\` before Poki export.`, 4);
26
+ }
27
+ const file = path.join(root, 'engine', 'engine', 'poki-capabilities.json');
28
+ let capability;
29
+ try {
30
+ capability = JSON.parse(fs.readFileSync(file, 'utf-8'));
31
+ }
32
+ catch {
33
+ throw new CliError('This engine does not advertise Poki export support. Run `bitmagic upgrade`, then `bitmagic verify`.', 4);
34
+ }
35
+ if (typeof capability !== 'object' || capability === null || !('exportVersion' in capability) || capability.exportVersion !== 1) {
36
+ throw new CliError('The engine Poki export capability is incompatible. Run `bitmagic self-update` and `bitmagic upgrade`.', 4);
37
+ }
38
+ }
39
+ export function pokiOutputPath(root, output, cwd) {
40
+ const result = output === undefined ? path.join(root, '.bitmagic', 'poki', 'poki.zip') : path.resolve(cwd, output);
41
+ if (path.extname(result).toLowerCase() !== '.zip')
42
+ throw new CliError('--output must name a .zip file.');
43
+ const relative = path.relative(root, result).split(path.sep).join('/');
44
+ if (/^(src|engine|node_modules|dist|\.git|\.agents|\.claude|\.kiro)(\/|$)/.test(relative)
45
+ || (relative.startsWith('.bitmagic/') && relative !== '.bitmagic/poki/poki.zip')) {
46
+ throw new CliError('--output must not overwrite project inputs, build files, or managed artifacts. Use a release directory.');
47
+ }
48
+ // Resolve symlinked parents too: a release directory must not be an alias for src/ or engine/.
49
+ let ancestor = path.dirname(result);
50
+ while (!fs.existsSync(ancestor))
51
+ ancestor = path.dirname(ancestor);
52
+ const actualRelative = path.relative(fs.realpathSync(root), path.join(fs.realpathSync(ancestor), path.relative(ancestor, result))).split(path.sep).join('/');
53
+ if (/^(src|engine|node_modules|dist|\.git|\.agents|\.claude|\.kiro)(\/|$)/.test(actualRelative)
54
+ || (actualRelative.startsWith('.bitmagic/') && actualRelative !== '.bitmagic/poki/poki.zip')
55
+ || (fs.existsSync(result) && fs.lstatSync(result).isSymbolicLink())) {
56
+ throw new CliError('--output must not use a symlinked file or parent directory.');
57
+ }
58
+ return result;
59
+ }
60
+ function payloadEntries(dir, prefix = '') {
61
+ const entries = {};
62
+ for (const entry of fs.readdirSync(path.join(dir, prefix), { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
63
+ const name = prefix + entry.name;
64
+ if (entry.isSymbolicLink())
65
+ throw new CliError(`Unexpected symlink in Poki payload: ${name}`);
66
+ if (entry.isDirectory())
67
+ Object.assign(entries, payloadEntries(dir, name + '/'));
68
+ else
69
+ entries[name] = fs.readFileSync(path.join(dir, name));
70
+ }
71
+ return entries;
72
+ }
73
+ function assertPackagedCheck(check, artifactDir) {
74
+ const failures = [...check.result.failures, ...check.localFailures, ...check.misses.map((url) => `External request: ${url}`)];
75
+ if (!check.result.ok || failures.length > 0) {
76
+ throw new CliError(`Poki package validation failed:\n${failures.join('\n')}\nDiagnostics: ${artifactDir}`, 7);
77
+ }
78
+ }
79
+ export async function runPokiPublish(args, deps = defaultDeps()) {
80
+ const output = deps.output ?? createOutput(args.json === true);
81
+ const context = loadProjectContext(deps.startDir);
82
+ const { root, metadata } = context;
83
+ const zipPath = pokiOutputPath(root, args.output, deps.startDir ?? process.cwd());
84
+ requirePokiCapability(root);
85
+ const fingerprint = computeFingerprint(root);
86
+ const gate = checkVerifyGate(readVerifyRecord(path.join(root, '.bitmagic', 'verify')), fingerprint, args.force === true);
87
+ if (!gate.ok)
88
+ throw new CliError(gate.message, 3);
89
+ const paths = buildBundlePaths(root);
90
+ const manifest = readBuildManifest(root);
91
+ if (manifest?.fingerprint !== fingerprint || !manifest.singleFile || !fs.existsSync(paths.htmlPath)
92
+ || manifest.sha256 !== createHash('sha256').update(fs.readFileSync(paths.htmlPath)).digest('hex')) {
93
+ output.info('Building the standalone Poki bundle…');
94
+ deps.build(root, metadata.engineVersion, { singleFile: true, stderr: args.json === true });
95
+ }
96
+ const html = fs.readFileSync(paths.htmlPath, 'utf-8');
97
+ const dir = path.join(root, '.bitmagic', 'poki');
98
+ fs.mkdirSync(dir, { recursive: true });
99
+ const stage = fs.mkdtempSync(path.join(dir, 'stage-'));
100
+ const payload = path.join(stage, 'payload');
101
+ const checksDir = path.join(dir, 'checks', path.basename(stage));
102
+ const cacheDir = path.join(dir, 'cache');
103
+ fs.mkdirSync(payload);
104
+ const warnings = [];
105
+ try {
106
+ const collected = await deps.collect(root);
107
+ for (const note of collected.notes) {
108
+ output.info(note);
109
+ warnings.push(note);
110
+ }
111
+ // The full engine bundle carries dormant examples/defaults as well as constructed URLs.
112
+ // Collect game references and HTML resources here; discover engine requests while running.
113
+ const urls = new Set([...collected.urls].filter(isStaticAsset)
114
+ .concat(scanAssetUrls(readCompiledGameCode(root)), scanHtmlAssets(html)));
115
+ output.info(`Packaging ${urls.size} assets…`);
116
+ const assetMap = await packageAssets({ urls, payloadDir: payload, cacheDir, fetch: deps.fetch, log: output.info });
117
+ const bases = new Map();
118
+ for (const base of collected.bases) {
119
+ const mapped = pokiAssetPath(base.endsWith('/') ? base : base + '/');
120
+ if (mapped !== null)
121
+ bases.set(base, mapped.replace(/\/index$/, ''));
122
+ }
123
+ const writePayload = () => {
124
+ fs.writeFileSync(path.join(payload, 'index.html'), transformPokiHtml({
125
+ html, assetMap, baseRewrites: bases, name: args.name,
126
+ }));
127
+ };
128
+ const orientation = readPlatformDeclaration(root).mobileOrientation;
129
+ writePayload();
130
+ for (const platform of ['desktop', 'mobile']) {
131
+ for (let pass = 0; pass < 3; pass++) {
132
+ output.info(`Discovering ${platform} runtime assets (pass ${pass + 1})…`);
133
+ const artifactDir = path.join(checksDir, `record-${platform}-${pass}`);
134
+ const check = await deps.check({ root, payloadDir: payload, artifactDir, mode: 'record', platform, orientation, log: output.info });
135
+ const unsupported = check.misses.filter((url) => !isStaticAsset(url));
136
+ if (unsupported.length > 0) {
137
+ throw new CliError(`This game requires external services that the Poki package cannot include:\n${unsupported.join('\n')}\nDiagnostics: ${artifactDir}`, 7);
138
+ }
139
+ if (check.misses.length === 0) {
140
+ assertPackagedCheck(check, artifactDir);
141
+ break;
142
+ }
143
+ if (pass === 2)
144
+ throw new CliError(`Runtime assets are still missing. See ${artifactDir}.`, 7);
145
+ for (const [url, rel] of await packageAssets({ urls: check.misses, payloadDir: payload, cacheDir, fetch: deps.fetch, log: output.info })) {
146
+ assetMap.set(url, rel);
147
+ }
148
+ writePayload();
149
+ }
150
+ }
151
+ const entries = payloadEntries(payload);
152
+ const zip = zipSync(entries, { level: 9 });
153
+ // Test the actual archive contents, not just the pre-archive staging directory.
154
+ const extracted = path.join(stage, 'extracted');
155
+ fs.mkdirSync(extracted);
156
+ for (const [name, bytes] of Object.entries(unzipSync(zip))) {
157
+ const file = path.join(extracted, name);
158
+ fs.mkdirSync(path.dirname(file), { recursive: true });
159
+ fs.writeFileSync(file, bytes);
160
+ }
161
+ const validation = [];
162
+ for (const platform of ['desktop', 'mobile']) {
163
+ for (const nested of [false, true]) {
164
+ output.info(`Validating the ZIP on ${platform} (${nested ? 'nested' : 'root'} path)…`);
165
+ const artifactDir = path.join(checksDir, `restricted-${platform}-${nested ? 'nested' : 'root'}`);
166
+ const check = await deps.check({ root, payloadDir: extracted, artifactDir, mode: 'restricted', platform, orientation, nested, log: output.info });
167
+ assertPackagedCheck(check, artifactDir);
168
+ warnings.push(...check.result.warnings);
169
+ validation.push({ platform, nested, sdkEvents: check.sdkEvents });
170
+ }
171
+ }
172
+ if (computeFingerprint(root) !== fingerprint)
173
+ throw new CliError('The project changed during export. Run `bitmagic verify` and export again.', 3);
174
+ const sizes = Object.entries(entries).map(([file, bytes]) => ({ file, bytes: bytes.byteLength, sha256: createHash('sha256').update(bytes).digest('hex') }));
175
+ const payloadDir = path.join(dir, 'payload');
176
+ const manifestPath = path.join(dir, 'manifest.json');
177
+ const result = {
178
+ ok: true, target: 'poki', packageFormatVersion: 1, zipPath, payloadDir, manifestPath, checksDir,
179
+ fingerprint, engineVersion: metadata.engineVersion, sha256: createHash('sha256').update(zip).digest('hex'),
180
+ zipBytes: zip.byteLength, unpackedBytes: sizes.reduce((total, file) => total + file.bytes, 0),
181
+ assetCount: assetMap.size, validation, sdkValidation: 'stub', inspectorValidated: false,
182
+ warnings: [...new Set(warnings)], files: sizes, builtAt: new Date().toISOString(),
183
+ };
184
+ fs.mkdirSync(path.dirname(zipPath), { recursive: true });
185
+ const zipTmp = `${zipPath}.tmp-${process.pid}`;
186
+ try {
187
+ fs.writeFileSync(zipTmp, zip);
188
+ fs.renameSync(zipTmp, zipPath);
189
+ }
190
+ finally {
191
+ fs.rmSync(zipTmp, { force: true });
192
+ }
193
+ fs.rmSync(payloadDir, { recursive: true, force: true });
194
+ fs.renameSync(payload, payloadDir);
195
+ fs.writeFileSync(path.join(stage, 'manifest.json'), JSON.stringify(result, null, 2) + '\n');
196
+ fs.renameSync(path.join(stage, 'manifest.json'), manifestPath);
197
+ for (const warning of result.warnings)
198
+ output.info(`warning: ${warning}`);
199
+ output.info(`Poki package ready: ${zipPath} (${result.zipBytes} bytes zipped; ${result.unpackedBytes} bytes unpacked).`);
200
+ output.info('Test the payload folder in https://inspector.poki.dev before submitting to Poki. Local checks use an SDK stub.');
201
+ output.result(result);
202
+ }
203
+ finally {
204
+ fs.rmSync(stage, { recursive: true, force: true });
205
+ }
206
+ }
207
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/poki/publish.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import { type TransformOptions } from '../package/transform.js';
2
+ export declare const POKI_SDK_URL = "https://game-cdn.poki.com/scripts/v2/poki-sdk.js";
3
+ /** Transform a pristine local build, never the HTML returned by publish/begin. */
4
+ export declare function transformPokiHtml(options: Omit<TransformOptions, 'distribution'> & {
5
+ name?: string;
6
+ }): string;
@@ -0,0 +1,30 @@
1
+ import { CliError } from '../errors.js';
2
+ import { transformBundleHtml } from '../package/transform.js';
3
+ export const POKI_SDK_URL = 'https://game-cdn.poki.com/scripts/v2/poki-sdk.js';
4
+ /** Transform a pristine local build, never the HTML returned by publish/begin. */
5
+ export function transformPokiHtml(options) {
6
+ const markup = options.html.replace(/(<script\b[^>]*>)[\s\S]*?<\/script>/gi, '$1</script>');
7
+ if (/bitmagic:meta:v1|id=["']bm-bundled-assets|name=["']bm:distribution/.test(markup)) {
8
+ throw new CliError('This bundle has already been packaged or published. Run `bitmagic build --single-file` again.');
9
+ }
10
+ if (/googletagmanager\.com|google-analytics\.com|id=["']bitmagic-branding/.test(markup)) {
11
+ throw new CliError('The input bundle contains analytics or a Bitmagic watermark. Build from the original project.');
12
+ }
13
+ // The standalone scaffold retains an import map for Bitmagic's hosted-build audit. It is
14
+ // unused here: every library is bundled, and Poki must not load CDN libraries.
15
+ const clean = options.html
16
+ .replace(/<script\b[^>]*type=["']importmap["'][^>]*>[\s\S]*?<\/script>/gi, '')
17
+ .replace(/<script\b[^>]*src=["']https:\/\/game-cdn\.poki\.com\/scripts\/v2\/poki-sdk\.js["'][^>]*>\s*<\/script>/gi, '');
18
+ let html = transformBundleHtml({ ...options, html: clean, distribution: 'poki' }).html;
19
+ if (options.name !== undefined) {
20
+ const title = options.name.replace(/[&<>"']/g, (char) => ({
21
+ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;',
22
+ })[char]);
23
+ html = /<title>[\s\S]*?<\/title>/i.test(html)
24
+ ? html.replace(/<title>[\s\S]*?<\/title>/i, () => `<title>${title}</title>`)
25
+ : html.replace('</head>', `<title>${title}</title></head>`);
26
+ }
27
+ // A synchronous classic script precedes even a game module placed at the start of <head>.
28
+ return html.replace('<head>', `<head>\n<script src="${POKI_SDK_URL}"></script>`);
29
+ }
30
+ //# sourceMappingURL=transform.js.map