@holostaff/sdk 0.3.1 → 0.4.1

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/README.md CHANGED
@@ -50,6 +50,12 @@ pass to `init()`.
50
50
  - POST identity / stage / signal / outcome events to the Holostaff runtime.
51
51
  - Track the current SPA route and last-user-activity time, and forward
52
52
  them to the runtime on route changes plus a low-frequency heartbeat.
53
+ - **Record the session with rrweb** (DOM, canvas at ~2 fps, media playback
54
+ state, inlined images/fonts) and batch it to the runtime, where the
55
+ vision pipeline watches the session and decides when the copilot should
56
+ step in. Password / email / tel inputs are always masked; mark rendered
57
+ PII with the `holostaff-mask` (text) or `holostaff-block` (region) CSS
58
+ classes; opt out entirely with `init({ observe: { enabled: false } })`.
53
59
  - Hold a server-sent-events channel open and render `text` interventions
54
60
  as a shadow-DOM pill (dismiss / engage / 30s auto-ignore), reporting
55
61
  outcomes back automatically.
@@ -57,7 +63,6 @@ pass to `init()`.
57
63
  **Does not (yet)**
58
64
  - Render non-text modalities (voice / email / sms / phone /
59
65
  screen automation) — those events are surfaced to `onError` and skipped.
60
- - Capture rrweb / DOM events — that lives in the Holostaff widget script.
61
66
 
62
67
  ## References
63
68
 
package/dist/index.d.ts CHANGED
@@ -36,6 +36,6 @@ export interface HolostaffApi {
36
36
  _destroy(): void;
37
37
  }
38
38
  export declare const holostaff: HolostaffApi;
39
- export type { BowtieStage, InitOptions, InterventionOutcome } from './types.js';
39
+ export type { BowtieStage, InitOptions, InterventionOutcome, ObserveOptions } from './types.js';
40
40
  export { BOWTIE_STAGES } from './types.js';
41
41
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAYH,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAgDxG,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,IAAI,IAAI,CAAA;IACrB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE;;;;;;OAMG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACzE,kCAAkC;IAClC,QAAQ,IAAI,IAAI,CAAA;CACjB;AAED,eAAO,MAAM,SAAS,EAAE,YAsKvB,CAAA;AAED,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAC/E,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAaH,OAAO,EAAiB,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAmDxG,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;IAClC,aAAa,IAAI,IAAI,CAAA;IACrB,cAAc,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAAA;IACxC,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;IACjE;;;;;;OAMG;IACH,aAAa,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,mBAAmB,GAAG,IAAI,CAAA;IACzE,kCAAkC;IAClC,QAAQ,IAAI,IAAI,CAAA;CACjB;AAED,eAAO,MAAM,SAAS,EAAE,YA4LvB,CAAA;AAED,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,mBAAmB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAC/F,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA"}
package/dist/index.js CHANGED
@@ -21,6 +21,7 @@ import { getOrMintDeviceId, getHostUserId, setHostUserId, clearHostUserId, } fro
21
21
  import { resolveTransportConfig, postJson, postBeacon, openCommandStream } from './transport.js';
22
22
  import { mintSessionId, bindUnload } from './session.js';
23
23
  import { startSignals } from './signals.js';
24
+ import { startObservations } from './observations.js';
24
25
  import { startWidget } from './widget.js';
25
26
  import { BOWTIE_STAGES } from './types.js';
26
27
  let state = null;
@@ -81,6 +82,16 @@ export const holostaff = {
81
82
  sourceId: opts.sourceId,
82
83
  buildBody: () => commonBody(nextState),
83
84
  });
85
+ // Vision-reconciliation wave — rrweb capture batched to
86
+ // /observations; the server replays in Browserbase and the Gemini
87
+ // perceive+decide tick runs on what it sees. On by default.
88
+ nextState.observeOpts = opts.observe;
89
+ nextState.observations = startObservations({
90
+ cfg: transport,
91
+ sessionId,
92
+ buildBody: () => commonBody(nextState),
93
+ observe: opts.observe,
94
+ });
84
95
  // Wave 3e — widget subscribes to the SSE channel and renders the
85
96
  // text pill on `fire_intervention` events. Outcomes flow back to
86
97
  // /outcome.
@@ -149,6 +160,16 @@ export const holostaff = {
149
160
  sourceId: s.sourceId,
150
161
  buildBody: () => commonBody(s),
151
162
  });
163
+ // Restart capture too — stopping and re-recording forces a fresh
164
+ // full DOM snapshot, which the new session's replay needs to
165
+ // bootstrap from.
166
+ s.observations?.dispose();
167
+ s.observations = startObservations({
168
+ cfg: s.transport,
169
+ sessionId: s.sessionId,
170
+ buildBody: () => commonBody(s),
171
+ observe: s.observeOpts,
172
+ });
152
173
  // Wave 3e — same for the SSE channel + widget. The old session is
153
174
  // closed; reopen against the new id so future fire_intervention
154
175
  // events reach the correct stream.
@@ -199,6 +220,7 @@ export const holostaff = {
199
220
  return;
200
221
  state.unload?.dispose();
201
222
  state.signals?.dispose();
223
+ state.observations?.dispose();
202
224
  state.widget?.dispose();
203
225
  state.commands?.close();
204
226
  state = null;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Observations — rrweb session capture (vision-reconciliation wave,
3
+ * Phase A).
4
+ *
5
+ * Records the visitor's session with rrweb and ships event batches to
6
+ * `POST /api/runtime/sessions/:sessionId/observations`, where the
7
+ * server's vision bridge replays them in Browserbase and screenshots
8
+ * feed the Gemini perceive+decide tick.
9
+ *
10
+ * Capture policy (wave doc §Phase A — "everything the user sees,
11
+ * except PII"):
12
+ * - Full DOM, canvas (sampled at ~2 fps — the VLM only ticks every
13
+ * 2–5s), media playback state, fonts + images inlined so replay
14
+ * doesn't depend on URLs staying reachable.
15
+ * - Typed PII never leaves the page: password / email / tel inputs
16
+ * are masked at the keystroke level. Rendered PII is the
17
+ * customer's to mark: `holostaff-mask` masks text content,
18
+ * `holostaff-block` blanks a region, `holostaff-ignore` skips an
19
+ * input entirely.
20
+ *
21
+ * Version pin: rrweb 2.0.0-alpha.4 — MUST match the server's replay
22
+ * bundle (server/src/bowtie/vision/rrweb.bundle.js); recorder and
23
+ * replayer share the event format.
24
+ *
25
+ * Loading: rrweb is imported dynamically so hosts that disable
26
+ * observation (or render server-side) never evaluate it; a failed
27
+ * import degrades to no-capture and routes to onError, per the SDK's
28
+ * fail-soft contract.
29
+ *
30
+ * Batching:
31
+ * - flush every FLUSH_INTERVAL_MS, or at MAX_BATCH_EVENTS, or when
32
+ * the approximate batch size passes MAX_BATCH_BYTES (full
33
+ * snapshots with inlined images are heavy — don't let them queue).
34
+ * - final flush on dispose goes over sendBeacon (survives unload);
35
+ * beacons cap at ~64KB so an oversized final batch is truncated to
36
+ * the most recent events — replay loses the tail of a dying
37
+ * session, never the session.
38
+ */
39
+ import { type TransportConfig } from './transport.js';
40
+ import type { ObserveOptions } from './types.js';
41
+ export interface ObservationsBindingDeps {
42
+ cfg: TransportConfig;
43
+ sessionId: string;
44
+ /** Common body fields — tenantId/sourceId/deviceId/hostUserId. */
45
+ buildBody: () => Record<string, unknown>;
46
+ observe?: ObserveOptions;
47
+ }
48
+ export interface ObservationsBinding {
49
+ /** Stop recording, flush the tail via beacon. */
50
+ dispose(): void;
51
+ }
52
+ export declare function startObservations(deps: ObservationsBindingDeps): ObservationsBinding;
53
+ //# sourceMappingURL=observations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observations.d.ts","sourceRoot":"","sources":["../src/observations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AAEH,OAAO,EAAwB,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAC3E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAOhD,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,eAAe,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,kEAAkE;IAClE,SAAS,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,OAAO,CAAC,EAAE,cAAc,CAAA;CACzB;AAED,MAAM,WAAW,mBAAmB;IAClC,iDAAiD;IACjD,OAAO,IAAI,IAAI,CAAA;CAChB;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,uBAAuB,GAAG,mBAAmB,CAyFpF"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Observations — rrweb session capture (vision-reconciliation wave,
3
+ * Phase A).
4
+ *
5
+ * Records the visitor's session with rrweb and ships event batches to
6
+ * `POST /api/runtime/sessions/:sessionId/observations`, where the
7
+ * server's vision bridge replays them in Browserbase and screenshots
8
+ * feed the Gemini perceive+decide tick.
9
+ *
10
+ * Capture policy (wave doc §Phase A — "everything the user sees,
11
+ * except PII"):
12
+ * - Full DOM, canvas (sampled at ~2 fps — the VLM only ticks every
13
+ * 2–5s), media playback state, fonts + images inlined so replay
14
+ * doesn't depend on URLs staying reachable.
15
+ * - Typed PII never leaves the page: password / email / tel inputs
16
+ * are masked at the keystroke level. Rendered PII is the
17
+ * customer's to mark: `holostaff-mask` masks text content,
18
+ * `holostaff-block` blanks a region, `holostaff-ignore` skips an
19
+ * input entirely.
20
+ *
21
+ * Version pin: rrweb 2.0.0-alpha.4 — MUST match the server's replay
22
+ * bundle (server/src/bowtie/vision/rrweb.bundle.js); recorder and
23
+ * replayer share the event format.
24
+ *
25
+ * Loading: rrweb is imported dynamically so hosts that disable
26
+ * observation (or render server-side) never evaluate it; a failed
27
+ * import degrades to no-capture and routes to onError, per the SDK's
28
+ * fail-soft contract.
29
+ *
30
+ * Batching:
31
+ * - flush every FLUSH_INTERVAL_MS, or at MAX_BATCH_EVENTS, or when
32
+ * the approximate batch size passes MAX_BATCH_BYTES (full
33
+ * snapshots with inlined images are heavy — don't let them queue).
34
+ * - final flush on dispose goes over sendBeacon (survives unload);
35
+ * beacons cap at ~64KB so an oversized final batch is truncated to
36
+ * the most recent events — replay loses the tail of a dying
37
+ * session, never the session.
38
+ */
39
+ import { postJson, postBeacon } from './transport.js';
40
+ const FLUSH_INTERVAL_MS = 5000;
41
+ const MAX_BATCH_EVENTS = 200;
42
+ const MAX_BATCH_BYTES = 800000;
43
+ const BEACON_SAFE_BYTES = 55000;
44
+ export function startObservations(deps) {
45
+ if (typeof window === 'undefined')
46
+ return { dispose: () => { } };
47
+ if (deps.observe?.enabled === false)
48
+ return { dispose: () => { } };
49
+ let disposed = false;
50
+ let stopRecording = null;
51
+ let buffer = [];
52
+ let bufferBytes = 0;
53
+ let flushTimer = null;
54
+ const path = `/api/runtime/sessions/${deps.sessionId}/observations`;
55
+ const flush = () => {
56
+ if (!buffer.length)
57
+ return;
58
+ const events = buffer;
59
+ buffer = [];
60
+ bufferBytes = 0;
61
+ void postJson(deps.cfg, path, { ...deps.buildBody(), events });
62
+ };
63
+ /** Unload-safe flush. Beacon payloads cap at ~64KB; keep the most
64
+ * recent events if the tail batch is oversized — replay loses the
65
+ * tail of a dying session, never the session. */
66
+ const flushBeacon = () => {
67
+ if (!buffer.length)
68
+ return;
69
+ let events = buffer;
70
+ buffer = [];
71
+ bufferBytes = 0;
72
+ // Size by the events alone (body adds ~200 constant bytes); halving
73
+ // converges in ≤4 rounds from the 800KB batch cap.
74
+ while (events.length > 1 && JSON.stringify(events).length > BEACON_SAFE_BYTES) {
75
+ events = events.slice(Math.ceil(events.length / 2));
76
+ }
77
+ postBeacon(deps.cfg, path, { ...deps.buildBody(), events });
78
+ };
79
+ const push = (event) => {
80
+ if (disposed)
81
+ return;
82
+ buffer.push(event);
83
+ // Approximate sizing — exact enough to keep batches under the cap.
84
+ try {
85
+ bufferBytes += JSON.stringify(event).length;
86
+ }
87
+ catch {
88
+ bufferBytes += 1000;
89
+ }
90
+ if (buffer.length >= MAX_BATCH_EVENTS || bufferBytes >= MAX_BATCH_BYTES)
91
+ flush();
92
+ };
93
+ // Dynamic import keeps rrweb out of hosts that never observe and
94
+ // makes a missing/incompatible module a soft failure.
95
+ void import('rrweb')
96
+ .then((rrweb) => {
97
+ if (disposed)
98
+ return;
99
+ const record = rrweb.record;
100
+ if (typeof record !== 'function') {
101
+ deps.cfg.onError?.(new Error('rrweb.record unavailable'), { method: 'OBSERVE', path });
102
+ return;
103
+ }
104
+ stopRecording = record({
105
+ emit: (event) => push(event),
106
+ // -- everything the user sees --
107
+ recordCanvas: true,
108
+ sampling: { canvas: 2 },
109
+ inlineImages: true,
110
+ collectFonts: true,
111
+ // -- except PII --
112
+ maskInputOptions: { password: true, email: true, tel: true },
113
+ maskAllInputs: deps.observe?.maskAllInputs ?? false,
114
+ maskTextClass: 'holostaff-mask',
115
+ blockClass: 'holostaff-block',
116
+ ignoreClass: 'holostaff-ignore',
117
+ ...(deps.observe?.blockSelector ? { blockSelector: deps.observe.blockSelector } : {}),
118
+ ...(deps.observe?.rrweb ?? {}),
119
+ }) ?? null;
120
+ flushTimer = setInterval(flush, FLUSH_INTERVAL_MS);
121
+ })
122
+ .catch((err) => {
123
+ deps.cfg.onError?.(err instanceof Error ? err : new Error(String(err)), { method: 'OBSERVE', path });
124
+ });
125
+ return {
126
+ dispose() {
127
+ if (disposed)
128
+ return;
129
+ disposed = true;
130
+ if (flushTimer != null) {
131
+ clearInterval(flushTimer);
132
+ flushTimer = null;
133
+ }
134
+ try {
135
+ stopRecording?.();
136
+ }
137
+ catch { /* recorder already gone */ }
138
+ stopRecording = null;
139
+ flushBeacon();
140
+ },
141
+ };
142
+ }
143
+ //# sourceMappingURL=observations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observations.js","sourceRoot":"","sources":["../src/observations.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -8,7 +8,28 @@
8
8
  */
9
9
  export type BowtieStage = 'awareness' | 'education' | 'selection' | 'mutual_commit' | 'onboarding' | 'adoption' | 'expansion';
10
10
  export declare const BOWTIE_STAGES: readonly BowtieStage[];
11
+ export interface ObserveOptions {
12
+ /** Master switch. Default true — vision-first runtime needs eyes. */
13
+ enabled?: boolean;
14
+ /** Mask every input, not just PII types. Default false. */
15
+ maskAllInputs?: boolean;
16
+ /** Extra CSS selector to block (region blanked in capture). */
17
+ blockSelector?: string;
18
+ /**
19
+ * Escape hatch: merged last into the rrweb record() options, so a
20
+ * customer can override anything (e.g. recordCanvas: false).
21
+ */
22
+ rrweb?: Record<string, unknown>;
23
+ }
11
24
  export interface InitOptions {
25
+ /**
26
+ * rrweb session-capture options. Capture is ON by default — the
27
+ * runtime is vision-first and decides from what it sees. Password /
28
+ * email / tel inputs are always masked; mark rendered PII with the
29
+ * `holostaff-mask` / `holostaff-block` CSS classes. Set
30
+ * `observe: { enabled: false }` to opt a host out entirely.
31
+ */
32
+ observe?: ObserveOptions;
12
33
  /** The knowledge source id (e.g. 'cli-source-abc'). Provided by the deploy PR. */
13
34
  sourceId: string;
14
35
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,WAAW,GACX,eAAe,GACf,YAAY,GACZ,UAAU,GACV,WAAW,CAAA;AAEf,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAQtC,CAAA;AAEV,MAAM,WAAW,WAAW;IAC1B,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE;AAED,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,WAAW,GACX,SAAS,GACT,YAAY,GACZ,SAAS,GACT,SAAS,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,WAAW,GACnB,WAAW,GACX,WAAW,GACX,WAAW,GACX,eAAe,GACf,YAAY,GACZ,UAAU,GACV,WAAW,CAAA;AAEf,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAQtC,CAAA;AAEV,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,2DAA2D;IAC3D,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,+DAA+D;IAC/D,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAChC;AAED,MAAM,WAAW,WAAW;IAC1B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB,kFAAkF;IAClF,QAAQ,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAA;IAChB,+EAA+E;IAC/E,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;OAIG;IACH,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CACtE;AAED,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,WAAW,GACX,SAAS,GACT,YAAY,GACZ,SAAS,GACT,SAAS,CAAA"}
package/dist/widget.d.ts CHANGED
@@ -1,20 +1,35 @@
1
1
  /**
2
- * Widget — Wave 3e.
2
+ * Widget — the intervention card.
3
3
  *
4
4
  * Listens to the SSE command channel for `fire_intervention` events
5
- * and renders a minimal text pill in the customer's host page. Wires
6
- * dismiss / engage user actions back to /outcome.
5
+ * and renders the copilot's message as a card in the host page,
6
+ * reporting dismiss / engage / ignore outcomes back to /outcome.
7
7
  *
8
- * Wave 3e scope:
9
- * - `text` modality only. Other modalities (voice / email / sms /
10
- * phone / screen_automation) are logged and ignored Wave 6.
11
- * - Single visible widget at a time. A new event while one is open
12
- * replaces it (and reports 'ignored' for the prior).
13
- * - No theming. Inline-styled floating pill, fixed lower-right.
8
+ * Appearance & lifecycle (redesigned with UX best practices after the
9
+ * first live dogfood session the v1 pill could linger after its
10
+ * outcome resolved and carried no copilot identity):
14
11
  *
15
- * The widget keeps zero dependencies on host CSS it injects its own
16
- * styles into the shadow root of a top-level container so host page
17
- * rules can't bleed in or out.
12
+ * - IDENTITY FIRST. Every card leads with the copilot's avatar and
13
+ * name the visitor always knows who is speaking. Missing avatar
14
+ * degrades to an initial-letter monogram, never an empty box.
15
+ * - RELEVANT OR SILENT. The server stamps the route the decision
16
+ * was made for; if the visitor has navigated since (stale fire),
17
+ * the card is not rendered and the outcome reports 'ignored'.
18
+ * - ANIMATED IN, ANIMATED OUT, THEN GONE. Entry: fade + 12px rise
19
+ * (240ms ease-out). Exit: fade + fall (180ms), and the DOM node is
20
+ * removed on transition end — no ghost cards. `prefers-reduced-
21
+ * motion` skips both.
22
+ * - ATTENTION IS BORROWED, NOT STOLEN. aria-live=polite (no focus
23
+ * steal), auto-ignore after 30s — but the timer PAUSES while the
24
+ * visitor hovers or focuses the card and resumes on leave, so
25
+ * reading slowly never counts as ignoring.
26
+ * - ONE CARD AT A TIME. A new fire animates the old card out (as
27
+ * 'ignored') before the new one enters.
28
+ * - Shadow-DOM isolated: host CSS can't bleed in, ours can't bleed
29
+ * out.
30
+ *
31
+ * Outcomes: ✕ → 'dismissed' · "Got it" → 'engaged' · 30s of unpaused
32
+ * inattention or stale-route skip → 'ignored'.
18
33
  */
19
34
  import { type TransportConfig } from './transport.js';
20
35
  export interface WidgetBindingDeps {
@@ -29,10 +44,5 @@ export interface WidgetBindingDeps {
29
44
  export interface WidgetBinding {
30
45
  dispose(): void;
31
46
  }
32
- /**
33
- * Start the widget subsystem. Subscribes to the SSE `fire_intervention`
34
- * event and shows the text pill when one arrives. Idempotent in the
35
- * sense that the SDK singleton ensures one binding per session.
36
- */
37
47
  export declare function startWidget(deps: WidgetBindingDeps): WidgetBinding;
38
48
  //# sourceMappingURL=widget.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAS/D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,eAAe,CAAA;IACpB,sFAAsF;IACtF,YAAY,EAAE,MAAM,MAAM,CAAA;IAC1B,mEAAmE;IACnE,SAAS,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,gEAAgE;IAChE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAA;CAChB;AAUD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAiDlE"}
1
+ {"version":3,"file":"widget.d.ts","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,OAAO,EAAY,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAW/D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,eAAe,CAAA;IACpB,sFAAsF;IACtF,YAAY,EAAE,MAAM,MAAM,CAAA;IAC1B,mEAAmE;IACnE,SAAS,EAAE,MAAM,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IACxC,gEAAgE;IAChE,MAAM,EAAE,WAAW,GAAG,IAAI,CAAA;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,OAAO,IAAI,IAAI,CAAA;CAChB;AAaD,wBAAgB,WAAW,CAAC,IAAI,EAAE,iBAAiB,GAAG,aAAa,CAoElE"}
package/dist/widget.js CHANGED
@@ -1,36 +1,55 @@
1
1
  /**
2
- * Widget — Wave 3e.
2
+ * Widget — the intervention card.
3
3
  *
4
4
  * Listens to the SSE command channel for `fire_intervention` events
5
- * and renders a minimal text pill in the customer's host page. Wires
6
- * dismiss / engage user actions back to /outcome.
5
+ * and renders the copilot's message as a card in the host page,
6
+ * reporting dismiss / engage / ignore outcomes back to /outcome.
7
7
  *
8
- * Wave 3e scope:
9
- * - `text` modality only. Other modalities (voice / email / sms /
10
- * phone / screen_automation) are logged and ignored Wave 6.
11
- * - Single visible widget at a time. A new event while one is open
12
- * replaces it (and reports 'ignored' for the prior).
13
- * - No theming. Inline-styled floating pill, fixed lower-right.
8
+ * Appearance & lifecycle (redesigned with UX best practices after the
9
+ * first live dogfood session the v1 pill could linger after its
10
+ * outcome resolved and carried no copilot identity):
14
11
  *
15
- * The widget keeps zero dependencies on host CSS it injects its own
16
- * styles into the shadow root of a top-level container so host page
17
- * rules can't bleed in or out.
12
+ * - IDENTITY FIRST. Every card leads with the copilot's avatar and
13
+ * name the visitor always knows who is speaking. Missing avatar
14
+ * degrades to an initial-letter monogram, never an empty box.
15
+ * - RELEVANT OR SILENT. The server stamps the route the decision
16
+ * was made for; if the visitor has navigated since (stale fire),
17
+ * the card is not rendered and the outcome reports 'ignored'.
18
+ * - ANIMATED IN, ANIMATED OUT, THEN GONE. Entry: fade + 12px rise
19
+ * (240ms ease-out). Exit: fade + fall (180ms), and the DOM node is
20
+ * removed on transition end — no ghost cards. `prefers-reduced-
21
+ * motion` skips both.
22
+ * - ATTENTION IS BORROWED, NOT STOLEN. aria-live=polite (no focus
23
+ * steal), auto-ignore after 30s — but the timer PAUSES while the
24
+ * visitor hovers or focuses the card and resumes on leave, so
25
+ * reading slowly never counts as ignoring.
26
+ * - ONE CARD AT A TIME. A new fire animates the old card out (as
27
+ * 'ignored') before the new one enters.
28
+ * - Shadow-DOM isolated: host CSS can't bleed in, ours can't bleed
29
+ * out.
30
+ *
31
+ * Outcomes: ✕ → 'dismissed' · "Got it" → 'engaged' · 30s of unpaused
32
+ * inattention or stale-route skip → 'ignored'.
18
33
  */
19
34
  import { postJson } from './transport.js';
20
- /** Auto-dismiss timeout — runtime doc §9.1 'ignored' outcome. */
35
+ /** Auto-ignore timeout — runtime doc §9.1 'ignored' outcome. */
21
36
  const AUTO_DISMISS_MS = 30000;
37
+ const ENTER_MS = 240;
38
+ const EXIT_MS = 180;
22
39
  /** Container id — single instance per page. */
23
40
  const CONTAINER_ID = 'holostaff-widget-root';
24
- /**
25
- * Start the widget subsystem. Subscribes to the SSE `fire_intervention`
26
- * event and shows the text pill when one arrives. Idempotent in the
27
- * sense that the SDK singleton ensures one binding per session.
28
- */
29
41
  export function startWidget(deps) {
30
42
  if (typeof window === 'undefined' || !deps.source) {
31
43
  return { dispose: () => { } };
32
44
  }
33
45
  let currentWidget = null;
46
+ const reportOutcome = (interventionId, outcome) => {
47
+ void postJson(deps.cfg, `/api/runtime/sessions/${deps.getSessionId()}/outcome`, {
48
+ ...deps.buildBody(),
49
+ interventionId,
50
+ outcome,
51
+ });
52
+ };
34
53
  const onFire = (rawEvent) => {
35
54
  let parsed = null;
36
55
  try {
@@ -44,12 +63,22 @@ export function startWidget(deps) {
44
63
  }
45
64
  if (!parsed)
46
65
  return;
47
- // Modality gate — only text is supported in v1.
66
+ // Modality gate — only text is renderable in this build.
48
67
  if (parsed.modality !== 'text') {
49
68
  deps.cfg.onError?.(new Error(`Modality '${parsed.modality}' is not supported in this SDK build`), { method: 'WIDGET', path: '(fire_intervention)' });
50
69
  return;
51
70
  }
52
- // If a widget is already up, evict it as 'ignored' before showing the new one.
71
+ // Stale-fire guard: the decision was made for a route the visitor
72
+ // has already left. Showing it now would be a non-sequitur — skip
73
+ // the render, close the loop as 'ignored'.
74
+ if (parsed.route) {
75
+ const decidedPath = parsed.route.split('?')[0];
76
+ if (decidedPath && decidedPath !== window.location.pathname) {
77
+ reportOutcome(parsed.interventionId, 'ignored');
78
+ return;
79
+ }
80
+ }
81
+ // One card at a time — retire the old one as 'ignored'.
53
82
  if (currentWidget) {
54
83
  currentWidget.reportAndClose('ignored');
55
84
  }
@@ -73,59 +102,131 @@ export function startWidget(deps) {
73
102
  function renderWidget(deps, event, onClosed) {
74
103
  const container = ensureContainer();
75
104
  const root = container.shadowRoot;
76
- // Clear any prior content (defensive — single-widget invariant).
105
+ // Defensive single-card invariant.
77
106
  root.innerHTML = '';
78
- const wrapper = document.createElement('div');
79
- wrapper.className = 'pill';
80
- wrapper.setAttribute('role', 'dialog');
81
- wrapper.setAttribute('aria-live', 'polite');
82
- wrapper.setAttribute('data-intervention-id', event.interventionId);
107
+ const reducedMotion = typeof window.matchMedia === 'function'
108
+ && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
109
+ const card = document.createElement('div');
110
+ card.className = 'card enter';
111
+ card.setAttribute('role', 'status');
112
+ card.setAttribute('aria-live', 'polite');
113
+ card.setAttribute('data-intervention-id', event.interventionId);
114
+ // -- Header: avatar + name + dismiss ---------------------------------
115
+ const head = document.createElement('div');
116
+ head.className = 'head';
117
+ const copilotName = event.copilot?.name?.trim() || 'Copilot';
118
+ const avatarUrl = event.copilot?.avatar?.trim() || '';
119
+ if (avatarUrl) {
120
+ const avatar = document.createElement('img');
121
+ avatar.className = 'avatar';
122
+ avatar.src = avatarUrl;
123
+ avatar.alt = '';
124
+ avatar.referrerPolicy = 'no-referrer';
125
+ // Broken avatar URL → swap in the monogram rather than the
126
+ // browser's broken-image glyph.
127
+ avatar.addEventListener('error', () => {
128
+ avatar.replaceWith(monogram(copilotName));
129
+ });
130
+ head.appendChild(avatar);
131
+ }
132
+ else {
133
+ head.appendChild(monogram(copilotName));
134
+ }
135
+ const name = document.createElement('div');
136
+ name.className = 'name';
137
+ name.textContent = copilotName;
138
+ head.appendChild(name);
139
+ const dismissBtn = document.createElement('button');
140
+ dismissBtn.className = 'x';
141
+ dismissBtn.type = 'button';
142
+ dismissBtn.setAttribute('aria-label', 'Dismiss');
143
+ dismissBtn.textContent = '✕';
144
+ head.appendChild(dismissBtn);
145
+ // -- Message + actions ------------------------------------------------
83
146
  const message = document.createElement('div');
84
147
  message.className = 'message';
85
148
  message.textContent = event.content || event.goal;
86
149
  const actions = document.createElement('div');
87
150
  actions.className = 'actions';
88
- const dismissBtn = document.createElement('button');
89
- dismissBtn.className = 'btn dismiss';
90
- dismissBtn.type = 'button';
91
- dismissBtn.textContent = 'Dismiss';
92
151
  const engageBtn = document.createElement('button');
93
152
  engageBtn.className = 'btn engage';
94
153
  engageBtn.type = 'button';
95
154
  engageBtn.textContent = 'Got it';
96
- actions.appendChild(dismissBtn);
97
155
  actions.appendChild(engageBtn);
98
- wrapper.appendChild(message);
99
- wrapper.appendChild(actions);
156
+ card.appendChild(head);
157
+ card.appendChild(message);
158
+ card.appendChild(actions);
100
159
  root.appendChild(styleNode());
101
- root.appendChild(wrapper);
160
+ root.appendChild(card);
161
+ // Entry animation — next frame so the transition actually runs.
162
+ if (reducedMotion) {
163
+ card.classList.remove('enter');
164
+ }
165
+ else {
166
+ requestAnimationFrame(() => requestAnimationFrame(() => card.classList.remove('enter')));
167
+ }
168
+ // -- Auto-ignore timer: pauses on hover/focus, resumes on leave ------
102
169
  let closed = false;
103
- let timeoutId = setTimeout(() => {
104
- instance.reportAndClose('ignored');
105
- }, AUTO_DISMISS_MS);
106
- const reportOutcome = (outcome) => {
107
- const body = {
170
+ let remainingMs = AUTO_DISMISS_MS;
171
+ let deadlineTimer = null;
172
+ let timerStartedAt = 0;
173
+ const startTimer = () => {
174
+ if (closed)
175
+ return;
176
+ timerStartedAt = Date.now();
177
+ deadlineTimer = setTimeout(() => instance.reportAndClose('ignored'), remainingMs);
178
+ };
179
+ const pauseTimer = () => {
180
+ if (deadlineTimer == null)
181
+ return;
182
+ clearTimeout(deadlineTimer);
183
+ deadlineTimer = null;
184
+ remainingMs = Math.max(1000, remainingMs - (Date.now() - timerStartedAt));
185
+ };
186
+ card.addEventListener('mouseenter', pauseTimer);
187
+ card.addEventListener('focusin', pauseTimer);
188
+ card.addEventListener('mouseleave', startTimer);
189
+ card.addEventListener('focusout', startTimer);
190
+ startTimer();
191
+ const sendOutcome = (outcome) => {
192
+ void postJson(deps.cfg, `/api/runtime/sessions/${deps.getSessionId()}/outcome`, {
108
193
  ...deps.buildBody(),
109
194
  interventionId: event.interventionId,
110
195
  outcome,
111
- };
112
- void postJson(deps.cfg, `/api/runtime/sessions/${deps.getSessionId()}/outcome`, body);
196
+ });
113
197
  };
114
198
  const close = (outcome) => {
115
199
  if (closed)
116
200
  return;
117
201
  closed = true;
118
- if (timeoutId != null) {
119
- clearTimeout(timeoutId);
120
- timeoutId = null;
202
+ if (deadlineTimer != null) {
203
+ clearTimeout(deadlineTimer);
204
+ deadlineTimer = null;
121
205
  }
122
206
  if (outcome)
123
- reportOutcome(outcome);
124
- try {
125
- root.removeChild(wrapper);
207
+ sendOutcome(outcome);
208
+ const remove = () => {
209
+ try {
210
+ root.removeChild(card);
211
+ }
212
+ catch { /* removed already */ }
213
+ onClosed();
214
+ };
215
+ if (reducedMotion) {
216
+ remove();
217
+ }
218
+ else {
219
+ card.classList.add('exit');
220
+ // transitionend can be swallowed if the tab is hidden — back it
221
+ // up with a timeout so the node ALWAYS leaves the DOM.
222
+ let removed = false;
223
+ const once = () => { if (!removed) {
224
+ removed = true;
225
+ remove();
226
+ } };
227
+ card.addEventListener('transitionend', once, { once: true });
228
+ setTimeout(once, EXIT_MS + 80);
126
229
  }
127
- catch { /* removed already */ }
128
- onClosed();
129
230
  };
130
231
  dismissBtn.addEventListener('click', () => close('dismissed'));
131
232
  engageBtn.addEventListener('click', () => close('engaged'));
@@ -136,6 +237,12 @@ function renderWidget(deps, event, onClosed) {
136
237
  };
137
238
  return instance;
138
239
  }
240
+ function monogram(name) {
241
+ const el = document.createElement('div');
242
+ el.className = 'avatar mono';
243
+ el.textContent = (name.trim()[0] ?? '?').toUpperCase();
244
+ return el;
245
+ }
139
246
  function ensureContainer() {
140
247
  let el = document.getElementById(CONTAINER_ID);
141
248
  if (el)
@@ -149,33 +256,55 @@ function ensureContainer() {
149
256
  }
150
257
  function styleNode() {
151
258
  const node = document.createElement('style');
152
- // Inline styles only — shadow-DOM scoped, no host page leakage.
259
+ // Shadow-DOM scoped; no host page leakage either direction.
153
260
  node.textContent = `
154
- .pill {
261
+ .card {
155
262
  pointer-events: auto;
156
- max-width: 360px;
263
+ width: 340px;
264
+ max-width: calc(100vw - 32px);
157
265
  background: #111;
158
266
  color: #fafafa;
159
- border-radius: 14px;
267
+ border-radius: 16px;
160
268
  box-shadow: 0 12px 32px rgba(0,0,0,0.32), 0 2px 8px rgba(0,0,0,0.12);
161
- padding: 14px 16px 12px;
162
- font: 14px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
269
+ padding: 12px 14px 12px;
270
+ font: 14px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, sans-serif;
271
+ opacity: 1;
272
+ transform: translateY(0);
273
+ transition: opacity ${ENTER_MS}ms ease-out, transform ${ENTER_MS}ms ease-out;
163
274
  }
164
- .message { margin-bottom: 12px; }
165
- .actions { display: flex; gap: 8px; justify-content: flex-end; }
275
+ .card.enter { opacity: 0; transform: translateY(12px); }
276
+ .card.exit { opacity: 0; transform: translateY(12px); transition-duration: ${EXIT_MS}ms; }
277
+ .head { display: flex; align-items: center; gap: 10px; margin-bottom: 8px; }
278
+ .avatar {
279
+ width: 36px; height: 36px; border-radius: 50%;
280
+ object-fit: cover; flex: none;
281
+ background: #2a2a2a;
282
+ }
283
+ .avatar.mono {
284
+ display: flex; align-items: center; justify-content: center;
285
+ color: #9ab8ff; font-weight: 600; font-size: 16px;
286
+ }
287
+ .name { font-weight: 600; font-size: 13px; color: #e8e8e8; flex: 1; }
288
+ .x {
289
+ appearance: none; border: 0; background: transparent;
290
+ color: #8a8a8a; font-size: 13px; line-height: 1;
291
+ padding: 6px; margin: -6px -4px -6px 0; border-radius: 8px;
292
+ cursor: pointer; flex: none;
293
+ }
294
+ .x:hover { color: #fff; background: rgba(255,255,255,0.08); }
295
+ .message { margin: 0 2px 12px; color: #f2f2f2; }
296
+ .actions { display: flex; justify-content: flex-end; }
166
297
  .btn {
167
- appearance: none;
168
- border: 0;
169
- padding: 6px 12px;
170
- border-radius: 8px;
171
- font: inherit;
172
- font-size: 13px;
298
+ appearance: none; border: 0;
299
+ padding: 7px 14px; border-radius: 9px;
300
+ font: inherit; font-size: 13px; font-weight: 500;
173
301
  cursor: pointer;
174
302
  }
175
- .btn.dismiss { background: transparent; color: #c7c7c7; }
176
- .btn.dismiss:hover { color: #fff; }
177
303
  .btn.engage { background: #4f8bff; color: #fff; }
178
304
  .btn.engage:hover { background: #6aa0ff; }
305
+ .btn:focus-visible, .x:focus-visible {
306
+ outline: 2px solid #9ab8ff; outline-offset: 2px;
307
+ }
179
308
  `;
180
309
  return node;
181
310
  }
@@ -1 +1 @@
1
- {"version":3,"file":"widget.js","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"widget.js","sourceRoot":"","sources":["../src/widget.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@holostaff/sdk",
3
- "version": "0.3.1",
3
+ "version": "0.4.1",
4
4
  "description": "Holostaff SDK — lifetime identity, stage detection, custom signal probes, and the intervention widget for the Holostaff runtime.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://docs.holostaff.ai",
@@ -38,5 +38,8 @@
38
38
  },
39
39
  "devDependencies": {
40
40
  "typescript": "^5.4.0"
41
+ },
42
+ "dependencies": {
43
+ "rrweb": "^2.0.0-alpha.4"
41
44
  }
42
45
  }