auto-webmcp 0.3.0 → 0.3.1

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;AAynBD;;;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"}
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,CAKd"}
@@ -503,17 +503,39 @@ function extractDefaultValue(control) {
503
503
  }
504
504
  return void 0;
505
505
  }
506
+ function collectShadowControls(root, visited = /* @__PURE__ */ new Set()) {
507
+ if (visited.has(root))
508
+ return [];
509
+ visited.add(root);
510
+ const results = [];
511
+ for (const el of Array.from(root.querySelectorAll("*"))) {
512
+ if (el.shadowRoot) {
513
+ results.push(
514
+ ...Array.from(
515
+ el.shadowRoot.querySelectorAll(
516
+ "input, textarea, select"
517
+ )
518
+ ),
519
+ ...collectShadowControls(el.shadowRoot, visited)
520
+ );
521
+ }
522
+ }
523
+ return results;
524
+ }
506
525
  function buildSchema(form) {
507
526
  const properties = {};
508
527
  const required = [];
509
528
  const fieldElements = /* @__PURE__ */ new Map();
510
529
  const processedRadioGroups = /* @__PURE__ */ new Set();
511
530
  const processedCheckboxGroups = /* @__PURE__ */ new Set();
512
- const controls = Array.from(
513
- form.querySelectorAll(
514
- "input, textarea, select"
515
- )
516
- );
531
+ const controls = [
532
+ ...Array.from(
533
+ form.querySelectorAll(
534
+ "input, textarea, select"
535
+ )
536
+ ),
537
+ ...collectShadowControls(form)
538
+ ];
517
539
  for (const control of controls) {
518
540
  const name = control.name;
519
541
  const fieldKey = name || resolveNativeControlFallbackKey(control);
@@ -691,9 +713,6 @@ function resolveAriaFieldKey(el) {
691
713
  return null;
692
714
  }
693
715
  function inferAriaFieldTitle(el) {
694
- const nativeTitle = el.getAttribute("toolparamtitle");
695
- if (nativeTitle?.trim())
696
- return nativeTitle.trim();
697
716
  const htmlEl = el;
698
717
  if (htmlEl.dataset?.["webmcpTitle"])
699
718
  return htmlEl.dataset["webmcpTitle"];
@@ -732,9 +751,6 @@ function inferAriaFieldDescription(el) {
732
751
  return "";
733
752
  }
734
753
  function inferFieldTitle(control) {
735
- const nativeTitle = control.getAttribute("toolparamtitle");
736
- if (nativeTitle?.trim())
737
- return nativeTitle.trim();
738
754
  if ("dataset" in control && control.dataset["webmcpTitle"]) {
739
755
  return control.dataset["webmcpTitle"];
740
756
  }
@@ -944,6 +960,9 @@ function buildExecuteHandler(form, config, toolName, metadata) {
944
960
  return async (params) => {
945
961
  pendingFillWarnings.set(form, []);
946
962
  fillFormFields(form, params);
963
+ const missingNow = getMissingRequired(metadata, params);
964
+ if (missingNow.length > 0)
965
+ pendingWarnings.set(form, missingNow);
947
966
  window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
948
967
  return new Promise((resolve, reject) => {
949
968
  pendingExecutions.set(form, { resolve, reject });
@@ -970,9 +989,10 @@ function buildExecuteHandler(form, config, toolName, metadata) {
970
989
  attachSubmitInterceptor(submitForm, toolName);
971
990
  }
972
991
  }
973
- const missing = getMissingRequired(metadata, params);
974
- if (missing.length > 0)
975
- pendingWarnings.set(submitForm, missing);
992
+ if (submitForm !== form && pendingWarnings.has(form)) {
993
+ pendingWarnings.set(submitForm, pendingWarnings.get(form));
994
+ pendingWarnings.delete(form);
995
+ }
976
996
  submitForm.requestSubmit();
977
997
  } catch (err) {
978
998
  reject(err instanceof Error ? err : new Error(String(err)));
@@ -994,17 +1014,37 @@ function attachSubmitInterceptor(form, toolName) {
994
1014
  pendingExecutions.delete(form);
995
1015
  const formData = serializeFormData(form, lastParams.get(form), formFieldElements.get(form));
996
1016
  lastFilledSnapshot.delete(form);
997
- const missing = pendingWarnings.get(form);
1017
+ const missingRequired = pendingWarnings.get(form) ?? [];
998
1018
  pendingWarnings.delete(form);
999
1019
  const fillWarnings = pendingFillWarnings.get(form) ?? [];
1000
1020
  pendingFillWarnings.delete(form);
1001
- const allWarnings = [
1002
- ...missing?.length ? [`required fields were not filled: ${missing.join(", ")}`] : [],
1003
- ...fillWarnings
1021
+ const skippedFields = fillWarnings.filter((w) => w.type === "not_filled").map((w) => w.field);
1022
+ const structured = {
1023
+ status: missingRequired.length > 0 || skippedFields.length > 0 ? "partial" : "success",
1024
+ filled_fields: formData,
1025
+ skipped_fields: skippedFields,
1026
+ missing_required: missingRequired,
1027
+ warnings: [
1028
+ ...missingRequired.map((f) => ({
1029
+ field: f,
1030
+ type: "missing_required",
1031
+ message: `required field "${f}" was not provided`
1032
+ })),
1033
+ ...fillWarnings
1034
+ ]
1035
+ };
1036
+ const allWarnMessages = [
1037
+ ...missingRequired.length ? [`required fields were not filled: ${missingRequired.join(", ")}`] : [],
1038
+ ...fillWarnings.map((w) => w.message)
1004
1039
  ];
1005
- const warningText = allWarnings.length ? ` Note: ${allWarnings.join("; ")}.` : "";
1040
+ const warningText = allWarnMessages.length ? ` Note: ${allWarnMessages.join("; ")}.` : "";
1006
1041
  const text = `Form submitted. Fields: ${JSON.stringify(formData)}${warningText}`;
1007
- const result = { content: [{ type: "text", text }] };
1042
+ const result = {
1043
+ content: [
1044
+ { type: "text", text },
1045
+ { type: "text", text: JSON.stringify(structured) }
1046
+ ]
1047
+ };
1008
1048
  if (e.agentInvoked && typeof e.respondWith === "function") {
1009
1049
  e.preventDefault();
1010
1050
  e.respondWith(Promise.resolve(result));
@@ -1138,16 +1178,26 @@ function fillInput(input, form, key, value) {
1138
1178
  const raw = String(value ?? "");
1139
1179
  const num = Number(raw);
1140
1180
  if (raw === "" || isNaN(num)) {
1141
- pendingFillWarnings.get(form)?.push(`"${key}" expects a number, got: ${JSON.stringify(value)}`);
1181
+ pendingFillWarnings.get(form)?.push({
1182
+ field: key,
1183
+ type: "type_mismatch",
1184
+ message: `"${key}" expects a number, got: ${JSON.stringify(value)}`,
1185
+ original: value
1186
+ });
1142
1187
  return;
1143
1188
  }
1144
1189
  const min = input.min !== "" ? parseFloat(input.min) : -Infinity;
1145
1190
  const max = input.max !== "" ? parseFloat(input.max) : Infinity;
1146
1191
  if (num < min || num > max) {
1147
- pendingFillWarnings.get(form)?.push(
1148
- `"${key}" value ${num} is outside allowed range [${input.min || "?"}, ${input.max || "?"}]`
1149
- );
1150
- input.value = String(Math.min(Math.max(num, min), max));
1192
+ const clamped = Math.min(Math.max(num, min), max);
1193
+ pendingFillWarnings.get(form)?.push({
1194
+ field: key,
1195
+ type: "clamped",
1196
+ message: `"${key}" value ${num} is outside allowed range [${input.min || "?"}, ${input.max || "?"}], clamped to ${clamped}`,
1197
+ original: num,
1198
+ actual: clamped
1199
+ });
1200
+ input.value = String(clamped);
1151
1201
  } else {
1152
1202
  input.value = String(num);
1153
1203
  }