@xenon-device-management/xenon 2.10.0 → 2.11.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.
Files changed (114) hide show
  1. package/lib/package.json +1 -1
  2. package/lib/public/assets/{AnnotationOverlay-LzfXiiZJ.js → AnnotationOverlay-BQPQ5bPF.js} +1 -1
  3. package/lib/public/assets/{ApiKeyGate-BzFDp4mK.js → ApiKeyGate-Bd7Pumwv.js} +1 -1
  4. package/lib/public/assets/{BugReportButton-BpgWvmZo.js → BugReportButton-iC7fxPxl.js} +1 -1
  5. package/lib/public/assets/{DeviceMosaicView-CCB-egSH.js → DeviceMosaicView-CNdES7nm.js} +1 -1
  6. package/lib/public/assets/{EmptyState-DkUVmANo.js → EmptyState-wZeJbGhN.js} +1 -1
  7. package/lib/public/assets/{FieldGroup-mbfnfTql.js → FieldGroup-tpRfmhlE.js} +1 -1
  8. package/lib/public/assets/{FilterMenu-BH5usz4Y.js → FilterMenu-BZwOppId.js} +1 -1
  9. package/lib/public/assets/{Menu-Cbo9mdTk.js → Menu-CahoAx8L.js} +1 -1
  10. package/lib/public/assets/{Modal-D6XfQHPr.js → Modal-mcM5W_Ji.js} +1 -1
  11. package/lib/public/assets/{RecordingPage-CmFPkWqH.js → RecordingPage-B4dFBndn.js} +1 -1
  12. package/lib/public/assets/{RecordingsPage-CSlKk2qC.js → RecordingsPage-BOez3f_9.js} +1 -1
  13. package/lib/public/assets/{SegmentedControl-BFW9Dlqd.js → SegmentedControl-qMSiMN1d.js} +1 -1
  14. package/lib/public/assets/{SettingCard-C4DioTTi.js → SettingCard-rcPtJ7HG.js} +1 -1
  15. package/lib/public/assets/{Table-DrKjlL00.js → Table-J3uognu0.js} +1 -1
  16. package/lib/public/assets/{activity-C9bE7Jm8.js → activity-_5pNSfKT.js} +1 -1
  17. package/lib/public/assets/{ai-settings-DRYic4oO.js → ai-settings-DTPRbkei.js} +1 -1
  18. package/lib/public/assets/{api-keys-CaQU0g7c.js → api-keys-CxkIUo76.js} +1 -1
  19. package/lib/public/assets/apps-BQKfuN3J.css +1 -0
  20. package/lib/public/assets/{apps-c1gUFmmK.js → apps-Bv0pAfxz.js} +2 -2
  21. package/lib/public/assets/{arrow-left-DMvAWA8r.js → arrow-left-uY7F6z1K.js} +1 -1
  22. package/lib/public/assets/{arrow-right-BEQgxmKT.js → arrow-right-BbAm_2Wa.js} +1 -1
  23. package/lib/public/assets/{arrow-up-right-Ba0e2GeU.js → arrow-up-right-x4H5NuvE.js} +1 -1
  24. package/lib/public/assets/{auth-shell-COODQnc7.js → auth-shell-CtMFhbnC.js} +2 -2
  25. package/lib/public/assets/{builds-page-DZQgWBUs.js → builds-page-B_O5uBSZ.js} +1 -1
  26. package/lib/public/assets/{button-WW9j43wR.js → button-CQoMQEj_.js} +1 -1
  27. package/lib/public/assets/{calendar-COUs9VxF.js → calendar-BZkpCqlL.js} +1 -1
  28. package/lib/public/assets/{check-D8ifHIJR.js → check-CAB6RYuc.js} +1 -1
  29. package/lib/public/assets/{chevron-right-BjKVUlB_.js → chevron-right-ec0unu3u.js} +1 -1
  30. package/lib/public/assets/{circle-check-CfP79QE2.js → circle-check-Dfg-gpjg.js} +1 -1
  31. package/lib/public/assets/{circle-x-BZbFCixZ.js → circle-x-cbPq6Btp.js} +1 -1
  32. package/lib/public/assets/{clock-BuTm35Qg.js → clock-DU9cBLi8.js} +1 -1
  33. package/lib/public/assets/{copy-W00zUBwN.js → copy-VM9kWPpE.js} +1 -1
  34. package/lib/public/assets/{device-explorer-BEpS-Y-_.js → device-explorer-ai0usQ8m.js} +1 -1
  35. package/lib/public/assets/{download-CGz-MS3y.js → download-WgW4AVid.js} +1 -1
  36. package/lib/public/assets/{forgot-password-DG7SqVgU.js → forgot-password-BGRpjTtt.js} +1 -1
  37. package/lib/public/assets/{index-EkaQM1DK.js → index-C33GjwPr.js} +2 -2
  38. package/lib/public/assets/{index-DWHTp1YP.js → index-DNDdHt3h.js} +1 -1
  39. package/lib/public/assets/{input-ChaTXeCq.js → input-DwiVcO3Q.js} +1 -1
  40. package/lib/public/assets/{keycodes-BhbgeW_r.js → keycodes-CvCtpVJD.js} +1 -1
  41. package/lib/public/assets/{line-chart-9P3RxScy.js → line-chart-PE5e9PeN.js} +1 -1
  42. package/lib/public/assets/{list-checks-_23IIEEL.js → list-checks-Bgn9GEEO.js} +1 -1
  43. package/lib/public/assets/{lock-B2JaqqRI.js → lock-Cb7My6hc.js} +1 -1
  44. package/lib/public/assets/{login-BEWIfLfC.js → login-CDmyzSpl.js} +1 -1
  45. package/lib/public/assets/{maintenance-settings-BGJIJQ-k.js → maintenance-settings-Bq6pKoBt.js} +1 -1
  46. package/lib/public/assets/{monitor-BrwMY4G0.js → monitor-BZSwrnPV.js} +1 -1
  47. package/lib/public/assets/{mouse-pointer-2-DsWDMyrY.js → mouse-pointer-2-BbFj8y8i.js} +1 -1
  48. package/lib/public/assets/{network-DfIhNVJv.js → network-DpwYGB0-.js} +1 -1
  49. package/lib/public/assets/{overview-B1mePY2_.js → overview-B4_IO-X8.js} +1 -1
  50. package/lib/public/assets/{page-header-DoD3TOzZ.js → page-header-BpLEuo7i.js} +1 -1
  51. package/lib/public/assets/{plus-BGvWvpBB.js → plus-DHZS0EGU.js} +1 -1
  52. package/lib/public/assets/{profile-page-CvV5aWvl.js → profile-page-DsHDIq-Y.js} +1 -1
  53. package/lib/public/assets/{reset-password-CGVd31LR.js → reset-password-DuUjhw_l.js} +1 -1
  54. package/lib/public/assets/{runbook-page-Bq2cvwb5.js → runbook-page-BI_ayvLd.js} +1 -1
  55. package/lib/public/assets/{select-CTcD4jWR.js → select-xiba9PSx.js} +1 -1
  56. package/lib/public/assets/selector-detail-redirect-Emz2obK_.js +1 -0
  57. package/lib/public/assets/selector-health-page-zpwrgalC.js +11 -0
  58. package/lib/public/assets/session-detail-page-BhlTJ1Oq.js +4 -0
  59. package/lib/public/assets/{settings-C-EnGIqs.js → settings-B-mabJFm.js} +1 -1
  60. package/lib/public/assets/{stat-tile-BY0RDTRm.js → stat-tile-lT8WcPgu.js} +1 -1
  61. package/lib/public/assets/{tablet-B4cFM-5B.js → tablet-DM8dp75P.js} +1 -1
  62. package/lib/public/assets/{teams-BFe-RpYd.js → teams-CRkb5-Fe.js} +1 -1
  63. package/lib/public/assets/{trash-2-CJCKBOP9.js → trash-2-Dxgryn4o.js} +1 -1
  64. package/lib/public/assets/{upload-DidWkbld.js → upload-Ci0vz0BP.js} +1 -1
  65. package/lib/public/assets/{use-builds-data-fnfxatOd.js → use-builds-data-DaaqMjjL.js} +1 -1
  66. package/lib/public/assets/{use-password-reset-mode-iPen3tmC.js → use-password-reset-mode-BvIyZtaF.js} +1 -1
  67. package/lib/public/assets/{users-CrcjmRdf.js → users-BT8qx3ea.js} +1 -1
  68. package/lib/public/assets/{users-DBUv0CJx.js → users-CWYHk75q.js} +1 -1
  69. package/lib/public/assets/{video-off-eh69-FKB.js → video-off-BvY08g6I.js} +1 -1
  70. package/lib/public/assets/view-state-83Z1gFME.js +1 -0
  71. package/lib/public/assets/{webhook-settings-CQoSshBn.js → webhook-settings-aHIlSJFP.js} +1 -1
  72. package/lib/public/assets/{zap-CICtWiLn.js → zap-qG2Li6rI.js} +1 -1
  73. package/lib/public/index.html +1 -1
  74. package/lib/src/app/index.js +2 -0
  75. package/lib/src/dashboard/event-manager.js +4 -6
  76. package/lib/src/gateway/nodeSessionMetrics.js +39 -0
  77. package/lib/src/gateway/nodeSessionStatus.js +32 -23
  78. package/lib/src/generated/client/edge.js +2 -2
  79. package/lib/src/generated/client/index.js +2 -2
  80. package/lib/src/generated/client/package.json +1 -1
  81. package/lib/src/generated/client/schema.prisma +6 -0
  82. package/lib/src/plugin.js +3 -0
  83. package/lib/src/services/SelectorVerificationJob.js +50 -5
  84. package/lib/src/services/SessionLifecycleService.js +16 -0
  85. package/lib/src/services/metrics/NodeMetricsCollector.js +114 -0
  86. package/lib/src/services/metrics/NodeMetricsStore.js +76 -0
  87. package/lib/src/services/metrics/SessionMetricsService.js +71 -14
  88. package/lib/src/services/metrics/nodeMetrics.js +92 -0
  89. package/lib/src/services/selector-health/selectorDetail.js +36 -20
  90. package/lib/src/sessions/RemoteSession.js +32 -0
  91. package/lib/src/sessions/SessionManager.js +63 -0
  92. package/lib/test/helpers/scratch-database.js +17 -3
  93. package/lib/test/unit/dashboard-events-metrics.spec.js +10 -0
  94. package/lib/test/unit/hub-node-session-metrics.spec.js +330 -0
  95. package/lib/test/unit/node-metrics-collector.spec.js +226 -0
  96. package/lib/test/unit/node-metrics-store.spec.js +70 -0
  97. package/lib/test/unit/node-session-metrics-route.spec.js +97 -0
  98. package/lib/test/unit/selector-health-detail.spec.js +57 -0
  99. package/lib/test/unit/selector-verification-job.spec.js +3 -0
  100. package/lib/test/unit/selector-verification-missed-regression.spec.js +132 -0
  101. package/lib/test/unit/session-log-indexes.spec.js +147 -0
  102. package/lib/test/unit/session-metrics-lifecycle.spec.js +55 -0
  103. package/lib/test/unit/session-metrics-service.spec.js +97 -0
  104. package/lib/test/unit/session-recovery-metrics.spec.js +94 -0
  105. package/lib/tsconfig.tsbuildinfo +1 -1
  106. package/package.json +1 -1
  107. package/prisma/migrations/20261002180000_session_log_indexes/migration.sql +5 -0
  108. package/prisma/migrations/20261002190000_log_profiling_session_indexes/migration.sql +5 -0
  109. package/prisma/schema.prisma +6 -0
  110. package/lib/public/assets/apps-DMhpZuKd.css +0 -1
  111. package/lib/public/assets/selector-detail-redirect-19odlD4B.js +0 -1
  112. package/lib/public/assets/selector-health-page-LqIsLrjW.js +0 -11
  113. package/lib/public/assets/session-detail-page-DQzb8_fq.js +0 -4
  114. package/lib/public/assets/view-state-CP9dE1UI.js +0 -1
@@ -0,0 +1,147 @@
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 supertest_1 = __importDefault(require("supertest"));
18
+ const typedi_1 = require("typedi");
19
+ const CleanupService_1 = require("../../src/services/CleanupService");
20
+ const scratch_database_1 = require("../helpers/scratch-database");
21
+ const selector_health_fixture_1 = require("../helpers/selector-health-fixture");
22
+ /** The SQL statements `run` makes. */
23
+ function sqlOf(db, run) {
24
+ return __awaiter(this, void 0, void 0, function* () {
25
+ db.queries.length = 0;
26
+ yield run();
27
+ return db.queries.slice();
28
+ });
29
+ }
30
+ /** How SQLite reads `table` in these statements: one line per step. */
31
+ function stepsOn(db, table, queries) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ var _a;
34
+ const steps = [];
35
+ for (const q of queries) {
36
+ if (!q.query.includes(`\`${table}\``))
37
+ continue;
38
+ // SQLite plans without looking at the values, and Prisma's logged
39
+ // parameters aren't JSON, so every placeholder gets null.
40
+ const placeholders = ((_a = q.query.match(/\?/g)) !== null && _a !== void 0 ? _a : []).length;
41
+ const plan = yield db.db.$queryRawUnsafe(`EXPLAIN QUERY PLAN ${q.query}`, ...new Array(placeholders).fill(null));
42
+ steps.push(...plan.map((p) => p.detail).filter((d) => new RegExp(`\\b${table}\\b`).test(d)));
43
+ }
44
+ return steps;
45
+ });
46
+ }
47
+ /** The steps that walk the whole table, or a whole index of it. */
48
+ const scansOf = (table, steps) => steps.filter((s) => new RegExp(`^SCAN (main\\.)?${table}\\b`).test(s));
49
+ const getAs = (auth, path) => () => __awaiter(void 0, void 0, void 0, function* () {
50
+ const res = yield (0, supertest_1.default)((0, selector_health_fixture_1.selectorHealthApp)(auth)).get(path);
51
+ (0, chai_1.expect)(res.status, `${path}: ${res.text}`).to.equal(200);
52
+ });
53
+ /**
54
+ * SessionLog holds every command of every session, so a read that scans it
55
+ * costs as much as the lab's whole history: on a million commands, the
56
+ * "To fix" list took 2.5 s and a session's own commands 80 ms. Each read
57
+ * these pages make must find its rows through an index.
58
+ */
59
+ describe('SessionLog is read through an index', function () {
60
+ this.timeout(30000);
61
+ const scratch = (0, scratch_database_1.useScratchDatabase)({ captureQueries: true });
62
+ before(() => __awaiter(this, void 0, void 0, function* () {
63
+ yield (0, selector_health_fixture_1.seedSelectorHealth)(scratch.db);
64
+ }));
65
+ const cases = [
66
+ ['the summary', selector_health_fixture_1.ADMIN, '/healing/summary?windowDays=365&tz=330'],
67
+ ["a member's summary", selector_health_fixture_1.MEMBER_A, '/healing/summary?windowDays=30'],
68
+ ['"To fix"', selector_health_fixture_1.ADMIN, '/healing/selectors?tab=fix&days=365'],
69
+ ['"To fix" with a search', selector_health_fixture_1.ADMIN, '/healing/selectors?tab=fix&days=30&q=confirm'],
70
+ ['"To fix" on one platform', selector_health_fixture_1.ADMIN, '/healing/selectors?tab=fix&days=30&platform=android'],
71
+ ['a member\'s "To fix"', selector_health_fixture_1.MEMBER_A, '/healing/selectors?tab=fix&days=30'],
72
+ ['"Fixed"', selector_health_fixture_1.ADMIN, '/healing/selectors?tab=fixed&days=30'],
73
+ ['a member\'s "Fixed"', selector_health_fixture_1.MEMBER_A, '/healing/selectors?tab=fixed&days=30'],
74
+ [
75
+ 'the panel',
76
+ selector_health_fixture_1.ADMIN,
77
+ `/healing/selectors/detail?strategy=xpath&selector=${encodeURIComponent(selector_health_fixture_1.SEL.hot)}&days=365`,
78
+ ],
79
+ [
80
+ "a member's panel",
81
+ selector_health_fixture_1.MEMBER_A,
82
+ `/healing/selectors/detail?strategy=xpath&selector=${encodeURIComponent(selector_health_fixture_1.SEL.hot)}&days=30`,
83
+ ],
84
+ ["a session's commands", selector_health_fixture_1.ADMIN, '/session/sh-s-shared-1/session_log'],
85
+ ];
86
+ for (const [name, auth, path] of cases) {
87
+ it(`reads ${name} without a scan`, () => __awaiter(this, void 0, void 0, function* () {
88
+ const steps = yield stepsOn(scratch, 'SessionLog', yield sqlOf(scratch, getAs(auth, path)));
89
+ (0, chai_1.expect)(steps, 'no SessionLog statement was captured').to.not.be.empty;
90
+ (0, chai_1.expect)(scansOf('SessionLog', steps), steps.join('\n')).to.deep.equal([]);
91
+ }));
92
+ }
93
+ });
94
+ /**
95
+ * A session's device logs (hundreds of lines a session) and the profiling
96
+ * rows sessions wrote before 2.10 are read by session on every session page,
97
+ * and deleted by session in cleanup. Neither table had an index on it.
98
+ */
99
+ describe("A session's logs and profiling are read through an index", function () {
100
+ this.timeout(30000);
101
+ const scratch = (0, scratch_database_1.useScratchDatabase)({ captureQueries: true });
102
+ before(() => __awaiter(this, void 0, void 0, function* () {
103
+ yield scratch.db.build.create({ data: { id: 'ix-build', name: 'ix' } });
104
+ yield scratch.db.session.create({
105
+ data: {
106
+ id: 'ix-session',
107
+ build_id: 'ix-build',
108
+ device_udid: 'ix-phone',
109
+ device_platform: 'android',
110
+ device_version: '14',
111
+ desired_capabilities: '{}',
112
+ session_capabilities: '{}',
113
+ node_id: 'localhost',
114
+ has_live_video: false,
115
+ },
116
+ });
117
+ yield scratch.db.log.createMany({
118
+ data: [
119
+ { session_id: 'ix-session', log_type: 'DEVICE', message: 'I/ActivityManager: start' },
120
+ { session_id: 'ix-session', log_type: 'DEBUG', message: 'step 1' },
121
+ ],
122
+ });
123
+ yield scratch.db.profiling.create({
124
+ data: { session_id: 'ix-session', cpu: '12', memory: '200', timestamp: new Date() },
125
+ });
126
+ }));
127
+ const reads = [
128
+ ['device logs', 'Log', '/session/ix-session/logs/device'],
129
+ ['debug logs', 'Log', '/session/ix-session/logs/debug'],
130
+ ['profiling', 'Profiling', '/session/ix-session/profiling'],
131
+ ];
132
+ for (const [name, table, path] of reads) {
133
+ it(`reads a session's ${name} without a scan`, () => __awaiter(this, void 0, void 0, function* () {
134
+ const steps = yield stepsOn(scratch, table, yield sqlOf(scratch, getAs(selector_health_fixture_1.ADMIN, path)));
135
+ (0, chai_1.expect)(steps, `no ${table} statement was captured`).to.not.be.empty;
136
+ (0, chai_1.expect)(scansOf(table, steps), steps.join('\n')).to.deep.equal([]);
137
+ }));
138
+ }
139
+ it("deletes a session's commands, logs and profiling without a scan", () => __awaiter(this, void 0, void 0, function* () {
140
+ const ran = yield sqlOf(scratch, () => typedi_1.Container.get(CleanupService_1.CleanupService).purgeBuild('ix-build', false));
141
+ for (const table of ['SessionLog', 'Log', 'Profiling']) {
142
+ const steps = yield stepsOn(scratch, table, ran);
143
+ (0, chai_1.expect)(steps, `no ${table} statement was captured`).to.not.be.empty;
144
+ (0, chai_1.expect)(scansOf(table, steps), `${table}:\n${steps.join('\n')}`).to.deep.equal([]);
145
+ }
146
+ }));
147
+ });
@@ -0,0 +1,55 @@
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 plugin_1 = require("../../src/plugin");
20
+ const NodeDevices_1 = __importDefault(require("../../src/device-managers/NodeDevices"));
21
+ const SessionLifecycleService_1 = require("../../src/services/SessionLifecycleService");
22
+ const SessionMetricsService_1 = require("../../src/services/metrics/SessionMetricsService");
23
+ const event_manager_1 = require("../../src/dashboard/event-manager");
24
+ const container_registration_1 = require("../helpers/container-registration");
25
+ const scratch_database_1 = require("../helpers/scratch-database");
26
+ /**
27
+ * A session's sampling stops however the session ends on this server, its
28
+ * dashboard on or off: on a node that ends the figures it holds for the hub.
29
+ */
30
+ describe('session sampling stops however a session ends', function () {
31
+ this.timeout(30000);
32
+ (0, scratch_database_1.useScratchDatabase)();
33
+ let restore;
34
+ let stop;
35
+ beforeEach(() => {
36
+ restore = (0, container_registration_1.saveRegistrations)(SessionMetricsService_1.SessionMetricsService);
37
+ stop = sinon_1.default.stub().resolves();
38
+ typedi_1.Container.set(SessionMetricsService_1.SessionMetricsService, { stop });
39
+ });
40
+ afterEach(() => {
41
+ sinon_1.default.restore();
42
+ restore();
43
+ });
44
+ it('at shutdown', () => __awaiter(this, void 0, void 0, function* () {
45
+ sinon_1.default.stub(event_manager_1.DASHBORD_EVENT_MANAGER, 'onSessionStopped').resolves();
46
+ yield typedi_1.Container.get(SessionLifecycleService_1.SessionLifecycleService).stopSessionForShutdown('s-down', 'shutdown');
47
+ (0, chai_1.expect)(stop.calledWith('s-down')).to.equal(true);
48
+ }));
49
+ it('when the driver shuts down unexpectedly on a node', () => __awaiter(this, void 0, void 0, function* () {
50
+ sinon_1.default.stub(NodeDevices_1.default.prototype, 'unblockDevice').resolves();
51
+ const plugin = { pluginArgs: { hub: 'http://hub:4723' } };
52
+ yield plugin_1.XenonPlugin.prototype.onUnexpectedShutdown.call(plugin, { sessionId: 's-crash', caps: {} }, null);
53
+ (0, chai_1.expect)(stop.calledWith('s-crash')).to.equal(true);
54
+ }));
55
+ });
@@ -32,6 +32,23 @@ class FakeSampler {
32
32
  });
33
33
  }
34
34
  }
35
+ class FakeStore {
36
+ constructor() {
37
+ this.calls = [];
38
+ }
39
+ begin(id, platform) {
40
+ this.calls.push(`begin ${id} ${platform}`);
41
+ }
42
+ add(id, s) {
43
+ this.calls.push(`add ${id} ${s.at}`);
44
+ }
45
+ gaveUp(id) {
46
+ this.calls.push(`gaveUp ${id}`);
47
+ }
48
+ end(id) {
49
+ this.calls.push(`end ${id}`);
50
+ }
51
+ }
35
52
  class TestMetrics extends SessionMetricsService_1.SessionMetricsService {
36
53
  constructor() {
37
54
  super(...arguments);
@@ -40,6 +57,19 @@ class TestMetrics extends SessionMetricsService_1.SessionMetricsService {
40
57
  this.failWrites = 0;
41
58
  this.samplers = [];
42
59
  this.caps = [];
60
+ this.store = new FakeStore();
61
+ this.collected = [];
62
+ this.collectorState = 'sampling';
63
+ }
64
+ nodeStore() {
65
+ return this.store;
66
+ }
67
+ collectorFor(source, hooks, after) {
68
+ this.collected.push({ source, after });
69
+ const f = new FakeSampler(hooks);
70
+ f.state = () => this.collectorState;
71
+ this.samplers.push(f);
72
+ return f;
43
73
  }
44
74
  context() {
45
75
  return {
@@ -159,6 +189,73 @@ describe('SessionMetricsService', () => {
159
189
  m.start({ sessionId: 's2', device: phone({ nodeId: 'node-2' }), capabilities: {} });
160
190
  (0, chai_1.expect)(m.samplers).to.deep.equal([]);
161
191
  });
192
+ it('on a node, holds the figures for the hub instead of writing them', () => __awaiter(void 0, void 0, void 0, function* () {
193
+ m.args = { hub: 'http://hub:4723' };
194
+ m.start({ sessionId: 's1', device: phone(), capabilities: {} });
195
+ const hooks = m.samplers[0].hooks;
196
+ [1, 2].forEach((t) => hooks.onSample(sample(t)));
197
+ hooks.onGiveUp('adb gone');
198
+ yield clock.tickAsync(types_1.FLUSH_INTERVAL_MS * 2);
199
+ yield m.stop('s1');
200
+ (0, chai_1.expect)(m.written).to.deep.equal([]);
201
+ (0, chai_1.expect)(m.store.calls).to.deep.equal([
202
+ 'begin s1 android',
203
+ 'add s1 1',
204
+ 'add s1 2',
205
+ 'gaveUp s1',
206
+ 'end s1',
207
+ ]);
208
+ (0, chai_1.expect)(m.samplers[0].stopped).to.equal(true);
209
+ }));
210
+ it('on a node with sessionMetrics off, holds nothing', () => {
211
+ m.args = { hub: 'http://hub:4723', sessionMetrics: false };
212
+ m.start({ sessionId: 's1', device: phone(), capabilities: {} });
213
+ (0, chai_1.expect)(m.samplers).to.have.length(0);
214
+ (0, chai_1.expect)(m.store.calls).to.deep.equal([]);
215
+ });
216
+ const source = {
217
+ nodeOrigin: () => 'http://node',
218
+ nodeMetrics: () => __awaiter(void 0, void 0, void 0, function* () { return ({ kind: 'refused' }); }),
219
+ };
220
+ it("on a hub, collects a node's phone from the node, never a cloud phone or without a session", () => {
221
+ const nodePhone = phone({ nodeId: 'node-2', host: 'http://node:4723' });
222
+ (0, chai_1.expect)(m.appliesTo(nodePhone, source)).to.equal(true);
223
+ (0, chai_1.expect)(m.appliesTo(nodePhone)).to.equal(false);
224
+ (0, chai_1.expect)(m.appliesTo(Object.assign(Object.assign({}, nodePhone), { cloud: 'browserstack' }), source)).to.equal(false);
225
+ (0, chai_1.expect)(m.appliesTo(phone({ nodeId: 'node-2', platform: 'ios', realDevice: false }), source)).to.equal(false);
226
+ m.args = { sessionMetrics: false };
227
+ (0, chai_1.expect)(m.appliesTo(nodePhone, source)).to.equal(false);
228
+ m.args = { hub: 'http://hub:4723' };
229
+ (0, chai_1.expect)(m.appliesTo(nodePhone, source)).to.equal(false);
230
+ });
231
+ it('collects from the node, from where it left off, and writes the figures as its own', () => __awaiter(void 0, void 0, void 0, function* () {
232
+ m.start({
233
+ sessionId: 's1',
234
+ device: phone({ nodeId: 'node-2' }),
235
+ capabilities: {},
236
+ source,
237
+ after: 40,
238
+ });
239
+ (0, chai_1.expect)(m.collected).to.deep.equal([{ source, after: 40 }]);
240
+ m.samplers[0].hooks.onSample(sample(41));
241
+ yield m.stop('s1');
242
+ (0, chai_1.expect)(m.written).to.deep.equal([{ sessionId: 's1', ats: [41] }]);
243
+ }));
244
+ it("says what the node says about a running session's sampling", () => {
245
+ m.start({ sessionId: 's1', device: phone({ nodeId: 'node-2' }), capabilities: {}, source });
246
+ (0, chai_1.expect)(m.recordingState('s1')).to.equal('sampling');
247
+ m.collectorState = 'off';
248
+ (0, chai_1.expect)(m.recordingState('s1')).to.equal('off');
249
+ });
250
+ it('writes the samples a sampler gives while it stops: the collector asks the node one last time', () => __awaiter(void 0, void 0, void 0, function* () {
251
+ m.start({ sessionId: 's1', device: phone({ nodeId: 'node-2' }), capabilities: {}, source });
252
+ const last = m.samplers[0];
253
+ last.stop = () => __awaiter(void 0, void 0, void 0, function* () {
254
+ last.hooks.onSample(sample(99));
255
+ });
256
+ yield m.stop('s1');
257
+ (0, chai_1.expect)(m.written).to.deep.equal([{ sessionId: 's1', ats: [99] }]);
258
+ }));
162
259
  });
163
260
  /** The real Android wiring, down to the adb process it runs. */
164
261
  class WiredMetrics extends SessionMetricsService_1.SessionMetricsService {
@@ -0,0 +1,94 @@
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 SessionManager_1 = require("../../src/sessions/SessionManager");
20
+ const SessionMetricsService_1 = require("../../src/services/metrics/SessionMetricsService");
21
+ const device_store_1 = require("../../src/data-service/device-store");
22
+ const prisma_store_1 = require("../../src/data-service/prisma-store");
23
+ const container_registration_1 = require("../helpers/container-registration");
24
+ const scratch_database_1 = require("../helpers/scratch-database");
25
+ /**
26
+ * After a hub restart, a node session whose figures the hub was collecting
27
+ * goes on being collected, from the newest sample the hub stored: the node's
28
+ * memory fills the gap.
29
+ */
30
+ describe('a hub restart resumes collecting a node session’s figures', function () {
31
+ this.timeout(30000);
32
+ const scratch = (0, scratch_database_1.useScratchDatabase)();
33
+ let restore;
34
+ let start;
35
+ let savedStore;
36
+ beforeEach(() => __awaiter(this, void 0, void 0, function* () {
37
+ restore = (0, container_registration_1.saveRegistrations)(SessionMetricsService_1.SessionMetricsService);
38
+ start = sinon_1.default.stub();
39
+ typedi_1.Container.set(SessionMetricsService_1.SessionMetricsService, { start });
40
+ savedStore = device_store_1.DeviceStoreFactory._deviceStore;
41
+ device_store_1.DeviceStoreFactory._deviceStore = new prisma_store_1.PrismaDeviceStore();
42
+ yield scratch.db.sessionMetric.deleteMany({});
43
+ yield scratch.db.session.deleteMany({});
44
+ yield scratch.db.device.deleteMany({});
45
+ yield scratch.db.device.create({
46
+ data: {
47
+ udid: 'node-phone',
48
+ host: 'http://127.0.0.1:1',
49
+ nodeId: 'node-2',
50
+ platform: 'android',
51
+ name: 'S9',
52
+ sdk: '10',
53
+ busy: true,
54
+ userBlocked: false,
55
+ offline: false,
56
+ },
57
+ });
58
+ const row = (id, profiled) => scratch.db.session.create({
59
+ data: {
60
+ id,
61
+ device_udid: 'node-phone',
62
+ device_platform: 'android',
63
+ device_version: '10',
64
+ desired_capabilities: '{}',
65
+ session_capabilities: '{}',
66
+ node_id: 'node-2',
67
+ has_live_video: false,
68
+ status: 'running',
69
+ is_profiling_available: profiled,
70
+ },
71
+ });
72
+ yield row('collected', true);
73
+ yield row('fresh', true);
74
+ yield row('never', false);
75
+ yield scratch.db.sessionMetric.createMany({
76
+ data: [100, 200].map((at) => ({ session_id: 'collected', at })),
77
+ });
78
+ }));
79
+ afterEach(() => {
80
+ for (const s of SessionManager_1.SESSION_MANAGER.getAllSessions())
81
+ SessionManager_1.SESSION_MANAGER.removeSession(s.getId());
82
+ device_store_1.DeviceStoreFactory._deviceStore = savedStore;
83
+ sinon_1.default.restore();
84
+ restore();
85
+ });
86
+ it('resumes each from its newest stored sample, and never one the hub did not collect', () => __awaiter(this, void 0, void 0, function* () {
87
+ yield new SessionManager_1.SessionManager().recoverActiveSessions('hub-1', '/wd/hub');
88
+ const byId = new Map(start.getCalls().map((c) => [c.args[0].sessionId, c.args[0]]));
89
+ (0, chai_1.expect)(Array.from(byId.keys()).sort()).to.deep.equal(['collected', 'fresh']);
90
+ (0, chai_1.expect)(byId.get('collected').after).to.equal(200);
91
+ (0, chai_1.expect)(byId.get('fresh').after).to.equal(null);
92
+ (0, chai_1.expect)(typeof byId.get('collected').source.nodeMetrics).to.equal('function');
93
+ }));
94
+ });
@@ -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/appiumBasePath.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.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/nodePhoneControl.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/recordingRequests.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/selector-health.ts","../src/app/routers/sessionInsights.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.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/app/ws/logcatWs.ts","../src/app/ws/nodeSocketRelay.ts","../src/app/ws/upgradeRouter.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/deviceClaims.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.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/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/localDeviceHosts.ts","../src/device-managers/ownDeviceRow.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/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.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/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/IOSTunnels.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/goIosBinary.ts","../src/device-managers/ios/iosAppIds.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/gateway/createHandoff.ts","../src/gateway/defaultGateway.ts","../src/gateway/forwardToNode.ts","../src/gateway/hubSessionToken.ts","../src/gateway/internalCall.ts","../src/gateway/nodeSessionStatus.ts","../src/gateway/nodeWebDriverUrl.ts","../src/gateway/sessionCreate.ts","../src/gateway/sessionGateway.ts","../src/gateway/sessionLocator.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/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/sessionListingFilter.ts","../src/middleware/sessionUpgradeGuard.ts","../src/middleware/verifyCredential.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/DisplayStateService.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/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.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/device-access/DeviceTeamResolver.ts","../src/services/device-access/LiveSessionOwners.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.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/inspector/verifyLocator.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/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/metrics/AndroidMetricsSampler.ts","../src/services/metrics/IOSMetricsSampler.ts","../src/services/metrics/SessionMetricsService.ts","../src/services/metrics/androidMetrics.ts","../src/services/metrics/iosMetrics.ts","../src/services/metrics/metricsBody.ts","../src/services/metrics/types.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/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.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/nodeRecordingSource.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/selector-health/access.ts","../src/services/selector-health/healingTrend.ts","../src/services/selector-health/people.ts","../src/services/selector-health/selectorDetail.ts","../src/services/selector-health/selectorKeys.ts","../src/services/selector-health/selectorList.ts","../src/services/selector-health/stateView.ts","../src/services/session/appCapability.ts","../src/services/session/nodeCreateCaps.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/sessions/appiumUmbrella.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/appium-umbrella.ts","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/fake-device-table.ts","../test/helpers/loki-stores.ts","../test/helpers/loopbackRequest.ts","../test/helpers/loopbackServer.ts","../test/helpers/own-node-id.ts","../test/helpers/scratch-database.ts","../test/helpers/scratch-port-leases.ts","../test/helpers/seedUser.ts","../test/helpers/selector-health-fixture.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/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.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-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.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/setup/scratch-default-database.js","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.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/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.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/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.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/boot-go-ios-reap.spec.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-forward-decision.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/create-error-message.spec.ts","../test/unit/create-handoff.spec.ts","../test/unit/dashboard-events-metrics.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-store-clear-at-boot.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.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/extract-team-cap.spec.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.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-no-cost.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/healing-trend.spec.ts","../test/unit/health-monitor-own-phones.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/hub-boot-sweep-recovery.spec.ts","../test/unit/hub-create-once.spec.ts","../test/unit/hub-create-session-umbrella.spec.ts","../test/unit/hub-gateway-create-appium-server.spec.ts","../test/unit/hub-node-control-forward.spec.ts","../test/unit/hub-node-gateway-appium-server.spec.ts","../test/unit/hub-node-race.spec.ts","../test/unit/hub-node-same-host.spec.ts","../test/unit/hub-register-removal.spec.ts","../test/unit/hub-remote-session-heartbeat.spec.ts","../test/unit/hub-routed-session-recovery.spec.ts","../test/unit/hub-session-token.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/internal-call.spec.ts","../test/unit/ios-discovery-same-host.spec.ts","../test/unit/ios-go-ios-tunnel-env.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-no-network-fallback.spec.ts","../test/unit/ios-stream-appium-tunnel.spec.ts","../test/unit/ios-stream-port-leases.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/ios-tunnels.spec.ts","../test/unit/ios-wda-status-identity.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/is-xenon-running.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/loopback-request.spec.ts","../test/unit/manualLock.test.ts","../test/unit/mark-node-busy-loki.spec.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/node-create-caps.spec.ts","../test/unit/node-gateway-create-appium-server.spec.ts","../test/unit/node-hub-session-owner.spec.ts","../test/unit/node-phone-control.spec.ts","../test/unit/node-recording-relay.spec.ts","../test/unit/node-socket-relay.spec.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-allocator-os-probe.spec.ts","../test/unit/port-allocator-pairs.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remote-session-create.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/screenshot-route.spec.ts","../test/unit/selector-event-model.spec.ts","../test/unit/selector-health-actions.spec.ts","../test/unit/selector-health-detail.spec.ts","../test/unit/selector-health-list.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-create-layer.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-list-insights.spec.ts","../test/unit/session-listing-auth.spec.ts","../test/unit/session-locator.spec.ts","../test/unit/session-metrics-parse.spec.ts","../test/unit/session-metrics-route.spec.ts","../test/unit/session-metrics-samplers.spec.ts","../test/unit/session-metrics-service.spec.ts","../test/unit/session-node-calls.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-recovery-routing.spec.ts","../test/unit/session-upgrade-guard.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-drain-remote.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-own-device-row.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/stream-viewer-hangup.spec.ts","../test/unit/stream-watchdog-timers.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/upgrade-router.spec.ts","../test/unit/upload-install-route.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/webdriver-info-route.spec.ts","../test/unit/ws-upgrade-routing-appium-server.spec.ts","../test/unit/xenon-options.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/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-reap-held-phone.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-sweeper-expiry.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.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/appiumBasePath.ts","../src/app/index.ts","../src/app/insertBeforeRoutes.ts","../src/app/registerCommandAuth.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/nodePhoneControl.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/recordingRequests.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/selector-health.ts","../src/app/routers/sessionInsights.ts","../src/app/routers/streamLeave.ts","../src/app/routers/streamStartConflict.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/app/ws/logcatWs.ts","../src/app/ws/nodeSocketRelay.ts","../src/app/ws/upgradeRouter.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/deviceClaims.ts","../src/data-service/deviceColumns.ts","../src/data-service/deviceFieldOwners.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/clipboardErrors.ts","../src/device-managers/deviceIdentity.ts","../src/device-managers/iOSTracker.ts","../src/device-managers/index.ts","../src/device-managers/localDeviceHosts.ts","../src/device-managers/ownDeviceRow.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/LogcatMultiplexer.ts","../src/device-managers/android/LogcatStreamService.ts","../src/device-managers/android/ScrcpyServerSession.ts","../src/device-managers/android/androidIdentity.ts","../src/device-managers/android/androidStreamReuse.ts","../src/device-managers/android/clipboardBroadcast.ts","../src/device-managers/android/displayState.ts","../src/device-managers/android/h264NalParser.ts","../src/device-managers/android/previewHold.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/IOSLogStreamService.ts","../src/device-managers/ios/IOSStreamService.ts","../src/device-managers/ios/IOSTunnels.ts","../src/device-managers/ios/WDAClient.ts","../src/device-managers/ios/appleIdentity.ts","../src/device-managers/ios/goIosBinary.ts","../src/device-managers/ios/iosAppIds.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/gateway/createHandoff.ts","../src/gateway/defaultGateway.ts","../src/gateway/forwardToNode.ts","../src/gateway/hubSessionToken.ts","../src/gateway/internalCall.ts","../src/gateway/nodeSessionMetrics.ts","../src/gateway/nodeSessionStatus.ts","../src/gateway/nodeWebDriverUrl.ts","../src/gateway/sessionCreate.ts","../src/gateway/sessionGateway.ts","../src/gateway/sessionLocator.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/commandAuth.ts","../src/middleware/commandCaller.ts","../src/middleware/controlDevice.ts","../src/middleware/csrfMiddleware.ts","../src/middleware/deviceAccessGuard.ts","../src/middleware/deviceTeamGuard.ts","../src/middleware/leaseTokenMiddleware.ts","../src/middleware/loginRateLimiter.ts","../src/middleware/rateLimitMiddleware.ts","../src/middleware/roleGuard.ts","../src/middleware/scopeGuard.ts","../src/middleware/sessionListingFilter.ts","../src/middleware/sessionUpgradeGuard.ts","../src/middleware/verifyCredential.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/DisplayStateService.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/fillMissingScreenSize.ts","../src/services/passwordResetLink.ts","../src/services/passwordResetMode.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/device-access/DeviceTeamResolver.ts","../src/services/device-access/LiveSessionOwners.ts","../src/services/device-access/SessionOwnerResolver.ts","../src/services/device-access/actor.ts","../src/services/device-access/appVisibility.ts","../src/services/device-access/callerTeamIds.ts","../src/services/device-access/deviceAccessPolicy.ts","../src/services/device-access/deviceVisibility.ts","../src/services/device-access/leaseOverride.ts","../src/services/device-access/queueVisibility.ts","../src/services/device-access/sessionVisibility.ts","../src/services/device-access/ticketActorAccess.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/inspector/verifyLocator.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/leaseSessionCaps.ts","../src/services/lease/leaseToken.ts","../src/services/logcat/PackageResolver.ts","../src/services/logcat/logSource.ts","../src/services/logcat/logcatParse.ts","../src/services/logcat/ostraceParse.ts","../src/services/metrics/AndroidMetricsSampler.ts","../src/services/metrics/IOSMetricsSampler.ts","../src/services/metrics/NodeMetricsCollector.ts","../src/services/metrics/NodeMetricsStore.ts","../src/services/metrics/SessionMetricsService.ts","../src/services/metrics/androidMetrics.ts","../src/services/metrics/iosMetrics.ts","../src/services/metrics/metricsBody.ts","../src/services/metrics/nodeMetrics.ts","../src/services/metrics/types.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/activeRecordings.ts","../src/services/recording/annotation-render.ts","../src/services/recording/annotationImage.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/nodeRecordingSource.ts","../src/services/recording/probeDuration.ts","../src/services/recording/proof-bundle.ts","../src/services/recording/recording-store.ts","../src/services/recording/recordingCleanup.ts","../src/services/recording/recordingFiles.ts","../src/services/recording/recordingSummary.ts","../src/services/recording/recordingTiming.ts","../src/services/selector-health/access.ts","../src/services/selector-health/healingTrend.ts","../src/services/selector-health/people.ts","../src/services/selector-health/selectorDetail.ts","../src/services/selector-health/selectorKeys.ts","../src/services/selector-health/selectorList.ts","../src/services/selector-health/stateView.ts","../src/services/session/appCapability.ts","../src/services/session/nodeCreateCaps.ts","../src/services/session/sessionCredentials.ts","../src/services/session/sessionIdentity.ts","../src/services/session/xenonOptions.ts","../src/services/telemetry/attributes.ts","../src/services/token/AppDownloadTicketService.ts","../src/services/token/JwtKeyService.ts","../src/services/token/StreamTicketService.ts","../src/services/token/mcpScopes.ts","../src/services/token/singleUseLedger.ts","../src/sessions/CloudSession.ts","../src/sessions/LocalSession.ts","../src/sessions/RemoteSession.ts","../src/sessions/SessionManager.ts","../src/sessions/XenonSession.ts","../src/sessions/appiumUmbrella.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/appium-umbrella.ts","../test/helpers/artifact-store.ts","../test/helpers/container-registration.ts","../test/helpers/fake-device-table.ts","../test/helpers/loki-stores.ts","../test/helpers/loopbackRequest.ts","../test/helpers/loopbackServer.ts","../test/helpers/own-node-id.ts","../test/helpers/scratch-database.ts","../test/helpers/scratch-port-leases.ts","../test/helpers/seedUser.ts","../test/helpers/selector-health-fixture.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/prisma-device-store-add-devices.spec.ts","../test/integration/prisma-device-store-team-filter.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-apps.spec.ts","../test/integration/team-visibility-control.spec.ts","../test/integration/team-visibility-dashboard.spec.ts","../test/integration/team-visibility-grid.spec.ts","../test/integration/team-visibility-leases.spec.ts","../test/integration/team-visibility-recordings.spec.ts","../test/integration/team-visibility-sessions.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/setup/scratch-default-database.js","../test/unit/AndroidDeviceManager.spec.ts","../test/unit/ApiKeyService.test.ts","../test/unit/AppDownloadTicketService.spec.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/active-recordings.spec.ts","../test/unit/aggregate-hotspots-session-scope.spec.ts","../test/unit/aggregate-hotspots-tuple-key.spec.ts","../test/unit/android-clipboard.spec.ts","../test/unit/android-h264-config.spec.ts","../test/unit/android-h264-service.spec.ts","../test/unit/android-identity.spec.ts","../test/unit/android-preview-hold.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/android-stream-stall-eof.spec.ts","../test/unit/annotation-image.spec.ts","../test/unit/annotation-render.spec.ts","../test/unit/apple-identity.spec.ts","../test/unit/apps-download.spec.ts","../test/unit/apps-team-visibility.spec.ts","../test/unit/auth-disabled-resolution.spec.ts","../test/unit/auth-me-auth-disabled.test.ts","../test/unit/authMiddleware.appTicket.spec.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/boot-go-ios-reap.spec.ts","../test/unit/bootstrap-identity.test.ts","../test/unit/build-export.spec.ts","../test/unit/busy-precheck.spec.ts","../test/unit/cliargs-admin-only.spec.ts","../test/unit/clipboard-route.spec.ts","../test/unit/command-auth-appium-server.spec.ts","../test/unit/command-auth.spec.ts","../test/unit/command-caller.spec.ts","../test/unit/commands.spec.js","../test/unit/composite-geometry.spec.ts","../test/unit/concurrency-gate.spec.ts","../test/unit/config.spec.js","../test/unit/container-registration.spec.ts","../test/unit/control-device-lookup.spec.ts","../test/unit/control-forward-decision.spec.ts","../test/unit/control-lookup-failure.spec.ts","../test/unit/create-error-message.spec.ts","../test/unit/create-handoff.spec.ts","../test/unit/dashboard-events-metrics.spec.ts","../test/unit/dashboard-events-team-scope.spec.ts","../test/unit/device-access-guard.spec.ts","../test/unit/device-access-policy.spec.ts","../test/unit/device-columns.spec.ts","../test/unit/device-service.spec.ts","../test/unit/device-store-clear-at-boot.spec.ts","../test/unit/device-sync-lost-update.spec.ts","../test/unit/device-team-guard.spec.ts","../test/unit/device-team-resolver.spec.ts","../test/unit/device-utils.spec.ts","../test/unit/display-state.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/extract-team-cap.spec.ts","../test/unit/ffmpeg-path.spec.ts","../test/unit/fill-missing-screen-size.spec.ts","../test/unit/findAndLockDevice-leasemerge.spec.ts","../test/unit/go-ios-version.spec.ts","../test/unit/grid-admin-only.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-no-cost.spec.ts","../test/unit/healing-state-endpoints.spec.ts","../test/unit/healing-tier-gate.spec.ts","../test/unit/healing-trend.spec.ts","../test/unit/health-monitor-own-phones.spec.ts","../test/unit/health-monitor-stream-lookup.spec.ts","../test/unit/helpers.spec.ts","../test/unit/hub-boot-sweep-recovery.spec.ts","../test/unit/hub-create-once.spec.ts","../test/unit/hub-create-session-umbrella.spec.ts","../test/unit/hub-gateway-create-appium-server.spec.ts","../test/unit/hub-node-control-forward.spec.ts","../test/unit/hub-node-gateway-appium-server.spec.ts","../test/unit/hub-node-race.spec.ts","../test/unit/hub-node-same-host.spec.ts","../test/unit/hub-node-session-metrics.spec.ts","../test/unit/hub-register-removal.spec.ts","../test/unit/hub-remote-session-heartbeat.spec.ts","../test/unit/hub-routed-session-recovery.spec.ts","../test/unit/hub-session-token.spec.ts","../test/unit/insert-before-routes.spec.ts","../test/unit/inspector-hierarchy.spec.ts","../test/unit/install-repository-app-team.spec.ts","../test/unit/internal-call.spec.ts","../test/unit/ios-discovery-same-host.spec.ts","../test/unit/ios-go-ios-tunnel-env.spec.ts","../test/unit/ios-idle-hold.spec.ts","../test/unit/ios-no-network-fallback.spec.ts","../test/unit/ios-stream-appium-tunnel.spec.ts","../test/unit/ios-stream-port-leases.spec.ts","../test/unit/ios-stream-port.spec.ts","../test/unit/ios-tunnel-process.spec.ts","../test/unit/ios-tunnels.spec.ts","../test/unit/ios-wda-status-identity.spec.ts","../test/unit/iosBattery.spec.ts","../test/unit/iosStreamDiagnostics.spec.ts","../test/unit/is-xenon-running.spec.ts","../test/unit/logcat-multiplexer.spec.ts","../test/unit/logcat-parse.spec.ts","../test/unit/logcat-stream-service.spec.ts","../test/unit/logcat-ws.spec.ts","../test/unit/loginRateLimiter.test.ts","../test/unit/loopback-request.spec.ts","../test/unit/manualLock.test.ts","../test/unit/mark-node-busy-loki.spec.ts","../test/unit/mjpeg-proxy-cache.spec.ts","../test/unit/network-addresses.test.ts","../test/unit/node-create-caps.spec.ts","../test/unit/node-gateway-create-appium-server.spec.ts","../test/unit/node-hub-session-owner.spec.ts","../test/unit/node-metrics-collector.spec.ts","../test/unit/node-metrics-store.spec.ts","../test/unit/node-phone-control.spec.ts","../test/unit/node-recording-relay.spec.ts","../test/unit/node-session-metrics-route.spec.ts","../test/unit/node-socket-relay.spec.ts","../test/unit/normalize-eol.spec.js","../test/unit/omni-vision.spec.ts","../test/unit/ostrace-parse.spec.ts","../test/unit/package-resolver.spec.ts","../test/unit/passwordResetMode.test.ts","../test/unit/plugin.spec.ts","../test/unit/port-allocator-os-probe.spec.ts","../test/unit/port-allocator-pairs.spec.ts","../test/unit/port-exhaustion.spec.ts","../test/unit/prisma.spec.ts","../test/unit/probe-duration.spec.ts","../test/unit/profile-router.test.ts","../test/unit/profileIdentity.spec.ts","../test/unit/proof-bundle.spec.ts","../test/unit/queue-requester.spec.ts","../test/unit/queue-team-scope-routes.spec.ts","../test/unit/queue-visibility.spec.ts","../test/unit/rateLimitMiddleware.test.ts","../test/unit/recording-cleanup.spec.ts","../test/unit/recording-downloads-visibility.spec.ts","../test/unit/recording-files.spec.ts","../test/unit/recording-instrumentation.spec.ts","../test/unit/recording-orchestrator.spec.ts","../test/unit/recording-requests.spec.ts","../test/unit/recording-source-ended.spec.ts","../test/unit/recording-store.spec.ts","../test/unit/recording-summary.spec.ts","../test/unit/recording-timing.spec.ts","../test/unit/recordings-library-routes.spec.ts","../test/unit/recordings-write-visibility.spec.ts","../test/unit/remote-session-create.spec.ts","../test/unit/remux-to-standard-mp4.spec.ts","../test/unit/reservation-team-visibility.spec.ts","../test/unit/reset-link.test.ts","../test/unit/roleGuard.test.ts","../test/unit/run-migrations-fail-fast.test.ts","../test/unit/run-migrations.test.ts","../test/unit/schema-required-args.spec.ts","../test/unit/scrcpy-server-session.spec.ts","../test/unit/scrcpy-version.spec.ts","../test/unit/screenshot-route.spec.ts","../test/unit/selector-event-model.spec.ts","../test/unit/selector-health-actions.spec.ts","../test/unit/selector-health-detail.spec.ts","../test/unit/selector-health-list.spec.ts","../test/unit/selector-state-service.spec.ts","../test/unit/selector-verification-job.spec.ts","../test/unit/selector-verification-missed-regression.spec.ts","../test/unit/session-app-resolution.spec.ts","../test/unit/session-assets.spec.ts","../test/unit/session-attribution-wiring.spec.ts","../test/unit/session-create-layer.spec.ts","../test/unit/session-credential-strip.spec.ts","../test/unit/session-credentials.spec.ts","../test/unit/session-identity.spec.ts","../test/unit/session-list-insights.spec.ts","../test/unit/session-listing-auth.spec.ts","../test/unit/session-locator.spec.ts","../test/unit/session-log-indexes.spec.ts","../test/unit/session-metrics-lifecycle.spec.ts","../test/unit/session-metrics-parse.spec.ts","../test/unit/session-metrics-route.spec.ts","../test/unit/session-metrics-samplers.spec.ts","../test/unit/session-metrics-service.spec.ts","../test/unit/session-node-calls.spec.ts","../test/unit/session-owner-resolver.spec.ts","../test/unit/session-recovery-metrics.spec.ts","../test/unit/session-recovery-routing.spec.ts","../test/unit/session-upgrade-guard.spec.ts","../test/unit/session-visibility.spec.ts","../test/unit/shutdown-drain-remote.spec.ts","../test/unit/shutdown-sync-nets.spec.ts","../test/unit/single-flight.spec.ts","../test/unit/socket-team-scope.integration.spec.ts","../test/unit/socketServer.bearer.spec.ts","../test/unit/socketServer.scopedEmit.spec.ts","../test/unit/socketServer.sessionCookie.spec.ts","../test/unit/stored-session-capabilities.spec.ts","../test/unit/stream-leave-route.spec.ts","../test/unit/stream-leave.spec.ts","../test/unit/stream-own-device-row.spec.ts","../test/unit/stream-start-conflict.spec.ts","../test/unit/stream-status-type.spec.ts","../test/unit/stream-stop-ownership.spec.ts","../test/unit/stream-stop-recording.spec.ts","../test/unit/stream-ticket-identity.spec.ts","../test/unit/stream-viewer-hangup.spec.ts","../test/unit/stream-watchdog-timers.spec.ts","../test/unit/sync-dir.spec.ts","../test/unit/team-filter.test.ts","../test/unit/tracing-service-init.spec.ts","../test/unit/upgrade-router.spec.ts","../test/unit/upload-install-route.spec.ts","../test/unit/userAuthorization.test.ts","../test/unit/users-router.test.ts","../test/unit/verify-credential.spec.ts","../test/unit/verify-locator.spec.ts","../test/unit/video-pipeline-args.spec.ts","../test/unit/video-pipeline-exit.spec.ts","../test/unit/video-pipeline-outputpath.spec.ts","../test/unit/wda-cap-injection.spec.ts","../test/unit/webdriver-info-route.spec.ts","../test/unit/ws-upgrade-routing-appium-server.spec.ts","../test/unit/xenon-options.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/allocate-lease-branch.spec.ts","../test/unit/lease/buildCapabilityBag.spec.ts","../test/unit/lease/lease-override.spec.ts","../test/unit/lease/lease-reap-held-phone.spec.ts","../test/unit/lease/lease-session-ownership.spec.ts","../test/unit/lease/lease-sweeper-expiry.spec.ts","../test/unit/lease/lease-team-visibility.spec.ts","../test/unit/lease/lease-token-log-filter.spec.ts","../test/unit/lease/lease-token-oracle.spec.ts","../test/unit/lease/leaseToken.spec.ts","../test/unit/lease/nodePairAuth.spec.ts","../test/unit/lease/session-lease-proof.spec.ts","../test/unit/ports/PortAllocatorService.spec.ts"],"version":"5.9.3"}