auto-webmcp 0.3.6 → 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.
@@ -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;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"}
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,CAMd"}
@@ -630,7 +630,7 @@ function buildSchema(form) {
630
630
  required.push(key);
631
631
  }
632
632
  }
633
- return { schema: { type: "object", properties, required }, fieldElements };
633
+ return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
634
634
  }
635
635
  function resolveNativeControlFallbackKey(control) {
636
636
  const el = control;
@@ -835,7 +835,24 @@ function analyzeOrphanInputGroup(container, inputs, submitBtn) {
835
835
  const name = inferOrphanToolName(container, submitBtn);
836
836
  const description = inferOrphanToolDescription(container);
837
837
  const { schema: inputSchema, fieldElements } = buildSchemaFromInputs(inputs);
838
- return { name, description, inputSchema, fieldElements };
838
+ const annotations = inferOrphanAnnotations(submitBtn);
839
+ return { name, description, inputSchema, annotations, fieldElements };
840
+ }
841
+ function inferOrphanAnnotations(submitBtn) {
842
+ const annotations = {};
843
+ const submitText = submitBtn instanceof HTMLInputElement ? submitBtn.value.trim() : submitBtn?.textContent?.trim() ?? "";
844
+ if (READONLY_BUTTON_PATTERNS.test(submitText)) {
845
+ annotations.readOnlyHint = true;
846
+ annotations.idempotentHint = true;
847
+ }
848
+ if (DESTRUCTIVE_BUTTON_PATTERNS.test(submitText)) {
849
+ annotations.destructiveHint = true;
850
+ }
851
+ if (annotations.readOnlyHint !== true) {
852
+ annotations.openWorldHint = true;
853
+ }
854
+ const hasNonDefault = annotations.readOnlyHint === true || annotations.destructiveHint === true || annotations.idempotentHint === true || annotations.openWorldHint === false;
855
+ return hasNonDefault ? annotations : {};
839
856
  }
840
857
  function inferOrphanToolName(container, submitBtn) {
841
858
  if (submitBtn) {
@@ -890,8 +907,8 @@ function buildSchemaFromInputs(inputs) {
890
907
  const processedRadioGroups = /* @__PURE__ */ new Set();
891
908
  const processedCheckboxGroups = /* @__PURE__ */ new Set();
892
909
  for (const control of inputs) {
893
- const name = control.name;
894
- const fieldKey = name || resolveNativeControlFallbackKey(control);
910
+ const rawName = control.name;
911
+ const fieldKey = (rawName ? sanitizeName(rawName) : null) || resolveNativeControlFallbackKey(control);
895
912
  if (!fieldKey)
896
913
  continue;
897
914
  if (control instanceof HTMLInputElement && control.type === "radio") {
@@ -930,12 +947,12 @@ function buildSchemaFromInputs(inputs) {
930
947
  }
931
948
  }
932
949
  properties[fieldKey] = schemaProp;
933
- if (!name)
950
+ if (!rawName)
934
951
  fieldElements.set(fieldKey, control);
935
952
  if (control.required)
936
953
  required.push(fieldKey);
937
954
  }
938
- return { schema: { type: "object", properties, required }, fieldElements };
955
+ return { schema: { "$schema": "https://json-schema.org/draft/2020-12/schema", type: "object", properties, required }, fieldElements };
939
956
  }
940
957
 
941
958
  // src/discovery.ts
@@ -1623,15 +1640,42 @@ async function scanOrphanInputs(config) {
1623
1640
  }
1624
1641
  }
1625
1642
  window.dispatchEvent(new CustomEvent("toolactivated", { detail: { toolName } }));
1626
- return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
1643
+ if (!config.autoSubmit) {
1644
+ return { content: [{ type: "text", text: "Fields filled. Ready to submit." }] };
1645
+ }
1646
+ let btn = null;
1647
+ const deadline = Date.now() + 2e3;
1648
+ while (Date.now() < deadline) {
1649
+ const candidates = Array.from(
1650
+ container.querySelectorAll(SUBMIT_BTN_SELECTOR)
1651
+ ).filter((b) => {
1652
+ const r = b.getBoundingClientRect();
1653
+ return r.width > 0 && r.height > 0;
1654
+ });
1655
+ const last = candidates[candidates.length - 1] ?? null;
1656
+ if (last) {
1657
+ btn = last;
1658
+ break;
1659
+ }
1660
+ await new Promise((r) => setTimeout(r, 100));
1661
+ }
1662
+ if (!btn) {
1663
+ return { content: [{ type: "text", text: "Fields filled but the submit button is still disabled. The page may require additional input before submitting." }] };
1664
+ }
1665
+ btn.click();
1666
+ return { content: [{ type: "text", text: "Fields filled and form submitted." }] };
1627
1667
  };
1628
1668
  try {
1629
- await navigator.modelContext.registerTool({
1669
+ const toolDef = {
1630
1670
  name: metadata.name,
1631
1671
  description: metadata.description,
1632
1672
  inputSchema: metadata.inputSchema,
1633
1673
  execute
1634
- });
1674
+ };
1675
+ if (metadata.annotations && Object.keys(metadata.annotations).length > 0) {
1676
+ toolDef.annotations = metadata.annotations;
1677
+ }
1678
+ await navigator.modelContext.registerTool(toolDef);
1635
1679
  if (config.debug) {
1636
1680
  console.debug(`[auto-webmcp] Orphan tool registered: ${metadata.name}`, metadata);
1637
1681
  }