stim 1.14.0 → 1.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +2 -0
  2. package/dist/activity-BxwdD81S.mjs +609 -0
  3. package/dist/agent-device-usage-output-Dpih1Tfa.mjs +411 -0
  4. package/dist/{android-d6rGq1pA.mjs → android-B_NumVyQ.mjs} +169 -81
  5. package/dist/{android-LbPFRWVL.mjs → android-Ift4kVvt.mjs} +517 -413
  6. package/dist/android-cas-8U4DPqeR.mjs +167 -0
  7. package/dist/android-cas-compiler.mjs +2 -2
  8. package/dist/{android-XpvCrV7q.mjs → android-r2rBL8kV.mjs} +2 -2
  9. package/dist/{app-install-BpgSgkJj.mjs → app-install-CKWdbXIX.mjs} +128 -151
  10. package/dist/attempt-Bk2ouQVL.mjs +39 -0
  11. package/dist/budget-DjrURfQn.mjs +2700 -0
  12. package/dist/{build-plan-Dcr-3ie0.mjs → build-plan-DjeSb2Xl.mjs} +192 -653
  13. package/dist/build-slots-rUk77xqh.mjs +132 -0
  14. package/dist/{cache-manifest-C68QQ0ua.mjs → cache-manifest-DnUHBJaU.mjs} +2 -2
  15. package/dist/cache-manifest.mjs +1 -1
  16. package/dist/{chrome-BPCiC3ZX.mjs → chrome-BrcVWQyD.mjs} +1 -1
  17. package/dist/cli-BkYZ_6hy.mjs +51 -0
  18. package/dist/cli.mjs +6 -42
  19. package/dist/client-BTY686R6.mjs +1368 -0
  20. package/dist/collector-run.mjs +9 -195
  21. package/dist/{command-output-DVcpw6eE.mjs → command-output-DnJMdEY-.mjs} +1 -1
  22. package/dist/{config-lvc7d3C2.mjs → config-D0DbpZtM.mjs} +28 -29
  23. package/dist/{created-devices-CllH_8eb.mjs → created-devices-D5owjN4C.mjs} +2 -2
  24. package/dist/{dependency-state-DsT7aKeo.mjs → dependency-state-B6cMXZab.mjs} +2 -2
  25. package/dist/{deps-D9IcKqXS.mjs → deps-urbmfXig.mjs} +3 -3
  26. package/dist/{detached-entry-DJHoca49.mjs → detached-entry-CiTEgMR1.mjs} +1 -1
  27. package/dist/dev-client-CroAIjjj.mjs +43 -0
  28. package/dist/{device-CjuuAJjQ.mjs → device-DZQjF7H5.mjs} +8 -7
  29. package/dist/device-capacity-BHwxNBlu.mjs +136 -0
  30. package/dist/device-host-worker.d.mts +1 -0
  31. package/dist/device-host-worker.mjs +964 -0
  32. package/dist/device-ios-BadmeL2V.mjs +381 -0
  33. package/dist/{device-lease-5c3WrVRm.mjs → device-lease-D-hLqx1b.mjs} +43 -36
  34. package/dist/{device-pool-BiyDyPP-.mjs → device-lease-run-CqjShqWW.mjs} +6 -126
  35. package/dist/device-pool-CUaEWMMm.mjs +125 -0
  36. package/dist/{device-remote-D87zEzaq.mjs → device-remote-D5WVWqOq.mjs} +69 -163
  37. package/dist/{doctor-x9pnU9fq.mjs → doctor-Cimf-gGB.mjs} +241 -103
  38. package/dist/{error-diagnostics-C5HzcwCW.mjs → error-diagnostics-B9L4Ae0x.mjs} +15 -18
  39. package/dist/{exec-DK8KaVHK.mjs → exec-CaErVv7t.mjs} +5 -1
  40. package/dist/{gc-ko6mUAYD.mjs → gc-Bqy4bjEu.mjs} +599 -108
  41. package/dist/{android-cas-iZK3DOCr.mjs → gradle-BsO1MdsH.mjs} +8 -294
  42. package/dist/{guide-6R0VNFqI.mjs → guide-B_uyKTxW.mjs} +2511 -239
  43. package/dist/{guide-status-BZrFPIA_.mjs → guide-status-CjEZMAD4.mjs} +3 -3
  44. package/dist/hosted-client-a-WmqE2L.mjs +197 -0
  45. package/dist/hosted-ios-CIWelIqf.mjs +220 -0
  46. package/dist/hosted-logs-D5g041Q3.mjs +187 -0
  47. package/dist/hosted-macos-BSZyIb3y.mjs +135 -0
  48. package/dist/idle-DYVymG92.mjs +1099 -0
  49. package/dist/idle-shutdown-CTsDnAde.mjs +122 -0
  50. package/dist/in-use-DvBw0Kxo.mjs +130 -0
  51. package/dist/{ios-BwDPrnYQ.mjs → ios-BaInn3sW.mjs} +201 -10
  52. package/dist/ios-Cr1h5gnO.mjs +189 -0
  53. package/dist/{ios-P1f5nm2n.mjs → ios-aq3QoGI3.mjs} +1159 -633
  54. package/dist/{ios-device-BiOsSVzd.mjs → ios-device-Ee7sDXfp.mjs} +1 -1
  55. package/dist/{ios-device-DGglU3E_.mjs → ios-device-FfCN_C8p.mjs} +12 -7
  56. package/dist/ios-state-DS5UpYTH.mjs +48 -0
  57. package/dist/{launch-verify-Deg4tB3Z.mjs → launch-verify-2DBRizjo.mjs} +5 -5
  58. package/dist/logs-CHEVK8zD.mjs +371 -0
  59. package/dist/machines-BIBUdhpj.mjs +265 -0
  60. package/dist/macos-CSYEAFmF.mjs +473 -0
  61. package/dist/macos-run.d.mts +5 -0
  62. package/dist/macos-run.mjs +2 -0
  63. package/dist/maintenance-run.d.mts +4 -0
  64. package/dist/maintenance-run.mjs +254 -0
  65. package/dist/{metro-CcEo8Fl8.mjs → metro-BeK1ZPz1.mjs} +20 -120
  66. package/dist/metro-gateway-BJ-rxQAB.mjs +84 -0
  67. package/dist/{named-ports-Blg8IxOh.mjs → named-ports-Bk_YXEmE.mjs} +6 -59
  68. package/dist/native-run-NaBrRFtQ.mjs +147 -0
  69. package/dist/{native-runtime-DjBHRg5m.mjs → native-runtime-DBzRnEKS.mjs} +9 -5
  70. package/dist/{ndjson-CDY9IkVC.mjs → ndjson-PclOIwVY.mjs} +2 -2
  71. package/dist/offload-worker.d.mts +122 -0
  72. package/dist/offload-worker.mjs +606 -0
  73. package/dist/{ownership-DyYDF5ww.mjs → ownership-DiA16AsN.mjs} +3 -2
  74. package/dist/ownership-hCkPzGmr.mjs +571 -0
  75. package/dist/{page-BHUzTDFt.mjs → page-QF_Ke10s.mjs} +7 -2
  76. package/dist/{ports-BguS83ex.mjs → ports-R2k4Knz3.mjs} +3 -3
  77. package/dist/prebuild-D2fsca_Z.mjs +213 -0
  78. package/dist/preview-DhVbvPAZ.mjs +318 -0
  79. package/dist/process-identity-BmRm1qV0.mjs +12 -0
  80. package/dist/{project-CWlvEaeN.mjs → project-Du91Ilvc.mjs} +74 -19
  81. package/dist/pull-request-pxnDCQzn.mjs +322 -0
  82. package/dist/pull-requests.d.mts +120 -0
  83. package/dist/pull-requests.mjs +2 -0
  84. package/dist/recordings-BIXOzVnr.mjs +37 -0
  85. package/dist/{reload-BiniwsSZ.mjs → reload-rM9jV1fz.mjs} +109 -24
  86. package/dist/{remote-cache-CcR6o6lI.mjs → remote-cache-C8-V13XN.mjs} +5 -5
  87. package/dist/run-f4vI6EnK.mjs +119 -0
  88. package/dist/{server-bare-DGfgyJ5J.mjs → server-bare-CpPGmnmO.mjs} +33 -15
  89. package/dist/server-expo-CVqO2c35.mjs +2 -0
  90. package/dist/{server-expo-BVuwQ65v.mjs → server-expo-MC0rHlOC.mjs} +8 -12
  91. package/dist/settings-BBpMcDbD.mjs +25 -0
  92. package/dist/{settings-B-fsC-Om.mjs → settings-ZkDzkzvB.mjs} +22 -10
  93. package/dist/settings-oTSkkNrM.mjs +1439 -0
  94. package/dist/settings.schema.json +845 -97
  95. package/dist/{simslim-DrDN4WuV.mjs → simslim-B8-7AoTI.mjs} +8 -132
  96. package/dist/{slot-launch-D5t8EiMf.mjs → slot-launch-B8VrHxn1.mjs} +11 -8
  97. package/dist/{spawn-claims-Drw_o-Fb.mjs → spawn-claims-D0XfSe8u.mjs} +1 -1
  98. package/dist/spawn-entry-jw19m8Nl.mjs +17 -0
  99. package/dist/stage-CzaiwFsI.mjs +143 -0
  100. package/dist/start-CX8Ig-U2.mjs +2 -0
  101. package/dist/{start-s4RXp1wy.mjs → start-ClDfwXa4.mjs} +116 -65
  102. package/dist/state-3DwSQIBK.mjs +41 -0
  103. package/dist/state-B4PQFXMW.d.mts +12 -0
  104. package/dist/{state-Dk9RVXI7.mjs → state-C1jB7Q8q.mjs} +70 -8
  105. package/dist/{state-DHqvsbqC.mjs → state-DcW6vOd_.mjs} +7 -4
  106. package/dist/stats-CEZ_i5je.mjs +77 -0
  107. package/dist/{status-BgAuxESg.mjs → status-BuvBFeII.mjs} +118 -20
  108. package/dist/{status-BsPAnfOI.mjs → status-Cs7VLg9D.mjs} +542 -283
  109. package/dist/status-DlKvVJBE.mjs +49 -0
  110. package/dist/stdout-reader-C8yjre1x.mjs +23 -0
  111. package/dist/stim-desktop-Cnz8CPnl.mjs +63 -0
  112. package/dist/stim-footprint.swift +32 -0
  113. package/dist/{stim-installations-CINXy_su.mjs → stim-installations-QMEI32v1.mjs} +1 -1
  114. package/dist/stop-B0Yxtmiy.mjs +48 -0
  115. package/dist/{stop-BzreOWJp.mjs → stop-Bffozsac.mjs} +83 -16
  116. package/dist/{stop-BWIF_6BK.mjs → stop-Dt_dM16A.mjs} +2 -2
  117. package/dist/stop-cause-CidxIqup.mjs +97 -0
  118. package/dist/supervisor-run.d.mts +43 -11
  119. package/dist/supervisor-run.mjs +363 -24
  120. package/dist/support-CAP8qDUF.mjs +316 -0
  121. package/dist/support-D4aYJniO.mjs +201 -0
  122. package/dist/teardown-CL6vDs2Y.mjs +727 -0
  123. package/dist/{xcode-Cp5KvK9x.mjs → toolchain-DkUflduf.mjs} +364 -14
  124. package/dist/trigger-Bemu8ytw.mjs +65 -0
  125. package/dist/trigger-CXts6qt1.mjs +2 -0
  126. package/dist/warm-progress-CpGv3Wb6.mjs +732 -0
  127. package/dist/{web-BsQs1WlO.mjs → web-DWUaMp8P.mjs} +37 -21
  128. package/dist/web-run.mjs +310 -13
  129. package/dist/workspace-process-lock-BL7Q0HCO.mjs +57 -0
  130. package/dist/workspace-state-B8-aJ1_5.mjs +371 -0
  131. package/dist/workspaces-BV4pdHFz.mjs +306 -0
  132. package/dist/{worktree-UrQWXSeb.mjs → worktree-K-xj9Db0.mjs} +625 -256
  133. package/dist/worktree-jnG8Iph5.mjs +2 -0
  134. package/package.json +10 -5
  135. package/shim/bundle-response.cjs +28 -12
  136. package/dist/activity-CYVDcrt3.mjs +0 -356
  137. package/dist/budget-CGDkhvv_.mjs +0 -1745
  138. package/dist/build-progress-DxKpwnaS.mjs +0 -247
  139. package/dist/idle-DXtx3RbX.mjs +0 -191
  140. package/dist/in-use-DlqBDKqY.mjs +0 -249
  141. package/dist/logs-Civ4gbBH.mjs +0 -486
  142. package/dist/merge-state-ytFQCeh4.mjs +0 -262
  143. package/dist/server-expo-DIHDhvGg.mjs +0 -2
  144. package/dist/settings-D61iNOsB.mjs +0 -629
  145. package/dist/start-Cetfvy8l.mjs +0 -2
  146. package/dist/stats-CFpFGlJV.mjs +0 -62
  147. package/dist/stats-CX1Z8Tca.mjs +0 -368
  148. package/dist/stim-desktop-CXt8-Z3J.mjs +0 -40
  149. package/dist/stop-cause-hjGBOZTG.mjs +0 -1231
  150. package/dist/worktree-BVrHsYZG.mjs +0 -752
  151. package/dist/worktree-CHWWvm5v.mjs +0 -2
  152. package/dist/{metro-store-DzeWkfqW.mjs → metro-store-CDDZHtPl.mjs} +1 -1
@@ -0,0 +1,265 @@
1
+ import { _ as loadConfig$1, d as getConfigDir } from "./config-D0DbpZtM.mjs";
2
+ import { w as withDirLock } from "./workspace-state-B8-aJ1_5.mjs";
3
+ import { S as readHostPermissions, _ as findPeer$1, b as realIo, g as endpoint, v as parseMachine$1, x as readAccessTicket } from "./client-BTY686R6.mjs";
4
+ import { mkdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
5
+ import { acceptsShape, deviceHostMachinesClaims, deviceHostMachinesFile, deviceHostMachinesLock, isJsonObject, readDeviceHostMachines, settingDefinition } from "@stim-cli/core/state";
6
+ import { releaseClaim, tryAcquireClaim } from "@stim-cli/core/ownership-claim";
7
+ import { hostname } from "node:os";
8
+ //#region src/device-host/machines.ts
9
+ function note(title, detail, fix = null) {
10
+ return {
11
+ code: "device-host-machine",
12
+ level: "note",
13
+ title,
14
+ detail,
15
+ fix
16
+ };
17
+ }
18
+ const approval = (machine, id) => `A person on ${machine} approves it with \`stim-server devices grant ${id} --device-host\`.`;
19
+ function configuredMachines() {
20
+ const hosting = loadConfig$1()?.hosting;
21
+ if (hosting !== void 0 && !isJsonObject(hosting)) return null;
22
+ const machines = hosting?.machines;
23
+ if (machines === void 0) return [];
24
+ return acceptsShape(settingDefinition("hosting.machines"), machines) ? machines : null;
25
+ }
26
+ function store(machines) {
27
+ withDirLock(deviceHostMachinesLock(), () => {
28
+ const file = deviceHostMachinesFile();
29
+ const tmp = `${file}.${process.pid}.${Math.random().toString(36).slice(2)}.tmp`;
30
+ try {
31
+ writeFileSync(tmp, `${JSON.stringify({
32
+ version: 1,
33
+ machines
34
+ }, null, 2)}\n`, { mode: 384 });
35
+ renameSync(tmp, file);
36
+ } finally {
37
+ rmSync(tmp, { force: true });
38
+ }
39
+ }, { ensureParent: () => mkdirSync(getConfigDir(), { recursive: true }) });
40
+ }
41
+ async function request(machine, peer, port, deviceName, io) {
42
+ const ticket = readAccessTicket();
43
+ const reply = await io.hello(endpoint(peer, port), {
44
+ request: "device-host",
45
+ deviceName,
46
+ ...ticket ? { setupTicket: ticket.ticket } : {}
47
+ });
48
+ if (!("result" in reply) || reply.result?.approval?.state !== "pending" || typeof reply.result.deviceToken !== "string" || !reply.result.deviceToken || typeof reply.result.device?.id !== "string" || !reply.result.device.id || typeof reply.result.approval.expiresAt !== "string" || !reply.result.approval.expiresAt) return {
49
+ report: {
50
+ machine,
51
+ dnsName: peer.dnsName,
52
+ state: "unreachable"
53
+ },
54
+ finding: note(`Could not ask ${machine} for hosting access`, "The worker did not return a pending request.")
55
+ };
56
+ const credential = {
57
+ machine,
58
+ nodeId: peer.nodeId,
59
+ dnsName: peer.dnsName,
60
+ deviceId: reply.result.device.id,
61
+ deviceToken: reply.result.deviceToken,
62
+ state: "pending",
63
+ requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
64
+ ...ticket ? { ticketHash: ticket.ticketHash } : {}
65
+ };
66
+ return {
67
+ report: {
68
+ machine,
69
+ dnsName: peer.dnsName,
70
+ state: "pending",
71
+ deviceId: credential.deviceId,
72
+ requestedAt: credential.requestedAt
73
+ },
74
+ finding: note(`Asked ${machine} for hosting access`, `The request lapses at ${reply.result.approval.expiresAt}.`, approval(machine, credential.deviceId)),
75
+ credential
76
+ };
77
+ }
78
+ /** Reports separately approved hosting machines. Only --fix asks or forgets credentials; every token stays pinned. */
79
+ async function inspectDeviceHostMachines({ fix }, io = realIo, entries = configuredMachines()) {
80
+ if (entries === null) return {
81
+ findings: [note("Invalid hosting.machines setting", "Use a hosting object with machines as an array of tailnet names. Existing hosting credentials and pinned nodes are preserved.", "Run `stim guide settings` and correct the setting before running doctor again.")],
82
+ machines: []
83
+ };
84
+ const unavailable = (state, finding) => ({
85
+ findings: [finding],
86
+ machines: entries.map((machine) => ({
87
+ machine,
88
+ state
89
+ }))
90
+ });
91
+ const unreadable = () => unavailable("credentials-unavailable", note("Hosting credentials are unreadable", `Stim preserves ${deviceHostMachinesFile()} and its pinned nodes.`, "Restore the existing file from a trusted backup or restore read access before running doctor again."));
92
+ if (!entries.length) {
93
+ if (!fix) return {
94
+ findings: [],
95
+ machines: []
96
+ };
97
+ try {
98
+ if (!readDeviceHostMachines().length) return {
99
+ findings: [],
100
+ machines: []
101
+ };
102
+ } catch {
103
+ return unreadable();
104
+ }
105
+ }
106
+ const claim = tryAcquireClaim({
107
+ root: deviceHostMachinesClaims(),
108
+ mode: "exclusive",
109
+ label: "hosting machine approval"
110
+ });
111
+ if (!claim.acquired) {
112
+ releaseClaim(claim.pending);
113
+ return unavailable("busy", note("Hosting machine approval is in use", "Another doctor run holds the hosting credential claim. Run doctor again after it finishes."));
114
+ }
115
+ try {
116
+ let credentials;
117
+ try {
118
+ credentials = readDeviceHostMachines();
119
+ } catch {
120
+ return unreadable();
121
+ }
122
+ if (fix) {
123
+ const kept = credentials.filter((each) => entries.includes(each.machine));
124
+ if (kept.length !== credentials.length) {
125
+ store(kept);
126
+ credentials = kept;
127
+ }
128
+ }
129
+ if (!entries.length) return {
130
+ findings: [],
131
+ machines: []
132
+ };
133
+ const status = io.status();
134
+ if (!isJsonObject(status)) return unavailable("tailscale-off", note("Hosting machines are unreachable", "hosting.machines names hosting machines, but Tailscale is not running."));
135
+ const self = isJsonObject(status.Self) ? status.Self : {};
136
+ const deviceName = (typeof self.HostName === "string" && self.HostName ? self.HostName : hostname()).replace(/[\p{Cc}\p{Cf}]/gu, "").trim().slice(0, 64) || "Mac";
137
+ const inspected = {
138
+ findings: [],
139
+ machines: []
140
+ };
141
+ const namedNodes = /* @__PURE__ */ new Set();
142
+ for (const machine of new Set(entries)) {
143
+ const parsed = parseMachine$1(machine);
144
+ if (!parsed) {
145
+ inspected.machines.push({
146
+ machine,
147
+ state: "invalid"
148
+ });
149
+ inspected.findings.push(note(`Hosting machine ${machine} is not a tailnet name`, "Expected `name` or `name:port`."));
150
+ continue;
151
+ }
152
+ const current = io.status();
153
+ if (!isJsonObject(current)) {
154
+ inspected.machines.push({
155
+ machine,
156
+ state: "tailscale-off"
157
+ });
158
+ inspected.findings.push(note(`Hosting machine ${machine} is unreachable`, "Tailscale stopped before this connection."));
159
+ continue;
160
+ }
161
+ const peer = findPeer$1(current, parsed.name);
162
+ if (peer === "missing" || peer === "ambiguous") {
163
+ inspected.machines.push({
164
+ machine,
165
+ state: "not-on-tailnet"
166
+ });
167
+ inspected.findings.push(note(`Hosting machine ${machine} is not on this tailnet`, peer === "missing" ? "No peer has that name." : "Several peers match that name."));
168
+ continue;
169
+ }
170
+ const nodeRoute = `${peer.nodeId}:${parsed.port}`;
171
+ if (namedNodes.has(nodeRoute)) {
172
+ inspected.machines.push({
173
+ machine,
174
+ dnsName: peer.dnsName,
175
+ state: "invalid"
176
+ });
177
+ inspected.findings.push(note(`Hosting machine ${machine} repeats a named node`, "Name each tailnet node and serve port only once in hosting.machines."));
178
+ continue;
179
+ }
180
+ namedNodes.add(nodeRoute);
181
+ const credential = credentials.find((each) => each.machine === machine);
182
+ const known = {
183
+ machine,
184
+ dnsName: peer.dnsName,
185
+ ...credential ? {
186
+ deviceId: credential.deviceId,
187
+ requestedAt: credential.requestedAt
188
+ } : {}
189
+ };
190
+ if (credential && credential.nodeId !== peer.nodeId) {
191
+ inspected.machines.push({
192
+ ...known,
193
+ state: "node-changed"
194
+ });
195
+ inspected.findings.push(note(`Hosting machine ${machine} is a different tailnet node`, "Stim refuses to connect or send the saved token.", `If that Mac was replaced, remove ${machine} from hosting.machines, run \`stim doctor --fix\`, then add it back and run \`stim doctor --fix\` again to request approval on the new node.`));
196
+ continue;
197
+ }
198
+ let ask = !credential && fix;
199
+ if (credential) {
200
+ const reply = await io.hello(endpoint(peer, parsed.port), { deviceToken: credential.deviceToken });
201
+ if ("result" in reply && reply.result?.device?.id === credential.deviceId && Array.isArray(reply.result.capabilities) && reply.result.capabilities.includes("device-host")) {
202
+ if (credential.state !== "approved") {
203
+ credentials = credentials.map((each) => each.machine === machine ? {
204
+ ...each,
205
+ state: "approved"
206
+ } : each);
207
+ store(credentials);
208
+ }
209
+ const host = readHostPermissions(reply.result.host);
210
+ if (host && (host.screenRecording === false || host.accessibility === false)) {
211
+ const panes = [...host.screenRecording === false ? ["Screen & System Audio Recording (Screen Recording on macOS 14)"] : [], ...host.accessibility === false ? ["Device Control and Data Access (Accessibility on macOS 26 and earlier)"] : []];
212
+ const detail = [...host.screenRecording === false ? ["Viewing hosted macOS apps needs Screen Recording."] : [], ...host.accessibility === false ? ["Controlling them needs the control permission."] : []];
213
+ inspected.findings.push(note(`Hosting machine ${machine} needs ${panes.join(" and ")} for ${host.name}`, detail.join(" "), `On ${machine}, approve ${host.name} in System Settings > Privacy & Security, or run \`stim-server service install\` there again to show the requests.`));
214
+ }
215
+ inspected.machines.push({
216
+ ...known,
217
+ state: "approved",
218
+ ...host ? { host } : {}
219
+ });
220
+ continue;
221
+ }
222
+ const pending = "error" in reply && reply.error?.code === "approval-pending";
223
+ const revoked = "error" in reply && reply.error?.code === "unauthorized";
224
+ const ticket = fix && pending && credential.state !== "approved" ? readAccessTicket() : void 0;
225
+ ask = fix && (revoked || !!ticket && credential.ticketHash !== ticket.ticketHash);
226
+ if (pending && !ask) {
227
+ inspected.machines.push({
228
+ ...known,
229
+ state: "pending"
230
+ });
231
+ inspected.findings.push(note(`Hosting machine ${machine} has not approved this Mac yet`, `Requested at ${credential.requestedAt}.`, approval(machine, credential.deviceId)));
232
+ continue;
233
+ }
234
+ if (!ask) {
235
+ inspected.machines.push({
236
+ ...known,
237
+ state: revoked ? "revoked" : "unreachable"
238
+ });
239
+ inspected.findings.push(note(`Hosting machine ${machine} ${revoked ? "no longer accepts this Mac" : "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.`));
240
+ continue;
241
+ }
242
+ }
243
+ if (ask) {
244
+ const result = await request(machine, peer, parsed.port, deviceName, io);
245
+ if (result.credential) {
246
+ credentials = [...credentials.filter((each) => each.machine !== machine), result.credential];
247
+ store(credentials);
248
+ }
249
+ inspected.machines.push(result.report);
250
+ inspected.findings.push(result.finding);
251
+ } else {
252
+ inspected.machines.push({
253
+ ...known,
254
+ state: "not-asked"
255
+ });
256
+ inspected.findings.push(note(`Hosting machine ${machine} has not approved this Mac`, "This Mac has not asked for hosting access.", "Run `stim doctor --fix` to ask."));
257
+ }
258
+ }
259
+ return inspected;
260
+ } finally {
261
+ releaseClaim(claim.acquired);
262
+ }
263
+ }
264
+ //#endregion
265
+ export { inspectDeviceHostMachines as n, configuredMachines as t };