stim 1.18.0 → 1.19.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 (140) hide show
  1. package/README.md +1 -1
  2. package/dist/{activity-BxnkDZDi.mjs → activity-BSw0x84R.mjs} +3 -3
  3. package/dist/{agent-device-usage-output-CZ66YA4T.mjs → agent-device-usage-output-Bjxu_VmX.mjs} +5 -5
  4. package/dist/{android-BvwuMUJ9.mjs → android-BXc6BmEi.mjs} +507 -347
  5. package/dist/{android-DC3ZLuw0.mjs → android-BdQC6zs1.mjs} +6 -6
  6. package/dist/{android-BKA16DTf.mjs → android-BvV1gGdN.mjs} +3 -3
  7. package/dist/{android-CBwCNicO.mjs → android-DE5g_5gv.mjs} +2 -2
  8. package/dist/{android-cas-BBFyr9CA.mjs → android-cas-C87geAg-.mjs} +3 -3
  9. package/dist/android-cas-compiler.mjs +1 -1
  10. package/dist/{api-D0VtFhqk.mjs → api-DIf_s86s.mjs} +5 -7
  11. package/dist/api-run.mjs +8 -8
  12. package/dist/api.d.mts +8 -2
  13. package/dist/api.mjs +1 -1
  14. package/dist/{app-install-D-PUENug.mjs → app-install-CFI4ptUL.mjs} +33 -13
  15. package/dist/{web-DTU0uiWj.mjs → browser-web-CDhqQxhv.mjs} +134 -172
  16. package/dist/{budget-DIhL2BKx.mjs → budget-Dz-kyXLv.mjs} +15 -202
  17. package/dist/{build-facts-DcLv2HSd.d.mts → build-facts-B87vo-Im.d.mts} +32 -1
  18. package/dist/{cache-manifest-BI7ozfmH.mjs → cache-manifest-DiwKSyv9.mjs} +1 -1
  19. package/dist/cache-manifest.mjs +1 -1
  20. package/dist/{chrome-DJnmnS5q.mjs → chrome-BTUOo8p2.mjs} +1 -1
  21. package/dist/{cli-DNJMwADx.mjs → cli-C9Zvgbdc.mjs} +20 -20
  22. package/dist/cli.mjs +1 -1
  23. package/dist/{client-DzhapoMB.mjs → client-CuUo8Nvg.mjs} +248 -23
  24. package/dist/collector-run.d.mts +6 -0
  25. package/dist/collector-run.mjs +6 -6
  26. package/dist/{command-output-CBtzyIgF.mjs → command-output-Bt8ygHE7.mjs} +1 -1
  27. package/dist/{config-CgYMahz7.mjs → config-DC5jEtd1.mjs} +6 -2
  28. package/dist/{created-devices-DKbeWsiK.mjs → created-devices-D0s26Hx5.mjs} +2 -2
  29. package/dist/{dependency-state-xKoOypBm.mjs → dependency-state-DKaS1OM9.mjs} +2 -2
  30. package/dist/{detached-entry-BLfcgc4O.mjs → detached-entry-pB_IPfV4.mjs} +1 -1
  31. package/dist/{dev-client-CLnIH02x.mjs → dev-client-CDY_zAmD.mjs} +2 -2
  32. package/dist/{device-D7oCHGWi.mjs → device-BHw0WlHl.mjs} +8 -8
  33. package/dist/{device-capacity-EUOOYr8T.mjs → device-capacity-BoN1jQkO.mjs} +23 -12
  34. package/dist/device-host-worker.mjs +14 -14
  35. package/dist/{gradle-C6GKnunQ.mjs → device-ios-B2ruohE-.mjs} +659 -105
  36. package/dist/{device-lease-Co-EwifR.mjs → device-lease-Cu7PtQpZ.mjs} +5 -5
  37. package/dist/{device-lease-run-w1xhCqIW.mjs → device-lease-run-D38SnZtt.mjs} +4 -4
  38. package/dist/{device-pool-F5WvRPtD.mjs → device-pool-CP4rAsHx.mjs} +3 -3
  39. package/dist/{device-remote-tHbd1fKy.mjs → device-remote-B5GiUifk.mjs} +15 -16
  40. package/dist/{doctor-B9ckYUoU.mjs → doctor-PRJH94v6.mjs} +53 -29
  41. package/dist/doctor-watchman-wZhyTdp4.mjs +259 -0
  42. package/dist/{error-diagnostics-BRXOqDzG.mjs → error-diagnostics--v5HGOU0.mjs} +10 -10
  43. package/dist/{exec-DWhCZDGm.mjs → exec-i8GDPwq9.mjs} +32 -8
  44. package/dist/{gc-Dh6mXOKC.mjs → gc-CyHMcKcn.mjs} +19 -19
  45. package/dist/{guide-tm6igAaa.mjs → guide-dRaQJJk9.mjs} +409 -472
  46. package/dist/{hosted-android-Bv285t_t.mjs → hosted-android-Bs7fytj7.mjs} +3 -3
  47. package/dist/{hosted-client-C-rMtppF.mjs → hosted-client-C5G4h_OJ.mjs} +1 -1
  48. package/dist/{hosted-ios-D5mNmtj4.mjs → hosted-ios-Bik035eL.mjs} +1 -1
  49. package/dist/{hosted-logs-DN8Iz4mJ.mjs → hosted-logs-CI9Az9a4.mjs} +7 -7
  50. package/dist/{hosted-macos-B-wEjlwG.mjs → hosted-macos-DABm3ScO.mjs} +4 -4
  51. package/dist/{hosted-native-DeeOG8xZ.mjs → hosted-native-DbV2aUVw.mjs} +12 -8
  52. package/dist/{idle-shutdown-jjtxAn5C.mjs → idle-shutdown-DYiMBn34.mjs} +7 -7
  53. package/dist/{ios-B3SbOWdw.mjs → ios-BWbHFZVz.mjs} +5 -5
  54. package/dist/{ios-Bvbf0SGY.mjs → ios-DCrkgXEM.mjs} +1 -1
  55. package/dist/{ios-DNpdygiv.mjs → ios-DYUr9LGc.mjs} +7 -6
  56. package/dist/ios-ITYno9rO.mjs +2241 -0
  57. package/dist/{ios-device-vOaByMhw.mjs → ios-device-CJ_ZOGky.mjs} +3 -3
  58. package/dist/{ios-device-Bn7jWDB1.mjs → ios-device-CrW8aMb5.mjs} +1 -1
  59. package/dist/{ios-state-B2pES6Vs.mjs → ios-state-By0XuLTQ.mjs} +1 -1
  60. package/dist/{launch-verify-hskNcWkZ.mjs → launch-verify-DCveSE6d.mjs} +4 -4
  61. package/dist/{logs-1Ylc1Ri6.mjs → logs-Bao1HOMy.mjs} +10 -10
  62. package/dist/{macos-DF6C7wUU.mjs → macos-ciyBdTY5.mjs} +108 -130
  63. package/dist/macos-nIOATJmR.mjs +2 -0
  64. package/dist/macos-run.mjs +1 -1
  65. package/dist/maintenance-run.mjs +7 -7
  66. package/dist/manifest-CX0d1IkZ.mjs +148 -0
  67. package/dist/{metro-Dh8T4Ytd.mjs → metro-DI2AjPF_.mjs} +194 -41
  68. package/dist/{metro-gateway-CEUw9RMH.mjs → metro-gateway-BxpJLIwh.mjs} +2 -2
  69. package/dist/{plan-placement-CtxkCO54.mjs → miss-reason-CjQCOKqq.mjs} +180 -296
  70. package/dist/{named-ports-BFIz1Shz.mjs → named-ports-B4iWH4E-.mjs} +12 -5
  71. package/dist/{native-runtime-D_603JiC.mjs → native-runtime-BGxsbfny.mjs} +6 -6
  72. package/dist/offload-worker.d.mts +1 -29
  73. package/dist/offload-worker.mjs +9 -8
  74. package/dist/{ownership-D6Se7gg_.mjs → ownership-EB0ySdGK.mjs} +2 -2
  75. package/dist/{placement-log-BcPhRwR4.mjs → placement-log-Dxe34rJm.mjs} +7 -3
  76. package/dist/plan-placement-BVY59qa8.mjs +290 -0
  77. package/dist/{ports-BLTtfBq-.mjs → ports-ByPc0_97.mjs} +3 -3
  78. package/dist/{prebuild-juCyreaR.mjs → prebuild-BKJ3wJI1.mjs} +4 -4
  79. package/dist/{preview-D5V07Nrl.mjs → preview-BbSottmO.mjs} +16 -17
  80. package/dist/project-B5eQ1USs.mjs +612 -0
  81. package/dist/{pull-request-u4vp7zmK.mjs → pull-request-IHNdMnG8.mjs} +1 -1
  82. package/dist/pull-requests.mjs +1 -1
  83. package/dist/react-native-ios-BMh2i25I.mjs +2 -0
  84. package/dist/react-native-ios-CSpIxexZ.mjs +2083 -0
  85. package/dist/{recordings-BAWltsVt.mjs → recordings-Bv8McZN4.mjs} +1 -1
  86. package/dist/{reload-DvyWzVjJ.mjs → reload-rAPdqeRR.mjs} +13 -14
  87. package/dist/{remote-cache-BGg7aGIZ.mjs → remote-cache-N3hAEaAL.mjs} +4 -4
  88. package/dist/{run-vhtDgpHO.mjs → run-lAkle1-c.mjs} +2 -2
  89. package/dist/{server-bare-B9E7S1aR.mjs → server-bare-CkIjnegq.mjs} +3 -3
  90. package/dist/server-expo-DGsdUGX2.mjs +2 -0
  91. package/dist/{server-expo-DoBHhuzK.mjs → server-expo-n3tUi3Em.mjs} +3 -3
  92. package/dist/{settings-Byp2AQ_E.mjs → settings-2am7TSxp.mjs} +5 -6
  93. package/dist/{settings-CQyMElEP.mjs → settings-CxgngUZk.mjs} +767 -15
  94. package/dist/settings.schema.json +72 -6
  95. package/dist/{simslim-EHBQ2R4G.mjs → simslim-D9LkJxIO.mjs} +5 -5
  96. package/dist/{slot-launch-C1nqh4mu.mjs → slot-launch-HV_KtPIw.mjs} +6 -6
  97. package/dist/{stage-g_WqWeaE.mjs → stage-BgaZJVZY.mjs} +1 -1
  98. package/dist/{start-NTc1Ifqs.mjs → start-D8NbxNBb.mjs} +1 -1
  99. package/dist/{start-D-IeOyoK.mjs → start-DtxthMfI.mjs} +29 -22
  100. package/dist/{state-BG-aAk4k.mjs → state-D2KtnALG.mjs} +2 -2
  101. package/dist/{state-xnqpx3AD.mjs → state-Tp4uImDS.mjs} +4 -2
  102. package/dist/{stats-DY6ekz8F.mjs → stats-8EJ5ivFT.mjs} +6 -6
  103. package/dist/{status-DCjZeE-K.mjs → status-BOyp0CUl.mjs} +25 -27
  104. package/dist/{stim-desktop-Behws_fi.mjs → stim-desktop-C65jk_q2.mjs} +1 -1
  105. package/dist/{stim-installations-aR_WsNOA.mjs → stim-installations-DbmUjsLv.mjs} +1 -1
  106. package/dist/stop-D0UIpZuh.mjs +72 -0
  107. package/dist/{stop-DIJtD2GL.mjs → stop-DRipAg-e.mjs} +2 -2
  108. package/dist/{stop-BTjs3xbc.mjs → stop-zDlknFoz.mjs} +78 -31
  109. package/dist/supervisor-run.mjs +14 -14
  110. package/dist/{support-BaayeYCf.mjs → support-CNqYkV0y.mjs} +7 -7
  111. package/dist/{support-Bwvbrq5-.mjs → support-DsNaFg6D.mjs} +5 -5
  112. package/dist/swiftpm-macos-aJzPAj1t.mjs +119 -0
  113. package/dist/{toolchain-Bnyd_K3A.mjs → toolchain-C3xSoyUl.mjs} +27 -270
  114. package/dist/{trigger-CJMhwXe8.mjs → trigger-CAhmG-4s.mjs} +3 -3
  115. package/dist/trigger-CoalsMTV.mjs +2 -0
  116. package/dist/{warm-progress-CjB-MP6H.mjs → warm-progress-pFLB2e6P.mjs} +133 -36
  117. package/dist/{status-Dcr0Qexd.mjs → watchman-BL1IdOtq.mjs} +75 -7
  118. package/dist/web-DFpFeZu5.mjs +2 -0
  119. package/dist/web-DbbrPUn0.mjs +127 -0
  120. package/dist/web-run.mjs +7 -7
  121. package/dist/{workspace-state-C59dqG-Z.mjs → workspace-state-CR9X86xJ.mjs} +1 -1
  122. package/dist/{workspaces-xXItD8Dj.mjs → workspaces-Djb2gfi9.mjs} +102 -18
  123. package/dist/{worktree-BSYlofkq.mjs → worktree-BL4M1rhB.mjs} +45 -42
  124. package/dist/{worktree-BJfnU6r5.mjs → worktree-DV-A0LNL.mjs} +1 -1
  125. package/package.json +5 -5
  126. package/shim/bundle-response.cjs +2 -1
  127. package/shim/bundle-response.d.cts +1 -1
  128. package/shim/expo-metro-config.cjs +1 -1
  129. package/dist/device-ios-6MewKKnc.mjs +0 -412
  130. package/dist/guide-status-Bhf9SJXc.mjs +0 -125
  131. package/dist/ios-CPdkoKaa.mjs +0 -3953
  132. package/dist/macos-Ck7OBMNY.mjs +0 -2
  133. package/dist/native-run-B06FkmZx.mjs +0 -158
  134. package/dist/project-C3ChRLZy.mjs +0 -212
  135. package/dist/projects-DD7dBTCj.mjs +0 -92
  136. package/dist/server-expo-Db9HBUoa.mjs +0 -2
  137. package/dist/stop-BGhKMOuH.mjs +0 -48
  138. package/dist/trigger-DWAq9hkw.mjs +0 -2
  139. package/dist/web-B6_bFDn7.mjs +0 -2
  140. package/dist/worktree-CsKYexJM.mjs +0 -753
@@ -1,2 +0,0 @@
1
- import { n as runMacos, t as macosCommand } from "./macos-DF6C7wUU.mjs";
2
- export { macosCommand as default, runMacos };
@@ -1,158 +0,0 @@
1
- import { a as formatElapsed } from "./command-output-CBtzyIgF.mjs";
2
- import { a as updateWorkspaceState, r as readWorkspaceState, t as clearWorkspaceStateKey, v as workspaceDir } from "./workspace-state-C59dqG-Z.mjs";
3
- import { i as signalDeclaredSpawns, r as refuseDeclaredSpawns, t as allowDeclaredSpawns } from "./spawn-claims-Kqiifsk2.mjs";
4
- import { a as withWorkspaceProcessLock } from "./named-ports-BFIz1Shz.mjs";
5
- //#region src/engine/native-run.ts
6
- const NATIVE_RUN_LOCK = "native-run";
7
- const NATIVE_RUN_WAIT_MS = 18e5;
8
- const WAIT_HEARTBEAT_MS = 3e4;
9
- const CANCEL_REQUEST_KEY = "nativeRunCancel";
10
- function nativeRunHolder(holder) {
11
- const { command, platform, slot } = holder.details;
12
- return {
13
- command: typeof command === "string" ? command : null,
14
- platform: typeof platform === "string" ? platform : null,
15
- slot: typeof slot === "string" ? slot : "default"
16
- };
17
- }
18
- function describeNativeRunHolder(holder, now) {
19
- const { command, slot } = nativeRunHolder(holder);
20
- const started = Date.parse(holder.startedAt);
21
- const facts = [`pid ${holder.owner.pid}`];
22
- if (Number.isFinite(started)) facts.push(`running for ${formatElapsed(now - started)}`);
23
- if (command === null) return `another Stim run (${facts.join(", ")})`;
24
- return `\`stim ${command}${slot === "default" ? "" : ` --slot ${slot}`}\` (${facts.join(", ")})`;
25
- }
26
- /**
27
- * Report a wait on the native-run lock: one line as soon as a holder is seen, a line for each new
28
- * holder, and a heartbeat every WAIT_HEARTBEAT_MS while the same holder keeps it.
29
- */
30
- function nativeRunWaitNotice({ write, now = Date.now, describe = describeNativeRunHolder }) {
31
- let claimId = null;
32
- let lastAt = 0;
33
- return (holder, firstLine) => {
34
- const at = now();
35
- if (holder.claimId !== claimId) {
36
- claimId = holder.claimId;
37
- lastAt = at;
38
- write(firstLine ?? `waiting for ${describe(holder, at)} in this workspace to finish`);
39
- return;
40
- }
41
- if (at - lastAt < WAIT_HEARTBEAT_MS) return;
42
- lastAt = at;
43
- write(`still waiting for ${describe(holder, at)}`);
44
- };
45
- }
46
- /**
47
- * What `stop` does about the run holding the native-run lock. A build is interrupted only when the stop
48
- * leaves it nothing to deploy to: the whole workspace stops, the build targets the stopped slot, or the
49
- * stopped slot is the workspace's only device. A build for another slot that stays is left running and
50
- * the stop proceeds without the lock. Only an owner whose identity is proven live is signalled.
51
- */
52
- function decideStopAction({ stopSlot, holder, ownerIdentity, deviceSlots }) {
53
- if (holder.command === "macos") {
54
- if (stopSlot !== void 0) return { action: "proceed" };
55
- return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
56
- }
57
- if (holder.command !== "ios" && holder.command !== "android") return { action: "wait" };
58
- if (!(stopSlot === void 0 || holder.slot === stopSlot || deviceSlots.includes(stopSlot) && deviceSlots.every((slot) => slot === stopSlot))) return { action: "proceed" };
59
- return ownerIdentity === "same" ? { action: "interrupt" } : { action: "refuse" };
60
- }
61
- function requestNativeRunCancel(root, claimId, pid = process.pid) {
62
- updateWorkspaceState(root, (state) => ({
63
- ...state,
64
- [CANCEL_REQUEST_KEY]: {
65
- claimId,
66
- pid,
67
- at: (/* @__PURE__ */ new Date()).toISOString()
68
- }
69
- }));
70
- }
71
- function cancelRequestFor(root, claimId) {
72
- const request = readWorkspaceState(root)?.[CANCEL_REQUEST_KEY];
73
- if (request?.claimId !== claimId || typeof request.pid !== "number") return null;
74
- return { pid: request.pid };
75
- }
76
- function clearNativeRunCancel(root, claimId) {
77
- try {
78
- clearWorkspaceStateKey(root, CANCEL_REQUEST_KEY, (value) => value?.claimId === claimId);
79
- } catch {}
80
- }
81
- let cancelled = null;
82
- let cancellationSignal;
83
- /** The active native run aborts this signal when it is cancelled. */
84
- function runCancellationSignal() {
85
- return cancellationSignal;
86
- }
87
- /** Why this process's native run was cancelled, or null while it was not. */
88
- function runCancellation() {
89
- return cancelled;
90
- }
91
- function cancelledFailure(platform, { code, message }) {
92
- if (cancelled === null) return null;
93
- return {
94
- code: "STIM_CANCELLED",
95
- message: `The ${platform} run was ${cancelled} before it finished.`,
96
- remedy: `Run \`stim ${platform}\` again when you want the app on a device.`,
97
- lines: [`it stopped at ${code ?? "an unfinished step"}${message ? `: ${message}` : ""}`]
98
- };
99
- }
100
- function cancelOnInterrupt({ root, claim, write, exit, controller }) {
101
- let signals = 0;
102
- const onInterrupt = () => {
103
- signals += 1;
104
- if (signals > 1) {
105
- exit(130);
106
- return;
107
- }
108
- const request = cancelRequestFor(root, claim.claimId);
109
- cancelled = request ? `cancelled by \`stim stop\` (pid ${request.pid})` : "cancelled by an interrupt";
110
- controller.abort();
111
- refuseDeclaredSpawns(`the run was ${cancelled}`);
112
- const signalled = signalDeclaredSpawns("SIGINT");
113
- write(signalled > 0 ? `${cancelled}; stopping the running build tool` : request ? `${cancelled}; stopping before the next build tool or install` : cancelled);
114
- if (signalled === 0 && !request) exit(130);
115
- };
116
- process.on("SIGINT", onInterrupt);
117
- return () => {
118
- process.off("SIGINT", onInterrupt);
119
- allowDeclaredSpawns();
120
- clearNativeRunCancel(root, claim.claimId);
121
- };
122
- }
123
- /**
124
- * Run an `ios`, `android` or `macos` invocation under the workspace's native-run lock: the claim records the
125
- * command, platform and slot, and a wait for another holder is reported on `write`. The first SIGINT
126
- * forwards the interrupt to the running declared build tool; a run `stim stop` cancelled between build
127
- * tools starts no further one; a terminal interrupt with no build tool running, or a second SIGINT, exits
128
- * with 130 at once.
129
- */
130
- function withNativeBuildRun(root, details, fn, { write, exit = (code) => process.exit(code) }) {
131
- const notice = nativeRunWaitNotice({ write });
132
- return withWorkspaceProcessLock(workspaceDir(root), NATIVE_RUN_LOCK, async (claim) => {
133
- cancelled = null;
134
- const controller = new AbortController();
135
- cancellationSignal = controller.signal;
136
- const dispose = cancelOnInterrupt({
137
- root,
138
- claim,
139
- write,
140
- exit,
141
- controller
142
- });
143
- try {
144
- return await fn(claim);
145
- } finally {
146
- dispose();
147
- cancellationSignal = void 0;
148
- }
149
- }, {
150
- external: true,
151
- waitMs: NATIVE_RUN_WAIT_MS,
152
- declareSpawns: true,
153
- details: { ...details },
154
- onHeld: (holder) => notice(holder)
155
- });
156
- }
157
- //#endregion
158
- export { decideStopAction as a, nativeRunWaitNotice as c, runCancellationSignal as d, withNativeBuildRun as f, clearNativeRunCancel as i, requestNativeRunCancel as l, NATIVE_RUN_WAIT_MS as n, describeNativeRunHolder as o, cancelledFailure as r, nativeRunHolder as s, NATIVE_RUN_LOCK as t, runCancellation as u };
@@ -1,212 +0,0 @@
1
- import { _ as loadConfig$1, g as isPathPrefix, l as findEnclosingWorktreeRoot, p as getProject } from "./config-CgYMahz7.mjs";
2
- import { y as repoRoot } from "./worktree-CsKYexJM.mjs";
3
- import { basename, dirname, join, resolve } from "path";
4
- import { findProjectRoot, findProjectRoot as findProjectRoot$1 } from "@stim-cli/core/state";
5
- import { existsSync, readFileSync, realpathSync } from "fs";
6
- //#region src/workspace/project.ts
7
- /**
8
- * The realpath of `name`'s package.json in the nearest `node_modules` at or above `projectRoot`.
9
- * Unlike `require.resolve`, it ignores `NODE_PATH`, which pnpm's bin shims point at the workspace's
10
- * hidden hoist directory holding every member's dependencies.
11
- */
12
- function resolvePackageJson(projectRoot, name) {
13
- for (let dir = resolve(projectRoot);; dir = dirname(dir)) {
14
- const candidate = join(dir, "node_modules", name, "package.json");
15
- if (existsSync(candidate)) return realpathSync(candidate);
16
- if (dirname(dir) === dir) return null;
17
- }
18
- }
19
- function isPackageResolvable(projectRoot, name) {
20
- return resolvePackageJson(projectRoot, name) !== null;
21
- }
22
- function projectShortcut(path, proj) {
23
- if (proj?.label) return proj.label;
24
- const rootPath = findEnclosingWorktreeRoot(path);
25
- if (rootPath && rootPath !== path) return `${projectShortcut(rootPath, getProject(rootPath))}/${path.split("/").pop() || path}`;
26
- return path.split("/").pop() || path;
27
- }
28
- function ownedDeviceLabel(projectPath) {
29
- const app = realpathSync(projectPath);
30
- const root = repoRoot(app);
31
- const appLabel = basename(app);
32
- if (!root) return appLabel;
33
- const worktreeLabel = basename(realpathSync(root));
34
- return worktreeLabel === appLabel ? appLabel : `${worktreeLabel}-${appLabel}`;
35
- }
36
- const NO_PROJECT_REFUSAL = {
37
- code: "STIM_NO_PROJECT",
38
- message: "Not in a React Native project (no package.json found).",
39
- remedy: "Run this from the app directory -- the one holding package.json."
40
- };
41
- function findServerWorkspace(startDir) {
42
- const nearest = findProjectRoot(startDir);
43
- if (!nearest) return null;
44
- if (existsSync(join(nearest, "Package.swift"))) return {
45
- root: nearest,
46
- from: null
47
- };
48
- if (appProjectProblem(nearest)?.kind !== "not-an-app") return {
49
- root: nearest,
50
- from: null
51
- };
52
- if (Object.keys(getProject(nearest)?.ports ?? {}).length) return {
53
- root: nearest,
54
- from: null
55
- };
56
- const top = repoRoot(nearest);
57
- if (!top) return {
58
- root: nearest,
59
- from: null
60
- };
61
- const worktree = expandedRealpath(top);
62
- const apps = Object.keys(loadConfig$1()?.projects ?? {}).filter((path) => {
63
- if (path === nearest || !isPathPrefix(worktree, expandedRealpath(path)) || appProjectProblem(path) !== null) return false;
64
- const owner = repoRoot(path);
65
- return owner !== null && expandedRealpath(owner) === worktree;
66
- });
67
- return apps.length === 1 ? {
68
- root: apps[0],
69
- from: nearest
70
- } : {
71
- root: nearest,
72
- from: null
73
- };
74
- }
75
- function findCommandWorkspace(startDir, note = (line) => console.error(line)) {
76
- const workspace = findServerWorkspace(startDir);
77
- if (workspace?.from) note(`Using the Stim workspace ${workspace.root}: ${workspace.from} is not a React Native or Expo app.`);
78
- return workspace?.root ?? null;
79
- }
80
- function expandedRealpath(path) {
81
- try {
82
- return realpathSync.native(path);
83
- } catch {
84
- return resolve(path);
85
- }
86
- }
87
- function loadPackageJson(projectRoot) {
88
- const p = join(projectRoot, "package.json");
89
- if (!existsSync(p)) return {
90
- pkg: null,
91
- parseError: null
92
- };
93
- try {
94
- return {
95
- pkg: JSON.parse(readFileSync(p, "utf-8")),
96
- parseError: null
97
- };
98
- } catch (error) {
99
- return {
100
- pkg: null,
101
- parseError: error?.message || String(error)
102
- };
103
- }
104
- }
105
- function readPackageJson(projectRoot) {
106
- return loadPackageJson(projectRoot).pkg;
107
- }
108
- const APP_DEPENDENCIES = ["react-native", "expo"];
109
- function declaresAppDependency(pkg) {
110
- if (!pkg || typeof pkg !== "object") return false;
111
- const { dependencies, devDependencies } = pkg;
112
- const deps = {
113
- ...dependencies,
114
- ...devDependencies
115
- };
116
- return APP_DEPENDENCIES.some((name) => name in deps);
117
- }
118
- function appProjectProblem(projectRoot) {
119
- const file = join(projectRoot, "package.json");
120
- const { pkg, parseError } = loadPackageJson(projectRoot);
121
- if (parseError) return {
122
- kind: "unreadable",
123
- message: `${file} is not valid JSON (${parseError}), so Stim cannot tell whether this is a React Native or Expo app.`,
124
- remedy: `Fix the JSON in ${file} -- an unfinished edit or a merge conflict leaves it unparseable -- then run the command again.`
125
- };
126
- if (declaresAppDependency(pkg)) return null;
127
- return {
128
- kind: "not-an-app",
129
- message: `${file} depends on neither react-native nor expo, so this is not a React Native or Expo app.`,
130
- remedy: "Run this from the app directory -- the one whose package.json depends on react-native or expo -- or from that directory inside a worktree."
131
- };
132
- }
133
- function detectIsExpo(projectRoot) {
134
- const pkg = readPackageJson(projectRoot);
135
- const iosScript = pkg?.scripts?.ios;
136
- if (typeof iosScript === "string") {
137
- if (/\bexpo\s+run:ios\b/.test(iosScript)) return true;
138
- if (/\breact-native\s+run-ios\b/.test(iosScript)) return false;
139
- }
140
- if (!pkg) return false;
141
- const hasExpoDep = "expo" in {
142
- ...pkg.dependencies,
143
- ...pkg.devDependencies
144
- };
145
- const resolvable = () => isPackageResolvable(projectRoot, "expo");
146
- if (!hasExpoDep && !resolvable()) return false;
147
- const appJson = readAppJson(projectRoot);
148
- if (appJson?.expo) return true;
149
- const text = readAppConfigText(projectRoot);
150
- if (text && /\b(?:from\s+['"]expo['"]|expo\/config|ExpoConfig)\b/.test(text)) return true;
151
- if (hasExpoDep && resolvable()) return true;
152
- if (looksLikeExpoConfig(appJson)) return true;
153
- if (podfileUsesExpoModules(projectRoot)) return true;
154
- return false;
155
- }
156
- function detectTutorial(appJson) {
157
- const extra = appJson?.expo?.extra;
158
- const version = typeof extra === "object" && extra !== null ? extra.stimTutorial : null;
159
- return typeof version === "number" && Number.isInteger(version) && version > 0 ? { version } : void 0;
160
- }
161
- function looksLikeExpoConfig(appJson) {
162
- if (!appJson || typeof appJson !== "object" || Array.isArray(appJson)) return false;
163
- if (appJson.expo) return true;
164
- if ([
165
- "slug",
166
- "plugins",
167
- "sdkVersion",
168
- "experiments",
169
- "runtimeVersion",
170
- "updates",
171
- "buildCacheProvider",
172
- "assetBundlePatterns",
173
- "splash",
174
- "orientation",
175
- "userInterfaceStyle"
176
- ].some((key) => appJson[key] !== void 0)) return true;
177
- return Boolean(appJson.extra && typeof appJson.extra === "object" && appJson.extra.eas);
178
- }
179
- function podfileUsesExpoModules(projectRoot) {
180
- const p = join(projectRoot, "ios", "Podfile");
181
- if (!existsSync(p)) return false;
182
- try {
183
- return /^[^#\n]*use_expo_modules!/m.test(readFileSync(p, "utf-8"));
184
- } catch {
185
- return false;
186
- }
187
- }
188
- function readAppJson(projectRoot) {
189
- const p = join(projectRoot, "app.json");
190
- if (!existsSync(p)) return null;
191
- try {
192
- return JSON.parse(readFileSync(p, "utf-8"));
193
- } catch {
194
- return null;
195
- }
196
- }
197
- function readAppConfigText(projectRoot) {
198
- for (const name of [
199
- "app.config.js",
200
- "app.config.ts",
201
- "app.config.cjs",
202
- "app.config.mjs"
203
- ]) {
204
- const p = join(projectRoot, name);
205
- if (existsSync(p)) try {
206
- return readFileSync(p, "utf-8");
207
- } catch {}
208
- }
209
- return null;
210
- }
211
- //#endregion
212
- export { detectTutorial as a, findServerWorkspace as c, projectShortcut as d, readAppConfigText as f, resolvePackageJson as h, detectIsExpo as i, isPackageResolvable as l, readPackageJson as m, appProjectProblem as n, findCommandWorkspace as o, readAppJson as p, declaresAppDependency as r, findProjectRoot$1 as s, NO_PROJECT_REFUSAL as t, ownedDeviceLabel as u };
@@ -1,92 +0,0 @@
1
- import { f as readAppConfigText, i as detectIsExpo, l as isPackageResolvable, m as readPackageJson, p as readAppJson, r as declaresAppDependency } from "./project-C3ChRLZy.mjs";
2
- import { Ft as MODE_BARE, It as MODE_EXPO } from "./budget-DIhL2BKx.mjs";
3
- import { B as settingValueAt, W as webSettings } from "./settings-CQyMElEP.mjs";
4
- import { existsSync, readdirSync } from "node:fs";
5
- import { join } from "node:path";
6
- //#region src/integrations/projects.ts
7
- const expo = {
8
- mode: MODE_EXPO,
9
- loadDevServer: async () => (await import("./server-expo-Db9HBUoa.mjs")).startExpoServer,
10
- platforms(root) {
11
- const appJson = readAppJson(root);
12
- const config = appJson?.expo ?? appJson;
13
- const text = readAppConfigText(root);
14
- const explicit = (text ? literalPlatforms(text) : null) ?? config?.platforms;
15
- if (Array.isArray(explicit)) return explicit.filter((platform) => platform === "ios" || platform === "android" || platform === "web");
16
- const pkg = readPackageJson(root);
17
- return [
18
- "ios",
19
- "android",
20
- ..."react-native-web" in {
21
- ...pkg?.dependencies,
22
- ...pkg?.devDependencies
23
- } || isPackageResolvable(root, "react-native-web") ? ["web"] : []
24
- ];
25
- }
26
- };
27
- const reactNative = {
28
- mode: MODE_BARE,
29
- loadDevServer: async () => (await import("./server-bare-B9E7S1aR.mjs")).startBareServer,
30
- platforms(root) {
31
- if (!declaresAppDependency(readPackageJson(root))) return [];
32
- const platforms = [];
33
- let ios = [];
34
- try {
35
- ios = readdirSync(join(root, "ios"));
36
- } catch {}
37
- if (ios.some((name) => name.endsWith(".xcodeproj") || name.endsWith(".xcworkspace"))) platforms.push("ios");
38
- if ([
39
- "build.gradle",
40
- "build.gradle.kts",
41
- "settings.gradle",
42
- "settings.gradle.kts"
43
- ].some((name) => existsSync(join(root, "android", name)))) platforms.push("android");
44
- return platforms;
45
- }
46
- };
47
- const swiftPackage = { platforms(root, settings) {
48
- return existsSync(join(root, "Package.swift")) && settingValueAt(settings, "macos.product") && settingValueAt(settings, "macos.infoPlist") ? ["macos"] : [];
49
- } };
50
- const configuredWeb = { platforms(_root, settings) {
51
- return webSettings(settings).url !== null ? ["web"] : [];
52
- } };
53
- function nativeProjectIntegration(root, isExpo = detectIsExpo) {
54
- return isExpo(root) ? expo : reactNative;
55
- }
56
- function detectPlatforms(root, settings) {
57
- const integrations = [
58
- nativeProjectIntegration(root),
59
- swiftPackage,
60
- configuredWeb
61
- ];
62
- const platforms = new Set(integrations.flatMap((integration) => integration.platforms(root, settings)));
63
- return [
64
- "ios",
65
- "android",
66
- "macos",
67
- "web"
68
- ].filter((platform) => platforms.has(platform));
69
- }
70
- function literalPlatforms(text) {
71
- const tokens = text.match(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|[A-Za-z_$][\w$]*|[^\s]/g)?.filter((token) => !token.startsWith("//") && !token.startsWith("/*")) ?? [];
72
- let open = 0;
73
- const index = tokens.findIndex((token, i) => {
74
- if (token === "[") open++;
75
- else if (token === "]") open--;
76
- return open === 0 && (token === "platforms" || token === "\"platforms\"" || token === "'platforms'") && tokens[i + 1] === ":";
77
- });
78
- if (index < 0 || tokens[index + 2] !== "[") return null;
79
- const platforms = [];
80
- let i = index + 3;
81
- while (tokens[i] !== "]") {
82
- const value = tokens[i]?.match(/^(['"])([a-z]+)\1$/)?.[2];
83
- if (value === void 0) return null;
84
- platforms.push(value);
85
- i++;
86
- if (tokens[i] === ",") i++;
87
- else if (tokens[i] !== "]") return null;
88
- }
89
- return tokens[i + 1] === "," || tokens[i + 1] === "}" ? platforms : null;
90
- }
91
- //#endregion
92
- export { nativeProjectIntegration as n, detectPlatforms as t };
@@ -1,2 +0,0 @@
1
- import { p as startExpoServer } from "./server-expo-DoBHhuzK.mjs";
2
- export { startExpoServer };
@@ -1,48 +0,0 @@
1
- import { n as ownership_claim_exports, t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
2
- import { c as writeWorkspaceState, v as workspaceDir } from "./workspace-state-C59dqG-Z.mjs";
3
- import { a as withWorkspaceProcessLock } from "./named-ports-BFIz1Shz.mjs";
4
- import { a as requiredMacosRecord, i as macosRuntimeClaim } from "./state-xnqpx3AD.mjs";
5
- import { n as stopHostedMacos } from "./hosted-macos-B-wEjlwG.mjs";
6
- import { readMacosRecord } from "@stim-cli/core/state";
7
- //#region src/macos/stop.ts
8
- async function stopProcess(record) {
9
- if (!record) return;
10
- for (const signal of ["SIGTERM", "SIGKILL"]) {
11
- const identity = (0, process_identity_exports.inspectProcessIdentity)(record);
12
- if (identity === "gone" || identity === "different") return;
13
- if (identity !== "same") throw Object.assign(/* @__PURE__ */ new Error(`Cannot verify macOS owner pid ${record.pid}; no signal was sent.`), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
14
- process.kill(record.pid, signal);
15
- if (await (0, process_identity_exports.waitForProcessExit)(record, 5e3)) return;
16
- }
17
- throw new Error(`Owned macOS process ${record.pid} did not exit.`);
18
- }
19
- async function stopMacosAppHeld(root) {
20
- const record = requiredMacosRecord(root);
21
- if (!record) return false;
22
- await stopProcess(record.supervisor);
23
- await stopProcess(readMacosRecord(root)?.app ?? record.app);
24
- const claims = (0, ownership_claim_exports.readClaimSet)(macosRuntimeClaim(root));
25
- if (claims.unresolved.length || claims.live.length) throw Object.assign(/* @__PURE__ */ new Error("The macOS runtime claim cannot be released; inspect its recorded owner before cleanup."), { code: "STIM_MACOS_OWNER_UNVERIFIED" });
26
- return true;
27
- }
28
- /** Stops the workspace's app here, or its session on the hosting Mac, which must confirm the session stopped. */
29
- function stopMacosApp(root) {
30
- const stop = async () => {
31
- const record = requiredMacosRecord(root);
32
- if (!record?.host) return stopMacosAppHeld(root);
33
- await stopHostedMacos(root, record.host);
34
- const { host: _host, hostLaunched: _launched, ...stopped } = record;
35
- writeWorkspaceState(root, { macos: {
36
- ...stopped,
37
- supervisor: void 0
38
- } });
39
- return true;
40
- };
41
- return withWorkspaceProcessLock(workspaceDir(root), "macos-launch", stop, {
42
- external: true,
43
- waitMs: 0,
44
- ownerPurpose: "stop macOS app"
45
- });
46
- }
47
- //#endregion
48
- export { stopMacosAppHeld as n, stopMacosApp as t };
@@ -1,2 +0,0 @@
1
- import { t as triggerMaintenance } from "./trigger-CJMhwXe8.mjs";
2
- export { triggerMaintenance };
@@ -1,2 +0,0 @@
1
- import { n as runWeb, r as webCommand, t as resolveWebUrl } from "./web-DTU0uiWj.mjs";
2
- export { webCommand as default, resolveWebUrl, runWeb };