viyv-browser-mcp 0.6.7 → 0.7.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.js CHANGED
@@ -967,6 +967,18 @@ form_input \u2014 For setting form values (PREFERRED for forms)
967
967
  - submit: true \u2192 sets value + presses Enter + waits for navigation
968
968
  - Best for: search boxes, login forms, any form submission
969
969
 
970
+ form_fill \u2014 For setting MULTIPLE form values in one call
971
+ - Same semantics as form_input for each field
972
+ - Sequential processing (important for dependent fields like country \u2192 city)
973
+ - Max 50 fields per call
974
+ - Optional submit after all fields are set
975
+ - Best for: registration forms, admin panels with many fields
976
+
977
+ bulk_action \u2014 For repeating the SAME action on multiple elements
978
+ - Actions: click, check, uncheck, focus, scroll_to
979
+ - Max 200 refs per call
980
+ - Best for: checking/unchecking many checkboxes, clicking multiple buttons
981
+
970
982
  type \u2014 For raw text input into focused element
971
983
  - Requires element to be focused first (click it first)
972
984
  - Character-by-character with keyDown/keyUp events
@@ -978,11 +990,21 @@ key \u2014 For keyboard shortcuts and special keys
978
990
  - Use repeat parameter for multiple presses
979
991
  - Use for: keyboard navigation, shortcuts, special key combos
980
992
 
993
+ file_upload \u2014 For uploading files or dropping files onto elements
994
+ - File input (ref \u2192 <input type="file">): sets files via CDP
995
+ - Drag & drop (ref \u2192 non-input, or coordinate): simulates file drag via CDP
996
+ - Don't click file inputs \u2014 use file_upload instead
997
+ - Best for: file inputs, canvas apps (Canva, Figma), custom drop zones
998
+
981
999
  Common patterns:
982
- Form fill: find(input) \u2192 form_input(ref, value, submit: true)
1000
+ Single field: find(input) \u2192 form_input(ref, value, submit: true)
1001
+ Multi-field form: read_page \u2192 form_fill([{ref, value}, ...], submit: true)
1002
+ Batch checkboxes: read_page \u2192 bulk_action(refs[], "check")
983
1003
  Button click: find(button) \u2192 click(ref) \u2192 wait_for(navigation)
984
1004
  Dropdown: click(select ref) \u2192 key("ArrowDown ArrowDown Enter")
985
- Search: form_input(search input ref, query, submit: true)`
1005
+ Search: form_input(search input ref, query, submit: true)
1006
+ File upload: find(file input) \u2192 file_upload(ref, paths)
1007
+ File drop: find(canvas) \u2192 file_upload(ref, paths) or file_upload(coordinate, paths)`
986
1008
  },
987
1009
  navigation: {
988
1010
  title: "Navigation \u2014 How to navigate between pages",
@@ -1030,6 +1052,12 @@ find \u2192 Locate specific elements
1030
1052
  - Returns text + rect + ref for each match
1031
1053
  - Best for: finding specific values on page
1032
1054
 
1055
+ read_table \u2192 Structured table data (headers + rows)
1056
+ - Best for: admin panel tables, data grids, price lists
1057
+ - Supports HTML <table> and ARIA role="table"
1058
+ - Cell interactive elements include refs for follow-up actions
1059
+ - Max 500 rows
1060
+
1033
1061
  batch_fetch \u2192 HTTP requests with browser session
1034
1062
  - Best for: API endpoints, AJAX data, paginated results
1035
1063
  - Uses browser cookies/auth automatically
@@ -1210,18 +1238,26 @@ ${guide.content}` };
1210
1238
  import { z } from "zod";
1211
1239
 
1212
1240
  // src/tools/advanced/file-upload.ts
1213
- var FILE_UPLOAD_DESCRIPTION = `Upload local files to file input by ref. Use absolute paths. Don't click file inputs.
1214
- Returns: { uploaded, fileCount }`;
1215
- var FILE_UPLOAD_DETAIL = `Upload local files to a file input element on the page using absolute file paths.
1216
- Do not click on file input elements \u2014 clicking opens a native file picker dialog.
1217
- Instead, use read_page or find to locate the file input, then use this tool with its ref.
1241
+ var FILE_UPLOAD_DESCRIPTION = `Upload files to file input or drop files onto any element.
1242
+ For <input type="file">: use ref. For canvas/drop zones (Canva, Figma): use ref or coordinate.
1243
+ Returns: { uploaded/dropped, fileCount }`;
1244
+ var FILE_UPLOAD_DETAIL = `Upload or drop local files onto page elements using absolute file paths.
1245
+
1246
+ Two modes:
1247
+ 1. **File input** (ref \u2192 <input type="file">): Sets files via CDP. Don't click file inputs \u2014 use this tool instead.
1248
+ 2. **Drag & drop** (ref \u2192 non-input, or coordinate): Simulates file drag & drop via CDP.
1249
+ Use for canvas apps (Canva, Figma), custom drop zones, or any non-input upload area.
1250
+
1251
+ If both ref and coordinate are provided, ref takes priority.
1218
1252
  The paths must be absolute paths accessible from the machine running Chrome.`;
1219
1253
  var FILE_UPLOAD_RETURNS = `{
1220
- uploaded: boolean
1254
+ uploaded?: boolean // file input mode
1255
+ dropped?: boolean // drag & drop mode
1221
1256
  fileCount: number
1222
- ref: string
1257
+ ref?: string
1258
+ coordinate?: [number, number]
1223
1259
  }`;
1224
- var FILE_UPLOAD_RELATED = ["upload_image", "find", "read_page"];
1260
+ var FILE_UPLOAD_RELATED = ["upload_image", "find", "read_page", "drag"];
1225
1261
 
1226
1262
  // src/tools/advanced/gif-creator.ts
1227
1263
  var GIF_CREATOR_DESCRIPTION = `Record/export GIF. Actions: start_recording, stop_recording, export, clear.
@@ -1358,6 +1394,30 @@ var BATCH_FETCH_RETURNS = `{
1358
1394
  }`;
1359
1395
  var BATCH_FETCH_RELATED = ["javascript_exec", "read_network_requests", "sm_fetch"];
1360
1396
 
1397
+ // src/tools/core/bulk-action.ts
1398
+ var BULK_ACTION_DESCRIPTION = `Execute the same action on multiple elements by ref. Actions: click, check, uncheck, focus, scroll_to.
1399
+ Returns: { total, succeeded, failed, results[] }`;
1400
+ var BULK_ACTION_DETAIL = `Execute a single action across multiple element refs in one call.
1401
+ Designed for repetitive operations like checking/unchecking many checkboxes in admin panels.
1402
+
1403
+ Actions:
1404
+ - click: DOM click on each element
1405
+ - check: Set checkbox/radio to checked (skip if already checked)
1406
+ - uncheck: Set checkbox to unchecked (skip if already unchecked)
1407
+ - focus: Focus each element sequentially
1408
+ - scroll_to: Scroll each element into view
1409
+
1410
+ Operations execute sequentially to avoid DOM mutation race conditions.
1411
+ Maximum 200 refs per call. Disabled elements are reported as errors.
1412
+ Refs can span multiple frames (main page and iframes).`;
1413
+ var BULK_ACTION_RETURNS = `{
1414
+ total: number
1415
+ succeeded: number
1416
+ failed: number
1417
+ results: Array<{ ref: string, ok: boolean, error?: string }>
1418
+ }`;
1419
+ var BULK_ACTION_RELATED = ["click", "form_input", "form_fill", "find", "read_page"];
1420
+
1361
1421
  // src/tools/core/click.ts
1362
1422
  var CLICK_DESCRIPTION = `Click at coordinate or ref. Actions: left/right/double/triple_click. Modifiers: ctrl/shift/alt/cmd.
1363
1423
  Does NOT wait for navigation \u2014 use form_input(submit:true) for forms.
@@ -1411,6 +1471,43 @@ var FIND_RETURNS = `{
1411
1471
  }`;
1412
1472
  var FIND_RELATED = ["read_page", "click", "form_input", "page_outline"];
1413
1473
 
1474
+ // src/tools/core/form-fill.ts
1475
+ var FORM_FILL_DESCRIPTION = `Set values on multiple form elements in one call. Same semantics as form_input for each field.
1476
+ Returns: { total, succeeded, failed, results[] }`;
1477
+ var FORM_FILL_DETAIL = `Set values on multiple form elements in a single call.
1478
+ Each field uses the same value-setting logic as form_input (supports text inputs,
1479
+ textareas, selects, checkboxes, radio buttons, contenteditable, date inputs).
1480
+
1481
+ Fields are processed sequentially in array order (important for dependent fields
1482
+ like country \u2192 city selects). Maximum 50 fields per call.
1483
+
1484
+ Each field result includes verification (verified: true/false) indicating whether
1485
+ the value was accepted by the page.
1486
+
1487
+ Optional submit: if submit is true, the form is submitted after setting all fields
1488
+ (same as form_input submit behavior \u2014 requestSubmit or Enter key fallback).
1489
+ Submit is only attempted if at least one field succeeded.
1490
+ The submitRef defaults to the last field's ref if not specified.`;
1491
+ var FORM_FILL_RETURNS = `{
1492
+ total: number // Total fields attempted
1493
+ succeeded: number // Fields set successfully
1494
+ failed: number // Fields that failed
1495
+ results: Array<{
1496
+ ref: string
1497
+ set: boolean
1498
+ value?: string // For text/select fields
1499
+ checked?: boolean // For checkbox/radio
1500
+ selectedText?: string // For select fields
1501
+ verified: boolean
1502
+ error?: string // If set failed
1503
+ warning?: string // If verification concern
1504
+ }>
1505
+ submitted?: boolean // If submit was requested
1506
+ navigated?: boolean // If navigation occurred after submit
1507
+ url?: string // New URL after navigation
1508
+ }`;
1509
+ var FORM_FILL_RELATED = ["form_input", "bulk_action", "find", "read_page"];
1510
+
1414
1511
  // src/tools/core/form-input.ts
1415
1512
  var FORM_INPUT_DESCRIPTION = `Set value on form element by ref. Supports inputs, selects, checkboxes, radio, contenteditable.
1416
1513
  Use submit:true to submit and wait for navigation.
@@ -1483,6 +1580,42 @@ Useful for revealing tooltips, dropdown menus, or triggering hover states.`;
1483
1580
  var HOVER_RETURNS = `{ hovered: true }`;
1484
1581
  var HOVER_RELATED = ["click", "wait_for", "screenshot"];
1485
1582
 
1583
+ // src/tools/core/inspect.ts
1584
+ var INSPECT_DESCRIPTION = `Inspect element: computed styles, attributes, dimensions, DOM structure, images.
1585
+ Use ref from read_page/find or CSS selector. Specify sections to control output size.
1586
+ Returns: { identity, box, typography, visual, layout, attributes, dom, form, image, accessibility }`;
1587
+ var INSPECT_DETAIL = `Deep-inspect a single element for development/QA tasks.
1588
+
1589
+ Sections (pick what you need via sections param, default: identity box typography visual layout attributes):
1590
+ - identity: tag, id, classes, role, data-* attributes
1591
+ - box: bounding rect, margin, padding, border-width, box-sizing, overflow
1592
+ - typography: font-family/size/weight/style, line-height, letter-spacing, text-align, color (#hex)
1593
+ - visual: background-color, border (color/style/radius), opacity, box-shadow, cursor
1594
+ - layout: display, position, z-index, top/right/bottom/left, flex/grid properties
1595
+ - attributes: all HTML attributes as key-value pairs
1596
+ - dom: parent path, child summary, textContent (500 chars), innerHTML (1000 chars)
1597
+ - form: value, checked, disabled, readonly, required, validation constraints, validity state
1598
+ - image: src, naturalWidth/Height, alt, loaded state + actual image as content block (for img/canvas/svg/video/audio)
1599
+ - accessibility: accessible name, role, all aria-* attrs, focusable, tab index, contrast ratio (WCAG)
1600
+
1601
+ Use properties param to request additional CSS properties not in the default sections.
1602
+ All colors returned in #hex format.`;
1603
+ var INSPECT_RETURNS = `{
1604
+ // Only requested sections are returned
1605
+ identity?: { tag, id?, classes[], role?, dataAttributes{} }
1606
+ box?: { rect{x,y,width,height}, margin{top,right,bottom,left}, padding{...}, borderWidth{...}, boxSizing, overflow{x,y} }
1607
+ typography?: { fontFamily, fontSize, fontWeight, fontStyle, lineHeight, letterSpacing, textAlign, color }
1608
+ visual?: { backgroundColor, border{color,style,radius}, opacity, boxShadow, cursor }
1609
+ layout?: { display, position, zIndex, top?, right?, bottom?, left?, flex?{direction,justifyContent,alignItems,gap,wrap}, grid?{...} }
1610
+ attributes?: { [name]: value }
1611
+ dom?: { parentPath, childSummary, textContent, innerHTML }
1612
+ form?: { value?, checked?, disabled, readonly, required, validation{}, validity{} }
1613
+ image?: { src?, currentSrc?, naturalWidth?, naturalHeight?, alt?, complete?, svgMarkup?, videoWidth?, videoHeight?, duration?, paused?, muted? } // + image/frame content block
1614
+ accessibility?: { accessibleName, role, ariaAttributes{}, focusable, tabIndex, contrastRatio{ratio,aa,aaa,textColor,bgColor} }
1615
+ properties?: { [cssPropertyName]: value } // extra CSS properties if requested
1616
+ }`;
1617
+ var INSPECT_RELATED = ["read_page", "find", "screenshot"];
1618
+
1486
1619
  // src/tools/core/javascript-exec.ts
1487
1620
  var JAVASCRIPT_EXEC_DESCRIPTION = `Execute JavaScript in page context. Supports top-level await. Use file_path for large results.
1488
1621
  Returns: { result }`;
@@ -1579,6 +1712,32 @@ var READ_PAGE_RETURNS = `{
1579
1712
  }`;
1580
1713
  var READ_PAGE_RELATED = ["page_outline", "find", "get_page_text", "screenshot"];
1581
1714
 
1715
+ // src/tools/core/read-table.ts
1716
+ var READ_TABLE_DESCRIPTION = `Extract structured table data by ref. Supports <table> and ARIA role="table".
1717
+ Returns: { headers, rows, totalRows, truncated, tableRef }`;
1718
+ var READ_TABLE_DETAIL = `Extract structured data from a table element identified by ref.
1719
+
1720
+ Supports:
1721
+ - Standard HTML tables (table/thead/tbody/tfoot/tr/th/td)
1722
+ - ARIA role-based tables (role="table", role="row", role="cell", role="columnheader")
1723
+ - Nested tables are excluded (only the target table level is extracted)
1724
+
1725
+ The ref can point to a <table> element, a role="table" element, or an ancestor/descendant
1726
+ of a table. The tool searches upward first, then downward to find the nearest table.
1727
+
1728
+ Cells containing interactive elements (links, buttons, inputs) include their refs
1729
+ in the format "text [ref_N]" so the agent can interact with them.
1730
+
1731
+ Cell content is truncated to 200 characters. Maximum 500 rows returned.`;
1732
+ var READ_TABLE_RETURNS = `{
1733
+ headers: string[] // Column headers (from <thead>/<th> or role="columnheader")
1734
+ rows: string[][] // Data rows (each row is array of cell strings)
1735
+ totalRows: number // Total rows before truncation
1736
+ truncated: boolean // Whether rows were truncated
1737
+ tableRef: string // Ref of the resolved table element
1738
+ }`;
1739
+ var READ_TABLE_RELATED = ["read_page", "find", "form_input", "form_fill", "get_page_text"];
1740
+
1582
1741
  // src/tools/core/screenshot.ts
1583
1742
  var SCREENSHOT_DESCRIPTION = `Take screenshot. Use ref for element, ref+refTo for range. WebP q70 default.
1584
1743
  Prefer read_page/find for text data \u2014 screenshot only when visual verification needed.
@@ -3000,8 +3159,8 @@ Actions:
3000
3159
  Returns: url_pattern, selector, element_tag, text_preview, created_by, latest_comment, attachment_count, has_screenshots.
3001
3160
  - get: Get full thread details including all comments. Requires thread_id.
3002
3161
  Comments include attachment metadata and screenshot IDs (images not inline \u2014 use get_attachment to download).
3003
- - add: Create new thread on an element. Requires ref (from read_page) or selector + body.
3004
- - reply: Add comment to existing thread. Requires thread_id + body.
3162
+ - add: Create new thread on an element. Requires ref (from read_page) or selector + body. Optional attachments (base64 images).
3163
+ - reply: Add comment to existing thread. Requires thread_id + body. Optional attachments (base64 images).
3005
3164
  - resolve: Mark thread as resolved. Requires thread_id. Optional resolution_note.
3006
3165
  - reopen: Reopen a resolved thread. Requires thread_id.
3007
3166
  - complete: Archive/dismiss a thread (removes pin). Requires thread_id.
@@ -3213,6 +3372,36 @@ var findTool = {
3213
3372
  maxResults: z.coerce.number().min(1).max(50).optional().describe("Max results to return (default: 25, max: 50)")
3214
3373
  })
3215
3374
  };
3375
+ var inspectTool = {
3376
+ name: "inspect",
3377
+ description: INSPECT_DESCRIPTION,
3378
+ detail: INSPECT_DETAIL,
3379
+ returns: INSPECT_RETURNS,
3380
+ category: "core",
3381
+ related: INSPECT_RELATED,
3382
+ inputSchema: z.object({
3383
+ tabId: z.coerce.number().describe("Tab ID"),
3384
+ ref: z.string().optional().describe("Element ref from read_page or find"),
3385
+ selector: z.string().optional().describe("CSS selector (alternative to ref)"),
3386
+ sections: z.array(
3387
+ z.enum([
3388
+ "identity",
3389
+ "box",
3390
+ "typography",
3391
+ "visual",
3392
+ "layout",
3393
+ "attributes",
3394
+ "dom",
3395
+ "form",
3396
+ "image",
3397
+ "accessibility"
3398
+ ])
3399
+ ).optional().describe(
3400
+ "Sections to return (default: identity, box, typography, visual, layout, attributes)"
3401
+ ),
3402
+ properties: z.array(z.string()).optional().describe('Additional CSS property names to include (e.g. ["gap", "grid-template-columns"])')
3403
+ })
3404
+ };
3216
3405
  var formInputTool = {
3217
3406
  name: "form_input",
3218
3407
  description: FORM_INPUT_DESCRIPTION,
@@ -3230,6 +3419,51 @@ var formInputTool = {
3230
3419
  listOptions: z.boolean().optional().describe("List select options without changing selection")
3231
3420
  })
3232
3421
  };
3422
+ var formFillTool = {
3423
+ name: "form_fill",
3424
+ description: FORM_FILL_DESCRIPTION,
3425
+ detail: FORM_FILL_DETAIL,
3426
+ returns: FORM_FILL_RETURNS,
3427
+ category: "core",
3428
+ related: FORM_FILL_RELATED,
3429
+ inputSchema: z.object({
3430
+ tabId: z.coerce.number().describe("Tab ID"),
3431
+ fields: z.array(
3432
+ z.object({
3433
+ ref: z.string().describe("Element reference ID"),
3434
+ value: z.union([z.string(), z.boolean(), z.coerce.number()]).describe("Value to set")
3435
+ })
3436
+ ).min(1).max(50).describe("Array of {ref, value} objects"),
3437
+ submit: z.boolean().optional().describe("Submit the form after setting all values"),
3438
+ submitRef: z.string().optional().describe("Ref of element to use for submit (default: last field)")
3439
+ })
3440
+ };
3441
+ var bulkActionTool = {
3442
+ name: "bulk_action",
3443
+ description: BULK_ACTION_DESCRIPTION,
3444
+ detail: BULK_ACTION_DETAIL,
3445
+ returns: BULK_ACTION_RETURNS,
3446
+ category: "core",
3447
+ related: BULK_ACTION_RELATED,
3448
+ inputSchema: z.object({
3449
+ tabId: z.coerce.number().describe("Tab ID"),
3450
+ refs: z.array(z.string()).min(1).max(200).describe("Array of element reference IDs"),
3451
+ action: z.enum(["click", "check", "uncheck", "focus", "scroll_to"]).describe("Action to perform on each element")
3452
+ })
3453
+ };
3454
+ var readTableTool = {
3455
+ name: "read_table",
3456
+ description: READ_TABLE_DESCRIPTION,
3457
+ detail: READ_TABLE_DETAIL,
3458
+ returns: READ_TABLE_RETURNS,
3459
+ category: "core",
3460
+ related: READ_TABLE_RELATED,
3461
+ inputSchema: z.object({
3462
+ tabId: z.coerce.number().describe("Tab ID"),
3463
+ ref: z.string().describe("Element reference ID pointing to or containing a table"),
3464
+ maxRows: z.coerce.number().min(1).max(500).optional().describe("Max rows to return (default: 500)")
3465
+ })
3466
+ };
3233
3467
  var javascriptExecTool = {
3234
3468
  name: "javascript_exec",
3235
3469
  description: JAVASCRIPT_EXEC_DESCRIPTION,
@@ -3537,8 +3771,11 @@ var fileUploadTool = {
3537
3771
  related: FILE_UPLOAD_RELATED,
3538
3772
  inputSchema: z.object({
3539
3773
  tabId: z.coerce.number().describe("Tab ID"),
3540
- ref: z.string().describe("Element reference ID of the file input"),
3541
- paths: z.array(z.string()).min(1).describe("Absolute file paths to upload")
3774
+ ref: z.string().describe("Element reference ID (file input or drop target)").optional(),
3775
+ coordinate: z.tuple([z.coerce.number(), z.coerce.number()]).describe("Drop target coordinates [x, y]").optional(),
3776
+ paths: z.array(z.string()).min(1).describe("Absolute file paths to upload/drop")
3777
+ }).refine((d) => d.ref || d.coordinate, {
3778
+ message: 'Either "ref" or "coordinate" must be provided'
3542
3779
  })
3543
3780
  };
3544
3781
  var agentTabAssignTool = {
@@ -3637,6 +3874,15 @@ var feedbackTool = {
3637
3874
  body: z.string().optional().describe("Comment text (for add/reply)"),
3638
3875
  thread_id: z.string().optional().describe("Thread ID (for reply/resolve/reopen/complete)"),
3639
3876
  resolution_note: z.string().optional().describe("Resolution note (for resolve)"),
3877
+ attachments: z.array(
3878
+ z.object({
3879
+ filename: z.string(),
3880
+ base64: z.string(),
3881
+ mime_type: z.string(),
3882
+ width: z.coerce.number(),
3883
+ height: z.coerce.number()
3884
+ })
3885
+ ).optional().describe("Image attachments as base64 (for add/reply, max 5)"),
3640
3886
  attachment_id: z.string().optional().describe("Attachment or screenshot ID (for get_attachment)"),
3641
3887
  status: z.enum(["open", "resolved", "completed", "all"]).optional().describe("Status filter (for list, default: open)")
3642
3888
  })
@@ -4464,7 +4710,11 @@ var allTools = [
4464
4710
  dragTool,
4465
4711
  readPageTool,
4466
4712
  findTool,
4713
+ inspectTool,
4467
4714
  formInputTool,
4715
+ formFillTool,
4716
+ bulkActionTool,
4717
+ readTableTool,
4468
4718
  javascriptExecTool,
4469
4719
  waitForTool,
4470
4720
  getPageTextTool,