@agimon-ai/browse-tool 0.2.0 → 0.2.2

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.
@@ -208,7 +208,35 @@ const ContentAction = {
208
208
  PRESS_KEY: "pressKey",
209
209
  WAIT_FOR: "waitFor"
210
210
  };
211
+ const DEFAULT_TOOL_TIMEOUT_MS = 18e4;
211
212
  const VALID_ACTIONS = new Set(Object.values(ContentAction));
213
+ function extractTelemetryContext(params) {
214
+ const telemetry = params.__browseToolTelemetry;
215
+ if (!telemetry || typeof telemetry !== "object") {
216
+ return void 0;
217
+ }
218
+ const traceId = typeof telemetry.traceId === "string" ? telemetry.traceId : void 0;
219
+ const spanId = typeof telemetry.spanId === "string" ? telemetry.spanId : void 0;
220
+ if (!traceId || !spanId) {
221
+ return void 0;
222
+ }
223
+ return { traceId, spanId };
224
+ }
225
+ async function emitTelemetry(level, message, action, telemetryContext) {
226
+ try {
227
+ await chrome.runtime.sendMessage({
228
+ type: "BROWSER_TELEMETRY_EVENT",
229
+ level,
230
+ message,
231
+ context: telemetryContext,
232
+ attributes: {
233
+ "browse_tool.content.action": action,
234
+ "browse_tool.page.url": location.href
235
+ }
236
+ });
237
+ } catch {
238
+ }
239
+ }
212
240
  function validateMessage(message) {
213
241
  if (!message || typeof message !== "object") return null;
214
242
  const msg = message;
@@ -229,7 +257,15 @@ chrome.runtime.onMessage.addListener(
229
257
  });
230
258
  return true;
231
259
  }
232
- handleContentAction(validated).then((result) => sendResponse({ success: true, result })).catch((error) => sendResponse({ success: false, error: error.message }));
260
+ const telemetryContext = extractTelemetryContext(validated.params);
261
+ void emitTelemetry("debug", "content action received", validated.action, telemetryContext);
262
+ handleContentAction(validated).then((result) => {
263
+ void emitTelemetry("debug", "content action completed", validated.action, telemetryContext);
264
+ sendResponse({ success: true, result });
265
+ }).catch((error) => {
266
+ void emitTelemetry("error", error.message, validated.action, telemetryContext);
267
+ sendResponse({ success: false, error: error.message });
268
+ });
233
269
  return true;
234
270
  }
235
271
  );
@@ -312,8 +348,13 @@ async function handleType(params) {
312
348
  }
313
349
  async function handleEvaluateScript(params) {
314
350
  const script = params.script;
315
- const fn = new Function(script);
316
- return fn();
351
+ try {
352
+ return await Promise.resolve((0, eval)(script));
353
+ } catch (error) {
354
+ throw new Error(error instanceof Error ? error.message : "Script execution failed", {
355
+ cause: error
356
+ });
357
+ }
317
358
  }
318
359
  async function handleGetElementInfo(params) {
319
360
  const locator = params;
@@ -411,7 +452,7 @@ async function handleWaitFor(params) {
411
452
  const selector = params.selector;
412
453
  const text = params.text;
413
454
  const state = params.state || "visible";
414
- const timeout = params.timeout || 3e4;
455
+ const timeout = params.timeout || DEFAULT_TOOL_TIMEOUT_MS;
415
456
  const startTime = Date.now();
416
457
  while (Date.now() - startTime < timeout) {
417
458
  if (selector) {
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sources":["../../src/extension/content/element-locator.ts","../../src/extension/content/accessibility-tree.ts","../../src/extension/content/index.ts"],"sourcesContent":["/**\n * Element Locator - Strategies for finding elements in the DOM\n *\n * Supports multiple location strategies:\n * - CSS selector\n * - XPath\n * - Text content\n * - Accessibility UID (from snapshot)\n */\n\nexport interface ElementLocator {\n selector?: string;\n xpath?: string;\n text?: string;\n uid?: string;\n role?: string;\n}\n\nconst uidToElement = new Map<string, WeakRef<Element>>();\nlet uidCounter = 0;\n\nexport function assignUid(element: Element): string {\n const uid = `e${++uidCounter}`;\n uidToElement.set(uid, new WeakRef(element));\n return uid;\n}\n\nexport function getElementByUid(uid: string): Element | null {\n const ref = uidToElement.get(uid);\n return ref?.deref() || null;\n}\n\nexport function clearUidMap(): void {\n uidToElement.clear();\n uidCounter = 0;\n}\n\nexport async function locateElement(locator: ElementLocator): Promise<Element | null> {\n // Try UID first (most precise)\n if (locator.uid) {\n const element = getElementByUid(locator.uid);\n if (element) return element;\n }\n\n // Try CSS selector\n if (locator.selector) {\n const element = document.querySelector(locator.selector);\n if (element) return element;\n }\n\n // Try XPath\n if (locator.xpath) {\n const result = document.evaluate(locator.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n if (result.singleNodeValue instanceof Element) {\n return result.singleNodeValue;\n }\n }\n\n // Try text content\n if (locator.text) {\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {\n acceptNode(node) {\n const el = node as Element;\n if (el.textContent?.includes(locator.text!)) {\n return NodeFilter.FILTER_ACCEPT;\n }\n return NodeFilter.FILTER_SKIP;\n },\n });\n const node = walker.nextNode();\n if (node instanceof Element) {\n return node;\n }\n }\n\n // Try role-based (ARIA)\n if (locator.role) {\n const element = document.querySelector(`[role=\"${locator.role}\"]`);\n if (element) return element;\n }\n\n return null;\n}\n","/**\n * Accessibility Tree Builder\n *\n * Generates an accessibility snapshot of the page,\n * similar to Playwright's accessibility tree format.\n */\n\nimport { assignUid, clearUidMap } from './element-locator.js';\n\nexport interface AccessibilityNode {\n uid: string;\n role: string;\n name?: string;\n value?: string;\n description?: string;\n children?: AccessibilityNode[];\n focused?: boolean;\n disabled?: boolean;\n checked?: boolean | 'mixed';\n selected?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n}\n\nexport function buildAccessibilityTree(): AccessibilityNode {\n // Clear previous UID assignments\n clearUidMap();\n\n const root = buildNode(document.body, 0);\n return root || { uid: 'root', role: 'none', name: 'Empty page' };\n}\n\nfunction buildNode(element: Element, depth: number): AccessibilityNode | null {\n // Skip hidden elements\n const style = getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return null;\n }\n\n const role = getRole(element);\n const name = getAccessibleName(element);\n const uid = assignUid(element);\n\n // Build children\n const children: AccessibilityNode[] = [];\n for (const child of element.children) {\n const childNode = buildNode(child, depth + 1);\n if (childNode) {\n children.push(childNode);\n }\n }\n\n // Skip non-semantic containers with no accessible name\n if (role === 'none' && !name && children.length === 1) {\n return children[0];\n }\n\n const node: AccessibilityNode = {\n uid,\n role,\n };\n\n if (name) node.name = name;\n if (children.length > 0) node.children = children;\n\n // Add state properties\n addStateProperties(element, node);\n\n return node;\n}\n\nfunction getRole(element: Element): string {\n // Explicit ARIA role\n const ariaRole = element.getAttribute('role');\n if (ariaRole) return ariaRole;\n\n // Implicit roles based on tag name\n const tagName = element.tagName.toLowerCase();\n const roleMap: Record<string, string> = {\n a: element.hasAttribute('href') ? 'link' : 'none',\n article: 'article',\n aside: 'complementary',\n button: 'button',\n footer: 'contentinfo',\n form: 'form',\n h1: 'heading',\n h2: 'heading',\n h3: 'heading',\n h4: 'heading',\n h5: 'heading',\n h6: 'heading',\n header: 'banner',\n img: 'img',\n input: getInputRole(element as HTMLInputElement),\n li: 'listitem',\n main: 'main',\n nav: 'navigation',\n ol: 'list',\n option: 'option',\n progress: 'progressbar',\n section: element.hasAttribute('aria-label') ? 'region' : 'none',\n select: 'combobox',\n table: 'table',\n tbody: 'rowgroup',\n td: 'cell',\n textarea: 'textbox',\n th: 'columnheader',\n tr: 'row',\n ul: 'list',\n };\n\n return roleMap[tagName] || 'none';\n}\n\nfunction getInputRole(input: HTMLInputElement): string {\n const type = (input.type || 'text').toLowerCase();\n const inputRoles: Record<string, string> = {\n button: 'button',\n checkbox: 'checkbox',\n email: 'textbox',\n number: 'spinbutton',\n password: 'textbox',\n radio: 'radio',\n range: 'slider',\n search: 'searchbox',\n submit: 'button',\n tel: 'textbox',\n text: 'textbox',\n url: 'textbox',\n };\n return inputRoles[type] || 'textbox';\n}\n\nfunction getAccessibleName(element: Element): string | undefined {\n // aria-label\n const ariaLabel = element.getAttribute('aria-label');\n if (ariaLabel) return ariaLabel;\n\n // aria-labelledby\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const labels = labelledBy\n .split(' ')\n .map((id) => document.getElementById(id)?.textContent)\n .filter(Boolean)\n .join(' ');\n if (labels) return labels;\n }\n\n // For inputs, check associated label\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n const id = element.id;\n if (id) {\n const label = document.querySelector(`label[for=\"${id}\"]`);\n if (label?.textContent) return label.textContent.trim();\n }\n }\n\n // Text content for certain elements\n const tagName = element.tagName.toLowerCase();\n if (['button', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'label', 'option'].includes(tagName)) {\n const text = element.textContent?.trim();\n if (text && text.length < 100) return text;\n }\n\n // Alt text for images\n if (element instanceof HTMLImageElement && element.alt) {\n return element.alt;\n }\n\n // Placeholder for inputs\n if (element instanceof HTMLInputElement && element.placeholder) {\n return element.placeholder;\n }\n\n return undefined;\n}\n\nfunction addStateProperties(element: Element, node: AccessibilityNode): void {\n // Focus state\n if (document.activeElement === element) {\n node.focused = true;\n }\n\n // Disabled state\n if ((element as HTMLInputElement).disabled) {\n node.disabled = true;\n }\n\n // Checked state\n if (element instanceof HTMLInputElement) {\n if (element.type === 'checkbox' || element.type === 'radio') {\n node.checked = element.indeterminate ? 'mixed' : element.checked;\n }\n }\n\n // Selected state\n if (element instanceof HTMLOptionElement) {\n node.selected = element.selected;\n }\n\n // Expanded state\n const ariaExpanded = element.getAttribute('aria-expanded');\n if (ariaExpanded) {\n node.expanded = ariaExpanded === 'true';\n }\n\n // Heading level\n const headingMatch = element.tagName.match(/^H([1-6])$/);\n if (headingMatch) {\n node.level = Number.parseInt(headingMatch[1], 10);\n }\n\n // Pressed state\n const ariaPressed = element.getAttribute('aria-pressed');\n if (ariaPressed) {\n node.pressed = ariaPressed === 'mixed' ? 'mixed' : ariaPressed === 'true';\n }\n}\n","/**\n * Content Script - DOM Interaction Layer\n *\n * Runs in the context of web pages and provides DOM manipulation\n * capabilities for browser automation tools.\n *\n * NOTE: This file must be self-contained (no imports from shared modules)\n * because Chrome content scripts cannot use ES modules.\n */\n\nimport { buildAccessibilityTree } from './accessibility-tree.js';\nimport { type ElementLocator, locateElement } from './element-locator.js';\n\n/**\n * Content action constants - inlined to avoid shared module imports\n */\nconst ContentAction = {\n CLICK: 'click',\n FILL: 'fill',\n TYPE: 'type',\n GET_SNAPSHOT: 'getSnapshot',\n EVALUATE_SCRIPT: 'evaluateScript',\n GET_ELEMENT_INFO: 'getElementInfo',\n HOVER: 'hover',\n SELECT: 'select',\n DRAG: 'drag',\n PRESS_KEY: 'pressKey',\n WAIT_FOR: 'waitFor',\n} as const;\n\ntype ContentActionType = (typeof ContentAction)[keyof typeof ContentAction];\n\ninterface ContentMessage {\n action: ContentActionType;\n params: Record<string, unknown>;\n}\n\ninterface ContentResponse {\n success: boolean;\n result?: unknown;\n error?: string;\n}\n\nconst VALID_ACTIONS = new Set(Object.values(ContentAction));\n\nfunction validateMessage(message: unknown): ContentMessage | null {\n if (!message || typeof message !== 'object') return null;\n const msg = message as Record<string, unknown>;\n if (typeof msg.action !== 'string' || !VALID_ACTIONS.has(msg.action as ContentActionType)) return null;\n if (msg.params !== undefined && (typeof msg.params !== 'object' || msg.params === null)) return null;\n return {\n action: msg.action as ContentActionType,\n params: (msg.params as Record<string, unknown>) || {},\n };\n}\n\nchrome.runtime.onMessage.addListener(\n (message: unknown, _sender: chrome.runtime.MessageSender, sendResponse: (response: ContentResponse) => void) => {\n const validated = validateMessage(message);\n if (!validated) {\n sendResponse({\n success: false,\n error: 'Invalid message format: missing or invalid action',\n });\n return true;\n }\n\n handleContentAction(validated)\n .then((result) => sendResponse({ success: true, result }))\n .catch((error: Error) => sendResponse({ success: false, error: error.message }));\n return true; // Async response\n },\n);\n\nasync function handleContentAction(message: ContentMessage): Promise<unknown> {\n const { action, params } = message;\n\n switch (action) {\n case ContentAction.CLICK:\n return handleClick(params);\n case ContentAction.FILL:\n return handleFill(params);\n case ContentAction.TYPE:\n return handleType(params);\n case ContentAction.GET_SNAPSHOT:\n return buildAccessibilityTree();\n case ContentAction.EVALUATE_SCRIPT:\n return handleEvaluateScript(params);\n case ContentAction.GET_ELEMENT_INFO:\n return handleGetElementInfo(params);\n case ContentAction.HOVER:\n return handleHover(params);\n case ContentAction.SELECT:\n return handleSelect(params);\n case ContentAction.DRAG:\n return handleDrag(params);\n case ContentAction.PRESS_KEY:\n return handlePressKey(params);\n case ContentAction.WAIT_FOR:\n return handleWaitFor(params);\n }\n}\n\nasync function handleClick(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n // Scroll element into view\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n // Simulate mouse events for realistic click\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n\n element.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('click', { bubbles: true, clientX: x, clientY: y }));\n}\n\nasync function handleFill(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const value = params.value as string;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) {\n throw new Error('Element is not an input or textarea');\n }\n\n // Focus and clear\n element.focus();\n element.value = '';\n\n // Set value and dispatch events\n element.value = value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n}\n\nasync function handleType(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const text = params.text as string;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (element instanceof HTMLElement) {\n element.focus();\n }\n\n // Type character by character\n for (const char of text) {\n element.dispatchEvent(new KeyboardEvent('keydown', { key: char, bubbles: true }));\n element.dispatchEvent(new KeyboardEvent('keypress', { key: char, bubbles: true }));\n\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n element.value += char;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n }\n\n element.dispatchEvent(new KeyboardEvent('keyup', { key: char, bubbles: true }));\n }\n}\n\nasync function handleEvaluateScript(params: Record<string, unknown>): Promise<unknown> {\n const script = params.script as string;\n // Use Function constructor to evaluate script in page context\n const fn = new Function(script);\n return fn();\n}\n\nasync function handleGetElementInfo(params: Record<string, unknown>): Promise<unknown> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id,\n className: element.className,\n textContent: element.textContent?.substring(0, 100),\n rect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n };\n}\n\nasync function handleHover(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n\n element.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mouseover', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mousemove', { bubbles: true, clientX: x, clientY: y }));\n}\n\nasync function handleSelect(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const value = params.value as string | string[];\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (!(element instanceof HTMLSelectElement)) {\n throw new Error('Element is not a select element');\n }\n\n const values = Array.isArray(value) ? value : [value];\n\n for (const option of element.options) {\n option.selected = values.includes(option.value) || values.includes(option.text);\n }\n\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n}\n\nasync function handleDrag(params: Record<string, unknown>): Promise<void> {\n const sourceLocator = params.source as ElementLocator;\n const targetLocator = params.target as ElementLocator;\n\n const sourceElement = await locateElement(sourceLocator);\n const targetElement = await locateElement(targetLocator);\n\n if (!sourceElement) {\n throw new Error('Source element not found');\n }\n\n if (!targetElement) {\n throw new Error('Target element not found');\n }\n\n const sourceRect = sourceElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n\n const sourceX = sourceRect.left + sourceRect.width / 2;\n const sourceY = sourceRect.top + sourceRect.height / 2;\n const targetX = targetRect.left + targetRect.width / 2;\n const targetY = targetRect.top + targetRect.height / 2;\n\n sourceElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, clientX: sourceX, clientY: sourceY }));\n sourceElement.dispatchEvent(new MouseEvent('dragstart', { bubbles: true, clientX: sourceX, clientY: sourceY }));\n\n targetElement.dispatchEvent(new MouseEvent('dragenter', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('dragover', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('drop', { bubbles: true, clientX: targetX, clientY: targetY }));\n\n sourceElement.dispatchEvent(new MouseEvent('dragend', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, clientX: targetX, clientY: targetY }));\n}\n\nasync function handlePressKey(params: Record<string, unknown>): Promise<void> {\n const key = params.key as string;\n const modifiers = params.modifiers as string[] | undefined;\n\n const eventInit: KeyboardEventInit = {\n key,\n bubbles: true,\n ctrlKey: modifiers?.includes('Control') || modifiers?.includes('Ctrl'),\n shiftKey: modifiers?.includes('Shift'),\n altKey: modifiers?.includes('Alt'),\n metaKey: modifiers?.includes('Meta') || modifiers?.includes('Command'),\n };\n\n const activeElement = document.activeElement || document.body;\n activeElement.dispatchEvent(new KeyboardEvent('keydown', eventInit));\n activeElement.dispatchEvent(new KeyboardEvent('keypress', eventInit));\n activeElement.dispatchEvent(new KeyboardEvent('keyup', eventInit));\n}\n\nasync function handleWaitFor(params: Record<string, unknown>): Promise<void> {\n const selector = params.selector as string | undefined;\n const text = params.text as string | undefined;\n const state = (params.state as string) || 'visible';\n const timeout = (params.timeout as number) || 30000;\n\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n if (selector) {\n const element = document.querySelector(selector);\n if (state === 'visible' && element && isVisible(element)) {\n return;\n }\n if (state === 'hidden' && (!element || !isVisible(element))) {\n return;\n }\n if (state === 'attached' && element) {\n return;\n }\n if (state === 'detached' && !element) {\n return;\n }\n }\n\n if (text) {\n const found = document.body.textContent?.includes(text);\n if (found) {\n return;\n }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(`Wait condition not met within ${timeout}ms`);\n}\n\nfunction isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';\n}\n"],"names":["node"],"mappings":"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"}
1
+ {"version":3,"file":"content.js","sources":["../../src/extension/content/element-locator.ts","../../src/extension/content/accessibility-tree.ts","../../src/extension/content/index.ts"],"sourcesContent":["/**\n * Element Locator - Strategies for finding elements in the DOM\n *\n * Supports multiple location strategies:\n * - CSS selector\n * - XPath\n * - Text content\n * - Accessibility UID (from snapshot)\n */\n\nexport interface ElementLocator {\n selector?: string;\n xpath?: string;\n text?: string;\n uid?: string;\n role?: string;\n}\n\nconst uidToElement = new Map<string, WeakRef<Element>>();\nlet uidCounter = 0;\n\nexport function assignUid(element: Element): string {\n const uid = `e${++uidCounter}`;\n uidToElement.set(uid, new WeakRef(element));\n return uid;\n}\n\nexport function getElementByUid(uid: string): Element | null {\n const ref = uidToElement.get(uid);\n return ref?.deref() || null;\n}\n\nexport function clearUidMap(): void {\n uidToElement.clear();\n uidCounter = 0;\n}\n\nexport async function locateElement(locator: ElementLocator): Promise<Element | null> {\n // Try UID first (most precise)\n if (locator.uid) {\n const element = getElementByUid(locator.uid);\n if (element) return element;\n }\n\n // Try CSS selector\n if (locator.selector) {\n const element = document.querySelector(locator.selector);\n if (element) return element;\n }\n\n // Try XPath\n if (locator.xpath) {\n const result = document.evaluate(locator.xpath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);\n if (result.singleNodeValue instanceof Element) {\n return result.singleNodeValue;\n }\n }\n\n // Try text content\n if (locator.text) {\n const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT, {\n acceptNode(node) {\n const el = node as Element;\n if (el.textContent?.includes(locator.text!)) {\n return NodeFilter.FILTER_ACCEPT;\n }\n return NodeFilter.FILTER_SKIP;\n },\n });\n const node = walker.nextNode();\n if (node instanceof Element) {\n return node;\n }\n }\n\n // Try role-based (ARIA)\n if (locator.role) {\n const element = document.querySelector(`[role=\"${locator.role}\"]`);\n if (element) return element;\n }\n\n return null;\n}\n","/**\n * Accessibility Tree Builder\n *\n * Generates an accessibility snapshot of the page,\n * similar to Playwright's accessibility tree format.\n */\n\nimport { assignUid, clearUidMap } from './element-locator.js';\n\nexport interface AccessibilityNode {\n uid: string;\n role: string;\n name?: string;\n value?: string;\n description?: string;\n children?: AccessibilityNode[];\n focused?: boolean;\n disabled?: boolean;\n checked?: boolean | 'mixed';\n selected?: boolean;\n expanded?: boolean;\n level?: number;\n pressed?: boolean | 'mixed';\n}\n\nexport function buildAccessibilityTree(): AccessibilityNode {\n // Clear previous UID assignments\n clearUidMap();\n\n const root = buildNode(document.body, 0);\n return root || { uid: 'root', role: 'none', name: 'Empty page' };\n}\n\nfunction buildNode(element: Element, depth: number): AccessibilityNode | null {\n // Skip hidden elements\n const style = getComputedStyle(element);\n if (style.display === 'none' || style.visibility === 'hidden') {\n return null;\n }\n\n const role = getRole(element);\n const name = getAccessibleName(element);\n const uid = assignUid(element);\n\n // Build children\n const children: AccessibilityNode[] = [];\n for (const child of element.children) {\n const childNode = buildNode(child, depth + 1);\n if (childNode) {\n children.push(childNode);\n }\n }\n\n // Skip non-semantic containers with no accessible name\n if (role === 'none' && !name && children.length === 1) {\n return children[0];\n }\n\n const node: AccessibilityNode = {\n uid,\n role,\n };\n\n if (name) node.name = name;\n if (children.length > 0) node.children = children;\n\n // Add state properties\n addStateProperties(element, node);\n\n return node;\n}\n\nfunction getRole(element: Element): string {\n // Explicit ARIA role\n const ariaRole = element.getAttribute('role');\n if (ariaRole) return ariaRole;\n\n // Implicit roles based on tag name\n const tagName = element.tagName.toLowerCase();\n const roleMap: Record<string, string> = {\n a: element.hasAttribute('href') ? 'link' : 'none',\n article: 'article',\n aside: 'complementary',\n button: 'button',\n footer: 'contentinfo',\n form: 'form',\n h1: 'heading',\n h2: 'heading',\n h3: 'heading',\n h4: 'heading',\n h5: 'heading',\n h6: 'heading',\n header: 'banner',\n img: 'img',\n input: getInputRole(element as HTMLInputElement),\n li: 'listitem',\n main: 'main',\n nav: 'navigation',\n ol: 'list',\n option: 'option',\n progress: 'progressbar',\n section: element.hasAttribute('aria-label') ? 'region' : 'none',\n select: 'combobox',\n table: 'table',\n tbody: 'rowgroup',\n td: 'cell',\n textarea: 'textbox',\n th: 'columnheader',\n tr: 'row',\n ul: 'list',\n };\n\n return roleMap[tagName] || 'none';\n}\n\nfunction getInputRole(input: HTMLInputElement): string {\n const type = (input.type || 'text').toLowerCase();\n const inputRoles: Record<string, string> = {\n button: 'button',\n checkbox: 'checkbox',\n email: 'textbox',\n number: 'spinbutton',\n password: 'textbox',\n radio: 'radio',\n range: 'slider',\n search: 'searchbox',\n submit: 'button',\n tel: 'textbox',\n text: 'textbox',\n url: 'textbox',\n };\n return inputRoles[type] || 'textbox';\n}\n\nfunction getAccessibleName(element: Element): string | undefined {\n // aria-label\n const ariaLabel = element.getAttribute('aria-label');\n if (ariaLabel) return ariaLabel;\n\n // aria-labelledby\n const labelledBy = element.getAttribute('aria-labelledby');\n if (labelledBy) {\n const labels = labelledBy\n .split(' ')\n .map((id) => document.getElementById(id)?.textContent)\n .filter(Boolean)\n .join(' ');\n if (labels) return labels;\n }\n\n // For inputs, check associated label\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n const id = element.id;\n if (id) {\n const label = document.querySelector(`label[for=\"${id}\"]`);\n if (label?.textContent) return label.textContent.trim();\n }\n }\n\n // Text content for certain elements\n const tagName = element.tagName.toLowerCase();\n if (['button', 'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'label', 'option'].includes(tagName)) {\n const text = element.textContent?.trim();\n if (text && text.length < 100) return text;\n }\n\n // Alt text for images\n if (element instanceof HTMLImageElement && element.alt) {\n return element.alt;\n }\n\n // Placeholder for inputs\n if (element instanceof HTMLInputElement && element.placeholder) {\n return element.placeholder;\n }\n\n return undefined;\n}\n\nfunction addStateProperties(element: Element, node: AccessibilityNode): void {\n // Focus state\n if (document.activeElement === element) {\n node.focused = true;\n }\n\n // Disabled state\n if ((element as HTMLInputElement).disabled) {\n node.disabled = true;\n }\n\n // Checked state\n if (element instanceof HTMLInputElement) {\n if (element.type === 'checkbox' || element.type === 'radio') {\n node.checked = element.indeterminate ? 'mixed' : element.checked;\n }\n }\n\n // Selected state\n if (element instanceof HTMLOptionElement) {\n node.selected = element.selected;\n }\n\n // Expanded state\n const ariaExpanded = element.getAttribute('aria-expanded');\n if (ariaExpanded) {\n node.expanded = ariaExpanded === 'true';\n }\n\n // Heading level\n const headingMatch = element.tagName.match(/^H([1-6])$/);\n if (headingMatch) {\n node.level = Number.parseInt(headingMatch[1], 10);\n }\n\n // Pressed state\n const ariaPressed = element.getAttribute('aria-pressed');\n if (ariaPressed) {\n node.pressed = ariaPressed === 'mixed' ? 'mixed' : ariaPressed === 'true';\n }\n}\n","/**\n * Content Script - DOM Interaction Layer\n *\n * Runs in the context of web pages and provides DOM manipulation\n * capabilities for browser automation tools.\n *\n * NOTE: This file must be self-contained (no imports from shared modules)\n * because Chrome content scripts cannot use ES modules.\n */\n\nimport { buildAccessibilityTree } from './accessibility-tree.js';\nimport { type ElementLocator, locateElement } from './element-locator.js';\n\n/**\n * Content action constants - inlined to avoid shared module imports\n */\nconst ContentAction = {\n CLICK: 'click',\n FILL: 'fill',\n TYPE: 'type',\n GET_SNAPSHOT: 'getSnapshot',\n EVALUATE_SCRIPT: 'evaluateScript',\n GET_ELEMENT_INFO: 'getElementInfo',\n HOVER: 'hover',\n SELECT: 'select',\n DRAG: 'drag',\n PRESS_KEY: 'pressKey',\n WAIT_FOR: 'waitFor',\n} as const;\n\nconst DEFAULT_TOOL_TIMEOUT_MS = 180_000;\n\ntype ContentActionType = (typeof ContentAction)[keyof typeof ContentAction];\n\ninterface ContentMessage {\n action: ContentActionType;\n params: Record<string, unknown>;\n}\n\ninterface TelemetryContext {\n traceId?: string;\n spanId?: string;\n}\n\ninterface ContentResponse {\n success: boolean;\n result?: unknown;\n error?: string;\n}\n\nconst VALID_ACTIONS = new Set(Object.values(ContentAction));\n\nfunction extractTelemetryContext(params: Record<string, unknown>): TelemetryContext | undefined {\n const telemetry = params.__browseToolTelemetry;\n if (!telemetry || typeof telemetry !== 'object') {\n return undefined;\n }\n\n const traceId =\n typeof (telemetry as { traceId?: unknown }).traceId === 'string'\n ? (telemetry as { traceId: string }).traceId\n : undefined;\n const spanId =\n typeof (telemetry as { spanId?: unknown }).spanId === 'string'\n ? (telemetry as { spanId: string }).spanId\n : undefined;\n\n if (!traceId || !spanId) {\n return undefined;\n }\n\n return { traceId, spanId };\n}\n\nasync function emitTelemetry(\n level: 'debug' | 'error',\n message: string,\n action: ContentActionType,\n telemetryContext?: TelemetryContext,\n): Promise<void> {\n try {\n await chrome.runtime.sendMessage({\n type: 'BROWSER_TELEMETRY_EVENT',\n level,\n message,\n context: telemetryContext,\n attributes: {\n 'browse_tool.content.action': action,\n 'browse_tool.page.url': location.href,\n },\n });\n } catch {\n // Ignore background messaging failures.\n }\n}\n\nfunction validateMessage(message: unknown): ContentMessage | null {\n if (!message || typeof message !== 'object') return null;\n const msg = message as Record<string, unknown>;\n if (typeof msg.action !== 'string' || !VALID_ACTIONS.has(msg.action as ContentActionType)) return null;\n if (msg.params !== undefined && (typeof msg.params !== 'object' || msg.params === null)) return null;\n return {\n action: msg.action as ContentActionType,\n params: (msg.params as Record<string, unknown>) || {},\n };\n}\n\nchrome.runtime.onMessage.addListener(\n (message: unknown, _sender: chrome.runtime.MessageSender, sendResponse: (response: ContentResponse) => void) => {\n const validated = validateMessage(message);\n if (!validated) {\n sendResponse({\n success: false,\n error: 'Invalid message format: missing or invalid action',\n });\n return true;\n }\n\n const telemetryContext = extractTelemetryContext(validated.params);\n void emitTelemetry('debug', 'content action received', validated.action, telemetryContext);\n\n handleContentAction(validated)\n .then((result) => {\n void emitTelemetry('debug', 'content action completed', validated.action, telemetryContext);\n sendResponse({ success: true, result });\n })\n .catch((error: Error) => {\n void emitTelemetry('error', error.message, validated.action, telemetryContext);\n sendResponse({ success: false, error: error.message });\n });\n return true; // Async response\n },\n);\n\nasync function handleContentAction(message: ContentMessage): Promise<unknown> {\n const { action, params } = message;\n\n switch (action) {\n case ContentAction.CLICK:\n return handleClick(params);\n case ContentAction.FILL:\n return handleFill(params);\n case ContentAction.TYPE:\n return handleType(params);\n case ContentAction.GET_SNAPSHOT:\n return buildAccessibilityTree();\n case ContentAction.EVALUATE_SCRIPT:\n return handleEvaluateScript(params);\n case ContentAction.GET_ELEMENT_INFO:\n return handleGetElementInfo(params);\n case ContentAction.HOVER:\n return handleHover(params);\n case ContentAction.SELECT:\n return handleSelect(params);\n case ContentAction.DRAG:\n return handleDrag(params);\n case ContentAction.PRESS_KEY:\n return handlePressKey(params);\n case ContentAction.WAIT_FOR:\n return handleWaitFor(params);\n }\n}\n\nasync function handleClick(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n // Scroll element into view\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n // Simulate mouse events for realistic click\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n\n element.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('click', { bubbles: true, clientX: x, clientY: y }));\n}\n\nasync function handleFill(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const value = params.value as string;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (!(element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement)) {\n throw new Error('Element is not an input or textarea');\n }\n\n // Focus and clear\n element.focus();\n element.value = '';\n\n // Set value and dispatch events\n element.value = value;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n}\n\nasync function handleType(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const text = params.text as string;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (element instanceof HTMLElement) {\n element.focus();\n }\n\n // Type character by character\n for (const char of text) {\n element.dispatchEvent(new KeyboardEvent('keydown', { key: char, bubbles: true }));\n element.dispatchEvent(new KeyboardEvent('keypress', { key: char, bubbles: true }));\n\n if (element instanceof HTMLInputElement || element instanceof HTMLTextAreaElement) {\n element.value += char;\n element.dispatchEvent(new Event('input', { bubbles: true }));\n }\n\n element.dispatchEvent(new KeyboardEvent('keyup', { key: char, bubbles: true }));\n }\n}\n\nasync function handleEvaluateScript(params: Record<string, unknown>): Promise<unknown> {\n const script = params.script as string;\n try {\n return await Promise.resolve((0, eval)(script));\n } catch (error) {\n throw new Error(error instanceof Error ? error.message : 'Script execution failed', {\n cause: error,\n });\n }\n}\n\nasync function handleGetElementInfo(params: Record<string, unknown>): Promise<unknown> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n return null;\n }\n\n const rect = element.getBoundingClientRect();\n return {\n tagName: element.tagName.toLowerCase(),\n id: element.id,\n className: element.className,\n textContent: element.textContent?.substring(0, 100),\n rect: {\n x: rect.x,\n y: rect.y,\n width: rect.width,\n height: rect.height,\n },\n };\n}\n\nasync function handleHover(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n element.scrollIntoView({ behavior: 'smooth', block: 'center' });\n\n const rect = element.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n\n element.dispatchEvent(new MouseEvent('mouseenter', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mouseover', { bubbles: true, clientX: x, clientY: y }));\n element.dispatchEvent(new MouseEvent('mousemove', { bubbles: true, clientX: x, clientY: y }));\n}\n\nasync function handleSelect(params: Record<string, unknown>): Promise<void> {\n const locator = params as ElementLocator;\n const value = params.value as string | string[];\n const element = await locateElement(locator);\n\n if (!element) {\n throw new Error('Element not found');\n }\n\n if (!(element instanceof HTMLSelectElement)) {\n throw new Error('Element is not a select element');\n }\n\n const values = Array.isArray(value) ? value : [value];\n\n for (const option of element.options) {\n option.selected = values.includes(option.value) || values.includes(option.text);\n }\n\n element.dispatchEvent(new Event('input', { bubbles: true }));\n element.dispatchEvent(new Event('change', { bubbles: true }));\n}\n\nasync function handleDrag(params: Record<string, unknown>): Promise<void> {\n const sourceLocator = params.source as ElementLocator;\n const targetLocator = params.target as ElementLocator;\n\n const sourceElement = await locateElement(sourceLocator);\n const targetElement = await locateElement(targetLocator);\n\n if (!sourceElement) {\n throw new Error('Source element not found');\n }\n\n if (!targetElement) {\n throw new Error('Target element not found');\n }\n\n const sourceRect = sourceElement.getBoundingClientRect();\n const targetRect = targetElement.getBoundingClientRect();\n\n const sourceX = sourceRect.left + sourceRect.width / 2;\n const sourceY = sourceRect.top + sourceRect.height / 2;\n const targetX = targetRect.left + targetRect.width / 2;\n const targetY = targetRect.top + targetRect.height / 2;\n\n sourceElement.dispatchEvent(new MouseEvent('mousedown', { bubbles: true, clientX: sourceX, clientY: sourceY }));\n sourceElement.dispatchEvent(new MouseEvent('dragstart', { bubbles: true, clientX: sourceX, clientY: sourceY }));\n\n targetElement.dispatchEvent(new MouseEvent('dragenter', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('dragover', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('drop', { bubbles: true, clientX: targetX, clientY: targetY }));\n\n sourceElement.dispatchEvent(new MouseEvent('dragend', { bubbles: true, clientX: targetX, clientY: targetY }));\n targetElement.dispatchEvent(new MouseEvent('mouseup', { bubbles: true, clientX: targetX, clientY: targetY }));\n}\n\nasync function handlePressKey(params: Record<string, unknown>): Promise<void> {\n const key = params.key as string;\n const modifiers = params.modifiers as string[] | undefined;\n\n const eventInit: KeyboardEventInit = {\n key,\n bubbles: true,\n ctrlKey: modifiers?.includes('Control') || modifiers?.includes('Ctrl'),\n shiftKey: modifiers?.includes('Shift'),\n altKey: modifiers?.includes('Alt'),\n metaKey: modifiers?.includes('Meta') || modifiers?.includes('Command'),\n };\n\n const activeElement = document.activeElement || document.body;\n activeElement.dispatchEvent(new KeyboardEvent('keydown', eventInit));\n activeElement.dispatchEvent(new KeyboardEvent('keypress', eventInit));\n activeElement.dispatchEvent(new KeyboardEvent('keyup', eventInit));\n}\n\nasync function handleWaitFor(params: Record<string, unknown>): Promise<void> {\n const selector = params.selector as string | undefined;\n const text = params.text as string | undefined;\n const state = (params.state as string) || 'visible';\n const timeout = (params.timeout as number) || DEFAULT_TOOL_TIMEOUT_MS;\n\n const startTime = Date.now();\n\n while (Date.now() - startTime < timeout) {\n if (selector) {\n const element = document.querySelector(selector);\n if (state === 'visible' && element && isVisible(element)) {\n return;\n }\n if (state === 'hidden' && (!element || !isVisible(element))) {\n return;\n }\n if (state === 'attached' && element) {\n return;\n }\n if (state === 'detached' && !element) {\n return;\n }\n }\n\n if (text) {\n const found = document.body.textContent?.includes(text);\n if (found) {\n return;\n }\n }\n\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(`Wait condition not met within ${timeout}ms`);\n}\n\nfunction isVisible(element: Element): boolean {\n const style = window.getComputedStyle(element);\n return style.display !== 'none' && style.visibility !== 'hidden' && style.opacity !== '0';\n}\n"],"names":["node"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- const e=require(`./stdio-ynNFGBY4.cjs`);require(`./playwright-test-CnsuVfC9.cjs`);let t=require(`@modelcontextprotocol/sdk/server/index.js`),n=require(`@modelcontextprotocol/sdk/types.js`);function r(){let e=()=>void 0;return{debug:e,info:e,warn:e,error:e}}var i=class extends Error{code=`UNKNOWN_TOOL`;recovery=`Use ListTools to see available tools.`;availableTools;constructor(e,t,n){super(`Unknown tool: ${e}. Available tools: ${t.slice(0,5).join(`, `)}${t.length>5?`, ... (${t.length} total)`:``}. Use ListTools to see all available tools.`,n),this.name=`UnknownToolError`,this.availableTools=t}},a=class extends Error{code=`TOOL_EXECUTION_ERROR`;recovery;toolName;constructor(e,t,n){super(`Tool execution failed for '${e}': ${t}`,n),this.name=`ToolExecutionError`,this.toolName=e,this.recovery=n?.recovery??`Check tool inputs and try again.`}};function o(e,t){let n=e instanceof Error?e.message:`Unknown error occurred`,r={error:{code:e instanceof Error&&`code`in e?e.code:`TOOL_EXECUTION_ERROR`,message:n,toolName:t,recovery:e instanceof Error&&`recovery`in e?e.recovery:`Check tool inputs and try again.`}};return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],isError:!0}}function s(s){let c=s?.container??e.n,l=s?.logger??r(),u=new t.Server({name:`browse-tool`,version:`0.1.0`},{capabilities:{tools:{}}}),d=c.getAll(e.p.Tool),f=new Map;for(let e of d){let t=e.getDefinition();f.set(t.name,e)}return l.info(`MCP server initialized`,{toolCount:d.length}),u.setRequestHandler(n.ListToolsRequestSchema,async()=>(l.debug(`ListTools request received`),{tools:d.map(e=>e.getDefinition())})),u.setRequestHandler(n.CallToolRequestSchema,async e=>{let{name:t,arguments:n}=e.params;l.debug(`Tool call received`,{toolName:t,timestamp:new Date().toISOString()});let r=f.get(t);if(!r){let e=Array.from(f.keys());throw l.warn(`Unknown tool requested`,{toolName:t,availableTools:e,timestamp:new Date().toISOString()}),new i(t,e)}try{return await r.execute(n)}catch(e){let n=e instanceof a?e:new a(t,e instanceof Error?e.message:String(e),{cause:e});return l.error(`Tool execution failed`,{toolName:t,error:n.message,code:n.code,timestamp:new Date().toISOString()}),o(n,t)}}),u}exports.PLAYWRIGHT_TYPES=e.p,exports.StdioTransportHandler=e.t,exports.ToolExecutionError=a,exports.UnknownToolError=i,exports.container=e.n,exports.createContainer=e.r,exports.createServer=s;
1
+ const e=require(`./stdio-DKou0TqY.cjs`);require(`./playwright-test-DTw_9rvK.cjs`);let t=require(`@modelcontextprotocol/sdk/server/index.js`),n=require(`@modelcontextprotocol/sdk/types.js`),r=require(`liquidjs`);function i(){let e=()=>void 0;return{debug:e,info:e,warn:e,error:e}}var a=class extends Error{code=`UNKNOWN_TOOL`;recovery=`Use ListTools to see available tools.`;availableTools;constructor(e,t,n){super(`Unknown tool: ${e}. Available tools: ${t.slice(0,5).join(`, `)}${t.length>5?`, ... (${t.length} total)`:``}. Use ListTools to see all available tools.`,n),this.name=`UnknownToolError`,this.availableTools=t}},o=class extends Error{code=`TOOL_EXECUTION_ERROR`;recovery;toolName;constructor(e,t,n){super(`Tool execution failed for '${e}': ${t}`,n),this.name=`ToolExecutionError`,this.toolName=e,this.recovery=n?.recovery??`Check tool inputs and try again.`}};function s(e,t){let n=e instanceof Error?e.message:`Unknown error occurred`,r={error:{code:e instanceof Error&&`code`in e?e.code:`TOOL_EXECUTION_ERROR`,message:n,toolName:t,recovery:e instanceof Error&&`recovery`in e?e.recovery:`Check tool inputs and try again.`}};return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],isError:!0}}function c(r){let c=r?.container??e.n,l=r?.logger??i(),u=new t.Server({name:`browse-tool`,version:`0.1.0`},{capabilities:{tools:{}}}),d=c.getAll(e.g.Tool),f=new Map;for(let e of d){let t=e.getDefinition();f.set(t.name,e)}return l.info(`MCP server initialized`,{toolCount:d.length}),u.setRequestHandler(n.ListToolsRequestSchema,async()=>(l.debug(`ListTools request received`),{tools:d.map(e=>e.getDefinition())})),u.setRequestHandler(n.CallToolRequestSchema,async e=>{let{name:t,arguments:n}=e.params;l.debug(`Tool call received`,{toolName:t,timestamp:new Date().toISOString()});let r=f.get(t);if(!r){let e=Array.from(f.keys());throw l.warn(`Unknown tool requested`,{toolName:t,availableTools:e,timestamp:new Date().toISOString()}),new a(t,e)}try{return await r.execute(n)}catch(e){let n=e instanceof o?e:new o(t,e instanceof Error?e.message:String(e),{cause:e});return l.error(`Tool execution failed`,{toolName:t,error:n.message,code:n.code,timestamp:new Date().toISOString()}),s(n,t)}}),u}var l='Create a browse-tool custom tool folder for use with `browse-tool mcp-serve --custom-tools <dir>`.\n\nGoal: {{ toolGoal }}\nPreferred tool name: {{ preferredToolName }}\nPage context: {{ pageContext }}\n\nRequirements:\n- Produce a `tools.yaml` file with a top-level `tools` array.\n- Each tool entry must include `name`, `description`, `script`, `capabilities`, and `inputSchema`.\n- Each tool entry may optionally include `suggestionActions` as a short text string describing the recommended next step after the tool succeeds.\n- `inputSchema` must be JSON Schema with `type: object`.\n- `inputSchema` must define `pageId` as `type: string` and include `pageId` in `required`.\n- The script file must be `.ts` and export a default function with the shape `({ page, input, logger }) => { ... }`.\n- The default export runs in Node.js, not inside the page.\n- Use the provided `page` object for browser interaction. It will be a Playwright page in playwright mode or an extension page proxy in extension mode.\n- Use the provided `logger` object for instrumentation. It exposes `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, and logs automatically attach to the active custom-tool telemetry context.\n- The logger also exposes `getTraceContext()` so a tool can return the active `traceId` and `spanId` when needed for downstream log inspection.\n- If you need DOM access, call `page.evaluate(...)` from the default export instead of assuming browser globals are available at module scope.\n- Keep the script self-contained and avoid relative imports.\n- Return either a plain object, a string, or an MCP-style `CallToolResult`.\n- Prefer read-only behavior unless the goal explicitly requires mutation.\n\nOutput format:\n- Show the full `tools.yaml` content.\n- Show the full `{{ preferredToolName }}.ts` content.\n- If the tool needs additional inputs beyond `pageId`, define them in `inputSchema` and read them from `input`.\n- Filesystem access is allowed because the script runs in Node.js.\n\nExample `tools.yaml` shape:\n```yaml\ntools:\n - name: get_post\n description: Get the current post from the open feed page\n script: get_post.ts\n suggestionActions: Open the author profile and review whether the post is worth engaging with\n capabilities:\n readOnlyHint: true\n openWorldHint: false\n inputSchema:\n type: object\n properties:\n pageId:\n type: string\n selector:\n type: string\n required:\n - pageId\n```\n\nExample script shape:\n```ts\nexport default async function getPost({ page, input, logger }) {\n const traceContext = logger.getTraceContext();\n logger.info("reading post", { attributes: { selector: input.selector ?? "body" } });\n const selector = input.selector ?? "body";\n const text = await page.evaluate((currentSelector) => {\n return document.querySelector(currentSelector)?.textContent ?? "";\n }, selector);\n return {\n pageUrl: page.url(),\n traceContext,\n text,\n };\n}\n```\n';const u={name:`custom_script_authoring`,description:`Generate a browse-tool custom tool folder with tools.yaml and TypeScript scripts.`,arguments:[{name:`toolGoal`,description:`What the custom tool should do on the page`,required:!0},{name:`toolName`,description:`Preferred snake_case tool name`,required:!1},{name:`pageContext`,description:`Optional context about the target page or workflow`,required:!1}]},d=new r.Liquid;function f(e){let t=e.toolName?.trim()||`custom_page_tool`,n=e.pageContext?.trim()||`No extra page context provided.`;return[{role:`user`,content:{type:`text`,text:d.parseAndRenderSync(l,{toolGoal:e.toolGoal,preferredToolName:t,pageContext:n})}}]}exports.PLAYWRIGHT_TYPES=e.g,exports.StdioTransportHandler=e.t,exports.ToolExecutionError=o,exports.UnknownToolError=a,exports.container=e.n,exports.createContainer=e.r,exports.createServer=c,exports.customScriptAuthoringPrompt=u,exports.generateCustomScriptAuthoringPrompt=f;
package/dist/index.mjs CHANGED
@@ -1,2 +1 @@
1
- import{n as e,p as t,r as n,t as r}from"./stdio-BP3yiSxK.mjs";import"./playwright-test-BwI7HgW7.mjs";import{Server as i}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as a,ListToolsRequestSchema as o}from"@modelcontextprotocol/sdk/types.js";function s(){let e=()=>void 0;return{debug:e,info:e,warn:e,error:e}}var c=class extends Error{code=`UNKNOWN_TOOL`;recovery=`Use ListTools to see available tools.`;availableTools;constructor(e,t,n){super(`Unknown tool: ${e}. Available tools: ${t.slice(0,5).join(`, `)}${t.length>5?`, ... (${t.length} total)`:``}. Use ListTools to see all available tools.`,n),this.name=`UnknownToolError`,this.availableTools=t}},l=class extends Error{code=`TOOL_EXECUTION_ERROR`;recovery;toolName;constructor(e,t,n){super(`Tool execution failed for '${e}': ${t}`,n),this.name=`ToolExecutionError`,this.toolName=e,this.recovery=n?.recovery??`Check tool inputs and try again.`}};function u(e,t){let n=e instanceof Error?e.message:`Unknown error occurred`,r={error:{code:e instanceof Error&&`code`in e?e.code:`TOOL_EXECUTION_ERROR`,message:n,toolName:t,recovery:e instanceof Error&&`recovery`in e?e.recovery:`Check tool inputs and try again.`}};return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],isError:!0}}function d(n){let r=n?.container??e,d=n?.logger??s(),f=new i({name:`browse-tool`,version:`0.1.0`},{capabilities:{tools:{}}}),p=r.getAll(t.Tool),m=new Map;for(let e of p){let t=e.getDefinition();m.set(t.name,e)}return d.info(`MCP server initialized`,{toolCount:p.length}),f.setRequestHandler(o,async()=>(d.debug(`ListTools request received`),{tools:p.map(e=>e.getDefinition())})),f.setRequestHandler(a,async e=>{let{name:t,arguments:n}=e.params;d.debug(`Tool call received`,{toolName:t,timestamp:new Date().toISOString()});let r=m.get(t);if(!r){let e=Array.from(m.keys());throw d.warn(`Unknown tool requested`,{toolName:t,availableTools:e,timestamp:new Date().toISOString()}),new c(t,e)}try{return await r.execute(n)}catch(e){let n=e instanceof l?e:new l(t,e instanceof Error?e.message:String(e),{cause:e});return d.error(`Tool execution failed`,{toolName:t,error:n.message,code:n.code,timestamp:new Date().toISOString()}),u(n,t)}}),f}export{t as PLAYWRIGHT_TYPES,r as StdioTransportHandler,l as ToolExecutionError,c as UnknownToolError,e as container,n as createContainer,d as createServer};
2
- //# sourceMappingURL=index.mjs.map
1
+ import{g as e,n as t,r as n,t as r}from"./stdio-ELROpCD_.mjs";import"./playwright-test-BwI7HgW7.mjs";import{Server as i}from"@modelcontextprotocol/sdk/server/index.js";import{CallToolRequestSchema as a,ListToolsRequestSchema as o}from"@modelcontextprotocol/sdk/types.js";import{Liquid as s}from"liquidjs";function c(){let e=()=>void 0;return{debug:e,info:e,warn:e,error:e}}var l=class extends Error{code=`UNKNOWN_TOOL`;recovery=`Use ListTools to see available tools.`;availableTools;constructor(e,t,n){super(`Unknown tool: ${e}. Available tools: ${t.slice(0,5).join(`, `)}${t.length>5?`, ... (${t.length} total)`:``}. Use ListTools to see all available tools.`,n),this.name=`UnknownToolError`,this.availableTools=t}},u=class extends Error{code=`TOOL_EXECUTION_ERROR`;recovery;toolName;constructor(e,t,n){super(`Tool execution failed for '${e}': ${t}`,n),this.name=`ToolExecutionError`,this.toolName=e,this.recovery=n?.recovery??`Check tool inputs and try again.`}};function d(e,t){let n=e instanceof Error?e.message:`Unknown error occurred`,r={error:{code:e instanceof Error&&`code`in e?e.code:`TOOL_EXECUTION_ERROR`,message:n,toolName:t,recovery:e instanceof Error&&`recovery`in e?e.recovery:`Check tool inputs and try again.`}};return{content:[{type:`text`,text:JSON.stringify(r,null,2)}],isError:!0}}function f(n){let r=n?.container??t,s=n?.logger??c(),f=new i({name:`browse-tool`,version:`0.1.0`},{capabilities:{tools:{}}}),p=r.getAll(e.Tool),m=new Map;for(let e of p){let t=e.getDefinition();m.set(t.name,e)}return s.info(`MCP server initialized`,{toolCount:p.length}),f.setRequestHandler(o,async()=>(s.debug(`ListTools request received`),{tools:p.map(e=>e.getDefinition())})),f.setRequestHandler(a,async e=>{let{name:t,arguments:n}=e.params;s.debug(`Tool call received`,{toolName:t,timestamp:new Date().toISOString()});let r=m.get(t);if(!r){let e=Array.from(m.keys());throw s.warn(`Unknown tool requested`,{toolName:t,availableTools:e,timestamp:new Date().toISOString()}),new l(t,e)}try{return await r.execute(n)}catch(e){let n=e instanceof u?e:new u(t,e instanceof Error?e.message:String(e),{cause:e});return s.error(`Tool execution failed`,{toolName:t,error:n.message,code:n.code,timestamp:new Date().toISOString()}),d(n,t)}}),f}var p='Create a browse-tool custom tool folder for use with `browse-tool mcp-serve --custom-tools <dir>`.\n\nGoal: {{ toolGoal }}\nPreferred tool name: {{ preferredToolName }}\nPage context: {{ pageContext }}\n\nRequirements:\n- Produce a `tools.yaml` file with a top-level `tools` array.\n- Each tool entry must include `name`, `description`, `script`, `capabilities`, and `inputSchema`.\n- Each tool entry may optionally include `suggestionActions` as a short text string describing the recommended next step after the tool succeeds.\n- `inputSchema` must be JSON Schema with `type: object`.\n- `inputSchema` must define `pageId` as `type: string` and include `pageId` in `required`.\n- The script file must be `.ts` and export a default function with the shape `({ page, input, logger }) => { ... }`.\n- The default export runs in Node.js, not inside the page.\n- Use the provided `page` object for browser interaction. It will be a Playwright page in playwright mode or an extension page proxy in extension mode.\n- Use the provided `logger` object for instrumentation. It exposes `trace`, `debug`, `info`, `warn`, `error`, and `fatal`, and logs automatically attach to the active custom-tool telemetry context.\n- The logger also exposes `getTraceContext()` so a tool can return the active `traceId` and `spanId` when needed for downstream log inspection.\n- If you need DOM access, call `page.evaluate(...)` from the default export instead of assuming browser globals are available at module scope.\n- Keep the script self-contained and avoid relative imports.\n- Return either a plain object, a string, or an MCP-style `CallToolResult`.\n- Prefer read-only behavior unless the goal explicitly requires mutation.\n\nOutput format:\n- Show the full `tools.yaml` content.\n- Show the full `{{ preferredToolName }}.ts` content.\n- If the tool needs additional inputs beyond `pageId`, define them in `inputSchema` and read them from `input`.\n- Filesystem access is allowed because the script runs in Node.js.\n\nExample `tools.yaml` shape:\n```yaml\ntools:\n - name: get_post\n description: Get the current post from the open feed page\n script: get_post.ts\n suggestionActions: Open the author profile and review whether the post is worth engaging with\n capabilities:\n readOnlyHint: true\n openWorldHint: false\n inputSchema:\n type: object\n properties:\n pageId:\n type: string\n selector:\n type: string\n required:\n - pageId\n```\n\nExample script shape:\n```ts\nexport default async function getPost({ page, input, logger }) {\n const traceContext = logger.getTraceContext();\n logger.info("reading post", { attributes: { selector: input.selector ?? "body" } });\n const selector = input.selector ?? "body";\n const text = await page.evaluate((currentSelector) => {\n return document.querySelector(currentSelector)?.textContent ?? "";\n }, selector);\n return {\n pageUrl: page.url(),\n traceContext,\n text,\n };\n}\n```\n';const m={name:`custom_script_authoring`,description:`Generate a browse-tool custom tool folder with tools.yaml and TypeScript scripts.`,arguments:[{name:`toolGoal`,description:`What the custom tool should do on the page`,required:!0},{name:`toolName`,description:`Preferred snake_case tool name`,required:!1},{name:`pageContext`,description:`Optional context about the target page or workflow`,required:!1}]},h=new s;function g(e){let t=e.toolName?.trim()||`custom_page_tool`,n=e.pageContext?.trim()||`No extra page context provided.`;return[{role:`user`,content:{type:`text`,text:h.parseAndRenderSync(p,{toolGoal:e.toolGoal,preferredToolName:t,pageContext:n})}}]}export{e as PLAYWRIGHT_TYPES,r as StdioTransportHandler,u as ToolExecutionError,l as UnknownToolError,t as container,n as createContainer,f as createServer,m as customScriptAuthoringPrompt,g as generateCustomScriptAuthoringPrompt};
@@ -249,5 +249,4 @@ import{createRequire as e}from"node:module";const t=Symbol.for(`__locatorProxyBr
249
249
  }
250
250
 
251
251
  return null;
252
- })()`}};const r=Symbol.for(`__pageProxyBrand__`);async function i(e,t,n=5e3){let r=Date.now();for(;Date.now()-r<n;){if(await e())return;await new Promise(e=>setTimeout(e,100))}throw Error(t)}function a(e,t){return e==null?!1:t instanceof RegExp?t.test(e):e===t}function o(e,t){return e==null?!1:t instanceof RegExp?t.test(e):e.includes(t)}function s(e,t){let n=e=>t?!e:e;return{async toBeVisible(r){await i(async()=>n(await e.isVisible()),t?`Expected element to not be visible`:`Expected element to be visible`,r?.timeout)},async toBeHidden(r){await i(async()=>n(!await e.isVisible()),t?`Expected element to not be hidden`:`Expected element to be hidden`,r?.timeout)},async toBeDisabled(r){await i(async()=>n(!!await e.evaluateProperty(`disabled`)),t?`Expected element to not be disabled`:`Expected element to be disabled`,r?.timeout)},async toBeEnabled(r){await i(async()=>n(!await e.evaluateProperty(`disabled`)),t?`Expected element to not be enabled`:`Expected element to be enabled`,r?.timeout)},async toBeChecked(r){await i(async()=>n(!!await e.evaluateProperty(`checked`)),t?`Expected element to not be checked`:`Expected element to be checked`,r?.timeout)},async toHaveValue(r,o){await i(async()=>n(a(await e.evaluateProperty(`value`),r)),t?`Expected element to not have value "${String(r)}"`:`Expected element to have value "${String(r)}"`,o?.timeout)},async toHaveText(r,o){await i(async()=>n(a((await e.textContent())?.trim()??null,r)),t?`Expected element to not have text "${String(r)}"`:`Expected element to have text "${String(r)}"`,o?.timeout)},async toContainText(r,a){await i(async()=>n(o(await e.textContent(),r)),t?`Expected element to not contain text "${String(r)}"`:`Expected element to contain text "${String(r)}"`,a?.timeout)},async toHaveCount(r,a){await i(async()=>n(await e.count()===r),t?`Expected element count to not be ${r}`:`Expected element count to be ${r}`,a?.timeout)},get not(){return s(e,!t)}}}function c(e,t){let n=e=>t?!e:e;return{async toHaveURL(r,o){await i(async()=>n(a(await e.currentUrlAsync(),r)),t?`Expected page to not have URL "${String(r)}"`:`Expected page to have URL "${String(r)}"`,o?.timeout)},async toHaveTitle(r,o){await i(async()=>n(a(await e.title(),r)),t?`Expected page to not have title "${String(r)}"`:`Expected page to have title "${String(r)}"`,o?.timeout)},get not(){return c(e,!t)}}}function l(e){let n=e;if(n[t])return s(e,!1);if(n[r])return c(e,!1);throw Error(`createExtensionExpect called with unsupported target`)}function u(){try{return e(import.meta.url).resolve(`playwright/test`),import.meta.url}catch{return typeof __PLAYWRIGHT_MCP_STUB_PATH__==`string`?`file://${__PLAYWRIGHT_MCP_STUB_PATH__}`:import.meta.url}}const d=process,f=d.__pw_initiator__;d.__pw_initiator__=void 0;const{expect:p}=e(u())(`playwright/test`);d.__pw_initiator__=f;var m=class{currentSpecPath=``;rootDescribe;currentDescribe;constructor(){this.rootDescribe=this.createDescribeBlock(``,null),this.currentDescribe=this.rootDescribe}createDescribeBlock(e,t){return{title:e,tests:[],beforeEachHooks:[],afterEachHooks:[],children:[],parent:t}}setSpecPath(e){this.currentSpecPath=e}reset(){this.currentSpecPath=``,this.rootDescribe=this.createDescribeBlock(``,null),this.currentDescribe=this.rootDescribe}addTest(e,t,n=!1,r=!1){let i={title:e,fn:t,fullTitle:this.getFullTitle(e),only:n,skip:r};return this.currentDescribe.tests.push(i),i}enterDescribe(e){let t=this.createDescribeBlock(e,this.currentDescribe);this.currentDescribe.children.push(t),this.currentDescribe=t}exitDescribe(){this.currentDescribe.parent&&(this.currentDescribe=this.currentDescribe.parent)}addBeforeEach(e){this.currentDescribe.beforeEachHooks.push(e)}addAfterEach(e){this.currentDescribe.afterEachHooks.push(e)}getFullTitle(e){let t=[],n=this.currentDescribe;for(;n;)n.title&&t.unshift(n.title),n=n.parent;return t.push(e),t.join(` > `)}flattenTests(e,t,n){let r=[],i=[...t,...e.beforeEachHooks],a=[...e.afterEachHooks,...n];for(let t of e.tests)r.push({title:t.title,fullTitle:t.fullTitle,fn:async e=>{for(let t of i)await t(e);await t.fn(e);for(let t of a)await t(e)},only:t.only,skip:t.skip});for(let t of e.children)r.push(...this.flattenTests(t,i,a));return r}retrieveAndReset(){let e=this.flattenTests(this.rootDescribe,[],[]),t={specPath:this.currentSpecPath,root:this.rootDescribe,allTests:e,testCount:e.length};return this.reset(),t}peek(){let e=this.flattenTests(this.rootDescribe,[],[]);return{specPath:this.currentSpecPath,root:this.rootDescribe,allTests:e,testCount:e.length}}};const h=`__playwrightMcpTestCollector__`,g=globalThis;g[h]||(g[h]=new m);const _=g[h];function v(e){let t=new Map;for(let[n,r]of Object.entries(e))typeof r==`function`?t.set(n,r):Array.isArray(r)&&r.length===2&&typeof r[1]==`function`&&t.set(n,r[1]);return t}function y(e){if(e.size===0)return e=>e;let t=[...e.entries()];return e=>async n=>{let r={...n};async function i(n){if(n>=t.length){await e(r);return}let[a,o]=t[n];await o(r,async e=>{r[a]=e,await i(n+1)})}await i(0)}}function b(e){let t=y(e);function n(e,n){_.addTest(e,t(n))}return n.only=function(e,n){_.addTest(e,t(n),!0,!1)},n.skip=function(e,n){_.addTest(e,t(n),!1,!0)},n.describe=function(e,t){_.enterDescribe(e),t(),_.exitDescribe()},n.beforeEach=function(e){_.addBeforeEach(t(e))},n.afterEach=function(e){_.addAfterEach(t(e))},n.extend=function(t){return b(new Map([...e,...v(t)]))},n}function x(e,t){_.addTest(e,t)}function S(e,t){_.addTest(e,t,!0,!1)}function C(e,t){_.addTest(e,t,!1,!0)}function w(e,t){_.enterDescribe(e),t(),_.exitDescribe()}function T(e){_.addBeforeEach(e)}function E(e){_.addAfterEach(e)}x.describe=w,x.beforeEach=T,x.afterEach=E,x.only=S,x.skip=C,x.extend=function(e){return b(v(e))};function D(e){_.reset(),_.setSpecPath(e)}function O(){return _.retrieveAndReset()}function k(){return _.peek()}function A(){_.reset()}const j=(e=>{let n=e;return n?.[t]||n?.[r]?l(e):p(e)});export{A as a,n as c,k as i,O as n,x as o,D as r,r as s,j as t};
253
- //# sourceMappingURL=playwright-test-BwI7HgW7.mjs.map
252
+ })()`}};const r=Symbol.for(`__pageProxyBrand__`);async function i(e,t,n=5e3){let r=Date.now();for(;Date.now()-r<n;){if(await e())return;await new Promise(e=>setTimeout(e,100))}throw Error(t)}function a(e,t){return e==null?!1:t instanceof RegExp?t.test(e):e===t}function o(e,t){return e==null?!1:t instanceof RegExp?t.test(e):e.includes(t)}function s(e,t){let n=e=>t?!e:e;return{async toBeVisible(r){await i(async()=>n(await e.isVisible()),t?`Expected element to not be visible`:`Expected element to be visible`,r?.timeout)},async toBeHidden(r){await i(async()=>n(!await e.isVisible()),t?`Expected element to not be hidden`:`Expected element to be hidden`,r?.timeout)},async toBeDisabled(r){await i(async()=>n(!!await e.evaluateProperty(`disabled`)),t?`Expected element to not be disabled`:`Expected element to be disabled`,r?.timeout)},async toBeEnabled(r){await i(async()=>n(!await e.evaluateProperty(`disabled`)),t?`Expected element to not be enabled`:`Expected element to be enabled`,r?.timeout)},async toBeChecked(r){await i(async()=>n(!!await e.evaluateProperty(`checked`)),t?`Expected element to not be checked`:`Expected element to be checked`,r?.timeout)},async toHaveValue(r,o){await i(async()=>n(a(await e.evaluateProperty(`value`),r)),t?`Expected element to not have value "${String(r)}"`:`Expected element to have value "${String(r)}"`,o?.timeout)},async toHaveText(r,o){await i(async()=>n(a((await e.textContent())?.trim()??null,r)),t?`Expected element to not have text "${String(r)}"`:`Expected element to have text "${String(r)}"`,o?.timeout)},async toContainText(r,a){await i(async()=>n(o(await e.textContent(),r)),t?`Expected element to not contain text "${String(r)}"`:`Expected element to contain text "${String(r)}"`,a?.timeout)},async toHaveCount(r,a){await i(async()=>n(await e.count()===r),t?`Expected element count to not be ${r}`:`Expected element count to be ${r}`,a?.timeout)},get not(){return s(e,!t)}}}function c(e,t){let n=e=>t?!e:e;return{async toHaveURL(r,o){await i(async()=>n(a(await e.currentUrlAsync(),r)),t?`Expected page to not have URL "${String(r)}"`:`Expected page to have URL "${String(r)}"`,o?.timeout)},async toHaveTitle(r,o){await i(async()=>n(a(await e.title(),r)),t?`Expected page to not have title "${String(r)}"`:`Expected page to have title "${String(r)}"`,o?.timeout)},get not(){return c(e,!t)}}}function l(e){let n=e;if(n[t])return s(e,!1);if(n[r])return c(e,!1);throw Error(`createExtensionExpect called with unsupported target`)}function u(){try{return e(import.meta.url).resolve(`playwright/test`),import.meta.url}catch{return typeof __PLAYWRIGHT_MCP_STUB_PATH__==`string`?`file://${__PLAYWRIGHT_MCP_STUB_PATH__}`:import.meta.url}}const d=process,f=d.__pw_initiator__;d.__pw_initiator__=void 0;const{expect:p}=e(u())(`playwright/test`);d.__pw_initiator__=f;var m=class{currentSpecPath=``;rootDescribe;currentDescribe;constructor(){this.rootDescribe=this.createDescribeBlock(``,null),this.currentDescribe=this.rootDescribe}createDescribeBlock(e,t){return{title:e,tests:[],beforeEachHooks:[],afterEachHooks:[],children:[],parent:t}}setSpecPath(e){this.currentSpecPath=e}reset(){this.currentSpecPath=``,this.rootDescribe=this.createDescribeBlock(``,null),this.currentDescribe=this.rootDescribe}addTest(e,t,n=!1,r=!1){let i={title:e,fn:t,fullTitle:this.getFullTitle(e),only:n,skip:r};return this.currentDescribe.tests.push(i),i}enterDescribe(e){let t=this.createDescribeBlock(e,this.currentDescribe);this.currentDescribe.children.push(t),this.currentDescribe=t}exitDescribe(){this.currentDescribe.parent&&(this.currentDescribe=this.currentDescribe.parent)}addBeforeEach(e){this.currentDescribe.beforeEachHooks.push(e)}addAfterEach(e){this.currentDescribe.afterEachHooks.push(e)}getFullTitle(e){let t=[],n=this.currentDescribe;for(;n;)n.title&&t.unshift(n.title),n=n.parent;return t.push(e),t.join(` > `)}flattenTests(e,t,n){let r=[],i=[...t,...e.beforeEachHooks],a=[...e.afterEachHooks,...n];for(let t of e.tests)r.push({title:t.title,fullTitle:t.fullTitle,fn:async e=>{for(let t of i)await t(e);await t.fn(e);for(let t of a)await t(e)},only:t.only,skip:t.skip});for(let t of e.children)r.push(...this.flattenTests(t,i,a));return r}retrieveAndReset(){let e=this.flattenTests(this.rootDescribe,[],[]),t={specPath:this.currentSpecPath,root:this.rootDescribe,allTests:e,testCount:e.length};return this.reset(),t}peek(){let e=this.flattenTests(this.rootDescribe,[],[]);return{specPath:this.currentSpecPath,root:this.rootDescribe,allTests:e,testCount:e.length}}};const h=`__playwrightMcpTestCollector__`,g=globalThis;g[h]||(g[h]=new m);const _=g[h];function v(e){let t=new Map;for(let[n,r]of Object.entries(e))typeof r==`function`?t.set(n,r):Array.isArray(r)&&r.length===2&&typeof r[1]==`function`&&t.set(n,r[1]);return t}function y(e){if(e.size===0)return e=>e;let t=[...e.entries()];return e=>async n=>{let r={...n};async function i(n){if(n>=t.length){await e(r);return}let[a,o]=t[n];await o(r,async e=>{r[a]=e,await i(n+1)})}await i(0)}}function b(e){let t=y(e);function n(e,n){_.addTest(e,t(n))}return n.only=function(e,n){_.addTest(e,t(n),!0,!1)},n.skip=function(e,n){_.addTest(e,t(n),!1,!0)},n.describe=function(e,t){_.enterDescribe(e),t(),_.exitDescribe()},n.beforeEach=function(e){_.addBeforeEach(t(e))},n.afterEach=function(e){_.addAfterEach(t(e))},n.extend=function(t){return b(new Map([...e,...v(t)]))},n}function x(e,t){_.addTest(e,t)}function S(e,t){_.addTest(e,t,!0,!1)}function C(e,t){_.addTest(e,t,!1,!0)}function w(e,t){_.enterDescribe(e),t(),_.exitDescribe()}function T(e){_.addBeforeEach(e)}function E(e){_.addAfterEach(e)}x.describe=w,x.beforeEach=T,x.afterEach=E,x.only=S,x.skip=C,x.extend=function(e){return b(v(e))};function D(e){_.reset(),_.setSpecPath(e)}function O(){return _.retrieveAndReset()}function k(){return _.peek()}function A(){_.reset()}const j=(e=>{let n=e;return n?.[t]||n?.[r]?l(e):p(e)});export{A as a,n as c,k as i,O as n,x as o,D as r,r as s,j as t};
@@ -1,4 +1,4 @@
1
- const e=require(`./stdio-ynNFGBY4.cjs`);let t=require(`node:module`);const n=Symbol.for(`__locatorProxyBrand__`);var r=class e{[n]=!0;constructor(e,t){this.page=e,this.steps=t}getByRole(t,n){return new e(this.page,[...this.steps,{type:`role`,role:t,options:n}])}getByText(t,n){return new e(this.page,[...this.steps,{type:`text`,text:t,options:n}])}getByLabel(t,n){return new e(this.page,[...this.steps,{type:`label`,text:t,options:n}])}getByPlaceholder(t,n){return new e(this.page,[...this.steps,{type:`placeholder`,text:t,options:n}])}getByTestId(t){return new e(this.page,[...this.steps,{type:`testId`,testId:t}])}locator(t){return new e(this.page,[...this.steps,{type:`css`,selector:t}])}filter(t){return new e(this.page,[...this.steps,{type:`filter`,options:t}])}first(){return new e(this.page,[...this.steps,{type:`first`}])}last(){return this.nth(-1)}nth(t){return new e(this.page,[...this.steps,{type:`nth`,index:t}])}async click(e){let t=await this.resolveAndMark(e?.timeout);await this.page.click(t)}async fill(e,t){let n=await this.resolveAndMark(t?.timeout);await this.page.fill(n,e)}async type(e,t){let n=await this.resolveAndMark(t?.timeout);await this.page.type(n,e,{delay:t?.delay})}async press(e){let t=await this.resolveAndMark();await this.page.click(t),await this.page.press(e)}async hover(e){let t=await this.resolveAndMark(e?.timeout);await this.page.hover(t)}async selectOption(e){let t=await this.resolveAndMark();await this.page.selectOption(t,e)}async check(){let e=await this.resolveAndMark();await this.page.click(e)}async uncheck(){let e=await this.resolveAndMark();await this.page.click(e)}async isVisible(){let e=this.buildResolveScript(`isVisible`);return await this.page.evaluate(e)??!1}async isHidden(){return!await this.isVisible()}async isEnabled(){return!await this.evaluateProperty(`disabled`)}async isDisabled(){return!!await this.evaluateProperty(`disabled`)}async isChecked(){return!!await this.evaluateProperty(`checked`)}async evaluateProperty(e){let t=this.buildResolveScript(`getProperty`,e);return this.page.evaluate(t)}async textContent(){let e=this.buildResolveScript(`textContent`);return this.page.evaluate(e)}async innerText(){let e=this.buildResolveScript(`innerText`);return await this.page.evaluate(e)??``}async inputValue(){let e=this.buildResolveScript(`inputValue`);return await this.page.evaluate(e)??``}async count(){let e=this.buildResolveScript(`count`);return await this.page.evaluate(e)??0}async waitFor(e){let t=e?.timeout??5e3,n=e?.state??`visible`,r=Date.now();for(;Date.now()-r<t;){if(n===`visible`&&await this.isVisible()||n===`hidden`&&!await this.isVisible()||n===`attached`&&await this.count()>0||n===`detached`&&await this.count()===0)return;await new Promise(e=>setTimeout(e,100))}throw Error(`Locator waitFor("${n}") timed out after ${t}ms`)}async resolveAndMark(e){let t=e??5e3,n=Date.now(),r=`pw-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;for(;Date.now()-n<t;){let e=this.buildResolveScript(`mark`,r);if(await this.page.evaluate(e))return`[data-pw-proxy="${r}"]`;await new Promise(e=>setTimeout(e,100))}throw Error(`Locator could not resolve element within ${t}ms. Steps: ${this.describeSteps()}`)}describeSteps(){return this.steps.map(e=>{switch(e.type){case`role`:return`getByRole("${e.role}"${e.options?.name?`, { name: "${String(e.options.name)}" }`:``})`;case`text`:return`getByText("${String(e.text)}")`;case`label`:return`getByLabel("${String(e.text)}")`;case`placeholder`:return`getByPlaceholder("${String(e.text)}")`;case`testId`:return`getByTestId("${e.testId}")`;case`css`:return`locator("${e.selector}")`;case`filter`:return`filter(...)`;case`first`:return`first()`;case`nth`:return`nth(${e.index})`}}).join(`.`)}serializeSteps(){return this.steps.map(e=>{if(e.type===`text`||e.type===`label`||e.type===`placeholder`)return{...e,text:e.text instanceof RegExp?{__regex__:e.text.source,flags:e.text.flags}:e.text};if(e.type===`role`&&e.options?.name instanceof RegExp)return{...e,options:{...e.options,name:{__regex__:e.options.name.source,flags:e.options.name.flags}}};if(e.type===`filter`){let t={};return e.options.hasText&&(t.hasText=e.options.hasText instanceof RegExp?{__regex__:e.options.hasText.source,flags:e.options.hasText.flags}:e.options.hasText),e.options.has&&(t.hasSteps=e.options.has.serializeSteps()),{type:`filter`,options:t}}return e})}buildResolveScript(e,t){return`(function() {
1
+ const e=require(`./stdio-DKou0TqY.cjs`);let t=require(`node:module`);const n=Symbol.for(`__locatorProxyBrand__`);var r=class e{[n]=!0;constructor(e,t){this.page=e,this.steps=t}getByRole(t,n){return new e(this.page,[...this.steps,{type:`role`,role:t,options:n}])}getByText(t,n){return new e(this.page,[...this.steps,{type:`text`,text:t,options:n}])}getByLabel(t,n){return new e(this.page,[...this.steps,{type:`label`,text:t,options:n}])}getByPlaceholder(t,n){return new e(this.page,[...this.steps,{type:`placeholder`,text:t,options:n}])}getByTestId(t){return new e(this.page,[...this.steps,{type:`testId`,testId:t}])}locator(t){return new e(this.page,[...this.steps,{type:`css`,selector:t}])}filter(t){return new e(this.page,[...this.steps,{type:`filter`,options:t}])}first(){return new e(this.page,[...this.steps,{type:`first`}])}last(){return this.nth(-1)}nth(t){return new e(this.page,[...this.steps,{type:`nth`,index:t}])}async click(e){let t=await this.resolveAndMark(e?.timeout);await this.page.click(t)}async fill(e,t){let n=await this.resolveAndMark(t?.timeout);await this.page.fill(n,e)}async type(e,t){let n=await this.resolveAndMark(t?.timeout);await this.page.type(n,e,{delay:t?.delay})}async press(e){let t=await this.resolveAndMark();await this.page.click(t),await this.page.press(e)}async hover(e){let t=await this.resolveAndMark(e?.timeout);await this.page.hover(t)}async selectOption(e){let t=await this.resolveAndMark();await this.page.selectOption(t,e)}async check(){let e=await this.resolveAndMark();await this.page.click(e)}async uncheck(){let e=await this.resolveAndMark();await this.page.click(e)}async isVisible(){let e=this.buildResolveScript(`isVisible`);return await this.page.evaluate(e)??!1}async isHidden(){return!await this.isVisible()}async isEnabled(){return!await this.evaluateProperty(`disabled`)}async isDisabled(){return!!await this.evaluateProperty(`disabled`)}async isChecked(){return!!await this.evaluateProperty(`checked`)}async evaluateProperty(e){let t=this.buildResolveScript(`getProperty`,e);return this.page.evaluate(t)}async textContent(){let e=this.buildResolveScript(`textContent`);return this.page.evaluate(e)}async innerText(){let e=this.buildResolveScript(`innerText`);return await this.page.evaluate(e)??``}async inputValue(){let e=this.buildResolveScript(`inputValue`);return await this.page.evaluate(e)??``}async count(){let e=this.buildResolveScript(`count`);return await this.page.evaluate(e)??0}async waitFor(e){let t=e?.timeout??5e3,n=e?.state??`visible`,r=Date.now();for(;Date.now()-r<t;){if(n===`visible`&&await this.isVisible()||n===`hidden`&&!await this.isVisible()||n===`attached`&&await this.count()>0||n===`detached`&&await this.count()===0)return;await new Promise(e=>setTimeout(e,100))}throw Error(`Locator waitFor("${n}") timed out after ${t}ms`)}async resolveAndMark(e){let t=e??5e3,n=Date.now(),r=`pw-${Date.now()}-${Math.random().toString(36).slice(2,8)}`;for(;Date.now()-n<t;){let e=this.buildResolveScript(`mark`,r);if(await this.page.evaluate(e))return`[data-pw-proxy="${r}"]`;await new Promise(e=>setTimeout(e,100))}throw Error(`Locator could not resolve element within ${t}ms. Steps: ${this.describeSteps()}`)}describeSteps(){return this.steps.map(e=>{switch(e.type){case`role`:return`getByRole("${e.role}"${e.options?.name?`, { name: "${String(e.options.name)}" }`:``})`;case`text`:return`getByText("${String(e.text)}")`;case`label`:return`getByLabel("${String(e.text)}")`;case`placeholder`:return`getByPlaceholder("${String(e.text)}")`;case`testId`:return`getByTestId("${e.testId}")`;case`css`:return`locator("${e.selector}")`;case`filter`:return`filter(...)`;case`first`:return`first()`;case`nth`:return`nth(${e.index})`}}).join(`.`)}serializeSteps(){return this.steps.map(e=>{if(e.type===`text`||e.type===`label`||e.type===`placeholder`)return{...e,text:e.text instanceof RegExp?{__regex__:e.text.source,flags:e.text.flags}:e.text};if(e.type===`role`&&e.options?.name instanceof RegExp)return{...e,options:{...e.options,name:{__regex__:e.options.name.source,flags:e.options.name.flags}}};if(e.type===`filter`){let t={};return e.options.hasText&&(t.hasText=e.options.hasText instanceof RegExp?{__regex__:e.options.hasText.source,flags:e.options.hasText.flags}:e.options.hasText),e.options.has&&(t.hasSteps=e.options.has.serializeSteps()),{type:`filter`,options:t}}return e})}buildResolveScript(e,t){return`(function() {
2
2
  var steps = ${JSON.stringify(this.serializeSteps())};
3
3
  var action = "${e}";
4
4
  var extra = ${t===void 0?`null`:JSON.stringify(t)};