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

maestro-manager

v0.0.1

Published

Daemonless iOS Maestro test runner with a shared simulator pool.

Readme

Maestro Manager

Daemonless iOS Maestro test runner with a shared simulator pool. The CLI creates named simulator slots, leases them to concurrent test runs, and records run state under the current pool prefix.

Prerequisites

  • macOS with Xcode command line tools and simulator support available through xcrun simctl.
  • Bun >=1.3.14 and Node.js >=24.16.0.
  • Maestro installed on PATH as maestro.
  • A built iOS .app bundle and Maestro flow YAML files.

Install dependencies:

bun install

Configuration

Create maestro-manager.config.json at the repo root, pass it with --config <path>, or set MAESTRO_MANAGER_CONFIG=<path>. Without either override, the CLI walks up from the current directory until it finds the config.

Minimal shape:

{
  "pool": {
    "prefix": "my-project-e2e",
    "deviceType": "iPhone 16",
    "default": 2,
    "max": 4
  },
  "app": {
    "appId": "com.example.MyApp",
    "glob": "~/Library/Developer/Xcode/DerivedData/*/Build/Products/*-iphonesimulator/*.app",
    "searchDirs": ["~/Library/Developer/Xcode/DerivedData"]
  },
  "flowsDir": "maestro/flows",
  "warmupDeepLink": "myapp://e2e/warmup",
  "java": {
    "home": null,
    "autodetect": ["JAVA_HOME", "mise", "/usr/libexec/java_home"]
  },
  "recordingsDir": "recordings",
  "hooks": {
    "pruneAccounts": ""
  }
}

Notes:

  • pool.prefix becomes part of simulator names and the state path. Keep it project-specific and safe: start with a letter or number, then use only letters, numbers, dots, underscores, and hyphens.
  • pool.default is the normal warm pool size. pool.max is the hard concurrency cap and must be <= 8. Keep pool.max <= 4 until the downstream project has proved its backend is stable at the higher concurrency.
  • flowsDir, recordingsDir, and entries in app.searchDirs resolve relative to the config file directory, with ~ expanded.
  • App resolution order is --app, then app.path, then app.glob, then scanning app.searchDirs for the newest .app matching app.appId. app.glob supports * and ? within path segments and ~ expansion.
  • hooks.pruneAccounts is an optional shell command run by clean --prune-accounts.

Common Workflows

Warm the default simulator pool:

maestro-manager up --app path/to/MyApp.app

By default, simulators boot headless: Maestro can run against them without opening Simulator.app. Use --headed when you want to watch the pool or a run:

maestro-manager up --headed --app path/to/MyApp.app
maestro-manager test --headed --sims 2

--headless is also accepted explicitly and conflicts with --headed.

Show pool slots, active leases, and recent runs:

maestro-manager status

Run all configured flows on two simulators:

maestro-manager test --sims 2

Stop this worktree's active leases but keep the pool:

maestro-manager stop

Reclaim stale leases and shut down idle simulators:

maestro-manager clean --idle-shutdown 30

clean runs a stateless reaper, even with no flags:

  • Reap orphaned runs. When a test worker is SIGKILLed or crashes, no signal trap fires, so its detached maestro process group — and the simulator's (often hung) app — keep running and burning CPU. The stale-lease reclaim deliberately refuses to reclaim such a slot while its maestro child is still alive (so it never yanks a simulator a live run is driving). clean detects this case — owner dead, heartbeat stale, maestro still alive — kills the orphaned maestro group, shuts the simulator down (killing the hung app), and reclaims the slot.
  • Reclaim stale leases whose owner and maestro child are both dead, shutting those simulators down too.

Live-leased simulators (a live owner) are never touched.

Add --delete-unavailable to also run xcrun simctl delete unavailable, removing broken-runtime CoreSimulator devices left behind by Xcode upgrades, removed runtimes, or other tools. This is global — it is NOT scoped to this pool's prefix — so it is opt-in and off by default:

maestro-manager clean --idle-shutdown 30 --delete-unavailable

Stop all leases, delete pool simulators, and clear pool state:

maestro-manager down

test runs all .yaml and .yml files in flowsDir when no flow paths are provided. Use --include-tags and --exclude-tags for manager-side tag selection, and put Maestro passthrough arguments after a literal --.

State And Logs

State is scoped by pool.prefix under:

~/.maestro-manager/<prefix>

Important paths include:

  • config-snapshot.json for the last config snapshot written by up.
  • sims/<sim-name>/udid, lastused, and lease/record.json for pool slots and lease ownership.
  • waiters/<runId>/ticket.json for queued work.
  • runs/index.json, runs/<runId>/run.json, and runs/<runId>/<flow>.log for run history and per-flow Maestro output.

maestro-manager down runs stop --all, deletes all pool simulators it can resolve, then removes ~/.maestro-manager/<prefix>.

Verification

Run the full local check:

bun run check

Run the no-excuse audit baseline check:

bash scripts/check-no-excuse-baseline.sh src