auto-webmcp 0.2.9 → 0.2.10

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.
@@ -207,6 +207,14 @@ function buildStringSchema(input) {
207
207
  }
208
208
  return prop;
209
209
  }
210
+ var PLACEHOLDER_PATTERNS = /^(select|choose|pick)\b|^--+|---/i;
211
+ function isPlaceholderOption(opt) {
212
+ if (opt.disabled)
213
+ return true;
214
+ if (opt.value !== "")
215
+ return false;
216
+ return PLACEHOLDER_PATTERNS.test(opt.text.trim());
217
+ }
210
218
  function mapSelectElement(select) {
211
219
  const enumValues = [];
212
220
  const oneOf = [];
@@ -218,7 +226,7 @@ function mapSelectElement(select) {
218
226
  for (const opt of Array.from(child.children)) {
219
227
  if (!(opt instanceof HTMLOptionElement))
220
228
  continue;
221
- if (opt.disabled || opt.value === "")
229
+ if (isPlaceholderOption(opt))
222
230
  continue;
223
231
  enumValues.push(opt.value);
224
232
  const entry = {
@@ -230,7 +238,7 @@ function mapSelectElement(select) {
230
238
  oneOf.push(entry);
231
239
  }
232
240
  } else if (child instanceof HTMLOptionElement) {
233
- if (child.disabled || child.value === "")
241
+ if (isPlaceholderOption(child))
234
242
  continue;
235
243
  enumValues.push(child.value);
236
244
  oneOf.push({ const: child.value, title: child.text.trim() || child.value });
@@ -238,6 +246,9 @@ function mapSelectElement(select) {
238
246
  }
239
247
  if (enumValues.length === 0)
240
248
  return { type: "string" };
249
+ if (select.multiple) {
250
+ return { type: "array", items: { type: "string", enum: enumValues } };
251
+ }
241
252
  return { type: "string", enum: enumValues, oneOf };
242
253
  }
243
254
  function collectCheckboxEnum(form, name) {
@@ -834,6 +845,7 @@ var lastParams = /* @__PURE__ */ new WeakMap();
834
845
  var formFieldElements = /* @__PURE__ */ new WeakMap();
835
846
  var pendingWarnings = /* @__PURE__ */ new WeakMap();
836
847
  var pendingFillWarnings = /* @__PURE__ */ new WeakMap();
848
+ var lastFilledSnapshot = /* @__PURE__ */ new WeakMap();
837
849
  var _inputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
838
850
  var _textareaValueSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, "value")?.set;
839
851
  var _checkedSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "checked")?.set;
@@ -894,6 +906,7 @@ function attachSubmitInterceptor(form, toolName) {
894
906
  const { resolve } = pending;
895
907
  pendingExecutions.delete(form);
896
908
  const formData = serializeFormData(form, lastParams.get(form), formFieldElements.get(form));
909
+ lastFilledSnapshot.delete(form);
897
910
  const missing = pendingWarnings.get(form);
898
911
  pendingWarnings.delete(form);
899
912
  const fillWarnings = pendingFillWarnings.get(form) ?? [];
@@ -912,6 +925,7 @@ function attachSubmitInterceptor(form, toolName) {
912
925
  resolve(result);
913
926
  });
914
927
  form.addEventListener("reset", () => {
928
+ lastFilledSnapshot.delete(form);
915
929
  window.dispatchEvent(new CustomEvent("toolcancel", { detail: { toolName } }));
916
930
  });
917
931
  }
@@ -964,16 +978,30 @@ function findNativeField(form, key) {
964
978
  function fillFormFields(form, params) {
965
979
  lastParams.set(form, params);
966
980
  const fieldEls = formFieldElements.get(form);
981
+ const snapshot = {};
967
982
  for (const [key, value] of Object.entries(params)) {
968
983
  const input = findNativeField(form, key);
969
984
  if (input) {
970
985
  if (input instanceof HTMLInputElement) {
971
986
  fillInput(input, form, key, value);
987
+ if (input.type === "checkbox") {
988
+ if (Array.isArray(value)) {
989
+ const esc = CSS.escape(key);
990
+ snapshot[key] = Array.from(
991
+ form.querySelectorAll(`input[type="checkbox"][name="${esc}"]`)
992
+ ).filter((b) => b.checked).map((b) => b.value);
993
+ } else {
994
+ snapshot[key] = input.checked;
995
+ }
996
+ } else {
997
+ snapshot[key] = input.value;
998
+ }
972
999
  } else if (input instanceof HTMLTextAreaElement) {
973
1000
  setReactValue(input, String(value ?? ""));
1001
+ snapshot[key] = input.value;
974
1002
  } else if (input instanceof HTMLSelectElement) {
975
- input.value = String(value ?? "");
976
- input.dispatchEvent(new Event("change", { bubbles: true }));
1003
+ fillSelectElement(input, value);
1004
+ snapshot[key] = input.multiple ? Array.from(input.options).filter((o) => o.selected).map((o) => o.value) : input.value;
977
1005
  }
978
1006
  continue;
979
1007
  }
@@ -990,16 +1018,20 @@ function fillFormFields(form, params) {
990
1018
  }
991
1019
  if (effectiveEl instanceof HTMLInputElement) {
992
1020
  fillInput(effectiveEl, form, key, value);
1021
+ snapshot[key] = effectiveEl.type === "checkbox" ? effectiveEl.checked : effectiveEl.value;
993
1022
  } else if (effectiveEl instanceof HTMLTextAreaElement) {
994
1023
  setReactValue(effectiveEl, String(value ?? ""));
1024
+ snapshot[key] = effectiveEl.value;
995
1025
  } else if (effectiveEl instanceof HTMLSelectElement) {
996
- effectiveEl.value = String(value ?? "");
997
- effectiveEl.dispatchEvent(new Event("change", { bubbles: true }));
1026
+ fillSelectElement(effectiveEl, value);
1027
+ snapshot[key] = effectiveEl.multiple ? Array.from(effectiveEl.options).filter((o) => o.selected).map((o) => o.value) : effectiveEl.value;
998
1028
  } else {
999
1029
  fillAriaField(effectiveEl, value);
1030
+ snapshot[key] = value;
1000
1031
  }
1001
1032
  }
1002
1033
  }
1034
+ lastFilledSnapshot.set(form, snapshot);
1003
1035
  }
1004
1036
  function fillInput(input, form, key, value) {
1005
1037
  const type = input.type.toLowerCase();
@@ -1056,6 +1088,18 @@ function fillInput(input, form, key, value) {
1056
1088
  }
1057
1089
  setReactValue(input, String(value ?? ""));
1058
1090
  }
1091
+ function fillSelectElement(select, value) {
1092
+ if (select.multiple) {
1093
+ const vals = Array.isArray(value) ? value.map(String) : [String(value ?? "")];
1094
+ for (const opt of Array.from(select.options)) {
1095
+ opt.selected = vals.includes(opt.value);
1096
+ }
1097
+ select.dispatchEvent(new Event("change", { bubbles: true }));
1098
+ return;
1099
+ }
1100
+ select.value = String(value ?? "");
1101
+ select.dispatchEvent(new Event("change", { bubbles: true }));
1102
+ }
1059
1103
  function fillAriaField(el, value) {
1060
1104
  const role = el.getAttribute("role");
1061
1105
  if (role === "checkbox" || role === "switch") {
@@ -1094,6 +1138,7 @@ function fillAriaField(el, value) {
1094
1138
  function serializeFormData(form, params, fieldEls) {
1095
1139
  const result = {};
1096
1140
  const data = new FormData(form);
1141
+ const snapshot = lastFilledSnapshot.get(form);
1097
1142
  for (const [key, val] of data.entries()) {
1098
1143
  if (result[key] !== void 0) {
1099
1144
  const existing = result[key];
@@ -1110,6 +1155,10 @@ function serializeFormData(form, params, fieldEls) {
1110
1155
  for (const key of Object.keys(params)) {
1111
1156
  if (key in result)
1112
1157
  continue;
1158
+ if (snapshot && key in snapshot) {
1159
+ result[key] = snapshot[key];
1160
+ continue;
1161
+ }
1113
1162
  const el = findNativeField(form, key) ?? fieldEls?.get(key) ?? null;
1114
1163
  if (!el)
1115
1164
  continue;
@@ -1148,8 +1197,7 @@ function fillElement(el, value) {
1148
1197
  } else if (el instanceof HTMLTextAreaElement) {
1149
1198
  setReactValue(el, String(value ?? ""));
1150
1199
  } else if (el instanceof HTMLSelectElement) {
1151
- el.value = String(value ?? "");
1152
- el.dispatchEvent(new Event("change", { bubbles: true }));
1200
+ fillSelectElement(el, value);
1153
1201
  } else {
1154
1202
  fillAriaField(el, value);
1155
1203
  }