@tapflowio/protocol 0.17.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 tapflow contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,17 @@
1
+ # @tapflowio/protocol
2
+
3
+ The wire contract for [tapflow](https://github.com/jo-duchan/tapflow)'s WebSocket traffic — the message types exchanged between the browser, the relay, and the device agents.
4
+
5
+ **Types only.** Nothing in this package emits runtime code, so importing it with `import type` leaves no trace in a bundle.
6
+
7
+ ```ts
8
+ import type { RelayToBrowser, BrowserToRelay } from '@tapflowio/protocol'
9
+ ```
10
+
11
+ It exists so the relay, the dashboard and the MCP server cannot drift apart on what a message looks like. It is published because `@tapflowio/relay` and `@tapflowio/mcp-server` depend on it; most users will never import it directly.
12
+
13
+ The binary frame envelope is a separate format and is not described here.
14
+
15
+ ## License
16
+
17
+ MIT
@@ -0,0 +1,359 @@
1
+ /** Agent resource sample, reported on `agent:resources` and echoed in a session listing. */
2
+ export interface AgentResources {
3
+ cpuPercent: number;
4
+ memUsedMB: number;
5
+ memTotalMB: number;
6
+ slotsAvailable: number;
7
+ slotsTotal: number;
8
+ /** Date.now() */
9
+ reportedAt: number;
10
+ }
11
+ /** What an agent reports about a device in `agent:register`. No `sessionId`/`busy` — the relay
12
+ * owns those. */
13
+ export interface DeviceReport {
14
+ id: string;
15
+ name: string;
16
+ platform: string;
17
+ status: string;
18
+ osVersion?: string;
19
+ }
20
+ /** A device as the relay lists it, after adding what only the relay knows. Named `DeviceSummary`
21
+ * rather than `DeviceInfo` because both packages already used that name for different shapes:
22
+ * the relay for this, the dashboard for the `session:deviceInfo` payload (`DeviceDetails`). */
23
+ export interface DeviceSummary extends DeviceReport {
24
+ sessionId: string;
25
+ busy: boolean;
26
+ }
27
+ /** The `session:deviceInfo` payload — what the viewer shows in its info card. */
28
+ export interface DeviceDetails {
29
+ deviceName: string;
30
+ osVersion: string;
31
+ }
32
+ /** `agents:listed` groups devices by agent machine. */
33
+ export interface SessionInfo {
34
+ agentName?: string;
35
+ platform?: string;
36
+ resources?: AgentResources;
37
+ devices: DeviceSummary[];
38
+ }
39
+ export interface ChromeRect {
40
+ x: number;
41
+ y: number;
42
+ width: number;
43
+ height: number;
44
+ }
45
+ export interface ChromeButton {
46
+ name: string;
47
+ accessibilityTitle: string;
48
+ anchor: string;
49
+ /** true = button is above the device frame (e.g. home button) */
50
+ onTop: boolean;
51
+ /** button center at retracted/default position, in 2× composite px */
52
+ normalOffset: {
53
+ x: number;
54
+ y: number;
55
+ };
56
+ /** button center at extended/hover position, in 2× composite px */
57
+ rolloverOffset: {
58
+ x: number;
59
+ y: number;
60
+ };
61
+ buttonW: number;
62
+ buttonH: number;
63
+ /** HID usage page for SimulatorKit injection (0 = unknown) */
64
+ usagePage: number;
65
+ /** HID usage code (0 = unknown) */
66
+ usage: number;
67
+ /** base64 PNG of the button at 2× (for the CSS-animated overlay) */
68
+ buttonPng?: string;
69
+ /** base64 PNG of the pressed state (imageDown asset) */
70
+ pressedPng?: string;
71
+ pressedRect?: ChromeRect;
72
+ }
73
+ export interface AndroidButton {
74
+ name: string;
75
+ accessibilityTitle: string;
76
+ keyCode: number;
77
+ }
78
+ /** iOS device chrome — the bezel artwork and hit regions the viewer composites around the screen. */
79
+ export interface ChromeData {
80
+ /** full composite PDF at 2× — device frame visible, screen hole transparent */
81
+ framePng: string;
82
+ bezelWidth: number;
83
+ bezelHeight: number;
84
+ /** full PDF width including devicePadding, at 2× px */
85
+ compositeWidth: number;
86
+ compositeHeight: number;
87
+ padding: {
88
+ left: number;
89
+ right: number;
90
+ top: number;
91
+ bottom: number;
92
+ };
93
+ screenRect: ChromeRect;
94
+ /** screen corner radius in 2× px (0 if the device has no rounded corners) */
95
+ screenCornerRadius: number;
96
+ logicalWidth: number;
97
+ logicalHeight: number;
98
+ buttons: ChromeButton[];
99
+ }
100
+ /** Android chrome — no bezel artwork; the emulator frame carries it. */
101
+ export interface AndroidChrome {
102
+ buttons: AndroidButton[];
103
+ streamType: 'h264';
104
+ screenWidth?: number;
105
+ screenHeight?: number;
106
+ cornerRadius?: number;
107
+ }
108
+ /** The `session:chrome` payload. The relay never reads it — it stores and forwards — but the
109
+ * contract still states the shape, because the viewer parses it. A new platform adds its variant
110
+ * here; relay and dashboard code stay unchanged, which is what the OCP rule asks for. */
111
+ export type ChromePayload = ChromeData | AndroidChrome;
112
+ export type RelayToAgent = {
113
+ type: 'agent:registered';
114
+ registeredSessions: Array<{
115
+ deviceId: string;
116
+ sessionId: string;
117
+ }>;
118
+ } | {
119
+ type: 'stream:request-idr';
120
+ sessionId: string;
121
+ } | {
122
+ type: 'device:shutdown';
123
+ sessionId: string;
124
+ payload: {
125
+ deviceId: string;
126
+ };
127
+ } | {
128
+ type: 'app:install';
129
+ sessionId: string;
130
+ payload: {
131
+ filePath: string;
132
+ bundleId: string | null;
133
+ };
134
+ } | {
135
+ type: 'app:launch';
136
+ sessionId: string;
137
+ payload: {
138
+ bundleId: string;
139
+ };
140
+ } | {
141
+ type: 'screenshot:request';
142
+ sessionId: string;
143
+ requestId: string;
144
+ format: 'png' | 'jpeg';
145
+ } | {
146
+ type: 'ui:tree:request';
147
+ sessionId: string;
148
+ requestId: string;
149
+ };
150
+ /**
151
+ * Why a session stopped existing, server-side. A literal union rather than a string so that adding
152
+ * a case is a compile-time event for every consumer that switches on it.
153
+ *
154
+ * Named `session:terminated`, not `session:ended`: `session:end` is already a message the *browser*
155
+ * sends to ask for shutdown, and the two would sit one letter apart in the same switch. This one
156
+ * travels the other way and is not an acknowledgement of that request.
157
+ */
158
+ export type SessionTerminatedReason = 'agent-disconnected';
159
+ export type RelayToBrowser = {
160
+ type: 'agents:listed';
161
+ sessions: SessionInfo[];
162
+ } | {
163
+ type: 'stream:registered';
164
+ } | {
165
+ type: 'session:joined';
166
+ sessionId: string;
167
+ capabilities: string[];
168
+ } | {
169
+ type: 'session:terminated';
170
+ sessionId: string;
171
+ reason: SessionTerminatedReason;
172
+ } | {
173
+ type: 'session:agent-away';
174
+ sessionId: string;
175
+ } | {
176
+ type: 'session:rebound';
177
+ sessionId: string;
178
+ capabilities: string[];
179
+ } | {
180
+ type: 'session:chrome';
181
+ payload: ChromePayload;
182
+ } | {
183
+ type: 'session:deviceInfo';
184
+ payload: DeviceDetails;
185
+ } | {
186
+ type: 'device:ready';
187
+ payload: {
188
+ deviceId: string;
189
+ };
190
+ } | {
191
+ type: 'error';
192
+ message: string;
193
+ } | {
194
+ type: 'app:install-error';
195
+ sessionId: string;
196
+ message: string;
197
+ } | {
198
+ type: 'app:launch-error';
199
+ sessionId: string;
200
+ message: string;
201
+ } | {
202
+ type: 'device:boot-error';
203
+ sessionId: string;
204
+ message: string;
205
+ } | {
206
+ type: 'open-url:error';
207
+ sessionId: string;
208
+ message: string;
209
+ } | {
210
+ type: 'app:clear-state-error';
211
+ sessionId: string;
212
+ message: string;
213
+ } | {
214
+ type: 'input:error';
215
+ sessionId: string;
216
+ message: string;
217
+ } | {
218
+ type: 'clipboard:error';
219
+ sessionId: string;
220
+ requestId: string;
221
+ message: string;
222
+ };
223
+ /** Everything the relay originates. Messages it merely forwards keep their inbound type — they are
224
+ * not re-created, so they are not checked against this union. */
225
+ export type RelayOutbound = RelayToAgent | RelayToBrowser;
226
+ /** Key input. The payload carries `code` — a `KeyboardEvent.code` name — and `modifiers` as a
227
+ * **bitmap**, not a list and not `key`.
228
+ *
229
+ * The dashboard union declared `{ key: string }` while every sender and both agents used
230
+ * `{ code, modifiers }`; the mismatch survived because `send()` took `object`. The authority is
231
+ * the consumer: `IOSAgent.ts` reads `{ code: string; modifiers?: number }` and passes the number
232
+ * straight to `touchHelper.sendKey(usage, modifiers ?? 0)`, where it is the HID modifier bitmap
233
+ * documented in packages/ios-agent/AGENTS.md (touch-helper type 9). */
234
+ export interface InputKey {
235
+ type: 'input:key';
236
+ sessionId: string;
237
+ payload: {
238
+ code: string;
239
+ modifiers?: number;
240
+ };
241
+ }
242
+ export interface Point {
243
+ x: number;
244
+ y: number;
245
+ }
246
+ /** The two clipboard requests a viewer can make. Kept as its own union because the bridge sends
247
+ * them through one call that takes the type as an argument. */
248
+ export type ClipboardRequest = {
249
+ type: 'clipboard:read';
250
+ sessionId: string;
251
+ requestId: string;
252
+ payload?: {
253
+ press?: 'copy' | 'cut';
254
+ };
255
+ } | {
256
+ type: 'clipboard:write';
257
+ sessionId: string;
258
+ requestId: string;
259
+ payload: {
260
+ text: string;
261
+ pasteAfter?: boolean;
262
+ };
263
+ };
264
+ export type BrowserToRelay = {
265
+ type: 'agents:list';
266
+ } | {
267
+ type: 'session:start';
268
+ sessionId: string;
269
+ } | {
270
+ type: 'session:end';
271
+ sessionId: string;
272
+ } | {
273
+ type: 'session:leave';
274
+ sessionId: string;
275
+ } | {
276
+ type: 'device:boot';
277
+ sessionId: string;
278
+ payload: {
279
+ deviceId: string;
280
+ resetMode?: 'app-only' | 'full-erase';
281
+ acceptH264?: boolean;
282
+ secureContext?: boolean;
283
+ };
284
+ } | {
285
+ type: 'device:shutdown';
286
+ sessionId: string;
287
+ payload: {
288
+ deviceId: string;
289
+ };
290
+ } | {
291
+ type: 'app:install';
292
+ sessionId: string;
293
+ buildId: number;
294
+ } | {
295
+ type: 'app:launch';
296
+ sessionId: string;
297
+ buildId: number;
298
+ } | {
299
+ type: 'app:clear-state';
300
+ sessionId: string;
301
+ payload?: {
302
+ bundleId?: string;
303
+ };
304
+ } | {
305
+ type: 'open-url';
306
+ sessionId: string;
307
+ payload: {
308
+ url: string;
309
+ };
310
+ } | {
311
+ type: 'input:touch:start';
312
+ sessionId: string;
313
+ payload: Point;
314
+ } | {
315
+ type: 'input:touch:move';
316
+ sessionId: string;
317
+ payload: Point;
318
+ } | {
319
+ type: 'input:touch:end';
320
+ sessionId: string;
321
+ payload?: Point;
322
+ } | {
323
+ type: 'input:pinch:start';
324
+ sessionId: string;
325
+ payload: {
326
+ f0: Point;
327
+ f1: Point;
328
+ };
329
+ } | {
330
+ type: 'input:pinch:move';
331
+ sessionId: string;
332
+ payload: {
333
+ f0: Point;
334
+ f1: Point;
335
+ };
336
+ } | {
337
+ type: 'input:pinch:end';
338
+ sessionId: string;
339
+ } | InputKey | {
340
+ type: 'input:type';
341
+ sessionId: string;
342
+ payload: {
343
+ text: string;
344
+ };
345
+ } | {
346
+ type: 'input:button';
347
+ sessionId: string;
348
+ payload: {
349
+ name: string;
350
+ phase?: 'down' | 'up';
351
+ };
352
+ } | {
353
+ type: 'input:rotate';
354
+ sessionId: string;
355
+ } | {
356
+ type: 'input:keyboard:toggle';
357
+ sessionId: string;
358
+ } | ClipboardRequest;
359
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js ADDED
@@ -0,0 +1,11 @@
1
+ // tapflow wire protocol — the WebSocket message contract shared by browser, relay and agents.
2
+ //
3
+ // Scope: JSON messages only. The binary frame envelope (TFFE) is not here — see
4
+ // contributing/frame-envelope.md. Runtime validators, if they ever exist, belong in this package
5
+ // next to the types they validate.
6
+ //
7
+ // Types only, deliberately. Consumers use `import type`, so nothing from this package reaches a
8
+ // runtime bundle. Do not add `enum` or const objects: they compile to runtime values, which would
9
+ // put JavaScript into the dashboard bundle the moment someone referenced one as a value.
10
+ export {};
11
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,8FAA8F;AAC9F,EAAE;AACF,gFAAgF;AAChF,iGAAiG;AACjG,mCAAmC;AACnC,EAAE;AACF,gGAAgG;AAChG,kGAAkG;AAClG,yFAAyF"}
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@tapflowio/protocol",
3
+ "version": "0.17.0",
4
+ "description": "Wire protocol contract for tapflow — the WebSocket message types exchanged between browser, relay, and device agents",
5
+ "keywords": [
6
+ "tapflow",
7
+ "protocol",
8
+ "websocket",
9
+ "types",
10
+ "qa"
11
+ ],
12
+ "homepage": "https://github.com/jo-duchan/tapflow",
13
+ "bugs": "https://github.com/jo-duchan/tapflow/issues",
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "https://github.com/jo-duchan/tapflow.git",
17
+ "directory": "packages/protocol"
18
+ },
19
+ "license": "MIT",
20
+ "author": "tapflow contributors",
21
+ "type": "module",
22
+ "main": "dist/index.js",
23
+ "types": "dist/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "source": "./src/index.ts",
28
+ "tsx": "./src/index.ts",
29
+ "import": "./dist/index.js",
30
+ "default": "./dist/index.js"
31
+ }
32
+ },
33
+ "files": [
34
+ "dist",
35
+ "README.md",
36
+ "LICENSE"
37
+ ],
38
+ "engines": {
39
+ "node": ">=20.12.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ },
44
+ "scripts": {
45
+ "build": "tsc -b",
46
+ "typecheck": "tsc -b && tsc -p tsconfig.assertions.json",
47
+ "lint": "eslint src"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "^5.0.0"
51
+ }
52
+ }