DSH Plugins Marketplace

DSH Plugins

Plugins

/

Development & Infrastructure

/

dsh-ios-simulator-helper

d

dsh-ios-simulator-helper

Manifest valid

The official ZCode ios-simulator plugin ported to native DSH tools: the original 20 ios_* tools keep their names and arguments, plus ios_shutdown_simulator, covering Xcode project discovery and scaffo

UI (client)hasBundlePatch

dsh-ios-simulator-helper

English | 简体中文

npm version license: MIT platform: macOS target: DSH

A DeepSeek Harness (DSH) native port of the official ZCode ios-simulator@0.1.0 plugin: all 20 original MCP tools preserved as native DSH tools, plus a full settings page (Settings → iOS Simulator) that edits the simulator parameters in-app instead of through environment variables.

  • Tool and argument names are identical to the original, so workflows written for the ios_simulator MCP server keep working; one tool is added — ios_shutdown_simulator, because the original could boot a simulator but never stop one.
  • 17 settings fields in 5 groups, all live-editable; an empty field falls back to the original plugin's IOS_SIM_* variable, then to the built-in default.
  • The settings page detects the host system and, on a non-macOS host, states that this plugin only supports macOS; every tool that drives Apple tooling then refuses with a clear message instead of failing with spawn xcrun ENOENT, while ios_preflight reports the failing host check and ios_discover_project, ios_create_app and ios_ui_status still answer.
  • Published as @zhz8888/dsh-ios-simulator-helper; the plugin page shows iOS Simulator Helper / iOS 模拟器助手 from locale/ rather than the raw package name, and both descriptions say the plugin is unofficial and not affiliated with Apple.

Quick start

On a Mac with full Xcode, at least one iOS runtime and DSH installed:

  1. Install the plugin

    dsh plugin --profile <profile> add @zhz8888/dsh-ios-simulator-helper
    

    In DSH Desktop, open Plugins and add the same package name there. Reload or restart DSH afterwards.

  2. Check the machine — open Settings → iOS Simulator and press Run diagnostic. It runs exactly the checks ios_preflight runs (full Xcode, a simulator runtime, idb), and prints a fix for anything missing.

  3. Use it — ask for what you want ("build and run this project on the iPhone 16 simulator", "screenshot the running app"), or call the 21 ios_* tools directly. Everything the tools need is editable on that settings page.

Contents

Requirements

DependencyNotes
macOSThe only supported host. xcrun simctl, xcodebuild and the simulator window app exist nowhere else.
Full Xcodexcode-select -p must point at Xcode.app/Contents/Developer; Command Line Tools alone are not enough.
An iOS Simulator runtimeAt least one iOS/iPadOS runtime installed from Xcode → Settings → Platforms.
Node.js ≥ 22The DSH host runtime.
idb (optional)Needed only by the ios_ui_* tools. Without it, build/run/screenshot/logs are unaffected.

ios_preflight checks every item above and prints a fix for each failure; the settings page's "Run diagnostic" button runs the same checks.

Install

dsh plugin --profile <profile> add @zhz8888/dsh-ios-simulator-helper

DSH Desktop: the desktop profile belongs to the Electron app — open Plugins, add @zhz8888/dsh-ios-simulator-helper there, and enable the row it creates. After a reload or restart the page is at Settings → iOS Simulator; it only appears while the host half actually serves this plugin's settings namespace.

The published tarball contains everything the plugin needs — the host half, the browser bundle, the bundled skill and the locale/ entries — and nothing is compiled at install time, so no build approval step is involved. @deepseek-ai/cordis, @deepseek-ai/dsh-tools and @deepseek-ai/schemastery are peer dependencies provided by the harness, so the plugin pulls in no second copy and has no runtime dependencies of its own; DSH's compatibility gate compares the @deepseek-ai/dsh* peer ranges against the running version and refuses to install on a mismatch.

Mount the package exactly once. dsh plugin add records the row in dsh.profile.bundles; adding a second row for the same package in the profile's own cordis.patch.yml registers every tool name twice and fails at the loader.

Upgrade and uninstall

dsh plugin --profile <profile> add @zhz8888/dsh-ios-simulator-helper@latest   # upgrade
dsh plugin --profile <profile> remove @zhz8888/dsh-ios-simulator-helper      # uninstall

Settings live in the profile, not in the package, so both commands leave them in place. The data directory (by default $DSH_HOME/ios-simulator-helper) holds screenshots, build logs and DerivedData; it is yours to delete, and uninstalling does not touch it.

Version gate

The DSH compatibility range is >=0.2.0-rc.2, a lower bound only, declared identically in peerDependencies, engines.dsh and dsh.compatibility.dsh: a runtime below it is refused at install time, and no future harness release is excluded.

One node-semver detail survives — a new tuple's prerelease such as 0.2.1-alpha.1 is not admitted by npm's and pnpm's default rules, so that install fails until either the range gains a branch for the tuple (">=0.2.0-rc.2 <0.2.1-0 || >=0.2.1-0") or the peer check is skipped:

dsh plugin --profile <profile> add @zhz8888/dsh-ios-simulator-helper \
  --config.strict-peer-dependencies=false

Stable releases (0.2.0, 0.2.1, 0.3.0, 1.0.0, …) are unaffected and always admitted.

Settings page

The settings namespace equals the profile patch row id equals ios-simulator-helper (also dsh.name). The page reads and writes through ctx.configForms, so staged edits, dirty detection, inline validation, optimistic concurrency (revisions) and "overridden / reset to default" all come from the harness. It is one card per category, built from the same field kit as the built-in settings pages (@deepseek-ai/dsh-client-ui-primitives); the three timeouts are entered in whole seconds, while the legacy IOS_SIM_*_MS variables are still read in milliseconds and converted.

Saving happens in a pill that sticks to the bottom of the page: it appears while edits are staged (or a write is in flight, or one failed), names that state next to a status dot, and carries Discard changes and Save (disabled while a draft is invalid). A draft that merely puts a control back to the value already in effect counts as no edit at all, a confirmation toast reports a write that landed, and leaving the page discards staged edits.

GroupFieldTypeDefaultLegacy env fallbackNotes
Simulator and devicedefaultDevicetext (suggestions from this machine)iPhone 16IOS_SIM_DEFAULT_DEVICEDevice-name fragment used when a tool names no udid/device; falls back to the first available iPhone on a miss.
defaultRuntimetext (suggestions from installed runtimes)emptyIOS_SIM_DEFAULT_RUNTIMERuntime fragment such as iOS-27; empty matches any. A preference, not a requirement: a stale value widens the pool instead of erroring.
autoBootSimulatorswitchonIOS_SIM_AUTO_BOOTWhen off, tools fail instead of running simctl boot for a stopped target.
autoOpenSimulatorswitchonIOS_SIM_AUTO_OPENMatches the original by opening the Simulator window (boot / show / open URL / build and run); off keeps everything headless.
bootTimeoutSecondsinteger120IOS_SIM_BOOT_TIMEOUT_MS (ms)Longest wait for one simctl boot / bootstatus, in seconds. The legacy variable keeps its millisecond spelling and is converted.
UI automationuiBackendselectautoIOS_SIM_UI_BACKENDauto probes for idb; idb requires it; none disables the UI tools; xcodebuildmcp is reserved.
idbBinarytextidbIOS_SIM_IDB_BINARYCommand name or absolute path of idb.
uiTimeoutSecondsinteger60IOS_SIM_UI_TIMEOUT_MS (ms)Longest runtime of one idb UI command, in seconds; the legacy variable is milliseconds.
Build and DerivedDatadefaultConfigurationtextDebugIOS_SIM_CONFIGURATIONUsed when a tool names no configuration.
buildTimeoutSecondsinteger600IOS_SIM_BUILD_TIMEOUT_MS (ms)Longest runtime of one xcodebuild build, in seconds; the legacy variable is milliseconds.
extraBuildArgsmultilineemptyIOS_SIM_EXTRA_BUILD_ARGSOne argument per line, # starts a comment; inserted after -derivedDataPath and before build.
derivedDataDirtextemptyIOS_SIM_DERIVED_DATA_DIREmpty uses <data dir>/DerivedData/<project fingerprint>.
disableCodeSigningswitchonIOS_SIM_DISABLE_CODE_SIGNINGThe original always passed CODE_SIGNING_ALLOWED=NO; off lets Xcode decide.
LogslogSecondsinteger120IOS_SIM_LOG_SECONDSRecent seconds ios_logs reads when the call names no window; capped at 3600.
logLimitinteger20000IOS_SIM_LOG_LIMITLargest rendered log ios_logs returns when the call names no limit.
Output directoriesdataDirtextemptyIOS_SIM_PLUGIN_DATARoot for screenshots, build logs and DerivedData; empty uses $DSH_HOME/ios-simulator-helper, then ~/.dsh/ios-simulator-helper.
screenshotDirtextemptyIOS_SIM_SCREENSHOT_DIREmpty uses <data dir>/screenshots.

Below the form sit the host check and three buttons:

  • Host system — decided twice: synchronously from the browser's own platform string (so a non-macOS browser sees the notice on first paint, before any request), then authoritatively from the host half's GET /api/ios-simulator-helper/host; the host wins on a conflict. When the host is unsupported — or the host never answered and the browser itself is non-macOS — a red notice titled "This plugin only supports macOS" appears above the form and names the detected platform.
  • Run diagnostic → GET /api/ios-simulator-helper/status, the same checks ios_preflight runs, listed one by one with status, detail and fix.
  • Refresh simulators and runtimes → GET /api/ios-simulator-helper/inventory, which discovers the Xcode path and version, the macOS version, simulators, runtimes and the resolved default target, to fill the fields' suggestion lists.

Legacy configuration

The original plugin's userConfig (default_device, ui_backend) and its environment variables IOS_SIM_DEFAULT_DEVICE, IOS_SIM_UI_BACKEND and IOS_SIM_PLUGIN_DATA still work as fallbacks (last column above), so an existing ZCode or CI setup needs no change. The original's IOS_SIM_PACKAGE_ROOT only located the plugin for its own MCP launcher; DSH resolves the package path directly and does not need it.

Screenshots

All four are the live page in DSH Desktop, in the order you scroll it — nothing is mocked up. They show the 1.1.0 card layout and the timeouts in whole seconds; the save bar only appears while an edit is staged, so it is not in these shots. The window ran the Chinese locale, so the section headings are Chinese while every field name is the same in both languages.

1. Simulator and device — the fields every ios_* call reads:

The iOS Simulator settings page in DSH Desktop: the simulator-and-device card with the default device, default runtime, auto boot, auto open and the boot timeout

2. UI automation and builds — the idb backend and its timeout, then the xcodebuild configuration, build timeout and extra arguments:

The page scrolled to UI automation and build settings: UI backend, idb binary, UI timeout, default configuration, build timeout and the extra xcodebuild arguments

3. Build tail and logs — the extra xcodebuild arguments, the DerivedData directory and the code-signing switch, then the ios_logs window and character limit:

The page scrolled further: the extra xcodebuild arguments, the DerivedData directory, code signing during builds, and the default log window and character limit

4. Output directories and the host check — where screenshots, logs and DerivedData land, then the macOS verdict with the two detection buttons:

The bottom of the page: the data and screenshot directories, then the host check reading "macOS — supported (darwin/arm64)" with the run-diagnostic and refresh buttons

screenshots.json lists these four files in this order next to package.json in the repository, which is how a plugin market finds them.

Tools

21 tools: the original 20 with identical names and arguments, plus one addition.

ToolPurpose
ios_preflightCheck the host (macOS), Xcode, xcodebuild, simctl, runtimes, simulators and the UI backend, and echo the current settings.
ios_list_simulatorsList iOS/iPadOS simulators and installed runtimes.
ios_boot_simulatorBoot the selected simulator, optionally opening the Simulator window.
ios_show_simulatorOpen the simulator window app — Simulator.app on Xcode 25 and earlier, Device Hub on Xcode 26 and later — optionally focused on one UDID.
ios_shutdown_simulatorAdded: shut the selected simulator down (simctl shutdown); already-stopped is a success, not an error.
ios_discover_projectFind .xcodeproj/.xcworkspace, schemes and bundle ids.
ios_create_appGenerate a minimal SwiftUI project (refuses to overwrite generated files by default).
ios_build_appBuild the iOS Simulator product with xcodebuild.
ios_build_and_runBuild → install → launch → show.
ios_install_appInstall a .app on the selected simulator (absolute paths allowed).
ios_launch_appLaunch by bundle id.
ios_terminate_appTerminate by bundle id.
ios_open_urlOpen a URL in the simulator.
ios_screenshotCapture a PNG to disk, and return it as an image when the model accepts image input.
ios_logsRead log show output, optionally filtered by bundle id.
ios_ui_statusReport UI-automation availability and the backend the settings selected.
ios_ui_tap / ios_ui_swipe / ios_ui_type_text / ios_ui_button / ios_ui_describeidb-backed tap / swipe / typing / hardware button / accessibility tree.

Two behaviours deserve their own note:

  • ios_screenshot always writes the PNG to disk (under <data dir>/screenshots/ by default) and additionally submits it to the host's attachment service for a canonical image block. When the current model declares no image input, or the deployment stores no attachments, the result degrades to text plus the file path instead of failing the call.
  • ios_build_and_run resolves the bundle id in four steps — a fix over the original, which asked xcodebuild -showBuildSettings alone and, in a restricted environment, silently returned undefined after a successful build: explicit bundleId argument → CFBundleIdentifier of the .app that was just built (read with plutil, i.e. the value simctl installs) → -showBuildSettings with the same -derivedDataPath → identifiers found in project.pbxproj. The winner is reported as bundleIdSource.

Skill and slash command

  • ios-dev skill — shipped in skills/ios-dev/ and registered by the host half through ctx.skills.register() as an embedded skill with the skill directory as its resourceBase. Rewritten for DSH: no mcp__… prefix, environment configuration points at the settings page, and the macOS precondition plus the "shut the simulator down when you are done" step are spelled out.
  • /ios-dev [goal] command — registered through ctx.commands.register(). DSH user commands deliberately never create a model message, so this command does the one thing that is useful without the model: it runs the environment diagnostic and prints the verdict, the failing checks and their fixes.

Differences from the original

AspectOriginal (ZCode)This plugin (DSH)
Tool exposurestdio MCP server ios-simulator; the model sees mcp__ios_simulator__*Native ctx.tools.register(); the model sees ios_*
User configurationplugin.json userConfig (2 items), injected as environment variablesSettings page with 17 fields on a schemastery Config, all .volatile(); the old environment variables remain as fallbacks
Host checkprocess.platform read once, inside ios_preflightCentralised requireMacOS() in front of every Apple-tooling call, plus the settings page's synchronous and authoritative verdicts
Working directoryprocess.cwd()exec.agent.session.header.cwd (the session workspace)
Data directoryIOS_SIM_PLUGIN_DATA / temp$DSH_HOME/ios-simulator-helper, configurable on the settings page
Path safetyinside(cwd, path) refuses escapesSame semantics, split into read-only paths (an absolute .app is fine) and write targets (must stay inside the session workspace)
Screenshot resultMCP image content (base64)An image block built from a host attachment reference, degraded to text plus a disk path on refusal
Result normalisationProviders return objects containing undefinedEvery tool result passes through toLosslessJson() (the registry rejects undefined)
Slash commandInjects a prompt into the model's conversationRuns the diagnostic and prints the verdict
Process invocationnode:child_process spawnUnchanged

Known limitations

  • macOS only. On any other host ios_preflight fails the Host OS (macOS) check and skips the remaining probes instead of producing meaningless spawn failures; every tool that drives Apple tooling refuses, ios_discover_project, ios_create_app and ios_ui_status still answer, and the settings page keeps the notice at the top.
  • ios_ui_* needs idb; ios_ui_status explains what is missing. xcodebuildmcp is only a reserved value (matching the original's reservedBackends) and is not implemented.
  • The original's ios_build_and_run always opened the Simulator window; here that is the autoOpenSimulator setting (on by default, so behaviour matches). ios_build_app and ios_screenshot still do not open windows, as in the original. The window app is Simulator.app on Xcode 25 and earlier and Device Hub on Xcode 26 and later; a window that cannot be opened is reported in the result (opened: false plus openWarning) and never fails the simctl steps.
  • ios_logs reads log show (no live stream), with a configurable and clamped window and length.
  • Swift macros (@State, #Preview) need swift-plugin-server, which cannot start its nested sandbox-exec when the caller is itself sandboxed. ios_build_app then retries the build once with OTHER_SWIFT_FLAGS=-disable-sandbox and reports macroSandboxRetry: true; a caller that was never sandboxed never sees a retry.
  • The generated project template is byte-for-byte the original's (an Xcode 14-compatible project.pbxproj, objectVersion = 56) and does not track newer Xcode templates.
  • The settings page has only been checked by eye in DSH Desktop: the plugin is installed into the desktop profile, and the four shots in assets/ are the latest manual pass, top to bottom. Dark theme, narrow-width wrapping and the non-macOS notice are still covered by the render tests, not by eye.
  • No credential handling: the plugin never reads or forwards key/token/secret environment variables.

Releases

Every release is one commit in two places: tagged vX.Y.Z on main and published to npm from that tag, whose SHA npm records as gitHead. The list is at Releases — v1.1.1 is the latest, after v1.1.0 and v1.0.0, all three dated 2026-10-17.

Contributing

Issues and pull requests are welcome at github.com/zhz8888/dsh-ios-simulator-helper. Every change has to keep pnpm check green — unit tests, a host/client consistency gate and a mount on a real Cordis host — and there is no CLA or form to fill in: a focused pull request that says what it changes and why is enough.

The package is shaped for the awesome-dsh-plugin market. Development conventions — commands, invariants, testing, commit and release rules — live in AGENTS.md.

License

MIT, copyright (c) 2026 zhz8888. Tool definitions, provider logic and the generated SwiftUI project template are ported from the ZCode official ios-simulator plugin, distributed under the MIT License by Z.ai; the template sources are kept verbatim. See the attribution at the end of LICENSE.

Comments

Loading…

Similar plugins

dsh-ios

by ZSeven-W

DeepSeek Harness (DSH) plugin: a live iOS Simulator — and a USB-connected iPhone — inside the conversation. 22 agent tools for booting, building, driving the UI by accessibility identity, OCR text or

UI & ExperienceManifest valid

★ 327

↓ 294/wk

MIT

TypeScript

Sep 24, 2026

dsh plugin --profile web add @zseven-w/dsh-ios

by Kickstartparty3459

Run live iOS simulators and your real iPhone over USB inside DeepSeek Harness conversations with 22 agent tools, MJPEG previews, and SwiftUI hot reload.

Development & InfrastructureManifest valid

★ 0

MIT

TypeScript

Oct 3, 2026

dsh plugin --profile web add @zseven-w/dsh-ios

dsh plugin: one hub over your coding IDEs (Trae/Qoder/ZCode/CatPaw/Codex/Claude Code/OpenCode/dsh) - session inventory, quota runway, shared prompt rules, Obsidian export (/ide-hub /hub-sessions /hub-usage)

Workflow & AutomationManifest valid

★ 0

MIT

TypeScript

dsh plugin --profile web add dsh-plugin-ide-hub

by Mars-Sea

Native iPhone companion plugin for DeepSeek Harness — sessions, approvals, questions, notifications, and secure remote access.

Manifest valid

★ 5

↓ 852/wk

MIT

TypeScript

Sep 30, 2026

dsh plugin --profile web add dsh-deeppilot

by harde1

Builds, tests, archives and runs an Xcode project or workspace on iOS or macOS through xcodebuild — a live filterable build log, scheme and destination pickers read from the project, and log streaming

Development & InfrastructureManifest valid

★ 0

MIT

JavaScript

Oct 12, 2026

dsh plugin --profile web add dsh-xcodebuild

by H1Kariiiiiii

该仓库暂未提供项目说明。

Tools & CapabilitiesUI & ExperienceManifest valid

★ 4

Apache-2.0

JavaScript

Oct 2, 2026

dsh plugin --profile web add dsh-icon-console