@kibee/sdk 0.1.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/index.d.mts +465 -0
- package/dist/index.d.ts +465 -0
- package/dist/index.js +1831 -0
- package/dist/index.mjs +1799 -0
- package/package.json +26 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
import { AnalyticsEvent, BridgeEventType, BridgeEnvelope, RegisteredTarget, FlowDefinition, IntentMatch, TargetRef as TargetRef$1, StartSessionRequest, SessionState, ResolveIntentRequest, RecoveryRequest, RecoveryResponse, TrackEventRequest, VisitorPollResponse, FlowCommand, VisibleTarget, SurfaceId } from '@kibee/contracts';
|
|
2
|
+
import { BeeRenderer } from '@kibee/renderer-three';
|
|
3
|
+
|
|
4
|
+
type BookmarkKind = "honey" | "sting";
|
|
5
|
+
interface FlowBeeBookmark {
|
|
6
|
+
id: string;
|
|
7
|
+
kind: BookmarkKind;
|
|
8
|
+
label: string;
|
|
9
|
+
note?: string;
|
|
10
|
+
pageUrl: string;
|
|
11
|
+
pageTitle: string;
|
|
12
|
+
target: {
|
|
13
|
+
kibeeId?: string;
|
|
14
|
+
beeId?: string;
|
|
15
|
+
selector?: string;
|
|
16
|
+
textHints?: string[];
|
|
17
|
+
};
|
|
18
|
+
/** Auto-captured positional/DOM context (see captureContext.ts) plus any
|
|
19
|
+
* extra fields the caller wants to attach. Backend uses this for clustering. */
|
|
20
|
+
metadata?: Record<string, unknown>;
|
|
21
|
+
createdAt: string;
|
|
22
|
+
updatedAt: string;
|
|
23
|
+
}
|
|
24
|
+
interface CreateBookmarkInput {
|
|
25
|
+
kind: BookmarkKind;
|
|
26
|
+
label: string;
|
|
27
|
+
note?: string;
|
|
28
|
+
target: {
|
|
29
|
+
kibeeId?: string;
|
|
30
|
+
beeId?: string;
|
|
31
|
+
selector?: string;
|
|
32
|
+
textHints?: string[];
|
|
33
|
+
};
|
|
34
|
+
metadata?: Record<string, unknown>;
|
|
35
|
+
}
|
|
36
|
+
declare class BookmarkMemory {
|
|
37
|
+
private storageKey;
|
|
38
|
+
list(): FlowBeeBookmark[];
|
|
39
|
+
create(input: CreateBookmarkInput): FlowBeeBookmark;
|
|
40
|
+
update(id: string, patch: Partial<Pick<FlowBeeBookmark, "label" | "note">>): FlowBeeBookmark | null;
|
|
41
|
+
remove(id: string): void;
|
|
42
|
+
findByPage(url?: string): FlowBeeBookmark[];
|
|
43
|
+
private read;
|
|
44
|
+
private write;
|
|
45
|
+
private generateId;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
interface KiBeeClientOptions {
|
|
49
|
+
apiBaseUrl?: string;
|
|
50
|
+
websiteId?: string;
|
|
51
|
+
publicKey?: string;
|
|
52
|
+
/** @deprecated alias for publicKey, removed in v1.0 */
|
|
53
|
+
apiKey?: string;
|
|
54
|
+
renderer: BeeRenderer;
|
|
55
|
+
mountContainer?: HTMLElement;
|
|
56
|
+
onEvent?: (event: AnalyticsEvent) => void;
|
|
57
|
+
/**
|
|
58
|
+
* Stable visitor id when the host cannot rely on normal page `localStorage`
|
|
59
|
+
* (e.g. Chrome extensions). When omitted, an id is created and stored under
|
|
60
|
+
* `kibee:visitor_id` in `localStorage` when available.
|
|
61
|
+
*/
|
|
62
|
+
visitorId?: string;
|
|
63
|
+
/**
|
|
64
|
+
* When true, the client constructs a BridgeClient and connects to /v1/bridge.
|
|
65
|
+
* Requires `apiToken` (a kibee-api JWT) to fetch a bridge token. Default false.
|
|
66
|
+
*/
|
|
67
|
+
useBridge?: boolean;
|
|
68
|
+
/**
|
|
69
|
+
* kibee-api JWT used to authenticate the POST /v1/bridge/token call.
|
|
70
|
+
* Required when `useBridge` is true. The host page is responsible for
|
|
71
|
+
* obtaining this token (via Auth0 sign-in flow on the web side).
|
|
72
|
+
*/
|
|
73
|
+
apiToken?: string;
|
|
74
|
+
}
|
|
75
|
+
declare class KiBeeClient {
|
|
76
|
+
private options;
|
|
77
|
+
private api;
|
|
78
|
+
private locator;
|
|
79
|
+
private highlight;
|
|
80
|
+
private bookmarks;
|
|
81
|
+
private registry;
|
|
82
|
+
private controller;
|
|
83
|
+
private initPromise;
|
|
84
|
+
private mountContainer?;
|
|
85
|
+
private currentPageId;
|
|
86
|
+
private currentSession;
|
|
87
|
+
private currentFlowId;
|
|
88
|
+
private adminSyncTimer;
|
|
89
|
+
/** Polling cadence when SSE is unavailable / closed — the visitor
|
|
90
|
+
* experience depends on this for new admin messages, so it stays
|
|
91
|
+
* tight (5s default; afforestation passes 2.5s). */
|
|
92
|
+
private fastPollInterval;
|
|
93
|
+
/** Cadence when SSE is healthy. Polling becomes a heartbeat — it only
|
|
94
|
+
* needs to catch state SSE doesn't push (friction score, pending
|
|
95
|
+
* pushes) and recover any messages we somehow missed. */
|
|
96
|
+
private readonly slowPollInterval;
|
|
97
|
+
private presenceSessionPromise;
|
|
98
|
+
/** EventSource subscription for the per-session visitor stream. */
|
|
99
|
+
private visitorStream;
|
|
100
|
+
/** Last-seen message timestamp for the polling fallback `?since=`. */
|
|
101
|
+
private lastVisitorMessageAt;
|
|
102
|
+
/** Set of message ids the SDK has emitted to the panel — dedupes when a
|
|
103
|
+
* message arrives via SSE *and* a subsequent poll. */
|
|
104
|
+
private seenMessageIds;
|
|
105
|
+
/** Distress signals tracker. Reset on a high-confidence resolve so the
|
|
106
|
+
* bee doesn't nag if the visitor recovers on their own. */
|
|
107
|
+
private consecutiveLowConfidence;
|
|
108
|
+
private lastDistressPromptAt;
|
|
109
|
+
/** Current chat mode mirrored from the server. The panel reads this to
|
|
110
|
+
* hide the "talk to a human" chip when an agent is on. */
|
|
111
|
+
private chatMode;
|
|
112
|
+
/** Mirror of whether the host's chat panel is currently visible. The
|
|
113
|
+
* panel dispatches kibee-panel-open / -close — we listen so we can
|
|
114
|
+
* decide whether to surface an inbound admin message as a bee tooltip
|
|
115
|
+
* (panel closed → speak it so the visitor notices) or stay quiet
|
|
116
|
+
* (panel open → the thread already shows it; tooltip would dupe). */
|
|
117
|
+
private panelOpen;
|
|
118
|
+
/** S3 T5: optional cross-surface bridge client. Initialized only when
|
|
119
|
+
* `useBridge: true` AND `apiToken` are passed at construction. */
|
|
120
|
+
private bridgeClient?;
|
|
121
|
+
/** S4 T4: unsubscribes for handlers registered against `bridgeClient`. Drained
|
|
122
|
+
* in `destroy()` so we don't leave dangling handlers if a host swaps clients. */
|
|
123
|
+
private bridgeUnsubscribes;
|
|
124
|
+
/** S4 T4: in-flight `flow:handoff` flowIds. Guards against the same flow being
|
|
125
|
+
* started twice if duplicate envelopes arrive (e.g. retried publish). */
|
|
126
|
+
private inflightHandoffFlowIds;
|
|
127
|
+
/** S4 T7: mirrors whether another surface (extension/desktop) is currently
|
|
128
|
+
* holding the listening floor (announced via `voice:state` over the bridge).
|
|
129
|
+
* The SDK has no built-in voice listening UI today — voice is host-implemented
|
|
130
|
+
* — so this is exposed as a flag + a `kibee-voice-state` CustomEvent that hosts
|
|
131
|
+
* can subscribe to in order to suppress their own listening indicator. */
|
|
132
|
+
private otherSurfaceListening;
|
|
133
|
+
readonly visitorId: string;
|
|
134
|
+
constructor(options: KiBeeClientOptions);
|
|
135
|
+
/**
|
|
136
|
+
* Connects to the cross-surface bridge (`/v1/bridge`). No-op when
|
|
137
|
+
* `useBridge` was false or `apiToken` was missing at construction.
|
|
138
|
+
*/
|
|
139
|
+
connectBridge(): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Register a handler for inbound bridge envelopes of a specific type.
|
|
142
|
+
* Returns an unsubscribe function. No-op (returns a noop unsubscribe)
|
|
143
|
+
* when the bridge isn't initialized.
|
|
144
|
+
*/
|
|
145
|
+
onBridgeEvent(type: BridgeEventType, handler: (envelope: BridgeEnvelope) => void): () => void;
|
|
146
|
+
/**
|
|
147
|
+
* S4 T6: ask another surface (typically `desktop`) to point its on-screen
|
|
148
|
+
* bee at a global screen coordinate. No-op when the bridge isn't wired
|
|
149
|
+
* (`useBridge: false` or `apiToken` missing) — the caller doesn't need
|
|
150
|
+
* to feature-detect.
|
|
151
|
+
*
|
|
152
|
+
* `tenantId`, `workspaceId`, and `visitorId` set here are advisory: the
|
|
153
|
+
* broker overwrites identity fields with JWT-derived values on receipt
|
|
154
|
+
* (S2 T2 invariant). `source: "web"` is hardcoded because the SDK ships
|
|
155
|
+
* web-only by default; the broker also enforces source against the
|
|
156
|
+
* value bound at WS handshake.
|
|
157
|
+
*/
|
|
158
|
+
requestPointTo(coord: {
|
|
159
|
+
x: number;
|
|
160
|
+
y: number;
|
|
161
|
+
screenIndex: number;
|
|
162
|
+
}): Promise<void>;
|
|
163
|
+
init(): Promise<void>;
|
|
164
|
+
identifyPage(pageId: string, metadata?: Record<string, unknown>): void;
|
|
165
|
+
registerTargets(targets: RegisteredTarget[]): void;
|
|
166
|
+
getRegisteredTargets(): RegisteredTarget[];
|
|
167
|
+
runFlow(flowOrId: string | FlowDefinition): Promise<FlowDefinition>;
|
|
168
|
+
/**
|
|
169
|
+
* Run a flow in interactive step-through mode: the bee tooltip shows
|
|
170
|
+
* prev / next buttons so the user controls the pace instead of
|
|
171
|
+
* auto-advancing on click/input events.
|
|
172
|
+
*/
|
|
173
|
+
runInteractiveFlow(flowOrId: string | FlowDefinition): Promise<FlowDefinition>;
|
|
174
|
+
ask(input: string): Promise<IntentMatch>;
|
|
175
|
+
/**
|
|
176
|
+
* Visitor-facing chat send. Wraps `ask()` so the rule-matched answer
|
|
177
|
+
* still drives flows when intent is clear, but ALSO:
|
|
178
|
+
* - emits a `kibee-message-received` event for each customer + ai
|
|
179
|
+
* message so the panel renders them as bubbles even before the SSE
|
|
180
|
+
* stream catches up
|
|
181
|
+
* - tracks distress signals (low confidence streaks, "human"
|
|
182
|
+
* keywords) and dispatches `kibee-distress-detected` so the panel
|
|
183
|
+
* can surface the inline "want a teammate?" prompt
|
|
184
|
+
*/
|
|
185
|
+
send(input: string): Promise<void>;
|
|
186
|
+
/**
|
|
187
|
+
* Visitor-initiated escalation. Called by the panel's "Talk to a human"
|
|
188
|
+
* chip and by the inline distress prompt's "Yes please" button.
|
|
189
|
+
*/
|
|
190
|
+
escalateToHuman(): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* Surface an incoming agent / AI message as a bee speech bubble when the
|
|
193
|
+
* panel is closed, so a passive visitor sees that someone replied. The
|
|
194
|
+
* panel-open path stays quiet because the panel thread already shows the
|
|
195
|
+
* message — speaking would dupe it.
|
|
196
|
+
*
|
|
197
|
+
* Skipped for `customer` (the visitor's own echoed message) and `system`
|
|
198
|
+
* (admin annotations like "Sahil joined the conversation" — visible only
|
|
199
|
+
* inside the panel).
|
|
200
|
+
*/
|
|
201
|
+
private maybeSpeakIncomingMessage;
|
|
202
|
+
private shouldShowDistressPrompt;
|
|
203
|
+
private dispatchDistressPrompt;
|
|
204
|
+
private requestHumanFromKeyword;
|
|
205
|
+
saveHoney(label: string, target: TargetRef$1, note?: string): Promise<FlowBeeBookmark | null>;
|
|
206
|
+
saveSting(label: string, target: TargetRef$1, note?: string): Promise<FlowBeeBookmark | null>;
|
|
207
|
+
listBookmarks(): FlowBeeBookmark[];
|
|
208
|
+
removeBookmark(id: string): void;
|
|
209
|
+
revisitBookmark(bookmark: FlowBeeBookmark): Promise<void>;
|
|
210
|
+
clearFocus(): void;
|
|
211
|
+
/**
|
|
212
|
+
* When true, the dock button toggles the in-app assistant (kibee-assist-toggle)
|
|
213
|
+
* instead of immediately undocking the bee.
|
|
214
|
+
*/
|
|
215
|
+
setDockAssistPanel(enabled: boolean): void;
|
|
216
|
+
track(type: string, metadata?: Record<string, unknown>): Promise<void>;
|
|
217
|
+
/** Returns the dock's current screen position (center of the dock button) */
|
|
218
|
+
getDockPosition(): {
|
|
219
|
+
x: number;
|
|
220
|
+
y: number;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Polls the API for admin-pushed flows/targets AND drains new chat
|
|
224
|
+
* messages on the same tick. Also opens the per-session visitor SSE
|
|
225
|
+
* stream so messages arrive in real time when the network supports it
|
|
226
|
+
* (polling stays as a guaranteed-delivery backstop).
|
|
227
|
+
*
|
|
228
|
+
* Call after init() and startSession() to enable admin push support.
|
|
229
|
+
*
|
|
230
|
+
* Cadence is SSE-aware: when the visitor stream is OPEN (realtime is
|
|
231
|
+
* delivering messages), polling backs off to a 30s heartbeat — just
|
|
232
|
+
* enough to catch state the SSE channel can't push (e.g. friction
|
|
233
|
+
* score, drained pending pushes). On SSE error/close the interval
|
|
234
|
+
* snaps back to `intervalMs` so polling carries the load until SSE
|
|
235
|
+
* reconnects.
|
|
236
|
+
*
|
|
237
|
+
* The single `/v1/visitor/sync` endpoint returns messages + pending
|
|
238
|
+
* pushes + mode + friction in one round-trip, so each tick is one
|
|
239
|
+
* request instead of two.
|
|
240
|
+
*/
|
|
241
|
+
enableAdminSync(intervalMs?: number): void;
|
|
242
|
+
disableAdminSync(): void;
|
|
243
|
+
/** (Re)arm the polling interval based on current SSE health. Called
|
|
244
|
+
* whenever SSE state changes (open / error) so the interval reflects
|
|
245
|
+
* reality without dropping a tick. */
|
|
246
|
+
private armSyncTimer;
|
|
247
|
+
/**
|
|
248
|
+
* Single visitor poll. Drains pending flow pushes (admin → SDK) AND
|
|
249
|
+
* sucks in new chat messages in one HTTP request. Always runs alongside
|
|
250
|
+
* SSE so a missed event during network blips eventually shows up;
|
|
251
|
+
* `seenMessageIds` dedupes anything SSE already delivered.
|
|
252
|
+
*/
|
|
253
|
+
private pollVisitorSync;
|
|
254
|
+
private handleVisitorPoll;
|
|
255
|
+
private openVisitorStream;
|
|
256
|
+
destroy(): void;
|
|
257
|
+
/**
|
|
258
|
+
* S4 T4: run a flow handed off via the bridge. Wraps `runFlow(flowId)` with
|
|
259
|
+
* an in-flight guard so duplicate `flow:handoff` envelopes for the same
|
|
260
|
+
* flowId (e.g. retried publish) don't start two concurrent runs.
|
|
261
|
+
*/
|
|
262
|
+
private runFlowFromHandoff;
|
|
263
|
+
private startSession;
|
|
264
|
+
/**
|
|
265
|
+
* Creates a server session once the page is known so admin "Visitors" and
|
|
266
|
+
* analytics can attach to a real `sessionId` (not only when a flow runs).
|
|
267
|
+
*/
|
|
268
|
+
private ensurePresenceSession;
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/** /v1/visitor/sync — unified poll envelope. Drains pending pushes as it
|
|
272
|
+
* reads messages so the SDK doesn't have to round-trip twice per tick. */
|
|
273
|
+
interface VisitorSyncResponse extends VisitorPollResponse {
|
|
274
|
+
pendingPushes: Array<{
|
|
275
|
+
flowId?: string;
|
|
276
|
+
targets?: TargetRef$1[];
|
|
277
|
+
}>;
|
|
278
|
+
}
|
|
279
|
+
interface KiBeeApiClientOptions {
|
|
280
|
+
websiteId?: string;
|
|
281
|
+
publicKey?: string;
|
|
282
|
+
/** @deprecated legacy x-kibee-key header — replaced by websiteId + publicKey */
|
|
283
|
+
legacyApiKey?: string;
|
|
284
|
+
}
|
|
285
|
+
declare class KiBeeApiClient {
|
|
286
|
+
private baseUrl;
|
|
287
|
+
private options;
|
|
288
|
+
constructor(baseUrl: string, options?: KiBeeApiClientOptions);
|
|
289
|
+
fetchFlow(id: string): Promise<FlowDefinition>;
|
|
290
|
+
startSession(input: StartSessionRequest): Promise<SessionState>;
|
|
291
|
+
resolveIntent(input: ResolveIntentRequest): Promise<IntentMatch>;
|
|
292
|
+
resolveRecovery(input: RecoveryRequest): Promise<RecoveryResponse>;
|
|
293
|
+
trackEvent(event: TrackEventRequest): Promise<void>;
|
|
294
|
+
/**
|
|
295
|
+
* Unified visitor poll. One round-trip pulls messages + pending pushes
|
|
296
|
+
* + mode + friction. Replaces the previous fetchVisitorMessages +
|
|
297
|
+
* /admin/sessions/:id/pending pair for visitors using publishable-key
|
|
298
|
+
* auth. The legacy fetchVisitorMessages remains for shipped SDK
|
|
299
|
+
* builds that haven't been updated yet.
|
|
300
|
+
*/
|
|
301
|
+
fetchVisitorSync(sessionId: string, since: string | null): Promise<VisitorSyncResponse>;
|
|
302
|
+
/**
|
|
303
|
+
* Legacy split poll — kept for backward compat. Prefer fetchVisitorSync.
|
|
304
|
+
*/
|
|
305
|
+
fetchVisitorMessages(sessionId: string, since: string | null): Promise<VisitorPollResponse>;
|
|
306
|
+
/**
|
|
307
|
+
* Visitor (or distress detector) requests a human. Sets
|
|
308
|
+
* `requested_human_at`, generates an AI summary for the agent, and lights
|
|
309
|
+
* up the "Needs help" badge in admin Hive.
|
|
310
|
+
*/
|
|
311
|
+
escalateToHuman(sessionId: string): Promise<void>;
|
|
312
|
+
/**
|
|
313
|
+
* Open the visitor's per-session SSE stream. EventSource can't pass auth
|
|
314
|
+
* headers, so the publishable key + websiteId ride along as query params.
|
|
315
|
+
* Caller wires `onmessage` and is responsible for re-opening on disconnect.
|
|
316
|
+
*
|
|
317
|
+
* Returns null when EventSource isn't available (older browsers / strict
|
|
318
|
+
* proxies) — caller falls back to polling `fetchVisitorMessages`.
|
|
319
|
+
*/
|
|
320
|
+
openVisitorStream(sessionId: string): EventSource | null;
|
|
321
|
+
private buildHeaders;
|
|
322
|
+
private request;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
interface TargetRef {
|
|
326
|
+
kibeeId?: string;
|
|
327
|
+
beeId?: string;
|
|
328
|
+
selector?: string;
|
|
329
|
+
textHints?: string[];
|
|
330
|
+
}
|
|
331
|
+
interface ResolvedTarget {
|
|
332
|
+
element: HTMLElement;
|
|
333
|
+
rect: DOMRect;
|
|
334
|
+
centerX: number;
|
|
335
|
+
centerY: number;
|
|
336
|
+
}
|
|
337
|
+
declare class Locator {
|
|
338
|
+
resolve(target: TargetRef): ResolvedTarget | null;
|
|
339
|
+
findElement(target: TargetRef): HTMLElement | null;
|
|
340
|
+
scrollIntoView(target: TargetRef, behavior?: ScrollBehavior): void;
|
|
341
|
+
private getSearchableText;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
type HighlightVariant = "pulse" | "ring" | "soft";
|
|
345
|
+
declare class HighlightRenderer {
|
|
346
|
+
private el;
|
|
347
|
+
mount(container?: HTMLElement): void;
|
|
348
|
+
show(rect: DOMRect, variant?: HighlightVariant): void;
|
|
349
|
+
hide(): void;
|
|
350
|
+
destroy(): void;
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
interface FlowExecutionHook {
|
|
354
|
+
(command: FlowCommand, phase: "started" | "completed" | "missing_target"): void;
|
|
355
|
+
}
|
|
356
|
+
declare class FlowController {
|
|
357
|
+
private bee;
|
|
358
|
+
private locator;
|
|
359
|
+
private highlight;
|
|
360
|
+
private bookmarks;
|
|
361
|
+
private onCommand?;
|
|
362
|
+
constructor(bee: BeeRenderer, locator: Locator, highlight: HighlightRenderer, bookmarks?: BookmarkMemory, onCommand?: FlowExecutionHook | undefined);
|
|
363
|
+
init(): Promise<void>;
|
|
364
|
+
runFlow(flow: FlowDefinition): Promise<void>;
|
|
365
|
+
/**
|
|
366
|
+
* Interactive step-through mode: bee flies to each `fly_to` step and shows
|
|
367
|
+
* prev / next buttons in the tooltip so the user controls the pace.
|
|
368
|
+
*/
|
|
369
|
+
runInteractiveFlow(flow: FlowDefinition): Promise<void>;
|
|
370
|
+
clearFocus(): void;
|
|
371
|
+
createHoneyBookmark(label: string, target: TargetRef$1, note?: string): Promise<FlowBeeBookmark | null>;
|
|
372
|
+
createStingBookmark(label: string, target: TargetRef$1, note?: string): Promise<FlowBeeBookmark | null>;
|
|
373
|
+
listBookmarks(): FlowBeeBookmark[];
|
|
374
|
+
getPageBookmarks(): FlowBeeBookmark[];
|
|
375
|
+
revisitBookmark(bookmark: FlowBeeBookmark): Promise<void>;
|
|
376
|
+
removeBookmark(id: string): void;
|
|
377
|
+
private execute;
|
|
378
|
+
private createBookmark;
|
|
379
|
+
private guideTo;
|
|
380
|
+
private waitForClick;
|
|
381
|
+
private waitForInput;
|
|
382
|
+
private delay;
|
|
383
|
+
private resolveGuidePlacement;
|
|
384
|
+
private pickGuideSide;
|
|
385
|
+
private resolveTopRightBeeOffset;
|
|
386
|
+
/** Area of intersection of two axis-aligned rectangles (px²). */
|
|
387
|
+
private rectOverlapArea;
|
|
388
|
+
/**
|
|
389
|
+
* Place the speech bubble with a healthy gap from the bee and pick left-vs-right
|
|
390
|
+
* by scoring overlap with the bee body and the highlighted target.
|
|
391
|
+
*/
|
|
392
|
+
private resolveTooltipPosition;
|
|
393
|
+
private notifyMissingTarget;
|
|
394
|
+
private finishAndDock;
|
|
395
|
+
/** Like finishAndDock but without docking — bee stays wherever it landed. */
|
|
396
|
+
private finishInPlace;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
declare class TargetRegistry {
|
|
400
|
+
private targets;
|
|
401
|
+
set(targets: RegisteredTarget[]): void;
|
|
402
|
+
list(): RegisteredTarget[];
|
|
403
|
+
getVisibleTargets(doc?: Document): VisibleTarget[];
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
interface BridgeClientOptions {
|
|
407
|
+
bridgeUrl: string;
|
|
408
|
+
source: SurfaceId;
|
|
409
|
+
visitorId: string;
|
|
410
|
+
tokenFetcher: () => Promise<{
|
|
411
|
+
token: string;
|
|
412
|
+
expiresAt: number;
|
|
413
|
+
}>;
|
|
414
|
+
}
|
|
415
|
+
interface ReconnectOptions {
|
|
416
|
+
maxAttempts?: number;
|
|
417
|
+
baseDelayMs?: number;
|
|
418
|
+
capDelayMs?: number;
|
|
419
|
+
}
|
|
420
|
+
type BridgeClientState = "disconnected" | "connecting" | "connected" | "failed";
|
|
421
|
+
type Handler = (envelope: BridgeEnvelope) => void;
|
|
422
|
+
/**
|
|
423
|
+
* Browser-side WebSocket client for the cross-surface bridge.
|
|
424
|
+
*
|
|
425
|
+
* Lifecycle (S3 — no auto-reconnect; that's S4 hardening):
|
|
426
|
+
* 1. `connect()` — fetches a bridge token via `tokenFetcher`, opens WS.
|
|
427
|
+
* 2. On open, sends `presence:hello` to bind the source server-side.
|
|
428
|
+
* 3. Inbound envelopes are validated via `isBridgeEnvelope` and dispatched
|
|
429
|
+
* to handlers registered via `on(type, handler)`.
|
|
430
|
+
* 4. `close()` — sends `presence:bye`, closes the WS.
|
|
431
|
+
*
|
|
432
|
+
* Identity overwrite happens server-side at the broker (per S1 T3 review).
|
|
433
|
+
* The client supplies `visitorId` only for envelope construction; the broker
|
|
434
|
+
* trusts the JWT.
|
|
435
|
+
*/
|
|
436
|
+
declare class BridgeClient {
|
|
437
|
+
private ws;
|
|
438
|
+
private handlers;
|
|
439
|
+
private opts;
|
|
440
|
+
state: BridgeClientState;
|
|
441
|
+
private heartbeatTimer?;
|
|
442
|
+
private lastPongAt;
|
|
443
|
+
constructor(opts: BridgeClientOptions);
|
|
444
|
+
on(eventType: BridgeEventType, handler: Handler): () => void;
|
|
445
|
+
connect(): Promise<void>;
|
|
446
|
+
private startHeartbeat;
|
|
447
|
+
private markDegraded;
|
|
448
|
+
send(envelope: BridgeEnvelope): void;
|
|
449
|
+
close(): void;
|
|
450
|
+
/**
|
|
451
|
+
* Wraps `connect()` with exponential backoff. Defaults: 10 attempts,
|
|
452
|
+
* 1s base, 30s cap (delays: 1s, 2s, 4s, 8s, 16s, 30s, 30s, ...). Adds
|
|
453
|
+
* 0–20% jitter per attempt.
|
|
454
|
+
*
|
|
455
|
+
* On success, `state` is `connected` and the method resolves.
|
|
456
|
+
* After `maxAttempts` failures, `state` is `failed` and the last error
|
|
457
|
+
* is re-thrown.
|
|
458
|
+
*
|
|
459
|
+
* `connect()` itself remains a single-attempt method so existing callers
|
|
460
|
+
* are unaffected.
|
|
461
|
+
*/
|
|
462
|
+
connectWithReconnect(opts?: ReconnectOptions): Promise<void>;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export { type BookmarkKind, BookmarkMemory, BridgeClient, type BridgeClientOptions, type CreateBookmarkInput, type FlowBeeBookmark, FlowController, type FlowExecutionHook, HighlightRenderer, type HighlightVariant, KiBeeApiClient, type KiBeeApiClientOptions, KiBeeClient, type KiBeeClientOptions, Locator, type ResolvedTarget, type TargetRef, TargetRegistry, type VisitorSyncResponse };
|