auto-webmcp 0.2.5 → 0.2.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 +87 -16
- package/dist/auto-webmcp.cjs.js.map +3 -3
- package/dist/auto-webmcp.esm.js +87 -16
- package/dist/auto-webmcp.esm.js.map +3 -3
- package/dist/auto-webmcp.iife.js +2 -2
- package/dist/auto-webmcp.iife.js.map +3 -3
- package/dist/interceptor.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/analyzer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAA8H,MAAM,aAAa,CAAC;AACrK,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,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,CAMxF;
|
|
1
|
+
{"version":3,"file":"analyzer.d.ts","sourceRoot":"","sources":["../src/analyzer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAA8H,MAAM,aAAa,CAAC;AACrK,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,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,CAMxF;AAkaD;;;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,CAKd"}
|
package/dist/auto-webmcp.cjs.js
CHANGED
|
@@ -192,7 +192,7 @@ function buildStringSchema(input) {
|
|
|
192
192
|
return prop;
|
|
193
193
|
}
|
|
194
194
|
function mapSelectElement(select) {
|
|
195
|
-
const filtered = Array.from(select.options).filter((o) => o.value !== "");
|
|
195
|
+
const filtered = Array.from(select.options).filter((o) => o.value !== "" && !o.disabled);
|
|
196
196
|
if (filtered.length === 0) {
|
|
197
197
|
return { type: "string" };
|
|
198
198
|
}
|
|
@@ -454,6 +454,12 @@ function resolveNativeControlFallbackKey(control) {
|
|
|
454
454
|
const label = control.getAttribute("aria-label");
|
|
455
455
|
if (label)
|
|
456
456
|
return sanitizeName(label);
|
|
457
|
+
if ((control instanceof HTMLInputElement || control instanceof HTMLTextAreaElement) && control.placeholder?.trim()) {
|
|
458
|
+
return sanitizeName(control.placeholder.trim());
|
|
459
|
+
}
|
|
460
|
+
if (control instanceof HTMLInputElement && control.type !== "text") {
|
|
461
|
+
return control.type;
|
|
462
|
+
}
|
|
457
463
|
return null;
|
|
458
464
|
}
|
|
459
465
|
function collectAriaControls(form) {
|
|
@@ -538,6 +544,9 @@ function inferFieldTitle(control) {
|
|
|
538
544
|
return humanizeName(control.name);
|
|
539
545
|
if (control.id)
|
|
540
546
|
return humanizeName(control.id);
|
|
547
|
+
if ((control instanceof HTMLInputElement || control instanceof HTMLTextAreaElement) && control.placeholder?.trim()) {
|
|
548
|
+
return control.placeholder.trim();
|
|
549
|
+
}
|
|
541
550
|
return "";
|
|
542
551
|
}
|
|
543
552
|
function inferFieldDescription(control) {
|
|
@@ -678,6 +687,7 @@ init_registry();
|
|
|
678
687
|
var pendingExecutions = /* @__PURE__ */ new WeakMap();
|
|
679
688
|
var lastParams = /* @__PURE__ */ new WeakMap();
|
|
680
689
|
var formFieldElements = /* @__PURE__ */ new WeakMap();
|
|
690
|
+
var pendingWarnings = /* @__PURE__ */ new WeakMap();
|
|
681
691
|
var _inputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
682
692
|
var _textareaValueSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, "value")?.set;
|
|
683
693
|
var _checkedSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "checked")?.set;
|
|
@@ -692,22 +702,36 @@ function buildExecuteHandler(form, config, toolName, metadata) {
|
|
|
692
702
|
return new Promise((resolve, reject) => {
|
|
693
703
|
pendingExecutions.set(form, { resolve, reject });
|
|
694
704
|
if (config.autoSubmit || form.hasAttribute("toolautosubmit") || form.dataset["webmcpAutosubmit"] !== void 0) {
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
705
|
+
waitForDomStable(form).then(async () => {
|
|
706
|
+
try {
|
|
707
|
+
fillFormFields(form, params);
|
|
708
|
+
for (let attempt = 0; attempt < 2; attempt++) {
|
|
709
|
+
const reset = getResetFields(form, params, formFieldElements.get(form));
|
|
710
|
+
if (reset.length === 0)
|
|
711
|
+
break;
|
|
712
|
+
fillFormFields(form, params);
|
|
713
|
+
await waitForDomStable(form, 400, 100);
|
|
714
|
+
}
|
|
715
|
+
let submitForm = form;
|
|
716
|
+
if (!form.isConnected) {
|
|
717
|
+
const liveBtn = document.querySelector(
|
|
718
|
+
'button[type="submit"]:not([disabled]), input[type="submit"]:not([disabled])'
|
|
719
|
+
);
|
|
720
|
+
const found = liveBtn?.closest("form");
|
|
721
|
+
if (found) {
|
|
722
|
+
submitForm = found;
|
|
723
|
+
pendingExecutions.set(submitForm, { resolve, reject });
|
|
724
|
+
attachSubmitInterceptor(submitForm, toolName);
|
|
725
|
+
}
|
|
707
726
|
}
|
|
727
|
+
const missing = getMissingRequired(metadata, params);
|
|
728
|
+
if (missing.length > 0)
|
|
729
|
+
pendingWarnings.set(submitForm, missing);
|
|
730
|
+
submitForm.requestSubmit();
|
|
731
|
+
} catch (err) {
|
|
732
|
+
reject(err instanceof Error ? err : new Error(String(err)));
|
|
708
733
|
}
|
|
709
|
-
|
|
710
|
-
}, 300);
|
|
734
|
+
});
|
|
711
735
|
}
|
|
712
736
|
});
|
|
713
737
|
};
|
|
@@ -723,7 +747,10 @@ function attachSubmitInterceptor(form, toolName) {
|
|
|
723
747
|
const { resolve } = pending;
|
|
724
748
|
pendingExecutions.delete(form);
|
|
725
749
|
const formData = serializeFormData(form, lastParams.get(form), formFieldElements.get(form));
|
|
726
|
-
const
|
|
750
|
+
const missing = pendingWarnings.get(form);
|
|
751
|
+
pendingWarnings.delete(form);
|
|
752
|
+
const warningText = missing?.length ? ` Note: required fields were not filled: ${missing.join(", ")}.` : "";
|
|
753
|
+
const text = `Form submitted. Fields: ${JSON.stringify(formData)}${warningText}`;
|
|
727
754
|
const result = { content: [{ type: "text", text }] };
|
|
728
755
|
if (e.agentInvoked && typeof e.respondWith === "function") {
|
|
729
756
|
e.preventDefault();
|
|
@@ -929,6 +956,50 @@ function fillElement(el, value) {
|
|
|
929
956
|
fillAriaField(el, value);
|
|
930
957
|
}
|
|
931
958
|
}
|
|
959
|
+
function waitForDomStable(form, maxMs = 800, debounceMs = 150) {
|
|
960
|
+
return new Promise((resolve) => {
|
|
961
|
+
let settled = false;
|
|
962
|
+
let debounceTimer = null;
|
|
963
|
+
const settle = () => {
|
|
964
|
+
if (settled)
|
|
965
|
+
return;
|
|
966
|
+
settled = true;
|
|
967
|
+
observer2.disconnect();
|
|
968
|
+
if (debounceTimer !== null)
|
|
969
|
+
clearTimeout(debounceTimer);
|
|
970
|
+
resolve();
|
|
971
|
+
};
|
|
972
|
+
const observer2 = new MutationObserver(() => {
|
|
973
|
+
if (debounceTimer !== null)
|
|
974
|
+
clearTimeout(debounceTimer);
|
|
975
|
+
debounceTimer = setTimeout(settle, debounceMs);
|
|
976
|
+
});
|
|
977
|
+
observer2.observe(form, { childList: true, subtree: true, attributes: true, characterData: true });
|
|
978
|
+
setTimeout(settle, maxMs);
|
|
979
|
+
debounceTimer = setTimeout(settle, debounceMs);
|
|
980
|
+
});
|
|
981
|
+
}
|
|
982
|
+
function getResetFields(form, params, fieldEls) {
|
|
983
|
+
const reset = [];
|
|
984
|
+
for (const [key, expected] of Object.entries(params)) {
|
|
985
|
+
const el = findNativeField(form, key) ?? (fieldEls?.get(key) ?? null);
|
|
986
|
+
if (!el)
|
|
987
|
+
continue;
|
|
988
|
+
if (el instanceof HTMLInputElement && el.type === "checkbox") {
|
|
989
|
+
if (el.checked !== Boolean(expected))
|
|
990
|
+
reset.push(key);
|
|
991
|
+
} else if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {
|
|
992
|
+
if (el.value !== String(expected ?? ""))
|
|
993
|
+
reset.push(key);
|
|
994
|
+
}
|
|
995
|
+
}
|
|
996
|
+
return reset;
|
|
997
|
+
}
|
|
998
|
+
function getMissingRequired(metadata, params) {
|
|
999
|
+
if (!metadata?.inputSchema?.required?.length)
|
|
1000
|
+
return [];
|
|
1001
|
+
return metadata.inputSchema.required.filter((fieldKey) => !(fieldKey in params));
|
|
1002
|
+
}
|
|
932
1003
|
|
|
933
1004
|
// src/enhancer.ts
|
|
934
1005
|
async function enrichMetadata(metadata, enhancer) {
|