auto-webmcp 0.3.7 → 0.3.8

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.
@@ -613,11 +613,12 @@ function buildSchema(form) {
613
613
  }
614
614
  return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
615
615
  }
616
+ var AUTO_GENERATED_ID_RE = /^_r_[0-9a-z]+_$|^:[a-z0-9]+:$/i;
616
617
  function resolveNativeControlFallbackKey(control) {
617
618
  const el = control;
618
619
  if (el.dataset["webmcpName"])
619
620
  return sanitizeName(el.dataset["webmcpName"]);
620
- if (control.id)
621
+ if (control.id && !AUTO_GENERATED_ID_RE.test(control.id))
621
622
  return sanitizeName(control.id);
622
623
  const label = control.getAttribute("aria-label");
623
624
  if (label)
@@ -1440,7 +1441,7 @@ async function registerForm(form, config) {
1440
1441
  registeredForms.add(form);
1441
1442
  registeredFormCount++;
1442
1443
  if (config.debug) {
1443
- console.debug(`[auto-webmcp] Registered: ${metadata.name}`, metadata);
1444
+ console.log(`[auto-webmcp] Registered: ${metadata.name}`, metadata);
1444
1445
  }
1445
1446
  emit("form:registered", form, metadata.name);
1446
1447
  }
@@ -1452,7 +1453,7 @@ async function unregisterForm(form, config) {
1452
1453
  await unregisterFormTool(form);
1453
1454
  registeredForms.delete(form);
1454
1455
  if (config.debug) {
1455
- console.debug(`[auto-webmcp] Unregistered: ${name}`);
1456
+ console.log(`[auto-webmcp] Unregistered: ${name}`);
1456
1457
  }
1457
1458
  emit("form:unregistered", form, name);
1458
1459
  }
@@ -1553,7 +1554,7 @@ async function scanOrphanInputs(config) {
1553
1554
  if (!isWebMCPSupported())
1554
1555
  return;
1555
1556
  const SUBMIT_BTN_SELECTOR = '[type="submit"]:not([disabled]), button:not([type]):not([disabled])';
1556
- const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"], button:not([type])';
1557
+ const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"]';
1557
1558
  const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search/i;
1558
1559
  const orphanInputs = Array.from(
1559
1560
  document.querySelectorAll(
@@ -1561,11 +1562,17 @@ async function scanOrphanInputs(config) {
1561
1562
  )
1562
1563
  ).filter((el) => {
1563
1564
  if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase())) {
1565
+ console.log(`[auto-webmcp] orphan: skipping excluded type "${el.type}" (name="${el.name}" id="${el.id}")`);
1564
1566
  return false;
1565
1567
  }
1566
1568
  const rect = el.getBoundingClientRect();
1567
- return rect.width > 0 && rect.height > 0;
1569
+ if (rect.width === 0 || rect.height === 0) {
1570
+ console.log(`[auto-webmcp] orphan: skipping invisible input (name="${el.name}" id="${el.id}")`);
1571
+ return false;
1572
+ }
1573
+ return true;
1568
1574
  });
1575
+ console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} visible orphan input(s)`);
1569
1576
  if (orphanInputs.length === 0)
1570
1577
  return;
1571
1578
  const groups = /* @__PURE__ */ new Map();
@@ -1582,10 +1589,12 @@ async function scanOrphanInputs(config) {
1582
1589
  }
1583
1590
  container = container.parentElement;
1584
1591
  }
1592
+ console.log(`[auto-webmcp] orphan: input (name="${input.name}" id="${input.id}") grouped into container`, foundContainer);
1585
1593
  if (!groups.has(foundContainer))
1586
1594
  groups.set(foundContainer, []);
1587
1595
  groups.get(foundContainer).push(input);
1588
1596
  }
1597
+ console.log(`[auto-webmcp] orphan: ${groups.size} group(s) found`);
1589
1598
  for (const [container, inputs] of groups) {
1590
1599
  const allCandidates = Array.from(
1591
1600
  container.querySelectorAll(SUBMIT_BTN_SELECTOR)
@@ -1594,6 +1603,12 @@ async function scanOrphanInputs(config) {
1594
1603
  return r.width > 0 && r.height > 0;
1595
1604
  });
1596
1605
  let submitBtn = allCandidates[allCandidates.length - 1] ?? null;
1606
+ const disabledCandidates = Array.from(
1607
+ container.querySelectorAll(SUBMIT_BTN_GROUPING_SELECTOR)
1608
+ ).filter((b) => b.disabled);
1609
+ if (!submitBtn && disabledCandidates.length > 0) {
1610
+ console.log(`[auto-webmcp] orphan: no enabled submit button found in container \u2014 ${disabledCandidates.length} disabled button(s) present:`, disabledCandidates.map((b) => b.textContent?.trim()));
1611
+ }
1597
1612
  if (!submitBtn) {
1598
1613
  const pageBtns = Array.from(document.querySelectorAll("button")).filter(
1599
1614
  (b) => {
@@ -1602,28 +1617,45 @@ async function scanOrphanInputs(config) {
1602
1617
  }
1603
1618
  );
1604
1619
  submitBtn = pageBtns[pageBtns.length - 1] ?? null;
1620
+ if (submitBtn)
1621
+ console.log(`[auto-webmcp] orphan: using page-wide fallback submit button: "${submitBtn.textContent?.trim()}"`);
1605
1622
  }
1623
+ console.log(`[auto-webmcp] orphan: submit button for group:`, submitBtn ? `"${submitBtn.textContent?.trim()}" disabled=${submitBtn.disabled}` : "none");
1606
1624
  const metadata = analyzeOrphanInputGroup(container, inputs, submitBtn);
1625
+ console.log(`[auto-webmcp] orphan: tool="${metadata.name}" schema keys:`, Object.keys(metadata.inputSchema.properties));
1607
1626
  const inputPairs = [];
1608
1627
  const schemaProps = metadata.inputSchema.properties;
1628
+ const AUTO_ID_RE = /^_r_[0-9a-z]+_$/i;
1609
1629
  for (const el of inputs) {
1610
- const key = el.name || el.dataset["webmcpName"] || el.id || el.getAttribute("aria-label") || null;
1630
+ const id = el.id && !AUTO_ID_RE.test(el.id) ? el.id : null;
1631
+ const key = el.name || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") || (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement ? el.placeholder || null : null) || null;
1611
1632
  const safeKey = key ? key.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) : null;
1612
- if (safeKey && schemaProps[safeKey]) {
1633
+ const matched = !!(safeKey && schemaProps[safeKey]);
1634
+ console.log(`[auto-webmcp] orphan: field (name="${el.name}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
1635
+ if (matched) {
1613
1636
  inputPairs.push({ key: safeKey, el });
1614
1637
  }
1615
1638
  }
1639
+ console.log(`[auto-webmcp] orphan: ${inputPairs.length}/${inputs.length} input(s) mapped to schema keys`);
1616
1640
  const toolName = metadata.name;
1617
1641
  const execute = async (params) => {
1642
+ console.log(`[auto-webmcp] orphan execute: tool="${toolName}" params=`, params);
1643
+ console.log(`[auto-webmcp] orphan execute: inputPairs=`, inputPairs.map((p) => p.key));
1618
1644
  for (const { key, el } of inputPairs) {
1619
1645
  if (params[key] !== void 0) {
1646
+ console.log(`[auto-webmcp] orphan execute: filling key="${key}" value=`, params[key], "element=", el);
1620
1647
  fillElement(el, params[key]);
1648
+ console.log(`[auto-webmcp] orphan execute: after fill, element value=`, el.value);
1649
+ } else {
1650
+ console.log(`[auto-webmcp] orphan execute: key="${key}" not in params, skipping`);
1621
1651
  }
1622
1652
  }
1623
1653
  window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
1624
1654
  if (!config.autoSubmit) {
1655
+ console.log(`[auto-webmcp] orphan execute: autoSubmit=false, returning without clicking submit`);
1625
1656
  return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
1626
1657
  }
1658
+ console.log(`[auto-webmcp] orphan execute: polling for enabled submit button (up to 2s)...`);
1627
1659
  let btn = null;
1628
1660
  const deadline = Date.now() + 2e3;
1629
1661
  while (Date.now() < deadline) {
@@ -1641,8 +1673,10 @@ async function scanOrphanInputs(config) {
1641
1673
  await new Promise((r) => setTimeout(r, 100));
1642
1674
  }
1643
1675
  if (!btn) {
1676
+ console.warn(`[auto-webmcp] orphan execute: submit button still disabled after 2s`);
1644
1677
  return { content: [{ type: "text", text: "Fields filled but the submit button is still disabled. The page may require additional input before submitting." }] };
1645
1678
  }
1679
+ console.log(`[auto-webmcp] orphan execute: clicking submit button "${btn.textContent?.trim()}"`);
1646
1680
  btn.click();
1647
1681
  return { content: [{ type: "text", text: "Fields filled and form submitted." }] };
1648
1682
  };
@@ -1658,7 +1692,7 @@ async function scanOrphanInputs(config) {
1658
1692
  }
1659
1693
  await navigator.modelContext.registerTool(toolDef);
1660
1694
  if (config.debug) {
1661
- console.debug(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
1695
+ console.log(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
1662
1696
  }
1663
1697
  } catch {
1664
1698
  }