@motebit/protocol 1.2.0 → 2.0.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 (60) hide show
  1. package/README.md +4 -2
  2. package/dist/artifact-type.d.ts +144 -0
  3. package/dist/artifact-type.d.ts.map +1 -0
  4. package/dist/artifact-type.js +107 -0
  5. package/dist/artifact-type.js.map +1 -0
  6. package/dist/audience.d.ts +108 -0
  7. package/dist/audience.d.ts.map +1 -0
  8. package/dist/audience.js +104 -0
  9. package/dist/audience.js.map +1 -0
  10. package/dist/co-browse.d.ts +369 -0
  11. package/dist/co-browse.d.ts.map +1 -0
  12. package/dist/co-browse.js +64 -0
  13. package/dist/co-browse.js.map +1 -0
  14. package/dist/computer-use.d.ts +463 -3
  15. package/dist/computer-use.d.ts.map +1 -1
  16. package/dist/computer-use.js +40 -0
  17. package/dist/computer-use.js.map +1 -1
  18. package/dist/event-type.d.ts +62 -0
  19. package/dist/event-type.d.ts.map +1 -0
  20. package/dist/event-type.js +123 -0
  21. package/dist/event-type.js.map +1 -0
  22. package/dist/index.d.ts +257 -20
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +84 -1
  25. package/dist/index.js.map +1 -1
  26. package/dist/memory-events.d.ts +13 -0
  27. package/dist/memory-events.d.ts.map +1 -1
  28. package/dist/money.d.ts +33 -0
  29. package/dist/money.d.ts.map +1 -0
  30. package/dist/money.js +41 -0
  31. package/dist/money.js.map +1 -0
  32. package/dist/perception.d.ts +347 -0
  33. package/dist/perception.d.ts.map +1 -0
  34. package/dist/perception.js +9 -0
  35. package/dist/perception.js.map +1 -0
  36. package/dist/retention-policy.d.ts +8 -1
  37. package/dist/retention-policy.d.ts.map +1 -1
  38. package/dist/retention-policy.js +18 -0
  39. package/dist/retention-policy.js.map +1 -1
  40. package/dist/routing.d.ts +266 -0
  41. package/dist/routing.d.ts.map +1 -0
  42. package/dist/routing.js +88 -0
  43. package/dist/routing.js.map +1 -0
  44. package/dist/sensitivity.d.ts +123 -0
  45. package/dist/sensitivity.d.ts.map +1 -0
  46. package/dist/sensitivity.js +154 -0
  47. package/dist/sensitivity.js.map +1 -0
  48. package/dist/settlement-asset.d.ts +92 -0
  49. package/dist/settlement-asset.d.ts.map +1 -0
  50. package/dist/settlement-asset.js +82 -0
  51. package/dist/settlement-asset.js.map +1 -0
  52. package/dist/settlement-mode.d.ts +144 -13
  53. package/dist/settlement-mode.d.ts.map +1 -1
  54. package/dist/settlement-mode.js +45 -1
  55. package/dist/settlement-mode.js.map +1 -1
  56. package/dist/transparency.d.ts +116 -0
  57. package/dist/transparency.d.ts.map +1 -0
  58. package/dist/transparency.js +67 -0
  59. package/dist/transparency.js.map +1 -0
  60. 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"}