@xenon-device-management/xenon 1.11.0 → 1.11.1

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/lib/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {
@@ -832,20 +832,18 @@ router.get('/:udid/stream', (req, res) => __awaiter(void 0, void 0, void 0, func
832
832
  }
833
833
  }
834
834
  else {
835
- // Android auto-start
836
- const androidStreamService = typedi_1.Container.get(AndroidStreamService_1.default);
837
- const session = androidStreamService.getStreamStatus(udid);
838
- if (session && session.status === 'running') {
839
- mjpegPort = session.mjpegPort;
835
+ // Android auto-start. Always go through startStream: it health-checks an
836
+ // existing session before reusing it (decideAndroidStreamReuse) and dedupes
837
+ // concurrent starts. The short-circuit that used to live here — hand back
838
+ // any session marked 'running' — bypassed both, re-introducing the very
839
+ // stale-port bug the service now guards against. Reuse stays just as cheap;
840
+ // the health check is an in-process property read, not a request.
841
+ try {
842
+ const result = yield typedi_1.Container.get(AndroidStreamService_1.default).startStream(udid);
843
+ mjpegPort = result.mjpegPort;
840
844
  }
841
- else {
842
- try {
843
- const result = yield androidStreamService.startStream(udid);
844
- mjpegPort = result.mjpegPort;
845
- }
846
- catch (err) {
847
- return res.status(503).send({ error: 'Android stream failed', message: err.message });
848
- }
845
+ catch (err) {
846
+ return res.status(503).send({ error: 'Android stream failed', message: err.message });
849
847
  }
850
848
  }
851
849
  if (!mjpegPort) {
@@ -66,6 +66,7 @@ const ResourceIsolationService_1 = require("../../services/ResourceIsolationServ
66
66
  const PortAllocator_1 = require("../../services/PortAllocator");
67
67
  const ffmpegPath_1 = require("../../helpers/ffmpegPath");
68
68
  const singleFlight_1 = require("../../helpers/singleFlight");
69
+ const androidStreamReuse_1 = require("./androidStreamReuse");
69
70
  // JPEG quality for the in-process sharp encoder (0-100). ~78 approximates the
70
71
  // old ffmpeg `-q:v 8` (mjpeg quantizer scale) — the low-lag/quality knob.
71
72
  const JPEG_QUALITY = 78;
@@ -216,11 +217,26 @@ let AndroidStreamService = class AndroidStreamService {
216
217
  startStream(udid) {
217
218
  return __awaiter(this, void 0, void 0, function* () {
218
219
  const performStartup = () => __awaiter(this, void 0, void 0, function* () {
219
- var _a, _b;
220
+ var _a, _b, _c;
220
221
  try {
222
+ // A session is handed back only when it is actually serving. A closed
223
+ // server, or one that went live without ever capturing a frame, was
224
+ // otherwise reused indefinitely and every consumer — recording included
225
+ // — got a port that yields nothing. See androidStreamReuse / issue #196.
221
226
  const existing = this.sessions.get(udid);
222
- if (existing && (existing.status === 'running' || existing.status === 'starting')) {
223
- return { mjpegPort: existing.mjpegPort };
227
+ const decision = (0, androidStreamReuse_1.decideAndroidStreamReuse)(existing && {
228
+ status: existing.status,
229
+ serverListening: ((_a = existing.server) === null || _a === void 0 ? void 0 : _a.listening) === true,
230
+ hasFrame: existing.latestFrame !== undefined,
231
+ });
232
+ if (decision.reuse) {
233
+ if (existing)
234
+ return { mjpegPort: existing.mjpegPort };
235
+ }
236
+ else if (existing) {
237
+ logger_1.default.warn(`[${udid}] Stream session on port ${existing.mjpegPort} is not usable ` +
238
+ `(${decision.reason}); discarding it and starting fresh.`);
239
+ yield this.disposeSession(udid, existing);
224
240
  }
225
241
  const device = yield device_store_1.DeviceStoreFactory.getStore().findDevice({ udid });
226
242
  if (!device)
@@ -256,12 +272,12 @@ let AndroidStreamService = class AndroidStreamService {
256
272
  break;
257
273
  }
258
274
  catch (bindErr) {
259
- logger_1.default.warn(`[${udid}] MJPEG bind failed on ${mjpegPort} (attempt ${attempt + 1}): ${(_a = bindErr === null || bindErr === void 0 ? void 0 : bindErr.message) !== null && _a !== void 0 ? _a : bindErr}`);
275
+ logger_1.default.warn(`[${udid}] MJPEG bind failed on ${mjpegPort} (attempt ${attempt + 1}): ${(_b = bindErr === null || bindErr === void 0 ? void 0 : bindErr.message) !== null && _b !== void 0 ? _b : bindErr}`);
260
276
  this.sessions.delete(udid);
261
277
  try {
262
- (_b = candidate.server) === null || _b === void 0 ? void 0 : _b.close();
278
+ (_c = candidate.server) === null || _c === void 0 ? void 0 : _c.close();
263
279
  }
264
- catch (_c) {
280
+ catch (_d) {
265
281
  /* ignore */
266
282
  }
267
283
  yield portAllocator.release(mjpegPort).catch(() => undefined);
@@ -318,6 +334,37 @@ let AndroidStreamService = class AndroidStreamService {
318
334
  return this.startFlight.run(udid, performStartup);
319
335
  });
320
336
  }
337
+ /**
338
+ * Release a dead session's resources so a fresh one can replace it.
339
+ *
340
+ * Deliberately *not* stopStream(): that also unblocks the device when the
341
+ * lock is a manual one, which would drop the caller's own hold on the device
342
+ * halfway through a restart. Only stream-owned resources are touched here.
343
+ */
344
+ disposeSession(udid, session) {
345
+ return __awaiter(this, void 0, void 0, function* () {
346
+ var _a;
347
+ // The capture loop and every writeFrame loop poll this, so flipping it
348
+ // first stops them before the server goes away.
349
+ session.status = 'stopped';
350
+ try {
351
+ (_a = session.server) === null || _a === void 0 ? void 0 : _a.close();
352
+ }
353
+ catch (_b) {
354
+ /* ignore */
355
+ }
356
+ session.server = null;
357
+ // Only drop our own entry — never evict a newer session for this udid.
358
+ if (this.sessions.get(udid) === session)
359
+ this.sessions.delete(udid);
360
+ try {
361
+ yield typedi_1.Container.get(PortAllocator_1.PortAllocator).release(session.mjpegPort);
362
+ }
363
+ catch (e) {
364
+ logger_1.default.warn(`[${udid}] Failed to release mjpeg port lease while restarting stream: ${e}`);
365
+ }
366
+ });
367
+ }
321
368
  stopStream(udid) {
322
369
  return __awaiter(this, void 0, void 0, function* () {
323
370
  var _a;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ /**
3
+ * Decide whether an existing Android MJPEG stream session can be handed back as
4
+ * is, or has to be torn down and restarted.
5
+ *
6
+ * Why this exists: `startStream` used to return `existing.mjpegPort` for any
7
+ * session marked 'running' *or* 'starting', with nothing verifying that a
8
+ * server was still bound to it. A session whose HTTP server had closed, or one
9
+ * that went live without ever capturing a frame (startStream warns and
10
+ * continues after a 5s first-frame wait), was therefore reused indefinitely —
11
+ * every caller, `ensureMjpegForRecording` included, got a port that serves
12
+ * nothing, and ffmpeg left a 0-byte mp4 behind. Same silent symptom as #194,
13
+ * reached by a different route. See issue #196.
14
+ *
15
+ * This is the Android analogue of `resolveIosMjpegPort` (#191), minus the async
16
+ * probe: the MJPEG server is ours and in-process, so its liveness is a property
17
+ * read rather than a loopback request.
18
+ *
19
+ * Kept free of TypeDI and `http` so the decision is unit-testable; the service
20
+ * maps its live session onto the view below.
21
+ */
22
+ Object.defineProperty(exports, "__esModule", { value: true });
23
+ exports.decideAndroidStreamReuse = decideAndroidStreamReuse;
24
+ function decideAndroidStreamReuse(session) {
25
+ if (!session)
26
+ return { reuse: false, reason: 'no-session' };
27
+ // 'starting' is deliberately excluded: the bind loop registers the candidate
28
+ // before awaiting the listen, so that status means "a port exists" and not
29
+ // "a port serves". Concurrent callers join the in-flight start via
30
+ // SingleFlight (#195) instead of being handed a half-bound port here.
31
+ if (session.status !== 'running')
32
+ return { reuse: false, reason: 'not-running' };
33
+ if (!session.serverListening)
34
+ return { reuse: false, reason: 'server-closed' };
35
+ if (!session.hasFrame)
36
+ return { reuse: false, reason: 'no-frame' };
37
+ return { reuse: true };
38
+ }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ require("reflect-metadata");
16
+ const chai_1 = require("chai");
17
+ const sinon_1 = __importDefault(require("sinon"));
18
+ const typedi_1 = require("typedi");
19
+ const AndroidStreamService_1 = __importDefault(require("../../src/device-managers/android/AndroidStreamService"));
20
+ const singleFlight_1 = require("../../src/helpers/singleFlight");
21
+ const PortAllocator_1 = require("../../src/services/PortAllocator");
22
+ const device_store_1 = require("../../src/data-service/device-store");
23
+ // Companion to android-stream-reuse.spec.ts: that one covers the decision, this
24
+ // one covers the wiring — that startStream still short-circuits on a healthy
25
+ // session, and that an unusable one is actually torn down (capture loop stopped,
26
+ // server closed, port lease released) instead of being left listening while a
27
+ // replacement binds a second port. See issue #196.
28
+ // Bypass the constructor: it starts a 1h watchdog interval we don't want.
29
+ function makeService(session) {
30
+ const svc = Object.create(AndroidStreamService_1.default.prototype);
31
+ svc.sessions = new Map();
32
+ svc.startFlight = new singleFlight_1.SingleFlight();
33
+ if (session)
34
+ svc.sessions.set(session.udid, session);
35
+ return svc;
36
+ }
37
+ function session(udid, mjpegPort, overrides = {}) {
38
+ return Object.assign({ udid,
39
+ mjpegPort, server: { listening: true, close: sinon_1.default.spy() }, status: 'running', latestFrame: Buffer.from([0xff, 0xd8]), lastViewerAt: Date.now(), viewerCount: 0 }, overrides);
40
+ }
41
+ describe('AndroidStreamService.startStream session reuse', () => {
42
+ let releaseSpy;
43
+ let getStoreStub;
44
+ beforeEach(() => {
45
+ releaseSpy = sinon_1.default.spy((_port) => __awaiter(void 0, void 0, void 0, function* () { return undefined; }));
46
+ const containerStub = sinon_1.default.stub(typedi_1.Container, 'get').callsFake((token) => {
47
+ if (token === PortAllocator_1.PortAllocator)
48
+ return { release: releaseSpy };
49
+ return containerStub.wrappedMethod.call(typedi_1.Container, token);
50
+ });
51
+ // Any attempt at a real startup dies here, which is what we want: it marks
52
+ // the point where the reuse short-circuit was NOT taken.
53
+ getStoreStub = sinon_1.default.stub(device_store_1.DeviceStoreFactory, 'getStore').returns({
54
+ findDevice: () => __awaiter(void 0, void 0, void 0, function* () { return undefined; }),
55
+ });
56
+ });
57
+ afterEach(() => sinon_1.default.restore());
58
+ it('hands back a healthy session without touching the device store', () => __awaiter(void 0, void 0, void 0, function* () {
59
+ const svc = makeService(session('android-1', 9100));
60
+ (0, chai_1.expect)(yield svc.startStream('android-1')).to.deep.equal({ mjpegPort: 9100 });
61
+ (0, chai_1.expect)(getStoreStub.called, 'reuse must not fall through to a real startup').to.be.false;
62
+ (0, chai_1.expect)(releaseSpy.called, 'a reused session keeps its port lease').to.be.false;
63
+ }));
64
+ for (const [label, overrides] of [
65
+ ['the server is no longer listening', { server: { listening: false, close: sinon_1.default.spy() } }],
66
+ ['it never captured a frame', { latestFrame: undefined }],
67
+ ['it is still starting', { status: 'starting' }],
68
+ ]) {
69
+ it(`discards a session and restarts when ${label}`, () => __awaiter(void 0, void 0, void 0, function* () {
70
+ const dead = session('android-1', 9100, overrides);
71
+ const svc = makeService(dead);
72
+ // No device in the store, so the fresh startup throws — proving we fell
73
+ // through rather than returning the stale port.
74
+ let err;
75
+ try {
76
+ yield svc.startStream('android-1');
77
+ }
78
+ catch (e) {
79
+ err = e;
80
+ }
81
+ (0, chai_1.expect)(err === null || err === void 0 ? void 0 : err.message, 'must attempt a real startup').to.match(/not found in DB/);
82
+ (0, chai_1.expect)(dead.status, 'capture loop must be told to stop').to.equal('stopped');
83
+ (0, chai_1.expect)(dead.server, 'server handle cleared').to.equal(null);
84
+ (0, chai_1.expect)(svc.sessions.has('android-1'), 'stale session evicted').to.be.false;
85
+ (0, chai_1.expect)(releaseSpy.calledWith(9100), 'stale port lease released').to.be.true;
86
+ }));
87
+ }
88
+ it('does not release a lease when there was no session at all', () => __awaiter(void 0, void 0, void 0, function* () {
89
+ const svc = makeService(null);
90
+ yield svc.startStream('android-1').catch(() => undefined);
91
+ (0, chai_1.expect)(releaseSpy.called).to.be.false;
92
+ }));
93
+ });
@@ -0,0 +1,71 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const chai_1 = require("chai");
4
+ const androidStreamReuse_1 = require("../../src/device-managers/android/androidStreamReuse");
5
+ // Guards issue #196. AndroidStreamService.startStream reused any session marked
6
+ // 'running' *or* 'starting' without checking that anything was still serving:
7
+ //
8
+ // const existing = this.sessions.get(udid);
9
+ // if (existing && (existing.status === 'running' || existing.status === 'starting')) {
10
+ // return { mjpegPort: existing.mjpegPort };
11
+ // }
12
+ //
13
+ // so a session whose HTTP server had closed, or which never captured a frame,
14
+ // handed every caller — including ensureMjpegForRecording — a port that serves
15
+ // nothing. ffmpeg then exits 1 against it and leaves a 0-byte mp4, the same
16
+ // silent symptom that took a while to diagnose in #194.
17
+ const healthy = {
18
+ status: 'running',
19
+ serverListening: true,
20
+ hasFrame: true,
21
+ };
22
+ describe('decideAndroidStreamReuse', () => {
23
+ it('reuses a running session that is listening and has a frame', () => {
24
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(healthy)).to.deep.equal({ reuse: true });
25
+ });
26
+ it('starts fresh when there is no session', () => {
27
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(undefined)).to.deep.equal({
28
+ reuse: false,
29
+ reason: 'no-session',
30
+ });
31
+ });
32
+ it("does not treat 'starting' as ready", () => {
33
+ // The bind loop registers the candidate as 'starting' *before* awaiting the
34
+ // listen, so a caller arriving in that window used to get a port that was
35
+ // not yet bound. SingleFlight (#195) closes the concurrent case; this keeps
36
+ // a session left stranded in 'starting' from being handed out later.
37
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(Object.assign(Object.assign({}, healthy), { status: 'starting' }))).to.deep.equal({
38
+ reuse: false,
39
+ reason: 'not-running',
40
+ });
41
+ });
42
+ it('restarts a stopped or errored session', () => {
43
+ for (const status of ['stopped', 'error']) {
44
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(Object.assign(Object.assign({}, healthy), { status })), status).to.deep.equal({
45
+ reuse: false,
46
+ reason: 'not-running',
47
+ });
48
+ }
49
+ });
50
+ it('restarts a running session whose server is no longer listening', () => {
51
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(Object.assign(Object.assign({}, healthy), { serverListening: false }))).to.deep.equal({
52
+ reuse: false,
53
+ reason: 'server-closed',
54
+ });
55
+ });
56
+ it('restarts a running session that never captured a frame', () => {
57
+ // startStream logs "no frames captured after 5000ms" and goes 'running'
58
+ // anyway, so this state is reachable today: every later caller gets a live
59
+ // socket that emits headers and no JPEGs.
60
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)(Object.assign(Object.assign({}, healthy), { hasFrame: false }))).to.deep.equal({
61
+ reuse: false,
62
+ reason: 'no-frame',
63
+ });
64
+ });
65
+ it('reports the most fundamental failure first', () => {
66
+ // A session that is neither running nor listening is reported as
67
+ // 'not-running' — the reason drives a log line, so it should name the cause
68
+ // rather than a downstream consequence of it.
69
+ (0, chai_1.expect)((0, androidStreamReuse_1.decideAndroidStreamReuse)({ status: 'stopped', serverListening: false, hasFrame: false })).to.deep.equal({ reuse: false, reason: 'not-running' });
70
+ });
71
+ });
@@ -1 +1 @@
1
- {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/helpers.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/manualLock.test.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
1
+ {"root":["../src/InternalHttpClient.ts","../src/PluginContext.ts","../src/XenonCapabilityManager.ts","../src/chromeUtils.ts","../src/config.ts","../src/device-utils.ts","../src/index.ts","../src/logger.ts","../src/plugin.ts","../src/prisma.ts","../src/app/index.ts","../src/app/swagger-docs.ts","../src/app/swagger.ts","../src/app/routers/androidH264Config.ts","../src/app/routers/apikeys.ts","../src/app/routers/apps.ts","../src/app/routers/audit.ts","../src/app/routers/auth.ts","../src/app/routers/bug-report.ts","../src/app/routers/build-export.ts","../src/app/routers/capabilities.ts","../src/app/routers/config.ts","../src/app/routers/control.ts","../src/app/routers/dashboard.ts","../src/app/routers/grid.ts","../src/app/routers/interceptor.ts","../src/app/routers/iosStreamPort.ts","../src/app/routers/ports.ts","../src/app/routers/processes.ts","../src/app/routers/profile.ts","../src/app/routers/profileIdentity.ts","../src/app/routers/projects.ts","../src/app/routers/recordings.ts","../src/app/routers/reservation.ts","../src/app/routers/sdk-leases.ts","../src/app/routers/sdk-version.ts","../src/app/routers/streamType.ts","../src/app/routers/teams.ts","../src/app/routers/users.ts","../src/app/routers/webhook.ts","../src/app/ws/h264StreamWs.ts","../src/commands/handle.ts","../src/commands/index.ts","../src/dashboard/asset-manager.ts","../src/dashboard/commands.ts","../src/dashboard/event-manager.ts","../src/dashboard/services/app-service.ts","../src/dashboard/services/failure-analysis-service.ts","../src/dashboard/services/session-service.ts","../src/data-service/CircuitBreaker.ts","../src/data-service/config-service.ts","../src/data-service/db.ts","../src/data-service/device-service.ts","../src/data-service/device-store.interface.ts","../src/data-service/device-store.ts","../src/data-service/pending-sessions-service.ts","../src/data-service/pluginArgs.ts","../src/data-service/prisma-service.ts","../src/data-service/prisma-store.ts","../src/data-service/queue-service.ts","../src/data-service/web-config-service.ts","../src/device-managers/AndroidDeviceManager.ts","../src/device-managers/ChromeDriverManager.ts","../src/device-managers/HealthMonitorService.ts","../src/device-managers/IOSDeviceManager.ts","../src/device-managers/NodeDevices.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/android/AndroidH264StreamService.ts","../src/device-managers/android/AndroidStreamService.ts","../src/device-managers/android/DeviceLockManager.ts","../src/device-managers/android/H264Multiplexer.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/scrcpyVersion.ts","../src/device-managers/cloud/CapabilityManager.ts","../src/device-managers/cloud/Devices.ts","../src/device-managers/ios/IOSDiscoveryService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/iosBattery.ts","../src/device-managers/ios/iosStreamDiagnostics.ts","../src/device-managers/ios/tunnelProcess.ts","../src/enums/Capabilities.ts","../src/enums/Cloud.ts","../src/enums/Platform.ts","../src/enums/SessionType.ts","../src/enums/SocketEvents.ts","../src/generated/client/default.d.ts","../src/generated/client/default.js","../src/generated/client/edge.d.ts","../src/generated/client/edge.js","../src/generated/client/index-browser.js","../src/generated/client/index.d.ts","../src/generated/client/index.js","../src/generated/client/wasm.d.ts","../src/generated/client/wasm.js","../src/generated/client/runtime/edge-esm.js","../src/generated/client/runtime/edge.js","../src/generated/client/runtime/index-browser.d.ts","../src/generated/client/runtime/index-browser.js","../src/generated/client/runtime/library.d.ts","../src/generated/client/runtime/library.js","../src/generated/client/runtime/react-native.js","../src/generated/client/runtime/wasm.js","../src/helpers/UniversalMjpegProxy.ts","../src/helpers/ffmpegPath.ts","../src/helpers/index.ts","../src/helpers/networkAddresses.ts","../src/helpers/singleFlight.ts","../src/interceptors/CommandInterceptor.ts","../src/interfaces/ICloudManager.ts","../src/interfaces/IDevice.ts","../src/interfaces/IDeviceFilterOptions.ts","../src/interfaces/IDeviceManager.ts","../src/interfaces/IOptions.ts","../src/interfaces/IPluginArgs.ts","../src/interfaces/ISessionCapability.ts","../src/logging/sessionContext.ts","../src/middleware/authMiddleware.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/profiling/AndroidAppProfiler.ts","../src/proxy/wd-command-proxy.ts","../src/scripts/generate-database-migration.ts","../src/scripts/goIosVersion.ts","../src/scripts/initialize-database.ts","../src/scripts/install-go-ios.ts","../src/scripts/prepare-prisma.ts","../src/scripts/run-migrations.ts","../src/services/AICommandService.ts","../src/services/AIService.ts","../src/services/ApiKeyService.ts","../src/services/CircuitBreaker.ts","../src/services/CleanupService.ts","../src/services/DeviceReconciler.ts","../src/services/EmailService.ts","../src/services/EventBus.ts","../src/services/EventLogService.ts","../src/services/InspectorService.ts","../src/services/InterceptorService.ts","../src/services/MetricsService.ts","../src/services/NetworkConditioningService.ts","../src/services/NotificationService.ts","../src/services/OrphanSweeper.ts","../src/services/PasswordResetService.ts","../src/services/PortAllocator.ts","../src/services/ProcessMetricsService.ts","../src/services/ProcessRegistry.ts","../src/services/RequestLogService.ts","../src/services/ResourceIsolationService.ts","../src/services/SecurityService.ts","../src/services/SelectorStateService.ts","../src/services/SelectorVerificationJob.ts","../src/services/ServerManager.ts","../src/services/SessionHeartbeatService.ts","../src/services/SessionLifecycleService.ts","../src/services/ShutdownCoordinator.ts","../src/services/SocketClient.ts","../src/services/SocketServer.ts","../src/services/TeamService.ts","../src/services/TracingService.ts","../src/services/UserService.ts","../src/services/UserSessionService.ts","../src/services/VideoPipelineService.ts","../src/services/sessionTokenGate.ts","../src/services/artifacts/ArtifactStore.ts","../src/services/autowait/AutowaitService.ts","../src/services/autowait/waitFor.ts","../src/services/bug-report/BugReportService.ts","../src/services/bug-report/archive.ts","../src/services/bug-report/har-collector.ts","../src/services/bug-report/manifest.ts","../src/services/bug-report/readme.ts","../src/services/bug-report/types.ts","../src/services/bug-report/video-slice.ts","../src/services/bug-report/window.ts","../src/services/healing/FuzzyXmlHealingProvider.ts","../src/services/healing/HealEtalonService.ts","../src/services/healing/HealedLocatorGenerator.ts","../src/services/healing/HealingMetrics.ts","../src/services/healing/HealingOrchestrator.ts","../src/services/healing/LlmHealingProvider.ts","../src/services/healing/OcrHealingProvider.ts","../src/services/healing/ResilioTreeHealingProvider.ts","../src/services/healing/VisualAiHealingProvider.ts","../src/services/healing/types.ts","../src/services/identity/bootstrap.ts","../src/services/identity/sessionCleanupCron.ts","../src/services/identity/userAuthorization.ts","../src/services/interceptor/AndroidProxyAdapter.ts","../src/services/interceptor/CertManager.ts","../src/services/interceptor/HarBuilder.ts","../src/services/interceptor/HostFilter.ts","../src/services/interceptor/MitmProxyHost.ts","../src/services/interceptor/MockEngine.ts","../src/services/interceptor/RequestBuffer.ts","../src/services/interceptor/SessionArchive.ts","../src/services/interceptor/types.ts","../src/services/lease/LeaseOrphanSweeper.ts","../src/services/lease/LeaseService.ts","../src/services/lease/buildCapabilityBag.ts","../src/services/lease/leaseToken.ts","../src/services/omni-vision/OmniVisionService.ts","../src/services/omni-vision/VisionAssertionService.ts","../src/services/ports/PortAllocatorClient.ts","../src/services/ports/PortAllocatorService.ts","../src/services/recording/RecordingOrchestrator.ts","../src/services/recording/annotation-render.ts","../src/services/recording/busy-precheck.ts","../src/services/recording/concurrency-gate.ts","../src/services/recording/ensureMjpegForRecording.ts","../src/services/recording/manualLock.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/telemetry/attributes.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/types/CLIArgs.ts","../src/types/CloudArgs.ts","../src/types/CloudSchema.ts","../src/types/DeviceType.ts","../src/types/DeviceUpdate.ts","../src/types/IOSDevice.ts","../src/types/Platform.ts","../src/types/SessionStatus.ts","../src/types/express.d.ts","../src/types/healing.d.ts","../src/types/identity.ts","../src/validators/CapabilityValidator.ts","../test/e2e/e2ehelper.ts","../test/e2e/plugin-harness.ts","../test/e2e/plugin.spec.ts","../test/e2e/startup-verification.spec.ts","../test/e2e/telemetry_verification.spec.ts","../test/e2e/video-recording-test.spec.js","../test/e2e/android/conf.spec.js","../test/e2e/android/conf2.spec.js","../test/e2e/android/conf3.spec.js","../test/e2e/hubnode/forward-request.spec.ts","../test/e2e/hubnode/hubnode.spec.ts","../test/e2e/ios/conf1.spec.js","../test/e2e/ios/conf2.spec.js","../test/helpers/seedUser.ts","../test/helpers/test-container.ts","../test/integration/androidDevices.spec.ts","../test/integration/audit-ingest.spec.ts","../test/integration/auth-flow.spec.ts","../test/integration/auth-rate-limit.spec.ts","../test/integration/bug-report-route.spec.ts","../test/integration/cliArgs.js","../test/integration/cross-workflow.spec.ts","../test/integration/forgot-password-rate-limit.spec.ts","../test/integration/forgot-password.spec.ts","../test/integration/healing-events-sessionfilter.spec.ts","../test/integration/legacy-deprecation-headers.spec.ts","../test/integration/migration.spec.ts","../test/integration/node-pair-auth-rest.spec.ts","../test/integration/ports-router.spec.ts","../test/integration/profile-tokens.spec.ts","../test/integration/recordings-router.spec.ts","../test/integration/reset-revokes-sessions.spec.ts","../test/integration/role-matrix.spec.ts","../test/integration/sdk-leases-router.spec.ts","../test/integration/sdk-version.spec.ts","../test/integration/selector-health-endpoint.spec.ts","../test/integration/selector-state-flow.spec.ts","../test/integration/team-membership-migration.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/users-flow.spec.ts","../test/integration/users-lockout.spec.ts","../test/integration/ios/01iOSSimulator.spec.ts","../test/integration/ios/02iOSDevices.spec.ts","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/ArtifactStore.spec.ts","../test/unit/AutowaitService.spec.ts","../test/unit/CapabilitiesRouter.spec.ts","../test/unit/ChromeDriverManager.spec.js","../test/unit/CleanupService.spec.ts","../test/unit/CommandInterceptor.autowait.spec.ts","../test/unit/DeviceModel.spec.ts","../test/unit/EmailService.test.ts","../test/unit/EventLogService.spec.ts","../test/unit/FuzzyXmlHealingProvider.test.ts","../test/unit/GetAdbOriginal.js","../test/unit/HealingCascade.test.ts","../test/unit/IOSDeviceManager.spec.js","../test/unit/JwtKeyService.spec.ts","../test/unit/McpScopes.spec.ts","../test/unit/OrphanSweeper.test.ts","../test/unit/PasswordResetService.test.ts","../test/unit/PortAllocator.test.ts","../test/unit/ProcessRegistry.test.ts","../test/unit/ProjectsRouter.spec.ts","../test/unit/RemoteIOs.spec.js","../test/unit/ResilioTreeHealingProvider.test.ts","../test/unit/SessionHeartbeatWrite.test.ts","../test/unit/SessionLifecycleCaps.spec.ts","../test/unit/SessionTokenGate.spec.ts","../test/unit/StreamTicketService.spec.ts","../test/unit/TeamService.test.ts","../test/unit/TokenEndpoint.spec.ts","../test/unit/UserService.test.ts","../test/unit/UserSessionService.test.ts","../test/unit/XenonCapabilityManager.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-stream-adb-path.spec.ts","../test/unit/android-stream-encoder.spec.ts","../test/unit/android-stream-fast-start.spec.ts","../test/unit/android-stream-release.spec.ts","../test/unit/android-stream-reuse-service.spec.ts","../test/unit/android-stream-reuse.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.bearer.spec.ts","../test/unit/authMiddleware.mcpAudience.spec.ts","../test/unit/authMiddleware.streamTicket.spec.ts","../test/unit/authMiddleware.test.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/commands.spec.js","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/device-service.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/enrich-devices-team-names.test.ts","../test/unit/event-manager-regression-hook.spec.ts","../test/unit/extract-access-key-token-pair.test.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/h264-multiplexer.spec.ts","../test/unit/h264-nal-parser.spec.ts","../test/unit/h264-ws-frame.spec.ts","../test/unit/healing-instrumentation.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/helpers.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/manualLock.test.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/plugin.spec.ts","../test/unit/prisma.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/bug-report/archive.spec.ts","../test/unit/bug-report/har-collector.spec.ts","../test/unit/bug-report/manifest.spec.ts","../test/unit/bug-report/readme.spec.ts","../test/unit/bug-report/route.spec.ts","../test/unit/bug-report/service.spec.ts","../test/unit/bug-report/video-slice.spec.ts","../test/unit/bug-report/window.spec.ts","../test/unit/fixtures/device.config.js","../test/unit/fixtures/devices.js","../test/unit/interceptor/AndroidProxyAdapter.spec.ts","../test/unit/interceptor/CertManager.spec.ts","../test/unit/interceptor/HarBuilder.spec.ts","../test/unit/interceptor/HostFilter.spec.ts","../test/unit/interceptor/MitmProxyHost.spec.ts","../test/unit/interceptor/MockEngine.spec.ts","../test/unit/interceptor/RequestBuffer.spec.ts","../test/unit/interceptor/SessionArchive.spec.ts","../test/unit/lease/LeaseOrphanSweeper.spec.ts","../test/unit/lease/LeaseService.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
4
4
  "description": "Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.",
5
5
  "main": "./lib/src/index.js",
6
6
  "exports": {