@syntrologie/adapt-chatbot 2.8.0-canary.414 → 2.8.0-canary.416

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.
@@ -20,7 +20,7 @@
20
20
  */
21
21
  import { LitElement } from 'lit';
22
22
  import './AdaptiveChatTrail.js';
23
- import type { InlineTrailWidget, TileReceipt, TrailMessage } from './AdaptiveChatTrail.js';
23
+ import type { InlineTrailWidget, InlineWidgetMounter, TileReceipt, TrailMessage } from './AdaptiveChatTrail.js';
24
24
  export declare class AdaptiveChatBar extends LitElement {
25
25
  static properties: {
26
26
  messages: {
@@ -58,6 +58,9 @@ export declare class AdaptiveChatBar extends LitElement {
58
58
  inlineWidgets: {
59
59
  attribute: boolean;
60
60
  };
61
+ mountInlineWidget: {
62
+ attribute: boolean;
63
+ };
61
64
  _input: {
62
65
  state: boolean;
63
66
  };
@@ -68,6 +71,10 @@ export declare class AdaptiveChatBar extends LitElement {
68
71
  /** Widgets rendered inline in the trail (reco carousel), sourced from
69
72
  * the store's `chat-inline` slot mounts. Forwarded to the trail. */
70
73
  inlineWidgets: InlineTrailWidget[];
74
+ /** Registry-backed mounter for inline widgets whose id is not their
75
+ * custom-element tag (product card, comparison, FAQ). Set by the
76
+ * mountable from `runtime.widgets`; forwarded to the trail. */
77
+ mountInlineWidget: InlineWidgetMounter | undefined;
71
78
  /**
72
79
  * Live reasoning narration from the model — streamed in via
73
80
  * AG-UI THINKING_TEXT_MESSAGE_CONTENT events and forwarded by
@@ -1 +1 @@
1
- {"version":3,"file":"AdaptiveChatBar.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAQ,UAAU,EAAW,MAAM,KAAK,CAAC;AAGhD,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAM3F,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAaxB;IAEF,QAAQ,EAAE,YAAY,EAAE,CAAM;IAC9B,SAAS,UAAS;IAClB,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC;yEACqE;IACrE,aAAa,EAAE,iBAAiB,EAAE,CAAM;IAExC;;;;;;;OAOG;IACH,YAAY,SAAM;IAClB;;;;;OAKG;IACH,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAa;IAE3E;;;uDAGmD;IACnD,aAAa,UAAS;IACtB,WAAW,SAAuB;IAClC;;;;;OAKG;IACH,aAAa,SAA0B;IACvC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAa;IACzC;;;;;;OAMG;IACH,QAAQ,UAAS;IACjB,MAAM,SAAM;IAEH,gBAAgB,IAAI,WAAW;IAI/B,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAYrC,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAShB;IAKF,OAAO,CAAC,kBAAkB,CAMxB;IAEF,OAAO,CAAC,sBAAsB,CAM5B;IAEF,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,iBAAiB,CAEvB;IAEF,OAAO,CAAC,KAAK;IAoBb;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB,CAmBxB;IAEF;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB,CAiBvB;IAEO,MAAM;CAiDhB;AA8OD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
1
+ {"version":3,"file":"AdaptiveChatBar.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBar.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,EAAQ,UAAU,EAAW,MAAM,KAAK,CAAC;AAGhD,OAAO,wBAAwB,CAAC;AAChC,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,WAAW,EACX,YAAY,EACb,MAAM,wBAAwB,CAAC;AAMhC,qBAAa,eAAgB,SAAQ,UAAU;IAC7C,OAAgB,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAcxB;IAEF,QAAQ,EAAE,YAAY,EAAE,CAAM;IAC9B,SAAS,UAAS;IAClB,YAAY,EAAE,WAAW,EAAE,CAAM;IACjC;yEACqE;IACrE,aAAa,EAAE,iBAAiB,EAAE,CAAM;IACxC;;oEAEgE;IAChE,iBAAiB,EAAE,mBAAmB,GAAG,SAAS,CAAa;IAE/D;;;;;;;OAOG;IACH,YAAY,SAAM;IAClB;;;;;OAKG;IACH,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,SAAS,CAAa;IAE3E;;;uDAGmD;IACnD,aAAa,UAAS;IACtB,WAAW,SAAuB;IAClC;;;;;OAKG;IACH,aAAa,SAA0B;IACvC;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAa;IACzC;;;;;;OAMG;IACH,QAAQ,UAAS;IACjB,MAAM,SAAM;IAEH,gBAAgB,IAAI,WAAW;IAI/B,iBAAiB,IAAI,IAAI;IASzB,oBAAoB,IAAI,IAAI;IAYrC,OAAO,CAAC,QAAQ,CAEd;IAEF,OAAO,CAAC,UAAU,CAShB;IAKF,OAAO,CAAC,kBAAkB,CAMxB;IAEF,OAAO,CAAC,sBAAsB,CAM5B;IAEF,OAAO,CAAC,uBAAuB,CAK7B;IAEF,OAAO,CAAC,iBAAiB,CAEvB;IAEF,OAAO,CAAC,KAAK;IAoBb;;;;;;;OAOG;IACH,OAAO,CAAC,kBAAkB,CAmBxB;IAEF;;;;;;;OAOG;IACH,OAAO,CAAC,iBAAiB,CAiBvB;IAEO,MAAM;CAkDhB;AA8OD,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,qBAAqB;QAC7B,mBAAmB,EAAE,eAAe,CAAC;KACtC;CACF"}
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  AdaptiveChatBar
3
- } from "./chunk-L3LR2J3L.js";
3
+ } from "./chunk-2NX6765N.js";
4
4
  import "./chunk-EWPPVPJ4.js";
5
- import "./chunk-UW3J6KA4.js";
5
+ import "./chunk-LTG5G6WN.js";
6
6
  import "./chunk-5PW6T3QF.js";
7
7
  import "./chunk-UVKRO5ER.js";
8
8
  export {
@@ -28,6 +28,14 @@
28
28
  * use is to let the conversation start empty.
29
29
  */
30
30
  import './AdaptiveChatBar';
31
+ /**
32
+ * Test-only: drop the warm store singleton (and its hydration latch) so each
33
+ * test can wire a fresh store to its own event bus / registry. Without this,
34
+ * the first test in a file permanently binds the store to ITS bus and the
35
+ * per-instance version dedup silently drops every later test's re-mounts.
36
+ * Mirrors `observer/index.ts` `_resetObserverForTests`.
37
+ */
38
+ export declare function _resetElementStoreForTests(): void;
31
39
  export declare function resolveTileWidget(templateId: string): string | undefined;
32
40
  export declare function refreshTemplateWidgetMap(uiTemplates: Record<string, unknown> | undefined): void;
33
41
  export declare const AdaptiveChatBarMountable: {
@@ -1 +1 @@
1
- {"version":3,"file":"AdaptiveChatBarMountable.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBarMountable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,mBAAmB,CAAC;AA6K3B,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAgB/F;AA4QD,eAAO,MAAM,wBAAwB;qBAClB,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI;sBAuE9D,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAQ5E,CAAC"}
1
+ {"version":3,"file":"AdaptiveChatBarMountable.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatBarMountable.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,mBAAmB,CAAC;AAoJ3B;;;;;;GAMG;AACH,wBAAgB,0BAA0B,IAAI,IAAI,CAIjD;AA6BD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAExE;AAED,wBAAgB,wBAAwB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,CAgB/F;AA0SD,eAAO,MAAM,wBAAwB;qBAClB,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,IAAI;sBA2F9D,WAAW,gBAAgB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CAQ5E,CAAC"}
@@ -70,10 +70,30 @@ export type TileReceipt = {
70
70
  */
71
71
  export interface InlineTrailWidget {
72
72
  instanceId: string;
73
- /** Custom-element tag (e.g. `syntro-product-reco-carousel`). */
73
+ /**
74
+ * The mount identifier for the widget. For self-defining, server-mounted
75
+ * widgets this IS the custom-element tag (e.g. `syntro-product-reco-carousel`)
76
+ * and the trail creates it directly. For admin-template widgets it is the
77
+ * runtime widget-id (e.g. `adaptive-product:card`, `adaptive-faq:accordion`),
78
+ * which is NOT a valid custom-element tag — those mount through the runtime
79
+ * widget registry via {@link InlineWidgetMounter}, which resolves the id to
80
+ * its real element exactly like the deck `SyntroTileCard` path.
81
+ */
74
82
  tag: string;
75
83
  props: Record<string, unknown>;
76
84
  }
85
+ /**
86
+ * Mounts a registry-registered widget (by its runtime widget-id) into
87
+ * `container` and returns the created element plus an unmount cleanup.
88
+ * Injected from the chat-bar mountable, bound to `runtime.widgets`. Lets the
89
+ * trail render inline tiles whose widget-id is not their custom-element tag
90
+ * (product card, comparison, FAQ accordion) — the registry owns the
91
+ * id → element resolution. Returns `null` when the id is not registered.
92
+ */
93
+ export type InlineWidgetMounter = (widgetId: string, container: HTMLElement, props: Record<string, unknown>) => {
94
+ element: HTMLElement;
95
+ cleanup: () => void;
96
+ } | null;
77
97
  export declare class AdaptiveChatTrail extends LitElement {
78
98
  static styles: import("lit").CSSResult;
79
99
  static properties: {
@@ -144,10 +164,18 @@ export declare class AdaptiveChatTrail extends LitElement {
144
164
  inlineWidgets: {
145
165
  attribute: boolean;
146
166
  };
167
+ /**
168
+ * Registry-backed mounter for inline widgets whose id is not their
169
+ * custom-element tag. Injected from the chat-bar mountable.
170
+ */
171
+ mountInlineWidget: {
172
+ attribute: boolean;
173
+ };
147
174
  };
148
175
  messages: TrailMessage[];
149
176
  tileReceipts: TileReceipt[];
150
177
  inlineWidgets: InlineTrailWidget[];
178
+ mountInlineWidget: InlineWidgetMounter | undefined;
151
179
  visibleCount: number;
152
180
  expanded: boolean;
153
181
  forceExpanded: boolean;
@@ -203,21 +231,37 @@ export declare class AdaptiveChatTrail extends LitElement {
203
231
  */
204
232
  private readonly _inlineAnchors;
205
233
  /**
206
- * instanceId → the live custom element mounted for an inline widget.
207
- * Cached so a prop patch (same instanceId, new props) updates the
208
- * EXISTING element instead of tearing it down and re-creating it —
209
- * which would reset the carousel's scroll position + internal state.
210
- * The element is created lazily via `document.createElement(tag)` the
211
- * first time we see a defined tag; an undefined tag caches `null` so
212
- * the fail-safe renders nothing without re-checking the registry.
234
+ * instanceId → the cached inline widget entry (render node + props target +
235
+ * optional registry cleanup). Cached so a prop patch (same instanceId, new
236
+ * props) updates the EXISTING element instead of tearing it down and
237
+ * re-creating it — which would reset the carousel's scroll position +
238
+ * internal state. Created lazily the first time we see the widget:
239
+ * `document.createElement(tag)` for a defined tag, or a registry mount for a
240
+ * widget-id. An unresolvable widget caches `null` so the fail-safe renders
241
+ * nothing without re-checking the registry.
213
242
  */
214
243
  private readonly _inlineElements;
244
+ disconnectedCallback(): void;
215
245
  willUpdate(changed: Map<string, unknown>): void;
216
246
  /**
217
- * Create (once) or refresh the cached custom element for an inline
218
- * widget. Mounts by tag name so the chat bundle never imports the
219
- * widget package. Fail-safe: if the tag is not a defined custom
220
- * element, cache `null` and render nothing (no broken box).
247
+ * Create (once) or refresh the cached element for an inline widget.
248
+ *
249
+ * Two mount paths, both keeping the chat bundle free of any widget-package
250
+ * import:
251
+ * - Direct tag (self-defining, server-mounted widgets like the reco
252
+ * carousel whose declared `widget` IS its custom-element tag):
253
+ * `document.createElement(tag)`.
254
+ * - Widget-id (admin-template widgets like `adaptive-product:card` or
255
+ * `adaptive-faq:accordion`, whose `widget` is a runtime widget-id, NOT a
256
+ * valid custom-element tag): mount through the runtime widget registry
257
+ * via {@link mountInlineWidget}, which resolves the id to its real
258
+ * element exactly like the deck `SyntroTileCard` path. Without this,
259
+ * `createElement('adaptive-product:card')` yields an inert unknown
260
+ * element and the tile renders permanently blank (the "inline mode
261
+ * shows nothing but the reco" bug).
262
+ *
263
+ * Fail-safe: an id that resolves to neither a defined tag nor a registered
264
+ * widget caches `null` and renders nothing (no broken box).
221
265
  */
222
266
  private _ensureInlineElement;
223
267
  updated(changed: Map<string, unknown>): void;
@@ -1 +1 @@
1
- {"version":3,"file":"AdaptiveChatTrail.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatTrail.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"AdaptiveChatTrail.d.ts","sourceRoot":"","sources":["../src/AdaptiveChatTrail.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  AdaptiveChatTrail,
3
3
  looksLikeSerializedModelResponse
4
- } from "./chunk-UW3J6KA4.js";
4
+ } from "./chunk-LTG5G6WN.js";
5
5
  import "./chunk-5PW6T3QF.js";
6
6
  import "./chunk-UVKRO5ER.js";
7
7
  export {
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  AdaptiveChipsStrip,
3
3
  SuggestionChipSchema
4
- } from "./chunk-RESPPVT5.js";
5
- import "./chunk-HJU43AWV.js";
4
+ } from "./chunk-CHYQU3KP.js";
5
+ import "./chunk-KPWW7N27.js";
6
6
  import "./chunk-UVKRO5ER.js";
7
7
  export {
8
8
  AdaptiveChipsStrip,
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  ChatAssistantLitMountable,
3
3
  renderFallbackHtml
4
- } from "./chunk-6L3H6OKP.js";
4
+ } from "./chunk-LXKDS4CG.js";
5
5
  import "./chunk-EWPPVPJ4.js";
6
6
  import "./chunk-5PW6T3QF.js";
7
- import "./chunk-HJU43AWV.js";
7
+ import "./chunk-KPWW7N27.js";
8
8
  import "./chunk-UVKRO5ER.js";
9
9
  export {
10
10
  ChatAssistantLitMountable,
@@ -0,0 +1,2 @@
1
+ import './AdaptiveChatBar';
2
+ //# sourceMappingURL=InlineRegistryWidgetMount.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InlineRegistryWidgetMount.test.d.ts","sourceRoot":"","sources":["../src/InlineRegistryWidgetMount.test.ts"],"names":[],"mappings":"AAiCA,OAAO,mBAAmB,CAAC"}
@@ -16,6 +16,10 @@ var AdaptiveChatBar = class extends LitElement {
16
16
  /** Widgets rendered inline in the trail (reco carousel), sourced from
17
17
  * the store's `chat-inline` slot mounts. Forwarded to the trail. */
18
18
  this.inlineWidgets = [];
19
+ /** Registry-backed mounter for inline widgets whose id is not their
20
+ * custom-element tag (product card, comparison, FAQ). Set by the
21
+ * mountable from `runtime.widgets`; forwarded to the trail. */
22
+ this.mountInlineWidget = void 0;
19
23
  /**
20
24
  * Live reasoning narration from the model — streamed in via
21
25
  * AG-UI THINKING_TEXT_MESSAGE_CONTENT events and forwarded by
@@ -187,6 +191,7 @@ var AdaptiveChatBar = class extends LitElement {
187
191
  .introSuggestion=${this.introSuggestion}
188
192
  .tileReceipts=${this.tileReceipts}
189
193
  .inlineWidgets=${this.inlineWidgets}
194
+ .mountInlineWidget=${this.mountInlineWidget}
190
195
  @trail-intro-suggestion=${this._onIntroSuggestion}
191
196
  @trail-suggested-reply=${this._onSuggestedReply}
192
197
  ></adaptive-chat-trail>
@@ -236,6 +241,7 @@ AdaptiveChatBar.properties = {
236
241
  maximized: { type: Boolean },
237
242
  tileReceipts: { attribute: false },
238
243
  inlineWidgets: { attribute: false },
244
+ mountInlineWidget: { attribute: false },
239
245
  _input: { state: true }
240
246
  };
241
247
  function rootStyles(forceExpanded) {
@@ -418,4 +424,4 @@ if (!customElements.get("adaptive-chat-bar")) {
418
424
  export {
419
425
  AdaptiveChatBar
420
426
  };
421
- //# sourceMappingURL=chunk-L3LR2J3L.js.map
427
+ //# sourceMappingURL=chunk-2NX6765N.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/AdaptiveChatBar.ts"],
4
+ "sourcesContent": ["/**\n * AdaptiveChatBar \u2014 the canvas lid composition for the chat-canvas\n * experience. Renders the bubble-up trail on top and an always-visible\n * input row below.\n *\n * Wiring contract (events out):\n * - `chat-message-sent` ({ text }): the user submitted text via Enter\n * or the send button. The owning code is responsible for pushing\n * this into the conversation history and producing a reply.\n *\n * Wiring contract (props in):\n * - `messages`: the conversation trail, passed straight through to\n * `<adaptive-chat-trail>`.\n * - `placeholder`: input placeholder copy. Defaults to a generic\n * \"Ask, find, or navigate\u2026\" \u2014 the host (typically the slot's lid\n * widget mount) can override to a context-specific string.\n *\n * Light DOM. Glassmorphism is applied at the input-row level so the\n * trail above floats over the host page without chrome. See PRD \u00A74.4.\n */\n\nimport { html, LitElement, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport './AdaptiveChatTrail.js';\nimport type {\n InlineTrailWidget,\n InlineWidgetMounter,\n TileReceipt,\n TrailMessage,\n} from './AdaptiveChatTrail.js';\nimport { getElementInstanceStore } from './elements/store-singleton.js';\n\nconst DEFAULT_PLACEHOLDER = 'Ask, find, or navigate\u2026';\nconst DEFAULT_ASSISTANT_NAME = 'Assistant';\n\nexport class AdaptiveChatBar extends LitElement {\n static override properties = {\n messages: { attribute: false },\n placeholder: { type: String },\n assistantName: { type: String },\n greeting: { type: String },\n inFlight: { type: Boolean, reflect: true },\n thinkingText: { attribute: false },\n introSuggestion: { attribute: false },\n forceExpanded: { type: Boolean, reflect: true },\n maximized: { type: Boolean },\n tileReceipts: { attribute: false },\n inlineWidgets: { attribute: false },\n mountInlineWidget: { attribute: false },\n _input: { state: true },\n };\n\n messages: TrailMessage[] = [];\n maximized = false;\n tileReceipts: TileReceipt[] = [];\n /** Widgets rendered inline in the trail (reco carousel), sourced from\n * the store's `chat-inline` slot mounts. Forwarded to the trail. */\n inlineWidgets: InlineTrailWidget[] = [];\n /** Registry-backed mounter for inline widgets whose id is not their\n * custom-element tag (product card, comparison, FAQ). Set by the\n * mountable from `runtime.widgets`; forwarded to the trail. */\n mountInlineWidget: InlineWidgetMounter | undefined = undefined;\n\n /**\n * Live reasoning narration from the model \u2014 streamed in via\n * AG-UI THINKING_TEXT_MESSAGE_CONTENT events and forwarded by\n * the ChatSession subscription on the host (mountable).\n * Forwarded verbatim to the trail, which renders it in place of\n * the silent loading dots between turns. Empty string when no\n * thinking turn is active.\n */\n thinkingText = '';\n /**\n * Pre-conversation suggestion button \u2014 forwarded to the trail's\n * empty-state pane. When the visitor clicks it the trail emits\n * `trail-intro-suggestion`; we catch that here and submit the\n * configured prompt through the normal send path.\n */\n introSuggestion: { label: string; prompt: string } | undefined = undefined;\n\n /** Pass-through to {@link AdaptiveChatTrail}'s ``forceExpanded`` prop.\n * Hosts that mount the chat-bar in a full-screen surface (mobile\n * panel, agent app, etc.) set this to skip the collapse affordance\n * \u2014 there is no smaller state to fall back to. */\n forceExpanded = false;\n placeholder = DEFAULT_PLACEHOLDER;\n /**\n * Name shown in the (forceExpanded) header. Defaults to a generic\n * \"Assistant\". Hosts can override per-workspace (e.g. Vela sets\n * \"Vela Concierge\") without inventing new SDK surface \u2014 it threads\n * through the same mount config the placeholder does.\n */\n assistantName = DEFAULT_ASSISTANT_NAME;\n /**\n * Initial assistant message shown before any real conversation\n * starts. Renders inside the trail as a phantom assistant chip\n * when messages.length === 0; auto-disappears as soon as the\n * first user message lands. Mirrors ChatAssistantLit's greeting.\n */\n greeting: string | undefined = undefined;\n /**\n * Whether a chat round-trip is in flight (request sent, awaiting\n * reply). The single send/stop button morphs accordingly: \u2191 when\n * ready, \u23F9 when in-flight. Parent owns this state \u2014 set true after\n * `chat-message-sent` fires, false when the reply lands or the\n * request is aborted. Enter is inert while in-flight.\n */\n inFlight = false;\n _input = '';\n\n override createRenderRoot(): HTMLElement {\n return this;\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Listen on the host element so that `tile-receipt-activate` events\n // dispatched directly on this element (as well as bubbling up from the\n // trail child) are handled in one place.\n this.addEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.addEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.removeEventListener('tile-receipt-activate', this._onTileReceiptActivate);\n this.removeEventListener('alert-receipt-activate', this._onAlertReceiptActivate);\n }\n\n // Host-level styling (display, width, height, flex, etc.) is owned\n // by the container \u2014 SDK shadow root provides default rules, panel\n // overrides via design tokens (--sc-chat-bar-host-*). This adaptive\n // never sets inline styles on itself. See SmartCanvasElementLit's\n // static styles for the rule.\n\n private _onInput = (e: Event): void => {\n this._input = (e.target as HTMLInputElement).value;\n };\n\n private _onKeyDown = (e: KeyboardEvent): void => {\n if (e.key === 'Enter' && !e.shiftKey) {\n e.preventDefault();\n // Enter is the send affordance \u2014 while in-flight there's nothing\n // to send, so it's a no-op. Interrupt requires the explicit\n // \u23F9 click to avoid surprise-aborting on a stray keystroke.\n if (this.inFlight) return;\n this._send();\n }\n };\n\n // Single button. Click delegates to send-or-interrupt based on\n // current state. Same DOM node, different behavior \u2014 discoverability\n // wins from the user not having to scan for which control is active.\n private _onSendOrInterrupt = (): void => {\n if (this.inFlight) {\n this.dispatchEvent(new CustomEvent('chat-interrupt', { bubbles: true, composed: true }));\n return;\n }\n this._send();\n };\n\n private _onTileReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n getElementInstanceStore()?.recreate(instanceId);\n this.dispatchEvent(\n new CustomEvent('tile-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onAlertReceiptActivate = (e: Event): void => {\n const { instanceId } = (e as CustomEvent<{ instanceId: string }>).detail;\n this.dispatchEvent(\n new CustomEvent('alert-recall', { detail: { instanceId }, bubbles: true, composed: true })\n );\n };\n\n private _onMaximizeToggle = (): void => {\n this.dispatchEvent(new CustomEvent('chat-maximize-toggle', { bubbles: true, composed: true }));\n };\n\n private _send(): void {\n const text = this._input.trim();\n if (!text) return;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text },\n bubbles: true,\n composed: true,\n })\n );\n this._input = '';\n // Drop the input value too \u2014 the input's bound value is `this._input`\n // via the render, but jsdom's two-way binding via property only takes\n // effect after the next render, so set it imperatively for the test\n // and for browser symmetry (most browsers do the right thing here\n // anyway because Lit re-renders on the state change).\n const input = this.querySelector<HTMLInputElement>('input[data-chat-input]');\n if (input) input.value = '';\n }\n\n /**\n * Visitor tapped the intro suggestion button in the empty-state\n * trail. Submit the configured prompt through the same channel as\n * a typed message so listeners (mountable \u2192 chatSession.send) see\n * a uniform shape \u2014 no need for a parallel \"suggestion-sent\" path.\n * The trail's intro pane auto-disappears the moment the first\n * message lands, so this also closes the empty state in one go.\n */\n private _onIntroSuggestion = (e: Event): void => {\n const detail = (e as CustomEvent<{ prompt: string }>).detail;\n if (!detail?.prompt) return;\n e.stopPropagation();\n if (this.inFlight) return;\n // Latch in-flight optimistically. `inFlight` is owned by the parent\n // mountable and only pushed back down after it handles\n // `chat-message-sent` + a Lit render cycle. Two taps in the same frame\n // both see inFlight===false otherwise, double-dispatching one intended\n // reply (C3). Set it true synchronously here; the parent confirms/owns\n // it from the next render and clears it when the reply lands.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.prompt },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n /**\n * Visitor tapped an inline `suggest_replies` chip in the trail. Submit\n * the chip text through the SAME `chat-message-sent` channel a typed\n * message uses, so the reply rides the existing send path (mountable \u2192\n * chatSession.send \u2192 transport) \u2014 no fabricated AG-UI events. The\n * trail clears the chips on its own once the reply lands and a newer\n * assistant turn becomes the latest.\n */\n private _onSuggestedReply = (e: Event): void => {\n const detail = (e as CustomEvent<{ text: string }>).detail;\n if (!detail?.text) return;\n e.stopPropagation();\n if (this.inFlight) return;\n // Latch in-flight optimistically \u2014 same race as `_onIntroSuggestion`\n // (C3). The parent owns `inFlight` and only re-asserts it after a render\n // cycle, so a same-frame double tap would otherwise fire two\n // `chat-message-sent` events for one chip.\n this.inFlight = true;\n this.dispatchEvent(\n new CustomEvent<{ text: string }>('chat-message-sent', {\n detail: { text: detail.text },\n bubbles: true,\n composed: true,\n })\n );\n };\n\n override render() {\n return html`\n <div style=${styleMap(rootStyles(this.forceExpanded))}>\n ${this.forceExpanded ? renderHeader(this.assistantName) : nothing}\n <adaptive-chat-trail\n .messages=${this.messages}\n .greeting=${this.greeting}\n .forceExpanded=${this.forceExpanded}\n .inFlight=${this.inFlight}\n .thinkingText=${this.thinkingText}\n .introSuggestion=${this.introSuggestion}\n .tileReceipts=${this.tileReceipts}\n .inlineWidgets=${this.inlineWidgets}\n .mountInlineWidget=${this.mountInlineWidget}\n @trail-intro-suggestion=${this._onIntroSuggestion}\n @trail-suggested-reply=${this._onSuggestedReply}\n ></adaptive-chat-trail>\n <div style=${styleMap(rowStyles(this.forceExpanded))} data-chat-row>\n <button\n type=\"button\"\n data-chat-maximize\n @click=${this._onMaximizeToggle}\n aria-label=${this.maximized ? 'Exit full screen' : 'Maximize chat'}\n title=${this.maximized ? 'Normal' : 'Maximize'}\n aria-pressed=${this.maximized ? 'true' : 'false'}\n style=${styleMap(maximizeStyles(this.maximized))}\n >${this.maximized ? '\u2921' : '\u2922'}</button>\n <input\n data-chat-input\n type=\"text\"\n placeholder=${this.placeholder}\n .value=${this._input}\n @input=${this._onInput}\n @keydown=${this._onKeyDown}\n style=${styleMap(inputStyles())}\n aria-label=\"Chat input\"\n />\n <button\n type=\"button\"\n data-chat-send\n data-state=${this.inFlight ? 'in-flight' : 'ready'}\n @click=${this._onSendOrInterrupt}\n aria-label=${this.inFlight ? 'Stop' : 'Send message'}\n title=${this.inFlight ? 'Interrupt' : 'Send'}\n style=${styleMap(sendStyles(this.inFlight))}\n >${this.inFlight ? '\u25A0' : '\u2191'}</button>\n </div>\n </div>\n `;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Styles \u2014 kept inline (Lit styleMap) so they participate in light-DOM\n// rendering and pick up host CSS variables (e.g. --sc-tile-background).\n// ---------------------------------------------------------------------------\n\nfunction rootStyles(forceExpanded: boolean): Record<string, string> {\n // When the host expects the chat to fill its container (full-screen\n // panel, agent app), we grow vertically AND wrap the whole widget in\n // its own chrome card \u2014 trail + input read as one cohesive surface\n // instead of a naked trail above a chrome'd input. Floating mounts\n // (bottom-right pinned, etc.) stay chrome-less here because their\n // chrome is owned by the host's positioned wrapper.\n if (!forceExpanded) {\n return {\n display: 'flex',\n flexDirection: 'column',\n gap: '6px',\n width: '100%',\n pointerEvents: 'auto',\n };\n }\n // Input is ABSOLUTELY positioned at the bottom of this chrome card\n // (see rowStyles forceExpanded mode). That guarantees the input is\n // always visible \u2014 even when the lid region is tighter than the\n // chat-bar would naturally want. The flex column above holds\n // header + trail; padding-bottom reserves the input's footprint so\n // trail content can never overlap.\n //\n // Priority of \"what disappears when space is tight\":\n // Trail (shrinks to 0 first via flex: 1 1 0)\n // Header (can shrink via default flex: 0 1 auto)\n // Input (NEVER \u2014 it's positioned absolute, always at the bottom)\n return {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n gap: '8px',\n width: '100%',\n height: '100%',\n boxSizing: 'border-box',\n flex: '1 1 auto',\n minHeight: '0',\n overflow: 'hidden',\n pointerEvents: 'auto',\n background: 'var(--sc-tile-background, rgba(255, 255, 255, 0.92))',\n border: 'var(--sc-tile-border, 1px solid rgba(0, 0, 0, 0.06))',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n boxShadow: 'var(--sc-tile-shadow, 0 12px 32px -16px rgba(0, 0, 0, 0.18))',\n // Reserves room for the absolute-positioned input pill (36px high\n // + 12px from bottom) plus a 16px visual gap above the input.\n padding: '0.75rem 0.75rem calc(36px + 1.75rem)',\n color: 'var(--sc-tile-title-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n // Override the trail's host-layout tokens so the trail (a flex item\n // of this column) fills a definite-height parent AND contributes its\n // content height in an indefinite one. basis AUTO (not 0) is\n // load-bearing: grow:1 still fills a full-screen panel, but basis auto\n // also lets the trail's content height propagate up the fill chain so a\n // SHRINK-WRAP host (velvet's bottom sheet) hugs the content with no void.\n // A basis-0 layer anywhere in the chain reports 0 min-content and\n // collapses the sheet to header+input. shrink:1 + min-height:0 still lets\n // the trail yield first when space is tight (input is absolute-pinned).\n // The SDK-level rule in SmartCanvasElementLit consumes these tokens on\n // adaptive-chat-trail's host element. Containers OWN host styling\n // via tokens; the adaptive never sets inline styles on its host.\n ['--sc-chat-trail-host-display']: 'flex',\n ['--sc-chat-trail-host-flex-direction']: 'column',\n ['--sc-chat-trail-host-flex']: '1 1 auto',\n ['--sc-chat-trail-host-min-height']: '0',\n ['--sc-chat-trail-host-overflow']: 'hidden',\n };\n}\n\nfunction rowStyles(forceExpanded: boolean): Record<string, string> {\n // forceExpanded \u2014 root container already carries the chrome; row\n // becomes a flat input-pill inside that chrome (subtle border + soft\n // background, no shadow/blur).\n if (forceExpanded) {\n // Absolute-pinned to the chrome card's bottom edge so it never\n // disappears under any container size. The chrome reserves\n // padding-bottom equal to this row's footprint so flex content\n // above (header + trail) can't overlap.\n return {\n position: 'absolute',\n left: '0.75rem',\n right: '0.75rem',\n bottom: '0.75rem',\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '6px 14px',\n borderRadius: '9999px',\n background: 'rgba(0, 0, 0, 0.04)',\n border: '1px solid rgba(0, 0, 0, 0.10)',\n color: 'var(--sc-content-text-color, inherit)',\n fontFamily: 'var(--sc-font-family, inherit)',\n minHeight: '36px',\n };\n }\n // Floating mount \u2014 keeps the original tile-chrome look.\n return {\n display: 'flex',\n alignItems: 'center',\n gap: '8px',\n padding: '10px 12px',\n borderRadius: 'var(--sc-tile-border-radius, 14px)',\n background: 'var(--sc-tile-background, rgba(15, 19, 24, 0.6))',\n backdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n WebkitBackdropFilter: 'var(--sc-chat-bar-blur, blur(24px) saturate(140%))',\n border: 'var(--sc-tile-border, 1px solid rgba(255, 255, 255, 0.08))',\n boxShadow: 'var(--sc-tile-shadow, 0 2px 12px rgba(0, 0, 0, 0.3))',\n color: 'var(--sc-tile-title-color, #fafafa)',\n fontFamily: 'var(--sc-font-family, inherit)',\n };\n}\n\n// Maximize / restore toggle in the chat bar. Legibility matters: the old\n// treatment reused the decorative avatar chip then stripped its background and\n// border and let `font: inherit` shrink the glyph \u2014 leaving a faint, ghosted\n// (0.95-alpha) character that read as \"barely visible\" and gave no visual\n// signal of its on/off state. This mirrors the sibling send button (28px,\n// filled-accent affordance) and makes the ACTIVE (maximized) state a filled\n// chip so the toggle state is obvious at a glance.\nfunction maximizeStyles(maximized: boolean): Record<string, string> {\n return {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '28px',\n height: '28px',\n borderRadius: '9999px',\n // Active (maximized): filled accent chip. Idle: subtle accent chip with a\n // visible ring. Colour is full-opacity in both states (no 0.95 ghosting).\n background: maximized\n ? 'hsl(var(--sc-accent-color) / 0.85)'\n : 'hsl(var(--sc-accent-color) / 0.15)',\n border: maximized ? 'none' : '1px solid hsl(var(--sc-accent-color) / 0.45)',\n color: maximized ? 'var(--sc-accent-foreground, #fff)' : 'hsl(var(--sc-accent-color))',\n flexShrink: '0',\n fontSize: '16px',\n lineHeight: '1',\n padding: '0',\n cursor: 'pointer',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\nfunction inputStyles(): Record<string, string> {\n return {\n flex: '1',\n minWidth: '0',\n background: 'transparent',\n border: 'none',\n outline: 'none',\n color: 'inherit',\n fontSize: '13px',\n };\n}\n\nfunction sendStyles(inFlight: boolean): Record<string, string> {\n return {\n width: '28px',\n height: '28px',\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n borderRadius: '9999px',\n // Ready: filled accent (send is the affordance). In-flight: hollow\n // ring + accent ring (stop is a one-of-a-kind disruptive action,\n // styled differently so the user reads \"this isn't just send\").\n background: inFlight ? 'transparent' : 'hsl(var(--sc-accent-color) / 0.85)',\n color: inFlight ? 'hsl(var(--sc-accent-color) / 0.95)' : 'var(--sc-accent-foreground, #fff)',\n border: inFlight ? '1px solid hsl(var(--sc-accent-color) / 0.55)' : 'none',\n cursor: 'pointer',\n flexShrink: '0',\n transition: 'background 150ms ease, color 150ms ease, border-color 150ms ease',\n };\n}\n\n/**\n * Compact single-line chat header. Prior version stacked the name over a\n * two-line status block inside a flex-column wrapper with a 28px avatar and\n * `padding: 4px 4px 12px`, which wasted a lot of vertical space (user\n * feedback: \"bad use of vertical space\"). This is now ONE inline row \u2014\n * small avatar dot \u00B7 name \u00B7 live-status dot \u00B7 short status \u2014 at roughly half\n * the height. All surfaces share this chrome.\n */\nfunction renderHeader(assistantName: string) {\n const headerStyles: Record<string, string> = {\n display: 'flex',\n alignItems: 'center',\n gap: '7px',\n // Halved vertical footprint: 6px total block padding vs the old 16px\n // (4px top + 12px bottom). Horizontal padding unchanged.\n padding: '3px 4px',\n borderBottom: '1px solid var(--sc-content-divider-color, rgba(0, 0, 0, 0.08))',\n flex: '0 0 auto',\n };\n // Small brand dot \u2014 shrunk from a 28px avatar to a 16px chip so the\n // whole header collapses to a single text line. Still tracks the\n // workspace brand primary so it matches the rest of the canvas chrome.\n const avatar: Record<string, string> = {\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n width: '16px',\n height: '16px',\n borderRadius: '9999px',\n background:\n 'var(--sc-tile-icon-background, linear-gradient(135deg, var(--sc-color-primary, #5faf7d) 0%, var(--sc-color-primary-hover, #3d8a5e) 100%))',\n color: '#fff',\n flexShrink: '0',\n fontSize: '9px',\n lineHeight: '1',\n };\n const name: Record<string, string> = {\n fontSize: '0.8rem',\n fontWeight: '600',\n color: 'var(--sc-content-text-color, inherit)',\n lineHeight: '1.2',\n flexShrink: '0',\n };\n // No status line or presence dot (\"Online \u00B7 understands your session\") \u2014\n // user feedback: that's chrome a visitor doesn't need. Avatar + name only.\n return html`\n <div style=${styleMap(headerStyles)} data-chat-header>\n <span style=${styleMap(avatar)} aria-hidden=\"true\">\u2726</span>\n <span style=${styleMap(name)}>${assistantName}</span>\n </div>\n `;\n}\n\nif (!customElements.get('adaptive-chat-bar')) {\n customElements.define('adaptive-chat-bar', AdaptiveChatBar);\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'adaptive-chat-bar': AdaptiveChatBar;\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -2,7 +2,7 @@ import {
2
2
  AuthoringFieldsZ,
3
3
  NotifyZ,
4
4
  TriggerWhenZ
5
- } from "./chunk-HJU43AWV.js";
5
+ } from "./chunk-KPWW7N27.js";
6
6
 
7
7
  // src/AdaptiveChipsStrip.ts
8
8
  import { html, LitElement, nothing } from "lit";
@@ -631,4 +631,4 @@ export {
631
631
  SuggestionChipSchema,
632
632
  AdaptiveChipsStrip
633
633
  };
634
- //# sourceMappingURL=chunk-RESPPVT5.js.map
634
+ //# sourceMappingURL=chunk-CHYQU3KP.js.map
@@ -181,6 +181,9 @@ function n(n2) {
181
181
  // ../../sdk-contracts/dist/canvas-context.js
182
182
  var canvasRuntimeContext = n("syntrologie:canvas-runtime");
183
183
 
184
+ // ../../sdk-contracts/dist/dive-deeper.js
185
+ var DIVE_DEEPER_EVENT = "syntro:chat:dive-deeper";
186
+
184
187
  // ../../sdk-contracts/dist/routes.js
185
188
  var utf8Decoder = new TextDecoder("utf-8", { fatal: false });
186
189
 
@@ -191,6 +194,7 @@ var TILE_UNMOUNTED_EVENT = "element.tile_unmounted";
191
194
  var TILE_REPLAY_REQUEST_EVENT = "element.tile_replay_request";
192
195
 
193
196
  export {
197
+ DIVE_DEEPER_EVENT,
194
198
  stripMountPlumbing,
195
199
  AuthoringFieldsZ,
196
200
  TriggerWhenZ,
@@ -228,4 +232,4 @@ export {
228
232
  * SPDX-License-Identifier: BSD-3-Clause
229
233
  *)
230
234
  */
231
- //# sourceMappingURL=chunk-HJU43AWV.js.map
235
+ //# sourceMappingURL=chunk-KPWW7N27.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../../../sdk-contracts/dist/mount-plumbing.js", "../../../sdk-contracts/dist/schemas.js", "../../../../node_modules/@lit/context/src/lib/create-context.ts", "../../../sdk-contracts/dist/canvas-context.js", "../../../sdk-contracts/dist/routes.js", "../../../sdk-contracts/dist/tile-lifecycle.js"],
4
- "sourcesContent": ["/**\n * Mount contract types and helper for adaptive widget mountables.\n *\n * The `WidgetRegistry` in `@syntrologie/runtime-sdk` delivers props to each\n * mountable as `{ ...tile.props, instanceId, runtime, tileId? }` spread flat\n * (see `MountableContract.test.ts` in runtime-sdk for the end-to-end lockdown).\n *\n * Adaptives that strip plumbing manually maintain private blacklists that\n * silently drift when the contract grows (PR #2234 and #2238 documented this).\n * `stripMountPlumbing` centralizes the list so adding a new plumbing key in\n * the future is a one-line change here that every adaptive picks up automatically.\n *\n * Adaptives whose widget schemas use Zod `.strict()` MUST call this before\n * validating, or strict-mode will reject the runtime-injected keys and the\n * widget will silently render its empty/error state.\n */\nexport const MOUNT_PLUMBING_KEYS = ['instanceId', 'runtime', 'tileId'];\nexport function stripMountPlumbing(config) {\n if (!config || typeof config !== 'object') {\n return {};\n }\n const out = { ...config };\n for (const key of MOUNT_PLUMBING_KEYS) {\n delete out[key];\n }\n return out;\n}\n", "/**\n * Shared Zod schemas for decision strategies, conditions, and event scoping.\n *\n * These are the canonical definitions \u2014 runtime-sdk and all adaptive packages\n * should import from here instead of duplicating.\n */\nimport { z } from 'zod';\n// =============================================================================\n// ANCHOR ID SCHEMA\n// =============================================================================\nexport const AnchorIdZ = z\n .object({\n selector: z.string(),\n route: z.union([z.string(), z.array(z.string())]),\n})\n .strict();\n// =============================================================================\n// AUTHORING FIELDS \u2014 id / title / description / validation\n//\n// Shared fields every action carries. `id` is the action identifier the\n// runtime uses to dispatch, dedupe, and drop/replace actions \u2014 it is NOT\n// stripped before serving. `title` / `description` / `validation` are\n// authoring-only metadata stripped server-side in `to_runtime_config`\n// (platform/backend/app/domains/experiments/helpers.py).\n//\n// They all appear in the JSON Schema (and therefore in the tactician's\n// prompt) because the LLM needs to know they are valid action properties \u2014\n// otherwise schema validation would reject what the prompt commands.\n//\n// Each action variant should `.extend(AuthoringFieldsZ)` alongside any\n// triggerWhen/condition extensions.\n// =============================================================================\nexport const AuthoringFieldsZ = {\n id: z.string().optional().describe('Stable action identifier (e.g. \"act_3db6a14d2ab0\").'),\n title: z\n .string()\n .max(200)\n .optional()\n .describe('Authoring-only: short label shown on the action plan dashboard. Stripped before serving to the runtime SDK.'),\n description: z\n .string()\n .max(1000)\n .optional()\n .describe('Authoring-only: one-sentence explanation of what this action does and why. Stripped before serving to the runtime SDK.'),\n validation: z\n .array(z.string().max(500))\n .max(10)\n .optional()\n .describe('Authoring-only: ordered steps a reviewer can follow to trigger this action and visually confirm it works. Each entry is one step. Stripped before serving to the runtime SDK.'),\n};\n// =============================================================================\n// TRIGGER VOCABULARY \u2014 canonical lists of valid event names, metric keys, etc.\n// These flow through to the JSON schema as enums and are used by the LLM prompt.\n// =============================================================================\n/** Events that can be counted in event_count conditions.\n *\n * Every value here must be an event the runtime actually emits \u2014 either a\n * PostHog-autocapture normalization (ui.click/scroll/input/change/submit) or\n * an event-processor detector (ui.hover/idle/scroll_thrash/focus_bounce/\n * hesitate/rage_click). Do not add aspirational names; a trigger counting an\n * event nothing emits never fires.\n */\nexport const COUNTABLE_EVENTS = [\n // User interactions (from PostHog autocapture normalization)\n 'ui.click',\n 'ui.scroll',\n 'ui.input',\n 'ui.change',\n 'ui.submit',\n // Behavioral detectors (from event-processor)\n 'ui.hover',\n 'ui.idle',\n 'ui.scroll_thrash',\n 'ui.focus_bounce',\n 'ui.hesitate',\n 'ui.rage_click',\n // Navigation\n 'nav.page_view',\n 'nav.page_leave',\n];\nexport const CountableEventZ = z\n .enum(COUNTABLE_EVENTS)\n .describe('Event name to count. ui.* = user interactions and behavioral detectors (hesitate, rage_click, scroll_thrash, focus_bounce, idle, hover); nav.* = page navigation.');\n/** Valid session metric keys. */\nexport const SESSION_METRIC_KEYS = ['time_on_page', 'page_views', 'scroll_depth'];\nexport const SessionMetricKeyZ = z\n .enum(SESSION_METRIC_KEYS)\n .describe('Session metric key. time_on_page = seconds on current page, page_views = pages visited this session, scroll_depth = 0-100 percentage.');\n/** Element chain match field prefixes for counter filters. */\nexport const ELEMENT_MATCH_FIELDS = ['tag_name', '$el_text'];\n// Note: attr__* is a dynamic prefix (attr__data-id, attr__class, attr__href, etc.)\n// and cannot be enumerated. The match key is either one of ELEMENT_MATCH_FIELDS\n// or starts with \"attr__\".\n// =============================================================================\n// CONDITION SCHEMAS\n// =============================================================================\nexport const PageUrlConditionZ = z\n .object({\n type: z.literal('page_url'),\n url: z.string().describe('URL path to match (e.g. \"/pricing\", \"/dashboard\")'),\n})\n .describe('Fires when the current page URL matches. Use for page-specific actions. ' +\n 'Example: {\"type\": \"page_url\", \"url\": \"/pricing\"}');\nexport const RouteConditionZ = z\n .object({\n type: z.literal('route'),\n routeId: z.string().describe('Named route ID from the route filter'),\n})\n .describe('Fires when the current route matches a named route ID.');\nexport const AnchorVisibleConditionZ = z\n .object({\n type: z.literal('anchor_visible'),\n anchorId: z.string().describe('CSS selector of the anchor element'),\n state: z\n .enum(['visible', 'present', 'absent'])\n .describe('\"visible\" = in viewport, \"present\" = in DOM, \"absent\" = not in DOM'),\n})\n .describe(\"Fires based on a DOM element's visibility state. \" +\n 'Example: {\"type\": \"anchor_visible\", \"anchorId\": \"#cta-button\", \"state\": \"visible\"}');\nexport const EventOccurredConditionZ = z\n .object({\n type: z.literal('event_occurred'),\n eventName: z.string().describe('Event name (e.g. \"ui.click\", \"$pageview\")'),\n withinMs: z.number().optional().describe('Time window in ms. Omit = any time this session.'),\n})\n .describe('Fires when a specific event has occurred during this session. ' +\n 'Example: {\"type\": \"event_occurred\", \"eventName\": \"ui.click\", \"withinMs\": 5000}');\nexport const StateEqualsConditionZ = z\n .object({\n type: z.literal('state_equals'),\n key: z\n .string()\n .describe('Key in the SDK persistent state store (localStorage). Only valid for keys the host app explicitly sets via syntro.state.set().'),\n value: z.unknown().describe('Expected value to match against'),\n})\n .describe('Checks the SDK persistent state store (localStorage). ONLY for host-app state set via syntro.state.set() \u2014 ' +\n 'NOT for user attributes like region, device, or UTM params (those are handled by segment targeting). ' +\n 'Do NOT use this for targeting. If you do not know the valid state keys, do not use this condition type.');\nexport const ViewportConditionZ = z\n .object({\n type: z.literal('viewport'),\n minWidth: z.number().optional().describe('Minimum viewport width in pixels'),\n maxWidth: z.number().optional().describe('Maximum viewport width in pixels'),\n minHeight: z.number().optional().describe('Minimum viewport height in pixels'),\n maxHeight: z.number().optional().describe('Maximum viewport height in pixels'),\n})\n .describe('Fires based on viewport (screen) size. Use for responsive behavior. ' +\n 'Example: {\"type\": \"viewport\", \"minWidth\": 768} \u2014 fires on tablet and larger.');\nexport const SessionMetricConditionZ = z\n .object({\n type: z.literal('session_metric'),\n key: SessionMetricKeyZ,\n operator: z.enum(['gte', 'lte', 'eq', 'gt', 'lt']),\n threshold: z.number().describe('Numeric threshold to compare against'),\n})\n .describe('Fires when a session metric crosses a threshold. Valid keys: \"time_on_page\" (seconds), ' +\n '\"page_views\" (count), \"scroll_depth\" (0-100). ' +\n 'Example: {\"type\": \"session_metric\", \"key\": \"time_on_page\", \"operator\": \"gte\", \"threshold\": 30}');\nexport const DismissedConditionZ = z\n .object({\n type: z.literal('dismissed'),\n key: z.string().describe('Dismissal key (usually a tile or action ID)'),\n inverted: z\n .boolean()\n .optional()\n .describe('When true, fires if NOT dismissed (default behavior)'),\n})\n .describe('Checks if an item has been dismissed by the user. Use with inverted: true to show only if not dismissed.');\nexport const CooldownActiveConditionZ = z\n .object({\n type: z.literal('cooldown_active'),\n key: z.string().describe('Cooldown key'),\n inverted: z.boolean().optional().describe('When true, fires if cooldown is NOT active'),\n})\n .describe('Checks if a cooldown timer is currently active. Use to prevent showing the same intervention too frequently.');\nexport const FrequencyLimitConditionZ = z\n .object({\n type: z.literal('frequency_limit'),\n key: z.string().describe('Frequency counter key'),\n limit: z.number().describe('Maximum allowed count'),\n inverted: z.boolean().optional().describe('When true, fires if limit NOT reached'),\n})\n .describe('Checks if a frequency limit has been reached. Use to cap how many times an action fires per session.');\nexport const MatchOpZ = z\n .object({\n equals: z.union([z.string(), z.number(), z.boolean()]).optional(),\n contains: z.string().optional(),\n})\n .describe('Match operator for counter filters. Exactly one of equals or contains must be specified.');\nexport const CounterDefZ = z\n .object({\n events: z\n .array(CountableEventZ)\n .min(1)\n .describe('Event names to count. Use values from the countable events enum.'),\n match: z\n .record(z.string(), MatchOpZ)\n .optional()\n .describe('Property filters. Keys are event prop names or element-chain fields ' +\n '(tag_name, $el_text, attr__*). All entries AND together.'),\n})\n .describe('Defines what events to count. Registered as an accumulator predicate at config-load time.');\nexport const EventCountConditionZ = z\n .object({\n type: z.literal('event_count'),\n key: z.string().describe('Unique key for this counter (used for accumulator registration)'),\n operator: z.enum(['gte', 'lte', 'eq', 'gt', 'lt']),\n count: z.number().int().min(0).describe('Target count threshold'),\n withinMs: z\n .number()\n .positive()\n .optional()\n .describe('Time window in ms. Omit = count across entire session.'),\n counter: CounterDefZ.optional().describe('Inline counter definition. Defines what events to count.'),\n})\n .describe('Fires when accumulated event count crosses a threshold. Most powerful trigger type. ' +\n 'Example: {\"type\": \"event_count\", \"key\": \"pricing-clicks\", \"operator\": \"gte\", \"count\": 3, ' +\n '\"counter\": {\"events\": [\"ui.click\"], \"match\": {\"attr__data-cta\": {\"contains\": \"pricing\"}}}}');\nexport const ConditionZ = z.discriminatedUnion('type', [\n PageUrlConditionZ,\n RouteConditionZ,\n AnchorVisibleConditionZ,\n EventOccurredConditionZ,\n StateEqualsConditionZ,\n ViewportConditionZ,\n SessionMetricConditionZ,\n DismissedConditionZ,\n CooldownActiveConditionZ,\n FrequencyLimitConditionZ,\n EventCountConditionZ,\n]);\n// =============================================================================\n// STRATEGY SCHEMAS\n// =============================================================================\nexport const RuleZ = z\n .object({\n conditions: z\n .array(ConditionZ)\n .describe('Array of conditions \u2014 ALL must match (AND logic) for this rule to fire.'),\n value: z\n .unknown()\n .describe('Value returned when all conditions match. For triggerWhen: true = fire the action.'),\n})\n .describe('A single rule. ALL conditions must match (AND logic). Rules in a strategy are evaluated ' +\n 'top-to-bottom \u2014 first rule where all conditions match wins and returns its value.');\nexport const RuleStrategyZ = z\n .object({\n type: z.literal('rules'),\n rules: z\n .array(RuleZ)\n .describe('Ordered list of rules. Evaluated top-to-bottom \u2014 first match wins.'),\n default: z\n .unknown()\n .describe('Fallback value when no rule matches. For triggerWhen: false = do not fire by default.'),\n})\n .describe('Rule-based strategy. Evaluates rules top-to-bottom. First rule where ALL conditions match ' +\n 'returns its value. If no rule matches, returns default. ' +\n 'For triggerWhen: set value=true on matching rules, default=false.');\nexport const ScoreStrategyZ = z\n .object({\n type: z.literal('score'),\n field: z.string(),\n threshold: z.number(),\n above: z.unknown(),\n below: z.unknown(),\n})\n .describe('Score-based strategy. Compares a field value against a threshold.');\nexport const ModelStrategyZ = z\n .object({\n type: z.literal('model'),\n modelId: z.string(),\n inputs: z.array(z.string()),\n outputMapping: z.record(z.string(), z.unknown()),\n default: z.unknown(),\n})\n .describe('ML model strategy. Sends inputs to a model and maps outputs.');\nexport const ExternalStrategyZ = z\n .object({\n type: z.literal('external'),\n endpoint: z.string(),\n method: z.enum(['GET', 'POST']).optional(),\n default: z.unknown(),\n timeoutMs: z.number().optional(),\n})\n .describe('External API strategy. Calls an endpoint to determine the value.');\nexport const DecisionStrategyZ = z.discriminatedUnion('type', [\n RuleStrategyZ,\n ScoreStrategyZ,\n ModelStrategyZ,\n ExternalStrategyZ,\n]);\n/** Canonical Zod schema for the optional triggerWhen field on actions and adaptive items. */\nexport const TriggerWhenZ = DecisionStrategyZ.nullable().optional();\n// =============================================================================\n// TRIGGER DOCUMENTATION \u2014 examples and match field docs\n// Exported as constants so the schema generator can inject them into the\n// JSON schema. The Python prompt builder reads them from the schema.\n// =============================================================================\n/** Complete triggerWhen examples showing the full rules wrapper structure. */\nexport const TRIGGER_EXAMPLES = [\n {\n name: 'Click count on a specific element',\n description: 'Fire when user clicks an element with data-id=\"hero-cta\" 2+ times',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'event_count',\n key: 'cta-clicks',\n operator: 'gte',\n count: 2,\n counter: {\n events: ['ui.click'],\n match: { 'attr__data-id': { equals: 'hero-cta' } },\n },\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'Time on page threshold',\n description: 'Fire after user spends 30+ seconds on the page',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'session_metric',\n key: 'time_on_page',\n operator: 'gte',\n threshold: 30,\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'Element visible in viewport',\n description: 'Fire when a DOM element becomes visible',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'anchor_visible',\n anchorId: '#pricing-section',\n state: 'visible',\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'No trigger (fire immediately)',\n description: 'Action fires as soon as the segment matches \u2014 no in-session condition needed',\n triggerWhen: null,\n },\n];\n/** Documentation for counter.match field keys. */\nexport const MATCH_FIELD_DOCS = {\n tag_name: 'HTML tag name (e.g. \"button\", \"a\", \"input\")',\n $el_text: 'Visible text content of the element',\n 'attr__*': 'HTML attribute prefixed with attr__. Example: attr__data-id matches the data-id attribute, ' +\n 'attr__class matches the class attribute, attr__href matches the href attribute.',\n};\n// =============================================================================\n// EVENT SCOPE SCHEMA\n// =============================================================================\n/** Scopes a widget to specific events/URLs. */\nexport const EventScopeZ = z.object({\n events: z.array(z.string()),\n urlContains: z.string().optional(),\n props: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),\n});\n// =============================================================================\n// NOTIFY SCHEMA\n// =============================================================================\n/** Toast notification config for triggerWhen transitions. */\nexport const NotifyZ = z\n .object({\n title: z.string().optional(),\n body: z.string().optional(),\n icon: z.string().optional(),\n})\n .nullable()\n .optional();\n", "/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * The Context type defines a type brand to associate a key value with the context value type\n */\nexport type Context<KeyType, ValueType> = KeyType & {__context__: ValueType};\n\n/**\n * @deprecated use Context instead\n */\nexport type ContextKey<KeyType, ValueType> = Context<KeyType, ValueType>;\n\n/**\n * A helper type which can extract a Context value type from a Context type\n */\nexport type ContextType<Key extends Context<unknown, unknown>> =\n Key extends Context<unknown, infer ValueType> ? ValueType : never;\n\n/**\n * Creates a typed Context.\n *\n * Contexts are compared with strict equality.\n *\n * If you want two separate `createContext()` calls to referer to the same\n * context, then use a key that will by equal under strict equality like a\n * string for `Symbol.for()`:\n *\n * ```ts\n * // true\n * createContext('my-context') === createContext('my-context')\n * // true\n * createContext(Symbol.for('my-context')) === createContext(Symbol.for('my-context'))\n * ```\n *\n * If you want a context to be unique so that it's guaranteed to not collide\n * with other contexts, use a key that's unique under strict equality, like\n * a `Symbol()` or object.:\n *\n * ```\n * // false\n * createContext({}) === createContext({})\n * // false\n * createContext(Symbol('my-context')) === createContext(Symbol('my-context'))\n * ```\n *\n * @param key a context key value\n * @template ValueType the type of value that can be provided by this context.\n * @returns the context key value cast to `Context<K, ValueType>`\n */\nexport function createContext<ValueType, K = unknown>(key: K) {\n return key as Context<K, ValueType>;\n}\n", "/**\n * Canvas runtime context \u2014 the shared @lit/context symbol both\n * runtime-sdk (the provider) and canvas-sdk / canvas authors (the\n * consumers) use to thread a narrow runtime handle through the canvas\n * element tree.\n *\n * Living here keeps the symbol identity stable across both packages.\n * If canvas-sdk created its own symbol with `createContext(...)`, it\n * would never match the one runtime-sdk publishes, and `<sc-mount>`\n * would silently see `undefined` instead of the widget registry.\n *\n * The shape declared here is a NARROW VIEW of `SmartCanvasRuntime`.\n * Canvas-side code reads only this subset. The runtime-sdk's\n * `SmartCanvasRuntime` type is a structural superset.\n */\nimport { createContext } from '@lit/context';\n/**\n * The @lit/context symbol. Both runtime-sdk's ContextProvider and\n * canvas-sdk's ContextConsumer must import THIS exact symbol \u2014 not a\n * symbol with the same string name \u2014 for context propagation to work.\n */\nexport const canvasRuntimeContext = createContext('syntrologie:canvas-runtime');\n", "/**\n * Canonical route normalization. See `routes.md` for rules and\n * `normalize-route.cases.json` for the parity corpus shared with the\n * Python implementation in syntrologie_common/sdk/routing.py.\n *\n * Two exports \u2014 `normalizeRoute` for literal paths, `normalizeRoutePattern`\n * for activation patterns containing `*`, `**`, `:param`. Today they share\n * an implementation because the rules happen to be wildcard-safe (no\n * lowercase, unreserved-only decode, slash collapse preserves `**`).\n * The seam is preserved as separate exports so the API can diverge\n * without consumer churn if rules change.\n */\n// RFC 3986 reserved characters (gen-delims + sub-delims). When a `%XX`\n// sequence decodes to one of these bytes, we keep the percent-encoded\n// form \u2014 decoding would re-segment the path or change its meaning.\nconst RESERVED_BYTES = new Set([\n 0x21, // !\n 0x23, // #\n 0x24, // $\n 0x26, // &\n 0x27, // '\n 0x28, // (\n 0x29, // )\n 0x2a, // *\n 0x2b, // +\n 0x2c, // ,\n 0x2f, // /\n 0x3a, // :\n 0x3b, // ;\n 0x3d, // =\n 0x3f, // ?\n 0x40, // @\n 0x5b, // [\n 0x5d, // ]\n]);\nconst utf8Decoder = new TextDecoder('utf-8', { fatal: false });\n/** Decode `%XX` sequences for unreserved bytes only. Collapses\n * adjacent `%XX` runs into a UTF-8 decode so `%C3%A9` \u2192 `\u00E9`. */\nfunction decodeUnreservedOnly(input) {\n let out = '';\n let pending = [];\n const flushPending = () => {\n if (pending.length === 0)\n return;\n const bytes = new Uint8Array(pending);\n out += utf8Decoder.decode(bytes);\n pending = [];\n };\n let i = 0;\n while (i < input.length) {\n const ch = input[i];\n if (ch === '%' && i + 2 < input.length && isHex(input[i + 1]) && isHex(input[i + 2])) {\n const byte = parseInt(input.slice(i + 1, i + 3), 16);\n if (RESERVED_BYTES.has(byte)) {\n flushPending();\n // Keep raw, but normalize hex case to uppercase so the\n // canonical form is stable across input casing.\n out += `%${input.slice(i + 1, i + 3).toUpperCase()}`;\n i += 3;\n }\n else {\n pending.push(byte);\n i += 3;\n }\n }\n else {\n flushPending();\n out += ch;\n i += 1;\n }\n }\n flushPending();\n return out;\n}\nfunction isHex(c) {\n return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');\n}\n/** Strip query string and hash fragment. */\nfunction stripQueryAndHash(s) {\n const q = s.indexOf('?');\n if (q !== -1)\n s = s.slice(0, q);\n const h = s.indexOf('#');\n if (h !== -1)\n s = s.slice(0, h);\n return s;\n}\n/**\n * Normalize a literal path (e.g. `window.location.pathname`, an\n * action's `route` field, a wiki route key).\n *\n * Throws `TypeError` if the input is not an absolute path. Callers\n * that want a soft API should use {@link normalizeRouteWithChange}.\n */\nexport function normalizeRoute(path) {\n if (typeof path !== 'string' || path.length === 0) {\n throw new TypeError('normalizeRoute: input must be a non-empty string');\n }\n if (!path.startsWith('/')) {\n throw new TypeError(`normalizeRoute: input must be absolute (start with '/'); got ${JSON.stringify(path)}`);\n }\n let s = stripQueryAndHash(path);\n s = decodeUnreservedOnly(s);\n s = s.replace(/\\/+/g, '/');\n if (s.length > 1 && s.endsWith('/'))\n s = s.slice(0, -1);\n return s;\n}\n/**\n * Normalize an activation route pattern. Preserves `*`, `**`,\n * `:param` exactly. Today equivalent to {@link normalizeRoute} \u2014 kept\n * as a separate export so rules can diverge later without API churn.\n */\nexport function normalizeRoutePattern(pattern) {\n return normalizeRoute(pattern);\n}\n/**\n * Normalize a route and report whether the input was already\n * canonical. Used by authoring tools to decide whether to emit a\n * warning to the LLM.\n */\nexport function normalizeRouteWithChange(path) {\n const canonical = normalizeRoute(path);\n return { canonical, changed: canonical !== path };\n}\n/** Pattern-side counterpart of {@link normalizeRouteWithChange}. */\nexport function normalizeRoutePatternWithChange(pattern) {\n const canonical = normalizeRoutePattern(pattern);\n return { canonical, changed: canonical !== pattern };\n}\n/**\n * Case-insensitive comparison of two already-canonical paths. Use\n * this anywhere two routes are compared for equality (wiki lookups,\n * non-pattern action route gates) \u2014 preserves casing in the inputs\n * while honoring case-insensitive routing on the customer's site.\n */\nexport function routesMatch(a, b) {\n return a.toLowerCase() === b.toLowerCase();\n}\n", "/**\n * Shared event contract for LLM-mounted tile lifecycle.\n *\n * Producer: `adaptive-chatbot`'s `TileHandler` publishes one of three\n * events whenever the LLM mounts/patches/unmounts a tile.\n *\n * Consumer: `runtime-sdk`'s `SmartCanvasElementLit` subscribes and\n * merges the resulting tiles into its slot-routing pipeline.\n *\n * Replay: `runtime-sdk` publishes `TILE_REPLAY_REQUEST_EVENT` whenever\n * it (re)subscribes; `adaptive-chatbot`'s ElementInstanceStore catches\n * that and re-publishes `TILE_MOUNTED_EVENT` for every active tile.\n *\n * This module is the single source of truth for the event names AND\n * the payload shapes. Both packages import the constants and the\n * `parseTile{Mounted,Patched,Unmounted}EventProps` helpers. Renaming a\n * field here is a TypeScript error on both sides \u2014 no silent drift.\n */\nexport const TILE_MOUNTED_EVENT = 'element.tile_mounted';\nexport const TILE_PATCHED_EVENT = 'element.tile_patched';\nexport const TILE_UNMOUNTED_EVENT = 'element.tile_unmounted';\nexport const TILE_REPLAY_REQUEST_EVENT = 'element.tile_replay_request';\n/**\n * Defensive parser for the event payload. Returns null on missing /\n * malformed fields rather than throwing. Subscribers MUST run the\n * incoming `event.props` through this so a contract drift surfaces as\n * a no-op log line, not a render crash.\n */\nexport function parseTileMountedEventProps(raw) {\n if (!raw || typeof raw !== 'object')\n return null;\n const r = raw;\n const slot = typeof r.slot === 'string' ? r.slot : '';\n const instance_id = typeof r.instance_id === 'string' ? r.instance_id : '';\n const widget = typeof r.widget === 'string' ? r.widget : '';\n if (!slot || !instance_id || !widget)\n return null;\n const props = r.props && typeof r.props === 'object' ? r.props : {};\n return { slot, instance_id, widget, props };\n}\nexport function parseTileUnmountedEventProps(raw) {\n if (!raw || typeof raw !== 'object')\n return null;\n const r = raw;\n const slot = typeof r.slot === 'string' ? r.slot : '';\n const instance_id = typeof r.instance_id === 'string' ? r.instance_id : '';\n if (!instance_id)\n return null;\n return { slot, instance_id };\n}\n"],
5
- "mappings": "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",
3
+ "sources": ["../../../sdk-contracts/dist/mount-plumbing.js", "../../../sdk-contracts/dist/schemas.js", "../../../../node_modules/@lit/context/src/lib/create-context.ts", "../../../sdk-contracts/dist/canvas-context.js", "../../../sdk-contracts/dist/dive-deeper.js", "../../../sdk-contracts/dist/routes.js", "../../../sdk-contracts/dist/tile-lifecycle.js"],
4
+ "sourcesContent": ["/**\n * Mount contract types and helper for adaptive widget mountables.\n *\n * The `WidgetRegistry` in `@syntrologie/runtime-sdk` delivers props to each\n * mountable as `{ ...tile.props, instanceId, runtime, tileId? }` spread flat\n * (see `MountableContract.test.ts` in runtime-sdk for the end-to-end lockdown).\n *\n * Adaptives that strip plumbing manually maintain private blacklists that\n * silently drift when the contract grows (PR #2234 and #2238 documented this).\n * `stripMountPlumbing` centralizes the list so adding a new plumbing key in\n * the future is a one-line change here that every adaptive picks up automatically.\n *\n * Adaptives whose widget schemas use Zod `.strict()` MUST call this before\n * validating, or strict-mode will reject the runtime-injected keys and the\n * widget will silently render its empty/error state.\n */\nexport const MOUNT_PLUMBING_KEYS = ['instanceId', 'runtime', 'tileId'];\nexport function stripMountPlumbing(config) {\n if (!config || typeof config !== 'object') {\n return {};\n }\n const out = { ...config };\n for (const key of MOUNT_PLUMBING_KEYS) {\n delete out[key];\n }\n return out;\n}\n", "/**\n * Shared Zod schemas for decision strategies, conditions, and event scoping.\n *\n * These are the canonical definitions \u2014 runtime-sdk and all adaptive packages\n * should import from here instead of duplicating.\n */\nimport { z } from 'zod';\n// =============================================================================\n// ANCHOR ID SCHEMA\n// =============================================================================\nexport const AnchorIdZ = z\n .object({\n selector: z.string(),\n route: z.union([z.string(), z.array(z.string())]),\n})\n .strict();\n// =============================================================================\n// AUTHORING FIELDS \u2014 id / title / description / validation\n//\n// Shared fields every action carries. `id` is the action identifier the\n// runtime uses to dispatch, dedupe, and drop/replace actions \u2014 it is NOT\n// stripped before serving. `title` / `description` / `validation` are\n// authoring-only metadata stripped server-side in `to_runtime_config`\n// (platform/backend/app/domains/experiments/helpers.py).\n//\n// They all appear in the JSON Schema (and therefore in the tactician's\n// prompt) because the LLM needs to know they are valid action properties \u2014\n// otherwise schema validation would reject what the prompt commands.\n//\n// Each action variant should `.extend(AuthoringFieldsZ)` alongside any\n// triggerWhen/condition extensions.\n// =============================================================================\nexport const AuthoringFieldsZ = {\n id: z.string().optional().describe('Stable action identifier (e.g. \"act_3db6a14d2ab0\").'),\n title: z\n .string()\n .max(200)\n .optional()\n .describe('Authoring-only: short label shown on the action plan dashboard. Stripped before serving to the runtime SDK.'),\n description: z\n .string()\n .max(1000)\n .optional()\n .describe('Authoring-only: one-sentence explanation of what this action does and why. Stripped before serving to the runtime SDK.'),\n validation: z\n .array(z.string().max(500))\n .max(10)\n .optional()\n .describe('Authoring-only: ordered steps a reviewer can follow to trigger this action and visually confirm it works. Each entry is one step. Stripped before serving to the runtime SDK.'),\n};\n// =============================================================================\n// TRIGGER VOCABULARY \u2014 canonical lists of valid event names, metric keys, etc.\n// These flow through to the JSON schema as enums and are used by the LLM prompt.\n// =============================================================================\n/** Events that can be counted in event_count conditions.\n *\n * Every value here must be an event the runtime actually emits \u2014 either a\n * PostHog-autocapture normalization (ui.click/scroll/input/change/submit) or\n * an event-processor detector (ui.hover/idle/scroll_thrash/focus_bounce/\n * hesitate/rage_click). Do not add aspirational names; a trigger counting an\n * event nothing emits never fires.\n */\nexport const COUNTABLE_EVENTS = [\n // User interactions (from PostHog autocapture normalization)\n 'ui.click',\n 'ui.scroll',\n 'ui.input',\n 'ui.change',\n 'ui.submit',\n // Behavioral detectors (from event-processor)\n 'ui.hover',\n 'ui.idle',\n 'ui.scroll_thrash',\n 'ui.focus_bounce',\n 'ui.hesitate',\n 'ui.rage_click',\n // Navigation\n 'nav.page_view',\n 'nav.page_leave',\n];\nexport const CountableEventZ = z\n .enum(COUNTABLE_EVENTS)\n .describe('Event name to count. ui.* = user interactions and behavioral detectors (hesitate, rage_click, scroll_thrash, focus_bounce, idle, hover); nav.* = page navigation.');\n/** Valid session metric keys. */\nexport const SESSION_METRIC_KEYS = ['time_on_page', 'page_views', 'scroll_depth'];\nexport const SessionMetricKeyZ = z\n .enum(SESSION_METRIC_KEYS)\n .describe('Session metric key. time_on_page = seconds on current page, page_views = pages visited this session, scroll_depth = 0-100 percentage.');\n/** Element chain match field prefixes for counter filters. */\nexport const ELEMENT_MATCH_FIELDS = ['tag_name', '$el_text'];\n// Note: attr__* is a dynamic prefix (attr__data-id, attr__class, attr__href, etc.)\n// and cannot be enumerated. The match key is either one of ELEMENT_MATCH_FIELDS\n// or starts with \"attr__\".\n// =============================================================================\n// CONDITION SCHEMAS\n// =============================================================================\nexport const PageUrlConditionZ = z\n .object({\n type: z.literal('page_url'),\n url: z.string().describe('URL path to match (e.g. \"/pricing\", \"/dashboard\")'),\n})\n .describe('Fires when the current page URL matches. Use for page-specific actions. ' +\n 'Example: {\"type\": \"page_url\", \"url\": \"/pricing\"}');\nexport const RouteConditionZ = z\n .object({\n type: z.literal('route'),\n routeId: z.string().describe('Named route ID from the route filter'),\n})\n .describe('Fires when the current route matches a named route ID.');\nexport const AnchorVisibleConditionZ = z\n .object({\n type: z.literal('anchor_visible'),\n anchorId: z.string().describe('CSS selector of the anchor element'),\n state: z\n .enum(['visible', 'present', 'absent'])\n .describe('\"visible\" = in viewport, \"present\" = in DOM, \"absent\" = not in DOM'),\n})\n .describe(\"Fires based on a DOM element's visibility state. \" +\n 'Example: {\"type\": \"anchor_visible\", \"anchorId\": \"#cta-button\", \"state\": \"visible\"}');\nexport const EventOccurredConditionZ = z\n .object({\n type: z.literal('event_occurred'),\n eventName: z.string().describe('Event name (e.g. \"ui.click\", \"$pageview\")'),\n withinMs: z.number().optional().describe('Time window in ms. Omit = any time this session.'),\n})\n .describe('Fires when a specific event has occurred during this session. ' +\n 'Example: {\"type\": \"event_occurred\", \"eventName\": \"ui.click\", \"withinMs\": 5000}');\nexport const StateEqualsConditionZ = z\n .object({\n type: z.literal('state_equals'),\n key: z\n .string()\n .describe('Key in the SDK persistent state store (localStorage). Only valid for keys the host app explicitly sets via syntro.state.set().'),\n value: z.unknown().describe('Expected value to match against'),\n})\n .describe('Checks the SDK persistent state store (localStorage). ONLY for host-app state set via syntro.state.set() \u2014 ' +\n 'NOT for user attributes like region, device, or UTM params (those are handled by segment targeting). ' +\n 'Do NOT use this for targeting. If you do not know the valid state keys, do not use this condition type.');\nexport const ViewportConditionZ = z\n .object({\n type: z.literal('viewport'),\n minWidth: z.number().optional().describe('Minimum viewport width in pixels'),\n maxWidth: z.number().optional().describe('Maximum viewport width in pixels'),\n minHeight: z.number().optional().describe('Minimum viewport height in pixels'),\n maxHeight: z.number().optional().describe('Maximum viewport height in pixels'),\n})\n .describe('Fires based on viewport (screen) size. Use for responsive behavior. ' +\n 'Example: {\"type\": \"viewport\", \"minWidth\": 768} \u2014 fires on tablet and larger.');\nexport const SessionMetricConditionZ = z\n .object({\n type: z.literal('session_metric'),\n key: SessionMetricKeyZ,\n operator: z.enum(['gte', 'lte', 'eq', 'gt', 'lt']),\n threshold: z.number().describe('Numeric threshold to compare against'),\n})\n .describe('Fires when a session metric crosses a threshold. Valid keys: \"time_on_page\" (seconds), ' +\n '\"page_views\" (count), \"scroll_depth\" (0-100). ' +\n 'Example: {\"type\": \"session_metric\", \"key\": \"time_on_page\", \"operator\": \"gte\", \"threshold\": 30}');\nexport const DismissedConditionZ = z\n .object({\n type: z.literal('dismissed'),\n key: z.string().describe('Dismissal key (usually a tile or action ID)'),\n inverted: z\n .boolean()\n .optional()\n .describe('When true, fires if NOT dismissed (default behavior)'),\n})\n .describe('Checks if an item has been dismissed by the user. Use with inverted: true to show only if not dismissed.');\nexport const CooldownActiveConditionZ = z\n .object({\n type: z.literal('cooldown_active'),\n key: z.string().describe('Cooldown key'),\n inverted: z.boolean().optional().describe('When true, fires if cooldown is NOT active'),\n})\n .describe('Checks if a cooldown timer is currently active. Use to prevent showing the same intervention too frequently.');\nexport const FrequencyLimitConditionZ = z\n .object({\n type: z.literal('frequency_limit'),\n key: z.string().describe('Frequency counter key'),\n limit: z.number().describe('Maximum allowed count'),\n inverted: z.boolean().optional().describe('When true, fires if limit NOT reached'),\n})\n .describe('Checks if a frequency limit has been reached. Use to cap how many times an action fires per session.');\nexport const MatchOpZ = z\n .object({\n equals: z.union([z.string(), z.number(), z.boolean()]).optional(),\n contains: z.string().optional(),\n})\n .describe('Match operator for counter filters. Exactly one of equals or contains must be specified.');\nexport const CounterDefZ = z\n .object({\n events: z\n .array(CountableEventZ)\n .min(1)\n .describe('Event names to count. Use values from the countable events enum.'),\n match: z\n .record(z.string(), MatchOpZ)\n .optional()\n .describe('Property filters. Keys are event prop names or element-chain fields ' +\n '(tag_name, $el_text, attr__*). All entries AND together.'),\n})\n .describe('Defines what events to count. Registered as an accumulator predicate at config-load time.');\nexport const EventCountConditionZ = z\n .object({\n type: z.literal('event_count'),\n key: z.string().describe('Unique key for this counter (used for accumulator registration)'),\n operator: z.enum(['gte', 'lte', 'eq', 'gt', 'lt']),\n count: z.number().int().min(0).describe('Target count threshold'),\n withinMs: z\n .number()\n .positive()\n .optional()\n .describe('Time window in ms. Omit = count across entire session.'),\n counter: CounterDefZ.optional().describe('Inline counter definition. Defines what events to count.'),\n})\n .describe('Fires when accumulated event count crosses a threshold. Most powerful trigger type. ' +\n 'Example: {\"type\": \"event_count\", \"key\": \"pricing-clicks\", \"operator\": \"gte\", \"count\": 3, ' +\n '\"counter\": {\"events\": [\"ui.click\"], \"match\": {\"attr__data-cta\": {\"contains\": \"pricing\"}}}}');\nexport const ConditionZ = z.discriminatedUnion('type', [\n PageUrlConditionZ,\n RouteConditionZ,\n AnchorVisibleConditionZ,\n EventOccurredConditionZ,\n StateEqualsConditionZ,\n ViewportConditionZ,\n SessionMetricConditionZ,\n DismissedConditionZ,\n CooldownActiveConditionZ,\n FrequencyLimitConditionZ,\n EventCountConditionZ,\n]);\n// =============================================================================\n// STRATEGY SCHEMAS\n// =============================================================================\nexport const RuleZ = z\n .object({\n conditions: z\n .array(ConditionZ)\n .describe('Array of conditions \u2014 ALL must match (AND logic) for this rule to fire.'),\n value: z\n .unknown()\n .describe('Value returned when all conditions match. For triggerWhen: true = fire the action.'),\n})\n .describe('A single rule. ALL conditions must match (AND logic). Rules in a strategy are evaluated ' +\n 'top-to-bottom \u2014 first rule where all conditions match wins and returns its value.');\nexport const RuleStrategyZ = z\n .object({\n type: z.literal('rules'),\n rules: z\n .array(RuleZ)\n .describe('Ordered list of rules. Evaluated top-to-bottom \u2014 first match wins.'),\n default: z\n .unknown()\n .describe('Fallback value when no rule matches. For triggerWhen: false = do not fire by default.'),\n})\n .describe('Rule-based strategy. Evaluates rules top-to-bottom. First rule where ALL conditions match ' +\n 'returns its value. If no rule matches, returns default. ' +\n 'For triggerWhen: set value=true on matching rules, default=false.');\nexport const ScoreStrategyZ = z\n .object({\n type: z.literal('score'),\n field: z.string(),\n threshold: z.number(),\n above: z.unknown(),\n below: z.unknown(),\n})\n .describe('Score-based strategy. Compares a field value against a threshold.');\nexport const ModelStrategyZ = z\n .object({\n type: z.literal('model'),\n modelId: z.string(),\n inputs: z.array(z.string()),\n outputMapping: z.record(z.string(), z.unknown()),\n default: z.unknown(),\n})\n .describe('ML model strategy. Sends inputs to a model and maps outputs.');\nexport const ExternalStrategyZ = z\n .object({\n type: z.literal('external'),\n endpoint: z.string(),\n method: z.enum(['GET', 'POST']).optional(),\n default: z.unknown(),\n timeoutMs: z.number().optional(),\n})\n .describe('External API strategy. Calls an endpoint to determine the value.');\nexport const DecisionStrategyZ = z.discriminatedUnion('type', [\n RuleStrategyZ,\n ScoreStrategyZ,\n ModelStrategyZ,\n ExternalStrategyZ,\n]);\n/** Canonical Zod schema for the optional triggerWhen field on actions and adaptive items. */\nexport const TriggerWhenZ = DecisionStrategyZ.nullable().optional();\n// =============================================================================\n// TRIGGER DOCUMENTATION \u2014 examples and match field docs\n// Exported as constants so the schema generator can inject them into the\n// JSON schema. The Python prompt builder reads them from the schema.\n// =============================================================================\n/** Complete triggerWhen examples showing the full rules wrapper structure. */\nexport const TRIGGER_EXAMPLES = [\n {\n name: 'Click count on a specific element',\n description: 'Fire when user clicks an element with data-id=\"hero-cta\" 2+ times',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'event_count',\n key: 'cta-clicks',\n operator: 'gte',\n count: 2,\n counter: {\n events: ['ui.click'],\n match: { 'attr__data-id': { equals: 'hero-cta' } },\n },\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'Time on page threshold',\n description: 'Fire after user spends 30+ seconds on the page',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'session_metric',\n key: 'time_on_page',\n operator: 'gte',\n threshold: 30,\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'Element visible in viewport',\n description: 'Fire when a DOM element becomes visible',\n triggerWhen: {\n type: 'rules',\n rules: [\n {\n conditions: [\n {\n type: 'anchor_visible',\n anchorId: '#pricing-section',\n state: 'visible',\n },\n ],\n value: true,\n },\n ],\n default: false,\n },\n },\n {\n name: 'No trigger (fire immediately)',\n description: 'Action fires as soon as the segment matches \u2014 no in-session condition needed',\n triggerWhen: null,\n },\n];\n/** Documentation for counter.match field keys. */\nexport const MATCH_FIELD_DOCS = {\n tag_name: 'HTML tag name (e.g. \"button\", \"a\", \"input\")',\n $el_text: 'Visible text content of the element',\n 'attr__*': 'HTML attribute prefixed with attr__. Example: attr__data-id matches the data-id attribute, ' +\n 'attr__class matches the class attribute, attr__href matches the href attribute.',\n};\n// =============================================================================\n// EVENT SCOPE SCHEMA\n// =============================================================================\n/** Scopes a widget to specific events/URLs. */\nexport const EventScopeZ = z.object({\n events: z.array(z.string()),\n urlContains: z.string().optional(),\n props: z.record(z.union([z.string(), z.number(), z.boolean()])).optional(),\n});\n// =============================================================================\n// NOTIFY SCHEMA\n// =============================================================================\n/** Toast notification config for triggerWhen transitions. */\nexport const NotifyZ = z\n .object({\n title: z.string().optional(),\n body: z.string().optional(),\n icon: z.string().optional(),\n})\n .nullable()\n .optional();\n", "/**\n * @license\n * Copyright 2021 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\n\n/**\n * The Context type defines a type brand to associate a key value with the context value type\n */\nexport type Context<KeyType, ValueType> = KeyType & {__context__: ValueType};\n\n/**\n * @deprecated use Context instead\n */\nexport type ContextKey<KeyType, ValueType> = Context<KeyType, ValueType>;\n\n/**\n * A helper type which can extract a Context value type from a Context type\n */\nexport type ContextType<Key extends Context<unknown, unknown>> =\n Key extends Context<unknown, infer ValueType> ? ValueType : never;\n\n/**\n * Creates a typed Context.\n *\n * Contexts are compared with strict equality.\n *\n * If you want two separate `createContext()` calls to referer to the same\n * context, then use a key that will by equal under strict equality like a\n * string for `Symbol.for()`:\n *\n * ```ts\n * // true\n * createContext('my-context') === createContext('my-context')\n * // true\n * createContext(Symbol.for('my-context')) === createContext(Symbol.for('my-context'))\n * ```\n *\n * If you want a context to be unique so that it's guaranteed to not collide\n * with other contexts, use a key that's unique under strict equality, like\n * a `Symbol()` or object.:\n *\n * ```\n * // false\n * createContext({}) === createContext({})\n * // false\n * createContext(Symbol('my-context')) === createContext(Symbol('my-context'))\n * ```\n *\n * @param key a context key value\n * @template ValueType the type of value that can be provided by this context.\n * @returns the context key value cast to `Context<K, ValueType>`\n */\nexport function createContext<ValueType, K = unknown>(key: K) {\n return key as Context<K, ValueType>;\n}\n", "/**\n * Canvas runtime context \u2014 the shared @lit/context symbol both\n * runtime-sdk (the provider) and canvas-sdk / canvas authors (the\n * consumers) use to thread a narrow runtime handle through the canvas\n * element tree.\n *\n * Living here keeps the symbol identity stable across both packages.\n * If canvas-sdk created its own symbol with `createContext(...)`, it\n * would never match the one runtime-sdk publishes, and `<sc-mount>`\n * would silently see `undefined` instead of the widget registry.\n *\n * The shape declared here is a NARROW VIEW of `SmartCanvasRuntime`.\n * Canvas-side code reads only this subset. The runtime-sdk's\n * `SmartCanvasRuntime` type is a structural superset.\n */\nimport { createContext } from '@lit/context';\n/**\n * The @lit/context symbol. Both runtime-sdk's ContextProvider and\n * canvas-sdk's ContextConsumer must import THIS exact symbol \u2014 not a\n * symbol with the same string name \u2014 for context propagation to work.\n */\nexport const canvasRuntimeContext = createContext('syntrologie:canvas-runtime');\n", "/**\n * \"Dive deeper\" contract \u2014 the ONE canonical way a space-constrained tile\n * (FAQ, comparison, \u2026) hands its content context back to the chat conversation\n * as a deep-dive turn.\n *\n * A tile that can only show a shallow slice of its content (a comparison matrix\n * capped to a few rows, an FAQ answer clamped to a few lines) renders a \"Dive\n * deeper\" affordance. Tapping it dispatches a `window` CustomEvent carrying the\n * tile's content summary; the chat-bar mountable listens for exactly this event\n * and turns it into a user-visible chat turn (\"Tell me more about: \u2026\") so the\n * agent can answer in full \u2014 no re-scrolling the cramped tile.\n *\n * This lives in the neutral `@syntrologie/sdk-contracts` (not in any single\n * adaptive) so BOTH the emitters (adaptive-product comparison, adaptive-faq)\n * and the listener (adaptive-chatbot chat bar) share one wire shape without\n * depending on each other. The event is canvas-agnostic \u2014 it never references a\n * deck, a slot, or a specific host canvas.\n */\n/** The `window` CustomEvent name carrying a {@link DiveDeeperDetail}. */\nexport const DIVE_DEEPER_EVENT = 'syntro:chat:dive-deeper';\n/**\n * Dispatch a {@link DIVE_DEEPER_EVENT} on `window`. Safe in non-DOM contexts\n * (SSR / tests without a window) \u2014 it no-ops. Emitters call this; they never\n * reach into the chat session directly, keeping the adaptive side decoupled\n * from the chat implementation.\n */\nexport function dispatchDiveDeeper(detail) {\n if (typeof window === 'undefined')\n return;\n window.dispatchEvent(new CustomEvent(DIVE_DEEPER_EVENT, { detail }));\n}\n", "/**\n * Canonical route normalization. See `routes.md` for rules and\n * `normalize-route.cases.json` for the parity corpus shared with the\n * Python implementation in syntrologie_common/sdk/routing.py.\n *\n * Two exports \u2014 `normalizeRoute` for literal paths, `normalizeRoutePattern`\n * for activation patterns containing `*`, `**`, `:param`. Today they share\n * an implementation because the rules happen to be wildcard-safe (no\n * lowercase, unreserved-only decode, slash collapse preserves `**`).\n * The seam is preserved as separate exports so the API can diverge\n * without consumer churn if rules change.\n */\n// RFC 3986 reserved characters (gen-delims + sub-delims). When a `%XX`\n// sequence decodes to one of these bytes, we keep the percent-encoded\n// form \u2014 decoding would re-segment the path or change its meaning.\nconst RESERVED_BYTES = new Set([\n 0x21, // !\n 0x23, // #\n 0x24, // $\n 0x26, // &\n 0x27, // '\n 0x28, // (\n 0x29, // )\n 0x2a, // *\n 0x2b, // +\n 0x2c, // ,\n 0x2f, // /\n 0x3a, // :\n 0x3b, // ;\n 0x3d, // =\n 0x3f, // ?\n 0x40, // @\n 0x5b, // [\n 0x5d, // ]\n]);\nconst utf8Decoder = new TextDecoder('utf-8', { fatal: false });\n/** Decode `%XX` sequences for unreserved bytes only. Collapses\n * adjacent `%XX` runs into a UTF-8 decode so `%C3%A9` \u2192 `\u00E9`. */\nfunction decodeUnreservedOnly(input) {\n let out = '';\n let pending = [];\n const flushPending = () => {\n if (pending.length === 0)\n return;\n const bytes = new Uint8Array(pending);\n out += utf8Decoder.decode(bytes);\n pending = [];\n };\n let i = 0;\n while (i < input.length) {\n const ch = input[i];\n if (ch === '%' && i + 2 < input.length && isHex(input[i + 1]) && isHex(input[i + 2])) {\n const byte = parseInt(input.slice(i + 1, i + 3), 16);\n if (RESERVED_BYTES.has(byte)) {\n flushPending();\n // Keep raw, but normalize hex case to uppercase so the\n // canonical form is stable across input casing.\n out += `%${input.slice(i + 1, i + 3).toUpperCase()}`;\n i += 3;\n }\n else {\n pending.push(byte);\n i += 3;\n }\n }\n else {\n flushPending();\n out += ch;\n i += 1;\n }\n }\n flushPending();\n return out;\n}\nfunction isHex(c) {\n return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F');\n}\n/** Strip query string and hash fragment. */\nfunction stripQueryAndHash(s) {\n const q = s.indexOf('?');\n if (q !== -1)\n s = s.slice(0, q);\n const h = s.indexOf('#');\n if (h !== -1)\n s = s.slice(0, h);\n return s;\n}\n/**\n * Normalize a literal path (e.g. `window.location.pathname`, an\n * action's `route` field, a wiki route key).\n *\n * Throws `TypeError` if the input is not an absolute path. Callers\n * that want a soft API should use {@link normalizeRouteWithChange}.\n */\nexport function normalizeRoute(path) {\n if (typeof path !== 'string' || path.length === 0) {\n throw new TypeError('normalizeRoute: input must be a non-empty string');\n }\n if (!path.startsWith('/')) {\n throw new TypeError(`normalizeRoute: input must be absolute (start with '/'); got ${JSON.stringify(path)}`);\n }\n let s = stripQueryAndHash(path);\n s = decodeUnreservedOnly(s);\n s = s.replace(/\\/+/g, '/');\n if (s.length > 1 && s.endsWith('/'))\n s = s.slice(0, -1);\n return s;\n}\n/**\n * Normalize an activation route pattern. Preserves `*`, `**`,\n * `:param` exactly. Today equivalent to {@link normalizeRoute} \u2014 kept\n * as a separate export so rules can diverge later without API churn.\n */\nexport function normalizeRoutePattern(pattern) {\n return normalizeRoute(pattern);\n}\n/**\n * Normalize a route and report whether the input was already\n * canonical. Used by authoring tools to decide whether to emit a\n * warning to the LLM.\n */\nexport function normalizeRouteWithChange(path) {\n const canonical = normalizeRoute(path);\n return { canonical, changed: canonical !== path };\n}\n/** Pattern-side counterpart of {@link normalizeRouteWithChange}. */\nexport function normalizeRoutePatternWithChange(pattern) {\n const canonical = normalizeRoutePattern(pattern);\n return { canonical, changed: canonical !== pattern };\n}\n/**\n * Case-insensitive comparison of two already-canonical paths. Use\n * this anywhere two routes are compared for equality (wiki lookups,\n * non-pattern action route gates) \u2014 preserves casing in the inputs\n * while honoring case-insensitive routing on the customer's site.\n */\nexport function routesMatch(a, b) {\n return a.toLowerCase() === b.toLowerCase();\n}\n", "/**\n * Shared event contract for LLM-mounted tile lifecycle.\n *\n * Producer: `adaptive-chatbot`'s `TileHandler` publishes one of three\n * events whenever the LLM mounts/patches/unmounts a tile.\n *\n * Consumer: `runtime-sdk`'s `SmartCanvasElementLit` subscribes and\n * merges the resulting tiles into its slot-routing pipeline.\n *\n * Replay: `runtime-sdk` publishes `TILE_REPLAY_REQUEST_EVENT` whenever\n * it (re)subscribes; `adaptive-chatbot`'s ElementInstanceStore catches\n * that and re-publishes `TILE_MOUNTED_EVENT` for every active tile.\n *\n * This module is the single source of truth for the event names AND\n * the payload shapes. Both packages import the constants and the\n * `parseTile{Mounted,Patched,Unmounted}EventProps` helpers. Renaming a\n * field here is a TypeScript error on both sides \u2014 no silent drift.\n */\nexport const TILE_MOUNTED_EVENT = 'element.tile_mounted';\nexport const TILE_PATCHED_EVENT = 'element.tile_patched';\nexport const TILE_UNMOUNTED_EVENT = 'element.tile_unmounted';\nexport const TILE_REPLAY_REQUEST_EVENT = 'element.tile_replay_request';\n/**\n * Defensive parser for the event payload. Returns null on missing /\n * malformed fields rather than throwing. Subscribers MUST run the\n * incoming `event.props` through this so a contract drift surfaces as\n * a no-op log line, not a render crash.\n */\nexport function parseTileMountedEventProps(raw) {\n if (!raw || typeof raw !== 'object')\n return null;\n const r = raw;\n const slot = typeof r.slot === 'string' ? r.slot : '';\n const instance_id = typeof r.instance_id === 'string' ? r.instance_id : '';\n const widget = typeof r.widget === 'string' ? r.widget : '';\n if (!slot || !instance_id || !widget)\n return null;\n const props = r.props && typeof r.props === 'object' ? r.props : {};\n return { slot, instance_id, widget, props };\n}\nexport function parseTileUnmountedEventProps(raw) {\n if (!raw || typeof raw !== 'object')\n return null;\n const r = raw;\n const slot = typeof r.slot === 'string' ? r.slot : '';\n const instance_id = typeof r.instance_id === 'string' ? r.instance_id : '';\n if (!instance_id)\n return null;\n return { slot, instance_id };\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["createContext", "key"]
7
7
  }