stim 1.17.1 → 1.18.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 +50 -1
- package/dist/{activity-IRvJY_ru.mjs → activity-BxnkDZDi.mjs} +4 -4
- package/dist/{agent-device-usage-output-BK41vnzN.mjs → agent-device-usage-output-CZ66YA4T.mjs} +8 -8
- package/dist/android-BKA16DTf.mjs +4 -0
- package/dist/{android-B6rDWrTm.mjs → android-BvwuMUJ9.mjs} +192 -98
- package/dist/{android-DE4v59Mb.mjs → android-CBwCNicO.mjs} +2 -2
- package/dist/{android-B_YNZy61.mjs → android-DC3ZLuw0.mjs} +9 -9
- package/dist/{android-cas-ZFpjJBL_.mjs → android-cas-BBFyr9CA.mjs} +5 -5
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/api-D0VtFhqk.mjs +152 -0
- package/dist/api-run.d.mts +1 -0
- package/dist/api-run.mjs +145 -0
- package/dist/api.d.mts +212 -0
- package/dist/api.mjs +2 -0
- package/dist/{app-install-VPkI5WEg.mjs → app-install-D-PUENug.mjs} +3 -3
- package/dist/{attempt-Bk2ouQVL.mjs → attempt-DW-mQqM7.mjs} +14 -4
- package/dist/{budget-CUDz870h.mjs → budget-DIhL2BKx.mjs} +1581 -61
- package/dist/build-facts-DcLv2HSd.d.mts +111 -0
- package/dist/{cache-manifest-DnUHBJaU.mjs → cache-manifest-BI7ozfmH.mjs} +3 -3
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{chrome-BrcVWQyD.mjs → chrome-DJnmnS5q.mjs} +1 -1
- package/dist/cli-DNJMwADx.mjs +68 -0
- package/dist/cli.mjs +1 -1
- package/dist/{client-CxNotugx.mjs → client-DzhapoMB.mjs} +184 -49
- package/dist/collector-run.mjs +9 -9
- package/dist/{command-output-CDAIFD-8.mjs → command-output-CBtzyIgF.mjs} +2 -2
- package/dist/{config-D0DbpZtM.mjs → config-CgYMahz7.mjs} +5 -5
- package/dist/{created-devices-CpvzBL25.mjs → created-devices-DKbeWsiK.mjs} +2 -2
- package/dist/{dependency-state-CLcBHH2M.mjs → dependency-state-xKoOypBm.mjs} +2 -2
- package/dist/{detached-entry-CiTEgMR1.mjs → detached-entry-BLfcgc4O.mjs} +1 -1
- package/dist/{dev-client-B-XC4uRH.mjs → dev-client-CLnIH02x.mjs} +2 -2
- package/dist/{device-C8IOoJPv.mjs → device-D7oCHGWi.mjs} +8 -8
- package/dist/{device-capacity-ZC4XSZ4R.mjs → device-capacity-EUOOYr8T.mjs} +13 -13
- package/dist/device-host-worker.mjs +19 -19
- package/dist/{device-ios-C2Um-XUR.mjs → device-ios-6MewKKnc.mjs} +13 -13
- package/dist/{device-lease-DpoS36_u.mjs → device-lease-Co-EwifR.mjs} +9 -9
- package/dist/{device-lease-run-B8YltIH_.mjs → device-lease-run-w1xhCqIW.mjs} +4 -4
- package/dist/{device-pool-3o7s5lo4.mjs → device-pool-F5WvRPtD.mjs} +3 -3
- package/dist/{device-remote-hFSkpfQu.mjs → device-remote-tHbd1fKy.mjs} +15 -15
- package/dist/{doctor-BF_435OC.mjs → doctor-B9ckYUoU.mjs} +33 -30
- package/dist/{error-diagnostics-C-NMnhrk.mjs → error-diagnostics-BRXOqDzG.mjs} +11 -11
- package/dist/{exec-CaErVv7t.mjs → exec-DWhCZDGm.mjs} +65 -2
- package/dist/{gc-BsWKa_-d.mjs → gc-Dh6mXOKC.mjs} +23 -469
- package/dist/{gradle-bsBRy6i9.mjs → gradle-C6GKnunQ.mjs} +6 -6
- package/dist/{guide-status-Du-ZQ3FD.mjs → guide-status-Bhf9SJXc.mjs} +3 -3
- package/dist/{guide-DC3n6-NH.mjs → guide-tm6igAaa.mjs} +314 -72
- package/dist/{hosted-android-DgU31wY3.mjs → hosted-android-Bv285t_t.mjs} +3 -3
- package/dist/{hosted-client-CdSoH-G6.mjs → hosted-client-C-rMtppF.mjs} +2 -2
- package/dist/{hosted-ios-BTaVj4Jb.mjs → hosted-ios-D5mNmtj4.mjs} +1 -1
- package/dist/{hosted-logs-SxfBvSvc.mjs → hosted-logs-DN8Iz4mJ.mjs} +9 -9
- package/dist/{hosted-macos-CT9E3meL.mjs → hosted-macos-B-wEjlwG.mjs} +5 -5
- package/dist/{hosted-native-CZLOrMrN.mjs → hosted-native-DeeOG8xZ.mjs} +6 -6
- package/dist/{idle-shutdown-IGyNV8Cr.mjs → idle-shutdown-jjtxAn5C.mjs} +7 -8
- package/dist/{ios-DSfnPfse.mjs → ios-B3SbOWdw.mjs} +19 -7
- package/dist/{ios-Cr1h5gnO.mjs → ios-Bvbf0SGY.mjs} +1 -1
- package/dist/{ios-C7JuT1bI.mjs → ios-CPdkoKaa.mjs} +181 -95
- package/dist/ios-DNpdygiv.mjs +7 -0
- package/dist/{ios-device-Ee7sDXfp.mjs → ios-device-Bn7jWDB1.mjs} +1 -1
- package/dist/{ios-device-pAN4t54-.mjs → ios-device-vOaByMhw.mjs} +3 -3
- package/dist/{ios-state-8L3lgum6.mjs → ios-state-B2pES6Vs.mjs} +1 -1
- package/dist/{launch-verify-lTnWZikR.mjs → launch-verify-hskNcWkZ.mjs} +5 -5
- package/dist/{logs-DNxKcok9.mjs → logs-1Ylc1Ri6.mjs} +13 -13
- package/dist/macos-Ck7OBMNY.mjs +2 -0
- package/dist/{macos-BEs8cwKx.mjs → macos-DF6C7wUU.mjs} +118 -34
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +349 -47
- package/dist/{metro-g8NqiJp-.mjs → metro-Dh8T4Ytd.mjs} +5 -5
- package/dist/{metro-gateway-CHqK0p-a.mjs → metro-gateway-CEUw9RMH.mjs} +4 -4
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-BAHFcJm6.mjs} +16 -2
- package/dist/{named-ports-C8m8EQs2.mjs → named-ports-BFIz1Shz.mjs} +61 -6
- package/dist/{native-run-D1Q56rAD.mjs → native-run-B06FkmZx.mjs} +4 -4
- package/dist/{native-runtime-YhaSxP4v.mjs → native-runtime-D_603JiC.mjs} +6 -6
- package/dist/{ndjson-PclOIwVY.mjs → ndjson-LGZAMsqa.mjs} +8 -4
- package/dist/offload-worker.d.mts +3 -17
- package/dist/offload-worker.mjs +10 -11
- package/dist/{ownership-DyRQru0q.mjs → ownership-D6Se7gg_.mjs} +3 -3
- package/dist/{page-QF_Ke10s.mjs → page-Bv9s2KwY.mjs} +1 -1
- package/dist/placement-log-BcPhRwR4.mjs +84 -0
- package/dist/{build-plan-BJSXzsCL.mjs → plan-placement-CtxkCO54.mjs} +122 -48
- package/dist/{ports-4nYqxPWC.mjs → ports-BLTtfBq-.mjs} +3 -3
- package/dist/{prebuild-D7RUMkwN.mjs → prebuild-juCyreaR.mjs} +5 -5
- package/dist/preview-D5V07Nrl.mjs +987 -0
- package/dist/{rolldown-runtime-BsOwBuO_.mjs → process-identity-Biv3arCO.mjs} +11 -1
- package/dist/{project-D47Rh0ly.mjs → project-C3ChRLZy.mjs} +4 -68
- package/dist/projects-DD7dBTCj.mjs +92 -0
- package/dist/{pull-request-pxnDCQzn.mjs → pull-request-u4vp7zmK.mjs} +1 -1
- package/dist/pull-requests.mjs +1 -1
- package/dist/{recordings-BNgsD1Tr.mjs → recordings-BAWltsVt.mjs} +1 -1
- package/dist/{reload-byOjE3P4.mjs → reload-DvyWzVjJ.mjs} +15 -15
- package/dist/{remote-cache-Ci4DQYYj.mjs → remote-cache-BGg7aGIZ.mjs} +5 -5
- package/dist/{run-CkE9y0nc.mjs → run-vhtDgpHO.mjs} +5 -5
- package/dist/{server-bare-BkrSxSsZ.mjs → server-bare-B9E7S1aR.mjs} +4 -5
- package/dist/server-expo-Db9HBUoa.mjs +2 -0
- package/dist/{server-expo-CHTyXD0G.mjs → server-expo-DoBHhuzK.mjs} +5 -6
- package/dist/{settings-SR9OmW9h.mjs → settings-Byp2AQ_E.mjs} +6 -5
- package/dist/{settings-Cfd-0r2d.mjs → settings-CQyMElEP.mjs} +24 -763
- package/dist/{settings-BBpMcDbD.mjs → settings-Djl-mpjX.mjs} +1 -1
- package/dist/settings.schema.json +128 -5
- package/dist/{simslim-BWNrc3M3.mjs → simslim-EHBQ2R4G.mjs} +7 -7
- package/dist/{slot-launch-DmjBmpQV.mjs → slot-launch-C1nqh4mu.mjs} +6 -6
- package/dist/{spawn-claims-D0XfSe8u.mjs → spawn-claims-Kqiifsk2.mjs} +1 -1
- package/dist/{spawn-entry-jw19m8Nl.mjs → spawn-entry-Dcb7sDUz.mjs} +1 -0
- package/dist/{stage-CzaiwFsI.mjs → stage-g_WqWeaE.mjs} +14 -3
- package/dist/{start-BHIersSm.mjs → start-D-IeOyoK.mjs} +19 -19
- package/dist/{start-BEP-XmEA.mjs → start-NTc1Ifqs.mjs} +1 -1
- package/dist/{state-PeQiJuIu.mjs → state-BG-aAk4k.mjs} +4 -4
- package/dist/{state-B4PQFXMW.d.mts → state-lKh8shBp.d.mts} +2 -3
- package/dist/{state-DyaNTgfR.mjs → state-xnqpx3AD.mjs} +2 -2
- package/dist/{stats-Bq4fJOdB.mjs → stats-DY6ekz8F.mjs} +5 -5
- package/dist/{status-DlKvVJBE.mjs → status-BEeL6IKz.mjs} +6 -4
- package/dist/{status-CqeWbIWW.mjs → status-DCjZeE-K.mjs} +34 -35
- package/dist/{status-CzS4bPO9.mjs → status-Dcr0Qexd.mjs} +5 -5
- package/dist/{stim-desktop-Cnz8CPnl.mjs → stim-desktop-Behws_fi.mjs} +1 -1
- package/dist/{stim-installations-QMEI32v1.mjs → stim-installations-aR_WsNOA.mjs} +1 -1
- package/dist/{stop-D03prQnW.mjs → stop-BGhKMOuH.mjs} +5 -5
- package/dist/{stop-Cj01je8D.mjs → stop-BTjs3xbc.mjs} +17 -18
- package/dist/{stop-DOxwkH4j.mjs → stop-DIJtD2GL.mjs} +2 -2
- package/dist/supervisor-run.d.mts +24 -22
- package/dist/supervisor-run.mjs +21 -22
- package/dist/{support-BE-tbOP9.mjs → support-BaayeYCf.mjs} +7 -7
- package/dist/{support-WvD__tSV.mjs → support-Bwvbrq5-.mjs} +5 -5
- package/dist/{toolchain-CdrxgUeA.mjs → toolchain-Bnyd_K3A.mjs} +480 -27
- package/dist/{trigger-Bemu8ytw.mjs → trigger-CJMhwXe8.mjs} +5 -5
- package/dist/trigger-DWAq9hkw.mjs +2 -0
- package/dist/{warm-progress-DF4JRvYI.mjs → warm-progress-CjB-MP6H.mjs} +7 -7
- package/dist/web-B6_bFDn7.mjs +2 -0
- package/dist/{web-DddUdJzr.mjs → web-DTU0uiWj.mjs} +22 -22
- package/dist/web-run.mjs +10 -10
- package/dist/{workspace-state-DqcCbpE7.mjs → workspace-state-C59dqG-Z.mjs} +3 -3
- package/dist/{ownership-BMLqyBgJ.mjs → workspaces-xXItD8Dj.mjs} +577 -23
- package/dist/{worktree-CsAjSmEo.mjs → worktree-BJfnU6r5.mjs} +1 -1
- package/dist/{worktree-AK_m-d_m.mjs → worktree-BSYlofkq.mjs} +234 -35
- package/dist/worktree-CsKYexJM.mjs +753 -0
- package/package.json +10 -5
- package/dist/build-progress-D0WkjCPd.mjs +0 -1036
- package/dist/build-slots-41v_d2x9.mjs +0 -142
- package/dist/cli-BLQqDGlX.mjs +0 -51
- package/dist/deps-CVxlsRFn.mjs +0 -438
- package/dist/errors-B6W7FkxQ.mjs +0 -15
- package/dist/idle-BXG__1BA.mjs +0 -176
- package/dist/in-use-CvGOUn-x.mjs +0 -130
- package/dist/preview-C_JjkEy4.mjs +0 -318
- package/dist/process-identity-BmRm1qV0.mjs +0 -12
- package/dist/server-expo-CeakhI8P.mjs +0 -2
- package/dist/state-BKa8wNN5.mjs +0 -148
- package/dist/stop-cause-rhmGfwvt.mjs +0 -97
- package/dist/trigger-CXts6qt1.mjs +0 -2
- package/dist/watchman-APYjXSQa.mjs +0 -48
- package/dist/workspace-process-lock-2mNzOlaB.mjs +0 -58
- package/dist/workspaces-Bcib97-6.mjs +0 -306
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
//#region src/engine/build-facts.d.ts
|
|
2
|
+
type CacheHitLevel = "local" | "remote" | false;
|
|
3
|
+
type LaunchStatus = boolean | "unverified" | "bundling";
|
|
4
|
+
interface LogsInfo {
|
|
5
|
+
dir?: string;
|
|
6
|
+
}
|
|
7
|
+
interface CompilationCacheActivity {
|
|
8
|
+
status: "reported" | "unavailable" | "not-run";
|
|
9
|
+
hits: number | null;
|
|
10
|
+
cacheableTasks: number | null;
|
|
11
|
+
hitRatePercent: number | null;
|
|
12
|
+
swiftTargetsWithoutExplicitModules?: number;
|
|
13
|
+
}
|
|
14
|
+
interface CcacheActivity {
|
|
15
|
+
status: "reported" | "unavailable" | "not-run";
|
|
16
|
+
hits: number | null;
|
|
17
|
+
misses: number | null;
|
|
18
|
+
hitRatePercent: number | null;
|
|
19
|
+
}
|
|
20
|
+
interface DevServerStart {
|
|
21
|
+
started: true;
|
|
22
|
+
reason: "not running" | "stopped (idle)";
|
|
23
|
+
}
|
|
24
|
+
interface RunLeaseFacts {
|
|
25
|
+
kind: string;
|
|
26
|
+
expiresAt: string;
|
|
27
|
+
}
|
|
28
|
+
interface IosFacts {
|
|
29
|
+
devicePlacement?: import("@stim-cli/core/state").DevicePlacement;
|
|
30
|
+
host?: import("@stim-cli/core/state").HostedIosStatus;
|
|
31
|
+
slot?: string;
|
|
32
|
+
platform: string;
|
|
33
|
+
udid: string;
|
|
34
|
+
deviceName: string | null;
|
|
35
|
+
deviceType: string | null;
|
|
36
|
+
runtime: string | null;
|
|
37
|
+
fingerprint?: string | null;
|
|
38
|
+
configuration: string | null;
|
|
39
|
+
scheme?: string;
|
|
40
|
+
cacheKey?: string | null;
|
|
41
|
+
cacheHit: CacheHitLevel;
|
|
42
|
+
cacheSkipped: boolean;
|
|
43
|
+
buildMachine?: string;
|
|
44
|
+
builtOn?: string;
|
|
45
|
+
/** The remote Mac that compiled the app when the build was offloaded; absent otherwise. */
|
|
46
|
+
offloadedTo?: string;
|
|
47
|
+
/** Why the app was built here after the run considered offloading it; absent otherwise. */
|
|
48
|
+
offloadFallback?: string;
|
|
49
|
+
compilationCache: CompilationCacheActivity;
|
|
50
|
+
waitedForBuild: {
|
|
51
|
+
pid: number | null;
|
|
52
|
+
ms: number;
|
|
53
|
+
} | null;
|
|
54
|
+
appPath?: string | null;
|
|
55
|
+
bundleId?: string | null;
|
|
56
|
+
installSkipped: boolean;
|
|
57
|
+
launched: LaunchStatus;
|
|
58
|
+
metroPort?: number | null;
|
|
59
|
+
logs: LogsInfo;
|
|
60
|
+
agentDevice?: {
|
|
61
|
+
stateDir: string;
|
|
62
|
+
};
|
|
63
|
+
durationMs?: number;
|
|
64
|
+
webPreviewUrl?: string | null;
|
|
65
|
+
lease?: RunLeaseFacts | null;
|
|
66
|
+
devServer?: DevServerStart;
|
|
67
|
+
}
|
|
68
|
+
interface AndroidFacts {
|
|
69
|
+
devicePlacement?: import("@stim-cli/core/state").DevicePlacement;
|
|
70
|
+
host?: import("@stim-cli/core/state").HostedAndroidStatus;
|
|
71
|
+
slot?: string;
|
|
72
|
+
platform: string;
|
|
73
|
+
serial: string | null;
|
|
74
|
+
avdName: string | null;
|
|
75
|
+
deviceName: string | null;
|
|
76
|
+
systemImage: string | null;
|
|
77
|
+
deviceProfile: string | null;
|
|
78
|
+
fingerprint: string | null;
|
|
79
|
+
cacheKey: string | null;
|
|
80
|
+
variant: string | null;
|
|
81
|
+
metroPort: number | null;
|
|
82
|
+
cacheHit: CacheHitLevel;
|
|
83
|
+
cacheSkipped: boolean;
|
|
84
|
+
buildMachine?: string;
|
|
85
|
+
builtOn?: string;
|
|
86
|
+
/** The remote Mac that compiled the APK when the build was offloaded; absent otherwise. */
|
|
87
|
+
offloadedTo?: string;
|
|
88
|
+
/** Why the APK was built here after the run considered offloading it; absent otherwise. */
|
|
89
|
+
offloadFallback?: string;
|
|
90
|
+
waitedForBuild: {
|
|
91
|
+
pid: number | null;
|
|
92
|
+
ms: number;
|
|
93
|
+
} | null;
|
|
94
|
+
appPath: string | null;
|
|
95
|
+
bundleId: string | null;
|
|
96
|
+
installSkipped: boolean;
|
|
97
|
+
launched: LaunchStatus;
|
|
98
|
+
ccache: CcacheActivity;
|
|
99
|
+
debugHttpHost: string | null;
|
|
100
|
+
debugHttpHostNote: string | null;
|
|
101
|
+
devClientUrl: string | null;
|
|
102
|
+
logs: string | null;
|
|
103
|
+
agentDevice?: {
|
|
104
|
+
stateDir: string;
|
|
105
|
+
};
|
|
106
|
+
durationMs: number | null;
|
|
107
|
+
lease?: RunLeaseFacts | null;
|
|
108
|
+
devServer?: DevServerStart;
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
111
|
+
export { IosFacts as i, CcacheActivity as n, CompilationCacheActivity as r, AndroidFacts as t };
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { d as getConfigDir } from "./config-
|
|
2
|
-
import { existsSync } from "fs";
|
|
3
|
-
import { homedir } from "os";
|
|
1
|
+
import { d as getConfigDir } from "./config-CgYMahz7.mjs";
|
|
4
2
|
import { isAbsolute, join, resolve } from "path";
|
|
3
|
+
import { existsSync } from "fs";
|
|
5
4
|
import { readCacheManifest, updateCacheManifest } from "@stim-cli/core";
|
|
5
|
+
import { homedir } from "os";
|
|
6
6
|
//#region src/cache/cache-manifest.ts
|
|
7
7
|
function manifestPath() {
|
|
8
8
|
return join(getConfigDir(), "caches.json");
|
package/dist/cache-manifest.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-
|
|
1
|
+
import { a as unregister, i as registeredCaches, n as readManifest, r as register, t as manifestPath } from "./cache-manifest-BI7ozfmH.mjs";
|
|
2
2
|
export { manifestPath, readManifest, register, registeredCaches, unregister };
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { n as debugLog } from "./exec-DWhCZDGm.mjs";
|
|
2
|
+
import { y as refuseRelativeStimPaths } from "./config-CgYMahz7.mjs";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { runId } from "@stim-cli/core/state";
|
|
5
|
+
import { Command } from "commander";
|
|
6
|
+
//#region bin/cli.ts
|
|
7
|
+
const commands = /* @__PURE__ */ new Map([
|
|
8
|
+
["doctor", () => import("./doctor-B9ckYUoU.mjs")],
|
|
9
|
+
["worktree", () => import("./worktree-BJfnU6r5.mjs")],
|
|
10
|
+
["start", () => import("./start-NTc1Ifqs.mjs")],
|
|
11
|
+
["ports", () => import("./ports-BLTtfBq-.mjs")],
|
|
12
|
+
["stop", () => import("./stop-DIJtD2GL.mjs")],
|
|
13
|
+
["ios", () => import("./ios-DNpdygiv.mjs")],
|
|
14
|
+
["android", () => import("./android-BKA16DTf.mjs")],
|
|
15
|
+
["web", () => import("./web-B6_bFDn7.mjs")],
|
|
16
|
+
["macos", () => import("./macos-Ck7OBMNY.mjs")],
|
|
17
|
+
["reload", () => import("./reload-DvyWzVjJ.mjs")],
|
|
18
|
+
["device", () => import("./device-D7oCHGWi.mjs")],
|
|
19
|
+
["logs", () => import("./logs-1Ylc1Ri6.mjs")],
|
|
20
|
+
["settings", () => import("./settings-Byp2AQ_E.mjs")],
|
|
21
|
+
["status", () => import("./status-DCjZeE-K.mjs")],
|
|
22
|
+
["stats", () => import("./stats-DY6ekz8F.mjs")],
|
|
23
|
+
["gc", () => import("./gc-Dh6mXOKC.mjs")],
|
|
24
|
+
["guide", () => import("./guide-tm6igAaa.mjs")]
|
|
25
|
+
]);
|
|
26
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf-8"));
|
|
27
|
+
const program = new Command();
|
|
28
|
+
program.name("stim").description("Isolated React Native dev environments per project/worktree").version(pkg.version);
|
|
29
|
+
try {
|
|
30
|
+
refuseRelativeStimPaths();
|
|
31
|
+
process.env.STIM_RUN_ID = runId();
|
|
32
|
+
const first = process.argv[2];
|
|
33
|
+
const loadCommand = commands.get((first === "help" ? process.argv[3] : first) ?? "");
|
|
34
|
+
if (loadCommand) (await loadCommand()).default(program, pkg.version);
|
|
35
|
+
else if (first !== "--version" && first !== "-V") {
|
|
36
|
+
const modules = await Promise.all([...commands.values()].map((load) => load()));
|
|
37
|
+
for (const module of modules) module.default(program, pkg.version);
|
|
38
|
+
}
|
|
39
|
+
program.hook("preAction", async (_command, action) => {
|
|
40
|
+
if (debugLog.enabled()) {
|
|
41
|
+
const path = [];
|
|
42
|
+
for (let each = action; each?.parent; each = each.parent) path.unshift(each.name());
|
|
43
|
+
const started = Date.now();
|
|
44
|
+
debugLog.log("run_start", {
|
|
45
|
+
version: pkg.version,
|
|
46
|
+
command: path,
|
|
47
|
+
flags: process.argv.slice(2).filter((arg) => arg.startsWith("-")).map((arg) => arg.split("=")[0])
|
|
48
|
+
});
|
|
49
|
+
process.on("exit", (code) => debugLog.log("run_end", {
|
|
50
|
+
exit: code,
|
|
51
|
+
ms: Date.now() - started
|
|
52
|
+
}));
|
|
53
|
+
}
|
|
54
|
+
try {
|
|
55
|
+
const { triggerMaintenance } = await import("./trigger-DWAq9hkw.mjs");
|
|
56
|
+
triggerMaintenance(action.name());
|
|
57
|
+
} catch {}
|
|
58
|
+
});
|
|
59
|
+
await program.parseAsync();
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const code = err?.code;
|
|
62
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
63
|
+
if (typeof code === "string" && code.startsWith("STIM_")) console.error(`${code}: ${message}`);
|
|
64
|
+
else console.error(`Unexpected error: ${message.replace(/\.$/, "")}. Report it at ${pkg.bugs.url}`);
|
|
65
|
+
process.exit(1);
|
|
66
|
+
}
|
|
67
|
+
//#endregion
|
|
68
|
+
export {};
|
package/dist/cli.mjs
CHANGED
|
@@ -4,6 +4,6 @@ const encode = (version) => version.split(".", 3).reduce((sum, part) => sum * 1e
|
|
|
4
4
|
if (encode(process.versions.node) < encode("22.12.0")) {
|
|
5
5
|
process.stderr.write(`STIM_NODE_UNSUPPORTED: Stim needs Node 22.12.0 or later; this is Node ${process.versions.node} at ${process.execPath}. To run Stim where a project pins an older Node, see https://stim.appandflow.com/docs/requirements#older-node-pins\n`);
|
|
6
6
|
process.exitCode = 1;
|
|
7
|
-
} else import("./cli-
|
|
7
|
+
} else import("./cli-DNJMwADx.mjs");
|
|
8
8
|
//#endregion
|
|
9
9
|
export {};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { t as getExecutor } from "./exec-
|
|
2
|
-
import { _ as loadConfig$1, d as getConfigDir } from "./config-
|
|
3
|
-
import { w as withDirLock } from "./workspace-state-
|
|
4
|
-
import {
|
|
5
|
-
import { createHash } from "node:crypto";
|
|
1
|
+
import { n as debugLog, t as getExecutor } from "./exec-DWhCZDGm.mjs";
|
|
2
|
+
import { _ as loadConfig$1, d as getConfigDir } from "./config-CgYMahz7.mjs";
|
|
3
|
+
import { w as withDirLock } from "./workspace-state-C59dqG-Z.mjs";
|
|
4
|
+
import { a as toolchainMismatches, d as readRubyVersion, h as COMPILATION_CACHE_UNAVAILABLE, j as CCACHE_UNAVAILABLE, s as manifestDigest } from "./toolchain-Bnyd_K3A.mjs";
|
|
6
5
|
import { closeSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readlinkSync, realpathSync, renameSync, rmSync, writeFileSync, writeSync } from "node:fs";
|
|
7
6
|
import { basename, dirname, join, relative } from "node:path";
|
|
7
|
+
import { OFFLOAD_MODES, acceptsShape, buildMachinesFile, buildMachinesLock, deviceHostMachinesClaims, deviceHostMachinesFile, deviceHostMachinesLock, endpoint, findPeer as findPeer$1, isJsonObject, parseMachine, parseMachine as parseMachine$1, pinnedEndpoint, readBuildMachines, readDeviceHostMachines, runId, saturation, settingDefinition } from "@stim-cli/core/state";
|
|
8
|
+
import { hostname } from "node:os";
|
|
8
9
|
import { InvalidArgumentError } from "commander";
|
|
9
|
-
import { OFFLOAD_MODES, acceptsShape, buildMachinesFile, buildMachinesLock, deviceHostMachinesClaims, deviceHostMachinesFile, deviceHostMachinesLock, endpoint, findPeer as findPeer$1, isJsonObject, parseMachine, parseMachine as parseMachine$1, pinnedEndpoint, readBuildMachines, readDeviceHostMachines, saturation, settingDefinition } from "@stim-cli/core/state";
|
|
10
10
|
import { releaseClaim, tryAcquireClaim } from "@stim-cli/core/ownership-claim";
|
|
11
|
-
import {
|
|
11
|
+
import { createHash } from "node:crypto";
|
|
12
12
|
import { WebSocket } from "ws";
|
|
13
13
|
//#region src/offload/access-ticket.ts
|
|
14
14
|
function readAccessTicket() {
|
|
@@ -30,6 +30,28 @@ function readHostPermissions(value) {
|
|
|
30
30
|
//#region src/offload/tailnet.ts
|
|
31
31
|
const MAC_APP_TAILSCALE = "/Applications/Tailscale.app/Contents/MacOS/Tailscale";
|
|
32
32
|
const HELLO_TIMEOUT_MS = 1e4;
|
|
33
|
+
function isLapsed(credential) {
|
|
34
|
+
return credential.state === "pending" && !!credential.expiresAt && Date.parse(credential.expiresAt) <= Date.now();
|
|
35
|
+
}
|
|
36
|
+
function markApproved(credential) {
|
|
37
|
+
const { expiresAt: _expiresAt, ...rest } = credential;
|
|
38
|
+
return {
|
|
39
|
+
...rest,
|
|
40
|
+
state: "approved"
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
function pendingReport(credential) {
|
|
44
|
+
return {
|
|
45
|
+
state: "pending",
|
|
46
|
+
...credential.expiresAt ? { expiresAt: credential.expiresAt } : {}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
function lapsedLine(machine, credential) {
|
|
50
|
+
return `${machine} did not approve this Mac before the request lapsed at ${credential.expiresAt}.`;
|
|
51
|
+
}
|
|
52
|
+
function requestedLine(credential) {
|
|
53
|
+
return `Requested at ${credential.requestedAt}${credential.expiresAt ? `; the request lapses at ${credential.expiresAt}` : ""}.`;
|
|
54
|
+
}
|
|
33
55
|
function tailscaleStatus() {
|
|
34
56
|
for (const binary of ["tailscale", MAC_APP_TAILSCALE]) {
|
|
35
57
|
const output = getExecutor().runFileQuiet(binary, ["status", "--json"], { timeoutMs: 5e3 });
|
|
@@ -161,6 +183,7 @@ async function request(machine, peer, port, deviceName, io) {
|
|
|
161
183
|
deviceToken: reply.result.deviceToken,
|
|
162
184
|
state: "pending",
|
|
163
185
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
186
|
+
expiresAt: reply.result.approval.expiresAt,
|
|
164
187
|
...ticket ? { ticketHash: ticket.ticketHash } : {}
|
|
165
188
|
};
|
|
166
189
|
return {
|
|
@@ -169,7 +192,8 @@ async function request(machine, peer, port, deviceName, io) {
|
|
|
169
192
|
dnsName: peer.dnsName,
|
|
170
193
|
state: "pending",
|
|
171
194
|
deviceId: credential.deviceId,
|
|
172
|
-
requestedAt: credential.requestedAt
|
|
195
|
+
requestedAt: credential.requestedAt,
|
|
196
|
+
expiresAt: credential.expiresAt
|
|
173
197
|
},
|
|
174
198
|
finding: note$1(`Asked ${machine} for hosting access`, `The request lapses at ${reply.result.approval.expiresAt}.`, approval$1(machine, credential.deviceId)),
|
|
175
199
|
credential
|
|
@@ -300,10 +324,7 @@ async function inspectDeviceHostMachines({ fix }, io = realIo, entries = configu
|
|
|
300
324
|
const reply = await io.hello(endpoint(peer, parsed.port), { deviceToken: credential.deviceToken });
|
|
301
325
|
if ("result" in reply && reply.result?.device?.id === credential.deviceId && Array.isArray(reply.result.capabilities) && reply.result.capabilities.includes("device-host")) {
|
|
302
326
|
if (credential.state !== "approved") {
|
|
303
|
-
credentials = credentials.map((each) => each.machine === machine ?
|
|
304
|
-
...each,
|
|
305
|
-
state: "approved"
|
|
306
|
-
} : each);
|
|
327
|
+
credentials = credentials.map((each) => each.machine === machine ? markApproved(each) : each);
|
|
307
328
|
store(credentials);
|
|
308
329
|
}
|
|
309
330
|
const host = readHostPermissions(reply.result.host);
|
|
@@ -326,17 +347,18 @@ async function inspectDeviceHostMachines({ fix }, io = realIo, entries = configu
|
|
|
326
347
|
if (pending && !ask) {
|
|
327
348
|
inspected.machines.push({
|
|
328
349
|
...known,
|
|
329
|
-
|
|
350
|
+
...pendingReport(credential)
|
|
330
351
|
});
|
|
331
|
-
inspected.findings.push(note$1(`Remote Mac ${machine} has not approved this Mac for device hosting yet`,
|
|
352
|
+
inspected.findings.push(note$1(`Remote Mac ${machine} has not approved this Mac for device hosting yet`, requestedLine(credential), approval$1(machine, credential.deviceId)));
|
|
332
353
|
continue;
|
|
333
354
|
}
|
|
334
355
|
if (!ask) {
|
|
356
|
+
const lapsed = revoked && isLapsed(credential);
|
|
335
357
|
inspected.machines.push({
|
|
336
358
|
...known,
|
|
337
|
-
state: revoked ? "revoked" : "unreachable"
|
|
359
|
+
state: lapsed ? "lapsed" : revoked ? "revoked" : "unreachable"
|
|
338
360
|
});
|
|
339
|
-
inspected.findings.push(note$1(`Remote Mac ${machine} ${revoked ? "no longer accepts this Mac for device hosting" : "did not confirm hosting access"}`, "The saved token and pinned node are preserved.", revoked ? "Run `stim doctor --fix` to ask again." : `Check stim-server and its tailnet serve route on ${machine}, then run doctor again.`));
|
|
361
|
+
inspected.findings.push(note$1(lapsed ? `Hosting request to ${machine} lapsed` : `Remote Mac ${machine} ${revoked ? "no longer accepts this Mac for device hosting" : "did not confirm hosting access"}`, lapsed ? `${lapsedLine(machine, credential)} The saved token and pinned node are preserved.` : "The saved token and pinned node are preserved.", revoked ? "Run `stim doctor --fix` to ask again." : `Check stim-server and its tailnet serve route on ${machine}, then run doctor again.`));
|
|
340
362
|
continue;
|
|
341
363
|
}
|
|
342
364
|
}
|
|
@@ -471,6 +493,7 @@ async function requestAccess(entry, peer, port, deviceName, io) {
|
|
|
471
493
|
deviceToken: reply.result.deviceToken,
|
|
472
494
|
state: "pending",
|
|
473
495
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
496
|
+
expiresAt: reply.result.approval.expiresAt,
|
|
474
497
|
...ticket ? { ticketHash: ticket.ticketHash } : {}
|
|
475
498
|
};
|
|
476
499
|
updateCredentials((credentials) => [...credentials.filter((each) => each.machine !== entry), credential]);
|
|
@@ -480,7 +503,8 @@ async function requestAccess(entry, peer, port, deviceName, io) {
|
|
|
480
503
|
state: "pending",
|
|
481
504
|
dnsName: peer.dnsName,
|
|
482
505
|
deviceId: credential.deviceId,
|
|
483
|
-
requestedAt: credential.requestedAt
|
|
506
|
+
requestedAt: credential.requestedAt,
|
|
507
|
+
expiresAt: credential.expiresAt
|
|
484
508
|
},
|
|
485
509
|
finding: note(`Asked ${entry} for build access`, `The request lapses at ${reply.result.approval.expiresAt}.`, approval(entry, credential.deviceId))
|
|
486
510
|
};
|
|
@@ -538,10 +562,7 @@ async function inspectMachine(entry, status, deviceName, fix, io, check) {
|
|
|
538
562
|
if ("result" in reply && reply.result.capabilities.includes("build")) {
|
|
539
563
|
const permissions = readHostPermissions(reply.result.host);
|
|
540
564
|
const host = permissions ? { host: permissions } : {};
|
|
541
|
-
if (credential.state !== "approved") updateCredentials((credentials) => credentials.map((each) => each.machine === entry ?
|
|
542
|
-
...each,
|
|
543
|
-
state: "approved"
|
|
544
|
-
} : each));
|
|
565
|
+
if (credential.state !== "approved") updateCredentials((credentials) => credentials.map((each) => each.machine === entry ? markApproved(each) : each));
|
|
545
566
|
if (!check) return {
|
|
546
567
|
report: {
|
|
547
568
|
...paired,
|
|
@@ -574,19 +595,26 @@ async function inspectMachine(entry, status, deviceName, fix, io, check) {
|
|
|
574
595
|
return {
|
|
575
596
|
report: {
|
|
576
597
|
...paired,
|
|
577
|
-
|
|
598
|
+
...pendingReport(credential)
|
|
578
599
|
},
|
|
579
|
-
finding: note(`Remote Mac ${entry} has not approved this Mac for builds yet`,
|
|
600
|
+
finding: note(`Remote Mac ${entry} has not approved this Mac for builds yet`, requestedLine(credential), approval(entry, credential.deviceId))
|
|
580
601
|
};
|
|
581
602
|
}
|
|
582
603
|
if ("error" in reply && reply.error.code === "unauthorized") {
|
|
583
604
|
if (fix) return requestAccess(entry, peer, parsed.port, deviceName, io);
|
|
605
|
+
if (isLapsed(credential)) return {
|
|
606
|
+
report: {
|
|
607
|
+
...paired,
|
|
608
|
+
state: "lapsed"
|
|
609
|
+
},
|
|
610
|
+
finding: note(`Build request to ${entry} lapsed`, lapsedLine(entry, credential), "Run `stim doctor --fix` to ask again.")
|
|
611
|
+
};
|
|
584
612
|
return {
|
|
585
613
|
report: {
|
|
586
614
|
...paired,
|
|
587
615
|
state: "revoked"
|
|
588
616
|
},
|
|
589
|
-
finding: note(`Remote Mac ${entry} no longer accepts this Mac for builds`, `${reply.error.message} It was revoked
|
|
617
|
+
finding: note(`Remote Mac ${entry} no longer accepts this Mac for builds`, `${reply.error.message} It was revoked or denied.`, "Run `stim doctor --fix` to ask again.")
|
|
590
618
|
};
|
|
591
619
|
}
|
|
592
620
|
const reason = "failed" in reply ? reply.failed : "error" in reply ? reply.error.message : "unexpected reply";
|
|
@@ -675,8 +703,26 @@ function requireConfiguredMachine(selected, machines) {
|
|
|
675
703
|
if (!match) throw new OffloadRefusal(selected, `not listed in remote.machines (configured: ${entries.join(", ") || "none"})`);
|
|
676
704
|
return match;
|
|
677
705
|
}
|
|
706
|
+
const settingSource = (flag, env, setting) => flag !== void 0 ? "flag" : env?.trim() ? "env" : setting !== void 0 ? "setting" : "default";
|
|
707
|
+
let buildMachineFlag;
|
|
708
|
+
/** The settings that decide where a build runs, with the layer each value came from, for this run's `--remote-build`. */
|
|
709
|
+
function buildPlacementSettings(selected) {
|
|
710
|
+
const flag = buildMachineFlag;
|
|
711
|
+
const remote = loadConfig$1()?.remote;
|
|
712
|
+
const rawMode = process.env.STIM_REMOTE_BUILD_MODE || remote?.buildMode;
|
|
713
|
+
return [{
|
|
714
|
+
key: "remote.build",
|
|
715
|
+
value: selected,
|
|
716
|
+
from: settingSource(flag, process.env.STIM_REMOTE_BUILD, remote?.build)
|
|
717
|
+
}, {
|
|
718
|
+
key: "remote.buildMode",
|
|
719
|
+
value: selected === "local" ? "off" : OFFLOAD_MODES.includes(rawMode) ? rawMode : "auto",
|
|
720
|
+
from: settingSource(void 0, process.env.STIM_REMOTE_BUILD_MODE, remote?.buildMode)
|
|
721
|
+
}];
|
|
722
|
+
}
|
|
678
723
|
function resolveBuildPlacement(flag) {
|
|
679
724
|
const remote = loadConfig$1()?.remote;
|
|
725
|
+
buildMachineFlag = flag;
|
|
680
726
|
let selected = "auto";
|
|
681
727
|
try {
|
|
682
728
|
selected = resolveBuildMachine(flag, process.env.STIM_REMOTE_BUILD, remote?.build);
|
|
@@ -695,6 +741,23 @@ function resolveBuildPlacement(flag) {
|
|
|
695
741
|
}
|
|
696
742
|
}
|
|
697
743
|
//#endregion
|
|
744
|
+
//#region src/remote-log.ts
|
|
745
|
+
let sink = null;
|
|
746
|
+
/** Where this run's failed requests to another Mac are written: its workspace log, so `stim logs` shows them. */
|
|
747
|
+
function setRemoteLogSink(next) {
|
|
748
|
+
sink = next;
|
|
749
|
+
}
|
|
750
|
+
function reportRemoteFailure(event, fields) {
|
|
751
|
+
try {
|
|
752
|
+
sink?.({
|
|
753
|
+
src: "build",
|
|
754
|
+
level: "warn",
|
|
755
|
+
event,
|
|
756
|
+
...fields
|
|
757
|
+
});
|
|
758
|
+
} catch {}
|
|
759
|
+
}
|
|
760
|
+
//#endregion
|
|
698
761
|
//#region src/offload/client.ts
|
|
699
762
|
const CONNECT_TIMEOUT_MS = 1e4;
|
|
700
763
|
const OFFER_TIMEOUT_MS = 2e4;
|
|
@@ -756,35 +819,43 @@ function offloadPlacement({ mode, machines, here, unsupported, selected = "auto"
|
|
|
756
819
|
if (machines === 0) throw new OffloadRefusal(selected, "no remote Mac is paired");
|
|
757
820
|
return {
|
|
758
821
|
offload: true,
|
|
822
|
+
code: "named",
|
|
759
823
|
reason: `selected with --remote-build ${selected}`
|
|
760
824
|
};
|
|
761
825
|
}
|
|
762
826
|
if (selected === "local") return {
|
|
763
827
|
offload: false,
|
|
828
|
+
code: "local-selected",
|
|
764
829
|
reason: "--remote-build local"
|
|
765
830
|
};
|
|
766
831
|
if (mode === "off") return {
|
|
767
832
|
offload: false,
|
|
833
|
+
code: "mode-off",
|
|
768
834
|
reason: "remote.buildMode is off"
|
|
769
835
|
};
|
|
770
836
|
if (machines === 0) return {
|
|
771
837
|
offload: false,
|
|
838
|
+
code: "no-remote-mac",
|
|
772
839
|
reason: "no remote Mac is paired"
|
|
773
840
|
};
|
|
774
841
|
if (unsupported) return {
|
|
775
842
|
offload: false,
|
|
843
|
+
code: "unsupported",
|
|
776
844
|
reason: unsupported
|
|
777
845
|
};
|
|
778
846
|
if (mode === "force") return {
|
|
779
847
|
offload: true,
|
|
848
|
+
code: "forced",
|
|
780
849
|
reason: "remote.buildMode is force"
|
|
781
850
|
};
|
|
782
851
|
const busy = saturation(here);
|
|
783
852
|
return busy ? {
|
|
784
853
|
offload: true,
|
|
854
|
+
code: "this-mac-busy",
|
|
785
855
|
reason: `this Mac is busy: ${busy} (${capacityText(here)})`
|
|
786
856
|
} : {
|
|
787
857
|
offload: false,
|
|
858
|
+
code: "this-mac-free",
|
|
788
859
|
reason: `${capacityText(here)} here`
|
|
789
860
|
};
|
|
790
861
|
}
|
|
@@ -823,25 +894,26 @@ function offerProblems(offer, target) {
|
|
|
823
894
|
function pickOffer({ mode, here, offers, target, selected = "auto" }) {
|
|
824
895
|
const slotsFull = here.maxBuilds > 0 && here.builds >= here.maxBuilds;
|
|
825
896
|
const reasons = [];
|
|
897
|
+
const candidates = [];
|
|
898
|
+
const skip = (machine, code, msg, detail) => {
|
|
899
|
+
reasons.push(`${machine}: ${msg}`);
|
|
900
|
+
candidates.push({
|
|
901
|
+
machine,
|
|
902
|
+
code,
|
|
903
|
+
msg,
|
|
904
|
+
...detail ? { detail } : {}
|
|
905
|
+
});
|
|
906
|
+
};
|
|
826
907
|
const ranked = [];
|
|
827
908
|
offers.forEach(({ machine, offer, failure }, index) => {
|
|
828
909
|
if (namedBuildMachine(selected) && machine !== selected) return;
|
|
829
|
-
if (!offer) return
|
|
910
|
+
if (!offer) return skip(machine, "unreachable", failure ?? "no offer");
|
|
830
911
|
const problems = offerProblems(offer, target);
|
|
831
|
-
if (problems.length)
|
|
832
|
-
reasons.push(`${machine}: ${problems.map((problem) => problem.reason).join("; ")}`);
|
|
833
|
-
return;
|
|
834
|
-
}
|
|
912
|
+
if (problems.length) return skip(machine, problemCode(problems[0]), problems.map((problem) => problem.reason).join("; "), problems.map((problem) => problem.code));
|
|
835
913
|
const load = offer.capacity.loadPerCore;
|
|
836
914
|
if (selected === "auto" && mode === "auto" && !slotsFull) {
|
|
837
|
-
if (typeof load !== "number")
|
|
838
|
-
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
841
|
-
if (load >= here.loadPerCore) {
|
|
842
|
-
reasons.push(`${machine}: no less loaded (load ${load}/core there, ${here.loadPerCore}/core here)`);
|
|
843
|
-
return;
|
|
844
|
-
}
|
|
915
|
+
if (typeof load !== "number") return skip(machine, "load", "capacity unknown (older stim-server) while this Mac has a free slot");
|
|
916
|
+
if (load >= here.loadPerCore) return skip(machine, "load", `no less loaded (load ${load}/core there, ${here.loadPerCore}/core here)`);
|
|
845
917
|
}
|
|
846
918
|
const score = Number(offer.warm.checkout) + Number(offer.warm.dependencies) + Number(offer.warm.build);
|
|
847
919
|
ranked.push({
|
|
@@ -849,13 +921,22 @@ function pickOffer({ mode, here, offers, target, selected = "auto" }) {
|
|
|
849
921
|
score,
|
|
850
922
|
load: typeof load === "number" ? load : Number.POSITIVE_INFINITY
|
|
851
923
|
});
|
|
924
|
+
candidates.push({
|
|
925
|
+
machine,
|
|
926
|
+
code: "accepted",
|
|
927
|
+
msg: typeof load === "number" ? `can take the build (load ${load}/core there)` : "can take the build"
|
|
928
|
+
});
|
|
852
929
|
});
|
|
853
930
|
ranked.sort((a, b) => b.score - a.score || a.load - b.load);
|
|
854
931
|
return {
|
|
855
932
|
order: ranked.map((each) => each.index),
|
|
856
|
-
reasons
|
|
933
|
+
reasons,
|
|
934
|
+
candidates
|
|
857
935
|
};
|
|
858
936
|
}
|
|
937
|
+
function problemCode({ code }) {
|
|
938
|
+
return code === "disk" || code === "busy" || code === "unreachable" ? code : code === "runtime" ? "no-matching-device" : "version-mismatch";
|
|
939
|
+
}
|
|
859
940
|
const openSockets = /* @__PURE__ */ new Set();
|
|
860
941
|
let closingOnExit = false;
|
|
861
942
|
/**
|
|
@@ -938,7 +1019,32 @@ var BuildConnection = class BuildConnection {
|
|
|
938
1019
|
socket.on("error", () => {});
|
|
939
1020
|
}
|
|
940
1021
|
/** Resolves why it could not connect; `refused` when the machine answered and turned this Mac away. */
|
|
941
|
-
static open(target, token, timeoutMs, capability = "build") {
|
|
1022
|
+
static async open(target, token, timeoutMs, capability = "build") {
|
|
1023
|
+
const started = performance.now();
|
|
1024
|
+
const result = await BuildConnection.connect(target, token, timeoutMs, capability);
|
|
1025
|
+
const ms = Math.round(performance.now() - started);
|
|
1026
|
+
debugLog.log("remote_connect", {
|
|
1027
|
+
host: target.host,
|
|
1028
|
+
capability,
|
|
1029
|
+
ms,
|
|
1030
|
+
timeoutMs,
|
|
1031
|
+
...result instanceof BuildConnection ? { ok: true } : {
|
|
1032
|
+
ok: false,
|
|
1033
|
+
failure: result.failure,
|
|
1034
|
+
code: result.code
|
|
1035
|
+
}
|
|
1036
|
+
});
|
|
1037
|
+
if (!(result instanceof BuildConnection)) reportRemoteFailure("remote_connect_failed", {
|
|
1038
|
+
host: target.host,
|
|
1039
|
+
capability,
|
|
1040
|
+
ms,
|
|
1041
|
+
timeoutMs,
|
|
1042
|
+
msg: result.failure,
|
|
1043
|
+
code: result.code
|
|
1044
|
+
});
|
|
1045
|
+
return result;
|
|
1046
|
+
}
|
|
1047
|
+
static connect(target, token, timeoutMs, capability) {
|
|
942
1048
|
return new Promise((resolve) => {
|
|
943
1049
|
const options = {
|
|
944
1050
|
handshakeTimeout: timeoutMs,
|
|
@@ -968,7 +1074,8 @@ var BuildConnection = class BuildConnection {
|
|
|
968
1074
|
protocol: 1,
|
|
969
1075
|
client: {
|
|
970
1076
|
name: "stim",
|
|
971
|
-
version: "1"
|
|
1077
|
+
version: "1",
|
|
1078
|
+
runId: runId()
|
|
972
1079
|
},
|
|
973
1080
|
auth: { deviceToken: token }
|
|
974
1081
|
}
|
|
@@ -1000,17 +1107,36 @@ var BuildConnection = class BuildConnection {
|
|
|
1000
1107
|
message: this.closed
|
|
1001
1108
|
} });
|
|
1002
1109
|
const id = this.nextId++;
|
|
1110
|
+
const started = performance.now();
|
|
1111
|
+
const done = (reply) => {
|
|
1112
|
+
const ms = Math.round(performance.now() - started);
|
|
1113
|
+
debugLog.log("remote_request", {
|
|
1114
|
+
method,
|
|
1115
|
+
ms,
|
|
1116
|
+
..."error" in reply ? {
|
|
1117
|
+
ok: false,
|
|
1118
|
+
code: reply.error.code
|
|
1119
|
+
} : { ok: true }
|
|
1120
|
+
});
|
|
1121
|
+
if ("error" in reply) reportRemoteFailure("remote_request_failed", {
|
|
1122
|
+
method,
|
|
1123
|
+
ms,
|
|
1124
|
+
code: reply.error.code,
|
|
1125
|
+
msg: reply.error.message
|
|
1126
|
+
});
|
|
1127
|
+
return reply;
|
|
1128
|
+
};
|
|
1003
1129
|
return new Promise((resolve) => {
|
|
1004
1130
|
const timer = setTimeout(() => {
|
|
1005
1131
|
this.pending.delete(id);
|
|
1006
|
-
resolve({ error: {
|
|
1132
|
+
resolve(done({ error: {
|
|
1007
1133
|
code: "timeout",
|
|
1008
1134
|
message: `${method} got no reply in ${timeoutMs / 1e3} s`
|
|
1009
|
-
} });
|
|
1135
|
+
} }));
|
|
1010
1136
|
}, timeoutMs);
|
|
1011
1137
|
this.pending.set(id, (reply) => {
|
|
1012
1138
|
clearTimeout(timer);
|
|
1013
|
-
resolve(reply);
|
|
1139
|
+
resolve(done(reply));
|
|
1014
1140
|
});
|
|
1015
1141
|
this.socket.send(JSON.stringify({
|
|
1016
1142
|
id,
|
|
@@ -1161,7 +1287,8 @@ async function probeMachine(credential, identity, { connectMs = CONNECT_TIMEOUT_
|
|
|
1161
1287
|
};
|
|
1162
1288
|
const reply = await connection.request("build.offer", {
|
|
1163
1289
|
repo: identity.repo,
|
|
1164
|
-
...identity.lockfile ? { lockfile: identity.lockfile } : {}
|
|
1290
|
+
...identity.lockfile ? { lockfile: identity.lockfile } : {},
|
|
1291
|
+
...identity.rubyVersion ? { rubyVersion: identity.rubyVersion } : {}
|
|
1165
1292
|
}, offerMs);
|
|
1166
1293
|
const failure = replyError(reply);
|
|
1167
1294
|
if (failure || !("result" in reply)) {
|
|
@@ -1181,7 +1308,7 @@ async function probeMachine(credential, identity, { connectMs = CONNECT_TIMEOUT_
|
|
|
1181
1308
|
* Asks every paired machine for an offer in parallel and keeps the connection to the one `pickOffer` chooses, or
|
|
1182
1309
|
* returns why none takes the build. A named selection probes only its credential and skips auto load gating.
|
|
1183
1310
|
*/
|
|
1184
|
-
async function chooseBuildMachine({ projectRoot, target, mode, here, note, machines = pairedMachines(), selected = "auto" }) {
|
|
1311
|
+
async function chooseBuildMachine({ projectRoot, target, mode, here, note, machines = pairedMachines(), selected = "auto", onCandidates }) {
|
|
1185
1312
|
const started = Date.now();
|
|
1186
1313
|
let identity;
|
|
1187
1314
|
try {
|
|
@@ -1190,8 +1317,12 @@ async function chooseBuildMachine({ projectRoot, target, mode, here, note, machi
|
|
|
1190
1317
|
return `this app is not in a git checkout (${error.message.split("\n")[0]})`;
|
|
1191
1318
|
}
|
|
1192
1319
|
if (namedBuildMachine(selected)) machines = machines.filter((each) => each.machine === selected).slice(0, 1);
|
|
1193
|
-
const
|
|
1194
|
-
const
|
|
1320
|
+
const rubyVersion = readRubyVersion(projectRoot) ?? void 0;
|
|
1321
|
+
const asked = await Promise.all(machines.map((credential) => probeMachine(credential, {
|
|
1322
|
+
...identity,
|
|
1323
|
+
rubyVersion
|
|
1324
|
+
})));
|
|
1325
|
+
const { order, reasons, candidates } = pickOffer({
|
|
1195
1326
|
selected,
|
|
1196
1327
|
mode,
|
|
1197
1328
|
here,
|
|
@@ -1205,6 +1336,7 @@ async function chooseBuildMachine({ projectRoot, target, mode, here, note, machi
|
|
|
1205
1336
|
asked.forEach((each, at) => {
|
|
1206
1337
|
if (!order.includes(at) && "connection" in each) each.connection.close();
|
|
1207
1338
|
});
|
|
1339
|
+
onCandidates?.(candidates);
|
|
1208
1340
|
if (order.length === 0) return reasons.length ? reasons.join("; ") : "no remote Mac is paired";
|
|
1209
1341
|
for (const reason of reasons) note(reason);
|
|
1210
1342
|
const [first, ...rest] = order.map((at) => {
|
|
@@ -1606,7 +1738,10 @@ function offloadCheck(projectRoot, targets) {
|
|
|
1606
1738
|
reason: `this app is not in a git checkout (${identity})`
|
|
1607
1739
|
}]
|
|
1608
1740
|
};
|
|
1609
|
-
const probe = await probeMachine(credential,
|
|
1741
|
+
const probe = await probeMachine(credential, {
|
|
1742
|
+
...identity,
|
|
1743
|
+
rubyVersion: readRubyVersion(projectRoot) ?? void 0
|
|
1744
|
+
}, {
|
|
1610
1745
|
connectMs: DOCTOR_CONNECT_MS,
|
|
1611
1746
|
offerMs: DOCTOR_OFFER_MS
|
|
1612
1747
|
});
|
|
@@ -1634,4 +1769,4 @@ function offloadCheck(projectRoot, targets) {
|
|
|
1634
1769
|
};
|
|
1635
1770
|
}
|
|
1636
1771
|
//#endregion
|
|
1637
|
-
export {
|
|
1772
|
+
export { pinnedEndpoint$1 as C, parseMachine$1 as S, resolveBuildPlacement as _, offloadBuild as a, hostingMachines as b, placementLoad as c, setRemoteLogSink as d, OffloadRefusal as f, resolveBuildMachine as g, parseBuildMachineOption as h, closeOffload as i, remotePhaseText as l, namedBuildMachine as m, buildPlacementCandidates as n, offloadCheck as o, buildPlacementSettings as p, chooseBuildMachine as r, offloadPlacement as s, BuildConnection as t, simulatorRuntime as u, inspectBuildMachines as v, realIo as w, inspectDeviceHostMachines as x, configuredMachines as y };
|