@redplanethq/corebrain 2.7.2 → 2.8.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.
Files changed (99) hide show
  1. package/dist/commands/browser/close-session.d.ts +10 -0
  2. package/dist/commands/browser/close-session.d.ts.map +1 -0
  3. package/dist/commands/browser/close-session.js +34 -0
  4. package/dist/commands/browser/close-session.js.map +1 -0
  5. package/dist/commands/browser/close.d.ts +2 -5
  6. package/dist/commands/browser/close.d.ts.map +1 -1
  7. package/dist/commands/browser/close.js +11 -38
  8. package/dist/commands/browser/close.js.map +1 -1
  9. package/dist/commands/browser/command.d.ts +3 -3
  10. package/dist/commands/browser/command.d.ts.map +1 -1
  11. package/dist/commands/browser/command.js +23 -26
  12. package/dist/commands/browser/command.js.map +1 -1
  13. package/dist/commands/browser/create-profile.d.ts +10 -0
  14. package/dist/commands/browser/create-profile.d.ts.map +1 -0
  15. package/dist/commands/browser/create-profile.js +37 -0
  16. package/dist/commands/browser/create-profile.js.map +1 -0
  17. package/dist/commands/browser/create-session.d.ts +4 -2
  18. package/dist/commands/browser/create-session.d.ts.map +1 -1
  19. package/dist/commands/browser/create-session.js +20 -10
  20. package/dist/commands/browser/create-session.js.map +1 -1
  21. package/dist/commands/browser/delete-profile.d.ts +10 -0
  22. package/dist/commands/browser/delete-profile.d.ts.map +1 -0
  23. package/dist/commands/browser/delete-profile.js +44 -0
  24. package/dist/commands/browser/delete-profile.js.map +1 -0
  25. package/dist/commands/browser/delete-session.d.ts.map +1 -1
  26. package/dist/commands/browser/delete-session.js +5 -13
  27. package/dist/commands/browser/delete-session.js.map +1 -1
  28. package/dist/commands/browser/install.d.ts.map +1 -1
  29. package/dist/commands/browser/install.js +18 -29
  30. package/dist/commands/browser/install.js.map +1 -1
  31. package/dist/commands/browser/list-sessions.d.ts.map +1 -1
  32. package/dist/commands/browser/list-sessions.js +8 -5
  33. package/dist/commands/browser/list-sessions.js.map +1 -1
  34. package/dist/commands/browser/open-head.d.ts.map +1 -1
  35. package/dist/commands/browser/open-head.js +21 -23
  36. package/dist/commands/browser/open-head.js.map +1 -1
  37. package/dist/commands/browser/open.d.ts +2 -2
  38. package/dist/commands/browser/open.d.ts.map +1 -1
  39. package/dist/commands/browser/open.js +27 -23
  40. package/dist/commands/browser/open.js.map +1 -1
  41. package/dist/commands/browser/set-browser.js +1 -1
  42. package/dist/commands/browser/set-browser.js.map +1 -1
  43. package/dist/commands/browser/status.d.ts.map +1 -1
  44. package/dist/commands/browser/status.js +23 -20
  45. package/dist/commands/browser/status.js.map +1 -1
  46. package/dist/commands/gateway/config.js +6 -6
  47. package/dist/commands/gateway/config.js.map +1 -1
  48. package/dist/commands/gateway/start.js +2 -2
  49. package/dist/commands/gateway/start.js.map +1 -1
  50. package/dist/server/gateway-client.js +2 -2
  51. package/dist/server/gateway-client.js.map +1 -1
  52. package/dist/server/tools/browser-tools.d.ts +0 -16
  53. package/dist/server/tools/browser-tools.d.ts.map +1 -1
  54. package/dist/server/tools/browser-tools.js +412 -121
  55. package/dist/server/tools/browser-tools.js.map +1 -1
  56. package/dist/server/tools/coding-tools.d.ts.map +1 -1
  57. package/dist/server/tools/coding-tools.js +4 -3
  58. package/dist/server/tools/coding-tools.js.map +1 -1
  59. package/dist/tui/chat.d.ts.map +1 -1
  60. package/dist/tui/chat.js +6 -4
  61. package/dist/tui/chat.js.map +1 -1
  62. package/dist/tui/hooks/use-conversation.d.ts.map +1 -1
  63. package/dist/tui/hooks/use-conversation.js +1 -0
  64. package/dist/tui/hooks/use-conversation.js.map +1 -1
  65. package/dist/types/config.d.ts +6 -1
  66. package/dist/types/config.d.ts.map +1 -1
  67. package/dist/utils/browser-config.d.ts +51 -0
  68. package/dist/utils/browser-config.d.ts.map +1 -0
  69. package/dist/utils/browser-config.js +293 -0
  70. package/dist/utils/browser-config.js.map +1 -0
  71. package/dist/utils/browser-manager.d.ts +27 -0
  72. package/dist/utils/browser-manager.d.ts.map +1 -0
  73. package/dist/utils/browser-manager.js +131 -0
  74. package/dist/utils/browser-manager.js.map +1 -0
  75. package/dist/utils/coding-agents/claude-code.d.ts +0 -1
  76. package/dist/utils/coding-agents/claude-code.d.ts.map +1 -1
  77. package/dist/utils/coding-agents/claude-code.js +0 -4
  78. package/dist/utils/coding-agents/claude-code.js.map +1 -1
  79. package/dist/utils/coding-agents/codex.d.ts +0 -1
  80. package/dist/utils/coding-agents/codex.d.ts.map +1 -1
  81. package/dist/utils/coding-agents/codex.js +0 -3
  82. package/dist/utils/coding-agents/codex.js.map +1 -1
  83. package/dist/utils/coding-agents/index.d.ts +0 -1
  84. package/dist/utils/coding-agents/index.d.ts.map +1 -1
  85. package/dist/utils/coding-agents/index.js +0 -3
  86. package/dist/utils/coding-agents/index.js.map +1 -1
  87. package/dist/utils/coding-agents/types.d.ts +0 -1
  88. package/dist/utils/coding-agents/types.d.ts.map +1 -1
  89. package/dist/utils/coding-agents/types.js +0 -1
  90. package/dist/utils/coding-agents/types.js.map +1 -1
  91. package/dist/utils/coding-runner.d.ts +2 -4
  92. package/dist/utils/coding-runner.d.ts.map +1 -1
  93. package/dist/utils/coding-runner.js +4 -7
  94. package/dist/utils/coding-runner.js.map +1 -1
  95. package/package.json +2 -1
  96. package/dist/utils/agent-browser.d.ts +0 -135
  97. package/dist/utils/agent-browser.d.ts.map +0 -1
  98. package/dist/utils/agent-browser.js +0 -561
  99. package/dist/utils/agent-browser.js.map +0 -1
@@ -1,193 +1,484 @@
1
1
  import zod from 'zod';
2
- import { browserOpen, browserClose, browserCommand, browserGetSessions, browserCloseAll, isBlockedCommand, getMaxSessions, } from '../../utils/agent-browser.js';
2
+ import { getOrLaunchSession, closeSession, closeAllSessions, getLiveSessions, } from '../../utils/browser-manager.js';
3
+ import { getConfiguredProfiles, getConfiguredSessions, getMaxProfiles, getMaxSessions, createSession, deleteSession, } from '../../utils/browser-config.js';
4
+ // ============ Helpers ============
5
+ function resolveLocator(page, element, ref) {
6
+ if (ref)
7
+ return page.locator(ref);
8
+ return page.getByText(element, { exact: false });
9
+ }
3
10
  // ============ Zod Schemas ============
4
- export const BrowserOpenSchema = zod.object({
5
- url: zod.string().describe('URL to open'),
6
- sessionName: zod
7
- .string()
8
- .optional()
9
- .default('corebrain')
10
- .describe('Session name (must be pre-configured, default: corebrain)'),
11
- headed: zod.boolean().optional().default(false).describe('Headed session'),
11
+ const SessionParam = zod
12
+ .string()
13
+ .describe('Session name (e.g. create_swiggy_order). Use browser_list_sessions to see available sessions.');
14
+ const NavigateSchema = zod.object({
15
+ url: zod.string().describe('URL to navigate to'),
16
+ session: SessionParam,
17
+ headed: zod.boolean().optional().default(false).describe('Launch in headed (visible) mode. Required for sites that block headless browsers (e.g. Swiggy, Amazon).'),
18
+ });
19
+ const SnapshotSchema = zod.object({ session: SessionParam });
20
+ const ClickSchema = zod.object({
21
+ element: zod.string().describe('Element description for text lookup'),
22
+ ref: zod.string().optional().describe('CSS/ARIA ref selector (takes priority over element)'),
23
+ session: SessionParam,
24
+ });
25
+ const FillSchema = zod.object({
26
+ element: zod.string().describe('Input element description'),
27
+ value: zod.string().describe('Value to fill'),
28
+ ref: zod.string().optional().describe('CSS/ARIA ref selector'),
29
+ session: SessionParam,
12
30
  });
13
- export const BrowserCloseSchema = zod.object({
14
- sessionName: zod.string().describe('Session name to close'),
31
+ const TypeSchema = zod.object({
32
+ element: zod.string().describe('Element description'),
33
+ text: zod.string().describe('Text to type character by character'),
34
+ ref: zod.string().optional().describe('CSS/ARIA ref selector'),
35
+ session: SessionParam,
15
36
  });
16
- export const BrowserCommandSchema = zod.object({
17
- sessionName: zod.string().describe('Session name to run command on'),
18
- command: zod
19
- .string()
20
- .describe('Command to run (e.g., click, fill, type, screenshot, etc.)'),
21
- args: zod
22
- .array(zod.string())
37
+ const PressKeySchema = zod.object({
38
+ key: zod.string().describe('Key to press (e.g. Enter, Tab, ArrowDown)'),
39
+ session: SessionParam,
40
+ });
41
+ const SelectOptionSchema = zod.object({
42
+ element: zod.string().describe('Select element description'),
43
+ value: zod.string().describe('Option value to select'),
44
+ ref: zod.string().optional().describe('CSS/ARIA ref selector'),
45
+ session: SessionParam,
46
+ });
47
+ const ScreenshotSchema = zod.object({ session: SessionParam });
48
+ const WaitForSchema = zod.object({
49
+ state: zod
50
+ .enum(['load', 'domcontentloaded', 'networkidle'])
23
51
  .optional()
24
- .default([])
25
- .describe('Command arguments'),
52
+ .default('load')
53
+ .describe('Load state to wait for'),
54
+ session: SessionParam,
55
+ });
56
+ const EvaluateSchema = zod.object({
57
+ script: zod.string().describe('JavaScript expression to evaluate in the page context'),
58
+ session: SessionParam,
59
+ });
60
+ const GoBackSchema = zod.object({ session: SessionParam });
61
+ const GoForwardSchema = zod.object({ session: SessionParam });
62
+ const ScrollSchema = zod.object({
63
+ deltaX: zod.number().optional().default(0).describe('Horizontal scroll amount in pixels'),
64
+ deltaY: zod.number().optional().default(300).describe('Vertical scroll amount in pixels'),
65
+ session: SessionParam,
66
+ });
67
+ const CloseSessionSchema = zod.object({ session: SessionParam });
68
+ const CloseAllSchema = zod.object({});
69
+ const ListSessionsSchema = zod.object({});
70
+ const CreateSessionSchema = zod.object({
71
+ session: zod.string().describe('Session name to create (e.g. swiggy_order)'),
72
+ profile: zod.string().describe('Profile to bind this session to (e.g. personal, work)'),
73
+ });
74
+ const DeleteSessionSchema = zod.object({
75
+ session: zod.string().describe('Session name to delete'),
26
76
  });
27
- export const BrowserGetSessionsSchema = zod.object({});
28
- export const BrowserCloseAllSchema = zod.object({});
29
77
  // ============ JSON Schemas ============
78
+ const sessionProp = {
79
+ type: 'string',
80
+ description: 'Session name (e.g. create_swiggy_order). Use browser_list_sessions to see configured sessions.',
81
+ };
30
82
  const jsonSchemas = {
31
- browser_open: {
83
+ browser_navigate: {
32
84
  type: 'object',
33
85
  properties: {
34
- url: { type: 'string', description: 'URL to open' },
35
- sessionName: {
36
- type: 'string',
37
- description: 'Session name (must be pre-configured). Default: personal. Use browser_list_sessions to see available sessions.',
38
- },
39
- headed: {
40
- type: 'boolean',
41
- description: 'Headed session. Default: false',
42
- },
86
+ url: { type: 'string', description: 'URL to navigate to' },
87
+ session: sessionProp,
88
+ headed: { type: 'boolean', description: 'Launch in headed (visible) mode. Required for sites that block headless browsers (e.g. Swiggy, Amazon). Default: false' },
43
89
  },
44
- required: ['url'],
90
+ required: ['url', 'session'],
45
91
  },
46
- browser_close: {
92
+ browser_snapshot: {
93
+ type: 'object',
94
+ properties: { session: sessionProp },
95
+ required: ['session'],
96
+ },
97
+ browser_click: {
47
98
  type: 'object',
48
99
  properties: {
49
- sessionName: { type: 'string', description: 'Session name to close' },
100
+ element: { type: 'string', description: 'Element text/description for lookup' },
101
+ ref: { type: 'string', description: 'CSS/ARIA selector (takes priority)' },
102
+ session: sessionProp,
50
103
  },
51
- required: ['sessionName'],
104
+ required: ['element', 'session'],
52
105
  },
53
- browser_command: {
106
+ browser_fill: {
54
107
  type: 'object',
55
108
  properties: {
56
- sessionName: {
57
- type: 'string',
58
- description: 'Session name to run command on',
59
- },
60
- command: {
109
+ element: { type: 'string', description: 'Input element text/description' },
110
+ value: { type: 'string', description: 'Value to fill' },
111
+ ref: { type: 'string', description: 'CSS/ARIA selector (takes priority)' },
112
+ session: sessionProp,
113
+ },
114
+ required: ['element', 'value', 'session'],
115
+ },
116
+ browser_type: {
117
+ type: 'object',
118
+ properties: {
119
+ element: { type: 'string', description: 'Element text/description' },
120
+ text: { type: 'string', description: 'Text to type character by character' },
121
+ ref: { type: 'string', description: 'CSS/ARIA selector (takes priority)' },
122
+ session: sessionProp,
123
+ },
124
+ required: ['element', 'text', 'session'],
125
+ },
126
+ browser_press_key: {
127
+ type: 'object',
128
+ properties: {
129
+ key: { type: 'string', description: 'Key to press (e.g. Enter, Tab, ArrowDown)' },
130
+ session: sessionProp,
131
+ },
132
+ required: ['key', 'session'],
133
+ },
134
+ browser_select_option: {
135
+ type: 'object',
136
+ properties: {
137
+ element: { type: 'string', description: 'Select element text/description' },
138
+ value: { type: 'string', description: 'Option value to select' },
139
+ ref: { type: 'string', description: 'CSS/ARIA selector (takes priority)' },
140
+ session: sessionProp,
141
+ },
142
+ required: ['element', 'value', 'session'],
143
+ },
144
+ browser_screenshot: {
145
+ type: 'object',
146
+ properties: { session: sessionProp },
147
+ required: ['session'],
148
+ },
149
+ browser_wait_for: {
150
+ type: 'object',
151
+ properties: {
152
+ state: {
61
153
  type: 'string',
62
- description: 'Command to run. Available: click, dblclick, fill, type, press, hover, select, check, uncheck, scroll, screenshot, snapshot, eval, get, is, find, wait, mouse, set, tab, frame, back, forward, reload. Blocked: open, close, cookies, storage, network, download, run, session, task, tunnel, state',
63
- },
64
- args: {
65
- type: 'array',
66
- items: { type: 'string' },
67
- description: 'Command arguments (selector, text, etc.)',
154
+ enum: ['load', 'domcontentloaded', 'networkidle'],
155
+ description: 'Load state to wait for (default: load)',
68
156
  },
157
+ session: sessionProp,
69
158
  },
70
- required: ['sessionName', 'command'],
159
+ required: ['session'],
71
160
  },
72
- browser_list_sessions: {
161
+ browser_evaluate: {
162
+ type: 'object',
163
+ properties: {
164
+ script: { type: 'string', description: 'JavaScript expression to evaluate in page context' },
165
+ session: sessionProp,
166
+ },
167
+ required: ['script', 'session'],
168
+ },
169
+ browser_go_back: {
170
+ type: 'object',
171
+ properties: { session: sessionProp },
172
+ required: ['session'],
173
+ },
174
+ browser_go_forward: {
175
+ type: 'object',
176
+ properties: { session: sessionProp },
177
+ required: ['session'],
178
+ },
179
+ browser_scroll: {
180
+ type: 'object',
181
+ properties: {
182
+ deltaX: { type: 'number', description: 'Horizontal scroll pixels (default: 0)' },
183
+ deltaY: { type: 'number', description: 'Vertical scroll pixels (default: 300)' },
184
+ session: sessionProp,
185
+ },
186
+ required: ['session'],
187
+ },
188
+ browser_close_session: {
189
+ type: 'object',
190
+ properties: { session: sessionProp },
191
+ required: ['session'],
192
+ },
193
+ browser_close_all: {
73
194
  type: 'object',
74
195
  properties: {},
75
196
  required: [],
76
- description: 'List all configured browser sessions',
77
197
  },
78
- browser_close_all: {
198
+ browser_list_sessions: {
79
199
  type: 'object',
80
200
  properties: {},
81
201
  required: [],
82
- description: 'Close all configured browser sessions',
202
+ },
203
+ browser_create_session: {
204
+ type: 'object',
205
+ properties: {
206
+ session: { type: 'string', description: 'Session name to create (e.g. swiggy_order)' },
207
+ profile: { type: 'string', description: 'Profile to bind this session to (e.g. personal, work)' },
208
+ },
209
+ required: ['session', 'profile'],
210
+ },
211
+ browser_delete_session: {
212
+ type: 'object',
213
+ properties: {
214
+ session: { type: 'string', description: 'Session name to delete' },
215
+ },
216
+ required: ['session'],
83
217
  },
84
218
  };
85
219
  // ============ Tool Definitions ============
86
220
  export const browserTools = [
87
221
  {
88
- name: 'browser_open',
89
- description: 'Open a browser with a URL using a pre-configured session. Use browser_list_sessions to see available sessions.',
90
- inputSchema: jsonSchemas.browser_open,
222
+ name: 'browser_navigate',
223
+ description: 'Navigate to a URL in a named browser session.',
224
+ inputSchema: jsonSchemas.browser_navigate,
91
225
  },
92
226
  {
93
- name: 'browser_close',
94
- description: 'Close a browser for the specified session',
95
- inputSchema: jsonSchemas.browser_close,
227
+ name: 'browser_snapshot',
228
+ description: 'Get an ARIA accessibility snapshot of the current page. Use this before interacting with elements to discover refs.',
229
+ inputSchema: jsonSchemas.browser_snapshot,
96
230
  },
97
231
  {
98
- name: 'browser_command',
99
- description: 'Run a browser command on a session. Commands: click, dblclick, fill, type, press, hover, select, check, uncheck, scroll, screenshot, snapshot, eval, get, is, find, wait, mouse, set, tab, frame, back, forward, reload',
100
- inputSchema: jsonSchemas.browser_command,
232
+ name: 'browser_click',
233
+ description: 'Click an element on the page by text description or ref selector.',
234
+ inputSchema: jsonSchemas.browser_click,
101
235
  },
102
236
  {
103
- name: 'browser_list_sessions',
104
- description: `List all configured browser sessions. Maximum ${getMaxSessions()} sessions allowed.`,
105
- inputSchema: jsonSchemas.browser_list_sessions,
237
+ name: 'browser_fill',
238
+ description: 'Fill an input field with a value (clears existing content first).',
239
+ inputSchema: jsonSchemas.browser_fill,
240
+ },
241
+ {
242
+ name: 'browser_type',
243
+ description: 'Type text into an element character by character (simulates real typing).',
244
+ inputSchema: jsonSchemas.browser_type,
245
+ },
246
+ {
247
+ name: 'browser_press_key',
248
+ description: 'Press a keyboard key (e.g. Enter, Tab, ArrowDown, Escape).',
249
+ inputSchema: jsonSchemas.browser_press_key,
250
+ },
251
+ {
252
+ name: 'browser_select_option',
253
+ description: 'Select an option from a <select> dropdown element.',
254
+ inputSchema: jsonSchemas.browser_select_option,
255
+ },
256
+ {
257
+ name: 'browser_screenshot',
258
+ description: 'Take a screenshot of the current page and return it as base64.',
259
+ inputSchema: jsonSchemas.browser_screenshot,
260
+ },
261
+ {
262
+ name: 'browser_wait_for',
263
+ description: 'Wait for a page load state (load, domcontentloaded, networkidle).',
264
+ inputSchema: jsonSchemas.browser_wait_for,
265
+ },
266
+ {
267
+ name: 'browser_evaluate',
268
+ description: 'Evaluate a JavaScript expression in the page context and return the result.',
269
+ inputSchema: jsonSchemas.browser_evaluate,
270
+ },
271
+ {
272
+ name: 'browser_go_back',
273
+ description: 'Navigate to the previous page in history.',
274
+ inputSchema: jsonSchemas.browser_go_back,
275
+ },
276
+ {
277
+ name: 'browser_go_forward',
278
+ description: 'Navigate to the next page in history.',
279
+ inputSchema: jsonSchemas.browser_go_forward,
280
+ },
281
+ {
282
+ name: 'browser_scroll',
283
+ description: 'Scroll the page by the specified pixel amounts.',
284
+ inputSchema: jsonSchemas.browser_scroll,
285
+ },
286
+ {
287
+ name: 'browser_close_session',
288
+ description: 'Close a running browser session (profile data is preserved on disk).',
289
+ inputSchema: jsonSchemas.browser_close_session,
106
290
  },
107
291
  {
108
292
  name: 'browser_close_all',
109
- description: 'Close all configured browser sessions at once.',
293
+ description: 'Close all running browser sessions.',
110
294
  inputSchema: jsonSchemas.browser_close_all,
111
295
  },
296
+ {
297
+ name: 'browser_list_sessions',
298
+ description: `List all configured sessions with their profiles and live status. Max ${getMaxSessions()} sessions, ${getMaxProfiles()} profiles.`,
299
+ inputSchema: jsonSchemas.browser_list_sessions,
300
+ },
301
+ {
302
+ name: 'browser_create_session',
303
+ description: 'Create a new browser session bound to a profile. Use browser_list_sessions to see available profiles first.',
304
+ inputSchema: jsonSchemas.browser_create_session,
305
+ },
306
+ {
307
+ name: 'browser_delete_session',
308
+ description: 'Delete a browser session from config (closes it if running, profile data preserved).',
309
+ inputSchema: jsonSchemas.browser_delete_session,
310
+ },
112
311
  ];
113
312
  // ============ Tool Execution ============
114
313
  export async function executeBrowserTool(toolName, params) {
115
314
  try {
116
315
  switch (toolName) {
117
- case 'browser_open': {
118
- const p = BrowserOpenSchema.parse(params);
119
- const r = await browserOpen(p.url, p.sessionName, p.headed);
120
- if (r.code !== 0) {
121
- return { success: false, error: r.stderr || 'Failed to open browser' };
122
- }
316
+ case 'browser_navigate': {
317
+ const p = NavigateSchema.parse(params);
318
+ const { session, error } = await getOrLaunchSession(p.session, p.headed);
319
+ if (error)
320
+ return { success: false, error };
321
+ const response = await session.page.goto(p.url);
123
322
  return {
124
323
  success: true,
125
324
  result: {
126
- message: `Opened ${p.url} with session "${p.sessionName} headed "${p.headed}"`,
127
- sessionName: p.sessionName,
325
+ url: p.url,
326
+ session: p.session,
327
+ status: response?.status(),
328
+ title: await session.page.title(),
128
329
  },
129
330
  };
130
331
  }
131
- case 'browser_close': {
132
- const p = BrowserCloseSchema.parse(params);
133
- const r = await browserClose(p.sessionName);
134
- if (r.code !== 0) {
135
- return { success: false, error: r.stderr || 'Failed to close browser' };
136
- }
137
- return {
138
- success: true,
139
- result: { message: `Closed browser for session "${p.sessionName}"` },
140
- };
332
+ case 'browser_snapshot': {
333
+ const p = SnapshotSchema.parse(params);
334
+ const { session, error } = await getOrLaunchSession(p.session);
335
+ if (error)
336
+ return { success: false, error };
337
+ const snapshot = await session.page.locator('body').ariaSnapshot();
338
+ return { success: true, result: { snapshot } };
339
+ }
340
+ case 'browser_click': {
341
+ const p = ClickSchema.parse(params);
342
+ const { session, error } = await getOrLaunchSession(p.session);
343
+ if (error)
344
+ return { success: false, error };
345
+ const locator = resolveLocator(session.page, p.element, p.ref);
346
+ await locator.click();
347
+ return { success: true, result: { message: `Clicked "${p.ref ?? p.element}"` } };
348
+ }
349
+ case 'browser_fill': {
350
+ const p = FillSchema.parse(params);
351
+ const { session, error } = await getOrLaunchSession(p.session);
352
+ if (error)
353
+ return { success: false, error };
354
+ const locator = resolveLocator(session.page, p.element, p.ref);
355
+ await locator.fill(p.value);
356
+ return { success: true, result: { message: `Filled "${p.ref ?? p.element}"` } };
357
+ }
358
+ case 'browser_type': {
359
+ const p = TypeSchema.parse(params);
360
+ const { session, error } = await getOrLaunchSession(p.session);
361
+ if (error)
362
+ return { success: false, error };
363
+ const locator = resolveLocator(session.page, p.element, p.ref);
364
+ await locator.pressSequentially(p.text);
365
+ return { success: true, result: { message: `Typed into "${p.ref ?? p.element}"` } };
366
+ }
367
+ case 'browser_press_key': {
368
+ const p = PressKeySchema.parse(params);
369
+ const { session, error } = await getOrLaunchSession(p.session);
370
+ if (error)
371
+ return { success: false, error };
372
+ await session.page.keyboard.press(p.key);
373
+ return { success: true, result: { message: `Pressed key "${p.key}"` } };
374
+ }
375
+ case 'browser_select_option': {
376
+ const p = SelectOptionSchema.parse(params);
377
+ const { session, error } = await getOrLaunchSession(p.session);
378
+ if (error)
379
+ return { success: false, error };
380
+ const locator = resolveLocator(session.page, p.element, p.ref);
381
+ await locator.selectOption(p.value);
382
+ return { success: true, result: { message: `Selected "${p.value}" in "${p.ref ?? p.element}"` } };
141
383
  }
142
- case 'browser_command': {
143
- const p = BrowserCommandSchema.parse(params);
144
- // Check if command is blocked before executing
145
- if (isBlockedCommand(p.command)) {
146
- return {
147
- success: false,
148
- error: `Command "${p.command}" is blocked. Use browser_open or browser_close instead for open/close, other blocked commands are not available.`,
149
- };
150
- }
151
- const r = await browserCommand(p.sessionName, p.command, p.args);
152
- if (r.code !== 0) {
153
- return {
154
- success: false,
155
- error: r.stderr || `Failed to run "${p.command}"`,
156
- };
157
- }
384
+ case 'browser_screenshot': {
385
+ const p = ScreenshotSchema.parse(params);
386
+ const { session, error } = await getOrLaunchSession(p.session);
387
+ if (error)
388
+ return { success: false, error };
389
+ const buffer = await session.page.screenshot();
390
+ return { success: true, result: { screenshot: buffer.toString('base64'), mimeType: 'image/png' } };
391
+ }
392
+ case 'browser_wait_for': {
393
+ const p = WaitForSchema.parse(params);
394
+ const { session, error } = await getOrLaunchSession(p.session);
395
+ if (error)
396
+ return { success: false, error };
397
+ await session.page.waitForLoadState(p.state);
398
+ return { success: true, result: { message: `Waited for "${p.state}"` } };
399
+ }
400
+ case 'browser_evaluate': {
401
+ const p = EvaluateSchema.parse(params);
402
+ const { session, error } = await getOrLaunchSession(p.session);
403
+ if (error)
404
+ return { success: false, error };
405
+ // eslint-disable-next-line no-new-func
406
+ const result = await session.page.evaluate(new Function(`return (${p.script})`));
407
+ return { success: true, result: { value: result } };
408
+ }
409
+ case 'browser_go_back': {
410
+ const p = GoBackSchema.parse(params);
411
+ const { session, error } = await getOrLaunchSession(p.session);
412
+ if (error)
413
+ return { success: false, error };
414
+ await session.page.goBack();
415
+ return { success: true, result: { url: session.page.url() } };
416
+ }
417
+ case 'browser_go_forward': {
418
+ const p = GoForwardSchema.parse(params);
419
+ const { session, error } = await getOrLaunchSession(p.session);
420
+ if (error)
421
+ return { success: false, error };
422
+ await session.page.goForward();
423
+ return { success: true, result: { url: session.page.url() } };
424
+ }
425
+ case 'browser_scroll': {
426
+ const p = ScrollSchema.parse(params);
427
+ const { session, error } = await getOrLaunchSession(p.session);
428
+ if (error)
429
+ return { success: false, error };
430
+ await session.page.mouse.wheel(p.deltaX, p.deltaY);
431
+ return { success: true, result: { message: `Scrolled (${p.deltaX}, ${p.deltaY})` } };
432
+ }
433
+ case 'browser_close_session': {
434
+ const p = CloseSessionSchema.parse(params);
435
+ const r = await closeSession(p.session);
436
+ if (!r.success)
437
+ return { success: false, error: r.error };
438
+ return { success: true, result: { message: `Closed session "${p.session}"` } };
439
+ }
440
+ case 'browser_close_all': {
441
+ CloseAllSchema.parse(params);
442
+ await closeAllSessions();
443
+ return { success: true, result: { message: 'Closed all browser sessions' } };
444
+ }
445
+ case 'browser_list_sessions': {
446
+ ListSessionsSchema.parse(params);
447
+ const configured = getConfiguredSessions();
448
+ const live = getLiveSessions();
449
+ const profiles = getConfiguredProfiles();
158
450
  return {
159
451
  success: true,
160
452
  result: {
161
- message: `Executed "${p.command}" on session "${p.sessionName}"`,
162
- output: r.stdout,
453
+ profiles,
454
+ sessions: configured.map(s => ({
455
+ ...s,
456
+ live: live.includes(s.name),
457
+ })),
458
+ maxProfiles: getMaxProfiles(),
459
+ maxSessions: getMaxSessions(),
163
460
  },
164
461
  };
165
462
  }
166
- case 'browser_list_sessions': {
167
- BrowserGetSessionsSchema.parse(params);
168
- const sessions = browserGetSessions();
169
- const maxSessions = getMaxSessions();
463
+ case 'browser_create_session': {
464
+ const p = CreateSessionSchema.parse(params);
465
+ const r = createSession(p.session, p.profile);
466
+ if (!r.success)
467
+ return { success: false, error: r.error };
170
468
  return {
171
469
  success: true,
172
- result: {
173
- sessions,
174
- count: sessions.length,
175
- maxSessions,
176
- },
470
+ result: { message: `Session "${p.session}" created (profile: ${p.profile})` },
177
471
  };
178
472
  }
179
- case 'browser_close_all': {
180
- BrowserCloseAllSchema.parse(params);
181
- const r = await browserCloseAll();
182
- if (r.code !== 0) {
183
- return {
184
- success: false,
185
- error: r.stderr || 'Failed to close all browsers',
186
- };
187
- }
473
+ case 'browser_delete_session': {
474
+ const p = DeleteSessionSchema.parse(params);
475
+ await closeSession(p.session);
476
+ const r = deleteSession(p.session);
477
+ if (!r.success)
478
+ return { success: false, error: r.error };
188
479
  return {
189
480
  success: true,
190
- result: { message: 'Closed all browser sessions', details: r.stdout },
481
+ result: { message: `Session "${p.session}" deleted` },
191
482
  };
192
483
  }
193
484
  default: