@qontinui/ui-bridge 0.1.1 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/ai/index.d.mts +893 -0
  2. package/dist/ai/index.d.ts +893 -0
  3. package/dist/ai/index.js +3897 -0
  4. package/dist/ai/index.js.map +1 -0
  5. package/dist/ai/index.mjs +3839 -0
  6. package/dist/ai/index.mjs.map +1 -0
  7. package/dist/control/index.d.mts +5 -4
  8. package/dist/control/index.d.ts +5 -4
  9. package/dist/core/index.d.mts +6 -4
  10. package/dist/core/index.d.ts +6 -4
  11. package/dist/core/index.js +581 -4
  12. package/dist/core/index.js.map +1 -1
  13. package/dist/core/index.mjs +581 -4
  14. package/dist/core/index.mjs.map +1 -1
  15. package/dist/debug/index.d.mts +3 -3
  16. package/dist/debug/index.d.ts +3 -3
  17. package/dist/index.d.mts +7 -5
  18. package/dist/index.d.ts +7 -5
  19. package/dist/index.js +4112 -12
  20. package/dist/index.js.map +1 -1
  21. package/dist/index.mjs +4056 -13
  22. package/dist/index.mjs.map +1 -1
  23. package/dist/{metrics-QCnK0EFw.d.ts → metrics-C9XRi_mL.d.ts} +2 -2
  24. package/dist/{metrics-BCG7z7Aq.d.mts → metrics-NC3csD0R.d.mts} +2 -2
  25. package/dist/react/index.d.mts +6 -5
  26. package/dist/react/index.d.ts +6 -5
  27. package/dist/react/index.js +587 -10
  28. package/dist/react/index.js.map +1 -1
  29. package/dist/react/index.mjs +587 -10
  30. package/dist/react/index.mjs.map +1 -1
  31. package/dist/{registry-CT6BVVKr.d.mts → registry-CIEDjbQ9.d.ts} +22 -1
  32. package/dist/{registry-D4mQ01B3.d.ts → registry-SsSDq46X.d.mts} +22 -1
  33. package/dist/render-log/index.d.mts +1 -1
  34. package/dist/render-log/index.d.ts +1 -1
  35. package/dist/types-BvCfFuEV.d.ts +534 -0
  36. package/dist/types-CFT3Dnx4.d.mts +534 -0
  37. package/dist/{types-BpvpStn3.d.mts → types-CPMbN_Iw.d.mts} +8 -0
  38. package/dist/{types-BpvpStn3.d.ts → types-CPMbN_Iw.d.ts} +8 -0
  39. package/dist/{types-DdJD9yw5.d.mts → types-Dr6tH-bm.d.mts} +1 -1
  40. package/dist/{types-BDkXy5si.d.ts → types-oCTrRxSw.d.ts} +1 -1
  41. package/dist/{websocket-client-DupH0X7B.d.ts → websocket-client-CX4QJesI.d.ts} +1 -1
  42. package/dist/{websocket-client-B2LC9CYc.d.mts → websocket-client-C_Na0OSp.d.mts} +1 -1
  43. package/package.json +6 -1
@@ -1,7 +1,8 @@
1
- import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-DdJD9yw5.mjs';
2
- export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-DdJD9yw5.mjs';
3
- import { U as UIBridgeRegistry } from '../registry-CT6BVVKr.mjs';
4
- import { a0 as WaitOptions } from '../types-BpvpStn3.mjs';
1
+ import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-Dr6tH-bm.mjs';
2
+ export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-Dr6tH-bm.mjs';
3
+ import { U as UIBridgeRegistry } from '../registry-SsSDq46X.mjs';
4
+ import { a0 as WaitOptions } from '../types-CPMbN_Iw.mjs';
5
+ import '../types-CFT3Dnx4.mjs';
5
6
 
6
7
  /**
7
8
  * Action Executor
@@ -1,7 +1,8 @@
1
- import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-BDkXy5si.js';
2
- export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-BDkXy5si.js';
3
- import { U as UIBridgeRegistry } from '../registry-D4mQ01B3.js';
4
- import { a0 as WaitOptions } from '../types-BpvpStn3.js';
1
+ import { A as ActionExecutor, b as ControlActionRequest, c as ControlActionResponse, C as ComponentActionRequest, a as ComponentActionResponse, W as WaitResult, F as FindRequest, g as FindResponse, d as ControlSnapshot, i as WorkflowEngine, j as WorkflowRunRequest, k as WorkflowRunResponse } from '../types-oCTrRxSw.js';
2
+ export { D as DiscoveredElement, e as DiscoveryRequest, f as DiscoveryResponse, K as KeyboardAction, M as MouseAction, S as ScrollAction, h as SelectAction, T as TypeAction, l as WorkflowRunStatus, m as WorkflowStepResult } from '../types-oCTrRxSw.js';
3
+ import { U as UIBridgeRegistry } from '../registry-CIEDjbQ9.js';
4
+ import { a0 as WaitOptions } from '../types-CPMbN_Iw.js';
5
+ import '../types-BvCfFuEV.js';
5
6
 
6
7
  /**
7
8
  * Action Executor
@@ -1,7 +1,9 @@
1
- import { E as ElementIdentifier } from '../types-BpvpStn3.mjs';
2
- export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-BpvpStn3.mjs';
3
- export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-CT6BVVKr.mjs';
4
- export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-B2LC9CYc.mjs';
1
+ import { E as ElementIdentifier } from '../types-CPMbN_Iw.mjs';
2
+ export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-CPMbN_Iw.mjs';
3
+ export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-SsSDq46X.mjs';
4
+ export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-C_Na0OSp.mjs';
5
+ import '../types-CFT3Dnx4.mjs';
6
+ import '../types-Dr6tH-bm.mjs';
5
7
 
6
8
  /**
7
9
  * Element Identification Module
@@ -1,7 +1,9 @@
1
- import { E as ElementIdentifier } from '../types-BpvpStn3.js';
2
- export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-BpvpStn3.js';
3
- export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-D4mQ01B3.js';
4
- export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-DupH0X7B.js';
1
+ import { E as ElementIdentifier } from '../types-CPMbN_Iw.js';
2
+ export { A as ActionHandler, a as ActionRequest, b as ActionResponse, B as BranchCondition, c as BridgeEvent, d as BridgeEventListener, e as BridgeEventType, f as BridgeSnapshot, C as ComponentAction, g as CustomAction, h as ElementState, i as ElementType, j as ExtractConfig, L as LogConfig, k as LoopConfig, N as NavigationResult, P as PathResult, R as RegisteredComponent, l as RegisteredElement, S as StandardAction, m as StateSnapshot, T as TransitionResult, U as UIBridgeConfig, n as UIBridgeFeatures, o as UIState, p as UIStateGroup, q as UITransition, W as WSClientConfig, r as WSClientMessage, s as WSClientMessageType, t as WSConnectionState, u as WSDiscoverMessage, v as WSErrorMessage, w as WSEventMessage, x as WSExecuteActionMessage, y as WSExecuteComponentActionMessage, z as WSExecuteWorkflowMessage, D as WSFindMessage, F as WSGetElementMessage, G as WSGetSnapshotMessage, H as WSMessageBase, I as WSPingMessage, J as WSPongMessage, K as WSResponseMessage, M as WSServerMessage, O as WSServerMessageType, Q as WSSubscribeMessage, V as WSSubscribedMessage, X as WSSubscriptionOptions, Y as WSUnsubscribeMessage, Z as WSUnsubscribedMessage, _ as WSWelcomeMessage, $ as WSWorkflowProgressMessage, a0 as WaitOptions, a1 as Workflow, a2 as WorkflowStep, a3 as WorkflowStepType } from '../types-CPMbN_Iw.js';
3
+ export { R as RegistryOptions, U as UIBridgeRegistry, g as getGlobalRegistry, r as resetGlobalRegistry, s as setGlobalRegistry } from '../registry-CIEDjbQ9.js';
4
+ export { U as UIBridgeWSClient, c as createWSClient } from '../websocket-client-CX4QJesI.js';
5
+ import '../types-BvCfFuEV.js';
6
+ import '../types-oCTrRxSw.js';
5
7
 
6
8
  /**
7
9
  * Element Identification Module
@@ -219,6 +219,376 @@ function elementMatchesIdentifier(element, identifier) {
219
219
  return identifier.uiId && element.getAttribute("data-ui-id") === identifier.uiId || identifier.testId && element.getAttribute("data-testid") === identifier.testId || identifier.awasId && element.getAttribute("data-awas-element") === identifier.awasId || identifier.htmlId && element.id === identifier.htmlId || false;
220
220
  }
221
221
 
222
+ // src/ai/fuzzy-matcher.ts
223
+ var DEFAULT_FUZZY_CONFIG = {
224
+ threshold: 0.7,
225
+ levenshteinWeight: 0.3,
226
+ jaroWinklerWeight: 0.4,
227
+ ngramWeight: 0.3,
228
+ ngramSize: 2,
229
+ caseSensitive: false,
230
+ ignoreWhitespace: true
231
+ };
232
+ function levenshteinDistance(s1, s2) {
233
+ const len1 = s1.length;
234
+ const len2 = s2.length;
235
+ const matrix = Array(len1 + 1).fill(null).map(() => Array(len2 + 1).fill(0));
236
+ for (let i = 0; i <= len1; i++) matrix[i][0] = i;
237
+ for (let j = 0; j <= len2; j++) matrix[0][j] = j;
238
+ for (let i = 1; i <= len1; i++) {
239
+ for (let j = 1; j <= len2; j++) {
240
+ const cost = s1[i - 1] === s2[j - 1] ? 0 : 1;
241
+ matrix[i][j] = Math.min(
242
+ matrix[i - 1][j] + 1,
243
+ // deletion
244
+ matrix[i][j - 1] + 1,
245
+ // insertion
246
+ matrix[i - 1][j - 1] + cost
247
+ // substitution
248
+ );
249
+ }
250
+ }
251
+ return matrix[len1][len2];
252
+ }
253
+ function levenshteinSimilarity(s1, s2) {
254
+ if (s1.length === 0 && s2.length === 0) return 1;
255
+ if (s1.length === 0 || s2.length === 0) return 0;
256
+ const distance = levenshteinDistance(s1, s2);
257
+ const maxLength = Math.max(s1.length, s2.length);
258
+ return 1 - distance / maxLength;
259
+ }
260
+ function jaroSimilarity(s1, s2) {
261
+ if (s1.length === 0 && s2.length === 0) return 1;
262
+ if (s1.length === 0 || s2.length === 0) return 0;
263
+ const matchDistance = Math.floor(Math.max(s1.length, s2.length) / 2) - 1;
264
+ const s1Matches = new Array(s1.length).fill(false);
265
+ const s2Matches = new Array(s2.length).fill(false);
266
+ let matches = 0;
267
+ let transpositions = 0;
268
+ for (let i = 0; i < s1.length; i++) {
269
+ const start = Math.max(0, i - matchDistance);
270
+ const end = Math.min(i + matchDistance + 1, s2.length);
271
+ for (let j = start; j < end; j++) {
272
+ if (s2Matches[j] || s1[i] !== s2[j]) continue;
273
+ s1Matches[i] = true;
274
+ s2Matches[j] = true;
275
+ matches++;
276
+ break;
277
+ }
278
+ }
279
+ if (matches === 0) return 0;
280
+ let k = 0;
281
+ for (let i = 0; i < s1.length; i++) {
282
+ if (!s1Matches[i]) continue;
283
+ while (!s2Matches[k]) k++;
284
+ if (s1[i] !== s2[k]) transpositions++;
285
+ k++;
286
+ }
287
+ return (matches / s1.length + matches / s2.length + (matches - transpositions / 2) / matches) / 3;
288
+ }
289
+ function jaroWinklerSimilarity(s1, s2, prefixScale = 0.1) {
290
+ const jaroSim = jaroSimilarity(s1, s2);
291
+ let prefixLength = 0;
292
+ const maxPrefix = Math.min(4, Math.min(s1.length, s2.length));
293
+ for (let i = 0; i < maxPrefix; i++) {
294
+ if (s1[i] === s2[i]) {
295
+ prefixLength++;
296
+ } else {
297
+ break;
298
+ }
299
+ }
300
+ return jaroSim + prefixLength * prefixScale * (1 - jaroSim);
301
+ }
302
+ function generateNgrams(s, n) {
303
+ const ngrams = /* @__PURE__ */ new Set();
304
+ if (s.length < n) {
305
+ ngrams.add(s);
306
+ return ngrams;
307
+ }
308
+ for (let i = 0; i <= s.length - n; i++) {
309
+ ngrams.add(s.substring(i, i + n));
310
+ }
311
+ return ngrams;
312
+ }
313
+ function ngramSimilarity(s1, s2, n = 2) {
314
+ if (s1.length === 0 && s2.length === 0) return 1;
315
+ if (s1.length === 0 || s2.length === 0) return 0;
316
+ const ngrams1 = generateNgrams(s1, n);
317
+ const ngrams2 = generateNgrams(s2, n);
318
+ let intersection = 0;
319
+ for (const ngram of ngrams1) {
320
+ if (ngrams2.has(ngram)) {
321
+ intersection++;
322
+ }
323
+ }
324
+ const union = ngrams1.size + ngrams2.size - intersection;
325
+ return union === 0 ? 0 : intersection / union;
326
+ }
327
+ function normalizeString(s, config = {}) {
328
+ let normalized = s;
329
+ if (!config.caseSensitive) {
330
+ normalized = normalized.toLowerCase();
331
+ }
332
+ if (config.ignoreWhitespace !== false) {
333
+ normalized = normalized.replace(/\s+/g, " ").trim();
334
+ }
335
+ return normalized;
336
+ }
337
+ function fuzzyMatch(source, target, config = {}) {
338
+ const finalConfig = { ...DEFAULT_FUZZY_CONFIG, ...config };
339
+ const normalizedSource = normalizeString(source, finalConfig);
340
+ const normalizedTarget = normalizeString(target, finalConfig);
341
+ const levenshteinScore = levenshteinSimilarity(normalizedSource, normalizedTarget);
342
+ const jaroWinklerScore = jaroWinklerSimilarity(normalizedSource, normalizedTarget);
343
+ const ngramScore = ngramSimilarity(normalizedSource, normalizedTarget, finalConfig.ngramSize);
344
+ const similarity = levenshteinScore * finalConfig.levenshteinWeight + jaroWinklerScore * finalConfig.jaroWinklerWeight + ngramScore * finalConfig.ngramWeight;
345
+ return {
346
+ similarity,
347
+ isMatch: similarity >= finalConfig.threshold,
348
+ scores: {
349
+ levenshtein: levenshteinScore,
350
+ jaroWinkler: jaroWinklerScore,
351
+ ngram: ngramScore
352
+ },
353
+ normalizedSource,
354
+ normalizedTarget
355
+ };
356
+ }
357
+ function tokenize(s) {
358
+ return s.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/[_-]/g, " ").replace(/\s+/g, " ").trim().toLowerCase().split(" ").filter((token) => token.length > 0);
359
+ }
360
+
361
+ // src/ai/alias-generator.ts
362
+ var DEFAULT_ALIAS_CONFIG = {
363
+ includeText: true,
364
+ includeAriaLabel: true,
365
+ includePlaceholder: true,
366
+ includeTitle: true,
367
+ includeSynonyms: true,
368
+ maxAliases: 20,
369
+ minLength: 2,
370
+ maxLength: 50
371
+ };
372
+ var SYNONYMS = {
373
+ // Submit-related
374
+ submit: ["send", "go", "confirm", "ok", "apply", "save", "done", "finish"],
375
+ send: ["submit", "deliver", "post"],
376
+ save: ["submit", "store", "keep", "apply"],
377
+ cancel: ["close", "dismiss", "abort", "back", "exit", "quit", "nevermind"],
378
+ close: ["cancel", "dismiss", "exit", "x"],
379
+ delete: ["remove", "trash", "erase", "clear", "destroy"],
380
+ remove: ["delete", "clear", "discard"],
381
+ edit: ["modify", "change", "update", "alter"],
382
+ update: ["edit", "modify", "save", "refresh"],
383
+ add: ["create", "new", "plus", "insert"],
384
+ create: ["add", "new", "make"],
385
+ search: ["find", "lookup", "query", "filter"],
386
+ find: ["search", "locate", "lookup"],
387
+ login: ["signin", "sign in", "log in", "authenticate", "enter"],
388
+ logout: ["signout", "sign out", "log out", "exit"],
389
+ register: ["signup", "sign up", "join", "create account"],
390
+ next: ["continue", "forward", "proceed", "advance"],
391
+ previous: ["back", "backward", "return", "prior"],
392
+ back: ["previous", "return", "backward"],
393
+ start: ["begin", "launch", "initiate", "run", "execute"],
394
+ stop: ["end", "halt", "pause", "terminate"],
395
+ enable: ["activate", "turn on", "switch on"],
396
+ disable: ["deactivate", "turn off", "switch off"],
397
+ show: ["display", "reveal", "view", "open"],
398
+ hide: ["conceal", "collapse", "close"],
399
+ expand: ["open", "show", "unfold", "reveal"],
400
+ collapse: ["close", "hide", "fold", "minimize"],
401
+ yes: ["ok", "confirm", "agree", "accept"],
402
+ no: ["cancel", "decline", "reject", "deny"],
403
+ help: ["support", "assistance", "info", "information", "faq"],
404
+ settings: ["preferences", "options", "config", "configuration"],
405
+ profile: ["account", "user", "me"],
406
+ download: ["export", "save", "get"],
407
+ upload: ["import", "load", "attach"],
408
+ refresh: ["reload", "update", "sync"],
409
+ copy: ["duplicate", "clone"],
410
+ paste: ["insert"],
411
+ select: ["choose", "pick"],
412
+ toggle: ["switch", "flip"],
413
+ // Form fields
414
+ email: ["e-mail", "mail"],
415
+ password: ["pass", "pwd", "secret"],
416
+ username: ["user", "login", "account", "name"],
417
+ firstname: ["first name", "given name", "forename"],
418
+ lastname: ["last name", "surname", "family name"],
419
+ fullname: ["full name", "name", "complete name"],
420
+ phone: ["telephone", "tel", "mobile", "cell"],
421
+ address: ["location", "street"],
422
+ city: ["town"],
423
+ country: ["nation"],
424
+ zip: ["zipcode", "postal", "postal code", "postcode"],
425
+ // Navigation
426
+ home: ["main", "start", "dashboard"],
427
+ menu: ["navigation", "nav"],
428
+ sidebar: ["side bar", "side panel", "side menu"]
429
+ };
430
+ var ELEMENT_ACTION_WORDS = {
431
+ button: ["button", "btn", "click"],
432
+ input: ["input", "field", "textbox", "box"],
433
+ textarea: ["textarea", "text area", "text field", "multiline"],
434
+ select: ["select", "dropdown", "combo", "picker", "chooser"],
435
+ checkbox: ["checkbox", "check", "tick"],
436
+ radio: ["radio", "option", "choice"],
437
+ link: ["link", "anchor", "href"],
438
+ form: ["form"],
439
+ menu: ["menu"],
440
+ menuitem: ["menu item", "option"],
441
+ tab: ["tab"],
442
+ dialog: ["dialog", "modal", "popup"],
443
+ switch: ["switch", "toggle"],
444
+ slider: ["slider", "range"]
445
+ };
446
+ function normalizeAlias(text) {
447
+ return text.toLowerCase().replace(/[^\w\s]/g, " ").replace(/\s+/g, " ").trim();
448
+ }
449
+ function extractWords(text) {
450
+ const tokens = tokenize(text);
451
+ return tokens.filter((t) => t.length >= 2);
452
+ }
453
+ function generateTextAliases(text, config) {
454
+ if (!text || !config.includeText) return [];
455
+ const aliases = [];
456
+ const normalized = normalizeAlias(text);
457
+ if (normalized.length >= config.minLength && normalized.length <= config.maxLength) {
458
+ aliases.push(normalized);
459
+ }
460
+ const words = extractWords(text);
461
+ for (const word of words) {
462
+ if (word.length >= config.minLength) {
463
+ aliases.push(word);
464
+ }
465
+ }
466
+ if (words.length >= 2 && words.length <= 4) {
467
+ const twoWords = words.slice(0, 2).join(" ");
468
+ if (twoWords.length <= config.maxLength) {
469
+ aliases.push(twoWords);
470
+ }
471
+ if (words.length > 2) {
472
+ const lastTwo = words.slice(-2).join(" ");
473
+ if (lastTwo.length <= config.maxLength) {
474
+ aliases.push(lastTwo);
475
+ }
476
+ }
477
+ }
478
+ return aliases;
479
+ }
480
+ function generateSynonyms(aliases, config) {
481
+ if (!config.includeSynonyms) return [];
482
+ const synonyms = [];
483
+ for (const alias of aliases) {
484
+ const words = alias.toLowerCase().split(/\s+/);
485
+ for (const word of words) {
486
+ if (SYNONYMS[word]) {
487
+ for (const synonym of SYNONYMS[word]) {
488
+ const newAlias = alias.toLowerCase().replace(word, synonym);
489
+ if (newAlias !== alias.toLowerCase()) {
490
+ synonyms.push(newAlias);
491
+ }
492
+ if (synonym.length >= config.minLength) {
493
+ synonyms.push(synonym);
494
+ }
495
+ }
496
+ }
497
+ }
498
+ }
499
+ return synonyms;
500
+ }
501
+ function generateTypeAliases(elementType) {
502
+ const type = elementType.toLowerCase();
503
+ return ELEMENT_ACTION_WORDS[type] || [type];
504
+ }
505
+ function generateAliases(input, config = {}) {
506
+ const finalConfig = { ...DEFAULT_ALIAS_CONFIG, ...config };
507
+ const aliasSet = /* @__PURE__ */ new Set();
508
+ const addAlias = (alias) => {
509
+ const normalized = normalizeAlias(alias);
510
+ if (normalized.length >= finalConfig.minLength && normalized.length <= finalConfig.maxLength) {
511
+ aliasSet.add(normalized);
512
+ }
513
+ };
514
+ const addAliases = (aliases2) => {
515
+ for (const alias of aliases2) {
516
+ addAlias(alias);
517
+ }
518
+ };
519
+ if (finalConfig.includeText && input.textContent) {
520
+ addAliases(generateTextAliases(input.textContent, finalConfig));
521
+ }
522
+ if (finalConfig.includeAriaLabel && input.ariaLabel) {
523
+ addAliases(generateTextAliases(input.ariaLabel, finalConfig));
524
+ }
525
+ if (finalConfig.includeAriaLabel && input.ariaLabelledBy) {
526
+ addAliases(generateTextAliases(input.ariaLabelledBy, finalConfig));
527
+ }
528
+ if (finalConfig.includePlaceholder && input.placeholder) {
529
+ addAliases(generateTextAliases(input.placeholder, finalConfig));
530
+ }
531
+ if (finalConfig.includeTitle && input.title) {
532
+ addAliases(generateTextAliases(input.title, finalConfig));
533
+ }
534
+ if (input.labelText) {
535
+ addAliases(generateTextAliases(input.labelText, finalConfig));
536
+ }
537
+ if (input.id) {
538
+ addAliases(extractWords(input.id));
539
+ }
540
+ if (input.name) {
541
+ addAliases(extractWords(input.name));
542
+ }
543
+ if (input.value && (input.elementType === "button" || input.inputType === "submit" || input.inputType === "button")) {
544
+ addAliases(generateTextAliases(input.value, finalConfig));
545
+ }
546
+ if (input.elementType) {
547
+ addAliases(generateTypeAliases(input.elementType));
548
+ }
549
+ if (input.inputType) {
550
+ addAlias(input.inputType);
551
+ if (input.inputType === "email") {
552
+ addAliases(["email", "e-mail", "email address"]);
553
+ } else if (input.inputType === "password") {
554
+ addAliases(["password", "pass", "pwd"]);
555
+ } else if (input.inputType === "tel") {
556
+ addAliases(["phone", "telephone", "mobile"]);
557
+ } else if (input.inputType === "url") {
558
+ addAliases(["url", "website", "link", "address"]);
559
+ } else if (input.inputType === "search") {
560
+ addAliases(["search", "find", "query"]);
561
+ }
562
+ }
563
+ if (finalConfig.includeSynonyms) {
564
+ const currentAliases = Array.from(aliasSet);
565
+ addAliases(generateSynonyms(currentAliases, finalConfig));
566
+ }
567
+ let aliases = Array.from(aliasSet);
568
+ aliases.sort((a, b) => a.length - b.length);
569
+ if (aliases.length > finalConfig.maxAliases) {
570
+ aliases = aliases.slice(0, finalConfig.maxAliases);
571
+ }
572
+ return aliases;
573
+ }
574
+ function generateDescription(input) {
575
+ const parts = [];
576
+ let name = input.ariaLabel || input.labelText || input.textContent || input.placeholder || input.title || input.id || input.name;
577
+ if (name) {
578
+ name = name.trim();
579
+ if (name.length > 30) {
580
+ name = name.substring(0, 27) + "...";
581
+ }
582
+ parts.push(`"${name}"`);
583
+ }
584
+ const typeWords = ELEMENT_ACTION_WORDS[input.elementType || ""] || [input.elementType || "element"];
585
+ parts.push(typeWords[0]);
586
+ if (input.inputType && input.inputType !== "text") {
587
+ parts.push(`(${input.inputType})`);
588
+ }
589
+ return parts.join(" ");
590
+ }
591
+
222
592
  // src/core/registry.ts
223
593
  function getElementState(element) {
224
594
  const rect = element.getBoundingClientRect();
@@ -417,9 +787,13 @@ var UIBridgeRegistry = class {
417
787
  registerElement(id, element, options = {}) {
418
788
  const type = options.type ?? inferElementType(element);
419
789
  const actions = options.actions ?? inferActions(type);
420
- element.setAttribute("data-ui-id", id);
790
+ const existingUiId = element.getAttribute("data-ui-id");
791
+ const actualId = existingUiId || id;
792
+ if (!existingUiId) {
793
+ element.setAttribute("data-ui-id", actualId);
794
+ }
421
795
  const registered = {
422
- id,
796
+ id: actualId,
423
797
  element,
424
798
  type,
425
799
  label: options.label,
@@ -430,8 +804,8 @@ var UIBridgeRegistry = class {
430
804
  registeredAt: Date.now(),
431
805
  mounted: true
432
806
  };
433
- this.elements.set(id, registered);
434
- this.emit("element:registered", { id, type, label: options.label });
807
+ this.elements.set(actualId, registered);
808
+ this.emit("element:registered", { id: actualId, type, label: options.label });
435
809
  return registered;
436
810
  }
437
811
  /**
@@ -471,6 +845,209 @@ var UIBridgeRegistry = class {
471
845
  }
472
846
  return void 0;
473
847
  }
848
+ /**
849
+ * Search for elements using AI search criteria
850
+ */
851
+ searchElements(criteria) {
852
+ const results = [];
853
+ const threshold = criteria.fuzzyThreshold ?? 0.7;
854
+ for (const element of this.elements.values()) {
855
+ if (!element.mounted) continue;
856
+ const state = element.getState();
857
+ if (!criteria.fuzzy && !state.visible) continue;
858
+ const aliases = element.aliases ?? this.generateElementAliases(element);
859
+ const textContent = state.textContent?.trim() || "";
860
+ const label = element.label || "";
861
+ let maxScore = 0;
862
+ const matchReasons = [];
863
+ const scores = {};
864
+ if (criteria.text) {
865
+ if (textContent.toLowerCase() === criteria.text.toLowerCase() || label.toLowerCase() === criteria.text.toLowerCase()) {
866
+ maxScore = 1;
867
+ matchReasons.push("exact text match");
868
+ scores.text = 1;
869
+ } else if (criteria.fuzzy !== false) {
870
+ const textResult = fuzzyMatch(criteria.text, textContent, { threshold });
871
+ const labelResult = fuzzyMatch(criteria.text, label, { threshold });
872
+ const bestResult = textResult.similarity > labelResult.similarity ? textResult : labelResult;
873
+ if (bestResult.isMatch) {
874
+ scores.text = bestResult.similarity;
875
+ if (bestResult.similarity > maxScore) {
876
+ maxScore = bestResult.similarity;
877
+ matchReasons.push(`text similarity: ${(bestResult.similarity * 100).toFixed(0)}%`);
878
+ }
879
+ }
880
+ }
881
+ }
882
+ if (criteria.textContains) {
883
+ if (textContent.toLowerCase().includes(criteria.textContains.toLowerCase()) || label.toLowerCase().includes(criteria.textContains.toLowerCase())) {
884
+ const containsScore = 0.85;
885
+ scores.text = Math.max(scores.text ?? 0, containsScore);
886
+ if (containsScore > maxScore) {
887
+ maxScore = containsScore;
888
+ matchReasons.push("text contains");
889
+ }
890
+ }
891
+ }
892
+ if (criteria.accessibleName) {
893
+ const ariaLabel = element.element.getAttribute("aria-label") || "";
894
+ const accessibleName = ariaLabel || label || textContent;
895
+ if (accessibleName.toLowerCase() === criteria.accessibleName.toLowerCase()) {
896
+ scores.accessibility = 1;
897
+ if (1 > maxScore) {
898
+ maxScore = 1;
899
+ matchReasons.push("accessible name match");
900
+ }
901
+ } else if (criteria.fuzzy !== false) {
902
+ const result = fuzzyMatch(criteria.accessibleName, accessibleName, { threshold });
903
+ if (result.isMatch) {
904
+ scores.accessibility = result.similarity;
905
+ if (result.similarity > maxScore) {
906
+ maxScore = result.similarity;
907
+ matchReasons.push(`accessible name similarity: ${(result.similarity * 100).toFixed(0)}%`);
908
+ }
909
+ }
910
+ }
911
+ }
912
+ if (criteria.role) {
913
+ const role = element.element.getAttribute("role") || this.inferRole(element.type);
914
+ if (role?.toLowerCase() === criteria.role.toLowerCase()) {
915
+ scores.role = 1;
916
+ if (1 > maxScore) {
917
+ maxScore = 1;
918
+ matchReasons.push(`role: ${criteria.role}`);
919
+ }
920
+ }
921
+ }
922
+ if (criteria.type) {
923
+ if (element.type === criteria.type) {
924
+ const typeScore = 0.9;
925
+ scores.role = Math.max(scores.role ?? 0, typeScore);
926
+ if (typeScore > maxScore) {
927
+ maxScore = typeScore;
928
+ matchReasons.push(`type: ${criteria.type}`);
929
+ }
930
+ }
931
+ }
932
+ for (const alias of aliases) {
933
+ const searchText = criteria.text || criteria.textContains || criteria.accessibleName;
934
+ if (searchText) {
935
+ if (alias.toLowerCase() === searchText.toLowerCase()) {
936
+ scores.fuzzy = 1;
937
+ if (1 > maxScore) {
938
+ maxScore = 1;
939
+ matchReasons.push(`alias: "${alias}"`);
940
+ }
941
+ } else if (criteria.fuzzy !== false) {
942
+ const result = fuzzyMatch(searchText, alias, { threshold });
943
+ if (result.isMatch && result.similarity > (scores.fuzzy ?? 0)) {
944
+ scores.fuzzy = result.similarity;
945
+ if (result.similarity > maxScore) {
946
+ maxScore = result.similarity;
947
+ matchReasons.push(`fuzzy alias: "${alias}"`);
948
+ }
949
+ }
950
+ }
951
+ }
952
+ }
953
+ if (maxScore >= threshold) {
954
+ const aiElement = {
955
+ id: element.id,
956
+ type: element.type,
957
+ label: element.label,
958
+ tagName: element.element.tagName.toLowerCase(),
959
+ role: element.element.getAttribute("role") || void 0,
960
+ accessibleName: element.element.getAttribute("aria-label") || element.label,
961
+ actions: element.actions,
962
+ state,
963
+ registered: true,
964
+ description: element.description || generateDescription({
965
+ textContent,
966
+ ariaLabel: element.element.getAttribute("aria-label"),
967
+ elementType: element.type,
968
+ id: element.id,
969
+ labelText: element.label
970
+ }),
971
+ aliases,
972
+ purpose: element.purpose,
973
+ suggestedActions: [],
974
+ semanticType: element.semanticType
975
+ };
976
+ results.push({
977
+ element: aiElement,
978
+ confidence: maxScore,
979
+ matchReasons,
980
+ scores
981
+ });
982
+ }
983
+ }
984
+ results.sort((a, b) => b.confidence - a.confidence);
985
+ return results;
986
+ }
987
+ /**
988
+ * Find element by visible text
989
+ */
990
+ findByText(text, fuzzy = true) {
991
+ const results = this.searchElements({ text, fuzzy, fuzzyThreshold: fuzzy ? 0.7 : 1 });
992
+ if (results.length > 0) {
993
+ return this.elements.get(results[0].element.id);
994
+ }
995
+ return void 0;
996
+ }
997
+ /**
998
+ * Find element by accessible name
999
+ */
1000
+ findByAccessibleName(name) {
1001
+ const results = this.searchElements({ accessibleName: name, fuzzy: true });
1002
+ if (results.length > 0) {
1003
+ return this.elements.get(results[0].element.id);
1004
+ }
1005
+ return void 0;
1006
+ }
1007
+ /**
1008
+ * Generate aliases for an element
1009
+ */
1010
+ generateElementAliases(element) {
1011
+ const state = element.getState();
1012
+ return generateAliases({
1013
+ textContent: state.textContent,
1014
+ ariaLabel: element.element.getAttribute("aria-label"),
1015
+ placeholder: element.element.getAttribute("placeholder"),
1016
+ title: element.element.getAttribute("title"),
1017
+ elementType: element.type,
1018
+ tagName: element.element.tagName.toLowerCase(),
1019
+ id: element.id,
1020
+ labelText: element.label
1021
+ });
1022
+ }
1023
+ /**
1024
+ * Infer ARIA role from element type
1025
+ */
1026
+ inferRole(type) {
1027
+ const roleMap = {
1028
+ button: "button",
1029
+ input: "textbox",
1030
+ select: "combobox",
1031
+ checkbox: "checkbox",
1032
+ radio: "radio",
1033
+ link: "link",
1034
+ form: void 0,
1035
+ textarea: "textbox",
1036
+ menu: "menu",
1037
+ menuitem: "menuitem",
1038
+ tab: "tab",
1039
+ dialog: "dialog",
1040
+ custom: void 0,
1041
+ switch: "switch",
1042
+ slider: "slider",
1043
+ combobox: "combobox",
1044
+ listbox: "listbox",
1045
+ option: "option",
1046
+ textbox: "textbox",
1047
+ generic: void 0
1048
+ };
1049
+ return roleMap[type];
1050
+ }
474
1051
  /**
475
1052
  * Register a component
476
1053
  */