@stim-cli/server 1.10.0 → 1.11.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 +194 -31
- package/dist/{protocol-dn2_TUeH.mjs → protocol-CmlG7X7_.mjs} +272 -11
- package/dist/protocol.d.mts +190 -11
- package/dist/protocol.mjs +2 -2
- package/dist/protocol.schema.json +484 -5
- package/dist/stim-frames/EmulatorDiscovery.swift +49 -0
- package/dist/stim-frames/EmulatorInput.swift +141 -0
- package/dist/stim-frames/GrpcFraming.swift +85 -0
- package/dist/stim-frames/InputMessages.swift +73 -0
- package/dist/stim-frames/ScreenshotMessages.swift +129 -0
- package/dist/stim-frames/ScreenshotStream.swift +130 -0
- package/dist/stim-frames/SimulatorDisplay.swift +116 -0
- package/dist/stim-frames/SimulatorHID.swift +101 -0
- package/dist/stim-frames/VideoEncoder.swift +282 -0
- package/dist/stim-frames/main.swift +389 -0
- package/dist/stim-server.mjs +1394 -124
- package/package.json +4 -4
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
//#region src/protocol.ts
|
|
2
2
|
const PROTOCOL_VERSION = 1;
|
|
3
3
|
const PROTOCOL_SCHEMA_FILE = "protocol.schema.json";
|
|
4
|
-
|
|
4
|
+
/** `read` serves state. `control` also runs {@link ACTIONS}; only the Mac grants it. */
|
|
5
|
+
const CAPABILITIES = ["read", "control"];
|
|
5
6
|
const METHODS = [
|
|
6
7
|
"hello",
|
|
7
8
|
"status.subscribe",
|
|
@@ -10,7 +11,12 @@ const METHODS = [
|
|
|
10
11
|
"stats.get",
|
|
11
12
|
"settings.get",
|
|
12
13
|
"frames.subscribe",
|
|
13
|
-
"
|
|
14
|
+
"frames.keyframe",
|
|
15
|
+
"build.plan",
|
|
16
|
+
"machine.get",
|
|
17
|
+
"machine.history",
|
|
18
|
+
"unsubscribe",
|
|
19
|
+
"action"
|
|
14
20
|
];
|
|
15
21
|
/**
|
|
16
22
|
* `unauthorized`, `pairing-expired` and `protocol-unsupported` refuse the client until it pairs again or
|
|
@@ -31,13 +37,18 @@ const ERROR_CODES = [
|
|
|
31
37
|
"status-failed",
|
|
32
38
|
"logs-failed",
|
|
33
39
|
"stim-failed",
|
|
34
|
-
"frames-failed"
|
|
40
|
+
"frames-failed",
|
|
41
|
+
"forbidden",
|
|
42
|
+
"unknown-action",
|
|
43
|
+
"action-busy",
|
|
44
|
+
"action-failed"
|
|
35
45
|
];
|
|
36
46
|
const LOG_SOURCES = [
|
|
37
47
|
"metro",
|
|
38
48
|
"client",
|
|
39
49
|
"device",
|
|
40
|
-
"build"
|
|
50
|
+
"build",
|
|
51
|
+
"agent"
|
|
41
52
|
];
|
|
42
53
|
const LOG_LEVELS = [
|
|
43
54
|
"debug",
|
|
@@ -47,6 +58,22 @@ const LOG_LEVELS = [
|
|
|
47
58
|
"fatal"
|
|
48
59
|
];
|
|
49
60
|
const MAX_LOG_TAIL = 5e3;
|
|
61
|
+
const FRAME_FPS = {
|
|
62
|
+
default: 5,
|
|
63
|
+
max: 30,
|
|
64
|
+
video: 60
|
|
65
|
+
};
|
|
66
|
+
const FRAME_EDGE = {
|
|
67
|
+
min: 240,
|
|
68
|
+
default: 1280,
|
|
69
|
+
max: 2048
|
|
70
|
+
};
|
|
71
|
+
const VIDEO_CODECS = ["h264"];
|
|
72
|
+
const VIDEO_HEADER_VERSION = 1;
|
|
73
|
+
/** The keyframe bit of a {@link VideoPacket}'s flags. */
|
|
74
|
+
const VIDEO_KEYFRAME = 1;
|
|
75
|
+
/** Each action runs one fixed `stim` command in the workspace. */
|
|
76
|
+
const ACTIONS = ["reload", "stop"];
|
|
50
77
|
const requestId = { type: ["integer", "string"] };
|
|
51
78
|
const protocolError = {
|
|
52
79
|
type: "object",
|
|
@@ -140,6 +167,7 @@ function protocolJsonSchema() {
|
|
|
140
167
|
"protocol",
|
|
141
168
|
"server",
|
|
142
169
|
"capabilities",
|
|
170
|
+
"actions",
|
|
143
171
|
"device"
|
|
144
172
|
],
|
|
145
173
|
additionalProperties: false,
|
|
@@ -150,19 +178,25 @@ function protocolJsonSchema() {
|
|
|
150
178
|
required: [
|
|
151
179
|
"name",
|
|
152
180
|
"version",
|
|
153
|
-
"stim"
|
|
181
|
+
"stim",
|
|
182
|
+
"home"
|
|
154
183
|
],
|
|
155
184
|
additionalProperties: false,
|
|
156
185
|
properties: {
|
|
157
186
|
name: { type: "string" },
|
|
158
187
|
version: { type: "string" },
|
|
159
|
-
stim: { type: "string" }
|
|
188
|
+
stim: { type: "string" },
|
|
189
|
+
home: { type: "string" }
|
|
160
190
|
}
|
|
161
191
|
},
|
|
162
192
|
capabilities: {
|
|
163
193
|
type: "array",
|
|
164
194
|
items: { enum: [...CAPABILITIES] }
|
|
165
195
|
},
|
|
196
|
+
actions: {
|
|
197
|
+
type: "array",
|
|
198
|
+
items: { enum: [...ACTIONS] }
|
|
199
|
+
},
|
|
166
200
|
device: {
|
|
167
201
|
type: "object",
|
|
168
202
|
required: ["id", "name"],
|
|
@@ -231,6 +265,81 @@ function protocolJsonSchema() {
|
|
|
231
265
|
type: "string",
|
|
232
266
|
minLength: 1,
|
|
233
267
|
default: "default"
|
|
268
|
+
},
|
|
269
|
+
fps: {
|
|
270
|
+
type: "integer",
|
|
271
|
+
minimum: 1,
|
|
272
|
+
maximum: FRAME_FPS.video,
|
|
273
|
+
default: FRAME_FPS.default,
|
|
274
|
+
description: `At most ${FRAME_FPS.max} unless the result offers video.`
|
|
275
|
+
},
|
|
276
|
+
maxEdge: {
|
|
277
|
+
type: "integer",
|
|
278
|
+
minimum: FRAME_EDGE.min,
|
|
279
|
+
maximum: FRAME_EDGE.max,
|
|
280
|
+
default: FRAME_EDGE.default
|
|
281
|
+
},
|
|
282
|
+
video: {
|
|
283
|
+
type: "array",
|
|
284
|
+
items: { enum: [...VIDEO_CODECS] }
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
ActionParams: { oneOf: [{
|
|
289
|
+
type: "object",
|
|
290
|
+
required: ["action", "workspace"],
|
|
291
|
+
additionalProperties: false,
|
|
292
|
+
properties: {
|
|
293
|
+
action: { const: "reload" },
|
|
294
|
+
workspace: {
|
|
295
|
+
type: "string",
|
|
296
|
+
description: "An environment path from a status payload."
|
|
297
|
+
},
|
|
298
|
+
platform: { enum: ["ios", "android"] }
|
|
299
|
+
}
|
|
300
|
+
}, {
|
|
301
|
+
type: "object",
|
|
302
|
+
required: ["action", "workspace"],
|
|
303
|
+
additionalProperties: false,
|
|
304
|
+
properties: {
|
|
305
|
+
action: { const: "stop" },
|
|
306
|
+
workspace: {
|
|
307
|
+
type: "string",
|
|
308
|
+
description: "An environment path from a status payload."
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}] },
|
|
312
|
+
ActionResult: {
|
|
313
|
+
type: "object",
|
|
314
|
+
required: [
|
|
315
|
+
"action",
|
|
316
|
+
"workspace",
|
|
317
|
+
"output"
|
|
318
|
+
],
|
|
319
|
+
additionalProperties: false,
|
|
320
|
+
properties: {
|
|
321
|
+
action: { enum: [...ACTIONS] },
|
|
322
|
+
workspace: { type: "string" },
|
|
323
|
+
output: {
|
|
324
|
+
type: "object",
|
|
325
|
+
description: "The JSON the command printed."
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
},
|
|
329
|
+
BuildPlanParams: {
|
|
330
|
+
type: "object",
|
|
331
|
+
required: ["workspace", "platform"],
|
|
332
|
+
additionalProperties: false,
|
|
333
|
+
properties: {
|
|
334
|
+
workspace: {
|
|
335
|
+
type: "string",
|
|
336
|
+
description: "An environment path from a status payload."
|
|
337
|
+
},
|
|
338
|
+
platform: { enum: ["ios", "android"] },
|
|
339
|
+
slot: {
|
|
340
|
+
type: "string",
|
|
341
|
+
pattern: "^[A-Za-z0-9][A-Za-z0-9_-]{0,63}$",
|
|
342
|
+
default: "default"
|
|
234
343
|
}
|
|
235
344
|
}
|
|
236
345
|
},
|
|
@@ -242,12 +351,142 @@ function protocolJsonSchema() {
|
|
|
242
351
|
description: "An environment path from a status payload."
|
|
243
352
|
} }
|
|
244
353
|
},
|
|
354
|
+
MachineHistory: {
|
|
355
|
+
type: "object",
|
|
356
|
+
required: ["intervalMs", "samples"],
|
|
357
|
+
additionalProperties: false,
|
|
358
|
+
properties: {
|
|
359
|
+
intervalMs: { type: "integer" },
|
|
360
|
+
samples: {
|
|
361
|
+
type: "array",
|
|
362
|
+
items: {
|
|
363
|
+
type: "object",
|
|
364
|
+
required: [
|
|
365
|
+
"at",
|
|
366
|
+
"cpu",
|
|
367
|
+
"memoryUsedBytes",
|
|
368
|
+
"memoryPressure",
|
|
369
|
+
"diskFreeBytes"
|
|
370
|
+
],
|
|
371
|
+
additionalProperties: false,
|
|
372
|
+
properties: {
|
|
373
|
+
at: { type: "integer" },
|
|
374
|
+
cpu: { type: ["number", "null"] },
|
|
375
|
+
memoryUsedBytes: { type: ["number", "null"] },
|
|
376
|
+
memoryPressure: { enum: [
|
|
377
|
+
0,
|
|
378
|
+
1,
|
|
379
|
+
2,
|
|
380
|
+
null
|
|
381
|
+
] },
|
|
382
|
+
diskFreeBytes: { type: ["number", "null"] }
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
MachineUsage: {
|
|
389
|
+
type: "object",
|
|
390
|
+
required: [
|
|
391
|
+
"volumes",
|
|
392
|
+
"memory",
|
|
393
|
+
"load",
|
|
394
|
+
"cpu",
|
|
395
|
+
"sampledAt"
|
|
396
|
+
],
|
|
397
|
+
additionalProperties: false,
|
|
398
|
+
properties: {
|
|
399
|
+
volumes: {
|
|
400
|
+
type: "array",
|
|
401
|
+
items: {
|
|
402
|
+
type: "object",
|
|
403
|
+
required: [
|
|
404
|
+
"mount",
|
|
405
|
+
"holds",
|
|
406
|
+
"freeBytes",
|
|
407
|
+
"totalBytes"
|
|
408
|
+
],
|
|
409
|
+
additionalProperties: false,
|
|
410
|
+
properties: {
|
|
411
|
+
mount: { type: "string" },
|
|
412
|
+
holds: {
|
|
413
|
+
type: "array",
|
|
414
|
+
items: { type: "string" }
|
|
415
|
+
},
|
|
416
|
+
freeBytes: { type: "number" },
|
|
417
|
+
totalBytes: { type: "number" }
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
},
|
|
421
|
+
memory: {
|
|
422
|
+
type: "object",
|
|
423
|
+
required: [
|
|
424
|
+
"totalBytes",
|
|
425
|
+
"usedBytes",
|
|
426
|
+
"pressure"
|
|
427
|
+
],
|
|
428
|
+
additionalProperties: false,
|
|
429
|
+
properties: {
|
|
430
|
+
totalBytes: { type: "number" },
|
|
431
|
+
usedBytes: { type: ["number", "null"] },
|
|
432
|
+
pressure: { enum: [
|
|
433
|
+
"normal",
|
|
434
|
+
"warning",
|
|
435
|
+
"critical",
|
|
436
|
+
null
|
|
437
|
+
] }
|
|
438
|
+
}
|
|
439
|
+
},
|
|
440
|
+
load: {
|
|
441
|
+
type: "object",
|
|
442
|
+
required: [
|
|
443
|
+
"avg1",
|
|
444
|
+
"avg5",
|
|
445
|
+
"avg15",
|
|
446
|
+
"cpus"
|
|
447
|
+
],
|
|
448
|
+
additionalProperties: false,
|
|
449
|
+
properties: {
|
|
450
|
+
avg1: { type: "number" },
|
|
451
|
+
avg5: { type: "number" },
|
|
452
|
+
avg15: { type: "number" },
|
|
453
|
+
cpus: { type: "integer" }
|
|
454
|
+
}
|
|
455
|
+
},
|
|
456
|
+
cpu: {
|
|
457
|
+
type: "object",
|
|
458
|
+
required: ["usage", "cores"],
|
|
459
|
+
additionalProperties: false,
|
|
460
|
+
properties: {
|
|
461
|
+
usage: { type: ["number", "null"] },
|
|
462
|
+
cores: { type: "integer" }
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
sampledAt: {
|
|
466
|
+
type: "string",
|
|
467
|
+
format: "date-time"
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
},
|
|
245
471
|
ClientRequest: { oneOf: [
|
|
246
472
|
request("hello", { $ref: "#/$defs/HelloParams" }),
|
|
247
473
|
request("status.subscribe"),
|
|
248
474
|
request("logs.query", { $ref: "#/$defs/LogFilter" }),
|
|
249
475
|
request("logs.subscribe", { $ref: "#/$defs/LogFilter" }),
|
|
250
476
|
request("frames.subscribe", { $ref: "#/$defs/FrameTarget" }),
|
|
477
|
+
request("frames.keyframe", {
|
|
478
|
+
type: "object",
|
|
479
|
+
required: ["subscription"],
|
|
480
|
+
additionalProperties: false,
|
|
481
|
+
properties: { subscription: { type: "string" } }
|
|
482
|
+
}),
|
|
483
|
+
request("build.plan", { $ref: "#/$defs/BuildPlanParams" }),
|
|
484
|
+
request("machine.get"),
|
|
485
|
+
optionalParams("machine.history", {
|
|
486
|
+
type: "object",
|
|
487
|
+
additionalProperties: false,
|
|
488
|
+
properties: { sinceMs: { type: "number" } }
|
|
489
|
+
}),
|
|
251
490
|
optionalParams("stats.get", { $ref: "#/$defs/WorkspaceParams" }),
|
|
252
491
|
optionalParams("settings.get", { $ref: "#/$defs/WorkspaceParams" }),
|
|
253
492
|
request("unsubscribe", {
|
|
@@ -255,7 +494,8 @@ function protocolJsonSchema() {
|
|
|
255
494
|
required: ["subscription"],
|
|
256
495
|
additionalProperties: false,
|
|
257
496
|
properties: { subscription: { type: "string" } }
|
|
258
|
-
})
|
|
497
|
+
}),
|
|
498
|
+
request("action", { $ref: "#/$defs/ActionParams" })
|
|
259
499
|
] },
|
|
260
500
|
ServerResponse: { oneOf: [{
|
|
261
501
|
type: "object",
|
|
@@ -265,11 +505,17 @@ function protocolJsonSchema() {
|
|
|
265
505
|
id: requestId,
|
|
266
506
|
result: { anyOf: [
|
|
267
507
|
{ $ref: "#/$defs/HelloResult" },
|
|
508
|
+
{ $ref: "#/$defs/ActionResult" },
|
|
509
|
+
{ $ref: "#/$defs/MachineUsage" },
|
|
510
|
+
{ $ref: "#/$defs/MachineHistory" },
|
|
268
511
|
{
|
|
269
512
|
type: "object",
|
|
270
513
|
required: ["subscription"],
|
|
271
514
|
additionalProperties: false,
|
|
272
|
-
properties: {
|
|
515
|
+
properties: {
|
|
516
|
+
subscription: { type: "string" },
|
|
517
|
+
video: { enum: [...VIDEO_CODECS] }
|
|
518
|
+
}
|
|
273
519
|
},
|
|
274
520
|
{
|
|
275
521
|
type: "object",
|
|
@@ -282,7 +528,7 @@ function protocolJsonSchema() {
|
|
|
282
528
|
},
|
|
283
529
|
{
|
|
284
530
|
type: "object",
|
|
285
|
-
description: "The payload of `stim stats --json` or `stim
|
|
531
|
+
description: "The payload of `stim stats --json`, `stim settings --json` or `stim ios|android --plan --json`, or {} for unsubscribe."
|
|
286
532
|
}
|
|
287
533
|
] }
|
|
288
534
|
}
|
|
@@ -363,7 +609,22 @@ function protocolJsonSchema() {
|
|
|
363
609
|
data: {
|
|
364
610
|
type: "string",
|
|
365
611
|
contentEncoding: "base64"
|
|
366
|
-
}
|
|
612
|
+
},
|
|
613
|
+
posture: { enum: ["folded", "unfolded"] }
|
|
614
|
+
}
|
|
615
|
+
},
|
|
616
|
+
{
|
|
617
|
+
type: "object",
|
|
618
|
+
required: [
|
|
619
|
+
"event",
|
|
620
|
+
"subscription",
|
|
621
|
+
"delayed"
|
|
622
|
+
],
|
|
623
|
+
additionalProperties: false,
|
|
624
|
+
properties: {
|
|
625
|
+
event: { const: "frame-delayed" },
|
|
626
|
+
subscription: { type: "string" },
|
|
627
|
+
delayed: { type: "boolean" }
|
|
367
628
|
}
|
|
368
629
|
},
|
|
369
630
|
{
|
|
@@ -390,4 +651,4 @@ function protocolJsonSchema() {
|
|
|
390
651
|
};
|
|
391
652
|
}
|
|
392
653
|
//#endregion
|
|
393
|
-
export {
|
|
654
|
+
export { FRAME_FPS as a, MAX_LOG_TAIL as c, PROTOCOL_VERSION as d, VIDEO_CODECS as f, protocolJsonSchema as h, FRAME_EDGE as i, METHODS as l, VIDEO_KEYFRAME as m, CAPABILITIES as n, LOG_LEVELS as o, VIDEO_HEADER_VERSION as p, ERROR_CODES as r, LOG_SOURCES as s, ACTIONS as t, PROTOCOL_SCHEMA_FILE as u };
|
package/dist/protocol.d.mts
CHANGED
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { NdjsonRecord, StatusPayload } from "@stim-cli/core/state";
|
|
1
|
+
import { BuildPlanPayload, NdjsonRecord, StatusPayload } from "@stim-cli/core/state";
|
|
2
2
|
//#region src/protocol.d.ts
|
|
3
3
|
declare const PROTOCOL_VERSION = 1;
|
|
4
4
|
declare const PROTOCOL_SCHEMA_FILE = "protocol.schema.json";
|
|
5
|
-
|
|
5
|
+
/** `read` serves state. `control` also runs {@link ACTIONS}; only the Mac grants it. */
|
|
6
|
+
declare const CAPABILITIES: readonly ["read", "control"];
|
|
6
7
|
type Capability = (typeof CAPABILITIES)[number];
|
|
7
|
-
declare const METHODS: readonly ["hello", "status.subscribe", "logs.query", "logs.subscribe", "stats.get", "settings.get", "frames.subscribe", "unsubscribe"];
|
|
8
|
+
declare const METHODS: readonly ["hello", "status.subscribe", "logs.query", "logs.subscribe", "stats.get", "settings.get", "frames.subscribe", "frames.keyframe", "build.plan", "machine.get", "machine.history", "unsubscribe", "action"];
|
|
8
9
|
type Method = (typeof METHODS)[number];
|
|
9
10
|
/**
|
|
10
11
|
* `unauthorized`, `pairing-expired` and `protocol-unsupported` refuse the client until it pairs again or
|
|
11
12
|
* updates; clients retry the others.
|
|
12
13
|
*/
|
|
13
|
-
declare const ERROR_CODES: readonly ["unauthorized", "pairing-expired", "protocol-unsupported", "identity-unavailable", "bad-request", "unknown-method", "already-authenticated", "unknown-subscription", "unknown-workspace", "limit-exceeded", "slow-client", "status-failed", "logs-failed", "stim-failed", "frames-failed"];
|
|
14
|
+
declare const ERROR_CODES: readonly ["unauthorized", "pairing-expired", "protocol-unsupported", "identity-unavailable", "bad-request", "unknown-method", "already-authenticated", "unknown-subscription", "unknown-workspace", "limit-exceeded", "slow-client", "status-failed", "logs-failed", "stim-failed", "frames-failed", "forbidden", "unknown-action", "action-busy", "action-failed"];
|
|
14
15
|
type ErrorCode = (typeof ERROR_CODES)[number];
|
|
15
16
|
type RequestId = number | string;
|
|
16
17
|
/** Spends a single-use pairing token; the result carries the new device token. */
|
|
@@ -32,13 +33,19 @@ interface HelloParams {
|
|
|
32
33
|
}
|
|
33
34
|
interface HelloResult {
|
|
34
35
|
protocol: number;
|
|
35
|
-
/**
|
|
36
|
+
/**
|
|
37
|
+
* The Mac's name, this package's version, the version of the `stim` it runs, and the home directory of the
|
|
38
|
+
* user it runs as, so clients can show paths under it as `~/...`.
|
|
39
|
+
*/
|
|
36
40
|
server: {
|
|
37
41
|
name: string;
|
|
38
42
|
version: string;
|
|
39
43
|
stim: string;
|
|
44
|
+
home: string;
|
|
40
45
|
};
|
|
41
46
|
capabilities: Capability[];
|
|
47
|
+
/** The actions this device may run: every one of {@link ACTIONS} with `control`, none without. */
|
|
48
|
+
actions: ActionName[];
|
|
42
49
|
/** The paired device this connection authenticated as, as `stim-server devices` lists it. */
|
|
43
50
|
device: {
|
|
44
51
|
id: string;
|
|
@@ -53,7 +60,7 @@ interface SubscribeResult {
|
|
|
53
60
|
interface UnsubscribeParams {
|
|
54
61
|
subscription: string;
|
|
55
62
|
}
|
|
56
|
-
declare const LOG_SOURCES: readonly ["metro", "client", "device", "build"];
|
|
63
|
+
declare const LOG_SOURCES: readonly ["metro", "client", "device", "build", "agent"];
|
|
57
64
|
type LogSource = (typeof LOG_SOURCES)[number];
|
|
58
65
|
declare const LOG_LEVELS: readonly ["debug", "info", "warn", "error", "fatal"];
|
|
59
66
|
type LogLevel = (typeof LOG_LEVELS)[number];
|
|
@@ -86,14 +93,151 @@ type StatsResult = Record<string, unknown>;
|
|
|
86
93
|
/** `stim settings --json`; the CLI masks sensitive values. */
|
|
87
94
|
type SettingsResult = Record<string, unknown>;
|
|
88
95
|
type Platform = "ios" | "android";
|
|
96
|
+
declare const FRAME_FPS: {
|
|
97
|
+
readonly default: 5;
|
|
98
|
+
readonly max: 30;
|
|
99
|
+
readonly video: 60;
|
|
100
|
+
};
|
|
101
|
+
declare const FRAME_EDGE: {
|
|
102
|
+
readonly min: 240;
|
|
103
|
+
readonly default: 1280;
|
|
104
|
+
readonly max: 2048;
|
|
105
|
+
};
|
|
89
106
|
/**
|
|
90
107
|
* A device `stim status` lists as owned by `workspace`, in `slot` (`default` when absent). Frames come only
|
|
91
|
-
* from a booted simulator or a running emulator Stim created.
|
|
108
|
+
* from a booted simulator or a running emulator Stim created. `fps` caps how many frames a second this
|
|
109
|
+
* subscription gets, and `maxEdge` asks for frames scaled to fit that many pixels; the server may send smaller
|
|
110
|
+
* frames, and larger ones while another subscriber of the same device asks for more.
|
|
92
111
|
*/
|
|
93
112
|
interface FrameTarget {
|
|
94
113
|
workspace: string;
|
|
95
114
|
platform: Platform;
|
|
96
115
|
slot?: string;
|
|
116
|
+
fps?: number;
|
|
117
|
+
maxEdge?: number;
|
|
118
|
+
/** The codecs this client decodes. The server picks one when it can encode video; see {@link FramesSubscribeResult}. */
|
|
119
|
+
video?: VideoCodec[];
|
|
120
|
+
}
|
|
121
|
+
declare const VIDEO_CODECS: readonly ["h264"];
|
|
122
|
+
type VideoCodec = (typeof VIDEO_CODECS)[number];
|
|
123
|
+
/**
|
|
124
|
+
* With `video`, frames arrive as binary WebSocket messages, one H.264 access unit each; see {@link VideoPacket}.
|
|
125
|
+
* A subscription whose device cannot be encoded, such as an iPhone Duo, still sends JSON `frame` events.
|
|
126
|
+
*/
|
|
127
|
+
interface FramesSubscribeResult extends SubscribeResult {
|
|
128
|
+
video?: VideoCodec;
|
|
129
|
+
}
|
|
130
|
+
/** Asks for a keyframe on a video subscription, after the client lost its decoder state. */
|
|
131
|
+
interface KeyframeParams {
|
|
132
|
+
subscription: string;
|
|
133
|
+
}
|
|
134
|
+
declare const VIDEO_HEADER_VERSION = 1;
|
|
135
|
+
/** The keyframe bit of a {@link VideoPacket}'s flags. */
|
|
136
|
+
declare const VIDEO_KEYFRAME = 1;
|
|
137
|
+
/**
|
|
138
|
+
* The layout of a binary video message, big-endian: u8 version ({@link VIDEO_HEADER_VERSION}), u8 flags
|
|
139
|
+
* ({@link VIDEO_KEYFRAME}), u16 header length, u32 sequence number of the messages sent on this subscription, f64 capture time in milliseconds since the
|
|
140
|
+
* epoch on the Mac's clock, u16 width, u16 height, u8 subscription id length N, N bytes of ASCII subscription
|
|
141
|
+
* id. After the header comes one Annex-B H.264 access unit; a keyframe carries its SPS and PPS. The stream has
|
|
142
|
+
* no B-frames, so each access unit is shown as it arrives.
|
|
143
|
+
*/
|
|
144
|
+
interface VideoPacket {
|
|
145
|
+
subscription: string;
|
|
146
|
+
keyframe: boolean;
|
|
147
|
+
sequence: number;
|
|
148
|
+
capturedAt: number;
|
|
149
|
+
width: number;
|
|
150
|
+
height: number;
|
|
151
|
+
accessUnit: Uint8Array;
|
|
152
|
+
}
|
|
153
|
+
/** Each action runs one fixed `stim` command in the workspace. */
|
|
154
|
+
declare const ACTIONS: readonly ["reload", "stop"];
|
|
155
|
+
type ActionName = (typeof ACTIONS)[number];
|
|
156
|
+
/**
|
|
157
|
+
* `reload` runs `stim reload --json`, with `platform` when both platforms are live; `stop` runs
|
|
158
|
+
* `stim stop --json`. `workspace` is an environment `path` from a status payload. Needs `control`.
|
|
159
|
+
*/
|
|
160
|
+
type ActionParams = {
|
|
161
|
+
action: "reload";
|
|
162
|
+
workspace: string;
|
|
163
|
+
platform?: Platform;
|
|
164
|
+
} | {
|
|
165
|
+
action: "stop";
|
|
166
|
+
workspace: string;
|
|
167
|
+
};
|
|
168
|
+
/** `output` is the JSON the command printed. */
|
|
169
|
+
interface ActionResult {
|
|
170
|
+
action: ActionName;
|
|
171
|
+
workspace: string;
|
|
172
|
+
output: Record<string, unknown>;
|
|
173
|
+
}
|
|
174
|
+
/** Predicts the next `ios` or `android` build of `workspace` in `slot` (`default` when absent). */
|
|
175
|
+
interface BuildPlanParams {
|
|
176
|
+
workspace: string;
|
|
177
|
+
platform: Platform;
|
|
178
|
+
slot?: string;
|
|
179
|
+
}
|
|
180
|
+
/** `stim ios|android --plan --json`. It builds, boots and installs nothing, and writes no Stim state. */
|
|
181
|
+
type BuildPlanResult = BuildPlanPayload;
|
|
182
|
+
type MemoryPressure = "normal" | "warning" | "critical";
|
|
183
|
+
/** A volume that holds Stim workspaces, Stim home, or the simulators. */
|
|
184
|
+
interface MachineVolume {
|
|
185
|
+
/** `/`, or `/Volumes/<name>` for an external volume. */
|
|
186
|
+
mount: string;
|
|
187
|
+
/** What Stim keeps there: `Workspaces`, `Stim home`, `Simulators`. */
|
|
188
|
+
holds: string[];
|
|
189
|
+
/** Free space without purgeable space, which is what Stim's disk budget measures. */
|
|
190
|
+
freeBytes: number;
|
|
191
|
+
totalBytes: number;
|
|
192
|
+
}
|
|
193
|
+
/** Cheap machine usage, read in the server process without running `stim`. */
|
|
194
|
+
interface MachineUsage {
|
|
195
|
+
volumes: MachineVolume[];
|
|
196
|
+
/**
|
|
197
|
+
* `usedBytes` is the Mac's memory in use, as Activity Monitor's "Memory Used" counts it: app memory, wired and
|
|
198
|
+
* compressed. `pressure` is the macOS memory pressure level. Both are null on other systems or when they cannot
|
|
199
|
+
* be read.
|
|
200
|
+
*/
|
|
201
|
+
memory: {
|
|
202
|
+
totalBytes: number;
|
|
203
|
+
usedBytes: number | null;
|
|
204
|
+
pressure: MemoryPressure | null;
|
|
205
|
+
};
|
|
206
|
+
load: {
|
|
207
|
+
avg1: number;
|
|
208
|
+
avg5: number;
|
|
209
|
+
avg15: number;
|
|
210
|
+
cpus: number;
|
|
211
|
+
};
|
|
212
|
+
/**
|
|
213
|
+
* `usage` is the Mac's overall CPU busy fraction (0..1), from the tick delta between this call and the
|
|
214
|
+
* previous one. Null on the first call of a server process, since there is no previous sample yet.
|
|
215
|
+
*/
|
|
216
|
+
cpu: {
|
|
217
|
+
usage: number | null;
|
|
218
|
+
cores: number;
|
|
219
|
+
};
|
|
220
|
+
sampledAt: string;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* One `machine.history` sample. `at` is epoch milliseconds. `cpu` is the busy fraction (0..1) since the previous
|
|
224
|
+
* sample. `memoryPressure` is 0 (normal), 1 (warning) or 2 (critical). `diskFreeBytes` is the free space of the
|
|
225
|
+
* startup volume, `/`. A field is null when it could not be read.
|
|
226
|
+
*/
|
|
227
|
+
interface UsageSample {
|
|
228
|
+
at: number;
|
|
229
|
+
cpu: number | null;
|
|
230
|
+
memoryUsedBytes: number | null;
|
|
231
|
+
memoryPressure: 0 | 1 | 2 | null;
|
|
232
|
+
diskFreeBytes: number | null;
|
|
233
|
+
}
|
|
234
|
+
/** Returns only the samples taken after `sinceMs`, epoch milliseconds. */
|
|
235
|
+
interface MachineHistoryParams {
|
|
236
|
+
sinceMs?: number;
|
|
237
|
+
}
|
|
238
|
+
interface MachineHistory {
|
|
239
|
+
intervalMs: number;
|
|
240
|
+
samples: UsageSample[];
|
|
97
241
|
}
|
|
98
242
|
interface Methods {
|
|
99
243
|
hello: {
|
|
@@ -122,12 +266,32 @@ interface Methods {
|
|
|
122
266
|
};
|
|
123
267
|
"frames.subscribe": {
|
|
124
268
|
params: FrameTarget;
|
|
125
|
-
result:
|
|
269
|
+
result: FramesSubscribeResult;
|
|
270
|
+
};
|
|
271
|
+
"frames.keyframe": {
|
|
272
|
+
params: KeyframeParams;
|
|
273
|
+
result: Record<string, never>;
|
|
274
|
+
};
|
|
275
|
+
"build.plan": {
|
|
276
|
+
params: BuildPlanParams;
|
|
277
|
+
result: BuildPlanResult;
|
|
278
|
+
};
|
|
279
|
+
"machine.get": {
|
|
280
|
+
params?: Record<string, never>;
|
|
281
|
+
result: MachineUsage;
|
|
282
|
+
};
|
|
283
|
+
"machine.history": {
|
|
284
|
+
params?: MachineHistoryParams;
|
|
285
|
+
result: MachineHistory;
|
|
126
286
|
};
|
|
127
287
|
unsubscribe: {
|
|
128
288
|
params: UnsubscribeParams;
|
|
129
289
|
result: Record<string, never>;
|
|
130
290
|
};
|
|
291
|
+
action: {
|
|
292
|
+
params: ActionParams;
|
|
293
|
+
result: ActionResult;
|
|
294
|
+
};
|
|
131
295
|
}
|
|
132
296
|
type ClientRequest = { [M in Method]: {
|
|
133
297
|
id: RequestId;
|
|
@@ -165,7 +329,7 @@ interface ErrorEvent {
|
|
|
165
329
|
subscription: string;
|
|
166
330
|
error: ProtocolError;
|
|
167
331
|
}
|
|
168
|
-
/** A
|
|
332
|
+
/** A frame of the device's screen, sent when the screen changed, at most `fps` times a second. */
|
|
169
333
|
interface FrameEvent {
|
|
170
334
|
event: "frame";
|
|
171
335
|
subscription: string;
|
|
@@ -177,11 +341,26 @@ interface FrameEvent {
|
|
|
177
341
|
capturedAt: string;
|
|
178
342
|
/** Base64-encoded image bytes. */
|
|
179
343
|
data: string;
|
|
344
|
+
/**
|
|
345
|
+
* An iPhone Duo's or Android foldable emulator's posture. A Duo reports the panel it lit: the cover when
|
|
346
|
+
* folded, the inner panel when unfolded. An emulator with a hinge reports `folded` while it shows only its
|
|
347
|
+
* outer display, and `unfolded` otherwise, including half open.
|
|
348
|
+
*/
|
|
349
|
+
posture?: "folded" | "unfolded";
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Captures for a `frames.subscribe` subscription are slow or a timed-out capture is being retried; the
|
|
353
|
+
* client keeps showing its last frame. Followed by `delayed: false` once captures recover.
|
|
354
|
+
*/
|
|
355
|
+
interface FrameDelayedEvent {
|
|
356
|
+
event: "frame-delayed";
|
|
357
|
+
subscription: string;
|
|
358
|
+
delayed: boolean;
|
|
180
359
|
}
|
|
181
|
-
type ServerEvent = StatusEvent | LogsEvent | FrameEvent | ErrorEvent;
|
|
360
|
+
type ServerEvent = StatusEvent | LogsEvent | FrameEvent | FrameDelayedEvent | ErrorEvent;
|
|
182
361
|
type ServerMessage = ServerResponse | ServerEvent;
|
|
183
362
|
type JsonSchema = Record<string, unknown>;
|
|
184
363
|
/** The JSON Schema of every message on the wire, written to `dist/protocol.schema.json` at build time. */
|
|
185
364
|
declare function protocolJsonSchema(): JsonSchema;
|
|
186
365
|
//#endregion
|
|
187
|
-
export { CAPABILITIES, Capability, ClientRequest, DeviceAuth, ERROR_CODES, ErrorCode, ErrorEvent, FrameEvent, FrameTarget, HelloParams, HelloResult, LOG_LEVELS, LOG_SOURCES, LogFilter, LogLevel, LogRecord, LogSource, LogsEvent, LogsQueryResult, MAX_LOG_TAIL, METHODS, Method, Methods, PROTOCOL_SCHEMA_FILE, PROTOCOL_VERSION, PairingAuth, Platform, ProtocolError, RequestId, ServerEvent, ServerMessage, ServerResponse, SettingsResult, StatsResult, StatusEvent, SubscribeResult, UnsubscribeParams, WorkspaceParams, protocolJsonSchema };
|
|
366
|
+
export { ACTIONS, ActionName, ActionParams, ActionResult, BuildPlanParams, BuildPlanResult, CAPABILITIES, Capability, ClientRequest, DeviceAuth, ERROR_CODES, ErrorCode, ErrorEvent, FRAME_EDGE, FRAME_FPS, FrameDelayedEvent, FrameEvent, FrameTarget, FramesSubscribeResult, HelloParams, HelloResult, KeyframeParams, LOG_LEVELS, LOG_SOURCES, LogFilter, LogLevel, LogRecord, LogSource, LogsEvent, LogsQueryResult, MAX_LOG_TAIL, METHODS, MachineHistory, MachineHistoryParams, MachineUsage, MachineVolume, MemoryPressure, Method, Methods, PROTOCOL_SCHEMA_FILE, PROTOCOL_VERSION, PairingAuth, Platform, ProtocolError, RequestId, ServerEvent, ServerMessage, ServerResponse, SettingsResult, StatsResult, StatusEvent, SubscribeResult, UnsubscribeParams, UsageSample, VIDEO_CODECS, VIDEO_HEADER_VERSION, VIDEO_KEYFRAME, VideoCodec, VideoPacket, WorkspaceParams, protocolJsonSchema };
|
package/dist/protocol.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { CAPABILITIES, ERROR_CODES, LOG_LEVELS, LOG_SOURCES, MAX_LOG_TAIL, METHODS, PROTOCOL_SCHEMA_FILE, PROTOCOL_VERSION, protocolJsonSchema };
|
|
1
|
+
import { a as FRAME_FPS, c as MAX_LOG_TAIL, d as PROTOCOL_VERSION, f as VIDEO_CODECS, h as protocolJsonSchema, i as FRAME_EDGE, l as METHODS, m as VIDEO_KEYFRAME, n as CAPABILITIES, o as LOG_LEVELS, p as VIDEO_HEADER_VERSION, r as ERROR_CODES, s as LOG_SOURCES, t as ACTIONS, u as PROTOCOL_SCHEMA_FILE } from "./protocol-CmlG7X7_.mjs";
|
|
2
|
+
export { ACTIONS, CAPABILITIES, ERROR_CODES, FRAME_EDGE, FRAME_FPS, LOG_LEVELS, LOG_SOURCES, MAX_LOG_TAIL, METHODS, PROTOCOL_SCHEMA_FILE, PROTOCOL_VERSION, VIDEO_CODECS, VIDEO_HEADER_VERSION, VIDEO_KEYFRAME, protocolJsonSchema };
|