@tapflowio/ios-agent 0.28.1 → 0.29.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/NOTICE +1 -1
- package/dist/IOSAgent.d.ts +24 -3
- package/dist/IOSAgent.d.ts.map +1 -1
- package/dist/IOSAgent.js +117 -29
- package/dist/IOSAgent.js.map +1 -1
- package/dist/LeanStore.d.ts +24 -3
- package/dist/LeanStore.d.ts.map +1 -1
- package/dist/LeanStore.js +61 -2
- package/dist/LeanStore.js.map +1 -1
- package/dist/SimctlWrapper.d.ts +14 -1
- package/dist/SimctlWrapper.d.ts.map +1 -1
- package/dist/SimctlWrapper.js +46 -3
- package/dist/SimctlWrapper.js.map +1 -1
- package/dist/TouchHelper.d.ts +11 -1
- package/dist/TouchHelper.d.ts.map +1 -1
- package/dist/TouchHelper.js +53 -2
- package/dist/TouchHelper.js.map +1 -1
- package/dist/leanLabels.d.ts +5 -0
- package/dist/leanLabels.d.ts.map +1 -1
- package/dist/leanLabels.js +5 -1
- package/dist/leanLabels.js.map +1 -1
- package/dist/serviceTiers.d.ts +25 -0
- package/dist/serviceTiers.d.ts.map +1 -0
- package/dist/serviceTiers.js +251 -0
- package/dist/serviceTiers.js.map +1 -0
- package/dist/xcuiTree.d.ts.map +1 -1
- package/dist/xcuiTree.js +23 -6
- package/dist/xcuiTree.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* The launchd labels the slim service tier disables, and the services each feature needs.
|
|
3
|
+
*
|
|
4
|
+
* Selected from simslim (https://github.com/MobAI-App/simslim, commit e752a728), which is:
|
|
5
|
+
*
|
|
6
|
+
* MIT License
|
|
7
|
+
*
|
|
8
|
+
* Copyright (c) 2026 Interlap
|
|
9
|
+
*
|
|
10
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
11
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
12
|
+
* in the Software without restriction, including without limitation the rights
|
|
13
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
14
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
15
|
+
* furnished to do so, subject to the following conditions:
|
|
16
|
+
*
|
|
17
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
18
|
+
* copies or substantial portions of the Software.
|
|
19
|
+
*
|
|
20
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
21
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
22
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
23
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
24
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
25
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
26
|
+
* SOFTWARE.
|
|
27
|
+
*/
|
|
28
|
+
import { LEAN_LABELS } from './leanLabels.js';
|
|
29
|
+
/**
|
|
30
|
+
* simslim's full profile, minus three it never turns off and says why: `assistantd` (Spotlight's app leaks memory
|
|
31
|
+
* without it), `gamed` and `sharingd`. Measured on an 8 GB Mac, booting with this list cut the boot's CPU
|
|
32
|
+
* saturation from 20–49 s to 7–14 s against Lean mode's list (`contributing/simulator-boot-contention.md`).
|
|
33
|
+
*
|
|
34
|
+
* It turns off what Lean mode keeps on purpose — widgets and Live Activities, Spotlight, on-device models, push,
|
|
35
|
+
* StoreKit and Wallet, photos, contacts, CloudKit, Sign in with Apple, App Attest — so it is only ever used when a
|
|
36
|
+
* run asks for it, and `keep` puts back what that run's app needs.
|
|
37
|
+
*/
|
|
38
|
+
export const SLIM_LABELS = [
|
|
39
|
+
'com.apple.FamilyControlsAgent',
|
|
40
|
+
'com.apple.GameController.gamecontrollerd',
|
|
41
|
+
'com.apple.MapKit.SnapshotService',
|
|
42
|
+
'com.apple.Maps.geocorrectiond',
|
|
43
|
+
'com.apple.Maps.mapspushd',
|
|
44
|
+
'com.apple.Maps.mapssyncd',
|
|
45
|
+
'com.apple.PosterBoard',
|
|
46
|
+
'com.apple.Safari.History',
|
|
47
|
+
'com.apple.Safari.SafeBrowsing.Service',
|
|
48
|
+
'com.apple.Safari.passwordbreachd',
|
|
49
|
+
'com.apple.SafariBookmarksSyncAgent',
|
|
50
|
+
'com.apple.ScreenTimeAgent',
|
|
51
|
+
'com.apple.ScreenTimeSettingsAgent',
|
|
52
|
+
'com.apple.SecureBackupDaemon',
|
|
53
|
+
'com.apple.StatusKitAgent',
|
|
54
|
+
'com.apple.TrustedPeersHelper',
|
|
55
|
+
'com.apple.UsageTrackingAgent',
|
|
56
|
+
'com.apple.WebBookmarks.webbookmarksd',
|
|
57
|
+
'com.apple.activityawardsd',
|
|
58
|
+
'com.apple.activitysharingd',
|
|
59
|
+
'com.apple.akd',
|
|
60
|
+
'com.apple.amsaccountsd',
|
|
61
|
+
'com.apple.amsengagementd',
|
|
62
|
+
'com.apple.amsondevicestoraged',
|
|
63
|
+
'com.apple.announced',
|
|
64
|
+
'com.apple.ap.adprivacyd',
|
|
65
|
+
'com.apple.ap.promotedcontentd',
|
|
66
|
+
'com.apple.appleaccountd',
|
|
67
|
+
'com.apple.appleaccounttransparencyd',
|
|
68
|
+
'com.apple.appleidsetupd',
|
|
69
|
+
'com.apple.appstorecomponentsd',
|
|
70
|
+
'com.apple.appstored',
|
|
71
|
+
'com.apple.apsd',
|
|
72
|
+
'com.apple.askpermissiond',
|
|
73
|
+
'com.apple.asktod',
|
|
74
|
+
'com.apple.assetsd',
|
|
75
|
+
'com.apple.assetsd.nebulad',
|
|
76
|
+
'com.apple.assetsubscriptiond',
|
|
77
|
+
'com.apple.assistant_cdmd',
|
|
78
|
+
'com.apple.assistant_service',
|
|
79
|
+
'com.apple.avatarsd',
|
|
80
|
+
'com.apple.bird',
|
|
81
|
+
'com.apple.businessservicesd',
|
|
82
|
+
'com.apple.calaccessd',
|
|
83
|
+
'com.apple.carkitd',
|
|
84
|
+
'com.apple.cdpd',
|
|
85
|
+
'com.apple.chronod',
|
|
86
|
+
'com.apple.ckdiscretionaryd',
|
|
87
|
+
'com.apple.cloudd',
|
|
88
|
+
'com.apple.cloudphotod',
|
|
89
|
+
'com.apple.cloudsettingssyncagent',
|
|
90
|
+
'com.apple.communicationtrustd',
|
|
91
|
+
'com.apple.companiond',
|
|
92
|
+
'com.apple.contacts.postersyncd',
|
|
93
|
+
'com.apple.contactsd',
|
|
94
|
+
'com.apple.coreidvd',
|
|
95
|
+
'com.apple.corespeechd',
|
|
96
|
+
'com.apple.corespotlightservice',
|
|
97
|
+
'com.apple.countryd',
|
|
98
|
+
'com.apple.dataaccess.dataaccessd',
|
|
99
|
+
'com.apple.deviceaccessd',
|
|
100
|
+
'com.apple.devicecheckd',
|
|
101
|
+
'com.apple.diagnosticextensionsd',
|
|
102
|
+
'com.apple.email.maild',
|
|
103
|
+
'com.apple.exchangesyncd',
|
|
104
|
+
'com.apple.facetimemessagestored',
|
|
105
|
+
'com.apple.familycircled',
|
|
106
|
+
'com.apple.familynotification',
|
|
107
|
+
'com.apple.feedbackd',
|
|
108
|
+
'com.apple.financed',
|
|
109
|
+
'com.apple.findmy.findmylocated',
|
|
110
|
+
'com.apple.finhealthd',
|
|
111
|
+
'com.apple.fitcore',
|
|
112
|
+
'com.apple.fitcore.session',
|
|
113
|
+
'com.apple.fitnesscoachingd',
|
|
114
|
+
'com.apple.fitnessintelligenced',
|
|
115
|
+
'com.apple.followupd',
|
|
116
|
+
'com.apple.gamesaved',
|
|
117
|
+
'com.apple.generativeexperiencesd',
|
|
118
|
+
'com.apple.geoanalyticsd',
|
|
119
|
+
'com.apple.healthappd',
|
|
120
|
+
'com.apple.healthcontentd',
|
|
121
|
+
'com.apple.healthd',
|
|
122
|
+
'com.apple.healtheventsd',
|
|
123
|
+
'com.apple.healthrecordsd',
|
|
124
|
+
'com.apple.homed',
|
|
125
|
+
'com.apple.homeeventsd',
|
|
126
|
+
'com.apple.icloudmailagent',
|
|
127
|
+
'com.apple.icloudsubscriptionoptimizerd',
|
|
128
|
+
'com.apple.identityservicesd',
|
|
129
|
+
'com.apple.ids_simd',
|
|
130
|
+
'com.apple.imautomatichistorydeletionagent',
|
|
131
|
+
'com.apple.imcore.imtransferagent',
|
|
132
|
+
'com.apple.imdpersistence.IMDPersistenceAgent',
|
|
133
|
+
'com.apple.ind',
|
|
134
|
+
'com.apple.intelligencecontextd',
|
|
135
|
+
'com.apple.intelligenceflowd',
|
|
136
|
+
'com.apple.intelligenceplatformd',
|
|
137
|
+
'com.apple.intelligencetasksd',
|
|
138
|
+
'com.apple.itunescloudd',
|
|
139
|
+
'com.apple.itunesstored',
|
|
140
|
+
'com.apple.jetpackassetd',
|
|
141
|
+
'com.apple.knowledgeconstructiond',
|
|
142
|
+
'com.apple.linkd',
|
|
143
|
+
'com.apple.liveactivitiesd',
|
|
144
|
+
'com.apple.managedconfiguration.passcodenagd',
|
|
145
|
+
'com.apple.maps.destinationd',
|
|
146
|
+
'com.apple.mediaanalysisd',
|
|
147
|
+
'com.apple.mediaanalysisd.service',
|
|
148
|
+
'com.apple.medialibraryd',
|
|
149
|
+
'com.apple.mediastream.mstreamd',
|
|
150
|
+
'com.apple.merchantd',
|
|
151
|
+
'com.apple.mlhostd',
|
|
152
|
+
'com.apple.mlruntimed',
|
|
153
|
+
'com.apple.mobileassetd',
|
|
154
|
+
'com.apple.modelcatalogd',
|
|
155
|
+
'com.apple.modelmanagerd',
|
|
156
|
+
'com.apple.musicd',
|
|
157
|
+
'com.apple.naturallanguaged',
|
|
158
|
+
'com.apple.navd',
|
|
159
|
+
'com.apple.newsd',
|
|
160
|
+
'com.apple.parsec-fbf',
|
|
161
|
+
'com.apple.parsecd',
|
|
162
|
+
'com.apple.passd',
|
|
163
|
+
'com.apple.peopled',
|
|
164
|
+
'com.apple.photoanalysisd',
|
|
165
|
+
'com.apple.photosface',
|
|
166
|
+
'com.apple.proactiveeventtrackerd',
|
|
167
|
+
'com.apple.protectedcloudstorage.protectedcloudkeysyncing',
|
|
168
|
+
'com.apple.purplebuddy.budd',
|
|
169
|
+
'com.apple.rapportd',
|
|
170
|
+
'com.apple.remindd',
|
|
171
|
+
'com.apple.replicatord',
|
|
172
|
+
'com.apple.rtcreportingd',
|
|
173
|
+
'com.apple.safarifetcherd',
|
|
174
|
+
'com.apple.searchd',
|
|
175
|
+
'com.apple.searchtoold',
|
|
176
|
+
'com.apple.securityuploadd',
|
|
177
|
+
'com.apple.siri.acousticsignature',
|
|
178
|
+
'com.apple.siri.context.service',
|
|
179
|
+
'com.apple.siriactionsd',
|
|
180
|
+
'com.apple.siriinferenced',
|
|
181
|
+
'com.apple.siriknowledged',
|
|
182
|
+
'com.apple.sirittsd',
|
|
183
|
+
'com.apple.sociallayerd',
|
|
184
|
+
'com.apple.sosd',
|
|
185
|
+
'com.apple.speechmodeltrainingd',
|
|
186
|
+
'com.apple.spotlightknowledged',
|
|
187
|
+
'com.apple.spotlightknowledged.updater',
|
|
188
|
+
'com.apple.stickersd',
|
|
189
|
+
'com.apple.storagedatad',
|
|
190
|
+
'com.apple.storekitd',
|
|
191
|
+
'com.apple.suggestd',
|
|
192
|
+
'com.apple.swcd',
|
|
193
|
+
'com.apple.syncdefaultsd',
|
|
194
|
+
'com.apple.telephonyutilities.callservicesd',
|
|
195
|
+
'com.apple.textunderstandingd',
|
|
196
|
+
'com.apple.tipsd',
|
|
197
|
+
'com.apple.triald',
|
|
198
|
+
'com.apple.tvremoted',
|
|
199
|
+
'com.apple.videosubscriptionsd',
|
|
200
|
+
'com.apple.voicebankingd',
|
|
201
|
+
'com.apple.voiced',
|
|
202
|
+
'com.apple.wcd',
|
|
203
|
+
'com.apple.weatherd',
|
|
204
|
+
'com.apple.webkit.adattributiond',
|
|
205
|
+
'com.apple.webkit.webpushd',
|
|
206
|
+
'com.apple.webprivacyd',
|
|
207
|
+
];
|
|
208
|
+
/**
|
|
209
|
+
* The services each feature needs, from simslim's `features.go` (same commit). A feature is a user-facing
|
|
210
|
+
* capability; its labels are what has to stay on for it to work. StoreKit needs Wallet and Finance too: products
|
|
211
|
+
* load without them, but a purchase fails when the sheet is presented.
|
|
212
|
+
*/
|
|
213
|
+
export const FEATURE_LABELS = {
|
|
214
|
+
'push': ['com.apple.apsd'],
|
|
215
|
+
'storekit': ['com.apple.storekitd', 'com.apple.itunesstored', 'com.apple.amsaccountsd', 'com.apple.amsengagementd', 'com.apple.amsondevicestoraged', 'com.apple.passd', 'com.apple.financed'],
|
|
216
|
+
'app-store': ['com.apple.appstored', 'com.apple.itunesstored'],
|
|
217
|
+
'universal-links': ['com.apple.swcd'],
|
|
218
|
+
'spotlight': ['com.apple.searchd', 'com.apple.searchtoold'],
|
|
219
|
+
'siri': ['com.apple.assistantd', 'com.apple.corespeechd'],
|
|
220
|
+
'icloud': ['com.apple.cloudd'],
|
|
221
|
+
'keychain-sync': ['com.apple.akd'],
|
|
222
|
+
'contacts': ['com.apple.contactsd'],
|
|
223
|
+
'calendar': ['com.apple.calaccessd'],
|
|
224
|
+
'reminders': ['com.apple.remindd'],
|
|
225
|
+
'mail': ['com.apple.email.maild'],
|
|
226
|
+
'photos': ['com.apple.assetsd', 'com.apple.photoanalysisd'],
|
|
227
|
+
'health': ['com.apple.healthd'],
|
|
228
|
+
'homekit': ['com.apple.homed'],
|
|
229
|
+
'imessage': ['com.apple.identityservicesd'],
|
|
230
|
+
'widgets': ['com.apple.chronod', 'com.apple.liveactivitiesd'],
|
|
231
|
+
// passd crashes at start-up without financed (leanLabels.ts), so keeping Wallet keeps both.
|
|
232
|
+
'wallet': ['com.apple.passd', 'com.apple.financed'],
|
|
233
|
+
'maps': ['com.apple.Maps.mapssyncd'],
|
|
234
|
+
'weather': ['com.apple.weatherd'],
|
|
235
|
+
'news': ['com.apple.newsd'],
|
|
236
|
+
'game-center': ['com.apple.gamed'],
|
|
237
|
+
'find-my': ['com.apple.findmy.findmylocated'],
|
|
238
|
+
'screen-time': ['com.apple.ScreenTimeAgent'],
|
|
239
|
+
};
|
|
240
|
+
/** Every label any tier can switch off — what an unreadable marker is recovered against (`LeanStore`). */
|
|
241
|
+
export const MANAGED_LABELS = [...new Set([...LEAN_LABELS, ...SLIM_LABELS])];
|
|
242
|
+
/**
|
|
243
|
+
* The labels a tier switches off on a device: the tier's list, less every service a kept feature needs.
|
|
244
|
+
* `stock` is the empty list, which is how "put everything back" is expressed to the store.
|
|
245
|
+
*/
|
|
246
|
+
export function labelsFor(tier) {
|
|
247
|
+
const base = tier.name === 'slim' ? SLIM_LABELS : tier.name === 'lean' ? LEAN_LABELS : [];
|
|
248
|
+
const kept = new Set(tier.keep.flatMap((f) => FEATURE_LABELS[f]));
|
|
249
|
+
return base.filter((label) => !kept.has(label));
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=serviceTiers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serviceTiers.js","sourceRoot":"","sources":["../src/serviceTiers.ts"],"names":[],"mappings":"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"}
|
package/dist/xcuiTree.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcuiTree.d.ts","sourceRoot":"","sources":["../src/xcuiTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,uBAAuB,CAAA;
|
|
1
|
+
{"version":3,"file":"xcuiTree.d.ts","sourceRoot":"","sources":["../src/xcuiTree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAiB,MAAM,uBAAuB,CAAA;AAwGrE,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,CAqDvD"}
|
package/dist/xcuiTree.js
CHANGED
|
@@ -7,7 +7,10 @@
|
|
|
7
7
|
// NavigationBar, 0x105808b10, {{0.0, 47.4}, {402.0, 47.4}}, identifier: 'The App'
|
|
8
8
|
// Other, 0x105810800, {{0.0, 131.3}, {402.0, 66.4}}, identifier: 'Echo Box', label: 'Echo Box'
|
|
9
9
|
// Other, 0x105811820, {{366.6, 94.7}, {32.2, 779.3}}, label: 'Vertical scroll bar', value: 0%
|
|
10
|
-
//
|
|
10
|
+
// TextField, 0x105812a00, {{20.0, 120.0}, {362.0, 34.0}}, identifier: 'email', placeholderValue: 'Email'
|
|
11
|
+
// Button, 0x105813b00, {{279.0, 795.0}, {98.0, 54.0}}, identifier: 'tab.web', label: 'Web', Selected
|
|
12
|
+
// Fields after the address appear in order: [pid], [frame], [identifier], [label], [placeholderValue],
|
|
13
|
+
// [value], then state flags (Selected, Focused, ...).
|
|
11
14
|
// XCUITest element type → unified vocabulary. XCUITest labels many custom/composed
|
|
12
15
|
// views as "Other" (they still carry identifier/label), so role is best-effort and
|
|
13
16
|
// identifier/label carry the selector weight.
|
|
@@ -52,11 +55,20 @@ const round4 = (n) => Math.round(n * 10000) / 10000;
|
|
|
52
55
|
const floor4 = (n) => Math.max(0, Math.floor(n * 10000 + 1e-9) / 10000);
|
|
53
56
|
const FRAME_RE = /\{\{(-?[\d.]+), (-?[\d.]+)\}, \{(-?[\d.]+), (-?[\d.]+)\}\}/;
|
|
54
57
|
// Terminate quoted fields on the next field boundary, so a quote inside the
|
|
55
|
-
// value (e.g. label: 'Don't') does not truncate the match.
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
// value (e.g. label: 'Don't') does not truncate the match. A boundary is one of
|
|
59
|
+
// the fields that can follow — `placeholderValue` on a text field, `value`
|
|
60
|
+
// even though it isn't captured — or the end of the line, which may carry state
|
|
61
|
+
// flags first (`, Selected`, `, Focused`). Missing either let the lazy match run
|
|
62
|
+
// on to the line's last quote: a placeholder field's identifier came out as
|
|
63
|
+
// `email', placeholderValue: 'Email`, and a selected tab's label as nothing.
|
|
64
|
+
// A flag may be two capitalised words: `Keyboard Focused` is printed on a text field being typed into
|
|
65
|
+
// (iOS 26.5, measured), which a single-word pattern would have let the lazy match run past.
|
|
66
|
+
const TRAILING_FLAGS = String.raw `(?:, [A-Z][A-Za-z]*(?: [A-Z][A-Za-z]*)*)*$`;
|
|
67
|
+
const IDENTIFIER_RE = new RegExp(String.raw `, identifier: '(.*?)'(?=, label: |, placeholderValue: |, value: |${TRAILING_FLAGS})`);
|
|
68
|
+
const LABEL_RE = new RegExp(String.raw `, label: '(.*?)'(?=, placeholderValue: |, value: |${TRAILING_FLAGS})`);
|
|
69
|
+
// Kept after typing: measured, a field holding "abc" still prints `placeholderValue: 'Email', value: abc`. An
|
|
70
|
+
// empty field echoes the placeholder into `value` too, which is one reason `value` is not read here.
|
|
71
|
+
const PLACEHOLDER_RE = new RegExp(String.raw `, placeholderValue: '(.*?)'(?=, value: |${TRAILING_FLAGS})`);
|
|
60
72
|
function parseLine(line) {
|
|
61
73
|
// Strip indentation + the root arrow, then take the type up to ", 0x<addr>".
|
|
62
74
|
const m = /^\s*→?\s*(.+?), 0x[0-9a-fA-F]+/.exec(line);
|
|
@@ -73,6 +85,9 @@ function parseLine(line) {
|
|
|
73
85
|
const lm = LABEL_RE.exec(line);
|
|
74
86
|
if (lm)
|
|
75
87
|
node.label = lm[1];
|
|
88
|
+
const pm = PLACEHOLDER_RE.exec(line);
|
|
89
|
+
if (pm && pm[1] !== '')
|
|
90
|
+
node.placeholder = pm[1];
|
|
76
91
|
return node;
|
|
77
92
|
}
|
|
78
93
|
export function parseTreeText(text) {
|
|
@@ -128,6 +143,8 @@ export function parseTreeText(text) {
|
|
|
128
143
|
};
|
|
129
144
|
if (node.identifier)
|
|
130
145
|
element.identifier = node.identifier;
|
|
146
|
+
if (node.placeholder)
|
|
147
|
+
element.placeholder = node.placeholder;
|
|
131
148
|
element.rawRole = node.type;
|
|
132
149
|
elements.push(element);
|
|
133
150
|
}
|
package/dist/xcuiTree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"xcuiTree.js","sourceRoot":"","sources":["../src/xcuiTree.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,uEAAuE;AACvE,EAAE;AACF,8CAA8C;AAC9C,oFAAoF;AACpF,iGAAiG;AACjG,gGAAgG;AAChG,
|
|
1
|
+
{"version":3,"file":"xcuiTree.js","sourceRoot":"","sources":["../src/xcuiTree.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,uEAAuE;AACvE,EAAE;AACF,8CAA8C;AAC9C,oFAAoF;AACpF,iGAAiG;AACjG,gGAAgG;AAChG,2GAA2G;AAC3G,uGAAuG;AACvG,uGAAuG;AACvG,sDAAsD;AAEtD,mFAAmF;AACnF,mFAAmF;AACnF,8CAA8C;AAC9C,SAAS,MAAM,CAAC,IAAY;IAC1B,QAAQ,IAAI,EAAE,CAAC;QACb,KAAK,QAAQ,CAAC;QACd,KAAK,KAAK;YACR,OAAO,QAAQ,CAAA;QACjB,KAAK,WAAW,CAAC;QACjB,KAAK,iBAAiB,CAAC;QACvB,KAAK,aAAa,CAAC;QACnB,KAAK,UAAU;YACb,OAAO,OAAO,CAAA;QAChB,KAAK,YAAY;YACf,OAAO,MAAM,CAAA;QACf,KAAK,OAAO,CAAC;QACb,KAAK,MAAM;YACT,OAAO,OAAO,CAAA;QAChB,KAAK,QAAQ,CAAC;QACd,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAA;QACjB,KAAK,UAAU;YACb,OAAO,UAAU,CAAA;QACnB,KAAK,QAAQ;YACX,OAAO,QAAQ,CAAA;QACjB,KAAK,OAAO,CAAC;QACb,KAAK,gBAAgB,CAAC;QACtB,KAAK,YAAY;YACf,OAAO,MAAM,CAAA;QACf,KAAK,MAAM;YACT,OAAO,MAAM,CAAA;QACf,KAAK,QAAQ,CAAC;QACd,KAAK,UAAU;YACb,OAAO,KAAK,CAAA;QACd;YACE,OAAO,OAAO,CAAA;IAClB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,GAAG,IAAI,GAAG,CAAgB,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAC7G,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,CAAA;AACnE,kFAAkF;AAClF,MAAM,MAAM,GAAG,CAAC,CAAS,EAAU,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,CAAA;AAUvF,MAAM,QAAQ,GAAG,4DAA4D,CAAA;AAC7E,4EAA4E;AAC5E,gFAAgF;AAChF,2EAA2E;AAC3E,gFAAgF;AAChF,iFAAiF;AACjF,4EAA4E;AAC5E,6EAA6E;AAC7E,sGAAsG;AACtG,4FAA4F;AAC5F,MAAM,cAAc,GAAG,MAAM,CAAC,GAAG,CAAA,4CAA4C,CAAA;AAC7E,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,oEAAoE,cAAc,GAAG,CAAC,CAAA;AACjI,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,qDAAqD,cAAc,GAAG,CAAC,CAAA;AAC7G,8GAA8G;AAC9G,qGAAqG;AACrG,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,2CAA2C,cAAc,GAAG,CAAC,CAAA;AAEzG,SAAS,SAAS,CAAC,IAAY;IAC7B,6EAA6E;IAC7E,MAAM,CAAC,GAAG,gCAAgC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACrD,IAAI,CAAC,CAAC;QAAE,OAAO,IAAI,CAAA;IACnB,MAAM,IAAI,GAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAEpC,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,EAAE,EAAE,CAAC;QACP,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAClH,CAAC;IACD,MAAM,EAAE,GAAG,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACnC,IAAI,EAAE;QAAE,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAC/B,MAAM,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC9B,IAAI,EAAE;QAAE,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAC1B,MAAM,EAAE,GAAG,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACpC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE;QAAE,IAAI,CAAC,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;IAChD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,QAAQ,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,kBAAkB,CAAC,CAAA;IACxE,MAAM,SAAS,GAAG,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAA;IAEnE,MAAM,GAAG,GAAc,EAAE,CAAA;IACzB,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAQ;QAC1B,gFAAgF;QAChF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,MAAK;QACzC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,IAAI;YAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IAC1B,CAAC;IAED,6EAA6E;IAC7E,gFAAgF;IAChF,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,KAAK,CAAA;IAClF,MAAM,KAAK,GAAG,WAAW,IAAI,GAAG,CAAC,MAAM,CAAmB,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACnE,IAAI,CAAC,CAAC,CAAC,KAAK;YAAE,OAAO,GAAG,CAAA;QACxB,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,MAAM,CAAA;QAC3C,OAAO,CAAC,GAAG,IAAI,IAAI,GAAG,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAA;IAC9D,CAAC,EAAE,SAAS,CAAC,CAAA;IACb,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC;QAAE,OAAO,EAAE,CAAA;IAE9D,MAAM,QAAQ,GAAgB,EAAE,CAAA;IAChC,KAAK,MAAM,IAAI,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,CAAC;YAAE,SAAQ;QAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAA;QAC9B,wEAAwE;QACxE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,SAAQ;QAEvE,2GAA2G;QAC3G,2GAA2G;QAC3G,kDAAkD;QAClD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QAC9D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;QAC/D,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,CAAA;QACjF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAA;QACnF,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE;YAAE,SAAQ;QAClC,MAAM,OAAO,GAAc;YACzB,IAAI;YACJ,KAAK;YACL,8GAA8G;YAC9G,KAAK,EAAE,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE;YACxG,OAAO,EAAE,IAAI,EAAE,mEAAmE;SACnF,CAAA;QACD,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;QACzD,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,WAAW,CAAA;QAC5D,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,IAAI,CAAA;QAC3B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACxB,CAAC;IACD,OAAO,QAAQ,CAAA;AACjB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tapflowio/ios-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "iOS simulator agent for tapflow — xcrun simctl control and screen streaming",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tapflow",
|
|
@@ -56,16 +56,16 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"ws": "^8.22.0",
|
|
59
|
-
"@tapflowio/agent-core": "0.
|
|
60
|
-
"@tapflowio/protocol": "0.
|
|
61
|
-
"@tapflowio/audiotap-helper": "0.3.
|
|
59
|
+
"@tapflowio/agent-core": "0.29.0",
|
|
60
|
+
"@tapflowio/protocol": "0.29.0",
|
|
61
|
+
"@tapflowio/audiotap-helper": "0.3.14"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@types/node": "^22.20.5",
|
|
65
65
|
"@types/ws": "^8.18.2",
|
|
66
66
|
"typescript": "^5.0.0",
|
|
67
67
|
"vitest": "^4.1.12",
|
|
68
|
-
"@tapflowio/relay": "0.
|
|
68
|
+
"@tapflowio/relay": "0.29.0",
|
|
69
69
|
"@tapflowio/test-utils": "0.0.0"
|
|
70
70
|
},
|
|
71
71
|
"scripts": {
|