stim 1.16.0 → 1.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/dist/{activity-BxwdD81S.mjs → activity-IRvJY_ru.mjs} +23 -3
  2. package/dist/{agent-device-usage-output-Dpih1Tfa.mjs → agent-device-usage-output-BK41vnzN.mjs} +3 -3
  3. package/dist/{android-Ift4kVvt.mjs → android--GorydsK.mjs} +679 -317
  4. package/dist/{android-B_NumVyQ.mjs → android-B_YNZy61.mjs} +7 -43
  5. package/dist/{android-r2rBL8kV.mjs → android-DE4v59Mb.mjs} +12 -3
  6. package/dist/{android-cas-8U4DPqeR.mjs → android-cas-ZFpjJBL_.mjs} +6 -5
  7. package/dist/{app-install-CKWdbXIX.mjs → app-install-VPkI5WEg.mjs} +6 -5
  8. package/dist/{budget-DjrURfQn.mjs → budget-DM984mnd.mjs} +34 -18
  9. package/dist/{build-plan-DjeSb2Xl.mjs → build-plan-CmQCoyT-.mjs} +345 -86
  10. package/dist/{build-slots-rUk77xqh.mjs → build-slots-41v_d2x9.mjs} +35 -25
  11. package/dist/{cli-BkYZ_6hy.mjs → cli-Daxug5-K.mjs} +17 -17
  12. package/dist/cli.mjs +1 -1
  13. package/dist/collector-run.mjs +3 -3
  14. package/dist/{command-output-DnJMdEY-.mjs → command-output-CDAIFD-8.mjs} +3 -3
  15. package/dist/{created-devices-D5owjN4C.mjs → created-devices-CpvzBL25.mjs} +1 -1
  16. package/dist/{dependency-state-B6cMXZab.mjs → dependency-state-CLcBHH2M.mjs} +1 -1
  17. package/dist/{deps-urbmfXig.mjs → deps-DNWaQs4V.mjs} +1 -1
  18. package/dist/{dev-client-CroAIjjj.mjs → dev-client-B-XC4uRH.mjs} +2 -2
  19. package/dist/{device-DZQjF7H5.mjs → device-C8IOoJPv.mjs} +7 -7
  20. package/dist/device-capacity-D0GWHnTM.mjs +580 -0
  21. package/dist/device-host-worker.mjs +436 -154
  22. package/dist/{device-ios-BadmeL2V.mjs → device-ios-Bc7vbGwl.mjs} +75 -44
  23. package/dist/{device-lease-D-hLqx1b.mjs → device-lease-DpoS36_u.mjs} +2 -2
  24. package/dist/{device-lease-run-CqjShqWW.mjs → device-lease-run-B8YltIH_.mjs} +3 -3
  25. package/dist/{device-pool-CUaEWMMm.mjs → device-pool-3o7s5lo4.mjs} +2 -2
  26. package/dist/{device-remote-D5WVWqOq.mjs → device-remote-hFSkpfQu.mjs} +12 -12
  27. package/dist/{doctor-Cimf-gGB.mjs → doctor-Cnk9d7Hm.mjs} +32 -51
  28. package/dist/{error-diagnostics-B9L4Ae0x.mjs → error-diagnostics-C-NMnhrk.mjs} +7 -7
  29. package/dist/{gc-Bqy4bjEu.mjs → gc-DxCL2A46.mjs} +308 -26
  30. package/dist/{gradle-BsO1MdsH.mjs → gradle-D7-L2Th3.mjs} +3 -3
  31. package/dist/{guide-B_uyKTxW.mjs → guide-DjrTQGik.mjs} +1662 -565
  32. package/dist/{guide-status-CjEZMAD4.mjs → guide-status-Du-ZQ3FD.mjs} +1 -1
  33. package/dist/hosted-android-DwLS4Mse.mjs +32 -0
  34. package/dist/{hosted-client-a-WmqE2L.mjs → hosted-client-wk1W_CNW.mjs} +2 -3
  35. package/dist/hosted-ios-aMo7Cljf.mjs +15 -0
  36. package/dist/{hosted-logs-D5g041Q3.mjs → hosted-logs-DqYmWtXc.mjs} +16 -16
  37. package/dist/{hosted-macos-BSZyIb3y.mjs → hosted-macos-dlHXEeF5.mjs} +4 -4
  38. package/dist/{hosted-ios-CIWelIqf.mjs → hosted-native-C9xJ9rpA.mjs} +77 -42
  39. package/dist/{idle-DYVymG92.mjs → idle-B2m-Ovod.mjs} +122 -58
  40. package/dist/{idle-shutdown-CTsDnAde.mjs → idle-shutdown-_3oOV1V_.mjs} +25 -17
  41. package/dist/{in-use-DvBw0Kxo.mjs → in-use-CvGOUn-x.mjs} +11 -11
  42. package/dist/{ios-aq3QoGI3.mjs → ios-DE6duQoz.mjs} +170 -88
  43. package/dist/{ios-BaInn3sW.mjs → ios-DSfnPfse.mjs} +4 -4
  44. package/dist/{ios-device-FfCN_C8p.mjs → ios-device-pAN4t54-.mjs} +1 -1
  45. package/dist/ios-state-8L3lgum6.mjs +89 -0
  46. package/dist/{launch-verify-2DBRizjo.mjs → launch-verify-lTnWZikR.mjs} +2 -2
  47. package/dist/{logs-CHEVK8zD.mjs → logs-DUoKlDoS.mjs} +36 -23
  48. package/dist/{client-BTY686R6.mjs → machines-C2XiNwh9.mjs} +278 -20
  49. package/dist/{macos-CSYEAFmF.mjs → macos-32po3kUq.mjs} +14 -14
  50. package/dist/macos-run.mjs +1 -1
  51. package/dist/maintenance-run.mjs +2 -2
  52. package/dist/{metro-BeK1ZPz1.mjs → metro-g8NqiJp-.mjs} +1 -1
  53. package/dist/{metro-gateway-BJ-rxQAB.mjs → metro-gateway-DmslUM30.mjs} +22 -3
  54. package/dist/{named-ports-Bk_YXEmE.mjs → named-ports-C8m8EQs2.mjs} +2 -2
  55. package/dist/{native-run-NaBrRFtQ.mjs → native-run-D1Q56rAD.mjs} +17 -6
  56. package/dist/{native-runtime-DBzRnEKS.mjs → native-runtime-DhJI3IVQ.mjs} +6 -6
  57. package/dist/offload-worker.mjs +8 -8
  58. package/dist/{teardown-CL6vDs2Y.mjs → ownership-BMLqyBgJ.mjs} +603 -26
  59. package/dist/{ownership-DiA16AsN.mjs → ownership-DyRQru0q.mjs} +2 -2
  60. package/dist/{ports-R2k4Knz3.mjs → ports-4nYqxPWC.mjs} +2 -2
  61. package/dist/{prebuild-D2fsca_Z.mjs → prebuild-D7RUMkwN.mjs} +3 -3
  62. package/dist/{preview-DhVbvPAZ.mjs → preview-CxPRIEht.mjs} +7 -7
  63. package/dist/{project-Du91Ilvc.mjs → project-D47Rh0ly.mjs} +7 -2
  64. package/dist/{recordings-BIXOzVnr.mjs → recordings-BNgsD1Tr.mjs} +1 -1
  65. package/dist/{reload-rM9jV1fz.mjs → reload-qZei6iWn.mjs} +62 -35
  66. package/dist/{remote-cache-C8-V13XN.mjs → remote-cache-Ci4DQYYj.mjs} +3 -3
  67. package/dist/{run-f4vI6EnK.mjs → run-CkE9y0nc.mjs} +1 -1
  68. package/dist/{server-bare-CpPGmnmO.mjs → server-bare-BkrSxSsZ.mjs} +1 -1
  69. package/dist/{server-expo-MC0rHlOC.mjs → server-expo-CHTyXD0G.mjs} +2 -2
  70. package/dist/server-expo-CeakhI8P.mjs +2 -0
  71. package/dist/{settings-oTSkkNrM.mjs → settings-Cfd-0r2d.mjs} +10 -9
  72. package/dist/{settings-ZkDzkzvB.mjs → settings-SR9OmW9h.mjs} +3 -3
  73. package/dist/settings.schema.json +42 -13
  74. package/dist/{simslim-B8-7AoTI.mjs → simslim-BWNrc3M3.mjs} +3 -3
  75. package/dist/{slot-launch-B8VrHxn1.mjs → slot-launch-DmjBmpQV.mjs} +8 -8
  76. package/dist/{start-CX8Ig-U2.mjs → start-BopZcr4n.mjs} +1 -1
  77. package/dist/{start-ClDfwXa4.mjs → start-uee1wWjY.mjs} +11 -11
  78. package/dist/{state-DcW6vOd_.mjs → state-BKa8wNN5.mjs} +1 -1
  79. package/dist/{state-3DwSQIBK.mjs → state-DyaNTgfR.mjs} +1 -1
  80. package/dist/{state-C1jB7Q8q.mjs → state-PeQiJuIu.mjs} +2 -2
  81. package/dist/{stats-CEZ_i5je.mjs → stats-Bq4fJOdB.mjs} +7 -4
  82. package/dist/{status-BuvBFeII.mjs → status-CzS4bPO9.mjs} +4 -4
  83. package/dist/{status-Cs7VLg9D.mjs → status-dXX2JX1C.mjs} +125 -35
  84. package/dist/{stop-Dt_dM16A.mjs → stop-BCwvvs7F.mjs} +2 -2
  85. package/dist/{stop-Bffozsac.mjs → stop-BjizrQwv.mjs} +48 -27
  86. package/dist/{stop-B0Yxtmiy.mjs → stop-Cr1d8DSE.mjs} +4 -4
  87. package/dist/{stop-cause-CidxIqup.mjs → stop-cause-rhmGfwvt.mjs} +1 -1
  88. package/dist/supervisor-run.d.mts +7 -4
  89. package/dist/supervisor-run.mjs +26 -28
  90. package/dist/{support-D4aYJniO.mjs → support-BJPgYCu-.mjs} +44 -19
  91. package/dist/{support-CAP8qDUF.mjs → support-F9-sr0Oi.mjs} +6 -6
  92. package/dist/{toolchain-DkUflduf.mjs → toolchain-CNIBTIOv.mjs} +7 -7
  93. package/dist/{warm-progress-CpGv3Wb6.mjs → warm-progress-DF4JRvYI.mjs} +3 -3
  94. package/dist/watchman-APYjXSQa.mjs +48 -0
  95. package/dist/{web-DWUaMp8P.mjs → web-exQtGkoc.mjs} +12 -13
  96. package/dist/web-run.mjs +4 -4
  97. package/dist/{workspace-process-lock-BL7Q0HCO.mjs → workspace-process-lock-2mNzOlaB.mjs} +3 -2
  98. package/dist/{workspace-state-B8-aJ1_5.mjs → workspace-state-DqcCbpE7.mjs} +2 -2
  99. package/dist/{workspaces-BV4pdHFz.mjs → workspaces-Bcib97-6.mjs} +3 -3
  100. package/dist/{worktree-jnG8Iph5.mjs → worktree-Dc98cE6_.mjs} +1 -1
  101. package/dist/{worktree-K-xj9Db0.mjs → worktree-ZpZR3S1k.mjs} +141 -40
  102. package/package.json +5 -5
  103. package/dist/device-capacity-BHwxNBlu.mjs +0 -136
  104. package/dist/ios-state-DS5UpYTH.mjs +0 -48
  105. package/dist/machines-BIBUdhpj.mjs +0 -265
  106. package/dist/ownership-hCkPzGmr.mjs +0 -571
  107. package/dist/server-expo-CVqO2c35.mjs +0 -2
@@ -1,52 +1,53 @@
1
1
  import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
2
  import { E as upsertProject, L as deviceSlotFileKey, R as deviceSlotKey, V as parseDeviceSlotOption, W as validateDeviceSlot, p as getProject, u as getConcurrencyLimits, v as recordIosSchemeApprovals, z as deviceSlotPlatforms } from "./config-D0DbpZtM.mjs";
3
3
  import { n as ownership_claim_exports } from "./process-identity-BmRm1qV0.mjs";
4
- import { _ as stepTimer, c as launchErrorReport, g as stepClock, h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-DnJMdEY-.mjs";
5
- import { B as settingsLayers, E as parseIosRemote, G as detectProviders, H as unknownSettingKeys, J as artifactCachePolicy, L as settingOriginScope, M as remoteIosSetting, N as resolveCacheProviderConfig, P as resolveSettings, R as settingShapeErrors, S as metroPortSetting, Tt as removeTemporaryEntry, V as tunnelModeSetting, X as optimizationBuildProfile, Z as resolveOptimizations, _ as iosSigningIdentitySha1Setting, a as SETTING_SHAPE_REMEDY, d as cacheProviderSettingError, g as iosSigningIdentitySettingError, gt as repoRoot, h as iosSigningIdentitySetting, it as gitCommonDir, k as publicUrlSetting, m as iosLanHostSettingError, p as iosLanHostSetting, v as iosSigningIdentitySha1SettingError, w as metroWarmupUrlSetting, wt as makeTemporaryDirectory } from "./settings-oTSkkNrM.mjs";
6
- import { n as appProjectProblem, o as findProjectRoot$1, r as detectIsExpo, t as NO_PROJECT_REFUSAL } from "./project-Du91Ilvc.mjs";
7
- import { l as resolveProjectMetro, o as pidExists, u as signalProcessTree } from "./metro-BeK1ZPz1.mjs";
8
- import { c as writeWorkspaceState, g as workspaceAgentDeviceDir, i as recordWorkspaceUse, r as readWorkspaceState$1, v as workspaceDir, x as workspaceLogsDir$1 } from "./workspace-state-B8-aJ1_5.mjs";
9
- import { t as budgetGate } from "./budget-DjrURfQn.mjs";
10
- import { A as providerDownloadPath, D as fingerprintProject, E as fingerprintDiffRecord, L as untrackedMissLine, M as refingerprintAfterMutation, N as resolveBuild, O as inputsChangedDuringBuild, P as storeBuild, R as untrackedNativeFiles, S as configInputsChanged, T as filesystemBuildCapability, _ as waitForBuild, b as buildCacheKey, g as releaseBuildLock, j as providerUploadOutcome, k as prepareProviderDownloadDir, m as acquireBuildLock, v as waitForSharedBuild, x as changedDuringBuildLine } from "./device-lease-D-hLqx1b.mjs";
11
- import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-rUk77xqh.mjs";
12
- import { m as writeWorkspaceLaunch, n as MODE_EXPO, t as MODE_BARE } from "./state-DcW6vOd_.mjs";
13
- import { S as statsProjectKey$1, _ as tapBuildLog, g as startBuildProgress, h as recordFinishedBuild, l as NO_BUILD_PROGRESS, v as createRunRecorder, x as recordRunStats, y as readRunEstimates } from "./idle-DYVymG92.mjs";
14
- import { ft as parkedMaxSetting, ot as POOL_SETTING_REMEDY } from "./android-B_NumVyQ.mjs";
15
- import { p as listIosRuntimes, r as clearIosAppData, u as listAllIosSims } from "./ios-BaInn3sW.mjs";
4
+ import { _ as stepTimer, c as launchErrorReport, g as stepClock, h as shortUdid, i as formatDuration, l as phaseLine, m as shortHash, n as appReadinessMessage, v as launchErrorPreview } from "./command-output-CDAIFD-8.mjs";
5
+ import { B as settingsLayers, C as metroWarmupUrlSetting, G as detectProviders, H as unknownSettingKeys, J as artifactCachePolicy, L as settingOriginScope, M as remoteIosSetting, N as resolveCacheProviderConfig, P as resolveSettings, R as settingShapeErrors, T as parseIosRemote, Tt as removeTemporaryEntry, V as tunnelModeSetting, X as optimizationBuildProfile, Z as resolveOptimizations, _ as iosSigningIdentitySha1SettingError, f as iosLanHostSetting, g as iosSigningIdentitySha1Setting, gt as repoRoot, h as iosSigningIdentitySettingError, i as SETTING_SHAPE_REMEDY, it as gitCommonDir, k as publicUrlSetting, m as iosSigningIdentitySetting, p as iosLanHostSettingError, u as cacheProviderSettingError, wt as makeTemporaryDirectory, x as metroPortSetting } from "./settings-Cfd-0r2d.mjs";
6
+ import { n as appProjectProblem, r as detectIsExpo, s as findProjectRoot$1, t as NO_PROJECT_REFUSAL } from "./project-D47Rh0ly.mjs";
7
+ import { l as resolveProjectMetro, o as pidExists, u as signalProcessTree } from "./metro-g8NqiJp-.mjs";
8
+ import { c as writeWorkspaceState, g as workspaceAgentDeviceDir, i as recordWorkspaceUse, r as readWorkspaceState$1, v as workspaceDir, x as workspaceLogsDir$1 } from "./workspace-state-DqcCbpE7.mjs";
9
+ import { t as budgetGate } from "./budget-DM984mnd.mjs";
10
+ import { A as providerDownloadPath, D as fingerprintProject, E as fingerprintDiffRecord, L as untrackedMissLine, M as refingerprintAfterMutation, N as resolveBuild, O as inputsChangedDuringBuild, P as storeBuild, R as untrackedNativeFiles, S as configInputsChanged, T as filesystemBuildCapability, _ as waitForBuild, b as buildCacheKey, g as releaseBuildLock, j as providerUploadOutcome, k as prepareProviderDownloadDir, m as acquireBuildLock, v as waitForSharedBuild, x as changedDuringBuildLine } from "./device-lease-DpoS36_u.mjs";
11
+ import { r as releaseBuildSlot, t as acquireBuildSlot } from "./build-slots-41v_d2x9.mjs";
12
+ import { m as writeWorkspaceLaunch, n as MODE_EXPO, t as MODE_BARE } from "./state-BKa8wNN5.mjs";
13
+ import { ft as parkedMaxSetting, ot as POOL_SETTING_REMEDY } from "./android-B_YNZy61.mjs";
14
+ import { p as listIosRuntimes, r as clearIosAppData, u as listAllIosSims } from "./ios-DSfnPfse.mjs";
16
15
  import { a as workspaceLinks, i as workspaceLinkLine } from "./stim-desktop-Cnz8CPnl.mjs";
16
+ import { C as recordRunStats, _ as tapBuildLog, g as startBuildProgress, h as recordFinishedBuild, l as NO_BUILD_PROGRESS, v as createRunRecorder, w as statsProjectKey$1, x as recordCapacityRefusal, y as readRunEstimates } from "./idle-B2m-Ovod.mjs";
17
17
  import { r as createNdjsonWriter } from "./ndjson-PclOIwVY.mjs";
18
- import { S as bundlerPin, _ as readBundleId, c as COMPILATION_CACHE_NOT_RUN, d as buildIos, g as readBundleExecutable, h as discoverXcodeProject, p as compilationCacheActivityLine, r as iosToolchain, v as resolveScheme } from "./toolchain-DkUflduf.mjs";
19
- import { a as offloadBuild, c as placementLoad, d as OffloadRefusal, f as namedBuildMachine, i as closeOffload, l as remotePhaseText, m as resolveBuildPlacement, n as buildPlacementCandidates, p as parseBuildMachineOption, r as chooseBuildMachine, s as offloadPlacement, u as simulatorRuntime } from "./client-BTY686R6.mjs";
20
- import { n as verifyCollectorOwnership } from "./ownership-DiA16AsN.mjs";
21
- import { C as pickDevClientScheme, S as restartedAppNote, T as schemesFromInfoPlist, _ as installIosApp, a as IOS_DEV_MENU_OFF_DEFAULTS_PLIST, d as devClientUrl, l as clearOtherUserApps, r as DEFAULT_METRO_PORT, v as iosAppProcess, x as launchIosApp } from "./app-install-CKWdbXIX.mjs";
22
- import { t as checkDeviceCapacity } from "./device-capacity-BHwxNBlu.mjs";
23
- import { n as devClientTakesDevMenuParams, t as devClientScheme } from "./dev-client-CroAIjjj.mjs";
18
+ import { S as bundlerPin, _ as readBundleId, c as COMPILATION_CACHE_NOT_RUN, d as buildIos, g as readBundleExecutable, h as discoverXcodeProject, p as compilationCacheActivityLine, r as iosToolchain, v as resolveScheme } from "./toolchain-CNIBTIOv.mjs";
19
+ import { _ as resolveBuildPlacement, a as chooseBuildMachine, d as remotePhaseText, f as simulatorRuntime, h as parseBuildMachineOption, i as buildPlacementCandidates, l as offloadPlacement, m as namedBuildMachine, o as closeOffload, p as OffloadRefusal, s as offloadBuild, u as placementLoad } from "./machines-C2XiNwh9.mjs";
20
+ import { r as hostedMetroSettings } from "./metro-gateway-DmslUM30.mjs";
21
+ import { n as verifyCollectorOwnership } from "./ownership-DyRQru0q.mjs";
22
+ import { r as checkDeviceCapacity } from "./device-capacity-D0GWHnTM.mjs";
23
+ import { D as schemesFromInfoPlist, S as restartedAppNote, T as pickDevClientScheme, _ as installIosApp, a as IOS_DEV_MENU_OFF_DEFAULTS_PLIST, d as devClientUrl, l as clearOtherUserApps, r as DEFAULT_METRO_PORT, v as iosAppProcess, x as launchIosApp } from "./app-install-VPkI5WEg.mjs";
24
+ import { n as devClientTakesDevMenuParams, t as devClientScheme } from "./dev-client-B-XC4uRH.mjs";
24
25
  import { t as spawnEntry } from "./spawn-entry-jw19m8Nl.mjs";
25
- import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-urbmfXig.mjs";
26
- import { i as staleNativeDirRefusal, n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-D2fsca_Z.mjs";
27
- import { c as readMetroRecords, f as verifyLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unattributedLaunchLines, n as LAUNCH_FATAL, o as isBundleProof, p as verifyReleaseLaunch, r as LAUNCH_UNVERIFIED, s as readCollectorRecords, t as LAUNCH_BUNDLING, u as unverifiedLaunchLines } from "./launch-verify-2DBRizjo.mjs";
28
- import { a as acquireRunLease, c as lostRefusal, d as runLease, f as waitFlagConflict, o as leaseExpiryText, s as lostLine, t as DEBUG_VERIFY_STEP_MS, u as releaseLeaseOnSignal } from "./device-lease-run-CqjShqWW.mjs";
29
- import { n as clearIosAdoptionPending } from "./device-ios-BadmeL2V.mjs";
30
- import { _ as simulatorBuildArch, a as deviceShortName, c as isReleaseConfiguration, d as printDiagnostics, f as resolveConfiguration, g as resolveSimulatorAppFlag, h as resolveRuntime, i as deviceModelRefusal, l as ownedSimFailure, m as resolveIosWait, n as buildLogFile, o as iosConfigurationSetting, p as resolveDeviceType, r as deviceLabel, s as iosProviderRunOptions, t as appNameFromPath, u as podAction, v as xcodeFailureReport } from "./support-D4aYJniO.mjs";
31
- import { a as easAuthNote, c as loadProjectProvider, f as resolveEasCliBin, i as checkEasAuth, m as uploadRemote, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as resolveRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-C8-V13XN.mjs";
32
- import { O as readRemoteSimulatorArch, a as ensureMetroReachable, k as gateMetroOrigin, l as remoteIosDeps, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, u as resolveRemoteContext, w as ownedSessionName } from "./device-remote-D5WVWqOq.mjs";
33
- import { d as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-NaBrRFtQ.mjs";
34
- import { a as isEasBuildFailure, i as easDeviceBuildRemedy, o as planEasDevelopmentBuild, s as resolveEasDevelopmentBuild } from "./simslim-B8-7AoTI.mjs";
35
- import { c as startDevServer, h as detectBundleId } from "./start-ClDfwXa4.mjs";
36
- import { a as refusePlan, c as skippedMissReason, f as swapJsBundle, h as ensureOwnedDevice, i as printPlan, m as ensureBooted, n as planFlagRefusal, o as explainBuildMiss, p as didSetUpDevice, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, v as warmMetro } from "./build-plan-DjeSb2Xl.mjs";
37
- import { a as sleep, i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-DBzRnEKS.mjs";
38
- import { t as selectFromPool } from "./device-pool-CUaEWMMm.mjs";
39
- import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-B8VrHxn1.mjs";
40
- import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-B9L4Ae0x.mjs";
41
- import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, i as iosDeviceProcess, l as listIosDevices, n as installIosDeviceApp, o as iosPoolNoCandidatesRefusal, p as verifyIosDeviceReleaseLaunch, r as iosDeviceBounds, t as awaitIosDeviceLaunch, u as localNetworkPending } from "./ios-device-FfCN_C8p.mjs";
42
- import { n as writeHostedIos, t as readHostedIos } from "./ios-state-DS5UpYTH.mjs";
43
- import { n as prepareHostedIos, t as placeHostedIos } from "./hosted-ios-CIWelIqf.mjs";
26
+ import { a as runPodInstall, n as podsAreStale, r as readPodState } from "./deps-DNWaQs4V.mjs";
27
+ import { i as staleNativeDirRefusal, n as recordPrebuild, r as runPrebuild, t as planPrebuild } from "./prebuild-D7RUMkwN.mjs";
28
+ import { c as readMetroRecords, f as verifyLaunch, i as RELEASE_VERIFY_WAIT_MS, l as unattributedLaunchLines, n as LAUNCH_FATAL, o as isBundleProof, p as verifyReleaseLaunch, r as LAUNCH_UNVERIFIED, s as readCollectorRecords, t as LAUNCH_BUNDLING, u as unverifiedLaunchLines } from "./launch-verify-lTnWZikR.mjs";
29
+ import { a as acquireRunLease, c as lostRefusal, d as runLease, f as waitFlagConflict, o as leaseExpiryText, s as lostLine, t as DEBUG_VERIFY_STEP_MS, u as releaseLeaseOnSignal } from "./device-lease-run-B8YltIH_.mjs";
30
+ import { n as clearIosAdoptionPending } from "./device-ios-Bc7vbGwl.mjs";
31
+ import { _ as resolveSimulatorAppFlag, a as deviceModelRefusal, c as iosProviderRunOptions, d as podAction, f as printDiagnostics, g as resolveRuntime, h as resolveIosWait, i as deviceLabel, l as isReleaseConfiguration, m as resolveDeviceType, n as buildLogFile, o as deviceShortName, p as resolveConfiguration, r as createIosDeviceWaitRun, s as iosConfigurationSetting, t as appNameFromPath, u as ownedSimFailure, v as simulatorBuildArch, y as xcodeFailureReport } from "./support-BJPgYCu-.mjs";
32
+ import { i as writeDevicePlacement, n as readHostedIos, o as writeHostedIos } from "./ios-state-8L3lgum6.mjs";
33
+ import { a as refusePlan, b as devicePlacementLine, c as skippedMissReason, f as swapJsBundle, h as ensureOwnedDevice, i as printPlan, m as ensureBooted, n as planFlagRefusal, o as explainBuildMiss, p as didSetUpDevice, r as planPayload, s as fingerprintErrorMissReason, t as planCachedBuild, v as warmMetro, y as automaticDevicePlacement } from "./build-plan-CmQCoyT-.mjs";
34
+ import { n as nativeRunCommand, r as siblingPlatformSlots, t as launchSlotScope } from "./slot-launch-DmjBmpQV.mjs";
35
+ import { a as easAuthNote, c as loadProjectProvider, f as resolveEasCliBin, i as checkEasAuth, m as uploadRemote, n as UPLOAD_TIMEOUT_MS, o as exitAfterFlush, p as resolveRemote, r as cacheLevel, s as isEasAuthFailureText, t as RESOLVE_TIMEOUT_MS } from "./remote-cache-Ci4DQYYj.mjs";
36
+ import { O as readRemoteSimulatorArch, a as ensureMetroReachable, k as gateMetroOrigin, l as remoteIosDeps, n as binOnPath, o as ensureRemoteBootOwned, r as bundleEntryPoint, u as resolveRemoteContext, w as ownedSessionName } from "./device-remote-hFSkpfQu.mjs";
37
+ import { d as runCancellationSignal, f as withNativeBuildRun, r as cancelledFailure, u as runCancellation } from "./native-run-D1Q56rAD.mjs";
38
+ import { a as isEasBuildFailure, i as easDeviceBuildRemedy, o as planEasDevelopmentBuild, s as resolveEasDevelopmentBuild } from "./simslim-BWNrc3M3.mjs";
39
+ import { c as startDevServer, h as detectBundleId } from "./start-uee1wWjY.mjs";
40
+ import { a as sleep, i as launchOutcomeRecord, n as ensureWorkspaceStorageSafely, r as isPhysicalDeviceRequest, t as ensureDevServer } from "./native-runtime-DhJI3IVQ.mjs";
41
+ import { t as selectFromPool } from "./device-pool-3o7s5lo4.mjs";
42
+ import { a as printNativeCrashReport, n as IOS_CRASH_REPORT_RETRY, o as simulatorConsolePaths, r as captureNativeCrashes, t as errorDiagnostics } from "./error-diagnostics-C-NMnhrk.mjs";
43
+ import { a as iosPoolCandidates, c as isWirelessIosDevice, f as resolveIosPhysicalDevice, i as iosDeviceProcess, l as listIosDevices, n as installIosDeviceApp, o as iosPoolNoCandidatesRefusal, p as verifyIosDeviceReleaseLaunch, r as iosDeviceBounds, t as awaitIosDeviceLaunch, u as localNetworkPending } from "./ios-device-pAN4t54-.mjs";
44
+ import { n as prepareHostedIos, t as placeHostedIos } from "./hosted-ios-aMo7Cljf.mjs";
44
45
  import { X509Certificate } from "node:crypto";
45
46
  import { existsSync, mkdirSync, mkdtempSync, openSync, rmSync, writeFileSync } from "node:fs";
46
47
  import { basename, join } from "node:path";
47
- import { hostSimulatorArch } from "@stim-cli/core";
48
+ import { hostSimulatorArch, workspaceId } from "@stim-cli/core";
48
49
  import { InvalidArgumentError } from "commander";
49
- import { buildDiagnostics, hostedIosStatus, isJsonObject, machineCapacity, parseMachine } from "@stim-cli/core/state";
50
+ import { buildDiagnostics, hostedIosStatus, machineCapacity, parseMachine } from "@stim-cli/core/state";
50
51
  import { networkInterfaces, tmpdir } from "node:os";
51
52
  import chalk from "chalk";
52
53
  import { createWarnOnce, loadCacheProvider, resolveTieredBuild, storeTieredBuild } from "@stim-cli/cache";
@@ -126,7 +127,7 @@ function copyAppAside(appPath, { exec = null, mkdtemp = () => makeTemporaryDirec
126
127
  }
127
128
  //#endregion
128
129
  //#region src/commands/ios/result.ts
129
- function lastBuildRecord({ fingerprint = null, cacheKey = null, cacheHit = false, cacheSkipped = false, durationMs = 0, appPath = null, bundleId = null, startedAt, status, errorCode = null, missReason = null, diagnostics = null, configuration = null, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null }) {
130
+ function lastBuildRecord({ devicePlacement, fingerprint = null, cacheKey = null, cacheHit = false, cacheSkipped = false, durationMs = 0, appPath = null, bundleId = null, startedAt, status, errorCode = null, missReason = null, diagnostics = null, configuration = null, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null }) {
130
131
  const record = {
131
132
  platform: "ios",
132
133
  fingerprint,
@@ -141,6 +142,7 @@ function lastBuildRecord({ fingerprint = null, cacheKey = null, cacheHit = false
141
142
  configuration
142
143
  };
143
144
  if (errorCode) record.errorCode = errorCode;
145
+ if (devicePlacement) record.devicePlacement = devicePlacement;
144
146
  record.buildMachine = buildMachine;
145
147
  if (builtOn) record.builtOn = builtOn;
146
148
  if (offloadedTo) record.offloadedTo = offloadedTo;
@@ -209,7 +211,7 @@ async function finishIosUpload(uploadPending, remote, phase, note) {
209
211
  }
210
212
  return false;
211
213
  }
212
- function reportIosResult({ host, slot, root, json, release, configuration, buildScheme = null, metroCheck, metroPort, logsDir, device, udid, appPath, bundleId, installSkipped, elapsed, startedAt, storeHash, storeKey, cacheHit, missReason, compilationCache, useBuildCache, waitedForBuild, launchState, launchWarning, providerName, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null, closeWriter, webPreviewUrl, lease, recordRun, reclaimed = [], devServer = null, links }) {
214
+ function reportIosResult({ devicePlacement, host, slot, root, json, release, configuration, buildScheme = null, metroCheck, metroPort, logsDir, device, udid, appPath, bundleId, installSkipped, elapsed, startedAt, storeHash, storeKey, cacheHit, missReason, compilationCache, useBuildCache, waitedForBuild, launchState, launchWarning, providerName, buildMachine = "auto", builtOn, offloadedTo = null, offloadFallback = null, closeWriter, webPreviewUrl, lease, recordRun, reclaimed = [], devServer = null, links }) {
213
215
  const durationMs = elapsed();
214
216
  recordRun({
215
217
  failed: false,
@@ -219,6 +221,7 @@ function reportIosResult({ host, slot, root, json, release, configuration, build
219
221
  offloadedTo
220
222
  });
221
223
  writeLastBuild(root, lastBuildRecord({
224
+ devicePlacement,
222
225
  fingerprint: storeHash,
223
226
  cacheKey: storeKey,
224
227
  cacheHit,
@@ -266,6 +269,7 @@ function reportIosResult({ host, slot, root, json, release, configuration, build
266
269
  offloadedTo,
267
270
  offloadFallback
268
271
  });
272
+ if (devicePlacement) facts.devicePlacement = devicePlacement;
269
273
  if (host) facts.host = host;
270
274
  if (json) console.log(JSON.stringify({
271
275
  ...facts,
@@ -311,7 +315,7 @@ var ArtifactRefusal = class extends Error {
311
315
  }
312
316
  };
313
317
  async function acquireIosArtifact({ root, logFile, udid, remoteDestination, hostedDestination, simulatorArch, device, configuration, buildScheme, buildProfile, buildMachine = "auto", isExpo, optimizations, cache, easBuild, easProfile, maxBuilds, progress }, d) {
314
- const { phase, note, logWriter, estimates, stats, step, miss, hit: lateHit, place, waitingOn } = progress;
318
+ const { phase, note, logWriter, estimates, stats, step, miss, hit: lateHit, place, waitingOn, waitingFor } = progress;
315
319
  const physical = device !== null;
316
320
  const keyOptions = {
317
321
  scheme: buildScheme,
@@ -435,7 +439,7 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, host
435
439
  }
436
440
  return;
437
441
  }
438
- step("cache-lookup");
442
+ if (useBuildCache) step("cache-lookup");
439
443
  const fingerprintTimer = stepTimer(d.now);
440
444
  let computedFingerprint;
441
445
  let fingerprintError = "no hash";
@@ -760,7 +764,8 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, host
760
764
  max: maxBuilds,
761
765
  root,
762
766
  logFile,
763
- out: note
767
+ out: note,
768
+ waitingFor: (info) => waitingFor?.(info, "build-slot")
764
769
  });
765
770
  slotWaitMs = buildSlot.slotWaitMs;
766
771
  } catch (e) {
@@ -1071,13 +1076,15 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, host
1071
1076
  if (offload) stats.setPlacement({
1072
1077
  decision: "fell-back",
1073
1078
  slotWaitMs,
1079
+ deviceSlotWaitMs: stats.deviceSlotWaitMs(),
1074
1080
  reason: offloadFallback ?? "offload failed",
1075
1081
  ...fallbackMachine ? { machine: fallbackMachine } : {}
1076
1082
  });
1077
1083
  else stats.setPlacement({
1078
1084
  decision: "here",
1079
1085
  reason: hereReason,
1080
- slotWaitMs
1086
+ slotWaitMs,
1087
+ deviceSlotWaitMs: stats.deviceSlotWaitMs()
1081
1088
  });
1082
1089
  builtOn = "here";
1083
1090
  buildFailure = {
@@ -1250,17 +1257,13 @@ async function acquireIosArtifact({ root, logFile, udid, remoteDestination, host
1250
1257
  //#region src/commands/ios/remote.ts
1251
1258
  function resolveIosRemote({ opts, settings, physical, recorded }) {
1252
1259
  const target = opts.remote !== void 0 ? parseIosRemote(opts.remote) : remoteIosSetting(settings);
1253
- if (target?.kind === "machine" && target.machine === "auto") return { failure: {
1254
- code: "STIM_BAD_ARG",
1255
- message: "stim ios --remote auto is not available yet: automatic placement has not shipped. Name a hosting Mac from hosting.machines."
1256
- } };
1257
1260
  if (physical && target?.kind === "machine") return { failure: {
1258
1261
  code: "STIM_BAD_ARG",
1259
1262
  message: "--device builds for a phone connected to this machine, and --remote installs on a remote one.",
1260
1263
  remedy: "Pass only one of --device and --remote; unset ios.remote for a local phone."
1261
1264
  } };
1262
1265
  const machine = target?.kind === "machine" ? target.machine : null;
1263
- if (recorded && recorded.machine !== machine) return { failure: {
1266
+ if (recorded && recorded.machine !== machine && machine !== "auto") return { failure: {
1264
1267
  code: "STIM_BAD_ARG",
1265
1268
  message: `This workspace's iOS simulator runs on ${recorded.machine}; run stim stop first.`
1266
1269
  } };
@@ -1289,7 +1292,7 @@ function selectIosTarget({ root, slot, opts, settings, physical, release, metroC
1289
1292
  });
1290
1293
  if ("failure" in selection) return selection;
1291
1294
  const localIos = selection.machine ? deviceSlotPlatforms(d.getProject(root), slot)?.ios : void 0;
1292
- if (selection.machine && localIos?.owned && localIos.deviceUdid) {
1295
+ if (selection.machine !== "auto" && selection.machine && localIos?.owned && localIos.deviceUdid) {
1293
1296
  let localRunning = true;
1294
1297
  try {
1295
1298
  localRunning = d.listAllIosSims({ timeoutMs: 5e3 }).some((sim) => sim.udid === localIos.deviceUdid && sim.state !== "Shutdown");
@@ -1299,13 +1302,55 @@ function selectIosTarget({ root, slot, opts, settings, physical, release, metroC
1299
1302
  message: `This workspace's iOS simulator for slot ${slot} runs on this Mac; run stim stop first.`
1300
1303
  } };
1301
1304
  }
1302
- if (selection.machine && !release && !metroCheck) return { failure: {
1305
+ if (selection.machine !== "auto" && selection.machine && !release && !metroCheck) return { failure: {
1303
1306
  code: "STIM_BAD_ARG",
1304
1307
  message: "Hosted Debug runs require the local Metro supervisor; --no-metro-check cannot be used.",
1305
1308
  remedy: "Run stim stop; stim start, then retry without --no-metro-check."
1306
1309
  } };
1307
1310
  return selection;
1308
1311
  }
1312
+ async function selectIosPlacement(args) {
1313
+ const selection = selectIosTarget(args);
1314
+ if ("failure" in selection || selection.machine !== "auto") return selection;
1315
+ const { root, slot, d, opts, deviceType, runtime, noWait, phase, release, metroCheck } = args;
1316
+ const viewer = resolveSimulatorAppFlag(opts.simulatorApp, args.physical, null);
1317
+ if ("refusal" in viewer) return { failure: viewer.refusal };
1318
+ const refusal = args.validateSelectors();
1319
+ if (refusal) return { failure: refusal };
1320
+ try {
1321
+ const placed = await d.automaticDevicePlacement({
1322
+ root,
1323
+ slot,
1324
+ platform: "ios",
1325
+ selectors: hostedIosSelectors(deviceType, runtime),
1326
+ buildMachine: opts.buildMachine,
1327
+ noWait
1328
+ });
1329
+ phase("placement:", devicePlacementLine(placed.placement, placed.skipped));
1330
+ if (placed.target && !release && !metroCheck) return { failure: {
1331
+ code: "STIM_BAD_ARG",
1332
+ message: "Hosted Debug runs require the local Metro supervisor; --no-metro-check cannot be used.",
1333
+ remedy: "Run stim stop; stim start, then retry without --no-metro-check."
1334
+ } };
1335
+ return {
1336
+ ...selection,
1337
+ machine: placed.target?.host.machine ?? null,
1338
+ recorded: void 0,
1339
+ auto: { target: placed.target },
1340
+ budget: placed.target ? {
1341
+ reclaimed: [],
1342
+ refusal: null
1343
+ } : void 0,
1344
+ devicePlacement: placed.placement
1345
+ };
1346
+ } catch (error) {
1347
+ return { failure: {
1348
+ code: error.code ?? "STIM_HOSTING_REFUSED",
1349
+ message: error.message,
1350
+ ...error instanceof Error && "remedy" in error && typeof error.remedy === "string" ? { remedy: error.remedy } : {}
1351
+ } };
1352
+ }
1353
+ }
1309
1354
  function hostedIosSelectors(deviceType, runtime) {
1310
1355
  return {
1311
1356
  ...deviceType ? { deviceType } : {},
@@ -1313,6 +1358,7 @@ function hostedIosSelectors(deviceType, runtime) {
1313
1358
  };
1314
1359
  }
1315
1360
  async function connectIosTarget(selection, selectors, d) {
1361
+ if (selection.auto) return { target: selection.auto.target };
1316
1362
  if (!selection.machine) return { target: null };
1317
1363
  try {
1318
1364
  return { target: await d.prepareHostedIos(selection.machine, selectors, selection.recorded) };
@@ -1330,7 +1376,11 @@ function hostedIosBuildTarget(target) {
1330
1376
  architecture: target.choice.architecture
1331
1377
  } } : {};
1332
1378
  }
1333
- async function iosPlacementBudget(d, root, note, hosted) {
1379
+ async function iosPlacementBudget(d, root, note, hosted, automatic) {
1380
+ if (automatic) return {
1381
+ ...automatic,
1382
+ refusal: hosted ? null : automatic.refusal
1383
+ };
1334
1384
  return hosted ? {
1335
1385
  reclaimed: [],
1336
1386
  refusal: null
@@ -1339,8 +1389,8 @@ async function iosPlacementBudget(d, root, note, hosted) {
1339
1389
  note
1340
1390
  });
1341
1391
  }
1342
- function hostedIosMetroNote(hosted, settings, note) {
1343
- if (hosted && settings.iosSimulatorApp !== void 0) note(chalk.dim(phaseLine("device", "iosSimulatorApp is ignored on a hosting Mac; the simulator boots headless.")));
1392
+ function hostedIosMetroNote(hosted, settings, note, simulatorApp) {
1393
+ if (hosted && (settings.iosSimulatorApp !== void 0 || simulatorApp !== void 0)) note(chalk.dim(phaseLine("device", "iosSimulatorApp is ignored on a hosting Mac; the simulator boots headless.")));
1344
1394
  if (hosted && (publicUrlSetting(settings) || tunnelModeSetting(settings))) note(chalk.dim(phaseLine("metro", "metro.publicUrl and metro.tunnel are ignored on a hosting Mac; Metro uses the private tailnet bridge.")));
1345
1395
  }
1346
1396
  async function connectIosBackend(root, backend, deviceType, d) {
@@ -1364,25 +1414,6 @@ async function connectIosBackend(root, backend, deviceType, d) {
1364
1414
  arch: await d.readRemoteSimulatorArch(resolved.ctx.existingDaemon)
1365
1415
  };
1366
1416
  }
1367
- function iosMetroSettings(settings, hosted) {
1368
- return hosted ? {
1369
- ...settings,
1370
- ios: {
1371
- ...isJsonObject(settings.ios) ? settings.ios : {},
1372
- remote: void 0
1373
- },
1374
- android: {
1375
- ...isJsonObject(settings.android) ? settings.android : {},
1376
- remote: void 0
1377
- },
1378
- metro: {
1379
- ...isJsonObject(settings.metro) ? settings.metro : {},
1380
- tunnel: void 0,
1381
- publicUrl: void 0,
1382
- ngrokUrl: void 0
1383
- }
1384
- } : settings;
1385
- }
1386
1417
  //#endregion
1387
1418
  //#region src/commands/ios/hosted.ts
1388
1419
  async function finishHostedIosRun({ target, d, artifact, root, slot, release, isExpo, metroCheck, metroPort, logsDir, fail, note, selectors, ...report }) {
@@ -2073,6 +2104,7 @@ async function replaceCollector({ root, slot = "default", udid, bundleId, appNam
2073
2104
  //#endregion
2074
2105
  //#region src/commands/ios/dependencies.ts
2075
2106
  const DEFAULT_DEPS = {
2107
+ automaticDevicePlacement,
2076
2108
  prepareHostedIos,
2077
2109
  placeHostedIos,
2078
2110
  readHostedIos,
@@ -2164,6 +2196,7 @@ const DEFAULT_DEPS = {
2164
2196
  writeWorkspaceState,
2165
2197
  createWriter: createNdjsonWriter,
2166
2198
  recordStats: recordRunStats,
2199
+ recordCapacityRefusal,
2167
2200
  readEstimates: readRunEstimates,
2168
2201
  now: () => Date.now()
2169
2202
  };
@@ -2408,7 +2441,7 @@ function launchFailureRemedy(remoteDevice, udid, bundleId, logFile) {
2408
2441
  if (remoteDevice) return remoteDevice.failureRemedy();
2409
2442
  return `If the simulator timed out, run \`stim doctor --platform ios\` and resolve any reported host memory pressure before retrying. Otherwise run \`xcrun simctl launch --terminate-running-process --console ${udid} ${bundleId}\` to see what the app reports, and check ${logFile}.`;
2410
2443
  }
2411
- async function finishIosRun({ artifact, d, root, slot, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, wireless, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, fail, phase, note, logWriter, elapsed, startedAt, closeWriter, lease, releaseLease, recordRun, reclaimed, devServer, enterPhase }) {
2444
+ async function finishIosRun({ devicePlacement, artifact, d, root, slot, json, release, configuration, buildScheme, isExpo, metroCheck, metroPort, logsDir, logFile, device, udid, physical, wireless, lanAddress, lanOriginUrl, remoteDevice, bootPromise, bootDuration, fail, phase, note, logWriter, elapsed, startedAt, closeWriter, lease, releaseLease, recordRun, reclaimed, devServer, enterPhase }) {
2412
2445
  const { path: appPath, bundleId: initialBundleId, failureFields: buildFailure, cache } = artifact;
2413
2446
  const { hit: cacheHit, providerName, buildMachine, builtOn, offloadedTo, offloadFallback, readEnabled: useBuildCache, missReason, waitedForBuild, compilation: compilationCache } = cache;
2414
2447
  const storeHash = cache.identity?.fingerprint ?? null;
@@ -2756,6 +2789,7 @@ async function finishIosRun({ artifact, d, root, slot, json, release, configurat
2756
2789
  const uploadsAbandoned = await artifact.completeUploads();
2757
2790
  return {
2758
2791
  facts: reportIosResult({
2792
+ devicePlacement,
2759
2793
  root,
2760
2794
  slot,
2761
2795
  json,
@@ -2968,10 +3002,10 @@ function iosCommand(program) {
2968
3002
  registerIos(program);
2969
3003
  }
2970
3004
  function registerIos(program, deps = {}) {
2971
- program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. A Debug run starts the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--build-machine <value>", "Build on auto, local, or one named machine; a name refuses without fallback", parseBuildMachineOption).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--plan", "Predict the next build without building, booting or installing: resolve the fingerprint, check the local then remote cache, and print the expected cache result and duration. Writes no Stim state.").option("--scheme <name>", "Shared Xcode app scheme to build; overrides automatic scheme selection, not the app URL scheme").option("--no-metro-check", "Skip the \"is this workspace's dev server running?\" check: do not start it, and build anyway").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--configuration <name>", "Xcode configuration to build (e.g. Release). A non-Debug configuration embeds the JS bundle and skips Metro entirely. Overrides the ios.configuration setting. Default: Debug").option("--device-type <name>", "Simulator model to create this workspace's owned sim as, exactly as `xcrun simctl list devicetypes` names it (e.g. \"iPad Pro 13-inch (M5)\"). Overrides the ios.deviceType setting for this invocation. A model no installed runtime can create refuses with STIM_BAD_ARG and prints the models they do offer.").option("--runtime <version>", "Simulator runtime to create this workspace's owned sim on, as a version (\"18.5\") or a runtime's full name (\"iOS 18.5\"); nothing else matches. Overrides the ios.runtime setting for this invocation. An unknown version refuses with STIM_BAD_ARG and prints the installed runtimes.").option("--simulator-app <app>", "Open the owned simulator in xcode, siniulator, or stim-desktop for this run, overriding the machine iosSimulatorApp setting. Also opens an already running simulator; local simulators only.").option("--device [udid]", "Build the iphoneos slice for a connected iPhone, install it, and launch it, instead of using this workspace's owned simulator. The phone can be cabled or paired over Wi-Fi. With no UDID, the first cabled device this workspace can lease is used, waiting for one that is busy; a Wi-Fi device is used only when no cabled one is connected and ready. In Debug the app is wired to this workspace's Metro over the LAN. Stim never creates, boots, or deletes a physical device.").option("--remote <target>", "Run on eas, proxy, or an approved Mac in hosting.machines; named Macs never fall back locally. auto is not available yet.", (value) => {
3005
+ program.command("ios").description("Build (or restore from the fingerprint cache), install and launch this workspace's app on its owned simulator, wired to the reserved Metro port. A Debug run starts the dev server when it is not running.").option("--eas-profile <name>", "Download a matching EAS development build; on a miss, print the build command without running it").option("--slot <name>", "Reusable device slot within this workspace (default: default)", parseDeviceSlotOption).option("--build-machine <value>", "Build on auto, local, or one named machine; a name refuses without fallback", parseBuildMachineOption).option("--json", "Emit the facts as a single JSON line on stdout; every other line goes to stderr").option("--plan", "Predict the next build without building, booting or installing: resolve the fingerprint, check the local then remote cache, and print the expected cache result and duration. Writes no Stim state.").option("--scheme <name>", "Shared Xcode app scheme to build; overrides automatic scheme selection, not the app URL scheme").option("--no-metro-check", "Skip the \"is this workspace's dev server running?\" check: do not start it, and build anyway").option("--no-build-cache", "Build fresh, ignoring cached artifacts (local and the project's build-cache provider); the fresh build still replaces the cache entry").option("--configuration <name>", "Xcode configuration to build (e.g. Release). A non-Debug configuration embeds the JS bundle and skips Metro entirely. Overrides the ios.configuration setting. Default: Debug").option("--device-type <name>", "Simulator model to create this workspace's owned sim as, exactly as `xcrun simctl list devicetypes` names it (e.g. \"iPad Pro 13-inch (M5)\"). Overrides the ios.deviceType setting for this invocation. A model no installed runtime can create refuses with STIM_BAD_ARG and prints the models they do offer.").option("--runtime <version>", "Simulator runtime to create this workspace's owned sim on, as a version (\"18.5\") or a runtime's full name (\"iOS 18.5\"); nothing else matches. Overrides the ios.runtime setting for this invocation. An unknown version refuses with STIM_BAD_ARG and prints the installed runtimes.").option("--simulator-app <app>", "Open the owned simulator in xcode, siniulator, or stim-desktop for this run, overriding the machine iosSimulatorApp setting. Also opens an already running simulator; local simulators only.").option("--device [udid]", "Build the iphoneos slice for a connected iPhone, install it, and launch it, instead of using this workspace's owned simulator. The phone can be cabled or paired over Wi-Fi. With no UDID, the first cabled device this workspace can lease is used, waiting for one that is busy; a Wi-Fi device is used only when no cabled one is connected and ready. In Debug the app is wired to this workspace's Metro over the LAN. Stim never creates, boots, or deletes a physical device.").option("--remote <target>", "Run on eas, proxy, or an approved Mac in hosting.machines; named Macs never fall back locally. auto places on an approved Mac when this Mac is full or busy.", (value) => {
2972
3006
  if (parseMachine(value)) return value.trim();
2973
3007
  throw new InvalidArgumentError("expected eas, proxy, auto, or a hosting Mac name");
2974
- }).option("--wait <seconds>", "How long to wait for another workspace to release the phone it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Only with --device.").option("--no-wait", "Install on a phone another workspace leases instead of waiting: this run takes no lease and, when both workspaces build the same app id, the install terminates the holder's running app. Only with --device.").action(async (opts) => {
3008
+ }).option("--wait <seconds>", "How long to wait for another workspace to release the phone it leases, before refusing with STIM_DEVICE_BUSY (default 60, 0 refuses at once). Without --device, wait for an owned-device slot (default 600 seconds; --no-wait refuses immediately).").option("--no-wait", "Install on a phone another workspace leases instead of waiting: this run takes no lease and, when both workspaces build the same app id, the install terminates the holder's running app. Without --device, refuse a full device cap or existing slot queue immediately.").action(async (opts) => {
2975
3009
  if (opts.plan) {
2976
3010
  const d = {
2977
3011
  ...DEFAULT_DEPS,
@@ -3181,10 +3215,12 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3181
3215
  phases: () => progress.durations(),
3182
3216
  deviceSetup: () => progress.deviceSetupKnown()
3183
3217
  });
3184
- const recordRun = stats.record;
3218
+ const deviceWaitRun = createIosDeviceWaitRun(stats, progress, runCancellationSignal());
3219
+ const recordRun = deviceWaitRun.record;
3185
3220
  let compilationCache = COMPILATION_CACHE_NOT_RUN;
3186
3221
  let reclaimed = [];
3187
3222
  let buildMachine = "auto";
3223
+ let devicePlacement;
3188
3224
  let builtConfiguration = null;
3189
3225
  const fail = ({ code, message, remedy = null, lines = [], logPath = null, build = null, lease, setup = false }) => {
3190
3226
  ({code, message, remedy, lines} = cancelledFailure("ios", {
@@ -3202,6 +3238,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3202
3238
  if (remedy) note(chalk.dim(phaseLine("remedy", remedy)));
3203
3239
  if (logPath) note(chalk.dim(phaseLine("log", logPath)));
3204
3240
  if (build) writeLastBuild(root, lastBuildRecord({
3241
+ devicePlacement,
3205
3242
  buildMachine,
3206
3243
  ...build,
3207
3244
  configuration: builtConfiguration,
@@ -3219,6 +3256,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3219
3256
  code,
3220
3257
  message: message ?? null,
3221
3258
  remedy: remedy ?? null,
3259
+ ...devicePlacement ? { devicePlacement } : {},
3222
3260
  ...compilationCache.status === "not-run" ? {} : { compilationCache },
3223
3261
  ...lease === void 0 ? {} : { lease },
3224
3262
  ...reclaimed.length ? { reclaimed } : {}
@@ -3299,11 +3337,20 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3299
3337
  });
3300
3338
  const wait = resolveIosWait(opts, physical);
3301
3339
  if ("failure" in wait) return fail(wait.failure);
3302
- const { waitSeconds, noWait } = wait;
3340
+ const { waitSeconds, noWait, deviceSlotWaitMs, checkCapacity } = wait;
3341
+ const deviceSlotWait = {
3342
+ waitMs: deviceSlotWaitMs,
3343
+ displayName: basename(root),
3344
+ ...deviceWaitRun.policy,
3345
+ onWait: (ms) => {
3346
+ deviceWaitRun.policy.onWait?.(ms);
3347
+ if (devicePlacement?.decision === "local" && ms > 0) devicePlacement.decision = "waited-locally";
3348
+ }
3349
+ };
3303
3350
  const isExpo = d.detectIsExpo(root);
3304
3351
  const schemeRefusal = explicitSchemeRefusal(root, buildScheme, isExpo, d);
3305
3352
  if (schemeRefusal) return fail(schemeRefusal);
3306
- const remoteSelection = selectIosTarget({
3353
+ const remoteSelection = await selectIosPlacement({
3307
3354
  root,
3308
3355
  slot,
3309
3356
  opts,
@@ -3311,11 +3358,30 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3311
3358
  physical,
3312
3359
  release,
3313
3360
  metroCheck,
3314
- d
3361
+ d,
3362
+ deviceType,
3363
+ runtime,
3364
+ validateSelectors: () => deviceModelRefusal({
3365
+ slot,
3366
+ deviceTypeFlag: opts.deviceType,
3367
+ runtimeFlag: opts.runtime,
3368
+ deviceType,
3369
+ runtime,
3370
+ physical,
3371
+ remoteBackend: null,
3372
+ deviceTypeOrigin: d.settingOriginScope(d.settingsLayers(settingsContext), "ios.deviceType"),
3373
+ runtimeOrigin: d.settingOriginScope(d.settingsLayers(settingsContext), "ios.runtime"),
3374
+ listRuntimes: d.listIosRuntimes
3375
+ }),
3376
+ noWait: deviceSlotWaitMs === 0,
3377
+ note,
3378
+ phase
3315
3379
  });
3316
3380
  if ("failure" in remoteSelection) return fail(remoteSelection.failure);
3381
+ devicePlacement = remoteSelection.devicePlacement;
3382
+ writeDevicePlacement(root, slot, "ios", devicePlacement);
3317
3383
  const { machine: hostedMachine, backend: remoteBackend } = remoteSelection;
3318
- const viewer = resolveSimulatorAppFlag(opts.simulatorApp, physical, hostedMachine ?? remoteBackend);
3384
+ const viewer = resolveSimulatorAppFlag(opts.simulatorApp, physical, hostedMachine ?? remoteBackend, Boolean(remoteSelection.auto));
3319
3385
  if ("refusal" in viewer) return fail(viewer.refusal);
3320
3386
  const { simulatorApp } = viewer;
3321
3387
  const settingsLayersForOrigin = d.settingsLayers(settingsContext);
@@ -3338,7 +3404,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3338
3404
  if ("failure" in connected) return fail(connected.failure);
3339
3405
  const hostedTarget = connected.target;
3340
3406
  try {
3341
- const budget = await iosPlacementBudget(d, root, note, Boolean(hostedTarget));
3407
+ const budget = await iosPlacementBudget(d, root, note, Boolean(hostedTarget), remoteSelection.budget);
3342
3408
  reclaimed = budget.reclaimed;
3343
3409
  if (budget.refusal) return fail(budget.refusal);
3344
3410
  const backendConnection = await connectIosBackend(root, remoteBackend, opts.deviceType, d);
@@ -3419,13 +3485,20 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3419
3485
  };
3420
3486
  wireless = resolved.wireless === true;
3421
3487
  }
3422
- if (!physical && !hostedTarget) {
3488
+ if (checkCapacity && !hostedTarget) {
3423
3489
  const capacity = d.checkDeviceCapacity({
3424
3490
  platform: "ios",
3425
3491
  project: proj,
3426
3492
  max: limits.maxDevices
3427
3493
  });
3428
- if (capacity) return fail(capacity);
3494
+ if (capacity) {
3495
+ if (capacity.code === "STIM_AT_CAPACITY") d.recordCapacityRefusal({
3496
+ platform: "ios",
3497
+ max: limits.maxDevices,
3498
+ workspace: workspaceId(root)
3499
+ }, d.now());
3500
+ return fail(capacity);
3501
+ }
3429
3502
  }
3430
3503
  let metroPort = proj?.metroPort ?? null;
3431
3504
  let lanAddress = null;
@@ -3453,6 +3526,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3453
3526
  settingsRoot: root,
3454
3527
  settings,
3455
3528
  flags: {
3529
+ deviceSlotWait,
3456
3530
  deviceType,
3457
3531
  runtime,
3458
3532
  runtimeFlag: resolveRuntime(opts.runtime, null),
@@ -3464,6 +3538,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3464
3538
  } catch (e) {
3465
3539
  return fail(ownedSimFailure(e));
3466
3540
  }
3541
+ deviceWaitRun.booting(device.booting);
3467
3542
  progress.deviceSetup(didSetUpDevice(device, Boolean(remoteDevice)));
3468
3543
  const prepareMs = prepare();
3469
3544
  if (device.created || prepareMs >= 2e3) phase("device", `${deviceLabel(device, device.deviceUdid)} ${device.created ? "created" : "prepared"} (${formatDuration(prepareMs)})`);
@@ -3479,7 +3554,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3479
3554
  const gate = await ensureDevServer({
3480
3555
  root,
3481
3556
  port: metroPort,
3482
- settings: iosMetroSettings(settings, Boolean(hostedTarget)),
3557
+ settings: hostedMetroSettings(settings, Boolean(hostedTarget)),
3483
3558
  remote: Boolean(remoteDevice),
3484
3559
  note,
3485
3560
  resolve: d.resolveProjectMetro,
@@ -3511,7 +3586,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3511
3586
  if (pin.port === null && !metroPort) note(chalk.yellow(`No Metro port is reserved for this workspace; wiring the app to ${DEFAULT_METRO_PORT}.`));
3512
3587
  metroPort = pin.port ?? metroPort ?? 8081;
3513
3588
  }
3514
- hostedIosMetroNote(Boolean(hostedTarget), settings, note);
3589
+ hostedIosMetroNote(Boolean(hostedTarget), settings, note, opts.simulatorApp);
3515
3590
  if (physical && metroPort !== null && !await resolveLanOrigin()) return false;
3516
3591
  if (remoteDevice && metroPort !== null) {
3517
3592
  const reachable = await d.ensureMetroReachable({
@@ -3586,6 +3661,8 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3586
3661
  }) : Promise.resolve(d.ensureBooted({
3587
3662
  platform: "ios",
3588
3663
  device,
3664
+ projectPath: root,
3665
+ deviceSlotWait,
3589
3666
  simulatorApp,
3590
3667
  out: note
3591
3668
  })).catch((e) => ({
@@ -3611,6 +3688,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3611
3688
  bootDuration = bootTimer();
3612
3689
  return result;
3613
3690
  });
3691
+ deviceWaitRun.booting({ done: bootPromise });
3614
3692
  return bootPromise.then((result) => result?.udid ?? "");
3615
3693
  };
3616
3694
  const localBoot = remoteDevice || hostedTarget ? null : startBoot();
@@ -3657,7 +3735,8 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3657
3735
  miss: progress.miss,
3658
3736
  hit: progress.hit,
3659
3737
  place: progress.place,
3660
- waitingOn: progress.waitingOn
3738
+ waitingOn: progress.waitingOn,
3739
+ waitingFor: progress.waitingFor
3661
3740
  }
3662
3741
  }, d));
3663
3742
  if (!acquiredArtifact.ok) {
@@ -3683,6 +3762,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3683
3762
  elapsed,
3684
3763
  startedAt,
3685
3764
  closeWriter: () => writer?.close(),
3765
+ devicePlacement,
3686
3766
  recordRun,
3687
3767
  reclaimed,
3688
3768
  devServer,
@@ -3760,6 +3840,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3760
3840
  closeWriter: () => writer?.close?.(),
3761
3841
  lease: leaseHandle,
3762
3842
  releaseLease,
3843
+ devicePlacement,
3763
3844
  recordRun,
3764
3845
  reclaimed,
3765
3846
  devServer,
@@ -3778,6 +3859,7 @@ async function runIos(opts = {}, overrides = {}, progress = NO_BUILD_PROGRESS) {
3778
3859
  artifact?.release();
3779
3860
  }
3780
3861
  } finally {
3862
+ await deviceWaitRun.finish();
3781
3863
  hostedTarget?.host.connection.close();
3782
3864
  }
3783
3865
  }
@@ -1,8 +1,8 @@
1
1
  import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
2
  import { _ as loadConfig$1 } from "./config-D0DbpZtM.mjs";
3
3
  import { n as stripAnsi, r as waitForChild, t as createLineReader } from "./process-output-Fpl8PYi8.mjs";
4
- import { r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-D5owjN4C.mjs";
5
- import { at as isStimOwnedSim } from "./android-B_NumVyQ.mjs";
4
+ import { r as recordCreatedDevice, t as forgetCreatedDevice } from "./created-devices-CpvzBL25.mjs";
5
+ import { at as isStimOwnedSim } from "./android-B_YNZy61.mjs";
6
6
  import { n as settingDefault, t as STIM_DESKTOP_OPEN_OPTIONS } from "./stim-desktop-Cnz8CPnl.mjs";
7
7
  import { createHash } from "node:crypto";
8
8
  import { closeSync, existsSync, lstatSync, mkdtempSync, openSync, readSync, readdirSync, rmSync, writeFileSync } from "node:fs";
@@ -668,8 +668,8 @@ function listUserApps(udid) {
668
668
  });
669
669
  }
670
670
  }
671
- function resolveOwnedIosSim(udid) {
672
- const sim = listAllIosSims().find((s) => s.udid === udid);
671
+ function resolveOwnedIosSim(udid, listed = listAllIosSims()) {
672
+ const sim = listed.find((s) => s.udid === udid && s.available);
673
673
  if (!sim) return { missing: true };
674
674
  if (!isStimOwnedSim(sim)) return { notOwned: sim.name };
675
675
  return { sim };
@@ -1,6 +1,6 @@
1
1
  import { t as getExecutor } from "./exec-CaErVv7t.mjs";
2
2
  import { n as TOOL_ERROR_PREFIX } from "./ios-device-Ee7sDXfp.mjs";
3
- import { i as INSTALL_ERROR } from "./app-install-CKWdbXIX.mjs";
3
+ import { i as INSTALL_ERROR } from "./app-install-VPkI5WEg.mjs";
4
4
  import { mkdtempSync, readFileSync, rmSync } from "node:fs";
5
5
  import { join } from "node:path";
6
6
  import { tmpdir } from "node:os";