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.
@@ -1 +1 @@
1
- {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAmJ,MAAM,aAAa,CAAC;AAC1L,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6FAA6F;IAC7F,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAKD,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAOxF;AAipBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,KAAK,CAAC,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC,EACzE,SAAS,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,IAAI,GACrD,YAAY,CAMd"}
1
+ {"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAmJ,MAAM,aAAa,CAAC;AAC1L,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,eAAe;IAC9B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,6FAA6F;IAC7F,aAAa,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAKD,iDAAiD;AACjD,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,IAAI,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,YAAY,GAAG,YAAY,CAOxF;AAspBD;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,SAAS,EAAE,OAAO,EAClB,MAAM,EAAE,KAAK,CAAC,gBAAgB,GAAG,mBAAmB,GAAG,iBAAiB,CAAC,EACzE,SAAS,EAAE,iBAAiB,GAAG,gBAAgB,GAAG,IAAI,GACrD,YAAY,CAMd"}
@@ -632,11 +632,12 @@ function buildSchema(form) {
632
632
  }
633
633
  return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
634
634
  }
635
+ var AUTO_GENERATED_ID_RE = /^_r_[0-9a-z]+_$|^:[a-z0-9]+:$/i;
635
636
  function resolveNativeControlFallbackKey(control) {
636
637
  const el = control;
637
638
  if (el.dataset["webmcpName"])
638
639
  return sanitizeName(el.dataset["webmcpName"]);
639
- if (control.id)
640
+ if (control.id && !AUTO_GENERATED_ID_RE.test(control.id))
640
641
  return sanitizeName(control.id);
641
642
  const label = control.getAttribute("aria-label");
642
643
  if (label)
@@ -1459,7 +1460,7 @@ async function registerForm(form, config) {
1459
1460
  registeredForms.add(form);
1460
1461
  registeredFormCount++;
1461
1462
  if (config.debug) {
1462
- console.debug(`[auto-webmcp] Registered: ${metadata.name}`, metadata);
1463
+ console.log(`[auto-webmcp] Registered: ${metadata.name}`, metadata);
1463
1464
  }
1464
1465
  emit("form:registered", form, metadata.name);
1465
1466
  }
@@ -1471,7 +1472,7 @@ async function unregisterForm(form, config) {
1471
1472
  await unregisterFormTool(form);
1472
1473
  registeredForms.delete(form);
1473
1474
  if (config.debug) {
1474
- console.debug(`[auto-webmcp] Unregistered: ${name}`);
1475
+ console.log(`[auto-webmcp] Unregistered: ${name}`);
1475
1476
  }
1476
1477
  emit("form:unregistered", form, name);
1477
1478
  }
@@ -1572,7 +1573,7 @@ async function scanOrphanInputs(config) {
1572
1573
  if (!isWebMCPSupported())
1573
1574
  return;
1574
1575
  const SUBMIT_BTN_SELECTOR = '[type="submit"]:not([disabled]), button:not([type]):not([disabled])';
1575
- const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"], button:not([type])';
1576
+ const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"]';
1576
1577
  const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search/i;
1577
1578
  const orphanInputs = Array.from(
1578
1579
  document.querySelectorAll(
@@ -1580,11 +1581,17 @@ async function scanOrphanInputs(config) {
1580
1581
  )
1581
1582
  ).filter((el) => {
1582
1583
  if (el instanceof HTMLInputElement && ORPHAN_EXCLUDED_TYPES.has(el.type.toLowerCase())) {
1584
+ console.log(`[auto-webmcp] orphan: skipping excluded type "${el.type}" (name="${el.name}" id="${el.id}")`);
1583
1585
  return false;
1584
1586
  }
1585
1587
  const rect = el.getBoundingClientRect();
1586
- return rect.width > 0 && rect.height > 0;
1588
+ if (rect.width === 0 || rect.height === 0) {
1589
+ console.log(`[auto-webmcp] orphan: skipping invisible input (name="${el.name}" id="${el.id}")`);
1590
+ return false;
1591
+ }
1592
+ return true;
1587
1593
  });
1594
+ console.log(`[auto-webmcp] orphan: found ${orphanInputs.length} visible orphan input(s)`);
1588
1595
  if (orphanInputs.length === 0)
1589
1596
  return;
1590
1597
  const groups = /* @__PURE__ */ new Map();
@@ -1601,10 +1608,12 @@ async function scanOrphanInputs(config) {
1601
1608
  }
1602
1609
  container = container.parentElement;
1603
1610
  }
1611
+ console.log(`[auto-webmcp] orphan: input (name="${input.name}" id="${input.id}") grouped into container`, foundContainer);
1604
1612
  if (!groups.has(foundContainer))
1605
1613
  groups.set(foundContainer, []);
1606
1614
  groups.get(foundContainer).push(input);
1607
1615
  }
1616
+ console.log(`[auto-webmcp] orphan: ${groups.size} group(s) found`);
1608
1617
  for (const [container, inputs] of groups) {
1609
1618
  const allCandidates = Array.from(
1610
1619
  container.querySelectorAll(SUBMIT_BTN_SELECTOR)
@@ -1613,6 +1622,12 @@ async function scanOrphanInputs(config) {
1613
1622
  return r.width > 0 && r.height > 0;
1614
1623
  });
1615
1624
  let submitBtn = allCandidates[allCandidates.length - 1] ?? null;
1625
+ const disabledCandidates = Array.from(
1626
+ container.querySelectorAll(SUBMIT_BTN_GROUPING_SELECTOR)
1627
+ ).filter((b) => b.disabled);
1628
+ if (!submitBtn && disabledCandidates.length > 0) {
1629
+ 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()));
1630
+ }
1616
1631
  if (!submitBtn) {
1617
1632
  const pageBtns = Array.from(document.querySelectorAll("button")).filter(
1618
1633
  (b) => {
@@ -1621,28 +1636,45 @@ async function scanOrphanInputs(config) {
1621
1636
  }
1622
1637
  );
1623
1638
  submitBtn = pageBtns[pageBtns.length - 1] ?? null;
1639
+ if (submitBtn)
1640
+ console.log(`[auto-webmcp] orphan: using page-wide fallback submit button: "${submitBtn.textContent?.trim()}"`);
1624
1641
  }
1642
+ console.log(`[auto-webmcp] orphan: submit button for group:`, submitBtn ? `"${submitBtn.textContent?.trim()}" disabled=${submitBtn.disabled}` : "none");
1625
1643
  const metadata = analyzeOrphanInputGroup(container, inputs, submitBtn);
1644
+ console.log(`[auto-webmcp] orphan: tool="${metadata.name}" schema keys:`, Object.keys(metadata.inputSchema.properties));
1626
1645
  const inputPairs = [];
1627
1646
  const schemaProps = metadata.inputSchema.properties;
1647
+ const AUTO_ID_RE = /^_r_[0-9a-z]+_$/i;
1628
1648
  for (const el of inputs) {
1629
- const key = el.name || el.dataset["webmcpName"] || el.id || el.getAttribute("aria-label") || null;
1649
+ const id = el.id && !AUTO_ID_RE.test(el.id) ? el.id : null;
1650
+ const key = el.name || el.dataset["webmcpName"] || id || el.getAttribute("aria-label") || (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement ? el.placeholder || null : null) || null;
1630
1651
  const safeKey = key ? key.toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "").slice(0, 64) : null;
1631
- if (safeKey && schemaProps[safeKey]) {
1652
+ const matched = !!(safeKey && schemaProps[safeKey]);
1653
+ console.log(`[auto-webmcp] orphan: field (name="${el.name}" id="${el.id}") rawKey="${key}" safeKey="${safeKey}" matched=${matched}`);
1654
+ if (matched) {
1632
1655
  inputPairs.push({ key: safeKey, el });
1633
1656
  }
1634
1657
  }
1658
+ console.log(`[auto-webmcp] orphan: ${inputPairs.length}/${inputs.length} input(s) mapped to schema keys`);
1635
1659
  const toolName = metadata.name;
1636
1660
  const execute = async (params) => {
1661
+ console.log(`[auto-webmcp] orphan execute: tool="${toolName}" params=`, params);
1662
+ console.log(`[auto-webmcp] orphan execute: inputPairs=`, inputPairs.map((p) => p.key));
1637
1663
  for (const { key, el } of inputPairs) {
1638
1664
  if (params[key] !== void 0) {
1665
+ console.log(`[auto-webmcp] orphan execute: filling key="${key}" value=`, params[key], "element=", el);
1639
1666
  fillElement(el, params[key]);
1667
+ console.log(`[auto-webmcp] orphan execute: after fill, element value=`, el.value);
1668
+ } else {
1669
+ console.log(`[auto-webmcp] orphan execute: key="${key}" not in params, skipping`);
1640
1670
  }
1641
1671
  }
1642
1672
  window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
1643
1673
  if (!config.autoSubmit) {
1674
+ console.log(`[auto-webmcp] orphan execute: autoSubmit=false, returning without clicking submit`);
1644
1675
  return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
1645
1676
  }
1677
+ console.log(`[auto-webmcp] orphan execute: polling for enabled submit button (up to 2s)...`);
1646
1678
  let btn = null;
1647
1679
  const deadline = Date.now() + 2e3;
1648
1680
  while (Date.now() < deadline) {
@@ -1660,8 +1692,10 @@ async function scanOrphanInputs(config) {
1660
1692
  await new Promise((r) => setTimeout(r, 100));
1661
1693
  }
1662
1694
  if (!btn) {
1695
+ console.warn(`[auto-webmcp] orphan execute: submit button still disabled after 2s`);
1663
1696
  return { content: [{ type: "text", text: "Fields filled but the submit button is still disabled. The page may require additional input before submitting." }] };
1664
1697
  }
1698
+ console.log(`[auto-webmcp] orphan execute: clicking submit button "${btn.textContent?.trim()}"`);
1665
1699
  btn.click();
1666
1700
  return { content: [{ type: "text", text: "Fields filled and form submitted." }] };
1667
1701
  };
@@ -1677,7 +1711,7 @@ async function scanOrphanInputs(config) {
1677
1711
  }
1678
1712
  await navigator.modelContext.registerTool(toolDef);
1679
1713
  if (config.debug) {
1680
- console.debug(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
1714
+ console.log(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
1681
1715
  }
1682
1716
  } catch {
1683
1717
  }