react-native-mcp-kit 4.0.0 → 4.1.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 +3 -3
- package/dist/babel/testIdPlugin.d.ts.map +1 -1
- package/dist/babel/testIdPlugin.js +22 -13
- package/dist/babel/testIdPlugin.js.map +1 -1
- package/dist/bin/ios-hid +0 -0
- package/dist/client/core/McpClient.d.ts.map +1 -1
- package/dist/client/core/McpClient.js +16 -2
- package/dist/client/core/McpClient.js.map +1 -1
- package/dist/server/bridge.d.ts +1 -0
- package/dist/server/bridge.d.ts.map +1 -1
- package/dist/server/bridge.js +1 -0
- package/dist/server/bridge.js.map +1 -1
- package/dist/server/host/coredevice/dtx.d.ts +79 -0
- package/dist/server/host/coredevice/dtx.d.ts.map +1 -0
- package/dist/server/host/coredevice/dtx.js +453 -0
- package/dist/server/host/coredevice/dtx.js.map +1 -0
- package/dist/server/host/coredevice/nska.d.ts +6 -0
- package/dist/server/host/coredevice/nska.d.ts.map +1 -0
- package/dist/server/host/coredevice/nska.js +277 -0
- package/dist/server/host/coredevice/nska.js.map +1 -0
- package/dist/server/host/coredevice/rsd.d.ts +20 -0
- package/dist/server/host/coredevice/rsd.d.ts.map +1 -0
- package/dist/server/host/coredevice/rsd.js +244 -0
- package/dist/server/host/coredevice/rsd.js.map +1 -0
- package/dist/server/host/coredevice/screenshot.d.ts +11 -0
- package/dist/server/host/coredevice/screenshot.d.ts.map +1 -0
- package/dist/server/host/coredevice/screenshot.js +84 -0
- package/dist/server/host/coredevice/screenshot.js.map +1 -0
- package/dist/server/host/coredevice/tunnel.d.ts +29 -0
- package/dist/server/host/coredevice/tunnel.d.ts.map +1 -0
- package/dist/server/host/coredevice/tunnel.js +222 -0
- package/dist/server/host/coredevice/tunnel.js.map +1 -0
- package/dist/server/host/coredevice/xpc.d.ts +21 -0
- package/dist/server/host/coredevice/xpc.d.ts.map +1 -0
- package/dist/server/host/coredevice/xpc.js +318 -0
- package/dist/server/host/coredevice/xpc.js.map +1 -0
- package/dist/server/host/deviceResolver.d.ts +8 -0
- package/dist/server/host/deviceResolver.d.ts.map +1 -1
- package/dist/server/host/deviceResolver.js +128 -62
- package/dist/server/host/deviceResolver.js.map +1 -1
- package/dist/server/host/tools/capture.d.ts.map +1 -1
- package/dist/server/host/tools/capture.js +26 -0
- package/dist/server/host/tools/capture.js.map +1 -1
- package/dist/server/mcpServer.d.ts.map +1 -1
- package/dist/server/mcpServer.js +1 -0
- package/dist/server/mcpServer.js.map +1 -1
- package/dist/shared/protocol.d.ts +2 -1
- package/dist/shared/protocol.d.ts.map +1 -1
- package/dist/shared/protocol.js +1 -1
- package/package.json +3 -1
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// NSKeyedArchiver encoder/decoder for the shapes DTX messages exchange
|
|
3
|
+
// with `com.apple.instruments.dtservicehub` services.
|
|
4
|
+
//
|
|
5
|
+
// NSKeyedArchiver wraps a value graph in a bplist00 with this shape:
|
|
6
|
+
//
|
|
7
|
+
// {
|
|
8
|
+
// "$archiver": "NSKeyedArchiver",
|
|
9
|
+
// "$version": 100000,
|
|
10
|
+
// "$top": { "root": UID(N) },
|
|
11
|
+
// "$objects": ["$null", <object 1>, <object 2>, ...]
|
|
12
|
+
// }
|
|
13
|
+
//
|
|
14
|
+
// Each complex object lives in `$objects` and references its class
|
|
15
|
+
// metadata (also an entry in `$objects`) via a `$class: UID(M)` field.
|
|
16
|
+
// Cross-references between objects are encoded as bplist UID values.
|
|
17
|
+
//
|
|
18
|
+
// Supported shapes: NSString, NSNumber, NSArray, NSDictionary, NSData
|
|
19
|
+
// (encode + decode), NSError + NSDate (decode only). The semantic graph
|
|
20
|
+
// is round-trip-equivalent with Apple's encoder; we don't dedupe leaf
|
|
21
|
+
// strings the way Apple does.
|
|
22
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
23
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
24
|
+
};
|
|
25
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
+
exports.decodeNska = exports.encodeNska = void 0;
|
|
27
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
28
|
+
const bplist_creator_1 = __importDefault(require("bplist-creator"));
|
|
29
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
30
|
+
const bplist_parser_1 = __importDefault(require("bplist-parser"));
|
|
31
|
+
const ARCHIVER_NAME = 'NSKeyedArchiver';
|
|
32
|
+
const ARCHIVER_VERSION = 100000;
|
|
33
|
+
const NULL_PLACEHOLDER = '$null';
|
|
34
|
+
const makeUid = (index) => {
|
|
35
|
+
return { UID: index };
|
|
36
|
+
};
|
|
37
|
+
const CLASS_NSARRAY = {
|
|
38
|
+
classes: ['NSArray', 'NSObject'],
|
|
39
|
+
classname: 'NSArray',
|
|
40
|
+
};
|
|
41
|
+
const CLASS_NSDICTIONARY = {
|
|
42
|
+
classes: ['NSDictionary', 'NSObject'],
|
|
43
|
+
classname: 'NSDictionary',
|
|
44
|
+
};
|
|
45
|
+
const CLASS_NSMUTABLEDATA = {
|
|
46
|
+
classes: ['NSMutableData', 'NSData', 'NSObject'],
|
|
47
|
+
classname: 'NSMutableData',
|
|
48
|
+
};
|
|
49
|
+
class ObjectsBuilder {
|
|
50
|
+
objects = [NULL_PLACEHOLDER];
|
|
51
|
+
classCache = new Map();
|
|
52
|
+
add(obj) {
|
|
53
|
+
const idx = this.objects.length;
|
|
54
|
+
this.objects.push(obj);
|
|
55
|
+
return idx;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Reserve a slot and return its index plus a `commit` that fills it in.
|
|
59
|
+
* Useful when the object's content depends on UIDs of objects we're
|
|
60
|
+
* about to emit (e.g. an array's NS.objects entries).
|
|
61
|
+
*/
|
|
62
|
+
reserve() {
|
|
63
|
+
const index = this.objects.length;
|
|
64
|
+
this.objects.push(NULL_PLACEHOLDER);
|
|
65
|
+
return {
|
|
66
|
+
commit: (obj) => {
|
|
67
|
+
this.objects[index] = obj;
|
|
68
|
+
},
|
|
69
|
+
index,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
classUid(descriptor) {
|
|
73
|
+
const cached = this.classCache.get(descriptor.classname);
|
|
74
|
+
if (cached !== undefined)
|
|
75
|
+
return cached;
|
|
76
|
+
const idx = this.add({
|
|
77
|
+
$classes: descriptor.classes,
|
|
78
|
+
$classname: descriptor.classname,
|
|
79
|
+
});
|
|
80
|
+
this.classCache.set(descriptor.classname, idx);
|
|
81
|
+
return idx;
|
|
82
|
+
}
|
|
83
|
+
finalize() {
|
|
84
|
+
return this.objects;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
const encodeValue = (value, builder) => {
|
|
88
|
+
if (value === null) {
|
|
89
|
+
return 0; // $null
|
|
90
|
+
}
|
|
91
|
+
if (typeof value === 'string') {
|
|
92
|
+
return builder.add(value);
|
|
93
|
+
}
|
|
94
|
+
if (typeof value === 'bigint') {
|
|
95
|
+
// bplist-creator stringifies bigints; downcast to JS number when
|
|
96
|
+
// it's safe (channel codes and message ids fit comfortably).
|
|
97
|
+
if (value > BigInt(Number.MAX_SAFE_INTEGER) || value < BigInt(Number.MIN_SAFE_INTEGER)) {
|
|
98
|
+
throw new Error(`bigint ${value} exceeds safe integer range for NSKA encode`);
|
|
99
|
+
}
|
|
100
|
+
return builder.add(Number(value));
|
|
101
|
+
}
|
|
102
|
+
if (typeof value === 'number') {
|
|
103
|
+
return builder.add(value);
|
|
104
|
+
}
|
|
105
|
+
if (typeof value === 'boolean') {
|
|
106
|
+
return builder.add(value);
|
|
107
|
+
}
|
|
108
|
+
if (Buffer.isBuffer(value)) {
|
|
109
|
+
const classUid = builder.classUid(CLASS_NSMUTABLEDATA);
|
|
110
|
+
return builder.add({
|
|
111
|
+
$class: makeUid(classUid),
|
|
112
|
+
'NS.data': value,
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
if (Array.isArray(value)) {
|
|
116
|
+
const slot = builder.reserve();
|
|
117
|
+
const classUid = builder.classUid(CLASS_NSARRAY);
|
|
118
|
+
const elementUids = value.map((v) => {
|
|
119
|
+
return makeUid(encodeValue(v, builder));
|
|
120
|
+
});
|
|
121
|
+
slot.commit({
|
|
122
|
+
$class: makeUid(classUid),
|
|
123
|
+
'NS.objects': elementUids,
|
|
124
|
+
});
|
|
125
|
+
return slot.index;
|
|
126
|
+
}
|
|
127
|
+
if (typeof value === 'object') {
|
|
128
|
+
const slot = builder.reserve();
|
|
129
|
+
const classUid = builder.classUid(CLASS_NSDICTIONARY);
|
|
130
|
+
const entries = Object.entries(value);
|
|
131
|
+
const keyUids = entries.map(([k]) => {
|
|
132
|
+
return makeUid(encodeValue(k, builder));
|
|
133
|
+
});
|
|
134
|
+
const valueUids = entries.map(([, v]) => {
|
|
135
|
+
return makeUid(encodeValue(v, builder));
|
|
136
|
+
});
|
|
137
|
+
slot.commit({
|
|
138
|
+
$class: makeUid(classUid),
|
|
139
|
+
'NS.keys': keyUids,
|
|
140
|
+
'NS.objects': valueUids,
|
|
141
|
+
});
|
|
142
|
+
return slot.index;
|
|
143
|
+
}
|
|
144
|
+
throw new Error(`Cannot NSKeyedArchive value of type ${typeof value}`);
|
|
145
|
+
};
|
|
146
|
+
const encodeNska = (value) => {
|
|
147
|
+
const builder = new ObjectsBuilder();
|
|
148
|
+
const rootIdx = encodeValue(value, builder);
|
|
149
|
+
const archive = {
|
|
150
|
+
$archiver: ARCHIVER_NAME,
|
|
151
|
+
$objects: builder.finalize(),
|
|
152
|
+
$top: { root: makeUid(rootIdx) },
|
|
153
|
+
$version: ARCHIVER_VERSION,
|
|
154
|
+
};
|
|
155
|
+
return (0, bplist_creator_1.default)(archive);
|
|
156
|
+
};
|
|
157
|
+
exports.encodeNska = encodeNska;
|
|
158
|
+
const isUid = (value) => {
|
|
159
|
+
return (typeof value === 'object' &&
|
|
160
|
+
value !== null &&
|
|
161
|
+
!Array.isArray(value) &&
|
|
162
|
+
!Buffer.isBuffer(value) &&
|
|
163
|
+
typeof value.UID === 'number');
|
|
164
|
+
};
|
|
165
|
+
const isObjectWithClass = (value) => {
|
|
166
|
+
return (typeof value === 'object' && value !== null && !Array.isArray(value) && !Buffer.isBuffer(value));
|
|
167
|
+
};
|
|
168
|
+
const classnameOf = (objects, obj) => {
|
|
169
|
+
if (!obj.$class)
|
|
170
|
+
return null;
|
|
171
|
+
const classObj = objects[obj.$class.UID];
|
|
172
|
+
if (!isObjectWithClass(classObj))
|
|
173
|
+
return null;
|
|
174
|
+
const name = classObj.$classname;
|
|
175
|
+
return typeof name === 'string' ? name : null;
|
|
176
|
+
};
|
|
177
|
+
// One-time logger for NSKeyedArchive classes we don't have a dedicated
|
|
178
|
+
// unwrap for. Helps surface gaps in the codec without spamming on every
|
|
179
|
+
// reply during a long-running session.
|
|
180
|
+
const warnedUnknownClasses = new Set();
|
|
181
|
+
const warnUnknownClassOnce = (name) => {
|
|
182
|
+
if (warnedUnknownClasses.has(name))
|
|
183
|
+
return;
|
|
184
|
+
warnedUnknownClasses.add(name);
|
|
185
|
+
// eslint-disable-next-line no-console
|
|
186
|
+
console.warn(`[coredevice/nska] Unknown NSKA class "${name}" — falling back to raw dictionary shape. ` +
|
|
187
|
+
`Add a handler in resolveValue if this should decode to a specific structure.`);
|
|
188
|
+
};
|
|
189
|
+
const resolveValue = (objects, value) => {
|
|
190
|
+
if (value === null || value === undefined)
|
|
191
|
+
return null;
|
|
192
|
+
if (typeof value === 'string') {
|
|
193
|
+
return value === NULL_PLACEHOLDER ? null : value;
|
|
194
|
+
}
|
|
195
|
+
if (typeof value === 'number')
|
|
196
|
+
return value;
|
|
197
|
+
if (typeof value === 'bigint')
|
|
198
|
+
return value;
|
|
199
|
+
if (typeof value === 'boolean')
|
|
200
|
+
return value;
|
|
201
|
+
if (Buffer.isBuffer(value))
|
|
202
|
+
return value;
|
|
203
|
+
if (isUid(value)) {
|
|
204
|
+
return resolveValue(objects, objects[value.UID]);
|
|
205
|
+
}
|
|
206
|
+
if (Array.isArray(value)) {
|
|
207
|
+
return value.map((v) => {
|
|
208
|
+
return resolveValue(objects, v);
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
if (isObjectWithClass(value)) {
|
|
212
|
+
const name = classnameOf(objects, value);
|
|
213
|
+
if (name === 'NSArray' || name === 'NSMutableArray') {
|
|
214
|
+
const items = Array.isArray(value['NS.objects']) ? value['NS.objects'] : [];
|
|
215
|
+
return items.map((item) => {
|
|
216
|
+
return resolveValue(objects, item);
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
if (name === 'NSDictionary' || name === 'NSMutableDictionary') {
|
|
220
|
+
const keys = Array.isArray(value['NS.keys']) ? value['NS.keys'] : [];
|
|
221
|
+
const vals = Array.isArray(value['NS.objects']) ? value['NS.objects'] : [];
|
|
222
|
+
const out = {};
|
|
223
|
+
for (let i = 0; i < keys.length; i++) {
|
|
224
|
+
const key = resolveValue(objects, keys[i]);
|
|
225
|
+
if (typeof key !== 'string')
|
|
226
|
+
continue;
|
|
227
|
+
out[key] = resolveValue(objects, vals[i]);
|
|
228
|
+
}
|
|
229
|
+
return out;
|
|
230
|
+
}
|
|
231
|
+
if (name === 'NSData' || name === 'NSMutableData') {
|
|
232
|
+
const data = value['NS.data'];
|
|
233
|
+
if (Buffer.isBuffer(data))
|
|
234
|
+
return data;
|
|
235
|
+
if (typeof data === 'string')
|
|
236
|
+
return Buffer.from(data, 'binary');
|
|
237
|
+
return Buffer.alloc(0);
|
|
238
|
+
}
|
|
239
|
+
if (name === 'NSDate') {
|
|
240
|
+
const t = value['NS.time'];
|
|
241
|
+
return typeof t === 'number' ? t : null;
|
|
242
|
+
}
|
|
243
|
+
if (name === 'NSError') {
|
|
244
|
+
const out = {};
|
|
245
|
+
out.domain = resolveValue(objects, value.NSDomain);
|
|
246
|
+
out.code = resolveValue(objects, value.NSCode);
|
|
247
|
+
out.userInfo = resolveValue(objects, value.NSUserInfo);
|
|
248
|
+
return out;
|
|
249
|
+
}
|
|
250
|
+
if (name === 'NSNumber') {
|
|
251
|
+
const n = value['NS.intval'] ?? value['NS.dblval'] ?? value['NS.bval'];
|
|
252
|
+
if (typeof n === 'number' || typeof n === 'bigint' || typeof n === 'boolean')
|
|
253
|
+
return n;
|
|
254
|
+
return null;
|
|
255
|
+
}
|
|
256
|
+
// Unknown class — log once, return the raw shape as a dictionary, sans $class.
|
|
257
|
+
if (name)
|
|
258
|
+
warnUnknownClassOnce(name);
|
|
259
|
+
const out = {};
|
|
260
|
+
for (const [k, v] of Object.entries(value)) {
|
|
261
|
+
if (k === '$class')
|
|
262
|
+
continue;
|
|
263
|
+
out[k] = resolveValue(objects, v);
|
|
264
|
+
}
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
return null;
|
|
268
|
+
};
|
|
269
|
+
const decodeNska = (buf) => {
|
|
270
|
+
const [parsed] = bplist_parser_1.default.parseBuffer(buf);
|
|
271
|
+
if (!parsed || !parsed.$top || !parsed.$objects) {
|
|
272
|
+
throw new Error('Invalid NSKeyedArchive: missing $top or $objects');
|
|
273
|
+
}
|
|
274
|
+
return resolveValue(parsed.$objects, parsed.$top.root);
|
|
275
|
+
};
|
|
276
|
+
exports.decodeNska = decodeNska;
|
|
277
|
+
//# sourceMappingURL=nska.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nska.js","sourceRoot":"","sources":["../../../../src/server/host/coredevice/nska.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type XpcValue } from './xpc';
|
|
2
|
+
interface RsdServiceEntry {
|
|
3
|
+
/** Port the service listens on inside the tunnel. RSD encodes this as a string; we parse to number. */
|
|
4
|
+
port: number;
|
|
5
|
+
/** Per-service metadata: `UsesRemoteXPC`, `EnableServiceSSL`, `Entitlement`, … */
|
|
6
|
+
properties: Record<string, XpcValue>;
|
|
7
|
+
}
|
|
8
|
+
export interface PeerInfo {
|
|
9
|
+
/** Device-level properties (OS version, build, ECID, …). */
|
|
10
|
+
properties: Record<string, XpcValue>;
|
|
11
|
+
/** Service name → entry. */
|
|
12
|
+
services: Record<string, RsdServiceEntry>;
|
|
13
|
+
}
|
|
14
|
+
interface FetchPeerInfoOptions {
|
|
15
|
+
/** Connect timeout. Default 10s. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
}
|
|
18
|
+
export declare const fetchPeerInfo: (deviceAddress: string, hostAddress: string, rsdPort: number, options?: FetchPeerInfoOptions) => Promise<PeerInfo>;
|
|
19
|
+
export {};
|
|
20
|
+
//# sourceMappingURL=rsd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsd.d.ts","sourceRoot":"","sources":["../../../../src/server/host/coredevice/rsd.ts"],"names":[],"mappings":"AAEA,OAAO,EAAY,KAAK,QAAQ,EAAoC,MAAM,OAAO,CAAC;AAgHlF,UAAU,eAAe;IACvB,uGAAuG;IACvG,IAAI,EAAE,MAAM,CAAC;IACb,kFAAkF;IAClF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,QAAQ;IACvB,4DAA4D;IAC5D,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrC,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3C;AAoED,UAAU,oBAAoB;IAC5B,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAKD,eAAO,MAAM,aAAa,kBACT,MAAM,eACR,MAAM,WACV,MAAM,YACN,oBAAoB,KAC5B,OAAO,CAAC,QAAQ,CAgGlB,CAAC"}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fetchPeerInfo = void 0;
|
|
4
|
+
const node_net_1 = require("node:net");
|
|
5
|
+
const xpc_1 = require("./xpc");
|
|
6
|
+
// HTTP/2-framed client for Apple's RemoteServiceDiscoveryProxy.
|
|
7
|
+
//
|
|
8
|
+
// RSD uses HTTP/2 framing but not HTTP/2 semantics — HEADERS frames are
|
|
9
|
+
// empty (`END_HEADERS` flag, no header block), DATA frames carry
|
|
10
|
+
// XpcWrapper payloads. Node's built-in `http2` enforces HTTP semantics
|
|
11
|
+
// so we frame the bytes ourselves.
|
|
12
|
+
//
|
|
13
|
+
// We're inside the encrypted CoreDevice tunnel, so no TLS wrapper is
|
|
14
|
+
// needed. The catch: sockets MUST source-bind to the Mac end of the
|
|
15
|
+
// tunnel (`fd<...>::2`, from `ifconfig utun<N>`) or kernel routing on
|
|
16
|
+
// hosts with multiple tunnels (Tailscale, WireGuard, …) picks the wrong
|
|
17
|
+
// utun and the device resets the connection.
|
|
18
|
+
const HTTP2_PREFACE = Buffer.from('PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n');
|
|
19
|
+
const FRAME_TYPE = {
|
|
20
|
+
DATA: 0x00,
|
|
21
|
+
GOAWAY: 0x07,
|
|
22
|
+
HEADERS: 0x01,
|
|
23
|
+
SETTINGS: 0x04,
|
|
24
|
+
WINDOW_UPDATE: 0x08,
|
|
25
|
+
};
|
|
26
|
+
// HTTP/2 SETTINGS identifiers (RFC 7540 §6.5.2). We only set these two —
|
|
27
|
+
// the rest are at peer default.
|
|
28
|
+
const SETTINGS = {
|
|
29
|
+
INITIAL_WINDOW_SIZE: 4,
|
|
30
|
+
MAX_CONCURRENT_STREAMS: 3,
|
|
31
|
+
};
|
|
32
|
+
// Stream IDs used during the RSD handshake. Apple expects these specific
|
|
33
|
+
// numbers: stream 1 carries the peer's `peer_info` reply, stream 3 carries
|
|
34
|
+
// our INIT_HANDSHAKE marker. Hardcoded to mirror what `remotepairingd` does
|
|
35
|
+
// on the device side.
|
|
36
|
+
const ROOT_CHANNEL_STREAM = 1;
|
|
37
|
+
const REPLY_CHANNEL_STREAM = 3;
|
|
38
|
+
// HTTP/2 flow-control window values. `1 048 576` (1 MiB) is the per-stream
|
|
39
|
+
// receive window — large enough that the device doesn't pause for credit
|
|
40
|
+
// during the burst of XPC frames that follows. `983 041` (= 0xF0001 =
|
|
41
|
+
// 1 MiB − 65 535) is the connection-level WINDOW_UPDATE the connection
|
|
42
|
+
// preface needs to bring the default 65 535-byte window up to 1 MiB; both
|
|
43
|
+
// values match what Apple's client sends.
|
|
44
|
+
const STREAM_INITIAL_WINDOW = 1_048_576;
|
|
45
|
+
const CONNECTION_WINDOW_INCREMENT = 983_041;
|
|
46
|
+
const buildH2Frame = (type, flags, streamId, payload) => {
|
|
47
|
+
const header = Buffer.alloc(9);
|
|
48
|
+
const length = payload.length;
|
|
49
|
+
header[0] = (length >>> 16) & 0xff;
|
|
50
|
+
header[1] = (length >>> 8) & 0xff;
|
|
51
|
+
header[2] = length & 0xff;
|
|
52
|
+
header[3] = type;
|
|
53
|
+
header[4] = flags;
|
|
54
|
+
header.writeUInt32BE(streamId, 5);
|
|
55
|
+
return payload.length === 0 ? header : Buffer.concat([header, payload]);
|
|
56
|
+
};
|
|
57
|
+
const buildSettingsFrame = () => {
|
|
58
|
+
const payload = Buffer.alloc(12);
|
|
59
|
+
payload.writeUInt16BE(SETTINGS.MAX_CONCURRENT_STREAMS, 0);
|
|
60
|
+
payload.writeUInt32BE(100, 2);
|
|
61
|
+
payload.writeUInt16BE(SETTINGS.INITIAL_WINDOW_SIZE, 6);
|
|
62
|
+
payload.writeUInt32BE(STREAM_INITIAL_WINDOW, 8);
|
|
63
|
+
return buildH2Frame(FRAME_TYPE.SETTINGS, 0x00, 0, payload);
|
|
64
|
+
};
|
|
65
|
+
const buildWindowUpdateFrame = (streamId, increment) => {
|
|
66
|
+
const payload = Buffer.alloc(4);
|
|
67
|
+
payload.writeUInt32BE(increment, 0);
|
|
68
|
+
return buildH2Frame(FRAME_TYPE.WINDOW_UPDATE, 0x00, streamId, payload);
|
|
69
|
+
};
|
|
70
|
+
const buildEmptyHeadersFrame = (streamId) => {
|
|
71
|
+
return buildH2Frame(FRAME_TYPE.HEADERS, 0x04 /* END_HEADERS */, streamId, Buffer.alloc(0));
|
|
72
|
+
};
|
|
73
|
+
const buildDataFrame = (streamId, payload) => {
|
|
74
|
+
return buildH2Frame(FRAME_TYPE.DATA, 0x00, streamId, payload);
|
|
75
|
+
};
|
|
76
|
+
class H2FrameReader {
|
|
77
|
+
buffer = Buffer.alloc(0);
|
|
78
|
+
push(chunk) {
|
|
79
|
+
this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
|
|
80
|
+
}
|
|
81
|
+
pop() {
|
|
82
|
+
if (this.buffer.length < 9)
|
|
83
|
+
return null;
|
|
84
|
+
const length = (this.buffer[0] << 16) | (this.buffer[1] << 8) | this.buffer[2];
|
|
85
|
+
if (this.buffer.length < 9 + length)
|
|
86
|
+
return null;
|
|
87
|
+
const frame = {
|
|
88
|
+
flags: this.buffer[4],
|
|
89
|
+
payload: this.buffer.subarray(9, 9 + length),
|
|
90
|
+
streamId: this.buffer.readUInt32BE(5) & 0x7fffffff,
|
|
91
|
+
type: this.buffer[3],
|
|
92
|
+
};
|
|
93
|
+
this.buffer = this.buffer.subarray(9 + length);
|
|
94
|
+
return frame;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
class RsdHandshakeError extends Error {
|
|
98
|
+
constructor(message) {
|
|
99
|
+
super(message);
|
|
100
|
+
this.name = 'RsdHandshakeError';
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Incremental XpcWrapper parser — tracks how far we've consumed so we don't
|
|
104
|
+
// re-walk the prefix on every socket chunk. The peer_info reply can span
|
|
105
|
+
// many DATA frames; without this we'd be O(N²) in total stream-1 bytes.
|
|
106
|
+
class PeerInfoParser {
|
|
107
|
+
buffer = Buffer.alloc(0);
|
|
108
|
+
offset = 0;
|
|
109
|
+
push(chunk) {
|
|
110
|
+
this.buffer = this.buffer.length === 0 ? chunk : Buffer.concat([this.buffer, chunk]);
|
|
111
|
+
while (this.offset + 16 <= this.buffer.length) {
|
|
112
|
+
let parsed;
|
|
113
|
+
try {
|
|
114
|
+
parsed = (0, xpc_1.parseXpcWrapper)(this.buffer, this.offset);
|
|
115
|
+
}
|
|
116
|
+
catch {
|
|
117
|
+
// Wrapper mid-stream; wait for more bytes.
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
if (parsed.totalSize <= 0 || this.offset + parsed.totalSize > this.buffer.length) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
this.offset += parsed.totalSize;
|
|
124
|
+
const payload = parsed.payload;
|
|
125
|
+
if (payload !== null &&
|
|
126
|
+
typeof payload === 'object' &&
|
|
127
|
+
!Array.isArray(payload) &&
|
|
128
|
+
!Buffer.isBuffer(payload) &&
|
|
129
|
+
'Services' in payload) {
|
|
130
|
+
return payload;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return null;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
const asRecord = (value) => {
|
|
137
|
+
return value && typeof value === 'object' && !Array.isArray(value) && !Buffer.isBuffer(value)
|
|
138
|
+
? value
|
|
139
|
+
: {};
|
|
140
|
+
};
|
|
141
|
+
const normalisePeerInfo = (dict) => {
|
|
142
|
+
const services = {};
|
|
143
|
+
for (const [name, raw] of Object.entries(asRecord(dict.Services))) {
|
|
144
|
+
const entry = asRecord(raw);
|
|
145
|
+
const portRaw = entry.Port;
|
|
146
|
+
const port = typeof portRaw === 'string'
|
|
147
|
+
? Number(portRaw)
|
|
148
|
+
: typeof portRaw === 'bigint'
|
|
149
|
+
? Number(portRaw)
|
|
150
|
+
: NaN;
|
|
151
|
+
if (!Number.isFinite(port))
|
|
152
|
+
continue;
|
|
153
|
+
services[name] = { port, properties: asRecord(entry.Properties) };
|
|
154
|
+
}
|
|
155
|
+
return { properties: asRecord(dict.Properties), services };
|
|
156
|
+
};
|
|
157
|
+
// Open a TCP connection to the RSD port, run the HTTP/2 + RemoteXPC
|
|
158
|
+
// handshake, parse the `peer_info` dict the device sends back on stream
|
|
159
|
+
// 1, close.
|
|
160
|
+
const fetchPeerInfo = async (deviceAddress, hostAddress, rsdPort, options = {}) => {
|
|
161
|
+
const timeoutMs = options.timeoutMs ?? 10_000;
|
|
162
|
+
const deadline = Date.now() + timeoutMs;
|
|
163
|
+
return new Promise((resolve, reject) => {
|
|
164
|
+
let socket;
|
|
165
|
+
try {
|
|
166
|
+
// Don't pass `family: 6` here — the IPv6 literal in `host` is
|
|
167
|
+
// sufficient, and specifying it explicitly causes the device to
|
|
168
|
+
// send SETTINGS once and then RST the connection.
|
|
169
|
+
socket = (0, node_net_1.createConnection)({ host: deviceAddress, localAddress: hostAddress, port: rsdPort });
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
reject(err);
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const peerParser = new PeerInfoParser();
|
|
176
|
+
const reader = new H2FrameReader();
|
|
177
|
+
let settled = false;
|
|
178
|
+
const cleanup = (err, value) => {
|
|
179
|
+
if (settled)
|
|
180
|
+
return;
|
|
181
|
+
settled = true;
|
|
182
|
+
try {
|
|
183
|
+
socket.destroy();
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// best-effort
|
|
187
|
+
}
|
|
188
|
+
if (err)
|
|
189
|
+
reject(err);
|
|
190
|
+
else if (value)
|
|
191
|
+
resolve(value);
|
|
192
|
+
};
|
|
193
|
+
const timer = setTimeout(() => {
|
|
194
|
+
cleanup(new RsdHandshakeError(`RSD handshake timed out after ${timeoutMs}ms`));
|
|
195
|
+
}, Math.max(0, deadline - Date.now()));
|
|
196
|
+
socket.on('connect', () => {
|
|
197
|
+
// Apple's RSD accepts the whole handshake batch in one write; an
|
|
198
|
+
// empty dict in the first DATA frame invites the peer to publish
|
|
199
|
+
// its Services list back to us. DATA_PRESENT is set only when the
|
|
200
|
+
// dict has keys; an empty dict ships with ALWAYS_SET alone.
|
|
201
|
+
socket.write(Buffer.concat([
|
|
202
|
+
HTTP2_PREFACE,
|
|
203
|
+
buildSettingsFrame(),
|
|
204
|
+
buildWindowUpdateFrame(0, CONNECTION_WINDOW_INCREMENT),
|
|
205
|
+
buildEmptyHeadersFrame(ROOT_CHANNEL_STREAM),
|
|
206
|
+
buildDataFrame(ROOT_CHANNEL_STREAM, (0, xpc_1.buildXpcWrapper)(xpc_1.XpcFlags.ALWAYS_SET, 0n, {})),
|
|
207
|
+
buildEmptyHeadersFrame(REPLY_CHANNEL_STREAM),
|
|
208
|
+
buildDataFrame(REPLY_CHANNEL_STREAM, (0, xpc_1.buildXpcWrapper)(xpc_1.XpcFlags.ALWAYS_SET | xpc_1.XpcFlags.INIT_HANDSHAKE, 0n, null)),
|
|
209
|
+
]));
|
|
210
|
+
});
|
|
211
|
+
socket.on('data', (chunk) => {
|
|
212
|
+
reader.push(chunk);
|
|
213
|
+
let frame;
|
|
214
|
+
while ((frame = reader.pop()) !== null) {
|
|
215
|
+
if (frame.type === FRAME_TYPE.DATA && frame.streamId === ROOT_CHANNEL_STREAM) {
|
|
216
|
+
const dict = peerParser.push(frame.payload);
|
|
217
|
+
if (dict) {
|
|
218
|
+
clearTimeout(timer);
|
|
219
|
+
cleanup(null, normalisePeerInfo(dict));
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (frame.type === FRAME_TYPE.GOAWAY) {
|
|
224
|
+
const lastStream = frame.payload.length >= 4 ? frame.payload.readUInt32BE(0) & 0x7fffffff : 0;
|
|
225
|
+
const errorCode = frame.payload.length >= 8 ? frame.payload.readUInt32BE(4) : 0;
|
|
226
|
+
cleanup(new RsdHandshakeError(`RSD sent GOAWAY (last_stream=${lastStream}, error=${errorCode})`));
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
});
|
|
231
|
+
socket.on('error', (err) => {
|
|
232
|
+
clearTimeout(timer);
|
|
233
|
+
cleanup(err);
|
|
234
|
+
});
|
|
235
|
+
socket.on('close', () => {
|
|
236
|
+
clearTimeout(timer);
|
|
237
|
+
if (!settled) {
|
|
238
|
+
cleanup(new RsdHandshakeError('RSD socket closed before peer_info received'));
|
|
239
|
+
}
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
};
|
|
243
|
+
exports.fetchPeerInfo = fetchPeerInfo;
|
|
244
|
+
//# sourceMappingURL=rsd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rsd.js","sourceRoot":"","sources":["../../../../src/server/host/coredevice/rsd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface CaptureScreenshotOptions {
|
|
2
|
+
/**
|
|
3
|
+
* Total wall-clock budget for the operation. Spent across three phases —
|
|
4
|
+
* tunnel startup, RSD peer-info fetch, DTX dispatch — each given the
|
|
5
|
+
* remaining budget at the time it runs. Default 30s.
|
|
6
|
+
*/
|
|
7
|
+
timeoutMs?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const captureScreenshot: (coreDeviceIdentifier: string, options?: CaptureScreenshotOptions) => Promise<Buffer>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=screenshot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../../src/server/host/coredevice/screenshot.ts"],"names":[],"mappings":"AAuCA,UAAU,wBAAwB;IAChC;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,iBAAiB,yBACN,MAAM,YACnB,wBAAwB,KAChC,OAAO,CAAC,MAAM,CA4EhB,CAAC"}
|