auto-webmcp 0.3.5 → 0.3.7
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 +55 -10
- package/dist/auto-webmcp.cjs.js.map +2 -2
- package/dist/auto-webmcp.esm.js +55 -10
- 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/dist/schema.d.ts +1 -0
- package/dist/schema.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auto-webmcp.esm.js
CHANGED
|
@@ -611,7 +611,7 @@ function buildSchema(form) {
|
|
|
611
611
|
required.push(key);
|
|
612
612
|
}
|
|
613
613
|
}
|
|
614
|
-
return { schema: { type: "object", properties, required }, fieldElements };
|
|
614
|
+
return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
|
|
615
615
|
}
|
|
616
616
|
function resolveNativeControlFallbackKey(control) {
|
|
617
617
|
const el = control;
|
|
@@ -816,7 +816,24 @@ function analyzeOrphanInputGroup(container, inputs, submitBtn) {
|
|
|
816
816
|
const name = inferOrphanToolName(container, submitBtn);
|
|
817
817
|
const description = inferOrphanToolDescription(container);
|
|
818
818
|
const { schema: inputSchema, fieldElements } = buildSchemaFromInputs(inputs);
|
|
819
|
-
|
|
819
|
+
const annotations = inferOrphanAnnotations(submitBtn);
|
|
820
|
+
return { name, description, inputSchema, annotations, fieldElements };
|
|
821
|
+
}
|
|
822
|
+
function inferOrphanAnnotations(submitBtn) {
|
|
823
|
+
const annotations = {};
|
|
824
|
+
const submitText = submitBtn instanceof HTMLInputElement ? submitBtn.value.trim() : submitBtn?.textContent?.trim() ?? "";
|
|
825
|
+
if (READONLY_BUTTON_PATTERNS.test(submitText)) {
|
|
826
|
+
annotations.readOnlyHint = true;
|
|
827
|
+
annotations.idempotentHint = true;
|
|
828
|
+
}
|
|
829
|
+
if (DESTRUCTIVE_BUTTON_PATTERNS.test(submitText)) {
|
|
830
|
+
annotations.destructiveHint = true;
|
|
831
|
+
}
|
|
832
|
+
if (annotations.readOnlyHint !== true) {
|
|
833
|
+
annotations.openWorldHint = true;
|
|
834
|
+
}
|
|
835
|
+
const hasNonDefault = annotations.readOnlyHint === true || annotations.destructiveHint === true || annotations.idempotentHint === true || annotations.openWorldHint === false;
|
|
836
|
+
return hasNonDefault ? annotations : {};
|
|
820
837
|
}
|
|
821
838
|
function inferOrphanToolName(container, submitBtn) {
|
|
822
839
|
if (submitBtn) {
|
|
@@ -871,8 +888,8 @@ function buildSchemaFromInputs(inputs) {
|
|
|
871
888
|
const processedRadioGroups = /* @__PURE__ */ new Set();
|
|
872
889
|
const processedCheckboxGroups = /* @__PURE__ */ new Set();
|
|
873
890
|
for (const control of inputs) {
|
|
874
|
-
const
|
|
875
|
-
const fieldKey =
|
|
891
|
+
const rawName = control.name;
|
|
892
|
+
const fieldKey = (rawName ? sanitizeName(rawName) : null) || resolveNativeControlFallbackKey(control);
|
|
876
893
|
if (!fieldKey)
|
|
877
894
|
continue;
|
|
878
895
|
if (control instanceof HTMLInputElement && control.type === "radio") {
|
|
@@ -911,12 +928,12 @@ function buildSchemaFromInputs(inputs) {
|
|
|
911
928
|
}
|
|
912
929
|
}
|
|
913
930
|
properties[fieldKey] = schemaProp;
|
|
914
|
-
if (!
|
|
931
|
+
if (!rawName)
|
|
915
932
|
fieldElements.set(fieldKey, control);
|
|
916
933
|
if (control.required)
|
|
917
934
|
required.push(fieldKey);
|
|
918
935
|
}
|
|
919
|
-
return { schema: { type: "object", properties, required }, fieldElements };
|
|
936
|
+
return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
|
|
920
937
|
}
|
|
921
938
|
|
|
922
939
|
// src/discovery.ts
|
|
@@ -1536,6 +1553,7 @@ async function scanOrphanInputs(config) {
|
|
|
1536
1553
|
if (!isWebMCPSupported())
|
|
1537
1554
|
return;
|
|
1538
1555
|
const SUBMIT_BTN_SELECTOR = '[type="submit"]:not([disabled]), button:not([type]):not([disabled])';
|
|
1556
|
+
const SUBMIT_BTN_GROUPING_SELECTOR = '[type="submit"], button:not([type])';
|
|
1539
1557
|
const SUBMIT_TEXT_RE = /subscribe|submit|sign[\s-]?up|send|join|go|search/i;
|
|
1540
1558
|
const orphanInputs = Array.from(
|
|
1541
1559
|
document.querySelectorAll(
|
|
@@ -1555,7 +1573,7 @@ async function scanOrphanInputs(config) {
|
|
|
1555
1573
|
let container = input.parentElement;
|
|
1556
1574
|
let foundContainer = input.parentElement ?? document.body;
|
|
1557
1575
|
while (container && container !== document.body) {
|
|
1558
|
-
const hasSubmitBtn = container.querySelector(
|
|
1576
|
+
const hasSubmitBtn = container.querySelector(SUBMIT_BTN_GROUPING_SELECTOR) !== null || Array.from(container.querySelectorAll("button")).some(
|
|
1559
1577
|
(b) => SUBMIT_TEXT_RE.test(b.textContent ?? "")
|
|
1560
1578
|
);
|
|
1561
1579
|
if (hasSubmitBtn) {
|
|
@@ -1603,15 +1621,42 @@ async function scanOrphanInputs(config) {
|
|
|
1603
1621
|
}
|
|
1604
1622
|
}
|
|
1605
1623
|
window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
|
|
1606
|
-
|
|
1624
|
+
if (!config.autoSubmit) {
|
|
1625
|
+
return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
|
|
1626
|
+
}
|
|
1627
|
+
let btn = null;
|
|
1628
|
+
const deadline = Date.now() + 2e3;
|
|
1629
|
+
while (Date.now() < deadline) {
|
|
1630
|
+
const candidates = Array.from(
|
|
1631
|
+
container.querySelectorAll(SUBMIT_BTN_SELECTOR)
|
|
1632
|
+
).filter((b) => {
|
|
1633
|
+
const r = b.getBoundingClientRect();
|
|
1634
|
+
return r.width > 0 && r.height > 0;
|
|
1635
|
+
});
|
|
1636
|
+
const last = candidates[candidates.length - 1] ?? null;
|
|
1637
|
+
if (last) {
|
|
1638
|
+
btn = last;
|
|
1639
|
+
break;
|
|
1640
|
+
}
|
|
1641
|
+
await new Promise((r) => setTimeout(r, 100));
|
|
1642
|
+
}
|
|
1643
|
+
if (!btn) {
|
|
1644
|
+
return { content: [{ type: "text", text: "Fields filled but the submit button is still disabled. The page may require additional input before submitting." }] };
|
|
1645
|
+
}
|
|
1646
|
+
btn.click();
|
|
1647
|
+
return { content: [{ type: "text", text: "Fields filled and form submitted." }] };
|
|
1607
1648
|
};
|
|
1608
1649
|
try {
|
|
1609
|
-
|
|
1650
|
+
const toolDef = {
|
|
1610
1651
|
name: metadata.name,
|
|
1611
1652
|
description: metadata.description,
|
|
1612
1653
|
inputSchema: metadata.inputSchema,
|
|
1613
1654
|
execute
|
|
1614
|
-
}
|
|
1655
|
+
};
|
|
1656
|
+
if (metadata.annotations && Object.keys(metadata.annotations).length > 0) {
|
|
1657
|
+
toolDef.annotations = metadata.annotations;
|
|
1658
|
+
}
|
|
1659
|
+
await navigator.modelContext.registerTool(toolDef);
|
|
1615
1660
|
if (config.debug) {
|
|
1616
1661
|
console.debug(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
|
|
1617
1662
|
}
|