auto-webmcp 0.3.18 → 0.3.19

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.
@@ -2051,6 +2051,8 @@ var reAnalysisTimers = /* @__PURE__ */ new Map();
2051
2051
  var RE_ANALYSIS_DEBOUNCE_MS = 300;
2052
2052
  var orphanRescanTimer = null;
2053
2053
  var ORPHAN_RESCAN_DEBOUNCE_MS = 500;
2054
+ var orphanRescanDelayedTimer = null;
2055
+ var ORPHAN_RESCAN_DELAYED_MS = 2e3;
2054
2056
  var registeredOrphanToolNames = /* @__PURE__ */ new Set();
2055
2057
  function scheduleOrphanRescan(config) {
2056
2058
  if (orphanRescanTimer)
@@ -2060,10 +2062,20 @@ function scheduleOrphanRescan(config) {
2060
2062
  void scanOrphanInputs(config);
2061
2063
  }, ORPHAN_RESCAN_DEBOUNCE_MS);
2062
2064
  }
2065
+ function scheduleOrphanRescanDelayed(config) {
2066
+ if (orphanRescanDelayedTimer)
2067
+ clearTimeout(orphanRescanDelayedTimer);
2068
+ orphanRescanDelayedTimer = setTimeout(() => {
2069
+ orphanRescanDelayedTimer = null;
2070
+ void scanOrphanInputs(config);
2071
+ }, ORPHAN_RESCAN_DELAYED_MS);
2072
+ }
2063
2073
  function isInterestingNode(node) {
2064
2074
  const tag = node.tagName.toLowerCase();
2065
2075
  if (tag === "input" || tag === "textarea" || tag === "select")
2066
2076
  return true;
2077
+ if (tag.includes("-"))
2078
+ return true;
2067
2079
  const role = node.getAttribute("role");
2068
2080
  if (role && ARIA_ROLES_TO_SCAN.includes(role))
2069
2081
  return true;
@@ -2144,6 +2156,9 @@ function startObserver(config) {
2144
2156
  }
2145
2157
  if (isInterestingNode(node) && !node.closest("form")) {
2146
2158
  scheduleOrphanRescan(config);
2159
+ if (node.tagName.toLowerCase().includes("-")) {
2160
+ scheduleOrphanRescanDelayed(config);
2161
+ }
2147
2162
  }
2148
2163
  }
2149
2164
  for (const node of mutation.removedNodes) {
@@ -2192,6 +2207,35 @@ var ORPHAN_EXCLUDED_TYPES = /* @__PURE__ */ new Set([
2192
2207
  "button",
2193
2208
  "image"
2194
2209
  ]);
2210
+ function collectShadowOrphanInputs(root, outerHost, visited = /* @__PURE__ */ new Set()) {
2211
+ if (visited.has(root))
2212
+ return [];
2213
+ visited.add(root);
2214
+ const results = [];
2215
+ for (const el of Array.from(root.querySelectorAll("*"))) {
2216
+ const sr = el.shadowRoot;
2217
+ if (!sr)
2218
+ continue;
2219
+ const host = outerHost ?? el;
2220
+ results.push(...collectShadowOrphanInputs(sr, host, visited));
2221
+ }
2222
+ if (root instanceof ShadowRoot) {
2223
+ const selector = 'input, textarea, select, [role="textbox"]:not(input):not(textarea), [role="searchbox"]:not(input):not(textarea), button[role="combobox"]';
2224
+ for (const el of Array.from(root.querySelectorAll(selector))) {
2225
+ if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase()))
2226
+ continue;
2227
+ if (el.closest("form"))
2228
+ continue;
2229
+ const rect = el.getBoundingClientRect();
2230
+ if (rect.width === 0 || rect.height === 0)
2231
+ continue;
2232
+ if (outerHost) {
2233
+ results.push({ el, shadowHost: outerHost });
2234
+ }
2235
+ }
2236
+ }
2237
+ return results;
2238
+ }
2195
2239
  async function scanOrphanInputs(config) {
2196
2240
  if (!isWebMCPSupported())
2197
2241
  return;
@@ -2214,8 +2258,9 @@ async function scanOrphanInputs(config) {
2214
2258
  }
2215
2259
  return true;
2216
2260
  });
2217
- console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} visible orphan input(s)`);
2218
- if (orphanInputs.length === 0)
2261
+ const shadowOrphans = collectShadowOrphanInputs(document.body, null);
2262
+ console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} light-DOM + ${shadowOrphans.length} shadow-DOM orphan inputs`);
2263
+ if (orphanInputs.length === 0 && shadowOrphans.length === 0)
2219
2264
  return;
2220
2265
  const groups = /* @__PURE__ */ new Map();
2221
2266
  for (const input of orphanInputs) {
@@ -2236,6 +2281,24 @@ async function scanOrphanInputs(config) {
2236
2281
  groups.set(foundContainer, []);
2237
2282
  groups.get(foundContainer).push(input);
2238
2283
  }
2284
+ for (const { el, shadowHost } of shadowOrphans) {
2285
+ let container = shadowHost.parentElement;
2286
+ let foundContainer = shadowHost.parentElement ?? document.body;
2287
+ while (container && container !== document.body) {
2288
+ const hasSubmitBtn = container.querySelector(SUBMIT_BTN_GROUPING_SELECTOR) !== null || Array.from(container.querySelectorAll("button")).some(
2289
+ (b) => SUBMIT_TEXT_RE.test(b.textContent ?? "")
2290
+ );
2291
+ if (hasSubmitBtn) {
2292
+ foundContainer = container;
2293
+ break;
2294
+ }
2295
+ container = container.parentElement;
2296
+ }
2297
+ console.log(`[auto-webmcp] orphan (shadow): input (id="${el.id}") via host <${shadowHost.tagName.toLowerCase()}> grouped into container`, foundContainer);
2298
+ if (!groups.has(foundContainer))
2299
+ groups.set(foundContainer, []);
2300
+ groups.get(foundContainer).push(el);
2301
+ }
2239
2302
  console.log(`[auto-webmcp] orphan: ${groups.size} group(s) found`);
2240
2303
  for (const [container, inputs] of groups) {
2241
2304
  const allCandidates = Array.from(