Introduction

Connecting iOS simulators to agents in DeepSeek Harness (DSH) is commonly done by opening a shell for them to call xcrun simctl directly. The practical problem with this path is that environment configuration is scattered across scripts and undocumented defaults commands, making the test environment hard to reproduce; the model only gets an untyped, unsafe shell entry point, making it impossible to audit afterwards what was changed and in what order.

qubyyang/awesome-ios-sim solves this problem. Instead of adding new simulator capabilities, it encapsulates “changing simulator state” into a fixed workflow:

profile + current snapshot -> diff -> deterministic plan -> explicit confirmation -> audited apply

Starting from a target profile and current snapshot, perform a diff, generate a deterministic ordered operation plan, and execute it with auditing only after explicit confirmation. Below, we introduce it sequentially by features, installation, and usage.

What is it

awesome-ios-sim positions itself as Simulator State as Code: capturing, diffing, planning, and safely applying iOS simulator state into reproducible, versioned profiles via a deterministic Swift CLI and MCP stdio server. The author is qubyyang, MIT licensed. The project is currently in alpha status, with the schema version being v1alpha1.

It targets three types of users simultaneously: iOS developers, CI pipelines, and AI agents.

Core Features

A fixed workflow: capture → diff → plan → confirm → apply

Simulator settings are converted into versionable JSON profiles that can be committed to the repository alongside test code. Any change is first generated offline as a plan, reviewed, and then applied. The plan is a deterministic list of ordered operations.

CLI and MCP server share the same engine

The repository produces two executables: ios-sim-state (CLI) and ios-sim-state-mcp (MCP stdio server). Both share the same planner, validation, and apply gating, so there is no situation where the CLI and the agent operate on separate logic.

Agent-friendly safe defaults

MCP tools use JSON Schema to describe parameters; simulator_apply defaults to dry-run, and actual changes are only made upon explicit confirmation.

Reusable layers and presets

It includes three built-in presets: booted, clean-status-bar, and shutdown. Run ios-sim-state presets to view their descriptions. Layers only contain reusable spec fields and no target. --layer and --preset can be passed repeatedly in the order they are to be composed, applied to compose, diff, or plan. The merge rules are deterministic: scalar values override later values, applications are replaced by bundleIdentifier, preferences are replaced by domain + key, and status bar fields are merged by key. v1alpha1 does not have a generic delete/tombstone operator; to uninstall an app, use presence: "absent".

Strict validation and execution receipts

Profiles are validated by the v1alpha1 JSON Schema, strictly decoded, and reject unknown fields and empty identifiers. After apply, each execution receipt records the actual parameter array, exit code, stdout, stderr, and timestamp for the executed operations; apply stops at the first failed operation.

Uses only public APIs, local-first

All changes are performed solely through Apple’s public xcrun simctl, without using the private CoreSimulator framework. No daemon, cloud account, telemetry, or API key is required.

Installation and Setup

Confirm the environment first, then install.

System Requirements

  • macOS 13 or later;
  • Swift 6;
  • Full Xcode and iOS Simulator runtime (inventory, snapshot, and apply operations all require this);
  • xcode-select points to the target Xcode installation.

Installing only the Command Line Tools allows building, but it does not include CoreSimulator/simctl, so actual operations cannot be performed.

Homebrew Installation

brew tap qubyyang/awesome-ios-sim https://github.com/qubyyang/awesome-ios-sim
brew install qubyyang/awesome-ios-sim/awesome-ios-sim

On prerelease macOS versions not yet recognized by Homebrew, you might encounter a packages.*_dunno API error. You can bypass this by using the source code tap mode:

HOMEBREW_NO_INSTALL_FROM_API=1 \
  brew install qubyyang/awesome-ios-sim/awesome-ios-sim

Note: The initial release archives (Apple Silicon/Intel) are not yet code-signed or notarized; the next tagged release will undergo Developer ID signing and Apple notarization, and will switch to a universal archive.

Source Installation

git clone https://github.com/qubyyang/awesome-ios-sim.git
cd awesome-ios-sim
swift build -c release

The build artifacts are located at .build/release/ios-sim-state and .build/release/ios-sim-state-mcp.

Installation as a dsh-plugin

The npm package @qubyyang/awesome-ios-sim (version 0.2.0-dev, OS restricted to darwin, engines require Node ^22.19.0 || >=24.0.0) exports ./dsh-plugin and can be installed as a dsh-plugin bundle into DeepSeek Harness. The installation section of the README does not provide a specific DSH installation command, but the repository header links to docs/DEEPSEEK_HARNESS.md and docs/MCP.md. The specific steps for DSH integration are based on these two documents.

Typical Usage

Using the repository’s built-in examples, let’s walk through the complete workflow. Step 1: List runtimes and simulators:

swift run ios-sim-state inventory

The output is stable JSON. Step 2: Capture a managed state of a simulator:

swift run ios-sim-state snapshot --device <UDID> > simulator.snapshot.json

Step 3: Compose layers and presets in order to generate the full target profile:

swift run ios-sim-state compose \
  --profile Examples/ui-tests.profile.json \
  --preset clean-status-bar \
  --layer Examples/ui-tests.layer.json > simulator.composed.json

Step 4: Generate a deterministic ordered operation plan offline:

swift run ios-sim-state plan \
  --profile Examples/ui-tests.profile.json \
  --snapshot Examples/ui-tests.snapshot.json > simulator.plan.json

Step 5: Preview the behavior of apply. Without --confirm, it defaults to dry-run and makes no changes:

swift run ios-sim-state apply --plan simulator.plan.json

After reviewing the plan from the steps above, add --confirm to execute it for real, and use --journal to preserve the execution log:

swift run ios-sim-state apply \
  --plan simulator.plan.json \
  --confirm \
  --journal simulator.report.json

The profile itself looks like this (taken from the README example):

{
  "apiVersion": "awesome-ios-sim/v1alpha1",
  "kind": "SimulatorState",
  "metadata": { "name": "ui-tests" },
  "target": {
    "name": "iPhone 17 Pro",
    "runtime": "com.apple.CoreSimulator.SimRuntime.iOS-27-0"
  },
  "spec": {
    "power": "shutdown",
    "applications": [
      {
        "bundleIdentifier": "com.example.app",
        "sourcePath": "/absolute/path/to/Example.app",
        "running": true,
        "launchArguments": ["--uitesting"]
      }
    ],
    "preferences": [
      {
        "domain": "com.example.app",
        "key": "hasSeenOnboarding",
        "value": false
      }
    ],
    "statusBar": { "time": "09:41", "batteryLevel": 100 }
  }
}

Fields with safe defaults can be omitted. power: "unchanged" will restore the original power state after temporary work; if the plan includes an erase, the booted device will shut down first; the boot operation will wait for simctl bootstatus -b to complete before proceeding. statusBar only accepts public simctl status_bar override items, and enumeration values and value ranges are validated before planning.

Use Cases and Notes

Suitable for two types of people: 1) Developers who need to reproduce iOS simulator test environments in CI or teams, who can simply commit profiles alongside test code; 2) DSH plugin authors connecting simulator capabilities to agents, who can replace the bare shell with MCP tools that feature JSON Schema and default dry-run.

Notes before use:

  1. The project is in alpha status and the schema is v1alpha1; changes may occur in the future;
  2. Before applying a plan that contains erase or app removal operations, manual review is mandatory;
  3. Apply stops at the first failed operation; use the journal to troubleshoot subsequent issues;
  4. The initial release archives are unsigned and notarized; teams with strict supply chain requirements can use source builds first.

Another reminder: such plugins run with the permissions of the current dsh process. It is recommended to check the source code and license before installing (this project is MIT licensed).

Conclusion

awesome-ios-sim does something not complicated: turning simulator state into a profile that can be committed, diffed, and reviewed just like code, allowing agents and humans to operate within the same workflow, with safety by default and auditable afterwards. See the directory page at https://www.skillhub.cn/plugins/qubyyang/awesome-ios-sim and the source code at https://github.com/qubyyang/awesome-ios-sim.