@midscene/playground 1.10.6 → 1.10.7-beta-20260720030503.0
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.
- package/dist/es/server.mjs +17 -10
- package/dist/es/server.mjs.map +1 -1
- package/dist/lib/server.js +15 -8
- package/dist/lib/server.js.map +1 -1
- package/package.json +3 -3
- package/static/index.html +1 -1
- package/static/static/js/async/985.9101002d.js +2 -0
- package/static/static/js/async/985.9101002d.js.map +1 -0
- package/static/static/js/index.7b7081f0.js +960 -0
- package/static/static/js/index.7b7081f0.js.map +1 -0
- package/static/static/js/async/985.c09263d7.js +0 -2
- package/static/static/js/async/985.c09263d7.js.map +0 -1
- package/static/static/js/index.5c44b734.js +0 -960
- package/static/static/js/index.5c44b734.js.map +0 -1
- /package/static/static/js/{index.5c44b734.js.LICENSE.txt → index.7b7081f0.js.LICENSE.txt} +0 -0
package/dist/es/server.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
2
|
import { createReadStream, existsSync, mkdirSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { stat } from "node:fs/promises";
|
|
4
|
-
import { basename, dirname, join, resolve as external_node_path_resolve, sep } from "node:path";
|
|
4
|
+
import { basename, dirname, extname, join, resolve as external_node_path_resolve, sep } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
6
|
import { describeElementAtPoint, runConnectivityTest } from "@midscene/core";
|
|
7
7
|
import { getModelRuntime } from "@midscene/core/ai-model";
|
|
@@ -10,7 +10,7 @@ import { getMidsceneRunSubDir } from "@midscene/shared/common";
|
|
|
10
10
|
import { PLAYGROUND_SERVER_PORT } from "@midscene/shared/constants";
|
|
11
11
|
import { ModelConfigManager, globalModelConfigManager, overrideAIConfig } from "@midscene/shared/env";
|
|
12
12
|
import { generateElementByPoint } from "@midscene/shared/extractor";
|
|
13
|
-
import { annotateRects, imageInfoOfBase64 } from "@midscene/shared/img";
|
|
13
|
+
import { annotateRects, imageInfoOfBase64, screenshotImageExtension, screenshotImageFormatFromExtension, screenshotImageFormatFromMimeType, screenshotImageMimeType } from "@midscene/shared/img";
|
|
14
14
|
import { getDebug } from "@midscene/shared/logger";
|
|
15
15
|
import { buildMidsceneRecorderActionSummary, buildMidsceneRecorderReplayInstruction } from "@midscene/shared/recorder";
|
|
16
16
|
import { antiEscapeScriptTag, uuid as utils_uuid } from "@midscene/shared/utils";
|
|
@@ -232,7 +232,7 @@ function writeRecorderAiDescribeScreenshot(imageBase64, suffix) {
|
|
|
232
232
|
const { base64, mimeType } = extractBase64Payload(imageBase64);
|
|
233
233
|
const bytes = Buffer.from(base64, 'base64');
|
|
234
234
|
const sha256 = createHash('sha256').update(bytes).digest('hex');
|
|
235
|
-
const extension = mimeType
|
|
235
|
+
const extension = recorderScreenshotAssetExtension(mimeType);
|
|
236
236
|
const pathParts = formatRecorderAiDescribeScreenshotPathParts();
|
|
237
237
|
const dumpRoot = external_node_path_resolve(getMidsceneRunSubDir('dump'), RECORDER_AI_DESCRIBE_SCREENSHOT_DUMP_DIR);
|
|
238
238
|
const dumpDir = assertPathInsideDirectory(dumpRoot, join(dumpRoot, pathParts.datePart, pathParts.hourPart));
|
|
@@ -262,7 +262,9 @@ function assertRecorderScreenshotAssetId(assetId) {
|
|
|
262
262
|
return assetId;
|
|
263
263
|
}
|
|
264
264
|
function recorderScreenshotAssetExtension(mimeType) {
|
|
265
|
-
|
|
265
|
+
const format = screenshotImageFormatFromMimeType(mimeType);
|
|
266
|
+
if (!format) return 'png';
|
|
267
|
+
return 'jpeg' === format ? 'jpg' : screenshotImageExtension(format);
|
|
266
268
|
}
|
|
267
269
|
function recorderScreenshotAssetPath(assetId, mimeType) {
|
|
268
270
|
const root = getRecorderScreenshotAssetRoot();
|
|
@@ -288,7 +290,7 @@ function initializeRecorderScreenshotAssetUsage() {
|
|
|
288
290
|
withFileTypes: true
|
|
289
291
|
})){
|
|
290
292
|
if (!entry.isFile()) continue;
|
|
291
|
-
const match = entry.name.match(/^(.*)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(?:png|jpg)$/i);
|
|
293
|
+
const match = entry.name.match(/^(.*)-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\.(?:png|jpg|webp)$/i);
|
|
292
294
|
if (!match?.[1]) continue;
|
|
293
295
|
const sessionId = match[1];
|
|
294
296
|
const bytes = statSync(join(root, entry.name)).size;
|
|
@@ -341,7 +343,8 @@ function findRecorderScreenshotAssetPath(assetId) {
|
|
|
341
343
|
const root = getRecorderScreenshotAssetRoot();
|
|
342
344
|
for (const extension of [
|
|
343
345
|
'png',
|
|
344
|
-
'jpg'
|
|
346
|
+
'jpg',
|
|
347
|
+
'webp'
|
|
345
348
|
]){
|
|
346
349
|
const filePath = assertPathInsideDirectory(root, join(root, `${safeAssetId}.${extension}`));
|
|
347
350
|
if (existsSync(filePath)) return filePath;
|
|
@@ -373,7 +376,7 @@ function pruneRecorderScreenshotAssetsForSession(sessionId, retainedAssetIds) {
|
|
|
373
376
|
withFileTypes: true
|
|
374
377
|
})){
|
|
375
378
|
if (!entry.isFile() || !entry.name.startsWith(prefix)) continue;
|
|
376
|
-
const assetId = entry.name.replace(/\.(?:png|jpg)$/i, '');
|
|
379
|
+
const assetId = entry.name.replace(/\.(?:png|jpg|webp)$/i, '');
|
|
377
380
|
const filePath = join(root, entry.name);
|
|
378
381
|
if (!retained.has(assetId)) {
|
|
379
382
|
rmSync(filePath, {
|
|
@@ -1914,7 +1917,7 @@ class PlaygroundServer {
|
|
|
1914
1917
|
if (!report) return res.status(404).json({
|
|
1915
1918
|
error: 'Report not found or expired'
|
|
1916
1919
|
});
|
|
1917
|
-
const match = /^([A-Za-z0-9_-]+)\.(png|jpe?g)$/.exec(req.params.assetName);
|
|
1920
|
+
const match = /^([A-Za-z0-9_-]+)\.(png|jpe?g|webp)$/.exec(req.params.assetName);
|
|
1918
1921
|
if (!match) return res.status(400).json({
|
|
1919
1922
|
error: 'Invalid screenshot asset'
|
|
1920
1923
|
});
|
|
@@ -1930,7 +1933,9 @@ class PlaygroundServer {
|
|
|
1930
1933
|
});
|
|
1931
1934
|
const commaIndex = dataUri.indexOf(',');
|
|
1932
1935
|
if (-1 === commaIndex) throw new Error('Invalid screenshot data URI');
|
|
1933
|
-
const
|
|
1936
|
+
const format = screenshotImageFormatFromExtension(extension);
|
|
1937
|
+
if (!format) throw new Error(`Unsupported screenshot extension: ${extension}`);
|
|
1938
|
+
const mimeType = screenshotImageMimeType(format);
|
|
1934
1939
|
return res.type(mimeType).send(Buffer.from(dataUri.slice(commaIndex + 1), 'base64'));
|
|
1935
1940
|
} catch (error) {
|
|
1936
1941
|
debugReport('failed to stream report screenshot: %s', error);
|
|
@@ -2322,7 +2327,9 @@ class PlaygroundServer {
|
|
|
2322
2327
|
if (!filePath) return res.status(404).json({
|
|
2323
2328
|
error: 'Recorder screenshot not found'
|
|
2324
2329
|
});
|
|
2325
|
-
|
|
2330
|
+
const format = screenshotImageFormatFromExtension(extname(filePath).slice(1));
|
|
2331
|
+
if (!format) throw new Error('Unsupported recorder screenshot format');
|
|
2332
|
+
res.type(screenshotImageMimeType(format));
|
|
2326
2333
|
return res.send(readFileSync(filePath));
|
|
2327
2334
|
} catch (error) {
|
|
2328
2335
|
return res.status(400).json({
|