npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xenon-device-management/xenon

v1.7.0

Published

Xenon - Intelligent Mobile Infrastructure. A self-healing device orchestration platform for Appium.

Downloads

484

Readme

Xenon


✨ What is Xenon?

Xenon is an intelligent Appium plugin that transforms your mobile device lab into a self-healing, autonomous infrastructure. Named after the noble gas known for its stability and reliability, Xenon brings enterprise-grade device orchestration to your testing pipeline.

Why Xenon?

| Problem | Xenon Solution | |---------|----------------| | Tests fail due to device state | Auto-recovery - Devices heal themselves | | Manual device management | Smart allocation - Queue, reserve, prioritize | | Debugging is painful | Interactive control - Live stream, touch, shell | | No visibility into failures | Rich artifacts - Video, screenshots, profiling | | Infrastructure silos | Unified dashboard - One view for all devices |


🚀 Features

Device Orchestration

  • Automatic device discovery - Android (USB + emulators), iOS (devices + simulators)
  • Smart session allocation - Queue management with ETA
  • WebSocket-First Sync - Real-time Hub-Node-Dashboard bidirectional sync
  • Device reservation - Manual mode for debugging
  • Team-based quotas - Fair resource sharing

Interactive Control

  • Live streaming - Real-time device screen in browser
  • Touch interaction - Tap, swipe, scroll remotely
  • App management - Install, uninstall, clear data
  • Interactive Shell - Execute ADB/iOS commands directly
  • Device information - Battery, storage, network status

🧠 AI Self-Healing (Flagship)

  • 5-Tier Healing Orchestration - From DOM to LLM recovery
  • Signature-Based Learning - Persistent "Etalon" signatures for high-confidence recovery
  • Multi-Modal Fallback - Syntactic -> OCR -> Visual AI -> LLM reasoning
  • Infrastructure-Free - Works with existing LokiJS (local) or PostgreSQL (remote)

Selector lifecycle (Trust & Truth layer)

Healed selectors flow through a state machine: Active → Pending → Resolved, with an optional Muted branch.

  • Active — a hot selector that's healing in flight; surfaces on the Selector Health dashboard, the CI gate, and the webhook digest.
  • Mark as Fixed — after rewriting the selector in your test source, click "Mark as Fixed" in the dashboard. The row moves to Pending.
  • Pending — Xenon watches subsequent CI builds. When 3 distinct build_ids have run the selector with no heals, it auto-promotes to Resolved (SelectorVerificationJob runs every 15 minutes).
  • Resolved — the rewrite stuck. Excluded from the CI gate and digest. A future heal flips the row back to Active with a regression badge (institutional memory).
  • Muted — a selector you've intentionally chosen to ignore (legacy flow, etc.). Hidden from dashboard, CI gate, and digest until unmuted.

The dashboard shows strategy + value (Accessibility ID: login-btn) so suggested rewrites are copy-ready in JS / Java / Python / C# / Ruby — your client language is remembered in localStorage.xenon.copyLang.

CI gate behavior change: muted/pending/resolved selectors no longer count toward /healing/hotspots/violations. If your CI was passing/failing based on that endpoint, the signal will get quieter after this release — selectors actively being managed are no longer flagged. Pass ?status=all to opt back into the old behavior.

Recording & Artifacts

  • Video recording - Full session capture
  • Screenshot capture - On-demand and per-command
  • Network interceptor - Live HTTP/HTTPS capture, mocking, and HAR export (docs)
  • Distributed Tracing - OpenTelemetry spans for exact command latency
  • Performance profiling - CPU, memory, FPS metrics
  • Log aggregation - Appium, device, app logs
  • OpenTelemetry Integration - Standardized distributed tracing for all sessions

Intelligence (Roadmap)

  • 🔲 Flaky test detection - Auto-identify unstable tests
  • 🔲 Error categorization - Crash vs timeout vs element not found
  • 🔲 Predictive health - USB/battery failure prediction

⚡ Quick Start

Installation

# Install Xenon plugin
appium plugin install --source=npm @xenon-device-management/xenon

# Or install from source
git clone https://github.com/xenon-platform/xenon.git
cd xenon
npm install
npm run build:all
appium plugin install --source=local .

Running

# Start Appium with Xenon
appium server --use-plugins=xenon \
  --plugin-xenon-platform=both \
  --plugin-xenon-enable-dashboard

🔧 Configuration

Xenon supports configuration via CLI arguments or a configuration file (YAML/JSON). We recommend using a configuration file for production deployments.

Using Configuration File (Recommended)

Create a xenon-config.yaml file:

server:
  usePlugins: ["xenon"]
  plugin:
    xenon:
      platform: both
      maxSessions: 8
      enableDashboard: true
      enableSelfHealing: true

Run Appium with the config:

appium server --config xenon-config.yaml

Runtime Configuration ⚡️

You can update configuration options at runtime without restarting the server using the API:

# Get current config
GET /xenon/api/config

# Update config (e.g. change max sessions)
PUT /xenon/api/config
{ "maxSessions": 10 }

Note: Some changes (like platform or hub URL) require a server restart to take full effect. The API response will indicate if a restart is required.

Build & Session Retention 🧹

Xenon includes an enterprise-ready cleanup job that automatically purges older builds, sessions, and associated assets (videos/screenshots) to manage disk space.

| Option | Description | Default | |--------|-------------|---------| | buildCleanupDays | Retention period in days | 30 | | buildCleanupMaxCount | Maximum number of builds to keep | 100 | | buildCleanupSchedule | Cron schedule for the cleanup job | "0 0 * * *" | | deleteBuildAssets | Delete video recordings and screenshots from disk | true |

Example (YAML):

plugin:
  xenon:
    buildCleanupDays: 14
    buildCleanupMaxCount: 50
    buildCleanupSchedule: "0 0 * * *"
    deleteBuildAssets: true

Detailed explanation of how the retention logic works can be found in the Data Retention & Maintenance Guide.

See docs/server-args.md for all available options.


📋 Capabilities

Xenon uses the xe: prefix for its custom capabilities. You can also use xenon: as an alternative.

Session & Build Tracking

| Capability | Description | Example | |------------|-------------|---------| | xe:build | Build name for grouping sessions | "xe:build": "Release-v2.0" | | xe:name | Session name for identification | "xe:name": "Login Test Suite" |

Recording & Screenshots

| Capability | Description | Default | |------------|-------------|---------| | xe:record_video | Enable video recording | true | | xe:screenshot_on_failure | Capture screenshot on test failure | true | | xe:screenshot_on_every_command | Capture screenshot after each command | false | | xe:save_device_logs | Save device logs (logcat/syslog) | false |

Device Filtering

| Capability | Description | Example | |------------|-------------|---------| | appium:udids | Comma-separated list of allowed UDIDs | "device1,device2" | | appium:minSDK | Minimum OS version | "15" | | appium:maxSDK | Maximum OS version | "17" | | appium:iPhoneOnly | Use only iPhone simulators | true | | appium:iPadOnly | Use only iPad simulators | true | | appium:filterByHost | Filter by node IP address | "192.168.0.100" |

Timeouts

| Capability | Description | Default | |------------|-------------|---------| | appium:deviceAvailabilityTimeout | Wait time for device availability (ms) | 180000 | | appium:deviceRetryInterval | Polling interval for device check (ms) | 10000 |

Example Configuration

const capabilities = {
  platformName: 'iOS',
  'appium:automationName': 'XCUITest',
  'appium:app': '/path/to/app.ipa',
  
  // Xenon capabilities
  'xe:build': 'Sprint-42',
  'xe:name': 'Login Flow Test',
  'xe:record_video': true,
  'xe:screenshot_on_failure': true,
  'xe:save_device_logs': true,
  
  // Device filtering
  'appium:minSDK': '16',
  'appium:iPhoneOnly': true
};

Custom Execute Script Commands

Xenon supports extended control and reporting via the xenon: execute script namespace. These commands allow you to interact with the Xenon dashboard and session management directly from your test code.

| Command | Description | Example | |---------|-------------|---------| | xenon: setSessionStatus | Mark session as passed/failed in dashboard | {"status": "passed", "reason": "All steps OK"} | | xenon: setSessionName | Update session name at runtime | {"name": "Step 2: Payment Verification"} | | xenon: captureEvidence | Trigger manual screenshot with custom label | {"reason": "Checkpoint reached", "label": "success"} | | xenon: addTag | Add searchable tags to the session | {"tag": "regression"} | | xenon: debug | Send custom debug logs to Xenon dashboard | {"message": "API Response: 200 OK"} |

Full reference for these commands is in the Swagger UI at /xenon/api-docs.


🧠 AI Self-Healing

Xenon features a best-in-class, 5-tier self-healing system that ensures your tests never fail due to minor UI changes. It automatically intercepts NoSuchElementError and attempts to recover the locator using increasingly advanced methods.

🛡️ The 5-Tier Strategy

| Tier | Provider | Mechanism | Stability | |:---|:---|:---|:---| | 1 | Native | Standard Appium findElement | Baseline | | 2 | Fuzzy XML| Weighted Signature Matching (Dice Coefficient) | 85%+ | | 3 | OCR | Local Text Recognition (Tesseract.js) | High | | 4 | Visual AI| AI-powered coordinate discovery | High | | 5 | LLM | Deep Reasoning (Gemini/OpenAI) | Absolute |

⚡ Signature-Based Learning (Etalon)

Xenon "learns" during every successful run. When an element is found, it captures a persistent Element Signature (Etalon).

  • Zero Configuration: Learning is fully automatic and backgrounded.
  • Persistent Memory: Signatures are stored in your database (LokiJS or PostgreSQL).
  • Extreme Precision: Even if id, text, or class changes, Xenon uses anchor attributes (content-desc, resource-id) from its memory to find the match with industrial-grade confidence.

🎛️ Control & Transparency

Xenon provides full visibility and control over its self-healing system:

  • Global Toggle: Enable or disable healing via CLI:
    appium server --use-plugins=xenon --plugin-xenon-enable-self-healing=true
  • Live Configuration: Toggle self-healing directly from the Xenon Dashboard Settings at runtime without restarting the server.
  • Audit Logs: Every healing event is recorded in the session command history. You can see:
    • Original Selector: The locator that failed.
    • Recovered Selector: The replacement locator found by Xenon.
    • Confidence Score: The mathematical match probability (0-1.0).
    • Healing Tier: Which tier (Fuzzy XML, OCR, etc.) performed the recovery.

📖 API Documentation

Xenon provides a comprehensive REST API for device management, session control, and more.

Swagger UI

Access interactive API documentation at:

http://localhost:4723/xenon/api-docs

OpenAPI Spec

Get the raw OpenAPI specification:

http://localhost:4723/xenon/api-docs.json

API Categories

| Category | Base Path | Description | |----------|-----------|-------------| | Devices | /xenon/api/devices | Device discovery and management | | Sessions | /xenon/api/session | Session management and logs | | Builds | /xenon/api/build | Build and test execution tracking | | Control | /xenon/api/control | Interactive device control | | Reservations | /xenon/api/reservation | Device reservation for exclusive use | | Applications | /xenon/api/apps | App repository and installation | | Webhooks | /xenon/api/webhook | Notification webhook configuration |

Key Endpoints

Devices

# Get all devices
GET /xenon/api/devices

# Get device by platform
GET /xenon/api/device/{platform}

# Block/Unblock device
POST /xenon/api/device/{udid}/block
POST /xenon/api/device/{udid}/unblock

Control API

# Take screenshot
GET /xenon/api/control/{udid}/screenshot

# Tap at coordinates
POST /xenon/api/control/{udid}/tap
{ "x": 100, "y": 200 }

# Swipe gesture
POST /xenon/api/control/{udid}/swipe
{ "x": 100, "y": 500, "endX": 100, "endY": 100, "duration": 1000 }

# Type text
POST /xenon/api/control/{udid}/text
{ "text": "Hello World" }

# Execute shell command (Android)
POST /xenon/api/control/{udid}/shell
{ "command": "pm list packages" }

# Live stream
GET /xenon/api/control/{udid}/stream

Reservations

# Reserve a device
POST /xenon/api/reservation
{ "udid": "...", "host": "...", "reservedBy": "John", "duration": "2h" }

# Release reservation
DELETE /xenon/api/reservation/{udid}/{host}

# Extend reservation
POST /xenon/api/reservation/{udid}/{host}/extend
{ "duration": "1h" }

🎨 Dashboard

Access the dashboard at http://localhost:4723/xenon/

Views

| View | Description | |------|-------------| | Devices | Real-time device grid with status indicators | | Sessions | Active and historical session management | | Builds | Test runs grouped by build identifier | | Control | Interactive device control interface |


📚 Documentation

The full documentation is available at: https://xenon-docs.vercel.app/

Quick Links


🏗️ Development

# Clone and install
git clone https://github.com/xenon-platform/xenon.git
cd xenon
npm install

# Build everything (Plugin + Dashboard)
npm run build:all

# High-velocity development loop
# (Auto-rebuilds and restarts Appium server)
npm run dev

# Run tests
npm run test:all              # Unit tests
npm run test:android          # Android integration
npm run test:ios              # iOS integration

🔐 Authentication

All /xenon/api/* endpoints are authenticated. Xenon supports three shapes — pick whichever matches your caller.

Identity model

Xenon ships an enterprise identity stack: users with roles (SUPER_ADMIN / ADMIN / MEMBER), teams that scope which devices a user can reach, and API tokens minted per-user with their own scope set. The dashboard, programmatic clients, and hub-node channel all flow through the same identity.

Auth shapes

| Shape | Header(s) | When to use | |---|---|---| | Cookie session | Cookie: xenon_dashboard_session=… | Dashboard browser sessions. Set by POST /api/auth/login with {email, password}. | | Pair auth | X-Xenon-Access-Key + X-Xenon-Token | Programmatic clients (CI, SDK, hub→node). Each user has one access key (rotatable) and any number of scoped tokens. | | Auth disabled | (none) | Local dev only. Set --plugin-xenon-auth-disabled (or XENON_AUTH_DISABLED=true). A WARN logs every 60 s. |

First-run bootstrap

On first start Xenon creates a SUPER_ADMIN user from these env vars (defaults [email protected] / Admin@123):

export XENON_BOOTSTRAP_ADMIN_EMAIL="[email protected]"
export XENON_BOOTSTRAP_ADMIN_PASSWORD="..."  # change me

Sign in at https://<host>/xenon/ with these credentials. From /profile you can mint API tokens and rotate your access key. For CI use, programmatically POST /api/auth/login to get the cookie, then POST /api/profile/tokens to mint a scoped token.

Generating a programmatic token

# 1. Get your access key + a fresh token from /profile in the dashboard, or:
curl -s -X POST -b "xenon_dashboard_session=$COOKIE" \
  -H 'Content-Type: application/json' \
  -d '{"name":"ci","scopes":["sessions","read"]}' \
  http://localhost:4723/xenon/api/profile/tokens

# 2. Use it on every subsequent call:
curl -H "X-Xenon-Access-Key: xen_..." -H "X-Xenon-Token: ..." \
  http://localhost:4723/xenon/api/devices

Scopes

Tokens carry one or more scopes; the user's role controls which scopes they can grant.

| Scope | Access | |-------|--------| | read | GET sessions, devices, logs, apps | | sessions | Create/delete sessions and reservations | | devices | Block/unblock devices, install apps, hub-node /register and /unblock | | admin | User / team / API-key management, webhooks |

Teams (device access control)

Scopes govern which verbs a token can call; teams govern which devices it can reach. A user bound to a team sees the team's devices plus the shared pool (teamId = null). admin-scope tokens bypass team filtering.

Test clients pass the access key via the xenon:accessKey capability:

const caps = {
  platformName: 'iOS',
  'appium:automationName': 'XCUITest',
  'xenon:accessKey': process.env.XENON_CI_KEY,   // user with team membership
  // optional: 'xenon:team': '<team-id>' to pin allocation (admins only for cross-team)
};

See docs/teams.md for creating teams, assigning devices, and the full error taxonomy.

Hub-node channel

Hub and node authenticate using the same pair-auth shape. Provision a User on the hub for each node, mint a devices-scoped token, and set both env vars on the node:

export XENON_HUB_ACCESS_KEY="xen_..."
export XENON_HUB_TOKEN="..."

Both REST /register calls and the Socket.io handshake will use this pair. See docs/node-provisioning.md for the full provisioning + recovery flow.


🌱 Environment Variables

Xenon reads these env vars in addition to the CLI flags. Prefer env vars for credentials so keys don't end up in shell history or config files.

| Variable | Purpose | |----------|---------| | XENON_AI_PROVIDER | AI backend: gemini, openai, anthropic, or ollama. Same as --plugin-xenon-aiProvider. | | XENON_AI_MODEL | Override the default model for the selected provider. | | XENON_AI_BASE_URL | Custom base URL (local Ollama, OpenAI-compatible gateway). | | XENON_GEMINI_API_KEY / GEMINI_API_KEY | Gemini credentials. XENON_-prefixed form wins if both set. | | XENON_OPENAI_API_KEY / OPENAI_API_KEY | OpenAI credentials. | | XENON_ANTHROPIC_API_KEY / ANTHROPIC_API_KEY | Anthropic credentials. | | XENON_OPENAI_MODEL | Alternate way to set the OpenAI model. | | XENON_OTEL_DEBUG | When true, OpenTelemetry adds a ConsoleSpanExporter so every span is logged. Dev/tracing only. | | XENON_DB_PROVIDER | sqlite or postgresql. Same as --plugin-xenon-databaseProvider. | | DATABASE_URL | Prisma database URL. Falls back to file:~/.cache/xenon/xenon.db. | | XENON_HUB_ACCESS_KEY | Node→hub outbound: access key the node sends in X-Xenon-Access-Key. Required alongside XENON_HUB_TOKEN. See docs/node-provisioning.md. | | XENON_HUB_TOKEN | Node→hub outbound: token the node sends in X-Xenon-Token. Required alongside XENON_HUB_ACCESS_KEY. | | XENON_BOOTSTRAP_ADMIN_EMAIL / XENON_BOOTSTRAP_ADMIN_PASSWORD | First-run super-admin user, created on first hub boot. Defaults [email protected] / Admin@123. Change in any non-throwaway environment. | | XENON_AUTH_DISABLED | true to disable all auth. Local dev only. | | XENON_AUTO_MIGRATE | When true (default), the hub auto-applies pending schema changes at startup (prisma db push for SQLite, prisma migrate deploy for PostgreSQL). Set false if you manage migrations externally via CI for auditable change-control. |

See docs/server-args.md for the full CLI-flag reference and how these variables interact with config files.


🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

Contributors


📜 License

ISC License - See LICENSE for details.