@cuekit-ai/react 1.3.3 → 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -112,15 +112,24 @@ var init_intent_store = __esm({
112
112
 
113
113
  // src/core/navigation.ts
114
114
  function setNavigationHandler(handler) {
115
+ console.log("\u{1F9ED} setNavigationHandler called with:", !!handler);
115
116
  navigationHandler = handler;
116
117
  }
117
118
  function navigate(path2, params) {
118
119
  const safeParams = params || {};
119
120
  const absolutePath = path2.startsWith("/") ? path2 : `/${path2}`;
121
+ console.log("\u{1F9ED} navigate() called with:", {
122
+ path: path2,
123
+ absolutePath,
124
+ safeParams,
125
+ hasNavigationHandler: !!navigationHandler
126
+ });
120
127
  if (navigationHandler) {
121
128
  try {
129
+ console.log("\u{1F9ED} Using navigationHandler:", absolutePath, safeParams);
122
130
  navigationHandler(absolutePath, safeParams);
123
131
  } catch (error) {
132
+ console.error("\u{1F9ED} NavigationHandler error:", error);
124
133
  }
125
134
  return;
126
135
  }
@@ -135,13 +144,22 @@ function navigate(path2, params) {
135
144
  navigation.push(fullPath);
136
145
  } else {
137
146
  if (typeof window !== "undefined") {
138
- window.location.href = fullPath;
147
+ if (window.location.hash && window.location.hash.startsWith("#")) {
148
+ window.location.hash = fullPath;
149
+ } else {
150
+ window.location.href = fullPath;
151
+ }
139
152
  }
140
153
  }
141
154
  }
142
155
  function getCurrentScreenName() {
143
156
  try {
144
157
  const path2 = getCurrentPath();
158
+ const pathParams = getCurrentPathParams();
159
+ if (path2 && Object.keys(pathParams).length > 0) {
160
+ const paramString = Object.entries(pathParams).map(([key, value]) => `${key}=${value}`).join(",");
161
+ return `${path2}?${paramString}`;
162
+ }
145
163
  return path2 || "UnknownScreen";
146
164
  } catch (e3) {
147
165
  return "UnknownScreen";
@@ -163,6 +181,45 @@ function getCurrentRouteParams() {
163
181
  return {};
164
182
  }
165
183
  }
184
+ function getCurrentPathParams() {
185
+ try {
186
+ const currentPath = getCurrentPath();
187
+ const params = {};
188
+ const numericIdMatch = currentPath.match(/\/(\d+)(?:\/|$)/);
189
+ if (numericIdMatch) {
190
+ params.id = numericIdMatch[1];
191
+ }
192
+ const uuidMatch = currentPath.match(
193
+ /\/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})(?:\/|$)/i
194
+ );
195
+ if (uuidMatch) {
196
+ params.uuid = uuidMatch[1];
197
+ }
198
+ const slugMatch = currentPath.match(/\/([a-z0-9-]+)(?:\/|$)/i);
199
+ if (slugMatch && !numericIdMatch && !uuidMatch) {
200
+ params.slug = slugMatch[1];
201
+ }
202
+ return params;
203
+ } catch (e3) {
204
+ return {};
205
+ }
206
+ }
207
+ function resolveRoutePath(routePath, params) {
208
+ try {
209
+ let resolvedPath = routePath;
210
+ Object.entries(params).forEach(([key, value]) => {
211
+ const placeholder = `:${key}`;
212
+ if (resolvedPath.includes(placeholder)) {
213
+ resolvedPath = resolvedPath.replace(placeholder, value);
214
+ }
215
+ });
216
+ resolvedPath = resolvedPath.replace(/:\w+/g, "");
217
+ resolvedPath = resolvedPath.replace(/\/+/g, "/");
218
+ return resolvedPath;
219
+ } catch (e3) {
220
+ return routePath;
221
+ }
222
+ }
166
223
  function onStateChange() {
167
224
  const routeName = getCurrentScreenName();
168
225
  const params = getCurrentRouteParams();
@@ -202,16 +259,26 @@ var init_navigation = __esm({
202
259
  navigationHandler = null;
203
260
  getCurrentPath = () => {
204
261
  if (typeof window === "undefined") return "";
262
+ if (window.location.hash && window.location.hash.startsWith("#")) {
263
+ const hashPath = window.location.hash.substring(1);
264
+ return hashPath.split("?")[0];
265
+ }
205
266
  return window.location.pathname;
206
267
  };
207
268
  getSearchParams = () => {
208
269
  if (typeof window === "undefined") return new URLSearchParams();
270
+ if (window.location.hash && window.location.hash.includes("?")) {
271
+ const queryString = window.location.hash.split("?")[1];
272
+ return new URLSearchParams(queryString);
273
+ }
209
274
  return new URLSearchParams(window.location.search);
210
275
  };
211
276
  safeNavigate = (name2, params = {}) => {
277
+ console.log("\u{1F9ED} safeNavigate called with:", { name: name2, params });
212
278
  if (name2) {
213
279
  navigate(name2, params);
214
280
  } else {
281
+ console.log("\u{1F9ED} safeNavigate: no name provided, skipping navigation");
215
282
  }
216
283
  };
217
284
  handleNavigationAndClick = (routeName, elementHash) => {
@@ -22916,6 +22983,13 @@ function getInteractiveElements() {
22916
22983
  }
22917
22984
  function getImmediateText(element3) {
22918
22985
  let text7 = "";
22986
+ const textAttributes = ["label", "text", "placeholder", "title", "alt", "aria-label"];
22987
+ for (const attr of textAttributes) {
22988
+ const value = element3.getAttribute(attr);
22989
+ if (value) {
22990
+ text7 += value + " ";
22991
+ }
22992
+ }
22919
22993
  if (element3.childNodes) {
22920
22994
  for (const node2 of Array.from(element3.childNodes)) {
22921
22995
  if (node2.nodeType === 3) {
@@ -22925,12 +22999,30 @@ function getImmediateText(element3) {
22925
22999
  }
22926
23000
  return text7.trim();
22927
23001
  }
22928
- function captureFullDOMStructure() {
22929
- console.log("\u{1F333} Capturing full DOM structure for Cuekit...");
22930
- const interactiveElements = [];
23002
+ function executeAction(action) {
23003
+ console.log("\u{1F3AF} Executing element action:", action);
23004
+ const { action_type, target_element, target } = action;
23005
+ switch (action_type) {
23006
+ case "click":
23007
+ return clickElement(target_element);
23008
+ case "navigate":
23009
+ return navigateToElement(target_element || target);
23010
+ case "input":
23011
+ case "focus":
23012
+ return focusElement(target_element);
23013
+ case "toggle":
23014
+ return toggleElement(target_element);
23015
+ default:
23016
+ console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
23017
+ return false;
23018
+ }
23019
+ }
23020
+ function captureAllInteractiveElements() {
23021
+ console.log("\u{1F333} Capturing ALL interactive elements for Cuekit...");
23022
+ const interactiveElements = {};
22931
23023
  const descriptionsMap = /* @__PURE__ */ new Map();
22932
- document.querySelectorAll("[data-for]").forEach((el) => {
22933
- const targetId = el.getAttribute("data-for");
23024
+ document.querySelectorAll("[data-ansyr-for]").forEach((el) => {
23025
+ const targetId = el.getAttribute("data-ansyr-for");
22934
23026
  if (!targetId) return;
22935
23027
  const tags = [];
22936
23028
  const description = el.getAttribute("data-ansyr-description");
@@ -22945,110 +23037,115 @@ function captureFullDOMStructure() {
22945
23037
  descriptionsMap.set(targetId, [...existingTags, ...tags]);
22946
23038
  }
22947
23039
  });
22948
- const allElements = getInteractiveElements();
22949
- allElements.forEach((element3) => {
23040
+ const allInteractiveElements = getInteractiveElements();
23041
+ console.log("\u{1F333} Found", allInteractiveElements.length, "interactive elements");
23042
+ allInteractiveElements.forEach((element3) => {
23043
+ if (!(element3 instanceof HTMLElement)) return;
22950
23044
  const style = getComputedStyle(element3);
22951
- if (element3.closest("[data-cuekit-ignore]") || !isElementClickable(element3) || element3.tagName.toLowerCase() === "script" || style.display === "none" || style.visibility === "hidden") {
23045
+ if (element3.closest("[data-cuekit-ignore]") || element3.tagName.toLowerCase() === "script" || style.display === "none" || style.visibility === "hidden") {
22952
23046
  return;
22953
23047
  }
23048
+ let elementId = null;
22954
23049
  const staticId = element3.getAttribute("data-ansyr-static");
22955
23050
  const dynamicId = element3.getAttribute("data-ansyr-dynamic");
22956
- const id = staticId || dynamicId;
23051
+ if (staticId) {
23052
+ elementId = staticId;
23053
+ console.log("\u{1F333} Using pre-assigned static ID:", elementId);
23054
+ } else if (dynamicId) {
23055
+ elementId = dynamicId;
23056
+ console.log("\u{1F333} Using pre-assigned dynamic ID:", elementId);
23057
+ } else {
23058
+ elementId = generateStableDOMId(element3);
23059
+ console.log("\u{1F333} Calculated stable DOM ID:", elementId);
23060
+ }
23061
+ if (!elementId) {
23062
+ console.log("\u{1F333} No ID could be determined for element:", element3);
23063
+ return;
23064
+ }
22957
23065
  const tags = [];
22958
23066
  const directDescription = element3.getAttribute("data-ansyr-description");
22959
23067
  if (directDescription) {
22960
23068
  tags.push(directDescription);
22961
23069
  }
22962
- if (id && descriptionsMap.has(id)) {
22963
- tags.push(...descriptionsMap.get(id) || []);
22964
- }
22965
- const dto = {
22966
- testID: id || generateStableDOMId(element3),
22967
- type: element3.tagName.toLowerCase(),
22968
- textContent: getImmediateText(element3) || element3.textContent?.trim() || "",
22969
- tags
22970
- };
22971
- interactiveElements.push(dto);
23070
+ if (descriptionsMap.has(elementId)) {
23071
+ tags.push(...descriptionsMap.get(elementId) || []);
23072
+ }
23073
+ const textContent = getImmediateText(element3) || element3.textContent?.trim() || "";
23074
+ interactiveElements[elementId] = [textContent, ...tags];
23075
+ console.log("\u{1F333} Captured element:", {
23076
+ id: elementId,
23077
+ tagName: element3.tagName,
23078
+ textContent: textContent.substring(0, 50),
23079
+ hasStaticId: !!staticId,
23080
+ hasDynamicId: !!dynamicId,
23081
+ isCalculated: !staticId && !dynamicId
23082
+ });
22972
23083
  });
22973
23084
  const result = {
22974
23085
  components: interactiveElements
22975
23086
  };
22976
- console.log("\u{1F333} Full DOM structure captured:", result);
23087
+ console.log("\u{1F333} All interactive elements captured:", result);
22977
23088
  return result;
22978
23089
  }
22979
- function isElementClickable(element3) {
22980
- const interactiveSelectors = [
22981
- "button",
22982
- "a",
22983
- "input",
22984
- "select",
22985
- "textarea",
22986
- '[role="button"]',
22987
- '[role="link"]',
22988
- '[role="tab"]',
22989
- "[data-onclick-id]",
22990
- "[data-on-press-id]",
22991
- "[onclick]",
22992
- "[onmousedown]",
22993
- "[onmouseup]",
22994
- "[ontouchstart]",
22995
- "[ontouchend]",
22996
- "[onkeydown]",
22997
- "[onkeyup]",
22998
- "[onkeypress]"
22999
- ];
23000
- for (const selector of interactiveSelectors) {
23001
- if (element3.matches(selector)) {
23002
- return true;
23003
- }
23004
- }
23005
- const hasClickEvents = element3.onclick !== null || element3.getAttribute("onclick") !== null;
23006
- const hasInteractiveEvents = element3.ontouchstart !== null || element3.getAttribute("ontouchstart") !== null || element3.ontouchend !== null || element3.getAttribute("ontouchend") !== null || element3.onkeydown !== null || element3.getAttribute("onkeydown") !== null || element3.onkeyup !== null || element3.getAttribute("onkeyup") !== null || element3.onkeypress !== null || element3.getAttribute("onkeypress") !== null;
23007
- const hasPointerCursor = element3.style.cursor === "pointer" || getComputedStyle(element3).cursor === "pointer";
23008
- const hasTabIndex = element3.hasAttribute("tabindex") && parseInt(element3.getAttribute("tabindex") || "0") >= 0;
23009
- const hasInteractiveDataAttrs = element3.hasAttribute("data-clickable") || element3.hasAttribute("data-interactive") || element3.hasAttribute("data-action") || element3.hasAttribute("data-handler");
23010
- const hasInteractiveAria = element3.hasAttribute("aria-pressed") || element3.hasAttribute("aria-expanded") || element3.hasAttribute("aria-selected") || element3.hasAttribute("aria-checked");
23011
- return hasClickEvents || hasInteractiveEvents || hasPointerCursor || hasTabIndex || hasInteractiveDataAttrs || hasInteractiveAria;
23090
+ function clearElementCache() {
23091
+ elementCache.clear();
23092
+ cacheTimestamp = 0;
23012
23093
  }
23013
- function executeAction(action) {
23014
- console.log("\u{1F3AF} Executing element action:", action);
23015
- const { action_type, target_element, target } = action;
23016
- switch (action_type) {
23017
- case "click":
23018
- return clickElement(target_element);
23019
- case "navigate":
23020
- return navigateToElement(target_element || target);
23021
- case "input":
23022
- case "focus":
23023
- return focusElement(target_element);
23024
- case "toggle":
23025
- return toggleElement(target_element);
23026
- default:
23027
- console.warn(`\u26A0\uFE0F Unknown action type: ${action_type}`);
23028
- return false;
23094
+ function validateDynamicElements() {
23095
+ if (false) {
23096
+ const elements = document.querySelectorAll("[data-ansyr-dynamic]");
23097
+ const ids = /* @__PURE__ */ new Set();
23098
+ const duplicates = [];
23099
+ elements.forEach((element3) => {
23100
+ const id = element3.getAttribute("data-ansyr-dynamic");
23101
+ if (id) {
23102
+ if (ids.has(id)) {
23103
+ duplicates.push(id);
23104
+ }
23105
+ ids.add(id);
23106
+ }
23107
+ });
23108
+ if (duplicates.length > 0) {
23109
+ console.warn("\u{1F6A8} CueKit: Duplicate dynamic IDs found:", duplicates);
23110
+ console.warn(
23111
+ "This can cause incorrect element targeting. Ensure each dynamic element has a unique identifier."
23112
+ );
23113
+ }
23029
23114
  }
23030
23115
  }
23031
- function getFullDOMStructure() {
23032
- return captureFullDOMStructure();
23033
- }
23034
23116
  function clickElement(elementId) {
23117
+ console.log("\u{1F5B1}\uFE0F clickElement called with:", elementId);
23035
23118
  if (!elementId) {
23119
+ console.log("\u{1F5B1}\uFE0F clickElement: no elementId provided");
23036
23120
  return false;
23037
23121
  }
23038
23122
  const domElement = findDOMElementById(elementId);
23123
+ console.log("\u{1F5B1}\uFE0F clickElement: found DOM element:", domElement);
23039
23124
  if (domElement) {
23125
+ console.log("\u{1F5B1}\uFE0F clickElement: attempting to click element:", {
23126
+ tagName: domElement.tagName,
23127
+ id: domElement.id,
23128
+ className: domElement.className,
23129
+ textContent: domElement.textContent?.substring(0, 50)
23130
+ });
23040
23131
  domElement.click();
23132
+ console.log("\u{1F5B1}\uFE0F clickElement: click() called successfully");
23041
23133
  return true;
23042
23134
  }
23135
+ console.log("\u{1F5B1}\uFE0F clickElement: element not found");
23043
23136
  return false;
23044
23137
  }
23045
23138
  function navigateToElement(target) {
23139
+ console.log("\u{1F9ED} navigateToElement called with:", target);
23046
23140
  if (!target) {
23141
+ console.log("\u{1F9ED} navigateToElement: no target provided");
23047
23142
  return false;
23048
23143
  }
23049
23144
  if (target.includes("/") || target.startsWith("http")) {
23145
+ console.log("\u{1F9ED} navigateToElement: using safeNavigate for path:", target);
23050
23146
  safeNavigate(target, {});
23051
23147
  } else {
23148
+ console.log("\u{1F9ED} navigateToElement: using handleNavigationAndClick for element:", target);
23052
23149
  handleNavigationAndClick(target, target);
23053
23150
  }
23054
23151
  return true;
@@ -23087,29 +23184,93 @@ function toggleElement(elementId) {
23087
23184
  }
23088
23185
  }
23089
23186
  function findDOMElementById(elementId) {
23187
+ console.log("\u{1F50D} findDOMElementById called with:", elementId);
23090
23188
  if (!elementId) {
23189
+ console.log("\u{1F50D} findDOMElementById: no elementId provided");
23091
23190
  return null;
23092
23191
  }
23093
- const interactiveElements = getInteractiveElements();
23094
- for (const element3 of interactiveElements) {
23095
- if (element3 instanceof HTMLElement) {
23192
+ const now = Date.now();
23193
+ if (now - cacheTimestamp < CACHE_TTL && elementCache.has(elementId)) {
23194
+ const cachedElement = elementCache.get(elementId);
23195
+ console.log("\u{1F50D} findDOMElementById: found in cache:", cachedElement);
23196
+ if (document.contains(cachedElement)) {
23197
+ console.log("\u{1F50D} findDOMElementById: returning cached element");
23198
+ return cachedElement;
23199
+ } else {
23200
+ console.log("\u{1F50D} findDOMElementById: cached element no longer in DOM, removing from cache");
23201
+ elementCache.delete(elementId);
23202
+ }
23203
+ }
23204
+ let foundElement = null;
23205
+ console.log(
23206
+ "\u{1F50D} findDOMElementById: checking for static element with selector:",
23207
+ `[data-ansyr-static="${elementId}"]`
23208
+ );
23209
+ const staticElement = document.querySelector(`[data-ansyr-static="${elementId}"]`);
23210
+ if (staticElement instanceof HTMLElement) {
23211
+ console.log("\u{1F50D} findDOMElementById: found static element:", staticElement);
23212
+ foundElement = staticElement;
23213
+ } else {
23214
+ console.log(
23215
+ "\u{1F50D} findDOMElementById: checking for dynamic element with selector:",
23216
+ `[data-ansyr-dynamic="${elementId}"]`
23217
+ );
23218
+ const dynamicElement = document.querySelector(`[data-ansyr-dynamic="${elementId}"]`);
23219
+ if (dynamicElement instanceof HTMLElement) {
23220
+ console.log("\u{1F50D} findDOMElementById: found dynamic element:", dynamicElement);
23221
+ foundElement = dynamicElement;
23222
+ }
23223
+ }
23224
+ if (!foundElement) {
23225
+ console.log(
23226
+ "\u{1F50D} findDOMElementById: no pre-assigned element found, scanning all interactive elements"
23227
+ );
23228
+ const interactiveElements = getInteractiveElements();
23229
+ console.log("\u{1F50D} findDOMElementById: found", interactiveElements.length, "interactive elements");
23230
+ for (const element3 of interactiveElements) {
23231
+ if (!(element3 instanceof HTMLElement)) continue;
23096
23232
  const staticId = element3.getAttribute("data-ansyr-static");
23097
23233
  const dynamicId = element3.getAttribute("data-ansyr-dynamic");
23098
- const currentElementId = staticId || dynamicId || generateStableDOMId(element3);
23234
+ let currentElementId = null;
23235
+ if (staticId) {
23236
+ currentElementId = staticId;
23237
+ } else if (dynamicId) {
23238
+ currentElementId = dynamicId;
23239
+ } else {
23240
+ currentElementId = generateStableDOMId(element3);
23241
+ }
23099
23242
  if (currentElementId === elementId) {
23100
- return element3;
23243
+ console.log("\u{1F50D} findDOMElementById: found element by ID match:", {
23244
+ element: element3,
23245
+ id: currentElementId,
23246
+ hasStaticId: !!staticId,
23247
+ hasDynamicId: !!dynamicId,
23248
+ isCalculated: !staticId && !dynamicId
23249
+ });
23250
+ foundElement = element3;
23251
+ break;
23101
23252
  }
23102
23253
  }
23254
+ if (!foundElement) {
23255
+ console.log("\u{1F50D} findDOMElementById: element not found in interactive elements scan");
23256
+ }
23103
23257
  }
23104
- return null;
23258
+ if (foundElement) {
23259
+ elementCache.set(elementId, foundElement);
23260
+ cacheTimestamp = now;
23261
+ }
23262
+ return foundElement;
23105
23263
  }
23106
- var INTERACTIVE_ELEMENT_SELECTOR;
23264
+ var INTERACTIVE_ELEMENT_SELECTOR, elementCache, cacheTimestamp, CACHE_TTL;
23107
23265
  var init_element_service = __esm({
23108
23266
  "src/utils/element-service.ts"() {
23109
23267
  "use strict";
23110
23268
  init_navigation();
23111
23269
  init_jsx_encoder();
23112
- INTERACTIVE_ELEMENT_SELECTOR = 'a, button, input, textarea, select, [role="button"], [onclick], [data-ansyr-static], [data-ansyr-dynamic]';
23270
+ INTERACTIVE_ELEMENT_SELECTOR = 'a, button, select, [role="button"], [role="link"], [role="tab"], [onclick], [onmousedown], [onmouseup], [ontouchstart], [ontouchend], [onkeydown], [onkeyup], [onkeypress], [onchange], [onsubmit], [onfocus], [onblur], [data-ansyr-static], [data-ansyr-dynamic]';
23271
+ elementCache = /* @__PURE__ */ new Map();
23272
+ cacheTimestamp = 0;
23273
+ CACHE_TTL = 5e3;
23113
23274
  }
23114
23275
  });
23115
23276
 
@@ -23119,6 +23280,7 @@ __export(webrtc_service_exports, {
23119
23280
  authenticate: () => authenticate,
23120
23281
  connectToRoom: () => connectToRoom,
23121
23282
  disconnectFromRoom: () => disconnectFromRoom,
23283
+ getCurrentCallbacks: () => getCurrentCallbacks,
23122
23284
  getParticipants: () => getParticipants,
23123
23285
  getRoom: () => getRoom,
23124
23286
  getRoomName: () => getRoomName,
@@ -23139,8 +23301,16 @@ function setAudioContainer(newAudioContainerRef) {
23139
23301
  audioContainerRef = newAudioContainerRef;
23140
23302
  }
23141
23303
  function setWebRTCCallbacks(newCallbacks) {
23304
+ console.log("\u{1F4E1} setWebRTCCallbacks called with:", {
23305
+ hasOnNavigationCommand: !!newCallbacks.onNavigationCommand,
23306
+ hasOnConnectionStateChange: !!newCallbacks.onConnectionStateChange,
23307
+ hasOnParticipantUpdate: !!newCallbacks.onParticipantUpdate
23308
+ });
23142
23309
  callbacks = newCallbacks;
23143
23310
  }
23311
+ function getCurrentCallbacks() {
23312
+ return callbacks;
23313
+ }
23144
23314
  async function authenticate(userIdentity, apiKey, appId) {
23145
23315
  try {
23146
23316
  const authPayload = {
@@ -23231,12 +23401,34 @@ function setupEventListeners() {
23231
23401
  track.detach().forEach((element3) => element3.remove());
23232
23402
  }).on(RoomEvent.DataReceived, (payload, participant) => {
23233
23403
  const decodedPayload = new TextDecoder().decode(payload);
23234
- try {
23235
- const message = JSON.parse(decodedPayload);
23236
- callbacks.onNavigationCommand?.(message);
23237
- } catch (error) {
23238
- const message = decodedPayload;
23239
- callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
23404
+ console.log("\u{1F4E1} WebRTC DataReceived:", { decodedPayload, participant: participant?.identity });
23405
+ if (decodedPayload.includes("|")) {
23406
+ const parts = decodedPayload.split("|");
23407
+ const textPart = parts[0];
23408
+ const jsonPart = parts[1];
23409
+ console.log("\u{1F4E1} WebRTC Pipe-separated message:", { textPart, jsonPart });
23410
+ if (textPart) {
23411
+ callbacks.onNavigationCommand?.({ type: "speech_text", data: textPart });
23412
+ }
23413
+ if (jsonPart) {
23414
+ try {
23415
+ const message = JSON.parse(jsonPart);
23416
+ console.log("\u{1F4E1} WebRTC Parsed JSON message:", message);
23417
+ callbacks.onNavigationCommand?.(message);
23418
+ } catch (error) {
23419
+ console.log("\u{1F4E1} WebRTC JSON parse error for JSON part:", error, "JSON part:", jsonPart);
23420
+ }
23421
+ }
23422
+ } else {
23423
+ try {
23424
+ const message = JSON.parse(decodedPayload);
23425
+ console.log("\u{1F4E1} WebRTC Parsed message:", message);
23426
+ callbacks.onNavigationCommand?.(message);
23427
+ } catch (error) {
23428
+ console.log("\u{1F4E1} WebRTC JSON parse error:", error, "Raw payload:", decodedPayload);
23429
+ const message = decodedPayload;
23430
+ callbacks.onNavigationCommand?.({ type: "raw_text", data: message });
23431
+ }
23240
23432
  }
23241
23433
  }).on(RoomEvent.Disconnected, () => {
23242
23434
  setWebRTCConnectionState({ isConnected: false, isConnecting: false });
@@ -23290,17 +23482,19 @@ async function sendUserCommand(command) {
23290
23482
  await sendData(command);
23291
23483
  }
23292
23484
  async function sendRuntimeData() {
23485
+ console.log("\u{1F9E0} checking room:", room);
23293
23486
  if (!room) {
23294
23487
  return;
23295
23488
  }
23489
+ console.log("\u{1F9E0} Sending runtime data", room);
23296
23490
  try {
23297
- const domStructure = captureFullDOMStructure();
23491
+ const allInteractiveElements = captureAllInteractiveElements();
23298
23492
  const screenName = getCurrentScreenName();
23299
23493
  const response = {
23300
23494
  type: "runtime_data_response",
23301
23495
  data: {
23302
- components: domStructure.components,
23303
- current_screen: screenName
23496
+ components: allInteractiveElements.components,
23497
+ currentRoute: screenName
23304
23498
  }
23305
23499
  };
23306
23500
  await sendData(JSON.stringify(response));
@@ -24507,17 +24701,20 @@ __export(index_exports, {
24507
24701
  InitCuekit: () => InitCuekit,
24508
24702
  MicButton: () => MicButton,
24509
24703
  VoiceIntensityVisualizer: () => VoiceIntensityVisualizer,
24510
- captureFullDOMStructure: () => captureFullDOMStructure,
24704
+ captureAllInteractiveElements: () => captureAllInteractiveElements,
24705
+ clearElementCache: () => clearElementCache,
24511
24706
  configureWebRTCServer: () => configureWebRTCServer,
24512
24707
  executeAction: () => executeAction,
24513
24708
  generateDynamicId: () => generateDynamicId,
24514
- getFullDOMStructure: () => getFullDOMStructure,
24709
+ getCurrentPathParams: () => getCurrentPathParams,
24515
24710
  getWebRTCServerConfig: () => getWebRTCServerConfig,
24516
24711
  initWebRTC: () => initWebRTC,
24517
24712
  initWebRTCWithDeployedBackend: () => initWebRTCWithDeployedBackend,
24713
+ resolveRoutePath: () => resolveRoutePath,
24518
24714
  useCuekit: () => useCuekit,
24519
24715
  useQubeContext: () => useQubeContext,
24520
- useWebRTC: () => useWebRTC
24716
+ useWebRTC: () => useWebRTC,
24717
+ validateDynamicElements: () => validateDynamicElements
24521
24718
  });
24522
24719
  module.exports = __toCommonJS(index_exports);
24523
24720
 
@@ -24651,25 +24848,12 @@ var CuekitProvider = ({
24651
24848
  Promise.resolve().then(() => (init_webrtc_service(), webrtc_service_exports)).then(({ setWebRTCCallbacks: setWebRTCCallbacks2 }) => {
24652
24849
  setWebRTCCallbacks2({
24653
24850
  onNavigationCommand: (command) => {
24654
- switch (command.type) {
24655
- case "static_data_ready":
24656
- break;
24657
- case "ai_intent":
24658
- if (command.actionType === "navigate" && command.current_page) {
24659
- if (navigationHandler2) {
24660
- navigationHandler2(command.current_page, {
24661
- intent: command.intent,
24662
- text: command.text,
24663
- confidence: command.confidence
24664
- });
24665
- }
24666
- }
24667
- break;
24668
- case "user_speech_text":
24669
- break;
24670
- case "ai_speech_text":
24671
- break;
24672
- default:
24851
+ if (command.data.actionType === "navigate" && command.data.routeName) {
24852
+ if (navigationHandler2) {
24853
+ navigationHandler2(command.data.routeName);
24854
+ }
24855
+ } else if (command.data.actionType === "click" && command.data.elementId) {
24856
+ console.log("AI intent: Click element", command.data.elementId);
24673
24857
  }
24674
24858
  },
24675
24859
  onConnectionStateChange: (state) => {
@@ -24897,6 +25081,14 @@ var useCuekit = (options) => {
24897
25081
  const handleNavigationCommand = (event) => {
24898
25082
  console.log(`\u2B07\uFE0F Received event from backend: ${event.type}`, event);
24899
25083
  switch (event.type) {
25084
+ case "speech_text": {
25085
+ console.log("\u{1F5E3}\uFE0F AI Speech text:", event.data);
25086
+ break;
25087
+ }
25088
+ case "raw_text": {
25089
+ console.log("\u{1F4DD} Raw text message:", event.data);
25090
+ break;
25091
+ }
24900
25092
  case "user_speech_chunk":
24901
25093
  case "ai_speech_chunk": {
24902
25094
  const role = event.type === "user_speech_chunk" ? "user" : "ai";
@@ -24932,16 +25124,21 @@ var useCuekit = (options) => {
24932
25124
  }
24933
25125
  case "ai_intent": {
24934
25126
  const intent = event.data;
24935
- if (intent.actionType === "click" && intent.actionMetadata.elementId) {
25127
+ console.log("\u{1F3AF} AI Intent received:", intent);
25128
+ if (intent.actionType === "click" && intent.elementId) {
25129
+ console.log("\u{1F3AF} Executing click action:", intent.elementId);
24936
25130
  executeAction({
24937
25131
  action_type: "click",
24938
- target_element: intent.actionMetadata.elementId
25132
+ target_element: intent.elementId
24939
25133
  });
24940
- } else if (intent.actionType === "navigate" && intent.actionMetadata.routeName) {
25134
+ } else if (intent.actionType === "navigate" && intent.routeName) {
25135
+ console.log("\u{1F3AF} Executing navigate action:", intent.routeName);
24941
25136
  executeAction({
24942
25137
  action_type: "navigate",
24943
- target_element: intent.actionMetadata.routeName
25138
+ target_element: intent.routeName
24944
25139
  });
25140
+ } else {
25141
+ console.log("\u{1F3AF} AI Intent not handled:", intent);
24945
25142
  }
24946
25143
  break;
24947
25144
  }
@@ -40556,9 +40753,7 @@ var MicButton = ({
40556
40753
  setStatus,
40557
40754
  participants
40558
40755
  } = useCuekit({
40559
- onNavigationCommand: (command) => {
40560
- console.log("\u{1F3A4} MicButton: Navigation command received:", command);
40561
- },
40756
+ // Don't override navigation command - let the provider handle it
40562
40757
  onConnectionStateChange: (state) => {
40563
40758
  console.log("\u{1F3A4} MicButton: Connection state changed:", state);
40564
40759
  },
@@ -40947,4 +41142,4 @@ function generateDynamicId(routePath, elementIdentifier) {
40947
41142
  }
40948
41143
 
40949
41144
  // src/index.ts
40950
- init_element_service();
41145
+ init_navigation();