stim 1.8.0 → 1.9.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 +23 -155
- package/dist/{android-BRgBYzU0.mjs → android-BPGizezh.mjs} +112 -135
- package/dist/{android-DeYdjjBP.mjs → android-DEgo4oCo.mjs} +2 -2
- package/dist/{android-DWssqHQ8.mjs → android-_y4Ohi5z.mjs} +54 -15
- package/dist/android-cas-compiler.mjs +2 -2
- package/dist/{android-cas-SWIjzeuL.mjs → android-cas-eiExNLf7.mjs} +21 -14
- package/dist/app-install-Uf3a83Tv.mjs +819 -0
- package/dist/{build-lock-CgtsB6TV.mjs → build-lock-DPXPLgTc.mjs} +120 -24
- package/dist/build-progress-CVqkfPC6.mjs +188 -0
- package/dist/{cache-manifest-CYJi8-Hx.mjs → cache-manifest-Dg7OnMrp.mjs} +4 -4
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +22 -19
- package/dist/collector-run.d.mts +2 -0
- package/dist/collector-run.mjs +10 -9
- package/dist/{command-output-B3ycpsYv.mjs → command-output-gByVmIjy.mjs} +11 -2
- package/dist/{config-B7iyKWkL.mjs → config-Cp9lM3wX.mjs} +187 -57
- package/dist/{dependency-state-D0M7oKA7.mjs → dependency-state-Bq5DcLGn.mjs} +2 -2
- package/dist/{deps-oCXVNEqQ.mjs → deps-Cip5vUm1.mjs} +8 -5
- package/dist/{detached-entry-Bpo6ZY_I.mjs → detached-entry-KEu0_AXL.mjs} +1 -1
- package/dist/{device-BUoZyMoR.mjs → dev-client-HyqISM0h.mjs} +1178 -635
- package/dist/{device-RdujjHLB.mjs → device-D4U-xLty.mjs} +13 -20
- package/dist/{device-lease-Ffz_M5t0.mjs → device-lease-Crs-HkJY.mjs} +16 -9
- package/dist/{device-pool-BxRwdufO.mjs → device-pool-CnTAz8X1.mjs} +7 -7
- package/dist/{device-remote-ByN8P6CB.mjs → device-remote-AQ5rQPqr.mjs} +482 -35
- package/dist/{doctor-BMt156qe.mjs → doctor-B_Ei3bZu.mjs} +95 -107
- package/dist/{error-diagnostics-D1Kaf-eT.mjs → error-diagnostics-Vfz83GCF.mjs} +22 -16
- package/dist/exec-jIAlgilk.mjs +132 -0
- package/dist/{gc-v2YcoJvm.mjs → gc-Ckw8RQHi.mjs} +763 -126
- package/dist/{guide-BTAlD1_y.mjs → guide-BiAbhs1J.mjs} +891 -501
- package/dist/{guide-status-Craq9z0t.mjs → guide-status-BAMVU0ZA.mjs} +5 -3
- package/dist/{ios-BcCiI4TS.mjs → ios-BL2NFckr.mjs} +43 -20
- package/dist/{ios-BP04pY5f.mjs → ios-BzUJWk1K.mjs} +141 -175
- package/dist/{ios-device-CauFJiYx.mjs → ios-device-D972i9wf.mjs} +149 -52
- package/dist/{ios-device-CFXA46ez.mjs → ios-device-DPsSm0v_.mjs} +3 -2
- package/dist/launch-verify-Q_OtW1Rf.mjs +365 -0
- package/dist/{logs-CakdBTtm.mjs → logs-CI9NQSK7.mjs} +18 -13
- package/dist/{logs-query-BGL-Pl12.mjs → logs-query-Cqma3WIu.mjs} +36 -28
- package/dist/{metro-C7bcJ0uo.mjs → metro-DrLHaMn2.mjs} +78 -8
- package/dist/{named-ports-DzMOlmaX.mjs → named-ports-CmLQSIRj.mjs} +4 -4
- package/dist/{ndjson-BZwI1NBv.mjs → ndjson-9uFNRwfe.mjs} +36 -3
- package/dist/{ownership-Cp52QAK1.mjs → ownership-D15Op8vN.mjs} +3 -3
- package/dist/{ownership-wolE-0Do.mjs → ownership-DCQPuWEc.mjs} +26 -7
- package/dist/{ports-BIbJaKNW.mjs → ports-BNKoWVWZ.mjs} +3 -3
- package/dist/{process-output-Dl5uKE03.mjs → process-output-Fpl8PYi8.mjs} +1 -1
- package/dist/{project-DDZWf_16.mjs → project-DS112DYB.mjs} +8 -3
- package/dist/{reload-BdypPbjM.mjs → reload-ZNJUo1pl.mjs} +12 -13
- package/dist/{server-bare-BQkyxa_b.mjs → server-bare-DWkkcIxV.mjs} +2 -2
- package/dist/{server-expo-BVAA1OqJ.mjs → server-expo-B_lctBR3.mjs} +8 -7
- package/dist/server-expo-CeILEu86.mjs +2 -0
- package/dist/settings-BKNh5rl4.mjs +376 -0
- package/dist/{settings-BXXorVM2.mjs → settings-D030k0t4.mjs} +464 -152
- package/dist/settings.schema.json +989 -0
- package/dist/{teardown-BJqEzPo_.mjs → sim-pool-KaIsp2Ft.mjs} +14 -419
- package/dist/simslim-B_LsGLuJ.mjs +259 -0
- package/dist/{slot-launch-ZUUe0TQP.mjs → slot-launch-DU9A-gYw.mjs} +4 -4
- package/dist/spawn-claims-Dn3C_N6w.mjs +49 -0
- package/dist/{start-CmxtOKjU.mjs → start-DYkkKF0s.mjs} +27 -31
- package/dist/{state-DZobzxLW.mjs → state-NcJzMEBF.mjs} +5 -3
- package/dist/{stats-CLg5RuDS.mjs → stats-B63-JVAY.mjs} +4 -4
- package/dist/{stats-BYcZ6n1h.mjs → stats-DG9e66Rz.mjs} +66 -5
- package/dist/status-S6ehL4Ui.mjs +932 -0
- package/dist/{stop-C8JW6kKp.mjs → stop-BO28HGqF.mjs} +101 -25
- package/dist/{stop-B1kOpYei.mjs → stop-T1R-cZRz.mjs} +2 -2
- package/dist/supervisor-run.mjs +52 -34
- package/dist/{workspace-process-lock-BYfZz_S-.mjs → workspace-process-lock-DWaiRD0e.mjs} +14 -9
- package/dist/{workspace-state-BT5E3SA2.mjs → workspace-state-DF2gCFhx.mjs} +52 -29
- package/dist/worktree-DKhSF0UX.mjs +2 -0
- package/dist/{worktree-CFLA-6MX.mjs → worktree-LGB-UwgG.mjs} +603 -59
- package/dist/{worktree-FG_ZKKdb.mjs → worktree-R_cUlE7s.mjs} +62 -41
- package/dist/{xcode-B6YaWeg0.mjs → xcode-BZqyxh3e.mjs} +216 -58
- package/package.json +5 -6
- package/skill/SKILL.md +2 -0
- package/dist/app-install-BDbsSgCl.mjs +0 -1175
- package/dist/build-slots-C-oAHRT1.mjs +0 -151
- package/dist/dev-client-BmT-ioFI.mjs +0 -797
- package/dist/exec-B29XNuhP.mjs +0 -77
- package/dist/reclaim-KJ-0uWEF.mjs +0 -361
- package/dist/server-expo-YDDG3eP7.mjs +0 -2
- package/dist/status-DdkLki47.mjs +0 -426
- package/dist/{metro-store-CDDZHtPl.mjs → metro-store-DzeWkfqW.mjs} +1 -1
|
@@ -1,17 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { r as createNdjsonWriter } from "./ndjson-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as stripAnsi } from "./process-output-
|
|
7
|
-
import {
|
|
8
|
-
import { l as phaseLine } from "./command-output-B3ycpsYv.mjs";
|
|
9
|
-
import { n as expoBinFromPackage, r as expoBinPath, s as findBinUpward } from "./server-expo-BVAA1OqJ.mjs";
|
|
10
|
-
import { C as shutdownIosSim, _ as renameIosSim, a as deleteIosSim, d as listIosDeviceTypes, g as parseRuntimeVersion, h as parkedSimName, o as deleteParkedIosSim, r as clearAppDataContainer, s as findAppDataContainer, x as resolveOwnedIosSim } from "./ios-BcCiI4TS.mjs";
|
|
1
|
+
import { B as assignSlotDevice, T as withConfigLock, U as deviceSlotPlatforms, d as getConfigPath, g as loadConfig, k as ownership_claim_exports, q as removeSlotDevice, s as ensureConfig, u as getConfigDir, x as saveConfig } from "./config-Cp9lM3wX.mjs";
|
|
2
|
+
import { t as getExecutor } from "./exec-jIAlgilk.mjs";
|
|
3
|
+
import { r as createNdjsonWriter } from "./ndjson-9uFNRwfe.mjs";
|
|
4
|
+
import { b as workspaceLogsDir } from "./workspace-state-DF2gCFhx.mjs";
|
|
5
|
+
import { u as resolvePackageJson } from "./project-DS112DYB.mjs";
|
|
6
|
+
import { n as stripAnsi } from "./process-output-Fpl8PYi8.mjs";
|
|
7
|
+
import { n as expoBinFromPackage, r as expoBinPath, s as findBinUpward } from "./server-expo-B_lctBR3.mjs";
|
|
11
8
|
import { createRequire } from "node:module";
|
|
12
|
-
import { existsSync,
|
|
13
|
-
import {
|
|
14
|
-
import { dirname, join } from "node:path";
|
|
9
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
10
|
+
import { join } from "node:path";
|
|
15
11
|
import { pathToFileURL } from "node:url";
|
|
16
12
|
import { format, isDeepStrictEqual } from "node:util";
|
|
17
13
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
@@ -471,6 +467,10 @@ async function uploadRemote({ provider, platform, projectRoot, fingerprintHash,
|
|
|
471
467
|
});
|
|
472
468
|
if (outcome.timedOut) return { timedOut: true };
|
|
473
469
|
if (outcome.error) return { failed: firstLine(outcome.error) };
|
|
470
|
+
if (typeof outcome.value !== "string" || outcome.value.trim() === "") {
|
|
471
|
+
const authLine = outcome.lines.find((line) => isEasAuthFailureText(line));
|
|
472
|
+
return { failed: authLine ? firstLine(authLine) : "the provider returned no upload destination" };
|
|
473
|
+
}
|
|
474
474
|
const destination = uploadDestination(outcome.lines);
|
|
475
475
|
return destination ? {
|
|
476
476
|
uploaded: true,
|
|
@@ -720,409 +720,4 @@ function dropParked(platform, udid) {
|
|
|
720
720
|
return removeParkedAfter(platform, udid, () => {}) !== null;
|
|
721
721
|
}
|
|
722
722
|
//#endregion
|
|
723
|
-
|
|
724
|
-
function parseAgentDeviceSessions(output) {
|
|
725
|
-
const result = JSON.parse(output);
|
|
726
|
-
if (result?.success !== true || !Array.isArray(result.data?.sessions)) throw new Error("agent-device did not return a successful session list");
|
|
727
|
-
return result.data.sessions.flatMap((entry) => {
|
|
728
|
-
if (!entry || typeof entry !== "object") return [];
|
|
729
|
-
const row = entry;
|
|
730
|
-
const id = row.platform === "ios" ? row.device_udid : row.id;
|
|
731
|
-
if (row.platform !== "ios" && row.platform !== "android" || typeof row.name !== "string" || !row.name.trim() || typeof id !== "string" || !id || typeof row.createdAt !== "number" || !Number.isFinite(row.createdAt) || row.platform === "ios" && row.id !== void 0 && row.id !== id) return [];
|
|
732
|
-
return [{
|
|
733
|
-
name: row.name,
|
|
734
|
-
platform: row.platform,
|
|
735
|
-
id,
|
|
736
|
-
createdAt: row.createdAt
|
|
737
|
-
}];
|
|
738
|
-
});
|
|
739
|
-
}
|
|
740
|
-
function report(message) {
|
|
741
|
-
process.stderr.write(`${phaseLine("device", message)}\n`);
|
|
742
|
-
}
|
|
743
|
-
function closeOwnedDeviceSessions(device, stillOwned) {
|
|
744
|
-
const exec = getExecutor();
|
|
745
|
-
const deadline = Date.now() + 15e3;
|
|
746
|
-
const run = (args) => {
|
|
747
|
-
const remaining = deadline - Date.now();
|
|
748
|
-
if (remaining <= 0) throw new Error("agent-device cleanup timed out");
|
|
749
|
-
return exec.runFile("agent-device", [
|
|
750
|
-
...args,
|
|
751
|
-
"--json",
|
|
752
|
-
"--daemon-transport",
|
|
753
|
-
"socket"
|
|
754
|
-
], {
|
|
755
|
-
timeoutMs: Math.min(5e3, remaining),
|
|
756
|
-
killSignal: "SIGKILL"
|
|
757
|
-
});
|
|
758
|
-
};
|
|
759
|
-
const list = () => parseAgentDeviceSessions(run([
|
|
760
|
-
"session",
|
|
761
|
-
"list",
|
|
762
|
-
"--session",
|
|
763
|
-
"stim-teardown-inventory"
|
|
764
|
-
]));
|
|
765
|
-
try {
|
|
766
|
-
if (!exec.findExecutable("agent-device")) return;
|
|
767
|
-
const sessions = list().filter((session) => session.platform === device.platform && session.id === device.id);
|
|
768
|
-
for (const session of sessions) try {
|
|
769
|
-
if (!list().some((current) => current.name === session.name && current.platform === session.platform && current.id === session.id && current.createdAt === session.createdAt)) continue;
|
|
770
|
-
if (!stillOwned()) return;
|
|
771
|
-
if (JSON.parse(run([
|
|
772
|
-
"close",
|
|
773
|
-
"--session",
|
|
774
|
-
session.name,
|
|
775
|
-
"--session-lock",
|
|
776
|
-
"reject",
|
|
777
|
-
"--platform",
|
|
778
|
-
device.platform,
|
|
779
|
-
device.platform === "ios" ? "--udid" : "--serial",
|
|
780
|
-
device.id
|
|
781
|
-
]))?.success !== true) throw new Error("agent-device did not confirm session close");
|
|
782
|
-
report(`closed agent-device session ${session.name} on ${device.id}`);
|
|
783
|
-
} catch (error) {
|
|
784
|
-
report(`could not close agent-device session ${session.name} on ${device.id}: ${error.message}`);
|
|
785
|
-
}
|
|
786
|
-
} catch (error) {
|
|
787
|
-
report(`could not list agent-device sessions for ${device.id}: ${error.message}`);
|
|
788
|
-
}
|
|
789
|
-
}
|
|
790
|
-
//#endregion
|
|
791
|
-
//#region src/devices/teardown.ts
|
|
792
|
-
function teardownParkedAvd(avdName) {
|
|
793
|
-
try {
|
|
794
|
-
return removeParkedAfter("android", avdName, () => {
|
|
795
|
-
const result = teardownOwnedAvd(avdName, {
|
|
796
|
-
del: true,
|
|
797
|
-
owner: { pool: true }
|
|
798
|
-
});
|
|
799
|
-
if (result.status !== "torn-down" && result.status !== "missing") throw new Error(result.reason);
|
|
800
|
-
}) ? {
|
|
801
|
-
status: "torn-down",
|
|
802
|
-
label: avdName
|
|
803
|
-
} : {
|
|
804
|
-
status: "skipped",
|
|
805
|
-
kind: "not-parked",
|
|
806
|
-
reason: "emulator is no longer parked"
|
|
807
|
-
};
|
|
808
|
-
} catch (error) {
|
|
809
|
-
return {
|
|
810
|
-
status: "failed",
|
|
811
|
-
reason: String(error?.message || error)
|
|
812
|
-
};
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
function teardownParkedIosSim(udid, { label, deleteSim = deleteParkedIosSim } = {}) {
|
|
816
|
-
try {
|
|
817
|
-
const removed = removeParkedAfter("ios", udid, () => {
|
|
818
|
-
closeOwnedDeviceSessions({
|
|
819
|
-
platform: "ios",
|
|
820
|
-
id: udid
|
|
821
|
-
}, () => Boolean(resolveOwnedIosSim(udid).sim));
|
|
822
|
-
deleteSim(udid);
|
|
823
|
-
});
|
|
824
|
-
if (!removed) return {
|
|
825
|
-
status: "skipped",
|
|
826
|
-
kind: "not-parked",
|
|
827
|
-
reason: "simulator is no longer parked"
|
|
828
|
-
};
|
|
829
|
-
return {
|
|
830
|
-
status: "torn-down",
|
|
831
|
-
label: label ?? removed.name
|
|
832
|
-
};
|
|
833
|
-
} catch (error) {
|
|
834
|
-
return {
|
|
835
|
-
status: "failed",
|
|
836
|
-
reason: String(error?.message || error)
|
|
837
|
-
};
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
function parkOwnedIosSim(udid, park) {
|
|
841
|
-
const resolved = resolveOwnedIosSim(udid);
|
|
842
|
-
if (resolved.missing) throw new Error(`simulator ${udid} disappeared after shutdown`);
|
|
843
|
-
if (resolved.notOwned) throw new Error(`simulator ${udid} is now named ${JSON.stringify(resolved.notOwned)}`);
|
|
844
|
-
const sim = resolved.sim;
|
|
845
|
-
if (sim.state !== "Shutdown") throw new Error(`simulator ${udid} is still ${sim.state} after shutdown`);
|
|
846
|
-
const model = listIosDeviceTypes().find((d) => d.identifier === sim.deviceTypeIdentifier)?.name ?? null;
|
|
847
|
-
const runtime = parseRuntimeVersion(sim.runtime);
|
|
848
|
-
if (park.bundleId) {
|
|
849
|
-
if (!sim.dataPath) throw new Error(`simulator ${udid} did not report a data path for app cleanup`);
|
|
850
|
-
const container = findAppDataContainer(sim.dataPath, park.bundleId);
|
|
851
|
-
if (container) clearAppDataContainer(container);
|
|
852
|
-
}
|
|
853
|
-
const name = parkedSimName(sim.udid, {
|
|
854
|
-
model,
|
|
855
|
-
runtime
|
|
856
|
-
});
|
|
857
|
-
renameIosSim(sim.udid, name);
|
|
858
|
-
const record = {
|
|
859
|
-
udid: sim.udid,
|
|
860
|
-
name,
|
|
861
|
-
deviceTypeIdentifier: sim.deviceTypeIdentifier,
|
|
862
|
-
runtimeIdentifier: sim.runtime,
|
|
863
|
-
parkedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
864
|
-
simslimManaged: Boolean(park.simslimManaged),
|
|
865
|
-
...park.bundleId ? { bundleId: park.bundleId } : {},
|
|
866
|
-
...park.cacheKey ? { cacheKey: park.cacheKey } : {}
|
|
867
|
-
};
|
|
868
|
-
return {
|
|
869
|
-
record,
|
|
870
|
-
evicted: parkSim({
|
|
871
|
-
platform: "ios",
|
|
872
|
-
projectPath: park.projectPath,
|
|
873
|
-
slot: park.slot,
|
|
874
|
-
record,
|
|
875
|
-
max: park.max
|
|
876
|
-
})
|
|
877
|
-
};
|
|
878
|
-
}
|
|
879
|
-
function teardownOwnedIosSim(udid, { del = false, label, park } = {}) {
|
|
880
|
-
let parkFallback;
|
|
881
|
-
try {
|
|
882
|
-
const resolved = resolveOwnedIosSim(udid);
|
|
883
|
-
if (resolved.notOwned) return {
|
|
884
|
-
status: "skipped",
|
|
885
|
-
kind: "not-owned",
|
|
886
|
-
reason: `sim is now named "${resolved.notOwned}", not Stim-owned by name`
|
|
887
|
-
};
|
|
888
|
-
if (resolved.missing) return { status: "missing" };
|
|
889
|
-
closeOwnedDeviceSessions({
|
|
890
|
-
platform: "ios",
|
|
891
|
-
id: udid
|
|
892
|
-
}, () => Boolean(resolveOwnedIosSim(udid).sim));
|
|
893
|
-
const current = resolveOwnedIosSim(udid);
|
|
894
|
-
if (current.missing) return { status: "missing" };
|
|
895
|
-
if (current.notOwned) return {
|
|
896
|
-
status: "skipped",
|
|
897
|
-
kind: "not-owned",
|
|
898
|
-
reason: "simulator ownership changed before shutdown"
|
|
899
|
-
};
|
|
900
|
-
shutdownIosSim(udid);
|
|
901
|
-
const sim = resolved.sim;
|
|
902
|
-
if (del && park && park.max > 0) try {
|
|
903
|
-
const { record, evicted } = parkOwnedIosSim(udid, park);
|
|
904
|
-
const removed = [];
|
|
905
|
-
const failures = [];
|
|
906
|
-
for (const entry of evicted) {
|
|
907
|
-
const result = teardownParkedIosSim(entry.udid, { label: entry.name });
|
|
908
|
-
if (result.status === "torn-down") removed.push({
|
|
909
|
-
udid: entry.udid,
|
|
910
|
-
name: entry.name
|
|
911
|
-
});
|
|
912
|
-
else if (result.status === "failed") failures.push(`could not delete evicted ${entry.name} (${entry.udid}): ${result.reason}`);
|
|
913
|
-
}
|
|
914
|
-
return {
|
|
915
|
-
status: "torn-down",
|
|
916
|
-
label: label ?? sim.name ?? udid,
|
|
917
|
-
parked: {
|
|
918
|
-
udid: record.udid,
|
|
919
|
-
name: record.name
|
|
920
|
-
},
|
|
921
|
-
evicted: removed,
|
|
922
|
-
...failures.length ? { evictionFailures: failures } : {}
|
|
923
|
-
};
|
|
924
|
-
} catch (e) {
|
|
925
|
-
parkFallback = String(e?.message || e);
|
|
926
|
-
}
|
|
927
|
-
if (del) deleteIosSim(udid);
|
|
928
|
-
return {
|
|
929
|
-
status: "torn-down",
|
|
930
|
-
label: label ?? sim.name ?? udid,
|
|
931
|
-
...parkFallback ? { parkFallback } : {}
|
|
932
|
-
};
|
|
933
|
-
} catch (e) {
|
|
934
|
-
return {
|
|
935
|
-
status: "failed",
|
|
936
|
-
reason: String(e?.message || e),
|
|
937
|
-
...parkFallback ? { parkFallback } : {}
|
|
938
|
-
};
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
function assertAvdReferences(avdName, owner) {
|
|
942
|
-
const config = loadConfig();
|
|
943
|
-
if (!config) throw new Error("Cannot verify AVD references without a Stim config; the data was kept.");
|
|
944
|
-
if (owner && "projectPath" in owner && owner.expectedRecord && !isDeepStrictEqual(deviceSlotPlatforms(config.projects[owner.projectPath], owner.slot)?.android, owner.expectedRecord)) throw new Error(`AVD ${avdName} has a changed workspace record; its data was kept.`);
|
|
945
|
-
for (const [projectPath, project] of Object.entries(config.projects)) for (const { slot, platforms } of projectDeviceSlots(project)) {
|
|
946
|
-
if (platforms.android?.avdName?.toLowerCase() !== avdName.toLowerCase()) continue;
|
|
947
|
-
if (!owner || !("projectPath" in owner) || owner.projectPath !== projectPath || (owner.slot ?? "default") !== slot || !platforms.android.owned) throw new Error(`AVD ${avdName} is referenced by ${projectPath} (${slot}); its data was kept.`);
|
|
948
|
-
}
|
|
949
|
-
if (readParked("android", { config }).some((entry) => entry.name.toLowerCase() === avdName.toLowerCase()) && !(owner && "pool" in owner)) throw new Error(`AVD ${avdName} is in the emulator pool; its data was kept.`);
|
|
950
|
-
}
|
|
951
|
-
function removeOrphanedAvdDirectory(candidate, owner) {
|
|
952
|
-
const surveyed = listOrphanedAvdDirectories(candidate.name).find((entry) => entry.directory === candidate.directory);
|
|
953
|
-
if (!surveyed || surveyed.name !== candidate.name || surveyed.dev !== candidate.dev || surveyed.ino !== candidate.ino) throw new Error(`AVD data at ${candidate.directory} changed or is registered; it was kept.`);
|
|
954
|
-
assertOwnedAvdStopped(candidate.name, { resolveDirectory: () => candidate.directory });
|
|
955
|
-
const detached = withConfigLock(() => {
|
|
956
|
-
const current = lstatSync(candidate.directory);
|
|
957
|
-
if (!current.isDirectory() || current.dev !== candidate.dev || current.ino !== candidate.ino) throw new Error(`AVD data at ${candidate.directory} changed or is registered; it was kept.`);
|
|
958
|
-
assertAvdReferences(candidate.name, owner);
|
|
959
|
-
const destination = join(dirname(candidate.directory), `stim-gc-${randomUUID()}.avd`);
|
|
960
|
-
renameSync(candidate.directory, destination);
|
|
961
|
-
return destination;
|
|
962
|
-
});
|
|
963
|
-
const current = lstatSync(detached);
|
|
964
|
-
if (!current.isDirectory() || current.dev !== candidate.dev || current.ino !== candidate.ino) throw new Error(`Detached AVD data changed at ${detached}; it was kept.`);
|
|
965
|
-
try {
|
|
966
|
-
rmSync(detached, { recursive: true });
|
|
967
|
-
} catch (error) {
|
|
968
|
-
throw new Error(`Could not remove AVD data at ${detached}; retry gc --delete: ${error.message}`, { cause: error });
|
|
969
|
-
}
|
|
970
|
-
}
|
|
971
|
-
function teardownUnregisteredAvd(avdName, del, owner, surveyed) {
|
|
972
|
-
const candidates = surveyed ? [surveyed] : listOrphanedAvdDirectories(avdName);
|
|
973
|
-
if (candidates.length === 0) {
|
|
974
|
-
if (avdStorageRoots().some((root) => avdPathExists(join(root, `${avdName}.ini`)) || avdPathExists(join(root, `${avdName}.avd`)))) throw new Error(`AVD ${avdName} is not listed but its storage remains; it was kept.`);
|
|
975
|
-
return { status: "missing" };
|
|
976
|
-
}
|
|
977
|
-
if (!del) return {
|
|
978
|
-
status: "skipped",
|
|
979
|
-
reason: "AVD registration is missing; its data was kept."
|
|
980
|
-
};
|
|
981
|
-
for (const candidate of candidates) {
|
|
982
|
-
if (candidate.name !== avdName) throw new Error(`AVD data does not match ${avdName}; it was kept.`);
|
|
983
|
-
removeOrphanedAvdDirectory(candidate, owner);
|
|
984
|
-
}
|
|
985
|
-
return {
|
|
986
|
-
status: "torn-down",
|
|
987
|
-
label: avdName
|
|
988
|
-
};
|
|
989
|
-
}
|
|
990
|
-
function teardownOwnedAvd(avdName, options = {}) {
|
|
991
|
-
if (!/^stim-[A-Za-z0-9._-]+$/.test(avdName)) return {
|
|
992
|
-
status: "skipped",
|
|
993
|
-
kind: "not-owned",
|
|
994
|
-
reason: `AVD ${avdName} is not Stim-owned by name`
|
|
995
|
-
};
|
|
996
|
-
let claim;
|
|
997
|
-
try {
|
|
998
|
-
claim = acquireAvdClaim(avdName);
|
|
999
|
-
const result = teardownClaimedAvd(avdName, claim, options);
|
|
1000
|
-
if (result.status === "torn-down" || result.status === "missing") options.onRemoved?.();
|
|
1001
|
-
return result;
|
|
1002
|
-
} catch (error) {
|
|
1003
|
-
return {
|
|
1004
|
-
status: "failed",
|
|
1005
|
-
reason: String(error?.message || error)
|
|
1006
|
-
};
|
|
1007
|
-
} finally {
|
|
1008
|
-
(0, ownership_claim_exports.releaseClaim)(claim);
|
|
1009
|
-
}
|
|
1010
|
-
}
|
|
1011
|
-
function teardownClaimedAvd(avdName, claim, { del = false, park, owner, orphanedDirectory, onlyIfMissing = false, waitForShutdown = waitForAndroidEmulatorShutdown, assertStopped = assertOwnedAvdStopped, resolveAvd = resolveOwnedAvdSerial }) {
|
|
1012
|
-
let parkFallback;
|
|
1013
|
-
try {
|
|
1014
|
-
if (del) withConfigLock(() => assertAvdReferences(avdName, owner));
|
|
1015
|
-
const resolved = resolveAvd(avdName);
|
|
1016
|
-
if (resolved.notOwned) return {
|
|
1017
|
-
status: "skipped",
|
|
1018
|
-
kind: "not-owned",
|
|
1019
|
-
reason: `AVD ${avdName} is not Stim-owned by name`
|
|
1020
|
-
};
|
|
1021
|
-
if (resolved.missing) return teardownUnregisteredAvd(avdName, del, owner, orphanedDirectory);
|
|
1022
|
-
if (onlyIfMissing) return {
|
|
1023
|
-
status: "skipped",
|
|
1024
|
-
reason: "AVD registration appeared; its record was kept."
|
|
1025
|
-
};
|
|
1026
|
-
if (orphanedDirectory) return {
|
|
1027
|
-
status: "skipped",
|
|
1028
|
-
reason: "AVD registration appeared; its data was kept."
|
|
1029
|
-
};
|
|
1030
|
-
const serial = resolved.serial;
|
|
1031
|
-
if (serial) {
|
|
1032
|
-
const stillOwned = () => {
|
|
1033
|
-
const current = resolveAvd(avdName);
|
|
1034
|
-
return !current.notOwned && !current.missing && current.serial === serial;
|
|
1035
|
-
};
|
|
1036
|
-
closeOwnedDeviceSessions({
|
|
1037
|
-
platform: "android",
|
|
1038
|
-
id: serial
|
|
1039
|
-
}, stillOwned);
|
|
1040
|
-
if (!stillOwned()) throw new Error(`Owned AVD ${avdName} changed before shutdown; it was kept.`);
|
|
1041
|
-
waitForShutdown(avdName, (timeoutMs) => {
|
|
1042
|
-
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
1043
|
-
try {
|
|
1044
|
-
shutdownAndroidEmulator(serial, timeoutMs);
|
|
1045
|
-
} finally {
|
|
1046
|
-
(0, ownership_claim_exports.clearClaimChild)(claim);
|
|
1047
|
-
}
|
|
1048
|
-
});
|
|
1049
|
-
} else assertStopped(avdName);
|
|
1050
|
-
if (del) {
|
|
1051
|
-
const current = resolveAvd(avdName);
|
|
1052
|
-
if (current.notOwned) return {
|
|
1053
|
-
status: "skipped",
|
|
1054
|
-
kind: "not-owned",
|
|
1055
|
-
reason: `AVD ${avdName} is not Stim-owned by name`
|
|
1056
|
-
};
|
|
1057
|
-
if (current.missing) return teardownUnregisteredAvd(avdName, del, owner);
|
|
1058
|
-
if (current.serial) throw new Error(`Owned AVD ${avdName} started again before deletion.`);
|
|
1059
|
-
assertStopped(avdName);
|
|
1060
|
-
withConfigLock(() => assertAvdReferences(avdName, owner));
|
|
1061
|
-
if (park && park.max > 0) try {
|
|
1062
|
-
const systemImage = ownedAvdSystemImage(avdName);
|
|
1063
|
-
if (!systemImage || !park.configuration || !ownedAvdMatchesConfiguration(avdName, park.configuration)) throw new Error("the AVD has no verified creation configuration");
|
|
1064
|
-
const evicted = parkSim({
|
|
1065
|
-
platform: "android",
|
|
1066
|
-
projectPath: park.projectPath,
|
|
1067
|
-
slot: park.slot,
|
|
1068
|
-
max: park.max,
|
|
1069
|
-
record: {
|
|
1070
|
-
udid: avdName,
|
|
1071
|
-
name: avdName,
|
|
1072
|
-
systemImage,
|
|
1073
|
-
configuration: park.configuration,
|
|
1074
|
-
parkedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
1075
|
-
}
|
|
1076
|
-
});
|
|
1077
|
-
const removed = [];
|
|
1078
|
-
const failures = [];
|
|
1079
|
-
for (const entry of evicted) {
|
|
1080
|
-
const result = teardownParkedAvd(entry.name);
|
|
1081
|
-
if (result.status === "torn-down") removed.push({
|
|
1082
|
-
udid: entry.name,
|
|
1083
|
-
name: entry.name,
|
|
1084
|
-
platform: "android"
|
|
1085
|
-
});
|
|
1086
|
-
else if (result.status === "failed") failures.push(`could not delete evicted ${entry.name}: ${result.reason}`);
|
|
1087
|
-
}
|
|
1088
|
-
return {
|
|
1089
|
-
status: "torn-down",
|
|
1090
|
-
label: avdName,
|
|
1091
|
-
parked: {
|
|
1092
|
-
udid: avdName,
|
|
1093
|
-
name: avdName,
|
|
1094
|
-
platform: "android"
|
|
1095
|
-
},
|
|
1096
|
-
evicted: removed,
|
|
1097
|
-
...failures.length ? { evictionFailures: failures } : {}
|
|
1098
|
-
};
|
|
1099
|
-
} catch (error) {
|
|
1100
|
-
parkFallback = String(error?.message || error);
|
|
1101
|
-
}
|
|
1102
|
-
const directory = ownedAvdDirectory(avdName);
|
|
1103
|
-
const paths = avdStorageRoots().map((root) => join(root, `${avdName}.ini`));
|
|
1104
|
-
if (directory) paths.push(directory);
|
|
1105
|
-
(0, ownership_claim_exports.markClaimChildPending)(claim);
|
|
1106
|
-
try {
|
|
1107
|
-
deleteAvd(avdName);
|
|
1108
|
-
} finally {
|
|
1109
|
-
(0, ownership_claim_exports.clearClaimChild)(claim);
|
|
1110
|
-
}
|
|
1111
|
-
const remaining = paths.filter(avdPathExists);
|
|
1112
|
-
if (remaining.length) throw new Error(`AVD ${avdName} was only partially deleted; data remains at ${remaining.join(", ")}.`);
|
|
1113
|
-
}
|
|
1114
|
-
return {
|
|
1115
|
-
status: "torn-down",
|
|
1116
|
-
label: avdName,
|
|
1117
|
-
serial: resolved.serial ?? null,
|
|
1118
|
-
...parkFallback ? { parkFallback } : {}
|
|
1119
|
-
};
|
|
1120
|
-
} catch (e) {
|
|
1121
|
-
return {
|
|
1122
|
-
status: "failed",
|
|
1123
|
-
reason: String(e?.message || e)
|
|
1124
|
-
};
|
|
1125
|
-
}
|
|
1126
|
-
}
|
|
1127
|
-
//#endregion
|
|
1128
|
-
export { resolveRemote as C, resolveEasCliBin as S, exitAfterFlush as _, POOL_SETTING_REMEDY as a, ownerFromConfig as b, isLegacyDeletionClaim as c, selectParked as d, RESOLVE_TIMEOUT_MS as f, easAuthNote as g, checkEasAuth as h, teardownParkedIosSim as i, parkedMaxSetting as l, cacheLevel as m, teardownOwnedIosSim as n, adoptParked as o, UPLOAD_TIMEOUT_MS as p, teardownParkedAvd as r, dropParked as s, teardownOwnedAvd as t, readParked as u, isEasAuthFailureText as v, uploadRemote as w, providerFromConfig as x, loadProjectProvider as y };
|
|
723
|
+
export { uploadRemote as S, loadProjectProvider as _, parkSim as a, resolveEasCliBin as b, removeParkedAfter as c, UPLOAD_TIMEOUT_MS as d, cacheLevel as f, isEasAuthFailureText as g, exitAfterFlush as h, isLegacyDeletionClaim as i, selectParked as l, easAuthNote as m, adoptParked as n, parkedMaxSetting as o, checkEasAuth as p, dropParked as r, readParked as s, POOL_SETTING_REMEDY as t, RESOLVE_TIMEOUT_MS as u, ownerFromConfig as v, resolveRemote as x, providerFromConfig as y };
|