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.
- package/README.md +1 -1
- package/dist/{activity-BxnkDZDi.mjs → activity-BSw0x84R.mjs} +3 -3
- package/dist/{agent-device-usage-output-CZ66YA4T.mjs → agent-device-usage-output-Bjxu_VmX.mjs} +5 -5
- package/dist/{android-BvwuMUJ9.mjs → android-BXc6BmEi.mjs} +507 -347
- package/dist/{android-DC3ZLuw0.mjs → android-BdQC6zs1.mjs} +6 -6
- package/dist/{android-BKA16DTf.mjs → android-BvV1gGdN.mjs} +3 -3
- package/dist/{android-CBwCNicO.mjs → android-DE5g_5gv.mjs} +2 -2
- package/dist/{android-cas-BBFyr9CA.mjs → android-cas-C87geAg-.mjs} +3 -3
- package/dist/android-cas-compiler.mjs +1 -1
- package/dist/{api-D0VtFhqk.mjs → api-DIf_s86s.mjs} +5 -7
- package/dist/api-run.mjs +8 -8
- package/dist/api.d.mts +8 -2
- package/dist/api.mjs +1 -1
- package/dist/{app-install-D-PUENug.mjs → app-install-CFI4ptUL.mjs} +33 -13
- package/dist/{web-DTU0uiWj.mjs → browser-web-CDhqQxhv.mjs} +134 -172
- package/dist/{budget-DIhL2BKx.mjs → budget-Dz-kyXLv.mjs} +15 -202
- package/dist/{build-facts-DcLv2HSd.d.mts → build-facts-B87vo-Im.d.mts} +32 -1
- package/dist/{cache-manifest-BI7ozfmH.mjs → cache-manifest-DiwKSyv9.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-DJnmnS5q.mjs → chrome-BTUOo8p2.mjs} +1 -1
- package/dist/{cli-DNJMwADx.mjs → cli-C9Zvgbdc.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/{client-DzhapoMB.mjs → client-CuUo8Nvg.mjs} +248 -23
- package/dist/collector-run.d.mts +6 -0
- package/dist/collector-run.mjs +6 -6
- package/dist/{command-output-CBtzyIgF.mjs → command-output-Bt8ygHE7.mjs} +1 -1
- package/dist/{config-CgYMahz7.mjs → config-DC5jEtd1.mjs} +6 -2
- package/dist/{created-devices-DKbeWsiK.mjs → created-devices-D0s26Hx5.mjs} +2 -2
- package/dist/{dependency-state-xKoOypBm.mjs → dependency-state-DKaS1OM9.mjs} +2 -2
- package/dist/{detached-entry-BLfcgc4O.mjs → detached-entry-pB_IPfV4.mjs} +1 -1
- package/dist/{dev-client-CLnIH02x.mjs → dev-client-CDY_zAmD.mjs} +2 -2
- package/dist/{device-D7oCHGWi.mjs → device-BHw0WlHl.mjs} +8 -8
- package/dist/{device-capacity-EUOOYr8T.mjs → device-capacity-BoN1jQkO.mjs} +23 -12
- package/dist/device-host-worker.mjs +14 -14
- package/dist/{gradle-C6GKnunQ.mjs → device-ios-B2ruohE-.mjs} +659 -105
- package/dist/{device-lease-Co-EwifR.mjs → device-lease-Cu7PtQpZ.mjs} +5 -5
- package/dist/{device-lease-run-w1xhCqIW.mjs → device-lease-run-D38SnZtt.mjs} +4 -4
- package/dist/{device-pool-F5WvRPtD.mjs → device-pool-CP4rAsHx.mjs} +3 -3
- package/dist/{device-remote-tHbd1fKy.mjs → device-remote-B5GiUifk.mjs} +15 -16
- package/dist/{doctor-B9ckYUoU.mjs → doctor-PRJH94v6.mjs} +53 -29
- package/dist/doctor-watchman-wZhyTdp4.mjs +259 -0
- package/dist/{error-diagnostics-BRXOqDzG.mjs → error-diagnostics--v5HGOU0.mjs} +10 -10
- package/dist/{exec-DWhCZDGm.mjs → exec-i8GDPwq9.mjs} +32 -8
- package/dist/{gc-Dh6mXOKC.mjs → gc-CyHMcKcn.mjs} +19 -19
- package/dist/{guide-tm6igAaa.mjs → guide-dRaQJJk9.mjs} +409 -472
- package/dist/{hosted-android-Bv285t_t.mjs → hosted-android-Bs7fytj7.mjs} +3 -3
- package/dist/{hosted-client-C-rMtppF.mjs → hosted-client-C5G4h_OJ.mjs} +1 -1
- package/dist/{hosted-ios-D5mNmtj4.mjs → hosted-ios-Bik035eL.mjs} +1 -1
- package/dist/{hosted-logs-DN8Iz4mJ.mjs → hosted-logs-CI9Az9a4.mjs} +7 -7
- package/dist/{hosted-macos-B-wEjlwG.mjs → hosted-macos-DABm3ScO.mjs} +4 -4
- package/dist/{hosted-native-DeeOG8xZ.mjs → hosted-native-DbV2aUVw.mjs} +12 -8
- package/dist/{idle-shutdown-jjtxAn5C.mjs → idle-shutdown-DYiMBn34.mjs} +7 -7
- package/dist/{ios-B3SbOWdw.mjs → ios-BWbHFZVz.mjs} +5 -5
- package/dist/{ios-Bvbf0SGY.mjs → ios-DCrkgXEM.mjs} +1 -1
- package/dist/{ios-DNpdygiv.mjs → ios-DYUr9LGc.mjs} +7 -6
- package/dist/ios-ITYno9rO.mjs +2241 -0
- package/dist/{ios-device-vOaByMhw.mjs → ios-device-CJ_ZOGky.mjs} +3 -3
- package/dist/{ios-device-Bn7jWDB1.mjs → ios-device-CrW8aMb5.mjs} +1 -1
- package/dist/{ios-state-B2pES6Vs.mjs → ios-state-By0XuLTQ.mjs} +1 -1
- package/dist/{launch-verify-hskNcWkZ.mjs → launch-verify-DCveSE6d.mjs} +4 -4
- package/dist/{logs-1Ylc1Ri6.mjs → logs-Bao1HOMy.mjs} +10 -10
- package/dist/{macos-DF6C7wUU.mjs → macos-ciyBdTY5.mjs} +108 -130
- package/dist/macos-nIOATJmR.mjs +2 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +7 -7
- package/dist/manifest-CX0d1IkZ.mjs +148 -0
- package/dist/{metro-Dh8T4Ytd.mjs → metro-DI2AjPF_.mjs} +194 -41
- package/dist/{metro-gateway-CEUw9RMH.mjs → metro-gateway-BxpJLIwh.mjs} +2 -2
- package/dist/{plan-placement-CtxkCO54.mjs → miss-reason-CjQCOKqq.mjs} +180 -296
- package/dist/{named-ports-BFIz1Shz.mjs → named-ports-B4iWH4E-.mjs} +12 -5
- package/dist/{native-runtime-D_603JiC.mjs → native-runtime-BGxsbfny.mjs} +6 -6
- package/dist/offload-worker.d.mts +1 -29
- package/dist/offload-worker.mjs +9 -8
- package/dist/{ownership-D6Se7gg_.mjs → ownership-EB0ySdGK.mjs} +2 -2
- package/dist/{placement-log-BcPhRwR4.mjs → placement-log-Dxe34rJm.mjs} +7 -3
- package/dist/plan-placement-BVY59qa8.mjs +290 -0
- package/dist/{ports-BLTtfBq-.mjs → ports-ByPc0_97.mjs} +3 -3
- package/dist/{prebuild-juCyreaR.mjs → prebuild-BKJ3wJI1.mjs} +4 -4
- package/dist/{preview-D5V07Nrl.mjs → preview-BbSottmO.mjs} +16 -17
- package/dist/project-B5eQ1USs.mjs +612 -0
- package/dist/{pull-request-u4vp7zmK.mjs → pull-request-IHNdMnG8.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/react-native-ios-BMh2i25I.mjs +2 -0
- package/dist/react-native-ios-CSpIxexZ.mjs +2083 -0
- package/dist/{recordings-BAWltsVt.mjs → recordings-Bv8McZN4.mjs} +1 -1
- package/dist/{reload-DvyWzVjJ.mjs → reload-rAPdqeRR.mjs} +13 -14
- package/dist/{remote-cache-BGg7aGIZ.mjs → remote-cache-N3hAEaAL.mjs} +4 -4
- package/dist/{run-vhtDgpHO.mjs → run-lAkle1-c.mjs} +2 -2
- package/dist/{server-bare-B9E7S1aR.mjs → server-bare-CkIjnegq.mjs} +3 -3
- package/dist/server-expo-DGsdUGX2.mjs +2 -0
- package/dist/{server-expo-DoBHhuzK.mjs → server-expo-n3tUi3Em.mjs} +3 -3
- package/dist/{settings-Byp2AQ_E.mjs → settings-2am7TSxp.mjs} +5 -6
- package/dist/{settings-CQyMElEP.mjs → settings-CxgngUZk.mjs} +767 -15
- package/dist/settings.schema.json +72 -6
- package/dist/{simslim-EHBQ2R4G.mjs → simslim-D9LkJxIO.mjs} +5 -5
- package/dist/{slot-launch-C1nqh4mu.mjs → slot-launch-HV_KtPIw.mjs} +6 -6
- package/dist/{stage-g_WqWeaE.mjs → stage-BgaZJVZY.mjs} +1 -1
- package/dist/{start-NTc1Ifqs.mjs → start-D8NbxNBb.mjs} +1 -1
- package/dist/{start-D-IeOyoK.mjs → start-DtxthMfI.mjs} +29 -22
- package/dist/{state-BG-aAk4k.mjs → state-D2KtnALG.mjs} +2 -2
- package/dist/{state-xnqpx3AD.mjs → state-Tp4uImDS.mjs} +4 -2
- package/dist/{stats-DY6ekz8F.mjs → stats-8EJ5ivFT.mjs} +6 -6
- package/dist/{status-DCjZeE-K.mjs → status-BOyp0CUl.mjs} +25 -27
- package/dist/{stim-desktop-Behws_fi.mjs → stim-desktop-C65jk_q2.mjs} +1 -1
- package/dist/{stim-installations-aR_WsNOA.mjs → stim-installations-DbmUjsLv.mjs} +1 -1
- package/dist/stop-D0UIpZuh.mjs +72 -0
- package/dist/{stop-DIJtD2GL.mjs → stop-DRipAg-e.mjs} +2 -2
- package/dist/{stop-BTjs3xbc.mjs → stop-zDlknFoz.mjs} +78 -31
- package/dist/supervisor-run.mjs +14 -14
- package/dist/{support-BaayeYCf.mjs → support-CNqYkV0y.mjs} +7 -7
- package/dist/{support-Bwvbrq5-.mjs → support-DsNaFg6D.mjs} +5 -5
- package/dist/swiftpm-macos-aJzPAj1t.mjs +119 -0
- package/dist/{toolchain-Bnyd_K3A.mjs → toolchain-C3xSoyUl.mjs} +27 -270
- package/dist/{trigger-CJMhwXe8.mjs → trigger-CAhmG-4s.mjs} +3 -3
- package/dist/trigger-CoalsMTV.mjs +2 -0
- package/dist/{warm-progress-CjB-MP6H.mjs → warm-progress-pFLB2e6P.mjs} +133 -36
- package/dist/{status-Dcr0Qexd.mjs → watchman-BL1IdOtq.mjs} +75 -7
- package/dist/web-DFpFeZu5.mjs +2 -0
- package/dist/web-DbbrPUn0.mjs +127 -0
- package/dist/web-run.mjs +7 -7
- package/dist/{workspace-state-C59dqG-Z.mjs → workspace-state-CR9X86xJ.mjs} +1 -1
- package/dist/{workspaces-xXItD8Dj.mjs → workspaces-Djb2gfi9.mjs} +102 -18
- package/dist/{worktree-BSYlofkq.mjs → worktree-BL4M1rhB.mjs} +45 -42
- package/dist/{worktree-BJfnU6r5.mjs → worktree-DV-A0LNL.mjs} +1 -1
- package/package.json +5 -5
- package/shim/bundle-response.cjs +2 -1
- package/shim/bundle-response.d.cts +1 -1
- package/shim/expo-metro-config.cjs +1 -1
- package/dist/device-ios-6MewKKnc.mjs +0 -412
- package/dist/guide-status-Bhf9SJXc.mjs +0 -125
- package/dist/ios-CPdkoKaa.mjs +0 -3953
- package/dist/macos-Ck7OBMNY.mjs +0 -2
- package/dist/native-run-B06FkmZx.mjs +0 -158
- package/dist/project-C3ChRLZy.mjs +0 -212
- package/dist/projects-DD7dBTCj.mjs +0 -92
- package/dist/server-expo-Db9HBUoa.mjs +0 -2
- package/dist/stop-BGhKMOuH.mjs +0 -48
- package/dist/trigger-DWAq9hkw.mjs +0 -2
- package/dist/web-B6_bFDn7.mjs +0 -2
- package/dist/worktree-CsKYexJM.mjs +0 -753
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
import { t as process_identity_exports } from "./process-identity-Biv3arCO.mjs";
|
|
2
|
+
import { B as parseDeviceSlotKey, R as deviceSlotKey, _ as loadConfig$1, g as isPathPrefix, l as findEnclosingWorktreeRoot, p as getProject } from "./config-DC5jEtd1.mjs";
|
|
3
|
+
import { C as workspaceStateFile, a as updateWorkspaceState, h as supervisorPidFile, o as withWorkspaceStateLock, r as readWorkspaceState$1, t as clearWorkspaceStateKey } from "./workspace-state-CR9X86xJ.mjs";
|
|
4
|
+
import { G as webSettings, V as settingValueAt, mt as repoRoot } from "./settings-CxgngUZk.mjs";
|
|
5
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { dirname, join, resolve } from "node:path";
|
|
7
|
+
import { basename as basename$1, dirname as dirname$1, join as join$1, resolve as resolve$1 } from "path";
|
|
8
|
+
import { projectRootDirectories } from "@stim-cli/core/state";
|
|
9
|
+
import { existsSync as existsSync$1, readFileSync as readFileSync$1, realpathSync as realpathSync$1 } from "fs";
|
|
10
|
+
//#region src/supervisor/state.ts
|
|
11
|
+
const MODE_BARE = "bare-inproc";
|
|
12
|
+
const MODE_EXPO = "expo-child";
|
|
13
|
+
function readMetroTunnel(root) {
|
|
14
|
+
const record = readWorkspaceState$1(root)?.metroTunnel;
|
|
15
|
+
if (!record || typeof record !== "object") return null;
|
|
16
|
+
const kind = record.kind;
|
|
17
|
+
const url = record.url;
|
|
18
|
+
if (typeof url !== "string" || url.length === 0) return null;
|
|
19
|
+
if (kind === "expo") return {
|
|
20
|
+
kind: "expo",
|
|
21
|
+
url
|
|
22
|
+
};
|
|
23
|
+
if (kind === "managed") {
|
|
24
|
+
const provider = record.provider;
|
|
25
|
+
const pid = record.pid;
|
|
26
|
+
const port = record.port;
|
|
27
|
+
const startedAt = record.startedAt;
|
|
28
|
+
const processToken = record.processToken;
|
|
29
|
+
const logFile = record.logFile;
|
|
30
|
+
if (provider !== "ngrok" && provider !== "cloudflared" && provider !== "tailscale" || typeof pid !== "number" || typeof port !== "number") return null;
|
|
31
|
+
return {
|
|
32
|
+
kind: "managed",
|
|
33
|
+
provider,
|
|
34
|
+
pid,
|
|
35
|
+
url,
|
|
36
|
+
port,
|
|
37
|
+
startedAt: typeof startedAt === "string" ? startedAt : "",
|
|
38
|
+
processToken: typeof processToken === "string" && processToken.length > 0 ? processToken : null,
|
|
39
|
+
...typeof logFile === "string" && logFile.length > 0 ? { logFile } : {}
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
function parseWorkspaceLaunchRecord(value) {
|
|
45
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return null;
|
|
46
|
+
const record = value;
|
|
47
|
+
if (typeof record.appId !== "string" || record.appId.length === 0) return null;
|
|
48
|
+
if (typeof record.deviceId !== "string" || record.deviceId.length === 0) return null;
|
|
49
|
+
if (record.metroPort !== null && typeof record.metroPort !== "number") return null;
|
|
50
|
+
if (typeof record.release !== "boolean") return null;
|
|
51
|
+
if (typeof record.launchedAt !== "string") return null;
|
|
52
|
+
return record;
|
|
53
|
+
}
|
|
54
|
+
function readWorkspaceLaunches(root) {
|
|
55
|
+
const launches = readWorkspaceState$1(root)?.launches;
|
|
56
|
+
if (!launches || typeof launches !== "object" || Array.isArray(launches)) return {};
|
|
57
|
+
const records = {};
|
|
58
|
+
for (const [key, value] of Object.entries(launches)) {
|
|
59
|
+
const record = parseWorkspaceLaunchRecord(value);
|
|
60
|
+
if (parseDeviceSlotKey(key) && record) records[key] = record;
|
|
61
|
+
}
|
|
62
|
+
return records;
|
|
63
|
+
}
|
|
64
|
+
function writeWorkspaceLaunch(root, platform, record, slot = "default") {
|
|
65
|
+
updateWorkspaceState(root, (state) => {
|
|
66
|
+
const launches = state.launches && typeof state.launches === "object" ? state.launches : {};
|
|
67
|
+
return {
|
|
68
|
+
...state,
|
|
69
|
+
launches: {
|
|
70
|
+
...launches,
|
|
71
|
+
[deviceSlotKey(platform, slot)]: record
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
function clearWorkspaceLaunches(root, slot) {
|
|
77
|
+
updateWorkspaceState(root, (state) => {
|
|
78
|
+
if (!state.launches || typeof state.launches !== "object") return state;
|
|
79
|
+
const launches = { ...state.launches };
|
|
80
|
+
delete launches[deviceSlotKey("ios", slot)];
|
|
81
|
+
delete launches[deviceSlotKey("android", slot)];
|
|
82
|
+
return {
|
|
83
|
+
...state,
|
|
84
|
+
launches
|
|
85
|
+
};
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
function readRemoteSession(root) {
|
|
89
|
+
const record = readWorkspaceState$1(root)?.remoteDevice;
|
|
90
|
+
if (!record || typeof record !== "object") return null;
|
|
91
|
+
const id = record.sessionId;
|
|
92
|
+
if (typeof id !== "string" || id.length === 0) return null;
|
|
93
|
+
const platform = record.platform;
|
|
94
|
+
const startedAt = record.startedAt;
|
|
95
|
+
const webPreviewUrl = record.webPreviewUrl;
|
|
96
|
+
const deviceType = record.deviceType;
|
|
97
|
+
return {
|
|
98
|
+
platform: platform === "ios" || platform === "android" ? platform : null,
|
|
99
|
+
sessionId: id,
|
|
100
|
+
startedAt: typeof startedAt === "string" ? startedAt : null,
|
|
101
|
+
webPreviewUrl: typeof webPreviewUrl === "string" && webPreviewUrl.length > 0 ? webPreviewUrl : null,
|
|
102
|
+
deviceType: typeof deviceType === "string" && deviceType.length > 0 ? deviceType : null
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function readRemoteSessionId(root) {
|
|
106
|
+
return readRemoteSession(root)?.sessionId ?? null;
|
|
107
|
+
}
|
|
108
|
+
function clearRemoteSession(root, expectedSessionId) {
|
|
109
|
+
clearWorkspaceStateKey(root, "remoteDevice", (value) => {
|
|
110
|
+
if (typeof value !== "object" || value === null) return false;
|
|
111
|
+
return value.sessionId === expectedSessionId;
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
function clearWorkspaceSupervisor(root, expected) {
|
|
115
|
+
return withWorkspaceStateLock(root, () => {
|
|
116
|
+
const current = readWorkspaceState$1(root)?.supervisor;
|
|
117
|
+
if (current && expected !== void 0 && !(0, process_identity_exports.sameProcessRecord)(current, expected)) return false;
|
|
118
|
+
clearWorkspaceStateKey(root, "supervisor", () => true);
|
|
119
|
+
clearExpoMetroTunnel(root);
|
|
120
|
+
if (expected === void 0 || readPidFile(root) === expected?.pid) rmSync(supervisorPidFile(root), { force: true });
|
|
121
|
+
return true;
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function clearExpoMetroTunnel(root) {
|
|
125
|
+
clearWorkspaceStateKey(root, "metroTunnel", (value) => {
|
|
126
|
+
return typeof value === "object" && value !== null && value.kind === "expo";
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
function clearManagedMetroTunnel(root, expected) {
|
|
130
|
+
if (!existsSync(workspaceStateFile(root))) return true;
|
|
131
|
+
return clearWorkspaceStateKey(root, "metroTunnel", (value) => {
|
|
132
|
+
if (typeof value !== "object" || value === null) return false;
|
|
133
|
+
const record = value;
|
|
134
|
+
return record.kind === "managed" && record.provider === expected.provider && record.pid === expected.pid && record.url === expected.url && record.port === expected.port && record.startedAt === expected.startedAt && (record.processToken ?? null) === (expected.processToken ?? null) && (record.logFile ?? null) === (expected.logFile ?? null);
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
function writePidFile(root, pid) {
|
|
138
|
+
const file = supervisorPidFile(root);
|
|
139
|
+
mkdirSync(dirname(file), { recursive: true });
|
|
140
|
+
writeFileSync(file, `${pid}\n`);
|
|
141
|
+
return file;
|
|
142
|
+
}
|
|
143
|
+
function readPidFile(root) {
|
|
144
|
+
try {
|
|
145
|
+
const pid = parseInt(readFileSync(supervisorPidFile(root), "utf-8").trim(), 10);
|
|
146
|
+
return Number.isFinite(pid) ? pid : null;
|
|
147
|
+
} catch {
|
|
148
|
+
return null;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
//#region src/workspace/project-files.ts
|
|
153
|
+
/**
|
|
154
|
+
* The realpath of `name`'s package.json in the nearest `node_modules` at or above `projectRoot`.
|
|
155
|
+
* Unlike `require.resolve`, it ignores `NODE_PATH`, which pnpm's bin shims point at the workspace's
|
|
156
|
+
* hidden hoist directory holding every member's dependencies.
|
|
157
|
+
*/
|
|
158
|
+
function resolvePackageJson(projectRoot, name) {
|
|
159
|
+
for (let dir = resolve$1(projectRoot);; dir = dirname$1(dir)) {
|
|
160
|
+
const candidate = join$1(dir, "node_modules", name, "package.json");
|
|
161
|
+
if (existsSync$1(candidate)) return realpathSync$1(candidate);
|
|
162
|
+
if (dirname$1(dir) === dir) return null;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function isPackageResolvable(projectRoot, name) {
|
|
166
|
+
return resolvePackageJson(projectRoot, name) !== null;
|
|
167
|
+
}
|
|
168
|
+
function loadPackageJson(projectRoot) {
|
|
169
|
+
const p = join$1(projectRoot, "package.json");
|
|
170
|
+
if (!existsSync$1(p)) return {
|
|
171
|
+
pkg: null,
|
|
172
|
+
parseError: null
|
|
173
|
+
};
|
|
174
|
+
try {
|
|
175
|
+
return {
|
|
176
|
+
pkg: JSON.parse(readFileSync$1(p, "utf-8")),
|
|
177
|
+
parseError: null
|
|
178
|
+
};
|
|
179
|
+
} catch (error) {
|
|
180
|
+
return {
|
|
181
|
+
pkg: null,
|
|
182
|
+
parseError: error?.message || String(error)
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
function readPackageJson(projectRoot) {
|
|
187
|
+
return loadPackageJson(projectRoot).pkg;
|
|
188
|
+
}
|
|
189
|
+
const APP_DEPENDENCIES = ["react-native", "expo"];
|
|
190
|
+
function declaresAppDependency(pkg) {
|
|
191
|
+
if (!pkg || typeof pkg !== "object") return false;
|
|
192
|
+
const { dependencies, devDependencies } = pkg;
|
|
193
|
+
const deps = {
|
|
194
|
+
...dependencies,
|
|
195
|
+
...devDependencies
|
|
196
|
+
};
|
|
197
|
+
return APP_DEPENDENCIES.some((name) => name in deps);
|
|
198
|
+
}
|
|
199
|
+
function appProjectProblem(projectRoot, { pkg, parseError } = loadPackageJson(projectRoot)) {
|
|
200
|
+
const file = join$1(projectRoot, "package.json");
|
|
201
|
+
if (parseError) return {
|
|
202
|
+
kind: "unreadable",
|
|
203
|
+
message: `${file} is not valid JSON (${parseError}), so Stim cannot tell whether this is a React Native or Expo app.`,
|
|
204
|
+
remedy: `Fix the JSON in ${file} -- an unfinished edit or a merge conflict leaves it unparseable -- then run the command again.`
|
|
205
|
+
};
|
|
206
|
+
if (declaresAppDependency(pkg)) return null;
|
|
207
|
+
return {
|
|
208
|
+
kind: "not-an-app",
|
|
209
|
+
message: `${file} depends on neither react-native nor expo, so this is not a React Native or Expo app.`,
|
|
210
|
+
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."
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function detectIsExpo(projectRoot) {
|
|
214
|
+
const pkg = readPackageJson(projectRoot);
|
|
215
|
+
const iosScript = pkg?.scripts?.ios;
|
|
216
|
+
if (typeof iosScript === "string") {
|
|
217
|
+
if (/\bexpo\s+run:ios\b/.test(iosScript)) return true;
|
|
218
|
+
if (/\breact-native\s+run-ios\b/.test(iosScript)) return false;
|
|
219
|
+
}
|
|
220
|
+
if (!pkg) return false;
|
|
221
|
+
const hasExpoDep = "expo" in {
|
|
222
|
+
...pkg.dependencies,
|
|
223
|
+
...pkg.devDependencies
|
|
224
|
+
};
|
|
225
|
+
const resolvable = () => isPackageResolvable(projectRoot, "expo");
|
|
226
|
+
if (!hasExpoDep && !resolvable()) return false;
|
|
227
|
+
const appJson = readAppJson(projectRoot);
|
|
228
|
+
if (appJson?.expo) return true;
|
|
229
|
+
const text = readAppConfigText(projectRoot);
|
|
230
|
+
if (text && /\b(?:from\s+['"]expo['"]|expo\/config|ExpoConfig)\b/.test(text)) return true;
|
|
231
|
+
if (hasExpoDep && resolvable()) return true;
|
|
232
|
+
if (looksLikeExpoConfig(appJson)) return true;
|
|
233
|
+
if (podfileUsesExpoModules(projectRoot)) return true;
|
|
234
|
+
return false;
|
|
235
|
+
}
|
|
236
|
+
function detectTutorial(appJson) {
|
|
237
|
+
const extra = appJson?.expo?.extra;
|
|
238
|
+
const version = typeof extra === "object" && extra !== null ? extra.stimTutorial : null;
|
|
239
|
+
return typeof version === "number" && Number.isInteger(version) && version > 0 ? { version } : void 0;
|
|
240
|
+
}
|
|
241
|
+
function looksLikeExpoConfig(appJson) {
|
|
242
|
+
if (!appJson || typeof appJson !== "object" || Array.isArray(appJson)) return false;
|
|
243
|
+
if (appJson.expo) return true;
|
|
244
|
+
if ([
|
|
245
|
+
"slug",
|
|
246
|
+
"plugins",
|
|
247
|
+
"sdkVersion",
|
|
248
|
+
"experiments",
|
|
249
|
+
"runtimeVersion",
|
|
250
|
+
"updates",
|
|
251
|
+
"buildCacheProvider",
|
|
252
|
+
"assetBundlePatterns",
|
|
253
|
+
"splash",
|
|
254
|
+
"orientation",
|
|
255
|
+
"userInterfaceStyle"
|
|
256
|
+
].some((key) => appJson[key] !== void 0)) return true;
|
|
257
|
+
return Boolean(appJson.extra && typeof appJson.extra === "object" && appJson.extra.eas);
|
|
258
|
+
}
|
|
259
|
+
function podfileUsesExpoModules(projectRoot) {
|
|
260
|
+
const p = join$1(projectRoot, "ios", "Podfile");
|
|
261
|
+
if (!existsSync$1(p)) return false;
|
|
262
|
+
try {
|
|
263
|
+
return /^[^#\n]*use_expo_modules!/m.test(readFileSync$1(p, "utf-8"));
|
|
264
|
+
} catch {
|
|
265
|
+
return false;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
function readAppJson(projectRoot) {
|
|
269
|
+
const p = join$1(projectRoot, "app.json");
|
|
270
|
+
if (!existsSync$1(p)) return null;
|
|
271
|
+
try {
|
|
272
|
+
return JSON.parse(readFileSync$1(p, "utf-8"));
|
|
273
|
+
} catch {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function readAppConfigText(projectRoot) {
|
|
278
|
+
for (const name of [
|
|
279
|
+
"app.config.js",
|
|
280
|
+
"app.config.ts",
|
|
281
|
+
"app.config.cjs",
|
|
282
|
+
"app.config.mjs"
|
|
283
|
+
]) {
|
|
284
|
+
const p = join$1(projectRoot, name);
|
|
285
|
+
if (existsSync$1(p)) try {
|
|
286
|
+
return readFileSync$1(p, "utf-8");
|
|
287
|
+
} catch {}
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
//#endregion
|
|
292
|
+
//#region src/integrations/project-registry.ts
|
|
293
|
+
function canonicalPath(path) {
|
|
294
|
+
try {
|
|
295
|
+
return realpathSync(resolve(path));
|
|
296
|
+
} catch {
|
|
297
|
+
return resolve(path);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function operationSelection(root, matches, operation) {
|
|
301
|
+
const results = matches.flatMap((match) => {
|
|
302
|
+
const problem = match.validate?.(operation);
|
|
303
|
+
return problem === void 0 ? [] : [{
|
|
304
|
+
match,
|
|
305
|
+
problem
|
|
306
|
+
}];
|
|
307
|
+
});
|
|
308
|
+
const unreadable = results.find(({ problem }) => problem?.kind === "unreadable");
|
|
309
|
+
if (unreadable?.problem) return { problem: unreadable.problem };
|
|
310
|
+
const providers = results.filter(({ problem }) => problem === null);
|
|
311
|
+
if (providers.length > 1) return { problem: {
|
|
312
|
+
kind: "ambiguous",
|
|
313
|
+
message: `Multiple project integrations support ${operation} at ${root}: ${providers.map(({ match }) => match.id).join(", ")}.`,
|
|
314
|
+
remedy: "Run this from the directory of the app you intend to use, with one integration for this operation."
|
|
315
|
+
} };
|
|
316
|
+
if (providers.length === 1) return { match: providers[0].match };
|
|
317
|
+
return { problem: results[0]?.problem ?? {
|
|
318
|
+
kind: "not-an-app",
|
|
319
|
+
message: `No project integration supports ${operation} at ${root}.`,
|
|
320
|
+
remedy: "Run this from the directory of a supported app."
|
|
321
|
+
} };
|
|
322
|
+
}
|
|
323
|
+
function operationProblem(root, matches, operation) {
|
|
324
|
+
const selected = operationSelection(root, matches, operation);
|
|
325
|
+
return "problem" in selected ? selected.problem : null;
|
|
326
|
+
}
|
|
327
|
+
function createProjectRegistry(integrations) {
|
|
328
|
+
const inspect = (root) => integrations.flatMap((integration) => {
|
|
329
|
+
const match = integration.inspect(root);
|
|
330
|
+
return match ? [{
|
|
331
|
+
id: integration.id,
|
|
332
|
+
...match
|
|
333
|
+
}] : [];
|
|
334
|
+
});
|
|
335
|
+
function findProjectRoot(startDir, read = inspect) {
|
|
336
|
+
let candidates = [];
|
|
337
|
+
for (const root of projectRootDirectories(startDir)) {
|
|
338
|
+
const matches = read(root);
|
|
339
|
+
const owned = new Set(matches.flatMap((match) => match.ownedRoots ?? []).map(canonicalPath));
|
|
340
|
+
candidates = candidates.filter((candidate) => !owned.has(candidate));
|
|
341
|
+
if (matches.some((match) => match.root === "explicit")) return candidates[0] ?? root;
|
|
342
|
+
if (matches.some((match) => match.root === "candidate")) candidates.push(root);
|
|
343
|
+
}
|
|
344
|
+
return candidates[0] ?? null;
|
|
345
|
+
}
|
|
346
|
+
function ownedRootProblem(root, matches) {
|
|
347
|
+
if (matches.some((match) => match.root === "candidate") && !matches.some((match) => match.root === "explicit")) {
|
|
348
|
+
const owner = findProjectRoot(root, (dir) => dir === root ? matches : inspect(dir));
|
|
349
|
+
if (owner !== null && owner !== root) return {
|
|
350
|
+
kind: "not-an-app",
|
|
351
|
+
message: `${root} belongs to the project at ${owner}.`,
|
|
352
|
+
remedy: `Run this from ${owner}.`
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
return null;
|
|
356
|
+
}
|
|
357
|
+
function projectProblem(root, operation) {
|
|
358
|
+
root = canonicalPath(root);
|
|
359
|
+
const matches = inspect(root);
|
|
360
|
+
return ownedRootProblem(root, matches) ?? operationProblem(root, matches, operation);
|
|
361
|
+
}
|
|
362
|
+
function selectMacos(root) {
|
|
363
|
+
root = canonicalPath(root);
|
|
364
|
+
const matches = inspect(root);
|
|
365
|
+
const problem = ownedRootProblem(root, matches);
|
|
366
|
+
if (problem) return { problem };
|
|
367
|
+
const selected = operationSelection(root, matches, "macos");
|
|
368
|
+
if ("problem" in selected) return selected;
|
|
369
|
+
if (selected.match.macos) return { load: selected.match.macos };
|
|
370
|
+
return { problem: {
|
|
371
|
+
kind: "not-an-app",
|
|
372
|
+
message: `The ${selected.match.id} integration does not provide a macOS operation.`,
|
|
373
|
+
remedy: "Use an integration with a macOS build recipe."
|
|
374
|
+
} };
|
|
375
|
+
}
|
|
376
|
+
function selectWeb(root) {
|
|
377
|
+
root = canonicalPath(root);
|
|
378
|
+
const matches = inspect(root);
|
|
379
|
+
const problem = ownedRootProblem(root, matches);
|
|
380
|
+
if (problem) return { problem };
|
|
381
|
+
const selected = operationSelection(root, matches, "web");
|
|
382
|
+
if ("problem" in selected) return selected;
|
|
383
|
+
if (selected.match.web) return { load: selected.match.web };
|
|
384
|
+
return { problem: {
|
|
385
|
+
kind: "not-an-app",
|
|
386
|
+
message: `The ${selected.match.id} integration does not provide a web operation.`,
|
|
387
|
+
remedy: "Use an integration with a web runtime recipe."
|
|
388
|
+
} };
|
|
389
|
+
}
|
|
390
|
+
function selectIos(root) {
|
|
391
|
+
root = canonicalPath(root);
|
|
392
|
+
const matches = inspect(root);
|
|
393
|
+
const problem = ownedRootProblem(root, matches);
|
|
394
|
+
if (problem) return { problem };
|
|
395
|
+
const selected = operationSelection(root, matches, "ios");
|
|
396
|
+
if ("problem" in selected) return selected;
|
|
397
|
+
if (selected.match.ios) return { load: selected.match.ios };
|
|
398
|
+
return { problem: {
|
|
399
|
+
kind: "not-an-app",
|
|
400
|
+
message: `The ${selected.match.id} integration does not provide an iOS operation.`,
|
|
401
|
+
remedy: "Use an integration with an iOS build and runtime recipe."
|
|
402
|
+
} };
|
|
403
|
+
}
|
|
404
|
+
function isMobileProject(root) {
|
|
405
|
+
root = canonicalPath(root);
|
|
406
|
+
const matches = inspect(root);
|
|
407
|
+
return ownedRootProblem(root, matches) === null && (operationProblem(root, matches, "ios") === null || operationProblem(root, matches, "android") === null);
|
|
408
|
+
}
|
|
409
|
+
function keepsWorkspace(root) {
|
|
410
|
+
const matches = inspect(root);
|
|
411
|
+
return matches.some((match) => match.application) || [
|
|
412
|
+
"ios",
|
|
413
|
+
"android",
|
|
414
|
+
"dev-server"
|
|
415
|
+
].some((operation) => operationProblem(root, matches, operation)?.kind === "unreadable");
|
|
416
|
+
}
|
|
417
|
+
function detectPlatforms(root, settings) {
|
|
418
|
+
const platforms = new Set(inspect(root).flatMap((match) => match.platforms(settings)));
|
|
419
|
+
return [
|
|
420
|
+
"ios",
|
|
421
|
+
"android",
|
|
422
|
+
"macos",
|
|
423
|
+
"web"
|
|
424
|
+
].filter((platform) => platforms.has(platform));
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
findProjectRoot,
|
|
428
|
+
projectProblem,
|
|
429
|
+
selectIos,
|
|
430
|
+
selectMacos,
|
|
431
|
+
selectWeb,
|
|
432
|
+
isMobileProject,
|
|
433
|
+
keepsWorkspace,
|
|
434
|
+
detectPlatforms
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
//#endregion
|
|
438
|
+
//#region src/integrations/projects.ts
|
|
439
|
+
const expo = {
|
|
440
|
+
mode: MODE_EXPO,
|
|
441
|
+
loadDevServer: async () => (await import("./server-expo-DGsdUGX2.mjs")).startExpoServer,
|
|
442
|
+
platforms(root) {
|
|
443
|
+
const appJson = readAppJson(root);
|
|
444
|
+
const config = appJson?.expo ?? appJson;
|
|
445
|
+
const text = readAppConfigText(root);
|
|
446
|
+
const explicit = (text ? literalPlatforms(text) : null) ?? config?.platforms;
|
|
447
|
+
if (Array.isArray(explicit)) return explicit.filter((platform) => platform === "ios" || platform === "android" || platform === "web");
|
|
448
|
+
const pkg = readPackageJson(root);
|
|
449
|
+
return [
|
|
450
|
+
"ios",
|
|
451
|
+
"android",
|
|
452
|
+
..."react-native-web" in {
|
|
453
|
+
...pkg?.dependencies,
|
|
454
|
+
...pkg?.devDependencies
|
|
455
|
+
} || isPackageResolvable(root, "react-native-web") ? ["web"] : []
|
|
456
|
+
];
|
|
457
|
+
}
|
|
458
|
+
};
|
|
459
|
+
const reactNative = {
|
|
460
|
+
mode: MODE_BARE,
|
|
461
|
+
loadDevServer: async () => (await import("./server-bare-CkIjnegq.mjs")).startBareServer,
|
|
462
|
+
platforms(root) {
|
|
463
|
+
if (!declaresAppDependency(readPackageJson(root))) return [];
|
|
464
|
+
const platforms = [];
|
|
465
|
+
let ios = [];
|
|
466
|
+
try {
|
|
467
|
+
ios = readdirSync(join(root, "ios"));
|
|
468
|
+
} catch {}
|
|
469
|
+
if (ios.some((name) => name.endsWith(".xcodeproj") || name.endsWith(".xcworkspace"))) platforms.push("ios");
|
|
470
|
+
if ([
|
|
471
|
+
"build.gradle",
|
|
472
|
+
"build.gradle.kts",
|
|
473
|
+
"settings.gradle",
|
|
474
|
+
"settings.gradle.kts"
|
|
475
|
+
].some((name) => existsSync(join(root, "android", name)))) platforms.push("android");
|
|
476
|
+
return platforms;
|
|
477
|
+
}
|
|
478
|
+
};
|
|
479
|
+
const projectRegistry = createProjectRegistry([
|
|
480
|
+
{
|
|
481
|
+
id: "react-native",
|
|
482
|
+
inspect(root) {
|
|
483
|
+
const problem = appProjectProblem(root, loadPackageJson(root));
|
|
484
|
+
return {
|
|
485
|
+
root: existsSync(join(root, "package.json")) ? "explicit" : false,
|
|
486
|
+
application: problem === null,
|
|
487
|
+
ownedRoots: problem === null ? [join(root, "ios"), join(root, "android")] : [],
|
|
488
|
+
platforms: (settings) => nativeProjectIntegration(root).platforms(root, settings),
|
|
489
|
+
validate: (operation) => operation === "ios" || operation === "android" || operation === "dev-server" ? problem : void 0,
|
|
490
|
+
ios: async () => (await import("./react-native-ios-BMh2i25I.mjs")).reactNativeIosProject(root)
|
|
491
|
+
};
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
{
|
|
495
|
+
id: "swift-package",
|
|
496
|
+
inspect(root) {
|
|
497
|
+
if (!existsSync(join(root, "Package.swift"))) return null;
|
|
498
|
+
return {
|
|
499
|
+
root: "explicit",
|
|
500
|
+
application: true,
|
|
501
|
+
platforms: (settings) => settingValueAt(settings, "macos.product") && settingValueAt(settings, "macos.infoPlist") ? ["macos"] : [],
|
|
502
|
+
validate: (operation) => operation === "macos" ? null : void 0,
|
|
503
|
+
macos: async () => (await import("./swiftpm-macos-aJzPAj1t.mjs")).swiftpmMacosProject(root)
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
},
|
|
507
|
+
{
|
|
508
|
+
id: "browser-web",
|
|
509
|
+
inspect(root) {
|
|
510
|
+
return {
|
|
511
|
+
root: false,
|
|
512
|
+
application: false,
|
|
513
|
+
platforms: (settings) => webSettings(settings).url !== null ? ["web"] : [],
|
|
514
|
+
validate: (operation) => operation === "web" ? null : void 0,
|
|
515
|
+
web: async () => (await import("./browser-web-CDhqQxhv.mjs")).browserWebProject(root)
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
]);
|
|
520
|
+
const detectPlatforms = projectRegistry.detectPlatforms;
|
|
521
|
+
function nativeProjectIntegration(root, isExpo = detectIsExpo) {
|
|
522
|
+
return isExpo(root) ? expo : reactNative;
|
|
523
|
+
}
|
|
524
|
+
function literalPlatforms(text) {
|
|
525
|
+
const tokens = text.match(/\/\*[\s\S]*?\*\/|\/\/[^\n]*|"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|[A-Za-z_$][\w$]*|[^\s]/g)?.filter((token) => !token.startsWith("//") && !token.startsWith("/*")) ?? [];
|
|
526
|
+
let open = 0;
|
|
527
|
+
const index = tokens.findIndex((token, i) => {
|
|
528
|
+
if (token === "[") open++;
|
|
529
|
+
else if (token === "]") open--;
|
|
530
|
+
return open === 0 && (token === "platforms" || token === "\"platforms\"" || token === "'platforms'") && tokens[i + 1] === ":";
|
|
531
|
+
});
|
|
532
|
+
if (index < 0 || tokens[index + 2] !== "[") return null;
|
|
533
|
+
const platforms = [];
|
|
534
|
+
let i = index + 3;
|
|
535
|
+
while (tokens[i] !== "]") {
|
|
536
|
+
const value = tokens[i]?.match(/^(['"])([a-z]+)\1$/)?.[2];
|
|
537
|
+
if (value === void 0) return null;
|
|
538
|
+
platforms.push(value);
|
|
539
|
+
i++;
|
|
540
|
+
if (tokens[i] === ",") i++;
|
|
541
|
+
else if (tokens[i] !== "]") return null;
|
|
542
|
+
}
|
|
543
|
+
return tokens[i + 1] === "," || tokens[i + 1] === "}" ? platforms : null;
|
|
544
|
+
}
|
|
545
|
+
//#endregion
|
|
546
|
+
//#region src/workspace/project.ts
|
|
547
|
+
const findProjectRoot = projectRegistry.findProjectRoot;
|
|
548
|
+
const projectProblem = projectRegistry.projectProblem;
|
|
549
|
+
const isMobileProject = projectRegistry.isMobileProject;
|
|
550
|
+
function projectShortcut(path, proj) {
|
|
551
|
+
if (proj?.label) return proj.label;
|
|
552
|
+
const rootPath = findEnclosingWorktreeRoot(path);
|
|
553
|
+
if (rootPath && rootPath !== path) return `${projectShortcut(rootPath, getProject(rootPath))}/${path.split("/").pop() || path}`;
|
|
554
|
+
return path.split("/").pop() || path;
|
|
555
|
+
}
|
|
556
|
+
function ownedDeviceLabel(projectPath) {
|
|
557
|
+
const app = realpathSync$1(projectPath);
|
|
558
|
+
const root = repoRoot(app);
|
|
559
|
+
const appLabel = basename$1(app);
|
|
560
|
+
if (!root) return appLabel;
|
|
561
|
+
const worktreeLabel = basename$1(realpathSync$1(root));
|
|
562
|
+
return worktreeLabel === appLabel ? appLabel : `${worktreeLabel}-${appLabel}`;
|
|
563
|
+
}
|
|
564
|
+
const NO_PROJECT_REFUSAL = {
|
|
565
|
+
code: "STIM_NO_PROJECT",
|
|
566
|
+
message: "Not in a React Native project (no package.json found).",
|
|
567
|
+
remedy: "Run this from the app directory -- the one holding package.json."
|
|
568
|
+
};
|
|
569
|
+
function findServerWorkspace(startDir, registry = projectRegistry) {
|
|
570
|
+
const nearest = registry.findProjectRoot(startDir);
|
|
571
|
+
if (!nearest) return null;
|
|
572
|
+
if (registry.keepsWorkspace(nearest)) return {
|
|
573
|
+
root: nearest,
|
|
574
|
+
from: null
|
|
575
|
+
};
|
|
576
|
+
if (Object.keys(getProject(nearest)?.ports ?? {}).length) return {
|
|
577
|
+
root: nearest,
|
|
578
|
+
from: null
|
|
579
|
+
};
|
|
580
|
+
const top = repoRoot(nearest);
|
|
581
|
+
if (!top) return {
|
|
582
|
+
root: nearest,
|
|
583
|
+
from: null
|
|
584
|
+
};
|
|
585
|
+
const worktree = expandedRealpath(top);
|
|
586
|
+
const apps = Object.keys(loadConfig$1()?.projects ?? {}).filter((path) => {
|
|
587
|
+
if (path === nearest || !isPathPrefix(worktree, expandedRealpath(path)) || !registry.isMobileProject(path)) return false;
|
|
588
|
+
const owner = repoRoot(path);
|
|
589
|
+
return owner !== null && expandedRealpath(owner) === worktree;
|
|
590
|
+
});
|
|
591
|
+
return apps.length === 1 ? {
|
|
592
|
+
root: apps[0],
|
|
593
|
+
from: nearest
|
|
594
|
+
} : {
|
|
595
|
+
root: nearest,
|
|
596
|
+
from: null
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
function findCommandWorkspace(startDir, note = (line) => console.error(line)) {
|
|
600
|
+
const workspace = findServerWorkspace(startDir);
|
|
601
|
+
if (workspace?.from) note(`Using the Stim workspace ${workspace.root}: ${workspace.from} is not a React Native or Expo app.`);
|
|
602
|
+
return workspace?.root ?? null;
|
|
603
|
+
}
|
|
604
|
+
function expandedRealpath(path) {
|
|
605
|
+
try {
|
|
606
|
+
return realpathSync$1.native(path);
|
|
607
|
+
} catch {
|
|
608
|
+
return resolve$1(path);
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
//#endregion
|
|
612
|
+
export { readWorkspaceLaunches as A, clearRemoteSession as C, readPidFile as D, readMetroTunnel as E, writeWorkspaceLaunch as M, readRemoteSession as O, clearManagedMetroTunnel as S, clearWorkspaceSupervisor as T, readAppJson as _, isMobileProject as a, MODE_EXPO as b, projectShortcut as c, projectRegistry as d, appProjectProblem as f, readAppConfigText as g, isPackageResolvable as h, findServerWorkspace as i, writePidFile as j, readRemoteSessionId as k, detectPlatforms as l, detectTutorial as m, findCommandWorkspace as n, ownedDeviceLabel as o, detectIsExpo as p, findProjectRoot as r, projectProblem as s, NO_PROJECT_REFUSAL as t, nativeProjectIntegration as u, resolvePackageJson as v, clearWorkspaceLaunches as w, clearExpoMetroTunnel as x, MODE_BARE as y };
|
package/dist/pull-requests.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as pullRequestLookup, c as worktreePullRequests, i as parseRemoteRepo, n as describePullRequest, o as pullRequestLookups, r as endedPullRequest, s as selectPullRequest, t as checkCounts } from "./pull-request-
|
|
1
|
+
import { a as pullRequestLookup, c as worktreePullRequests, i as parseRemoteRepo, n as describePullRequest, o as pullRequestLookups, r as endedPullRequest, s as selectPullRequest, t as checkCounts } from "./pull-request-IHNdMnG8.mjs";
|
|
2
2
|
export { checkCounts, describePullRequest, endedPullRequest, parseRemoteRepo, pullRequestLookup, pullRequestLookups, selectPullRequest, worktreePullRequests };
|