stim 1.20.2 → 1.22.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 +141 -8
- package/dist/acquire-artifact-Co2k4f7O.mjs +171 -0
- package/dist/act-DsuqEkiM.mjs +2801 -0
- package/dist/activity-CMLmzp7o.mjs +1397 -0
- package/dist/{agent-device-usage-output-Dzgv6lgR.mjs → agent-device-usage-output-DUFaTMdd.mjs} +23 -67
- package/dist/{android-DCKZrNvV.mjs → android-ByRMUoiJ.mjs} +157 -93
- package/dist/{android-Mz_Inn3w.mjs → android-C7sVmyI9.mjs} +299 -116
- package/dist/{android-Dlzxshgp.mjs → android-DGkNqa_c.mjs} +5 -5
- package/dist/{android-HqP1_vB_.mjs → android-DR5lZ2Az.mjs} +2 -2
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-Bl-cLJBk.mjs → android-cas-ngferVq2.mjs} +7 -6
- package/dist/android-project-BCAAmMwz.mjs +12 -0
- package/dist/android-project-DVWyCbWU.d.mts +391 -0
- package/dist/api.d.mts +810 -64
- package/dist/api.mjs +782 -1
- package/dist/{artifact-HSwkIWEQ.mjs → artifact-8EY8SAPw.mjs} +240 -213
- package/dist/{artifact-D3czlUvT.mjs → artifact-DJPy518Y.mjs} +203 -164
- package/dist/artifact-platform-CXcmX_j3.mjs +27 -0
- package/dist/{browser-web-CA-F1GQo.mjs → browser-web-Bcv99PBM.mjs} +194 -64
- package/dist/budget-Cvwn54qV.mjs +9285 -0
- package/dist/{build-DYDbfkk5.mjs → build-CabC3G23.mjs} +153 -98
- package/dist/build-cache-Dv7RN200.mjs +602 -0
- package/dist/build-plan-DUC8Ka9y.mjs +248 -0
- package/dist/{cache-manifest-XH-fvDUj.mjs → cache-manifest-DSeQjt-Q.mjs} +2 -2
- package/dist/cache-manifest.mjs +1 -1
- package/dist/{ccache-zdKiYQ3E.mjs → ccache-Btwc36-I.mjs} +10 -9
- package/dist/{cdp-Dq_ypAlJ.mjs → cdp-3fwICjzi.mjs} +18 -5
- package/dist/{chrome-BnzZMqsR.mjs → chrome-Bbw689-6.mjs} +7 -4
- package/dist/{cli-CLP3diBm.mjs → cli-CHZa9Lvk.mjs} +20 -20
- package/dist/cli.mjs +1 -1
- package/dist/client-OyRoEuSr.mjs +1577 -0
- package/dist/collector-run.d.mts +4 -40
- package/dist/collector-run.mjs +9 -8
- package/dist/{command-output-BTy8hZ0F.mjs → command-output-gwpm28fu.mjs} +1 -1
- package/dist/config-DlrsduwG.mjs +955 -0
- package/dist/{created-devices-Dzd5C2LF.mjs → created-devices-x9rN6bhs.mjs} +14 -4
- package/dist/{dependency-state-DG0p31-y.mjs → dependency-state-1I9KZT1Y.mjs} +20 -5
- package/dist/{detached-entry-B9C_zeQC.mjs → detached-entry-BwNEtIrP.mjs} +1 -1
- package/dist/{dev-client-DAWVIGBu.mjs → dev-client-BSDR5h3F.mjs} +2 -2
- package/dist/{device-BECOiufl.mjs → device-B-L3Fbxy.mjs} +91 -34
- package/dist/device-DklWZLqb.mjs +1068 -0
- package/dist/{device-capacity-CBUAcRyQ.mjs → device-capacity-DK5_EwRS.mjs} +42 -13
- package/dist/device-host-worker.mjs +76 -79
- package/dist/{device-ios-COSi6oS1.mjs → device-ios-DoB6KFCO.mjs} +77 -51
- package/dist/{device-lease-run-Cw2M4z51.mjs → device-lease-run-xJPQ_QQG.mjs} +14 -26
- package/dist/{device-pool-Bf-pOhSw.mjs → device-pool-BMkdsefq.mjs} +5 -5
- package/dist/{doctor-kfMBnUw6.mjs → doctor-Bo7BXLux.mjs} +271 -320
- package/dist/{doctor-CB8oZKCk.mjs → doctor-D5_EzwfA.mjs} +186 -91
- package/dist/doctor-fingerprint-DZLoYFVb.mjs +16 -0
- package/dist/doctor-fingerprint.mjs +19 -0
- package/dist/doctor-thjWAV0z.mjs +2 -0
- package/dist/{doctor-watchman-BRyV2adA.mjs → doctor-watchman-N2wDotwQ.mjs} +40 -21
- package/dist/{eas-build-JyfqyHfC.mjs → eas-build-CwknaQYj.mjs} +53 -20
- package/dist/{build-plan-B7SZsc2N.mjs → eas-fallback-CSgAulr5.mjs} +41 -214
- package/dist/{watchman-CPQFZLXY.mjs → eas-session-ledger-DlY_serQ.mjs} +230 -11
- package/dist/{error-diagnostics-BR677IDM.mjs → error-diagnostics-DBWO2rxE.mjs} +172 -82
- package/dist/exec-DEoAhcze.mjs +858 -0
- package/dist/exec-DnYc4HGH.d.mts +78 -0
- package/dist/{gc-qWOMdnER.mjs → gc-CXxN-4SE.mjs} +1091 -1029
- package/dist/gc-DnNDQyaP.mjs +3 -0
- package/dist/{guide-G9cAbVAc.mjs → guide-Br0LEfKy.mjs} +1165 -297
- package/dist/{hosted-android-C3MHGld1.mjs → hosted-android-B-9f-jkd.mjs} +10 -8
- package/dist/{hosted-client-ZEKpS9vw.mjs → hosted-client-DZAPrcro.mjs} +34 -19
- package/dist/{hosted-ios-l-o3iM9J.mjs → hosted-ios-CsCS21hn.mjs} +1 -1
- package/dist/{hosted-logs-EzQM7-3Z.mjs → hosted-logs-FIRx9X2f.mjs} +77 -43
- package/dist/{hosted-macos-BACVAVqE.mjs → hosted-macos-_awYSpfv.mjs} +35 -22
- package/dist/{hosted-native-A4s1QPXe.mjs → hosted-native-BdzE668-.mjs} +49 -27
- package/dist/idle-C4cZ757K.d.mts +24 -0
- package/dist/{idle-shutdown-DtxhPTKe.mjs → idle-shutdown-DDg3SdvY.mjs} +11 -10
- package/dist/ios-CDvlmUs7.d.mts +24 -0
- package/dist/{ios-BwVCF7oA.mjs → ios-Ds1clbIt.mjs} +8 -8
- package/dist/{ios-device-D7pi2Sca.mjs → ios-device--h_-8ENa.mjs} +51 -26
- package/dist/{ios-device-B5veSDDQ.mjs → ios-device-BXZ0c7Kb.mjs} +1 -1
- package/dist/{ios-RkW4pnQf.mjs → ios-hcBpnEGk.mjs} +200 -93
- package/dist/{ios-Ce7bc7br.mjs → ios-pm4nL6By.mjs} +160 -108
- package/dist/{ios-project-K9hY_Jab.mjs → ios-project-CZhKODF3.mjs} +13 -13
- package/dist/ios-signing-BtAffm0A.mjs +489 -0
- package/dist/{ios-state-CBLe1xYw.mjs → ios-state-Dtw5K2aI.mjs} +1 -1
- package/dist/{ios-nOLJGVdy.mjs → ios-xtlRHaeB.mjs} +1 -1
- package/dist/{js-swap-Bb3nsS07.mjs → js-swap-Bwhh4S7V.mjs} +30 -25
- package/dist/{launch-C3qJ6Agb.mjs → launch-BjxemNpK.mjs} +85 -543
- package/dist/{launch-F4sOqAhB.mjs → launch-CCzXlc8r.mjs} +91 -90
- package/dist/logs-BfwwadsZ.mjs +479 -0
- package/dist/logs-jTS_lHSo.mjs +248 -0
- package/dist/{macos-D7uDvO-z.mjs → macos-DVlSSyUg.mjs} +1 -1
- package/dist/macos-NfV2D7dO.mjs +694 -0
- package/dist/macos-run.mjs +1 -1
- package/dist/maintenance-run.mjs +123 -248
- package/dist/{metro-DnCEjCxs.mjs → metro-DiXtA3Ty.mjs} +107 -30
- package/dist/metro-gateway-CKZqKqx7.mjs +209 -0
- package/dist/{named-ports-4WopRPg-.mjs → named-ports-DkEzOfzO.mjs} +42 -90
- package/dist/native-android-CqgnOgsT.mjs +645 -0
- package/dist/native-gradle-artifact-inputs-DHFnmrVf.mjs +270 -0
- package/dist/native-gradle-inputs-Dnh84Zbd.mjs +211 -0
- package/dist/native-inputs-TRTTTRxt.mjs +91 -0
- package/dist/native-run-NwUuxbkg.mjs +276 -0
- package/dist/{native-runtime-k8dTIrbK.mjs → native-runtime-B7KIafpM.mjs} +11 -9
- package/dist/native-source-Y0yLhFyQ.mjs +133 -0
- package/dist/{native-xcode-inputs-CykopJdM.mjs → native-xcode-inputs-D_VOfFL7.mjs} +26 -18
- package/dist/{native-xcode-ios-Bbf30Gm0.mjs → native-xcode-ios-BYDOHWLN.mjs} +104 -60
- package/dist/{ndjson-GOnbyvso.mjs → ndjson-CgE_o3Dl.mjs} +3 -3
- package/dist/offload-worker.d.mts +59 -41
- package/dist/offload-worker.mjs +478 -115
- package/dist/operation-exec-BW0em61G.mjs +171 -0
- package/dist/{ownership-DCtw_2IA.mjs → ownership-C5fo5Edb.mjs} +3 -3
- package/dist/{page-DRHy329N.mjs → page-DBL2PiUU.mjs} +12 -5
- package/dist/paths-BsJMoPP2.mjs +12 -0
- package/dist/paths-DQtTgsBf.mjs +42 -0
- package/dist/{placement-log-MOfPVgaM.mjs → placement-log-BnGgJRRZ.mjs} +5 -5
- package/dist/{plan-placement-V0TdzYXp.mjs → plan-placement-DIsMtN-d.mjs} +15 -11
- package/dist/{ports-DdSUicVo.mjs → ports-Cy1RkmuQ.mjs} +3 -3
- package/dist/prebuild-D4JoEAEs.mjs +484 -0
- package/dist/{project-_phNIJfs.mjs → project-wM_XFTvE.mjs} +65 -37
- package/dist/{pull-request-CQ8sPbZa.mjs → pull-request-W1IuLXDt.mjs} +102 -20
- package/dist/pull-request-eODyIqZF.d.mts +124 -0
- package/dist/pull-requests.d.mts +2 -120
- package/dist/pull-requests.mjs +2 -2
- package/dist/{react-native-android-CM1XRDwv.mjs → react-native-android-6OZ7MSM7.mjs} +121 -72
- package/dist/{gradle-DSrXb6lG.mjs → react-native-build-Dvd8hC21.mjs} +292 -15
- package/dist/react-native-doctor-DsoSF1Y9.mjs +234 -0
- package/dist/{react-native-ios-Dhq_eiYQ.mjs → react-native-ios-4u1Rn-GR.mjs} +71 -39
- package/dist/{recordings-D0d5aQt0.mjs → recordings-CQmfzAh7.mjs} +12 -9
- package/dist/registration-BcRgF6Ox.mjs +51 -0
- package/dist/{reload-C8JhxjSh.mjs → reload-BzkYabB-.mjs} +94 -47
- package/dist/reload-D7AVlb8N.mjs +2 -0
- package/dist/{remote-BiR6aYjy.mjs → remote-DjGDmlTZ.mjs} +26 -18
- package/dist/result-D2Ykz_iD.mjs +435 -0
- package/dist/{run-BtPgpKks.mjs → run-DidHghD1.mjs} +5 -5
- package/dist/selection-DSMbWEX2.mjs +620 -0
- package/dist/{server-bare-R2m_gsH8.mjs → server-bare-CafzuyFB.mjs} +3 -4
- package/dist/{server-command-CTtCkmcQ.mjs → server-command-C6QjeupS.mjs} +14 -7
- package/dist/{server-expo-DsguMGUF.mjs → server-expo-CrjB29pq.mjs} +54 -11
- package/dist/server-expo-D58c9L0M.mjs +2 -0
- package/dist/{settings-B717odTD.mjs → settings-C7O8A6ZI.mjs} +309 -119
- package/dist/settings-DpR-1Wnn.mjs +114 -0
- package/dist/settings-write-CzD60rOD.mjs +360 -0
- package/dist/settings.schema.json +176 -16
- package/dist/{simslim-CCr3rE-A.mjs → simslim-BNckWpXi.mjs} +14 -12
- package/dist/{slot-launch-DPt0m9Nd.mjs → slot-launch-CbfmNgM6.mjs} +15 -20
- package/dist/{spawn-entry-Dcb7sDUz.mjs → spawn-entry-jw19m8Nl.mjs} +0 -1
- package/dist/stage-Bps5oius.mjs +200 -0
- package/dist/{start-TXeMmmO2.mjs → start-Br-oxqMD.mjs} +1 -1
- package/dist/start-EojN4WFz.mjs +1364 -0
- package/dist/{state-D1Icyjlu.mjs → state--smjFSTL.mjs} +55 -13
- package/dist/{state-CG_OFoaA.mjs → state-08I3hw3_.mjs} +3 -2
- package/dist/{stats-BoY5sEPU.mjs → stats-D3GerlFW.mjs} +7 -13
- package/dist/stats-report-BzaPrRm6.mjs +16 -0
- package/dist/{status-BTA7kKiQ.mjs → status-BRROykC8.mjs} +7 -5
- package/dist/status-EvrK72L2.mjs +2 -0
- package/dist/{status-WgFbkRzj.mjs → status-WBDajew2.mjs} +554 -452
- package/dist/{status-watch-C23ILtf9.mjs → status-watch-Bg_u-pwR.mjs} +222 -25
- package/dist/status-worker.d.mts +1 -0
- package/dist/status-worker.mjs +19 -0
- package/dist/stim-desktop-D5OGpYZM.mjs +112 -0
- package/dist/{stop-DR6VoDIk.mjs → stop-DTZ9uTw3.mjs} +2 -2
- package/dist/{stop-DPEhunlw.mjs → stop-Dky10AEJ.mjs} +33 -23
- package/dist/{stop-BNmBMi1F.mjs → stop-Mv6W9FAk.mjs} +137 -98
- package/dist/supervisor-run.d.mts +8 -17
- package/dist/supervisor-run.mjs +56 -28
- package/dist/{support-CwjbFs9H.mjs → support-CNioewsd.mjs} +14 -14
- package/dist/{support-DMTqj3Hm.mjs → support-yUiOjnVY.mjs} +20 -13
- package/dist/swiftpm-artifact-inputs-DFcGsXDP.mjs +153 -0
- package/dist/swiftpm-macos-BIak-Rxv.mjs +532 -0
- package/dist/toolchain-BY8X8HXx.mjs +2 -0
- package/dist/toolchain-DpJMHq0n.mjs +876 -0
- package/dist/{trigger-CigAYjeL.mjs → trigger-Cbyc41d_.mjs} +21 -6
- package/dist/trigger-yb_nFzPF.mjs +2 -0
- package/dist/{warm-progress-BuY-Fvfn.mjs → warm-progress-CA3TgT3-.mjs} +263 -156
- package/dist/web-CZ07gd77.mjs +2 -0
- package/dist/{web-BDBMxDpx.mjs → web-DKx6yoFA.mjs} +20 -14
- package/dist/web-run.mjs +13 -12
- package/dist/windows-report.d.mts +1 -0
- package/dist/windows-report.mjs +18 -0
- package/dist/windows-report.ps1 +43 -0
- package/dist/{workspace-state-DJt_MMvf.mjs → workspace-state-U08dEzhG.mjs} +62 -58
- package/dist/{workspaces-C36s2jb9.mjs → workspaces-CpANmBlq.mjs} +1723 -1286
- package/dist/{worktree-CgvJYJ-Q.mjs → worktree-CHecZ4Oq.mjs} +1097 -547
- package/dist/worktree-ZqZVjD9K.mjs +2 -0
- package/dist/xcode-BXn9-xYx.mjs +896 -0
- package/package.json +7 -5
- package/shim/android-audio/Main.java +24 -0
- package/shim/android-audio/README.md +17 -0
- package/shim/android-audio.jar +0 -0
- package/shim/android-optimizations.gradle +7 -5
- package/dist/activity-BSV745Kz.mjs +0 -629
- package/dist/api-qvOzWyfO.mjs +0 -154
- package/dist/api-run.mjs +0 -294
- package/dist/app-install-BIKtMfPq.mjs +0 -896
- package/dist/artifact-lifecycle-DzPpBYvK.mjs +0 -30
- package/dist/budget-f7516Zk0.mjs +0 -4106
- package/dist/build-facts-DcLv2HSd.d.mts +0 -111
- package/dist/cancellation-C_22VQTH.mjs +0 -24
- package/dist/client-qQAaXSUs.mjs +0 -1771
- package/dist/config-BYDxlMY3.mjs +0 -562
- package/dist/device-DuiPJQSn.mjs +0 -290
- package/dist/device-lease-BX1sJQ2E.mjs +0 -1224
- package/dist/device-remote-xRT0Vmo9.mjs +0 -1272
- package/dist/eas-session-ledger-Cm0Gwq2F.mjs +0 -207
- package/dist/exec-DqKo9GKJ.mjs +0 -268
- package/dist/git-DDfFzkMm.mjs +0 -45
- package/dist/launch-verify-B6Q8hZP-.mjs +0 -428
- package/dist/logs-BGrEUaEs.mjs +0 -383
- package/dist/macos-Ch5VJmcS.mjs +0 -584
- package/dist/metro-gateway-CX9Xlkq2.mjs +0 -103
- package/dist/miss-reason-mKzZ4VvN.mjs +0 -238
- package/dist/native-android-D5qc3-_v.mjs +0 -226
- package/dist/native-gradle-inputs-BsLRrl7u.mjs +0 -349
- package/dist/ndjson-Du3j0AQ9.d.mts +0 -17
- package/dist/plan-C4TjdPsR.mjs +0 -260
- package/dist/prebuild-DYbucPXy.mjs +0 -212
- package/dist/preview-78a9kR_-.mjs +0 -1011
- package/dist/react-native-build-CtCccJtb.mjs +0 -239
- package/dist/react-native-doctor-CfRnFfjs.mjs +0 -78
- package/dist/remote-cache-OyOyVIS3.mjs +0 -526
- package/dist/result-CaJg5Iat.mjs +0 -186
- package/dist/server-expo-Bigriskl.mjs +0 -2
- package/dist/settings-BORNaaCO.mjs +0 -402
- package/dist/settings-vk3mJGSm.d.mts +0 -13
- package/dist/spawn-claims-DVS5RkMS.mjs +0 -72
- package/dist/stage-KNTQopqv.mjs +0 -157
- package/dist/start-BWqzODpb.mjs +0 -1116
- package/dist/stim-desktop-BzBN2Em2.mjs +0 -63
- package/dist/swiftpm-macos-DRNVJWlb.mjs +0 -119
- package/dist/tailnet-Dh-qiYzG.mjs +0 -265
- package/dist/toolchain-BFkAcstd.mjs +0 -2
- package/dist/toolchain-DxSsNssu.mjs +0 -1657
- package/dist/trigger-9_USgmxz.mjs +0 -2
- package/dist/web-Dq-i3wzJ.mjs +0 -2
- package/dist/worktree-DpLdCHga.mjs +0 -2
- package/dist/{api-run.d.mts → doctor-fingerprint.d.mts} +0 -0
- package/dist/{errors-DzkMYh8Q.mjs → errors-ccaPc4ox.mjs} +2 -2
|
@@ -1,23 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
13
|
-
import { NATIVE_CRASH_LOG_PREFIX, attachExpoErrorContext, readLogRecords, readLogTimeline } from "@stim-cli/core/state";
|
|
1
|
+
import { t as getExecutor } from "./exec-DEoAhcze.mjs";
|
|
2
|
+
import { v as withDirLock$1 } from "./paths-DQtTgsBf.mjs";
|
|
3
|
+
import { H as deviceSlotPlatforms, V as deviceSlotKey, p as getProject } from "./config-DlrsduwG.mjs";
|
|
4
|
+
import { v as launchErrorPreview } from "./command-output-gwpm28fu.mjs";
|
|
5
|
+
import { r as readWorkspaceState$1 } from "./workspace-state-U08dEzhG.mjs";
|
|
6
|
+
import { I as readWorkspaceLaunches } from "./project-wM_XFTvE.mjs";
|
|
7
|
+
import { d as resolveProjectMetro } from "./metro-DiXtA3Ty.mjs";
|
|
8
|
+
import { S as parseLease, v as deviceLeasePath, y as fileLeaseIo } from "./activity-CMLmzp7o.mjs";
|
|
9
|
+
import { o as androidHome, u as androidToolCwd } from "./android-C7sVmyI9.mjs";
|
|
10
|
+
import { r as deviceConsoleLevel } from "./ios-device-BXZ0c7Kb.mjs";
|
|
11
|
+
import { n as parseLogcatLine } from "./android-DR5lZ2Az.mjs";
|
|
14
12
|
import { createHash, randomUUID } from "node:crypto";
|
|
13
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
|
|
15
14
|
import { homedir } from "node:os";
|
|
15
|
+
import { basename, dirname, join, resolve, sep } from "node:path";
|
|
16
|
+
import { withDirLockAsync } from "@stim-cli/core";
|
|
17
|
+
import { NATIVE_CRASH_LOG_PREFIX, attachExpoErrorContext, readLogRecords, readLogTimeline } from "@stim-cli/core/state";
|
|
18
|
+
import { mkdir, readFile, readdir, stat, unlink, writeFile } from "node:fs/promises";
|
|
16
19
|
//#region src/diagnostics/diagnostic-store.ts
|
|
17
20
|
/** Publishes an immutable diagnostic snapshot atomically; existing evidence wins. */
|
|
18
21
|
function writeDiagnosticOnce(path, content) {
|
|
19
22
|
mkdirSync(dirname(path), { recursive: true });
|
|
20
|
-
withDirLock(`${path}.lock`, () => {
|
|
23
|
+
withDirLock$1(`${path}.lock`, () => {
|
|
21
24
|
if (existsSync(path)) return;
|
|
22
25
|
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
23
26
|
try {
|
|
@@ -33,6 +36,27 @@ function writeDiagnosticOnce(path, content) {
|
|
|
33
36
|
pollMs: 10
|
|
34
37
|
});
|
|
35
38
|
}
|
|
39
|
+
/** Publishes an immutable diagnostic snapshot without blocking on content writes or lock contention. */
|
|
40
|
+
async function writeDiagnosticOnceAsync(path, content, signal) {
|
|
41
|
+
signal?.throwIfAborted();
|
|
42
|
+
await mkdir(dirname(path), { recursive: true });
|
|
43
|
+
const temporary = `${path}.${randomUUID()}.tmp`;
|
|
44
|
+
try {
|
|
45
|
+
await writeFile(temporary, content, {
|
|
46
|
+
flag: "wx",
|
|
47
|
+
signal
|
|
48
|
+
});
|
|
49
|
+
await withDirLockAsync(`${path}.lock`, () => {
|
|
50
|
+
signal?.throwIfAborted();
|
|
51
|
+
if (!existsSync(path)) renameSync(temporary, path);
|
|
52
|
+
}, {
|
|
53
|
+
waitMs: 100,
|
|
54
|
+
pollMs: 10
|
|
55
|
+
});
|
|
56
|
+
} finally {
|
|
57
|
+
await unlink(temporary).catch(() => {});
|
|
58
|
+
}
|
|
59
|
+
}
|
|
36
60
|
//#endregion
|
|
37
61
|
//#region src/diagnostics/native-crash.ts
|
|
38
62
|
const IOS_CRASH_REPORT_RETRY = "iOS crash reports can take about a minute or longer to appear. Run `stim logs --errors` again for the native stack.";
|
|
@@ -115,7 +139,7 @@ function parseAndroidCrashes(text, target, clockOffsetMs) {
|
|
|
115
139
|
}];
|
|
116
140
|
});
|
|
117
141
|
}
|
|
118
|
-
function symbolicateIos(record, report, appPath, deadline) {
|
|
142
|
+
async function symbolicateIos(record, report, appPath, deadline, signal) {
|
|
119
143
|
if (!appPath || !existsSync(appPath) || !Array.isArray(record.stack)) return record;
|
|
120
144
|
const thread = report.threads?.find((entry) => entry.triggered) ?? report.threads?.[report.faultingThread ?? -1];
|
|
121
145
|
const stack = [...record.stack];
|
|
@@ -133,11 +157,11 @@ function symbolicateIos(record, report, appPath, deadline) {
|
|
|
133
157
|
const binary = relative ? resolve(appPath, relative) : null;
|
|
134
158
|
let matched = null;
|
|
135
159
|
if (binary && binary.startsWith(resolve(appPath) + sep) && existsSync(binary)) {
|
|
136
|
-
if (
|
|
160
|
+
if ((await crashCommand("xcrun", [
|
|
137
161
|
"dwarfdump",
|
|
138
162
|
"--uuid",
|
|
139
163
|
binary
|
|
140
|
-
], { timeoutMs: 2e3 })?.toLowerCase().includes(`uuid: ${image.uuid.toLowerCase()} (${image.arch.toLowerCase()})`)) matched = binary;
|
|
164
|
+
], { timeoutMs: 2e3 }, signal))?.toLowerCase().includes(`uuid: ${image.uuid.toLowerCase()} (${image.arch.toLowerCase()})`)) matched = binary;
|
|
141
165
|
}
|
|
142
166
|
verified.set(imageIndex, matched);
|
|
143
167
|
}
|
|
@@ -145,7 +169,7 @@ function symbolicateIos(record, report, appPath, deadline) {
|
|
|
145
169
|
if (!binary || Date.now() >= deadline) continue;
|
|
146
170
|
const address = image.base + frame.imageOffset;
|
|
147
171
|
if (!Number.isSafeInteger(address)) continue;
|
|
148
|
-
const output =
|
|
172
|
+
const output = await crashCommand("xcrun", [
|
|
149
173
|
"atos",
|
|
150
174
|
"-o",
|
|
151
175
|
binary,
|
|
@@ -154,7 +178,7 @@ function symbolicateIos(record, report, appPath, deadline) {
|
|
|
154
178
|
"-l",
|
|
155
179
|
`0x${image.base.toString(16)}`,
|
|
156
180
|
`0x${address.toString(16)}`
|
|
157
|
-
], { timeoutMs: 2e3 });
|
|
181
|
+
], { timeoutMs: 2e3 }, signal);
|
|
158
182
|
if (output && !/^0x[0-9a-f]+$/i.test(output) && !/error:|cannot|unable/i.test(output)) stack[index] = {
|
|
159
183
|
file: image.name ?? basename(binary),
|
|
160
184
|
fn: output
|
|
@@ -165,7 +189,7 @@ function symbolicateIos(record, report, appPath, deadline) {
|
|
|
165
189
|
stack
|
|
166
190
|
};
|
|
167
191
|
}
|
|
168
|
-
function symbolicateAndroid(record, root, budget) {
|
|
192
|
+
async function symbolicateAndroid(record, root, budget, signal, env = process.env) {
|
|
169
193
|
if (!root || typeof record.msg !== "string" || !/#\d+ pc /.test(record.msg)) return record;
|
|
170
194
|
const frames = [...record.msg.matchAll(/^\s*#\d+ pc ([0-9a-f]+)\s+(\S+)(.*)$/gim)];
|
|
171
195
|
const stack = frames.map(([, address, file, suffix]) => ({
|
|
@@ -173,12 +197,12 @@ function symbolicateAndroid(record, root, budget) {
|
|
|
173
197
|
fn: `${suffix?.trim() || `0x${address}`} [captured native frame]`
|
|
174
198
|
}));
|
|
175
199
|
let deadline = Math.min(Date.now() + 2e3, budget - 1e3);
|
|
176
|
-
const ndks = join(androidHome(), "ndk");
|
|
200
|
+
const ndks = join(androidHome(env), "ndk");
|
|
177
201
|
let tools;
|
|
178
202
|
try {
|
|
179
|
-
for (const version of
|
|
203
|
+
for (const version of (await readdir(ndks)).toSorted().toReversed()) {
|
|
180
204
|
const prebuilt = join(ndks, version, "toolchains/llvm/prebuilt");
|
|
181
|
-
for (const host of
|
|
205
|
+
for (const host of await readdir(prebuilt)) {
|
|
182
206
|
const bin = join(prebuilt, host, "bin");
|
|
183
207
|
if (existsSync(join(bin, "llvm-symbolizer"))) {
|
|
184
208
|
tools = bin;
|
|
@@ -189,10 +213,10 @@ function symbolicateAndroid(record, root, budget) {
|
|
|
189
213
|
}
|
|
190
214
|
} catch {}
|
|
191
215
|
const files = [];
|
|
192
|
-
const visit = (directory, depth) => {
|
|
216
|
+
const visit = async (directory, depth) => {
|
|
193
217
|
if (depth > 10 || files.length > 500 || Date.now() >= deadline) return;
|
|
194
218
|
try {
|
|
195
|
-
for (const entry of
|
|
219
|
+
for (const entry of await readdir(directory, { withFileTypes: true })) if (entry.isDirectory()) await visit(join(directory, entry.name), depth + 1);
|
|
196
220
|
else if (entry.isFile() && entry.name.endsWith(".so")) files.push(join(directory, entry.name));
|
|
197
221
|
} catch {}
|
|
198
222
|
};
|
|
@@ -201,7 +225,7 @@ function symbolicateAndroid(record, root, budget) {
|
|
|
201
225
|
"android/app/src/main/jniLibs",
|
|
202
226
|
"android/app/build/intermediates/cxx",
|
|
203
227
|
"android/app/.cxx"
|
|
204
|
-
]) visit(join(root, directory), 0);
|
|
228
|
+
]) await visit(join(root, directory), 0);
|
|
205
229
|
deadline = budget;
|
|
206
230
|
const byId = /* @__PURE__ */ new Map();
|
|
207
231
|
for (const [index, [, address, file, suffix]] of frames.entries()) {
|
|
@@ -209,21 +233,25 @@ function symbolicateAndroid(record, root, budget) {
|
|
|
209
233
|
const id = /\(BuildId: ([0-9a-f]+)\)/i.exec(suffix ?? "")?.[1]?.toLowerCase();
|
|
210
234
|
if (!id) continue;
|
|
211
235
|
if (!byId.has(id)) {
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
236
|
+
let binary;
|
|
237
|
+
for (const path of files.filter((candidate) => file.endsWith(".apk") || basename(candidate) === basename(file))) {
|
|
238
|
+
if (Date.now() >= deadline) break;
|
|
239
|
+
const notes = await crashCommand(join(tools, "llvm-readelf"), ["--notes", path], { timeoutMs: 1e3 }, signal);
|
|
240
|
+
if (/Build ID: ([0-9a-f]+)/i.exec(notes ?? "")?.[1]?.toLowerCase() === id) {
|
|
241
|
+
binary = path;
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
}
|
|
217
245
|
byId.set(id, binary ?? null);
|
|
218
246
|
}
|
|
219
247
|
const binary = byId.get(id);
|
|
220
248
|
if (!binary) continue;
|
|
221
|
-
const [fn, location] =
|
|
249
|
+
const [fn, location] = (await crashCommand(join(tools, "llvm-symbolizer"), [
|
|
222
250
|
"--no-inlines",
|
|
223
251
|
"--demangle",
|
|
224
252
|
`--obj=${binary}`,
|
|
225
253
|
`0x${address}`
|
|
226
|
-
], { timeoutMs: 1e3 })?.split("\n") ?? [];
|
|
254
|
+
], { timeoutMs: 1e3 }, signal))?.split("\n") ?? [];
|
|
227
255
|
const match = /^(.*):(\d+):(\d+)$/.exec(location ?? "");
|
|
228
256
|
if (fn && fn !== "??" && match && match[1] !== "??" && Number(match[2]) > 0) stack[index] = {
|
|
229
257
|
fn,
|
|
@@ -241,15 +269,15 @@ function symbolicateAndroid(record, root, budget) {
|
|
|
241
269
|
symbolicationNote: stack.some((frame) => !frame.line) ? "Native symbols are partial: unresolved frames retain crash-buffer symbols/addresses. Full captured report: stim logs --source device --json." : void 0
|
|
242
270
|
};
|
|
243
271
|
}
|
|
244
|
-
function simulatorConsolePaths(target, prepare = false, remote = false) {
|
|
272
|
+
async function simulatorConsolePaths(target, prepare = false, remote = false, signal) {
|
|
245
273
|
if (remote) return void 0;
|
|
246
|
-
const container =
|
|
274
|
+
const container = await crashCommand("xcrun", [
|
|
247
275
|
"simctl",
|
|
248
276
|
"get_app_container",
|
|
249
277
|
target.deviceId,
|
|
250
278
|
target.appId,
|
|
251
279
|
"data"
|
|
252
|
-
], { timeoutMs: 2e3 });
|
|
280
|
+
], { timeoutMs: 2e3 }, signal);
|
|
253
281
|
if (!container?.startsWith("/")) return void 0;
|
|
254
282
|
const directory = join(container, "Library/Caches/Stim");
|
|
255
283
|
const key = createHash("sha256").update(JSON.stringify([
|
|
@@ -262,24 +290,35 @@ function simulatorConsolePaths(target, prepare = false, remote = false) {
|
|
|
262
290
|
stderr: join(directory, `launch-${key}.stderr`)
|
|
263
291
|
};
|
|
264
292
|
if (prepare) try {
|
|
265
|
-
|
|
266
|
-
for (const path of Object.values(paths))
|
|
293
|
+
await mkdir(directory, { recursive: true });
|
|
294
|
+
for (const path of Object.values(paths)) await writeFile(path, "", {
|
|
295
|
+
flag: "wx",
|
|
296
|
+
signal
|
|
297
|
+
});
|
|
267
298
|
} catch {
|
|
299
|
+
signal?.throwIfAborted();
|
|
268
300
|
return;
|
|
269
301
|
}
|
|
302
|
+
signal?.throwIfAborted();
|
|
270
303
|
return paths;
|
|
271
304
|
}
|
|
272
|
-
function simulatorFatalConsole(target) {
|
|
273
|
-
const paths = simulatorConsolePaths(target);
|
|
274
|
-
|
|
305
|
+
async function simulatorFatalConsole(target, signal) {
|
|
306
|
+
const paths = await simulatorConsolePaths(target, false, false, signal);
|
|
307
|
+
const records = [];
|
|
308
|
+
for (const path of Object.values(paths ?? {})) {
|
|
309
|
+
signal?.throwIfAborted();
|
|
275
310
|
try {
|
|
276
|
-
|
|
277
|
-
if (
|
|
278
|
-
|
|
311
|
+
const info = await stat(path);
|
|
312
|
+
if (info.size > 8388608) continue;
|
|
313
|
+
if (target.until !== void 0 && info.mtimeMs > target.until) continue;
|
|
314
|
+
const text = await readFile(path, {
|
|
315
|
+
encoding: "utf8",
|
|
316
|
+
signal
|
|
317
|
+
});
|
|
279
318
|
const fatal = text.split("\n").filter((line) => deviceConsoleLevel(line) === "fatal");
|
|
280
|
-
if (!fatal.length)
|
|
281
|
-
|
|
282
|
-
ts: Math.max(target.since + 1,
|
|
319
|
+
if (!fatal.length) continue;
|
|
320
|
+
records.push({
|
|
321
|
+
ts: Math.max(target.since + 1, info.mtimeMs),
|
|
283
322
|
src: "device",
|
|
284
323
|
platform: "ios",
|
|
285
324
|
level: "fatal",
|
|
@@ -291,34 +330,60 @@ function simulatorFatalConsole(target) {
|
|
|
291
330
|
msg: fatal.join("\n"),
|
|
292
331
|
rawReport: text,
|
|
293
332
|
symbolicationNote: `Captured app stderr; the full operating system crash report is not available yet. ${IOS_CRASH_REPORT_RETRY}`
|
|
294
|
-
}
|
|
295
|
-
} catch {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
333
|
+
});
|
|
334
|
+
} catch {}
|
|
335
|
+
}
|
|
336
|
+
signal?.throwIfAborted();
|
|
337
|
+
return records;
|
|
299
338
|
}
|
|
300
339
|
/** Reads platform crash evidence without starting, stopping or modifying a device. */
|
|
301
|
-
function captureNativeCrashes(target, logsDir) {
|
|
340
|
+
async function captureNativeCrashes(target, logsDir, signal, env = process.env) {
|
|
341
|
+
signal?.throwIfAborted();
|
|
302
342
|
let records = [];
|
|
303
343
|
try {
|
|
304
344
|
if (target.platform === "ios" && !target.physical && process.platform === "darwin") {
|
|
305
345
|
const deadline = Date.now() + 4e3;
|
|
306
|
-
records = simulatorFatalConsole(target);
|
|
307
|
-
const directory = join(homedir(), "Library/Logs/DiagnosticReports");
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
346
|
+
records = await simulatorFatalConsole(target, signal);
|
|
347
|
+
const directory = join(env.HOME || homedir(), "Library/Logs/DiagnosticReports");
|
|
348
|
+
const reports = [];
|
|
349
|
+
for (const name of await readdir(directory)) {
|
|
350
|
+
signal?.throwIfAborted();
|
|
351
|
+
if (!name.endsWith(".ips")) continue;
|
|
352
|
+
const path = join(directory, name);
|
|
353
|
+
const time = (await stat(path)).mtimeMs;
|
|
354
|
+
if (time >= target.since) reports.push({
|
|
355
|
+
path,
|
|
356
|
+
time
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
reports.sort((a, b) => b.time - a.time);
|
|
360
|
+
const nativeReports = [];
|
|
361
|
+
for (const { path } of reports.slice(0, 50)) {
|
|
362
|
+
if (Date.now() >= deadline) break;
|
|
363
|
+
if ((await stat(path)).size > 8388608) continue;
|
|
364
|
+
const parsed = parseIosCrash(await readFile(path, {
|
|
365
|
+
encoding: "utf8",
|
|
366
|
+
signal
|
|
367
|
+
}), target);
|
|
368
|
+
if (parsed) nativeReports.push(await symbolicateIos(parsed.record, parsed.report, target.appPath, deadline, signal));
|
|
369
|
+
}
|
|
317
370
|
if (nativeReports.length) records = nativeReports;
|
|
318
371
|
} else if (target.platform === "android") {
|
|
319
|
-
const
|
|
320
|
-
|
|
321
|
-
|
|
372
|
+
const before = Date.now();
|
|
373
|
+
const clock = (await crashCommand("adb", [
|
|
374
|
+
"-s",
|
|
375
|
+
target.deviceId,
|
|
376
|
+
"shell",
|
|
377
|
+
"date",
|
|
378
|
+
"+%s%3N"
|
|
379
|
+
], {
|
|
380
|
+
timeoutMs: 1e3,
|
|
381
|
+
cwd: androidToolCwd()
|
|
382
|
+
}, signal))?.trim();
|
|
383
|
+
const after = Date.now();
|
|
384
|
+
if (!/^\d{13}$/.test(clock ?? "") || after < before || after - before > 1e3) return [];
|
|
385
|
+
const offset = Math.round((before + after) / 2) - Number(clock);
|
|
386
|
+
const text = await crashCommand("adb", [
|
|
322
387
|
"-s",
|
|
323
388
|
target.deviceId,
|
|
324
389
|
"logcat",
|
|
@@ -332,11 +397,12 @@ function captureNativeCrashes(target, logsDir) {
|
|
|
332
397
|
], {
|
|
333
398
|
timeoutMs: 3e3,
|
|
334
399
|
cwd: androidToolCwd()
|
|
335
|
-
});
|
|
400
|
+
}, signal);
|
|
336
401
|
const deadline = Date.now() + 4e3;
|
|
337
|
-
if (text)
|
|
402
|
+
if (text) for (const record of parseAndroidCrashes(text, target, offset)) records.push(await symbolicateAndroid(record, target.root, deadline, signal, env));
|
|
338
403
|
}
|
|
339
404
|
} catch {}
|
|
405
|
+
signal?.throwIfAborted();
|
|
340
406
|
for (const record of records) {
|
|
341
407
|
if (target.slot && target.slot !== "default") record.slot = target.slot;
|
|
342
408
|
try {
|
|
@@ -346,23 +412,26 @@ function captureNativeCrashes(target, logsDir) {
|
|
|
346
412
|
record.incident ?? record.deviceTs,
|
|
347
413
|
record.rawReport
|
|
348
414
|
])).digest("hex");
|
|
349
|
-
|
|
415
|
+
await writeDiagnosticOnceAsync(join(logsDir, `${NATIVE_CRASH_LOG_PREFIX}${key}.ndjson`), `${JSON.stringify(record)}\n`, signal);
|
|
350
416
|
} catch {}
|
|
351
417
|
}
|
|
418
|
+
signal?.throwIfAborted();
|
|
352
419
|
return records;
|
|
353
420
|
}
|
|
354
|
-
function printNativeCrashReport(target, logsDir, emit, remote) {
|
|
421
|
+
async function printNativeCrashReport(target, logsDir, emit, remote, signal, env) {
|
|
355
422
|
if (remote) return;
|
|
356
|
-
for (const line of launchErrorPreview(captureNativeCrashes(target, logsDir), target.root)) emit(line);
|
|
423
|
+
for (const line of launchErrorPreview(await captureNativeCrashes(target, logsDir, signal, env), target.root)) emit(line);
|
|
357
424
|
}
|
|
358
|
-
/** Captures
|
|
359
|
-
function captureWorkspaceCrashes(root, logsDir) {
|
|
360
|
-
|
|
361
|
-
const
|
|
425
|
+
/** Captures current launch crashes. Supplying attempts skips the timeline read and returns an empty array. */
|
|
426
|
+
async function captureWorkspaceCrashes(root, logsDir, attempts, signal, env = process.env) {
|
|
427
|
+
signal?.throwIfAborted();
|
|
428
|
+
const timeline = attempts === void 0 ? readLogRecords(logsDir, (name) => !name.startsWith(NATIVE_CRASH_LOG_PREFIX)) : [];
|
|
429
|
+
const launchAttempts = attempts ?? timeline.filter((record) => record.event === "launch_attempt");
|
|
362
430
|
const launches = readWorkspaceLaunches(root);
|
|
363
431
|
const latest = /* @__PURE__ */ new Map();
|
|
364
|
-
for (const attempt of
|
|
432
|
+
for (const attempt of launchAttempts) if (attempt.platform === "ios" || attempt.platform === "android") latest.set(deviceSlotKey(attempt.platform, String(attempt.slot ?? "default")), attempt);
|
|
365
433
|
for (const [key, attempt] of latest) {
|
|
434
|
+
signal?.throwIfAborted();
|
|
366
435
|
const platform = attempt.platform;
|
|
367
436
|
const slot = String(attempt.slot ?? "default");
|
|
368
437
|
try {
|
|
@@ -383,7 +452,7 @@ function captureWorkspaceCrashes(root, logsDir) {
|
|
|
383
452
|
if (platform === "ios" && configured.deviceUdid !== deviceId) continue;
|
|
384
453
|
if (platform === "android") {
|
|
385
454
|
if (!configured.avdName) continue;
|
|
386
|
-
if (
|
|
455
|
+
if ((await crashCommand("adb", [
|
|
387
456
|
"-s",
|
|
388
457
|
deviceId,
|
|
389
458
|
"emu",
|
|
@@ -392,10 +461,10 @@ function captureWorkspaceCrashes(root, logsDir) {
|
|
|
392
461
|
], {
|
|
393
462
|
timeoutMs: 2e3,
|
|
394
463
|
cwd: androidToolCwd()
|
|
395
|
-
})?.split("\n")[0]?.trim() !== configured.avdName) continue;
|
|
464
|
+
}, signal))?.split("\n")[0]?.trim() !== configured.avdName) continue;
|
|
396
465
|
}
|
|
397
466
|
}
|
|
398
|
-
captureNativeCrashes({
|
|
467
|
+
await captureNativeCrashes({
|
|
399
468
|
root,
|
|
400
469
|
slot,
|
|
401
470
|
platform,
|
|
@@ -405,10 +474,31 @@ function captureWorkspaceCrashes(root, logsDir) {
|
|
|
405
474
|
until,
|
|
406
475
|
physical: attempt?.physical === true,
|
|
407
476
|
appPath: attempt?.appPath ?? readWorkspaceState$1(root)?.lastBuild?.appPath
|
|
408
|
-
}, logsDir);
|
|
477
|
+
}, logsDir, signal, env);
|
|
409
478
|
} catch {}
|
|
410
479
|
}
|
|
411
|
-
|
|
480
|
+
signal?.throwIfAborted();
|
|
481
|
+
return attempts === void 0 ? readLogTimeline(logsDir, timeline) : [];
|
|
482
|
+
}
|
|
483
|
+
async function crashCommand(file, args, options, signal) {
|
|
484
|
+
signal?.throwIfAborted();
|
|
485
|
+
let cancel;
|
|
486
|
+
try {
|
|
487
|
+
const result = await getExecutor().runFileQuietAsync(file, args, {
|
|
488
|
+
...options,
|
|
489
|
+
...signal ? { onSpawn(child) {
|
|
490
|
+
cancel = () => {
|
|
491
|
+
child.kill("SIGKILL");
|
|
492
|
+
};
|
|
493
|
+
signal.addEventListener("abort", cancel, { once: true });
|
|
494
|
+
if (signal.aborted) cancel();
|
|
495
|
+
} } : {}
|
|
496
|
+
});
|
|
497
|
+
signal?.throwIfAborted();
|
|
498
|
+
return result;
|
|
499
|
+
} finally {
|
|
500
|
+
if (cancel) signal?.removeEventListener("abort", cancel);
|
|
501
|
+
}
|
|
412
502
|
}
|
|
413
503
|
//#endregion
|
|
414
504
|
//#region src/diagnostics/error-symbolication.ts
|