auto-webmcp 0.3.22 → 0.3.24

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.
@@ -1362,9 +1362,11 @@ function buildExecuteHandler(form, config, toolName, metadata) {
1362
1362
  lastFilledSnapshot.delete(submitForm);
1363
1363
  lastFilledSnapshot.delete(form);
1364
1364
  preFillValues.delete(form);
1365
+ const valErrors = structured.validation_errors ?? [];
1366
+ const valSummary = valErrors.length > 0 ? ` Fix: ${valErrors.map((e) => `"${e.field}" (${e.message})`).join("; ")}.` : "";
1365
1367
  resolve({
1366
1368
  content: [
1367
- { type: "text", text: "Form submission blocked by native validation." },
1369
+ { type: "text", text: `Form blocked by validation.${valSummary}` },
1368
1370
  { type: "text", text: JSON.stringify(structured) }
1369
1371
  ]
1370
1372
  });
@@ -1416,12 +1418,20 @@ function attachSubmitInterceptor(form, toolName) {
1416
1418
  ],
1417
1419
  ...existingVals !== void 0 && { existing_values: existingVals }
1418
1420
  };
1421
+ const notFilledFields = fillWarnings.filter((w) => w.type === "not_filled").map((w) => w.field);
1422
+ const totalParams = Object.keys(lastParams.get(form) ?? {}).length;
1423
+ const filledCount = Object.keys(formData).length;
1419
1424
  const allWarnMessages = [
1420
- ...missingRequired.length ? [`required fields were not filled: ${missingRequired.join(", ")}`] : [],
1421
- ...fillWarnings.map((w) => w.message)
1425
+ ...missingRequired.length ? [`required fields not provided: ${missingRequired.join(", ")}`] : [],
1426
+ ...notFilledFields.map((f) => {
1427
+ const w = fillWarnings.find((fw) => fw.field === f);
1428
+ return `"${f}" could not be filled (${w?.message ?? "no matching option"})`;
1429
+ }),
1430
+ ...fillWarnings.filter((w) => w.type !== "not_filled").map((w) => w.message)
1422
1431
  ];
1423
- const warningText = allWarnMessages.length ? ` Note: ${allWarnMessages.join("; ")}.` : "";
1424
- const text = `Form submitted. Fields: ${JSON.stringify(formData)}${warningText}`;
1432
+ const warningText = allWarnMessages.length ? ` Issues: ${allWarnMessages.join("; ")}.` : "";
1433
+ const fillSummary = notFilledFields.length > 0 || missingRequired.length > 0 ? `Filled ${filledCount} of ${totalParams} field(s).` : "Form submitted successfully.";
1434
+ const text = `${fillSummary}${warningText} Fields: ${JSON.stringify(formData)}`;
1425
1435
  const result = {
1426
1436
  content: [
1427
1437
  { type: "text", text },
@@ -1929,7 +1939,7 @@ async function fillLookupInput(el, value) {
1929
1939
  });
1930
1940
  if (!listbox) {
1931
1941
  console.warn("[auto-webmcp] fillLookupInput: listbox did not appear after 3s, leaving text as-is");
1932
- return;
1942
+ return false;
1933
1943
  }
1934
1944
  const lightOptions = Array.from(listbox.querySelectorAll('[role="option"]'));
1935
1945
  const shadowOptions = queryShadowAll(listbox, '[role="option"]');
@@ -1950,6 +1960,7 @@ async function fillLookupInput(el, value) {
1950
1960
  match.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
1951
1961
  match.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
1952
1962
  match.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
1963
+ return true;
1953
1964
  } else {
1954
1965
  console.warn(
1955
1966
  "[auto-webmcp] fillLookupInput: no option matched",
@@ -1957,6 +1968,7 @@ async function fillLookupInput(el, value) {
1957
1968
  "available:",
1958
1969
  options.map((o) => o.getAttribute("data-value") ?? o.textContent?.trim())
1959
1970
  );
1971
+ return false;
1960
1972
  }
1961
1973
  }
1962
1974
  async function fillComboboxButton(el, value) {
@@ -2001,7 +2013,7 @@ async function fillComboboxButton(el, value) {
2001
2013
  });
2002
2014
  if (!listbox) {
2003
2015
  console.warn("[auto-webmcp] fillComboboxButton: listbox did not appear after 3s");
2004
- return;
2016
+ return false;
2005
2017
  }
2006
2018
  const lightOptions = Array.from(listbox.querySelectorAll('[role="option"]'));
2007
2019
  const shadowOptions = queryShadowAll(listbox, '[role="option"]');
@@ -2019,6 +2031,7 @@ async function fillComboboxButton(el, value) {
2019
2031
  match.dispatchEvent(new PointerEvent("pointerdown", { bubbles: true, cancelable: true }));
2020
2032
  match.dispatchEvent(new MouseEvent("mousedown", { bubbles: true, cancelable: true }));
2021
2033
  match.dispatchEvent(new MouseEvent("click", { bubbles: true, cancelable: true }));
2034
+ return true;
2022
2035
  } else {
2023
2036
  console.warn(
2024
2037
  "[auto-webmcp] fillComboboxButton: no option matched",
@@ -2026,6 +2039,7 @@ async function fillComboboxButton(el, value) {
2026
2039
  "available:",
2027
2040
  options.map((o) => o.getAttribute("data-value") ?? o.textContent?.trim())
2028
2041
  );
2042
+ return false;
2029
2043
  }
2030
2044
  }
2031
2045
 
@@ -2495,13 +2509,18 @@ async function scanOrphanInputs(config) {
2495
2509
  const execute = async (params, _client) => {
2496
2510
  console.log(`[auto-webmcp] orphan execute: tool="${toolName}" params=`, params);
2497
2511
  console.log(`[auto-webmcp] orphan execute: inputPairs=`, inputPairs.map((p) => p.key));
2512
+ const notFilled = [];
2498
2513
  for (const { key, el } of inputPairs) {
2499
2514
  if (params[key] !== void 0) {
2500
2515
  console.log(`[auto-webmcp] orphan execute: filling key="${key}" value=`, params[key], "element=", el);
2501
2516
  if (el.getAttribute("role") === "combobox" && el.tagName.toLowerCase() === "input" && (el.getAttribute("aria-autocomplete") === "list" || el.getAttribute("aria-haspopup") === "listbox")) {
2502
- await fillLookupInput(el, params[key]);
2517
+ const filled = await fillLookupInput(el, params[key]);
2518
+ if (!filled)
2519
+ notFilled.push(key);
2503
2520
  } else if (el.getAttribute("role") === "combobox" && el.tagName.toLowerCase() === "button") {
2504
- await fillComboboxButton(el, params[key]);
2521
+ const filled = await fillComboboxButton(el, params[key]);
2522
+ if (!filled)
2523
+ notFilled.push(key);
2505
2524
  } else {
2506
2525
  fillElement(el, params[key]);
2507
2526
  }
@@ -2513,8 +2532,10 @@ async function scanOrphanInputs(config) {
2513
2532
  window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
2514
2533
  const shouldAutoSubmit = config.autoSubmit || !!submitBtn?.hasAttribute("toolautosubmit") || submitBtn instanceof HTMLElement && submitBtn.dataset["webmcpAutosubmit"] !== void 0 || container.hasAttribute("toolautosubmit") || container instanceof HTMLElement && container.dataset["webmcpAutosubmit"] !== void 0;
2515
2534
  if (!shouldAutoSubmit) {
2535
+ const issueText = notFilled.length > 0 ? ` Could not fill: ${notFilled.map((f) => `"${f}" (no matching option)`).join(", ")}.` : "";
2536
+ const readyText = notFilled.length > 0 ? `Fields partially filled.${issueText} Review in browser, then click Save.` : "Fields filled. Ready to submit.";
2516
2537
  console.log(`[auto-webmcp] orphan execute: autoSubmit=false, returning without clicking submit`);
2517
- return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
2538
+ return { content: [{ type: "text", text: readyText }] };
2518
2539
  }
2519
2540
  console.log(`[auto-webmcp] orphan execute: resolving submit button (up to 2s)...`);
2520
2541
  let btn = null;