@xenon-device-management/xenon 1.1.9 → 1.1.11

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.1.9",
3
+ "version": "1.1.11",
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": {
@@ -60,12 +60,18 @@ let XenonManager = class XenonManager {
60
60
  this.init();
61
61
  }
62
62
  for (const deviceManager of this.deviceManagers) {
63
- devices.push(...(yield deviceManager.getDevices({
64
- androidDeviceType: this.context.pluginArgs.androidDeviceType,
65
- iosDeviceType: this.context.pluginArgs.iosDeviceType,
66
- }, existingDeviceDetails || [])).map((device) => {
67
- return Object.assign(Object.assign({}, device), { nodeId: !device.cloud ? this.context.nodeId : undefined });
68
- }));
63
+ try {
64
+ const discoveredDevices = yield deviceManager.getDevices({
65
+ androidDeviceType: this.context.pluginArgs.androidDeviceType,
66
+ iosDeviceType: this.context.pluginArgs.iosDeviceType,
67
+ }, existingDeviceDetails || []);
68
+ devices.push(...discoveredDevices.map((device) => {
69
+ return Object.assign(Object.assign({}, device), { nodeId: !device.cloud ? this.context.nodeId : undefined });
70
+ }));
71
+ }
72
+ catch (err) {
73
+ this.log.error(`Device manager ${deviceManager.constructor.name} failed to get devices: ${err.message || err}`);
74
+ }
69
75
  }
70
76
  return devices;
71
77
  });
@@ -213,14 +213,22 @@ let IOSDiscoveryService = class IOSDiscoveryService {
213
213
  console.log('[POISON PILL] REAL fetchLocalSimulators CALLED IN TEST MODE!');
214
214
  }
215
215
  const simctl = new node_simctl_1.default();
216
- const list = yield simctl.list();
217
- // Log unavailable runtimes
218
- list.runtimes
219
- .filter((r) => !r.isAvailable)
220
- .forEach((r) => this.log.error(`Runtime not available: ${r.name}`));
221
- const iosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('iOS'))));
222
- const tvosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('tvOS'))));
223
- let simulators = [...iosSims, ...tvosSims];
216
+ let simulators = [];
217
+ try {
218
+ const list = yield simctl.list();
219
+ // Log unavailable runtimes
220
+ if (list && list.runtimes) {
221
+ list.runtimes
222
+ .filter((r) => !r.isAvailable)
223
+ .forEach((r) => this.log.error(`Runtime not available: ${r.name}`));
224
+ }
225
+ const iosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('iOS'))));
226
+ const tvosSims = (0, lodash_1.flatten)(Object.values((yield simctl.getDevicesByParsing('tvOS'))));
227
+ simulators = [...iosSims, ...tvosSims];
228
+ }
229
+ catch (e) {
230
+ this.log.error(`Failed to fetch local simulators: ${e.message || e}`);
231
+ }
224
232
  if (this.pluginArgs.bootedSimulators) {
225
233
  simulators = simulators.filter((d) => d.state === 'Booted');
226
234
  }
@@ -326,6 +326,26 @@ const config = {
326
326
  "fromEnvVar": null,
327
327
  "value": "debian-openssl-3.0.x",
328
328
  "native": true
329
+ },
330
+ {
331
+ "fromEnvVar": null,
332
+ "value": "darwin"
333
+ },
334
+ {
335
+ "fromEnvVar": null,
336
+ "value": "darwin-arm64"
337
+ },
338
+ {
339
+ "fromEnvVar": null,
340
+ "value": "linux-musl-arm64-openssl-3.0.x"
341
+ },
342
+ {
343
+ "fromEnvVar": null,
344
+ "value": "linux-musl-openssl-3.0.x"
345
+ },
346
+ {
347
+ "fromEnvVar": null,
348
+ "value": "debian-openssl-3.0.x"
329
349
  }
330
350
  ],
331
351
  "previewFeatures": [],
@@ -352,8 +372,8 @@ const config = {
352
372
  }
353
373
  }
354
374
  },
355
- "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Build {\n id String @id @default(uuid())\n name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n}\n\nmodel Session {\n id String @id\n build_id String?\n name String?\n status String @default(\"running\")\n desired_capabilities String\n session_capabilities String\n node_id String\n has_live_video Boolean\n video_recording_enabled Boolean @default(true)\n video_recording String?\n startTime DateTime @default(now())\n endTime DateTime?\n failure_reason String?\n is_profiling_available Boolean @default(false)\n device_info String?\n device_udid String\n device_platform String\n device_version String\n device_name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n performance_trace String? @map(\"performance_trace\")\n failure_category String?\n ai_analysis String?\n tags String?\n trace_id String?\n Log Log[]\n Profiling Profiling[]\n build Build? @relation(fields: [build_id], references: [id])\n SessionLog SessionLog[]\n}\n\nmodel SessionLog {\n id String @id @default(uuid())\n session_id String\n command_name String?\n url String\n method String\n title String\n subtitle String?\n body String?\n response String\n screenshot String?\n is_success Boolean?\n is_error Boolean @default(false)\n is_healed Boolean @default(false)\n original_selector String?\n healed_selector String?\n healing_confidence Float?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n duration Int?\n span_id String?\n trace_id String?\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Log {\n id String @id @default(uuid())\n session_id String\n log_type String\n message String\n timestamp DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Profiling {\n id Int @id @default(autoincrement())\n session_id String\n cpu String?\n memory String?\n total_cpu_used String?\n total_memory_used String?\n raw_cpu_log String?\n raw_memory_log String?\n timestamp DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel App {\n id String @id @default(uuid())\n name String\n filename String\n filepath String\n mimetype String\n size Int\n packageName String?\n version String?\n platform String?\n md5 String? @unique\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Device {\n udid String\n host String\n systemPort Int?\n proxyPort Int?\n proxyHost String?\n wdaLocalPort Int?\n name String? @default(\"unknown\")\n state String? @default(\"available\")\n sdk String? @default(\"unknown\")\n platform String? @default(\"unknown\")\n deviceType String? @default(\"real\")\n busy Boolean? @default(false)\n userBlocked Boolean? @default(false)\n realDevice Boolean? @default(true)\n session_id String?\n offline Boolean? @default(false)\n mjpegServerPort Int?\n lastCmdExecutedAt Float?\n totalUtilizationTimeMilliSec Float @default(0)\n sessionStartTime Float @default(0)\n newCommandTimeout Int?\n cloud String?\n derivedDataPath String?\n chromeDriverPath String?\n capability String?\n adbRemoteHost String?\n adbPort Int?\n nodeId String?\n screenWidth String?\n screenHeight String?\n dashboard_link String?\n total_session_count Int? @default(0)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n healthCheckError String?\n healthStatus String? @default(\"Healthy\")\n lastHealthCheckAt Float?\n batteryLevel Int?\n reservationReason String?\n reservedBy String?\n reservedUntil Float?\n storageFree String?\n tags String?\n thermalStatus String?\n sessionProgress String? @default(\"\")\n totalHealedCount Int? @default(0)\n ip String? @default(\"\")\n\n @@id([udid, host])\n}\n\nmodel PendingSession {\n id Int @id @default(autoincrement())\n capability_id String @unique\n capability String\n createdAt Float\n}\n\nmodel CLIArgs {\n id Int @id @default(autoincrement())\n args String\n createdAt DateTime @default(now())\n}\n\nmodel WebhookConfig {\n id String @id @default(uuid())\n url String\n type String @default(\"slack\")\n events String\n active Boolean @default(true)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n payloadTemplate String?\n}\n\nmodel WebConfig {\n id String @id @default(\"global\")\n name String @unique\n value String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel LocatorEtalon {\n id String @id @default(uuid())\n selector String @unique\n strategy String\n attributes String\n nodeName String\n lastSeen DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
356
- "inlineSchemaHash": "2ecdf68b3a1d1cbaa0a262bdfe4306df216ba4e13d1f044e12df2584012ff74c",
375
+ "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n binaryTargets = [\"native\", \"darwin\", \"darwin-arm64\", \"linux-musl-arm64-openssl-3.0.x\", \"linux-musl-openssl-3.0.x\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Build {\n id String @id @default(uuid())\n name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n}\n\nmodel Session {\n id String @id\n build_id String?\n name String?\n status String @default(\"running\")\n desired_capabilities String\n session_capabilities String\n node_id String\n has_live_video Boolean\n video_recording_enabled Boolean @default(true)\n video_recording String?\n startTime DateTime @default(now())\n endTime DateTime?\n failure_reason String?\n is_profiling_available Boolean @default(false)\n device_info String?\n device_udid String\n device_platform String\n device_version String\n device_name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n performance_trace String? @map(\"performance_trace\")\n failure_category String?\n ai_analysis String?\n tags String?\n trace_id String?\n Log Log[]\n Profiling Profiling[]\n build Build? @relation(fields: [build_id], references: [id])\n SessionLog SessionLog[]\n}\n\nmodel SessionLog {\n id String @id @default(uuid())\n session_id String\n command_name String?\n url String\n method String\n title String\n subtitle String?\n body String?\n response String\n screenshot String?\n is_success Boolean?\n is_error Boolean @default(false)\n is_healed Boolean @default(false)\n original_selector String?\n healed_selector String?\n healing_confidence Float?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n duration Int?\n span_id String?\n trace_id String?\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Log {\n id String @id @default(uuid())\n session_id String\n log_type String\n message String\n timestamp DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Profiling {\n id Int @id @default(autoincrement())\n session_id String\n cpu String?\n memory String?\n total_cpu_used String?\n total_memory_used String?\n raw_cpu_log String?\n raw_memory_log String?\n timestamp DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel App {\n id String @id @default(uuid())\n name String\n filename String\n filepath String\n mimetype String\n size Int\n packageName String?\n version String?\n platform String?\n md5 String? @unique\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Device {\n udid String\n host String\n systemPort Int?\n proxyPort Int?\n proxyHost String?\n wdaLocalPort Int?\n name String? @default(\"unknown\")\n state String? @default(\"available\")\n sdk String? @default(\"unknown\")\n platform String? @default(\"unknown\")\n deviceType String? @default(\"real\")\n busy Boolean? @default(false)\n userBlocked Boolean? @default(false)\n realDevice Boolean? @default(true)\n session_id String?\n offline Boolean? @default(false)\n mjpegServerPort Int?\n lastCmdExecutedAt Float?\n totalUtilizationTimeMilliSec Float @default(0)\n sessionStartTime Float @default(0)\n newCommandTimeout Int?\n cloud String?\n derivedDataPath String?\n chromeDriverPath String?\n capability String?\n adbRemoteHost String?\n adbPort Int?\n nodeId String?\n screenWidth String?\n screenHeight String?\n dashboard_link String?\n total_session_count Int? @default(0)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n healthCheckError String?\n healthStatus String? @default(\"Healthy\")\n lastHealthCheckAt Float?\n batteryLevel Int?\n reservationReason String?\n reservedBy String?\n reservedUntil Float?\n storageFree String?\n tags String?\n thermalStatus String?\n sessionProgress String? @default(\"\")\n totalHealedCount Int? @default(0)\n ip String? @default(\"\")\n\n @@id([udid, host])\n}\n\nmodel PendingSession {\n id Int @id @default(autoincrement())\n capability_id String @unique\n capability String\n createdAt Float\n}\n\nmodel CLIArgs {\n id Int @id @default(autoincrement())\n args String\n createdAt DateTime @default(now())\n}\n\nmodel WebhookConfig {\n id String @id @default(uuid())\n url String\n type String @default(\"slack\")\n events String\n active Boolean @default(true)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n payloadTemplate String?\n}\n\nmodel WebConfig {\n id String @id @default(\"global\")\n name String @unique\n value String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel LocatorEtalon {\n id String @id @default(uuid())\n selector String @unique\n strategy String\n attributes String\n nodeName String\n lastSeen DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
376
+ "inlineSchemaHash": "7f76917a15a7227d2f6c32628b293d3aa7d972d6f8dec8d9f6947357c00fabe0",
357
377
  "copyEngine": true
358
378
  }
359
379
  config.dirname = '/'
@@ -327,6 +327,26 @@ const config = {
327
327
  "fromEnvVar": null,
328
328
  "value": "debian-openssl-3.0.x",
329
329
  "native": true
330
+ },
331
+ {
332
+ "fromEnvVar": null,
333
+ "value": "darwin"
334
+ },
335
+ {
336
+ "fromEnvVar": null,
337
+ "value": "darwin-arm64"
338
+ },
339
+ {
340
+ "fromEnvVar": null,
341
+ "value": "linux-musl-arm64-openssl-3.0.x"
342
+ },
343
+ {
344
+ "fromEnvVar": null,
345
+ "value": "linux-musl-openssl-3.0.x"
346
+ },
347
+ {
348
+ "fromEnvVar": null,
349
+ "value": "debian-openssl-3.0.x"
330
350
  }
331
351
  ],
332
352
  "previewFeatures": [],
@@ -353,8 +373,8 @@ const config = {
353
373
  }
354
374
  }
355
375
  },
356
- "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Build {\n id String @id @default(uuid())\n name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n}\n\nmodel Session {\n id String @id\n build_id String?\n name String?\n status String @default(\"running\")\n desired_capabilities String\n session_capabilities String\n node_id String\n has_live_video Boolean\n video_recording_enabled Boolean @default(true)\n video_recording String?\n startTime DateTime @default(now())\n endTime DateTime?\n failure_reason String?\n is_profiling_available Boolean @default(false)\n device_info String?\n device_udid String\n device_platform String\n device_version String\n device_name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n performance_trace String? @map(\"performance_trace\")\n failure_category String?\n ai_analysis String?\n tags String?\n trace_id String?\n Log Log[]\n Profiling Profiling[]\n build Build? @relation(fields: [build_id], references: [id])\n SessionLog SessionLog[]\n}\n\nmodel SessionLog {\n id String @id @default(uuid())\n session_id String\n command_name String?\n url String\n method String\n title String\n subtitle String?\n body String?\n response String\n screenshot String?\n is_success Boolean?\n is_error Boolean @default(false)\n is_healed Boolean @default(false)\n original_selector String?\n healed_selector String?\n healing_confidence Float?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n duration Int?\n span_id String?\n trace_id String?\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Log {\n id String @id @default(uuid())\n session_id String\n log_type String\n message String\n timestamp DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Profiling {\n id Int @id @default(autoincrement())\n session_id String\n cpu String?\n memory String?\n total_cpu_used String?\n total_memory_used String?\n raw_cpu_log String?\n raw_memory_log String?\n timestamp DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel App {\n id String @id @default(uuid())\n name String\n filename String\n filepath String\n mimetype String\n size Int\n packageName String?\n version String?\n platform String?\n md5 String? @unique\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Device {\n udid String\n host String\n systemPort Int?\n proxyPort Int?\n proxyHost String?\n wdaLocalPort Int?\n name String? @default(\"unknown\")\n state String? @default(\"available\")\n sdk String? @default(\"unknown\")\n platform String? @default(\"unknown\")\n deviceType String? @default(\"real\")\n busy Boolean? @default(false)\n userBlocked Boolean? @default(false)\n realDevice Boolean? @default(true)\n session_id String?\n offline Boolean? @default(false)\n mjpegServerPort Int?\n lastCmdExecutedAt Float?\n totalUtilizationTimeMilliSec Float @default(0)\n sessionStartTime Float @default(0)\n newCommandTimeout Int?\n cloud String?\n derivedDataPath String?\n chromeDriverPath String?\n capability String?\n adbRemoteHost String?\n adbPort Int?\n nodeId String?\n screenWidth String?\n screenHeight String?\n dashboard_link String?\n total_session_count Int? @default(0)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n healthCheckError String?\n healthStatus String? @default(\"Healthy\")\n lastHealthCheckAt Float?\n batteryLevel Int?\n reservationReason String?\n reservedBy String?\n reservedUntil Float?\n storageFree String?\n tags String?\n thermalStatus String?\n sessionProgress String? @default(\"\")\n totalHealedCount Int? @default(0)\n ip String? @default(\"\")\n\n @@id([udid, host])\n}\n\nmodel PendingSession {\n id Int @id @default(autoincrement())\n capability_id String @unique\n capability String\n createdAt Float\n}\n\nmodel CLIArgs {\n id Int @id @default(autoincrement())\n args String\n createdAt DateTime @default(now())\n}\n\nmodel WebhookConfig {\n id String @id @default(uuid())\n url String\n type String @default(\"slack\")\n events String\n active Boolean @default(true)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n payloadTemplate String?\n}\n\nmodel WebConfig {\n id String @id @default(\"global\")\n name String @unique\n value String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel LocatorEtalon {\n id String @id @default(uuid())\n selector String @unique\n strategy String\n attributes String\n nodeName String\n lastSeen DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
357
- "inlineSchemaHash": "2ecdf68b3a1d1cbaa0a262bdfe4306df216ba4e13d1f044e12df2584012ff74c",
376
+ "inlineSchema": "generator client {\n provider = \"prisma-client-js\"\n output = \"../src/generated/client\"\n binaryTargets = [\"native\", \"darwin\", \"darwin-arm64\", \"linux-musl-arm64-openssl-3.0.x\", \"linux-musl-openssl-3.0.x\", \"debian-openssl-3.0.x\"]\n}\n\ndatasource db {\n provider = \"sqlite\"\n url = env(\"DATABASE_URL\")\n}\n\nmodel Build {\n id String @id @default(uuid())\n name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n sessions Session[]\n}\n\nmodel Session {\n id String @id\n build_id String?\n name String?\n status String @default(\"running\")\n desired_capabilities String\n session_capabilities String\n node_id String\n has_live_video Boolean\n video_recording_enabled Boolean @default(true)\n video_recording String?\n startTime DateTime @default(now())\n endTime DateTime?\n failure_reason String?\n is_profiling_available Boolean @default(false)\n device_info String?\n device_udid String\n device_platform String\n device_version String\n device_name String?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n performance_trace String? @map(\"performance_trace\")\n failure_category String?\n ai_analysis String?\n tags String?\n trace_id String?\n Log Log[]\n Profiling Profiling[]\n build Build? @relation(fields: [build_id], references: [id])\n SessionLog SessionLog[]\n}\n\nmodel SessionLog {\n id String @id @default(uuid())\n session_id String\n command_name String?\n url String\n method String\n title String\n subtitle String?\n body String?\n response String\n screenshot String?\n is_success Boolean?\n is_error Boolean @default(false)\n is_healed Boolean @default(false)\n original_selector String?\n healed_selector String?\n healing_confidence Float?\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n duration Int?\n span_id String?\n trace_id String?\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Log {\n id String @id @default(uuid())\n session_id String\n log_type String\n message String\n timestamp DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel Profiling {\n id Int @id @default(autoincrement())\n session_id String\n cpu String?\n memory String?\n total_cpu_used String?\n total_memory_used String?\n raw_cpu_log String?\n raw_memory_log String?\n timestamp DateTime\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n session Session @relation(fields: [session_id], references: [id])\n}\n\nmodel App {\n id String @id @default(uuid())\n name String\n filename String\n filepath String\n mimetype String\n size Int\n packageName String?\n version String?\n platform String?\n md5 String? @unique\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel Device {\n udid String\n host String\n systemPort Int?\n proxyPort Int?\n proxyHost String?\n wdaLocalPort Int?\n name String? @default(\"unknown\")\n state String? @default(\"available\")\n sdk String? @default(\"unknown\")\n platform String? @default(\"unknown\")\n deviceType String? @default(\"real\")\n busy Boolean? @default(false)\n userBlocked Boolean? @default(false)\n realDevice Boolean? @default(true)\n session_id String?\n offline Boolean? @default(false)\n mjpegServerPort Int?\n lastCmdExecutedAt Float?\n totalUtilizationTimeMilliSec Float @default(0)\n sessionStartTime Float @default(0)\n newCommandTimeout Int?\n cloud String?\n derivedDataPath String?\n chromeDriverPath String?\n capability String?\n adbRemoteHost String?\n adbPort Int?\n nodeId String?\n screenWidth String?\n screenHeight String?\n dashboard_link String?\n total_session_count Int? @default(0)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n healthCheckError String?\n healthStatus String? @default(\"Healthy\")\n lastHealthCheckAt Float?\n batteryLevel Int?\n reservationReason String?\n reservedBy String?\n reservedUntil Float?\n storageFree String?\n tags String?\n thermalStatus String?\n sessionProgress String? @default(\"\")\n totalHealedCount Int? @default(0)\n ip String? @default(\"\")\n\n @@id([udid, host])\n}\n\nmodel PendingSession {\n id Int @id @default(autoincrement())\n capability_id String @unique\n capability String\n createdAt Float\n}\n\nmodel CLIArgs {\n id Int @id @default(autoincrement())\n args String\n createdAt DateTime @default(now())\n}\n\nmodel WebhookConfig {\n id String @id @default(uuid())\n url String\n type String @default(\"slack\")\n events String\n active Boolean @default(true)\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n payloadTemplate String?\n}\n\nmodel WebConfig {\n id String @id @default(\"global\")\n name String @unique\n value String\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n\nmodel LocatorEtalon {\n id String @id @default(uuid())\n selector String @unique\n strategy String\n attributes String\n nodeName String\n lastSeen DateTime @default(now())\n createdAt DateTime @default(now())\n updatedAt DateTime @updatedAt\n}\n",
377
+ "inlineSchemaHash": "7f76917a15a7227d2f6c32628b293d3aa7d972d6f8dec8d9f6947357c00fabe0",
358
378
  "copyEngine": true
359
379
  }
360
380
 
@@ -394,6 +414,22 @@ Object.assign(exports, Prisma)
394
414
  // file annotations for bundling tools to include these files
395
415
  path.join(__dirname, "libquery_engine-debian-openssl-3.0.x.so.node");
396
416
  path.join(process.cwd(), "src/generated/client/libquery_engine-debian-openssl-3.0.x.so.node")
417
+
418
+ // file annotations for bundling tools to include these files
419
+ path.join(__dirname, "libquery_engine-darwin.dylib.node");
420
+ path.join(process.cwd(), "src/generated/client/libquery_engine-darwin.dylib.node")
421
+
422
+ // file annotations for bundling tools to include these files
423
+ path.join(__dirname, "libquery_engine-darwin-arm64.dylib.node");
424
+ path.join(process.cwd(), "src/generated/client/libquery_engine-darwin-arm64.dylib.node")
425
+
426
+ // file annotations for bundling tools to include these files
427
+ path.join(__dirname, "libquery_engine-linux-musl-arm64-openssl-3.0.x.so.node");
428
+ path.join(process.cwd(), "src/generated/client/libquery_engine-linux-musl-arm64-openssl-3.0.x.so.node")
429
+
430
+ // file annotations for bundling tools to include these files
431
+ path.join(__dirname, "libquery_engine-linux-musl-openssl-3.0.x.so.node");
432
+ path.join(process.cwd(), "src/generated/client/libquery_engine-linux-musl-openssl-3.0.x.so.node")
397
433
  // file annotations for bundling tools to include these files
398
434
  path.join(__dirname, "schema.prisma");
399
435
  path.join(process.cwd(), "src/generated/client/schema.prisma")
@@ -1,5 +1,5 @@
1
1
  {
2
- "name": "prisma-client-13e1423b784bce9c972b5f4bbb80f3a058f5cae24934a667c8e9c6d7cf3ba1a9",
2
+ "name": "prisma-client-cf9f5a6be2cfd2d218df08695ed2c30662b57b9a397c8e2997d1e1fec4e22a5f",
3
3
  "main": "index.js",
4
4
  "types": "index.d.ts",
5
5
  "browser": "index-browser.js",
@@ -1,6 +1,7 @@
1
1
  generator client {
2
- provider = "prisma-client-js"
3
- output = "../src/generated/client"
2
+ provider = "prisma-client-js"
3
+ output = "../src/generated/client"
4
+ binaryTargets = ["native", "darwin", "darwin-arm64", "linux-musl-arm64-openssl-3.0.x", "linux-musl-openssl-3.0.x", "debian-openssl-3.0.x"]
4
5
  }
5
6
 
6
7
  datasource db {
package/lib/src/index.js CHANGED
@@ -52,6 +52,7 @@ Object.defineProperty(exports, "XenonPlugin", { enumerable: true, get: function
52
52
  const ffmpeg_1 = require("@ffmpeg-installer/ffmpeg");
53
53
  const logger_1 = __importDefault(require("./logger"));
54
54
  const typedi_1 = require("typedi");
55
+ const lodash_1 = __importDefault(require("lodash"));
55
56
  // Add FFMPEG to path for appium to record video of the session
56
57
  process.env.PATH = process.env.PATH + ':' + ffmpeg_1.path.replace(/ffmpeg$/g, '');
57
58
  /**
@@ -88,7 +89,9 @@ process.on('unhandledRejection', (reason, promise) => {
88
89
  logger_1.default.error('❌ [Xenon] Unhandled Rejection at:', promise, 'reason:', reason);
89
90
  });
90
91
  process.on('uncaughtException', (err) => {
91
- logger_1.default.error('❌ [Xenon] Uncaught Exception:', err);
92
+ const errorDetails = err instanceof Error ? Object.assign({ name: err.name, message: err.message, stack: err.stack }, (lodash_1.default.omit(err, ['name', 'message', 'stack']))) : err;
93
+ logger_1.default.error('❌ [Xenon] Uncaught Exception:', JSON.stringify(errorDetails, null, 2));
94
+ logger_1.default.error('❌ [Xenon] Stack Trace:', err instanceof Error ? err.stack : new Error().stack);
92
95
  // Give logger time to flush before exiting
93
96
  setTimeout(() => process.exit(1), 1000);
94
97
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xenon-device-management/xenon",
3
- "version": "1.1.9",
3
+ "version": "1.1.11",
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": {
@@ -1,6 +1,7 @@
1
1
  generator client {
2
- provider = "prisma-client-js"
3
- output = "../src/generated/client"
2
+ provider = "prisma-client-js"
3
+ output = "../src/generated/client"
4
+ binaryTargets = ["native", "darwin", "darwin-arm64", "linux-musl-arm64-openssl-3.0.x", "linux-musl-openssl-3.0.x", "debian-openssl-3.0.x"]
4
5
  }
5
6
 
6
7
  datasource db {
@@ -3,22 +3,22 @@ const path = require('path');
3
3
  const fs = require('fs');
4
4
 
5
5
  /**
6
- * Robust Prisma Client Generator (v1.1.8)
6
+ * Robust Prisma Client Generator (v1.1.9)
7
7
  *
8
- * This script runs 'prisma generate' with extreme diagnostics.
9
- * It ensures the custom output directory exists and won't crash npm install.
8
+ * This script runs 'prisma generate' and ensures the output is placed
9
+ * where both source code and compiled code (lib) can find it.
10
10
  */
11
11
  function generate() {
12
12
  const rootDir = path.resolve(__dirname, '..');
13
- const outputDir = path.resolve(rootDir, 'src/generated/client');
13
+ const srcOutputDir = path.resolve(rootDir, 'src/generated/client');
14
+ const libOutputDir = path.resolve(rootDir, 'lib/src/generated/client');
14
15
 
15
16
  console.log('📦 [Xenon] Initializing Prisma generation...');
16
17
  console.log(`📂 [Xenon] Root: ${rootDir}`);
17
- console.log(`📂 [Xenon] Target: ${outputDir}`);
18
18
 
19
- // Ensure output directory exists
20
- if (!fs.existsSync(path.resolve(rootDir, 'src/generated'))) {
21
- fs.mkdirSync(path.resolve(rootDir, 'src/generated'), { recursive: true });
19
+ // Ensure src/generated exists (Prisma will create 'client' subfolder)
20
+ if (!fs.existsSync(path.dirname(srcOutputDir))) {
21
+ fs.mkdirSync(path.dirname(srcOutputDir), { recursive: true });
22
22
  }
23
23
 
24
24
  try {
@@ -39,9 +39,25 @@ function generate() {
39
39
  });
40
40
 
41
41
  console.log('✅ [Xenon] Prisma client generated in src/generated/client.');
42
+
43
+ // CRITICAL: If we are in an installed environment (lib exists),
44
+ // we must copy the generated client to lib/src/generated/client
45
+ // because the compiled code imports from there.
46
+ if (fs.existsSync(path.resolve(rootDir, 'lib'))) {
47
+ console.log('📂 [Xenon] Detected "lib" directory. Syncing generated client...');
48
+
49
+ if (!fs.existsSync(path.dirname(libOutputDir))) {
50
+ fs.mkdirSync(path.dirname(libOutputDir), { recursive: true });
51
+ }
52
+
53
+ // Simple recursive copy
54
+ copyRecursiveSync(srcOutputDir, libOutputDir);
55
+ console.log('✅ [Xenon] Prisma client synced to lib/src/generated/client.');
56
+ }
57
+
42
58
  } catch (error) {
43
59
  console.error('⚠️ [Xenon] Prisma generation encountered an issue.');
44
- console.error('⚠️ [Xenon] This is expected in some Appium/NPM environments.');
60
+ console.error('⚠️ [Xenon] This is expected in some restricted environments.');
45
61
  console.error('⚠️ [Xenon] Error:', error.message);
46
62
 
47
63
  // Always exit 0 to prevent npm install failure
@@ -49,4 +65,20 @@ function generate() {
49
65
  }
50
66
  }
51
67
 
68
+ function copyRecursiveSync(src, dest) {
69
+ const exists = fs.existsSync(src);
70
+ const stats = exists && fs.statSync(src);
71
+ const isDirectory = exists && stats.isDirectory();
72
+ if (isDirectory) {
73
+ if (!fs.existsSync(dest)) {
74
+ fs.mkdirSync(dest, { recursive: true });
75
+ }
76
+ fs.readdirSync(src).forEach((childItemName) => {
77
+ copyRecursiveSync(path.join(src, childItemName), path.join(dest, childItemName));
78
+ });
79
+ } else {
80
+ fs.copyFileSync(src, dest);
81
+ }
82
+ }
83
+
52
84
  generate();