@tapflowio/ios-agent 0.30.0 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/bin/guest-helper +0 -0
  2. package/bin/screencapture-helper +0 -0
  3. package/dist/DeviceChromeLoader.d.ts +28 -1
  4. package/dist/DeviceChromeLoader.d.ts.map +1 -1
  5. package/dist/DeviceChromeLoader.js +118 -37
  6. package/dist/DeviceChromeLoader.js.map +1 -1
  7. package/dist/FoldableInput.d.ts +58 -0
  8. package/dist/FoldableInput.d.ts.map +1 -0
  9. package/dist/FoldableInput.js +166 -0
  10. package/dist/FoldableInput.js.map +1 -0
  11. package/dist/GuestHelper.d.ts +109 -0
  12. package/dist/GuestHelper.d.ts.map +1 -0
  13. package/dist/GuestHelper.js +437 -0
  14. package/dist/GuestHelper.js.map +1 -0
  15. package/dist/IOSAgent.d.ts +119 -2
  16. package/dist/IOSAgent.d.ts.map +1 -1
  17. package/dist/IOSAgent.js +586 -24
  18. package/dist/IOSAgent.js.map +1 -1
  19. package/dist/InputChannel.d.ts +38 -0
  20. package/dist/InputChannel.d.ts.map +1 -0
  21. package/dist/InputChannel.js +7 -0
  22. package/dist/InputChannel.js.map +1 -0
  23. package/dist/PanelState.d.ts +72 -0
  24. package/dist/PanelState.d.ts.map +1 -0
  25. package/dist/PanelState.js +192 -0
  26. package/dist/PanelState.js.map +1 -0
  27. package/dist/PhysicalOrientation.d.ts +58 -0
  28. package/dist/PhysicalOrientation.d.ts.map +1 -0
  29. package/dist/PhysicalOrientation.js +155 -0
  30. package/dist/PhysicalOrientation.js.map +1 -0
  31. package/dist/ScreenCaptureStreamer.d.ts +12 -1
  32. package/dist/ScreenCaptureStreamer.d.ts.map +1 -1
  33. package/dist/ScreenCaptureStreamer.js +28 -3
  34. package/dist/ScreenCaptureStreamer.js.map +1 -1
  35. package/dist/SimctlWrapper.d.ts +18 -1
  36. package/dist/SimctlWrapper.d.ts.map +1 -1
  37. package/dist/SimctlWrapper.js +43 -1
  38. package/dist/SimctlWrapper.js.map +1 -1
  39. package/dist/TouchHelper.d.ts +3 -2
  40. package/dist/TouchHelper.d.ts.map +1 -1
  41. package/dist/TouchHelper.js +4 -6
  42. package/dist/TouchHelper.js.map +1 -1
  43. package/dist/TypePanels.d.ts +33 -0
  44. package/dist/TypePanels.d.ts.map +1 -0
  45. package/dist/TypePanels.js +68 -0
  46. package/dist/TypePanels.js.map +1 -0
  47. package/dist/panels.d.ts +52 -0
  48. package/dist/panels.d.ts.map +1 -0
  49. package/dist/panels.js +68 -0
  50. package/dist/panels.js.map +1 -0
  51. package/package.json +6 -5
@@ -0,0 +1,192 @@
1
+ import { execFile } from 'child_process';
2
+ import { readFile, unlink } from 'fs/promises';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import { randomUUID } from 'crypto';
6
+ import { promisify } from 'util';
7
+ import { createLogger } from '@tapflowio/agent-core';
8
+ const logger = createLogger('ios-agent:panel-state');
9
+ const execFileAsync = promisify(execFile);
10
+ // One `devicectl device info displays` measured ~0.23 s on the Mac mini (Xcode 27.1).
11
+ const DEVICECTL_TIMEOUT_MS = 10_000;
12
+ // A fold is not done when the sweep is: measured on Xcode 27.1, both panels go dark 1–2 s after the
13
+ // command and the new one lights 4–6 s after it, and devicectl's `active` flips within about a second
14
+ // of the framebuffer. A wait shorter than that reports a successful fold as a failed one.
15
+ export const FOLD_SETTLE_MS = 10_000;
16
+ const AWAIT_INTERVAL_MS = 300;
17
+ // How long a panel nobody asked for must stay lit before it is followed. Measured on Xcode 27.1: a Duo
18
+ // coming up from an erase lit its unfolded panel for at most 3.2 s, some 49 s into the boot, and went back
19
+ // to its cover — once in two erase boots, and on each of three session re-entries on a Duo DeviceHub was
20
+ // showing. Followed, the viewer swapped to a dark unfolded panel and back. A fold made in DeviceHub holds.
21
+ export const PANEL_HOLD_MS = 4_000;
22
+ export const defaultPanelStateNative = {
23
+ async readDisplays(udid) {
24
+ // devicectl writes JSON only to a file. Read and removed asynchronously, like the call itself —
25
+ // this runs on the loop that forwards frames (contributing/agent-event-loop-blocking.md).
26
+ const out = join(tmpdir(), `tapflow-devicectl-${udid}-${randomUUID()}.json`);
27
+ try {
28
+ await execFileAsync('xcrun', ['devicectl', 'device', 'info', 'displays', '--device', udid, '--quiet', '--json-output', out], { timeout: DEVICECTL_TIMEOUT_MS });
29
+ return JSON.parse(await readFile(out, 'utf8'));
30
+ }
31
+ finally {
32
+ unlink(out).catch(() => { });
33
+ }
34
+ },
35
+ };
36
+ const ROTATIONS = { rot0: 0, rot90: 90, rot180: 180, rot270: 270 };
37
+ /** The integrated panels in a devicectl displays document, or null if the document is not one. A rotation
38
+ * it does not know is null on that panel — not a guess, which would turn the picture, and not the whole
39
+ * reading, which would also lose which panel is lit and leave input waiting for it. A first version did
40
+ * the latter, and input never started on a Duo whose first readings after its boot carried one. */
41
+ export function parseDisplays(doc) {
42
+ const displays = doc?.result?.displays;
43
+ if (!Array.isArray(displays))
44
+ return null;
45
+ const panels = [];
46
+ for (const d of displays) {
47
+ const type = d.type;
48
+ if (!type || !('integrated' in type))
49
+ continue;
50
+ if (typeof d.displayId !== 'number' || typeof d.active !== 'boolean')
51
+ return null;
52
+ panels.push({ displayId: d.displayId, active: d.active, rotation: ROTATIONS[String(d.currentOrientation)] ?? null });
53
+ }
54
+ if (panels.length === 0)
55
+ return null;
56
+ const lit = panels.find((p) => p.active);
57
+ return { lit: lit ? { displayId: lit.displayId, rotation: lit.rotation } : null, panels };
58
+ }
59
+ /**
60
+ * Which panel a multi-panel device is showing, observed rather than inferred from the hinge angle: the
61
+ * host cannot tell (both panels report Power On to `simctl io`) and the angle is the guest's to turn
62
+ * into a panel, so devicectl's `active` is the answer SpringBoard itself gave.
63
+ *
64
+ * Keyed by udid and kept outside `DeviceState`, which every relay reconnect rebuilds.
65
+ */
66
+ export class PanelState {
67
+ native;
68
+ holdMs;
69
+ flights = new Map();
70
+ known = new Map();
71
+ // A different panel read lit, not yet held for `holdMs`, and when it was first read so.
72
+ candidates = new Map();
73
+ // Bumped by `forget`: a reading started before it describes the device as it was, and is dropped.
74
+ generations = new Map();
75
+ constructor(native = defaultPanelStateNative, holdMs = PANEL_HOLD_MS) {
76
+ this.native = native;
77
+ this.holdMs = holdMs;
78
+ }
79
+ /**
80
+ * A fresh reading. **A read that arrives while a call is in flight never joins it**: it gets exactly one
81
+ * more call that starts after the current one ends, shared with any other reads that arrive meanwhile.
82
+ * Joining would hand a caller who asked after a fold a reading taken before it — measured as the way a
83
+ * poll turns a successful Unfold into a reported failure.
84
+ *
85
+ * Resolves null when the call fails; `last()` keeps the previous answer.
86
+ */
87
+ read(udid) {
88
+ const flight = this.flights.get(udid);
89
+ if (!flight)
90
+ return this.startFlight(udid);
91
+ if (!flight.next) {
92
+ flight.next = flight.current.then(() => {
93
+ const f = this.flights.get(udid);
94
+ if (f)
95
+ f.next = null;
96
+ return this.startFlight(udid);
97
+ });
98
+ }
99
+ return flight.next;
100
+ }
101
+ /**
102
+ * The lit panel the device has settled on, or null before any reading named one. Synchronous, for the paths
103
+ * that cannot await. **Not simply the last reading**: a change nobody asked for counts only once the new
104
+ * panel has stayed lit for `holdMs` (see PANEL_HOLD_MS) — a fold this agent made and waited for with
105
+ * `awaitLit` counts at once. Until then this keeps the panel before it.
106
+ */
107
+ last(udid) {
108
+ return this.known.get(udid) ?? null;
109
+ }
110
+ /** Whether a different panel has been read lit and is still being held to `holdMs` — read again after it. */
111
+ changing(udid) {
112
+ return this.candidates.has(udid);
113
+ }
114
+ forget(udid) {
115
+ this.known.delete(udid);
116
+ this.candidates.delete(udid);
117
+ this.generations.set(udid, (this.generations.get(udid) ?? 0) + 1);
118
+ }
119
+ /** Reads until `done` holds, or `timeoutMs` passes (then null). For a fold: the sweep finishing is not
120
+ * the panel changing — see FOLD_SETTLE_MS. */
121
+ async awaitLit(udid, done, timeoutMs = FOLD_SETTLE_MS) {
122
+ const deadline = Date.now() + timeoutMs;
123
+ for (;;) {
124
+ const reading = await this.read(udid);
125
+ if (reading && done(reading)) {
126
+ // Asked for and arrived: nothing to hold it to.
127
+ if (reading.lit)
128
+ this.settle(udid, reading);
129
+ return reading;
130
+ }
131
+ if (Date.now() + AWAIT_INTERVAL_MS > deadline)
132
+ return null;
133
+ await new Promise((r) => setTimeout(r, AWAIT_INTERVAL_MS));
134
+ }
135
+ }
136
+ startFlight(udid) {
137
+ const generation = this.generations.get(udid) ?? 0;
138
+ const current = this.native.readDisplays(udid).then((doc) => {
139
+ // Forgotten while it ran — the device shut down or was erased under it. Kept, it would put the panel
140
+ // lit before the shutdown back as the one the next boot starts from.
141
+ if ((this.generations.get(udid) ?? 0) !== generation)
142
+ return null;
143
+ const reading = parseDisplays(doc);
144
+ // What it said goes in the log: the one time this fired on a real Duo, nobody could see why.
145
+ if (!reading)
146
+ logger.warn(`devicectl gave ${udid} a displays document this agent does not recognise: ${JSON.stringify(doc).slice(0, 400)}`);
147
+ // Only a reading that names a lit panel replaces the last one: mid-fold both are dark, and the
148
+ // last panel is the better answer for anything that cannot wait.
149
+ if (reading?.lit)
150
+ this.observe(udid, { ...reading, lit: reading.lit });
151
+ return reading;
152
+ }, (e) => {
153
+ logger.warn(`devicectl displays failed for ${udid}: ${e instanceof Error ? e.message : String(e)}`);
154
+ return null;
155
+ });
156
+ const flight = { current, next: null };
157
+ this.flights.set(udid, flight);
158
+ void current.then(() => {
159
+ if (this.flights.get(udid) === flight && !flight.next)
160
+ this.flights.delete(udid);
161
+ });
162
+ return current;
163
+ }
164
+ observe(udid, reading) {
165
+ const known = this.known.get(udid);
166
+ if (!known?.lit || known.lit.displayId === reading.lit.displayId) {
167
+ const dropped = this.candidates.get(udid)?.reading.lit?.displayId;
168
+ if (dropped !== undefined)
169
+ logger.info(`${udid} lit display ${dropped} only briefly — not followed`);
170
+ this.settle(udid, reading);
171
+ return;
172
+ }
173
+ const candidate = this.candidates.get(udid);
174
+ if (candidate?.reading.lit?.displayId !== reading.lit.displayId) {
175
+ this.candidates.set(udid, { reading, since: Date.now() });
176
+ }
177
+ else if (Date.now() - candidate.since >= this.holdMs) {
178
+ this.settle(udid, reading);
179
+ }
180
+ else {
181
+ candidate.reading = reading;
182
+ }
183
+ }
184
+ settle(udid, reading) {
185
+ const before = this.known.get(udid)?.lit?.displayId;
186
+ this.known.set(udid, reading);
187
+ this.candidates.delete(udid);
188
+ if (before !== undefined && before !== reading.lit?.displayId)
189
+ logger.info(`${udid} now shows display ${reading.lit?.displayId}`);
190
+ }
191
+ }
192
+ //# sourceMappingURL=PanelState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PanelState.js","sourceRoot":"","sources":["../src/PanelState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,IAAI,CAAA;AAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAC3B,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACnC,OAAO,EAAE,SAAS,EAAE,MAAM,MAAM,CAAA;AAChC,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAA;AAEpD,MAAM,MAAM,GAAG,YAAY,CAAC,uBAAuB,CAAC,CAAA;AACpD,MAAM,aAAa,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAA;AAEzC,sFAAsF;AACtF,MAAM,oBAAoB,GAAG,MAAM,CAAA;AACnC,oGAAoG;AACpG,sGAAsG;AACtG,0FAA0F;AAC1F,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAA;AACpC,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAC7B,uGAAuG;AACvG,2GAA2G;AAC3G,yGAAyG;AACzG,2GAA2G;AAC3G,MAAM,CAAC,MAAM,aAAa,GAAG,KAAK,CAAA;AAyBlC,MAAM,CAAC,MAAM,uBAAuB,GAAqB;IACvD,KAAK,CAAC,YAAY,CAAC,IAAI;QACrB,gGAAgG;QAChG,0FAA0F;QAC1F,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,qBAAqB,IAAI,IAAI,UAAU,EAAE,OAAO,CAAC,CAAA;QAC5E,IAAI,CAAC;YACH,MAAM,aAAa,CAAC,OAAO,EAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,SAAS,EAAE,eAAe,EAAE,GAAG,CAAC,EACzH,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC,CAAA;YACpC,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;QAChD,CAAC;gBAAS,CAAC;YACT,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAuB,CAAC,CAAC,CAAA;QAClD,CAAC;IACH,CAAC;CACF,CAAA;AAED,MAAM,SAAS,GAA6B,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,CAAA;AAE5F;;;oGAGoG;AACpG,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,MAAM,QAAQ,GAAI,GAAkD,EAAE,MAAM,EAAE,QAAQ,CAAA;IACtF,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAA;IACzC,MAAM,MAAM,GAAgB,EAAE,CAAA;IAC9B,KAAK,MAAM,CAAC,IAAI,QAA0C,EAAE,CAAC;QAC3D,MAAM,IAAI,GAAG,CAAC,CAAC,IAA2C,CAAA;QAC1D,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC;YAAE,SAAQ;QAC9C,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,MAAM,KAAK,SAAS;YAAE,OAAO,IAAI,CAAA;QACjF,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAA;IACtH,CAAC;IACD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAA;IACpC,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAA;IACxC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,CAAA;AAC3F,CAAC;AAOD;;;;;;GAMG;AACH,MAAM,OAAO,UAAU;IASF;IACR;IATM,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAA;IACnC,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAA;IACxD,wFAAwF;IACvE,UAAU,GAAG,IAAI,GAAG,EAAoD,CAAA;IACzF,kGAAkG;IACjF,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;IAExD,YACmB,SAA2B,uBAAuB,EAC1D,SAAS,aAAa;QADd,WAAM,GAAN,MAAM,CAA4C;QAC1D,WAAM,GAAN,MAAM,CAAgB;IAC9B,CAAC;IAEJ;;;;;;;OAOG;IACH,IAAI,CAAC,IAAY;QACf,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACrC,IAAI,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;QAC1C,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;YACjB,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;gBACrC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;gBAChC,IAAI,CAAC;oBAAE,CAAC,CAAC,IAAI,GAAG,IAAI,CAAA;gBACpB,OAAO,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAA;YAC/B,CAAC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,MAAM,CAAC,IAAI,CAAA;IACpB,CAAC;IAED;;;;;OAKG;IACH,IAAI,CAAC,IAAY;QACf,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAA;IACrC,CAAC;IAED,6GAA6G;IAC7G,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;IAClC,CAAC;IAED,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACvB,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;IACnE,CAAC;IAED;mDAC+C;IAC/C,KAAK,CAAC,QAAQ,CAAC,IAAY,EAAE,IAAkC,EAAE,SAAS,GAAG,cAAc;QACzF,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAA;QACvC,SAAS,CAAC;YACR,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACrC,IAAI,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,gDAAgD;gBAChD,IAAI,OAAO,CAAC,GAAG;oBAAE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;gBAC3C,OAAO,OAAO,CAAA;YAChB,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,iBAAiB,GAAG,QAAQ;gBAAE,OAAO,IAAI,CAAA;YAC1D,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,iBAAiB,CAAC,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IAEO,WAAW,CAAC,IAAY;QAC9B,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAClD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,IAAI,CACjD,CAAC,GAAG,EAAE,EAAE;YACN,qGAAqG;YACrG,qEAAqE;YACrE,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,UAAU;gBAAE,OAAO,IAAI,CAAA;YACjE,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,CAAA;YAClC,6FAA6F;YAC7F,IAAI,CAAC,OAAO;gBAAE,MAAM,CAAC,IAAI,CAAC,kBAAkB,IAAI,uDAAuD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;YAC3I,+FAA+F;YAC/F,iEAAiE;YACjE,IAAI,OAAO,EAAE,GAAG;gBAAE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,GAAG,OAAO,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;YACtE,OAAO,OAAO,CAAA;QAChB,CAAC,EACD,CAAC,CAAU,EAAE,EAAE;YACb,MAAM,CAAC,IAAI,CAAC,iCAAiC,IAAI,KAAK,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;YACnG,OAAO,IAAI,CAAA;QACb,CAAC,CACF,CAAA;QACD,MAAM,MAAM,GAAW,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAA;QAC9C,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAA;QAC9B,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE;YACrB,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI;gBAAE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAClF,CAAC,CAAC,CAAA;QACF,OAAO,OAAO,CAAA;IAChB,CAAC;IAEO,OAAO,CAAC,IAAY,EAAE,OAAiE;QAC7F,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClC,IAAI,CAAC,KAAK,EAAE,GAAG,IAAI,KAAK,CAAC,GAAG,CAAC,SAAS,KAAK,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YACjE,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,CAAA;YACjE,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,gBAAgB,OAAO,8BAA8B,CAAC,CAAA;YACpG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;YAC1B,OAAM;QACR,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAC3C,IAAI,SAAS,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC;YAChE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;QAC3D,CAAC;aAAM,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YACvD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC5B,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,OAAO,GAAG,OAAO,CAAA;QAC7B,CAAC;IACH,CAAC;IAEO,MAAM,CAAC,IAAY,EAAE,OAAqB;QAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,SAAS,CAAA;QACnD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;QAC7B,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QAC5B,IAAI,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,OAAO,CAAC,GAAG,EAAE,SAAS;YAAE,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,sBAAsB,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,CAAA;IACnI,CAAC;CACF"}
@@ -0,0 +1,58 @@
1
+ import type { Rotation } from './PanelState.js';
2
+ /** A device's physical orientation, in devicectl's (UIDeviceOrientation's) names. */
3
+ export type DeviceOrientation = 'portrait' | 'landscapeRight' | 'portraitUpsideDown' | 'landscapeLeft';
4
+ /**
5
+ * How far each orientation turns the device clockwise as DeviceHub draws it. Measured on the iPhone Duo's
6
+ * cover with Safari up: one clockwise turn from portrait reads `landscapeRight`, and that is the panel
7
+ * DeviceHub shows on its right side.
8
+ */
9
+ export declare const ORIENTATION_DEGREES: Record<DeviceOrientation, Rotation>;
10
+ /** The orientation a quarter turn away. */
11
+ export declare function turned(from: DeviceOrientation, direction: 'clockwise' | 'counterclockwise'): DeviceOrientation;
12
+ export interface PhysicalOrientationNative {
13
+ /** The parsed JSON of `devicectl device orientation get` for this device. */
14
+ readOrientation(udid: string): Promise<unknown>;
15
+ }
16
+ /**
17
+ * Two sources, chosen by the host rather than tried in turn. **Xcode 27**: `devicectl device orientation get`,
18
+ * public. **Older**: devicectl does not see simulators, so the guest helper asks backboardd (`guest-helper
19
+ * --orientation`, the one file private API lives in). Not a fallback for a failed devicectl read on Xcode 27: on
20
+ * iOS 27.1 backboardd's value did not follow a turn made in DeviceHub (measured on the Duo), so it would answer
21
+ * portrait for a device that is not — a failed read is no answer, and the caller keeps the last one.
22
+ */
23
+ export declare const defaultPhysicalOrientationNative: PhysicalOrientationNative;
24
+ /**
25
+ * The device's physical orientation in a devicectl document, or null if it is not one. Lying flat
26
+ * (`faceUp`/`faceDown`) reads as the last orientation it stood in (`deviceOrientationNonFlat`), which is how
27
+ * a phone on a table keeps its screen. `unknown` is what a device reports until anything has turned it
28
+ * (measured on a fresh iPhone 18 Pro); it boots upright and is drawn upright, so it reads as portrait.
29
+ */
30
+ export declare function parseOrientation(doc: unknown): DeviceOrientation | null;
31
+ /**
32
+ * Which way the device is held — what DeviceHub turns its whole frame by. **Not the interface orientation**:
33
+ * `devicectl device info displays` follows what the app on screen shows, so a home screen (which never
34
+ * turns on an iPhone) left it at portrait while DeviceHub turned the device four times. This is the
35
+ * orientation the device keeps for whatever app comes up next, and it is what DeviceHub, tapflow's helper,
36
+ * Purple and `devicectl orientation set` all write — measured for each.
37
+ *
38
+ * Same read discipline as `PanelState` (a read during a call gets the next call, never joins it), keyed by
39
+ * udid outside `DeviceState` so a relay reconnect keeps it.
40
+ */
41
+ export declare class PhysicalOrientation {
42
+ private readonly native;
43
+ private readonly flights;
44
+ private readonly known;
45
+ private readonly generations;
46
+ constructor(native?: PhysicalOrientationNative);
47
+ /** A fresh reading, or null when the call fails (`last()` keeps the previous answer). */
48
+ read(udid: string): Promise<DeviceOrientation | null>;
49
+ last(udid: string): DeviceOrientation | null;
50
+ /** What tapflow turned the device to, for when it cannot be read back at all — neither source answered (the
51
+ * guest helper is arm64-only, so an Intel Mac): the memory a single-panel device turns from there. */
52
+ note(udid: string, orientation: DeviceOrientation): void;
53
+ forget(udid: string): void;
54
+ /** Reads until `done` holds, or `timeoutMs` passes (then null). */
55
+ await(udid: string, done: (o: DeviceOrientation) => boolean, timeoutMs: number): Promise<DeviceOrientation | null>;
56
+ private startFlight;
57
+ }
58
+ //# sourceMappingURL=PhysicalOrientation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhysicalOrientation.d.ts","sourceRoot":"","sources":["../src/PhysicalOrientation.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAa/C,qFAAqF;AACrF,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,gBAAgB,GAAG,oBAAoB,GAAG,eAAe,CAAA;AAEtG;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,iBAAiB,EAAE,QAAQ,CAEnE,CAAA;AAID,2CAA2C;AAC3C,wBAAgB,MAAM,CAAC,IAAI,EAAE,iBAAiB,EAAE,SAAS,EAAE,WAAW,GAAG,kBAAkB,GAAG,iBAAiB,CAE9G;AAED,MAAM,WAAW,yBAAyB;IACxC,6EAA6E;IAC7E,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CAChD;AAcD;;;;;;GAMG;AACH,eAAO,MAAM,gCAAgC,EAAE,yBAc9C,CAAA;AAID;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,GAAG,IAAI,CAQvE;AAOD;;;;;;;;;GASG;AACH,qBAAa,mBAAmB;IAMlB,OAAO,CAAC,QAAQ,CAAC,MAAM;IALnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA4B;IACpD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAuC;IAE7D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAA4B;gBAE3B,MAAM,GAAE,yBAA4D;IAEjG,yFAAyF;IACzF,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAarD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,GAAG,IAAI;IAI5C;2GACuG;IACvG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,iBAAiB,GAAG,IAAI;IAIxD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAK1B,mEAAmE;IAC7D,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,iBAAiB,KAAK,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAUxH,OAAO,CAAC,WAAW;CAoBpB"}
@@ -0,0 +1,155 @@
1
+ import { execFile } from 'child_process';
2
+ import { join } from 'path';
3
+ import { promisify } from 'util';
4
+ import { createLogger } from '@tapflowio/agent-core';
5
+ const logger = createLogger('ios-agent:physical-orientation');
6
+ const execFileAsync = promisify(execFile);
7
+ // One `devicectl device orientation get` measured ~0.18 s on the Mac mini (Xcode 27.1).
8
+ const DEVICECTL_TIMEOUT_MS = 10_000;
9
+ // One `guest-helper --orientation` through `simctl spawn` measured 0.33–0.42 s, 1.6 s right after a boot (Xcode 26.6).
10
+ const GUEST_READ_TIMEOUT_MS = 10_000;
11
+ // The same binary `GuestHelper` spawns; not imported from it, which would make this module start the helper's.
12
+ const GUEST_HELPER_BINARY = join(import.meta.dirname, '..', 'bin', 'guest-helper');
13
+ const AWAIT_INTERVAL_MS = 300;
14
+ /**
15
+ * How far each orientation turns the device clockwise as DeviceHub draws it. Measured on the iPhone Duo's
16
+ * cover with Safari up: one clockwise turn from portrait reads `landscapeRight`, and that is the panel
17
+ * DeviceHub shows on its right side.
18
+ */
19
+ export const ORIENTATION_DEGREES = {
20
+ portrait: 0, landscapeRight: 90, portraitUpsideDown: 180, landscapeLeft: 270,
21
+ };
22
+ const ORDER = ['portrait', 'landscapeRight', 'portraitUpsideDown', 'landscapeLeft'];
23
+ /** The orientation a quarter turn away. */
24
+ export function turned(from, direction) {
25
+ return ORDER[(ORDER.indexOf(from) + (direction === 'clockwise' ? 1 : 3)) % 4];
26
+ }
27
+ /** Whether this host's devicectl sees simulators — Xcode 27 and later. Asked once per process; **a failed check
28
+ * is not an answer and is asked again** — kept as "no", an Xcode 27 host would read the guest's value, which does
29
+ * not follow DeviceHub, until the agent restarted. The read fails instead, and the caller keeps the last one. */
30
+ let devicectlSeesSimulators = null;
31
+ function hostDevicectlSeesSimulators() {
32
+ devicectlSeesSimulators ??= execFileAsync('xcodebuild', ['-version'], { timeout: 30_000 }).then(({ stdout }) => Number(/Xcode (\d+)/.exec(stdout)?.[1] ?? 0) >= 27, (e) => { devicectlSeesSimulators = null; throw e; });
33
+ return devicectlSeesSimulators;
34
+ }
35
+ /**
36
+ * Two sources, chosen by the host rather than tried in turn. **Xcode 27**: `devicectl device orientation get`,
37
+ * public. **Older**: devicectl does not see simulators, so the guest helper asks backboardd (`guest-helper
38
+ * --orientation`, the one file private API lives in). Not a fallback for a failed devicectl read on Xcode 27: on
39
+ * iOS 27.1 backboardd's value did not follow a turn made in DeviceHub (measured on the Duo), so it would answer
40
+ * portrait for a device that is not — a failed read is no answer, and the caller keeps the last one.
41
+ */
42
+ export const defaultPhysicalOrientationNative = {
43
+ async readOrientation(udid) {
44
+ if (await hostDevicectlSeesSimulators()) {
45
+ // `-j -` puts the JSON on stdout and everything human-readable on stderr.
46
+ const { stdout } = await execFileAsync('xcrun', ['devicectl', 'device', 'orientation', 'get', '--device', udid, '-j', '-'], { timeout: DEVICECTL_TIMEOUT_MS });
47
+ return JSON.parse(stdout);
48
+ }
49
+ const { stdout } = await execFileAsync('xcrun', ['simctl', 'spawn', udid, GUEST_HELPER_BINARY, '--orientation'], { timeout: GUEST_READ_TIMEOUT_MS });
50
+ const name = /^orientation (\w+)$/m.exec(stdout)?.[1];
51
+ if (!name)
52
+ throw new Error(`guest-helper --orientation said: ${stdout.trim().slice(0, 200)}`);
53
+ // The shape devicectl answers in, so one parser reads both.
54
+ return { result: { deviceOrientation: name } };
55
+ },
56
+ };
57
+ const KNOWN = new Set(ORDER);
58
+ /**
59
+ * The device's physical orientation in a devicectl document, or null if it is not one. Lying flat
60
+ * (`faceUp`/`faceDown`) reads as the last orientation it stood in (`deviceOrientationNonFlat`), which is how
61
+ * a phone on a table keeps its screen. `unknown` is what a device reports until anything has turned it
62
+ * (measured on a fresh iPhone 18 Pro); it boots upright and is drawn upright, so it reads as portrait.
63
+ */
64
+ export function parseOrientation(doc) {
65
+ const result = doc?.result;
66
+ if (!result)
67
+ return null;
68
+ for (const key of ['deviceOrientation', 'deviceOrientationNonFlat']) {
69
+ const value = String(result[key]);
70
+ if (KNOWN.has(value))
71
+ return value;
72
+ }
73
+ return result.deviceOrientationNonFlat === 'unknown' || result.deviceOrientation === 'unknown' ? 'portrait' : null;
74
+ }
75
+ /**
76
+ * Which way the device is held — what DeviceHub turns its whole frame by. **Not the interface orientation**:
77
+ * `devicectl device info displays` follows what the app on screen shows, so a home screen (which never
78
+ * turns on an iPhone) left it at portrait while DeviceHub turned the device four times. This is the
79
+ * orientation the device keeps for whatever app comes up next, and it is what DeviceHub, tapflow's helper,
80
+ * Purple and `devicectl orientation set` all write — measured for each.
81
+ *
82
+ * Same read discipline as `PanelState` (a read during a call gets the next call, never joins it), keyed by
83
+ * udid outside `DeviceState` so a relay reconnect keeps it.
84
+ */
85
+ export class PhysicalOrientation {
86
+ native;
87
+ flights = new Map();
88
+ known = new Map();
89
+ // Bumped by `forget`, for the reason `PanelState` gives.
90
+ generations = new Map();
91
+ constructor(native = defaultPhysicalOrientationNative) {
92
+ this.native = native;
93
+ }
94
+ /** A fresh reading, or null when the call fails (`last()` keeps the previous answer). */
95
+ read(udid) {
96
+ const flight = this.flights.get(udid);
97
+ if (!flight)
98
+ return this.startFlight(udid);
99
+ if (!flight.next) {
100
+ flight.next = flight.current.then(() => {
101
+ const f = this.flights.get(udid);
102
+ if (f)
103
+ f.next = null;
104
+ return this.startFlight(udid);
105
+ });
106
+ }
107
+ return flight.next;
108
+ }
109
+ last(udid) {
110
+ return this.known.get(udid) ?? null;
111
+ }
112
+ /** What tapflow turned the device to, for when it cannot be read back at all — neither source answered (the
113
+ * guest helper is arm64-only, so an Intel Mac): the memory a single-panel device turns from there. */
114
+ note(udid, orientation) {
115
+ this.known.set(udid, orientation);
116
+ }
117
+ forget(udid) {
118
+ this.known.delete(udid);
119
+ this.generations.set(udid, (this.generations.get(udid) ?? 0) + 1);
120
+ }
121
+ /** Reads until `done` holds, or `timeoutMs` passes (then null). */
122
+ async await(udid, done, timeoutMs) {
123
+ const deadline = Date.now() + timeoutMs;
124
+ for (;;) {
125
+ const reading = await this.read(udid);
126
+ if (reading && done(reading))
127
+ return reading;
128
+ if (Date.now() + AWAIT_INTERVAL_MS > deadline)
129
+ return null;
130
+ await new Promise((r) => setTimeout(r, AWAIT_INTERVAL_MS));
131
+ }
132
+ }
133
+ startFlight(udid) {
134
+ const generation = this.generations.get(udid) ?? 0;
135
+ const current = this.native.readOrientation(udid).then((doc) => {
136
+ if ((this.generations.get(udid) ?? 0) !== generation)
137
+ return null;
138
+ const reading = parseOrientation(doc);
139
+ if (reading)
140
+ this.known.set(udid, reading);
141
+ else
142
+ logger.warn(`devicectl gave ${udid} an orientation this agent does not recognise: ${JSON.stringify(doc).slice(0, 400)}`);
143
+ return reading;
144
+ }, (e) => {
145
+ logger.warn(`devicectl orientation failed for ${udid}: ${e instanceof Error ? e.message : String(e)}`);
146
+ return null;
147
+ });
148
+ const flight = { current, next: null };
149
+ this.flights.set(udid, flight);
150
+ void current.then(() => { if (this.flights.get(udid) === flight && !flight.next)
151
+ this.flights.delete(udid); });
152
+ return current;
153
+ }
154
+ }
155
+ //# sourceMappingURL=PhysicalOrientation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PhysicalOrientation.js","sourceRoot":"","sources":["../src/PhysicalOrientation.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,7 @@
1
+ export interface PanelSize {
2
+ width: number;
3
+ height: number;
4
+ }
1
5
  export interface StreamFrame {
2
6
  payload: Buffer;
3
7
  /** H.264 IDR (keyframe). Always false for JPEG. */
@@ -12,8 +16,15 @@ export declare class ScreenCaptureStreamer {
12
16
  private readonly fps;
13
17
  private readonly codec;
14
18
  private readonly maxSize;
19
+ private panel;
15
20
  private proc;
16
- constructor(udid: string, fps?: number, codec?: 'jpeg' | 'h264', maxSize?: number);
21
+ constructor(udid: string, fps?: number, codec?: 'jpeg' | 'h264', maxSize?: number, panel?: PanelSize | null);
22
+ /**
23
+ * Switch a multi-panel device's capture to another panel (a fold), as a text line on the helper's stdin.
24
+ * The helper restarts the H.264 session at the new size with a keyframe first. Remembered, so it is
25
+ * never sent twice in a row; a restarted streamer is built with the panel instead (`--panel`).
26
+ */
27
+ selectPanel(panel: PanelSize): void;
17
28
  /**
18
29
  * Forces an IDR on the next H.264 frame (1-byte stdin command to the helper).
19
30
  * Used by the relay's drop-to-keyframe recovery to resync fast. No-op for JPEG.
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenCaptureStreamer.d.ts","sourceRoot":"","sources":["../src/ScreenCaptureStreamer.ts"],"names":[],"mappings":"AAoCA,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAA;CAClB;AAGD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,GACZ;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAczC;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAGtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAX1B,OAAO,CAAC,IAAI,CAA8C;gBAMvC,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAW,EAChB,KAAK,GAAE,MAAM,GAAG,MAAe,EAG/B,OAAO,GAAE,MAAU;IAGtC;;;OAGG;IACH,eAAe,IAAI,IAAI;IAMvB,KAAK,IAAI,cAAc,CAAC,WAAW,CAAC;CAyDrC"}
1
+ {"version":3,"file":"ScreenCaptureStreamer.d.ts","sourceRoot":"","sources":["../src/ScreenCaptureStreamer.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAA;IACf,mDAAmD;IACnD,QAAQ,EAAE,OAAO,CAAA;CAClB;AAGD,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,GACZ;IAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAczC;AAED,qBAAa,qBAAqB;IAO9B,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,GAAG;IACpB,OAAO,CAAC,QAAQ,CAAC,KAAK;IAGtB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAGxB,OAAO,CAAC,KAAK;IAdf,OAAO,CAAC,IAAI,CAA8C;gBAMvC,IAAI,EAAE,MAAM,EACZ,GAAG,GAAE,MAAW,EAChB,KAAK,GAAE,MAAM,GAAG,MAAe,EAG/B,OAAO,GAAE,MAAU,EAG5B,KAAK,GAAE,SAAS,GAAG,IAAW;IAGxC;;;;OAIG;IACH,WAAW,CAAC,KAAK,EAAE,SAAS,GAAG,IAAI;IAOnC;;;OAGG;IACH,eAAe,IAAI,IAAI;IAMvB,KAAK,IAAI,cAAc,CAAC,WAAW,CAAC;CA4DrC"}
@@ -21,13 +21,17 @@ function ensureCompiled() {
21
21
  throw new PlatformError('screencapture-helper binary missing and Swift source not found — reinstall @tapflowio/ios-agent');
22
22
  }
23
23
  logger.info('compiling screencapture-helper...');
24
+ // -O: the helper runs per frame for the whole session; unoptimised it cost ~2 points of a core more while a video
25
+ // played (11–12% against ~10%, measured).
24
26
  execFileSync('swiftc', [
25
27
  SWIFT_SRC,
28
+ '-O',
26
29
  '-o', BINARY,
27
30
  '-framework', 'CoreVideo',
28
31
  '-framework', 'ImageIO',
29
32
  '-framework', 'VideoToolbox',
30
33
  '-framework', 'CoreMedia',
34
+ '-framework', 'Metal',
31
35
  ], { stdio: ['ignore', 'ignore', 'inherit'] });
32
36
  logger.info('compiled OK');
33
37
  }
@@ -54,6 +58,7 @@ export class ScreenCaptureStreamer {
54
58
  fps;
55
59
  codec;
56
60
  maxSize;
61
+ panel;
57
62
  proc = null;
58
63
  // udid first, and the defaulted parameters after it. It used to carry `= 'booted'` and sit second;
59
64
  // dropping that default left `fps = 30` unreachable, since every caller has to pass fps to get to
@@ -61,11 +66,28 @@ export class ScreenCaptureStreamer {
61
66
  constructor(udid, fps = 30, codec = 'jpeg',
62
67
  // Downscale cap (longest side, px) the helper encodes at; 0 = native. Passed to the Swift helper
63
68
  // as TAPFLOW_IOS_MAX_SIZE so the per-session tier wins over any inherited env value.
64
- maxSize = 0) {
69
+ maxSize = 0,
70
+ // A multi-panel device's panel, by framebuffer size; null captures the largest surface, which is the
71
+ // only panel of every other device. See `selectPanel`.
72
+ panel = null) {
65
73
  this.udid = udid;
66
74
  this.fps = fps;
67
75
  this.codec = codec;
68
76
  this.maxSize = maxSize;
77
+ this.panel = panel;
78
+ }
79
+ /**
80
+ * Switch a multi-panel device's capture to another panel (a fold), as a text line on the helper's stdin.
81
+ * The helper restarts the H.264 session at the new size with a keyframe first. Remembered, so it is
82
+ * never sent twice in a row; a restarted streamer is built with the panel instead (`--panel`).
83
+ */
84
+ selectPanel(panel) {
85
+ if (this.panel?.width === panel.width && this.panel?.height === panel.height)
86
+ return;
87
+ this.panel = panel;
88
+ const stdin = this.proc?.stdin;
89
+ if (stdin?.writable)
90
+ stdin.write(`panel ${panel.width}x${panel.height}\n`);
69
91
  }
70
92
  /**
71
93
  * Forces an IDR on the next H.264 frame (1-byte stdin command to the helper).
@@ -80,7 +102,8 @@ export class ScreenCaptureStreamer {
80
102
  }
81
103
  start() {
82
104
  ensureCompiled();
83
- const proc = spawn(BINARY, [String(this.fps), this.udid, this.codec], {
105
+ const panelArgs = this.panel ? ['--panel', `${this.panel.width}x${this.panel.height}`] : [];
106
+ const proc = spawn(BINARY, [String(this.fps), this.udid, this.codec, ...panelArgs], {
84
107
  stdio: ['pipe', 'pipe', 'pipe'],
85
108
  env: { ...process.env, TAPFLOW_IOS_MAX_SIZE: String(this.maxSize) },
86
109
  });
@@ -108,7 +131,9 @@ export class ScreenCaptureStreamer {
108
131
  proc.stdout.on('data', (chunk) => {
109
132
  if (done)
110
133
  return;
111
- buf = Buffer.concat([buf, chunk]);
134
+ // Most chunks start a frame with nothing left over; `concat` would copy each one anyway. The frames point
135
+ // into `chunk` then, which the stream never reuses.
136
+ buf = buf.length === 0 ? chunk : Buffer.concat([buf, chunk]);
112
137
  const { frames, rest } = parseStreamFrames(buf, h264);
113
138
  for (const f of frames)
114
139
  controller.enqueue(f);
@@ -1 +1 @@
1
- {"version":3,"file":"ScreenCaptureStreamer.js","sourceRoot":"","sources":["../src/ScreenCaptureStreamer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScreenCaptureStreamer.js","sourceRoot":"","sources":["../src/ScreenCaptureStreamer.ts"],"names":[],"mappings":"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"}
@@ -5,15 +5,19 @@ export declare function launchFailureReason(e: unknown): string;
5
5
  import type { Device } from '@tapflowio/agent-core';
6
6
  import type { FormFactor } from '@tapflowio/protocol';
7
7
  import { type SimctlRunner } from './simctl.js';
8
+ import { type IntegratedScreen, type TypePanel } from './panels.js';
8
9
  export declare function isDeviceMissingError(err: unknown): boolean;
9
10
  /** The device clipboard held more than `MAX_CLIPBOARD_BYTES`. The app did copy — we just cannot
10
11
  * carry it — so a caller mid-handshake must NOT restore over it. */
11
12
  export declare class ClipboardTooLargeError extends PlatformError {
12
13
  }
14
+ /** A plist as JSON, the way `plutil` converts it. Injectable so tests never read the host's device types. */
15
+ export type PlistReader = (path: string) => Promise<unknown>;
13
16
  export declare class SimctlWrapper {
14
17
  private readonly runner;
18
+ private readonly readPlist;
15
19
  private readonly kbd;
16
- constructor(runner?: SimctlRunner);
20
+ constructor(runner?: SimctlRunner, readPlist?: PlistReader);
17
21
  /**
18
22
  * `timeoutMs` bounds the underlying `xcrun simctl list`. Left off everywhere except the boot poll:
19
23
  * a blanket timeout would fail a legitimately slow call, which is the reason `SimctlExecOpts.timeoutMs`
@@ -30,6 +34,19 @@ export declare class SimctlWrapper {
30
34
  * Rejects on failure; the caller falls back to its last answer, or to none.
31
35
  */
32
36
  formFactorsByType(): Promise<Map<string, FormFactor>>;
37
+ /**
38
+ * How many integrated panels each of `typeIds` has, from its `capabilities.plist`. A type whose plist
39
+ * cannot be read counts as one panel: that is every device type before the Duo, and a wrong "one" leaves
40
+ * a multi-panel device on the Indigo path, which is how it behaved before this existed.
41
+ */
42
+ integratedPanelCounts(typeIds: string[]): Promise<Map<string, number>>;
43
+ /** The integrated panels of `typeId` — empty when the type or its plist lists none (Xcode 26). **Rejects when
44
+ * the plist cannot be read**, unlike `integratedPanelCounts`: `TypePanels` keeps an answer for the life of the
45
+ * process and drops only a rejection, so a slow `plutil` read as "no panels" stood until the agent restarted —
46
+ * the unfolded panel drawn a quarter off, and the panels at two scales. */
47
+ typePanels(typeId: string): Promise<TypePanel[]>;
48
+ /** The integrated panels of a booted device. Their UUIDs change on every boot, so this is read per boot. */
49
+ integratedScreens(udid: string): Promise<IntegratedScreen[]>;
33
50
  boot(deviceId: string): Promise<void>;
34
51
  static readonly BOOT_READY_TIMEOUT_MS = 90000;
35
52
  private static readonly BOOT_POLL_INTERVAL_MS;
@@ -1 +1 @@
1
- {"version":3,"file":"SimctlWrapper.d.ts","sourceRoot":"","sources":["../src/SimctlWrapper.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"SimctlWrapper.d.ts","sourceRoot":"","sources":["../src/SimctlWrapper.ts"],"names":[],"mappings":"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"}