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.
- package/dist/analyzer.d.ts.map +1 -1
- package/dist/auto-webmcp.cjs.js +42 -8
- package/dist/auto-webmcp.cjs.js.map +2 -2
- package/dist/auto-webmcp.esm.js +42 -8
- package/dist/auto-webmcp.esm.js.map +2 -2
- package/dist/auto-webmcp.iife.js +1 -1
- package/dist/auto-webmcp.iife.js.map +3 -3
- package/dist/discovery.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auto-webmcp.esm.js
CHANGED
|
@@ -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.
|
|
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.
|
|
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"]
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
1695
|
+
console.log(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
|
|
1662
1696
|
}
|
|
1663
1697
|
} catch {
|
|
1664
1698
|
}
|