@syntrologie/runtime-sdk 2.11.0 → 2.13.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 (57) hide show
  1. package/CAPABILITIES.md +261 -173
  2. package/README.md +2 -0
  3. package/dist/actions/schema.d.ts +7 -7
  4. package/dist/actions/schema.js +3 -4
  5. package/dist/actions/types.d.ts +1 -1
  6. package/dist/actions/validation-core.d.ts +24 -0
  7. package/dist/actions/validation-rules.d.ts +74 -0
  8. package/dist/actions/validation.d.ts +5 -11
  9. package/dist/bootstrap-init.d.ts +33 -0
  10. package/dist/bootstrap-runtime.d.ts +7 -0
  11. package/dist/bootstrap-types.d.ts +90 -0
  12. package/dist/bootstrap.d.ts +19 -83
  13. package/dist/{chunk-Q77NT67W.js → chunk-BU4Z6PD7.js} +16 -1
  14. package/dist/{chunk-Q77NT67W.js.map → chunk-BU4Z6PD7.js.map} +1 -1
  15. package/dist/{chunk-H3FAYTUV.js → chunk-GF364MMB.js} +1343 -393
  16. package/dist/chunk-GF364MMB.js.map +7 -0
  17. package/dist/{chunk-NBFQGKSV.js → chunk-L6RJMBR2.js} +4 -4
  18. package/dist/{chunk-NBFQGKSV.js.map → chunk-L6RJMBR2.js.map} +2 -2
  19. package/dist/{chunk-37TTQRH5.js → chunk-XDYJ64IN.js} +2 -2
  20. package/dist/config/schema.js +2 -3
  21. package/dist/decisions/schema.js +1 -2
  22. package/dist/events/EventBus.d.ts +27 -1
  23. package/dist/events/history.d.ts +9 -0
  24. package/dist/events/index.d.ts +3 -0
  25. package/dist/events/types.d.ts +24 -0
  26. package/dist/events/validation.d.ts +7 -0
  27. package/dist/index.d.ts +0 -2
  28. package/dist/index.js +1133 -2039
  29. package/dist/index.js.map +4 -4
  30. package/dist/overlays/runtime/overlay/overlay-runner.d.ts +4 -0
  31. package/dist/overlays/runtime/overlay/overlay-state.d.ts +21 -0
  32. package/dist/overlays/types.d.ts +3 -1
  33. package/dist/react.js +6 -5
  34. package/dist/react.js.map +2 -2
  35. package/dist/smart-canvas.esm.js +92 -108
  36. package/dist/smart-canvas.esm.js.map +4 -4
  37. package/dist/smart-canvas.js +4763 -4955
  38. package/dist/smart-canvas.js.map +4 -4
  39. package/dist/smart-canvas.min.js +92 -108
  40. package/dist/smart-canvas.min.js.map +4 -4
  41. package/dist/telemetry/InterventionTracker.d.ts +23 -0
  42. package/dist/telemetry/adapters/posthog.d.ts +5 -10
  43. package/dist/telemetry/index.d.ts +1 -0
  44. package/dist/test/setup.d.ts +1 -0
  45. package/dist/token.d.ts +2 -0
  46. package/dist/version.d.ts +1 -1
  47. package/package.json +23 -29
  48. package/schema/canvas-config.schema.json +1 -1
  49. package/scripts/syntroReactPlugin.mjs +3 -0
  50. package/scripts/validate-config.mjs +42 -0
  51. package/dist/chunk-H3FAYTUV.js.map +0 -7
  52. package/dist/chunk-JMHRHAEL.js +0 -18
  53. package/dist/chunk-JMHRHAEL.js.map +0 -7
  54. package/dist/replayMirror-QZ3GQ527.js +0 -32
  55. package/dist/replayMirror-QZ3GQ527.js.map +0 -7
  56. package/dist/telemetry/replayMirror.d.ts +0 -7
  57. /package/dist/{chunk-37TTQRH5.js.map → chunk-XDYJ64IN.js.map} +0 -0
package/CAPABILITIES.md CHANGED
@@ -54,8 +54,8 @@ Change a page header when the element is visible:
54
54
  },
55
55
  "actions": [
56
56
  {
57
- "kind": "set_text",
58
- "anchorId": "h1.hero-title",
57
+ "kind": "content:setText",
58
+ "anchorId": { "selector": "h1.hero-title", "route": "/" },
59
59
  "text": "Welcome to Our New Experience"
60
60
  }
61
61
  ]
@@ -160,62 +160,73 @@ The widget reads auth credentials from the browser:
160
160
 
161
161
  DOM content modification capabilities for text, attributes, styles, HTML, and classes.
162
162
 
163
+ ## When to use
164
+
165
+ | Goal | Action |
166
+ |------|--------|
167
+ | Replace an element's text | `content:setText` |
168
+ | Change an HTML attribute (href, src, data-*) | `content:setAttr` |
169
+ | Modify inline styles (color, size, spacing) | `content:setStyle` |
170
+ | Inject new HTML before/after/inside an element | `content:insertHtml` |
171
+ | Add a CSS class (show/hide, animate) | `content:addClass` |
172
+ | Remove a CSS class | `content:removeClass` |
173
+
163
174
  ## Actions
164
175
 
165
- ### set_text
176
+ ### content:setText
166
177
 
167
178
  Replaces the text content of an element.
168
179
 
169
- | Property | Type | Required | Description |
170
- | ---------- | ------------ | -------- | ---------------- |
171
- | `kind` | `"set_text"` | Yes | Action type |
172
- | `anchorId` | string | Yes | Element selector |
173
- | `text` | string | Yes | New text content |
180
+ | Property | Type | Required | Description |
181
+ | ---------- | ------------------- | -------- | ---------------- |
182
+ | `kind` | `"content:setText"` | Yes | Action type |
183
+ | `anchorId` | object | Yes | `{ selector, route }` |
184
+ | `text` | string | Yes | New text content |
174
185
 
175
186
  ```json
176
187
  {
177
- "kind": "set_text",
178
- "anchorId": "h1.hero-title",
188
+ "kind": "content:setText",
189
+ "anchorId": { "selector": "h1.hero-title", "route": "/" },
179
190
  "text": "Start Your Free Trial Today"
180
191
  }
181
192
  ```
182
193
 
183
- ### set_attr
194
+ ### content:setAttr
184
195
 
185
196
  Sets an HTML attribute on an element.
186
197
 
187
- | Property | Type | Required | Description |
188
- | ---------- | ------------ | -------- | ---------------- |
189
- | `kind` | `"set_attr"` | Yes | Action type |
190
- | `anchorId` | string | Yes | Element selector |
191
- | `attr` | string | Yes | Attribute name |
192
- | `value` | string | Yes | Attribute value |
198
+ | Property | Type | Required | Description |
199
+ | ---------- | ------------------- | -------- | ---------------- |
200
+ | `kind` | `"content:setAttr"` | Yes | Action type |
201
+ | `anchorId` | object | Yes | `{ selector, route }` |
202
+ | `attr` | string | Yes | Attribute name |
203
+ | `value` | string | Yes | Attribute value |
193
204
 
194
205
  **Blocked attributes:** Event handlers (`onclick`, `onerror`, etc.) are not allowed.
195
206
 
196
207
  ```json
197
208
  {
198
- "kind": "set_attr",
199
- "anchorId": "#signup-form",
209
+ "kind": "content:setAttr",
210
+ "anchorId": { "selector": "#signup-form", "route": "/" },
200
211
  "attr": "data-experiment",
201
212
  "value": "signup-v2"
202
213
  }
203
214
  ```
204
215
 
205
- ### set_style
216
+ ### content:setStyle
206
217
 
207
218
  Sets inline CSS styles on an element.
208
219
 
209
- | Property | Type | Required | Description |
210
- | ---------- | ------------- | -------- | ------------------------ |
211
- | `kind` | `"set_style"` | Yes | Action type |
212
- | `anchorId` | string | Yes | Element selector |
213
- | `styles` | object | Yes | CSS property/value pairs |
220
+ | Property | Type | Required | Description |
221
+ | ---------- | -------------------- | -------- | ------------------------ |
222
+ | `kind` | `"content:setStyle"` | Yes | Action type |
223
+ | `anchorId` | object | Yes | `{ selector, route }` |
224
+ | `styles` | object | Yes | CSS property/value pairs |
214
225
 
215
226
  ```json
216
227
  {
217
- "kind": "set_style",
218
- "anchorId": ".hero-section",
228
+ "kind": "content:setStyle",
229
+ "anchorId": { "selector": ".hero-section", "route": "/" },
219
230
  "styles": {
220
231
  "background-color": "#1e40af",
221
232
  "padding": "2rem"
@@ -223,17 +234,17 @@ Sets inline CSS styles on an element.
223
234
  }
224
235
  ```
225
236
 
226
- ### insert_html
237
+ ### content:insertHtml
227
238
 
228
239
  Inserts HTML content relative to an element.
229
240
 
230
- | Property | Type | Required | Description |
231
- | ---------- | --------------- | -------- | ----------------------------------------------------------- |
232
- | `kind` | `"insert_html"` | Yes | Action type |
233
- | `anchorId` | string | Yes | Element selector |
234
- | `html` | string | Yes | HTML content (sanitized) |
235
- | `position` | string | Yes | `"before"`, `"after"`, `"prepend"`, `"append"`, `"replace"` |
236
- | `deepLink` | object | No | Makes the entire inserted element clickable to open the canvas panel and navigate to a specific tile |
241
+ | Property | Type | Required | Description |
242
+ | ---------- | --------------------- | -------- | ----------------------------------------------------------- |
243
+ | `kind` | `"content:insertHtml"` | Yes | Action type |
244
+ | `anchorId` | object | Yes | `{ selector, route }` |
245
+ | `html` | string | Yes | HTML content (sanitized) |
246
+ | `position` | string | Yes | `"before"`, `"after"`, `"prepend"`, `"append"`, `"replace"` |
247
+ | `deepLink` | object | No | Makes the entire inserted element clickable to open the canvas panel and navigate to a specific tile |
237
248
 
238
249
  **Positions:**
239
250
 
@@ -245,8 +256,8 @@ Inserts HTML content relative to an element.
245
256
 
246
257
  ```json
247
258
  {
248
- "kind": "insert_html",
249
- "anchorId": ".cta-button",
259
+ "kind": "content:insertHtml",
260
+ "anchorId": { "selector": ".cta-button", "route": "/" },
250
261
  "html": "<span class=\"badge\">NEW</span>",
251
262
  "position": "append"
252
263
  }
@@ -263,8 +274,8 @@ Use `deepLink` to make inserted content open the canvas panel and navigate to a
263
274
 
264
275
  ```json
265
276
  {
266
- "kind": "insert_html",
267
- "anchorId": "[data-id='pricing-heading']",
277
+ "kind": "content:insertHtml",
278
+ "anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
268
279
  "html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
269
280
  "position": "after",
270
281
  "deepLink": { "tileId": "plan_selector_faq" }
@@ -273,38 +284,38 @@ Use `deepLink` to make inserted content open the canvas panel and navigate to a
273
284
 
274
285
  The SDK automatically handles opening the canvas, setting the cursor to pointer, and publishing a `notification.deep_link` event. The click handler is wired up and cleaned up by the SDK — no JavaScript in the HTML is needed.
275
286
 
276
- ### add_class
287
+ ### content:addClass
277
288
 
278
289
  Adds a CSS class to an element.
279
290
 
280
- | Property | Type | Required | Description |
281
- | ----------- | ------------- | -------- | ----------------- |
282
- | `kind` | `"add_class"` | Yes | Action type |
283
- | `anchorId` | string | Yes | Element selector |
284
- | `className` | string | Yes | Class name to add |
291
+ | Property | Type | Required | Description |
292
+ | ----------- | -------------------- | -------- | ----------------- |
293
+ | `kind` | `"content:addClass"` | Yes | Action type |
294
+ | `anchorId` | object | Yes | `{ selector, route }` |
295
+ | `className` | string | Yes | Class name to add |
285
296
 
286
297
  ```json
287
298
  {
288
- "kind": "add_class",
289
- "anchorId": ".pricing-card",
299
+ "kind": "content:addClass",
300
+ "anchorId": { "selector": ".pricing-card", "route": "/pricing" },
290
301
  "className": "highlighted"
291
302
  }
292
303
  ```
293
304
 
294
- ### remove_class
305
+ ### content:removeClass
295
306
 
296
307
  Removes a CSS class from an element.
297
308
 
298
- | Property | Type | Required | Description |
299
- | ----------- | ---------------- | -------- | -------------------- |
300
- | `kind` | `"remove_class"` | Yes | Action type |
301
- | `anchorId` | string | Yes | Element selector |
302
- | `className` | string | Yes | Class name to remove |
309
+ | Property | Type | Required | Description |
310
+ | ----------- | ----------------------- | -------- | -------------------- |
311
+ | `kind` | `"content:removeClass"` | Yes | Action type |
312
+ | `anchorId` | object | Yes | `{ selector, route }` |
313
+ | `className` | string | Yes | Class name to remove |
303
314
 
304
315
  ```json
305
316
  {
306
- "kind": "remove_class",
307
- "anchorId": ".pricing-card",
317
+ "kind": "content:removeClass",
318
+ "anchorId": { "selector": ".pricing-card", "route": "/pricing" },
308
319
  "className": "hidden"
309
320
  }
310
321
  ```
@@ -316,24 +327,50 @@ Removes a CSS class from an element.
316
327
 
317
328
  Collapsible Q&A accordion with actions, rich content, feedback, and personalization.
318
329
 
319
- ## Actions
330
+ ## When to use
331
+
332
+ | Goal | Action |
333
+ |------|--------|
334
+ | Add an FAQ accordion widget | Add a **tile** in `tiles[]` with `widget: "adaptive-faq:accordion"` |
335
+ | Scroll to and expand a specific FAQ item | `faq:scroll_to` |
336
+ | Open, close, or toggle a FAQ item | `faq:toggle_item` |
337
+ | Add, remove, reorder, or replace FAQ items | `faq:update` |
320
338
 
321
- ### mount_faq
339
+ ## Mounting an FAQ Widget
322
340
 
323
- Mounts an FAQ accordion widget to a surface slot.
341
+ FAQ widgets are mounted via **tiles** (not actions). Add an entry to the `tiles[]` array in the config:
342
+
343
+ ```json
344
+ {
345
+ "tiles": [
346
+ {
347
+ "id": "my-faq",
348
+ "title": "Frequently Asked Questions",
349
+ "content": {
350
+ "type": "custom",
351
+ "component": "adaptive-faq:accordion",
352
+ "props": {
353
+ "expandBehavior": "single",
354
+ "searchable": true,
355
+ "items": [ ... ]
356
+ }
357
+ }
358
+ }
359
+ ]
360
+ }
361
+ ```
362
+
363
+ ### Tile Props
324
364
 
325
365
  | Property | Type | Required | Description |
326
366
  | ----------------------- | --------------------------------- | -------- | ------------------------------------------------------------------- |
327
- | `kind` | `"mount_faq"` | Yes | Action type |
328
- | `slot` | string | Yes | Target slot (e.g., `"drawer_right"`, `"overlay_center"`) |
329
- | `config.title` | string | No | Widget title |
330
- | `config.expandBehavior` | `"single"` \| `"multiple"` | No | Whether one or many items can be open at once (default: `"single"`) |
331
- | `config.searchable` | boolean | No | Show a search/filter input (default: `false`) |
332
- | `config.theme` | `"light"` \| `"dark"` \| `"auto"` | No | Color theme (default: `"auto"`) |
333
- | `config.items` | array | Yes | FAQ items (see below) |
334
- | `config.feedback` | boolean \| FeedbackConfig | No | Enable per-item feedback widget |
335
- | `config.ordering` | OrderingStrategy | No | Item ordering strategy (default: `"static"`) |
336
- | `config.injections` | InjectionRule[] | No | Dynamic item injection rules |
367
+ | `expandBehavior` | `"single"` \| `"multiple"` | No | Whether one or many items can be open at once (default: `"single"`) |
368
+ | `searchable` | boolean | No | Show a search/filter input (default: `false`) |
369
+ | `theme` | `"light"` \| `"dark"` \| `"auto"` | No | Color theme (default: `"auto"`) |
370
+ | `items` | array | Yes | FAQ items (see below) |
371
+ | `feedback` | boolean \| FeedbackConfig | No | Enable per-item feedback widget |
372
+ | `ordering` | OrderingStrategy | No | Item ordering strategy (default: `"static"`) |
373
+ | `injections` | InjectionRule[] | No | Dynamic item injection rules |
337
374
 
338
375
  ### FAQ Item Schema
339
376
 
@@ -348,65 +385,63 @@ Each item in the `items` array:
348
385
  | `config.category` | string | No | Category for grouping items |
349
386
  | `config.priority` | number | No | Priority weight for ordering |
350
387
  | `config.answerStrategy` | AnswerStrategy | No | AI-generated answer configuration |
351
- | `showWhen` | DecisionStrategy \| null | No | Conditional visibility strategy |
388
+ | `triggerWhen` | DecisionStrategy \| null | No | Conditional visibility strategy |
389
+
390
+ **Full tile example with FAQ items:**
352
391
 
353
392
  ```json
354
393
  {
355
- "kind": "mount_faq",
356
- "slot": "drawer_right",
357
- "config": {
358
- "title": "Frequently Asked Questions",
359
- "expandBehavior": "single",
360
- "searchable": true,
361
- "theme": "auto",
362
- "feedback": {
363
- "style": "thumbs",
364
- "prompt": "Was this helpful?"
365
- },
366
- "ordering": "priority",
367
- "items": [
368
- {
369
- "kind": "faq:question",
370
- "config": {
371
- "id": "getting-started",
372
- "question": "How do I get started?",
373
- "answer": "Sign up for a free account and follow our quickstart guide.",
374
- "category": "General",
375
- "priority": 10
376
- }
377
- },
378
- {
379
- "kind": "faq:question",
380
- "config": {
381
- "id": "payment-methods",
382
- "question": "What payment methods do you accept?",
383
- "answer": "We accept all major credit cards and PayPal.",
384
- "category": "Billing",
385
- "priority": 5
386
- },
387
- "showWhen": {
388
- "type": "rules",
389
- "rules": [
394
+ "tiles": [
395
+ {
396
+ "id": "help-faq",
397
+ "title": "Frequently Asked Questions",
398
+ "content": {
399
+ "type": "custom",
400
+ "component": "adaptive-faq:accordion",
401
+ "props": {
402
+ "expandBehavior": "single",
403
+ "searchable": true,
404
+ "feedback": {
405
+ "style": "thumbs",
406
+ "prompt": "Was this helpful?"
407
+ },
408
+ "ordering": "priority",
409
+ "items": [
390
410
  {
391
- "conditions": [{ "type": "page_url", "pattern": "/pricing*" }],
392
- "value": true
411
+ "kind": "faq:question",
412
+ "config": {
413
+ "id": "getting-started",
414
+ "question": "How do I get started?",
415
+ "answer": "Sign up for a free account and follow our quickstart guide.",
416
+ "category": "General",
417
+ "priority": 10
418
+ }
419
+ },
420
+ {
421
+ "kind": "faq:question",
422
+ "config": {
423
+ "id": "payment-methods",
424
+ "question": "What payment methods do you accept?",
425
+ "answer": "We accept all major credit cards and PayPal.",
426
+ "category": "Billing",
427
+ "priority": 5
428
+ }
393
429
  }
394
- ],
395
- "default": false
430
+ ]
396
431
  }
397
432
  }
398
- ]
399
- }
433
+ }
434
+ ]
400
435
  }
401
436
  ```
402
437
 
403
- ### scroll_to_faq
438
+ ### faq:scroll_to
404
439
 
405
440
  Scrolls the viewport to a specific FAQ item and optionally expands it.
406
441
 
407
442
  | Property | Type | Required | Default | Description |
408
443
  | -------------- | ----------------- | -------- | ---------- | ------------------------------------------ |
409
- | `kind` | `"scroll_to_faq"` | Yes | | Action type |
444
+ | `kind` | `"faq:scroll_to"` | Yes | | Action type |
410
445
  | `itemId` | string | No\* | | Target item ID |
411
446
  | `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
412
447
  | `expand` | boolean | No | `true` | Whether to expand the item after scrolling |
@@ -416,20 +451,20 @@ Scrolls the viewport to a specific FAQ item and optionally expands it.
416
451
 
417
452
  ```json
418
453
  {
419
- "kind": "scroll_to_faq",
454
+ "kind": "faq:scroll_to",
420
455
  "itemId": "payment-methods",
421
456
  "expand": true,
422
457
  "behavior": "smooth"
423
458
  }
424
459
  ```
425
460
 
426
- ### toggle_faq_item
461
+ ### faq:toggle_item
427
462
 
428
463
  Opens, closes, or toggles a FAQ item's expanded state.
429
464
 
430
465
  | Property | Type | Required | Default | Description |
431
466
  | -------------- | ------------------- | -------- | ---------- | --------------------------------------- |
432
- | `kind` | `"toggle_faq_item"` | Yes | | Action type |
467
+ | `kind` | `"faq:toggle_item"` | Yes | | Action type |
433
468
  | `itemId` | string | No\* | | Target item ID |
434
469
  | `itemQuestion` | string | No\* | | Target item question text (fuzzy match) |
435
470
  | `state` | string | No | `"toggle"` | `"open"`, `"closed"`, `"toggle"` |
@@ -438,19 +473,19 @@ Opens, closes, or toggles a FAQ item's expanded state.
438
473
 
439
474
  ```json
440
475
  {
441
- "kind": "toggle_faq_item",
476
+ "kind": "faq:toggle_item",
442
477
  "itemId": "getting-started",
443
478
  "state": "open"
444
479
  }
445
480
  ```
446
481
 
447
- ### update_faq
482
+ ### faq:update
448
483
 
449
484
  Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
450
485
 
451
486
  | Property | Type | Required | Description |
452
487
  | ----------- | ------------------- | -------- | ------------------------------------------------------- |
453
- | `kind` | `"update_faq"` | Yes | Action type |
488
+ | `kind` | `"faq:update"` | Yes | Action type |
454
489
  | `operation` | string | Yes | `"add"`, `"remove"`, `"reorder"`, `"replace"` |
455
490
  | `items` | FAQQuestionAction[] | No | Items to add or replace with (required for add/replace) |
456
491
  | `itemId` | string | No | Item to remove (required for remove) |
@@ -462,7 +497,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
462
497
 
463
498
  ```json
464
499
  {
465
- "kind": "update_faq",
500
+ "kind": "faq:update",
466
501
  "operation": "add",
467
502
  "position": "append",
468
503
  "items": [
@@ -482,7 +517,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
482
517
 
483
518
  ```json
484
519
  {
485
- "kind": "update_faq",
520
+ "kind": "faq:update",
486
521
  "operation": "remove",
487
522
  "itemId": "outdated-question"
488
523
  }
@@ -492,7 +527,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
492
527
 
493
528
  ```json
494
529
  {
495
- "kind": "update_faq",
530
+ "kind": "faq:update",
496
531
  "operation": "reorder",
497
532
  "order": ["getting-started", "new-feature", "payment-methods"]
498
533
  }
@@ -502,7 +537,7 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
502
537
 
503
538
  ```json
504
539
  {
505
- "kind": "update_faq",
540
+ "kind": "faq:update",
506
541
  "operation": "replace",
507
542
  "items": [
508
543
  {
@@ -521,12 +556,12 @@ Dynamically adds, removes, reorders, or replaces FAQ items at runtime.
521
556
 
522
557
  The FAQ widget uses a **compositional action pattern** where `faq:question` actions serve as configuration data rendered by the widget, rather than being executed by the runtime. This allows:
523
558
 
524
- - **Per-item conditional visibility** via `showWhen` strategies -- items can appear or hide based on page URL, user segment, viewport, or any DecisionStrategy condition
559
+ - **Per-item conditional visibility** via `triggerWhen` strategies -- items can appear or hide based on page URL, user segment, viewport, or any DecisionStrategy condition
525
560
  - **Category grouping** -- items with a `category` field are grouped under collapsible section headers
526
561
  - **Dynamic injection** -- `injections` rules can add items when trigger conditions are met, supporting contextual FAQ content
527
562
  - **Ordering control** -- the `ordering` strategy determines how items are sorted within categories
528
563
 
529
- Items without `showWhen` are always visible. Items without `category` appear in an ungrouped section.
564
+ Items without `triggerWhen` are always visible. Items without `category` appear in an ungrouped section.
530
565
 
531
566
  ## Rich Answer Content
532
567
 
@@ -672,17 +707,67 @@ Injection rules add contextual FAQ items when conditions are met:
672
707
 
673
708
  Gamification capabilities including badges, points, and leaderboards.
674
709
 
710
+ ## When to use
711
+
712
+ | Goal | Action |
713
+ |------|--------|
714
+ | Award a badge to a user | `gamification:awardBadge` |
715
+ | Add points to a user's score | `gamification:addPoints` |
716
+ | Mount a gamification widget (leaderboard, progress) | Add a **tile** with `component: "adaptive-gamification:leaderboard"` |
717
+
675
718
  ## Actions
676
719
 
677
- ### mount_gamification
720
+ ### gamification:awardBadge
721
+
722
+ Awards a badge to the current user.
723
+
724
+ | Property | Type | Required | Description |
725
+ | -------- | -------------------------- | -------- | ---------------- |
726
+ | `kind` | `"gamification:awardBadge"` | Yes | Action type |
727
+ | `badgeId` | string | Yes | Badge identifier |
728
+
729
+ ```json
730
+ {
731
+ "kind": "gamification:awardBadge",
732
+ "badgeId": "first-purchase"
733
+ }
734
+ ```
735
+
736
+ ### gamification:addPoints
737
+
738
+ Adds points to the current user's score.
678
739
 
679
- Mounts gamification UI elements.
740
+ | Property | Type | Required | Description |
741
+ | -------- | -------------------------- | -------- | ---------------- |
742
+ | `kind` | `"gamification:addPoints"` | Yes | Action type |
743
+ | `points` | number | Yes | Points to add |
680
744
 
681
- | Property | Type | Required | Description |
682
- | -------- | ---------------------- | -------- | -------------------------- |
683
- | `kind` | `"mount_gamification"` | Yes | Action type |
684
- | `slot` | string | Yes | Target slot |
685
- | `config` | object | Yes | Gamification configuration |
745
+ ```json
746
+ {
747
+ "kind": "gamification:addPoints",
748
+ "points": 50
749
+ }
750
+ ```
751
+
752
+ ### Gamification Widget (via Tile)
753
+
754
+ Mount gamification UI elements (leaderboard, badge display, progress tracker) via a **tile**:
755
+
756
+ ```json
757
+ {
758
+ "tiles": [
759
+ {
760
+ "id": "gamification",
761
+ "title": "Your Progress",
762
+ "content": {
763
+ "type": "custom",
764
+ "component": "adaptive-gamification:leaderboard",
765
+ "props": { ... }
766
+ }
767
+ }
768
+ ]
769
+ }
770
+ ```
686
771
 
687
772
  ### Configuration Schema
688
773
 
@@ -707,9 +792,13 @@ Mounts gamification UI elements.
707
792
 
708
793
  ```json
709
794
  {
710
- "kind": "mount_gamification",
711
- "slot": "overlay_corner_br",
712
- "config": {
795
+ "tiles": [{
796
+ "id": "gamification-widget",
797
+ "title": "Achievements",
798
+ "content": {
799
+ "type": "custom",
800
+ "component": "adaptive-gamification:leaderboard",
801
+ "props": {
713
802
  "badges": [
714
803
  {
715
804
  "id": "first-purchase",
@@ -719,18 +808,6 @@ Mounts gamification UI elements.
719
808
  "trigger": {
720
809
  "event": "purchase_completed"
721
810
  }
722
- },
723
- {
724
- "id": "explorer",
725
- "name": "Explorer",
726
- "icon": "compass",
727
- "description": "Visited 10 different pages",
728
- "trigger": {
729
- "event": "page_view",
730
- "conditions": [
731
- { "type": "session_metric", "key": "unique_pages", "operator": ">=", "threshold": 10 }
732
- ]
733
- }
734
811
  }
735
812
  ],
736
813
  "points": {
@@ -759,6 +836,14 @@ Mounts gamification UI elements.
759
836
 
760
837
  Navigation tips accordion widget with conditional item visibility and toast notifications.
761
838
 
839
+ ## When to use
840
+
841
+ | Goal | Action |
842
+ |------|--------|
843
+ | Scroll to an element on the page | `navigation:scrollTo` |
844
+ | Navigate to a different URL | `navigation:navigate` |
845
+ | Show contextual navigation tips widget | Add a **tile** with `component: "adaptive-nav:tips"` |
846
+
762
847
  ## Widget: `adaptive-nav:tips`
763
848
 
764
849
  Accordion of contextual navigation tips. Each tip has a collapsible header and expanded body with optional CTA link.
@@ -879,15 +964,26 @@ Navigates to a URL.
879
964
 
880
965
  Visual overlay capabilities including highlights, tooltips, badges, pulse animations, and celebrations.
881
966
 
967
+ ## When to use
968
+
969
+ | Goal | Action |
970
+ |------|--------|
971
+ | Draw attention to an element (spotlight) | `overlays:highlight` |
972
+ | Show contextual help or guidance near an element | `overlays:tooltip` |
973
+ | Add a notification indicator (count, "NEW") | `overlays:badge` |
974
+ | Subtle attention-grab animation | `overlays:pulse` |
975
+ | Show a blocking or non-blocking dialog | `overlays:modal` |
976
+ | Celebrate a user achievement | `overlays:celebrate` |
977
+
882
978
  ## Actions
883
979
 
884
- ### highlight
980
+ ### overlays:highlight
885
981
 
886
982
  Creates a spotlight effect around an element with a scrim overlay.
887
983
 
888
984
  | Property | Type | Required | Default | Description |
889
985
  | -------------------- | ------------- | -------- | ----------- | --------------------------------------- |
890
- | `kind` | `"highlight"` | Yes | | Action type |
986
+ | `kind` | `"overlays:highlight"` | Yes | | Action type |
891
987
  | `anchorId` | string | Yes | | Element selector |
892
988
  | `style.color` | string | No | `"#5b8cff"` | Ring color |
893
989
  | `style.scrimOpacity` | number | No | `0.55` | Backdrop opacity 0-1 (set to 0 to hide) |
@@ -896,7 +992,7 @@ Creates a spotlight effect around an element with a scrim overlay.
896
992
 
897
993
  ```json
898
994
  {
899
- "kind": "highlight",
995
+ "kind": "overlays:highlight",
900
996
  "anchorId": "#signup-button",
901
997
  "style": {
902
998
  "color": "#22c55e",
@@ -905,13 +1001,13 @@ Creates a spotlight effect around an element with a scrim overlay.
905
1001
  }
906
1002
  ```
907
1003
 
908
- ### tooltip
1004
+ ### overlays:tooltip
909
1005
 
910
1006
  Shows a tooltip near an element with optional title, body, and CTA.
911
1007
 
912
1008
  | Property | Type | Required | Default | Description |
913
1009
  | -------------------- | ----------- | -------- | ------------- | -------------------------------------- |
914
- | `kind` | `"tooltip"` | Yes | | Action type |
1010
+ | `kind` | `"overlays:tooltip"` | Yes | | Action type |
915
1011
  | `anchorId` | string | Yes | | Element selector |
916
1012
  | `content.title` | string | No | | Tooltip heading |
917
1013
  | `content.body` | string | Yes | | Tooltip text |
@@ -927,14 +1023,14 @@ Shows a tooltip near an element with optional title, body, and CTA.
927
1023
 
928
1024
  ```json
929
1025
  {
930
- "kind": "tooltip",
1026
+ "kind": "overlays:tooltip",
931
1027
  "anchorId": "#pricing-toggle",
932
1028
  "content": {
933
1029
  "title": "Save 20%",
934
1030
  "body": "Switch to annual billing to save on your subscription.",
935
1031
  "cta": {
936
1032
  "label": "Switch Now",
937
- "action": { "kind": "navigate", "url": "/billing?annual=true" }
1033
+ "action": { "kind": "navigation:navigate", "url": "/billing?annual=true" }
938
1034
  }
939
1035
  },
940
1036
  "placement": "bottom",
@@ -973,45 +1069,45 @@ Use `ctaButtons` for tooltips with multiple actions. Each button has:
973
1069
  - `"faq:open:<questionId>"` — Convention for companion FAQ tooltips (see adaptive-faq CAPABILITIES for details). Publishes `action.tooltip_cta_clicked` which the FAQ widget listens for.
974
1070
  - Any other value — Publishes `action.tooltip_cta_clicked` with the `actionId` in event props for custom handling
975
1071
 
976
- ### badge
1072
+ ### overlays:badge
977
1073
 
978
1074
  Adds a small badge indicator near an element.
979
1075
 
980
1076
  | Property | Type | Required | Default | Description |
981
1077
  | ---------- | --------- | -------- | ------------- | -------------------------------------------------------------- |
982
- | `kind` | `"badge"` | Yes | | Action type |
1078
+ | `kind` | `"overlays:badge"` | Yes | | Action type |
983
1079
  | `anchorId` | string | Yes | | Element selector |
984
1080
  | `text` | string | Yes | | Badge text (e.g., "NEW", "3") |
985
1081
  | `position` | string | No | `"top-right"` | `"top-left"`, `"top-right"`, `"bottom-left"`, `"bottom-right"` |
986
1082
 
987
1083
  ```json
988
1084
  {
989
- "kind": "badge",
1085
+ "kind": "overlays:badge",
990
1086
  "anchorId": "#inbox-icon",
991
1087
  "text": "5",
992
1088
  "position": "top-right"
993
1089
  }
994
1090
  ```
995
1091
 
996
- ### pulse
1092
+ ### overlays:pulse
997
1093
 
998
1094
  Adds a pulsing animation to draw attention.
999
1095
 
1000
1096
  | Property | Type | Required | Default | Description |
1001
1097
  | ---------- | --------- | -------- | ------- | ------------------------ |
1002
- | `kind` | `"pulse"` | Yes | | Action type |
1098
+ | `kind` | `"overlays:pulse"` | Yes | | Action type |
1003
1099
  | `anchorId` | string | Yes | | Element selector |
1004
1100
  | `duration` | number | No | `2000` | Animation duration in ms |
1005
1101
 
1006
1102
  ```json
1007
1103
  {
1008
- "kind": "pulse",
1104
+ "kind": "overlays:pulse",
1009
1105
  "anchorId": ".notification-bell",
1010
1106
  "duration": 3000
1011
1107
  }
1012
1108
  ```
1013
1109
 
1014
- ### modal
1110
+ ### overlays:modal
1015
1111
 
1016
1112
  Shows a centered modal dialog with optional CTA buttons.
1017
1113
 
@@ -1051,7 +1147,7 @@ Shows a centered modal dialog with optional CTA buttons.
1051
1147
  }
1052
1148
  ```
1053
1149
 
1054
- ### celebrate
1150
+ ### overlays:celebrate
1055
1151
 
1056
1152
  Renders a fullscreen Canvas 2D celebration effect. One action kind with a pluggable `effect` parameter supporting multiple visual presets.
1057
1153
 
@@ -1273,15 +1369,7 @@ Control when adaptives activate using `DecisionStrategy`:
1273
1369
 
1274
1370
  ### 1. Choose the Right Action Type
1275
1371
 
1276
- | Goal | Action |
1277
- |------|--------|
1278
- | Change text | `set_text` |
1279
- | Add visual indicator | `badge`, `pulse` |
1280
- | Show help text | `tooltip` |
1281
- | Draw attention | `highlight` |
1282
- | Add content | `insert_html` |
1283
- | Navigate user | `scroll_to`, `navigate` |
1284
- | Show UI panel | `mount_widget` + Surfaces |
1372
+ Each adaptive package has a "When to use" guide at the top of its capabilities section above. Refer to those for action selection guidance.
1285
1373
 
1286
1374
  ### 2. Anchor Selection
1287
1375
 
@@ -1313,8 +1401,8 @@ When `content:insertHtml` needs to open the canvas panel (e.g., a "Help Me Choos
1313
1401
 
1314
1402
  ```json
1315
1403
  {
1316
- "kind": "insert_html",
1317
- "anchorId": "[data-id='pricing-heading']",
1404
+ "kind": "content:insertHtml",
1405
+ "anchorId": { "selector": "[data-id='pricing-heading']", "route": "/" },
1318
1406
  "html": "<button style='background: #4a90e2; color: white; border: none; padding: 8px 16px; border-radius: 20px; cursor: pointer;'>Help Me Choose</button>",
1319
1407
  "position": "after",
1320
1408
  "deepLink": { "tileId": "plan_selector_faq" }
@@ -1327,4 +1415,4 @@ The `deepLink` object:
1327
1415
 
1328
1416
  The SDK automatically opens the canvas, navigates to the tile, sets cursor to pointer, and wires up click/cleanup handlers.
1329
1417
 
1330
- **NEVER use `onclick`, `window.SynOS`, or any JavaScript in `insert_html` HTML strings.** The HTML is sanitized and event handlers are stripped. Use `deepLink` instead.
1418
+ **NEVER use `onclick`, `window.SynOS`, or any JavaScript in `content:insertHtml` HTML strings.** The HTML is sanitized and event handlers are stripped. Use `deepLink` instead.