@tapflowio/ios-agent 0.19.0 → 0.20.1

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 (24) hide show
  1. package/bin/TapflowNetFilter.app/Contents/CodeResources +0 -0
  2. package/bin/TapflowNetFilter.app/Contents/Info.plist +48 -0
  3. package/bin/TapflowNetFilter.app/Contents/Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/Info.plist +58 -0
  4. package/bin/TapflowNetFilter.app/Contents/Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/MacOS/dev.tapflow.netfilter.ext +0 -0
  5. package/bin/TapflowNetFilter.app/Contents/Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/_CodeSignature/CodeResources +123 -0
  6. package/bin/TapflowNetFilter.app/Contents/Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/embedded.provisionprofile +0 -0
  7. package/bin/TapflowNetFilter.app/Contents/MacOS/TapflowNetFilter +0 -0
  8. package/bin/TapflowNetFilter.app/Contents/PkgInfo +1 -0
  9. package/bin/TapflowNetFilter.app/Contents/_CodeSignature/CodeResources +151 -0
  10. package/bin/TapflowNetFilter.app/Contents/embedded.provisionprofile +0 -0
  11. package/bin/libtapflow-nethook.dylib +0 -0
  12. package/dist/IOSAgent.d.ts +131 -3
  13. package/dist/IOSAgent.d.ts.map +1 -1
  14. package/dist/IOSAgent.js +312 -20
  15. package/dist/IOSAgent.js.map +1 -1
  16. package/dist/SimctlWrapper.d.ts +24 -0
  17. package/dist/SimctlWrapper.d.ts.map +1 -1
  18. package/dist/SimctlWrapper.js +32 -0
  19. package/dist/SimctlWrapper.js.map +1 -1
  20. package/dist/SimulatorNetwork.d.ts +414 -0
  21. package/dist/SimulatorNetwork.d.ts.map +1 -0
  22. package/dist/SimulatorNetwork.js +996 -0
  23. package/dist/SimulatorNetwork.js.map +1 -0
  24. package/package.json +10 -8
@@ -0,0 +1,48 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>BuildMachineOSBuild</key>
6
+ <string>25F84</string>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>en</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>TapflowNetFilter</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>dev.tapflow.netfilter</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>TapflowNetFilter</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>APPL</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>1.0</string>
21
+ <key>CFBundleSupportedPlatforms</key>
22
+ <array>
23
+ <string>MacOSX</string>
24
+ </array>
25
+ <key>CFBundleVersion</key>
26
+ <string>1788368455</string>
27
+ <key>DTCompiler</key>
28
+ <string>com.apple.compilers.llvm.clang.1_0</string>
29
+ <key>DTPlatformBuild</key>
30
+ <string>25F70</string>
31
+ <key>DTPlatformName</key>
32
+ <string>macosx</string>
33
+ <key>DTPlatformVersion</key>
34
+ <string>26.5</string>
35
+ <key>DTSDKBuild</key>
36
+ <string>25F70</string>
37
+ <key>DTSDKName</key>
38
+ <string>macosx26.5</string>
39
+ <key>DTXcode</key>
40
+ <string>2660</string>
41
+ <key>DTXcodeBuild</key>
42
+ <string>17F113</string>
43
+ <key>LSMinimumSystemVersion</key>
44
+ <string>15.0</string>
45
+ <key>NSSystemExtensionUsageDescription</key>
46
+ <string>tapflow uses a network filter to turn a simulator's network on and off.</string>
47
+ </dict>
48
+ </plist>
@@ -0,0 +1,58 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>BuildMachineOSBuild</key>
6
+ <string>25F84</string>
7
+ <key>CFBundleDevelopmentRegion</key>
8
+ <string>en</string>
9
+ <key>CFBundleExecutable</key>
10
+ <string>dev.tapflow.netfilter.ext</string>
11
+ <key>CFBundleIdentifier</key>
12
+ <string>dev.tapflow.netfilter.ext</string>
13
+ <key>CFBundleInfoDictionaryVersion</key>
14
+ <string>6.0</string>
15
+ <key>CFBundleName</key>
16
+ <string>dev.tapflow.netfilter.ext</string>
17
+ <key>CFBundlePackageType</key>
18
+ <string>SYSX</string>
19
+ <key>CFBundleShortVersionString</key>
20
+ <string>1.0</string>
21
+ <key>CFBundleSupportedPlatforms</key>
22
+ <array>
23
+ <string>MacOSX</string>
24
+ </array>
25
+ <key>CFBundleVersion</key>
26
+ <string>1788368455</string>
27
+ <key>DTCompiler</key>
28
+ <string>com.apple.compilers.llvm.clang.1_0</string>
29
+ <key>DTPlatformBuild</key>
30
+ <string>25F70</string>
31
+ <key>DTPlatformName</key>
32
+ <string>macosx</string>
33
+ <key>DTPlatformVersion</key>
34
+ <string>26.5</string>
35
+ <key>DTSDKBuild</key>
36
+ <string>25F70</string>
37
+ <key>DTSDKName</key>
38
+ <string>macosx26.5</string>
39
+ <key>DTXcode</key>
40
+ <string>2660</string>
41
+ <key>DTXcodeBuild</key>
42
+ <string>17F113</string>
43
+ <key>LSMinimumSystemVersion</key>
44
+ <string>15.0</string>
45
+ <key>NSSystemExtensionUsageDescription</key>
46
+ <string>tapflow uses a network filter to turn a simulator's network on and off.</string>
47
+ <key>NetworkExtension</key>
48
+ <dict>
49
+ <key>NEMachServiceName</key>
50
+ <string>6FBS3QP893.dev.tapflow.netfilter.ext</string>
51
+ <key>NEProviderClasses</key>
52
+ <dict>
53
+ <key>com.apple.networkextension.filter-data</key>
54
+ <string>dev_tapflow_netfilter_ext.Provider</string>
55
+ </dict>
56
+ </dict>
57
+ </dict>
58
+ </plist>
@@ -0,0 +1,123 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>files</key>
6
+ <dict/>
7
+ <key>files2</key>
8
+ <dict>
9
+ <key>embedded.provisionprofile</key>
10
+ <dict>
11
+ <key>hash2</key>
12
+ <data>
13
+ /gvzc8lxriJf3uBd6cZwgCfAPw5+UhGN4Du8fKeP+Fg=
14
+ </data>
15
+ </dict>
16
+ </dict>
17
+ <key>rules</key>
18
+ <dict>
19
+ <key>^Resources/</key>
20
+ <true/>
21
+ <key>^Resources/.*\.lproj/</key>
22
+ <dict>
23
+ <key>optional</key>
24
+ <true/>
25
+ <key>weight</key>
26
+ <real>1000</real>
27
+ </dict>
28
+ <key>^Resources/.*\.lproj/locversion.plist$</key>
29
+ <dict>
30
+ <key>omit</key>
31
+ <true/>
32
+ <key>weight</key>
33
+ <real>1100</real>
34
+ </dict>
35
+ <key>^Resources/Base\.lproj/</key>
36
+ <dict>
37
+ <key>weight</key>
38
+ <real>1010</real>
39
+ </dict>
40
+ <key>^version.plist$</key>
41
+ <true/>
42
+ </dict>
43
+ <key>rules2</key>
44
+ <dict>
45
+ <key>.*\.dSYM($|/)</key>
46
+ <dict>
47
+ <key>weight</key>
48
+ <real>11</real>
49
+ </dict>
50
+ <key>^(.*/)?\.DS_Store$</key>
51
+ <dict>
52
+ <key>omit</key>
53
+ <true/>
54
+ <key>weight</key>
55
+ <real>2000</real>
56
+ </dict>
57
+ <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
58
+ <dict>
59
+ <key>nested</key>
60
+ <true/>
61
+ <key>weight</key>
62
+ <real>10</real>
63
+ </dict>
64
+ <key>^.*</key>
65
+ <true/>
66
+ <key>^Info\.plist$</key>
67
+ <dict>
68
+ <key>omit</key>
69
+ <true/>
70
+ <key>weight</key>
71
+ <real>20</real>
72
+ </dict>
73
+ <key>^PkgInfo$</key>
74
+ <dict>
75
+ <key>omit</key>
76
+ <true/>
77
+ <key>weight</key>
78
+ <real>20</real>
79
+ </dict>
80
+ <key>^Resources/</key>
81
+ <dict>
82
+ <key>weight</key>
83
+ <real>20</real>
84
+ </dict>
85
+ <key>^Resources/.*\.lproj/</key>
86
+ <dict>
87
+ <key>optional</key>
88
+ <true/>
89
+ <key>weight</key>
90
+ <real>1000</real>
91
+ </dict>
92
+ <key>^Resources/.*\.lproj/locversion.plist$</key>
93
+ <dict>
94
+ <key>omit</key>
95
+ <true/>
96
+ <key>weight</key>
97
+ <real>1100</real>
98
+ </dict>
99
+ <key>^Resources/Base\.lproj/</key>
100
+ <dict>
101
+ <key>weight</key>
102
+ <real>1010</real>
103
+ </dict>
104
+ <key>^[^/]+$</key>
105
+ <dict>
106
+ <key>nested</key>
107
+ <true/>
108
+ <key>weight</key>
109
+ <real>10</real>
110
+ </dict>
111
+ <key>^embedded\.provisionprofile$</key>
112
+ <dict>
113
+ <key>weight</key>
114
+ <real>20</real>
115
+ </dict>
116
+ <key>^version\.plist$</key>
117
+ <dict>
118
+ <key>weight</key>
119
+ <real>20</real>
120
+ </dict>
121
+ </dict>
122
+ </dict>
123
+ </plist>
@@ -0,0 +1 @@
1
+ APPL????
@@ -0,0 +1,151 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <plist version="1.0">
4
+ <dict>
5
+ <key>files</key>
6
+ <dict/>
7
+ <key>files2</key>
8
+ <dict>
9
+ <key>Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/Info.plist</key>
10
+ <dict>
11
+ <key>hash2</key>
12
+ <data>
13
+ OftYOF4mpMeJO2ZBYP9bVoYYEbD8unetiZcme9agrkg=
14
+ </data>
15
+ </dict>
16
+ <key>Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/MacOS/dev.tapflow.netfilter.ext</key>
17
+ <dict>
18
+ <key>hash2</key>
19
+ <data>
20
+ Q6nFisozyDJARUmPBgqtk1viYcybjQwg55U4V+rCAYE=
21
+ </data>
22
+ </dict>
23
+ <key>Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/_CodeSignature/CodeResources</key>
24
+ <dict>
25
+ <key>hash2</key>
26
+ <data>
27
+ jhkkIzf2QwiZmCGMMc0rHv/o7MY263G6MRchxbFaQKY=
28
+ </data>
29
+ </dict>
30
+ <key>Library/SystemExtensions/dev.tapflow.netfilter.ext.systemextension/Contents/embedded.provisionprofile</key>
31
+ <dict>
32
+ <key>hash2</key>
33
+ <data>
34
+ /gvzc8lxriJf3uBd6cZwgCfAPw5+UhGN4Du8fKeP+Fg=
35
+ </data>
36
+ </dict>
37
+ <key>embedded.provisionprofile</key>
38
+ <dict>
39
+ <key>hash2</key>
40
+ <data>
41
+ eJ9XOE8PI1L7ZWroUjaeoUJm94LVOMd8zJALu6X4apE=
42
+ </data>
43
+ </dict>
44
+ </dict>
45
+ <key>rules</key>
46
+ <dict>
47
+ <key>^Resources/</key>
48
+ <true/>
49
+ <key>^Resources/.*\.lproj/</key>
50
+ <dict>
51
+ <key>optional</key>
52
+ <true/>
53
+ <key>weight</key>
54
+ <real>1000</real>
55
+ </dict>
56
+ <key>^Resources/.*\.lproj/locversion.plist$</key>
57
+ <dict>
58
+ <key>omit</key>
59
+ <true/>
60
+ <key>weight</key>
61
+ <real>1100</real>
62
+ </dict>
63
+ <key>^Resources/Base\.lproj/</key>
64
+ <dict>
65
+ <key>weight</key>
66
+ <real>1010</real>
67
+ </dict>
68
+ <key>^version.plist$</key>
69
+ <true/>
70
+ </dict>
71
+ <key>rules2</key>
72
+ <dict>
73
+ <key>.*\.dSYM($|/)</key>
74
+ <dict>
75
+ <key>weight</key>
76
+ <real>11</real>
77
+ </dict>
78
+ <key>^(.*/)?\.DS_Store$</key>
79
+ <dict>
80
+ <key>omit</key>
81
+ <true/>
82
+ <key>weight</key>
83
+ <real>2000</real>
84
+ </dict>
85
+ <key>^(Frameworks|SharedFrameworks|PlugIns|Plug-ins|XPCServices|Helpers|MacOS|Library/(Automator|Spotlight|LoginItems))/</key>
86
+ <dict>
87
+ <key>nested</key>
88
+ <true/>
89
+ <key>weight</key>
90
+ <real>10</real>
91
+ </dict>
92
+ <key>^.*</key>
93
+ <true/>
94
+ <key>^Info\.plist$</key>
95
+ <dict>
96
+ <key>omit</key>
97
+ <true/>
98
+ <key>weight</key>
99
+ <real>20</real>
100
+ </dict>
101
+ <key>^PkgInfo$</key>
102
+ <dict>
103
+ <key>omit</key>
104
+ <true/>
105
+ <key>weight</key>
106
+ <real>20</real>
107
+ </dict>
108
+ <key>^Resources/</key>
109
+ <dict>
110
+ <key>weight</key>
111
+ <real>20</real>
112
+ </dict>
113
+ <key>^Resources/.*\.lproj/</key>
114
+ <dict>
115
+ <key>optional</key>
116
+ <true/>
117
+ <key>weight</key>
118
+ <real>1000</real>
119
+ </dict>
120
+ <key>^Resources/.*\.lproj/locversion.plist$</key>
121
+ <dict>
122
+ <key>omit</key>
123
+ <true/>
124
+ <key>weight</key>
125
+ <real>1100</real>
126
+ </dict>
127
+ <key>^Resources/Base\.lproj/</key>
128
+ <dict>
129
+ <key>weight</key>
130
+ <real>1010</real>
131
+ </dict>
132
+ <key>^[^/]+$</key>
133
+ <dict>
134
+ <key>nested</key>
135
+ <true/>
136
+ <key>weight</key>
137
+ <real>10</real>
138
+ </dict>
139
+ <key>^embedded\.provisionprofile$</key>
140
+ <dict>
141
+ <key>weight</key>
142
+ <real>20</real>
143
+ </dict>
144
+ <key>^version\.plist$</key>
145
+ <dict>
146
+ <key>weight</key>
147
+ <real>20</real>
148
+ </dict>
149
+ </dict>
150
+ </dict>
151
+ </plist>
Binary file
@@ -1,7 +1,8 @@
1
- import type { Device, DeviceAgent, UIElement } from '@tapflowio/agent-core';
1
+ import type { Device, DeviceAgent, NetworkControlCapability, NetworkStatePayload, UIElement } from '@tapflowio/agent-core';
2
2
  export declare const IOS_BUTTON_ALIASES: Record<string, string>;
3
3
  import { type SleepBlocker } from '@tapflowio/agent-core/utils';
4
4
  import { SimctlWrapper } from './SimctlWrapper.js';
5
+ import { SimulatorNetwork } from './SimulatorNetwork.js';
5
6
  export interface IOSAgentOptions {
6
7
  fps?: number;
7
8
  intervalMs?: number;
@@ -14,9 +15,13 @@ export interface IOSAgentOptions {
14
15
  token?: string;
15
16
  /** Handshake(연결~agent:registered) 타임아웃 ms. 기본 10초, 테스트용 주입 가능. */
16
17
  handshakeTimeoutMs?: number;
18
+ /** The three-layer network control (#607). Injectable so a test can point it somewhere harmless;
19
+ * defaults to one wired to this agent's simctl (and, under vitest, to nothing real). */
20
+ network?: SimulatorNetwork;
17
21
  }
18
- export declare class IOSAgent implements DeviceAgent {
22
+ export declare class IOSAgent implements DeviceAgent, NetworkControlCapability {
19
23
  private readonly simctl;
24
+ private readonly network;
20
25
  private readonly fps;
21
26
  private readonly intervalMs;
22
27
  private readonly reconnectDelays;
@@ -48,6 +53,26 @@ export declare class IOSAgent implements DeviceAgent {
48
53
  * inside `onopen` on a local socket. */
49
54
  private sendOn;
50
55
  private deviceStates;
56
+ /**
57
+ * Devices **this agent booted**, by device id.
58
+ *
59
+ * Separate from `DeviceState.booted` because the two answer different questions and have different
60
+ * lifetimes. `booted` is liveness and is a cache: `initDeviceStates` rebuilds the whole map on
61
+ * every `agent:registered`, so it does not survive a reconnect. This does — the agent process is
62
+ * the same one across a reconnect — and it is what says *which* device is tapflow's when a
63
+ * developer has a second simulator of their own open.
64
+ *
65
+ * Without it, a reconnect on a two-simulator desk left the capability entry points asking simctl,
66
+ * getting two live devices, and refusing both. Written only where a boot succeeds; never by
67
+ * `ackInput`, which verifies liveness and proves nothing about ownership.
68
+ *
69
+ * **The `DeviceAgent.boot`/`shutdown` delegates do not touch this**, and that is deliberate: they
70
+ * hand a device id straight to simctl without opening a session, so a device they start is not one
71
+ * this agent is driving. Nothing in the repo calls either — the same position `stream()` is in — so
72
+ * wiring ownership through them would be a mechanism built for a caller that does not exist. A
73
+ * future caller that wants both should go through the boot handler rather than around it.
74
+ */
75
+ private readonly ownedDevices;
51
76
  private lastBundleIds;
52
77
  private readonly uiTreeReader;
53
78
  private readonly sleepBlocker;
@@ -139,13 +164,116 @@ export declare class IOSAgent implements DeviceAgent {
139
164
  * (`AndroidAgent.ts:1429`); these do the same. Throwing beats falling back to simctl's `booted`
140
165
  * alias, which would quietly act on whichever simulator happened to be up. */
141
166
  installApp(appPath: string): Promise<void>;
167
+ /** The device a session is driving, or undefined when nothing is booted. */
168
+ /**
169
+ * The session's device, **only while it is up**.
170
+ *
171
+ * `deviceStates` holds one entry per *registered* simulator, not per running one, so this used to
172
+ * answer for a device that was shut down — or never booted. The network path is where that costs
173
+ * something: a toggle after a shutdown writes the kernel rule for a dead udid, and `arm()` is the
174
+ * only thing that clears it, which now happens on the *next* boot of that device. Until then the
175
+ * host is dropping flows for nothing, and a simulator that reuses the udid comes up offline.
176
+ *
177
+ * **`booted` alone is not the check, and reading it as one is a regression this shipped once.**
178
+ * The flag is a cache, not the truth: `initDeviceStates` runs on `agent:registered`, which is every
179
+ * *reconnect* and not only the first connection, so it is `false` for a simulator that has been up
180
+ * the whole time. Gated on the flag alone, a relay restart left the toggle answering
181
+ * `No booted device` for a running device and left `network:request-state` — the message a viewer's
182
+ * re-join sends, which exists precisely for this moment — silently unanswered, so the control never
183
+ * left `waiting`.
184
+ *
185
+ * So it falls back to asking simctl and caches the answer, which is what `ackInput` already does
186
+ * with the same flag and for the same reason. That is also why this is async.
187
+ */
188
+ private deviceFor;
189
+ /**
190
+ * Send the current state to a session.
191
+ *
192
+ * Uncorrelated on purpose: this answers `device:ready` and a viewer's re-join, neither of which is a
193
+ * request anyone is waiting on. Silent with no device, for the same reason `network:error` would be
194
+ * addressed to nobody.
195
+ */
196
+ private reportNetworkState;
197
+ /**
198
+ * A device that was offline stopped being enforced — tell whoever is watching it.
199
+ *
200
+ * **Uncorrelated, and it has to be**: nobody asked. `network:error` is the wrong carrier for the
201
+ * same reason — that type is *"a `network:set` that could not be dispatched"*, and this is not a
202
+ * request failing. `network:state` already supports an unsolicited frame; the viewer re-join path
203
+ * has been sending one since #614.
204
+ *
205
+ * **Every session holding the device, not one.** A device can sit behind two sessions, and the one
206
+ * that happened to make the last request is not necessarily the one whose tester is looking at it.
207
+ *
208
+ * Synchronous on purpose: `deviceFor` asks simctl before believing a device is up, and this runs
209
+ * from a timer while something has just gone wrong with that device. The state being reported is
210
+ * about the filter, not about whether the simulator is still booted.
211
+ */
212
+ private reportEnforcementLost;
213
+ private handleNetworkSet;
214
+ /**
215
+ * The two capability entry points, which resolve their device the way every other one on this class
216
+ * does — **`soleDeviceState`, not the first key in the map.**
217
+ *
218
+ * `deviceStates` holds one entry per *registered* simulator and this Mac reports dozens, so
219
+ * `keys().next()` is whichever simctl listed first, almost always a shut-down one. That was wrong
220
+ * before the liveness check and became a hard failure after it: `deviceFor` answers `undefined` for
221
+ * a shut-down device, so both of these threw `No booted device` while a booted device sat right
222
+ * there. `soleDeviceState` filters on `booted` and refuses to guess between two, which is the
223
+ * policy this class already settled and wrote down — these were simply not using it.
224
+ *
225
+ * `deviceFor` stays for the wire path, where the caller names a session and the only open question
226
+ * is whether that device is up.
227
+ */
228
+ setNetworkOffline(offline: boolean): Promise<NetworkStatePayload>;
229
+ networkState(): Promise<NetworkStatePayload>;
142
230
  launchApp(bundleId: string): Promise<void>;
143
231
  /** The one booted session, or undefined when there is no unambiguous answer. Callers that can
144
232
  * reasonably do nothing (input) use this; callers that owe the user a result use
145
233
  * `soleDeviceState`, which throws instead. */
146
234
  private liveDeviceState;
235
+ /** The one device out of `live`, or the refusal. Factored so the async resolver below answers
236
+ * ambiguity with the same words rather than its own. */
237
+ private soleOf;
238
+ /**
239
+ * **The synchronous resolver, and `stream()` is the only caller left.**
240
+ *
241
+ * Everything else that resolves a device for a capability call awaits `soleLiveDeviceState`,
242
+ * which asks simctl rather than trusting `booted` — a flag `initDeviceStates` clears on every
243
+ * reconnect. `stream()` returns a `ReadableStream` and is part of `DeviceAgent`, so it cannot
244
+ * await without changing that interface across both agents.
245
+ *
246
+ * **It is deliberately left with the stale flag, and nothing was added to paper over that.** A
247
+ * refresh that marked every simulator simctl reports as booted was written and removed: it also
248
+ * marked the ones a developer had open in Simulator.app, which destroys the very thing `booted`
249
+ * disambiguates by — *the device this agent booted* — and made all the callers above refuse with
250
+ * "2 booted devices" on the common two-simulator desk. Fire-and-forget, it could also resurrect a
251
+ * flag a `device:shutdown` had just cleared, with no path back.
252
+ *
253
+ * That was a mechanism for a method **nothing in this repo calls**. A future caller needs the
254
+ * interface decision, not a guess: make `stream()` async across `DeviceAgent`, or give it an
255
+ * explicit device argument.
256
+ */
147
257
  private soleDeviceState;
148
- private soleDeviceId;
258
+ /**
259
+ * `soleDeviceState`, but **it asks simctl before believing that nothing is booted**.
260
+ *
261
+ * `booted` is a cache and `initDeviceStates` clears it on `agent:registered` — every reconnect,
262
+ * not only the first connection. So after a relay restart every flag reads false while the
263
+ * simulators are still running, and a resolver that trusts the cache refuses a live device until
264
+ * something else happens to refresh it. On the wire path that is `deviceFor`; these two entry
265
+ * points have no session id to work from, so without this they stay broken.
266
+ *
267
+ * Only the empty case pays for the `listDevices` call: a cache that already names a booted device
268
+ * is not wrong, just possibly incomplete, and the ambiguity refusal is stricter for having fewer
269
+ * candidates rather than looser.
270
+ *
271
+ * **Every entry point that can await now comes through here** — the network pair, `installApp`,
272
+ * `launchApp`, `queryUITree`, `screenshot`, `openUrl`. `stream()` cannot, and `soleDeviceState`
273
+ * above says what that costs and why nothing was bolted on to hide it.
274
+ */
275
+ private soleLiveDeviceState;
276
+ private soleLiveDeviceId;
149
277
  queryUITree(): Promise<UIElement[]>;
150
278
  private audioEnabled;
151
279
  private startAudioCapture;
@@ -1 +1 @@
1
- {"version":3,"file":"IOSAgent.d.ts","sourceRoot":"","sources":["../src/IOSAgent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"IOSAgent.d.ts","sourceRoot":"","sources":["../src/IOSAgent.ts"],"names":[],"mappings":"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"}