Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

iOS simulators can live in Xcode's device set (drivers.ios.deviceSet)

已关闭
#968 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

@V3RON 已经在做这个了。

开始于 2026年10月26日。

  • #976 来自 @V3RON —— 已合并

评估

难度
5/5
预计耗时
一周以上
新手友好度
38/100
Issue 类型
功能
描述清晰度
描述清楚
活跃度
活跃
技术栈
ios, typescript

调研方向

Start with src/drivers/ios/index.ts and trace how IosSimctlDriver.create reads driver options, builds simctl arguments, lists managed devices, and sets the lease environment. Then read src/daemon/main.ts for driver refusal handling and src/instructions/index.ts plus the named website page for the required guidance; update the related tests, including the issue’s roughly 12 test lines. Done means both device set modes, refusal cases, grants, instructions, and build guidance match the spec.

由索引模型根据 Issue 内容生成。

描述

task:blocked

Part of #962.

Scope

An operator sets drivers.ios.deviceSet: "default" and restarts the daemon. Simlock then keeps its iOS simulators in Xcode's own device set, so xcodebuild, the React Native CLI, Detox and agent-device's XCTest runner target a leased simulator by its UDID. Simlock still claims only simulators whose mark names its own instance. A bad value, or a switch with simulators left from the other setting, turns iOS off with a reason doctor shows. Unset, everything is as today. The website gets a "Build and run your app" page, and simlock instructions names the build route for each setting. simlock doctor shows a refused driver's reason (today a refused driver makes doctor fail, F29). A stopped slow-lane run leaves no simulator in the maintainer's Xcode set.

One task, kept whole: every behaviour reads the one setting through the iOS driver, and the docs and instructions must change with it (documentation rule 9). About 12 Tests lines.

The "Build and run your app" page (using-devices/build-and-run.mdx) holds: under simlock, -DVTSimulatorSetLocation="$SIMLOCK_IOS_DEVICE_SET" on Xcode 27 or later, and on older Xcode or a tool that takes no extra xcodebuild arguments the generic build (-destination 'generic/platform=iOS Simulator') then simlock simctl install or agent-device install; under default, -destination "platform=iOS Simulator,id=<udid>" directly; on Android, ANDROID_ADB_SERVER_PORT from the grant and -s <serial> (or ANDROID_SERIAL); and a warning for default: xcrun simctl shutdown all stops leased simulators, Simlock reboots each under its lease and the holder loses running apps, and one erased while stopped ends its lease. How to switch: the key, a restart, and the device-set-changed steps. An operator who set drivers.ios.deviceRoot runs those steps with it still set, and removes it only when switching to "default"; the leftover check reads only the default own root, so a custom root's simulators are named by these steps, not by the check (decided in delivery, pending the maintainer).

In short

drivers.ios.deviceSet is "simlock" (default, today's behaviour) or "default" (Xcode's set, ~/Library/Developer/CoreSimulator/Devices). Under "default" no simctl call carries --set, the grant carries no SIMLOCK_IOS_DEVICE_SET, and a simulator is this Simlock's only when its durable mark names this instance's id. The check for simulators left from the other setting reads files only, at driver start: no simctl call is added to start-up.

flowchart LR
  C[config: drivers.ios.deviceSet] --> D["IosSimctlDriver.create (CHANGED)"]
  D -->|bad value / leftovers| R[iOS off: invalid-device-set / device-set-changed]
  D --> S["simctl argv: --set root, or none (CHANGED)"]
  D --> L["listManaged: all in set, or only this instance's marks (CHANGED)"]
  D --> E["grant env: SIMLOCK_IOS_DEVICE_SET, or none (CHANGED)"]
  E --> A[agent-device daemon: set, or Xcode's set]

Messages, word for word (<…> are the variable parts):

  • Bad value: Refusing the ios device set: drivers.ios.deviceSet must be "simlock" or "default", but it is <JSON of the value>
  • deviceRoot with "default": Refusing the ios device set: drivers.ios.deviceRoot names Simlock's own set, but drivers.ios.deviceSet is "default". Remove one of them.
  • Leftovers under "default": Refusing the ios device set: Simlock's own set at <root> still holds <n> simulator(s) (<udid>, <udid>, …). Set drivers.ios.deviceSet back to simlock, run `simlock nuke --delete-devices` and `simlock doctor --purge-orphans`, then switch again. Delete any that remain with `xcrun simctl --set <root> delete <udid>`.
  • Leftovers under "simlock": Refusing the ios device set: Xcode's device set still holds <n> of this Simlock's simulator(s) (<udid>, …). Set drivers.ios.deviceSet back to default, run `simlock nuke --delete-devices` and `simlock doctor --purge-orphans`, then switch again. Delete any that remain with `xcrun simctl delete <udid>`.
deviceSet deviceRoot Today After
not set not set own set own set
"simlock" /Volumes/sims own set at /Volumes/sims the same
"default" not set key ignored, own set Xcode's set
"default" /Volumes/sims key ignored iOS off, invalid-device-set
"Default", "", true, 1 not set key ignored iOS off, invalid-device-set

The operator's and agent's sessions are in #962, How it works for the user.

If this goes wrong, a user would notice Simlock wiping or deleting a simulator of their own or of another Simlock, or iOS staying off after they followed the printed steps.

Technical spec

Facts

At 3de46d1ff unless noted.

# Fact Source
F1 Every scoped simctl call is built by one method, ["simctl", "--set", this.#deviceRoot, ...args]; #invokeSimctl uses it src/drivers/ios/index.ts:1565-1571
F2 The passthrough builds its own argv ["simctl", "--set", this.#deviceRoot, ...args] with env: {} src/drivers/ios/index.ts:1337-1342
F3 runtime delete goes through #scopedSimctlArgv src/drivers/ios/index.ts:545-555
F4 Unscoped calls: findLegacy, destroyLegacy, and #listedImages' simctl list -j devices of the default set src/drivers/ios/index.ts:1084-1113, :634-637, :1573-1584
F5 listManaged lists every device in the scoped set and reads its marks, with no other filter src/drivers/ios/index.ts:1123-1140
F6 provision names a device simlock-<id> (cosmetic) and writes the mark (:741); reclaim writes a fresh mark (:1062) src/drivers/ios/index.ts:726-741, :1062
F7 #writeMark writes { token, udid, writtenAt }, erasable <dir>/data/simlock-mark.json first, then durable <dir>/simlock-mark.json; #readToken reads only token src/drivers/ios/index.ts:1449-1490
F8 The device folder is join(this.#deviceRoot, udid) src/drivers/ios/index.ts:1427-1429
F9 create calls ensureOwnedRoot on configuredDeviceRoot(options); revalidateRoot calls it again src/drivers/ios/index.ts:358-386
F10 A non-string or relative deviceRoot throws OwnedRootError(…, "not-absolute", …, "ios") src/drivers/ios/index.ts:1706-1724
F11 IosSimctlDriverOptions carries instanceId and coreSimulatorRoot; the daemon passes coreSimulatorRoot: ~/Library/Developer/CoreSimulator src/drivers/ios/index.ts:201, :207; src/daemon/main.ts:1368
F12 The daemon catches an iOS OwnedRootError, logs "Skipped iOS driver: device root rejected", and emits driver.root-rejected with { platform, reason, root }; Android starts on src/daemon/main.ts:1404-1409, :1490-1502
F13 RootRejectionReason is a closed union in core, listed in EVENTS.md; the bus payload reason is a string src/core/device-root.ts:10-24; src/bus/index.ts:415-419; docs/internal/EVENTS.md:153
F14 virtualLeaseEnvironment returns { SIMLOCK_IOS_DEVICE_SET: this.#deviceRoot }; a virtual leaseEnvironment returns the same src/drivers/ios/index.ts:1306-1313
F15 The screen capture gets SIMLOCK_IOS_DEVICE_SET: options.deviceSet for a simulator (deviceSet: deviceRoot); the capture program searches the default set when the variable is unset src/drivers/ios/screen-capture.ts:120-124; src/drivers/ios/index.ts:339; vendor/screen-capture/Sources/simlock-screen-capture/FrameCapture.swift:417-441
F16 The agent-device supervisor copies SIMLOCK_IOS_DEVICE_SET to AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET only when present, iOS on, role not phones; the env comes from every driver's virtualLeaseEnvironment src/agent-device/host/agent-device-supervisor.ts:576-581; src/daemon/main.ts:488-490
F17 agent-device with no set runs simctl without --set and xcodebuild with a plain -destination agent-device v0.21.28 packages/platform-apple/src/core/simctl.ts:28-29, packages/platform-apple/src/runner/runner-device-set.ts:24-26, packages/kernel/src/device.ts:346-348
F18 The agent-device front refuses a client --ios-simulator-device-set src/agent-device/front/request-rules.ts:145-151
F19 doctor --purge-orphans destroys devices listManaged reports that have no registry record, after revalidateRoot src/core/doctor.ts:264, :335-356, :393-410
F20 nuke --delete-devices destroys only registry virtual devices it can bring to shutdown src/core/nuke-service.ts:95-150
F21 foreignDevices in component.list counts devices outside Simlock using a runtime; iOS takes it from the default set's list -j devices per runtime src/contract/operations.ts:897-923; src/drivers/ios/index.ts:634-651, :1976-1989
F22 The passthrough refuses create, erase, delete, shutdown all, runtime delete, and any flag before the subcommand src/drivers/ios/index.ts:126-136, :1372-1426
F23 Driver config is opaque to core: drivers.<platform>.* is a string/number/boolean record the driver reads src/core/config.ts:266-269, :1238
F24 A second instance under one OS user is a second SIMLOCK_HOME with its own instanceId; the slow lane runs every daemon from a temp home src/core/AGENTS.md Known gaps; e2e/helpers/env.ts:177-202; scripts/slow-e2e.sh:22-25
F25 Xcode 27.0: xcodebuild build -destination "platform=iOS Simulator,id=<udid>" of a simulator in a custom set fails "Unable to find a device matching the provided destination specifier"; the same with -DVTSimulatorSetLocation=<set> prints ** BUILD SUCCEEDED ** command run on this Mac, 2026-10-23 (ADR 0048 Context)
F26 #147 (PR #960) adds IOS_BUILDS to src/instructions/index.ts ("Simlock's simulators live in a device set of their own…") with required phrases pinned in src/instructions/index.test.ts gh pr diff 960 lines 439-450, 560-564
F27 The slow-lane suite seeds one shared daemon with configOverrides e2e/slow-agent-device.test.ts:136-146
F28 iOS discovery catches only OwnedRootError; any other error from create is rethrown and stops the daemon start src/daemon/main.ts:1399-1402, :414
F29 Core's driver-unavailable doctor finding is not a kind in the wire doctorFindingSchema; doctor.run's handler returns core findings unchanged; a result that fails its output schema becomes INTERNAL src/core/doctor.ts:1137-1143; src/contract/schemas.ts:868-943; src/daemon/dispatcher.ts:812-823; src/daemon/dispatch.ts:191-193
F30 ScriptedProcessRunner throws Unexpected process invocation on a call it was not scripted for src/ports/process-runner.ts:688-695
F31 provision runs simctl create, then #writeMark, with no cleanup if the mark write throws src/drivers/ios/index.ts:731-741
F32 Doctor turns a registry-device-missing device that findLegacy finds into legacy-device, which --fix destroys; a lost durable mark is otherwise report-only durable-mark-missing src/core/doctor.ts:486-519, :830-840, :1115-1129
F33 The start-up write-leftovers sweep reads dirname(deviceRoot) and removes only staging entries named after the root's own basename src/core/write-leftovers.ts:9-34; src/daemon/main.ts:609, :1837-1842
F34 scripts/slow-e2e.sh clean/stop find a run's processes by /tmp/simlock-slow/ in their command line, then delete that folder scripts/slow-e2e.sh:59-95
F35 An instance's id lives in ${SIMLOCK_HOME}/instance.json src/core/instance-identity.ts:13
F36 The screen-capture env spreads the daemon's base environment and only overwrites SIMLOCK_IOS_DEVICE_SET src/drivers/ios/screen-capture.ts:120-124
F37 unusedDevices (the residue sentence after a runtime removal) counts never-booted default-set devices of that runtime src/drivers/ios/index.ts:653-658, :533-541
F38 The website says foreignDevices counts Xcode-set simulators booted at least once website/src/content/docs/docs/worker/runtimes-and-images.mdx:142
F39 The protocol range is { min: 60, max: 60 } src/contract/protocol.ts:13

Values sent elsewhere:

  • driver.root-rejected reason: invalid-device-set, device-set-changed. The bus types it as string (F13), so it passes; RootRejectionReason gains both.
  • root in that payload: for invalid-device-set, the configured deviceSet value as a string (JSON.stringify for a non-string); for device-set-changed, the path of the set that holds the leftovers.
  • The durable and erasable marks gain instanceId (F7, F11). A mark without it reads as no instance.
Modules touched

Searches: rg -n "deviceRoot|--set|SIMLOCK_IOS_DEVICE_SET|RootRejectionReason|#writeMark|#readMark|foreignDevices" src e2e website/src/content/docs docs/internal/EVENTS.md, and rg -n "device set" website/src/content/docs.

  • src/drivers/ios/index.ts: read deviceSet; create validates it and runs the leftover check (files only); under "default": no --set in F1/F2/F3, deviceRoot and the device folders are <coreSimulatorRoot>/Devices (the sweep then looks only for entries named after Devices, which Simlock never makes there, F33), no ensureOwnedRoot, revalidateRoot resolves, listManaged filters by this instance's durable mark, #listedImages counts the rest as foreign and unused, findLegacy answers undefined (so a lost mark stays report-only, F32), a failed mark write in provision deletes the new simulator before rethrowing, no SIMLOCK_IOS_DEVICE_SET in the lease environment. Under both: the marks carry instanceId.
  • src/drivers/ios/screen-capture.ts: when the driver passes no set, remove SIMLOCK_IOS_DEVICE_SET from the spread environment (F36).
  • src/contract/schemas.ts: a driver-unavailable arm (platform, reason, detail) in doctorFindingSchema; src/contract/protocol.ts: this PR bumps the protocol by one (min and max).
  • src/cli/commands/doctor.ts: writes Unavailable [<platform>] <reason>: <detail> to stderr for each driver-unavailable finding, beside the other finding lines; stdout unchanged.
  • scripts/slow-e2e.sh: clean (and stop, which calls it) also deletes, with xcrun simctl delete <udid>, each simulator in ~/Library/Developer/CoreSimulator/Devices whose durable mark names the instanceId of a home under the lane folder, before removing the folder (F34, F35).
  • src/core/device-root.ts: two new RootRejectionReasons.
  • src/drivers/ios/AGENTS.md, src/drivers/AGENTS.md: the --set rule and ownership rule per setting; the new key.
  • docs/internal/EVENTS.md: driver.root-rejected reasons.
  • src/instructions/index.ts, src/instructions/index.test.ts (from #147): the "iOS builds" section for both settings.
  • src/agent-device/host/agent-device-supervisor.test.ts: the absent-key case (no code change, F16).
  • e2e/slow-agent-device.test.ts (and its helper as #957 leaves it): a "default" daemon case.
  • Website: reference/configuration.mdx (the key), worker/cleanup.mdx (roots, the two reasons, "never touches Xcode's set" per setting), using-devices/working-with-a-device.mdx (env table, simctl --set text, refusals, rules), introduction/how-it-works.mdx (Device), worker/runtimes-and-images.mdx (foreignDevices, F38), reference/cli.mdx (SIMLOCK_IOS_DEVICE_SET "iOS simulator under simlock"), new using-devices/build-and-run.mdx and its line in website/astro.config.mjs under "Using devices".
flowchart LR
  main[daemon/main.ts] --> ios["drivers/ios/index.ts (CHANGED)"]
  ios --> root["core/device-root.ts (CHANGED)"]
  ios --> cap["drivers/ios/screen-capture.ts (CHANGED)"]
  main --> sup[agent-device supervisor]
  ios -. lease env .-> sup
  instr["instructions/index.ts (CHANGED)"]
  disp[daemon/dispatcher.ts] --> doc[core doctor]
  disp --> schema["contract/schemas.ts (CHANGED)"]
Contract and event changes

doctorFindingSchema gains the driver-unavailable arm core already produces (F29): platform (a platform), reason (a string, at most 64 characters), detail (a string). This PR bumps the protocol by one. driver.root-rejected itself is not a contract shape (rg "root-rejected" src/contract finds nothing; the bus payload reason is a string, F13). driver.root-rejected gains reasons invalid-device-set and device-set-changed: docs/internal/EVENTS.md:153 lists them.

New config field drivers.ios.deviceSet: a string, exactly "simlock" or "default" (case-sensitive); absent means "simlock". Anything else gets invalid-device-set. New mark field instanceId: the instance's id string as written; read as absent when missing or not a non-empty string.

Other code on the same state

Searches: the set path (rg -n "deviceRoot|--set" src, 41 hits), the marks (rg -n "simlock-mark|readMark|provenanceDrift" src, 14 hits), the default set (rg -n "legacySimctl|CoreSimulator" src, 9 hits).

  • Lease health monitor (src/leasing/lease-health-monitor.ts:176, :386-404): reads listManaged and the marks. Under "default" it sees only this instance's devices; drift reads as today, since durable/erasable tokens are unchanged.
  • Doctor (src/core/doctor.ts:264, :1115-1124): orphans and provenance from listManaged; under "default" only this instance's devices, so another instance's or the user's never become orphans.
  • Startup read (src/core/startup-read.ts:64): one listManaged per driver; same filter.
  • findLegacy / destroyLegacy (F4): unscoped already; under "default" the same set. Only registry records reach them.
  • Another Simlock instance under "default" in the same Xcode set: each lists only its own marks, so neither sees the other's devices. Its simctl writes touch only UDIDs its own registry names.
  • #958 (device.exec fill-in): changes the same passthrough method. T1 builds on it: the argv rule here applies to the argv #958 builds.
Failure modes
Call Outcome What happens Limit, counted from
leftover check under "default": read Simlock's own root folder UUID-named entries device-set-changed, iOS off none (file reads)
same none, or no folder iOS starts same
same unreadable (not ENOENT) OwnedRootError reason unreadable, iOS off; never a daemon-fatal error (F28) same
leftover check under "simlock": read <coreSimulatorRoot>/Devices/*/simlock-mark.json (skipped when no coreSimulatorRoot is given, as in the test helper) a mark naming this instance device-set-changed, iOS off same
same no folder; only unmarked or other-instance marks; a mark file unreadable or corrupt (skipped) iOS starts same
same the folder unreadable (not ENOENT) OwnedRootError reason unreadable, iOS off same
#writeMark in provision under "default" throws simctl delete <udid> (best effort), then the error is rethrown 30 s for the delete, from spawn
mark read under "default" listManaged unreadable, corrupt device not listed (no instance proven) none (file read)

State: the marks gain a field, written atomically as today. A restart between simctl create and the durable mark under "default" leaves one unlisted simlock-<id> simulator in Xcode's set; it is rare, no test, and ios/AGENTS.md Known gaps names it with its fix (xcrun simctl delete <udid>). No new shared state.

Rules in play
  • ADR 0048 §1–5: the key, ownership by instance mark, refusal on a change, no set in any env, refusals kept.
  • ADR 0001 §6, "Orphans are reported, never automatically destroyed": kept; only the orphan rule's input is filtered.
  • Safety: "Simlock destroys only what its registry owns" (docs/internal/ARCHITECTURE.md:112-113): listManaged never offers a device this instance did not mark.
  • Drivers rule 1, "A refusal (OwnedRootError) skips that platform only": both new refusals are OwnedRootErrors.
  • Drivers rule 3, "drivers.<platform>.* are carried unread": core does not validate the key (F23).
  • Documentation rule 9: every page above changes in this PR.
  • Contract manual, "Every change to a contract shape bumps it by one in the same PR": the driver-unavailable arm bumps the protocol by one.
Tests

Seam: IosSimctlDriver (src/drivers/ios/index.test.ts, with ScriptedProcessRunner and MemoryFilesystem), plus agent-device-supervisor.test.ts, src/instructions/index.test.ts and the slow lane. Model on "refuses the platform, not the daemon, when the configured device root is not a path" (index.test.ts:1537) and "reports every device in its set, whatever the device is named" (:1335). Unset key = today: the leftover check reads only files, which the existing tests' MemoryFilesystem does not hold, so no existing test gets a new process call (F30), and the existing suite proves it unchanged.

  • The driver given deviceSet runs every simctl call with or without --set: cases key unset and "simlock" (--set <root> on create, boot, erase, delete, list, runtime delete); "default" (none of them carries --set).
  • An operator with a bad value or a conflicting deviceRoot gets OwnedRootError reason invalid-device-set with the message above: cases "Default", "", true, "default" with deviceRoot set.
  • An operator who switches with leftovers gets device-set-changed: cases "default" with two devices in Simlock's set (refused, message names both UDIDs and xcrun simctl --set <root> delete <udid>); "default" with the set empty, and with no root folder (starts); "simlock" with a device in Xcode's set marked by this instance (refused, xcrun simctl delete <udid>); "simlock" with only unmarked and other-instance devices there (starts); an unreadable folder (unreadable); no case runs a process.
  • A new or reclaimed simulator's marks name this instance: cases "simlock", "default"; both mark files carry instanceId. Under "default", a mark write that fails in provision runs simctl delete <udid> and rethrows.
  • Under "default", listManaged reports only devices whose durable mark names this instance: cases this instance's mark (listed); erasable mark gone (listed, erasable undefined); no mark; a mark with no instanceId; another instance's mark; unmarked named simlock-1 (none of these four listed); findLegacy of a registered UDID answers undefined under "default".
  • Under "default", listComponents foreignDevices and the removal's unused count take only devices this instance's mark does not name: three used devices on one runtime (this instance's, unmarked, another instance's) → foreignDevices 2; three never-used ones → unused count 2.
  • A lease holder and the screen capture get the set only under "simlock": cases "simlock" ({ SIMLOCK_IOS_DEVICE_SET: <root> }, capture env has it); "default" ({}, capture env lacks it, also when the daemon's own environment had it); a physical device under both (SIMLOCK_DEVICE_UDID only).
  • simlock simctl under "default" runs plain xcrun simctl and keeps its refusals: cases install <udid> app.app (argv ["simctl","install",…], no --set); erase <udid>, shutdown all, --set /tmp list (refused as today).
  • The agent-device simulator daemon gets no AGENT_DEVICE_IOS_SIMULATOR_DEVICE_SET when the lease env lacks SIMLOCK_IOS_DEVICE_SET and iOS is on (extends "passes every key and value of the drivers' environment unchanged", agent-device-supervisor.test.ts:627).
  • simlock instructions' "iOS builds" section names the route per grant: required phrases SIMLOCK_IOS_DEVICE_SET, -DVTSimulatorSetLocation, Xcode 27, generic/platform=iOS Simulator, xcodebuild -destination id=<udid>.
  • An operator running simlock doctor while iOS is refused gets a driver-unavailable finding with its reason and detail, not INTERNAL (src/daemon/dispatcher.test.ts, extends "doctor.run forwards purgeOrphans…" at :915): cases invalid-device-set, device-set-changed; and simlock doctor writes Unavailable [ios] <reason>: <detail> on stderr with stdout unchanged (src/cli/index.test.ts, modelled on :2364).
  • Slow lane, e2e/slow-agent-device.test.ts: under a daemon with drivers.ios.deviceSet: "default", an agent opens an iOS device, plain xcrun simctl list devices (no --set) lists its UDID, and snapshot answers; teardown runs simlock nuke --delete-devices --yes so no simulator is left in Xcode's set.
  • The "Build and run your app" page's switch steps tell an operator with a custom drivers.ios.deviceRoot to keep it set while running simlock nuke --delete-devices and simlock doctor --purge-orphans, and to remove it only when switching to "default" (checked by the Done when docs review; decided in delivery, pending the maintainer).

Done when

  • pnpm test:changed passes, with the Tests lines above.
  • pnpm --dir website install && pnpm --dir website build && node website/scripts/check-openapi.mjs passes.
  • In each page listed under Modules touched, every iOS hit of rg -n "simctl --set|device set|deviceRoot|SIMLOCK_IOS_DEVICE_SET|foreignDevices" website/src/content/docs says which setting it holds for; website/src/content/docs/docs/using-devices/build-and-run.mdx exists and is in the sidebar under "Using devices".
  • docs/internal/EVENTS.md lists invalid-device-set and device-set-changed.
  • Slow lane (real simulator): scripts/slow-e2e.sh e2e/slow-agent-device.test.ts passes the "default" case.
  • Slow lane: start that case, run scripts/slow-e2e.sh stop while it runs, then xcrun simctl list devices shows no simulator whose durable mark names a lane instance.

Out of scope

  • Flipping the default (ADR 0048 §6).
  • Scoping simlock simctl to the lease's device (#948).
  • Moving devices between sets.
  • Android and physical devices.

Depends on

  • #958
  • #147
  • #957
  • #966 (both bump the protocol)

Written by an agent.

主要语言
TypeScript
星标
22
派生
2
平均合并
9 小时 19 分钟
30 天内合并 PR
430

环境准备

这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

callstackincubator/simlock 的其他 Issue

查看 callstackincubator/simlock 的全部 Issue

相似的 Issue

更多 TypeScript Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。