@motebit/protocol 1.2.0 → 1.3.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/dist/artifact-type.d.ts +118 -0
- package/dist/artifact-type.d.ts.map +1 -0
- package/dist/artifact-type.js +97 -0
- package/dist/artifact-type.js.map +1 -0
- package/dist/audience.d.ts +108 -0
- package/dist/audience.d.ts.map +1 -0
- package/dist/audience.js +104 -0
- package/dist/audience.js.map +1 -0
- package/dist/co-browse.d.ts +369 -0
- package/dist/co-browse.d.ts.map +1 -0
- package/dist/co-browse.js +64 -0
- package/dist/co-browse.js.map +1 -0
- package/dist/computer-use.d.ts +463 -3
- package/dist/computer-use.d.ts.map +1 -1
- package/dist/computer-use.js +40 -0
- package/dist/computer-use.js.map +1 -1
- package/dist/index.d.ts +152 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -1
- package/dist/money.d.ts +33 -0
- package/dist/money.d.ts.map +1 -0
- package/dist/money.js +41 -0
- package/dist/money.js.map +1 -0
- package/dist/perception.d.ts +308 -0
- package/dist/perception.d.ts.map +1 -0
- package/dist/perception.js +9 -0
- package/dist/perception.js.map +1 -0
- package/dist/retention-policy.d.ts +8 -1
- package/dist/retention-policy.d.ts.map +1 -1
- package/dist/retention-policy.js +18 -0
- package/dist/retention-policy.js.map +1 -1
- package/dist/sensitivity.d.ts +73 -0
- package/dist/sensitivity.d.ts.map +1 -0
- package/dist/sensitivity.js +97 -0
- package/dist/sensitivity.js.map +1 -0
- package/dist/transparency.d.ts +116 -0
- package/dist/transparency.d.ts.map +1 -0
- package/dist/transparency.js +67 -0
- package/dist/transparency.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,369 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Co-browse — control state machine for the `virtual_browser`
|
|
3
|
+
* embodiment.
|
|
4
|
+
*
|
|
5
|
+
* Doctrine: `motebit-computer.md` §"Embodiment modes" places co-browse
|
|
6
|
+
* as a *substate* of `virtual_browser`, not a new mode. Same isolated
|
|
7
|
+
* Chromium, same session-scoped consent boundary; what changes is who
|
|
8
|
+
* holds the pointer/keyboard. The `ControlState` here is the typed
|
|
9
|
+
* "who's driving" axis the runtime + slab + dispatcher all read.
|
|
10
|
+
*
|
|
11
|
+
* Why a discriminated union and not a flat enum. The four state names
|
|
12
|
+
* (`user`, `motebit`, `handoff_pending`, `paused`) are stable; what
|
|
13
|
+
* varies is the data each state carries. `handoff_pending` needs to
|
|
14
|
+
* know who currently holds and who's requesting (so a deny resolves
|
|
15
|
+
* to the right side); `paused` needs to remember who was driving so
|
|
16
|
+
* `resume` doesn't lose continuity. Discriminated union keeps the
|
|
17
|
+
* face of the type aligned with the four-state shape while making
|
|
18
|
+
* the per-state shape a compile-time fact, not a "remember to
|
|
19
|
+
* inspect this field when kind is X" comment.
|
|
20
|
+
*
|
|
21
|
+
* Why fail-closed-to-user on disconnect. The user is the always-
|
|
22
|
+
* trusted party in motebit's trust model — every other party
|
|
23
|
+
* (including the motebit itself, including any peer) is downstream of
|
|
24
|
+
* the user's identity. A connection drop could mean the user has
|
|
25
|
+
* actively stopped the session, lost network, or closed the tab; in
|
|
26
|
+
* any of those cases the safest semantics is revert-to-user (the
|
|
27
|
+
* motebit cannot continue acting on a page the user can no longer
|
|
28
|
+
* observe). Doctrine: spec/computer-use-v1.md §3.3 user-floor
|
|
29
|
+
* invariant, applied to control rather than dispatch.
|
|
30
|
+
*
|
|
31
|
+
* @alpha
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Who currently holds (or is requesting) drive control of the
|
|
35
|
+
* isolated browser. Two parties only — peers don't hold control via
|
|
36
|
+
* this primitive (that's a different substate of `virtual_browser`
|
|
37
|
+
* gated through the federation trust graph).
|
|
38
|
+
* @alpha
|
|
39
|
+
*/
|
|
40
|
+
export type ControlHolder = "user" | "motebit";
|
|
41
|
+
/**
|
|
42
|
+
* The "who's driving" state of a co-browse session. Discriminated by
|
|
43
|
+
* `kind`:
|
|
44
|
+
*
|
|
45
|
+
* - `user` — user drives. Motebit observes via screencast. The
|
|
46
|
+
* default state at session open.
|
|
47
|
+
* - `motebit` — motebit drives. User observes. AI-loop tool calls
|
|
48
|
+
* to `computer` execute action; the live screencast surfaces
|
|
49
|
+
* what the AI is doing.
|
|
50
|
+
* - `handoff_pending` — a control change has been requested and
|
|
51
|
+
* is awaiting approval. `current` is the party currently holding;
|
|
52
|
+
* `requesting` is the party asking to take over. The `current`
|
|
53
|
+
* party still drives until the request resolves.
|
|
54
|
+
* - `paused` — neither party acts. Sourced from the v1.2 user-
|
|
55
|
+
* floor halt primitive; `previousDriver` lets `resume` restore
|
|
56
|
+
* continuity.
|
|
57
|
+
*
|
|
58
|
+
* Transitions are pure: every state is reachable only by the typed
|
|
59
|
+
* inputs declared in `CoBrowseTransitionKind`. No "anything → any"
|
|
60
|
+
* fallbacks — drift here would mean the consent contract becomes a
|
|
61
|
+
* thing you discover at runtime, not a thing you read off the type.
|
|
62
|
+
* @alpha
|
|
63
|
+
*/
|
|
64
|
+
export type ControlState = {
|
|
65
|
+
readonly kind: "user";
|
|
66
|
+
} | {
|
|
67
|
+
readonly kind: "motebit";
|
|
68
|
+
} | {
|
|
69
|
+
readonly kind: "handoff_pending";
|
|
70
|
+
readonly current: ControlHolder;
|
|
71
|
+
readonly requesting: ControlHolder;
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: "paused";
|
|
74
|
+
readonly previousDriver: ControlHolder;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Closed set of transitions the state machine accepts. Every audit
|
|
78
|
+
* event for a control change carries one of these as its
|
|
79
|
+
* `transition_kind`. Adding a new kind is a protocol change — the
|
|
80
|
+
* audit event's structural set must stay closed so verifiers know
|
|
81
|
+
* which transitions are valid history.
|
|
82
|
+
* @alpha
|
|
83
|
+
*/
|
|
84
|
+
export declare const CO_BROWSE_TRANSITION_KINDS: readonly ["request_control", "grant_control", "deny_control", "reclaim_control", "release_control", "yield_control", "pause", "resume", "disconnect"];
|
|
85
|
+
/** @alpha */
|
|
86
|
+
export type CoBrowseTransitionKind = (typeof CO_BROWSE_TRANSITION_KINDS)[number];
|
|
87
|
+
/**
|
|
88
|
+
* Audit-event payload for a co-browse control transition. Emitted on
|
|
89
|
+
* every successful state change. Doctrine: every receipt is the
|
|
90
|
+
* substrate of awareness — control transitions are receipt-level
|
|
91
|
+
* events the agent can read back via `list_events` to reconstruct
|
|
92
|
+
* "who was driving when."
|
|
93
|
+
*
|
|
94
|
+
* `from` and `to` are full `ControlState` values, so a verifier
|
|
95
|
+
* replaying the event log can independently rebuild the state
|
|
96
|
+
* machine without re-running the transition functions. `initiator`
|
|
97
|
+
* is the party that requested the transition (for `disconnect` it's
|
|
98
|
+
* `"system"` — the runtime detected the drop, not a party action).
|
|
99
|
+
* @alpha
|
|
100
|
+
*/
|
|
101
|
+
export interface CoBrowseControlChangedPayload {
|
|
102
|
+
readonly session_id: string;
|
|
103
|
+
readonly motebit_id: string;
|
|
104
|
+
readonly transition_kind: CoBrowseTransitionKind;
|
|
105
|
+
readonly initiator: ControlHolder | "system";
|
|
106
|
+
readonly from: ControlState;
|
|
107
|
+
readonly to: ControlState;
|
|
108
|
+
readonly timestamp: number;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Modifier keys held during a user input event. Booleans for each
|
|
112
|
+
* standard modifier the AI loop's gate reads back; matches the
|
|
113
|
+
* shape `KeyboardEvent` exposes in the browser.
|
|
114
|
+
* @alpha
|
|
115
|
+
*/
|
|
116
|
+
export interface KeyModifiers {
|
|
117
|
+
readonly ctrl: boolean;
|
|
118
|
+
readonly meta: boolean;
|
|
119
|
+
readonly alt: boolean;
|
|
120
|
+
readonly shift: boolean;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Wire format for a user-driven input event forwarded into the cloud
|
|
124
|
+
* Chromium. Carries the raw data Chromium needs to dispatch (text,
|
|
125
|
+
* coordinates) — the audit shape (`UserInputForwardedPayload`)
|
|
126
|
+
* redacts before logging.
|
|
127
|
+
*
|
|
128
|
+
* Coordinate system: `click.x` and `click.y` are logical-pixel
|
|
129
|
+
* coordinates against the cloud Chromium viewport (same coordinate
|
|
130
|
+
* system `ComputerAction.click` uses for motebit-side dispatch).
|
|
131
|
+
* The capture surface is responsible for translating screen pixels
|
|
132
|
+
* to logical pixels via the screencast's natural dimensions.
|
|
133
|
+
*
|
|
134
|
+
* @alpha
|
|
135
|
+
*/
|
|
136
|
+
export type UserInputEvent =
|
|
137
|
+
/**
|
|
138
|
+
* Pointer click. Logical-pixel coordinates against the cloud
|
|
139
|
+
* Chromium viewport.
|
|
140
|
+
*/
|
|
141
|
+
{
|
|
142
|
+
readonly kind: "click";
|
|
143
|
+
readonly x: number;
|
|
144
|
+
readonly y: number;
|
|
145
|
+
readonly button: "left" | "right" | "middle";
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Keyboard event. `key` is the browser `KeyboardEvent.key`
|
|
149
|
+
* value — single character for printable input ("a"), named
|
|
150
|
+
* key for control keys ("Enter", "Backspace"), Playwright-
|
|
151
|
+
* compatible combo for shortcuts ("Control+a"). The cloud-browser
|
|
152
|
+
* service maps:
|
|
153
|
+
* - Single printable char + no modifiers → `page.keyboard.type(key)`.
|
|
154
|
+
* - Named key OR any modifier present → `page.keyboard.press(combo)`.
|
|
155
|
+
*/
|
|
156
|
+
| {
|
|
157
|
+
readonly kind: "key";
|
|
158
|
+
readonly key: string;
|
|
159
|
+
readonly modifiers: KeyModifiers;
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Clipboard paste. The wire carries raw text; the audit logs only
|
|
163
|
+
* length + line_count + looks_like_url (never content). Server-
|
|
164
|
+
* side: dispatched as `page.keyboard.type(text)` for v1, which
|
|
165
|
+
* synthesizes per-character keypresses. A future slice may
|
|
166
|
+
* upgrade to CDP `Input.insertText` for true paste semantics.
|
|
167
|
+
*/
|
|
168
|
+
| {
|
|
169
|
+
readonly kind: "paste";
|
|
170
|
+
readonly text: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Mouse wheel scroll. Logical-pixel `(x, y)` is the cursor anchor
|
|
174
|
+
* for the scroll (Playwright requires the cursor over the
|
|
175
|
+
* scrollable element); `(dx, dy)` are the scroll deltas in CSS
|
|
176
|
+
* pixels matching the browser `WheelEvent.deltaX`/`deltaY` axis
|
|
177
|
+
* convention (positive `dy` scrolls down, positive `dx` scrolls
|
|
178
|
+
* right). `event_count` tracks how many native wheel events the
|
|
179
|
+
* capture surface coalesced into this one — kept in the wire so
|
|
180
|
+
* the audit can record interaction density without inflating the
|
|
181
|
+
* log to one entry per native event.
|
|
182
|
+
*
|
|
183
|
+
* Slice 2c-batching scope: the capture surface MUST coalesce
|
|
184
|
+
* native wheel events at ≤60Hz (one wire event per ~16ms window).
|
|
185
|
+
* Server-side: `page.mouse.move(x, y) + page.mouse.wheel(dx, dy)`.
|
|
186
|
+
*/
|
|
187
|
+
| {
|
|
188
|
+
readonly kind: "wheel";
|
|
189
|
+
readonly x: number;
|
|
190
|
+
readonly y: number;
|
|
191
|
+
readonly dx: number;
|
|
192
|
+
readonly dy: number;
|
|
193
|
+
readonly event_count: number;
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* User-driven navigation. The wire carries the normalized URL
|
|
197
|
+
* (the address-bar surface MUST normalize before forwarding —
|
|
198
|
+
* `^[a-z][a-z0-9+.-]*:\/\/` passes through, otherwise prepend
|
|
199
|
+
* `https://`). Server-side: `page.goto(url, { waitUntil:
|
|
200
|
+
* "domcontentloaded" })`. The screencast surface reflects the
|
|
201
|
+
* new page automatically; navigate does not return a screenshot
|
|
202
|
+
* payload (unlike motebit-side `ComputerAction.navigate`, which
|
|
203
|
+
* carries inline heuristics for the AI loop's text response).
|
|
204
|
+
*
|
|
205
|
+
* Slice 2d scope: URL navigation only. Genuine search ("best
|
|
206
|
+
* laptops 2026" → DuckDuckGo) deferred; the address-bar surface
|
|
207
|
+
* is responsible for narrowing to URL-shaped input in v1.
|
|
208
|
+
*/
|
|
209
|
+
| {
|
|
210
|
+
readonly kind: "navigate";
|
|
211
|
+
readonly url: string;
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Slice 2e — browser history navigation. The triple `back` /
|
|
215
|
+
* `forward` / `reload` map to Playwright's `page.goBack` /
|
|
216
|
+
* `page.goForward` / `page.reload` and complete the
|
|
217
|
+
* "Chrome-feel" minimum on the user-driveable side. Each is a
|
|
218
|
+
* parameter-less event — the cursor anchor / URL / etc. don't
|
|
219
|
+
* apply.
|
|
220
|
+
*
|
|
221
|
+
* Empty-history semantics: `back` / `forward` against a session
|
|
222
|
+
* with no matching history MUST be a no-op (Playwright returns
|
|
223
|
+
* null; the wire treats null + thrown identically as success).
|
|
224
|
+
* The user's UX is "I clicked the button and nothing changed,"
|
|
225
|
+
* which matches a real browser at the start of its history.
|
|
226
|
+
*/
|
|
227
|
+
| {
|
|
228
|
+
readonly kind: "back";
|
|
229
|
+
} | {
|
|
230
|
+
readonly kind: "forward";
|
|
231
|
+
} | {
|
|
232
|
+
readonly kind: "reload";
|
|
233
|
+
};
|
|
234
|
+
/**
|
|
235
|
+
* Outcome of a `forwardUserInput` call. `forwarded` means the wire
|
|
236
|
+
* landed at Chromium; `rejected` means the runtime denied dispatch
|
|
237
|
+
* before the wire (gate, missing dispatcher) or the transport
|
|
238
|
+
* failed.
|
|
239
|
+
* @alpha
|
|
240
|
+
*/
|
|
241
|
+
export type UserInputForwardOutcome = "forwarded" | "rejected";
|
|
242
|
+
/**
|
|
243
|
+
* Closed set of reasons a user-input forward can be rejected.
|
|
244
|
+
* Verifiers discriminate on this exhaustively.
|
|
245
|
+
* @alpha
|
|
246
|
+
*/
|
|
247
|
+
export type UserInputRejectionReason =
|
|
248
|
+
/** Gate denied: `controlState.kind !== "user"` at forward time. */
|
|
249
|
+
"not_in_user_state"
|
|
250
|
+
/** Session is closed; nowhere to forward to. */
|
|
251
|
+
| "session_closed"
|
|
252
|
+
/** Dispatcher transport failed (HTTP error, network drop). */
|
|
253
|
+
| "transport_error"
|
|
254
|
+
/** Surface dispatcher does not implement input forwarding. */
|
|
255
|
+
| "not_supported";
|
|
256
|
+
/**
|
|
257
|
+
* Character class for a key audit entry. The redaction default —
|
|
258
|
+
* raw characters NEVER land in the audit log; the class survives.
|
|
259
|
+
* @alpha
|
|
260
|
+
*/
|
|
261
|
+
export type CharacterClass = "letter" | "digit" | "punct" | "whitespace" | "control" | "modifier" | "unknown";
|
|
262
|
+
/**
|
|
263
|
+
* Semantic role of a key for audit purposes. Coarser-grained than
|
|
264
|
+
* `key_code` would be — "the user pressed something that submits
|
|
265
|
+
* a form" rather than "the user pressed Return on a U.S. layout."
|
|
266
|
+
* @alpha
|
|
267
|
+
*/
|
|
268
|
+
export type KeyRole = "enter" | "tab" | "escape" | "backspace" | "arrow" | "shortcut" | "printable" | "unknown";
|
|
269
|
+
/**
|
|
270
|
+
* Per-kind audit detail. The wire-format `UserInputEvent` is
|
|
271
|
+
* mapped through redaction at the runtime layer to produce one of
|
|
272
|
+
* these shapes; raw text/keys/pixel coordinates do NOT appear here.
|
|
273
|
+
* @alpha
|
|
274
|
+
*/
|
|
275
|
+
export type UserInputForwardedDetail = {
|
|
276
|
+
readonly kind: "click";
|
|
277
|
+
/** Normalized [0, 1] x against the rendered screencast rect. */
|
|
278
|
+
readonly x_norm: number;
|
|
279
|
+
/** Normalized [0, 1] y against the rendered screencast rect. */
|
|
280
|
+
readonly y_norm: number;
|
|
281
|
+
readonly button: "left" | "right" | "middle";
|
|
282
|
+
} | {
|
|
283
|
+
readonly kind: "key";
|
|
284
|
+
readonly character_class: CharacterClass;
|
|
285
|
+
readonly key_role: KeyRole;
|
|
286
|
+
readonly modifiers: KeyModifiers;
|
|
287
|
+
} | {
|
|
288
|
+
readonly kind: "paste";
|
|
289
|
+
readonly length: number;
|
|
290
|
+
readonly line_count: number;
|
|
291
|
+
readonly looks_like_url: boolean;
|
|
292
|
+
} | {
|
|
293
|
+
readonly kind: "wheel";
|
|
294
|
+
/** Normalized [0, 1] x of the wheel anchor against the rendered screencast rect. */
|
|
295
|
+
readonly x_norm: number;
|
|
296
|
+
/** Normalized [0, 1] y of the wheel anchor. */
|
|
297
|
+
readonly y_norm: number;
|
|
298
|
+
/**
|
|
299
|
+
* Scroll deltas in CSS pixels — wire-format passthrough. Wheel
|
|
300
|
+
* deltas don't carry sensitivity (they're cursor-anchored
|
|
301
|
+
* scroll amounts, not text); logging them is not a privacy
|
|
302
|
+
* concern.
|
|
303
|
+
*/
|
|
304
|
+
readonly dx: number;
|
|
305
|
+
readonly dy: number;
|
|
306
|
+
/** Native wheel events coalesced into this one (interaction density). */
|
|
307
|
+
readonly event_count: number;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* URL-redacted navigate detail. The wire carries the full URL;
|
|
311
|
+
* the audit logs only the **scheme + host** plus presence flags
|
|
312
|
+
* for path / query. Mirrors browser-history privacy: "where did
|
|
313
|
+
* the user go" survives the audit, "what specifically did they
|
|
314
|
+
* fetch" does not.
|
|
315
|
+
*
|
|
316
|
+
* Why redact the path/query: URLs commonly carry session tokens,
|
|
317
|
+
* bearer tokens, account ids, or sensitive identifiers
|
|
318
|
+
* (`?reset_token=...`, `/patient/12345`). The user's signed
|
|
319
|
+
* audit log is a more permanent artifact than a browser history;
|
|
320
|
+
* conservative is correct.
|
|
321
|
+
*
|
|
322
|
+
* Malformed URLs (URL parser threw) collapse to
|
|
323
|
+
* `{ scheme: "unknown", host: "unknown", has_path: false,
|
|
324
|
+
* has_query: false }` — defensive.
|
|
325
|
+
*/
|
|
326
|
+
| {
|
|
327
|
+
readonly kind: "navigate";
|
|
328
|
+
readonly scheme: string;
|
|
329
|
+
readonly host: string;
|
|
330
|
+
readonly has_path: boolean;
|
|
331
|
+
readonly has_query: boolean;
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Slice 2e — history-navigation audit shapes. Parameter-less
|
|
335
|
+
* events; the audit just records that the user pressed
|
|
336
|
+
* back/forward/reload. No path/url to redact; no anchor coords
|
|
337
|
+
* to normalize.
|
|
338
|
+
*/
|
|
339
|
+
| {
|
|
340
|
+
readonly kind: "back";
|
|
341
|
+
} | {
|
|
342
|
+
readonly kind: "forward";
|
|
343
|
+
} | {
|
|
344
|
+
readonly kind: "reload";
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
* Audit-event payload for a user-driven input forward. Emitted on
|
|
348
|
+
* every forward attempt — both successes and rejections — so the
|
|
349
|
+
* audit trail records who tried to drive when. Sibling of
|
|
350
|
+
* `CoBrowseControlChangedPayload`; same `EventType`-keyed event
|
|
351
|
+
* stream the runtime already threads through `appendWithClock`.
|
|
352
|
+
*
|
|
353
|
+
* `control_state_at_forwarding` mirrors the `control_state_at_denial`
|
|
354
|
+
* field on motebit-side denials (Slice 1) — verifiers replaying
|
|
355
|
+
* the log don't have to cross-reference adjacent control events to
|
|
356
|
+
* answer "what state were we in when this fired."
|
|
357
|
+
* @alpha
|
|
358
|
+
*/
|
|
359
|
+
export interface UserInputForwardedPayload {
|
|
360
|
+
readonly session_id: string;
|
|
361
|
+
readonly motebit_id: string;
|
|
362
|
+
readonly outcome: UserInputForwardOutcome;
|
|
363
|
+
/** Present iff `outcome === "rejected"`. */
|
|
364
|
+
readonly rejection_reason?: UserInputRejectionReason;
|
|
365
|
+
readonly control_state_at_forwarding: ControlState;
|
|
366
|
+
readonly detail: UserInputForwardedDetail;
|
|
367
|
+
readonly timestamp: number;
|
|
368
|
+
}
|
|
369
|
+
//# sourceMappingURL=co-browse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"co-browse.d.ts","sourceRoot":"","sources":["../src/co-browse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Co-browse — control state machine for the `virtual_browser`
|
|
3
|
+
* embodiment.
|
|
4
|
+
*
|
|
5
|
+
* Doctrine: `motebit-computer.md` §"Embodiment modes" places co-browse
|
|
6
|
+
* as a *substate* of `virtual_browser`, not a new mode. Same isolated
|
|
7
|
+
* Chromium, same session-scoped consent boundary; what changes is who
|
|
8
|
+
* holds the pointer/keyboard. The `ControlState` here is the typed
|
|
9
|
+
* "who's driving" axis the runtime + slab + dispatcher all read.
|
|
10
|
+
*
|
|
11
|
+
* Why a discriminated union and not a flat enum. The four state names
|
|
12
|
+
* (`user`, `motebit`, `handoff_pending`, `paused`) are stable; what
|
|
13
|
+
* varies is the data each state carries. `handoff_pending` needs to
|
|
14
|
+
* know who currently holds and who's requesting (so a deny resolves
|
|
15
|
+
* to the right side); `paused` needs to remember who was driving so
|
|
16
|
+
* `resume` doesn't lose continuity. Discriminated union keeps the
|
|
17
|
+
* face of the type aligned with the four-state shape while making
|
|
18
|
+
* the per-state shape a compile-time fact, not a "remember to
|
|
19
|
+
* inspect this field when kind is X" comment.
|
|
20
|
+
*
|
|
21
|
+
* Why fail-closed-to-user on disconnect. The user is the always-
|
|
22
|
+
* trusted party in motebit's trust model — every other party
|
|
23
|
+
* (including the motebit itself, including any peer) is downstream of
|
|
24
|
+
* the user's identity. A connection drop could mean the user has
|
|
25
|
+
* actively stopped the session, lost network, or closed the tab; in
|
|
26
|
+
* any of those cases the safest semantics is revert-to-user (the
|
|
27
|
+
* motebit cannot continue acting on a page the user can no longer
|
|
28
|
+
* observe). Doctrine: spec/computer-use-v1.md §3.3 user-floor
|
|
29
|
+
* invariant, applied to control rather than dispatch.
|
|
30
|
+
*
|
|
31
|
+
* @alpha
|
|
32
|
+
*/
|
|
33
|
+
/**
|
|
34
|
+
* Closed set of transitions the state machine accepts. Every audit
|
|
35
|
+
* event for a control change carries one of these as its
|
|
36
|
+
* `transition_kind`. Adding a new kind is a protocol change — the
|
|
37
|
+
* audit event's structural set must stay closed so verifiers know
|
|
38
|
+
* which transitions are valid history.
|
|
39
|
+
* @alpha
|
|
40
|
+
*/
|
|
41
|
+
export const CO_BROWSE_TRANSITION_KINDS = [
|
|
42
|
+
"request_control",
|
|
43
|
+
"grant_control",
|
|
44
|
+
"deny_control",
|
|
45
|
+
"reclaim_control",
|
|
46
|
+
"release_control",
|
|
47
|
+
// Agent-surface pivot — user voluntarily yields drive back to
|
|
48
|
+
// motebit. Symmetric to `release_control` (motebit yields to user),
|
|
49
|
+
// and the protocol-level partner to the `/back` surface affordance.
|
|
50
|
+
// No approval required: the user's identity is the trust root and
|
|
51
|
+
// they unilaterally decide who drives, including handing control
|
|
52
|
+
// back to motebit. From `{kind: "user"}` only; from any other state
|
|
53
|
+
// this is `invalid_from_state`. Closes the cobrowser-default-polarity
|
|
54
|
+
// asymmetry where the protocol named "user takes" but not "user
|
|
55
|
+
// gives" — implicit when user was the always-default driver, named
|
|
56
|
+
// now that motebit-default is the new register. Doctrine:
|
|
57
|
+
// chrome-as-state-render.md § "Take-the-wheel affordance in PR 1"
|
|
58
|
+
// + the cobrowse-as-mode reshape's `/back` slice.
|
|
59
|
+
"yield_control",
|
|
60
|
+
"pause",
|
|
61
|
+
"resume",
|
|
62
|
+
"disconnect",
|
|
63
|
+
];
|
|
64
|
+
//# sourceMappingURL=co-browse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"co-browse.js","sourceRoot":"","sources":["../src/co-browse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AA4CH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,0BAA0B,GAAG;IACxC,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,iBAAiB;IACjB,iBAAiB;IACjB,8DAA8D;IAC9D,oEAAoE;IACpE,oEAAoE;IACpE,kEAAkE;IAClE,iEAAiE;IACjE,oEAAoE;IACpE,sEAAsE;IACtE,gEAAgE;IAChE,mEAAmE;IACnE,0DAA0D;IAC1D,kEAAkE;IAClE,kDAAkD;IAClD,eAAe;IACf,OAAO;IACP,QAAQ;IACR,YAAY;CACJ,CAAC"}
|