auto-chrome-mcp-shared 1.1.0 → 1.2.0

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/index.d.mts CHANGED
@@ -198,6 +198,10 @@ declare const TOOL_NAMES: {
198
198
  PERFORMANCE_ANALYZE_INSIGHT: string;
199
199
  GIF_RECORDER: string;
200
200
  BATCH: string;
201
+ SET_WORK_TAB: string;
202
+ WAIT_FOR: string;
203
+ SCROLL_COLLECT: string;
204
+ EXTRACT: string;
201
205
  };
202
206
  RECORD_REPLAY: {
203
207
  FLOW_RUN: string;
package/dist/index.d.ts CHANGED
@@ -198,6 +198,10 @@ declare const TOOL_NAMES: {
198
198
  PERFORMANCE_ANALYZE_INSIGHT: string;
199
199
  GIF_RECORDER: string;
200
200
  BATCH: string;
201
+ SET_WORK_TAB: string;
202
+ WAIT_FOR: string;
203
+ SCROLL_COLLECT: string;
204
+ EXTRACT: string;
201
205
  };
202
206
  RECORD_REPLAY: {
203
207
  FLOW_RUN: string;
package/dist/index.js CHANGED
@@ -112,7 +112,11 @@ var TOOL_NAMES = {
112
112
  PERFORMANCE_STOP_TRACE: "performance_stop_trace",
113
113
  PERFORMANCE_ANALYZE_INSIGHT: "performance_analyze_insight",
114
114
  GIF_RECORDER: "chrome_gif_recorder",
115
- BATCH: "chrome_batch"
115
+ BATCH: "chrome_batch",
116
+ SET_WORK_TAB: "chrome_set_work_tab",
117
+ WAIT_FOR: "chrome_wait_for",
118
+ SCROLL_COLLECT: "chrome_scroll_collect",
119
+ EXTRACT: "chrome_extract"
116
120
  },
117
121
  RECORD_REPLAY: {
118
122
  FLOW_RUN: "record_replay_flow_run",
@@ -146,9 +150,110 @@ var TOOL_SCHEMAS = [
146
150
  required: ["steps"]
147
151
  }
148
152
  },
153
+ {
154
+ name: TOOL_NAMES.BROWSER.EXTRACT,
155
+ description: "Extract ONLY the fields you need from the page via CSS selectors \u2014 far cheaper than reading the whole page when you know what you want (e.g. price, title, links). Deterministic and precise. Prefer this over chrome_get_web_content/chrome_read_page for targeted scraping.",
156
+ inputSchema: {
157
+ type: "object",
158
+ properties: {
159
+ tabId: {
160
+ type: "number",
161
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
162
+ },
163
+ fields: {
164
+ type: "object",
165
+ description: "Map of fieldName \u2192 CSS selector (string) or { selector, attr?, all? }. Default value = trimmed innerText of first match; attr returns that attribute (href/src resolve to absolute URLs); all:true returns an array over every match (max 100, 2000 chars each). Max 20 fields."
166
+ },
167
+ frameId: {
168
+ type: "number",
169
+ description: "Optional frame id to extract from a specific iframe."
170
+ }
171
+ },
172
+ required: ["fields"]
173
+ }
174
+ },
175
+ {
176
+ name: TOOL_NAMES.BROWSER.WAIT_FOR,
177
+ description: 'Wait until the page is actually ready before acting \u2014 prevents "clicked/read too early" failures after navigation, clicks, or AJAX updates. Conditions (AND-combined, at least one required): selector appears/visible/hidden, text appears, document ready, or network idle. A timeout returns success:false with the observed state (not an error) so you can decide next steps.',
178
+ inputSchema: {
179
+ type: "object",
180
+ properties: {
181
+ tabId: {
182
+ type: "number",
183
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
184
+ },
185
+ selector: { type: "string", description: "CSS selector to wait for" },
186
+ state: {
187
+ type: "string",
188
+ enum: ["visible", "attached", "hidden"],
189
+ description: "Selector condition (default 'visible'). 'hidden' = absent or not visible."
190
+ },
191
+ text: { type: "string", description: "Wait until this text appears in the page body" },
192
+ documentReady: {
193
+ type: "boolean",
194
+ description: "Wait for document.readyState === 'complete'"
195
+ },
196
+ networkIdleMs: {
197
+ type: "number",
198
+ description: "Wait until the tab has no in-flight network requests for this many ms (e.g. 500)"
199
+ },
200
+ timeoutMs: { type: "number", description: "Max wait (default 15000, max 60000)" },
201
+ pollMs: { type: "number", description: "Poll interval (default 250, min 100)" }
202
+ },
203
+ required: []
204
+ }
205
+ },
206
+ {
207
+ name: TOOL_NAMES.BROWSER.SCROLL_COLLECT,
208
+ description: "Collect content from infinite-scroll / lazy-loaded pages in ONE call: repeatedly scrolls to the bottom (window or a container element), waits for new content, and returns the accumulated text or links. Stops when the page stops growing, stopText appears, maxScrolls or maxChars is reached.",
209
+ inputSchema: {
210
+ type: "object",
211
+ properties: {
212
+ tabId: {
213
+ type: "number",
214
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
215
+ },
216
+ maxScrolls: { type: "number", description: "Max scroll passes (default 10, max 30)" },
217
+ delayMs: {
218
+ type: "number",
219
+ description: "Wait after each scroll for content to load (default 700, 200\u20133000)"
220
+ },
221
+ containerSelector: {
222
+ type: "string",
223
+ description: "Scroll this element instead of the window (e.g. a feed container)"
224
+ },
225
+ stopText: { type: "string", description: "Stop early when this text appears" },
226
+ collect: {
227
+ type: "string",
228
+ enum: ["text", "links"],
229
+ description: "What to return (default 'text'). 'links' = deduped [{text, href}]"
230
+ },
231
+ maxChars: { type: "number", description: "Output cap (default 100000, max 300000)" }
232
+ },
233
+ required: []
234
+ }
235
+ },
236
+ {
237
+ name: TOOL_NAMES.BROWSER.SET_WORK_TAB,
238
+ description: "Retarget this session's default work tab WITHOUT activating/focusing anything (unlike chrome_switch_tab). Use when a tool result reports new_tabs_opened (a popup/new tab appeared, e.g. OAuth login) and you want subsequent tabId-less tool calls to target it \u2014 then call again with the original tabId to return. No args = report current work tab. clear:true = unset.",
239
+ inputSchema: {
240
+ type: "object",
241
+ properties: {
242
+ tabId: {
243
+ type: "number",
244
+ description: "Tab id to make this session's work tab. Omit to just query the current one."
245
+ },
246
+ clear: {
247
+ type: "boolean",
248
+ description: "Unset the session work tab (default false)"
249
+ }
250
+ },
251
+ required: []
252
+ }
253
+ },
149
254
  {
150
255
  name: TOOL_NAMES.BROWSER.GET_WINDOWS_AND_TABS,
151
- description: "Get all currently open browser windows and tabs",
256
+ description: "Get all currently open browser windows and tabs. Marks MCP session work tabs (mcpWorkTabSessions), the dedicated MCP work window (isMcpWorkWindow), and tabs recently spawned by page actions such as popups (recentlySpawned with openerTabId).",
152
257
  inputSchema: {
153
258
  type: "object",
154
259
  properties: {},
@@ -289,6 +394,18 @@ Tip: If the returned elements do not include the specific element you need, use
289
394
  windowId: {
290
395
  type: "number",
291
396
  description: "Target window ID to pick active tab when tabId is omitted."
397
+ },
398
+ allFrames: {
399
+ type: "boolean",
400
+ description: "Also collect content from iframes (merged, annotated with frameId \u2014 pair frame-local refs with that frameId). Default: false"
401
+ },
402
+ diff: {
403
+ type: "boolean",
404
+ description: "When true (default), returns {unchanged:true} instead of the full body if the page content is identical to your previous read \u2014 reuse the earlier content. Pass false to force full re-send."
405
+ },
406
+ compact: {
407
+ type: "boolean",
408
+ description: "Lossless output compaction (collapse empty wrappers etc., ~30-50% smaller). Default: true. Pass false for the verbose format."
292
409
  }
293
410
  },
294
411
  required: []
@@ -305,6 +422,10 @@ Tip: If the returned elements do not include the specific element you need, use
305
422
  type: "boolean",
306
423
  description: "Avoid focusing/activating tab/window for certain operations (best-effort). Default: false"
307
424
  },
425
+ fullResolution: {
426
+ type: "boolean",
427
+ description: 'For action="screenshot"/"zoom": skip the \u22641568px downscale of the returned image (default: false)'
428
+ },
308
429
  action: {
309
430
  type: "string",
310
431
  description: "Action to perform: left_click | right_click | double_click | triple_click | left_click_drag | scroll | scroll_to | type | key | fill | fill_form | hover | wait | resize_page | zoom | screenshot"
@@ -552,7 +673,11 @@ Tip: If the returned elements do not include the specific element you need, use
552
673
  height: { type: "number", description: "Height in pixels (default: 600)" },
553
674
  storeBase64: {
554
675
  type: "boolean",
555
- description: "return screenshot in base64 format (default: false) if you want to see the page, recommend set this to be true"
676
+ description: "Return the screenshot as an MCP image content block (default: false). Recommended when you want to SEE the page. The image is auto-downscaled to \u22641568px long edge (metadata reports imageScale vs the CSS viewport for coordinate math); pass fullResolution:true to skip downscaling."
677
+ },
678
+ fullResolution: {
679
+ type: "boolean",
680
+ description: "Skip the \u22641568px downscale for the returned image (default: false)"
556
681
  },
557
682
  fullPage: {
558
683
  type: "boolean",
@@ -640,6 +765,14 @@ Tip: If the returned elements do not include the specific element you need, use
640
765
  selector: {
641
766
  type: "string",
642
767
  description: "CSS selector to get content from a specific element. If provided, only content from this element will be returned"
768
+ },
769
+ raw: {
770
+ type: "boolean",
771
+ description: "Text mode returns reader-view content by default (navigation/footer/cookie-banner noise stripped, main content kept \u2014 fullTextChars vs returnedChars reported). Pass true for the unfiltered full text. Default: false"
772
+ },
773
+ diff: {
774
+ type: "boolean",
775
+ description: "When true (default), returns {unchanged:true} instead of the body if identical to your previous read of this tab \u2014 reuse the earlier content. Pass false to force full re-send."
643
776
  }
644
777
  },
645
778
  required: []
@@ -717,6 +850,18 @@ Tip: If the returned elements do not include the specific element you need, use
717
850
  tabId: {
718
851
  type: "number",
719
852
  description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
853
+ },
854
+ limit: {
855
+ type: "number",
856
+ description: 'action="stop": return at most this many captured requests (default 100; paginate with offset)'
857
+ },
858
+ offset: {
859
+ type: "number",
860
+ description: 'action="stop": skip this many captured requests (default 0)'
861
+ },
862
+ countOnly: {
863
+ type: "boolean",
864
+ description: 'action="stop": return only counts/summary without the request array (default: false)'
720
865
  }
721
866
  },
722
867
  required: ["action"]
@@ -760,6 +905,18 @@ Tip: If the returned elements do not include the specific element you need, use
760
905
  excludeCurrentTabs: {
761
906
  type: "boolean",
762
907
  description: "When set to true, filters out URLs that are currently open in any browser tab. Useful for finding pages you've visited but don't have open anymore. (default: false)"
908
+ },
909
+ limit: {
910
+ type: "number",
911
+ description: "Return at most this many entries (default 100; pagination with offset)"
912
+ },
913
+ offset: {
914
+ type: "number",
915
+ description: "Skip this many entries before returning (default 0)"
916
+ },
917
+ countOnly: {
918
+ type: "boolean",
919
+ description: "Return only totalCount without the entries array (default: false)"
763
920
  }
764
921
  },
765
922
  required: []
@@ -1168,6 +1325,14 @@ Tip: If the returned elements do not include the specific element you need, use
1168
1325
  type: "number",
1169
1326
  description: "Maximum number of console messages to capture in snapshot mode (default: 100). If limit is provided, it takes precedence."
1170
1327
  },
1328
+ offset: {
1329
+ type: "number",
1330
+ description: "Skip this many messages before returning (pagination; default 0)"
1331
+ },
1332
+ countOnly: {
1333
+ type: "boolean",
1334
+ description: "Return only counts/summary without the message array (default: false)"
1335
+ },
1171
1336
  mode: {
1172
1337
  type: "string",
1173
1338
  enum: ["snapshot", "buffer"],
package/dist/index.mjs CHANGED
@@ -67,7 +67,11 @@ var TOOL_NAMES = {
67
67
  PERFORMANCE_STOP_TRACE: "performance_stop_trace",
68
68
  PERFORMANCE_ANALYZE_INSIGHT: "performance_analyze_insight",
69
69
  GIF_RECORDER: "chrome_gif_recorder",
70
- BATCH: "chrome_batch"
70
+ BATCH: "chrome_batch",
71
+ SET_WORK_TAB: "chrome_set_work_tab",
72
+ WAIT_FOR: "chrome_wait_for",
73
+ SCROLL_COLLECT: "chrome_scroll_collect",
74
+ EXTRACT: "chrome_extract"
71
75
  },
72
76
  RECORD_REPLAY: {
73
77
  FLOW_RUN: "record_replay_flow_run",
@@ -101,9 +105,110 @@ var TOOL_SCHEMAS = [
101
105
  required: ["steps"]
102
106
  }
103
107
  },
108
+ {
109
+ name: TOOL_NAMES.BROWSER.EXTRACT,
110
+ description: "Extract ONLY the fields you need from the page via CSS selectors \u2014 far cheaper than reading the whole page when you know what you want (e.g. price, title, links). Deterministic and precise. Prefer this over chrome_get_web_content/chrome_read_page for targeted scraping.",
111
+ inputSchema: {
112
+ type: "object",
113
+ properties: {
114
+ tabId: {
115
+ type: "number",
116
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
117
+ },
118
+ fields: {
119
+ type: "object",
120
+ description: "Map of fieldName \u2192 CSS selector (string) or { selector, attr?, all? }. Default value = trimmed innerText of first match; attr returns that attribute (href/src resolve to absolute URLs); all:true returns an array over every match (max 100, 2000 chars each). Max 20 fields."
121
+ },
122
+ frameId: {
123
+ type: "number",
124
+ description: "Optional frame id to extract from a specific iframe."
125
+ }
126
+ },
127
+ required: ["fields"]
128
+ }
129
+ },
130
+ {
131
+ name: TOOL_NAMES.BROWSER.WAIT_FOR,
132
+ description: 'Wait until the page is actually ready before acting \u2014 prevents "clicked/read too early" failures after navigation, clicks, or AJAX updates. Conditions (AND-combined, at least one required): selector appears/visible/hidden, text appears, document ready, or network idle. A timeout returns success:false with the observed state (not an error) so you can decide next steps.',
133
+ inputSchema: {
134
+ type: "object",
135
+ properties: {
136
+ tabId: {
137
+ type: "number",
138
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
139
+ },
140
+ selector: { type: "string", description: "CSS selector to wait for" },
141
+ state: {
142
+ type: "string",
143
+ enum: ["visible", "attached", "hidden"],
144
+ description: "Selector condition (default 'visible'). 'hidden' = absent or not visible."
145
+ },
146
+ text: { type: "string", description: "Wait until this text appears in the page body" },
147
+ documentReady: {
148
+ type: "boolean",
149
+ description: "Wait for document.readyState === 'complete'"
150
+ },
151
+ networkIdleMs: {
152
+ type: "number",
153
+ description: "Wait until the tab has no in-flight network requests for this many ms (e.g. 500)"
154
+ },
155
+ timeoutMs: { type: "number", description: "Max wait (default 15000, max 60000)" },
156
+ pollMs: { type: "number", description: "Poll interval (default 250, min 100)" }
157
+ },
158
+ required: []
159
+ }
160
+ },
161
+ {
162
+ name: TOOL_NAMES.BROWSER.SCROLL_COLLECT,
163
+ description: "Collect content from infinite-scroll / lazy-loaded pages in ONE call: repeatedly scrolls to the bottom (window or a container element), waits for new content, and returns the accumulated text or links. Stops when the page stops growing, stopText appears, maxScrolls or maxChars is reached.",
164
+ inputSchema: {
165
+ type: "object",
166
+ properties: {
167
+ tabId: {
168
+ type: "number",
169
+ description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
170
+ },
171
+ maxScrolls: { type: "number", description: "Max scroll passes (default 10, max 30)" },
172
+ delayMs: {
173
+ type: "number",
174
+ description: "Wait after each scroll for content to load (default 700, 200\u20133000)"
175
+ },
176
+ containerSelector: {
177
+ type: "string",
178
+ description: "Scroll this element instead of the window (e.g. a feed container)"
179
+ },
180
+ stopText: { type: "string", description: "Stop early when this text appears" },
181
+ collect: {
182
+ type: "string",
183
+ enum: ["text", "links"],
184
+ description: "What to return (default 'text'). 'links' = deduped [{text, href}]"
185
+ },
186
+ maxChars: { type: "number", description: "Output cap (default 100000, max 300000)" }
187
+ },
188
+ required: []
189
+ }
190
+ },
191
+ {
192
+ name: TOOL_NAMES.BROWSER.SET_WORK_TAB,
193
+ description: "Retarget this session's default work tab WITHOUT activating/focusing anything (unlike chrome_switch_tab). Use when a tool result reports new_tabs_opened (a popup/new tab appeared, e.g. OAuth login) and you want subsequent tabId-less tool calls to target it \u2014 then call again with the original tabId to return. No args = report current work tab. clear:true = unset.",
194
+ inputSchema: {
195
+ type: "object",
196
+ properties: {
197
+ tabId: {
198
+ type: "number",
199
+ description: "Tab id to make this session's work tab. Omit to just query the current one."
200
+ },
201
+ clear: {
202
+ type: "boolean",
203
+ description: "Unset the session work tab (default false)"
204
+ }
205
+ },
206
+ required: []
207
+ }
208
+ },
104
209
  {
105
210
  name: TOOL_NAMES.BROWSER.GET_WINDOWS_AND_TABS,
106
- description: "Get all currently open browser windows and tabs",
211
+ description: "Get all currently open browser windows and tabs. Marks MCP session work tabs (mcpWorkTabSessions), the dedicated MCP work window (isMcpWorkWindow), and tabs recently spawned by page actions such as popups (recentlySpawned with openerTabId).",
107
212
  inputSchema: {
108
213
  type: "object",
109
214
  properties: {},
@@ -244,6 +349,18 @@ Tip: If the returned elements do not include the specific element you need, use
244
349
  windowId: {
245
350
  type: "number",
246
351
  description: "Target window ID to pick active tab when tabId is omitted."
352
+ },
353
+ allFrames: {
354
+ type: "boolean",
355
+ description: "Also collect content from iframes (merged, annotated with frameId \u2014 pair frame-local refs with that frameId). Default: false"
356
+ },
357
+ diff: {
358
+ type: "boolean",
359
+ description: "When true (default), returns {unchanged:true} instead of the full body if the page content is identical to your previous read \u2014 reuse the earlier content. Pass false to force full re-send."
360
+ },
361
+ compact: {
362
+ type: "boolean",
363
+ description: "Lossless output compaction (collapse empty wrappers etc., ~30-50% smaller). Default: true. Pass false for the verbose format."
247
364
  }
248
365
  },
249
366
  required: []
@@ -260,6 +377,10 @@ Tip: If the returned elements do not include the specific element you need, use
260
377
  type: "boolean",
261
378
  description: "Avoid focusing/activating tab/window for certain operations (best-effort). Default: false"
262
379
  },
380
+ fullResolution: {
381
+ type: "boolean",
382
+ description: 'For action="screenshot"/"zoom": skip the \u22641568px downscale of the returned image (default: false)'
383
+ },
263
384
  action: {
264
385
  type: "string",
265
386
  description: "Action to perform: left_click | right_click | double_click | triple_click | left_click_drag | scroll | scroll_to | type | key | fill | fill_form | hover | wait | resize_page | zoom | screenshot"
@@ -507,7 +628,11 @@ Tip: If the returned elements do not include the specific element you need, use
507
628
  height: { type: "number", description: "Height in pixels (default: 600)" },
508
629
  storeBase64: {
509
630
  type: "boolean",
510
- description: "return screenshot in base64 format (default: false) if you want to see the page, recommend set this to be true"
631
+ description: "Return the screenshot as an MCP image content block (default: false). Recommended when you want to SEE the page. The image is auto-downscaled to \u22641568px long edge (metadata reports imageScale vs the CSS viewport for coordinate math); pass fullResolution:true to skip downscaling."
632
+ },
633
+ fullResolution: {
634
+ type: "boolean",
635
+ description: "Skip the \u22641568px downscale for the returned image (default: false)"
511
636
  },
512
637
  fullPage: {
513
638
  type: "boolean",
@@ -595,6 +720,14 @@ Tip: If the returned elements do not include the specific element you need, use
595
720
  selector: {
596
721
  type: "string",
597
722
  description: "CSS selector to get content from a specific element. If provided, only content from this element will be returned"
723
+ },
724
+ raw: {
725
+ type: "boolean",
726
+ description: "Text mode returns reader-view content by default (navigation/footer/cookie-banner noise stripped, main content kept \u2014 fullTextChars vs returnedChars reported). Pass true for the unfiltered full text. Default: false"
727
+ },
728
+ diff: {
729
+ type: "boolean",
730
+ description: "When true (default), returns {unchanged:true} instead of the body if identical to your previous read of this tab \u2014 reuse the earlier content. Pass false to force full re-send."
598
731
  }
599
732
  },
600
733
  required: []
@@ -672,6 +805,18 @@ Tip: If the returned elements do not include the specific element you need, use
672
805
  tabId: {
673
806
  type: "number",
674
807
  description: "Optional target tab id. Defaults to the MCP work tab (background work mode) or the active tab."
808
+ },
809
+ limit: {
810
+ type: "number",
811
+ description: 'action="stop": return at most this many captured requests (default 100; paginate with offset)'
812
+ },
813
+ offset: {
814
+ type: "number",
815
+ description: 'action="stop": skip this many captured requests (default 0)'
816
+ },
817
+ countOnly: {
818
+ type: "boolean",
819
+ description: 'action="stop": return only counts/summary without the request array (default: false)'
675
820
  }
676
821
  },
677
822
  required: ["action"]
@@ -715,6 +860,18 @@ Tip: If the returned elements do not include the specific element you need, use
715
860
  excludeCurrentTabs: {
716
861
  type: "boolean",
717
862
  description: "When set to true, filters out URLs that are currently open in any browser tab. Useful for finding pages you've visited but don't have open anymore. (default: false)"
863
+ },
864
+ limit: {
865
+ type: "number",
866
+ description: "Return at most this many entries (default 100; pagination with offset)"
867
+ },
868
+ offset: {
869
+ type: "number",
870
+ description: "Skip this many entries before returning (default 0)"
871
+ },
872
+ countOnly: {
873
+ type: "boolean",
874
+ description: "Return only totalCount without the entries array (default: false)"
718
875
  }
719
876
  },
720
877
  required: []
@@ -1123,6 +1280,14 @@ Tip: If the returned elements do not include the specific element you need, use
1123
1280
  type: "number",
1124
1281
  description: "Maximum number of console messages to capture in snapshot mode (default: 100). If limit is provided, it takes precedence."
1125
1282
  },
1283
+ offset: {
1284
+ type: "number",
1285
+ description: "Skip this many messages before returning (pagination; default 0)"
1286
+ },
1287
+ countOnly: {
1288
+ type: "boolean",
1289
+ description: "Return only counts/summary without the message array (default: false)"
1290
+ },
1126
1291
  mode: {
1127
1292
  type: "string",
1128
1293
  enum: ["snapshot", "buffer"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auto-chrome-mcp-shared",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "author": "hangye (upstream), scalemaker-ship-it (scalemaker fork)",
5
5
  "main": "dist/index.js",
6
6
  "module": "./dist/index.mjs",