@everydaydevopsio/pilot 0.5.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.
Files changed (108) hide show
  1. package/.ai-agent-bridge.yaml +10 -0
  2. package/.dockerignore +9 -0
  3. package/CLAUDE.md +61 -0
  4. package/LICENSE +21 -0
  5. package/README.md +252 -0
  6. package/dist/browser.d.ts +100 -0
  7. package/dist/browser.d.ts.map +1 -0
  8. package/dist/browser.js +654 -0
  9. package/dist/browser.js.map +1 -0
  10. package/dist/cli/init.d.ts +4 -0
  11. package/dist/cli/init.d.ts.map +1 -0
  12. package/dist/cli/init.js +56 -0
  13. package/dist/cli/init.js.map +1 -0
  14. package/dist/cli/skill-template.d.ts +2 -0
  15. package/dist/cli/skill-template.d.ts.map +1 -0
  16. package/dist/cli/skill-template.js +114 -0
  17. package/dist/cli/skill-template.js.map +1 -0
  18. package/dist/commands/click.d.ts +21 -0
  19. package/dist/commands/click.d.ts.map +1 -0
  20. package/dist/commands/click.js +64 -0
  21. package/dist/commands/click.js.map +1 -0
  22. package/dist/commands/evaluate.d.ts +14 -0
  23. package/dist/commands/evaluate.d.ts.map +1 -0
  24. package/dist/commands/evaluate.js +28 -0
  25. package/dist/commands/evaluate.js.map +1 -0
  26. package/dist/commands/navigate.d.ts +19 -0
  27. package/dist/commands/navigate.d.ts.map +1 -0
  28. package/dist/commands/navigate.js +78 -0
  29. package/dist/commands/navigate.js.map +1 -0
  30. package/dist/commands/page_info.d.ts +8 -0
  31. package/dist/commands/page_info.d.ts.map +1 -0
  32. package/dist/commands/page_info.js +13 -0
  33. package/dist/commands/page_info.js.map +1 -0
  34. package/dist/commands/screenshot.d.ts +18 -0
  35. package/dist/commands/screenshot.d.ts.map +1 -0
  36. package/dist/commands/screenshot.js +37 -0
  37. package/dist/commands/screenshot.js.map +1 -0
  38. package/dist/commands/tabs.d.ts +10 -0
  39. package/dist/commands/tabs.d.ts.map +1 -0
  40. package/dist/commands/tabs.js +15 -0
  41. package/dist/commands/tabs.js.map +1 -0
  42. package/dist/commands/type.d.ts +14 -0
  43. package/dist/commands/type.d.ts.map +1 -0
  44. package/dist/commands/type.js +61 -0
  45. package/dist/commands/type.js.map +1 -0
  46. package/dist/commands/wait.d.ts +17 -0
  47. package/dist/commands/wait.d.ts.map +1 -0
  48. package/dist/commands/wait.js +61 -0
  49. package/dist/commands/wait.js.map +1 -0
  50. package/dist/mcp/console-buffer.d.ts +28 -0
  51. package/dist/mcp/console-buffer.d.ts.map +1 -0
  52. package/dist/mcp/console-buffer.js +68 -0
  53. package/dist/mcp/console-buffer.js.map +1 -0
  54. package/dist/mcp/index.d.ts +3 -0
  55. package/dist/mcp/index.d.ts.map +1 -0
  56. package/dist/mcp/index.js +74 -0
  57. package/dist/mcp/index.js.map +1 -0
  58. package/dist/mcp/server.d.ts +18 -0
  59. package/dist/mcp/server.d.ts.map +1 -0
  60. package/dist/mcp/server.js +46 -0
  61. package/dist/mcp/server.js.map +1 -0
  62. package/dist/mcp/tools/browser.d.ts +5 -0
  63. package/dist/mcp/tools/browser.d.ts.map +1 -0
  64. package/dist/mcp/tools/browser.js +435 -0
  65. package/dist/mcp/tools/browser.js.map +1 -0
  66. package/dist/mcp/tools/errors.d.ts +4 -0
  67. package/dist/mcp/tools/errors.d.ts.map +1 -0
  68. package/dist/mcp/tools/errors.js +117 -0
  69. package/dist/mcp/tools/errors.js.map +1 -0
  70. package/dist/mcp/tools/names.d.ts +7 -0
  71. package/dist/mcp/tools/names.d.ts.map +1 -0
  72. package/dist/mcp/tools/names.js +24 -0
  73. package/dist/mcp/tools/names.js.map +1 -0
  74. package/dist/util/config.d.ts +34 -0
  75. package/dist/util/config.d.ts.map +1 -0
  76. package/dist/util/config.js +53 -0
  77. package/dist/util/config.js.map +1 -0
  78. package/dist/util/logger.d.ts +4 -0
  79. package/dist/util/logger.d.ts.map +1 -0
  80. package/dist/util/logger.js +16 -0
  81. package/dist/util/logger.js.map +1 -0
  82. package/dist/viewport.d.ts +105 -0
  83. package/dist/viewport.d.ts.map +1 -0
  84. package/dist/viewport.js +145 -0
  85. package/dist/viewport.js.map +1 -0
  86. package/package.json +74 -0
  87. package/smoke/mcp-smoke.ts +161 -0
  88. package/src/browser.ts +798 -0
  89. package/src/cli/init.ts +62 -0
  90. package/src/cli/skill-template.ts +113 -0
  91. package/src/commands/click.ts +93 -0
  92. package/src/commands/evaluate.ts +45 -0
  93. package/src/commands/navigate.ts +105 -0
  94. package/src/commands/page_info.ts +21 -0
  95. package/src/commands/screenshot.ts +72 -0
  96. package/src/commands/tabs.ts +35 -0
  97. package/src/commands/type.ts +77 -0
  98. package/src/commands/wait.ts +90 -0
  99. package/src/mcp/console-buffer.ts +94 -0
  100. package/src/mcp/index.ts +107 -0
  101. package/src/mcp/server.ts +67 -0
  102. package/src/mcp/tools/browser.ts +605 -0
  103. package/src/mcp/tools/errors.ts +158 -0
  104. package/src/mcp/tools/names.ts +25 -0
  105. package/src/util/config.ts +71 -0
  106. package/src/util/logger.ts +18 -0
  107. package/src/viewport.ts +204 -0
  108. package/tsconfig.json +24 -0
@@ -0,0 +1,435 @@
1
+ import { z } from 'zod';
2
+ import { executeScreenshot } from '../../commands/screenshot.js';
3
+ import { executeNavigate } from '../../commands/navigate.js';
4
+ import { executeClick } from '../../commands/click.js';
5
+ import { executeType } from '../../commands/type.js';
6
+ import { executeEvaluate } from '../../commands/evaluate.js';
7
+ import { executeWait } from '../../commands/wait.js';
8
+ import { executePageInfo } from '../../commands/page_info.js';
9
+ import { executeListTabs, executeNewTab, executeCloseTab, executeSwitchTab } from '../../commands/tabs.js';
10
+ import { VIEWPORT_PRESETS, applyViewport } from '../../viewport.js';
11
+ // Raw shapes for MCP SDK (expects ZodRawShape, not ZodObject)
12
+ const screenshotShape = {
13
+ format: z
14
+ .enum(['png', 'jpeg'])
15
+ .default('png')
16
+ .describe('Image format (png or jpeg)'),
17
+ quality: z
18
+ .number()
19
+ .int()
20
+ .min(1)
21
+ .max(100)
22
+ .default(80)
23
+ .describe('JPEG quality (1-100, ignored for PNG)'),
24
+ fullPage: z
25
+ .boolean()
26
+ .default(false)
27
+ .describe('Capture full scrollable page instead of viewport')
28
+ };
29
+ const navigateShape = {
30
+ url: z.string().url().describe('URL to navigate to'),
31
+ waitUntil: z
32
+ .enum(['load', 'domcontentloaded', 'networkidle'])
33
+ .default('load')
34
+ .describe('Wait condition: load, domcontentloaded, or networkidle'),
35
+ timeoutMs: z
36
+ .number()
37
+ .int()
38
+ .positive()
39
+ .default(30000)
40
+ .describe('Navigation timeout in milliseconds')
41
+ };
42
+ const clickShape = {
43
+ selector: z.string().optional().describe('CSS selector to click'),
44
+ x: z.number().optional().describe('Viewport X coordinate'),
45
+ y: z.number().optional().describe('Viewport Y coordinate'),
46
+ button: z
47
+ .enum(['left', 'right', 'middle'])
48
+ .default('left')
49
+ .describe('Mouse button'),
50
+ clickCount: z
51
+ .number()
52
+ .int()
53
+ .positive()
54
+ .default(1)
55
+ .describe('Number of clicks (2 for double-click)'),
56
+ timeoutMs: z
57
+ .number()
58
+ .int()
59
+ .positive()
60
+ .default(5000)
61
+ .describe('Timeout waiting for selector')
62
+ };
63
+ const typeShape = {
64
+ text: z.string().describe('Text to type'),
65
+ selector: z.string().optional().describe('CSS selector to focus first'),
66
+ clearFirst: z
67
+ .boolean()
68
+ .default(false)
69
+ .describe('Clear the field before typing'),
70
+ delayMs: z
71
+ .number()
72
+ .int()
73
+ .min(0)
74
+ .default(0)
75
+ .describe('Delay between keystrokes in milliseconds')
76
+ };
77
+ const evaluateShape = {
78
+ expression: z.string().describe('JavaScript expression to evaluate'),
79
+ awaitPromise: z
80
+ .boolean()
81
+ .default(true)
82
+ .describe('Await if result is a Promise'),
83
+ timeoutMs: z
84
+ .number()
85
+ .int()
86
+ .positive()
87
+ .default(10000)
88
+ .describe('Evaluation timeout in milliseconds')
89
+ };
90
+ const waitShape = {
91
+ selector: z.string().optional().describe('Wait for selector to exist'),
92
+ selectorVisible: z
93
+ .string()
94
+ .optional()
95
+ .describe('Wait for selector to be visible'),
96
+ networkIdle: z.boolean().optional().describe('Wait for network to be idle'),
97
+ ms: z.number().int().min(0).optional().describe('Fixed delay in ms'),
98
+ timeoutMs: z
99
+ .number()
100
+ .int()
101
+ .positive()
102
+ .default(10000)
103
+ .describe('Overall timeout')
104
+ };
105
+ const startShape = {
106
+ headless: z
107
+ .boolean()
108
+ .optional()
109
+ .describe('Run Chrome headless. When omitted, falls back to PILOT_HEADLESS (default: true).'),
110
+ chromePath: z
111
+ .string()
112
+ .optional()
113
+ .describe('Path to Chrome executable (auto-detected if omitted)'),
114
+ profileName: z
115
+ .string()
116
+ .optional()
117
+ .describe('Browser profile name. Data is stored under $XDG_DATA_HOME/pilot/<profileName>/ (default: ~/.local/share/pilot/<profileName>/). Defaults to PILOT_PROFILE_NAME env var or "profile1".'),
118
+ viewport: z
119
+ .enum(Object.keys(VIEWPORT_PRESETS))
120
+ .optional()
121
+ .describe(`Viewport preset: ${Object.entries(VIEWPORT_PRESETS)
122
+ .map(([name, cfg]) => `${name} (${cfg.width}x${cfg.height})`)
123
+ .join(', ')}. Defaults to PILOT_VIEWPORT env var or "desktop".`),
124
+ viewportWidth: z
125
+ .number()
126
+ .int()
127
+ .positive()
128
+ .optional()
129
+ .describe('Custom viewport width in pixels. Overrides the preset width.'),
130
+ viewportHeight: z
131
+ .number()
132
+ .int()
133
+ .positive()
134
+ .optional()
135
+ .describe('Custom viewport height in pixels. Overrides the preset height.'),
136
+ deviceScaleFactor: z
137
+ .number()
138
+ .positive()
139
+ .optional()
140
+ .describe('Custom device scale factor (DPR). Overrides the preset value. Only takes effect in locked (non-responsive) mode.'),
141
+ responsive: z
142
+ .boolean()
143
+ .optional()
144
+ .describe('Responsive mode. When true, the page uses real window dimensions and reflows on resize (like a normal browser). Desktop presets default to true; mobile/tablet presets leave this unset (locked viewport). Set to false to lock the viewport with setDeviceMetricsOverride.')
145
+ };
146
+ const newTabShape = {
147
+ url: z
148
+ .string()
149
+ .optional()
150
+ .describe('URL to open in the new tab (opens blank tab if omitted)')
151
+ };
152
+ const closeTabShape = {
153
+ targetId: z.string().describe('Target ID of the tab to close')
154
+ };
155
+ const switchTabShape = {
156
+ targetId: z.string().describe('Target ID of the tab to switch to')
157
+ };
158
+ const viewportResizeShape = {
159
+ width: z.number().int().positive().describe('New viewport width in pixels'),
160
+ height: z.number().int().positive().describe('New viewport height in pixels'),
161
+ deviceScaleFactor: z
162
+ .number()
163
+ .positive()
164
+ .optional()
165
+ .describe('Device scale factor (DPR). Defaults to the current value if omitted.'),
166
+ mobile: z
167
+ .boolean()
168
+ .optional()
169
+ .describe('Emulate a mobile device. Defaults to the current value if omitted.')
170
+ };
171
+ function requireClient(context) {
172
+ const manager = context.manager;
173
+ if (!manager || !manager.isConnected()) {
174
+ throw new Error('Browser not started. Call browser_start first.');
175
+ }
176
+ const client = manager.getClient();
177
+ return { client, manager };
178
+ }
179
+ export function registerBrowserTools(server, context, makeBrowserManager) {
180
+ server.tool('browser_start', 'Launch the Chrome browser. Call this before using any other browser tools.', startShape, async ({ headless, chromePath, profileName, viewport, viewportWidth, viewportHeight, deviceScaleFactor, responsive }) => {
181
+ if (context.manager?.isConnected()) {
182
+ return {
183
+ content: [
184
+ {
185
+ type: 'text',
186
+ text: 'Browser is already running.'
187
+ }
188
+ ]
189
+ };
190
+ }
191
+ if (context.manager) {
192
+ await context.manager.destroy();
193
+ context.manager = null;
194
+ }
195
+ const manager = makeBrowserManager();
196
+ const { headless: effectiveHeadless, viewport: effectiveViewport } = await manager.launch({
197
+ headless,
198
+ chromePath,
199
+ profileName,
200
+ viewport,
201
+ viewportWidth,
202
+ viewportHeight,
203
+ deviceScaleFactor,
204
+ responsive
205
+ });
206
+ context.manager = manager;
207
+ return {
208
+ content: [
209
+ {
210
+ type: 'text',
211
+ text: `Browser started${effectiveHeadless ? ' (headless)' : ' (visible)'}, viewport: ${effectiveViewport}.`
212
+ }
213
+ ]
214
+ };
215
+ });
216
+ server.tool('browser_stop', 'Stop the Chrome browser and free all resources.', {}, async () => {
217
+ if (!context.manager) {
218
+ return {
219
+ content: [{ type: 'text', text: 'Browser is not running.' }]
220
+ };
221
+ }
222
+ await context.manager.destroy();
223
+ context.manager = null;
224
+ return {
225
+ content: [{ type: 'text', text: 'Browser stopped.' }]
226
+ };
227
+ });
228
+ server.tool('browser_screenshot', 'Capture a screenshot of the current browser viewport or full page', screenshotShape, async ({ format, quality, fullPage }) => {
229
+ const { client } = requireClient(context);
230
+ const result = await executeScreenshot(client, {
231
+ format,
232
+ quality,
233
+ fullPage
234
+ });
235
+ const base64Match = result.dataUrl.match(/^data:image\/\w+;base64,(.+)$/);
236
+ if (base64Match) {
237
+ return {
238
+ content: [
239
+ {
240
+ type: 'image',
241
+ data: base64Match[1],
242
+ mimeType: format === 'jpeg' ? 'image/jpeg' : 'image/png'
243
+ }
244
+ ]
245
+ };
246
+ }
247
+ return {
248
+ content: [
249
+ {
250
+ type: 'text',
251
+ text: `Screenshot captured: ${result.width}x${result.height}`
252
+ }
253
+ ]
254
+ };
255
+ });
256
+ server.tool('browser_navigate', 'Navigate to a URL and wait for page load', navigateShape, async ({ url, waitUntil, timeoutMs }) => {
257
+ const { client, manager } = requireClient(context);
258
+ const result = await executeNavigate(client, manager, {
259
+ url,
260
+ waitUntil,
261
+ timeoutMs
262
+ });
263
+ return {
264
+ content: [
265
+ {
266
+ type: 'text',
267
+ text: `Navigated to ${result.url} (status: ${result.status})`
268
+ }
269
+ ]
270
+ };
271
+ });
272
+ server.tool('browser_click', 'Click an element by CSS selector or coordinates. Either selector or x/y coordinates required.', clickShape, async (params) => {
273
+ if (params.selector === undefined &&
274
+ (params.x === undefined || params.y === undefined)) {
275
+ return {
276
+ content: [
277
+ {
278
+ type: 'text',
279
+ text: 'Error: Either selector or x/y coordinates are required'
280
+ }
281
+ ],
282
+ isError: true
283
+ };
284
+ }
285
+ const { client } = requireClient(context);
286
+ const result = await executeClick(client, params);
287
+ return {
288
+ content: [
289
+ {
290
+ type: 'text',
291
+ text: `Clicked at (${result.x}, ${result.y})`
292
+ }
293
+ ]
294
+ };
295
+ });
296
+ server.tool('browser_type', 'Type text into the focused element or a specified selector', typeShape, async (params) => {
297
+ const { client } = requireClient(context);
298
+ await executeType(client, params);
299
+ return {
300
+ content: [
301
+ {
302
+ type: 'text',
303
+ text: `Typed "${params.text}"${params.selector ? ` into ${params.selector}` : ''}`
304
+ }
305
+ ]
306
+ };
307
+ });
308
+ server.tool('browser_evaluate', 'Execute JavaScript in the page context and return the result', evaluateShape, async ({ expression, awaitPromise, timeoutMs }) => {
309
+ const { client } = requireClient(context);
310
+ const result = await executeEvaluate(client, {
311
+ expression,
312
+ awaitPromise,
313
+ timeoutMs
314
+ });
315
+ return {
316
+ content: [
317
+ {
318
+ type: 'text',
319
+ text: JSON.stringify({ value: result.value, type: result.type }, null, 2)
320
+ }
321
+ ]
322
+ };
323
+ });
324
+ server.tool('browser_wait', 'Wait for a selector, network idle, or fixed delay. At least one wait condition required.', waitShape, async (params) => {
325
+ if (params.selector === undefined &&
326
+ params.selectorVisible === undefined &&
327
+ params.networkIdle === undefined &&
328
+ params.ms === undefined) {
329
+ return {
330
+ content: [
331
+ {
332
+ type: 'text',
333
+ text: 'Error: At least one wait condition is required'
334
+ }
335
+ ],
336
+ isError: true
337
+ };
338
+ }
339
+ const { client, manager } = requireClient(context);
340
+ const result = await executeWait(client, manager, params);
341
+ return {
342
+ content: [
343
+ {
344
+ type: 'text',
345
+ text: `Wait completed in ${result.elapsed}ms`
346
+ }
347
+ ]
348
+ };
349
+ });
350
+ server.tool('browser_page_info', 'Get information about the current page (URL, title, ready state)', {}, async () => {
351
+ const { client } = requireClient(context);
352
+ const result = await executePageInfo(client);
353
+ return {
354
+ content: [
355
+ {
356
+ type: 'text',
357
+ text: JSON.stringify(result, null, 2)
358
+ }
359
+ ]
360
+ };
361
+ });
362
+ server.tool('browser_list_tabs', 'List all open browser tabs with their target IDs, URLs, titles, and active status', {}, async () => {
363
+ const { manager } = requireClient(context);
364
+ const tabs = await executeListTabs(manager);
365
+ return {
366
+ content: [
367
+ {
368
+ type: 'text',
369
+ text: JSON.stringify(tabs, null, 2)
370
+ }
371
+ ]
372
+ };
373
+ });
374
+ server.tool('browser_new_tab', 'Open a new browser tab, optionally navigating to a URL', newTabShape, async ({ url }) => {
375
+ const { manager } = requireClient(context);
376
+ const result = await executeNewTab(manager, url);
377
+ return {
378
+ content: [
379
+ {
380
+ type: 'text',
381
+ text: `New tab opened (targetId: ${result.targetId}, url: ${result.url})`
382
+ }
383
+ ]
384
+ };
385
+ });
386
+ server.tool('browser_close_tab', 'Close a browser tab by its target ID. Cannot close the currently active tab.', closeTabShape, async ({ targetId }) => {
387
+ const { manager } = requireClient(context);
388
+ await executeCloseTab(manager, targetId);
389
+ return {
390
+ content: [
391
+ {
392
+ type: 'text',
393
+ text: `Tab ${targetId} closed.`
394
+ }
395
+ ]
396
+ };
397
+ });
398
+ server.tool('browser_switch_tab', 'Switch the active browser tab to the one with the given target ID. All subsequent commands will target this tab.', switchTabShape, async ({ targetId }) => {
399
+ const { manager } = requireClient(context);
400
+ await executeSwitchTab(manager, targetId);
401
+ return {
402
+ content: [
403
+ {
404
+ type: 'text',
405
+ text: `Switched to tab ${targetId}.`
406
+ }
407
+ ]
408
+ };
409
+ });
410
+ server.tool('browser_viewport_resize', 'Resize the browser viewport to new dimensions. Updates both the window size and the rendering viewport. Disables responsive mode so the viewport stays locked at the specified size.', viewportResizeShape, async ({ width, height, deviceScaleFactor, mobile }) => {
411
+ const { client, manager } = requireClient(context);
412
+ const current = manager.getViewportConfig();
413
+ const effectiveMobile = mobile ?? current?.mobile ?? false;
414
+ const newConfig = {
415
+ width,
416
+ height,
417
+ deviceScaleFactor: deviceScaleFactor ?? current?.deviceScaleFactor ?? 1,
418
+ mobile: effectiveMobile,
419
+ responsive: false,
420
+ ...(effectiveMobile &&
421
+ current?.userAgent && { userAgent: current.userAgent })
422
+ };
423
+ await applyViewport(client, newConfig);
424
+ manager.setViewportConfig(newConfig);
425
+ return {
426
+ content: [
427
+ {
428
+ type: 'text',
429
+ text: `Viewport resized to ${width}x${height} (DPR: ${newConfig.deviceScaleFactor}, mobile: ${newConfig.mobile}).`
430
+ }
431
+ ]
432
+ };
433
+ });
434
+ }
435
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../../src/mcp/tools/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ConsoleBuffer } from '../console-buffer.js';
3
+ export declare function registerErrorTools(server: McpServer, buffer: ConsoleBuffer): void;
4
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/errors.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,sBAAsB,CAAC;AA8CxE,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,aAAa,GACpB,IAAI,CA0GN"}
@@ -0,0 +1,117 @@
1
+ import { z } from 'zod';
2
+ // Raw shapes for MCP SDK (expects ZodRawShape, not ZodObject)
3
+ const getConsoleLogsShape = {
4
+ level: z
5
+ .enum(['log', 'warn', 'error', 'info', 'debug'])
6
+ .optional()
7
+ .describe('Filter by single log level'),
8
+ levels: z
9
+ .array(z.enum(['log', 'warn', 'error', 'info', 'debug']))
10
+ .optional()
11
+ .describe('Filter by multiple log levels'),
12
+ sinceMs: z
13
+ .number()
14
+ .int()
15
+ .positive()
16
+ .optional()
17
+ .describe('Only messages from the last N milliseconds'),
18
+ limit: z
19
+ .number()
20
+ .int()
21
+ .positive()
22
+ .default(100)
23
+ .describe('Maximum messages to return')
24
+ };
25
+ const getErrorsShape = {
26
+ sinceMs: z
27
+ .number()
28
+ .int()
29
+ .positive()
30
+ .optional()
31
+ .describe('Only errors from the last N milliseconds'),
32
+ limit: z
33
+ .number()
34
+ .int()
35
+ .positive()
36
+ .default(50)
37
+ .describe('Maximum errors to return'),
38
+ includeWarnings: z
39
+ .boolean()
40
+ .default(false)
41
+ .describe('Include warnings in addition to errors')
42
+ };
43
+ export function registerErrorTools(server, buffer) {
44
+ server.tool('browser_get_console_logs', 'Get console log messages from the browser. Use this to see console output during testing.', getConsoleLogsShape, async ({ level, levels, sinceMs, limit }) => {
45
+ let filterLevels;
46
+ if (levels && levels.length > 0) {
47
+ filterLevels = levels;
48
+ }
49
+ else if (level) {
50
+ filterLevels = level;
51
+ }
52
+ const messages = buffer.getAll({
53
+ level: filterLevels,
54
+ sinceMs,
55
+ limit
56
+ });
57
+ const total = buffer.size();
58
+ return {
59
+ content: [
60
+ {
61
+ type: 'text',
62
+ text: JSON.stringify({
63
+ messages,
64
+ count: messages.length,
65
+ total,
66
+ hasMore: total > messages.length
67
+ }, null, 2)
68
+ }
69
+ ]
70
+ };
71
+ });
72
+ server.tool('browser_get_errors', 'Get console errors (and optionally warnings) from the browser. Use this to check for JavaScript errors while testing an application.', getErrorsShape, async ({ sinceMs, limit, includeWarnings }) => {
73
+ const levels = includeWarnings
74
+ ? ['error', 'warn']
75
+ : ['error'];
76
+ const errors = buffer.getAll({
77
+ level: levels,
78
+ sinceMs,
79
+ limit
80
+ });
81
+ const total = buffer.size();
82
+ if (errors.length === 0) {
83
+ return {
84
+ content: [
85
+ {
86
+ type: 'text',
87
+ text: 'No errors found.'
88
+ }
89
+ ]
90
+ };
91
+ }
92
+ return {
93
+ content: [
94
+ {
95
+ type: 'text',
96
+ text: JSON.stringify({
97
+ errors,
98
+ count: errors.length,
99
+ hasMore: total > errors.length
100
+ }, null, 2)
101
+ }
102
+ ]
103
+ };
104
+ });
105
+ server.tool('browser_clear_errors', 'Clear the console message buffer. Use this before testing to get a clean slate.', {}, async () => {
106
+ const cleared = buffer.clear();
107
+ return {
108
+ content: [
109
+ {
110
+ type: 'text',
111
+ text: `Cleared ${cleared} console messages.`
112
+ }
113
+ ]
114
+ };
115
+ });
116
+ }
117
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/mcp/tools/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Canonical list of MCP tool names registered by this server.
3
+ * Shared between the smoke test and e2e test suite so both stay in sync.
4
+ */
5
+ export declare const EXPECTED_TOOLS: readonly ["browser_start", "browser_stop", "browser_screenshot", "browser_navigate", "browser_click", "browser_type", "browser_evaluate", "browser_wait", "browser_page_info", "browser_list_tabs", "browser_new_tab", "browser_close_tab", "browser_switch_tab", "browser_viewport_resize", "browser_get_console_logs", "browser_get_errors", "browser_clear_errors"];
6
+ export type ToolName = (typeof EXPECTED_TOOLS)[number];
7
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/names.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,eAAO,MAAM,cAAc,wWAkBjB,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Canonical list of MCP tool names registered by this server.
3
+ * Shared between the smoke test and e2e test suite so both stay in sync.
4
+ */
5
+ export const EXPECTED_TOOLS = [
6
+ 'browser_start',
7
+ 'browser_stop',
8
+ 'browser_screenshot',
9
+ 'browser_navigate',
10
+ 'browser_click',
11
+ 'browser_type',
12
+ 'browser_evaluate',
13
+ 'browser_wait',
14
+ 'browser_page_info',
15
+ 'browser_list_tabs',
16
+ 'browser_new_tab',
17
+ 'browser_close_tab',
18
+ 'browser_switch_tab',
19
+ 'browser_viewport_resize',
20
+ 'browser_get_console_logs',
21
+ 'browser_get_errors',
22
+ 'browser_clear_errors'
23
+ ];
24
+ //# sourceMappingURL=names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../../../src/mcp/tools/names.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,eAAe;IACf,cAAc;IACd,oBAAoB;IACpB,kBAAkB;IAClB,eAAe;IACf,cAAc;IACd,kBAAkB;IAClB,cAAc;IACd,mBAAmB;IACnB,mBAAmB;IACnB,iBAAiB;IACjB,mBAAmB;IACnB,oBAAoB;IACpB,yBAAyB;IACzB,0BAA0B;IAC1B,oBAAoB;IACpB,sBAAsB;CACd,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod';
2
+ declare const ConfigSchema: z.ZodObject<{
3
+ cdpPort: z.ZodDefault<z.ZodNumber>;
4
+ cdpHost: z.ZodDefault<z.ZodString>;
5
+ cdpRetryMs: z.ZodDefault<z.ZodNumber>;
6
+ cdpMaxRetryMs: z.ZodDefault<z.ZodNumber>;
7
+ logLevel: z.ZodDefault<z.ZodEnum<{
8
+ fatal: "fatal";
9
+ error: "error";
10
+ warn: "warn";
11
+ info: "info";
12
+ debug: "debug";
13
+ trace: "trace";
14
+ }>>;
15
+ chromePath: z.ZodOptional<z.ZodString>;
16
+ headless: z.ZodDefault<z.ZodBoolean>;
17
+ profileName: z.ZodDefault<z.ZodString>;
18
+ viewport: z.ZodDefault<z.ZodString>;
19
+ responsive: z.ZodOptional<z.ZodBoolean>;
20
+ }, z.core.$strip>;
21
+ export type Config = z.infer<typeof ConfigSchema>;
22
+ export interface CliArgs {
23
+ cdpPort?: number;
24
+ cdpHost?: string;
25
+ logLevel?: string;
26
+ chromePath?: string;
27
+ headless?: boolean;
28
+ profileName?: string;
29
+ viewport?: string;
30
+ responsive?: boolean;
31
+ }
32
+ export declare function loadConfig(cliArgs?: CliArgs): Config;
33
+ export {};
34
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/util/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;iBAahB,CAAC;AAEH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,MAAM,WAAW,OAAO;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,wBAAgB,UAAU,CAAC,OAAO,GAAE,OAAY,GAAG,MAAM,CAwCxD"}