@mearl/client 2.20.0 → 2.20.1

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.
@@ -323,6 +323,12 @@ export type BrowserProviderInputSchema = (BrowserProviderSchemaBase & {
323
323
  maxLength?: number;
324
324
  pattern?: string;
325
325
  placeholder?: string;
326
+ options?: readonly {
327
+ value: string;
328
+ label: string;
329
+ description?: string;
330
+ disabled?: boolean;
331
+ }[];
326
332
  }) | (BrowserProviderSchemaBase & {
327
333
  type: 'number';
328
334
  integer?: boolean;
@@ -353,8 +359,29 @@ export interface BrowserProviderDefinition {
353
359
  configuration?: {
354
360
  inputSchema: BrowserProviderObjectSchema;
355
361
  };
362
+ dynamicLaunchForm?: boolean;
363
+ launchForm?: BrowserProviderLaunchForm;
356
364
  };
357
365
  }
366
+ export interface BrowserProviderLaunchFormVariant {
367
+ id: string;
368
+ title: string;
369
+ description?: string;
370
+ inputSchema?: BrowserProviderObjectSchema;
371
+ values?: Record<string, BrowserJsonValue>;
372
+ refreshOn?: readonly string[];
373
+ dynamicFields?: readonly string[];
374
+ }
375
+ export interface BrowserProviderLaunchForm {
376
+ inputSchema: BrowserProviderObjectSchema;
377
+ variants?: readonly BrowserProviderLaunchFormVariant[];
378
+ variant?: string;
379
+ values?: Record<string, BrowserJsonValue>;
380
+ refreshOn?: readonly string[];
381
+ dynamicFields?: readonly string[];
382
+ message?: string;
383
+ blocked?: boolean;
384
+ }
358
385
  export interface BrowserProviderListResult {
359
386
  providers: BrowserProviderDefinition[];
360
387
  }
@@ -49,7 +49,7 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
49
49
  modalRestoreFrame = null;
50
50
  if (document.querySelector?.('dialog:modal')) return;
51
51
  const positions = [];
52
- for (const { presentation } of inlineAgentPanels.values()) {
52
+ for (const { presentation } of anchoredAgentPanels.values()) {
53
53
  if (!presentation.element.isConnected) continue;
54
54
  const rect = presentation.element.getBoundingClientRect();
55
55
  if (![rect.top, rect.left, rect.width, rect.height].every(Number.isFinite)) continue;
@@ -206,36 +206,41 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
206
206
  return context === undefined ? null : context.trim();
207
207
  };
208
208
 
209
- const inlineAgentPanels = new Map();
209
+ const anchoredAgentPanels = new Map();
210
210
 
211
- const stopInlineAgentPanelTracking = key => {
211
+ const stopAgentAnchorTracking = key => {
212
212
  if (key) {
213
- inlineAgentPanels.get(key)?.cleanup();
214
- inlineAgentPanels.delete(key);
213
+ anchoredAgentPanels.get(key)?.cleanup();
214
+ anchoredAgentPanels.delete(key);
215
215
  return;
216
216
  }
217
- for (const tracked of inlineAgentPanels.values()) tracked.cleanup();
218
- inlineAgentPanels.clear();
217
+ for (const tracked of anchoredAgentPanels.values()) tracked.cleanup();
218
+ anchoredAgentPanels.clear();
219
219
  };
220
220
 
221
- const inlineAgentPanelAnchor = (options, key) => {
221
+ const agentPanelAnchor = (options, key, layout) => {
222
222
  const anchor = options.anchor;
223
223
  if (!(anchor instanceof Element)) {
224
- throw new Error('Inline Agent panel anchor must be an element');
224
+ throw new Error('Agent panel anchor must be an element');
225
225
  }
226
226
  const rect = anchor.getBoundingClientRect();
227
227
  if (![rect.top, rect.left, rect.width, rect.height].every(Number.isFinite)) {
228
- throw new Error('Inline Agent panel anchor returned invalid bounds');
228
+ throw new Error('Agent panel anchor returned invalid bounds');
229
229
  }
230
230
  return {
231
231
  element: anchor,
232
232
  key,
233
+ layout,
233
234
  bounds: { top: rect.top, left: rect.left, width: rect.width, height: rect.height },
234
235
  };
235
236
  };
236
237
 
237
- const trackInlineAgentPanel = presentation => {
238
- stopInlineAgentPanelTracking(presentation.key);
238
+ const trackAgentAnchor = presentation => {
239
+ if (presentation.layout === 'workspace' || [...anchoredAgentPanels.values()].some(item => item.presentation.layout === 'workspace')) {
240
+ stopAgentAnchorTracking();
241
+ } else {
242
+ stopAgentAnchorTracking(presentation.key);
243
+ }
239
244
  let frame = null;
240
245
  const update = () => {
241
246
  frame = null;
@@ -281,7 +286,7 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
281
286
  window.removeEventListener('resize', schedule);
282
287
  document.removeEventListener('scroll', schedule, true);
283
288
  };
284
- inlineAgentPanels.set(presentation.key, { presentation, cleanup });
289
+ anchoredAgentPanels.set(presentation.key, { presentation, cleanup });
285
290
  };
286
291
 
287
292
  const scrollInlineAgentPage = (presentation, deltaX, deltaY) => {
@@ -311,8 +316,11 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
311
316
  };
312
317
 
313
318
  const agentPanelPresentation = (options, layout, key) => {
314
- if (layout !== 'inline') return null;
315
- return inlineAgentPanelAnchor(options, key);
319
+ if (layout === 'inline') return agentPanelAnchor(options, key, layout);
320
+ if (layout === 'workspace' && options.anchor !== undefined) {
321
+ return agentPanelAnchor(options, key || 'toolbox-workspace', layout);
322
+ }
323
+ return null;
316
324
  };
317
325
 
318
326
  const setAgentPanelVisible = async (visible, options = {}) => {
@@ -332,16 +340,16 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
332
340
  });
333
341
  if (presentation) {
334
342
  await ready;
335
- trackInlineAgentPanel(presentation);
343
+ trackAgentAnchor(presentation);
336
344
  } else if (!visible && key) {
337
- stopInlineAgentPanelTracking(key);
345
+ stopAgentAnchorTracking(key);
338
346
  } else {
339
- stopInlineAgentPanelTracking();
347
+ stopAgentAnchorTracking();
340
348
  }
341
349
  try {
342
350
  await request;
343
351
  } catch (error) {
344
- if (presentation) stopInlineAgentPanelTracking(presentation.key);
352
+ if (presentation) stopAgentAnchorTracking(presentation.key);
345
353
  throw error;
346
354
  }
347
355
  };
@@ -409,14 +417,14 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
409
417
  });
410
418
  if (presentation) {
411
419
  await ready;
412
- trackInlineAgentPanel(presentation);
420
+ trackAgentAnchor(presentation);
413
421
  } else {
414
- stopInlineAgentPanelTracking();
422
+ stopAgentAnchorTracking();
415
423
  }
416
424
  try {
417
425
  await request;
418
426
  } catch (error) {
419
- if (presentation) stopInlineAgentPanelTracking(presentation.key);
427
+ if (presentation) stopAgentAnchorTracking(presentation.key);
420
428
  throw error;
421
429
  }
422
430
  };
@@ -480,14 +488,14 @@ const PAGE_BRIDGE_SCRIPT = String.raw `(() => {
480
488
  if (
481
489
  response?.type === 'agent-panel-wheel' &&
482
490
  typeof response.key === 'string' &&
483
- inlineAgentPanels.has(response.key) &&
491
+ anchoredAgentPanels.has(response.key) &&
484
492
  typeof response.deltaX === 'number' &&
485
493
  Number.isFinite(response.deltaX) &&
486
494
  typeof response.deltaY === 'number' &&
487
495
  Number.isFinite(response.deltaY)
488
496
  ) {
489
497
  scrollInlineAgentPage(
490
- inlineAgentPanels.get(response.key).presentation,
498
+ anchoredAgentPanels.get(response.key).presentation,
491
499
  response.deltaX,
492
500
  response.deltaY,
493
501
  );
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mearl/client",
3
- "version": "2.20.0",
3
+ "version": "2.20.1",
4
4
  "description": "Unified Mearl SDK & CLI for local and remote browsers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -59,8 +59,8 @@
59
59
  "commander": "^15.0.0",
60
60
  "fastest-levenshtein": "^1.0.16",
61
61
  "ws": "^8.18.0",
62
- "@mearl/cloud-types": "2.20.0",
63
- "@mearl/provider": "2.20.0"
62
+ "@mearl/cloud-types": "2.20.1",
63
+ "@mearl/provider": "2.20.1"
64
64
  },
65
65
  "devDependencies": {
66
66
  "@types/node": "^24.9.1",